mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +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]>
72 lines
2.2 KiB
JavaScript
72 lines
2.2 KiB
JavaScript
import { createOpenAiChatHandler } from './openai/chat.js';
|
|
import { defaultSourceRoot } from './common/source-root.js';
|
|
import { handleHudSummary } from './openai/hud-summary.js';
|
|
import { createDebugLogHandler } from './openai/debug-log.js';
|
|
import {
|
|
createRealtimeOAuthLoginHandler,
|
|
createRealtimeOAuthStatusHandler,
|
|
createRealtimeTokenHandler,
|
|
} from './openai/realtime.js';
|
|
import { sameSiteGated } from './common/same-site.js';
|
|
import { createCodexOAuthLogin } from './openai/codex-auth.js';
|
|
|
|
/**
|
|
* Vite plugin: OpenAI Realtime ephemeral client secret.
|
|
*
|
|
* Keeps the selected cloud credential server-side while the browser connects
|
|
* to the Realtime API over WebRTC with a short-lived secret.
|
|
*/
|
|
function openAiRealtimeProxy({
|
|
sourceRoot = defaultSourceRoot,
|
|
annotationGuidance,
|
|
realtime = {},
|
|
} = {}) {
|
|
const oauthLogin = createCodexOAuthLogin(realtime);
|
|
function install(middlewares) {
|
|
middlewares.use(
|
|
'/api/openai/chat',
|
|
createOpenAiChatHandler({ ...realtime, annotationGuidance }),
|
|
);
|
|
// Cost-bearing and log endpoints refuse cross-site browser requests
|
|
// (see server/providers/common/same-site.js and SECURITY.md).
|
|
middlewares.use('/api/openai/hud-summary', sameSiteGated(handleHudSummary));
|
|
|
|
middlewares.use(
|
|
'/api/realtime/debug-log',
|
|
sameSiteGated(createDebugLogHandler({ sourceRoot })),
|
|
);
|
|
|
|
middlewares.use(
|
|
'/api/realtime/token',
|
|
sameSiteGated(
|
|
createRealtimeTokenHandler({ ...realtime, annotationGuidance }),
|
|
),
|
|
);
|
|
|
|
middlewares.use(
|
|
'/api/realtime/oauth-status',
|
|
sameSiteGated(createRealtimeOAuthStatusHandler({ oauthLogin })),
|
|
);
|
|
|
|
middlewares.use(
|
|
'/api/realtime/oauth-login',
|
|
sameSiteGated(createRealtimeOAuthLoginHandler({ oauthLogin })),
|
|
);
|
|
}
|
|
|
|
return {
|
|
name: 'openai-realtime-proxy',
|
|
configureServer(server) {
|
|
install(server.middlewares);
|
|
server.httpServer?.once('close', oauthLogin.dispose);
|
|
},
|
|
configurePreviewServer(server) {
|
|
install(server.middlewares);
|
|
server.httpServer?.once('close', oauthLogin.dispose);
|
|
},
|
|
closeBundle: oauthLogin.dispose,
|
|
};
|
|
}
|
|
|
|
export { openAiRealtimeProxy };
|