@convai/web-sdk 1.8.0-beta.4 → 1.8.0-beta.6
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/README.md +64 -3
- package/dist/core/CharacterRoster.d.ts +84 -0
- package/dist/core/CharacterRoster.d.ts.map +1 -0
- package/dist/core/CharacterRoster.js +348 -0
- package/dist/core/CharacterRoster.js.map +1 -0
- package/dist/core/CharacterVersionManager.d.ts +100 -0
- package/dist/core/CharacterVersionManager.d.ts.map +1 -0
- package/dist/core/CharacterVersionManager.js +227 -0
- package/dist/core/CharacterVersionManager.js.map +1 -0
- package/dist/core/ConvaiClient.d.ts +109 -1
- package/dist/core/ConvaiClient.d.ts.map +1 -1
- package/dist/core/ConvaiClient.js +642 -49
- package/dist/core/ConvaiClient.js.map +1 -1
- package/dist/core/ConvaiRoomError.d.ts +48 -0
- package/dist/core/ConvaiRoomError.d.ts.map +1 -0
- package/dist/core/ConvaiRoomError.js +111 -0
- package/dist/core/ConvaiRoomError.js.map +1 -0
- package/dist/core/MessageHandler.d.ts +14 -0
- package/dist/core/MessageHandler.d.ts.map +1 -1
- package/dist/core/MessageHandler.js +111 -5
- package/dist/core/MessageHandler.js.map +1 -1
- package/dist/core/SSESession.d.ts +15 -0
- package/dist/core/SSESession.d.ts.map +1 -1
- package/dist/core/SSESession.js +92 -3
- package/dist/core/SSESession.js.map +1 -1
- package/dist/core/characterReference.d.ts +40 -0
- package/dist/core/characterReference.d.ts.map +1 -0
- package/dist/core/characterReference.js +72 -0
- package/dist/core/characterReference.js.map +1 -0
- package/dist/core/connectRequest.d.ts +1 -0
- package/dist/core/connectRequest.d.ts.map +1 -1
- package/dist/core/connectRequest.js +11 -0
- package/dist/core/connectRequest.js.map +1 -1
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/rosterRequest.d.ts +57 -0
- package/dist/core/rosterRequest.d.ts.map +1 -0
- package/dist/core/rosterRequest.js +210 -0
- package/dist/core/rosterRequest.js.map +1 -0
- package/dist/core/types.d.ts +717 -7
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/react/components/rtc-widget/components/MarkdownRenderer.d.ts.map +1 -1
- package/dist/react/components/rtc-widget/components/MarkdownRenderer.js +39 -44
- package/dist/react/components/rtc-widget/components/MarkdownRenderer.js.map +1 -1
- package/dist/react/hooks/useConvaiClient.d.ts.map +1 -1
- package/dist/react/hooks/useConvaiClient.js +15 -2
- package/dist/react/hooks/useConvaiClient.js.map +1 -1
- package/dist/utils/inlineMarkdown.d.ts +38 -0
- package/dist/utils/inlineMarkdown.d.ts.map +1 -0
- package/dist/utils/inlineMarkdown.js +106 -0
- package/dist/utils/inlineMarkdown.js.map +1 -0
- package/dist/vanilla/AudioRenderer.d.ts.map +1 -1
- package/dist/vanilla/AudioRenderer.js +6 -0
- package/dist/vanilla/AudioRenderer.js.map +1 -1
- package/dist/vanilla/ConvaiWidget.d.ts.map +1 -1
- package/dist/vanilla/ConvaiWidget.js +71 -57
- package/dist/vanilla/ConvaiWidget.js.map +1 -1
- package/dist/vanilla/index.d.ts +2 -0
- package/dist/vanilla/index.d.ts.map +1 -1
- package/dist/vanilla/index.js +2 -0
- package/dist/vanilla/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageHandler.js","sourceRoot":"","sources":["../../src/core/MessageHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { Room, RoomEvent } from \"livekit-client\";\nimport { ChatMessage, ConvaiAction, InteractionCreated, ServerResponse } from \"./types\";\nimport { EventEmitter } from \"./EventEmitter\";\nimport {\n BlendshapeQueue,\n type BlendshapeChunkMetadata,\n} from \"./BlendshapeQueue\";\n\ntype LifecycleOwnerPayload = {\n response_id?: string;\n neurosync_turn_id?: number;\n turn_id?: number;\n epoch?: number;\n};\n\n/**\n * Handles incoming messages from Convai\n * Processes various message types from the AI assistant and updates chat history\n */\nexport class MessageHandler extends EventEmitter {\n private room: Room | null = null;\n private chatMessages: ChatMessage[] = [];\n private activeBotLlmMessageId: string | null = null;\n private userTranscription: string = \"\";\n private logRtviMessages: boolean = true;\n private isBotResponding: boolean = false;\n private isSpeaking: boolean = false;\n private isListening: boolean = false;\n private totalBlendshapesReceived: number = 0;\n private blendshapeQueue: BlendshapeQueue;\n private _currentEmotion: { emotion: string; scale?: number } | null = null;\n // bot-output segments already added to the chat. The server re-sends the\n // same segment (full text) as TTS progress advances (spoken_status\n // in-progress → completed); only the first sighting may touch the chat.\n private seenBotOutputSegments = new Set<number | string>();\n\n // Fix 4: store a single bound reference so setupListeners/cleanupListeners use the\n // exact same function object. Previously .bind(this) in each call created a new\n // reference every time, making room.off() a no-op and leaking listeners on reconnect.\n private readonly _boundHandleDataReceived: (\n payload: Uint8Array,\n participant: unknown,\n ) => void;\n\n constructor(room?: Room) {\n super();\n this._boundHandleDataReceived = this.handleDataReceived.bind(this);\n this.blendshapeQueue = new BlendshapeQueue();\n if (room) {\n this.setRoom(room);\n }\n }\n\n /**\n * Get the blendshape queue instance\n */\n getBlendshapeQueue(): BlendshapeQueue {\n return this.blendshapeQueue;\n }\n\n /**\n * Enable or disable console logging for decoded incoming RTVI messages.\n */\n setRtviMessageLogging(enabled: boolean): void {\n this.logRtviMessages = enabled;\n }\n\n /**\n * Get current chat messages\n */\n getChatMessages(): ChatMessage[] {\n return this.chatMessages;\n }\n\n /**\n * Get current user transcription\n */\n getUserTranscription(): string {\n return this.userTranscription;\n }\n\n /**\n * Get bot responding state\n */\n getIsBotResponding(): boolean {\n return this.isBotResponding;\n }\n\n /**\n * Get speaking state\n */\n getIsSpeaking(): boolean {\n return this.isSpeaking;\n }\n\n /**\n * Get current bot emotion (updated from bot-emotion messages)\n */\n getEmotion(): { emotion: string; scale?: number } | null {\n return this._currentEmotion;\n }\n\n /**\n * Get whether the user is currently speaking (bot is in \"listening\" state).\n * True from user-started-speaking until user-stopped-speaking.\n */\n getIsListening(): boolean {\n return this.isListening;\n }\n\n /**\n * Local interruption path used by the client before the server cancel/terminal\n * arrives. Keep MessageHandler state and BlendshapeQueue state in sync so the\n * next bot-started-speaking can activate cleanly.\n */\n interruptLipsyncPlayback(): void {\n const wasSpeaking = this.isSpeaking;\n this.isSpeaking = false;\n this.blendshapeQueue.interrupt();\n if (wasSpeaking) {\n this.emit(\"speakingChange\", false);\n }\n }\n\n /**\n * Set the LiveKit room instance\n */\n setRoom(room: Room): void {\n // Clean up previous room listeners\n if (this.room) {\n this.cleanupListeners();\n }\n\n this.room = room;\n this.setupListeners();\n }\n\n /**\n * Setup message listeners\n */\n private setupListeners(): void {\n if (!this.room) return;\n\n this.room.on(RoomEvent.DataReceived, this._boundHandleDataReceived);\n }\n\n /**\n * Clean up message listeners\n */\n private cleanupListeners(): void {\n if (!this.room) return;\n\n this.room.off(RoomEvent.DataReceived, this._boundHandleDataReceived);\n }\n\n /**\n * Handle incoming data message\n */\n private handleDataReceived(\n payload: Uint8Array,\n _participant: unknown,\n _transport: \"livekit\" | \"websocket\" = \"livekit\",\n ): void {\n let messageString = \"\";\n let parsed = false;\n\n try {\n // Decode bytes to string\n const decoder = new TextDecoder();\n messageString = decoder.decode(payload);\n\n // Parse JSON\n const messageData = JSON.parse(messageString);\n parsed = true;\n\n // Extract and categorize messages for chat display\n const timestamp = new Date().toISOString();\n const messageId = `${messageData.type}-${Date.now()}-${Math.random()}`;\n\n // Handle different message types\n switch (messageData.type) {\n // User text messages - Skip these, only allow user-transcription\n case \"user_text_message\":\n case \"user-llm-text\":\n case \"text-input\":\n case \"user-input\":\n case \"text-message\":\n case \"chat-message\":\n case \"input-text\":\n case \"message\":\n // Skip user text messages - only allow user-transcription\n break;\n\n // Bot Ready - Bot is ready, connection should be true\n case \"bot-ready\":\n this.emit(\"botReady\");\n break;\n\n // Bot LLM Started - Begin streaming response\n case \"bot-llm-started\":\n this.isBotResponding = true;\n this.emit(\"botRespondingChange\", true);\n this.seenBotOutputSegments.clear();\n\n // Add initial streaming message to chat\n const streamingMessage: ChatMessage = {\n id: messageId,\n type: \"bot-llm-text\",\n content: \"\",\n timestamp: timestamp,\n isStreaming: true,\n };\n this.activeBotLlmMessageId = messageId;\n this.chatMessages.push(streamingMessage);\n this.emit(\"messagesChange\", this.chatMessages);\n break;\n\n // Bot Output - Aggregated output stream (sentence/word-level, replaces bot-transcript)\n // Payload: { text, spoken, aggregated_by, segment_id, spoken_status,\n // spoken_progress }. The same segment_id is re-sent with the FULL\n // segment text on every TTS progress tick (spoken_status\n // \"in-progress\" → \"completed\"), so appending per event repeats the\n // sentence once per tick.\n case \"bot-output\":\n if (messageData.data?.text) {\n const newText = messageData.data.text;\n const segmentId = messageData.data.segment_id as\n | number\n | string\n | undefined;\n this.emit(\"botOutput\", {\n text: newText,\n spoken: messageData.data.spoken ?? false,\n aggregatedBy: messageData.data.aggregated_by ?? \"sentence\",\n segmentId,\n spokenStatus: messageData.data.spoken_status,\n });\n\n // Progress re-send of a segment already in the chat — skip.\n if (segmentId !== undefined) {\n if (this.seenBotOutputSegments.has(segmentId)) break;\n this.seenBotOutputSegments.add(segmentId);\n }\n\n const activeBotLlmMessage = this.activeBotLlmMessageId\n ? this.chatMessages.find(\n (message) => message.id === this.activeBotLlmMessageId,\n )\n : undefined;\n const lastMsg = this.chatMessages[this.chatMessages.length - 1];\n // When the reply is rendered by the LLM text stream\n // (bot-llm-text), the TTS echo adds nothing — never mix\n // bot-output into an LLM bubble (streaming or complete).\n if (activeBotLlmMessage?.type === \"bot-llm-text\") break;\n if (lastMsg?.type === \"bot-llm-text\") break;\n if (\n lastMsg?.type === \"bot-output\" &&\n lastMsg.content.includes(newText)\n ) {\n break;\n }\n if (lastMsg?.type === \"bot-output\" && lastMsg.isStreaming) {\n this.chatMessages[this.chatMessages.length - 1] = {\n ...lastMsg,\n content: lastMsg.content + newText,\n };\n } else {\n this.chatMessages.push({\n id: `bot-output-${Date.now()}-${Math.random()}`,\n type: \"bot-output\",\n content: newText,\n timestamp: new Date().toISOString(),\n isStreaming: true,\n });\n }\n this.emit(\"messagesChange\", this.chatMessages);\n }\n break;\n\n // Bot LLM Text Messages - Streaming chunks\n case \"bot-llm-text\":\n if (messageData.data?.text) {\n const newChunk = messageData.data.text;\n\n // Update the streaming message in chat\n const activeIndex = this.activeBotLlmMessageId\n ? this.chatMessages.findIndex(\n (message) =>\n message.id === this.activeBotLlmMessageId &&\n message.type === \"bot-llm-text\" &&\n message.isStreaming,\n )\n : -1;\n if (activeIndex >= 0) {\n const activeMessage = this.chatMessages[activeIndex];\n this.chatMessages[activeIndex] = {\n ...activeMessage,\n content: activeMessage.content + newChunk,\n };\n } else {\n // If no streaming message exists yet, create one\n const streamingMsg: ChatMessage = {\n id: `${messageData.type}-${Date.now()}-${Math.random()}`,\n type: \"bot-llm-text\",\n content: newChunk,\n timestamp: new Date().toISOString(),\n isStreaming: true,\n };\n this.activeBotLlmMessageId = streamingMsg.id;\n this.chatMessages.push(streamingMsg);\n }\n this.emit(\"messagesChange\", this.chatMessages);\n }\n break;\n\n // Bot LLM Stopped - Complete streaming response\n case \"bot-llm-stopped\":\n const activeIndex = this.activeBotLlmMessageId\n ? this.chatMessages.findIndex(\n (message) => message.id === this.activeBotLlmMessageId,\n )\n : -1;\n if (activeIndex >= 0 && this.chatMessages[activeIndex].isStreaming) {\n const activeMessage = this.chatMessages[activeIndex];\n this.chatMessages[activeIndex] = {\n ...activeMessage,\n isStreaming: false,\n };\n }\n\n // Clear streaming state\n this.isBotResponding = false;\n this.emit(\"botRespondingChange\", false);\n this.emit(\"messagesChange\", this.chatMessages);\n break;\n\n // User Transcription Messages\n case \"user-transcription\":\n if (messageData.data?.text) {\n const messageContent = messageData.data.text;\n\n if (messageData.data?.final) {\n // Final transcription - accumulate in single bubble until bot responds\n const lastUserMsg =\n this.chatMessages[this.chatMessages.length - 1];\n\n // Check if last message is an accumulating user message (isStreaming=true)\n if (\n lastUserMsg &&\n lastUserMsg.type === \"user-transcription\" &&\n lastUserMsg.isStreaming === true\n ) {\n // Accumulate: append new content to existing message with space\n const accumulatedContent =\n lastUserMsg.content.trim() + \" \" + messageContent.trim();\n\n this.chatMessages[this.chatMessages.length - 1] = {\n ...lastUserMsg,\n content: accumulatedContent,\n timestamp: timestamp,\n };\n } else {\n // Start new accumulating message (isStreaming=true means \"still accumulating\")\n const userMessage: ChatMessage = {\n id: messageId,\n type: \"user-transcription\",\n content: messageContent,\n timestamp: timestamp,\n isStreaming: true,\n };\n this.chatMessages.push(userMessage);\n }\n this.emit(\"messagesChange\", this.chatMessages);\n\n // Clear live transcription when final\n this.userTranscription = \"\";\n this.emit(\"userTranscriptionChange\", \"\");\n } else {\n // Non-final transcription - show in input field\n this.userTranscription = messageContent;\n this.emit(\"userTranscriptionChange\", messageContent);\n }\n }\n break;\n\n // Bot Emotion Messages — LiveKit path: arrives as an RTVI message frame (messageData.data)\n case \"bot-emotion\":\n if (messageData.data?.emotion) {\n this._currentEmotion = {\n emotion: messageData.data.emotion,\n scale: messageData.data.scale,\n };\n console.log(\"[SDK bot-emotion]\", messageData.data);\n this.emit(\"emotionChange\", this._currentEmotion);\n const emotionMessage: ChatMessage = {\n id: messageId,\n type: \"bot-emotion\",\n content: `${messageData.data.emotion} (scale: ${messageData.data.scale || 1})`,\n timestamp,\n };\n this.chatMessages.push(emotionMessage);\n this.emit(\"messagesChange\", this.chatMessages);\n }\n break;\n // Bot TTS Text - Words as spoken by TTS (word-by-word for socket-based TTS)\n case \"bot-tts-text\":\n if (messageData.data?.text) {\n this.emit(\"botTtsText\", { text: messageData.data.text });\n }\n break;\n\n // Bot TTS lifecycle (more granular than bot-started/stopped-speaking)\n case \"bot-tts-started\":\n this.emit(\"botTtsStarted\");\n break;\n\n case \"bot-tts-stopped\":\n this.emit(\"botTtsStopped\");\n break;\n\n // Server-side muting indicators\n case \"user-mute-started\":\n this.emit(\"userMuteStarted\");\n break;\n\n case \"user-mute-stopped\":\n this.emit(\"userMuteStopped\");\n break;\n\n case \"user-started-speaking\":\n this.isListening = true;\n this.emit(\"listeningChange\", true);\n break;\n\n case \"user-stopped-speaking\":\n this.isListening = false;\n this.emit(\"listeningChange\", false);\n break;\n\n // Bot Started Speaking (priority over listening: state becomes speaking)\n case \"bot-started-speaking\": {\n const owner = this.lifecycleOwner(messageData.data);\n if (this.blendshapeQueue.isStaleOwner(owner)) {\n break;\n }\n const allowed = this.blendshapeQueue.startBotSpeaking();\n if (allowed) {\n this.isSpeaking = true;\n this.totalBlendshapesReceived = 0;\n this.emit(\"speakingChange\", true);\n }\n break;\n }\n\n // Bot Stopped Speaking\n case \"bot-stopped-speaking\":\n if (this.blendshapeQueue.isStaleOwner(this.lifecycleOwner(messageData.data))) {\n break;\n }\n if (this.isSpeaking) {\n this.isSpeaking = false;\n this.blendshapeQueue.stopBotSpeaking();\n this.emit(\"speakingChange\", false);\n }\n break;\n\n // Action Response Messages (LiveKit/WebRTC path)\n case \"action-response\":\n this._handleActionResponse(messageData.data?.actions ?? [], messageId, timestamp);\n break;\n\n case \"metrics\":\n if (messageData.data) {\n this.emit(\"metrics\", messageData.data);\n }\n break;\n // Behavior Tree Response Messages\n case \"behavior-tree-response\":\n if (messageData.data?.narrative_section_id) {\n const behaviorMessage: ChatMessage = {\n id: messageId,\n type: \"behavior-tree\",\n content: `Narrative Section: ${messageData.data.narrative_section_id}`,\n timestamp,\n };\n this.chatMessages.push(behaviorMessage);\n this.emit(\"messagesChange\", this.chatMessages);\n }\n break;\n\n // Server Message - Contains various data types like blendshapes\n case \"server-message\":\n if (messageData.data) {\n const serverData = messageData.data;\n\n switch (serverData.type) {\n case \"final-user-transcription\":\n if (serverData.text) {\n const finalText = serverData.text;\n const lastUserMsg =\n this.chatMessages[this.chatMessages.length - 1];\n if (\n lastUserMsg &&\n lastUserMsg.type === \"user-transcription\" &&\n lastUserMsg.isStreaming === true\n ) {\n this.chatMessages[this.chatMessages.length - 1] = {\n ...lastUserMsg,\n content: finalText,\n timestamp,\n isStreaming: false,\n };\n } else {\n this.chatMessages.push({\n id: `${serverData.type}-${Date.now()}-${Math.random()}`,\n type: \"user-transcription\",\n content: finalText,\n timestamp,\n isStreaming: false,\n });\n }\n this.emit(\"messagesChange\", this.chatMessages);\n this.userTranscription = \"\";\n this.emit(\"userTranscriptionChange\", \"\");\n }\n break;\n\n // WebSocket path: arrives inside a bot-text data message as serverData (not messageData.data)\n case \"bot-emotion\":\n if (serverData.emotion) {\n this._currentEmotion = {\n emotion: serverData.emotion,\n scale: serverData.scale,\n };\n console.log(\"[SDK bot-emotion (ws)]\", serverData);\n this.emit(\"emotionChange\", this._currentEmotion);\n }\n break;\n\n case \"blendshape-turn-stats\":\n if (this.blendshapeQueue.isStaleOwner(this.lifecycleOwner(serverData))) {\n break;\n }\n this.blendshapeQueue.endConversation(\n serverData.stats,\n this.lifecycleOwner(serverData),\n );\n this.emit(\"blendshapeStatsReceived\", serverData);\n break;\n\n case \"chunked-neurosync-blendshapes\":\n if (serverData.blendshapes) {\n const owner = this.lifecycleOwner(serverData);\n if (this.blendshapeQueue.isRetiredOwner(owner)) {\n break;\n }\n // If the queue is idle (no active conversation, bot not yet speaking),\n // start a conversation so early chunks from an initial bot greeting\n // are accepted rather than silently dropped.\n if (\n !this.blendshapeQueue.isConversationActive() &&\n !this.isSpeaking\n ) {\n this.blendshapeQueue.startConversation();\n }\n this.blendshapeQueue.addChunk(\n serverData.blendshapes,\n owner,\n );\n if (\n this.blendshapeQueue.consumeOwnerReplacementStoppedSpeaking() &&\n this.isSpeaking\n ) {\n this.isSpeaking = false;\n this.emit(\"speakingChange\", false);\n }\n this.totalBlendshapesReceived +=\n serverData.blendshapes.length;\n this.emit(\"blendshapes\", serverData);\n }\n break;\n\n case \"neurosync-blendshapes-cancel\": {\n const cancelledActive = this.blendshapeQueue.cancelOwner(\n this.lifecycleOwner(serverData),\n );\n if (cancelledActive && this.isSpeaking) {\n this.isSpeaking = false;\n this.emit(\"speakingChange\", false);\n }\n this.emit(\"blendshapeCancel\", serverData);\n break;\n }\n\n case \"user-idle-warning\": {\n const remainingSeconds: number | null =\n serverData.remaining_seconds ??\n serverData.remainingSeconds ??\n null;\n this.emit(\"idleWarning\", { remainingSeconds });\n this.chatMessages.push({\n id: `user-idle-warning-${Date.now()}-${Math.random()}`,\n type: \"idle-warning\",\n content:\n remainingSeconds !== null ? String(remainingSeconds) : \"\",\n timestamp,\n });\n this.emit(\"messagesChange\", this.chatMessages);\n break;\n }\n\n case \"llm-no-response\":\n this.emit(\"llmNoResponse\");\n this.chatMessages.push({\n id: `llm-no-response-${Date.now()}-${Math.random()}`,\n type: \"llm-no-response\",\n content: \"\",\n timestamp,\n });\n this.emit(\"messagesChange\", this.chatMessages);\n break;\n\n // Action Response (WebSocket/RTVI path — wrapped in server-message)\n case \"action-response\":\n this._handleActionResponse(serverData.actions ?? [], messageId, timestamp);\n break;\n\n // Server acknowledgment — arrives wrapped in server-message envelope\n case \"server-response\": {\n // client-ready is an internal RTVI handshake; server echoes an\n // \"Unknown message type\" error for it which is expected and harmless.\n if (serverData.event_type === \"client-ready\") break;\n const serverResponse: ServerResponse = {\n event_type: serverData.event_type ?? \"unknown\",\n status: serverData.status ?? \"error\",\n message: serverData.message ?? null,\n extras: serverData.extras ?? null,\n };\n this.emit(\"serverResponse\", serverResponse);\n break;\n }\n\n // interaction-created: session IDs for analytics/tracking\n case \"interaction-created\": {\n const interactionCreated: InteractionCreated = {\n interactionId: serverData.interaction_id,\n characterSessionId: serverData.character_session_id,\n };\n this.emit(\"interactionCreated\", interactionCreated);\n break;\n }\n }\n }\n break;\n\n // Fallback: server-response at top level (not currently observed but kept for safety)\n case \"server-response\": {\n if (messageData.event_type === \"client-ready\") break;\n const serverResponse: ServerResponse = {\n event_type: messageData.event_type ?? \"unknown\",\n status: messageData.status ?? \"error\",\n message: messageData.message ?? null,\n extras: messageData.extras ?? null,\n };\n this.emit(\"serverResponse\", serverResponse);\n break;\n }\n\n // Silently ignore other message types\n case \"moderation-response\":\n case \"trigger-message\":\n case \"update-template-keys\":\n case \"update-dynamic-info\":\n case \"interrupt-bot\":\n break;\n }\n } catch (error) {\n // Silently handle parse errors\n }\n }\n\n private _handleActionResponse(\n actions: ConvaiAction[],\n messageId: string,\n timestamp: string,\n ): void {\n this.emit(\"actionResponse\", { actions });\n const label = actions.length === 0\n ? \"No action\"\n : actions.map((a) => (a.target ? `${a.name} → ${a.target}` : a.name)).join(\", \");\n const actionMessage: ChatMessage = {\n id: messageId,\n type: \"action\",\n content: label,\n timestamp,\n };\n this.chatMessages.push(actionMessage);\n this.emit(\"messagesChange\", this.chatMessages);\n }\n\n private lifecycleOwner(\n data: LifecycleOwnerPayload | undefined,\n ): BlendshapeChunkMetadata {\n if (!data) {\n return {};\n }\n\n return {\n responseId: data.response_id,\n neurosyncTurnId: data.neurosync_turn_id ?? data.turn_id,\n epoch: data.epoch,\n fps: this.numberOrUndefined((data as { fps?: number }).fps),\n startFrameIndex: this.numberOrUndefined(\n (data as { start_frame_index?: number }).start_frame_index,\n ),\n };\n }\n\n private numberOrUndefined(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value)\n ? value\n : undefined;\n }\n\n /**\n * Public entry point for WebSocket transport to inject messages into the same pipeline.\n */\n handleDataReceivedPublic(payload: Uint8Array): void {\n this.handleDataReceived(payload, null, \"websocket\");\n }\n\n /**\n * Reset message state\n */\n reset(): void {\n this.chatMessages = [];\n this.activeBotLlmMessageId = null;\n this.userTranscription = \"\";\n this.isBotResponding = false;\n this.isSpeaking = false;\n this.isListening = false;\n this.totalBlendshapesReceived = 0;\n this._currentEmotion = null;\n this.blendshapeQueue.reset();\n this.emit(\"messagesChange\", this.chatMessages);\n this.emit(\"userTranscriptionChange\", \"\");\n this.emit(\"botRespondingChange\", false);\n this.emit(\"speakingChange\", false);\n this.emit(\"listeningChange\", false);\n this.emit(\"emotionChange\", null);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MessageHandler.js","sourceRoot":"","sources":["../../src/core/MessageHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { Room, RoomEvent } from \"livekit-client\";\nimport {\n ChatMessage,\n ConvaiAction,\n InteractionCreated,\n ServerResponse,\n CharacterStatusEvent,\n} from \"./types\";\nimport { EventEmitter } from \"./EventEmitter\";\nimport {\n BlendshapeQueue,\n type BlendshapeChunkMetadata,\n} from \"./BlendshapeQueue\";\n\ntype LifecycleOwnerPayload = {\n response_id?: string;\n neurosync_turn_id?: number;\n turn_id?: number;\n epoch?: number;\n};\n\n/**\n * Handles incoming messages from Convai\n * Processes various message types from the AI assistant and updates chat history\n */\nexport class MessageHandler extends EventEmitter {\n private room: Room | null = null;\n private chatMessages: ChatMessage[] = [];\n private activeBotLlmMessageId: string | null = null;\n private userTranscription: string = \"\";\n private logRtviMessages: boolean = true;\n private isBotResponding: boolean = false;\n private isSpeaking: boolean = false;\n private isListening: boolean = false;\n private totalBlendshapesReceived: number = 0;\n private blendshapeQueue: BlendshapeQueue;\n private _currentEmotion: { emotion: string; scale?: number } | null = null;\n // bot-output segments already added to the chat. The server re-sends the\n // same segment (full text) as TTS progress advances (spoken_status\n // in-progress → completed); only the first sighting may touch the chat.\n private seenBotOutputSegments = new Set<number | string>();\n\n // Fix 4: store a single bound reference so setupListeners/cleanupListeners use the\n // exact same function object. Previously .bind(this) in each call created a new\n // reference every time, making room.off() a no-op and leaking listeners on reconnect.\n private readonly _boundHandleDataReceived: (\n payload: Uint8Array,\n participant: unknown,\n ) => void;\n\n constructor(room?: Room) {\n super();\n this._boundHandleDataReceived = this.handleDataReceived.bind(this);\n this.blendshapeQueue = new BlendshapeQueue();\n if (room) {\n this.setRoom(room);\n }\n }\n\n /**\n * Get the blendshape queue instance\n */\n getBlendshapeQueue(): BlendshapeQueue {\n return this.blendshapeQueue;\n }\n\n /**\n * Enable or disable console logging for decoded incoming RTVI messages.\n */\n setRtviMessageLogging(enabled: boolean): void {\n this.logRtviMessages = enabled;\n }\n\n /**\n * Get current chat messages\n */\n getChatMessages(): ChatMessage[] {\n return this.chatMessages;\n }\n\n /**\n * Get current user transcription\n */\n getUserTranscription(): string {\n return this.userTranscription;\n }\n\n /**\n * Get bot responding state\n */\n getIsBotResponding(): boolean {\n return this.isBotResponding;\n }\n\n /**\n * Get speaking state\n */\n getIsSpeaking(): boolean {\n return this.isSpeaking;\n }\n\n /**\n * Get current bot emotion (updated from bot-emotion messages)\n */\n getEmotion(): { emotion: string; scale?: number } | null {\n return this._currentEmotion;\n }\n\n /**\n * Get whether the user is currently speaking (bot is in \"listening\" state).\n * True from user-started-speaking until user-stopped-speaking.\n */\n getIsListening(): boolean {\n return this.isListening;\n }\n\n /**\n * Local interruption path used by the client before the server cancel/terminal\n * arrives. Keep MessageHandler state and BlendshapeQueue state in sync so the\n * next bot-started-speaking can activate cleanly.\n */\n interruptLipsyncPlayback(): void {\n const wasSpeaking = this.isSpeaking;\n this.isSpeaking = false;\n this.blendshapeQueue.interrupt();\n if (wasSpeaking) {\n this.emit(\"speakingChange\", false);\n }\n }\n\n /**\n * Set the LiveKit room instance\n */\n setRoom(room: Room): void {\n // Clean up previous room listeners\n if (this.room) {\n this.cleanupListeners();\n }\n\n this.room = room;\n this.setupListeners();\n }\n\n /**\n * Setup message listeners\n */\n private setupListeners(): void {\n if (!this.room) return;\n\n this.room.on(RoomEvent.DataReceived, this._boundHandleDataReceived);\n }\n\n /**\n * Clean up message listeners\n */\n private cleanupListeners(): void {\n if (!this.room) return;\n\n this.room.off(RoomEvent.DataReceived, this._boundHandleDataReceived);\n }\n\n /**\n * Handle incoming data message\n */\n private handleDataReceived(\n payload: Uint8Array,\n _participant: unknown,\n _transport: \"livekit\" | \"websocket\" = \"livekit\",\n ): void {\n let messageString = \"\";\n let parsed = false;\n\n try {\n // Decode bytes to string\n const decoder = new TextDecoder();\n messageString = decoder.decode(payload);\n\n // Parse JSON\n const messageData = JSON.parse(messageString);\n parsed = true;\n\n // Extract and categorize messages for chat display\n const timestamp = new Date().toISOString();\n const messageId = `${messageData.type}-${Date.now()}-${Math.random()}`;\n\n // Multi-character routing identity, carried inline on every\n // character-originated event. Undefined in single-character sessions, so\n // these spread to nothing and every existing message keeps its shape.\n const attribution: Pick<ChatMessage, \"membershipId\" | \"characterId\"> = {\n ...(messageData.data?.membership_id && {\n membershipId: messageData.data.membership_id as string,\n }),\n ...(messageData.data?.character_id && {\n characterId: messageData.data.character_id as string,\n }),\n };\n /**\n * Two instances must never share a streaming bubble. Without this a\n * target switch mid-turn splices one character's text onto another's,\n * because the merge would only be checking `isStreaming`.\n */\n const sameSpeaker = (msg: ChatMessage | undefined): boolean =>\n !!msg && msg.membershipId === attribution.membershipId;\n\n // Handle different message types\n switch (messageData.type) {\n // User text messages - Skip these, only allow user-transcription\n case \"user_text_message\":\n case \"user-llm-text\":\n case \"text-input\":\n case \"user-input\":\n case \"text-message\":\n case \"chat-message\":\n case \"input-text\":\n case \"message\":\n // Skip user text messages - only allow user-transcription\n break;\n\n // Bot Ready - Bot is ready, connection should be true\n case \"bot-ready\":\n // `about` carries this instance's routing identity in a roster room,\n // and the same fields are also flattened onto `data`. Prefer `about`,\n // fall back to the flattened copy, and pass undefined for a\n // single-character session.\n this.emit(\n \"botReady\",\n messageData.data?.about ??\n (messageData.data?.membership_id ? messageData.data : undefined),\n );\n break;\n\n // Bot LLM Started - Begin streaming response\n case \"bot-llm-started\":\n this.isBotResponding = true;\n this.emit(\"botRespondingChange\", true);\n this.seenBotOutputSegments.clear();\n\n // Add initial streaming message to chat\n const streamingMessage: ChatMessage = {\n id: messageId,\n type: \"bot-llm-text\",\n content: \"\",\n timestamp: timestamp,\n isStreaming: true,\n ...attribution,\n };\n this.activeBotLlmMessageId = messageId;\n this.chatMessages.push(streamingMessage);\n this.emit(\"messagesChange\", this.chatMessages);\n break;\n\n // Bot Output - Aggregated output stream (sentence/word-level, replaces bot-transcript)\n // Payload: { text, spoken, aggregated_by, segment_id, spoken_status,\n // spoken_progress }. The same segment_id is re-sent with the FULL\n // segment text on every TTS progress tick (spoken_status\n // \"in-progress\" → \"completed\"), so appending per event repeats the\n // sentence once per tick.\n case \"bot-output\":\n if (messageData.data?.text) {\n const newText = messageData.data.text;\n const segmentId = messageData.data.segment_id as\n | number\n | string\n | undefined;\n this.emit(\"botOutput\", {\n text: newText,\n spoken: messageData.data.spoken ?? false,\n aggregatedBy: messageData.data.aggregated_by ?? \"sentence\",\n segmentId,\n spokenStatus: messageData.data.spoken_status,\n });\n\n // Progress re-send of a segment already in the chat — skip.\n if (segmentId !== undefined) {\n if (this.seenBotOutputSegments.has(segmentId)) break;\n this.seenBotOutputSegments.add(segmentId);\n }\n\n const activeBotLlmMessage = this.activeBotLlmMessageId\n ? this.chatMessages.find(\n (message) => message.id === this.activeBotLlmMessageId,\n )\n : undefined;\n const lastMsg = this.chatMessages[this.chatMessages.length - 1];\n // When the reply is rendered by the LLM text stream\n // (bot-llm-text), the TTS echo adds nothing — never mix\n // bot-output into an LLM bubble (streaming or complete).\n if (activeBotLlmMessage?.type === \"bot-llm-text\") break;\n if (lastMsg?.type === \"bot-llm-text\") break;\n if (\n lastMsg?.type === \"bot-output\" &&\n lastMsg.content.includes(newText)\n ) {\n break;\n }\n if (\n lastMsg?.type === \"bot-output\" &&\n lastMsg.isStreaming &&\n sameSpeaker(lastMsg)\n ) {\n this.chatMessages[this.chatMessages.length - 1] = {\n ...lastMsg,\n content: lastMsg.content + newText,\n };\n } else {\n this.chatMessages.push({\n id: `bot-output-${Date.now()}-${Math.random()}`,\n type: \"bot-output\",\n content: newText,\n timestamp: new Date().toISOString(),\n isStreaming: true,\n ...attribution,\n });\n }\n this.emit(\"messagesChange\", this.chatMessages);\n }\n break;\n\n // Bot LLM Text Messages - Streaming chunks\n case \"bot-llm-text\":\n if (messageData.data?.text) {\n const newChunk = messageData.data.text;\n\n // Update the streaming message in chat\n const activeIndex = this.activeBotLlmMessageId\n ? this.chatMessages.findIndex(\n (message) =>\n message.id === this.activeBotLlmMessageId &&\n message.type === \"bot-llm-text\" &&\n message.isStreaming &&\n sameSpeaker(message),\n )\n : -1;\n if (activeIndex >= 0) {\n const activeMessage = this.chatMessages[activeIndex];\n this.chatMessages[activeIndex] = {\n ...activeMessage,\n content: activeMessage.content + newChunk,\n };\n } else {\n // If no streaming message exists yet, create one\n const streamingMsg: ChatMessage = {\n id: `${messageData.type}-${Date.now()}-${Math.random()}`,\n type: \"bot-llm-text\",\n content: newChunk,\n timestamp: new Date().toISOString(),\n isStreaming: true,\n ...attribution,\n };\n this.activeBotLlmMessageId = streamingMsg.id;\n this.chatMessages.push(streamingMsg);\n }\n this.emit(\"messagesChange\", this.chatMessages);\n }\n break;\n\n // Bot LLM Stopped - Complete streaming response\n case \"bot-llm-stopped\":\n const activeIndex = this.activeBotLlmMessageId\n ? this.chatMessages.findIndex(\n (message) => message.id === this.activeBotLlmMessageId,\n )\n : -1;\n if (activeIndex >= 0 && this.chatMessages[activeIndex].isStreaming) {\n const activeMessage = this.chatMessages[activeIndex];\n this.chatMessages[activeIndex] = {\n ...activeMessage,\n isStreaming: false,\n };\n }\n\n // Clear streaming state\n this.isBotResponding = false;\n this.emit(\"botRespondingChange\", false);\n this.emit(\"messagesChange\", this.chatMessages);\n break;\n\n // Text-only Interactions API terminal marker. This is deliberately a\n // separate event: a completed REST turn must not be represented as a\n // synthetic bot-llm-stopped message.\n case \"bot-turn-completed\":\n const completedIndex = this.activeBotLlmMessageId\n ? this.chatMessages.findIndex(\n (message) => message.id === this.activeBotLlmMessageId,\n )\n : -1;\n if (completedIndex >= 0 && this.chatMessages[completedIndex].isStreaming) {\n this.chatMessages[completedIndex] = {\n ...this.chatMessages[completedIndex],\n isStreaming: false,\n };\n this.emit(\"messagesChange\", this.chatMessages);\n }\n this.isBotResponding = false;\n this.emit(\"botRespondingChange\", false);\n this.emit(\"botTurnCompleted\", messageData.data ?? {});\n break;\n\n // User Transcription Messages\n case \"user-transcription\":\n if (messageData.data?.text) {\n const messageContent = messageData.data.text;\n\n if (messageData.data?.final) {\n // Final transcription - accumulate in single bubble until bot responds\n const lastUserMsg =\n this.chatMessages[this.chatMessages.length - 1];\n\n // Check if last message is an accumulating user message (isStreaming=true)\n if (\n lastUserMsg &&\n lastUserMsg.type === \"user-transcription\" &&\n lastUserMsg.isStreaming === true\n ) {\n // Accumulate: append new content to existing message with space\n const accumulatedContent =\n lastUserMsg.content.trim() + \" \" + messageContent.trim();\n\n this.chatMessages[this.chatMessages.length - 1] = {\n ...lastUserMsg,\n content: accumulatedContent,\n timestamp: timestamp,\n };\n } else {\n // Start new accumulating message (isStreaming=true means \"still accumulating\")\n const userMessage: ChatMessage = {\n id: messageId,\n type: \"user-transcription\",\n content: messageContent,\n timestamp: timestamp,\n isStreaming: true,\n };\n this.chatMessages.push(userMessage);\n }\n this.emit(\"messagesChange\", this.chatMessages);\n\n // Clear live transcription when final\n this.userTranscription = \"\";\n this.emit(\"userTranscriptionChange\", \"\");\n } else {\n // Non-final transcription - show in input field\n this.userTranscription = messageContent;\n this.emit(\"userTranscriptionChange\", messageContent);\n }\n }\n break;\n\n // Bot Emotion Messages — LiveKit path: arrives as an RTVI message frame (messageData.data)\n case \"bot-emotion\":\n if (messageData.data?.emotion) {\n this._currentEmotion = {\n emotion: messageData.data.emotion,\n scale: messageData.data.scale,\n };\n if (this.logRtviMessages) console.log(\"[SDK bot-emotion]\", messageData.data);\n this.emit(\"emotionChange\", this._currentEmotion);\n const emotionMessage: ChatMessage = {\n id: messageId,\n type: \"bot-emotion\",\n content: `${messageData.data.emotion} (scale: ${messageData.data.scale || 1})`,\n timestamp,\n };\n this.chatMessages.push(emotionMessage);\n this.emit(\"messagesChange\", this.chatMessages);\n }\n break;\n // Bot TTS Text - Words as spoken by TTS (word-by-word for socket-based TTS)\n case \"bot-tts-text\":\n if (messageData.data?.text) {\n this.emit(\"botTtsText\", { text: messageData.data.text });\n }\n break;\n\n // Bot TTS lifecycle (more granular than bot-started/stopped-speaking)\n case \"bot-tts-started\":\n this.emit(\"botTtsStarted\");\n break;\n\n case \"bot-tts-stopped\":\n this.emit(\"botTtsStopped\");\n break;\n\n // Server-side muting indicators\n case \"user-mute-started\":\n this.emit(\"userMuteStarted\");\n break;\n\n case \"user-mute-stopped\":\n this.emit(\"userMuteStopped\");\n break;\n\n case \"user-started-speaking\":\n this.isListening = true;\n this.emit(\"listeningChange\", true);\n break;\n\n case \"user-stopped-speaking\":\n this.isListening = false;\n this.emit(\"listeningChange\", false);\n break;\n\n // Bot Started Speaking (priority over listening: state becomes speaking)\n case \"bot-started-speaking\": {\n const owner = this.lifecycleOwner(messageData.data);\n if (this.blendshapeQueue.isStaleOwner(owner)) {\n break;\n }\n const allowed = this.blendshapeQueue.startBotSpeaking();\n if (allowed) {\n this.isSpeaking = true;\n this.totalBlendshapesReceived = 0;\n this.emit(\"speakingChange\", true);\n }\n break;\n }\n\n // Bot Stopped Speaking\n case \"bot-stopped-speaking\":\n if (this.blendshapeQueue.isStaleOwner(this.lifecycleOwner(messageData.data))) {\n break;\n }\n if (this.isSpeaking) {\n this.isSpeaking = false;\n this.blendshapeQueue.stopBotSpeaking();\n this.emit(\"speakingChange\", false);\n }\n break;\n\n // Action Response Messages (LiveKit/WebRTC path)\n case \"action-response\":\n this._handleActionResponse(messageData.data?.actions ?? [], messageId, timestamp);\n break;\n\n case \"metrics\":\n if (messageData.data) {\n this.emit(\"metrics\", messageData.data);\n }\n break;\n\n // Per-turn usage/cost breakdown. Informational only: the server streams\n // it once the client opts in with usage-toggle, and it never affects\n // server-side usage tracking or billing.\n case \"usage-update\":\n if (messageData.data) {\n this.emit(\"usageUpdate\", messageData.data);\n }\n break;\n // Behavior Tree Response Messages\n case \"behavior-tree-response\":\n if (messageData.data?.narrative_section_id) {\n const behaviorMessage: ChatMessage = {\n id: messageId,\n type: \"behavior-tree\",\n content: `Narrative Section: ${messageData.data.narrative_section_id}`,\n timestamp,\n };\n this.chatMessages.push(behaviorMessage);\n this.emit(\"messagesChange\", this.chatMessages);\n }\n break;\n\n // Server Message - Contains various data types like blendshapes\n case \"server-message\":\n if (messageData.data) {\n const serverData = messageData.data;\n\n switch (serverData.type) {\n case \"final-user-transcription\":\n if (serverData.text) {\n const finalText = serverData.text;\n const lastUserMsg =\n this.chatMessages[this.chatMessages.length - 1];\n if (\n lastUserMsg &&\n lastUserMsg.type === \"user-transcription\" &&\n lastUserMsg.isStreaming === true\n ) {\n this.chatMessages[this.chatMessages.length - 1] = {\n ...lastUserMsg,\n content: finalText,\n timestamp,\n isStreaming: false,\n };\n } else {\n this.chatMessages.push({\n id: `${serverData.type}-${Date.now()}-${Math.random()}`,\n type: \"user-transcription\",\n content: finalText,\n timestamp,\n isStreaming: false,\n });\n }\n this.emit(\"messagesChange\", this.chatMessages);\n this.userTranscription = \"\";\n this.emit(\"userTranscriptionChange\", \"\");\n }\n break;\n\n // WebSocket path: arrives inside a bot-text data message as serverData (not messageData.data)\n case \"bot-emotion\":\n if (serverData.emotion) {\n this._currentEmotion = {\n emotion: serverData.emotion,\n scale: serverData.scale,\n };\n if (this.logRtviMessages) console.log(\"[SDK bot-emotion (ws)]\", serverData);\n this.emit(\"emotionChange\", this._currentEmotion);\n }\n break;\n\n case \"blendshape-turn-stats\":\n if (this.blendshapeQueue.isStaleOwner(this.lifecycleOwner(serverData))) {\n break;\n }\n this.blendshapeQueue.endConversation(\n serverData.stats,\n this.lifecycleOwner(serverData),\n );\n this.emit(\"blendshapeStatsReceived\", serverData);\n break;\n\n case \"chunked-neurosync-blendshapes\":\n if (serverData.blendshapes) {\n const owner = this.lifecycleOwner(serverData);\n if (this.blendshapeQueue.isRetiredOwner(owner)) {\n break;\n }\n // If the queue is idle (no active conversation, bot not yet speaking),\n // start a conversation so early chunks from an initial bot greeting\n // are accepted rather than silently dropped.\n if (\n !this.blendshapeQueue.isConversationActive() &&\n !this.isSpeaking\n ) {\n this.blendshapeQueue.startConversation();\n }\n this.blendshapeQueue.addChunk(\n serverData.blendshapes,\n owner,\n );\n if (\n this.blendshapeQueue.consumeOwnerReplacementStoppedSpeaking() &&\n this.isSpeaking\n ) {\n this.isSpeaking = false;\n this.emit(\"speakingChange\", false);\n }\n this.totalBlendshapesReceived +=\n serverData.blendshapes.length;\n this.emit(\"blendshapes\", serverData);\n }\n break;\n\n case \"neurosync-blendshapes-cancel\": {\n const cancelledActive = this.blendshapeQueue.cancelOwner(\n this.lifecycleOwner(serverData),\n );\n if (cancelledActive && this.isSpeaking) {\n this.isSpeaking = false;\n this.emit(\"speakingChange\", false);\n }\n this.emit(\"blendshapeCancel\", serverData);\n break;\n }\n\n case \"user-idle-warning\": {\n const remainingSeconds: number | null =\n serverData.remaining_seconds ??\n serverData.remainingSeconds ??\n null;\n this.emit(\"idleWarning\", { remainingSeconds });\n this.chatMessages.push({\n id: `user-idle-warning-${Date.now()}-${Math.random()}`,\n type: \"idle-warning\",\n content:\n remainingSeconds !== null ? String(remainingSeconds) : \"\",\n timestamp,\n });\n this.emit(\"messagesChange\", this.chatMessages);\n break;\n }\n\n case \"llm-no-response\":\n this.emit(\"llmNoResponse\");\n this.chatMessages.push({\n id: `llm-no-response-${Date.now()}-${Math.random()}`,\n type: \"llm-no-response\",\n content: \"\",\n timestamp,\n });\n this.emit(\"messagesChange\", this.chatMessages);\n break;\n\n // Action Response (WebSocket/RTVI path — wrapped in server-message)\n case \"action-response\":\n this._handleActionResponse(serverData.actions ?? [], messageId, timestamp);\n break;\n\n // Server acknowledgment — arrives wrapped in server-message envelope\n case \"server-response\": {\n // client-ready is an internal RTVI handshake; server echoes an\n // \"Unknown message type\" error for it which is expected and harmless.\n if (serverData.event_type === \"client-ready\") break;\n const serverResponse: ServerResponse = {\n event_type: serverData.event_type ?? \"unknown\",\n status: serverData.status ?? \"error\",\n message: serverData.message ?? null,\n extras: serverData.extras ?? null,\n };\n this.emit(\"serverResponse\", serverResponse);\n break;\n }\n\n /**\n * Lifecycle of one roster member. Emitted when a member is added\n * at runtime, becomes ready, or fails after /connect already\n * returned 200. `bot-ready` stays the readiness authority --\n * a `character-status` of \"ready\" must not enable interaction on\n * its own -- but this is the only way a background dispatch\n * failure is ever reported.\n */\n case \"character-status\": {\n const status: CharacterStatusEvent = {\n status: (serverData.status as CharacterStatusEvent[\"status\"]) ?? \"starting\",\n membershipId: (serverData.membership_id as string) ?? \"\",\n characterId: (serverData.character_id as string) ?? \"\",\n characterSessionId:\n (serverData.character_session_id as string) ?? null,\n participantIdentity:\n (serverData.participant_identity as string) ??\n (serverData.membership_id\n ? `character:${serverData.membership_id}`\n : \"\"),\n roomSessionId: (serverData.room_session_id as string) ?? null,\n rosterEpoch:\n typeof serverData.roster_epoch === \"number\"\n ? serverData.roster_epoch\n : null,\n failureCode: (serverData.failure_code as string) ?? null,\n };\n // Unattributable status is dropped rather than guessed at.\n if (status.membershipId) this.emit(\"characterStatus\", status);\n break;\n }\n\n // interaction-created: session IDs for analytics/tracking\n case \"interaction-created\": {\n const interactionCreated: InteractionCreated = {\n interactionId: serverData.interaction_id,\n characterSessionId: serverData.character_session_id,\n };\n this.emit(\"interactionCreated\", interactionCreated);\n break;\n }\n }\n }\n break;\n\n // Fallback: server-response at top level (not currently observed but kept for safety)\n case \"server-response\": {\n if (messageData.event_type === \"client-ready\") break;\n const serverResponse: ServerResponse = {\n event_type: messageData.event_type ?? \"unknown\",\n status: messageData.status ?? \"error\",\n message: messageData.message ?? null,\n extras: messageData.extras ?? null,\n };\n this.emit(\"serverResponse\", serverResponse);\n break;\n }\n\n // Silently ignore other message types\n case \"moderation-response\":\n case \"trigger-message\":\n case \"update-template-keys\":\n case \"update-dynamic-info\":\n case \"interrupt-bot\":\n break;\n }\n } catch (error) {\n // Silently handle parse errors\n }\n }\n\n private _handleActionResponse(\n actions: ConvaiAction[],\n messageId: string,\n timestamp: string,\n ): void {\n this.emit(\"actionResponse\", { actions });\n const label = actions.length === 0\n ? \"No action\"\n : actions.map((a) => (a.target ? `${a.name} → ${a.target}` : a.name)).join(\", \");\n const actionMessage: ChatMessage = {\n id: messageId,\n type: \"action\",\n content: label,\n timestamp,\n };\n this.chatMessages.push(actionMessage);\n this.emit(\"messagesChange\", this.chatMessages);\n }\n\n private lifecycleOwner(\n data: LifecycleOwnerPayload | undefined,\n ): BlendshapeChunkMetadata {\n if (!data) {\n return {};\n }\n\n return {\n responseId: data.response_id,\n neurosyncTurnId: data.neurosync_turn_id ?? data.turn_id,\n epoch: data.epoch,\n fps: this.numberOrUndefined((data as { fps?: number }).fps),\n startFrameIndex: this.numberOrUndefined(\n (data as { start_frame_index?: number }).start_frame_index,\n ),\n };\n }\n\n private numberOrUndefined(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value)\n ? value\n : undefined;\n }\n\n /**\n * Public entry point for WebSocket transport to inject messages into the same pipeline.\n */\n handleDataReceivedPublic(payload: Uint8Array): void {\n this.handleDataReceived(payload, null, \"websocket\");\n }\n\n /**\n * Insert a message into the transcript locally. Nothing is transmitted and\n * no LLM turn is billed -- this is for client-side lines (a greeting, a\n * system notice, a replayed history entry) that must appear in the chat.\n *\n * Subscribers see it through the same `messagesChange` as a live message,\n * so React and the widgets pick it up with no special casing.\n */\n appendLocalMessage(message: {\n sender: \"user\" | \"bot\";\n content: string;\n membershipId?: string;\n characterId?: string;\n }): ChatMessage {\n const chatMessage: ChatMessage = {\n id: `local-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`,\n type: message.sender === \"user\" ? \"user-llm-text\" : \"bot-llm-text\",\n content: message.content,\n timestamp: new Date().toISOString(),\n ...(message.membershipId && { membershipId: message.membershipId }),\n ...(message.characterId && { characterId: message.characterId }),\n };\n this.chatMessages.push(chatMessage);\n this.emit(\"messagesChange\", this.chatMessages);\n return chatMessage;\n }\n\n /**\n * Reset message state\n */\n reset(): void {\n this.chatMessages = [];\n this.activeBotLlmMessageId = null;\n this.userTranscription = \"\";\n this.isBotResponding = false;\n this.isSpeaking = false;\n this.isListening = false;\n this.totalBlendshapesReceived = 0;\n this._currentEmotion = null;\n this.blendshapeQueue.reset();\n this.emit(\"messagesChange\", this.chatMessages);\n this.emit(\"userTranscriptionChange\", \"\");\n this.emit(\"botRespondingChange\", false);\n this.emit(\"speakingChange\", false);\n this.emit(\"listeningChange\", false);\n this.emit(\"emotionChange\", null);\n }\n}\n"]}
|
|
@@ -11,7 +11,15 @@ export interface SSESessionOptions {
|
|
|
11
11
|
enableEmotion?: ConvaiConfig["enableEmotion"];
|
|
12
12
|
emotionConfig?: ConvaiConfig["emotionConfig"];
|
|
13
13
|
actionConfig?: ConvaiConfig["actionConfig"];
|
|
14
|
+
capabilities?: ConvaiConfig["capabilities"];
|
|
15
|
+
dynamicInfo?: ConvaiConfig["dynamicInfo"];
|
|
16
|
+
keepInContext?: ConvaiConfig["keepInContext"];
|
|
17
|
+
narrativeTemplateKeys?: ConvaiConfig["narrativeTemplateKeys"];
|
|
18
|
+
sceneDescription?: ConvaiConfig["sceneDescription"];
|
|
19
|
+
respondModes?: ConvaiConfig["respondModes"];
|
|
14
20
|
debug?: boolean;
|
|
21
|
+
useResponseLifecycleContract?: boolean;
|
|
22
|
+
invocationMetadata?: ConvaiConfig["invocationMetadata"];
|
|
15
23
|
onMessage: (payload: Uint8Array) => void;
|
|
16
24
|
onError: (error: unknown) => void;
|
|
17
25
|
}
|
|
@@ -29,14 +37,21 @@ export declare class SSESession {
|
|
|
29
37
|
private queue;
|
|
30
38
|
private pendingBotLlmText;
|
|
31
39
|
private botLlmTextFlushTimer;
|
|
40
|
+
private pendingMessages;
|
|
32
41
|
constructor(options: SSESessionOptions);
|
|
33
42
|
get isConnected(): boolean;
|
|
34
43
|
connect(): void;
|
|
35
44
|
sendMessage(type: string, data: unknown, id?: string): void;
|
|
36
45
|
sendMessages(messages: SSEMessage[]): void;
|
|
46
|
+
/** Update request-scoped dynamic context without opening a control-only request. */
|
|
47
|
+
updateDynamicInfo(dynamicInfo: string): void;
|
|
48
|
+
getDynamicInfo(): string | undefined;
|
|
49
|
+
/** Carry a silent control update into the next stateless interaction request. */
|
|
50
|
+
queueMessage(type: string, data: unknown): void;
|
|
37
51
|
disconnect(): Promise<void>;
|
|
38
52
|
private sendInteraction;
|
|
39
53
|
private readEvents;
|
|
54
|
+
private consumeReader;
|
|
40
55
|
private queueBotLlmText;
|
|
41
56
|
private flushBotLlmText;
|
|
42
57
|
private clearPendingBotLlmText;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SSESession.d.ts","sourceRoot":"","sources":["../../src/core/SSESession.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"SSESession.d.ts","sourceRoot":"","sources":["../../src/core/SSESession.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAO5C,MAAM,WAAW,iBAAiB;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC3C,oBAAoB,EAAE,CAAC,kBAAkB,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,eAAe,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IACrC,aAAa,CAAC,EAAE,YAAY,CAAC,eAAe,CAAC,CAAC;IAC9C,aAAa,CAAC,EAAE,YAAY,CAAC,eAAe,CAAC,CAAC;IAC9C,YAAY,CAAC,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;IAC5C,YAAY,CAAC,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;IAC5C,WAAW,CAAC,EAAE,YAAY,CAAC,aAAa,CAAC,CAAC;IAC1C,aAAa,CAAC,EAAE,YAAY,CAAC,eAAe,CAAC,CAAC;IAC9C,qBAAqB,CAAC,EAAE,YAAY,CAAC,uBAAuB,CAAC,CAAC;IAC9D,gBAAgB,CAAC,EAAE,YAAY,CAAC,kBAAkB,CAAC,CAAC;IACpD,YAAY,CAAC,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,kBAAkB,CAAC,EAAE,YAAY,CAAC,oBAAoB,CAAC,CAAC;IACxD,SAAS,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;IACzC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,gFAAgF;AAChF,qBAAa,UAAU;IAST,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAM;IACnD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,iBAAiB,CAAM;IAC/B,OAAO,CAAC,oBAAoB,CAA8C;IAC1E,OAAO,CAAC,eAAe,CAAoB;gBAEd,OAAO,EAAE,iBAAiB;IAEvD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,OAAO,IAAI,IAAI;IAIf,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAI3D,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI;IAmB1C,oFAAoF;IACpF,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAI5C,cAAc,IAAI,MAAM,GAAG,SAAS;IAIpC,iFAAiF;IACjF,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAIzC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YASnB,eAAe;YAkGf,UAAU;YAkBV,aAAa;IA4E3B,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,sBAAsB;CAO/B"}
|
package/dist/core/SSESession.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildActionConnectConfig, buildEmotionConnectConfig, } from "./connectRequest.js";
|
|
1
|
+
import { buildActionConnectConfig, buildEmotionConnectConfig, serializeActionProtocolCapabilities, } from "./connectRequest.js";
|
|
2
2
|
/** Text-only interaction transport. One POST/SSE stream is used per message. */
|
|
3
3
|
export class SSESession {
|
|
4
4
|
constructor(options) {
|
|
@@ -8,6 +8,7 @@ export class SSESession {
|
|
|
8
8
|
this.queue = Promise.resolve();
|
|
9
9
|
this.pendingBotLlmText = "";
|
|
10
10
|
this.botLlmTextFlushTimer = null;
|
|
11
|
+
this.pendingMessages = [];
|
|
11
12
|
}
|
|
12
13
|
get isConnected() {
|
|
13
14
|
return this.connected;
|
|
@@ -25,19 +26,35 @@ export class SSESession {
|
|
|
25
26
|
.then(() => {
|
|
26
27
|
if (!this.connected)
|
|
27
28
|
return;
|
|
28
|
-
|
|
29
|
+
const pending = this.pendingMessages;
|
|
30
|
+
this.pendingMessages = [];
|
|
31
|
+
const context = messages.filter((message) => message.type === "update-dynamic-info");
|
|
32
|
+
const rest = messages.filter((message) => message.type !== "update-dynamic-info");
|
|
33
|
+
return this.sendInteraction([...context, ...pending, ...rest], this.options.takeStateOfMind());
|
|
29
34
|
})
|
|
30
35
|
.catch((error) => {
|
|
31
36
|
if (!isAbortError(error))
|
|
32
37
|
this.options.onError(error);
|
|
33
38
|
});
|
|
34
39
|
}
|
|
40
|
+
/** Update request-scoped dynamic context without opening a control-only request. */
|
|
41
|
+
updateDynamicInfo(dynamicInfo) {
|
|
42
|
+
this.options.dynamicInfo = dynamicInfo;
|
|
43
|
+
}
|
|
44
|
+
getDynamicInfo() {
|
|
45
|
+
return this.options.dynamicInfo;
|
|
46
|
+
}
|
|
47
|
+
/** Carry a silent control update into the next stateless interaction request. */
|
|
48
|
+
queueMessage(type, data) {
|
|
49
|
+
this.pendingMessages.push({ type, data });
|
|
50
|
+
}
|
|
35
51
|
async disconnect() {
|
|
36
52
|
this.connected = false;
|
|
37
53
|
this.abortController?.abort();
|
|
38
54
|
await this.queue;
|
|
39
55
|
this.clearPendingBotLlmText();
|
|
40
56
|
this.abortController = null;
|
|
57
|
+
this.pendingMessages = [];
|
|
41
58
|
}
|
|
42
59
|
async sendInteraction(messages, stateOfMind) {
|
|
43
60
|
const controller = new AbortController();
|
|
@@ -69,9 +86,46 @@ export class SSESession {
|
|
|
69
86
|
...(buildActionConnectConfig(this.options) && {
|
|
70
87
|
action_config: buildActionConnectConfig(this.options),
|
|
71
88
|
}),
|
|
89
|
+
...(this.options.capabilities && {
|
|
90
|
+
capabilities: serializeActionProtocolCapabilities(this.options.capabilities),
|
|
91
|
+
}),
|
|
92
|
+
...(this.options.dynamicInfo && {
|
|
93
|
+
dynamic_info: {
|
|
94
|
+
text: this.options.dynamicInfo,
|
|
95
|
+
...(this.options.keepInContext !== undefined && {
|
|
96
|
+
keep_in_context: this.options.keepInContext,
|
|
97
|
+
}),
|
|
98
|
+
},
|
|
99
|
+
}),
|
|
100
|
+
...(this.options.narrativeTemplateKeys &&
|
|
101
|
+
Object.keys(this.options.narrativeTemplateKeys).length > 0 && {
|
|
102
|
+
narrative_template_keys: this.options.narrativeTemplateKeys,
|
|
103
|
+
}),
|
|
104
|
+
...(this.options.sceneDescription && {
|
|
105
|
+
scene_description: this.options.sceneDescription,
|
|
106
|
+
}),
|
|
107
|
+
...(this.options.respondModes && {
|
|
108
|
+
respond_modes: serializeRespondModes(this.options.respondModes),
|
|
109
|
+
}),
|
|
72
110
|
...(this.options.debug !== undefined
|
|
73
111
|
? { debug: this.options.debug }
|
|
74
112
|
: {}),
|
|
113
|
+
...(this.options.useResponseLifecycleContract !== undefined
|
|
114
|
+
? {
|
|
115
|
+
use_response_lifecycle_contract: this.options.useResponseLifecycleContract,
|
|
116
|
+
}
|
|
117
|
+
: {}),
|
|
118
|
+
...(this.options.invocationMetadata && {
|
|
119
|
+
invocation_metadata: {
|
|
120
|
+
source: this.options.invocationMetadata.source ?? "web_sdk",
|
|
121
|
+
...(this.options.invocationMetadata.clientVersion && {
|
|
122
|
+
client_version: this.options.invocationMetadata.clientVersion,
|
|
123
|
+
}),
|
|
124
|
+
...(this.options.invocationMetadata.extraMetadata && {
|
|
125
|
+
extra_metadata: this.options.invocationMetadata.extraMetadata,
|
|
126
|
+
}),
|
|
127
|
+
},
|
|
128
|
+
}),
|
|
75
129
|
messages: messages.map(({ type, data, id }) => ({
|
|
76
130
|
label: "rtvi-ai",
|
|
77
131
|
type,
|
|
@@ -96,13 +150,34 @@ export class SSESession {
|
|
|
96
150
|
}
|
|
97
151
|
async readEvents(body, signal) {
|
|
98
152
|
const reader = body.getReader();
|
|
153
|
+
try {
|
|
154
|
+
await this.consumeReader(reader, signal);
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
// A spec-compliant fetch errors the body when its signal aborts, and the
|
|
158
|
+
// read loop exits on that rejection. Not every runtime the SDK now
|
|
159
|
+
// targets (Node, SSR shims, polyfills) does, and with no cancel the
|
|
160
|
+
// loop would await a read that never settles -- so disconnect() would
|
|
161
|
+
// hang forever. Cancelling is idempotent on an already-closed stream.
|
|
162
|
+
await reader.cancel().catch(() => { });
|
|
163
|
+
reader.releaseLock();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async consumeReader(reader, signal) {
|
|
99
167
|
const decoder = new TextDecoder();
|
|
100
168
|
let buffer = "";
|
|
101
169
|
let eventType = "message";
|
|
102
170
|
let eventData = [];
|
|
103
171
|
const dispatch = () => {
|
|
104
|
-
if (eventData.length === 0)
|
|
172
|
+
if (eventData.length === 0) {
|
|
173
|
+
// Per the SSE spec a frame with no data is not dispatched, but its
|
|
174
|
+
// event-type buffer is still reset. Leaving it set would hand the type
|
|
175
|
+
// to the next frame that omits its own `event:` line -- so a bare
|
|
176
|
+
// `event: done` marker would retype the frame after it as `done`, and
|
|
177
|
+
// that frame would be swallowed as a session-id lookup.
|
|
178
|
+
eventType = "message";
|
|
105
179
|
return;
|
|
180
|
+
}
|
|
106
181
|
const dataText = eventData.join("\n");
|
|
107
182
|
let data = dataText;
|
|
108
183
|
try {
|
|
@@ -191,6 +266,20 @@ export class SSESession {
|
|
|
191
266
|
}
|
|
192
267
|
}
|
|
193
268
|
SSESession.BOT_LLM_TEXT_FLUSH_MS = 16;
|
|
269
|
+
function serializeRespondModes(config) {
|
|
270
|
+
return {
|
|
271
|
+
...(config.text !== undefined && { text: config.text }),
|
|
272
|
+
...(config.audio !== undefined && { audio: config.audio }),
|
|
273
|
+
...(config.vision !== undefined && { vision: config.vision }),
|
|
274
|
+
...(config.contextUpdate !== undefined && {
|
|
275
|
+
context_update: config.contextUpdate,
|
|
276
|
+
}),
|
|
277
|
+
...(config.trigger !== undefined && { trigger: config.trigger }),
|
|
278
|
+
...(config.sceneMetadata !== undefined && {
|
|
279
|
+
scene_metadata: config.sceneMetadata,
|
|
280
|
+
}),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
194
283
|
function isAbortError(error) {
|
|
195
284
|
return (typeof error === "object" &&
|
|
196
285
|
error !== null &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SSESession.js","sourceRoot":"","sources":["../../src/core/SSESession.ts"],"names":[],"mappings":"AACA,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAyB1B,gFAAgF;AAChF,MAAM,OAAO,UAAU;IAQrB,YAA6B,OAA0B;QAA1B,YAAO,GAAP,OAAO,CAAmB;QAN/C,cAAS,GAAG,KAAK,CAAC;QAClB,oBAAe,GAA2B,IAAI,CAAC;QAC/C,UAAK,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;QACzC,sBAAiB,GAAG,EAAE,CAAC;QACvB,yBAAoB,GAAyC,IAAI,CAAC;IAEhB,CAAC;IAE3D,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,OAAO;QACL,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;IAED,WAAW,CAAC,IAAY,EAAE,IAAa,EAAE,EAAW;QAClD,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,YAAY,CAAC,QAAsB;QACjC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAClC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK;aACpB,IAAI,CAAC,GAAG,EAAE;YACT,IAAI,CAAC,IAAI,CAAC,SAAS;gBAAE,OAAO;YAC5B,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;QACxE,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACxB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;gBAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC;QAC9B,MAAM,IAAI,CAAC,KAAK,CAAC;QACjB,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC9B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;IAC9B,CAAC;IAEO,KAAK,CAAC,eAAe,CAC3B,QAAsB,EACtB,WAA0B;QAE1B,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;YAChE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE;gBAC3D,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE;oBACrD,MAAM,EAAE,mBAAmB;oBAC3B,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;oBACtC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACtD,GAAG,CAAC,kBAAkB,IAAI,kBAAkB,KAAK,IAAI;wBACnD,CAAC,CAAC,EAAE,oBAAoB,EAAE,kBAAkB,EAAE;wBAC9C,CAAC,CAAC,EAAE,CAAC;oBACP,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS;wBACxB,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;wBACzC,CAAC,CAAC,EAAE,CAAC;oBACP,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe;wBAC9B,CAAC,CAAC,EAAE,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE;wBACrD,CAAC,CAAC,EAAE,CAAC;oBACP,GAAG,CAAC,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI;wBAC7C,cAAc,EAAE,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC;qBACxD,CAAC;oBACF,GAAG,CAAC,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI;wBAC5C,aAAa,EAAE,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC;qBACtD,CAAC;oBACF,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS;wBAClC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;wBAC/B,CAAC,CAAC,EAAE,CAAC;oBACP,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;wBAC9C,KAAK,EAAE,SAAS;wBAChB,IAAI;wBACJ,GAAG,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACnC,IAAI;qBACL,CAAC,CAAC;iBACJ,CAAC;gBACF,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CACb,wBAAwB,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CACpE,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;YAE5E,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QAC1D,CAAC;gBAAS,CAAC;YACT,IAAI,IAAI,CAAC,eAAe,KAAK,UAAU;gBAAE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QACvE,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,UAAU,CACtB,IAAgC,EAChC,MAAmB;QAEnB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,SAAS,GAAG,SAAS,CAAC;QAC1B,IAAI,SAAS,GAAa,EAAE,CAAC;QAE7B,MAAM,QAAQ,GAAG,GAAG,EAAE;YACpB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YACnC,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,IAAI,GAAY,QAAQ,CAAC;YAC7B,IAAI,CAAC;gBACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACP,qFAAqF;YACvF,CAAC;YACD,IACE,SAAS,KAAK,cAAc;gBAC5B,OAAO,IAAI,KAAK,QAAQ;gBACxB,IAAI,KAAK,IAAI;gBACb,OAAQ,IAA2B,CAAC,IAAI,KAAK,QAAQ,EACrD,CAAC;gBACD,IAAI,CAAC,eAAe,CAAE,IAAyB,CAAC,IAAI,CAAC,CAAC;gBACtD,SAAS,GAAG,SAAS,CAAC;gBACtB,SAAS,GAAG,EAAE,CAAC;gBACf,OAAO;YACT,CAAC;YACD,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;gBACpD,MAAM,SAAS,GAAI,IAA2C;oBAC5D,EAAE,oBAAoB,CAAC;gBACzB,IAAI,OAAO,SAAS,KAAK,QAAQ;oBAAE,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;YAClF,CAAC;iBAAM,CAAC;gBACN,IAAI,SAAS,KAAK,OAAO;oBAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACtD,IAAI,CAAC,OAAO,CAAC,SAAS,CACpB,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CACpE,CAAC;YACJ,CAAC;YACD,SAAS,GAAG,SAAS,CAAC;YACtB,SAAS,GAAG,EAAE,CAAC;QACjB,CAAC,CAAC;QAEF,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;YACnD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACpC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;YAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI;oBAAE,QAAQ,EAAE,CAAC;qBACjB,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;oBAAE,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;qBAChE,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;oBAClC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;YACD,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,MAAM,EAAE,CAAC;oBACX,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;wBAAE,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;yBAC/D,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC;wBAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;gBACnF,CAAC;gBACD,QAAQ,EAAE,CAAC;gBACX,IAAI,CAAC,eAAe,EAAE,CAAC;gBACvB,OAAO;YACT,CAAC;QACH,CAAC;IACH,CAAC;IAEO,eAAe,CAAC,IAAY;QAClC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC;QAC/B,IAAI,IAAI,CAAC,oBAAoB,KAAK,IAAI;YAAE,OAAO;QAC/C,IAAI,CAAC,oBAAoB,GAAG,UAAU,CAAC,GAAG,EAAE;YAC1C,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;YACjC,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,CAAC,EAAE,UAAU,CAAC,qBAAqB,CAAC,CAAC;IACvC,CAAC;IAEO,eAAe;QACrB,IAAI,IAAI,CAAC,oBAAoB,KAAK,IAAI,EAAE,CAAC;YACvC,YAAY,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YACxC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,iBAAiB;YAAE,OAAO;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACpC,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,SAAS,CACpB,IAAI,WAAW,EAAE,CAAC,MAAM,CACtB,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CACzD,CACF,CAAC;IACJ,CAAC;IAEO,sBAAsB;QAC5B,IAAI,IAAI,CAAC,oBAAoB,KAAK,IAAI,EAAE,CAAC;YACvC,YAAY,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YACxC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;IAC9B,CAAC;;AAxMuB,gCAAqB,GAAG,EAAE,AAAL,CAAM;AA2MrD,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,KAAK,CAAC,IAAI,KAAK,YAAY,CAC5B,CAAC;AACJ,CAAC","sourcesContent":["import type { ConvaiConfig } from \"./types\";\nimport {\n buildActionConnectConfig,\n buildEmotionConnectConfig,\n} from \"./connectRequest\";\n\nexport interface SSESessionOptions {\n interactionApiUrl: string;\n authorization: string;\n characterId: string;\n getCharacterSessionId: () => string | null;\n onCharacterSessionId: (characterSessionId: string) => void;\n endUserId?: string;\n endUserMetadata?: Record<string, unknown>;\n takeStateOfMind: () => string | null;\n enableEmotion?: ConvaiConfig[\"enableEmotion\"];\n emotionConfig?: ConvaiConfig[\"emotionConfig\"];\n actionConfig?: ConvaiConfig[\"actionConfig\"];\n debug?: boolean;\n onMessage: (payload: Uint8Array) => void;\n onError: (error: unknown) => void;\n}\n\nexport interface SSEMessage {\n type: string;\n data: unknown;\n id?: string;\n}\n\n/** Text-only interaction transport. One POST/SSE stream is used per message. */\nexport class SSESession {\n private static readonly BOT_LLM_TEXT_FLUSH_MS = 16;\n private connected = false;\n private abortController: AbortController | null = null;\n private queue: Promise<void> = Promise.resolve();\n private pendingBotLlmText = \"\";\n private botLlmTextFlushTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(private readonly options: SSESessionOptions) {}\n\n get isConnected(): boolean {\n return this.connected;\n }\n\n connect(): void {\n this.connected = true;\n }\n\n sendMessage(type: string, data: unknown, id?: string): void {\n this.sendMessages([{ type, data, ...(id !== undefined ? { id } : {}) }]);\n }\n\n sendMessages(messages: SSEMessage[]): void {\n if (messages.length === 0) return;\n this.queue = this.queue\n .then(() => {\n if (!this.connected) return;\n return this.sendInteraction(messages, this.options.takeStateOfMind());\n })\n .catch((error: unknown) => {\n if (!isAbortError(error)) this.options.onError(error);\n });\n }\n\n async disconnect(): Promise<void> {\n this.connected = false;\n this.abortController?.abort();\n await this.queue;\n this.clearPendingBotLlmText();\n this.abortController = null;\n }\n\n private async sendInteraction(\n messages: SSEMessage[],\n stateOfMind: string | null,\n ): Promise<void> {\n const controller = new AbortController();\n this.abortController = controller;\n try {\n const characterSessionId = this.options.getCharacterSessionId();\n const response = await fetch(this.options.interactionApiUrl, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.options.authorization}`,\n Accept: \"text/event-stream\",\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n character_id: this.options.characterId,\n ...(stateOfMind ? { state_of_mind: stateOfMind } : {}),\n ...(characterSessionId && characterSessionId !== \"-1\"\n ? { character_session_id: characterSessionId }\n : {}),\n ...(this.options.endUserId\n ? { end_user_id: this.options.endUserId }\n : {}),\n ...(this.options.endUserMetadata\n ? { end_user_metadata: this.options.endUserMetadata }\n : {}),\n ...(buildEmotionConnectConfig(this.options) && {\n emotion_config: buildEmotionConnectConfig(this.options),\n }),\n ...(buildActionConnectConfig(this.options) && {\n action_config: buildActionConnectConfig(this.options),\n }),\n ...(this.options.debug !== undefined\n ? { debug: this.options.debug }\n : {}),\n messages: messages.map(({ type, data, id }) => ({\n label: \"rtvi-ai\",\n type,\n ...(id !== undefined ? { id } : {}),\n data,\n })),\n }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\n `Interaction API HTTP ${response.status}${text ? `: ${text}` : \"\"}`,\n );\n }\n if (!response.body) throw new Error(\"Interaction API returned no SSE body\");\n\n await this.readEvents(response.body, controller.signal);\n } finally {\n if (this.abortController === controller) this.abortController = null;\n }\n }\n\n private async readEvents(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n ): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let eventType = \"message\";\n let eventData: string[] = [];\n\n const dispatch = () => {\n if (eventData.length === 0) return;\n const dataText = eventData.join(\"\\n\");\n let data: unknown = dataText;\n try {\n data = JSON.parse(dataText);\n } catch {\n // SSE data is JSON for the interaction API; preserve malformed data for diagnostics.\n }\n if (\n eventType === \"bot-llm-text\" &&\n typeof data === \"object\" &&\n data !== null &&\n typeof (data as { text?: unknown }).text === \"string\"\n ) {\n this.queueBotLlmText((data as { text: string }).text);\n eventType = \"message\";\n eventData = [];\n return;\n }\n this.flushBotLlmText();\n if (eventType === \"session\" || eventType === \"done\") {\n const sessionId = (data as { character_session_id?: unknown })\n ?.character_session_id;\n if (typeof sessionId === \"string\") this.options.onCharacterSessionId(sessionId);\n } else {\n if (eventType === \"error\") this.options.onError(data);\n this.options.onMessage(\n new TextEncoder().encode(JSON.stringify({ type: eventType, data })),\n );\n }\n eventType = \"message\";\n eventData = [];\n };\n\n while (!signal.aborted) {\n const { done, value } = await reader.read();\n buffer += decoder.decode(value, { stream: !done });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n if (!line) dispatch();\n else if (line.startsWith(\"event:\")) eventType = line.slice(6).trim();\n else if (line.startsWith(\"data:\")) {\n eventData.push(line.slice(5).trimStart());\n }\n }\n if (done) {\n if (buffer) {\n if (buffer.startsWith(\"event:\")) eventType = buffer.slice(6).trim();\n else if (buffer.startsWith(\"data:\")) eventData.push(buffer.slice(5).trimStart());\n }\n dispatch();\n this.flushBotLlmText();\n return;\n }\n }\n }\n\n private queueBotLlmText(text: string): void {\n this.pendingBotLlmText += text;\n if (this.botLlmTextFlushTimer !== null) return;\n this.botLlmTextFlushTimer = setTimeout(() => {\n this.botLlmTextFlushTimer = null;\n this.flushBotLlmText();\n }, SSESession.BOT_LLM_TEXT_FLUSH_MS);\n }\n\n private flushBotLlmText(): void {\n if (this.botLlmTextFlushTimer !== null) {\n clearTimeout(this.botLlmTextFlushTimer);\n this.botLlmTextFlushTimer = null;\n }\n if (!this.pendingBotLlmText) return;\n const text = this.pendingBotLlmText;\n this.pendingBotLlmText = \"\";\n this.options.onMessage(\n new TextEncoder().encode(\n JSON.stringify({ type: \"bot-llm-text\", data: { text } }),\n ),\n );\n }\n\n private clearPendingBotLlmText(): void {\n if (this.botLlmTextFlushTimer !== null) {\n clearTimeout(this.botLlmTextFlushTimer);\n this.botLlmTextFlushTimer = null;\n }\n this.pendingBotLlmText = \"\";\n }\n}\n\nfunction isAbortError(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"name\" in error &&\n error.name === \"AbortError\"\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SSESession.js","sourceRoot":"","sources":["../../src/core/SSESession.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ConvaiConfig } from \"./types\";\nimport {\n buildActionConnectConfig,\n buildEmotionConnectConfig,\n serializeActionProtocolCapabilities,\n} from \"./connectRequest\";\n\nexport interface SSESessionOptions {\n interactionApiUrl: string;\n authorization: string;\n characterId: string;\n getCharacterSessionId: () => string | null;\n onCharacterSessionId: (characterSessionId: string) => void;\n endUserId?: string;\n endUserMetadata?: Record<string, unknown>;\n takeStateOfMind: () => string | null;\n enableEmotion?: ConvaiConfig[\"enableEmotion\"];\n emotionConfig?: ConvaiConfig[\"emotionConfig\"];\n actionConfig?: ConvaiConfig[\"actionConfig\"];\n capabilities?: ConvaiConfig[\"capabilities\"];\n dynamicInfo?: ConvaiConfig[\"dynamicInfo\"];\n keepInContext?: ConvaiConfig[\"keepInContext\"];\n narrativeTemplateKeys?: ConvaiConfig[\"narrativeTemplateKeys\"];\n sceneDescription?: ConvaiConfig[\"sceneDescription\"];\n respondModes?: ConvaiConfig[\"respondModes\"];\n debug?: boolean;\n useResponseLifecycleContract?: boolean;\n invocationMetadata?: ConvaiConfig[\"invocationMetadata\"];\n onMessage: (payload: Uint8Array) => void;\n onError: (error: unknown) => void;\n}\n\nexport interface SSEMessage {\n type: string;\n data: unknown;\n id?: string;\n}\n\n/** Text-only interaction transport. One POST/SSE stream is used per message. */\nexport class SSESession {\n private static readonly BOT_LLM_TEXT_FLUSH_MS = 16;\n private connected = false;\n private abortController: AbortController | null = null;\n private queue: Promise<void> = Promise.resolve();\n private pendingBotLlmText = \"\";\n private botLlmTextFlushTimer: ReturnType<typeof setTimeout> | null = null;\n private pendingMessages: SSEMessage[] = [];\n\n constructor(private readonly options: SSESessionOptions) {}\n\n get isConnected(): boolean {\n return this.connected;\n }\n\n connect(): void {\n this.connected = true;\n }\n\n sendMessage(type: string, data: unknown, id?: string): void {\n this.sendMessages([{ type, data, ...(id !== undefined ? { id } : {}) }]);\n }\n\n sendMessages(messages: SSEMessage[]): void {\n if (messages.length === 0) return;\n this.queue = this.queue\n .then(() => {\n if (!this.connected) return;\n const pending = this.pendingMessages;\n this.pendingMessages = [];\n const context = messages.filter((message) => message.type === \"update-dynamic-info\");\n const rest = messages.filter((message) => message.type !== \"update-dynamic-info\");\n return this.sendInteraction(\n [...context, ...pending, ...rest],\n this.options.takeStateOfMind(),\n );\n })\n .catch((error: unknown) => {\n if (!isAbortError(error)) this.options.onError(error);\n });\n }\n\n /** Update request-scoped dynamic context without opening a control-only request. */\n updateDynamicInfo(dynamicInfo: string): void {\n this.options.dynamicInfo = dynamicInfo;\n }\n\n getDynamicInfo(): string | undefined {\n return this.options.dynamicInfo;\n }\n\n /** Carry a silent control update into the next stateless interaction request. */\n queueMessage(type: string, data: unknown): void {\n this.pendingMessages.push({ type, data });\n }\n\n async disconnect(): Promise<void> {\n this.connected = false;\n this.abortController?.abort();\n await this.queue;\n this.clearPendingBotLlmText();\n this.abortController = null;\n this.pendingMessages = [];\n }\n\n private async sendInteraction(\n messages: SSEMessage[],\n stateOfMind: string | null,\n ): Promise<void> {\n const controller = new AbortController();\n this.abortController = controller;\n try {\n const characterSessionId = this.options.getCharacterSessionId();\n const response = await fetch(this.options.interactionApiUrl, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.options.authorization}`,\n Accept: \"text/event-stream\",\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n character_id: this.options.characterId,\n ...(stateOfMind ? { state_of_mind: stateOfMind } : {}),\n ...(characterSessionId && characterSessionId !== \"-1\"\n ? { character_session_id: characterSessionId }\n : {}),\n ...(this.options.endUserId\n ? { end_user_id: this.options.endUserId }\n : {}),\n ...(this.options.endUserMetadata\n ? { end_user_metadata: this.options.endUserMetadata }\n : {}),\n ...(buildEmotionConnectConfig(this.options) && {\n emotion_config: buildEmotionConnectConfig(this.options),\n }),\n ...(buildActionConnectConfig(this.options) && {\n action_config: buildActionConnectConfig(this.options),\n }),\n ...(this.options.capabilities && {\n capabilities: serializeActionProtocolCapabilities(this.options.capabilities),\n }),\n ...(this.options.dynamicInfo && {\n dynamic_info: {\n text: this.options.dynamicInfo,\n ...(this.options.keepInContext !== undefined && {\n keep_in_context: this.options.keepInContext,\n }),\n },\n }),\n ...(this.options.narrativeTemplateKeys &&\n Object.keys(this.options.narrativeTemplateKeys).length > 0 && {\n narrative_template_keys: this.options.narrativeTemplateKeys,\n }),\n ...(this.options.sceneDescription && {\n scene_description: this.options.sceneDescription,\n }),\n ...(this.options.respondModes && {\n respond_modes: serializeRespondModes(this.options.respondModes),\n }),\n ...(this.options.debug !== undefined\n ? { debug: this.options.debug }\n : {}),\n ...(this.options.useResponseLifecycleContract !== undefined\n ? {\n use_response_lifecycle_contract:\n this.options.useResponseLifecycleContract,\n }\n : {}),\n ...(this.options.invocationMetadata && {\n invocation_metadata: {\n source: this.options.invocationMetadata.source ?? \"web_sdk\",\n ...(this.options.invocationMetadata.clientVersion && {\n client_version: this.options.invocationMetadata.clientVersion,\n }),\n ...(this.options.invocationMetadata.extraMetadata && {\n extra_metadata: this.options.invocationMetadata.extraMetadata,\n }),\n },\n }),\n messages: messages.map(({ type, data, id }) => ({\n label: \"rtvi-ai\",\n type,\n ...(id !== undefined ? { id } : {}),\n data,\n })),\n }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\n `Interaction API HTTP ${response.status}${text ? `: ${text}` : \"\"}`,\n );\n }\n if (!response.body) throw new Error(\"Interaction API returned no SSE body\");\n\n await this.readEvents(response.body, controller.signal);\n } finally {\n if (this.abortController === controller) this.abortController = null;\n }\n }\n\n private async readEvents(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n ): Promise<void> {\n const reader = body.getReader();\n try {\n await this.consumeReader(reader, signal);\n } finally {\n // A spec-compliant fetch errors the body when its signal aborts, and the\n // read loop exits on that rejection. Not every runtime the SDK now\n // targets (Node, SSR shims, polyfills) does, and with no cancel the\n // loop would await a read that never settles -- so disconnect() would\n // hang forever. Cancelling is idempotent on an already-closed stream.\n await reader.cancel().catch(() => {});\n reader.releaseLock();\n }\n }\n\n private async consumeReader(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n signal: AbortSignal,\n ): Promise<void> {\n const decoder = new TextDecoder();\n let buffer = \"\";\n let eventType = \"message\";\n let eventData: string[] = [];\n\n const dispatch = () => {\n if (eventData.length === 0) {\n // Per the SSE spec a frame with no data is not dispatched, but its\n // event-type buffer is still reset. Leaving it set would hand the type\n // to the next frame that omits its own `event:` line -- so a bare\n // `event: done` marker would retype the frame after it as `done`, and\n // that frame would be swallowed as a session-id lookup.\n eventType = \"message\";\n return;\n }\n const dataText = eventData.join(\"\\n\");\n let data: unknown = dataText;\n try {\n data = JSON.parse(dataText);\n } catch {\n // SSE data is JSON for the interaction API; preserve malformed data for diagnostics.\n }\n if (\n eventType === \"bot-llm-text\" &&\n typeof data === \"object\" &&\n data !== null &&\n typeof (data as { text?: unknown }).text === \"string\"\n ) {\n this.queueBotLlmText((data as { text: string }).text);\n eventType = \"message\";\n eventData = [];\n return;\n }\n this.flushBotLlmText();\n if (eventType === \"session\" || eventType === \"done\") {\n const sessionId = (data as { character_session_id?: unknown })\n ?.character_session_id;\n if (typeof sessionId === \"string\") this.options.onCharacterSessionId(sessionId);\n } else {\n if (eventType === \"error\") this.options.onError(data);\n this.options.onMessage(\n new TextEncoder().encode(JSON.stringify({ type: eventType, data })),\n );\n }\n eventType = \"message\";\n eventData = [];\n };\n\n while (!signal.aborted) {\n const { done, value } = await reader.read();\n buffer += decoder.decode(value, { stream: !done });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n if (!line) dispatch();\n else if (line.startsWith(\"event:\")) eventType = line.slice(6).trim();\n else if (line.startsWith(\"data:\")) {\n eventData.push(line.slice(5).trimStart());\n }\n }\n if (done) {\n if (buffer) {\n if (buffer.startsWith(\"event:\")) eventType = buffer.slice(6).trim();\n else if (buffer.startsWith(\"data:\")) eventData.push(buffer.slice(5).trimStart());\n }\n dispatch();\n this.flushBotLlmText();\n return;\n }\n }\n }\n\n private queueBotLlmText(text: string): void {\n this.pendingBotLlmText += text;\n if (this.botLlmTextFlushTimer !== null) return;\n this.botLlmTextFlushTimer = setTimeout(() => {\n this.botLlmTextFlushTimer = null;\n this.flushBotLlmText();\n }, SSESession.BOT_LLM_TEXT_FLUSH_MS);\n }\n\n private flushBotLlmText(): void {\n if (this.botLlmTextFlushTimer !== null) {\n clearTimeout(this.botLlmTextFlushTimer);\n this.botLlmTextFlushTimer = null;\n }\n if (!this.pendingBotLlmText) return;\n const text = this.pendingBotLlmText;\n this.pendingBotLlmText = \"\";\n this.options.onMessage(\n new TextEncoder().encode(\n JSON.stringify({ type: \"bot-llm-text\", data: { text } }),\n ),\n );\n }\n\n private clearPendingBotLlmText(): void {\n if (this.botLlmTextFlushTimer !== null) {\n clearTimeout(this.botLlmTextFlushTimer);\n this.botLlmTextFlushTimer = null;\n }\n this.pendingBotLlmText = \"\";\n }\n}\n\nfunction serializeRespondModes(\n config: NonNullable<ConvaiConfig[\"respondModes\"]>,\n): Record<string, unknown> {\n return {\n ...(config.text !== undefined && { text: config.text }),\n ...(config.audio !== undefined && { audio: config.audio }),\n ...(config.vision !== undefined && { vision: config.vision }),\n ...(config.contextUpdate !== undefined && {\n context_update: config.contextUpdate,\n }),\n ...(config.trigger !== undefined && { trigger: config.trigger }),\n ...(config.sceneMetadata !== undefined && {\n scene_metadata: config.sceneMetadata,\n }),\n };\n}\n\nfunction isAbortError(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"name\" in error &&\n error.name === \"AbortError\"\n );\n}\n"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Character references.
|
|
3
|
+
*
|
|
4
|
+
* The runtime accepts a bare character UUID or a UUID followed by a version
|
|
5
|
+
* selector: `<uuid>-draft`, `<uuid>-latest`, or `<uuid>-1.2[.3]`. The SDK
|
|
6
|
+
* keeps the two halves apart — the bare UUID still names the character for
|
|
7
|
+
* memory, character info and analytics, while the joined reference is what
|
|
8
|
+
* goes on the wire to `/connect` and the interaction API.
|
|
9
|
+
*/
|
|
10
|
+
/** A version selector: the editable draft, the promoted latest, or an immutable tag. */
|
|
11
|
+
export type CharacterVersionSelector = "draft" | "latest" | (string & {});
|
|
12
|
+
export interface CharacterReference {
|
|
13
|
+
/** The bare character UUID, lower-cased. */
|
|
14
|
+
characterId: string;
|
|
15
|
+
/** The selector, or null for a bare reference. */
|
|
16
|
+
version: CharacterVersionSelector | null;
|
|
17
|
+
/** What goes on the wire: the UUID, or `<uuid>-<selector>`. */
|
|
18
|
+
reference: string;
|
|
19
|
+
}
|
|
20
|
+
/** True when `value` is `draft`, `latest`, or a `major.minor[.patch]` tag. */
|
|
21
|
+
export declare function isCharacterVersionSelector(value: unknown): value is CharacterVersionSelector;
|
|
22
|
+
/**
|
|
23
|
+
* Split a character id that may already carry a selector suffix. Returns null
|
|
24
|
+
* when the value is neither a UUID nor a versioned reference — callers that
|
|
25
|
+
* accept opaque ids (legacy non-UUID characters) fall back to the raw string.
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseCharacterReference(value: string): CharacterReference | null;
|
|
28
|
+
/**
|
|
29
|
+
* Combine a `characterId` and an optional `characterVersion` config field into
|
|
30
|
+
* the reference sent to the runtime.
|
|
31
|
+
*
|
|
32
|
+
* - `characterId` may be a bare UUID or already carry a selector.
|
|
33
|
+
* - `characterVersion` must be a valid selector when provided.
|
|
34
|
+
* - Supplying both is allowed only when they agree.
|
|
35
|
+
* - A non-UUID `characterId` cannot be versioned.
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveCharacterReference(characterId: string, characterVersion?: CharacterVersionSelector | null): CharacterReference;
|
|
38
|
+
/** True when `value` is a bare character UUID. */
|
|
39
|
+
export declare function isCharacterUuid(value: string): boolean;
|
|
40
|
+
//# sourceMappingURL=characterReference.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"characterReference.d.ts","sourceRoot":"","sources":["../../src/core/characterReference.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,wFAAwF;AACxF,MAAM,MAAM,wBAAwB,GAAG,OAAO,GAAG,QAAQ,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAY1E,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACzC,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,8EAA8E;AAC9E,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,wBAAwB,CAE5F;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAUhF;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,gBAAgB,CAAC,EAAE,wBAAwB,GAAG,IAAI,GACjD,kBAAkB,CA8BpB;AAED,kDAAkD;AAClD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtD"}
|