@cognidesk/voice-websocket 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +375 -0
- package/dist/index.js +841 -0
- package/dist/index.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { WebSocketServer } from \"ws\";\nimport type { IncomingMessage, Server as HttpServer } from \"node:http\";\nimport type { Duplex } from \"node:stream\";\nimport type { RawData, WebSocket } from \"ws\";\nimport type {\n HandleVoiceUserMessageInput,\n HandleVoiceUserMessageResult,\n RuntimeEvent,\n StartVoiceResult,\n VoiceProfile,\n VoiceSocketMetadata,\n} from \"@cognidesk/core\";\n\nexport const COGNIDESK_VOICE_PROTOCOL = \"cognidesk.voice.v1\" as const;\n\nexport type VoiceProtocol = typeof COGNIDESK_VOICE_PROTOCOL;\n\nexport type VoiceBrowserClientEvent =\n | {\n type: \"session.update\";\n event_id?: string;\n session?: Record<string, unknown>;\n }\n | {\n type: \"input_audio_buffer.append\";\n event_id?: string;\n audio: string;\n sequence?: number;\n }\n | {\n type: \"input_audio_buffer.commit\";\n event_id?: string;\n }\n | {\n type: \"input_audio_buffer.clear\";\n event_id?: string;\n }\n | {\n type: \"response.cancel\";\n event_id?: string;\n response_id?: string;\n interruptedMessageId?: string;\n playedUntilMs?: number;\n audioEndMs?: number;\n reason?: string;\n }\n | {\n type: \"conversation.item.truncate\";\n event_id?: string;\n item_id?: string;\n content_index?: number;\n audio_end_ms?: number;\n };\n\nexport type VoiceBrowserServerEvent =\n | {\n type: \"cognidesk.connection.ready\";\n event_id: string;\n protocol: VoiceProtocol;\n conversation: StartVoiceResult[\"conversation\"];\n channelSegment: StartVoiceResult[\"channelSegment\"];\n connection: StartVoiceResult[\"connection\"];\n lastAckSequence: number;\n }\n | {\n type: \"cognidesk.connection.reconnect_token\";\n event_id: string;\n token: string;\n expiresAt: string;\n }\n | {\n type: \"cognidesk.audio.ack\";\n event_id: string;\n sequence: number;\n }\n | {\n type: \"cognidesk.runtime_event\";\n event_id: string;\n event: RuntimeEvent;\n }\n | {\n type: \"cognidesk.turn.completed\";\n event_id: string;\n text: string;\n activeJourneyId?: string;\n }\n | {\n type: \"cognidesk.interruption.recorded\";\n event_id: string;\n event: RuntimeEvent;\n }\n | {\n type: \"cognidesk.voice.preamble\";\n event_id: string;\n text: string;\n elapsedMs: number;\n }\n | {\n type: \"input_audio_buffer.speech_started\";\n event_id?: string;\n audio_start_ms?: number;\n item_id?: string;\n }\n | {\n type: \"input_audio_buffer.speech_stopped\";\n event_id?: string;\n audio_end_ms?: number;\n item_id?: string;\n }\n | {\n type: \"input_audio_transcription.completed\";\n event_id: string;\n text: string;\n item_id?: string;\n startedAtMs?: number;\n endedAtMs?: number;\n transcriptionSource?: string;\n metadata?: Record<string, unknown>;\n }\n | {\n type: \"response.output_audio.delta\";\n event_id?: string;\n response_id?: string;\n item_id?: string;\n output_index?: number;\n content_index?: number;\n delta: string;\n }\n | {\n type: \"response.output_audio.done\";\n event_id?: string;\n response_id?: string;\n item_id?: string;\n output_index?: number;\n content_index?: number;\n }\n | {\n type: \"response.output_audio_transcript.delta\";\n event_id?: string;\n response_id?: string;\n item_id?: string;\n output_index?: number;\n content_index?: number;\n delta: string;\n }\n | {\n type: \"response.output_audio_transcript.done\";\n event_id?: string;\n response_id?: string;\n item_id?: string;\n output_index?: number;\n content_index?: number;\n transcript: string;\n }\n | {\n type: \"response.done\";\n event_id?: string;\n response?: unknown;\n }\n | {\n type: \"error\";\n event_id?: string;\n error: {\n code: string;\n message: string;\n retryable?: boolean;\n details?: unknown;\n };\n };\n\nexport type VoiceProviderEvent =\n | {\n kind: \"input_transcript.completed\";\n text: string;\n itemId?: string;\n startedAtMs?: number;\n endedAtMs?: number;\n transcriptionSource?: string;\n metadata?: Record<string, unknown>;\n }\n | {\n kind: \"server_event\";\n event: VoiceBrowserServerEvent;\n }\n | {\n kind: \"runtime_events\";\n events: RuntimeEvent[];\n }\n | {\n kind: \"error\";\n code?: string;\n message: string;\n retryable?: boolean;\n details?: unknown;\n };\n\ntype VoiceInputTranscriptEvent = Extract<VoiceProviderEvent, { kind: \"input_transcript.completed\" }>;\n\nexport interface VoiceProviderConnectInput {\n session: VoiceSocketSession;\n profile?: VoiceProfile;\n control?: VoiceControlSurface;\n signal: AbortSignal;\n onEvent(event: VoiceProviderEvent): Promise<void> | void;\n}\n\nexport interface VoiceProviderSession {\n send(event: VoiceBrowserClientEvent): Promise<void> | void;\n speak(input: { text: string; result?: HandleVoiceUserMessageResult }): Promise<void> | void;\n preamble?(input: { text: string }): Promise<void> | void;\n close(): Promise<void> | void;\n}\n\nexport interface VoiceProvider {\n readonly id: string;\n connect(input: VoiceProviderConnectInput): Promise<VoiceProviderSession>;\n}\n\nexport interface VoiceControlTool {\n name: string;\n description?: string;\n parameters?: unknown;\n}\n\nexport interface VoiceControlToolCall {\n session: VoiceSocketSession;\n name: string;\n arguments: unknown;\n callId: string;\n itemId?: string;\n responseId?: string;\n signal: AbortSignal;\n notify?(notification: VoiceControlNotification): Promise<void>;\n}\n\nexport interface VoiceControlToolResult {\n output: unknown;\n events?: RuntimeEvent[];\n}\n\nexport interface VoiceControlNotification {\n message: string;\n events?: RuntimeEvent[];\n responseInstructions?: string;\n createResponse?: boolean;\n}\n\nexport interface VoiceControlSurface {\n tools: VoiceControlTool[];\n instructions?: string;\n createSessionInstructions?(input: { session: VoiceSocketSession }): Promise<string> | string;\n handleToolCall(input: VoiceControlToolCall): Promise<VoiceControlToolResult> | VoiceControlToolResult;\n}\n\nexport interface VoiceSocketLike {\n send(data: string): void;\n close(code?: number, reason?: string): void;\n on(event: \"message\", listener: (data: string | ArrayBuffer | Uint8Array) => void): void;\n on(event: \"close\", listener: (code?: number, reason?: string) => void): void;\n on(event: \"error\", listener: (error: unknown) => void): void;\n}\n\nexport interface VoiceRecorder {\n onAudio?(input: {\n session: VoiceSocketSession;\n speaker: \"user\" | \"assistant\";\n audio: string;\n sequence?: number;\n }): Promise<void> | void;\n onTranscript?(input: {\n session: VoiceSocketSession;\n speaker: \"user\" | \"assistant\";\n text: string;\n runtimeEvent?: RuntimeEvent;\n }): Promise<void> | void;\n}\n\nexport interface VoiceSocketSession {\n id: string;\n conversation: StartVoiceResult[\"conversation\"];\n channelSegment: StartVoiceResult[\"channelSegment\"];\n connection: StartVoiceResult[\"connection\"];\n events: RuntimeEvent[];\n createdAt: string;\n updatedAt: string;\n status: \"pending\" | \"connected\" | \"reconnecting\" | \"ended\";\n lastAckSequence: number;\n reconnectGraceUntil?: string;\n}\n\nexport interface VoiceSocketToken {\n token: string;\n connectionId: string;\n sessionId: string;\n purpose: \"start\" | \"reconnect\";\n expiresAt: string;\n consumedAt?: string;\n}\n\nexport interface VoiceSessionStore {\n createSession(input: {\n result: StartVoiceResult;\n tokenTtlMs: number;\n now?: Date;\n }): Promise<{ session: VoiceSocketSession; socket: VoiceSocketMetadata }>;\n claimToken(input: {\n connectionId: string;\n token: string;\n now?: Date;\n }): Promise<{ session: VoiceSocketSession; token: VoiceSocketToken; reconnect: boolean } | null>;\n issueReconnectToken(input: {\n sessionId: string;\n ttlMs: number;\n now?: Date;\n }): Promise<VoiceSocketToken>;\n acknowledgeAudio(input: {\n sessionId: string;\n sequence: number;\n now?: Date;\n }): Promise<VoiceSocketSession>;\n markConnected(sessionId: string, now?: Date): Promise<VoiceSocketSession>;\n markReconnecting(sessionId: string, now?: Date, graceMs?: number): Promise<VoiceSocketSession>;\n markEnded(sessionId: string, now?: Date): Promise<VoiceSocketSession>;\n getSession(sessionId: string): Promise<VoiceSocketSession | null>;\n}\n\nexport interface InMemoryVoiceSessionStoreOptions {\n createToken?: () => string;\n}\n\nexport function createInMemoryVoiceSessionStore(\n options: InMemoryVoiceSessionStoreOptions = {},\n): VoiceSessionStore {\n const sessions = new Map<string, VoiceSocketSession>();\n const tokens = new Map<string, VoiceSocketToken>();\n const createToken = options.createToken ?? (() => createId(\"voice_socket_token\"));\n\n return {\n async createSession(input) {\n const now = input.now ?? new Date();\n const result = input.result;\n const session: VoiceSocketSession = {\n id: result.connection.id,\n conversation: result.conversation,\n channelSegment: result.channelSegment,\n connection: result.connection,\n events: result.events,\n createdAt: now.toISOString(),\n updatedAt: now.toISOString(),\n status: \"pending\",\n lastAckSequence: 0,\n };\n sessions.set(session.id, session);\n const token = createTokenRecord({\n createToken,\n connectionId: session.connection.id,\n sessionId: session.id,\n purpose: \"start\",\n ttlMs: input.tokenTtlMs,\n now,\n });\n tokens.set(token.token, token);\n return {\n session,\n socket: {\n url: \"\",\n token: token.token,\n expiresAt: token.expiresAt,\n protocol: COGNIDESK_VOICE_PROTOCOL,\n },\n };\n },\n\n async claimToken(input) {\n const now = input.now ?? new Date();\n const token = tokens.get(input.token);\n if (!token) return null;\n if (token.connectionId !== input.connectionId) return null;\n if (token.consumedAt) return null;\n if (Date.parse(token.expiresAt) <= now.getTime()) return null;\n const session = sessions.get(token.sessionId);\n if (!session || session.status === \"ended\") return null;\n token.consumedAt = now.toISOString();\n tokens.set(token.token, token);\n return {\n session,\n token,\n reconnect: token.purpose === \"reconnect\",\n };\n },\n\n async issueReconnectToken(input) {\n const session = sessions.get(input.sessionId);\n if (!session) throw new Error(`Voice session '${input.sessionId}' was not found.`);\n const token = createTokenRecord({\n createToken,\n connectionId: session.connection.id,\n sessionId: session.id,\n purpose: \"reconnect\",\n ttlMs: input.ttlMs,\n now: input.now ?? new Date(),\n });\n tokens.set(token.token, token);\n return token;\n },\n\n async acknowledgeAudio(input) {\n const session = requireSession(sessions, input.sessionId);\n if (input.sequence > session.lastAckSequence) {\n session.lastAckSequence = input.sequence;\n session.updatedAt = (input.now ?? new Date()).toISOString();\n sessions.set(session.id, session);\n }\n return session;\n },\n\n async markConnected(sessionId, now = new Date()) {\n const session = requireSession(sessions, sessionId);\n session.status = \"connected\";\n session.updatedAt = now.toISOString();\n delete session.reconnectGraceUntil;\n sessions.set(session.id, session);\n return session;\n },\n\n async markReconnecting(sessionId, now = new Date(), graceMs = 30_000) {\n const session = requireSession(sessions, sessionId);\n session.status = \"reconnecting\";\n session.updatedAt = now.toISOString();\n session.reconnectGraceUntil = new Date(now.getTime() + graceMs).toISOString();\n sessions.set(session.id, session);\n return session;\n },\n\n async markEnded(sessionId, now = new Date()) {\n const session = requireSession(sessions, sessionId);\n session.status = \"ended\";\n session.updatedAt = now.toISOString();\n sessions.set(session.id, session);\n return session;\n },\n\n async getSession(sessionId) {\n return sessions.get(sessionId) ?? null;\n },\n };\n}\n\nexport interface VoiceSocketHandshakeOptions {\n store: VoiceSessionStore;\n tokenTtlMs?: number;\n pathPrefix?: string;\n baseUrl?: string;\n}\n\nexport function createVoiceSocketHandshake(options: VoiceSocketHandshakeOptions) {\n const tokenTtlMs = options.tokenTtlMs ?? 60_000;\n const pathPrefix = normalizePathPrefix(options.pathPrefix ?? \"/voice/connections\");\n\n return {\n async createSocket(input: {\n result: StartVoiceResult;\n request: Request;\n basePath: string;\n }): Promise<VoiceSocketMetadata> {\n const created = await options.store.createSession({\n result: input.result,\n tokenTtlMs,\n });\n return {\n ...created.socket,\n url: buildSocketUrl({\n requestUrl: input.request.url,\n basePath: input.basePath,\n pathPrefix,\n connectionId: input.result.connection.id,\n token: created.socket.token,\n ...(options.baseUrl ? { baseUrl: options.baseUrl } : {}),\n }),\n };\n },\n };\n}\n\nexport interface VoiceRuntime {\n handleVoiceUserMessage<TTurn = unknown>(\n input: HandleVoiceUserMessageInput<TTurn>,\n ): Promise<HandleVoiceUserMessageResult>;\n commitVoiceTranscript?(input: {\n conversationId: string;\n channelSegmentId: string;\n speaker: \"user\" | \"assistant\";\n text: string;\n recordingReferenceId?: string;\n startedAtMs?: number;\n endedAtMs?: number;\n transcriptionSource?: string;\n metadata?: Record<string, unknown>;\n }): Promise<{ events: RuntimeEvent[]; event: RuntimeEvent; message: RuntimeEvent }>;\n recordVoiceInterruption(input: {\n conversationId: string;\n channelSegmentId: string;\n connectionId?: string;\n interruptedMessageId?: string;\n source?: \"userSpeech\" | \"adapter\" | \"provider\";\n reason?: string;\n recordingReferenceId?: string;\n offsetMs?: number;\n }): Promise<RuntimeEvent>;\n endVoiceSegment(input: {\n conversationId: string;\n channelSegmentId: string;\n connectionId?: string;\n reason?: string;\n }): Promise<RuntimeEvent>;\n}\n\nexport interface HandleVoiceSocketOptions {\n socket: VoiceSocketLike;\n connectionId: string;\n token: string;\n store: VoiceSessionStore;\n runtime: VoiceRuntime;\n provider: VoiceProvider;\n control?: VoiceControlSurface;\n profile?: VoiceProfile;\n recorder?: VoiceRecorder;\n initialGreeting?: string;\n reconnectTokenTtlMs?: number;\n reconnectGraceMs?: number;\n inputTranscriptDebounceMs?: number;\n turnPreambleMs?: number;\n signal?: AbortSignal;\n}\n\nexport async function handleVoiceSocket(options: HandleVoiceSocketOptions): Promise<void> {\n const claimed = await options.store.claimToken({\n connectionId: options.connectionId,\n token: options.token,\n });\n if (!claimed) {\n send(options.socket, {\n type: \"error\",\n event_id: createId(\"voice_event\"),\n error: {\n code: \"invalid_voice_socket_token\",\n message: \"Voice socket token is invalid, expired, or already used.\",\n },\n });\n options.socket.close(4401, \"Invalid voice socket token\");\n return;\n }\n\n const controller = new AbortController();\n const abort = () => controller.abort();\n options.signal?.addEventListener(\"abort\", abort, { once: true });\n const session = await options.store.markConnected(claimed.session.id);\n let providerSession: VoiceProviderSession | null = null;\n let closed = false;\n const inputTranscriptDebounceMs = Math.max(0, options.inputTranscriptDebounceMs ?? 350);\n const turnPreambleMs = Math.max(0, options.turnPreambleMs ?? 1_200);\n const useRealtimeControl = Boolean(options.control);\n let pendingInputTranscript: VoiceInputTranscriptEvent | null = null;\n let pendingInputTranscriptTimer: ReturnType<typeof setTimeout> | null = null;\n let turnPreambleTimer: ReturnType<typeof setTimeout> | null = null;\n let inputTranscriptQueue = Promise.resolve();\n let speechQueue = Promise.resolve();\n let speechGeneration = 0;\n\n const sendRuntimeEvents = (events: RuntimeEvent[]) => {\n for (const event of events) {\n send(options.socket, {\n type: \"cognidesk.runtime_event\",\n event_id: createId(\"voice_event\"),\n event,\n });\n }\n };\n\n const issueReconnect = async () => {\n const token = await options.store.issueReconnectToken({\n sessionId: session.id,\n ttlMs: options.reconnectTokenTtlMs ?? 30_000,\n });\n send(options.socket, {\n type: \"cognidesk.connection.reconnect_token\",\n event_id: createId(\"voice_event\"),\n token: token.token,\n expiresAt: token.expiresAt,\n });\n };\n\n const clearTurnPreambleTimer = () => {\n if (!turnPreambleTimer) return;\n clearTimeout(turnPreambleTimer);\n turnPreambleTimer = null;\n };\n\n const queueSpeechAction = (\n generation: number,\n action: () => Promise<void> | void,\n ) => {\n const queued = speechQueue.catch(() => undefined).then(async () => {\n if (closed || generation !== speechGeneration) return;\n await action();\n });\n speechQueue = queued.catch((error) => {\n send(options.socket, {\n type: \"error\",\n event_id: createId(\"voice_event\"),\n error: {\n code: \"voice_speech_failed\",\n message: error instanceof Error ? error.message : \"Failed to queue voice speech.\",\n },\n });\n });\n };\n\n const startTurnPreambleTimer = (text: string, generation: number) => {\n clearTurnPreambleTimer();\n if (!providerSession?.preamble) return;\n if (turnPreambleMs === 0) return;\n turnPreambleTimer = setTimeout(() => {\n turnPreambleTimer = null;\n queueSpeechAction(generation, () => providerSession?.preamble?.({ text }));\n }, turnPreambleMs);\n };\n\n const handleProviderEvent = async (event: VoiceProviderEvent) => {\n if (event.kind === \"runtime_events\") {\n sendRuntimeEvents(event.events);\n return;\n }\n if (event.kind === \"server_event\") {\n if (isAgentResponseSignal(event.event)) clearTurnPreambleTimer();\n send(options.socket, event.event);\n if (event.event.type === \"response.output_audio.delta\") {\n await options.recorder?.onAudio?.({\n session,\n speaker: \"assistant\",\n audio: event.event.delta,\n });\n }\n if (useRealtimeControl && event.event.type === \"response.output_audio_transcript.done\") {\n await commitControlAssistantTranscript(event.event.transcript, \"openai-realtime\");\n }\n return;\n }\n if (event.kind === \"error\") {\n send(options.socket, {\n type: \"error\",\n event_id: createId(\"voice_event\"),\n error: {\n code: event.code ?? \"voice_provider_error\",\n message: event.message,\n ...(event.retryable !== undefined ? { retryable: event.retryable } : {}),\n ...(event.details !== undefined ? { details: event.details } : {}),\n },\n });\n return;\n }\n scheduleInputTranscript(event);\n };\n\n const scheduleInputTranscript = (event: VoiceInputTranscriptEvent) => {\n const text = event.text.trim();\n if (!text) return;\n sendInputTranscriptCompleted(event, text);\n pendingInputTranscript = mergeInputTranscript(\n pendingInputTranscript,\n {\n ...event,\n text,\n },\n );\n if (pendingInputTranscriptTimer) clearTimeout(pendingInputTranscriptTimer);\n if (inputTranscriptDebounceMs === 0) {\n const transcript = pendingInputTranscript;\n pendingInputTranscript = null;\n if (transcript) queueInputTranscript(transcript);\n return;\n }\n const waitMs = debounceMsForTranscript(pendingInputTranscript.text, inputTranscriptDebounceMs);\n pendingInputTranscriptTimer = setTimeout(() => {\n const transcript = pendingInputTranscript;\n pendingInputTranscript = null;\n pendingInputTranscriptTimer = null;\n if (transcript) queueInputTranscript(transcript);\n }, waitMs);\n };\n\n const sendInputTranscriptCompleted = (event: VoiceInputTranscriptEvent, text: string) => {\n send(options.socket, {\n type: \"input_audio_transcription.completed\",\n event_id: createId(\"voice_event\"),\n text,\n ...optionalStringField(\"item_id\", event.itemId),\n ...optionalNumberField(\"startedAtMs\", event.startedAtMs),\n ...optionalNumberField(\"endedAtMs\", event.endedAtMs),\n ...optionalStringField(\"transcriptionSource\", event.transcriptionSource),\n ...(event.metadata !== undefined ? { metadata: event.metadata } : {}),\n });\n };\n\n const queueInputTranscript = (event: VoiceInputTranscriptEvent) => {\n inputTranscriptQueue = inputTranscriptQueue\n .then(() => useRealtimeControl ? commitControlInputTranscript(event) : commitInputTranscript(event))\n .catch((error) => {\n send(options.socket, {\n type: \"error\",\n event_id: createId(\"voice_event\"),\n error: {\n code: \"voice_transcript_commit_failed\",\n message: error instanceof Error ? error.message : \"Failed to commit voice transcript.\",\n },\n });\n });\n };\n\n const flushPendingInputTranscript = async () => {\n if (pendingInputTranscriptTimer) {\n clearTimeout(pendingInputTranscriptTimer);\n pendingInputTranscriptTimer = null;\n }\n const transcript = pendingInputTranscript;\n pendingInputTranscript = null;\n if (transcript) queueInputTranscript(transcript);\n await inputTranscriptQueue;\n };\n\n const commitControlInputTranscript = async (event: VoiceInputTranscriptEvent) => {\n if (!options.runtime.commitVoiceTranscript) return;\n const committed = await options.runtime.commitVoiceTranscript({\n conversationId: session.conversation.id,\n channelSegmentId: session.channelSegment.id,\n speaker: \"user\",\n text: event.text,\n transcriptionSource: event.transcriptionSource ?? \"provider\",\n ...optionalNumberField(\"startedAtMs\", event.startedAtMs),\n ...optionalNumberField(\"endedAtMs\", event.endedAtMs),\n ...(event.metadata !== undefined ? { metadata: event.metadata } : {}),\n });\n sendRuntimeEvents(committed.events);\n await options.recorder?.onTranscript?.({\n session,\n speaker: \"user\",\n text: event.text,\n runtimeEvent: committed.event,\n });\n };\n\n const commitControlAssistantTranscript = async (text: string | undefined, transcriptionSource: string) => {\n const normalized = normalizeSpeechText(text ?? \"\");\n if (!normalized || !options.runtime.commitVoiceTranscript) return;\n await flushPendingInputTranscript();\n const committed = await options.runtime.commitVoiceTranscript({\n conversationId: session.conversation.id,\n channelSegmentId: session.channelSegment.id,\n speaker: \"assistant\",\n text: normalized,\n transcriptionSource,\n });\n sendRuntimeEvents(committed.events);\n await options.recorder?.onTranscript?.({\n session,\n speaker: \"assistant\",\n text: normalized,\n runtimeEvent: committed.event,\n });\n send(options.socket, {\n type: \"cognidesk.turn.completed\",\n event_id: createId(\"voice_event\"),\n text: normalized,\n });\n };\n\n const controlSurface = options.control\n ? {\n ...options.control,\n handleToolCall: async (call: VoiceControlToolCall) => {\n await flushPendingInputTranscript();\n return options.control!.handleToolCall(call);\n },\n }\n : undefined;\n\n const commitInputTranscript = async (event: VoiceInputTranscriptEvent) => {\n const generation = ++speechGeneration;\n let assistantSpeechBuffer = \"\";\n let assistantSpeechQueued = false;\n const queueAssistantSpeech = (text: string, result?: HandleVoiceUserMessageResult) => {\n const normalized = normalizeSpeechText(text);\n if (!normalized) return;\n clearTurnPreambleTimer();\n assistantSpeechQueued = true;\n queueSpeechAction(generation, () => providerSession?.speak({ text: normalized, ...(result ? { result } : {}) }));\n };\n const flushAssistantSpeech = (force: boolean) => {\n while (true) {\n const chunk = takeSpeakablePrefix(assistantSpeechBuffer, force);\n if (!chunk) return;\n assistantSpeechBuffer = assistantSpeechBuffer.slice(chunk.consumed).trimStart();\n queueAssistantSpeech(chunk.text);\n if (!force) return;\n }\n };\n startTurnPreambleTimer(event.text, generation);\n const result = await options.runtime.handleVoiceUserMessage({\n conversationId: session.conversation.id,\n channelSegmentId: session.channelSegment.id,\n connectionId: session.connection.id,\n text: event.text,\n transcriptionSource: event.transcriptionSource ?? \"provider\",\n ...optionalNumberField(\"startedAtMs\", event.startedAtMs),\n ...optionalNumberField(\"endedAtMs\", event.endedAtMs),\n ...(event.metadata !== undefined ? { metadata: event.metadata } : {}),\n onAssistantTextDelta: (textDelta) => {\n assistantSpeechBuffer += textDelta;\n flushAssistantSpeech(false);\n },\n });\n clearTurnPreambleTimer();\n flushAssistantSpeech(true);\n if (!assistantSpeechQueued) {\n queueAssistantSpeech(result.text, result);\n }\n sendRuntimeEvents(result.events);\n const userRuntimeEvent = result.voiceEvents.find((candidate) =>\n candidate.type === \"voice.transcript.committed\" && candidate.data.speaker === \"user\"\n );\n await options.recorder?.onTranscript?.({\n session,\n speaker: \"user\",\n text: event.text,\n ...(userRuntimeEvent ? { runtimeEvent: userRuntimeEvent } : {}),\n });\n const assistantRuntimeEvent = result.voiceEvents.find((candidate) =>\n candidate.type === \"voice.transcript.committed\" && candidate.data.speaker === \"assistant\"\n );\n await options.recorder?.onTranscript?.({\n session,\n speaker: \"assistant\",\n text: result.text,\n ...(assistantRuntimeEvent ? { runtimeEvent: assistantRuntimeEvent } : {}),\n });\n send(options.socket, {\n type: \"cognidesk.turn.completed\",\n event_id: createId(\"voice_event\"),\n text: result.text,\n ...(result.activeJourneyId ? { activeJourneyId: result.activeJourneyId } : {}),\n });\n };\n\n try {\n const controlInstructions = await options.control?.createSessionInstructions?.({ session });\n providerSession = await options.provider.connect({\n session,\n ...(options.profile ? { profile: options.profile } : {}),\n ...(controlSurface ? {\n control: {\n ...controlSurface,\n instructions: [\n controlSurface.instructions,\n controlInstructions,\n ].filter(Boolean).join(\"\\n\\n\"),\n },\n } : {}),\n signal: controller.signal,\n onEvent: handleProviderEvent,\n });\n } catch (error) {\n send(options.socket, {\n type: \"error\",\n event_id: createId(\"voice_event\"),\n error: {\n code: \"voice_provider_connect_failed\",\n message: error instanceof Error ? error.message : \"Voice provider connection failed.\",\n },\n });\n options.socket.close(1011, \"Voice provider connection failed\");\n return;\n }\n\n send(options.socket, {\n type: \"cognidesk.connection.ready\",\n event_id: createId(\"voice_event\"),\n protocol: COGNIDESK_VOICE_PROTOCOL,\n conversation: session.conversation,\n channelSegment: session.channelSegment,\n connection: session.connection,\n lastAckSequence: session.lastAckSequence,\n });\n await issueReconnect();\n if (options.initialGreeting?.trim()) {\n queueSpeechAction(speechGeneration, () => providerSession?.speak({ text: options.initialGreeting!.trim() }));\n }\n\n options.socket.on(\"message\", (data) => {\n void handleClientMessage(String(data)).catch((error) => {\n send(options.socket, {\n type: \"error\",\n event_id: createId(\"voice_event\"),\n error: {\n code: \"voice_socket_message_failed\",\n message: error instanceof Error ? error.message : \"Failed to handle voice socket message.\",\n },\n });\n });\n });\n\n options.socket.on(\"error\", (error) => {\n send(options.socket, {\n type: \"error\",\n event_id: createId(\"voice_event\"),\n error: {\n code: \"voice_socket_error\",\n message: error instanceof Error ? error.message : \"Voice socket error.\",\n },\n });\n });\n\n options.socket.on(\"close\", (code) => {\n if (closed) return;\n closed = true;\n speechGeneration++;\n if (pendingInputTranscriptTimer) clearTimeout(pendingInputTranscriptTimer);\n clearTurnPreambleTimer();\n pendingInputTranscript = null;\n controller.abort();\n options.signal?.removeEventListener(\"abort\", abort);\n void providerSession?.close();\n const normalClose = code === undefined || code === 1000 || code === 1001;\n if (normalClose) {\n void options.store.markEnded(session.id).then(() =>\n options.runtime.endVoiceSegment({\n conversationId: session.conversation.id,\n channelSegmentId: session.channelSegment.id,\n connectionId: session.connection.id,\n reason: \"socket_closed\",\n })\n );\n } else {\n void options.store.markReconnecting(\n session.id,\n new Date(),\n options.reconnectGraceMs ?? 30_000,\n );\n }\n });\n\n async function handleClientMessage(raw: string) {\n const event = parseClientEvent(raw);\n if (event.type === \"input_audio_buffer.append\") {\n assertBase64Audio(event.audio);\n const sequence = event.sequence;\n const previousAckSequence = session.lastAckSequence;\n if (sequence !== undefined) {\n await options.store.acknowledgeAudio({ sessionId: session.id, sequence });\n send(options.socket, {\n type: \"cognidesk.audio.ack\",\n event_id: createId(\"voice_event\"),\n sequence,\n });\n }\n await options.recorder?.onAudio?.({\n session,\n speaker: \"user\",\n audio: event.audio,\n ...(sequence !== undefined ? { sequence } : {}),\n });\n if (sequence === undefined || sequence > previousAckSequence) {\n await providerSession?.send(event);\n }\n return;\n }\n if (event.type === \"response.cancel\") {\n speechGeneration++;\n clearTurnPreambleTimer();\n await providerSession?.send(event);\n const interruption = await options.runtime.recordVoiceInterruption({\n conversationId: session.conversation.id,\n channelSegmentId: session.channelSegment.id,\n connectionId: session.connection.id,\n source: \"userSpeech\",\n reason: event.reason ?? \"client_cancelled_response\",\n ...optionalStringField(\"interruptedMessageId\", event.interruptedMessageId),\n ...optionalNumberField(\"offsetMs\", event.playedUntilMs ?? event.audioEndMs),\n });\n send(options.socket, {\n type: \"cognidesk.interruption.recorded\",\n event_id: createId(\"voice_event\"),\n event: interruption,\n });\n sendRuntimeEvents([interruption]);\n return;\n }\n await providerSession?.send(event);\n }\n}\n\nexport interface AttachNodeVoiceWebSocketAdapterOptions {\n server: HttpServer;\n store: VoiceSessionStore;\n runtime: VoiceRuntime;\n provider: VoiceProvider;\n control?: VoiceControlSurface;\n profile?: VoiceProfile;\n recorder?: VoiceRecorder;\n pathPrefix?: string;\n initialGreeting?: string;\n reconnectTokenTtlMs?: number;\n reconnectGraceMs?: number;\n turnPreambleMs?: number;\n}\n\nexport function attachNodeVoiceWebSocketAdapter(options: AttachNodeVoiceWebSocketAdapterOptions) {\n const pathPrefix = normalizePathPrefix(options.pathPrefix ?? \"/voice/connections\");\n const webSocketServer = new WebSocketServer({ noServer: true });\n\n const upgradeListener = (request: IncomingMessage, socket: Duplex, head: Buffer) => {\n const parsed = parseVoiceSocketRequest(request, pathPrefix);\n if (!parsed) return;\n webSocketServer.handleUpgrade(request, socket, head, (webSocket) => {\n webSocketServer.emit(\"connection\", webSocket, request, parsed);\n });\n };\n\n options.server.on(\"upgrade\", upgradeListener);\n webSocketServer.on(\"connection\", (webSocket: WebSocket, _request: IncomingMessage, parsed: VoiceSocketRequest) => {\n void handleVoiceSocket({\n socket: adaptNodeWebSocket(webSocket),\n connectionId: parsed.connectionId,\n token: parsed.token,\n store: options.store,\n runtime: options.runtime,\n provider: options.provider,\n ...(options.control ? { control: options.control } : {}),\n ...(options.profile ? { profile: options.profile } : {}),\n ...(options.recorder ? { recorder: options.recorder } : {}),\n ...(options.initialGreeting !== undefined ? { initialGreeting: options.initialGreeting } : {}),\n ...(options.reconnectTokenTtlMs !== undefined ? { reconnectTokenTtlMs: options.reconnectTokenTtlMs } : {}),\n ...(options.reconnectGraceMs !== undefined ? { reconnectGraceMs: options.reconnectGraceMs } : {}),\n ...(options.turnPreambleMs !== undefined ? { turnPreambleMs: options.turnPreambleMs } : {}),\n });\n });\n\n return {\n close() {\n options.server.off(\"upgrade\", upgradeListener);\n webSocketServer.close();\n },\n webSocketServer,\n };\n}\n\ninterface VoiceSocketRequest {\n connectionId: string;\n token: string;\n}\n\nfunction parseVoiceSocketRequest(request: IncomingMessage, pathPrefix: string): VoiceSocketRequest | null {\n if (!request.url) return null;\n const url = new URL(request.url, \"http://localhost\");\n const expectedPrefix = `${pathPrefix}/`;\n if (!url.pathname.startsWith(expectedPrefix) || !url.pathname.endsWith(\"/socket\")) return null;\n const connectionId = decodeURIComponent(url.pathname.slice(expectedPrefix.length, -\"/socket\".length));\n if (!connectionId) return null;\n const token = url.searchParams.get(\"token\") ?? parseTokenFromProtocol(request.headers[\"sec-websocket-protocol\"]);\n if (!token) return null;\n return { connectionId, token };\n}\n\nfunction adaptNodeWebSocket(socket: WebSocket): VoiceSocketLike {\n return {\n send(data) {\n socket.send(data);\n },\n close(code, reason) {\n socket.close(code, reason);\n },\n on(event, listener) {\n if (event === \"message\") {\n socket.on(\"message\", (data: RawData) => {\n (listener as (data: string) => void)(rawDataToString(data));\n });\n return;\n }\n if (event === \"close\") {\n socket.on(\"close\", (code, reason) => {\n (listener as (code?: number, reason?: string) => void)(code, reason.toString(\"utf8\"));\n });\n return;\n }\n socket.on(\"error\", listener);\n },\n };\n}\n\nfunction parseClientEvent(raw: string): VoiceBrowserClientEvent {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error(\"Voice socket message must be valid JSON.\");\n }\n if (!isRecord(parsed)) throw new Error(\"Voice socket message must be a JSON object.\");\n const type = parsed.type;\n if (typeof type !== \"string\") throw new Error(\"Voice socket message type is required.\");\n switch (type) {\n case \"session.update\":\n return { type, ...optionalEventId(parsed), ...(isRecord(parsed.session) ? { session: parsed.session } : {}) };\n case \"input_audio_buffer.append\": {\n const audio = requiredString(parsed, \"audio\");\n const sequence = optionalInteger(parsed, \"sequence\");\n return { type, audio, ...optionalEventId(parsed), ...(sequence !== undefined ? { sequence } : {}) };\n }\n case \"input_audio_buffer.commit\":\n case \"input_audio_buffer.clear\":\n return { type, ...optionalEventId(parsed) };\n case \"response.cancel\":\n return {\n type,\n ...optionalEventId(parsed),\n ...optionalStringField(\"response_id\", optionalString(parsed, \"response_id\")),\n ...optionalStringField(\"interruptedMessageId\", optionalString(parsed, \"interruptedMessageId\")),\n ...optionalStringField(\"reason\", optionalString(parsed, \"reason\")),\n ...optionalNumberField(\"playedUntilMs\", optionalInteger(parsed, \"playedUntilMs\")),\n ...optionalNumberField(\"audioEndMs\", optionalInteger(parsed, \"audioEndMs\")),\n };\n case \"conversation.item.truncate\":\n return {\n type,\n ...optionalEventId(parsed),\n ...optionalStringField(\"item_id\", optionalString(parsed, \"item_id\")),\n ...optionalNumberField(\"content_index\", optionalInteger(parsed, \"content_index\")),\n ...optionalNumberField(\"audio_end_ms\", optionalInteger(parsed, \"audio_end_ms\")),\n };\n default:\n throw new Error(`Unsupported voice socket event '${type}'.`);\n }\n}\n\nfunction buildSocketUrl(input: {\n requestUrl: string;\n baseUrl?: string;\n basePath: string;\n pathPrefix: string;\n connectionId: string;\n token: string;\n}) {\n const requestUrl = new URL(input.requestUrl);\n const base = input.baseUrl ? new URL(input.baseUrl) : requestUrl;\n const protocol = base.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n const url = new URL(`${input.basePath}${input.pathPrefix}/${encodeURIComponent(input.connectionId)}/socket`, base);\n url.protocol = protocol;\n url.searchParams.set(\"token\", input.token);\n return url.toString();\n}\n\nfunction normalizePathPrefix(path: string) {\n const withSlash = path.startsWith(\"/\") ? path : `/${path}`;\n return withSlash.endsWith(\"/\") ? withSlash.slice(0, -1) : withSlash;\n}\n\nfunction createTokenRecord(input: {\n createToken: () => string;\n connectionId: string;\n sessionId: string;\n purpose: \"start\" | \"reconnect\";\n ttlMs: number;\n now: Date;\n}): VoiceSocketToken {\n return {\n token: input.createToken(),\n connectionId: input.connectionId,\n sessionId: input.sessionId,\n purpose: input.purpose,\n expiresAt: new Date(input.now.getTime() + input.ttlMs).toISOString(),\n };\n}\n\nfunction requireSession(sessions: Map<string, VoiceSocketSession>, sessionId: string) {\n const session = sessions.get(sessionId);\n if (!session) throw new Error(`Voice session '${sessionId}' was not found.`);\n return session;\n}\n\nfunction send(socket: VoiceSocketLike, event: VoiceBrowserServerEvent) {\n socket.send(JSON.stringify(event));\n}\n\nfunction mergeInputTranscript(\n current: VoiceInputTranscriptEvent | null,\n next: VoiceInputTranscriptEvent,\n): VoiceInputTranscriptEvent {\n if (!current) return next;\n const merged: VoiceInputTranscriptEvent = {\n kind: \"input_transcript.completed\",\n text: `${current.text} ${next.text}`.trim(),\n };\n const itemId = next.itemId ?? current.itemId;\n if (itemId) merged.itemId = itemId;\n const startedAtMs = current.startedAtMs ?? next.startedAtMs;\n if (startedAtMs !== undefined) merged.startedAtMs = startedAtMs;\n const endedAtMs = next.endedAtMs ?? current.endedAtMs;\n if (endedAtMs !== undefined) merged.endedAtMs = endedAtMs;\n const transcriptionSource = next.transcriptionSource ?? current.transcriptionSource;\n if (transcriptionSource) merged.transcriptionSource = transcriptionSource;\n const metadata = {\n ...(current.metadata ?? {}),\n ...(next.metadata ?? {}),\n };\n if (Object.keys(metadata).length > 0) merged.metadata = metadata;\n return merged;\n}\n\nfunction isAgentResponseSignal(event: VoiceBrowserServerEvent) {\n return event.type === \"response.output_audio.delta\"\n || event.type === \"response.output_audio_transcript.delta\"\n || event.type === \"response.output_audio_transcript.done\"\n || event.type === \"response.done\";\n}\n\nfunction takeSpeakablePrefix(text: string, force: boolean): { text: string; consumed: number } | null {\n if (!text.trim()) return null;\n if (force) return { text: normalizeSpeechText(text), consumed: text.length };\n const sentenceBoundary = findLastSentenceBoundary(text);\n if (sentenceBoundary > 0) {\n return {\n text: normalizeSpeechText(text.slice(0, sentenceBoundary)),\n consumed: sentenceBoundary,\n };\n }\n if (text.length < 180) return null;\n const softBoundary = findSoftBoundary(text, 140);\n if (softBoundary <= 0) return null;\n return {\n text: normalizeSpeechText(text.slice(0, softBoundary)),\n consumed: softBoundary,\n };\n}\n\nfunction findLastSentenceBoundary(text: string) {\n let boundary = -1;\n const pattern = /[.!?。!?](?:[\"')\\]]+)?\\s+/g;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(text)) !== null) {\n boundary = match.index + match[0].length;\n }\n return boundary;\n}\n\nfunction findSoftBoundary(text: string, minIndex: number) {\n const candidates = [\", \", \"; \", \": \", \"\\n\", \" \"];\n for (const candidate of candidates) {\n const boundary = text.lastIndexOf(candidate);\n if (boundary >= minIndex) return boundary + candidate.length;\n }\n return -1;\n}\n\nfunction normalizeSpeechText(text: string) {\n return text.replace(/\\s+/g, \" \").trim();\n}\n\nfunction debounceMsForTranscript(text: string, baseMs: number) {\n const wordCount = text.trim().split(\" \").filter(Boolean).length;\n return wordCount <= 2 ? Math.max(baseMs, 900) : baseMs;\n}\n\nfunction rawDataToString(data: RawData) {\n if (typeof data === \"string\") return data;\n if (Buffer.isBuffer(data)) return data.toString(\"utf8\");\n if (Array.isArray(data)) return Buffer.concat(data).toString(\"utf8\");\n return Buffer.from(data).toString(\"utf8\");\n}\n\nfunction parseTokenFromProtocol(value: string | string[] | undefined) {\n const raw = Array.isArray(value) ? value.join(\",\") : value;\n if (!raw) return undefined;\n const protocols = raw.split(\",\").map((candidate) => candidate.trim()).filter(Boolean);\n const bearer = protocols.find((candidate) => candidate.startsWith(\"cognidesk.voice.token.\"));\n return bearer?.slice(\"cognidesk.voice.token.\".length);\n}\n\nfunction assertBase64Audio(value: string) {\n if (value.length === 0) throw new Error(\"audio must not be empty.\");\n if (!/^[A-Za-z0-9+/]+={0,2}$/.test(value)) throw new Error(\"audio must be base64 encoded.\");\n}\n\nfunction optionalEventId(value: Record<string, unknown>) {\n return optionalStringField(\"event_id\", optionalString(value, \"event_id\"));\n}\n\nfunction requiredString(value: Record<string, unknown>, key: string) {\n const result = optionalString(value, key);\n if (!result) throw new Error(`${key} must be a non-empty string.`);\n return result;\n}\n\nfunction optionalString(value: Record<string, unknown>, key: string) {\n const candidate = value[key];\n if (candidate === undefined || candidate === null) return undefined;\n if (typeof candidate !== \"string\") throw new Error(`${key} must be a string.`);\n const trimmed = candidate.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction optionalInteger(value: Record<string, unknown>, key: string) {\n const candidate = value[key];\n if (candidate === undefined || candidate === null) return undefined;\n if (typeof candidate !== \"number\" || !Number.isSafeInteger(candidate) || candidate < 0) {\n throw new Error(`${key} must be a non-negative integer.`);\n }\n return candidate;\n}\n\nfunction optionalStringField<TKey extends string>(key: TKey, value: string | undefined) {\n return value ? { [key]: value } as Record<TKey, string> : {};\n}\n\nfunction optionalNumberField<TKey extends string>(key: TKey, value: number | undefined) {\n return value !== undefined ? { [key]: value } as Record<TKey, number> : {};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value && typeof value === \"object\" && !Array.isArray(value));\n}\n\nfunction createId(prefix: string) {\n const random = globalThis.crypto?.randomUUID?.()\n ?? Math.random().toString(36).slice(2);\n return `${prefix}_${random}`;\n}\n"],"mappings":"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","names":["result"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cognidesk/voice-websocket",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsup src/index.ts --format esm --dts --sourcemap",
|
|
16
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
17
|
+
"test": "vitest run --passWithNoTests",
|
|
18
|
+
"lint": "tsc -p tsconfig.json --noEmit"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@cognidesk/core": "0.0.1",
|
|
22
|
+
"ws": "^8.21.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/ws": "^8.18.1",
|
|
26
|
+
"tsup": "^8.5.0",
|
|
27
|
+
"typescript": "^5.9.3",
|
|
28
|
+
"vitest": "^4.0.14"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public",
|
|
32
|
+
"registry": "https://registry.npmjs.org/"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist"
|
|
36
|
+
]
|
|
37
|
+
}
|