mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
Chat sits next to the mic in the command dock. Replies are silent and never request the microphone; the first message connects with the selected provider and runs the same map actions as voice through each provider's text API (OpenAI OPENAI_CHAT_MODEL, Gemini GEMINI_CHAT_MODEL via generateContent, which never starts Live). Only one mode runs at a time. - Chat panel rendered by the voice control presenter: conversation, recent and quick-command suggestions, Up/Down history, attachments (map-layer references or small UTF-8 text files, sent only with the message) - Chat and voice panels sit above the dock or dock into the right rail's column; minimized bars sit centred above the dock, and height animates on swaps - A centred panel steps down to its bar for the Location and Visual Presets trays without moving focus, rests above an open tray, and docks right while expanded over one; it returns to the centre once the trays close - Minimized voice previews the last sentence from each side; the empty Voice Preview suggests things to say - Settings opened from chat keep chat's frame and show the shared AI provider and quick commands; voice Settings show Back to voice - Closing chat ends a typed session; the voice panel's close turns voice off - The dock widens its voice control for the chat button and restyles its wings, which show icons only at 900px and below; assistant panels share the left panels' glass, and Cyber keeps its own surfaces - Server text-chat handlers with body, time and per-IP limits (GEV_RATELIMIT_*_CHAT_PER_MIN), documented in SECURITY.md; tests and all eleven locales Co-authored-by: Darren Dignam <[email protected]>
32 lines
1.4 KiB
JavaScript
32 lines
1.4 KiB
JavaScript
import { realtimeDirectives } from '../openai/instructions.js';
|
|
|
|
// Voice wording in the shared directives and its written form. A test checks
|
|
// each phrase still occurs in the directives, so rewording one there fails
|
|
// rather than leaking spoken wording into chat.
|
|
export const TEXT_WORDING = Object.freeze([
|
|
['without speaking first', 'without writing a preamble'],
|
|
['before speaking', 'before confirming'],
|
|
['may first say ONE sentence', 'may first write ONE sentence'],
|
|
["speak the result's say line", "write the result's say line"],
|
|
['on the voice card: speak a caveat', 'in the tool result: include a caveat'],
|
|
['as you talk', 'as you write'],
|
|
['you can read aloud', 'you can report'],
|
|
]);
|
|
|
|
// Shared-manual adaptation follows Darren Dignam's GEV COMMAND approach (#976).
|
|
// Keep our Radio handoff and annotation outcome policies from the shared manual.
|
|
export function textInstructions(annotationGuidance) {
|
|
return realtimeDirectives(annotationGuidance)
|
|
.map((line, index) => {
|
|
if (index === 0)
|
|
return "You are GEV Chat, a concise text assistant for a Cesium geospatial app called God's Eye View.";
|
|
if (index === 1)
|
|
return 'Have a natural written conversation. This is text-only chat; no microphone or generated audio is used.';
|
|
return TEXT_WORDING.reduce(
|
|
(text, [spoken, written]) => text.replace(spoken, written),
|
|
line,
|
|
);
|
|
})
|
|
.join('\n');
|
|
}
|