@ai-matrx/chat 0.3.33 → 0.4.2
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 +46 -0
- package/dist/agents/addressing/useAgentHref.js +4 -1
- package/dist/agents/api/submit-tool-results.js +11 -1
- package/dist/agents/components/ambient-assistant/intelligence-places.js +2 -2
- package/dist/agents/components/chat/intelligence-places.js +7 -7
- package/dist/agents/components/chat/useCanvasScopedToConversation.js +1 -1
- package/dist/agents/components/inputs/smart-input/RunToolPicker.js +7 -13
- package/dist/agents/components/inputs/smart-input/composer/ComposerAgentPill.js +3 -2
- package/dist/agents/components/inputs/smart-input/composer/useComposerAgent.js +5 -5
- package/dist/agents/components/inputs/smart-input/composer/useComposerAgentFilter.js +3 -2
- package/dist/agents/components/messages-display/AgentConversationDisplay.js +4 -1
- package/dist/agents/components/run-controls/RunConfigOverrides.js +10 -16
- package/dist/agents/components/run-controls/panels/shared.d.ts +1 -1
- package/dist/agents/components/shared/AgentConversationColumn.js +3 -2
- package/dist/agents/components/working-document/workingDocumentSurface.d.ts +1 -1
- package/dist/agents/hooks/useAgentModelLabel.js +4 -3
- package/dist/agents/hooks/useDiffEnrichment.js +3 -5
- package/dist/agents/hooks/useModelControls.d.ts +5 -161
- package/dist/agents/identity/model-catalog.d.ts +37 -0
- package/dist/agents/identity/model-catalog.js +105 -0
- package/dist/agents/redux/agent-definition/selectors.d.ts +237 -237
- package/dist/agents/redux/agent-definition/thunks.d.ts +1 -1
- package/dist/agents/redux/agent-settings/agentSettingsSlice.d.ts +1 -1
- package/dist/agents/redux/agent-settings/agentSettingsSlice.js +4 -6
- package/dist/agents/redux/agent-settings/selectors.d.ts +13 -152
- package/dist/agents/redux/agent-settings/selectors.js +0 -39
- package/dist/agents/redux/agent-settings/useNormalizedControls.d.ts +8 -0
- package/dist/agents/redux/agent-settings/useNormalizedControls.js +24 -0
- package/dist/agents/redux/agent-shortcut-categories/selectors.d.ts +50 -50
- package/dist/agents/redux/agent-shortcuts/selectors.d.ts +147 -147
- package/dist/agents/redux/conversation-history/selectors.d.ts +16 -16
- package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +2 -2
- package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +54 -54
- package/dist/agents/redux/execution-system/context-state/context-state.selectors.d.ts +14 -14
- package/dist/agents/redux/execution-system/conversations/conversations.selectors.d.ts +5 -5
- 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 +50 -0
- package/dist/agents/redux/execution-system/host-conversations/host-conversation.thunks.js +367 -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/instance-context/instance-context.selectors.d.ts +3 -3
- 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 -8
- package/dist/agents/redux/execution-system/instance-ui-state/instance-ui-state.selectors.d.ts +5 -5
- 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 -7
- package/dist/agents/redux/execution-system/messages/messages.selectors.d.ts +1 -1
- package/dist/agents/redux/execution-system/observability/observability.selectors.d.ts +7 -7
- package/dist/agents/redux/execution-system/observational-memory/observational-memory.selectors.d.ts +1 -1
- package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +14 -14
- package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.js +2 -1
- package/dist/agents/redux/execution-system/thunks/execute-manual-instance.thunk.js +4 -3
- 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 +5 -3
- 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/continuation-body.d.ts +1 -0
- package/dist/agents/redux/execution-system/utils/continuation-body.js +2 -1
- package/dist/agents/redux/model-registry.d.ts +6 -4
- package/dist/agents/redux/model-registry.js +23 -5
- package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +1 -1
- package/dist/agents/redux/tools/tools.selectors.d.ts +1 -1
- 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/generation-job.js +4 -7
- package/dist/agents/runtime/get-model-capabilities.js +3 -3
- package/dist/agents/types/instance.types.d.ts +2 -1
- package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +2 -2
- package/dist/cx-chat/components/SsrSidebarChats.js +1 -1
- package/dist/cx-chat/components/sidebar/SidebarUserFooter.js +1 -1
- 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 +44 -0
- package/dist/host/configure.d.ts +9 -1
- package/dist/host/configure.js +44 -8
- package/dist/host/content-ir-slots.d.ts +5 -1
- package/dist/host/content-ir-slots.js +5 -1
- package/dist/host/contract.d.ts +39 -2
- package/dist/host/db-types.d.ts +375 -10
- 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/workspace-gate.d.ts +16 -0
- package/dist/host/defaults/workspace-gate.js +88 -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 +5 -2
- package/dist/host/index.js +21 -1
- 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 +25 -2
- package/dist/host/registered-source.js +2 -2
- package/dist/host/source.d.ts +109 -0
- package/dist/host/source.js +86 -0
- package/dist/host/ui-slots.d.ts +8 -8
- package/dist/host/ui-slots.js +5 -3
- package/dist/mandates/useMandate.js +13 -0
- package/dist/public-chat/components/PublicMessageOptionsMenu.js +1 -1
- package/dist/store/create-chat-store.d.ts +4 -4
- package/dist/store/middlewares.d.ts +5 -5
- package/dist/store/slices.d.ts +1 -1
- package/dist/store/slices.js +4 -3
- package/dist/surfaces/redux/selectors.d.ts +2 -2
- package/dist/testing/turn-harness.d.ts +35 -0
- package/dist/testing/turn-harness.js +85 -0
- package/dist/tool-call-visualization/intelligence-places.js +1 -1
- package/dist/tool-call-visualization/redux/selectors.d.ts +1 -1
- package/dist/voice-agent/intelligence-places.js +6 -6
- package/package.json +9 -6
- package/dist/agents/model-registry/modelRegistrySlice.d.ts +0 -691
- package/dist/agents/model-registry/modelRegistrySlice.js +0 -574
- package/dist/host/model-class.d.ts +0 -33
- package/dist/host/model-class.js +0 -21
|
@@ -51,8 +51,8 @@ export declare const selectContextState: (conversationId: string) => ((state: {
|
|
|
51
51
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
52
52
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
53
53
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
54
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
55
54
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
55
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
56
56
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
57
57
|
clearCache: () => void;
|
|
58
58
|
resultsCount: () => number;
|
|
@@ -122,8 +122,8 @@ export declare const selectEstimatedTokens: (conversationId: string) => ((state:
|
|
|
122
122
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
123
123
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
124
124
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
125
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
126
125
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
126
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
127
127
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => number) & {
|
|
128
128
|
clearCache: () => void;
|
|
129
129
|
resultsCount: () => number;
|
|
@@ -178,8 +178,8 @@ export declare const selectEstimatedTokens: (conversationId: string) => ((state:
|
|
|
178
178
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
179
179
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
180
180
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
181
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
182
181
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
182
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
183
183
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
184
184
|
clearCache: () => void;
|
|
185
185
|
resultsCount: () => number;
|
|
@@ -255,8 +255,8 @@ export declare const selectContextFillRatio: (conversationId: string, windowToke
|
|
|
255
255
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
256
256
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
257
257
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
258
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
259
258
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
259
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
260
260
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => number) & {
|
|
261
261
|
clearCache: () => void;
|
|
262
262
|
resultsCount: () => number;
|
|
@@ -311,8 +311,8 @@ export declare const selectContextFillRatio: (conversationId: string, windowToke
|
|
|
311
311
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
312
312
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
313
313
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
314
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
315
314
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
315
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
316
316
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => number) & {
|
|
317
317
|
clearCache: () => void;
|
|
318
318
|
resultsCount: () => number;
|
|
@@ -367,8 +367,8 @@ export declare const selectContextFillRatio: (conversationId: string, windowToke
|
|
|
367
367
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
368
368
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
369
369
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
370
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
371
370
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
371
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
372
372
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
373
373
|
clearCache: () => void;
|
|
374
374
|
resultsCount: () => number;
|
|
@@ -449,8 +449,8 @@ export declare const selectCacheLikelyAlive: (conversationId: string) => ((state
|
|
|
449
449
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
450
450
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
451
451
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
452
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
453
452
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
453
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
454
454
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => boolean) & {
|
|
455
455
|
clearCache: () => void;
|
|
456
456
|
resultsCount: () => number;
|
|
@@ -505,8 +505,8 @@ export declare const selectCacheLikelyAlive: (conversationId: string) => ((state
|
|
|
505
505
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
506
506
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
507
507
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
508
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
509
508
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
509
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
510
510
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
511
511
|
clearCache: () => void;
|
|
512
512
|
resultsCount: () => number;
|
|
@@ -579,8 +579,8 @@ export declare const selectCacheSecondsRemaining: (conversationId: string) => ((
|
|
|
579
579
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
580
580
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
581
581
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
582
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
583
582
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
583
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
584
584
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => number) & {
|
|
585
585
|
clearCache: () => void;
|
|
586
586
|
resultsCount: () => number;
|
|
@@ -635,8 +635,8 @@ export declare const selectCacheSecondsRemaining: (conversationId: string) => ((
|
|
|
635
635
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
636
636
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
637
637
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
638
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
639
638
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
639
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
640
640
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
641
641
|
clearCache: () => void;
|
|
642
642
|
resultsCount: () => number;
|
|
@@ -708,8 +708,8 @@ export declare const selectLastTrimSummary: (conversationId: string) => ((state:
|
|
|
708
708
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
709
709
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
710
710
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
711
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
712
711
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
712
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
713
713
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => import("./context-state.slice.js").TrimSummary | null) & {
|
|
714
714
|
clearCache: () => void;
|
|
715
715
|
resultsCount: () => number;
|
|
@@ -764,8 +764,8 @@ export declare const selectLastTrimSummary: (conversationId: string) => ((state:
|
|
|
764
764
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
765
765
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
766
766
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
767
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
768
767
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
768
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
769
769
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
770
770
|
clearCache: () => void;
|
|
771
771
|
resultsCount: () => number;
|
|
@@ -837,8 +837,8 @@ export declare const selectLastRawUsage: (conversationId: string) => ((state: {
|
|
|
837
837
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
838
838
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
839
839
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
840
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
841
840
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
841
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
842
842
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => Record<string, unknown> | null) & {
|
|
843
843
|
clearCache: () => void;
|
|
844
844
|
resultsCount: () => number;
|
|
@@ -893,8 +893,8 @@ export declare const selectLastRawUsage: (conversationId: string) => ((state: {
|
|
|
893
893
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
894
894
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
895
895
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
896
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
897
896
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
897
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
898
898
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
|
|
899
899
|
clearCache: () => void;
|
|
900
900
|
resultsCount: () => number;
|
|
@@ -48,8 +48,8 @@ export declare const selectConversationIdsByAgent: ((state: {
|
|
|
48
48
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
49
49
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
50
50
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
51
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
52
51
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
52
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
53
53
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => Record<string, string[]>) & {
|
|
54
54
|
clearCache: () => void;
|
|
55
55
|
resultsCount: () => number;
|
|
@@ -113,8 +113,8 @@ export declare const selectInstancesByAgent: (agentId: string) => ((state: {
|
|
|
113
113
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
114
114
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
115
115
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
116
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
117
116
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
117
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
118
118
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ExecutionInstance[]) & {
|
|
119
119
|
clearCache: () => void;
|
|
120
120
|
resultsCount: () => number;
|
|
@@ -183,8 +183,8 @@ export declare const selectConversationSurfaceOwnsOutput: ((state: {
|
|
|
183
183
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
184
184
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
185
185
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
186
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
187
186
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
187
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
188
188
|
} & import("../../../../store/root-state.js").ChatHostReadSlices, conversationId: string | null | undefined) => boolean) & {
|
|
189
189
|
clearCache: () => void;
|
|
190
190
|
resultsCount: () => number;
|
|
@@ -249,8 +249,8 @@ export declare const selectRunningInstances: ((state: {
|
|
|
249
249
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
250
250
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
251
251
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
252
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
253
252
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
253
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
254
254
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => ExecutionInstance[]) & {
|
|
255
255
|
clearCache: () => void;
|
|
256
256
|
resultsCount: () => number;
|
|
@@ -343,8 +343,8 @@ export declare const selectConversationScopeIds: (conversationId: string) => ((s
|
|
|
343
343
|
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
344
344
|
agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
|
|
345
345
|
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
346
|
-
modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
|
|
347
346
|
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
347
|
+
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
348
348
|
} & import("../../../../store/root-state.js").ChatHostReadSlices) => {
|
|
349
349
|
organizationId: string | null;
|
|
350
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,50 @@
|
|
|
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 HostTurn } from "../../../../host/source.js";
|
|
16
|
+
import { type MessageRecord } from "../messages/messages.slice.js";
|
|
17
|
+
type Dispatch = ChatDispatch;
|
|
18
|
+
type GetState = () => ChatRootState;
|
|
19
|
+
export declare function hostRecordToMessageRecord(conversationId: string, record: HostMessageRecord): MessageRecord;
|
|
20
|
+
/** Read (or re-read) the host's history into the store. The host's sentence on failure. */
|
|
21
|
+
export declare function loadHostHistory(dispatch: Dispatch, getState: GetState, conversationId: string, options?: {
|
|
22
|
+
older?: boolean;
|
|
23
|
+
}): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Run one host turn through the ONE stream parser. `user` is the person's message when the host
|
|
26
|
+
* started the turn; a turn this tab sent already shows it (no second copy).
|
|
27
|
+
*/
|
|
28
|
+
export declare function runHostTurn(dispatch: Dispatch, getState: GetState, conversationId: string, turn: HostTurn): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* The person's send on a host conversation. Resolves when the host accepted it (the turn then
|
|
31
|
+
* streams, here or through `sink.turn`); rejects with the host's refusal so the caller puts the
|
|
32
|
+
* words back in the box.
|
|
33
|
+
*/
|
|
34
|
+
export declare function sendToHost(dispatch: Dispatch, getState: GetState, conversationId: string, text: string, mode: "send" | "queue" | "steer"): Promise<void>;
|
|
35
|
+
/** Stop: the host ends its run; our read of the turn ends now either way. */
|
|
36
|
+
export declare function stopHostTurn(conversationId: string): Promise<void>;
|
|
37
|
+
export declare function answerHostAsk(conversationId: string, askId: string, value: unknown): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Bind a conversation to a host-owned source: the instance, the plain-data entry, the
|
|
40
|
+
* subscription, and the first history read. Returns the unbind.
|
|
41
|
+
*/
|
|
42
|
+
export declare function bindHostConversation(dispatch: Dispatch, getState: GetState, args: {
|
|
43
|
+
conversationId: string;
|
|
44
|
+
source: ChatMessageSource;
|
|
45
|
+
database: boolean;
|
|
46
|
+
surfaceKey?: string;
|
|
47
|
+
}): () => void;
|
|
48
|
+
/** For thunks that only hold state: is this conversation hosted (branch first, never reach a db). */
|
|
49
|
+
export declare function hostConversationOf(state: ChatRootState, conversationId: string): import("./host-conversations.slice.js").HostConversationEntry | null;
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,367 @@
|
|
|
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 { createInstanceFull } from "../create-instance-full.js";
|
|
7
|
+
import {
|
|
8
|
+
addOptimisticUserMessage,
|
|
9
|
+
hydrateMessages,
|
|
10
|
+
prependMessages,
|
|
11
|
+
removeMessage,
|
|
12
|
+
reserveMessage,
|
|
13
|
+
setMessagesHydrationFailure,
|
|
14
|
+
updateMessageRecord,
|
|
15
|
+
setOlderLoading
|
|
16
|
+
} from "../messages/messages.slice.js";
|
|
17
|
+
import { selectNextMessagePosition } from "../messages/messages.selectors.js";
|
|
18
|
+
import { createRequest, setRequestStatus } from "../active-requests/active-requests.slice.js";
|
|
19
|
+
import { setInstanceStatus } from "../conversations/conversations.slice.js";
|
|
20
|
+
import { processStream } from "../thunks/process-stream.js";
|
|
21
|
+
import {
|
|
22
|
+
registerAbortController,
|
|
23
|
+
unregisterAbortController
|
|
24
|
+
} from "../thunks/abort-registry.js";
|
|
25
|
+
import {
|
|
26
|
+
hostConversationBound,
|
|
27
|
+
hostConversationHeld,
|
|
28
|
+
hostConversationUnavailable,
|
|
29
|
+
hostConversationUnbound
|
|
30
|
+
} from "./host-conversations.slice.js";
|
|
31
|
+
import { getHostSource, registerHostSource, unregisterHostSource } from "./source-registry.js";
|
|
32
|
+
import { selectHostConversation } from "./host-conversations.selectors.js";
|
|
33
|
+
const localEcho = /* @__PURE__ */ new Map();
|
|
34
|
+
const liveTurn = /* @__PURE__ */ new Map();
|
|
35
|
+
function hostRecordToMessageRecord(conversationId, record) {
|
|
36
|
+
return {
|
|
37
|
+
id: record.id,
|
|
38
|
+
conversationId,
|
|
39
|
+
agentId: null,
|
|
40
|
+
role: record.role,
|
|
41
|
+
content: record.content,
|
|
42
|
+
contentHistory: null,
|
|
43
|
+
userContent: null,
|
|
44
|
+
position: record.position,
|
|
45
|
+
source: "host",
|
|
46
|
+
status: "active",
|
|
47
|
+
isVisibleToModel: true,
|
|
48
|
+
isVisibleToUser: true,
|
|
49
|
+
metadata: {},
|
|
50
|
+
createdAt: record.createdAt,
|
|
51
|
+
deletedAt: null,
|
|
52
|
+
error: record.error ? { type: record.error.code ?? "host_error", message: record.error.message } : null
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function applyHistory(dispatch, conversationId, page, older) {
|
|
56
|
+
const records = page.records.map((r) => hostRecordToMessageRecord(conversationId, r));
|
|
57
|
+
const oldestPosition = records.reduce(
|
|
58
|
+
(min, r) => min === null || r.position < min ? r.position : min,
|
|
59
|
+
null
|
|
60
|
+
);
|
|
61
|
+
const pagination = { oldestPosition, hasMoreOlder: page.hasMoreOlder };
|
|
62
|
+
if (older) dispatch(prependMessages({ conversationId, messages: records, pagination }));
|
|
63
|
+
else dispatch(hydrateMessages({ conversationId, messages: records, pagination }));
|
|
64
|
+
dispatch(hostConversationUnavailable({ conversationId, reason: page.unavailable ?? null }));
|
|
65
|
+
dispatch(
|
|
66
|
+
setMessagesHydrationFailure({
|
|
67
|
+
conversationId,
|
|
68
|
+
failure: page.unavailable && records.length === 0 ? page.unavailable : null
|
|
69
|
+
})
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
async function loadHostHistory(dispatch, getState, conversationId, options = {}) {
|
|
73
|
+
const source = getHostSource(conversationId);
|
|
74
|
+
if (!source) return;
|
|
75
|
+
const entry = getState().messages.byConversationId[conversationId];
|
|
76
|
+
if (options.older) {
|
|
77
|
+
if (!entry?.hasMoreOlder || entry.isLoadingOlder) return;
|
|
78
|
+
dispatch(setOlderLoading({ conversationId, loading: true }));
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const page = await source.load(
|
|
82
|
+
conversationId,
|
|
83
|
+
options.older ? { before: entry?.oldestPosition ?? null } : void 0
|
|
84
|
+
);
|
|
85
|
+
if (getHostSource(conversationId) !== source) return;
|
|
86
|
+
applyHistory(dispatch, conversationId, page, Boolean(options.older));
|
|
87
|
+
} catch (error) {
|
|
88
|
+
const reason = error instanceof Error && error.message ? error.message : "This chat's history could not be read.";
|
|
89
|
+
dispatch(setMessagesHydrationFailure({ conversationId, failure: reason }));
|
|
90
|
+
dispatch(hostConversationUnavailable({ conversationId, reason }));
|
|
91
|
+
} finally {
|
|
92
|
+
if (options.older) dispatch(setOlderLoading({ conversationId, loading: false }));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const DROPPED_EVENTS = /* @__PURE__ */ new Set(["record_reserved", "record_update"]);
|
|
96
|
+
const DROPPED_TABLES = /* @__PURE__ */ new Set(["message", "cx_message", "conversation", "cx_conversation"]);
|
|
97
|
+
function hostTurnBody(response, signal) {
|
|
98
|
+
const body = response.body;
|
|
99
|
+
if (!body) return response;
|
|
100
|
+
const reader = body.getReader();
|
|
101
|
+
const decoder = new TextDecoder();
|
|
102
|
+
const encoder = new TextEncoder();
|
|
103
|
+
let carry = "";
|
|
104
|
+
const keep = (line) => {
|
|
105
|
+
if (!line.trim()) return false;
|
|
106
|
+
try {
|
|
107
|
+
const frame = JSON.parse(line);
|
|
108
|
+
return !(typeof frame.event === "string" && DROPPED_EVENTS.has(frame.event) && typeof frame.data?.table === "string" && DROPPED_TABLES.has(frame.data.table));
|
|
109
|
+
} catch {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
const stream = new ReadableStream({
|
|
114
|
+
start(controller) {
|
|
115
|
+
signal.addEventListener("abort", () => {
|
|
116
|
+
try {
|
|
117
|
+
controller.close();
|
|
118
|
+
} catch {
|
|
119
|
+
}
|
|
120
|
+
void reader.cancel().catch(() => {
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
async pull(controller) {
|
|
125
|
+
for (; ; ) {
|
|
126
|
+
if (signal.aborted) return;
|
|
127
|
+
let chunk;
|
|
128
|
+
try {
|
|
129
|
+
chunk = await reader.read();
|
|
130
|
+
} catch (error) {
|
|
131
|
+
if (!signal.aborted) controller.error(error);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (signal.aborted) return;
|
|
135
|
+
if (chunk.done) {
|
|
136
|
+
if (keep(carry)) controller.enqueue(encoder.encode(`${carry}
|
|
137
|
+
`));
|
|
138
|
+
carry = "";
|
|
139
|
+
controller.close();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const lines = (carry + decoder.decode(chunk.value, { stream: true })).split("\n");
|
|
143
|
+
carry = lines.pop() ?? "";
|
|
144
|
+
const kept = lines.filter(keep);
|
|
145
|
+
if (kept.length > 0) {
|
|
146
|
+
controller.enqueue(encoder.encode(`${kept.join("\n")}
|
|
147
|
+
`));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
cancel() {
|
|
153
|
+
void reader.cancel().catch(() => {
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
return new Response(stream, { status: response.status, headers: response.headers });
|
|
158
|
+
}
|
|
159
|
+
async function runHostTurn(dispatch, getState, conversationId, turn) {
|
|
160
|
+
const { requestId } = turn;
|
|
161
|
+
let userMessageClientTempId;
|
|
162
|
+
const echoes = localEcho.get(conversationId) ?? 0;
|
|
163
|
+
if (echoes > 0) {
|
|
164
|
+
if (echoes === 1) localEcho.delete(conversationId);
|
|
165
|
+
else localEcho.set(conversationId, echoes - 1);
|
|
166
|
+
} else if (turn.user && turn.user.length > 0) {
|
|
167
|
+
userMessageClientTempId = addUserMessage(dispatch, getState, conversationId, turn.user, requestId);
|
|
168
|
+
settleUserMessage(dispatch, conversationId, userMessageClientTempId);
|
|
169
|
+
}
|
|
170
|
+
const controller = new AbortController();
|
|
171
|
+
liveTurn.set(conversationId, { requestId, controller });
|
|
172
|
+
registerAbortController(conversationId, controller);
|
|
173
|
+
dispatch(createRequest({ requestId, conversationId }));
|
|
174
|
+
dispatch(
|
|
175
|
+
reserveMessage({
|
|
176
|
+
conversationId,
|
|
177
|
+
messageId: mintClientTempId("assistant", requestId),
|
|
178
|
+
role: "assistant",
|
|
179
|
+
position: selectNextMessagePosition(conversationId)(getState()),
|
|
180
|
+
requestId,
|
|
181
|
+
streamSlotStart: 0
|
|
182
|
+
})
|
|
183
|
+
);
|
|
184
|
+
dispatch(setInstanceStatus({ conversationId, status: "running" }));
|
|
185
|
+
dispatch(setInstanceStatus({ conversationId, status: "streaming" }));
|
|
186
|
+
dispatch(setRequestStatus({ requestId, status: "streaming" }));
|
|
187
|
+
try {
|
|
188
|
+
await processStream({
|
|
189
|
+
requestId,
|
|
190
|
+
conversationId,
|
|
191
|
+
response: hostTurnBody(hostTurnResponse(turn), controller.signal),
|
|
192
|
+
submitAt: performance.now(),
|
|
193
|
+
conversationIdAt: null,
|
|
194
|
+
dispatch,
|
|
195
|
+
getState,
|
|
196
|
+
userMessageClientTempId,
|
|
197
|
+
// The host's events may name its own conversation id (a CLI session id); everything
|
|
198
|
+
// lands on the bound conversation.
|
|
199
|
+
forceLocalConversationId: true
|
|
200
|
+
});
|
|
201
|
+
} catch (error) {
|
|
202
|
+
dispatch(
|
|
203
|
+
setRequestStatus({
|
|
204
|
+
requestId,
|
|
205
|
+
status: "error",
|
|
206
|
+
error: {
|
|
207
|
+
error_type: "client_error",
|
|
208
|
+
message: error instanceof Error ? error.message : String(error)
|
|
209
|
+
}
|
|
210
|
+
})
|
|
211
|
+
);
|
|
212
|
+
dispatch(setInstanceStatus({ conversationId, status: "error" }));
|
|
213
|
+
} finally {
|
|
214
|
+
if (liveTurn.get(conversationId)?.controller === controller) liveTurn.delete(conversationId);
|
|
215
|
+
unregisterAbortController(conversationId, controller);
|
|
216
|
+
if (controller.signal.aborted) {
|
|
217
|
+
dispatch(setInstanceStatus({ conversationId, status: "cancelled" }));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function dropLastOptimisticUser(dispatch, getState, conversationId, text) {
|
|
222
|
+
const entry = getState().messages.byConversationId[conversationId];
|
|
223
|
+
if (!entry) return;
|
|
224
|
+
for (let i = entry.orderedIds.length - 1; i >= 0; i -= 1) {
|
|
225
|
+
const record = entry.byId[entry.orderedIds[i]];
|
|
226
|
+
if (record?.role !== "user" || record._clientStatus !== "pending") continue;
|
|
227
|
+
const parts = record.content;
|
|
228
|
+
if (Array.isArray(parts) && parts.some((p) => p?.type === "text" && p.text === text)) {
|
|
229
|
+
dispatch(removeMessage({ conversationId, messageId: record.id }));
|
|
230
|
+
}
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function addUserMessage(dispatch, getState, conversationId, content, requestId) {
|
|
235
|
+
const clientTempId = mintClientTempId("user", uuidv4());
|
|
236
|
+
dispatch(
|
|
237
|
+
addOptimisticUserMessage({
|
|
238
|
+
conversationId,
|
|
239
|
+
clientTempId,
|
|
240
|
+
content,
|
|
241
|
+
position: selectNextMessagePosition(conversationId)(getState()),
|
|
242
|
+
...requestId ? { requestId } : {}
|
|
243
|
+
})
|
|
244
|
+
);
|
|
245
|
+
return clientTempId;
|
|
246
|
+
}
|
|
247
|
+
async function sendToHost(dispatch, getState, conversationId, text, mode) {
|
|
248
|
+
const source = getHostSource(conversationId);
|
|
249
|
+
if (!source?.send) throw new Error("This chat is read-only here.");
|
|
250
|
+
const controller = new AbortController();
|
|
251
|
+
const shown = mode === "send";
|
|
252
|
+
let shownId = null;
|
|
253
|
+
if (shown) {
|
|
254
|
+
shownId = addUserMessage(dispatch, getState, conversationId, [{ type: "text", text }], void 0);
|
|
255
|
+
localEcho.set(conversationId, (localEcho.get(conversationId) ?? 0) + 1);
|
|
256
|
+
}
|
|
257
|
+
let turn;
|
|
258
|
+
try {
|
|
259
|
+
turn = await source.send({ conversationId, text, mode }, controller.signal);
|
|
260
|
+
} catch (error) {
|
|
261
|
+
if (shown) {
|
|
262
|
+
const left = (localEcho.get(conversationId) ?? 1) - 1;
|
|
263
|
+
if (left > 0) localEcho.set(conversationId, left);
|
|
264
|
+
else localEcho.delete(conversationId);
|
|
265
|
+
dropLastOptimisticUser(dispatch, getState, conversationId, text);
|
|
266
|
+
}
|
|
267
|
+
throw error;
|
|
268
|
+
}
|
|
269
|
+
if (shownId) settleUserMessage(dispatch, conversationId, shownId);
|
|
270
|
+
if (turn) await runHostTurn(dispatch, getState, conversationId, turn);
|
|
271
|
+
}
|
|
272
|
+
function settleUserMessage(dispatch, conversationId, messageId) {
|
|
273
|
+
dispatch(
|
|
274
|
+
updateMessageRecord({ conversationId, messageId, patch: { _clientStatus: "complete" } })
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
async function stopHostTurn(conversationId) {
|
|
278
|
+
const source = getHostSource(conversationId);
|
|
279
|
+
const live = liveTurn.get(conversationId);
|
|
280
|
+
try {
|
|
281
|
+
await source?.stop?.(conversationId, live?.requestId ?? null);
|
|
282
|
+
} finally {
|
|
283
|
+
live?.controller.abort();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
async function answerHostAsk(conversationId, askId, value) {
|
|
287
|
+
const source = getHostSource(conversationId);
|
|
288
|
+
if (!source?.answer) throw new Error("Answers are not taken here.");
|
|
289
|
+
await source.answer(conversationId, askId, value);
|
|
290
|
+
}
|
|
291
|
+
function bindHostConversation(dispatch, getState, args) {
|
|
292
|
+
const { conversationId, source, database, surfaceKey } = args;
|
|
293
|
+
registerHostSource(conversationId, source);
|
|
294
|
+
if (!getState().conversations.byConversationId[conversationId]) {
|
|
295
|
+
dispatch(
|
|
296
|
+
createInstanceFull({
|
|
297
|
+
conversationId,
|
|
298
|
+
agentId: "",
|
|
299
|
+
agentType: "user",
|
|
300
|
+
origin: "manual",
|
|
301
|
+
...surfaceKey ? { surfaceKey } : {},
|
|
302
|
+
overrides: {},
|
|
303
|
+
inputCapabilities: { base: {} },
|
|
304
|
+
variables: {},
|
|
305
|
+
userInput: {},
|
|
306
|
+
clientTools: {},
|
|
307
|
+
uiState: {},
|
|
308
|
+
messages: { apiEndpointMode: "host" }
|
|
309
|
+
})
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
dispatch(
|
|
313
|
+
hostConversationBound({
|
|
314
|
+
conversationId,
|
|
315
|
+
entry: {
|
|
316
|
+
sourceId: source.id,
|
|
317
|
+
whileBusy: source.whileBusy,
|
|
318
|
+
persistence: source.persistence,
|
|
319
|
+
held: null,
|
|
320
|
+
unavailable: null,
|
|
321
|
+
database,
|
|
322
|
+
canSend: typeof source.send === "function",
|
|
323
|
+
canStop: typeof source.stop === "function",
|
|
324
|
+
canRetry: typeof source.retry === "function",
|
|
325
|
+
canAnswer: typeof source.answer === "function",
|
|
326
|
+
hasConversationList: Boolean(source.conversations)
|
|
327
|
+
}
|
|
328
|
+
})
|
|
329
|
+
);
|
|
330
|
+
const unsubscribe = source.subscribe(conversationId, {
|
|
331
|
+
turn: (turn) => {
|
|
332
|
+
if (getHostSource(conversationId) !== source) return;
|
|
333
|
+
void runHostTurn(dispatch, getState, conversationId, turn);
|
|
334
|
+
},
|
|
335
|
+
history: () => {
|
|
336
|
+
if (getHostSource(conversationId) !== source) return;
|
|
337
|
+
void loadHostHistory(dispatch, getState, conversationId);
|
|
338
|
+
},
|
|
339
|
+
held: (reason) => {
|
|
340
|
+
if (getHostSource(conversationId) !== source) return;
|
|
341
|
+
dispatch(hostConversationHeld({ conversationId, reason }));
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
void loadHostHistory(dispatch, getState, conversationId);
|
|
345
|
+
return () => {
|
|
346
|
+
unsubscribe();
|
|
347
|
+
if (getHostSource(conversationId) === source) {
|
|
348
|
+
liveTurn.get(conversationId)?.controller.abort();
|
|
349
|
+
unregisterHostSource(conversationId, source);
|
|
350
|
+
dispatch(hostConversationUnbound(conversationId));
|
|
351
|
+
localEcho.delete(conversationId);
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function hostConversationOf(state, conversationId) {
|
|
356
|
+
return selectHostConversation(conversationId)(state);
|
|
357
|
+
}
|
|
358
|
+
export {
|
|
359
|
+
answerHostAsk,
|
|
360
|
+
bindHostConversation,
|
|
361
|
+
hostConversationOf,
|
|
362
|
+
hostRecordToMessageRecord,
|
|
363
|
+
loadHostHistory,
|
|
364
|
+
runHostTurn,
|
|
365
|
+
sendToHost,
|
|
366
|
+
stopHostTurn
|
|
367
|
+
};
|