- Android voice assistant: RecognitionService, VoiceInteractionSession with startAssistantActivity, es-HN speech recognition - Voice transcript sent to first alive terminal via WebSocket, opens FloatingTranscriptDebug on correct session - PiP window: fix close button using getCurrentWebviewWindow(), add mini/restore toggle, remove alwaysOnTop - Add webview-close and window-destroy permissions to capabilities - Pixel art ocean scrollbar on /transcript-debug respecting scroll nav mode settings - Widget improvements: terminal list service, input widget provider, updated layouts
35 lines
1.2 KiB
TypeScript
35 lines
1.2 KiB
TypeScript
import { jsonResponse, errorResponse } from '../utils/cors'
|
|
import { PORT_TERMINAL } from '../config'
|
|
|
|
/**
|
|
* Proxy GET /api/session-state → terminal server.
|
|
* Returns session-state + terminal-registry combined,
|
|
* so external clients (Android widget) get everything in one call.
|
|
*/
|
|
export async function handleSessionStateProxy(url: URL): Promise<Response> {
|
|
const controller = new AbortController()
|
|
const timeout = setTimeout(() => controller.abort(), 6000)
|
|
|
|
try {
|
|
const [stateResp, registryResp] = await Promise.all([
|
|
fetch(`http://localhost:${PORT_TERMINAL}/session-state`, { signal: controller.signal }),
|
|
fetch(`http://localhost:${PORT_TERMINAL}/terminal-registry`, { signal: controller.signal })
|
|
])
|
|
|
|
const stateData = stateResp.ok ? await stateResp.json() : { agents: {} }
|
|
const registryData = registryResp.ok ? await registryResp.json() : { registry: [] }
|
|
|
|
return jsonResponse({
|
|
agents: stateData.agents ?? {},
|
|
registry: registryData.registry ?? []
|
|
})
|
|
} catch (e: any) {
|
|
const msg = e.name === 'AbortError'
|
|
? 'Terminal server timeout (6s)'
|
|
: `Failed to reach terminal server: ${e.message}`
|
|
return errorResponse(msg, 502)
|
|
} finally {
|
|
clearTimeout(timeout)
|
|
}
|
|
}
|