@vellumai/assistant 0.11.3 → 0.11.4-dev.202608190019.b94dbf2
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/AGENTS.md +9 -3
- package/ARCHITECTURE.md +32 -10
- package/docs/architecture/memory.md +43 -5
- package/docs/architecture/security.md +96 -152
- package/docs/architecture/turn-actor.md +70 -0
- package/docs/browser-use-architecture-phase2.md +128 -56
- package/docs/flux-turn-detection-spike.md +248 -0
- package/docs/guardian-request-flow.md +35 -0
- package/docs/stt-provider-onboarding.md +3 -1
- package/knip.json +3 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +60 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +60 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +34 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +166 -1
- package/node_modules/@vellumai/gateway-client/src/index.ts +2 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +60 -0
- package/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/openapi.yaml +289 -113
- package/package.json +1 -1
- package/scripts/voice-ttft-spike.ts +3 -3
- package/scripts/write-plugin-api-shim.ts +10 -0
- package/src/__tests__/app-compiler.test.ts +38 -3
- package/src/__tests__/app-control-flow.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +2 -2
- package/src/__tests__/assistant-feature-flag-guard.test.ts +25 -3
- package/src/__tests__/attachments-store.test.ts +21 -12
- package/src/__tests__/byok-default-profile-ensure.test.ts +17 -0
- package/src/__tests__/call-setup-flow-name-capture.test.ts +0 -1
- package/src/__tests__/call-site-routing-provider.test.ts +1 -1
- package/src/__tests__/channel-availability-routes.test.ts +14 -1
- package/src/__tests__/channel-capabilities-dedupe.test.ts +214 -0
- package/src/__tests__/channel-delivery-store.test.ts +14 -14
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +4 -4
- package/src/__tests__/channel-setup-panel-ack.test.ts +1 -1
- package/src/__tests__/checker.test.ts +20 -314
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +6 -2
- package/src/__tests__/compaction-events.test.ts +8 -10
- package/src/__tests__/config-loader-backfill.test.ts +3 -3
- package/src/__tests__/config-schema.test.ts +25 -10
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +8 -11
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +8 -11
- package/src/__tests__/conversation-agent-loop.test.ts +32 -21
- package/src/__tests__/conversation-attachments.test.ts +0 -1
- package/src/__tests__/conversation-attention-store.test.ts +63 -0
- package/src/__tests__/conversation-confirmation-signals.test.ts +112 -0
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -4
- package/src/__tests__/conversation-fork-crud.test.ts +69 -0
- package/src/__tests__/conversation-fork-referential.test.ts +67 -0
- package/src/__tests__/conversation-fork-retrospective.test.ts +24 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +209 -0
- package/src/__tests__/conversation-notifiers-provenance.test.ts +59 -0
- package/src/__tests__/conversation-queue.test.ts +154 -4
- package/src/__tests__/conversation-routes-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +1 -1
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +9 -9
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +1 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +187 -102
- package/src/__tests__/conversation-runtime-workspace.test.ts +14 -10
- package/src/__tests__/conversation-slash-queue.test.ts +3 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-app-open.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-history-restored-completion.test.ts +21 -14
- package/src/__tests__/conversation-surfaces-queued-emit.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-state-update.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-table-action.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +1 -1
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +1 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +1 -1
- package/src/__tests__/credential-prompt-route.test.ts +7 -10
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/cu-unified-flow.test.ts +1 -0
- package/src/__tests__/custom-profile-ensure.test.ts +5 -1
- package/src/__tests__/default-plugin-names-guard.test.ts +12 -1
- package/src/__tests__/discord-access-request-privacy.test.ts +5 -1
- package/src/__tests__/discord-requester-notice-privacy.test.ts +3 -3
- package/src/__tests__/document-append-idempotency.test.ts +233 -0
- package/src/__tests__/document-sync-tags.test.ts +0 -75
- package/src/__tests__/dynamic-skill-background-guard.test.ts +0 -2
- package/src/__tests__/edit-propagation.test.ts +107 -11
- package/src/__tests__/file-ops-service.test.ts +163 -30
- package/src/__tests__/filesystem-tools.test.ts +23 -24
- package/src/__tests__/gateway-only-guard.test.ts +2 -5
- package/src/__tests__/helpers/gateway-classify-mock.ts +27 -6
- package/src/__tests__/helpers/mock-actor-context.ts +49 -0
- package/src/__tests__/helpers/mock-conversation.ts +13 -1
- package/src/__tests__/host-file-read-tool.test.ts +16 -19
- package/src/__tests__/http-user-message-parity.test.ts +1 -1
- package/src/__tests__/init-feature-flag-overrides.test.ts +49 -0
- package/src/__tests__/injector-chain.test.ts +63 -41
- package/src/__tests__/injector-disk-pressure.test.ts +11 -23
- package/src/__tests__/inline-skill-load-permissions.test.ts +47 -36
- package/src/__tests__/llm-context-resolution.test.ts +73 -1
- package/src/__tests__/llm-schema.test.ts +5 -2
- package/src/__tests__/managed-skill-lifecycle.test.ts +7 -0
- package/src/__tests__/mcp-list-plugin-servers.test.ts +250 -0
- package/src/__tests__/media-generate-image.test.ts +131 -21
- package/src/__tests__/memory-retrieval-hook.test.ts +100 -7
- package/src/__tests__/messages-read-boundary-guard.test.ts +134 -0
- package/src/__tests__/mtime-cache.test.ts +3 -1
- package/src/__tests__/non-member-access-request.test.ts +0 -20
- package/src/__tests__/outbound-slack-persistence.test.ts +40 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +0 -4
- package/src/__tests__/plugin-api-store-credential.test.ts +261 -0
- package/src/__tests__/plugin-api-webhook-url.test.ts +10 -7
- package/src/__tests__/plugin-disabled-state.test.ts +2 -0
- package/src/__tests__/plugin-effective-enabled-set.test.ts +55 -3
- package/src/__tests__/plugin-execution-context.test.ts +73 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +5 -1
- package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +7 -4
- package/src/__tests__/plugin-secret-pattern-contribution.test.ts +1 -1
- package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +14 -7
- package/src/__tests__/provider-commit-message-generator.test.ts +20 -0
- package/src/__tests__/proxy-approval-callback.test.ts +1 -0
- package/src/__tests__/qdrant-manager.test.ts +14 -1
- package/src/__tests__/reaction-persistence.test.ts +200 -7
- package/src/__tests__/require-fresh-approval.test.ts +0 -4
- package/src/__tests__/risk-classification-boundary-guard.test.ts +115 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +460 -105
- package/src/__tests__/run-due-schedules.test.ts +21 -0
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +187 -18
- package/src/__tests__/schedule-routes.test.ts +23 -0
- package/src/__tests__/schedule-store.test.ts +17 -0
- package/src/__tests__/scoped-approval-grants.test.ts +11 -6
- package/src/__tests__/secret-ingress-channel.test.ts +0 -1
- package/src/__tests__/secret-ingress-http.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +3 -3
- package/src/__tests__/skills.test.ts +32 -0
- package/src/__tests__/slack-edit-ordering-characterization.test.ts +0 -1
- package/src/__tests__/starter-task-flow.test.ts +5 -4
- package/src/__tests__/subagent-call-site-routing.test.ts +31 -19
- package/src/__tests__/subagent-fork-prompt-role.test.ts +1 -1
- package/src/__tests__/subagent-spawn-and-await.test.ts +18 -17
- package/src/__tests__/subagent-tool-gate-mode.test.ts +1 -1
- package/src/__tests__/subagent-tools.test.ts +81 -101
- package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +1 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +132 -5
- package/src/__tests__/tool-executor.test.ts +68 -39
- package/src/__tests__/turn-events-store.test.ts +43 -0
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +1 -1
- package/src/__tests__/ui-shape-teaching.test.ts +33 -0
- package/src/__tests__/ui-visual-surface.test.ts +1 -1
- package/src/__tests__/ui-voice-picker-surface.test.ts +128 -0
- package/src/__tests__/ui-work-result-surface.test.ts +1 -1
- package/src/__tests__/user-plugin-loader.test.ts +3 -1
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/__tests__/visible-app-context.test.ts +16 -9
- package/src/__tests__/voice-config-update.test.ts +40 -0
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +5 -3
- package/src/__tests__/voice-session-bridge.test.ts +85 -29
- package/src/__tests__/worker-entrypoint-guards.test.ts +54 -0
- package/src/__tests__/worker-plugin-surface.test.ts +77 -0
- package/src/__tests__/workspace-migration-142-consolidate-voice-front-door.test.ts +158 -0
- package/src/__tests__/workspace-migration-143-repair-deprecated-codex-model-id.test.ts +133 -0
- package/src/__tests__/workspace-migration-144-convert-stranded-subscription-openai-profiles.test.ts +316 -0
- package/src/__tests__/workspace-migration-145-collapse-profile-bindings-to-entries.test.ts +325 -0
- package/src/__tests__/workspace-migration-146-repair-retired-fireworks-deepseek-flash-model-id.test.ts +235 -0
- package/src/acp/__tests__/acp-claude-oauth.test.ts +10 -2
- package/src/acp/__tests__/auth-required.test.ts +161 -0
- package/src/acp/acp-claude-oauth.ts +19 -2
- package/src/acp/agent-process.test.ts +100 -0
- package/src/acp/agent-process.ts +29 -26
- package/src/acp/auth-required.ts +102 -0
- package/src/acp/session-manager.test.ts +119 -0
- package/src/acp/session-manager.ts +76 -3
- package/src/api/events/acp-auth-required.ts +55 -0
- package/src/api/events/host-file.ts +2 -2
- package/src/api/index.ts +7 -0
- package/src/api/surfaces.ts +12 -3
- package/src/apps/app-store.ts +3 -0
- package/src/bundler/package-resolver.ts +2 -30
- package/src/calls/__tests__/voice-session-bridge.test.ts +194 -11
- package/src/calls/__tests__/voice-triage-escalate.test.ts +102 -0
- package/src/calls/call-controller.ts +19 -3
- package/src/calls/call-setup-flow.ts +0 -1
- package/src/calls/media-stream-stt-session.ts +15 -0
- package/src/calls/voice-session-bridge.ts +115 -41
- package/src/calls/voice-triage-escalate.ts +105 -2
- package/src/channels/__tests__/plugin-channel-declarations.test.ts +161 -0
- package/src/channels/config.ts +13 -0
- package/src/channels/plugin-channel-declarations.ts +108 -0
- package/src/channels/types.ts +30 -0
- package/src/cli/AGENTS.md +5 -2
- package/src/cli/bundled-modules.ts +29 -0
- package/src/cli/commands/credentials.help.ts +2 -2
- package/src/cli/commands/db/repair.ts +4 -8
- package/src/cli/commands/domain.ts +6 -3
- package/src/cli/commands/email.ts +6 -3
- package/src/cli/commands/inference-providers.ts +1 -1
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/mcp.help.ts +13 -4
- package/src/cli/commands/mcp.ts +9 -0
- package/src/cli/commands/memory/__tests__/memory-v2.test.ts +57 -7
- package/src/cli/commands/memory/__tests__/memory-v3.test.ts +128 -5
- package/src/cli/commands/memory/index.help.ts +84 -28
- package/src/cli/commands/memory/index.ts +2 -0
- package/src/cli/commands/memory/memory-v2.ts +58 -54
- package/src/cli/commands/memory/memory-v3.ts +64 -0
- package/src/cli/commands/memory/memory-validate.ts +18 -0
- package/src/cli/commands/plugins.ts +85 -36
- package/src/cli/commands/schedules.ts +35 -1
- package/src/cli/commands/stt.help.ts +27 -2
- package/src/cli/commands/trust.ts +3 -14
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +39 -0
- package/src/cli/lib/bundled-marketplace.json +14 -1
- package/src/cli/lib/upgrade-plugin.ts +42 -0
- package/src/config/__tests__/balanced-model-experiment.test.ts +278 -0
- package/src/config/__tests__/default-profile-catalog.test.ts +34 -2
- package/src/config/__tests__/default-provider.test.ts +6 -1
- package/src/config/__tests__/profile-materialization.test.ts +75 -19
- package/src/config/assistant-feature-flags.ts +36 -15
- package/src/config/balanced-model-experiment.ts +35 -0
- package/src/config/bundled-skills/acp/SKILL.md +6 -7
- package/src/config/bundled-skills/document-editor/SKILL.md +2 -2
- package/src/config/bundled-skills/document-editor/TOOLS.json +2 -2
- package/src/config/bundled-skills/image-studio/SKILL.md +5 -4
- package/src/config/bundled-skills/image-studio/TOOLS.json +1 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +101 -0
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +14 -4
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/settings/tools/navigate-settings-tab.test.ts +65 -0
- package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +7 -1
- package/src/config/bundled-skills/settings/tools/shared.ts +16 -0
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +19 -1
- package/src/config/bundled-skills/skill-management/TOOLS.json +9 -3
- package/src/config/bundled-skills/subagent/SKILL.md +17 -12
- package/src/config/bundled-skills/subagent/TOOLS.json +4 -4
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +22 -1
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +9 -2
- package/src/config/call-site-defaults.ts +11 -5
- package/src/config/default-profile-catalog.ts +179 -16
- package/src/config/default-profile-names.ts +4 -1
- package/src/config/default-provider-resolution.ts +4 -0
- package/src/config/feature-flag-registry.json +12 -12
- package/src/config/llm-context-resolution.ts +11 -3
- package/src/config/llm-resolver.ts +28 -1
- package/src/config/profile-materialization.ts +70 -22
- package/src/config/schemas/__tests__/live-voice.test.ts +107 -4
- package/src/config/schemas/call-site-catalog.ts +4 -4
- package/src/config/schemas/live-voice.ts +57 -23
- package/src/config/schemas/llm.ts +59 -32
- package/src/config/schemas/mcp.ts +23 -0
- package/src/config/schemas/plugin-updates.ts +6 -2
- package/src/config/schemas/stt.ts +1 -0
- package/src/config/skills.ts +9 -2
- package/src/context/outbound-sanitize.ts +96 -1
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +1 -1
- package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +82 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +15 -10
- package/src/daemon/conversation-agent-loop.ts +31 -19
- package/src/daemon/conversation-messaging.ts +5 -1
- package/src/daemon/conversation-notifiers.ts +20 -10
- package/src/daemon/conversation-process.ts +20 -6
- package/src/daemon/conversation-runtime-assembly.ts +12 -6
- package/src/daemon/conversation-store.ts +14 -4
- package/src/daemon/conversation-surfaces.ts +75 -26
- package/src/daemon/conversation-tool-setup.ts +3 -6
- package/src/daemon/conversation.ts +154 -51
- package/src/daemon/doordash-steps.ts +2 -2
- package/src/daemon/lifecycle.ts +14 -1
- package/src/daemon/mcp-reload-service.ts +36 -6
- package/src/daemon/process-message.ts +13 -26
- package/src/daemon/providers-setup.ts +6 -3
- package/src/daemon/trust-context-types.ts +29 -0
- package/src/daemon/trust-context.ts +12 -7
- package/src/daemon/wake-conversation-ops.ts +3 -2
- package/src/daemon/windows-compiled-entry.ts +4 -0
- package/src/documents/document-store.ts +143 -240
- package/src/hooks/hook-loader.ts +3 -3
- package/src/hooks/registry.ts +103 -45
- package/src/hooks/types.ts +5 -0
- package/src/inbound/__tests__/oauth-callback-url.test.ts +83 -0
- package/src/inbound/oauth-callback-url.ts +61 -0
- package/src/ipc/gateway-client.test.ts +1 -1
- package/src/ipc/gateway-client.ts +14 -21
- package/src/ipc/gateway-flag-listener.ts +17 -3
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +1 -104
- package/src/live-voice/__tests__/live-voice-events.test.ts +7 -8
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +1050 -0
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +115 -8
- package/src/live-voice/__tests__/live-voice-photo.test.ts +100 -0
- package/src/live-voice/__tests__/live-voice-progress.test.ts +60 -194
- package/src/live-voice/__tests__/live-voice-stt.test.ts +14 -0
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +29 -0
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +0 -483
- package/src/live-voice/__tests__/live-voice-vad.test.ts +0 -16
- package/src/live-voice/__tests__/progress-narration.test.ts +214 -0
- package/src/live-voice/live-voice-archive.ts +2 -0
- package/src/live-voice/live-voice-manager.ts +16 -3
- package/src/live-voice/live-voice-metrics.ts +57 -32
- package/src/live-voice/live-voice-photo.ts +1 -2
- package/src/live-voice/live-voice-session.ts +598 -323
- package/src/live-voice/progress-narration.ts +277 -0
- package/src/live-voice/protocol.ts +21 -1
- package/src/live-voice/windows-compiled-live-voice.ts +4 -0
- package/src/mcp/__tests__/effective-config.test.ts +238 -0
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
- package/src/mcp/__tests__/mcp-oauth-client-registration.test.ts +200 -0
- package/src/mcp/__tests__/mcp-oauth-provider.test.ts +9 -9
- package/src/mcp/__tests__/plugin-server-credential-isolation.test.ts +95 -0
- package/src/mcp/client.ts +16 -11
- package/src/mcp/effective-config.ts +113 -0
- package/src/mcp/manager.ts +11 -6
- package/src/mcp/mcp-auth-orchestrator.ts +13 -22
- package/src/mcp/mcp-oauth-provider.ts +205 -240
- package/src/monitoring/__tests__/plugin-auto-update.test.ts +166 -3
- package/src/monitoring/control.ts +1 -0
- package/src/monitoring/db-integrity-sample.ts +4 -5
- package/src/monitoring/plugin-auto-update.ts +128 -24
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/approval-card-data.ts +33 -0
- package/src/notifications/signal.ts +1 -0
- package/src/permissions/AGENTS.md +16 -0
- package/src/permissions/checker.test.ts +75 -122
- package/src/permissions/checker.ts +44 -560
- package/src/permissions/confirmation-guardian-request.test.ts +15 -11
- package/src/permissions/confirmation-guardian-request.ts +2 -2
- package/src/permissions/prompter.ts +1 -5
- package/src/permissions/question-guardian-request.test.ts +14 -6
- package/src/permissions/question-guardian-request.ts +1 -2
- package/src/persistence/attachments-store.ts +8 -1
- package/src/persistence/bookmark-crud.ts +3 -7
- package/src/persistence/conversation-attention-store.ts +16 -45
- package/src/persistence/conversation-crud.ts +33 -4
- package/src/persistence/conversation-lineage.ts +9 -0
- package/src/persistence/conversation-queries.ts +182 -52
- package/src/persistence/delivery-crud.ts +150 -36
- package/src/persistence/embeddings/qdrant-manager.ts +84 -49
- package/src/persistence/external-conversation-store.ts +32 -4
- package/src/persistence/llm-request-log-store.ts +4 -10
- package/src/persistence/llm-usage-store.ts +8 -3
- package/src/persistence/message-reads.test.ts +197 -0
- package/src/persistence/message-reads.ts +211 -0
- package/src/persistence/migrations/360-add-document-workspace-path.ts +5 -14
- package/src/persistence/migrations/366-chatgpt-subscription-row-identity.test.ts +120 -0
- package/src/persistence/migrations/366-chatgpt-subscription-row-identity.ts +62 -0
- package/src/persistence/real-user-turn-filter.ts +27 -3
- package/src/persistence/schema/documents.ts +4 -4
- package/src/persistence/steps.ts +9 -0
- package/src/plugin-api/__tests__/oauth-callback-url-export.test.ts +29 -0
- package/src/plugin-api/constants.ts +8 -0
- package/src/plugin-api/conversation-turn.ts +195 -5
- package/src/plugin-api/index.ts +38 -6
- package/src/plugin-api/resolve-credential.ts +3 -2
- package/src/plugin-api/store-credential.ts +146 -0
- package/src/plugin-api/vision-support.test.ts +1 -1
- package/src/plugin-api/webhook-url.ts +13 -11
- package/src/plugins/__tests__/mcp-servers.test.ts +371 -0
- package/src/plugins/defaults/main.ts +21 -7
- package/src/plugins/defaults/memory/AGENTS.md +15 -3
- package/src/plugins/defaults/memory/__tests__/buffer-format.test.ts +204 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +72 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +4 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +4 -1
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +0 -1
- package/src/plugins/defaults/memory/buffer-format.ts +165 -0
- package/src/plugins/defaults/memory/context-search/sources/conversations.ts +6 -0
- package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +77 -0
- package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +24 -6
- package/src/plugins/defaults/memory/graph/image-ref-utils.ts +3 -0
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +1 -30
- package/src/plugins/defaults/memory/graph-topology/pending-buffer.test.ts +34 -0
- package/src/plugins/defaults/memory/graph-topology/pending-buffer.ts +17 -24
- package/src/plugins/defaults/memory/hooks/post-compact.ts +1 -4
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +53 -5
- package/src/plugins/defaults/memory/indexer.ts +3 -1
- package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +19 -7
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +4 -4
- package/src/plugins/defaults/memory/src/__tests__/memory-v3-gate-stats.test.ts +281 -0
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +12 -10
- package/src/plugins/defaults/memory/src/memory-v3-routes.ts +207 -0
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +147 -0
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-prompt-flag-gating-guard.test.ts +8 -0
- package/src/plugins/defaults/memory/substrate/__tests__/edge-index.test.ts +0 -30
- package/src/plugins/defaults/memory/substrate/__tests__/ingest.test.ts +73 -1
- package/src/plugins/defaults/memory/substrate/__tests__/page-index.test.ts +37 -0
- package/src/plugins/defaults/memory/substrate/__tests__/page-links.test.ts +208 -0
- package/src/plugins/defaults/memory/substrate/__tests__/prompts-consolidation.test.ts +158 -1
- package/src/plugins/defaults/memory/substrate/__tests__/static-context.test.ts +195 -58
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +93 -24
- package/src/plugins/defaults/memory/substrate/edge-index.ts +0 -31
- package/src/plugins/defaults/memory/substrate/ingest.ts +59 -0
- package/src/plugins/defaults/memory/substrate/page-index.ts +35 -8
- package/src/plugins/defaults/memory/substrate/page-links.ts +133 -0
- package/src/plugins/defaults/memory/substrate/page-store.ts +10 -0
- package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +124 -34
- package/src/plugins/defaults/memory/substrate/skill-content.ts +8 -1
- package/src/plugins/defaults/memory/substrate/static-context.ts +160 -33
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +2 -4
- package/src/plugins/defaults/memory/v1/graph/extraction.ts +3 -1
- package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +18 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +66 -1
- package/src/plugins/defaults/memory/v3/card.ts +9 -9
- package/src/plugins/defaults/memory/v3/core-set.test.ts +7 -0
- package/src/plugins/defaults/memory/v3/core-set.ts +5 -1
- package/src/plugins/defaults/memory/v3/edge.ts +13 -57
- package/src/plugins/defaults/memory/v3/injector.ts +8 -0
- package/src/plugins/defaults/memory/v3/prune.ts +2 -0
- package/src/plugins/defaults/memory/v3/selection-log-store.ts +2 -0
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +23 -9
- package/src/plugins/defaults/memory/worker-control.ts +1 -0
- package/src/plugins/defaults/memory/worker.ts +6 -3
- package/src/plugins/defaults/worker-entrypoints.ts +3 -0
- package/src/plugins/external-plugin-loader.ts +47 -0
- package/src/plugins/mcp-servers.ts +361 -0
- package/src/plugins/mtime-cache.ts +37 -46
- package/src/plugins/pipeline.ts +14 -7
- package/src/plugins/plugin-execution-context.ts +35 -11
- package/src/plugins/worker-plugin-surface.ts +33 -0
- package/src/prompts/templates/system-sections.ts +0 -7
- package/src/providers/__tests__/connection-model-compat.test.ts +1 -1
- package/src/providers/__tests__/context-overflow-error.test.ts +24 -0
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +214 -2
- package/src/providers/__tests__/preflight-resolved-config.test.ts +57 -0
- package/src/providers/__tests__/retry-callsite.test.ts +25 -2
- package/src/providers/anthropic/__tests__/pause-turn-continuation.test.ts +170 -0
- package/src/providers/anthropic/client.ts +332 -241
- package/src/providers/call-site-routing.ts +30 -3
- package/src/providers/connection-resolution.ts +194 -11
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +4 -0
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/inference/auth.ts +6 -0
- package/src/providers/inference/connection-availability.ts +24 -2
- package/src/providers/inference/connections.ts +2 -0
- package/src/providers/model-catalog.ts +3 -3
- package/src/providers/model-intents.ts +28 -8
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +163 -40
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +125 -2
- package/src/providers/openai/chat-completions-provider.ts +133 -36
- package/src/providers/openai/codex-models.ts +2 -1
- package/src/providers/provider-send-message.ts +32 -3
- package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +433 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +625 -0
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +34 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +285 -6
- package/src/providers/speech-to-text/deepgram-flux-frames.ts +395 -0
- package/src/providers/speech-to-text/deepgram-flux-realtime.ts +679 -0
- package/src/providers/speech-to-text/provider-catalog.ts +99 -8
- package/src/providers/speech-to-text/resolve.ts +25 -2
- package/src/routes/control.ts +1 -0
- package/src/routes/route-host-client.ts +1 -0
- package/src/routes/route-host-protocol.ts +7 -0
- package/src/routes/worker.ts +48 -15
- package/src/runtime/AGENTS.md +16 -17
- package/src/runtime/access-request-helper.ts +9 -12
- package/src/runtime/agent-wake.ts +18 -15
- package/src/runtime/effective-capabilities.test.ts +43 -0
- package/src/runtime/effective-capabilities.ts +27 -0
- package/src/runtime/guardian-reply-router.ts +6 -2
- package/src/runtime/pre-first-message-gate.ts +4 -0
- package/src/runtime/routes/__tests__/acp-claude-auth-routes.test.ts +12 -4
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +522 -2
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +52 -0
- package/src/runtime/routes/__tests__/default-provider-routes.test.ts +61 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +44 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +102 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +132 -35
- package/src/runtime/routes/__tests__/schedule-routes-disarm-reason.test.ts +215 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +25 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +55 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher-host.test.ts +52 -1
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +133 -1
- package/src/runtime/routes/channel-availability-routes.ts +32 -14
- package/src/runtime/routes/channel-route-shared.ts +0 -6
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +6 -6
- package/src/runtime/routes/conversation-list-routes.ts +181 -23
- package/src/runtime/routes/conversation-management-routes.ts +17 -12
- package/src/runtime/routes/conversation-query-routes.ts +40 -27
- package/src/runtime/routes/conversation-routes.ts +43 -29
- package/src/runtime/routes/credential-prompt-routes.ts +4 -7
- package/src/runtime/routes/credential-routes.ts +26 -82
- package/src/runtime/routes/default-provider-routes.ts +15 -0
- package/src/runtime/routes/documents-routes.ts +3 -222
- package/src/runtime/routes/inbound-message-handler.ts +21 -45
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +0 -1
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -9
- package/src/runtime/routes/inbound-stages/admission-policy.ts +1 -17
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.test.ts +0 -1
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +2 -3
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +101 -79
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +0 -1
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +12 -7
- package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +91 -8
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +72 -79
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +2 -3
- package/src/runtime/routes/inference-profiles-routes.ts +20 -11
- package/src/runtime/routes/inference-provider-connection-routes.ts +77 -15
- package/src/runtime/routes/log-export-routes.ts +3 -0
- package/src/runtime/routes/mcp-auth-routes.ts +148 -57
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +2 -0
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +3 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -2
- package/src/runtime/routes/playground/reset-circuit.ts +1 -1
- package/src/runtime/routes/plugins-routes.ts +38 -8
- package/src/runtime/routes/schedule-routes.ts +94 -7
- package/src/runtime/routes/settings-routes.ts +6 -6
- package/src/runtime/routes/stt-routes.ts +31 -25
- package/src/runtime/routes/surface-action-routes.ts +20 -19
- package/src/runtime/routes/surface-conversation-resolver.ts +3 -0
- package/src/runtime/routes/user-route-dispatcher.ts +69 -15
- package/src/runtime/routes/user-route-import.ts +108 -0
- package/src/runtime/routes/user-route-resolution.ts +18 -1
- package/src/runtime/routes/workspace-routes.ts +0 -9
- package/src/runtime/routes/workspace-utils.ts +3 -13
- package/src/runtime/services/conversation-serializer.ts +7 -2
- package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +68 -5
- package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +81 -0
- package/src/schedule/plugin-schedule-availability.ts +58 -0
- package/src/schedule/plugin-schedule-declarations.ts +23 -27
- package/src/schedule/plugin-schedule-reconciler.ts +12 -3
- package/src/schedule/schedule-store.ts +5 -1
- package/src/schedule/scheduler.ts +9 -4
- package/src/schedule/worker-control.ts +1 -0
- package/src/schedule/worker.ts +6 -0
- package/src/security/oauth2.ts +6 -22
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +22 -0
- package/src/stt/__tests__/types.test.ts +94 -0
- package/src/stt/daemon-batch-transcriber.ts +10 -0
- package/src/stt/stt-stream-session.ts +8 -4
- package/src/stt/types.ts +103 -0
- package/src/subagent/__tests__/consult-prompt.test.ts +26 -15
- package/src/subagent/consult-context.ts +11 -11
- package/src/subagent/consult-prompt.ts +26 -35
- package/src/subagent/manager.ts +21 -40
- package/src/subagent/notify.ts +7 -1
- package/src/subagent/types.ts +15 -12
- package/src/tools/__tests__/tool-input-schemas.test.ts +7 -7
- package/src/tools/acp/spawn.test.ts +97 -0
- package/src/tools/acp/spawn.ts +38 -4
- package/src/tools/credentials/ref-parse.ts +35 -0
- package/src/tools/credentials/resolve.ts +4 -10
- package/src/tools/credentials/store.ts +168 -0
- package/src/tools/document/document-tool.ts +12 -3
- package/src/tools/executor.ts +53 -15
- package/src/tools/filesystem/read.ts +27 -10
- package/src/tools/host-filesystem/read.ts +27 -15
- package/src/tools/network/url-safety.ts +9 -16
- package/src/tools/permission-checker.ts +43 -52
- package/src/tools/registry.ts +2 -1
- package/src/tools/shared/filesystem/file-ops-service.ts +63 -35
- package/src/tools/shared/filesystem/legacy-read-args.ts +22 -0
- package/src/tools/shared/filesystem/types.ts +5 -5
- package/src/tools/skills/scaffold-managed.ts +25 -7
- package/src/tools/subagent/spawn.ts +28 -88
- package/src/tools/tool-types.ts +26 -13
- package/src/tools/types.ts +6 -6
- package/src/tools/ui-surface/surface-shape-docs.ts +12 -1
- package/src/tools/workflows/run-workflow.ts +1 -2
- package/src/tts/__tests__/reasoning-tag-filter.test.ts +78 -0
- package/src/tts/reasoning-tag-filter.ts +89 -0
- package/src/util/__tests__/worker-process-command.test.ts +37 -0
- package/src/util/logger.ts +16 -0
- package/src/util/think-tag-stream.ts +95 -0
- package/src/util/worker-process.ts +37 -4
- package/src/windows-compiled-cli.ts +32 -0
- package/src/windows-compiled-entry.ts +4 -0
- package/src/windows-compiled-logger.ts +6 -0
- package/src/windows-compiled-worker-entry.ts +29 -0
- package/src/workspace/byok-default-profile-ensure.ts +76 -24
- package/src/workspace/custom-profile-ensure.ts +4 -24
- package/src/workspace/migrations/142-consolidate-voice-front-door.ts +70 -0
- package/src/workspace/migrations/143-repair-deprecated-codex-model-id.ts +134 -0
- package/src/workspace/migrations/144-convert-stranded-subscription-openai-profiles.ts +265 -0
- package/src/workspace/migrations/145-collapse-profile-bindings-to-entries.ts +328 -0
- package/src/workspace/migrations/146-repair-retired-fireworks-deepseek-flash-model-id.ts +195 -0
- package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +0 -10
- package/src/workspace/migrations/registry.ts +10 -0
- package/src/workspace/provider-commit-message-generator.ts +7 -5
- package/src/__tests__/document-workspace-file.test.ts +0 -467
- package/src/live-voice/__tests__/front-decision.test.ts +0 -645
- package/src/live-voice/front-decision.ts +0 -476
- package/src/permissions/ipc-risk-types.ts +0 -143
- package/src/permissions/risk-types.ts +0 -76
- package/src/subagent/__tests__/consult-transcript.test.ts +0 -184
- package/src/subagent/consult-transcript.ts +0 -90
|
@@ -85,6 +85,8 @@ import type {
|
|
|
85
85
|
} from "./message-protocol.js";
|
|
86
86
|
import { INTERACTIVE_SURFACE_TYPES } from "./message-protocol.js";
|
|
87
87
|
import { isRowVisibleToUntrustedActor } from "./message-provenance.js";
|
|
88
|
+
import type { TrustContext } from "./trust-context-types.js";
|
|
89
|
+
import { restingTrust } from "./trust-context-types.js";
|
|
88
90
|
export {
|
|
89
91
|
buildSurfaceShowPair,
|
|
90
92
|
type CurrentTurnSurface,
|
|
@@ -138,16 +140,40 @@ const ModelActionSchema = SurfaceActionSchema.extend({
|
|
|
138
140
|
|
|
139
141
|
const MAX_UNDO_DEPTH = 10;
|
|
140
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Whether a surface-action turn (a user clicked a button or submitted a form on
|
|
145
|
+
* a UI surface) runs with a human declared present. The handler does not yet
|
|
146
|
+
* learn the actor's interface, so it cannot declare presence the way the send
|
|
147
|
+
* route does; the turn runs non-interactive, which is what the state-derived
|
|
148
|
+
* fallback resolved to between turns. Deriving it from the actor's interface
|
|
149
|
+
* is a policy change tracked separately.
|
|
150
|
+
*/
|
|
151
|
+
const SURFACE_ACTION_TURN_IS_INTERACTIVE = false;
|
|
152
|
+
|
|
141
153
|
/**
|
|
142
154
|
* Pending surface types that do not hold the one-interactive-surface-at-a-time
|
|
143
|
-
* lock.
|
|
144
|
-
* answer, so a live one must not block the next
|
|
155
|
+
* lock. Each renders content the user reads (or settles on its own) rather
|
|
156
|
+
* than a question they must answer, so a live one must not block the next
|
|
157
|
+
* surface.
|
|
145
158
|
*/
|
|
146
159
|
const NON_BLOCKING_PENDING_SURFACE_TYPES = new Set<SurfaceType>([
|
|
147
160
|
"dynamic_page",
|
|
148
161
|
"visual",
|
|
162
|
+
"voice_picker",
|
|
149
163
|
]);
|
|
150
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Surface types that carry no terminal action: the card settles when the user
|
|
167
|
+
* interacts with it, so no click could ever satisfy an attached `actions`
|
|
168
|
+
* entry or an explicit `await_action`. Both are generic ui_show params though,
|
|
169
|
+
* so nothing stops the model attaching them here, and doing so wedges the
|
|
170
|
+
* turn: the client latches `awaiting_user_input` on the presence of actions
|
|
171
|
+
* alone and no action ever arrives to clear it, leaving the composer disabled
|
|
172
|
+
* and Stop hidden while the daemon is still streaming. Stripping them makes
|
|
173
|
+
* the "never blocks a turn" contract structural rather than advisory.
|
|
174
|
+
*/
|
|
175
|
+
const ACTIONLESS_SURFACE_TYPES = new Set<SurfaceType>(["voice_picker"]);
|
|
176
|
+
|
|
151
177
|
/**
|
|
152
178
|
* Debounce window for persisting `ui_surface_update` data back to the
|
|
153
179
|
* message row. Surfaces typically receive bursts of updates (e.g. a
|
|
@@ -1358,7 +1384,7 @@ export function openChannelSetupPanel(
|
|
|
1358
1384
|
data: safeParseSurfaceData("channel_setup", data) ?? {},
|
|
1359
1385
|
});
|
|
1360
1386
|
|
|
1361
|
-
ctx.
|
|
1387
|
+
ctx.emit({
|
|
1362
1388
|
type: "open_panel",
|
|
1363
1389
|
panelType: "channel_setup",
|
|
1364
1390
|
data,
|
|
@@ -1496,7 +1522,7 @@ function pushUndoState(
|
|
|
1496
1522
|
export function handleSurfaceUndo(ctx: Conversation, surfaceId: string): void {
|
|
1497
1523
|
const stack = ctx.surfaceUndoStacks.get(surfaceId);
|
|
1498
1524
|
if (!stack || stack.length === 0) {
|
|
1499
|
-
ctx.
|
|
1525
|
+
ctx.emit({
|
|
1500
1526
|
type: "ui_surface_undo_result",
|
|
1501
1527
|
conversationId: ctx.conversationId,
|
|
1502
1528
|
surfaceId,
|
|
@@ -1509,7 +1535,7 @@ export function handleSurfaceUndo(ctx: Conversation, surfaceId: string): void {
|
|
|
1509
1535
|
const previousHtml = stack.pop()!;
|
|
1510
1536
|
const stored = ctx.surfaceState.get(surfaceId);
|
|
1511
1537
|
if (!stored || stored.surfaceType !== "dynamic_page") {
|
|
1512
|
-
ctx.
|
|
1538
|
+
ctx.emit({
|
|
1513
1539
|
type: "ui_surface_undo_result",
|
|
1514
1540
|
conversationId: ctx.conversationId,
|
|
1515
1541
|
surfaceId,
|
|
@@ -1543,7 +1569,7 @@ export function handleSurfaceUndo(ctx: Conversation, surfaceId: string): void {
|
|
|
1543
1569
|
html: previousHtml,
|
|
1544
1570
|
};
|
|
1545
1571
|
s.data = revertedData;
|
|
1546
|
-
ctx.
|
|
1572
|
+
ctx.emit({
|
|
1547
1573
|
type: "ui_surface_update",
|
|
1548
1574
|
conversationId: ctx.conversationId,
|
|
1549
1575
|
surfaceId: sid,
|
|
@@ -1580,7 +1606,7 @@ export function handleSurfaceUndo(ctx: Conversation, surfaceId: string): void {
|
|
|
1580
1606
|
html: previousHtml,
|
|
1581
1607
|
};
|
|
1582
1608
|
stored.data = revertedData;
|
|
1583
|
-
ctx.
|
|
1609
|
+
ctx.emit({
|
|
1584
1610
|
type: "ui_surface_update",
|
|
1585
1611
|
conversationId: ctx.conversationId,
|
|
1586
1612
|
surfaceId,
|
|
@@ -1588,7 +1614,7 @@ export function handleSurfaceUndo(ctx: Conversation, surfaceId: string): void {
|
|
|
1588
1614
|
});
|
|
1589
1615
|
}
|
|
1590
1616
|
|
|
1591
|
-
ctx.
|
|
1617
|
+
ctx.emit({
|
|
1592
1618
|
type: "ui_surface_undo_result",
|
|
1593
1619
|
conversationId: ctx.conversationId,
|
|
1594
1620
|
surfaceId,
|
|
@@ -1880,7 +1906,13 @@ export async function handleSurfaceAction(
|
|
|
1880
1906
|
// reconstruct the same-user binding for host proxies (CU / app-control),
|
|
1881
1907
|
// mirroring the normal message path.
|
|
1882
1908
|
sourceActorPrincipalId?: string,
|
|
1909
|
+
// Trust of the actor committing this action, resolved by the route from the
|
|
1910
|
+
// verified requester. Passed rather than read back off the conversation so a
|
|
1911
|
+
// click that lands mid-turn is attributed to its clicker instead of to
|
|
1912
|
+
// whoever occupies the resting slot.
|
|
1913
|
+
requesterTrustContext?: TrustContext,
|
|
1883
1914
|
): Promise<SurfaceActionResult> {
|
|
1915
|
+
const actionTrustContext = requesterTrustContext ?? restingTrust(ctx);
|
|
1884
1916
|
// ── Standalone surface interception ──────────────────────────────
|
|
1885
1917
|
// Daemon-driven surfaces (from `requestInteractiveUi`) register a
|
|
1886
1918
|
// pending entry in `pendingStandaloneSurfaces`. When the user clicks
|
|
@@ -2026,7 +2058,7 @@ export async function handleSurfaceAction(
|
|
|
2026
2058
|
// `await` resolves as soon as the conversation is created + titled +
|
|
2027
2059
|
// published to the event hub. The HTTP POST /v1/surface-actions
|
|
2028
2060
|
// response returns promptly — the seed turn runs in the background.
|
|
2029
|
-
const originTrustContext =
|
|
2061
|
+
const originTrustContext = actionTrustContext;
|
|
2030
2062
|
const { conversationId } = await launchConversation({
|
|
2031
2063
|
title,
|
|
2032
2064
|
seedPrompt,
|
|
@@ -2045,14 +2077,11 @@ export async function handleSurfaceAction(
|
|
|
2045
2077
|
return { accepted: true, conversationId };
|
|
2046
2078
|
}
|
|
2047
2079
|
|
|
2048
|
-
// Trust of the actor committing THIS action
|
|
2049
|
-
//
|
|
2050
|
-
//
|
|
2051
|
-
// the same value, so the completion path's persisted read stays scoped to
|
|
2052
|
-
// exactly what this actor's live view would have held. Unresolvable trust
|
|
2053
|
-
// fails closed to the untrusted filter.
|
|
2080
|
+
// Trust of the actor committing THIS action, so the completion path's
|
|
2081
|
+
// persisted read stays scoped to exactly what this actor's live view would
|
|
2082
|
+
// have held. Unresolvable trust fails closed to the untrusted filter.
|
|
2054
2083
|
const requesterCanAccessMemory = resolveCapabilities(
|
|
2055
|
-
|
|
2084
|
+
actionTrustContext?.trustClass,
|
|
2056
2085
|
).canAccessMemory;
|
|
2057
2086
|
|
|
2058
2087
|
const pending = ctx.pendingSurfaceActions.get(surfaceId);
|
|
@@ -2198,6 +2227,8 @@ export async function handleSurfaceAction(
|
|
|
2198
2227
|
activeSurfaceId: surfaceId,
|
|
2199
2228
|
displayContent,
|
|
2200
2229
|
sourceActorPrincipalId,
|
|
2230
|
+
trustContext: actionTrustContext,
|
|
2231
|
+
isInteractive: SURFACE_ACTION_TURN_IS_INTERACTIVE,
|
|
2201
2232
|
// Rides the metadata bag rather than a typed option: the queue
|
|
2202
2233
|
// round-trips `metadata` but not `PersistMessageOptions`.
|
|
2203
2234
|
metadata: { scripted: isSyntheticSurfaceActionContent(content) },
|
|
@@ -2260,6 +2291,10 @@ export async function handleSurfaceAction(
|
|
|
2260
2291
|
activeSurfaceId: surfaceId,
|
|
2261
2292
|
displayContent,
|
|
2262
2293
|
sourceActorPrincipalId,
|
|
2294
|
+
// Reached only when `enqueueMessage` declined to queue: the click is
|
|
2295
|
+
// starting this turn, so it is the actor the run belongs to.
|
|
2296
|
+
trustContext: actionTrustContext,
|
|
2297
|
+
isInteractive: SURFACE_ACTION_TURN_IS_INTERACTIVE,
|
|
2263
2298
|
scripted: isSyntheticSurfaceActionContent(content),
|
|
2264
2299
|
})
|
|
2265
2300
|
.catch((err) => {
|
|
@@ -2446,6 +2481,8 @@ export async function handleSurfaceAction(
|
|
|
2446
2481
|
activeSurfaceId: surfaceId,
|
|
2447
2482
|
displayContent,
|
|
2448
2483
|
sourceActorPrincipalId,
|
|
2484
|
+
trustContext: actionTrustContext,
|
|
2485
|
+
isInteractive: SURFACE_ACTION_TURN_IS_INTERACTIVE,
|
|
2449
2486
|
// Rides the metadata bag rather than a typed option: the queue
|
|
2450
2487
|
// round-trips `metadata` but not `PersistMessageOptions`.
|
|
2451
2488
|
metadata: { scripted: isSyntheticSurfaceActionContent(content) },
|
|
@@ -2518,6 +2555,10 @@ export async function handleSurfaceAction(
|
|
|
2518
2555
|
activeSurfaceId: surfaceId,
|
|
2519
2556
|
displayContent,
|
|
2520
2557
|
sourceActorPrincipalId,
|
|
2558
|
+
// Same as the history-restored branch: the enqueue declined, so this
|
|
2559
|
+
// click is the turn about to run.
|
|
2560
|
+
trustContext: actionTrustContext,
|
|
2561
|
+
isInteractive: SURFACE_ACTION_TURN_IS_INTERACTIVE,
|
|
2521
2562
|
scripted: isSyntheticSurfaceActionContent(content),
|
|
2522
2563
|
})
|
|
2523
2564
|
.catch((err) => {
|
|
@@ -2582,7 +2623,7 @@ export function refreshSurfacesForApp(
|
|
|
2582
2623
|
}
|
|
2583
2624
|
|
|
2584
2625
|
// Push the update to the client
|
|
2585
|
-
ctx.
|
|
2626
|
+
ctx.emit({
|
|
2586
2627
|
type: "ui_surface_update",
|
|
2587
2628
|
conversationId: ctx.conversationId,
|
|
2588
2629
|
surfaceId,
|
|
@@ -3279,8 +3320,12 @@ export async function surfaceProxyResolver(
|
|
|
3279
3320
|
}
|
|
3280
3321
|
inputActions = valid.length > 0 ? valid : undefined;
|
|
3281
3322
|
}
|
|
3282
|
-
const
|
|
3283
|
-
|
|
3323
|
+
const isActionless = ACTIONLESS_SURFACE_TYPES.has(surfaceType);
|
|
3324
|
+
const actions = isActionless
|
|
3325
|
+
? undefined
|
|
3326
|
+
: choiceData !== undefined
|
|
3327
|
+
? buildChoiceActions(choiceData)
|
|
3328
|
+
: inputActions;
|
|
3284
3329
|
const hasActions = Array.isArray(actions) && actions.length > 0;
|
|
3285
3330
|
if (surfaceType === "choice" && !hasActions) {
|
|
3286
3331
|
return {
|
|
@@ -3332,7 +3377,11 @@ export async function surfaceProxyResolver(
|
|
|
3332
3377
|
: surfaceType === "table"
|
|
3333
3378
|
? hasActions
|
|
3334
3379
|
: INTERACTIVE_SURFACE_TYPES.includes(surfaceType);
|
|
3335
|
-
|
|
3380
|
+
// An explicit `await_action: true` is honored for every other type; an
|
|
3381
|
+
// actionless surface has nothing to await, so it is forced false.
|
|
3382
|
+
const awaitAction = isActionless
|
|
3383
|
+
? false
|
|
3384
|
+
: ((input.await_action as boolean) ?? isInteractive);
|
|
3336
3385
|
|
|
3337
3386
|
// Only one non-persistent interactive surface at a time. If another
|
|
3338
3387
|
// surface is already awaiting user input, reject this one so the LLM
|
|
@@ -3411,7 +3460,7 @@ export async function surfaceProxyResolver(
|
|
|
3411
3460
|
"Sending ui_surface_show to client",
|
|
3412
3461
|
);
|
|
3413
3462
|
|
|
3414
|
-
ctx.
|
|
3463
|
+
ctx.emit({
|
|
3415
3464
|
type: "ui_surface_show",
|
|
3416
3465
|
conversationId: ctx.conversationId,
|
|
3417
3466
|
surfaceId,
|
|
@@ -3530,7 +3579,7 @@ export async function surfaceProxyResolver(
|
|
|
3530
3579
|
mergedData = patch;
|
|
3531
3580
|
}
|
|
3532
3581
|
|
|
3533
|
-
ctx.
|
|
3582
|
+
ctx.emit({
|
|
3534
3583
|
type: "ui_surface_update",
|
|
3535
3584
|
conversationId: ctx.conversationId,
|
|
3536
3585
|
surfaceId,
|
|
@@ -3588,7 +3637,7 @@ export async function surfaceProxyResolver(
|
|
|
3588
3637
|
isError: true,
|
|
3589
3638
|
};
|
|
3590
3639
|
}
|
|
3591
|
-
ctx.
|
|
3640
|
+
ctx.emit({
|
|
3592
3641
|
type: "ui_surface_complete",
|
|
3593
3642
|
conversationId: ctx.conversationId,
|
|
3594
3643
|
surfaceId,
|
|
@@ -3596,7 +3645,7 @@ export async function surfaceProxyResolver(
|
|
|
3596
3645
|
submittedData: lastAction.data,
|
|
3597
3646
|
});
|
|
3598
3647
|
} else {
|
|
3599
|
-
ctx.
|
|
3648
|
+
ctx.emit({
|
|
3600
3649
|
type: "ui_surface_dismiss",
|
|
3601
3650
|
conversationId: ctx.conversationId,
|
|
3602
3651
|
surfaceId,
|
|
@@ -3698,7 +3747,7 @@ export async function surfaceProxyResolver(
|
|
|
3698
3747
|
// Inline-only preview card emitted during app_create — do not open a
|
|
3699
3748
|
// workspace panel and do not register surface state. The client renders
|
|
3700
3749
|
// this as a tappable inline card that opens the app on demand.
|
|
3701
|
-
ctx.
|
|
3750
|
+
ctx.emit({
|
|
3702
3751
|
type: "ui_surface_show",
|
|
3703
3752
|
conversationId: ctx.conversationId,
|
|
3704
3753
|
surfaceId,
|
|
@@ -3728,7 +3777,7 @@ export async function surfaceProxyResolver(
|
|
|
3728
3777
|
title: app.name,
|
|
3729
3778
|
});
|
|
3730
3779
|
|
|
3731
|
-
ctx.
|
|
3780
|
+
ctx.emit({
|
|
3732
3781
|
type: "ui_surface_show",
|
|
3733
3782
|
conversationId: ctx.conversationId,
|
|
3734
3783
|
surfaceId,
|
|
@@ -245,9 +245,7 @@ export function createToolExecutor(
|
|
|
245
245
|
toolUseId?: string,
|
|
246
246
|
) => Promise<ToolExecutionResult> {
|
|
247
247
|
// Register the conversation's sendToClient for browser screencast surface messages
|
|
248
|
-
registerConversationSender(ctx.conversationId, (msg) =>
|
|
249
|
-
ctx.sendToClient(msg),
|
|
250
|
-
);
|
|
248
|
+
registerConversationSender(ctx.conversationId, (msg) => ctx.emit(msg));
|
|
251
249
|
|
|
252
250
|
// Execution-layer allowlist gate (`subagentToolGateMode === "execution"`,
|
|
253
251
|
// see {@link SubagentToolGateMode}): rejects non-allowlisted calls BEFORE
|
|
@@ -389,8 +387,7 @@ export function createToolExecutor(
|
|
|
389
387
|
// Per-turn trust snapshot: prefer the snapshot captured at turn start so
|
|
390
388
|
// a concurrent owner meta command (/status, /clean) that mutates the live
|
|
391
389
|
// trustContext cannot elevate the in-flight turn to guardian.
|
|
392
|
-
const turnTrust =
|
|
393
|
-
ctx.currentTurnTrustContext ?? ctx.trustContext ?? FALLBACK_TURN_TRUST;
|
|
390
|
+
const turnTrust = ctx.getTurnOrRestingTrust() ?? FALLBACK_TURN_TRUST;
|
|
394
391
|
|
|
395
392
|
const toolContext: ToolContext = {
|
|
396
393
|
workingDir: ctx.workingDir,
|
|
@@ -441,7 +438,7 @@ export function createToolExecutor(
|
|
|
441
438
|
sendToClient: (msg) => {
|
|
442
439
|
// Tool context's sendToClient uses a loose { type: string; [key: string]: unknown }
|
|
443
440
|
// signature, but at runtime these are always AssistantEvent instances.
|
|
444
|
-
ctx.
|
|
441
|
+
ctx.emit(msg as AssistantEvent);
|
|
445
442
|
if (msg.type === "ui_surface_show") {
|
|
446
443
|
// The tool-context sendToClient signature is loose, so the show
|
|
447
444
|
// message's fields are untyped here; map them through the same
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
derefToolResultReReads,
|
|
42
42
|
postTurnTruncateToolResults,
|
|
43
43
|
} from "../context/post-turn-tool-result-truncation.js";
|
|
44
|
+
import { isGuardianCardRow } from "../notifications/approval-card-data.js";
|
|
44
45
|
import { PermissionPrompter } from "../permissions/prompter.js";
|
|
45
46
|
import { SecretPrompter } from "../permissions/secret-prompter.js";
|
|
46
47
|
import type { UserDecision } from "../permissions/types.js";
|
|
@@ -319,7 +320,21 @@ export class Conversation {
|
|
|
319
320
|
/** @internal */ prompter: PermissionPrompter;
|
|
320
321
|
/** @internal */ secretPrompter: SecretPrompter;
|
|
321
322
|
private executor: ToolExecutor;
|
|
322
|
-
/**
|
|
323
|
+
/**
|
|
324
|
+
* The conversation's event sink, fixed for its whole life. Top-level
|
|
325
|
+
* conversations deliver to the SSE hub, so every subscribed client sees
|
|
326
|
+
* every event without any per-turn wiring; a subagent's sink re-envelopes
|
|
327
|
+
* its events under the parent conversation. Reached only through
|
|
328
|
+
* {@link emit}, which also notifies {@link addEventObserver} observers.
|
|
329
|
+
*/
|
|
330
|
+
private readonly sendToClient: (msg: AssistantEvent) => void;
|
|
331
|
+
/**
|
|
332
|
+
* Observers notified after every {@link emit}, in registration order. An
|
|
333
|
+
* observer sees the event after the sink delivered it, so anything it does
|
|
334
|
+
* in response (e.g. voice auto-resolving a confirmation) lands on the wire
|
|
335
|
+
* after the event itself.
|
|
336
|
+
*/
|
|
337
|
+
private readonly eventObservers = new Set<(msg: AssistantEvent) => void>();
|
|
323
338
|
/** @internal */ workingDir: string;
|
|
324
339
|
/** @internal */ allowedToolNames?: Set<string>;
|
|
325
340
|
/**
|
|
@@ -435,7 +450,18 @@ export class Conversation {
|
|
|
435
450
|
* @internal
|
|
436
451
|
*/
|
|
437
452
|
currentCallSite?: LLMCallSite;
|
|
438
|
-
/**
|
|
453
|
+
/**
|
|
454
|
+
* Whether no human is present to see UI or answer prompts. Derived from the
|
|
455
|
+
* in-flight turn's interactivity ({@link currentTurnIsNonInteractive}); a
|
|
456
|
+
* conversation with no turn in flight has no client. Presence is a property
|
|
457
|
+
* of the turn, never of where events are delivered, so there is no setter:
|
|
458
|
+
* dispatch paths declare interactivity per turn (`isInteractive` on
|
|
459
|
+
* `runAgentLoop`, or a wake's pin), and this reads it.
|
|
460
|
+
* @internal
|
|
461
|
+
*/
|
|
462
|
+
get hasNoClient(): boolean {
|
|
463
|
+
return this.currentTurnIsNonInteractive ?? true;
|
|
464
|
+
}
|
|
439
465
|
/**
|
|
440
466
|
* For subagent conversations, the id of the parent that spawned this one; set
|
|
441
467
|
* once at construction and never reassigned. `undefined` for top-level
|
|
@@ -757,10 +783,10 @@ export class Conversation {
|
|
|
757
783
|
this.workingDir = workingDir;
|
|
758
784
|
this.sendToClient = sendToClient;
|
|
759
785
|
this.graphMemory = new ConversationGraphMemory(conversationId);
|
|
760
|
-
|
|
786
|
+
// The prompter emits through the conversation so its confirmation_request
|
|
787
|
+
// reaches the sink and every observer (voice policy) like any other event.
|
|
788
|
+
this.prompter = new PermissionPrompter((msg) => this.emit(msg));
|
|
761
789
|
this.prompter.setOnStateChanged((requestId, state, source, toolUseId) => {
|
|
762
|
-
// Route through emitConfirmationStateChanged so the event reaches
|
|
763
|
-
// the client via sendToClient (wired to the SSE hub for HTTP conversations).
|
|
764
790
|
this.emitConfirmationStateChanged({
|
|
765
791
|
conversationId: this.conversationId,
|
|
766
792
|
requestId,
|
|
@@ -1316,6 +1342,16 @@ export class Conversation {
|
|
|
1316
1342
|
parsedMessages.length,
|
|
1317
1343
|
);
|
|
1318
1344
|
for (const [index, message] of parsedMessages.entries()) {
|
|
1345
|
+
// Applied after the compaction slice, never before it: the slice and
|
|
1346
|
+
// `rowToHistoryIndex` are both computed against the full row list, so
|
|
1347
|
+
// dropping earlier would shift them. A dropped row maps to a null
|
|
1348
|
+
// history index exactly like a fully-injected user row that strips to
|
|
1349
|
+
// nothing. `index` is shared with `slicedDbMessages`, which
|
|
1350
|
+
// `parsedMessages` maps 1:1.
|
|
1351
|
+
if (isGuardianCardRow(slicedDbMessages[index]?.content)) {
|
|
1352
|
+
preRepairIndexBySlicedRow[index] = null;
|
|
1353
|
+
continue;
|
|
1354
|
+
}
|
|
1319
1355
|
const stripped =
|
|
1320
1356
|
index < preStrippedCount
|
|
1321
1357
|
? stripInjectionsForCompaction([message])
|
|
@@ -1418,7 +1454,7 @@ export class Conversation {
|
|
|
1418
1454
|
messageCount: this.messages.length,
|
|
1419
1455
|
});
|
|
1420
1456
|
|
|
1421
|
-
this.restoreSurfaceStateFromHistory();
|
|
1457
|
+
this.restoreSurfaceStateFromHistory(parsedMessages);
|
|
1422
1458
|
this.graphMemory.restoreState();
|
|
1423
1459
|
|
|
1424
1460
|
// Row→history correspondence for this load: slice offset, then the
|
|
@@ -1450,14 +1486,19 @@ export class Conversation {
|
|
|
1450
1486
|
* populate surfaceState so that findConversationBySurfaceId works for
|
|
1451
1487
|
* surfaces restored from history (e.g. after daemon restart).
|
|
1452
1488
|
*
|
|
1453
|
-
*
|
|
1454
|
-
*
|
|
1455
|
-
*
|
|
1456
|
-
*
|
|
1489
|
+
* Scans the live (non-compacted) window only, never all DB rows, because
|
|
1490
|
+
* surface IDs are not globally unique and restoring stale compacted
|
|
1491
|
+
* surfaces would let findConversationBySurfaceId route actions to the wrong
|
|
1492
|
+
* conversation.
|
|
1493
|
+
*
|
|
1494
|
+
* Takes that window as rows rather than reading `this.messages`, because a
|
|
1495
|
+
* surface's lifecycle and the model's context are different questions. A
|
|
1496
|
+
* guardian card is absent from `this.messages`, but it is exactly the card
|
|
1497
|
+
* whose Approve/Reject buttons must still route after a restart.
|
|
1457
1498
|
*/
|
|
1458
|
-
private restoreSurfaceStateFromHistory(): void {
|
|
1499
|
+
private restoreSurfaceStateFromHistory(liveWindow: Message[]): void {
|
|
1459
1500
|
this.surfaceState.clear();
|
|
1460
|
-
for (const msg of
|
|
1501
|
+
for (const msg of liveWindow) {
|
|
1461
1502
|
if (!Array.isArray(msg.content)) {
|
|
1462
1503
|
continue;
|
|
1463
1504
|
}
|
|
@@ -1489,31 +1530,55 @@ export class Conversation {
|
|
|
1489
1530
|
await this.loadFromDb();
|
|
1490
1531
|
}
|
|
1491
1532
|
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1533
|
+
/**
|
|
1534
|
+
* Deliver an event through the conversation's sink, then to every observer.
|
|
1535
|
+
* The single emission point for conversation-level events (activity state,
|
|
1536
|
+
* confirmation prompts and state, notifier output, out-of-turn pushes); the
|
|
1537
|
+
* agent loop's own stream rides its per-turn `onEvent`, which defaults to
|
|
1538
|
+
* this when the caller passes none.
|
|
1539
|
+
*/
|
|
1540
|
+
readonly emit = (msg: AssistantEvent): void => {
|
|
1541
|
+
try {
|
|
1542
|
+
this.sendToClient(msg);
|
|
1543
|
+
} catch (err) {
|
|
1544
|
+
log.warn(
|
|
1545
|
+
{ err, conversationId: this.conversationId, type: msg.type },
|
|
1546
|
+
"conversation sink threw",
|
|
1547
|
+
);
|
|
1548
|
+
}
|
|
1549
|
+
for (const observer of this.eventObservers) {
|
|
1503
1550
|
try {
|
|
1504
|
-
|
|
1551
|
+
observer(msg);
|
|
1505
1552
|
} catch (err) {
|
|
1506
1553
|
log.warn(
|
|
1507
|
-
{ err, conversationId: this.conversationId },
|
|
1508
|
-
"
|
|
1554
|
+
{ err, conversationId: this.conversationId, type: msg.type },
|
|
1555
|
+
"conversation event observer threw",
|
|
1509
1556
|
);
|
|
1510
1557
|
}
|
|
1511
1558
|
}
|
|
1559
|
+
};
|
|
1560
|
+
|
|
1561
|
+
/**
|
|
1562
|
+
* Observe every event this conversation emits, after the sink delivered it.
|
|
1563
|
+
* For policy layered on delivery (voice auto-resolves approval prompts it
|
|
1564
|
+
* has no UI for), not for delivery itself. Returns the disposer.
|
|
1565
|
+
*/
|
|
1566
|
+
addEventObserver(observer: (msg: AssistantEvent) => void): () => void {
|
|
1567
|
+
this.eventObservers.add(observer);
|
|
1568
|
+
return () => {
|
|
1569
|
+
this.eventObservers.delete(observer);
|
|
1570
|
+
};
|
|
1512
1571
|
}
|
|
1513
1572
|
|
|
1514
|
-
/**
|
|
1515
|
-
|
|
1516
|
-
|
|
1573
|
+
/**
|
|
1574
|
+
* Re-emit the last activity state so a client that reconnected mid-phase
|
|
1575
|
+
* sees the current phase instead of the last one it received before
|
|
1576
|
+
* disconnecting. The send route calls this on every interactive send.
|
|
1577
|
+
*/
|
|
1578
|
+
replayActivityState(): void {
|
|
1579
|
+
if (this.lastActivityStateMsg) {
|
|
1580
|
+
this.emit(this.lastActivityStateMsg);
|
|
1581
|
+
}
|
|
1517
1582
|
}
|
|
1518
1583
|
|
|
1519
1584
|
setSubagentAllowedTools(tools: Set<string> | undefined): void {
|
|
@@ -1801,7 +1866,7 @@ export class Conversation {
|
|
|
1801
1866
|
} {
|
|
1802
1867
|
return enqueueMessageImpl(this, {
|
|
1803
1868
|
...options,
|
|
1804
|
-
onEvent: options.onEvent ?? this.
|
|
1869
|
+
onEvent: options.onEvent ?? this.emit,
|
|
1805
1870
|
});
|
|
1806
1871
|
}
|
|
1807
1872
|
|
|
@@ -1976,14 +2041,7 @@ export class Conversation {
|
|
|
1976
2041
|
type: "confirmation_state_changed",
|
|
1977
2042
|
...params,
|
|
1978
2043
|
} as AssistantEvent;
|
|
1979
|
-
|
|
1980
|
-
this.sendToClient(msg);
|
|
1981
|
-
} catch (err) {
|
|
1982
|
-
log.warn(
|
|
1983
|
-
{ err, conversationId: this.conversationId },
|
|
1984
|
-
"sendToClient threw in emitConfirmationStateChanged",
|
|
1985
|
-
);
|
|
1986
|
-
}
|
|
2044
|
+
this.emit(msg);
|
|
1987
2045
|
}
|
|
1988
2046
|
|
|
1989
2047
|
emitActivityState(
|
|
@@ -2008,14 +2066,7 @@ export class Conversation {
|
|
|
2008
2066
|
...(statusText ? { statusText } : {}),
|
|
2009
2067
|
} as AssistantEvent;
|
|
2010
2068
|
this.lastActivityStateMsg = msg;
|
|
2011
|
-
|
|
2012
|
-
this.sendToClient(msg);
|
|
2013
|
-
} catch (err) {
|
|
2014
|
-
log.warn(
|
|
2015
|
-
{ err, conversationId: this.conversationId },
|
|
2016
|
-
"sendToClient threw in emitActivityState",
|
|
2017
|
-
);
|
|
2018
|
-
}
|
|
2069
|
+
this.emit(msg);
|
|
2019
2070
|
}
|
|
2020
2071
|
|
|
2021
2072
|
/**
|
|
@@ -2069,7 +2120,7 @@ export class Conversation {
|
|
|
2069
2120
|
onEvent?: (msg: AssistantEvent) => void,
|
|
2070
2121
|
): void {
|
|
2071
2122
|
try {
|
|
2072
|
-
(onEvent ?? this.
|
|
2123
|
+
(onEvent ?? this.emit)({
|
|
2073
2124
|
type: "context_window_usage",
|
|
2074
2125
|
conversationId: this.conversationId,
|
|
2075
2126
|
tokens,
|
|
@@ -2421,11 +2472,11 @@ export class Conversation {
|
|
|
2421
2472
|
) {
|
|
2422
2473
|
await this.agentLoop.compactionCircuit.recordOutcome(
|
|
2423
2474
|
result.summaryFailed,
|
|
2424
|
-
this.
|
|
2475
|
+
this.emit,
|
|
2425
2476
|
);
|
|
2426
2477
|
}
|
|
2427
2478
|
if (result.compacted) {
|
|
2428
|
-
await applyCompactionResult(this, result, this.
|
|
2479
|
+
await applyCompactionResult(this, result, this.emit, null, {
|
|
2429
2480
|
slackContextCompactionWatermarkTs:
|
|
2430
2481
|
fixedBoundarySlackWatermarkTs ??
|
|
2431
2482
|
getSlackCompactionWatermarkForPrefix(
|
|
@@ -2488,6 +2539,54 @@ export class Conversation {
|
|
|
2488
2539
|
return this.authContext;
|
|
2489
2540
|
}
|
|
2490
2541
|
|
|
2542
|
+
/**
|
|
2543
|
+
* Trust the in-flight turn is executing under.
|
|
2544
|
+
*
|
|
2545
|
+
* Use this for authorization and for routing a reply to the requester:
|
|
2546
|
+
* cases where substituting the conversation's owner would be wrong rather
|
|
2547
|
+
* than approximate. Provenance is not such a case; see
|
|
2548
|
+
* {@link getTurnOrRestingTrust} and `docs/architecture/turn-actor.md`.
|
|
2549
|
+
*
|
|
2550
|
+
* `undefined` when no turn recorded one, which is a gap in the entry point
|
|
2551
|
+
* rather than an answer. Deliberately does not fall back to the
|
|
2552
|
+
* conversation's trust: a caller that can accept the conversation's owner
|
|
2553
|
+
* instead spells `?? getTrustContext()`, so the substitution is visible
|
|
2554
|
+
* where it happens.
|
|
2555
|
+
*/
|
|
2556
|
+
getTurnTrust(): TrustContext | undefined {
|
|
2557
|
+
return this.currentTurnTrustContext;
|
|
2558
|
+
}
|
|
2559
|
+
|
|
2560
|
+
/**
|
|
2561
|
+
* Trust of the actor the conversation belongs to, independent of any turn.
|
|
2562
|
+
*
|
|
2563
|
+
* Use this where there is no turn to speak of: routes reporting on a
|
|
2564
|
+
* conversation, hydration, and persisting conversation-level options. A
|
|
2565
|
+
* caller that wants the conversation's owner *rather than* whoever is
|
|
2566
|
+
* currently acting should be obviously doing so; if it is not obvious,
|
|
2567
|
+
* {@link getTurnTrust} is probably the one meant.
|
|
2568
|
+
*/
|
|
2569
|
+
getTrustContext(): TrustContext | undefined {
|
|
2570
|
+
return this.trustContext;
|
|
2571
|
+
}
|
|
2572
|
+
|
|
2573
|
+
/**
|
|
2574
|
+
* Trust of the in-flight turn, or the conversation's owner when the turn
|
|
2575
|
+
* recorded none. The substitution is in the name: callers that can accept
|
|
2576
|
+
* the owner as a stand-in ask this, including provenance stamping, whose
|
|
2577
|
+
* readers treat an absent trust class as more trusted than `"unknown"`.
|
|
2578
|
+
* Callers for which the owner would be wrong rather than approximate call
|
|
2579
|
+
* {@link getTurnTrust} and handle `undefined`.
|
|
2580
|
+
*
|
|
2581
|
+
* The fallback half is load-bearing, not transitional politeness: a
|
|
2582
|
+
* deferred wake fires with no inbound actor, and refusing it an answer
|
|
2583
|
+
* denies every sensitive tool in the resumed turn (LUM-2929). It becomes
|
|
2584
|
+
* removable in one place when every entry point records a turn actor.
|
|
2585
|
+
*/
|
|
2586
|
+
getTurnOrRestingTrust(): TrustContext | undefined {
|
|
2587
|
+
return this.currentTurnTrustContext ?? this.trustContext;
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2491
2590
|
/**
|
|
2492
2591
|
* The actor principal that owns the current turn, for host-proxy routing.
|
|
2493
2592
|
* Prefers the in-flight turn's actor over the conversation's resting
|
|
@@ -2633,6 +2732,8 @@ export class Conversation {
|
|
|
2633
2732
|
titleText?: string;
|
|
2634
2733
|
/** See {@link runAgentLoopImpl} — hidden machine-signal turn marker. */
|
|
2635
2734
|
isHiddenPrompt?: boolean;
|
|
2735
|
+
/** See {@link runAgentLoopImpl}: triggering row's daemon-authored kind. */
|
|
2736
|
+
messageKind?: string;
|
|
2636
2737
|
/**
|
|
2637
2738
|
* See {@link runAgentLoopImpl}: the row the end-of-turn reply
|
|
2638
2739
|
* notification treats as the prompt this turn answers.
|
|
@@ -2674,7 +2775,7 @@ export class Conversation {
|
|
|
2674
2775
|
this,
|
|
2675
2776
|
content,
|
|
2676
2777
|
userMessageId,
|
|
2677
|
-
onEvent ?? this.
|
|
2778
|
+
onEvent ?? this.emit,
|
|
2678
2779
|
rest,
|
|
2679
2780
|
);
|
|
2680
2781
|
}
|
|
@@ -2700,7 +2801,7 @@ export class Conversation {
|
|
|
2700
2801
|
this.cacheWarmAbort = undefined;
|
|
2701
2802
|
return processMessageImpl(this, {
|
|
2702
2803
|
...options,
|
|
2703
|
-
onEvent: options.onEvent ?? this.
|
|
2804
|
+
onEvent: options.onEvent ?? this.emit,
|
|
2704
2805
|
});
|
|
2705
2806
|
}
|
|
2706
2807
|
|
|
@@ -2728,6 +2829,7 @@ export class Conversation {
|
|
|
2728
2829
|
actionId: string,
|
|
2729
2830
|
data?: Record<string, unknown>,
|
|
2730
2831
|
sourceActorPrincipalId?: string,
|
|
2832
|
+
requesterTrustContext?: TrustContext,
|
|
2731
2833
|
): Promise<SurfaceActionResult> {
|
|
2732
2834
|
return handleSurfaceActionImpl(
|
|
2733
2835
|
this,
|
|
@@ -2735,6 +2837,7 @@ export class Conversation {
|
|
|
2735
2837
|
actionId,
|
|
2736
2838
|
data,
|
|
2737
2839
|
sourceActorPrincipalId,
|
|
2840
|
+
requesterTrustContext,
|
|
2738
2841
|
);
|
|
2739
2842
|
}
|
|
2740
2843
|
|
|
@@ -130,7 +130,7 @@ function pushStepsUpdate(
|
|
|
130
130
|
};
|
|
131
131
|
const updatedData = { ...card, templateData: updatedTemplateData };
|
|
132
132
|
stored.data = updatedData;
|
|
133
|
-
ctx.
|
|
133
|
+
ctx.emit({
|
|
134
134
|
type: "ui_surface_update",
|
|
135
135
|
conversationId: ctx.conversationId,
|
|
136
136
|
surfaceId: SURFACE_ID,
|
|
@@ -218,7 +218,7 @@ export function updateDoordashProgress(
|
|
|
218
218
|
},
|
|
219
219
|
} satisfies CardSurfaceData;
|
|
220
220
|
ctx.surfaceState.set(SURFACE_ID, { surfaceType: "card", data });
|
|
221
|
-
ctx.
|
|
221
|
+
ctx.emit({
|
|
222
222
|
type: "ui_surface_show",
|
|
223
223
|
conversationId: ctx.conversationId,
|
|
224
224
|
surfaceId: SURFACE_ID,
|