@ai-matrx/chat 0.4.0 → 0.4.7
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/CHANGELOG.md +80 -0
- package/dist/agent-copy/RichCopySplit.d.ts +17 -0
- package/dist/agent-copy/RichCopySplit.js +34 -0
- package/dist/agents/addressing/useAgentHref.js +4 -1
- package/dist/agents/api/submit-tool-results.js +11 -1
- package/dist/agents/components/agent-widgets/chat-assistant/AssistantMessageCard.js +1 -1
- package/dist/agents/components/chat/ConversationRecordsChip.js +1 -1
- package/dist/agents/components/chat/useCanvasScopedToConversation.js +1 -1
- package/dist/agents/components/context-items/bodies/WorkingDocumentBody.d.ts +5 -2
- package/dist/agents/components/context-items/bodies/WorkingDocumentBody.js +6 -1
- package/dist/agents/components/context-policies-display/ContextValueBody.js +1 -1
- package/dist/agents/components/context-preview/ContextCompareView.js +1 -1
- package/dist/agents/components/custom-agent/CustomAgentWindow.js +1 -1
- package/dist/agents/components/inputs/smart-input/AgentTextarea.d.ts +6 -1
- package/dist/agents/components/inputs/smart-input/AgentTextarea.js +2 -2
- package/dist/agents/components/inputs/smart-input/ComposerToolsNotice.d.ts +1 -0
- package/dist/agents/components/inputs/smart-input/ComposerToolsNotice.js +5 -0
- package/dist/agents/components/inputs/smart-input/ConversationContextRail.d.ts +5 -1
- package/dist/agents/components/inputs/smart-input/ConversationContextRail.js +6 -1
- package/dist/agents/components/inputs/smart-input/InboxQueueStrip.d.ts +6 -1
- package/dist/agents/components/inputs/smart-input/InboxQueueStrip.js +6 -1
- package/dist/agents/components/inputs/smart-input/InputActionButtons.js +8 -6
- package/dist/agents/components/inputs/smart-input/SmartInputFileDropTarget.d.ts +5 -1
- package/dist/agents/components/inputs/smart-input/SmartInputFileDropTarget.js +8 -1
- package/dist/agents/components/inputs/smart-input/composer/ComposerAgentPill.js +2 -2
- package/dist/agents/components/inputs/smart-input/composer/ComposerChipsRow.d.ts +5 -2
- package/dist/agents/components/inputs/smart-input/composer/ComposerChipsRow.js +6 -1
- package/dist/agents/components/inputs/smart-input/composer/ComposerMetaRow.d.ts +6 -8
- package/dist/agents/components/inputs/smart-input/composer/ComposerMetaRow.js +13 -1
- package/dist/agents/components/inputs/smart-input/composer/useOutputShapeCatalog.d.ts +1 -1
- package/dist/agents/components/inputs/smart-input/composer/useOutputShapeCatalog.js +1 -1
- package/dist/agents/components/live-run/LiveRunDisplay.js +1 -1
- package/dist/agents/components/live-run/RunSetDisplay.js +1 -1
- package/dist/agents/components/memory/components/AgentMemoryAllView.js +1 -1
- package/dist/agents/components/messages-display/AgentConversationDisplay.js +4 -1
- package/dist/agents/components/messages-display/assistant/AgentAssistantMessage.d.ts +1 -0
- package/dist/agents/components/messages-display/assistant/AgentAssistantMessage.js +4 -3
- package/dist/agents/components/messages-display/assistant/AgentEmptyMessageDisplay.js +1 -1
- package/dist/agents/components/messages-display/assistant/AssistantMessageFooter.d.ts +2 -2
- package/dist/agents/components/messages-display/assistant/AssistantMessageFooter.js +4 -7
- package/dist/agents/components/messages-display/assistant/InPlaceAnswerEditor.js +2 -2
- package/dist/agents/components/messages-display/citations/MessageSourcesRow.js +1 -1
- package/dist/agents/components/messages-display/rich-document/chat-message-source.d.ts +2 -0
- package/dist/agents/components/messages-display/rich-document/chat-message-source.js +41 -0
- package/dist/agents/components/messages-display/rich-document/chatMessageActions.d.ts +31 -0
- package/dist/agents/components/messages-display/rich-document/chatMessageActions.js +39 -0
- package/dist/agents/components/messages-display/user/AgentUserMessage.d.ts +1 -0
- package/dist/agents/components/messages-display/user/AgentUserMessage.js +7 -4
- package/dist/agents/components/messages-display/user/CollabNoteMessage.js +1 -1
- package/dist/agents/components/messages-display/user/UserActionBar.js +49 -39
- package/dist/agents/components/run-controls/panels/shared.d.ts +1 -0
- package/dist/agents/components/shared/AgentConversationColumn.js +3 -2
- package/dist/agents/components/working-document/WorkingDocumentEditor.d.ts +1 -1
- package/dist/agents/components/working-document/WorkingDocumentPanel.js +2 -1
- package/dist/agents/components/working-document/workingDocumentSurface.d.ts +1 -1
- package/dist/agents/identity/model-catalog.js +5 -3
- package/dist/agents/identity/run-tier-store.js +3 -0
- package/dist/agents/redux/agent-definition/cache-bust-middleware.js +2 -0
- package/dist/agents/redux/agent-definition/selectors.d.ts +237 -0
- package/dist/agents/redux/agent-settings/agentSettingsSlice.d.ts +0 -4
- package/dist/agents/redux/agent-settings/agentSettingsSlice.js +12 -5
- package/dist/agents/redux/agent-settings/selectors.d.ts +12 -0
- package/dist/agents/redux/agent-shortcut-categories/selectors.d.ts +50 -0
- package/dist/agents/redux/agent-shortcuts/selectors.d.ts +147 -0
- package/dist/agents/redux/conversation-history/selectors.d.ts +16 -0
- package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +2 -0
- package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +54 -0
- package/dist/agents/redux/execution-system/context-state/context-state.selectors.d.ts +14 -0
- package/dist/agents/redux/execution-system/conversations/conversations.selectors.d.ts +5 -0
- package/dist/agents/redux/execution-system/host-conversations/conversation-abilities.d.ts +12 -0
- package/dist/agents/redux/execution-system/host-conversations/conversation-abilities.js +25 -0
- package/dist/agents/redux/execution-system/host-conversations/host-conversation.thunks.d.ts +53 -0
- package/dist/agents/redux/execution-system/host-conversations/host-conversation.thunks.js +412 -0
- package/dist/agents/redux/execution-system/host-conversations/host-conversations.selectors.d.ts +28 -0
- package/dist/agents/redux/execution-system/host-conversations/host-conversations.selectors.js +41 -0
- package/dist/agents/redux/execution-system/host-conversations/host-conversations.slice.d.ts +43 -0
- package/dist/agents/redux/execution-system/host-conversations/host-conversations.slice.js +38 -0
- package/dist/agents/redux/execution-system/host-conversations/source-registry.d.ts +9 -0
- package/dist/agents/redux/execution-system/host-conversations/source-registry.js +15 -0
- package/dist/agents/redux/execution-system/host-conversations/useHostConversation.d.ts +4 -0
- package/dist/agents/redux/execution-system/host-conversations/useHostConversation.js +24 -0
- package/dist/agents/redux/execution-system/inbox/inbox-turn-end.middleware.js +2 -1
- package/dist/agents/redux/execution-system/instance-context/instance-context.selectors.d.ts +3 -0
- package/dist/agents/redux/execution-system/instance-resources/default-remark-durability.d.ts +22 -0
- package/dist/agents/redux/execution-system/instance-resources/default-remark-durability.js +164 -0
- package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.d.ts +8 -0
- package/dist/agents/redux/execution-system/instance-ui-state/instance-ui-state.selectors.d.ts +5 -0
- package/dist/agents/redux/execution-system/instance-ui-state/run-configuration-persist.js +2 -0
- package/dist/agents/redux/execution-system/instance-user-input/composer-draft-store.js +20 -0
- package/dist/agents/redux/execution-system/instance-user-input/useComposerDraftRestore.js +2 -1
- package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.selectors.d.ts +7 -0
- package/dist/agents/redux/execution-system/messages/messages.selectors.d.ts +1 -0
- package/dist/agents/redux/execution-system/messages/messages.selectors.js +1 -1
- package/dist/agents/redux/execution-system/observability/observability.selectors.d.ts +7 -0
- package/dist/agents/redux/execution-system/observational-memory/observational-memory.selectors.d.ts +1 -0
- package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +14 -0
- package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.js +8 -1
- package/dist/agents/redux/execution-system/thunks/execute-manual-instance.thunk.js +2 -1
- package/dist/agents/redux/execution-system/thunks/load-conversation.thunk.js +6 -0
- package/dist/agents/redux/execution-system/thunks/load-older-messages.thunk.js +12 -0
- package/dist/agents/redux/execution-system/thunks/process-stream.js +6 -4
- package/dist/agents/redux/execution-system/thunks/resolve-base-url.js +1 -1
- package/dist/agents/redux/execution-system/thunks/smart-execute.thunk.js +43 -0
- package/dist/agents/redux/execution-system/utils/assemble-cx-content-blocks.js +2 -1
- package/dist/agents/redux/execution-system/utils/continuation-body.d.ts +1 -0
- package/dist/agents/redux/execution-system/utils/continuation-body.js +2 -1
- package/dist/agents/redux/execution-system/utils/inbound-render-block.d.ts +8 -0
- package/dist/agents/redux/execution-system/utils/inbound-render-block.js +17 -2
- package/dist/agents/redux/execution-system/utils/normalize-content-blocks.js +1 -1
- package/dist/agents/redux/execution-system/utils/progress-data-block.d.ts +11 -0
- package/dist/agents/redux/execution-system/utils/progress-data-block.js +37 -0
- package/dist/agents/redux/execution-system/utils/stream-block-accumulator.js +10 -8
- package/dist/agents/redux/mcp/mcp.slice.js +15 -7
- package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +1 -0
- package/dist/agents/redux/tools/tools.selectors.d.ts +1 -0
- package/dist/agents/redux/tools/tools.thunks.js +3 -0
- package/dist/agents/resources/default-picker-items.d.ts +17 -0
- package/dist/agents/resources/default-picker-items.js +48 -0
- package/dist/agents/runtime-reconnect/ServerOperationBanner.d.ts +6 -1
- package/dist/agents/runtime-reconnect/ServerOperationBanner.js +6 -1
- package/dist/agents/types/instance.types.d.ts +2 -1
- package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +2 -0
- package/dist/agents/ui-first-tools/ui/ApprovalCard.js +1 -1
- package/dist/agents/ui-first-tools/ui/AskCard.js +1 -1
- package/dist/agents/ui-first-tools/ui/lists/TaskPanel.js +1 -1
- package/dist/conversation/hooks/useDomCapturePrint.js +1 -1
- package/dist/conversation/utils/markdown-print.js +1 -1
- package/dist/cx-chat/components/SsrSidebarChats.js +1 -1
- package/dist/cx-chat/components/messages/AssistantMessage.js +3 -5
- package/dist/cx-chat/components/sidebar/SidebarUserFooter.js +1 -1
- package/dist/cx-conversation/AssistantMessage.js +3 -5
- package/dist/host/app-data-slots.d.ts +85 -0
- package/dist/host/app-data-slots.js +42 -0
- package/dist/host/app-identity.d.ts +20 -0
- package/dist/host/app-identity.js +21 -0
- package/dist/host/bare-host-chrome.d.ts +14 -0
- package/dist/host/bare-host-chrome.js +45 -0
- package/dist/host/configure.d.ts +9 -1
- package/dist/host/configure.js +44 -8
- package/dist/host/contract.d.ts +39 -2
- package/dist/host/db-types.d.ts +99 -1
- package/dist/host/defaults/navigation-hooks.d.ts +2 -0
- package/dist/host/defaults/navigation-hooks.js +7 -1
- package/dist/host/defaults/navigation.d.ts +4 -3
- package/dist/host/defaults/navigation.js +38 -7
- package/dist/host/defaults/org.d.ts +12 -4
- package/dist/host/defaults/org.js +39 -1
- package/dist/host/defaults/prefs.d.ts +11 -0
- package/dist/host/defaults/prefs.js +43 -0
- package/dist/host/defaults/workspace-gate.d.ts +16 -0
- package/dist/host/defaults/workspace-gate.js +89 -0
- package/dist/host/diagnostics.d.ts +7 -2
- package/dist/host/diagnostics.js +6 -0
- package/dist/host/identity.js +2 -1
- package/dist/host/index.d.ts +6 -3
- package/dist/host/index.js +23 -2
- package/dist/host/no-database.d.ts +38 -0
- package/dist/host/no-database.js +107 -0
- package/dist/host/react.d.ts +1 -0
- package/dist/host/react.js +40 -2
- package/dist/host/registered-source.js +2 -2
- package/dist/host/source.d.ts +130 -0
- package/dist/host/source.js +86 -0
- package/dist/host/ui-slots.d.ts +9 -31
- package/dist/host/ui-slots.js +5 -37
- package/dist/mandates/useMandate.js +13 -0
- package/dist/public-chat/components/PublicMessageOptionsMenu.js +3 -2
- package/dist/store/create-chat-store.d.ts +4 -2
- package/dist/store/middlewares.d.ts +5 -0
- package/dist/store/slices.d.ts +1 -0
- package/dist/store/slices.js +4 -1
- package/dist/surfaces/redux/selectors.d.ts +2 -0
- package/dist/surfaces/redux/surfaceConfigSlice.js +2 -0
- package/dist/surfaces/redux/userStateSlice.js +3 -1
- package/dist/surfaces/runtime/agent-offer.js +1 -1
- package/dist/surfaces/runtime/surface-writeback.js +1 -1
- package/dist/testing/turn-harness.d.ts +35 -0
- package/dist/testing/turn-harness.js +85 -0
- package/dist/tool-call-visualization/db-renderer/fetchToolRendererRow.js +2 -0
- package/dist/tool-call-visualization/redux/selectors.d.ts +1 -0
- package/dist/tool-call-visualization/renderers/agent-call/AgentCallInline.js +1 -1
- package/dist/tool-call-visualization/renderers/agent-call/CollabCallCard.js +1 -1
- package/dist/tool-call-visualization/renderers/fs/FsInline.js +1 -1
- package/dist/tool-call-visualization/renderers/random-wheel/RandomWheelInline.js +1 -1
- package/dist/tool-call-visualization/renderers/research/ResearchOverlay.js +4 -4
- package/dist/tool-call-visualization/renderers/research/SubagentReportBlock.js +2 -2
- package/dist/tool-call-visualization/renderers/scrape/ScrapeOverlay.js +1 -1
- package/dist/tool-call-visualization/renderers/search/SearchInline.js +1 -1
- package/dist/tool-call-visualization/renderers/search/SearchOverlay.js +1 -1
- package/dist/tool-call-visualization/renderers/sql/SqlInline.js +1 -1
- package/dist/tool-call-visualization/result-fields/KeyValueGrid.js +1 -1
- package/dist/tool-call-visualization/result-fields/ResultMarkdown.js +1 -1
- package/dist/tool-call-visualization/result-fields/ResultValue.js +1 -1
- package/dist/tool-call-visualization/surface-write/SurfaceWriteDiff.js +1 -1
- package/dist/ui/AudioOutputBlockSkeleton.d.ts +17 -0
- package/dist/ui/AudioOutputBlockSkeleton.js +78 -0
- package/dist/ui/chat-protocol-from-stream.d.ts +60 -0
- package/dist/ui/chat-protocol-from-stream.js +135 -0
- package/dist/ui/markdown-stream/EnhancedChatMarkdown.d.ts +59 -0
- package/dist/ui/markdown-stream/EnhancedChatMarkdown.js +1108 -0
- package/dist/ui/markdown-stream/MarkdownStream.d.ts +88 -0
- package/dist/ui/markdown-stream/MarkdownStream.js +14 -0
- package/dist/ui/markdown-stream/MarkdownStreamImpl.d.ts +4 -0
- package/dist/ui/markdown-stream/MarkdownStreamImpl.js +86 -0
- package/dist/ui/markdown-stream/StreamAwareChatMarkdown.d.ts +58 -0
- package/dist/ui/markdown-stream/StreamAwareChatMarkdown.js +294 -0
- package/dist/ui/markdown-stream/internal-handlers/AgentCallChildTrace.d.ts +22 -0
- package/dist/ui/markdown-stream/internal-handlers/AgentCallChildTrace.js +128 -0
- package/dist/ui/markdown-stream/internal-handlers/InlineAssistantError.d.ts +3 -0
- package/dist/ui/markdown-stream/internal-handlers/InlineAssistantError.js +26 -0
- package/dist/ui/markdown-stream/internal-handlers/InlineThinkingSlot.d.ts +14 -0
- package/dist/ui/markdown-stream/internal-handlers/InlineThinkingSlot.js +23 -0
- package/dist/ui/markdown-stream/internal-handlers/ToolHandlers.d.ts +42 -0
- package/dist/ui/markdown-stream/internal-handlers/ToolHandlers.js +109 -0
- package/dist/ui/markdown-stream/useBoundAgentOutputSchema.d.ts +2 -0
- package/dist/ui/markdown-stream/useBoundAgentOutputSchema.js +33 -0
- package/dist/window-panels/windows/agents/AgentAssistantMarkdownDebugWindow.js +1 -1
- package/package.json +10 -5
- package/dist/host/content-ir-slots.d.ts +0 -231
- package/dist/host/content-ir-slots.js +0 -131
- package/dist/host/markdown-slots.d.ts +0 -53
- package/dist/host/markdown-slots.js +0 -32
- package/dist/host/rich-document-slots.d.ts +0 -123
- package/dist/host/rich-document-slots.js +0 -36
- package/dist/utils/content-ir/report-kind-at-raw-renderer.d.ts +0 -19
- package/dist/utils/content-ir/report-kind-at-raw-renderer.js +0 -32
|
@@ -52,6 +52,7 @@ export declare const selectContextState: (conversationId: string) => ((state: {
|
|
|
52
52
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
53
53
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
54
54
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
55
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
55
56
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
56
57
|
clearCache: () => void;
|
|
57
58
|
resultsCount: () => number;
|
|
@@ -122,6 +123,7 @@ export declare const selectEstimatedTokens: (conversationId: string) => ((state:
|
|
|
122
123
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
123
124
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
124
125
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
126
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
125
127
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => number) & {
|
|
126
128
|
clearCache: () => void;
|
|
127
129
|
resultsCount: () => number;
|
|
@@ -177,6 +179,7 @@ export declare const selectEstimatedTokens: (conversationId: string) => ((state:
|
|
|
177
179
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
178
180
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
179
181
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
182
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
180
183
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
181
184
|
clearCache: () => void;
|
|
182
185
|
resultsCount: () => number;
|
|
@@ -253,6 +256,7 @@ export declare const selectContextFillRatio: (conversationId: string, windowToke
|
|
|
253
256
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
254
257
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
255
258
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
259
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
256
260
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => number) & {
|
|
257
261
|
clearCache: () => void;
|
|
258
262
|
resultsCount: () => number;
|
|
@@ -308,6 +312,7 @@ export declare const selectContextFillRatio: (conversationId: string, windowToke
|
|
|
308
312
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
309
313
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
310
314
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
315
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
311
316
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => number) & {
|
|
312
317
|
clearCache: () => void;
|
|
313
318
|
resultsCount: () => number;
|
|
@@ -363,6 +368,7 @@ export declare const selectContextFillRatio: (conversationId: string, windowToke
|
|
|
363
368
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
364
369
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
365
370
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
371
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
366
372
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
367
373
|
clearCache: () => void;
|
|
368
374
|
resultsCount: () => number;
|
|
@@ -444,6 +450,7 @@ export declare const selectCacheLikelyAlive: (conversationId: string) => ((state
|
|
|
444
450
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
445
451
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
446
452
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
453
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
447
454
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => boolean) & {
|
|
448
455
|
clearCache: () => void;
|
|
449
456
|
resultsCount: () => number;
|
|
@@ -499,6 +506,7 @@ export declare const selectCacheLikelyAlive: (conversationId: string) => ((state
|
|
|
499
506
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
500
507
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
501
508
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
509
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
502
510
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
503
511
|
clearCache: () => void;
|
|
504
512
|
resultsCount: () => number;
|
|
@@ -572,6 +580,7 @@ export declare const selectCacheSecondsRemaining: (conversationId: string) => ((
|
|
|
572
580
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
573
581
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
574
582
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
583
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
575
584
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => number) & {
|
|
576
585
|
clearCache: () => void;
|
|
577
586
|
resultsCount: () => number;
|
|
@@ -627,6 +636,7 @@ export declare const selectCacheSecondsRemaining: (conversationId: string) => ((
|
|
|
627
636
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
628
637
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
629
638
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
639
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
630
640
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
631
641
|
clearCache: () => void;
|
|
632
642
|
resultsCount: () => number;
|
|
@@ -699,6 +709,7 @@ export declare const selectLastTrimSummary: (conversationId: string) => ((state:
|
|
|
699
709
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
700
710
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
701
711
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
712
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
702
713
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => import("./context-state.slice.js").TrimSummary | null) & {
|
|
703
714
|
clearCache: () => void;
|
|
704
715
|
resultsCount: () => number;
|
|
@@ -754,6 +765,7 @@ export declare const selectLastTrimSummary: (conversationId: string) => ((state:
|
|
|
754
765
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
755
766
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
756
767
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
768
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
757
769
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
758
770
|
clearCache: () => void;
|
|
759
771
|
resultsCount: () => number;
|
|
@@ -826,6 +838,7 @@ export declare const selectLastRawUsage: (conversationId: string) => ((state: {
|
|
|
826
838
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
827
839
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
828
840
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
841
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
829
842
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => Record<string, unknown> | null) & {
|
|
830
843
|
clearCache: () => void;
|
|
831
844
|
resultsCount: () => number;
|
|
@@ -881,6 +894,7 @@ export declare const selectLastRawUsage: (conversationId: string) => ((state: {
|
|
|
881
894
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
882
895
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
883
896
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
897
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
884
898
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
885
899
|
clearCache: () => void;
|
|
886
900
|
resultsCount: () => number;
|
|
@@ -49,6 +49,7 @@ export declare const selectConversationIdsByAgent: ((state: {
|
|
|
49
49
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
50
50
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
51
51
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
52
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
52
53
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => Record<string, string[]>) & {
|
|
53
54
|
clearCache: () => void;
|
|
54
55
|
resultsCount: () => number;
|
|
@@ -113,6 +114,7 @@ export declare const selectInstancesByAgent: (agentId: string) => ((state: {
|
|
|
113
114
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
114
115
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
115
116
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
117
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
116
118
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ExecutionInstance[]) & {
|
|
117
119
|
clearCache: () => void;
|
|
118
120
|
resultsCount: () => number;
|
|
@@ -182,6 +184,7 @@ export declare const selectConversationSurfaceOwnsOutput: ((state: {
|
|
|
182
184
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
183
185
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
184
186
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
187
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
185
188
|
} & import("../../../../store/root-state.js").ChatHostReadSlices, conversationId: string | null | undefined) => boolean) & {
|
|
186
189
|
clearCache: () => void;
|
|
187
190
|
resultsCount: () => number;
|
|
@@ -247,6 +250,7 @@ export declare const selectRunningInstances: ((state: {
|
|
|
247
250
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
248
251
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
249
252
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
253
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
250
254
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ExecutionInstance[]) & {
|
|
251
255
|
clearCache: () => void;
|
|
252
256
|
resultsCount: () => number;
|
|
@@ -340,6 +344,7 @@ export declare const selectConversationScopeIds: (conversationId: string) => ((s
|
|
|
340
344
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
341
345
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
342
346
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
347
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
343
348
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => {
|
|
344
349
|
organizationId: string | null;
|
|
345
350
|
projectId: string | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The conversation's abilities, provided ONCE by `AgentConversationColumn` (HOST-OWNED-SOURCE-PLAN
|
|
3
|
+
* §2.3). Every database-backed control reads `useConversationAbilities()` and is ABSENT when the
|
|
4
|
+
* ability is false — never a dead button. Outside a column: a database-backed conversation.
|
|
5
|
+
*/
|
|
6
|
+
import { type ReactNode } from "react";
|
|
7
|
+
import { type ConversationAbilities } from "./host-conversations.selectors.js";
|
|
8
|
+
export declare function ConversationAbilitiesProvider({ conversationId, children, }: {
|
|
9
|
+
conversationId: string;
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
}): import("react").JSX.Element;
|
|
12
|
+
export declare function useConversationAbilities(): ConversationAbilities;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext } from "react";
|
|
4
|
+
import { useAppSelector } from "../../../../store/hooks.js";
|
|
5
|
+
import {
|
|
6
|
+
FULL_CONVERSATION_ABILITIES,
|
|
7
|
+
selectConversationAbilities
|
|
8
|
+
} from "./host-conversations.selectors.js";
|
|
9
|
+
const ConversationAbilitiesContext = createContext(
|
|
10
|
+
FULL_CONVERSATION_ABILITIES
|
|
11
|
+
);
|
|
12
|
+
function ConversationAbilitiesProvider({
|
|
13
|
+
conversationId,
|
|
14
|
+
children
|
|
15
|
+
}) {
|
|
16
|
+
const abilities = useAppSelector(selectConversationAbilities(conversationId));
|
|
17
|
+
return /* @__PURE__ */ jsx(ConversationAbilitiesContext.Provider, { value: abilities, children });
|
|
18
|
+
}
|
|
19
|
+
function useConversationAbilities() {
|
|
20
|
+
return useContext(ConversationAbilitiesContext);
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
ConversationAbilitiesProvider,
|
|
24
|
+
useConversationAbilities
|
|
25
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The engine half of a host-owned conversation (HOST-OWNED-SOURCE-PLAN §2.3, P28b).
|
|
3
|
+
*
|
|
4
|
+
* ONE store, ONE stream parser, ONE renderer serve both kinds of conversation:
|
|
5
|
+
* - binding creates the same instance every conversation has (`createInstanceFull`, endpoint
|
|
6
|
+
* mode "host"), registers the source, and hydrates its history through `hydrateMessages`;
|
|
7
|
+
* - every live turn — sent here or started by the host — runs through `processStream`
|
|
8
|
+
* unchanged (typed events are wrapped as the platform's NDJSON `Response`);
|
|
9
|
+
* - message ids are minted by the client (no `record_reserved` ever arrives), and whether the
|
|
10
|
+
* conversation is SAVED comes from `source.persistence`, never from that.
|
|
11
|
+
*
|
|
12
|
+
* Nothing here reaches `host/db` or the server port.
|
|
13
|
+
*/
|
|
14
|
+
import type { ChatDispatch, ChatRootState } from "../../../../store/root-state.js";
|
|
15
|
+
import { type ChatMessageSource, type HostMessageRecord, type HostToolCall, type HostTurn } from "../../../../host/source.js";
|
|
16
|
+
import { type CxToolCallRecord } from "../observability/observability.slice.js";
|
|
17
|
+
import { type MessageRecord } from "../messages/messages.slice.js";
|
|
18
|
+
type Dispatch = ChatDispatch;
|
|
19
|
+
type GetState = () => ChatRootState;
|
|
20
|
+
export declare function hostRecordToMessageRecord(conversationId: string, record: HostMessageRecord): MessageRecord;
|
|
21
|
+
/** A host's tool call as the record a saved `tool_call` part's card reads (no database row). */
|
|
22
|
+
export declare function hostToolCallToRecord(conversationId: string, call: HostToolCall): CxToolCallRecord;
|
|
23
|
+
/** Read (or re-read) the host's history into the store. The host's sentence on failure. */
|
|
24
|
+
export declare function loadHostHistory(dispatch: Dispatch, getState: GetState, conversationId: string, options?: {
|
|
25
|
+
older?: boolean;
|
|
26
|
+
}): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Run one host turn through the ONE stream parser. `user` is the person's message when the host
|
|
29
|
+
* started the turn; a turn this tab sent already shows it (no second copy).
|
|
30
|
+
*/
|
|
31
|
+
export declare function runHostTurn(dispatch: Dispatch, getState: GetState, conversationId: string, turn: HostTurn): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* The person's send on a host conversation. Resolves when the host accepted it (the turn then
|
|
34
|
+
* streams, here or through `sink.turn`); rejects with the host's refusal so the caller puts the
|
|
35
|
+
* words back in the box.
|
|
36
|
+
*/
|
|
37
|
+
export declare function sendToHost(dispatch: Dispatch, getState: GetState, conversationId: string, text: string, mode: "send" | "queue" | "steer"): Promise<void>;
|
|
38
|
+
/** Stop: the host ends its run; our read of the turn ends now either way. */
|
|
39
|
+
export declare function stopHostTurn(conversationId: string): Promise<void>;
|
|
40
|
+
export declare function answerHostAsk(conversationId: string, askId: string, value: unknown): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Bind a conversation to a host-owned source: the instance, the plain-data entry, the
|
|
43
|
+
* subscription, and the first history read. Returns the unbind.
|
|
44
|
+
*/
|
|
45
|
+
export declare function bindHostConversation(dispatch: Dispatch, getState: GetState, args: {
|
|
46
|
+
conversationId: string;
|
|
47
|
+
source: ChatMessageSource;
|
|
48
|
+
database: boolean;
|
|
49
|
+
surfaceKey?: string;
|
|
50
|
+
}): () => void;
|
|
51
|
+
/** For thunks that only hold state: is this conversation hosted (branch first, never reach a db). */
|
|
52
|
+
export declare function hostConversationOf(state: ChatRootState, conversationId: string): import("./host-conversations.slice.js").HostConversationEntry | null;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from "uuid";
|
|
2
|
+
import { mintClientTempId } from "@ai-matrx/kit/ids";
|
|
3
|
+
import {
|
|
4
|
+
hostTurnResponse
|
|
5
|
+
} from "../../../../host/source.js";
|
|
6
|
+
import { upsertToolCall } from "../observability/observability.slice.js";
|
|
7
|
+
import { createInstanceFull } from "../create-instance-full.js";
|
|
8
|
+
import {
|
|
9
|
+
addOptimisticUserMessage,
|
|
10
|
+
hydrateMessages,
|
|
11
|
+
prependMessages,
|
|
12
|
+
removeMessage,
|
|
13
|
+
reserveMessage,
|
|
14
|
+
setMessagesHydrationFailure,
|
|
15
|
+
updateMessageRecord,
|
|
16
|
+
setOlderLoading
|
|
17
|
+
} from "../messages/messages.slice.js";
|
|
18
|
+
import { selectNextMessagePosition } from "../messages/messages.selectors.js";
|
|
19
|
+
import { createRequest, setRequestStatus } from "../active-requests/active-requests.slice.js";
|
|
20
|
+
import { setInstanceStatus } from "../conversations/conversations.slice.js";
|
|
21
|
+
import { processStream } from "../thunks/process-stream.js";
|
|
22
|
+
import {
|
|
23
|
+
registerAbortController,
|
|
24
|
+
unregisterAbortController
|
|
25
|
+
} from "../thunks/abort-registry.js";
|
|
26
|
+
import {
|
|
27
|
+
hostConversationBound,
|
|
28
|
+
hostConversationHeld,
|
|
29
|
+
hostConversationUnavailable,
|
|
30
|
+
hostConversationUnbound
|
|
31
|
+
} from "./host-conversations.slice.js";
|
|
32
|
+
import { getHostSource, registerHostSource, unregisterHostSource } from "./source-registry.js";
|
|
33
|
+
import { selectHostConversation } from "./host-conversations.selectors.js";
|
|
34
|
+
const localEcho = /* @__PURE__ */ new Map();
|
|
35
|
+
const liveTurn = /* @__PURE__ */ new Map();
|
|
36
|
+
function hostRecordToMessageRecord(conversationId, record) {
|
|
37
|
+
return {
|
|
38
|
+
id: record.id,
|
|
39
|
+
conversationId,
|
|
40
|
+
agentId: null,
|
|
41
|
+
role: record.role,
|
|
42
|
+
content: record.content,
|
|
43
|
+
contentHistory: null,
|
|
44
|
+
userContent: null,
|
|
45
|
+
position: record.position,
|
|
46
|
+
source: "host",
|
|
47
|
+
status: "active",
|
|
48
|
+
isVisibleToModel: true,
|
|
49
|
+
isVisibleToUser: true,
|
|
50
|
+
metadata: {},
|
|
51
|
+
createdAt: record.createdAt,
|
|
52
|
+
deletedAt: null,
|
|
53
|
+
error: record.error ? { type: record.error.code ?? "host_error", message: record.error.message } : null
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function hostToolCallToRecord(conversationId, call) {
|
|
57
|
+
const at = (/* @__PURE__ */ new Date(0)).toISOString();
|
|
58
|
+
return {
|
|
59
|
+
id: `host-tool-${conversationId}-${call.callId}`,
|
|
60
|
+
conversationId,
|
|
61
|
+
userRequestId: null,
|
|
62
|
+
messageId: call.messageId ?? null,
|
|
63
|
+
userId: "",
|
|
64
|
+
callId: call.callId,
|
|
65
|
+
toolName: call.name,
|
|
66
|
+
toolNameAsCalled: call.displayName ?? null,
|
|
67
|
+
toolType: "host",
|
|
68
|
+
iteration: 0,
|
|
69
|
+
status: call.status,
|
|
70
|
+
success: call.status === "completed" && !call.isError,
|
|
71
|
+
isError: call.isError,
|
|
72
|
+
errorType: call.isError ? "tool_error" : null,
|
|
73
|
+
errorMessage: call.isError ? call.output : null,
|
|
74
|
+
arguments: call.arguments,
|
|
75
|
+
output: call.isError ? null : call.output,
|
|
76
|
+
outputChars: call.output?.length ?? 0,
|
|
77
|
+
outputPreview: null,
|
|
78
|
+
outputType: null,
|
|
79
|
+
inputTokens: null,
|
|
80
|
+
outputTokens: null,
|
|
81
|
+
totalTokens: null,
|
|
82
|
+
costUsd: null,
|
|
83
|
+
durationMs: 0,
|
|
84
|
+
startedAt: at,
|
|
85
|
+
completedAt: at,
|
|
86
|
+
parentCallId: null,
|
|
87
|
+
retryCount: null,
|
|
88
|
+
persistKey: null,
|
|
89
|
+
filePath: null,
|
|
90
|
+
executionEvents: call.displayName ? [{ event: "tool_started", call_id: call.callId, tool_name: call.name, data: { display_name: call.displayName } }] : null,
|
|
91
|
+
metadata: {},
|
|
92
|
+
createdAt: at,
|
|
93
|
+
deletedAt: null
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function applyHistory(dispatch, conversationId, page, older) {
|
|
97
|
+
const records = page.records.map((r) => hostRecordToMessageRecord(conversationId, r));
|
|
98
|
+
const oldestPosition = records.reduce(
|
|
99
|
+
(min, r) => min === null || r.position < min ? r.position : min,
|
|
100
|
+
null
|
|
101
|
+
);
|
|
102
|
+
const pagination = { oldestPosition, hasMoreOlder: page.hasMoreOlder };
|
|
103
|
+
for (const call of page.toolCalls ?? []) {
|
|
104
|
+
dispatch(upsertToolCall(hostToolCallToRecord(conversationId, call)));
|
|
105
|
+
}
|
|
106
|
+
if (older) dispatch(prependMessages({ conversationId, messages: records, pagination }));
|
|
107
|
+
else dispatch(hydrateMessages({ conversationId, messages: records, pagination }));
|
|
108
|
+
dispatch(hostConversationUnavailable({ conversationId, reason: page.unavailable ?? null }));
|
|
109
|
+
dispatch(
|
|
110
|
+
setMessagesHydrationFailure({
|
|
111
|
+
conversationId,
|
|
112
|
+
failure: page.unavailable && records.length === 0 ? page.unavailable : null
|
|
113
|
+
})
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
async function loadHostHistory(dispatch, getState, conversationId, options = {}) {
|
|
117
|
+
const source = getHostSource(conversationId);
|
|
118
|
+
if (!source) return;
|
|
119
|
+
const entry = getState().messages.byConversationId[conversationId];
|
|
120
|
+
if (options.older) {
|
|
121
|
+
if (!entry?.hasMoreOlder || entry.isLoadingOlder) return;
|
|
122
|
+
dispatch(setOlderLoading({ conversationId, loading: true }));
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
const page = await source.load(
|
|
126
|
+
conversationId,
|
|
127
|
+
options.older ? { before: entry?.oldestPosition ?? null } : void 0
|
|
128
|
+
);
|
|
129
|
+
if (getHostSource(conversationId) !== source) return;
|
|
130
|
+
applyHistory(dispatch, conversationId, page, Boolean(options.older));
|
|
131
|
+
} catch (error) {
|
|
132
|
+
const reason = error instanceof Error && error.message ? error.message : "This chat's history could not be read.";
|
|
133
|
+
dispatch(setMessagesHydrationFailure({ conversationId, failure: reason }));
|
|
134
|
+
dispatch(hostConversationUnavailable({ conversationId, reason }));
|
|
135
|
+
} finally {
|
|
136
|
+
if (options.older) dispatch(setOlderLoading({ conversationId, loading: false }));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const DROPPED_EVENTS = /* @__PURE__ */ new Set(["record_reserved", "record_update"]);
|
|
140
|
+
const DROPPED_TABLES = /* @__PURE__ */ new Set(["message", "cx_message", "conversation", "cx_conversation"]);
|
|
141
|
+
function hostTurnBody(response, signal) {
|
|
142
|
+
const body = response.body;
|
|
143
|
+
if (!body) return response;
|
|
144
|
+
const reader = body.getReader();
|
|
145
|
+
const decoder = new TextDecoder();
|
|
146
|
+
const encoder = new TextEncoder();
|
|
147
|
+
let carry = "";
|
|
148
|
+
const keep = (line) => {
|
|
149
|
+
if (!line.trim()) return false;
|
|
150
|
+
try {
|
|
151
|
+
const frame = JSON.parse(line);
|
|
152
|
+
return !(typeof frame.event === "string" && DROPPED_EVENTS.has(frame.event) && typeof frame.data?.table === "string" && DROPPED_TABLES.has(frame.data.table));
|
|
153
|
+
} catch {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
const stream = new ReadableStream({
|
|
158
|
+
start(controller) {
|
|
159
|
+
signal.addEventListener("abort", () => {
|
|
160
|
+
try {
|
|
161
|
+
controller.close();
|
|
162
|
+
} catch {
|
|
163
|
+
}
|
|
164
|
+
void reader.cancel().catch(() => {
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
},
|
|
168
|
+
async pull(controller) {
|
|
169
|
+
for (; ; ) {
|
|
170
|
+
if (signal.aborted) return;
|
|
171
|
+
let chunk;
|
|
172
|
+
try {
|
|
173
|
+
chunk = await reader.read();
|
|
174
|
+
} catch (error) {
|
|
175
|
+
if (!signal.aborted) controller.error(error);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (signal.aborted) return;
|
|
179
|
+
if (chunk.done) {
|
|
180
|
+
if (keep(carry)) controller.enqueue(encoder.encode(`${carry}
|
|
181
|
+
`));
|
|
182
|
+
carry = "";
|
|
183
|
+
controller.close();
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const lines = (carry + decoder.decode(chunk.value, { stream: true })).split("\n");
|
|
187
|
+
carry = lines.pop() ?? "";
|
|
188
|
+
const kept = lines.filter(keep);
|
|
189
|
+
if (kept.length > 0) {
|
|
190
|
+
controller.enqueue(encoder.encode(`${kept.join("\n")}
|
|
191
|
+
`));
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
cancel() {
|
|
197
|
+
void reader.cancel().catch(() => {
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
return new Response(stream, { status: response.status, headers: response.headers });
|
|
202
|
+
}
|
|
203
|
+
async function runHostTurn(dispatch, getState, conversationId, turn) {
|
|
204
|
+
const { requestId } = turn;
|
|
205
|
+
let userMessageClientTempId;
|
|
206
|
+
const echoes = localEcho.get(conversationId) ?? 0;
|
|
207
|
+
if (echoes > 0) {
|
|
208
|
+
if (echoes === 1) localEcho.delete(conversationId);
|
|
209
|
+
else localEcho.set(conversationId, echoes - 1);
|
|
210
|
+
} else if (turn.user && turn.user.length > 0) {
|
|
211
|
+
userMessageClientTempId = addUserMessage(dispatch, getState, conversationId, turn.user, requestId);
|
|
212
|
+
settleUserMessage(dispatch, conversationId, userMessageClientTempId);
|
|
213
|
+
}
|
|
214
|
+
const controller = new AbortController();
|
|
215
|
+
liveTurn.set(conversationId, { requestId, controller });
|
|
216
|
+
registerAbortController(conversationId, controller);
|
|
217
|
+
dispatch(createRequest({ requestId, conversationId }));
|
|
218
|
+
dispatch(
|
|
219
|
+
reserveMessage({
|
|
220
|
+
conversationId,
|
|
221
|
+
messageId: mintClientTempId("assistant", requestId),
|
|
222
|
+
role: "assistant",
|
|
223
|
+
position: selectNextMessagePosition(conversationId)(getState()),
|
|
224
|
+
requestId,
|
|
225
|
+
streamSlotStart: 0
|
|
226
|
+
})
|
|
227
|
+
);
|
|
228
|
+
dispatch(setInstanceStatus({ conversationId, status: "running" }));
|
|
229
|
+
dispatch(setInstanceStatus({ conversationId, status: "streaming" }));
|
|
230
|
+
dispatch(setRequestStatus({ requestId, status: "streaming" }));
|
|
231
|
+
try {
|
|
232
|
+
await processStream({
|
|
233
|
+
requestId,
|
|
234
|
+
conversationId,
|
|
235
|
+
response: hostTurnBody(hostTurnResponse(turn), controller.signal),
|
|
236
|
+
submitAt: performance.now(),
|
|
237
|
+
conversationIdAt: null,
|
|
238
|
+
dispatch,
|
|
239
|
+
getState,
|
|
240
|
+
userMessageClientTempId,
|
|
241
|
+
// The host's events may name its own conversation id (a CLI session id); everything
|
|
242
|
+
// lands on the bound conversation.
|
|
243
|
+
forceLocalConversationId: true
|
|
244
|
+
});
|
|
245
|
+
} catch (error) {
|
|
246
|
+
dispatch(
|
|
247
|
+
setRequestStatus({
|
|
248
|
+
requestId,
|
|
249
|
+
status: "error",
|
|
250
|
+
error: {
|
|
251
|
+
error_type: "client_error",
|
|
252
|
+
message: error instanceof Error ? error.message : String(error)
|
|
253
|
+
}
|
|
254
|
+
})
|
|
255
|
+
);
|
|
256
|
+
dispatch(setInstanceStatus({ conversationId, status: "error" }));
|
|
257
|
+
} finally {
|
|
258
|
+
if (liveTurn.get(conversationId)?.controller === controller) liveTurn.delete(conversationId);
|
|
259
|
+
unregisterAbortController(conversationId, controller);
|
|
260
|
+
if (controller.signal.aborted) {
|
|
261
|
+
dispatch(setInstanceStatus({ conversationId, status: "cancelled" }));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function dropLastOptimisticUser(dispatch, getState, conversationId, text) {
|
|
266
|
+
const entry = getState().messages.byConversationId[conversationId];
|
|
267
|
+
if (!entry) return;
|
|
268
|
+
for (let i = entry.orderedIds.length - 1; i >= 0; i -= 1) {
|
|
269
|
+
const record = entry.byId[entry.orderedIds[i]];
|
|
270
|
+
if (record?.role !== "user" || record._clientStatus !== "pending") continue;
|
|
271
|
+
const parts = record.content;
|
|
272
|
+
if (Array.isArray(parts) && parts.some((p) => p?.type === "text" && p.text === text)) {
|
|
273
|
+
dispatch(removeMessage({ conversationId, messageId: record.id }));
|
|
274
|
+
}
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
function addUserMessage(dispatch, getState, conversationId, content, requestId) {
|
|
279
|
+
const clientTempId = mintClientTempId("user", uuidv4());
|
|
280
|
+
dispatch(
|
|
281
|
+
addOptimisticUserMessage({
|
|
282
|
+
conversationId,
|
|
283
|
+
clientTempId,
|
|
284
|
+
content,
|
|
285
|
+
position: selectNextMessagePosition(conversationId)(getState()),
|
|
286
|
+
...requestId ? { requestId } : {}
|
|
287
|
+
})
|
|
288
|
+
);
|
|
289
|
+
return clientTempId;
|
|
290
|
+
}
|
|
291
|
+
async function sendToHost(dispatch, getState, conversationId, text, mode) {
|
|
292
|
+
const source = getHostSource(conversationId);
|
|
293
|
+
if (!source?.send) throw new Error("This chat is read-only here.");
|
|
294
|
+
const controller = new AbortController();
|
|
295
|
+
const shown = mode === "send";
|
|
296
|
+
let shownId = null;
|
|
297
|
+
if (shown) {
|
|
298
|
+
shownId = addUserMessage(dispatch, getState, conversationId, [{ type: "text", text }], void 0);
|
|
299
|
+
localEcho.set(conversationId, (localEcho.get(conversationId) ?? 0) + 1);
|
|
300
|
+
}
|
|
301
|
+
let turn;
|
|
302
|
+
try {
|
|
303
|
+
turn = await source.send({ conversationId, text, mode }, controller.signal);
|
|
304
|
+
} catch (error) {
|
|
305
|
+
if (shown) {
|
|
306
|
+
const left = (localEcho.get(conversationId) ?? 1) - 1;
|
|
307
|
+
if (left > 0) localEcho.set(conversationId, left);
|
|
308
|
+
else localEcho.delete(conversationId);
|
|
309
|
+
dropLastOptimisticUser(dispatch, getState, conversationId, text);
|
|
310
|
+
}
|
|
311
|
+
throw error;
|
|
312
|
+
}
|
|
313
|
+
if (shownId) settleUserMessage(dispatch, conversationId, shownId);
|
|
314
|
+
if (turn) await runHostTurn(dispatch, getState, conversationId, turn);
|
|
315
|
+
}
|
|
316
|
+
function settleUserMessage(dispatch, conversationId, messageId) {
|
|
317
|
+
dispatch(
|
|
318
|
+
updateMessageRecord({ conversationId, messageId, patch: { _clientStatus: "complete" } })
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
async function stopHostTurn(conversationId) {
|
|
322
|
+
const source = getHostSource(conversationId);
|
|
323
|
+
const live = liveTurn.get(conversationId);
|
|
324
|
+
try {
|
|
325
|
+
await source?.stop?.(conversationId, live?.requestId ?? null);
|
|
326
|
+
} finally {
|
|
327
|
+
live?.controller.abort();
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
async function answerHostAsk(conversationId, askId, value) {
|
|
331
|
+
const source = getHostSource(conversationId);
|
|
332
|
+
if (!source?.answer) throw new Error("Answers are not taken here.");
|
|
333
|
+
await source.answer(conversationId, askId, value);
|
|
334
|
+
}
|
|
335
|
+
function bindHostConversation(dispatch, getState, args) {
|
|
336
|
+
const { conversationId, source, database, surfaceKey } = args;
|
|
337
|
+
registerHostSource(conversationId, source);
|
|
338
|
+
if (!getState().conversations.byConversationId[conversationId]) {
|
|
339
|
+
dispatch(
|
|
340
|
+
createInstanceFull({
|
|
341
|
+
conversationId,
|
|
342
|
+
agentId: "",
|
|
343
|
+
agentType: "user",
|
|
344
|
+
origin: "manual",
|
|
345
|
+
...surfaceKey ? { surfaceKey } : {},
|
|
346
|
+
overrides: {},
|
|
347
|
+
inputCapabilities: { base: {} },
|
|
348
|
+
variables: {},
|
|
349
|
+
userInput: {},
|
|
350
|
+
clientTools: {},
|
|
351
|
+
uiState: {},
|
|
352
|
+
messages: { apiEndpointMode: "host" }
|
|
353
|
+
})
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
dispatch(
|
|
357
|
+
hostConversationBound({
|
|
358
|
+
conversationId,
|
|
359
|
+
entry: {
|
|
360
|
+
sourceId: source.id,
|
|
361
|
+
whileBusy: source.whileBusy,
|
|
362
|
+
persistence: source.persistence,
|
|
363
|
+
held: null,
|
|
364
|
+
unavailable: null,
|
|
365
|
+
database,
|
|
366
|
+
canSend: typeof source.send === "function",
|
|
367
|
+
canStop: typeof source.stop === "function",
|
|
368
|
+
canRetry: typeof source.retry === "function",
|
|
369
|
+
canAnswer: typeof source.answer === "function",
|
|
370
|
+
hasConversationList: Boolean(source.conversations)
|
|
371
|
+
}
|
|
372
|
+
})
|
|
373
|
+
);
|
|
374
|
+
const unsubscribe = source.subscribe(conversationId, {
|
|
375
|
+
turn: (turn) => {
|
|
376
|
+
if (getHostSource(conversationId) !== source) return;
|
|
377
|
+
void runHostTurn(dispatch, getState, conversationId, turn);
|
|
378
|
+
},
|
|
379
|
+
history: () => {
|
|
380
|
+
if (getHostSource(conversationId) !== source) return;
|
|
381
|
+
void loadHostHistory(dispatch, getState, conversationId);
|
|
382
|
+
},
|
|
383
|
+
held: (reason) => {
|
|
384
|
+
if (getHostSource(conversationId) !== source) return;
|
|
385
|
+
dispatch(hostConversationHeld({ conversationId, reason }));
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
void loadHostHistory(dispatch, getState, conversationId);
|
|
389
|
+
return () => {
|
|
390
|
+
unsubscribe();
|
|
391
|
+
if (getHostSource(conversationId) === source) {
|
|
392
|
+
liveTurn.get(conversationId)?.controller.abort();
|
|
393
|
+
unregisterHostSource(conversationId, source);
|
|
394
|
+
dispatch(hostConversationUnbound(conversationId));
|
|
395
|
+
localEcho.delete(conversationId);
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
function hostConversationOf(state, conversationId) {
|
|
400
|
+
return selectHostConversation(conversationId)(state);
|
|
401
|
+
}
|
|
402
|
+
export {
|
|
403
|
+
answerHostAsk,
|
|
404
|
+
bindHostConversation,
|
|
405
|
+
hostConversationOf,
|
|
406
|
+
hostRecordToMessageRecord,
|
|
407
|
+
hostToolCallToRecord,
|
|
408
|
+
loadHostHistory,
|
|
409
|
+
runHostTurn,
|
|
410
|
+
sendToHost,
|
|
411
|
+
stopHostTurn
|
|
412
|
+
};
|