@ai-matrx/chat 0.6.6 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/README.md +1 -1
- package/dist/agents/components/agent-widgets/AgentChatHistorySidebar.js +16 -55
- package/dist/agents/components/chat/chat-door.d.ts +67 -0
- package/dist/agents/components/chat/chat-door.js +100 -0
- package/dist/agents/components/conversation-history/AgentConversationList.d.ts +83 -0
- package/dist/agents/components/conversation-history/AgentConversationList.js +252 -0
- package/dist/agents/components/conversation-history/ConversationArchiveSection.d.ts +5 -1
- package/dist/agents/components/conversation-history/ConversationArchiveSection.js +22 -4
- package/dist/agents/components/conversation-history/ConversationHistorySidebar.js +20 -65
- package/dist/agents/components/inputs/input-components/TextareaInput.js +2 -0
- package/dist/agents/components/inputs/input-components/VariableInputComponent.js +7 -6
- package/dist/agents/components/inputs/smart-input/ConversationCompanionPills.d.ts +3 -0
- package/dist/agents/components/inputs/smart-input/ConversationCompanionPills.js +40 -0
- package/dist/agents/components/inputs/smart-input/ConversationContextRail.js +6 -29
- package/dist/agents/components/inputs/smart-input/DeviceToolsModeRow.d.ts +3 -0
- package/dist/agents/components/inputs/smart-input/DeviceToolsModeRow.js +35 -0
- package/dist/agents/components/inputs/smart-input/InboxQueueStrip.js +0 -8
- package/dist/agents/components/inputs/smart-input/RunToolPicker.js +15 -11
- package/dist/agents/components/inputs/smart-input/composer/ComposerPlusMenu.js +22 -0
- package/dist/agents/components/inputs/smart-input/rail-pill.d.ts +35 -0
- package/dist/agents/components/inputs/smart-input/rail-pill.js +30 -0
- package/dist/agents/components/inputs/variable-input-variations/AgentVariableForm.js +52 -48
- package/dist/agents/components/run-controls/panels/shared.d.ts +1 -1
- package/dist/agents/components/shared/AgentModeController.js +3 -2
- package/dist/agents/components/shell/AgentRunSidebarMenu.js +15 -54
- package/dist/agents/components/working-document/documents-workspace/DocumentsListRail.js +1 -2
- package/dist/agents/engine.d.ts +15 -0
- package/dist/agents/engine.js +17 -0
- package/dist/agents/hooks/useModelControls.js +3 -175
- package/dist/agents/redux/agent-definition/selectors.d.ts +237 -237
- 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/thunks.js +6 -18
- package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +1 -73
- package/dist/agents/redux/conversation-list/conversation-list.selectors.js +2 -36
- package/dist/agents/redux/conversation-list/conversation-list.slice.d.ts +7 -22
- package/dist/agents/redux/conversation-list/conversation-list.slice.js +7 -62
- package/dist/agents/redux/conversation-list/conversation-list.thunks.d.ts +0 -25
- package/dist/agents/redux/conversation-list/conversation-list.thunks.js +2 -58
- package/dist/agents/redux/conversation-list/conversation-list.types.d.ts +0 -5
- package/dist/agents/redux/conversation-list/conversation-rows.d.ts +16 -0
- package/dist/agents/redux/conversation-list/conversation-rows.js +24 -0
- package/dist/agents/redux/conversation-list/conversation-trash.thunks.d.ts +1 -0
- package/dist/agents/redux/conversation-list/conversation-trash.thunks.js +13 -18
- 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/instance-context/instance-context.selectors.d.ts +3 -3
- 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-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/create-instance.thunk.d.ts +10 -1
- package/dist/agents/redux/execution-system/thunks/create-instance.thunk.js +114 -265
- package/dist/agents/redux/execution-system/thunks/dispatch-matrx-extend-tool.thunk.js +18 -2
- package/dist/agents/redux/execution-system/thunks/dispatch-surface-client-tool.thunk.js +10 -28
- package/dist/agents/redux/execution-system/thunks/dispatch-surface-write.thunk.js +10 -25
- package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.js +20 -0
- package/dist/agents/redux/execution-system/thunks/execute-manual-instance.thunk.js +6 -1
- package/dist/agents/redux/execution-system/thunks/notify-and-play-dispatcher.d.ts +58 -0
- package/dist/agents/redux/execution-system/thunks/notify-and-play-dispatcher.js +62 -0
- package/dist/agents/redux/execution-system/thunks/post-delegated-tool-outcome.d.ts +23 -0
- package/dist/agents/redux/execution-system/thunks/post-delegated-tool-outcome.js +37 -0
- package/dist/agents/redux/execution-system/thunks/resume-instance.thunk.js +10 -2
- package/dist/agents/redux/execution-system/utils/build-tool-injection.d.ts +7 -0
- package/dist/agents/redux/execution-system/utils/build-tool-injection.js +18 -6
- package/dist/agents/redux/execution-system/utils/host-turn.d.ts +45 -0
- package/dist/agents/redux/execution-system/utils/host-turn.js +119 -0
- package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +1 -1
- package/dist/agents/scribe-tools/dispatcher/dispatch-scribe-tool.thunk.d.ts +50 -20
- package/dist/agents/scribe-tools/dispatcher/dispatch-scribe-tool.thunk.js +9 -101
- package/dist/agents/types/tool-injection.types.d.ts +18 -2
- package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +2 -2
- package/dist/agents/ui-first-tools/redux/pending-asks.slice.d.ts +2 -1
- package/dist/agents/ui-first-tools/redux/resolve-asks-with-input.thunk.js +1 -1
- package/dist/agents/ui-first-tools/tools/ask-response.d.ts +29 -0
- package/dist/agents/ui-first-tools/tools/ask-response.js +15 -0
- package/dist/agents/ui-first-tools/tools/schemas.d.ts +3 -25
- package/dist/agents/ui-first-tools/tools/schemas.js +1 -12
- package/dist/agents/ui-first-tools/ui/ApprovalCard.js +1 -1
- package/dist/agents/ui-first-tools/ui/AskWizard.d.ts +1 -1
- package/dist/agents/ui-first-tools/ui/AskWizard.js +1 -1
- package/dist/cx-chat/_legacy-stubs.d.ts +5 -5
- package/dist/cx-chat/components/SsrSidebarChats.js +13 -15
- package/dist/cx-chat/components/messages/UserMessage.d.ts +2 -2
- package/dist/cx-chat/types/conversation.d.ts +6 -6
- package/dist/cx-chat/utils/buildContentBlocksForSave.d.ts +1 -1
- package/dist/cx-chat/utils/cx-content-converter.d.ts +1 -1
- package/dist/host/bare-host-chrome.js +9 -3
- package/dist/host/composer-extensions.d.ts +75 -0
- package/dist/host/composer-extensions.js +92 -0
- package/dist/host/configure.js +1 -0
- package/dist/host/contract.d.ts +105 -13
- package/dist/host/defaults/confirm.d.ts +15 -0
- package/dist/host/defaults/confirm.js +25 -0
- package/dist/host/defaults/files-ui.d.ts +85 -0
- package/dist/host/defaults/files-ui.js +158 -0
- package/dist/host/defaults/gates.d.ts +27 -0
- package/dist/host/defaults/gates.js +72 -0
- package/dist/host/defaults/media-client.d.ts +15 -0
- package/dist/host/defaults/media-client.js +40 -0
- package/dist/host/defaults/voice.d.ts +81 -0
- package/dist/host/defaults/voice.js +239 -0
- package/dist/host/device-tool-handoff.d.ts +26 -0
- package/dist/host/device-tool-handoff.js +45 -0
- package/dist/host/index.d.ts +1 -0
- package/dist/host/index.js +4 -1
- package/dist/host/microphone.d.ts +11 -0
- package/dist/host/microphone.js +17 -0
- package/dist/host/ui-slots.d.ts +29 -74
- package/dist/host/ui-slots.js +40 -42
- package/dist/store/create-chat-store.d.ts +2 -2
- package/dist/store/middlewares.d.ts +5 -5
- package/dist/store/slices.d.ts +1 -1
- package/dist/surfaces/redux/selectors.d.ts +2 -2
- package/dist/tool-call-visualization/components/ToolCallVisualization.js +3 -2
- package/dist/tool-call-visualization/configured-rows/ConfiguredRowRenderer.d.ts +15 -0
- package/dist/tool-call-visualization/configured-rows/ConfiguredRowRenderer.js +36 -0
- package/dist/tool-call-visualization/configured-rows/ConfiguredToolRow.d.ts +40 -0
- package/dist/tool-call-visualization/configured-rows/ConfiguredToolRow.js +296 -0
- package/dist/tool-call-visualization/configured-rows/CopyToolButton.d.ts +23 -0
- package/dist/tool-call-visualization/configured-rows/CopyToolButton.js +62 -0
- package/dist/tool-call-visualization/configured-rows/ToolProgressView.d.ts +23 -0
- package/dist/tool-call-visualization/configured-rows/ToolProgressView.js +147 -0
- package/dist/tool-call-visualization/configured-rows/field-components.d.ts +15 -0
- package/dist/tool-call-visualization/configured-rows/field-components.js +244 -0
- package/dist/tool-call-visualization/configured-rows/helpers.d.ts +39 -0
- package/dist/tool-call-visualization/configured-rows/helpers.js +110 -0
- package/dist/tool-call-visualization/configured-rows/register.d.ts +25 -0
- package/dist/tool-call-visualization/configured-rows/register.js +51 -0
- package/dist/tool-call-visualization/configured-rows/registries.d.ts +27 -0
- package/dist/tool-call-visualization/configured-rows/registries.js +14 -0
- package/dist/tool-call-visualization/configured-rows/to-row-entry.d.ts +8 -0
- package/dist/tool-call-visualization/configured-rows/to-row-entry.js +38 -0
- package/dist/tool-call-visualization/configured-rows/transforms.d.ts +14 -0
- package/dist/tool-call-visualization/configured-rows/transforms.js +30 -0
- package/dist/tool-call-visualization/configured-rows/types.d.ts +140 -0
- package/dist/tool-call-visualization/redux/selectors.d.ts +1 -1
- package/dist/tool-call-visualization/registry/registry.d.ts +1 -1
- package/dist/tool-call-visualization/registry/registry.js +8 -1
- package/dist/tool-call-visualization/types.d.ts +1 -1
- package/dist/ui/chat-protocol-types.d.ts +0 -1
- package/dist/ui/ownership.d.ts +25 -0
- package/dist/ui/ownership.js +18 -0
- package/dist/voice-agent/audio/audioCapture.js +11 -6
- package/dist/window-panels/windows/agents/AgentRunHistoryWindow.d.ts +1 -2
- package/dist/window-panels/windows/agents/AgentRunHistoryWindow.js +21 -181
- package/dist/window-panels/windows/agents/AgentRunWindow.js +26 -13
- package/package.json +4627 -125
- package/dist/agents/components/agent-widgets/chat-assistant/AssistantMessageCard.d.ts +0 -7
- package/dist/agents/components/agent-widgets/chat-assistant/AssistantMessageCard.js +0 -33
- package/dist/agents/components/agent-widgets/chat-assistant/StatusCard.d.ts +0 -6
- package/dist/agents/components/agent-widgets/chat-assistant/StatusCard.js +0 -21
- package/dist/agents/components/agent-widgets/chat-assistant/UserMessageCard.d.ts +0 -6
- package/dist/agents/components/agent-widgets/chat-assistant/UserMessageCard.js +0 -11
- package/dist/agents/components/agent-widgets/chat-assistant/VariableInputCard.d.ts +0 -12
- package/dist/agents/components/agent-widgets/chat-assistant/VariableInputCard.js +0 -7
- package/dist/agents/components/agent-widgets/execution-gates/PreExecutionCard.d.ts +0 -4
- package/dist/agents/components/agent-widgets/execution-gates/PreExecutionCard.js +0 -81
- package/dist/agents/components/run/run-sidebar/SidebarHeader.d.ts +0 -21
- package/dist/agents/components/run/run-sidebar/SidebarHeader.js +0 -50
- package/dist/agents/components/run-controls/AdvancedRunSettings/index.d.ts +0 -6
- package/dist/agents/components/run-controls/AdvancedRunSettings/index.js +0 -32
- package/dist/agents/components/run-controls/RunSettingsModal.d.ts +0 -5
- package/dist/agents/components/run-controls/RunSettingsModal.js +0 -22
- package/dist/agents/components/shell/AgentBuildSidebarExtras.d.ts +0 -6
- package/dist/agents/components/shell/AgentBuildSidebarExtras.js +0 -30
- package/dist/agents/constants/agent-system-competitors.d.ts +0 -9
- package/dist/agents/constants/agent-system-competitors.js +0 -125
- package/dist/agents/hooks/message-crud/useMessageActions.d.ts +0 -29
- package/dist/agents/hooks/message-crud/useMessageActions.js +0 -119
- package/dist/agents/hooks/useConversationPendingCalls.d.ts +0 -30
- package/dist/agents/hooks/useConversationPendingCalls.js +0 -42
- package/dist/agents/model-registry/model-classes.d.ts +0 -1
- package/dist/agents/model-registry/model-classes.js +0 -1
- package/dist/agents/redux/conversation-history/index.d.ts +0 -18
- package/dist/agents/redux/conversation-history/index.js +0 -4
- package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.thunks.d.ts +0 -38
- package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.thunks.js +0 -42
- package/dist/agents/redux/execution-system/message-crud/server/compact-turns.thunk.d.ts +0 -58
- package/dist/agents/redux/execution-system/message-crud/server/compact-turns.thunk.js +0 -50
- package/dist/agents/redux/execution-system/message-crud/server/fork-and-run-server.thunk.d.ts +0 -76
- package/dist/agents/redux/execution-system/message-crud/server/fork-and-run-server.thunk.js +0 -101
- package/dist/agents/redux/execution-system/thunks/attach-workflow-run.d.ts +0 -38
- package/dist/agents/redux/execution-system/thunks/attach-workflow-run.js +0 -25
- package/dist/agents/redux/execution-system/utils/source-slice-helpers.d.ts +0 -45
- package/dist/agents/redux/execution-system/utils/source-slice-helpers.js +0 -50
- package/dist/agents/runtime/realtime/launchRealtimeSession.thunk.d.ts +0 -25
- package/dist/agents/runtime/realtime/launchRealtimeSession.thunk.js +0 -15
- package/dist/agents/services/agentService.d.ts +0 -12
- package/dist/agents/services/agentService.js +0 -92
- package/dist/agents/utils/escape-code-fences.d.ts +0 -15
- package/dist/agents/utils/escape-code-fences.js +0 -9
- package/dist/agents/utils/normalize-managed-options.d.ts +0 -30
- package/dist/agents/utils/normalize-managed-options.js +0 -29
- package/dist/agents/utils/processedDocumentContext.d.ts +0 -51
- package/dist/agents/utils/processedDocumentContext.js +0 -51
- package/dist/agents/utils/variable-validation.d.ts +0 -28
- package/dist/agents/utils/variable-validation.js +0 -54
- package/dist/cx-chat/components/ChatConversationSkeleton.d.ts +0 -9
- package/dist/cx-chat/components/ChatConversationSkeleton.js +0 -45
- package/dist/cx-chat/components/ChatPanelBackButton.d.ts +0 -1
- package/dist/cx-chat/components/ChatPanelBackButton.js +0 -26
- package/dist/cx-chat/components/messages/MessageErrorBoundary.d.ts +0 -20
- package/dist/cx-chat/components/messages/MessageErrorBoundary.js +0 -40
- package/dist/cx-chat/components/variable-inputs/CheckboxGroupInput.d.ts +0 -14
- package/dist/cx-chat/components/variable-inputs/CheckboxGroupInput.js +0 -160
- package/dist/cx-chat/components/variable-inputs/NumberInput.d.ts +0 -15
- package/dist/cx-chat/components/variable-inputs/NumberInput.js +0 -79
- package/dist/cx-chat/components/variable-inputs/RadioGroupInput.d.ts +0 -14
- package/dist/cx-chat/components/variable-inputs/RadioGroupInput.js +0 -125
- package/dist/cx-chat/components/variable-inputs/SelectInput.d.ts +0 -14
- package/dist/cx-chat/components/variable-inputs/SelectInput.js +0 -92
- package/dist/cx-chat/components/variable-inputs/TextareaInput.d.ts +0 -14
- package/dist/cx-chat/components/variable-inputs/TextareaInput.js +0 -46
- package/dist/cx-chat/components/variable-inputs/ToggleInput.d.ts +0 -14
- package/dist/cx-chat/components/variable-inputs/ToggleInput.js +0 -46
- package/dist/cx-chat/hooks/useChatPersistence.d.ts +0 -28
- package/dist/cx-chat/hooks/useChatPersistence.js +0 -180
- package/dist/cx-chat/hooks/useInstanceBootstrap.d.ts +0 -1
- package/dist/cx-chat/hooks/useInstanceBootstrap.js +0 -115
- package/dist/cx-chat/types/content.d.ts +0 -184
- package/dist/cx-chat/types/content.js +0 -91
- package/dist/cx-chat/types/cx-tables.d.ts +0 -176
- package/dist/cx-chat/utils/settings-diff.d.ts +0 -13
- package/dist/cx-chat/utils/settings-diff.js +0 -25
- package/dist/public-chat/components/AgentSelector.d.ts +0 -22
- package/dist/public-chat/components/AgentSelector.js +0 -80
- package/dist/public-chat/components/GuidedVariableInputs.d.ts +0 -25
- package/dist/public-chat/components/GuidedVariableInputs.js +0 -623
- package/dist/public-chat/components/PublicVariableInputs.d.ts +0 -29
- package/dist/public-chat/components/PublicVariableInputs.js +0 -172
- package/dist/public-chat/types/content.d.ts +0 -184
- package/dist/public-chat/types/content.js +0 -91
- package/dist/tool-call-visualization/renderers/_shared-entity/EntityOpenActions.d.ts +0 -15
- package/dist/tool-call-visualization/renderers/_shared-entity/EntityOpenActions.js +0 -31
- package/dist/tool-call-visualization/utils/toolCallBlockToLifecycleEntry.d.ts +0 -24
- package/dist/tool-call-visualization/utils/toolCallBlockToLifecycleEntry.js +0 -26
- package/dist/ui/AudioOutputBlockSkeleton.d.ts +0 -17
- package/dist/ui/AudioOutputBlockSkeleton.js +0 -78
- package/dist/ui/lazy/PublicChatVariableInputs.d.ts +0 -2
- package/dist/ui/lazy/PublicChatVariableInputs.js +0 -16
- package/dist/utils/xml/readXmlTag.d.ts +0 -12
- package/dist/utils/xml/readXmlTag.js +0 -66
- /package/dist/{cx-chat/types/cx-tables.js → tool-call-visualization/configured-rows/types.js} +0 -0
|
@@ -1,42 +1,27 @@
|
|
|
1
1
|
import { createAsyncThunk } from "@reduxjs/toolkit";
|
|
2
2
|
import { extractErrorMessage } from "@ai-matrx/data/net";
|
|
3
|
-
import {
|
|
3
|
+
import { postDelegatedToolOutcome } from "./post-delegated-tool-outcome.js";
|
|
4
4
|
import {
|
|
5
5
|
applySurfaceWrite,
|
|
6
6
|
readSurfaceWriteAddress
|
|
7
7
|
} from "../../../../surfaces/runtime/surface-writeback.js";
|
|
8
8
|
import { surfaceWriteToolOutput } from "../../../../surfaces/runtime/surface-write-tool-output.js";
|
|
9
9
|
import { createSurfaceToolCall } from "./surface-tool-call.js";
|
|
10
|
-
import { upsertToolLifecycle } from "../active-requests/active-requests.slice.js";
|
|
11
10
|
import { setInstanceStatus } from "../conversations/conversations.slice.js";
|
|
12
11
|
const dispatchSurfaceWrite = createAsyncThunk(
|
|
13
12
|
"surfaceWriteback/dispatchAgentWrite",
|
|
14
13
|
async ({ conversationId, requestId, callId, toolName, args }, { dispatch, getState }) => {
|
|
15
14
|
const startedAt = performance.now();
|
|
16
15
|
const finish = (output, errorMessage) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
...errorMessage ? { errorType: "surface_write_failed", errorMessage } : {}
|
|
27
|
-
})
|
|
28
|
-
);
|
|
29
|
-
dispatch(
|
|
30
|
-
submitToolResult({
|
|
31
|
-
conversationId,
|
|
32
|
-
call_id: callId,
|
|
33
|
-
tool_name: toolName,
|
|
34
|
-
is_error: Boolean(errorMessage),
|
|
35
|
-
output,
|
|
36
|
-
duration_ms: durationMs,
|
|
37
|
-
...errorMessage ? { error_message: errorMessage } : {}
|
|
38
|
-
})
|
|
39
|
-
);
|
|
16
|
+
postDelegatedToolOutcome(dispatch, {
|
|
17
|
+
conversationId,
|
|
18
|
+
requestId,
|
|
19
|
+
callId,
|
|
20
|
+
toolName,
|
|
21
|
+
output,
|
|
22
|
+
error: errorMessage ? { type: "surface_write_failed", message: errorMessage } : void 0,
|
|
23
|
+
durationMs: Math.round(performance.now() - startedAt)
|
|
24
|
+
});
|
|
40
25
|
};
|
|
41
26
|
const target = args.target;
|
|
42
27
|
if (typeof target !== "string" || !target.trim()) {
|
|
@@ -11,6 +11,7 @@ import { mintClientTempId } from "@ai-matrx/kit/ids";
|
|
|
11
11
|
import { createAsyncThunk } from "@reduxjs/toolkit";
|
|
12
12
|
import { toast } from "../../../../host/notify.js";
|
|
13
13
|
import { buildToolInjection } from "../utils/build-tool-injection.js";
|
|
14
|
+
import { mergeHostTurnContext } from "../utils/host-turn.js";
|
|
14
15
|
import { resolveRequestOverrides } from "../utils/request-overrides.js";
|
|
15
16
|
import { attachOutputKindsFromState, attachSkillConfigFromState } from "../utils/build-skill-config-for-request.js";
|
|
16
17
|
import { buildContinuationBody } from "../utils/continuation-body.js";
|
|
@@ -35,6 +36,7 @@ import {
|
|
|
35
36
|
selectVariablesForRequest
|
|
36
37
|
} from "../instance-variable-values/instance-variable-values.selectors.js";
|
|
37
38
|
import { selectSettingsOverridesForApi } from "../instance-model-overrides/instance-model-overrides.selectors.js";
|
|
39
|
+
import { collectAttachmentSourceContext } from "../../../../host/composer-extensions.js";
|
|
38
40
|
import { selectInstanceContextEntries } from "../instance-context/instance-context.selectors.js";
|
|
39
41
|
import {
|
|
40
42
|
consumePerTurnContext,
|
|
@@ -465,6 +467,12 @@ const executeInstance = createAsyncThunk(
|
|
|
465
467
|
if (injection.tools_replace)
|
|
466
468
|
payload.tools_replace = injection.tools_replace;
|
|
467
469
|
if (injection.client) payload.client = injection.client;
|
|
470
|
+
if (injection.hostContext) {
|
|
471
|
+
payload.context = mergeHostTurnContext(
|
|
472
|
+
payload.context,
|
|
473
|
+
injection.hostContext
|
|
474
|
+
);
|
|
475
|
+
}
|
|
468
476
|
if (payload.target_instance_id && !injection.client?.state?.["desktop-native"]) {
|
|
469
477
|
delete payload.target_instance_id;
|
|
470
478
|
}
|
|
@@ -559,6 +567,18 @@ const executeInstance = createAsyncThunk(
|
|
|
559
567
|
...hostExtras.context
|
|
560
568
|
};
|
|
561
569
|
}
|
|
570
|
+
{
|
|
571
|
+
const sourceContext = await collectAttachmentSourceContext(
|
|
572
|
+
conversationId,
|
|
573
|
+
(sourceId, error) => console.warn(`[Matrx] Attachment source "${sourceId}" failed and was skipped:`, error)
|
|
574
|
+
);
|
|
575
|
+
if (sourceContext) {
|
|
576
|
+
routedPayload.context = {
|
|
577
|
+
...routedPayload.context ?? {},
|
|
578
|
+
...sourceContext
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
}
|
|
562
582
|
{
|
|
563
583
|
const { overrides, error } = resolveRequestOverrides(
|
|
564
584
|
state,
|
|
@@ -106,6 +106,7 @@ import { payloadSafetyStore } from "@ai-matrx/kit/payload-safety";
|
|
|
106
106
|
import { netRequests } from "../../../../host/diagnostics.js";
|
|
107
107
|
import { buildRequestUserOverrides } from "../utils/request-user-overrides.js";
|
|
108
108
|
import { buildToolInjection } from "../utils/build-tool-injection.js";
|
|
109
|
+
import { mergeHostTurnContext } from "../utils/host-turn.js";
|
|
109
110
|
import { resolveRequestOverrides } from "../utils/request-overrides.js";
|
|
110
111
|
import { attachOutputKindsFromState, attachSkillConfigFromState } from "../utils/build-skill-config-for-request.js";
|
|
111
112
|
import { isUiGateKey } from "../../agent-settings/ui-gates.js";
|
|
@@ -289,7 +290,11 @@ async function assembleManualRequest(state, conversationId, opts) {
|
|
|
289
290
|
if (agent.variableDefinitions?.length) {
|
|
290
291
|
request.variable_definitions = agent.variableDefinitions;
|
|
291
292
|
}
|
|
292
|
-
|
|
293
|
+
const mergedContext = mergeHostTurnContext(
|
|
294
|
+
context,
|
|
295
|
+
injection.hostContext
|
|
296
|
+
);
|
|
297
|
+
if (mergedContext) request.context = mergedContext;
|
|
293
298
|
request.context_withheld = context_withheld;
|
|
294
299
|
if (page_context) request.page_context = page_context;
|
|
295
300
|
if (context_surfaces) request.context_surfaces = context_surfaces;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createNotifyAndPlayDispatcher — the one dispatcher for tool families that run
|
|
3
|
+
* IMMEDIATELY with no approval pause (scribe playback, the war-room master's
|
|
4
|
+
* notify-and-watch tools). It validates args against the family's Zod schema,
|
|
5
|
+
* runs the family's handler, and reports through `postDelegatedToolOutcome`.
|
|
6
|
+
* A family supplies only its name check, its registry lookup and its label.
|
|
7
|
+
*
|
|
8
|
+
* Safety without an approval gate:
|
|
9
|
+
* 1. Args are Zod-validated before anything runs (malformed => clean error).
|
|
10
|
+
* 2. The handler resolves its own target and refuses cleanly (`ok:false`).
|
|
11
|
+
* 3. Every result goes through the single funnel so the hard-suspended loop
|
|
12
|
+
* resumes exactly once. The dispatcher never throws.
|
|
13
|
+
*/
|
|
14
|
+
import type { ThunkDispatch } from "redux-thunk";
|
|
15
|
+
import type { UnknownAction } from "@reduxjs/toolkit";
|
|
16
|
+
import type { z } from "zod";
|
|
17
|
+
export interface NotifyAndPlayPayload {
|
|
18
|
+
conversationId: string;
|
|
19
|
+
requestId: string;
|
|
20
|
+
callId: string;
|
|
21
|
+
toolName: string;
|
|
22
|
+
args: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
interface NotifyAndPlayContext<S> {
|
|
25
|
+
conversationId: string;
|
|
26
|
+
callId: string;
|
|
27
|
+
userId: string;
|
|
28
|
+
dispatch: ThunkDispatch<S, unknown, UnknownAction>;
|
|
29
|
+
getState: () => S;
|
|
30
|
+
}
|
|
31
|
+
export interface NotifyAndPlayEntry<S> {
|
|
32
|
+
schema: z.ZodTypeAny;
|
|
33
|
+
handler: {
|
|
34
|
+
run: (args: never, ctx: NotifyAndPlayContext<S>) => Promise<unknown>;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export declare function createNotifyAndPlayDispatcher<S extends {
|
|
38
|
+
userAuth?: {
|
|
39
|
+
id?: string | null;
|
|
40
|
+
} | null;
|
|
41
|
+
}>(options: {
|
|
42
|
+
/** Redux action type prefix, e.g. "scribeTools/dispatch". */
|
|
43
|
+
typePrefix: string;
|
|
44
|
+
/** Human label used in the unknown-tool message, e.g. "scribe". */
|
|
45
|
+
family: string;
|
|
46
|
+
isToolName: (name: string) => boolean;
|
|
47
|
+
getEntry: (name: string) => NotifyAndPlayEntry<S> | undefined;
|
|
48
|
+
}): import("@reduxjs/toolkit").AsyncThunk<void, NotifyAndPlayPayload, {
|
|
49
|
+
dispatch?: ThunkDispatch<unknown, unknown, UnknownAction>;
|
|
50
|
+
extra?: unknown;
|
|
51
|
+
rejectValue?: unknown;
|
|
52
|
+
serializedErrorType?: unknown;
|
|
53
|
+
pendingMeta?: unknown;
|
|
54
|
+
fulfilledMeta?: unknown;
|
|
55
|
+
rejectedMeta?: unknown;
|
|
56
|
+
state: S;
|
|
57
|
+
}>;
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { createAsyncThunk } from "@reduxjs/toolkit";
|
|
2
|
+
import { extractErrorMessage } from "@ai-matrx/data/net";
|
|
3
|
+
import { postDelegatedToolOutcome } from "./post-delegated-tool-outcome.js";
|
|
4
|
+
function createNotifyAndPlayDispatcher(options) {
|
|
5
|
+
const { typePrefix, family, isToolName, getEntry } = options;
|
|
6
|
+
return createAsyncThunk(
|
|
7
|
+
typePrefix,
|
|
8
|
+
async ({ conversationId, requestId, callId, toolName, args }, { dispatch, getState }) => {
|
|
9
|
+
const userId = getState().userAuth?.id ?? null;
|
|
10
|
+
const base = { conversationId, requestId, callId, toolName };
|
|
11
|
+
const fail = (errorType, message, durationMs) => postDelegatedToolOutcome(dispatch, {
|
|
12
|
+
...base,
|
|
13
|
+
output: { ok: false, reason: errorType, message },
|
|
14
|
+
error: { type: errorType, message },
|
|
15
|
+
durationMs
|
|
16
|
+
});
|
|
17
|
+
if (!userId) {
|
|
18
|
+
fail("unauthenticated", "user not authenticated");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const entry = isToolName(toolName) ? getEntry(toolName) : void 0;
|
|
22
|
+
if (!entry) {
|
|
23
|
+
fail("unknown_tool", `Unknown ${family} tool: ${toolName}`);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const parsed = entry.schema.safeParse(args);
|
|
27
|
+
if (!parsed.success) {
|
|
28
|
+
fail(
|
|
29
|
+
"schema",
|
|
30
|
+
`args failed schema for ${toolName}: ${JSON.stringify(
|
|
31
|
+
parsed.error.format()
|
|
32
|
+
)}`
|
|
33
|
+
);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const startedAt = performance.now();
|
|
37
|
+
try {
|
|
38
|
+
const result = await entry.handler.run(parsed.data, {
|
|
39
|
+
conversationId,
|
|
40
|
+
callId,
|
|
41
|
+
userId,
|
|
42
|
+
dispatch,
|
|
43
|
+
getState
|
|
44
|
+
});
|
|
45
|
+
postDelegatedToolOutcome(dispatch, {
|
|
46
|
+
...base,
|
|
47
|
+
output: result,
|
|
48
|
+
durationMs: Math.round(performance.now() - startedAt)
|
|
49
|
+
});
|
|
50
|
+
} catch (cause) {
|
|
51
|
+
fail(
|
|
52
|
+
"handler_threw",
|
|
53
|
+
extractErrorMessage(cause),
|
|
54
|
+
Math.round(performance.now() - startedAt)
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
export {
|
|
61
|
+
createNotifyAndPlayDispatcher
|
|
62
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONE way a client-delegated tool call reports its outcome: close the
|
|
3
|
+
* lifecycle row (so the live tool card stops waiting) AND post the result
|
|
4
|
+
* through the single `submitToolResult` funnel (so the hard-suspended loop
|
|
5
|
+
* resumes exactly once). Every dispatcher — scribe, war-room, surface client
|
|
6
|
+
* tools, surface writes — calls this instead of hand-writing the pair.
|
|
7
|
+
*/
|
|
8
|
+
import type { ChatDispatch } from "../../../../store/root-state.js";
|
|
9
|
+
export interface DelegatedToolOutcome {
|
|
10
|
+
conversationId: string;
|
|
11
|
+
requestId: string;
|
|
12
|
+
callId: string;
|
|
13
|
+
toolName: string;
|
|
14
|
+
/** The result body posted to the loop and shown on the card. */
|
|
15
|
+
output: Record<string, unknown>;
|
|
16
|
+
/** Present => the call failed; `type` is the lifecycle errorType. */
|
|
17
|
+
error?: {
|
|
18
|
+
type: string;
|
|
19
|
+
message: string;
|
|
20
|
+
};
|
|
21
|
+
durationMs?: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function postDelegatedToolOutcome(dispatch: ChatDispatch, { conversationId, requestId, callId, toolName, output, error, durationMs, }: DelegatedToolOutcome): void;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { submitToolResult } from "../../../api/submit-tool-results.js";
|
|
2
|
+
import { upsertToolLifecycle } from "../active-requests/active-requests.slice.js";
|
|
3
|
+
function postDelegatedToolOutcome(dispatch, {
|
|
4
|
+
conversationId,
|
|
5
|
+
requestId,
|
|
6
|
+
callId,
|
|
7
|
+
toolName,
|
|
8
|
+
output,
|
|
9
|
+
error,
|
|
10
|
+
durationMs
|
|
11
|
+
}) {
|
|
12
|
+
dispatch(
|
|
13
|
+
upsertToolLifecycle({
|
|
14
|
+
requestId,
|
|
15
|
+
callId,
|
|
16
|
+
toolName,
|
|
17
|
+
status: error ? "error" : "completed",
|
|
18
|
+
isDelegated: true,
|
|
19
|
+
result: output,
|
|
20
|
+
...error ? { errorType: error.type, errorMessage: error.message } : {}
|
|
21
|
+
})
|
|
22
|
+
);
|
|
23
|
+
dispatch(
|
|
24
|
+
submitToolResult({
|
|
25
|
+
conversationId,
|
|
26
|
+
call_id: callId,
|
|
27
|
+
tool_name: toolName,
|
|
28
|
+
is_error: Boolean(error),
|
|
29
|
+
output,
|
|
30
|
+
...error ? { error_message: error.message } : {},
|
|
31
|
+
...durationMs !== void 0 ? { duration_ms: durationMs } : {}
|
|
32
|
+
})
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
postDelegatedToolOutcome
|
|
37
|
+
};
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
warmLocalEngineForConversation
|
|
12
12
|
} from "./resolve-base-url.js";
|
|
13
13
|
import { buildToolInjection } from "../utils/build-tool-injection.js";
|
|
14
|
+
import { mergeHostTurnContext } from "../utils/host-turn.js";
|
|
14
15
|
import {
|
|
15
16
|
hasAbortController,
|
|
16
17
|
whenAbortControllerReleased
|
|
@@ -135,7 +136,8 @@ const resumeInstance = createAsyncThunk(
|
|
|
135
136
|
}
|
|
136
137
|
resumeBackend = backend;
|
|
137
138
|
const injection = await buildToolInjection(state, conversationId, {
|
|
138
|
-
mode: "additive"
|
|
139
|
+
mode: "additive",
|
|
140
|
+
phase: "resume"
|
|
139
141
|
});
|
|
140
142
|
await dispatch(refreshSurfaceScope({ conversationId })).unwrap().catch(
|
|
141
143
|
(error) => console.error(
|
|
@@ -171,7 +173,13 @@ const resumeInstance = createAsyncThunk(
|
|
|
171
173
|
).filter((id) => typeof id === "string" && id.length > 0);
|
|
172
174
|
const body = {
|
|
173
175
|
user_request_id: userRequestId,
|
|
174
|
-
...
|
|
176
|
+
...(() => {
|
|
177
|
+
const merged = mergeHostTurnContext(
|
|
178
|
+
context,
|
|
179
|
+
injection.hostContext
|
|
180
|
+
);
|
|
181
|
+
return merged ? { context: merged } : {};
|
|
182
|
+
})(),
|
|
175
183
|
context_withheld,
|
|
176
184
|
...page_context && { page_context },
|
|
177
185
|
...context_surfaces && { context_surfaces },
|
|
@@ -21,6 +21,7 @@ import type { ChatRootState } from "../../../../store/root-state.js";
|
|
|
21
21
|
import type { ToolInjectionResult, ToolSpec } from "../../../types/tool-injection.types.js";
|
|
22
22
|
import "../client-capabilities/register-all.js";
|
|
23
23
|
import type { UserOverrides } from "../../../types/request.types.js";
|
|
24
|
+
import type { ChatHostTurnPhase } from "../../../../host/contract.js";
|
|
24
25
|
interface BuildOptions {
|
|
25
26
|
mode?: "additive" | "replace";
|
|
26
27
|
/**
|
|
@@ -29,6 +30,12 @@ interface BuildOptions {
|
|
|
29
30
|
* aren't in the slice (e.g. an agent-as-tool projection).
|
|
30
31
|
*/
|
|
31
32
|
seedTools?: ToolSpec[];
|
|
33
|
+
/**
|
|
34
|
+
* Which moment of the turn this request is for — handed to the host's turn port
|
|
35
|
+
* (`registry.contextSources`). A start latches the device reference + ask/act mode for the turn.
|
|
36
|
+
* Default: "start".
|
|
37
|
+
*/
|
|
38
|
+
phase?: ChatHostTurnPhase;
|
|
32
39
|
}
|
|
33
40
|
export declare function buildToolInjection(state: ChatRootState, conversationId: string, options?: BuildOptions): Promise<ToolInjectionResult>;
|
|
34
41
|
/**
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
announceWithheldSurfaceWriteTools,
|
|
40
40
|
resolveRunOutputContract
|
|
41
41
|
} from "./output-contract-guard.js";
|
|
42
|
+
import { collectHostTurnContribution } from "./host-turn.js";
|
|
42
43
|
import {
|
|
43
44
|
isToolBlocked,
|
|
44
45
|
selectBlockedToolPatterns
|
|
@@ -194,12 +195,15 @@ async function buildToolInjection(state, conversationId, options = {}) {
|
|
|
194
195
|
}
|
|
195
196
|
}
|
|
196
197
|
const providers = getRegisteredCapabilities();
|
|
197
|
-
const resolved = await Promise.all(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
198
|
+
const [resolved, hostTurn] = await Promise.all([
|
|
199
|
+
Promise.all(
|
|
200
|
+
providers.map(async (p) => {
|
|
201
|
+
const payload = await p.selectPayload(state, conversationId);
|
|
202
|
+
return payload == null ? null : { name: p.name, payload, stateless: p.stateless ?? false };
|
|
203
|
+
})
|
|
204
|
+
),
|
|
205
|
+
collectHostTurnContribution(state, conversationId, options.phase ?? "start")
|
|
206
|
+
]);
|
|
203
207
|
let client;
|
|
204
208
|
const activeCapabilities = [];
|
|
205
209
|
const stateMap = {};
|
|
@@ -209,6 +213,11 @@ async function buildToolInjection(state, conversationId, options = {}) {
|
|
|
209
213
|
if (entry.stateless) continue;
|
|
210
214
|
stateMap[entry.name] = entry.payload;
|
|
211
215
|
}
|
|
216
|
+
for (const [name, payload] of Object.entries(hostTurn?.capabilities ?? {})) {
|
|
217
|
+
if (activeCapabilities.includes(name)) continue;
|
|
218
|
+
activeCapabilities.push(name);
|
|
219
|
+
if (payload != null) stateMap[name] = payload;
|
|
220
|
+
}
|
|
212
221
|
const desktopTargetInstanceId = selectDesktopTargetInstanceId(state);
|
|
213
222
|
const existingDesktopState = stateMap["desktop-native"];
|
|
214
223
|
if (desktopTargetInstanceId && existingDesktopState) {
|
|
@@ -235,6 +244,9 @@ async function buildToolInjection(state, conversationId, options = {}) {
|
|
|
235
244
|
else result.tools = allTools;
|
|
236
245
|
}
|
|
237
246
|
if (client) result.client = client;
|
|
247
|
+
if (hostTurn?.context && Object.keys(hostTurn.context).length > 0) {
|
|
248
|
+
result.hostContext = hostTurn.context;
|
|
249
|
+
}
|
|
238
250
|
return result;
|
|
239
251
|
}
|
|
240
252
|
function selectEffectiveAutoTools(state, conversationId) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host's per-turn contribution (`registry.contextSources`) and what the package keeps from it.
|
|
3
|
+
*
|
|
4
|
+
* `buildToolInjection` — the one envelope builder for execute, manual and resume — asks the
|
|
5
|
+
* host once per request: which server-registered client capabilities it offers (with their
|
|
6
|
+
* `client.state` payloads), which entries join the request's `context`, and an opaque device
|
|
7
|
+
* reference for the turn. The wait is bounded (`HOST_TURN_BUDGET_MS`): a host that answers too
|
|
8
|
+
* late, or throws, is skipped for that request and the skip is announced through diagnostics —
|
|
9
|
+
* a slow host never stalls a send.
|
|
10
|
+
*
|
|
11
|
+
* The device reference and the person's ask/act choice are LATCHED when the turn starts (the
|
|
12
|
+
* person's send) and handed to `deviceTools.invoke` for every call of that turn, resumes
|
|
13
|
+
* included — so switching tabs or flipping the mode mid-run never moves a run already going.
|
|
14
|
+
*/
|
|
15
|
+
import type { ChatRootState } from "../../../../store/root-state.js";
|
|
16
|
+
import type { ChatDevicePermissionMode, ChatHostTurnContribution, ChatHostTurnPhase } from "../../../../host/contract.js";
|
|
17
|
+
/** The longest a request waits on the host's turn contribution. */
|
|
18
|
+
export declare const HOST_TURN_BUDGET_MS = 1500;
|
|
19
|
+
/** Prefs key for one agent's device-tool mode (`"ask"` | `"act"`). */
|
|
20
|
+
export declare const DEVICE_PERMISSION_MODE_KEY = "chat.device-tools.permission-mode";
|
|
21
|
+
export declare function devicePermissionModeKey(agentId: string | null): string;
|
|
22
|
+
/** The person's stored ask/act choice for this agent; `"ask"` until they choose. */
|
|
23
|
+
export declare function readDevicePermissionMode(agentId: string | null): ChatDevicePermissionMode;
|
|
24
|
+
export declare function writeDevicePermissionMode(agentId: string | null, mode: ChatDevicePermissionMode): void;
|
|
25
|
+
interface LatchedTurn {
|
|
26
|
+
agentId: string | null;
|
|
27
|
+
permissionMode: ChatDevicePermissionMode;
|
|
28
|
+
deviceRef?: unknown;
|
|
29
|
+
}
|
|
30
|
+
/** What the current turn of this conversation latched at send time (device tools read this). */
|
|
31
|
+
export declare function getLatchedTurn(conversationId: string): LatchedTurn | null;
|
|
32
|
+
/** Test seam: forget every latched turn. */
|
|
33
|
+
export declare function resetLatchedTurns(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Ask every registered context source for this request's contribution (in parallel, each
|
|
36
|
+
* bounded). On a start, latch the device reference and the ask/act mode for the turn; a resume
|
|
37
|
+
* keeps what the start latched (a resume whose start predates this page load latches then).
|
|
38
|
+
*/
|
|
39
|
+
export declare function collectHostTurnContribution(state: ChatRootState, conversationId: string, phase: ChatHostTurnPhase): Promise<ChatHostTurnContribution | null>;
|
|
40
|
+
/**
|
|
41
|
+
* Merge the host's context entries under what the request already carries: a key the person
|
|
42
|
+
* or the agent set always wins. Returns the original object when the host adds nothing.
|
|
43
|
+
*/
|
|
44
|
+
export declare function mergeHostTurnContext<T extends Record<string, unknown> | undefined>(existing: T, hostContext: Readonly<Record<string, unknown>> | undefined): T | Record<string, unknown>;
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { getChatHost, isChatHostConfigured } from "../../../../host/configure.js";
|
|
2
|
+
const HOST_TURN_BUDGET_MS = 1500;
|
|
3
|
+
const DEVICE_PERMISSION_MODE_KEY = "chat.device-tools.permission-mode";
|
|
4
|
+
function devicePermissionModeKey(agentId) {
|
|
5
|
+
return `${DEVICE_PERMISSION_MODE_KEY}:${agentId ?? "default"}`;
|
|
6
|
+
}
|
|
7
|
+
function readDevicePermissionMode(agentId) {
|
|
8
|
+
if (!isChatHostConfigured()) return "ask";
|
|
9
|
+
const prefs = getChatHost().prefs;
|
|
10
|
+
const own = prefs.get(devicePermissionModeKey(agentId));
|
|
11
|
+
if (own === "ask" || own === "act") return own;
|
|
12
|
+
const fallback = prefs.get(devicePermissionModeKey(null));
|
|
13
|
+
return fallback === "act" ? "act" : "ask";
|
|
14
|
+
}
|
|
15
|
+
function writeDevicePermissionMode(agentId, mode) {
|
|
16
|
+
if (!isChatHostConfigured()) return;
|
|
17
|
+
getChatHost().prefs.set(devicePermissionModeKey(agentId), mode);
|
|
18
|
+
}
|
|
19
|
+
const latchedByConversation = /* @__PURE__ */ new Map();
|
|
20
|
+
function getLatchedTurn(conversationId) {
|
|
21
|
+
return latchedByConversation.get(conversationId) ?? null;
|
|
22
|
+
}
|
|
23
|
+
function resetLatchedTurns() {
|
|
24
|
+
latchedByConversation.clear();
|
|
25
|
+
}
|
|
26
|
+
function agentIdOf(state, conversationId) {
|
|
27
|
+
return state.conversations?.byConversationId?.[conversationId]?.agentId ?? null;
|
|
28
|
+
}
|
|
29
|
+
function announceSkip(sourceId, conversationId, phase, cause) {
|
|
30
|
+
const message = cause === "timeout" ? `Context source "${sourceId}" did not answer within ${HOST_TURN_BUDGET_MS}ms; this ${phase} request went without it.` : `Context source "${sourceId}" failed; this ${phase} request went without it.`;
|
|
31
|
+
try {
|
|
32
|
+
getChatHost().diagnostics.capture(cause === "timeout" ? new Error(message) : cause, {
|
|
33
|
+
area: "host-turn",
|
|
34
|
+
code: cause === "timeout" ? "host_turn_timeout" : "host_turn_failed",
|
|
35
|
+
detail: { sourceId, conversationId, phase, message }
|
|
36
|
+
});
|
|
37
|
+
} catch {
|
|
38
|
+
console.warn(`[host-turn] ${message}`, cause);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function askSource(source, input) {
|
|
42
|
+
let timer;
|
|
43
|
+
const outcome = await Promise.race([
|
|
44
|
+
Promise.resolve().then(() => source.contribute(input)).then((value) => ({ ok: true, value })).catch((error) => ({ ok: false, error })),
|
|
45
|
+
new Promise((resolve) => {
|
|
46
|
+
timer = setTimeout(() => resolve({ ok: false, error: "timeout" }), HOST_TURN_BUDGET_MS);
|
|
47
|
+
})
|
|
48
|
+
]);
|
|
49
|
+
if (timer) clearTimeout(timer);
|
|
50
|
+
if (outcome.ok) return outcome.value ?? null;
|
|
51
|
+
announceSkip(source.id, input.conversationId, input.phase, outcome.error);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
function mergeContributions(parts) {
|
|
55
|
+
const capabilities = {};
|
|
56
|
+
const context = {};
|
|
57
|
+
let deviceRef = void 0;
|
|
58
|
+
let any = false;
|
|
59
|
+
for (const part of parts) {
|
|
60
|
+
if (!part) continue;
|
|
61
|
+
any = true;
|
|
62
|
+
for (const [name, payload] of Object.entries(part.capabilities ?? {})) {
|
|
63
|
+
if (!(name in capabilities)) capabilities[name] = payload;
|
|
64
|
+
}
|
|
65
|
+
for (const [key, value] of Object.entries(part.context ?? {})) {
|
|
66
|
+
if (!(key in context)) context[key] = value;
|
|
67
|
+
}
|
|
68
|
+
if (deviceRef === void 0 && part.deviceRef !== void 0) deviceRef = part.deviceRef;
|
|
69
|
+
}
|
|
70
|
+
if (!any) return null;
|
|
71
|
+
return {
|
|
72
|
+
...Object.keys(capabilities).length > 0 && { capabilities },
|
|
73
|
+
...Object.keys(context).length > 0 && { context },
|
|
74
|
+
...deviceRef !== void 0 && { deviceRef }
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async function collectHostTurnContribution(state, conversationId, phase) {
|
|
78
|
+
if (!isChatHostConfigured()) return null;
|
|
79
|
+
const host = getChatHost();
|
|
80
|
+
const agentId = agentIdOf(state, conversationId);
|
|
81
|
+
const sources = host.registry.contextSources ?? [];
|
|
82
|
+
const input = { conversationId, agentId, phase };
|
|
83
|
+
const contribution = sources.length > 0 ? mergeContributions(await Promise.all(sources.map((source) => askSource(source, input)))) : null;
|
|
84
|
+
if (host.deviceTools) {
|
|
85
|
+
const prior = latchedByConversation.get(conversationId);
|
|
86
|
+
if (phase === "start" || !prior) {
|
|
87
|
+
latchedByConversation.set(conversationId, {
|
|
88
|
+
agentId,
|
|
89
|
+
permissionMode: readDevicePermissionMode(agentId),
|
|
90
|
+
...contribution?.deviceRef !== void 0 && { deviceRef: contribution.deviceRef }
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return contribution;
|
|
95
|
+
}
|
|
96
|
+
function mergeHostTurnContext(existing, hostContext) {
|
|
97
|
+
if (!hostContext) return existing;
|
|
98
|
+
const keys = Object.keys(hostContext);
|
|
99
|
+
if (keys.length === 0) return existing;
|
|
100
|
+
const merged = { ...existing ?? {} };
|
|
101
|
+
let added = false;
|
|
102
|
+
for (const key of keys) {
|
|
103
|
+
if (key in merged) continue;
|
|
104
|
+
merged[key] = hostContext[key];
|
|
105
|
+
added = true;
|
|
106
|
+
}
|
|
107
|
+
return added ? merged : existing;
|
|
108
|
+
}
|
|
109
|
+
export {
|
|
110
|
+
DEVICE_PERMISSION_MODE_KEY,
|
|
111
|
+
HOST_TURN_BUDGET_MS,
|
|
112
|
+
collectHostTurnContribution,
|
|
113
|
+
devicePermissionModeKey,
|
|
114
|
+
getLatchedTurn,
|
|
115
|
+
mergeHostTurnContext,
|
|
116
|
+
readDevicePermissionMode,
|
|
117
|
+
resetLatchedTurns,
|
|
118
|
+
writeDevicePermissionMode
|
|
119
|
+
};
|
|
@@ -71,7 +71,7 @@ export declare const selectProposedDirectives: (conversationId: string) => ((sta
|
|
|
71
71
|
voiceAgent: import("../../../voice-agent/types.js").VoiceAgentState;
|
|
72
72
|
agentDefinition: import("../../types/agent-definition.types.js").AgentDefinitionSliceState;
|
|
73
73
|
conversationList: import("../conversation-list/conversation-list.types.js").ConversationListState;
|
|
74
|
-
conversationHistory: import("../conversation-history/
|
|
74
|
+
conversationHistory: import("../conversation-history/types.js").ConversationHistoryState;
|
|
75
75
|
agentShortcut: import("../agent-shortcuts/types.js").AgentShortcutSliceState;
|
|
76
76
|
agentShortcutCategory: import("../agent-shortcut-categories/types.js").AgentShortcutCategorySliceState;
|
|
77
77
|
surfaceUserState: import("../../../surfaces/redux/userStateSlice.js").SurfaceUserStateSlice;
|