@vellumai/assistant 0.6.6 → 0.7.0
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 +20 -0
- package/ARCHITECTURE.md +45 -36
- package/Dockerfile +26 -6
- package/README.md +8 -10
- package/__tests__/permissions/gateway-threshold-reader.test.ts +14 -20
- package/bun.lock +306 -119
- package/docs/architecture/memory.md +1 -90
- package/docs/architecture/security.md +15 -30
- package/docs/credential-execution-service.md +7 -5
- package/docs/skills.md +10 -10
- package/docs/stt-provider-onboarding.md +17 -45
- package/examples/plugins/echo/bun.lock +25 -0
- package/knip.json +8 -22
- package/node_modules/@vellumai/ces-client/bun.lock +33 -0
- package/node_modules/@vellumai/ces-client/package.json +25 -0
- package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +631 -0
- package/node_modules/@vellumai/ces-client/src/__tests__/package-boundary.test.ts +138 -0
- package/node_modules/@vellumai/ces-client/src/credential-rpc.ts +13 -0
- package/node_modules/@vellumai/ces-client/src/http-credentials.ts +296 -0
- package/node_modules/@vellumai/ces-client/src/http-log-export.ts +111 -0
- package/node_modules/@vellumai/ces-client/src/index.ts +43 -0
- package/node_modules/@vellumai/ces-client/src/rpc-client.ts +445 -0
- package/node_modules/@vellumai/credential-storage/src/__tests__/package-boundary.test.ts +32 -6
- package/node_modules/@vellumai/egress-proxy/src/__tests__/package-boundary.test.ts +32 -1
- package/node_modules/@vellumai/gateway-client/bun.lock +39 -0
- package/node_modules/@vellumai/gateway-client/package.json +23 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/gateway-client.test.ts +343 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/package-boundary.test.ts +140 -0
- package/node_modules/@vellumai/gateway-client/src/http-delivery.ts +422 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +35 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +331 -0
- package/node_modules/@vellumai/gateway-client/src/types.ts +131 -0
- package/node_modules/@vellumai/gateway-client/tsconfig.json +20 -0
- package/node_modules/@vellumai/{ces-contracts → service-contracts}/bun.lock +1 -1
- package/node_modules/@vellumai/{ces-contracts → service-contracts}/package.json +4 -2
- package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/__tests__/contracts.test.ts +5 -1
- package/node_modules/@vellumai/service-contracts/src/__tests__/package-boundary.test.ts +155 -0
- package/node_modules/@vellumai/service-contracts/src/credential-rpc.ts +23 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +25 -0
- package/node_modules/@vellumai/{ces-contracts/src/index.ts → service-contracts/src/transport.ts} +6 -28
- package/node_modules/@vellumai/service-contracts/src/trust-rules.ts +116 -0
- package/node_modules/@vellumai/service-contracts/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +891 -0
- package/node_modules/@vellumai/skill-host-contracts/bun.lock +24 -0
- package/node_modules/@vellumai/skill-host-contracts/package.json +18 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +91 -0
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +1348 -0
- package/node_modules/@vellumai/skill-host-contracts/src/index.ts +6 -0
- package/node_modules/@vellumai/skill-host-contracts/src/runtime-mode.ts +11 -0
- package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +32 -0
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +333 -0
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +444 -0
- package/node_modules/@vellumai/skill-host-contracts/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/tsconfig.test.json +12 -0
- package/openapi.yaml +2855 -556
- package/package.json +13 -7
- package/scripts/check-circular-deps.ts +80 -0
- package/scripts/generate-openapi.ts +24 -7
- package/{src/memory/graph/inspect.ts → scripts/memory-inspect.ts} +27 -27
- package/src/__tests__/access-request-decision.test.ts +2 -11
- package/src/__tests__/acp-session.test.ts +4 -150
- package/src/__tests__/actor-token-service.test.ts +17 -678
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +2 -6
- package/src/__tests__/agent-loop-override-profile.test.ts +404 -0
- package/src/__tests__/agent-loop-thinking.test.ts +4 -4
- package/src/__tests__/agent-wake-override-profile.test.ts +261 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -1
- package/src/__tests__/anthropic-provider.test.ts +127 -15
- package/src/__tests__/app-routes-csp.test.ts +106 -55
- package/src/__tests__/approval-cascade.test.ts +3 -355
- package/src/__tests__/approval-conversation-turn.test.ts +3 -8
- package/src/__tests__/approval-hardcoded-copy-guard.test.ts +1 -1
- package/src/__tests__/approval-primitive.test.ts +2 -1
- package/src/__tests__/approval-routes-http.test.ts +34 -451
- package/src/__tests__/assistant-events-sse-hardening.test.ts +73 -80
- package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -3
- package/src/__tests__/attachment-upload-trusted-source.test.ts +139 -0
- package/src/__tests__/attachments-store.test.ts +46 -1
- package/src/__tests__/audit-log-rotation.test.ts +2 -1
- package/src/__tests__/auto-analysis-end-to-end.test.ts +8 -20
- package/src/__tests__/background-shell-bash.test.ts +227 -0
- package/src/__tests__/background-shell-host-bash.test.ts +474 -0
- package/src/__tests__/background-tool-registry.test.ts +145 -0
- package/src/__tests__/background-tool-routes.test.ts +175 -0
- package/src/__tests__/btw-routes.test.ts +147 -183
- package/src/__tests__/call-controller.test.ts +15 -2
- package/src/__tests__/call-conversation-messages.test.ts +2 -1
- package/src/__tests__/call-domain.test.ts +2 -2
- package/src/__tests__/call-pointer-messages.test.ts +11 -13
- package/src/__tests__/call-recovery.test.ts +2 -1
- package/src/__tests__/call-routes-http.test.ts +3 -14
- package/src/__tests__/call-store.test.ts +2 -1
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +31 -62
- package/src/__tests__/canonical-guardian-store.test.ts +2 -2
- package/src/__tests__/catalog-files.test.ts +0 -26
- package/src/__tests__/ces-rpc-credential-backend.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +79 -49
- package/src/__tests__/channel-approval.test.ts +9 -7
- package/src/__tests__/channel-approvals.test.ts +9 -180
- package/src/__tests__/channel-delivery-store.test.ts +11 -10
- package/src/__tests__/channel-guardian.test.ts +14 -25
- package/src/__tests__/channel-readiness-service.test.ts +8 -6
- package/src/__tests__/channel-reply-delivery.test.ts +3 -19
- package/src/__tests__/channel-retry-sweep.test.ts +2 -5
- package/src/__tests__/checker.test.ts +274 -3921
- package/src/__tests__/circuit-breaker-pipeline.test.ts +1 -1
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +208 -0
- package/src/__tests__/cli.test.ts +1 -38
- package/src/__tests__/compaction-events.test.ts +0 -1
- package/src/__tests__/compaction-pipeline.test.ts +1 -1
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +2 -2
- package/src/__tests__/compaction-timeout-recovery.test.ts +1 -1
- package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -7
- package/src/__tests__/config-model-image-provider.test.ts +0 -1
- package/src/__tests__/config-schema-cmd.test.ts +1 -1
- package/src/__tests__/config-schema.test.ts +30 -221
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +4 -25
- package/src/__tests__/contact-store-user-file.test.ts +2 -1
- package/src/__tests__/contacts-tools.test.ts +56 -29
- package/src/__tests__/contacts-write.test.ts +6 -61
- package/src/__tests__/context-search-agent-protocol.test.ts +230 -0
- package/src/__tests__/context-search-agent-runner.test.ts +998 -0
- package/src/__tests__/context-search-conversations-source.test.ts +320 -0
- package/src/__tests__/context-search-fanout.test.ts +380 -0
- package/src/__tests__/context-search-memory-source.test.ts +311 -0
- package/src/__tests__/context-search-pkb-source.test.ts +444 -0
- package/src/__tests__/context-search-types.test.ts +95 -0
- package/src/__tests__/context-search-workspace-source.test.ts +545 -0
- package/src/__tests__/context-window-manager.test.ts +25 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +10 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +631 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +15 -2
- package/src/__tests__/conversation-agent-loop.test.ts +24 -2
- package/src/__tests__/conversation-analysis-routes.test.ts +60 -82
- package/src/__tests__/conversation-attachments.test.ts +9 -20
- package/src/__tests__/conversation-attention-store.test.ts +2 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +4 -2
- package/src/__tests__/conversation-clear-safety.test.ts +53 -95
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -39
- package/src/__tests__/conversation-crud-inference-profile.test.ts +54 -0
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +63 -157
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-disk-view.test.ts +5 -4
- package/src/__tests__/conversation-fork-crud.test.ts +26 -55
- package/src/__tests__/conversation-fork-route.test.ts +5 -74
- package/src/__tests__/conversation-inference-profile-list.test.ts +128 -0
- package/src/__tests__/conversation-inference-profile-route.test.ts +216 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +4 -81
- package/src/__tests__/conversation-key-store-disk-view.test.ts +2 -1
- package/src/__tests__/conversation-lifecycle.test.ts +0 -1
- package/src/__tests__/conversation-list-source.test.ts +2 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +0 -1
- package/src/__tests__/conversation-pairing.test.ts +0 -1
- package/src/__tests__/conversation-pre-run-repair.test.ts +137 -297
- package/src/__tests__/conversation-process-callsite.test.ts +0 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -1
- package/src/__tests__/conversation-queue.test.ts +1 -33
- package/src/__tests__/conversation-routes-disk-view.test.ts +124 -97
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +80 -55
- package/src/__tests__/conversation-routes-slash-commands.test.ts +83 -12
- package/src/__tests__/conversation-runtime-assembly.test.ts +41 -84
- package/src/__tests__/conversation-slash-commands.test.ts +6 -43
- package/src/__tests__/conversation-slash-queue.test.ts +0 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -1
- package/src/__tests__/conversation-speed-override.test.ts +0 -1
- package/src/__tests__/conversation-starter-routes.test.ts +177 -55
- package/src/__tests__/conversation-starters-cadence.test.ts +2 -2
- package/src/__tests__/conversation-store.test.ts +2 -375
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +1 -1
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +6 -6
- package/src/__tests__/conversation-unread-route.test.ts +1 -1
- package/src/__tests__/conversation-usage.test.ts +2 -1
- package/src/__tests__/conversation-wipe.test.ts +2 -103
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -1
- package/src/__tests__/conversations-defer-cli.test.ts +150 -0
- package/src/__tests__/credential-execution-admin-cli.test.ts +1 -1
- package/src/__tests__/credential-execution-api-key-propagation.test.ts +2 -2
- package/src/__tests__/credential-execution-approval-bridge.test.ts +22 -289
- package/src/__tests__/credential-execution-client.test.ts +1 -1
- package/src/__tests__/credential-execution-managed-contract.test.ts +1 -1
- package/src/__tests__/credential-security-invariants.test.ts +14 -0
- package/src/__tests__/credentials-cli.test.ts +45 -21
- package/src/__tests__/daemon-credential-client.test.ts +23 -108
- package/src/__tests__/db-acp-history.test.ts +284 -0
- package/src/__tests__/db-activation-state.test.ts +240 -0
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +2 -1
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +248 -0
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +2 -1
- package/src/__tests__/db-memory-graph-event-date-repair.test.ts +116 -0
- package/src/__tests__/db-rename-inference-profile-snake-case-migration.test.ts +132 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
- package/src/__tests__/delete-propagation.test.ts +3 -2
- package/src/__tests__/deterministic-verification-control-plane.test.ts +39 -32
- package/src/__tests__/dm-backfill.test.ts +3 -2
- package/src/__tests__/edit-propagation.test.ts +5 -7
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +1 -1
- package/src/__tests__/empty-response-pipeline.test.ts +1 -1
- package/src/__tests__/events-client-registration.test.ts +297 -0
- package/src/__tests__/file-write-tool.test.ts +2 -4
- package/src/__tests__/filing-service.test.ts +144 -17
- package/src/__tests__/followup-tools.test.ts +2 -1
- package/src/__tests__/gateway-client-managed-outbound.test.ts +8 -12
- package/src/__tests__/gateway-only-enforcement.test.ts +2 -6
- package/src/__tests__/gateway-only-guard.test.ts +4 -3
- package/src/__tests__/gemini-provider.test.ts +276 -10
- package/src/__tests__/graph-extraction-event-date.test.ts +30 -0
- package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -1
- package/src/__tests__/guardian-action-followup-executor.test.ts +2 -2
- package/src/__tests__/guardian-action-followup-store.test.ts +2 -1
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +9 -9
- package/src/__tests__/guardian-action-late-reply.test.ts +2 -1
- package/src/__tests__/guardian-action-store.test.ts +2 -1
- package/src/__tests__/guardian-action-sweep.test.ts +9 -8
- package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +21 -118
- package/src/__tests__/guardian-dispatch.test.ts +14 -11
- package/src/__tests__/guardian-grant-minting.test.ts +9 -15
- package/src/__tests__/guardian-outbound-http.test.ts +71 -106
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +34 -90
- package/src/__tests__/guardian-routing-state.test.ts +14 -22
- package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -2
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +253 -0
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +8 -4
- package/src/__tests__/heartbeat-service.test.ts +39 -21
- package/src/__tests__/helpers/call-route-handler.ts +72 -0
- package/src/__tests__/helpers/channel-test-adapter.ts +161 -0
- package/src/__tests__/helpers/gateway-classify-mock.ts +67 -0
- package/src/__tests__/helpers/mock-logger.ts +36 -0
- package/src/__tests__/history-repair-pipeline.test.ts +1 -1
- package/src/__tests__/home-state-routes.test.ts +10 -31
- package/src/__tests__/host-browser-e2e-cloud.test.ts +2 -1
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +12 -2
- package/src/__tests__/host-browser-routes.test.ts +36 -91
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +10 -2
- package/src/__tests__/host-proxy-interface.test.ts +3 -3
- package/src/__tests__/host-shell-tool.test.ts +2 -4
- package/src/__tests__/host-transfer-pending-interactions.test.ts +160 -0
- package/src/__tests__/host-transfer-proxy.test.ts +733 -0
- package/src/__tests__/http-conversation-lineage.test.ts +3 -2
- package/src/__tests__/http-user-message-parity.test.ts +20 -11
- package/src/__tests__/inbound-invite-redemption.test.ts +3 -2
- package/src/__tests__/injector-chain.test.ts +16 -17
- package/src/__tests__/inline-skill-load-permissions.test.ts +41 -206
- package/src/__tests__/install-skill-routing.test.ts +1 -1
- package/src/__tests__/invite-redemption-service.test.ts +2 -1
- package/src/__tests__/invite-routes-http.test.ts +80 -12
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -1
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +2 -1
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +157 -0
- package/src/__tests__/list-messages-attachments.test.ts +52 -55
- package/src/__tests__/list-messages-page-latest.test.ts +283 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +16 -17
- package/src/__tests__/llm-call-pipeline.test.ts +7 -8
- package/src/__tests__/llm-context-normalization.test.ts +69 -4
- package/src/__tests__/llm-context-route-provider.test.ts +39 -113
- package/src/__tests__/llm-request-log-turn-query.test.ts +2 -1
- package/src/__tests__/llm-resolver.test.ts +211 -0
- package/src/__tests__/llm-schema.test.ts +57 -1
- package/src/__tests__/llm-usage-store.test.ts +2 -1
- package/src/__tests__/log-export-workspace.test.ts +28 -17
- package/src/__tests__/mcp-abort-signal.test.ts +2 -3
- package/src/__tests__/mcp-client-auth.test.ts +2 -3
- package/src/__tests__/memory-admin-recall.test.ts +221 -0
- package/src/__tests__/memory-recall-log-store.test.ts +2 -1
- package/src/__tests__/memory-retrieval-pipeline.test.ts +6 -8
- package/src/__tests__/memory-upsert-concurrency.test.ts +2 -1
- package/src/__tests__/migration-cross-version-compatibility.test.ts +14 -13
- package/src/__tests__/migration-export-http.test.ts +17 -17
- package/src/__tests__/migration-export-to-gcs.test.ts +491 -0
- package/src/__tests__/migration-import-commit-http.test.ts +16 -16
- package/src/__tests__/migration-import-from-gcs.test.ts +533 -0
- package/src/__tests__/migration-import-from-url.test.ts +16 -23
- package/src/__tests__/migration-import-preflight-http.test.ts +13 -13
- package/src/__tests__/migration-jobs-status.test.ts +164 -0
- package/src/__tests__/migration-validate-http.test.ts +48 -83
- package/src/__tests__/mock-gateway-ipc.ts +32 -62
- package/src/__tests__/model-intents.test.ts +15 -2
- package/src/__tests__/nl-approval-parser.test.ts +13 -17
- package/src/__tests__/non-member-access-request.test.ts +13 -5
- package/src/__tests__/notification-guardian-path.test.ts +15 -8
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +2 -1
- package/src/__tests__/notification-telegram-adapter.test.ts +57 -55
- package/src/__tests__/oauth-apps-routes.test.ts +76 -122
- package/src/__tests__/oauth-cli.test.ts +14 -1
- package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
- package/src/__tests__/oauth-provider-visibility.test.ts +3 -1
- package/src/__tests__/oauth-providers-routes.test.ts +78 -101
- package/src/__tests__/oauth-store.test.ts +3 -1
- package/src/__tests__/oauth2-gateway-transport.test.ts +6 -3
- package/src/__tests__/openai-provider.test.ts +105 -6
- package/src/__tests__/openai-responses-provider.test.ts +146 -4
- package/src/__tests__/openrouter-provider-only.test.ts +22 -4
- package/src/__tests__/overflow-reduce-pipeline.test.ts +4 -9
- package/src/__tests__/permission-types.test.ts +3 -18
- package/src/__tests__/persistence-pipeline.test.ts +3 -2
- package/src/__tests__/pipeline-runner.test.ts +1 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +27 -20
- package/src/__tests__/platform.test.ts +11 -63
- package/src/__tests__/playbook-execution.test.ts +2 -1
- package/src/__tests__/playbook-tools.test.ts +2 -1
- package/src/__tests__/plugin-bootstrap.test.ts +51 -5
- package/src/__tests__/plugin-registry.test.ts +30 -0
- package/src/__tests__/plugin-route-contribution.test.ts +17 -11
- package/src/__tests__/plugin-skill-contribution.test.ts +3 -3
- package/src/__tests__/plugin-tool-contribution.test.ts +10 -4
- package/src/__tests__/plugin-types.test.ts +1 -1
- package/src/__tests__/pricing.test.ts +151 -2
- package/src/__tests__/profiler-routes.test.ts +112 -177
- package/src/__tests__/provider-send-message-override-profile.test.ts +223 -0
- package/src/__tests__/proxy-approval-callback.test.ts +6 -554
- package/src/__tests__/qdrant-collection-migration.test.ts +7 -7
- package/src/__tests__/reaction-persistence.test.ts +3 -2
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
- package/src/__tests__/recording-handler.test.ts +0 -2
- package/src/__tests__/registry.test.ts +1 -0
- package/src/__tests__/relay-server.test.ts +19 -4
- package/src/__tests__/require-fresh-approval.test.ts +19 -168
- package/src/__tests__/resolve-trust-class.test.ts +2 -1
- package/src/__tests__/retry-thinking-tool-choice.test.ts +19 -7
- package/src/__tests__/retry-verbosity-normalization.test.ts +139 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +26 -6
- package/src/__tests__/runtime-events-sse-parity.test.ts +12 -13
- package/src/__tests__/runtime-events-sse.test.ts +13 -21
- package/src/__tests__/schedule-routes.test.ts +226 -129
- package/src/__tests__/schedule-store.test.ts +119 -1
- package/src/__tests__/schedule-tools.test.ts +2 -1
- package/src/__tests__/scheduler-recurrence.test.ts +2 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +2 -1
- package/src/__tests__/scheduler-wake.test.ts +356 -0
- package/src/__tests__/scoped-approval-grants.test.ts +2 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -1
- package/src/__tests__/secret-detection-handler.test.ts +2 -9
- package/src/__tests__/secret-ingress-http.test.ts +38 -21
- package/src/__tests__/secret-routes-managed-proxy.test.ts +46 -102
- package/src/__tests__/secret-scanner-executor.test.ts +1 -2
- package/src/__tests__/send-endpoint-busy.test.ts +38 -25
- package/src/__tests__/sequence-store.test.ts +2 -1
- package/src/__tests__/server-history-render.test.ts +2 -2
- package/src/__tests__/service-contracts-import-guard.test.ts +185 -0
- package/src/__tests__/set-permission-mode.test.ts +0 -10
- package/src/__tests__/settings-routes.test.ts +35 -68
- package/src/__tests__/skill-boundary-guard.test.ts +105 -0
- package/src/__tests__/skill-load-inline-command.test.ts +2 -2
- package/src/__tests__/skill-load-inline-includes.test.ts +2 -2
- package/src/__tests__/skill-runtime-path.test.ts +64 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +0 -2
- package/src/__tests__/slack-inbound-verification.test.ts +11 -2
- package/src/__tests__/slack-messaging-token-resolution.test.ts +1 -3
- package/src/__tests__/slack-reaction-approvals.test.ts +4 -4
- package/src/__tests__/slack-share-routes.test.ts +37 -72
- package/src/__tests__/subagent-call-site-routing.test.ts +79 -0
- package/src/__tests__/subagent-fork-spawn.test.ts +20 -28
- package/src/__tests__/subagent-notify-parent.test.ts +6 -29
- package/src/__tests__/subagent-role-registry.test.ts +3 -3
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +52 -104
- package/src/__tests__/subagent-tools.test.ts +0 -1
- package/src/__tests__/suggestion-routes.test.ts +55 -62
- package/src/__tests__/task-compiler.test.ts +2 -1
- package/src/__tests__/task-management-tools.test.ts +2 -1
- package/src/__tests__/task-memory-cleanup.test.ts +2 -1
- package/src/__tests__/task-scheduler.test.ts +2 -1
- package/src/__tests__/telegram-config.test.ts +0 -1
- package/src/__tests__/terminal-tools.test.ts +5 -314
- package/src/__tests__/test-preload.ts +0 -11
- package/src/__tests__/thread-backfill.test.ts +3 -2
- package/src/__tests__/token-estimate-pipeline.test.ts +68 -15
- package/src/__tests__/tool-approval-handler.test.ts +21 -63
- package/src/__tests__/tool-audit-listener.test.ts +3 -3
- package/src/__tests__/tool-domain-event-publisher.test.ts +3 -3
- package/src/__tests__/tool-error-pipeline.test.ts +6 -6
- package/src/__tests__/tool-execute-pipeline.test.ts +6 -8
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +64 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +28 -56
- package/src/__tests__/tool-executor.test.ts +322 -1633
- package/src/__tests__/tool-grant-request-escalation.test.ts +90 -311
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +1 -1
- package/src/__tests__/trust-context-guards.test.ts +1 -1
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +7 -15
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +178 -354
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +3 -2
- package/src/__tests__/trusted-contact-multichannel.test.ts +3 -2
- package/src/__tests__/trusted-contact-verification.test.ts +2 -1
- package/src/__tests__/turn-boundary-resolution.test.ts +2 -1
- package/src/__tests__/twilio-routes.test.ts +25 -66
- package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -7
- package/src/__tests__/usage-routes.test.ts +73 -90
- package/src/__tests__/user-plugin-loader.test.ts +54 -12
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +2 -2
- package/src/__tests__/verification-control-plane-policy.test.ts +95 -14
- package/src/__tests__/voice-ingress-preflight.test.ts +5 -5
- package/src/__tests__/voice-invite-redemption.test.ts +2 -1
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +3 -3
- package/src/__tests__/voice-session-bridge.test.ts +285 -106
- package/src/__tests__/volume-security-guard.test.ts +0 -2
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -1
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +3 -1
- package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +2 -1
- package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +1 -1
- package/src/__tests__/workspace-migration-052-seed-default-inference-profiles.test.ts +260 -0
- package/src/__tests__/workspace-migration-053-release-notes-acp-codex.test.ts +225 -0
- package/src/__tests__/workspace-migration-054-seed-recall-callsite.test.ts +235 -0
- package/src/__tests__/workspace-migration-055-release-notes-agentic-recall.test.ts +128 -0
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +232 -0
- package/src/__tests__/workspace-migration-acp-sessions-ui.test.ts +144 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +1 -1
- package/src/__tests__/workspace-migration-memory-v2-init.test.ts +274 -0
- package/src/acp/__tests__/client-handler.test.ts +64 -0
- package/src/acp/__tests__/helpers/acp-config-stub.ts +62 -0
- package/src/acp/__tests__/helpers/which-stub.ts +45 -0
- package/src/acp/__tests__/session-manager-persistence.test.ts +366 -0
- package/src/acp/__tests__/session-manager-startup.test.ts +159 -0
- package/src/acp/__tests__/session-manager.test.ts +83 -0
- package/src/acp/client-handler.ts +23 -139
- package/src/acp/resolve-agent.test.ts +291 -0
- package/src/acp/resolve-agent.ts +176 -0
- package/src/acp/session-manager.ts +166 -7
- package/src/acp/types.ts +2 -50
- package/src/agent/loop.ts +37 -14
- package/src/agent/message-types.ts +0 -2
- package/src/approvals/AGENTS.md +1 -1
- package/src/approvals/__tests__/guardian-feed-event.test.ts +1 -9
- package/src/approvals/approval-primitive.ts +3 -20
- package/src/approvals/guardian-decision-primitive.ts +37 -68
- package/src/approvals/guardian-request-resolvers.ts +29 -103
- package/src/avatar/character-components.ts +6 -6
- package/src/{config/bundled-skills/settings/tools → avatar}/identity-avatar.ts +1 -1
- package/src/backup/__tests__/backup-worker.test.ts +0 -2
- package/src/backup/__tests__/paths.test.ts +3 -2
- package/src/backup/backup-worker.ts +1 -10
- package/src/backup/paths.ts +2 -18
- package/src/backup/restore.ts +7 -11
- package/src/browser/__tests__/operations.test.ts +0 -35
- package/src/browser/operations.ts +1 -47
- package/src/bundler/package-resolver.ts +2 -6
- package/src/calls/active-call-lease.ts +1 -1
- package/src/calls/call-constants.ts +1 -1
- package/src/calls/call-controller.ts +1 -5
- package/src/calls/call-domain.ts +14 -14
- package/src/calls/call-pointer-messages.ts +4 -9
- package/src/calls/call-store.ts +2 -1
- package/src/calls/guardian-action-sweep.ts +9 -25
- package/src/calls/guardian-dispatch.ts +1 -20
- package/src/calls/media-stream-audio-transcode.ts +2 -41
- package/src/calls/media-stream-server.ts +2 -3
- package/src/calls/media-stream-stt-session.ts +1 -3
- package/src/calls/relay-access-wait.ts +5 -8
- package/src/calls/relay-server.ts +15 -18
- package/src/calls/relay-setup-router.ts +2 -2
- package/src/calls/relay-verification.ts +4 -4
- package/src/calls/twilio-rest.ts +1 -1
- package/src/calls/twilio-routes.ts +160 -78
- package/src/calls/voice-control-protocol.ts +10 -10
- package/src/calls/voice-ingress-preflight.ts +2 -2
- package/src/calls/voice-session-bridge.ts +137 -42
- package/src/channels/__tests__/types.test.ts +25 -3
- package/src/channels/permission-profiles.ts +2 -72
- package/src/channels/types.ts +42 -26
- package/src/cli/AGENTS.md +1 -0
- package/src/cli/__tests__/notifications.test.ts +12 -10
- package/src/cli/commands/__tests__/attachment.test.ts +14 -8
- package/src/cli/commands/__tests__/backup.test.ts +3 -14
- package/src/cli/commands/__tests__/browser.test.ts +36 -31
- package/src/cli/commands/__tests__/cache.test.ts +23 -18
- package/src/cli/commands/__tests__/memory-v2.test.ts +396 -0
- package/src/cli/commands/__tests__/task.test.ts +36 -35
- package/src/cli/commands/__tests__/trust.test.ts +602 -0
- package/src/cli/commands/__tests__/ui-confirm.test.ts +14 -14
- package/src/cli/commands/__tests__/ui.test.ts +17 -17
- package/src/cli/commands/__tests__/watchers.test.ts +29 -29
- package/src/cli/commands/__tests__/webhooks.test.ts +544 -0
- package/src/cli/commands/attachment.ts +12 -8
- package/src/cli/commands/auth.ts +1 -1
- package/src/cli/commands/avatar.ts +192 -9
- package/src/cli/commands/backup.ts +14 -44
- package/src/cli/commands/browser.ts +52 -4
- package/src/cli/commands/cache.ts +7 -5
- package/src/cli/commands/channel-verification-sessions.ts +6 -6
- package/src/cli/commands/clients.ts +11 -12
- package/src/cli/commands/completions.ts +1 -1
- package/src/cli/commands/contacts.ts +10 -10
- package/src/cli/commands/conversations-defer.ts +364 -0
- package/src/cli/commands/conversations-import.ts +2 -3
- package/src/cli/commands/conversations.ts +63 -53
- package/src/cli/commands/credential-execution.ts +1 -1
- package/src/cli/commands/credentials.ts +139 -5
- package/src/cli/commands/default-action.ts +1 -1
- package/src/cli/commands/domain.ts +2 -2
- package/src/cli/commands/email.ts +7 -7
- package/src/cli/commands/image-generation.ts +1 -1
- package/src/cli/commands/keys.ts +2 -2
- package/src/cli/commands/mcp.ts +1 -1
- package/src/cli/commands/memory-v2.ts +343 -0
- package/src/cli/commands/memory.ts +8 -8
- package/src/cli/commands/notifications.ts +21 -20
- package/src/cli/commands/oauth/__tests__/connect.test.ts +23 -5
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +1 -1
- package/src/cli/commands/oauth/__tests__/mode.test.ts +1 -1
- package/src/cli/commands/oauth/__tests__/status.test.ts +1 -1
- package/src/cli/commands/oauth/__tests__/token.test.ts +1 -1
- package/src/cli/commands/oauth/connect.ts +2 -2
- package/src/cli/commands/oauth/shared.ts +29 -2
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -6
- package/src/cli/commands/platform/__tests__/connect.test.ts +23 -11
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +22 -10
- package/src/cli/commands/platform/__tests__/status.test.ts +22 -10
- package/src/cli/commands/platform/connect.ts +3 -3
- package/src/cli/commands/platform/disconnect.ts +4 -6
- package/src/cli/commands/platform/index.ts +12 -10
- package/src/cli/commands/routes.ts +7 -1
- package/src/cli/commands/sequence.ts +7 -7
- package/src/cli/commands/skills.ts +188 -82
- package/src/cli/commands/task.ts +12 -10
- package/src/cli/commands/trust.ts +460 -162
- package/src/cli/commands/ui.ts +3 -3
- package/src/cli/commands/usage.ts +10 -5
- package/src/cli/commands/watchers.ts +8 -8
- package/src/cli/commands/webhooks.ts +270 -0
- package/src/cli/lib/daemon-avatar-client.ts +37 -0
- package/src/cli/lib/daemon-credential-client.ts +27 -189
- package/src/cli/lib/ipc-params.ts +22 -0
- package/src/cli/program.ts +4 -0
- package/src/cli.ts +1 -61
- package/src/config/acp-defaults.test.ts +57 -0
- package/src/config/acp-defaults.ts +40 -0
- package/src/config/acp-schema.ts +1 -1
- package/src/config/assistant-feature-flags.ts +18 -142
- package/src/config/bundled-skills/acp/SKILL.md +44 -16
- package/src/config/bundled-skills/acp/TOOLS.json +45 -1
- package/src/config/bundled-skills/acp/tools/acp-list-agents.ts +12 -0
- package/src/config/bundled-skills/acp/tools/acp-steer.ts +12 -0
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +14 -14
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +1 -4
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +11 -6
- package/src/config/bundled-skills/media-processing/__tests__/cost-tracker.test.ts +6 -6
- package/src/config/bundled-skills/media-processing/services/reduce.ts +0 -13
- package/src/config/bundled-skills/messaging/tools/gmail-mime-helpers.ts +1 -1
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +1 -1
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +1 -1
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +1 -1
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +1 -1
- package/src/config/bundled-skills/settings/SKILL.md +2 -17
- package/src/config/bundled-skills/settings/TOOLS.json +0 -56
- package/src/config/bundled-skills/subagent/SKILL.md +2 -0
- package/src/config/bundled-tool-registry.ts +4 -6
- package/src/config/env.ts +7 -8
- package/src/config/feature-flag-registry.json +16 -24
- package/src/config/llm-resolver.ts +51 -33
- package/src/config/loader.ts +12 -15
- package/src/config/schema.ts +5 -72
- package/src/config/schemas/__tests__/filing.test.ts +58 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +186 -0
- package/src/config/schemas/filing.ts +12 -0
- package/src/config/schemas/host-browser.ts +2 -2
- package/src/config/schemas/inference.ts +0 -2
- package/src/config/schemas/ingress.ts +1 -1
- package/src/config/schemas/llm.ts +51 -9
- package/src/config/schemas/memory-storage.ts +1 -1
- package/src/config/schemas/memory-v2.ts +176 -0
- package/src/config/schemas/memory.ts +2 -0
- package/src/config/schemas/security.ts +0 -60
- package/src/config/schemas/services.ts +46 -7
- package/src/config/skills.ts +1 -1
- package/src/config/types.ts +0 -41
- package/src/contacts/contact-store.ts +2 -2
- package/src/contacts/contacts-write.ts +0 -38
- package/src/contacts/types.ts +8 -10
- package/src/context/token-estimator.ts +1 -1
- package/src/context/tool-result-truncation.ts +1 -1
- package/src/context/window-manager.ts +1 -1
- package/src/credential-execution/approval-bridge.ts +7 -69
- package/src/credential-execution/client.ts +17 -422
- package/src/credential-execution/feature-gates.ts +1 -2
- package/src/credential-execution/managed-catalog.ts +1 -1
- package/src/credential-health/credential-health-service.ts +1 -1
- package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -13
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +1 -1
- package/src/daemon/__tests__/daemon-skill-host.test.ts +272 -0
- package/src/daemon/__tests__/meet-host-supervisor.test.ts +587 -0
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +463 -0
- package/src/daemon/approval-generators.ts +2 -14
- package/src/daemon/classifier.ts +0 -106
- package/src/daemon/config-watcher.ts +14 -54
- package/src/daemon/connection-policy.ts +0 -14
- package/src/daemon/conversation-agent-loop-handlers.ts +37 -6
- package/src/daemon/conversation-agent-loop.ts +164 -53
- package/src/daemon/conversation-attachments.ts +5 -81
- package/src/daemon/conversation-error.ts +9 -5
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-launch.ts +1 -1
- package/src/daemon/conversation-messaging.ts +1 -1
- package/src/daemon/conversation-notifiers.ts +1 -1
- package/src/daemon/conversation-process.ts +9 -13
- package/src/daemon/conversation-runtime-assembly.ts +26 -88
- package/src/daemon/conversation-slash.ts +4 -160
- package/src/daemon/conversation-store.ts +368 -0
- package/src/daemon/conversation-surfaces.ts +5 -4
- package/src/daemon/conversation-tool-setup.ts +23 -172
- package/src/daemon/conversation.ts +46 -182
- package/src/daemon/daemon-control.ts +3 -3
- package/src/daemon/daemon-skill-host.ts +262 -0
- package/src/daemon/external-plugins-bootstrap.ts +67 -13
- package/src/daemon/handlers/config-channels.ts +2 -2
- package/src/daemon/handlers/config-embeddings.ts +1 -1
- package/src/daemon/handlers/config-ingress.ts +24 -2
- package/src/daemon/handlers/config-model.test.ts +17 -0
- package/src/daemon/handlers/config-model.ts +7 -52
- package/src/daemon/handlers/config-telegram.ts +6 -53
- package/src/daemon/handlers/config-voice.ts +1 -1
- package/src/daemon/handlers/conversations.ts +22 -156
- package/src/daemon/handlers/recording.ts +1 -1
- package/src/daemon/handlers/shared.ts +34 -35
- package/src/daemon/handlers/skills.ts +15 -23
- package/src/daemon/host-transfer-proxy.ts +500 -0
- package/src/daemon/lifecycle.ts +23 -258
- package/src/daemon/meet-host-startup.ts +51 -0
- package/src/daemon/meet-host-supervisor.ts +781 -0
- package/src/daemon/meet-manifest-loader.ts +410 -0
- package/src/daemon/memory-v2-startup.ts +35 -0
- package/src/daemon/message-protocol.ts +4 -7
- package/src/daemon/message-types/acp.ts +1 -0
- package/src/daemon/message-types/conversations.ts +16 -2
- package/src/daemon/message-types/host-transfer.ts +41 -0
- package/src/daemon/message-types/integrations.ts +6 -0
- package/src/daemon/message-types/messages.ts +14 -14
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/settings.ts +0 -6
- package/src/daemon/message-types/shared.ts +5 -2
- package/src/daemon/message-types/subagents.ts +2 -1
- package/src/daemon/message-types/workspace.ts +0 -2
- package/src/daemon/pkb-reminder-builder.test.ts +13 -12
- package/src/daemon/pkb-reminder-builder.ts +8 -16
- package/src/daemon/process-message.ts +616 -0
- package/src/daemon/providers-setup.ts +14 -6
- package/src/daemon/server.ts +79 -1274
- package/src/daemon/shutdown-handlers.ts +1 -1
- package/src/daemon/startup-error.ts +1 -1
- package/src/daemon/trust-context.ts +32 -0
- package/src/daemon/wake-target-adapter.ts +223 -0
- package/src/email/feature-gate.ts +1 -1
- package/src/events/domain-events.ts +1 -8
- package/src/events/tool-audit-listener.ts +2 -8
- package/src/events/tool-metrics-listener.ts +1 -4
- package/src/filing/filing-service.ts +194 -54
- package/src/followups/followup-store.ts +3 -71
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +89 -21
- package/src/heartbeat/heartbeat-service.ts +32 -11
- package/src/home/__tests__/phase5-exit-criteria.test.ts +18 -1
- package/src/home/__tests__/rollup-producer.test.ts +67 -2
- package/src/home/assistant-feed-authoring.ts +8 -1
- package/src/home/feed-types.ts +1 -1
- package/src/home/relationship-state-writer.ts +1 -1
- package/src/home/rewrite-feed-title.ts +58 -0
- package/src/home/rollup-producer.ts +16 -3
- package/src/inbound/platform-callback-registration.ts +1 -17
- package/src/ipc/__tests__/attachment-ipc.test.ts +128 -66
- package/src/ipc/__tests__/browser-ipc.test.ts +75 -51
- package/src/ipc/__tests__/cache-ipc.test.ts +52 -107
- package/src/ipc/__tests__/cli-ipc.test.ts +9 -6
- package/src/ipc/__tests__/skill-server-bidirectional.test.ts +254 -0
- package/src/ipc/__tests__/skill-server.test.ts +182 -0
- package/src/ipc/__tests__/socket-path.test.ts +69 -23
- package/src/ipc/__tests__/ui-request-route.test.ts +241 -216
- package/src/ipc/__tests__/watcher-ipc.test.ts +33 -33
- package/src/ipc/assistant-server.ts +450 -0
- package/src/ipc/cli-client.ts +3 -3
- package/src/ipc/gateway-client.test.ts +131 -0
- package/src/ipc/gateway-client.ts +98 -123
- package/src/ipc/ipc-framing.ts +281 -0
- package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +152 -0
- package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +219 -0
- package/src/ipc/routes/db-proxy.ts +73 -0
- package/src/ipc/routes/route-adapter.ts +32 -0
- package/src/ipc/routes/trust-rules.test.ts +218 -0
- package/src/ipc/skill-ipc-types.ts +13 -0
- package/src/ipc/skill-routes/__tests__/config.test.ts +146 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +402 -0
- package/src/ipc/skill-routes/__tests__/identity.test.ts +81 -0
- package/src/ipc/skill-routes/__tests__/log.test.ts +133 -0
- package/src/ipc/skill-routes/__tests__/memory.test.ts +178 -0
- package/src/ipc/skill-routes/__tests__/platform.test.ts +111 -0
- package/src/ipc/skill-routes/__tests__/providers.test.ts +265 -0
- package/src/ipc/skill-routes/__tests__/registries.test.ts +361 -0
- package/src/ipc/skill-routes/config.ts +47 -0
- package/src/ipc/skill-routes/events.ts +131 -0
- package/src/ipc/skill-routes/identity.ts +34 -0
- package/src/ipc/skill-routes/index.ts +37 -0
- package/src/ipc/skill-routes/log.ts +40 -0
- package/src/ipc/skill-routes/memory.ts +76 -0
- package/src/ipc/skill-routes/platform.ts +39 -0
- package/src/ipc/skill-routes/providers.ts +163 -0
- package/src/ipc/skill-routes/registries.ts +393 -0
- package/src/ipc/skill-server.ts +771 -0
- package/src/ipc/skill-socket-path.ts +20 -0
- package/src/ipc/socket-cleanup.ts +92 -0
- package/src/ipc/socket-path.ts +63 -32
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +374 -0
- package/src/live-voice/__tests__/live-voice-archive.test.ts +525 -0
- package/src/live-voice/__tests__/live-voice-events.test.ts +473 -0
- package/src/live-voice/__tests__/live-voice-integration.test.ts +359 -0
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +179 -0
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +349 -0
- package/src/live-voice/__tests__/live-voice-stt.test.ts +244 -0
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +337 -0
- package/src/live-voice/__tests__/live-voice-tts.test.ts +337 -0
- package/src/live-voice/__tests__/protocol.test.ts +295 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +421 -0
- package/src/live-voice/live-voice-archive.ts +758 -0
- package/src/live-voice/live-voice-metrics.ts +472 -0
- package/src/live-voice/live-voice-session-manager.ts +222 -0
- package/src/live-voice/live-voice-session.ts +1144 -0
- package/src/live-voice/live-voice-tts.ts +260 -0
- package/src/live-voice/protocol.ts +524 -0
- package/src/mcp/client.ts +2 -2
- package/src/media/types.ts +4 -4
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +4 -28
- package/src/memory/__tests__/auto-analysis-guard.test.ts +2 -2
- package/src/memory/__tests__/conversation-analyze-job.test.ts +7 -62
- package/src/memory/__tests__/conversation-group-migration.test.ts +2 -2
- package/src/memory/__tests__/find-analysis-conversation.test.ts +2 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +235 -0
- package/src/memory/admin.ts +65 -7
- package/src/memory/app-git-service.ts +0 -14
- package/src/memory/attachments-store.ts +14 -16
- package/src/memory/auto-analysis-enqueue.ts +2 -17
- package/src/memory/canonical-guardian-store.ts +2 -1
- package/src/memory/channel-verification-sessions.ts +1 -1
- package/src/memory/checkpoints.ts +1 -1
- package/src/memory/context-search/agent-protocol.ts +424 -0
- package/src/memory/context-search/agent-runner.ts +1295 -0
- package/src/memory/context-search/format.ts +160 -0
- package/src/memory/context-search/limits.ts +106 -0
- package/src/memory/context-search/search.ts +387 -0
- package/src/memory/context-search/sources/conversations.ts +278 -0
- package/src/memory/context-search/sources/memory.ts +90 -0
- package/src/memory/context-search/sources/pkb.ts +468 -0
- package/src/memory/context-search/sources/workspace.ts +1255 -0
- package/src/memory/context-search/types.ts +49 -0
- package/src/memory/conversation-analyze-job.ts +3 -24
- package/src/memory/conversation-attention-store.ts +1 -1
- package/src/memory/conversation-bootstrap.ts +1 -1
- package/src/memory/conversation-crud.ts +69 -127
- package/src/memory/conversation-directories.ts +1 -11
- package/src/memory/conversation-display-order-migration.ts +11 -2
- package/src/memory/conversation-group-migration.ts +20 -4
- package/src/memory/conversation-key-store.ts +3 -4
- package/src/memory/conversation-queries.ts +13 -26
- package/src/memory/conversation-starter-validation.ts +88 -0
- package/src/memory/conversation-starters-cadence.ts +1 -1
- package/src/memory/conversation-title-service.ts +2 -1
- package/src/memory/db-init.ts +14 -4
- package/src/memory/db-maintenance.ts +1 -1
- package/src/memory/delivery-channels.ts +1 -14
- package/src/memory/delivery-crud.ts +2 -32
- package/src/memory/delivery-status.ts +1 -1
- package/src/memory/embedding-gemini.test.ts +4 -4
- package/src/memory/external-conversation-store.ts +1 -1
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +412 -0
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +225 -0
- package/src/memory/graph/bootstrap.test.ts +2 -7
- package/src/memory/graph/bootstrap.ts +2 -1
- package/src/memory/graph/capability-seed.ts +3 -3
- package/src/memory/graph/compaction.ts +1 -1
- package/src/memory/graph/consolidation.ts +13 -10
- package/src/memory/graph/conversation-graph-memory.ts +151 -1
- package/src/memory/graph/decay.ts +1 -1
- package/src/memory/graph/extraction.ts +53 -21
- package/src/memory/graph/graph-memory-state-store.ts +1 -1
- package/src/memory/graph/graph-search.test.ts +94 -2
- package/src/memory/graph/graph-search.ts +22 -7
- package/src/memory/graph/image-ref-utils.ts +1 -1
- package/src/memory/graph/retriever.test.ts +158 -4
- package/src/memory/graph/retriever.ts +17 -5
- package/src/memory/graph/store.test.ts +2 -1
- package/src/memory/graph/store.ts +1 -1
- package/src/memory/graph/tool-handlers.ts +73 -247
- package/src/memory/graph/tools.ts +35 -53
- package/src/memory/group-crud.ts +1 -2
- package/src/memory/guardian-action-store.ts +2 -1
- package/src/memory/guardian-approvals.ts +1 -1
- package/src/memory/guardian-rate-limits.ts +1 -1
- package/src/memory/indexer.ts +43 -17
- package/src/memory/invite-store.ts +1 -1
- package/src/memory/job-handlers/backfill.ts +1 -1
- package/src/memory/job-handlers/cleanup.ts +2 -1
- package/src/memory/job-handlers/conversation-starters.ts +18 -10
- package/src/memory/job-handlers/embedding.test.ts +2 -1
- package/src/memory/job-handlers/embedding.ts +1 -1
- package/src/memory/job-handlers/index-maintenance.ts +1 -1
- package/src/memory/job-handlers/summarization.ts +3 -3
- package/src/memory/job-utils.ts +3 -3
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +362 -0
- package/src/memory/jobs/embed-concept-page.ts +210 -0
- package/src/memory/jobs/embed-pkb-file.test.ts +2 -1
- package/src/memory/jobs-store.ts +10 -2
- package/src/memory/jobs-worker.ts +58 -5
- package/src/memory/lifecycle-events-store.ts +1 -1
- package/src/memory/llm-request-log-store.ts +1 -1
- package/src/memory/llm-usage-store.ts +1 -1
- package/src/memory/media-store.ts +1 -1
- package/src/memory/memory-recall-log-store.ts +1 -1
- package/src/memory/migrations/038-actor-token-records.ts +3 -0
- package/src/memory/migrations/039-actor-refresh-token-records.ts +3 -0
- package/src/memory/migrations/226-schedule-wake-conversation-id.ts +11 -0
- package/src/memory/migrations/227-add-conversation-inference-profile.ts +18 -0
- package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +27 -0
- package/src/memory/migrations/229-delete-private-conversations.test.ts +1087 -0
- package/src/memory/migrations/229-delete-private-conversations.ts +210 -0
- package/src/memory/migrations/230-acp-session-history.ts +41 -0
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +128 -0
- package/src/memory/migrations/232-activation-state.ts +38 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/migrations/registry.ts +7 -0
- package/src/memory/pkb/pkb-index.test.ts +4 -5
- package/src/memory/pkb/pkb-reconcile.test.ts +4 -5
- package/src/memory/pkb/pkb-search.test.ts +83 -3
- package/src/memory/pkb/pkb-search.ts +27 -14
- package/src/memory/published-pages-store.ts +1 -1
- package/src/memory/schema/acp.ts +30 -0
- package/src/memory/schema/conversations.ts +1 -1
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/infrastructure.ts +1 -32
- package/src/memory/schema/memory-graph.ts +36 -14
- package/src/memory/scoped-approval-grants.ts +2 -1
- package/src/memory/search/semantic.ts +2 -2
- package/src/memory/shared-app-links-store.ts +2 -1
- package/src/memory/tool-usage-store.ts +1 -1
- package/src/memory/trace-event-store.ts +2 -1
- package/src/memory/turn-events-store.ts +1 -1
- package/src/memory/v2/__tests__/activation-store.test.ts +202 -0
- package/src/memory/v2/__tests__/activation.test.ts +956 -0
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +610 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +395 -0
- package/src/memory/v2/__tests__/edges.test.ts +435 -0
- package/src/memory/v2/__tests__/injection.test.ts +792 -0
- package/src/memory/v2/__tests__/migration.test.ts +812 -0
- package/src/memory/v2/__tests__/page-store.test.ts +334 -0
- package/src/memory/v2/__tests__/qdrant.test.ts +438 -0
- package/src/memory/v2/__tests__/sim.test.ts +549 -0
- package/src/memory/v2/__tests__/skill-content.test.ts +85 -0
- package/src/memory/v2/__tests__/skill-qdrant.test.ts +657 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +351 -0
- package/src/memory/v2/__tests__/sweep-job.test.ts +441 -0
- package/src/memory/v2/activation-store.ts +109 -0
- package/src/memory/v2/activation.ts +490 -0
- package/src/memory/v2/backfill-jobs.ts +442 -0
- package/src/memory/v2/consolidation-job.ts +304 -0
- package/src/memory/v2/edges.ts +217 -0
- package/src/memory/v2/injection.ts +307 -0
- package/src/memory/v2/migration.ts +654 -0
- package/src/memory/v2/now-text.ts +38 -0
- package/src/memory/v2/page-store.ts +245 -0
- package/src/memory/v2/prompts/consolidation.ts +185 -0
- package/src/memory/v2/prompts/sweep.ts +56 -0
- package/src/memory/v2/qdrant.ts +342 -0
- package/src/memory/v2/sim.ts +206 -0
- package/src/memory/v2/skill-content.ts +42 -0
- package/src/memory/v2/skill-qdrant.ts +395 -0
- package/src/memory/v2/skill-store.ts +128 -0
- package/src/memory/v2/sweep-job.ts +298 -0
- package/src/memory/v2/types.ts +116 -0
- package/src/memory/validation.ts +1 -1
- package/src/messaging/providers/index.ts +262 -0
- package/src/messaging/providers/slack/api.ts +242 -0
- package/src/messaging/providers/slack/message-metadata.ts +1 -1
- package/src/messaging/providers/slack/send.ts +383 -0
- package/src/messaging/providers/telegram-bot/adapter.ts +4 -42
- package/src/messaging/providers/telegram-bot/api.ts +253 -0
- package/src/messaging/providers/telegram-bot/client.ts +17 -58
- package/src/messaging/providers/telegram-bot/send.ts +232 -0
- package/src/messaging/providers/whatsapp/adapter.ts +4 -36
- package/src/messaging/providers/whatsapp/api.ts +319 -0
- package/src/messaging/providers/whatsapp/client.ts +4 -48
- package/src/messaging/providers/whatsapp/send.ts +209 -0
- package/src/notifications/adapters/slack.ts +5 -23
- package/src/notifications/adapters/telegram.ts +8 -29
- package/src/notifications/conversation-candidates.ts +1 -1
- package/src/notifications/conversation-seed-composer.ts +12 -6
- package/src/notifications/copy-composer.ts +1 -1
- package/src/notifications/decision-engine.ts +1 -1
- package/src/notifications/decisions-store.ts +1 -1
- package/src/notifications/deliveries-store.ts +2 -1
- package/src/notifications/deterministic-checks.ts +1 -1
- package/src/notifications/events-store.ts +1 -13
- package/src/notifications/preferences-store.ts +1 -1
- package/src/notifications/signal.ts +0 -9
- package/src/oauth/connection-resolver.ts +11 -2
- package/src/oauth/oauth-store.ts +2 -1
- package/src/outbound-proxy/index.ts +0 -1
- package/src/permissions/approval-policy.test.ts +149 -132
- package/src/permissions/approval-policy.ts +65 -91
- package/src/permissions/checker.test.ts +632 -0
- package/src/permissions/checker.ts +266 -459
- package/src/permissions/gateway-threshold-reader.ts +28 -47
- package/src/permissions/ipc-risk-types.ts +95 -0
- package/src/permissions/prompter.ts +4 -9
- package/src/permissions/risk-types.ts +24 -210
- package/src/permissions/types.ts +17 -47
- package/src/permissions/workspace-policy.ts +2 -4
- package/src/playbooks/playbook-compiler.ts +1 -1
- package/src/plugins/defaults/index.ts +1 -1
- package/src/plugins/defaults/injectors.ts +18 -21
- package/src/plugins/defaults/llm-call.ts +6 -9
- package/src/plugins/defaults/memory-retrieval.ts +1 -6
- package/src/plugins/defaults/overflow-reduce.ts +9 -5
- package/src/plugins/defaults/token-estimate.ts +2 -3
- package/src/plugins/registry.ts +61 -1
- package/src/plugins/types.ts +6 -7
- package/src/plugins/user-loader.ts +36 -10
- package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +197 -0
- package/src/prompts/persona-resolver.ts +2 -4
- package/src/prompts/system-prompt.ts +39 -0
- package/src/prompts/templates/SOUL.md +3 -1
- package/src/providers/__tests__/provider-env-vars.test.ts +0 -21
- package/src/providers/__tests__/retry-callsite.test.ts +3 -6
- package/src/providers/anthropic/client.ts +71 -19
- package/src/providers/call-site-routing.ts +7 -3
- package/src/providers/fireworks/client.ts +3 -0
- package/src/providers/gemini/client.ts +96 -22
- package/src/providers/managed-proxy/context.ts +0 -12
- package/src/providers/model-catalog.ts +83 -8
- package/src/providers/model-intents.ts +7 -8
- package/src/providers/openai/chat-completions-provider.ts +37 -7
- package/src/providers/openai/responses-provider.ts +39 -4
- package/src/providers/openrouter/client.ts +4 -5
- package/src/providers/provider-env-vars.ts +4 -12
- package/src/providers/provider-send-message.ts +16 -11
- package/src/providers/registry.ts +1 -1
- package/src/providers/retry.ts +52 -23
- package/src/providers/speech-to-text/openai-whisper-stream.ts +1 -1
- package/src/providers/speech-to-text/openai-whisper.ts +3 -6
- package/src/providers/speech-to-text/provider-catalog.ts +75 -0
- package/src/providers/speech-to-text/xai.ts +5 -5
- package/src/providers/thinking-config.ts +34 -0
- package/src/providers/types.ts +22 -10
- package/src/runtime/AGENTS.md +10 -9
- package/src/runtime/__tests__/agent-wake.test.ts +33 -9
- package/src/runtime/__tests__/client-registry.test.ts +5 -27
- package/src/runtime/__tests__/interactive-ui.test.ts +157 -246
- package/src/runtime/access-request-helper.ts +9 -20
- package/src/runtime/actor-trust-resolver.ts +2 -2
- package/src/runtime/agent-wake.ts +174 -68
- package/src/runtime/approval-conversation-turn.ts +2 -15
- package/src/runtime/approval-message-composer.ts +11 -60
- package/src/runtime/assistant-event.ts +18 -66
- package/src/runtime/auth/__tests__/guard-tests.test.ts +6 -30
- package/src/runtime/auth/__tests__/middleware.test.ts +10 -10
- package/src/runtime/auth/__tests__/route-policy.test.ts +0 -8
- package/src/runtime/auth/context.ts +9 -0
- package/src/runtime/auth/middleware.ts +4 -4
- package/src/runtime/auth/route-policy.ts +195 -4
- package/src/runtime/auth/token-service.ts +1 -100
- package/src/runtime/capability-tokens.ts +89 -313
- package/src/runtime/channel-approval-types.ts +1 -6
- package/src/runtime/channel-approvals.ts +7 -79
- package/src/runtime/channel-readiness-service.ts +2 -2
- package/src/runtime/channel-reply-delivery.ts +2 -8
- package/src/runtime/channel-retry-sweep.ts +20 -17
- package/src/runtime/client-registry.ts +21 -28
- package/src/runtime/confirmation-request-guardian-bridge.ts +2 -7
- package/src/runtime/gateway-client.ts +37 -378
- package/src/runtime/guardian-action-grant-minter.ts +2 -3
- package/src/runtime/guardian-action-message-composer.ts +11 -52
- package/src/runtime/guardian-action-service.ts +19 -7
- package/src/runtime/guardian-decision-types.ts +4 -65
- package/src/runtime/guardian-reply-router.ts +10 -19
- package/src/runtime/guardian-vellum-migration.ts +5 -64
- package/src/runtime/http-errors.ts +3 -0
- package/src/runtime/http-router.ts +50 -7
- package/src/runtime/http-server.ts +345 -1110
- package/src/runtime/http-types.ts +15 -98
- package/src/runtime/interactive-ui-types.ts +145 -0
- package/src/runtime/interactive-ui.ts +38 -196
- package/src/runtime/invite-redemption-service.ts +1 -1
- package/src/runtime/invite-redemption-templates.ts +1 -1
- package/src/runtime/local-actor-identity.ts +13 -43
- package/src/runtime/message-composer-types.ts +134 -0
- package/src/runtime/middleware/rate-limiter.ts +1 -1
- package/src/runtime/middleware/request-logger.ts +5 -2
- package/src/runtime/migrations/__tests__/job-registry.test.ts +346 -0
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +16 -0
- package/src/runtime/migrations/job-registry.ts +281 -0
- package/src/runtime/migrations/vbundle-builder.ts +3 -4
- package/src/runtime/migrations/vbundle-importer.ts +1 -1
- package/src/runtime/migrations/vbundle-streaming-importer.ts +0 -13
- package/src/runtime/migrations/vbundle-tar-stream.ts +11 -3
- package/src/runtime/nl-approval-parser.ts +16 -21
- package/src/runtime/pending-interactions.ts +29 -12
- package/src/runtime/routes/__tests__/acp-routes.test.ts +395 -0
- package/src/runtime/routes/__tests__/backup-routes.test.ts +204 -320
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +72 -4
- package/src/runtime/routes/__tests__/stt-routes.test.ts +182 -223
- package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +230 -0
- package/src/{ipc/__tests__/task-ipc.test.ts → runtime/routes/__tests__/task-routes.test.ts} +116 -96
- package/src/runtime/routes/__tests__/tts-routes.test.ts +185 -289
- package/src/runtime/routes/access-request-decision.ts +25 -50
- package/src/runtime/routes/acp-routes.test.ts +371 -0
- package/src/runtime/routes/acp-routes.ts +392 -166
- package/src/runtime/routes/app-management-routes.ts +464 -660
- package/src/runtime/routes/app-routes.ts +192 -177
- package/src/runtime/routes/approval-routes.ts +116 -434
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +24 -84
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +3 -10
- package/src/runtime/routes/attachment-routes.ts +409 -253
- package/src/runtime/routes/audio-routes.ts +51 -18
- package/src/runtime/routes/avatar-routes.ts +82 -75
- package/src/runtime/routes/background-tool-routes.ts +94 -0
- package/src/runtime/routes/backup-routes.ts +154 -336
- package/src/runtime/routes/brain-graph-routes.ts +83 -110
- package/src/runtime/routes/browser-routes.ts +141 -0
- package/src/runtime/routes/btw-routes.ts +62 -106
- package/src/runtime/routes/cache-routes.ts +96 -0
- package/src/runtime/routes/call-routes.ts +208 -247
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +1 -1
- package/src/runtime/routes/channel-delivery-routes.ts +25 -27
- package/src/runtime/routes/channel-readiness-routes.ts +83 -120
- package/src/runtime/routes/channel-route-definitions.ts +62 -0
- package/src/runtime/routes/channel-route-shared.ts +14 -18
- package/src/runtime/routes/channel-verification-routes.ts +207 -187
- package/src/runtime/routes/client-routes.ts +48 -0
- package/src/runtime/routes/contact-routes.ts +533 -407
- package/src/runtime/routes/conversation-analysis-routes.ts +48 -49
- package/src/runtime/routes/conversation-attention-routes.ts +55 -67
- package/src/runtime/routes/conversation-list-routes.ts +265 -0
- package/src/runtime/routes/conversation-management-routes.ts +626 -715
- package/src/runtime/routes/conversation-query-routes.ts +510 -460
- package/src/runtime/routes/conversation-routes.ts +456 -368
- package/src/runtime/routes/conversation-starter-routes.ts +121 -71
- package/src/runtime/routes/credential-prompt-routes.ts +124 -0
- package/src/runtime/routes/debug-routes.ts +34 -39
- package/src/runtime/routes/defer-routes.ts +230 -0
- package/src/runtime/routes/diagnostics-routes.ts +79 -70
- package/src/runtime/routes/documents-routes.ts +117 -106
- package/src/runtime/routes/errors.ts +132 -0
- package/src/runtime/routes/events-routes.ts +97 -58
- package/src/runtime/routes/filing-routes.ts +65 -78
- package/src/runtime/routes/global-search-routes.ts +51 -57
- package/src/runtime/routes/group-routes.ts +199 -181
- package/src/runtime/routes/guardian-action-routes.ts +103 -169
- package/src/runtime/routes/guardian-approval-interception.ts +27 -58
- package/src/runtime/routes/guardian-approval-prompt.ts +10 -21
- package/src/runtime/routes/guardian-approval-reply-helpers.ts +2 -6
- package/src/runtime/routes/guardian-expiry-sweep.ts +19 -36
- package/src/runtime/routes/heartbeat-routes.ts +194 -209
- package/src/runtime/routes/home-feed-routes.ts +85 -187
- package/src/runtime/routes/home-state-routes.ts +27 -24
- package/src/runtime/routes/host-bash-routes.ts +42 -52
- package/src/runtime/routes/host-browser-routes.ts +38 -69
- package/src/runtime/routes/host-cu-routes.ts +74 -70
- package/src/runtime/routes/host-file-routes.ts +50 -60
- package/src/runtime/routes/host-transfer-routes.ts +220 -0
- package/src/runtime/routes/http-adapter.ts +172 -0
- package/src/runtime/routes/identity-routes.ts +83 -79
- package/src/runtime/routes/inbound-conversation.ts +11 -18
- package/src/runtime/routes/inbound-message-handler.ts +74 -110
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +79 -138
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +2 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +54 -90
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +25 -50
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +7 -7
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +5 -5
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +5 -6
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -24
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -10
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -4
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +3 -3
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +19 -26
- package/src/runtime/routes/index.ts +197 -0
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +25 -32
- package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +22 -31
- package/src/runtime/routes/integrations/slack/channel.ts +69 -66
- package/src/runtime/routes/integrations/slack/share.ts +49 -58
- package/src/runtime/routes/integrations/telegram.ts +91 -74
- package/src/runtime/routes/integrations/twilio.ts +163 -240
- package/src/runtime/routes/integrations/vercel.ts +57 -54
- package/src/runtime/routes/interface-routes.ts +43 -0
- package/src/runtime/routes/internal-oauth-routes.ts +56 -0
- package/src/runtime/routes/internal-twilio-routes.ts +46 -0
- package/src/runtime/routes/llm-context-normalization.ts +4 -2
- package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
- package/src/runtime/routes/log-export-routes.ts +90 -100
- package/src/runtime/routes/memory-item-routes.test.ts +152 -175
- package/src/runtime/routes/memory-item-routes.ts +243 -323
- package/src/runtime/routes/memory-v2-routes.ts +193 -0
- package/src/runtime/routes/migration-rollback-routes.ts +167 -212
- package/src/runtime/routes/migration-routes.ts +877 -374
- package/src/runtime/routes/notification-routes.ts +199 -70
- package/src/runtime/routes/oauth-apps.ts +254 -251
- package/src/runtime/routes/oauth-providers.ts +66 -57
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +60 -120
- package/src/runtime/routes/playground/__tests__/guard.test.ts +34 -54
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +107 -151
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +41 -117
- package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +95 -138
- package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +115 -217
- package/src/runtime/routes/playground/__tests__/state.test.ts +41 -90
- package/src/runtime/routes/playground/conversation-not-found.ts +9 -11
- package/src/runtime/routes/playground/force-compact.ts +41 -54
- package/src/runtime/routes/playground/guard.ts +18 -19
- package/src/runtime/routes/playground/helpers.ts +103 -0
- package/src/runtime/routes/playground/index.ts +15 -25
- package/src/runtime/routes/playground/inject-failures.ts +48 -64
- package/src/runtime/routes/playground/reset-circuit.ts +31 -57
- package/src/runtime/routes/playground/seed-conversation.ts +66 -92
- package/src/runtime/routes/playground/seeded-conversations.ts +60 -64
- package/src/runtime/routes/playground/state.ts +23 -24
- package/src/runtime/routes/profiler-routes.ts +132 -167
- package/src/runtime/routes/ps-routes.ts +120 -0
- package/src/runtime/routes/recording-routes.ts +197 -258
- package/src/runtime/routes/rename-conversation-routes.ts +89 -0
- package/src/runtime/routes/schedule-routes.ts +238 -242
- package/src/runtime/routes/secret-routes.ts +219 -265
- package/src/runtime/routes/secrets-deps.ts +24 -0
- package/src/runtime/routes/settings-routes.ts +361 -441
- package/src/runtime/routes/skills-routes.ts +434 -469
- package/src/runtime/routes/stt-routes.ts +196 -206
- package/src/runtime/routes/subagents-routes.ts +125 -141
- package/src/runtime/routes/suggest-trust-rule-routes.ts +244 -0
- package/src/runtime/routes/surface-action-routes.ts +135 -190
- package/src/runtime/routes/surface-content-routes.ts +84 -118
- package/src/runtime/routes/task-routes.ts +354 -0
- package/src/runtime/routes/telemetry-routes.ts +33 -49
- package/src/runtime/routes/trace-event-routes.ts +55 -74
- package/src/runtime/routes/trust-rules-routes.ts +147 -239
- package/src/runtime/routes/tts-routes.ts +187 -169
- package/src/runtime/routes/types.ts +139 -0
- package/src/{ipc/routes/ui-request.ts → runtime/routes/ui-request-routes.ts} +23 -17
- package/src/runtime/routes/upgrade-broadcast-routes.ts +156 -197
- package/src/runtime/routes/usage-routes.ts +143 -169
- package/src/runtime/routes/user-routes.ts +102 -18
- package/src/runtime/routes/wake-conversation-routes.ts +49 -0
- package/src/{ipc/routes/watcher.ts → runtime/routes/watcher-routes.ts} +84 -39
- package/src/runtime/routes/wipe-conversation-routes.ts +89 -0
- package/src/runtime/routes/work-items-routes.test.ts +10 -20
- package/src/runtime/routes/work-items-routes.ts +418 -433
- package/src/runtime/routes/workspace-commit-routes.ts +30 -61
- package/src/runtime/routes/workspace-routes.test.ts +254 -381
- package/src/runtime/routes/workspace-routes.ts +238 -246
- package/src/runtime/runtime-mode.ts +8 -1
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +80 -118
- package/src/runtime/services/analyze-conversation.ts +14 -41
- package/src/runtime/services/conversation-serializer.ts +181 -0
- package/src/runtime/trust-context-resolver.ts +3 -2
- package/src/runtime/verification-outbound-actions.ts +13 -49
- package/src/schedule/schedule-store.ts +64 -2
- package/src/schedule/scheduler.ts +101 -0
- package/src/security/ces-credential-client.ts +32 -169
- package/src/security/ces-rpc-credential-backend.ts +1 -1
- package/src/security/credential-backend.ts +6 -6
- package/src/security/oauth-completion-page.ts +1 -1
- package/src/security/oauth2.ts +3 -6
- package/src/sequence/analytics.ts +1 -1
- package/src/sequence/guardrails.ts +3 -3
- package/src/sequence/store.ts +2 -1
- package/src/signals/bash.ts +1 -1
- package/src/signals/event-stream.ts +1 -1
- package/src/skills/catalog-cache.ts +7 -0
- package/src/skills/catalog-files.ts +0 -5
- package/src/skills/catalog-install.ts +28 -18
- package/src/skills/category-inference.ts +0 -11
- package/src/skills/clawhub.ts +2 -2
- package/src/skills/managed-store.ts +2 -2
- package/src/skills/remote-skill-policy.ts +6 -7
- package/src/subagent/index.ts +2 -6
- package/src/subagent/manager.ts +27 -23
- package/src/subagent/types.ts +9 -0
- package/src/tasks/SPEC.md +2 -2
- package/src/tasks/task-compiler.ts +1 -1
- package/src/tasks/task-runner.ts +2 -22
- package/src/tasks/task-store.ts +1 -1
- package/src/tools/acp/list-agents.test.ts +115 -0
- package/src/tools/acp/list-agents.ts +31 -0
- package/src/tools/acp/spawn.test.ts +379 -0
- package/src/tools/acp/spawn.ts +142 -62
- package/src/tools/acp/steer.test.ts +101 -0
- package/src/tools/acp/steer.ts +38 -0
- package/src/tools/background-tool-registry.ts +98 -0
- package/src/tools/browser/browser-execution.ts +34 -7
- package/src/tools/browser/browser-manager.ts +1 -8
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +1 -1
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +3 -1
- package/src/tools/browser/cdp-client/types.ts +4 -1
- package/src/tools/computer-use/definitions.ts +1 -1
- package/src/tools/credential-execution/make-authenticated-request.ts +2 -2
- package/src/tools/credential-execution/manage-secure-command-tool.ts +1 -1
- package/src/tools/credential-execution/run-authenticated-command.ts +2 -2
- package/src/tools/credentials/broker-types.ts +2 -1
- package/src/tools/document/editor-template.ts +1 -1
- package/src/tools/execution-timeout.ts +1 -1
- package/src/tools/executor.ts +10 -15
- package/src/tools/host-filesystem/transfer.test.ts +268 -0
- package/src/tools/host-filesystem/transfer.ts +234 -0
- package/src/tools/host-terminal/host-shell.ts +189 -11
- package/src/tools/mcp/mcp-tool-factory.ts +1 -1
- package/src/tools/memory/register.test.ts +161 -1
- package/src/tools/memory/register.ts +19 -34
- package/src/tools/permission-checker.ts +18 -219
- package/src/tools/policy-context.ts +1 -8
- package/src/tools/registry.ts +16 -1
- package/src/tools/secret-detection-handler.ts +13 -103
- package/src/tools/shared/shell-output.ts +4 -1
- package/src/tools/side-effects.ts +2 -2
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/subagent/spawn.ts +35 -11
- package/src/tools/terminal/safe-env.ts +9 -1
- package/src/tools/terminal/shell.ts +161 -31
- package/src/tools/tool-approval-handler.ts +4 -70
- package/src/tools/tool-input-summary.ts +10 -0
- package/src/tools/types.ts +143 -163
- package/src/tools/ui-surface/definitions.ts +2 -2
- package/src/util/debounce.ts +0 -21
- package/src/util/errors.ts +0 -8
- package/src/util/log-redact.ts +0 -1
- package/src/util/platform.ts +85 -124
- package/src/util/pricing.ts +109 -6
- package/src/watcher/engine.ts +42 -20
- package/src/watcher/watcher-store.ts +2 -1
- package/src/work-items/work-item-store.ts +1 -1
- package/src/workspace/git-service.ts +1 -6
- package/src/workspace/migrations/006-services-config.ts +10 -1
- package/src/workspace/migrations/017-seed-persona-dirs.ts +1 -1
- package/src/workspace/migrations/019-scope-journal-to-guardian.ts +1 -1
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +1 -1
- package/src/workspace/migrations/031-drop-user-md.ts +1 -1
- package/src/workspace/migrations/045-release-notes-meet-avatar.ts +3 -4
- package/src/workspace/migrations/052-seed-default-inference-profiles.ts +150 -0
- package/src/workspace/migrations/053-release-notes-acp-codex.ts +107 -0
- package/src/workspace/migrations/054-seed-recall-callsite.ts +102 -0
- package/src/workspace/migrations/055-release-notes-agentic-recall.ts +63 -0
- package/src/workspace/migrations/056-release-notes-inference-profile-reordering.ts +65 -0
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +98 -0
- package/src/workspace/migrations/058-release-notes-acp-sessions-ui.ts +71 -0
- package/src/workspace/migrations/059-move-pid-to-workspace.ts +53 -0
- package/src/workspace/migrations/060-memory-v2-init.ts +53 -0
- package/src/workspace/migrations/rebuild-conversation-disk-view.ts +1 -1
- package/src/workspace/migrations/registry.ts +18 -0
- package/src/workspace/migrations/runner.ts +2 -2
- package/src/workspace/provider-commit-message-generator.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +0 -471
- package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +0 -436
- package/src/__tests__/cli-command-risk-guard.test.ts +0 -368
- package/src/__tests__/config-watcher-feature-flags.test.ts +0 -211
- package/src/__tests__/conversation-approval-overrides.test.ts +0 -207
- package/src/__tests__/conversation-host-access-routes.test.ts +0 -229
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +0 -226
- package/src/__tests__/conversation-tool-setup-side-effect-flag.test.ts +0 -167
- package/src/__tests__/ephemeral-permissions.test.ts +0 -474
- package/src/__tests__/extension-id-sync-guard.test.ts +0 -241
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +0 -374
- package/src/__tests__/native-host-marker-sync-guard.test.ts +0 -157
- package/src/__tests__/pairing-concurrent.test.ts +0 -84
- package/src/__tests__/pairing-routes.test.ts +0 -181
- package/src/__tests__/parser.test.ts +0 -595
- package/src/__tests__/permission-checker-host-gate.test.ts +0 -488
- package/src/__tests__/permission-controls-v2-flag.test.ts +0 -55
- package/src/__tests__/permission-mode.test.ts +0 -89
- package/src/__tests__/provider-env-vars-scope.test.ts +0 -52
- package/src/__tests__/risk-classifier-parity.test.ts +0 -230
- package/src/__tests__/shell-identity.test.ts +0 -236
- package/src/__tests__/shell-parser-fuzz.test.ts +0 -629
- package/src/__tests__/shell-parser-property.test.ts +0 -936
- package/src/__tests__/starter-bundle.test.ts +0 -173
- package/src/__tests__/stt-catalog-parity.test.ts +0 -282
- package/src/__tests__/task-runner.test.ts +0 -224
- package/src/__tests__/tool-executor-shell-integration.test.ts +0 -354
- package/src/__tests__/trust-store-pattern-matches.test.ts +0 -29
- package/src/__tests__/trust-store.test.ts +0 -2013
- package/src/__tests__/v2-consent-policy.test.ts +0 -103
- package/src/browser/identifiers.ts +0 -51
- package/src/cli/db.ts +0 -1
- package/src/config/bundled-skills/settings/tools/avatar-get.ts +0 -40
- package/src/config/bundled-skills/settings/tools/avatar-remove.ts +0 -64
- package/src/config/bundled-skills/settings/tools/avatar-update.ts +0 -88
- package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +0 -127
- package/src/daemon/approved-devices-store.ts +0 -110
- package/src/daemon/external-skills-bootstrap.ts +0 -41
- package/src/daemon/message-types/trust.ts +0 -71
- package/src/daemon/pairing-store.ts +0 -229
- package/src/ipc/cli-server.ts +0 -252
- package/src/ipc/routes/attachment.ts +0 -114
- package/src/ipc/routes/browser-context.ts +0 -63
- package/src/ipc/routes/browser.ts +0 -97
- package/src/ipc/routes/cache.ts +0 -96
- package/src/ipc/routes/get-contact.ts +0 -16
- package/src/ipc/routes/index.ts +0 -35
- package/src/ipc/routes/list-clients.ts +0 -31
- package/src/ipc/routes/merge-contacts.ts +0 -17
- package/src/ipc/routes/notification.ts +0 -133
- package/src/ipc/routes/rename-conversation.ts +0 -59
- package/src/ipc/routes/search-contacts.ts +0 -19
- package/src/ipc/routes/task-queue.ts +0 -226
- package/src/ipc/routes/task.ts +0 -173
- package/src/ipc/routes/upsert-contact.ts +0 -25
- package/src/ipc/routes/wake-conversation.ts +0 -19
- package/src/memory/db.ts +0 -23
- package/src/permissions/arg-parser.test.ts +0 -161
- package/src/permissions/arg-parser.ts +0 -141
- package/src/permissions/bash-risk-classifier.test.ts +0 -1620
- package/src/permissions/bash-risk-classifier.ts +0 -950
- package/src/permissions/command-registry.test.ts +0 -774
- package/src/permissions/command-registry.ts +0 -1005
- package/src/permissions/defaults.ts +0 -314
- package/src/permissions/file-risk-classifier.test.ts +0 -535
- package/src/permissions/file-risk-classifier.ts +0 -274
- package/src/permissions/permission-mode.ts +0 -24
- package/src/permissions/schedule-risk-classifier.test.ts +0 -129
- package/src/permissions/schedule-risk-classifier.ts +0 -85
- package/src/permissions/shell-identity.ts +0 -297
- package/src/permissions/skill-risk-classifier.test.ts +0 -311
- package/src/permissions/skill-risk-classifier.ts +0 -214
- package/src/permissions/trust-client.ts +0 -359
- package/src/permissions/trust-store-interface.ts +0 -100
- package/src/permissions/trust-store.ts +0 -1330
- package/src/permissions/v2-consent-policy.ts +0 -87
- package/src/permissions/web-risk-classifier.test.ts +0 -170
- package/src/permissions/web-risk-classifier.ts +0 -89
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +0 -715
- package/src/runtime/__tests__/capability-tokens.test.ts +0 -258
- package/src/runtime/actor-refresh-token-store.ts +0 -156
- package/src/runtime/actor-token-store.ts +0 -207
- package/src/runtime/auth/__tests__/credential-service.test.ts +0 -264
- package/src/runtime/auth/credential-service.ts +0 -352
- package/src/runtime/conversation-approval-overrides.ts +0 -86
- package/src/runtime/routes/browser-extension-pair-routes.ts +0 -575
- package/src/runtime/routes/channel-routes.ts +0 -112
- package/src/runtime/routes/contact-routes.test.ts +0 -298
- package/src/runtime/routes/guardian-bootstrap-routes.ts +0 -175
- package/src/runtime/routes/guardian-refresh-routes.ts +0 -79
- package/src/runtime/routes/invite-routes.ts +0 -280
- package/src/runtime/routes/pairing-routes.ts +0 -431
- package/src/runtime/routes/playground/deps.ts +0 -56
- package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +0 -67
- package/src/runtime/services/analyze-deps-singleton.ts +0 -32
- package/src/tasks/ephemeral-permissions.ts +0 -55
- package/src/tools/terminal/parser.ts +0 -623
- package/src/types/qrcode.d.ts +0 -13
- package/src/util/network-info.ts +0 -55
- /package/node_modules/@vellumai/{ces-contracts → ces-client}/tsconfig.json +0 -0
- /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/__tests__/grants.test.ts +0 -0
- /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/error.ts +0 -0
- /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/grants.ts +0 -0
- /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/handles.ts +0 -0
- /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/rendering.ts +0 -0
- /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/rpc.ts +0 -0
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from "../../agent/message-types.js";
|
|
20
20
|
import {
|
|
21
21
|
canServiceRegistryBrowser,
|
|
22
|
+
canServiceSseBrowser,
|
|
22
23
|
CHANNEL_IDS,
|
|
23
24
|
INTERFACE_IDS,
|
|
24
25
|
type InterfaceId,
|
|
@@ -29,6 +30,7 @@ import {
|
|
|
29
30
|
} from "../../channels/types.js";
|
|
30
31
|
import { isHttpAuthDisabled } from "../../config/env.js";
|
|
31
32
|
import { getConfig } from "../../config/loader.js";
|
|
33
|
+
import { createApprovalConversationGenerator } from "../../daemon/approval-generators.js";
|
|
32
34
|
import type { Conversation } from "../../daemon/conversation.js";
|
|
33
35
|
import {
|
|
34
36
|
buildModelInfoEvent,
|
|
@@ -39,6 +41,7 @@ import {
|
|
|
39
41
|
resolveSlash,
|
|
40
42
|
type SlashContext,
|
|
41
43
|
} from "../../daemon/conversation-slash.js";
|
|
44
|
+
import { getOrCreateConversation as getOrCreateConversationInstance } from "../../daemon/conversation-store.js";
|
|
42
45
|
import {
|
|
43
46
|
getCannedFirstGreeting,
|
|
44
47
|
isWakeUpGreeting,
|
|
@@ -48,19 +51,26 @@ import { HostBashProxy } from "../../daemon/host-bash-proxy.js";
|
|
|
48
51
|
import { HostBrowserProxy } from "../../daemon/host-browser-proxy.js";
|
|
49
52
|
import { HostCuProxy } from "../../daemon/host-cu-proxy.js";
|
|
50
53
|
import { HostFileProxy } from "../../daemon/host-file-proxy.js";
|
|
54
|
+
import { HostTransferProxy } from "../../daemon/host-transfer-proxy.js";
|
|
51
55
|
import type { ServerMessage } from "../../daemon/message-protocol.js";
|
|
52
56
|
import type {
|
|
53
57
|
HostProxyTransportMetadata,
|
|
54
58
|
NonHostProxyTransportMetadata,
|
|
55
59
|
} from "../../daemon/message-types/conversations.js";
|
|
56
|
-
import
|
|
60
|
+
import { HeartbeatService } from "../../heartbeat/heartbeat-service.js";
|
|
57
61
|
import { emitFeedEvent } from "../../home/emit-feed-event.js";
|
|
58
62
|
import {
|
|
59
63
|
writeOnboardingSidecar,
|
|
60
64
|
writeRelationshipState,
|
|
61
65
|
} from "../../home/relationship-state-writer.js";
|
|
62
66
|
import { rewriteCommandPreview } from "../../home/rewrite-command-preview.js";
|
|
63
|
-
import
|
|
67
|
+
import { ipcCall } from "../../ipc/gateway-client.js";
|
|
68
|
+
import {
|
|
69
|
+
getAttachmentById,
|
|
70
|
+
getAttachmentMetadataForMessage,
|
|
71
|
+
getAttachmentsByIds,
|
|
72
|
+
getSourcePathsForAttachments,
|
|
73
|
+
} from "../../memory/attachments-store.js";
|
|
64
74
|
import {
|
|
65
75
|
createCanonicalGuardianRequest,
|
|
66
76
|
generateCanonicalRequestCode,
|
|
@@ -76,6 +86,7 @@ import {
|
|
|
76
86
|
hasMessages,
|
|
77
87
|
type MessageRow,
|
|
78
88
|
provenanceFromTrustContext,
|
|
89
|
+
setConversationInferenceProfile,
|
|
79
90
|
setConversationOriginChannelIfUnset,
|
|
80
91
|
setConversationOriginInterfaceIfUnset,
|
|
81
92
|
} from "../../memory/conversation-crud.js";
|
|
@@ -90,18 +101,19 @@ import { checkIngressForSecrets } from "../../security/secret-ingress.js";
|
|
|
90
101
|
import { redactSecrets } from "../../security/secret-scanner.js";
|
|
91
102
|
import { summarizeToolInput } from "../../tools/tool-input-summary.js";
|
|
92
103
|
import { getLogger } from "../../util/logger.js";
|
|
93
|
-
import {
|
|
104
|
+
import {
|
|
105
|
+
getInterfacesDir,
|
|
106
|
+
getWorkspacePromptPath,
|
|
107
|
+
} from "../../util/platform.js";
|
|
94
108
|
import { silentlyWithLog } from "../../util/silently.js";
|
|
95
109
|
import { buildAssistantEvent } from "../assistant-event.js";
|
|
110
|
+
import { assistantEventHub } from "../assistant-event-hub.js";
|
|
96
111
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
|
|
97
|
-
import type { AuthContext } from "../auth/types.js";
|
|
98
112
|
import { getChromeExtensionRegistry } from "../chrome-extension-registry.js";
|
|
99
113
|
import { getClientRegistry } from "../client-registry.js";
|
|
100
114
|
import { bridgeConfirmationRequestToGuardian } from "../confirmation-request-guardian-bridge.js";
|
|
101
115
|
import { routeGuardianReply } from "../guardian-reply-router.js";
|
|
102
116
|
import { healGuardianBindingDrift } from "../guardian-vellum-migration.js";
|
|
103
|
-
import { httpError } from "../http-errors.js";
|
|
104
|
-
import type { RouteDefinition } from "../http-router.js";
|
|
105
117
|
import type {
|
|
106
118
|
ApprovalConversationGenerator,
|
|
107
119
|
RuntimeAttachmentMetadata,
|
|
@@ -114,6 +126,9 @@ import {
|
|
|
114
126
|
resolveTrustContext,
|
|
115
127
|
withSourceChannel,
|
|
116
128
|
} from "../trust-context-resolver.js";
|
|
129
|
+
import { BadRequestError, InternalError, RouteError } from "./errors.js";
|
|
130
|
+
import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
131
|
+
import { RouteResponse } from "./types.js";
|
|
117
132
|
|
|
118
133
|
const log = getLogger("conversation-routes");
|
|
119
134
|
|
|
@@ -121,6 +136,15 @@ const log = getLogger("conversation-routes");
|
|
|
121
136
|
const NO_RESPONSE_INLINE_RE = /<no_response\s*\/?>/g;
|
|
122
137
|
|
|
123
138
|
const SUGGESTION_CACHE_MAX = 100;
|
|
139
|
+
const VALID_RISK_THRESHOLDS = ["none", "low", "medium", "high"] as const;
|
|
140
|
+
type RiskThreshold = (typeof VALID_RISK_THRESHOLDS)[number];
|
|
141
|
+
|
|
142
|
+
function isValidRiskThreshold(value: unknown): value is RiskThreshold {
|
|
143
|
+
return (
|
|
144
|
+
typeof value === "string" &&
|
|
145
|
+
VALID_RISK_THRESHOLDS.includes(value as RiskThreshold)
|
|
146
|
+
);
|
|
147
|
+
}
|
|
124
148
|
|
|
125
149
|
function collectCanonicalGuardianRequestHintIds(
|
|
126
150
|
conversationId: string,
|
|
@@ -368,11 +392,11 @@ function getInterfaceFilesWithMtimes(
|
|
|
368
392
|
}
|
|
369
393
|
|
|
370
394
|
export function handleListMessages(
|
|
371
|
-
|
|
395
|
+
{ queryParams }: RouteHandlerArgs,
|
|
372
396
|
interfacesDir: string | null,
|
|
373
|
-
):
|
|
374
|
-
const conversationId =
|
|
375
|
-
const conversationKey =
|
|
397
|
+
): Record<string, unknown> {
|
|
398
|
+
const conversationId = queryParams?.conversationId;
|
|
399
|
+
const conversationKey = queryParams?.conversationKey;
|
|
376
400
|
|
|
377
401
|
let resolvedConversationId: string | undefined;
|
|
378
402
|
if (conversationId) {
|
|
@@ -381,30 +405,40 @@ export function handleListMessages(
|
|
|
381
405
|
const mapping = getConversationByKey(conversationKey);
|
|
382
406
|
resolvedConversationId = mapping?.conversationId;
|
|
383
407
|
} else {
|
|
384
|
-
|
|
385
|
-
"BAD_REQUEST",
|
|
408
|
+
throw new BadRequestError(
|
|
386
409
|
"conversationKey or conversationId query parameter is required",
|
|
387
|
-
400,
|
|
388
410
|
);
|
|
389
411
|
}
|
|
390
412
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
const beforeTimestampRaw = url.searchParams.get("beforeTimestamp");
|
|
396
|
-
const limitRaw = url.searchParams.get("limit");
|
|
413
|
+
const beforeTimestampRaw = queryParams?.beforeTimestamp;
|
|
414
|
+
const limitRaw = queryParams?.limit;
|
|
415
|
+
const pageRaw = queryParams?.page;
|
|
397
416
|
|
|
398
417
|
// Validate: reject NaN values with 400
|
|
399
|
-
if (beforeTimestampRaw
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
);
|
|
418
|
+
if (beforeTimestampRaw != null && isNaN(Number(beforeTimestampRaw))) {
|
|
419
|
+
throw new BadRequestError("beforeTimestamp must be a valid number");
|
|
420
|
+
}
|
|
421
|
+
if (limitRaw != null && isNaN(Number(limitRaw))) {
|
|
422
|
+
throw new BadRequestError("limit must be a valid number");
|
|
405
423
|
}
|
|
406
|
-
if (
|
|
407
|
-
|
|
424
|
+
if (pageRaw != null && pageRaw !== "latest") {
|
|
425
|
+
throw new BadRequestError("page must be 'latest' when provided");
|
|
426
|
+
}
|
|
427
|
+
const isLatestPage = pageRaw === "latest";
|
|
428
|
+
|
|
429
|
+
if (!resolvedConversationId) {
|
|
430
|
+
// Unresolved conversation keys still need to advertise the stable
|
|
431
|
+
// `page=latest` contract so the web client can rely on metadata fields
|
|
432
|
+
// being present even before any message is persisted.
|
|
433
|
+
if (isLatestPage && beforeTimestampRaw == null) {
|
|
434
|
+
return {
|
|
435
|
+
messages: [],
|
|
436
|
+
hasMore: false,
|
|
437
|
+
oldestTimestamp: null,
|
|
438
|
+
oldestMessageId: null,
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
return { messages: [] };
|
|
408
442
|
}
|
|
409
443
|
|
|
410
444
|
const beforeTimestamp = beforeTimestampRaw
|
|
@@ -415,10 +449,12 @@ export function handleListMessages(
|
|
|
415
449
|
? Math.min(Math.max(Math.floor(Number(limitRaw)), 1), 500)
|
|
416
450
|
: undefined;
|
|
417
451
|
|
|
418
|
-
//
|
|
419
|
-
//
|
|
420
|
-
//
|
|
421
|
-
|
|
452
|
+
// Paginate when either `beforeTimestamp` (older-page request) or
|
|
453
|
+
// `page=latest` (initial newest-N request) is set. When both are sent,
|
|
454
|
+
// `beforeTimestamp` wins because the caller is explicitly asking for an
|
|
455
|
+
// older page; `getMessagesPaginated` ignores `beforeTimestamp === undefined`
|
|
456
|
+
// and returns the newest `limit` messages in chronological order.
|
|
457
|
+
const isPaginated = beforeTimestamp != null || isLatestPage;
|
|
422
458
|
|
|
423
459
|
let rawMessages: MessageRow[];
|
|
424
460
|
let hasMore = false;
|
|
@@ -583,12 +619,12 @@ export function handleListMessages(
|
|
|
583
619
|
// aren't lost before DB compaction relinks them.
|
|
584
620
|
const idsToQuery = [m.id, ...(mergedIdMap.get(m.id) ?? [])];
|
|
585
621
|
const linked = idsToQuery.flatMap((id) =>
|
|
586
|
-
|
|
622
|
+
getAttachmentMetadataForMessage(id),
|
|
587
623
|
);
|
|
588
624
|
if (linked.length > 0) {
|
|
589
625
|
msgAttachments = linked.map((a) => {
|
|
590
626
|
if (a.mimeType.startsWith("image/")) {
|
|
591
|
-
const full =
|
|
627
|
+
const full = getAttachmentById(a.id, {
|
|
592
628
|
hydrateFileData: true,
|
|
593
629
|
});
|
|
594
630
|
return {
|
|
@@ -664,15 +700,28 @@ export function handleListMessages(
|
|
|
664
700
|
rawMessages.length > 0 ? rawMessages[0].createdAt : undefined;
|
|
665
701
|
const oldestMessageId =
|
|
666
702
|
rawMessages.length > 0 ? rawMessages[0].id : undefined;
|
|
667
|
-
|
|
703
|
+
// `page=latest` always emits both metadata fields so the web client has
|
|
704
|
+
// a stable contract; emit `null` when the conversation is empty.
|
|
705
|
+
// The existing `beforeTimestamp` branch keeps its conditional shape to
|
|
706
|
+
// avoid disturbing current callers.
|
|
707
|
+
if (isLatestPage && beforeTimestamp == null) {
|
|
708
|
+
return {
|
|
709
|
+
messages,
|
|
710
|
+
hasMore,
|
|
711
|
+
oldestTimestamp: oldestTimestamp ?? null,
|
|
712
|
+
oldestMessageId: oldestMessageId ?? null,
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
return {
|
|
668
717
|
messages,
|
|
669
718
|
hasMore,
|
|
670
719
|
...(oldestTimestamp != null ? { oldestTimestamp } : {}),
|
|
671
720
|
...(oldestMessageId != null ? { oldestMessageId } : {}),
|
|
672
|
-
}
|
|
721
|
+
};
|
|
673
722
|
}
|
|
674
723
|
|
|
675
|
-
return
|
|
724
|
+
return { messages };
|
|
676
725
|
}
|
|
677
726
|
|
|
678
727
|
// ── Tool-result merging ─────────────────────────────────────────────
|
|
@@ -1003,7 +1052,6 @@ function makeHubPublisher(
|
|
|
1003
1052
|
allowlistOptions: msg.allowlistOptions,
|
|
1004
1053
|
scopeOptions: msg.scopeOptions,
|
|
1005
1054
|
persistentDecisionsAllowed: msg.persistentDecisionsAllowed,
|
|
1006
|
-
temporaryOptionsAvailable: msg.temporaryOptionsAvailable,
|
|
1007
1055
|
},
|
|
1008
1056
|
});
|
|
1009
1057
|
|
|
@@ -1024,6 +1072,7 @@ function makeHubPublisher(
|
|
|
1024
1072
|
dedupKey,
|
|
1025
1073
|
urgency: msg.riskLevel === "high" ? "high" : "medium",
|
|
1026
1074
|
conversationId,
|
|
1075
|
+
detailPanel: { kind: "toolPermission" },
|
|
1027
1076
|
}).catch((err) => {
|
|
1028
1077
|
log.warn(
|
|
1029
1078
|
{ err, requestId: msg.requestId },
|
|
@@ -1044,6 +1093,7 @@ function makeHubPublisher(
|
|
|
1044
1093
|
dedupKey,
|
|
1045
1094
|
urgency: msg.riskLevel === "high" ? "high" : "medium",
|
|
1046
1095
|
conversationId,
|
|
1096
|
+
detailPanel: { kind: "toolPermission" },
|
|
1047
1097
|
});
|
|
1048
1098
|
}
|
|
1049
1099
|
})
|
|
@@ -1225,83 +1275,93 @@ function registerHostProxyPendingInteraction(
|
|
|
1225
1275
|
});
|
|
1226
1276
|
return msg.requestId;
|
|
1227
1277
|
}
|
|
1278
|
+
if (msg.type === "host_transfer_request") {
|
|
1279
|
+
pendingInteractions.register(msg.requestId, {
|
|
1280
|
+
conversation,
|
|
1281
|
+
conversationId,
|
|
1282
|
+
kind: "host_transfer",
|
|
1283
|
+
});
|
|
1284
|
+
return msg.requestId;
|
|
1285
|
+
}
|
|
1228
1286
|
return undefined;
|
|
1229
1287
|
}
|
|
1230
1288
|
|
|
1231
1289
|
/**
|
|
1232
1290
|
* Resolve the host_browser sender function for a conversation turn.
|
|
1233
1291
|
*
|
|
1234
|
-
*
|
|
1235
|
-
*
|
|
1236
|
-
*
|
|
1237
|
-
*
|
|
1238
|
-
*
|
|
1239
|
-
*
|
|
1240
|
-
*
|
|
1241
|
-
*
|
|
1242
|
-
*
|
|
1243
|
-
*
|
|
1244
|
-
* timeout (30 s) instead of failing immediately at send time when the
|
|
1245
|
-
* registry throws on a missing connection.
|
|
1292
|
+
* Transport selection:
|
|
1293
|
+
* 1. **WebSocket registry** — when the guardian has an active entry in
|
|
1294
|
+
* ChromeExtensionRegistry (self-hosted direct WS connection), the
|
|
1295
|
+
* registry-routed sender is returned. Frames go directly over the
|
|
1296
|
+
* WebSocket to the extension.
|
|
1297
|
+
* 2. **SSE event hub** — when no WebSocket connection exists but a
|
|
1298
|
+
* chrome-extension client is connected via SSE (cloud/platform mode),
|
|
1299
|
+
* the SSE hub sender (`onEvent`) is returned. The extension receives
|
|
1300
|
+
* `host_browser_request` frames as SSE events and POSTs results back
|
|
1301
|
+
* to `/v1/host-browser-result`.
|
|
1246
1302
|
*
|
|
1247
|
-
*
|
|
1248
|
-
*
|
|
1249
|
-
*
|
|
1250
|
-
* `
|
|
1251
|
-
*
|
|
1303
|
+
* When neither transport is available, `onEvent` is returned as the
|
|
1304
|
+
* default sender (used by macOS for its native host_browser path).
|
|
1305
|
+
* `hasSseExtension` is `false` in that case so the caller can avoid
|
|
1306
|
+
* provisioning a stale `HostBrowserProxy` for interfaces that don't
|
|
1307
|
+
* natively support host_browser.
|
|
1252
1308
|
*/
|
|
1253
1309
|
function resolveHostBrowserSender(
|
|
1254
1310
|
conversation: Conversation,
|
|
1255
1311
|
conversationId: string,
|
|
1256
|
-
|
|
1312
|
+
actorPrincipalId: string | undefined,
|
|
1257
1313
|
onEvent: (msg: ServerMessage) => void,
|
|
1258
1314
|
sourceInterface: InterfaceId,
|
|
1259
|
-
): {
|
|
1260
|
-
|
|
1315
|
+
): {
|
|
1316
|
+
sender: (msg: ServerMessage) => void;
|
|
1317
|
+
isRegistryRouted: boolean;
|
|
1318
|
+
hasSseExtension: boolean;
|
|
1319
|
+
} {
|
|
1261
1320
|
const guardianId =
|
|
1262
|
-
conversation.trustContext?.guardianPrincipalId ??
|
|
1263
|
-
authContext.actorPrincipalId;
|
|
1321
|
+
conversation.trustContext?.guardianPrincipalId ?? actorPrincipalId;
|
|
1264
1322
|
const hasExtensionConnection =
|
|
1265
1323
|
!!guardianId && !!getChromeExtensionRegistry().get(guardianId);
|
|
1266
1324
|
|
|
1267
|
-
//
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
// Build a registry-routed sender. The guardian principal ID is resolved
|
|
1276
|
-
// at send time rather than captured here so that queue-drain restores
|
|
1277
|
-
// (which re-fire this closure outside the original POST context) follow
|
|
1278
|
-
// the conversation's bound guardian identity rather than a stale
|
|
1279
|
-
// authContext.actorPrincipalId.
|
|
1280
|
-
const registrySender = (msg: ServerMessage): void => {
|
|
1281
|
-
const requestId = registerHostProxyPendingInteraction(
|
|
1282
|
-
msg,
|
|
1283
|
-
conversation,
|
|
1284
|
-
conversationId,
|
|
1285
|
-
);
|
|
1286
|
-
const gid =
|
|
1287
|
-
conversation.trustContext?.guardianPrincipalId ??
|
|
1288
|
-
authContext.actorPrincipalId;
|
|
1289
|
-
if (!gid) {
|
|
1290
|
-
if (requestId) pendingInteractions.resolve(requestId);
|
|
1291
|
-
throw new Error(
|
|
1292
|
-
"host_browser send skipped: no guardianId on AuthContext",
|
|
1293
|
-
);
|
|
1294
|
-
}
|
|
1295
|
-
const ok = getChromeExtensionRegistry().send(gid, msg);
|
|
1296
|
-
if (!ok) {
|
|
1297
|
-
if (requestId) pendingInteractions.resolve(requestId);
|
|
1298
|
-
throw new Error(
|
|
1299
|
-
`host_browser send failed: no active connection for guardian ${gid}`,
|
|
1325
|
+
// Priority 1: WebSocket registry — direct WS to the extension.
|
|
1326
|
+
if (hasExtensionConnection) {
|
|
1327
|
+
const registrySender = (msg: ServerMessage): void => {
|
|
1328
|
+
const requestId = registerHostProxyPendingInteraction(
|
|
1329
|
+
msg,
|
|
1330
|
+
conversation,
|
|
1331
|
+
conversationId,
|
|
1300
1332
|
);
|
|
1301
|
-
|
|
1302
|
-
|
|
1333
|
+
const gid =
|
|
1334
|
+
conversation.trustContext?.guardianPrincipalId ?? actorPrincipalId;
|
|
1335
|
+
if (!gid) {
|
|
1336
|
+
if (requestId) pendingInteractions.resolve(requestId);
|
|
1337
|
+
throw new Error(
|
|
1338
|
+
"host_browser send skipped: no guardianId on AuthContext",
|
|
1339
|
+
);
|
|
1340
|
+
}
|
|
1341
|
+
const ok = getChromeExtensionRegistry().send(gid, msg);
|
|
1342
|
+
if (!ok) {
|
|
1343
|
+
if (requestId) pendingInteractions.resolve(requestId);
|
|
1344
|
+
throw new Error(
|
|
1345
|
+
`host_browser send failed: no active connection for guardian ${gid}`,
|
|
1346
|
+
);
|
|
1347
|
+
}
|
|
1348
|
+
};
|
|
1349
|
+
return {
|
|
1350
|
+
sender: registrySender,
|
|
1351
|
+
isRegistryRouted: true,
|
|
1352
|
+
hasSseExtension: false,
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
// Priority 2: SSE-connected chrome extension (cloud/platform mode).
|
|
1357
|
+
// Check the ClientRegistry for a chrome-extension client specifically —
|
|
1358
|
+
// getMostRecentByCapability("host_browser") would also match macOS
|
|
1359
|
+
// clients, which handle browser frames through their own native path.
|
|
1360
|
+
const hasSseExtension =
|
|
1361
|
+
canServiceSseBrowser(sourceInterface) &&
|
|
1362
|
+
!!getClientRegistry().getMostRecentByInterface("chrome-extension");
|
|
1303
1363
|
|
|
1304
|
-
return { sender:
|
|
1364
|
+
return { sender: onEvent, isRegistryRouted: false, hasSseExtension };
|
|
1305
1365
|
}
|
|
1306
1366
|
|
|
1307
1367
|
/**
|
|
@@ -1395,15 +1455,13 @@ export function persistOnboardingArtifacts(onboarding: {
|
|
|
1395
1455
|
}
|
|
1396
1456
|
|
|
1397
1457
|
export async function handleSendMessage(
|
|
1398
|
-
|
|
1458
|
+
{ body: rawBody, headers }: RouteHandlerArgs,
|
|
1399
1459
|
deps: {
|
|
1400
1460
|
sendMessageDeps?: SendMessageDeps;
|
|
1401
1461
|
approvalConversationGenerator?: ApprovalConversationGenerator;
|
|
1402
|
-
heartbeatService?: HeartbeatService;
|
|
1403
1462
|
},
|
|
1404
|
-
|
|
1405
|
-
)
|
|
1406
|
-
const body = (await req.json()) as {
|
|
1463
|
+
): Promise<unknown> {
|
|
1464
|
+
const body = (rawBody ?? {}) as {
|
|
1407
1465
|
conversationKey?: string;
|
|
1408
1466
|
content?: string;
|
|
1409
1467
|
attachmentIds?: string[];
|
|
@@ -1416,6 +1474,8 @@ export async function handleSendMessage(
|
|
|
1416
1474
|
hostUsername?: string;
|
|
1417
1475
|
clientId?: string;
|
|
1418
1476
|
clientMessageId?: string;
|
|
1477
|
+
inferenceProfile?: string | null;
|
|
1478
|
+
riskThreshold?: string;
|
|
1419
1479
|
onboarding?: {
|
|
1420
1480
|
tools: string[];
|
|
1421
1481
|
tasks: string[];
|
|
@@ -1425,35 +1485,70 @@ export async function handleSendMessage(
|
|
|
1425
1485
|
};
|
|
1426
1486
|
};
|
|
1427
1487
|
|
|
1488
|
+
const actorPrincipalId = headers?.["x-vellum-actor-principal-id"];
|
|
1489
|
+
const principalType = headers?.["x-vellum-principal-type"];
|
|
1490
|
+
|
|
1428
1491
|
const { conversationKey, content, attachmentIds } = body;
|
|
1429
1492
|
const clientMessageId =
|
|
1430
1493
|
typeof body.clientMessageId === "string" ? body.clientMessageId : undefined;
|
|
1494
|
+
const requestedInferenceProfile =
|
|
1495
|
+
typeof body.inferenceProfile === "string"
|
|
1496
|
+
? body.inferenceProfile
|
|
1497
|
+
: undefined;
|
|
1498
|
+
const requestedRiskThreshold = body.riskThreshold;
|
|
1499
|
+
if (
|
|
1500
|
+
body.inferenceProfile != null &&
|
|
1501
|
+
typeof body.inferenceProfile !== "string"
|
|
1502
|
+
) {
|
|
1503
|
+
throw new BadRequestError(
|
|
1504
|
+
"inferenceProfile must be a non-empty string or null",
|
|
1505
|
+
);
|
|
1506
|
+
}
|
|
1507
|
+
if (requestedInferenceProfile === "") {
|
|
1508
|
+
throw new BadRequestError(
|
|
1509
|
+
"inferenceProfile must be a non-empty string or null",
|
|
1510
|
+
);
|
|
1511
|
+
}
|
|
1512
|
+
if (requestedInferenceProfile !== undefined) {
|
|
1513
|
+
const profiles = getConfig().llm.profiles ?? {};
|
|
1514
|
+
if (
|
|
1515
|
+
!Object.prototype.hasOwnProperty.call(profiles, requestedInferenceProfile)
|
|
1516
|
+
) {
|
|
1517
|
+
throw new BadRequestError(
|
|
1518
|
+
`Profile "${requestedInferenceProfile}" is not defined in llm.profiles`,
|
|
1519
|
+
);
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
if (
|
|
1523
|
+
requestedRiskThreshold !== undefined &&
|
|
1524
|
+
!isValidRiskThreshold(requestedRiskThreshold)
|
|
1525
|
+
) {
|
|
1526
|
+
throw new BadRequestError(
|
|
1527
|
+
`riskThreshold must be one of: ${VALID_RISK_THRESHOLDS.join(", ")}`,
|
|
1528
|
+
);
|
|
1529
|
+
}
|
|
1431
1530
|
if (!body.sourceChannel || typeof body.sourceChannel !== "string") {
|
|
1432
|
-
|
|
1531
|
+
throw new BadRequestError("sourceChannel is required");
|
|
1433
1532
|
}
|
|
1434
1533
|
const sourceChannel = parseChannelId(body.sourceChannel);
|
|
1435
1534
|
|
|
1436
1535
|
if (!sourceChannel) {
|
|
1437
|
-
|
|
1438
|
-
"BAD_REQUEST",
|
|
1536
|
+
throw new BadRequestError(
|
|
1439
1537
|
`Invalid sourceChannel: ${
|
|
1440
1538
|
body.sourceChannel
|
|
1441
1539
|
}. Valid values: ${CHANNEL_IDS.join(", ")}`,
|
|
1442
|
-
400,
|
|
1443
1540
|
);
|
|
1444
1541
|
}
|
|
1445
1542
|
|
|
1446
1543
|
if (!body.interface || typeof body.interface !== "string") {
|
|
1447
|
-
|
|
1544
|
+
throw new BadRequestError("interface is required");
|
|
1448
1545
|
}
|
|
1449
1546
|
const sourceInterface = parseInterfaceId(body.interface);
|
|
1450
1547
|
if (!sourceInterface) {
|
|
1451
|
-
|
|
1452
|
-
"BAD_REQUEST",
|
|
1548
|
+
throw new BadRequestError(
|
|
1453
1549
|
`Invalid interface: ${body.interface}. Valid values: ${INTERFACE_IDS.join(
|
|
1454
1550
|
", ",
|
|
1455
1551
|
)}`,
|
|
1456
|
-
400,
|
|
1457
1552
|
);
|
|
1458
1553
|
}
|
|
1459
1554
|
|
|
@@ -1465,7 +1560,7 @@ export async function handleSendMessage(
|
|
|
1465
1560
|
|
|
1466
1561
|
// Reject non-string content values (numbers, objects, etc.)
|
|
1467
1562
|
if (content != null && typeof content !== "string") {
|
|
1468
|
-
|
|
1563
|
+
throw new BadRequestError("content must be a string");
|
|
1469
1564
|
}
|
|
1470
1565
|
|
|
1471
1566
|
const trimmedContent = typeof content === "string" ? content.trim() : "";
|
|
@@ -1473,23 +1568,17 @@ export async function handleSendMessage(
|
|
|
1473
1568
|
Array.isArray(attachmentIds) && attachmentIds.length > 0;
|
|
1474
1569
|
|
|
1475
1570
|
if (trimmedContent.length === 0 && !hasAttachments) {
|
|
1476
|
-
|
|
1477
|
-
"BAD_REQUEST",
|
|
1478
|
-
"content or attachmentIds is required",
|
|
1479
|
-
400,
|
|
1480
|
-
);
|
|
1571
|
+
throw new BadRequestError("content or attachmentIds is required");
|
|
1481
1572
|
}
|
|
1482
1573
|
|
|
1483
1574
|
// Validate that all attachment IDs resolve
|
|
1484
1575
|
if (hasAttachments) {
|
|
1485
|
-
const resolved =
|
|
1576
|
+
const resolved = getAttachmentsByIds(attachmentIds);
|
|
1486
1577
|
if (resolved.length !== attachmentIds.length) {
|
|
1487
1578
|
const resolvedIds = new Set(resolved.map((a) => a.id));
|
|
1488
1579
|
const missing = attachmentIds.filter((id) => !resolvedIds.has(id));
|
|
1489
|
-
|
|
1490
|
-
"BAD_REQUEST",
|
|
1580
|
+
throw new BadRequestError(
|
|
1491
1581
|
`Attachment IDs not found: ${missing.join(", ")}`,
|
|
1492
|
-
400,
|
|
1493
1582
|
);
|
|
1494
1583
|
}
|
|
1495
1584
|
}
|
|
@@ -1498,36 +1587,52 @@ export async function handleSendMessage(
|
|
|
1498
1587
|
if (trimmedContent.length > 0 && !body.bypassSecretCheck) {
|
|
1499
1588
|
const ingressResult = checkIngressForSecrets(trimmedContent);
|
|
1500
1589
|
if (ingressResult.blocked) {
|
|
1501
|
-
return
|
|
1502
|
-
{
|
|
1590
|
+
return new RouteResponse(
|
|
1591
|
+
JSON.stringify({
|
|
1503
1592
|
accepted: false,
|
|
1504
1593
|
error: "secret_blocked",
|
|
1505
1594
|
message: ingressResult.userNotice,
|
|
1506
1595
|
detectedTypes: ingressResult.detectedTypes,
|
|
1507
|
-
},
|
|
1508
|
-
{
|
|
1596
|
+
}),
|
|
1597
|
+
{ "content-type": "application/json" },
|
|
1598
|
+
422,
|
|
1509
1599
|
);
|
|
1510
1600
|
}
|
|
1511
1601
|
}
|
|
1512
1602
|
|
|
1513
1603
|
if (!deps.sendMessageDeps) {
|
|
1514
|
-
|
|
1515
|
-
"SERVICE_UNAVAILABLE",
|
|
1604
|
+
throw new RouteError(
|
|
1516
1605
|
"Message processing is not available",
|
|
1606
|
+
"SERVICE_UNAVAILABLE",
|
|
1517
1607
|
503,
|
|
1518
1608
|
);
|
|
1519
1609
|
}
|
|
1520
1610
|
|
|
1521
1611
|
// Desktop messages are always from the guardian — reset the heartbeat
|
|
1522
1612
|
// timer so the next heartbeat is a full interval after this interaction.
|
|
1523
|
-
|
|
1613
|
+
HeartbeatService.getInstance()?.resetTimer();
|
|
1524
1614
|
|
|
1525
|
-
const conversationType =
|
|
1526
|
-
body.conversationType === "private" ? ("private" as const) : undefined;
|
|
1527
1615
|
const mapping = getOrCreateConversation(resolvedConversationKey, {
|
|
1528
|
-
conversationType,
|
|
1616
|
+
conversationType: "standard",
|
|
1529
1617
|
});
|
|
1530
1618
|
|
|
1619
|
+
if (requestedRiskThreshold !== undefined) {
|
|
1620
|
+
const result = await ipcCall("set_conversation_threshold", {
|
|
1621
|
+
conversationId: mapping.conversationId,
|
|
1622
|
+
threshold: requestedRiskThreshold,
|
|
1623
|
+
});
|
|
1624
|
+
if (result === undefined) {
|
|
1625
|
+
log.error(
|
|
1626
|
+
{
|
|
1627
|
+
conversationId: mapping.conversationId,
|
|
1628
|
+
threshold: requestedRiskThreshold,
|
|
1629
|
+
},
|
|
1630
|
+
"Failed to set conversation risk threshold override via gateway IPC",
|
|
1631
|
+
);
|
|
1632
|
+
throw new InternalError("Failed to persist risk threshold override");
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1531
1636
|
const smDeps = deps.sendMessageDeps;
|
|
1532
1637
|
|
|
1533
1638
|
// Notify all connected clients that the conversation list changed when
|
|
@@ -1571,27 +1676,18 @@ export async function handleSendMessage(
|
|
|
1571
1676
|
interfaceId: sourceInterface,
|
|
1572
1677
|
} satisfies NonHostProxyTransportMetadata);
|
|
1573
1678
|
|
|
1574
|
-
// Register/refresh the client in the unified client registry so
|
|
1575
|
-
// `assistant clients list` can discover all connected interfaces.
|
|
1576
|
-
// Uses the client-supplied clientId when available (stable per-install
|
|
1577
|
-
// UUID), falling back to a synthetic key derived from interfaceId so
|
|
1578
|
-
// older clients that don't send clientId still appear in the registry.
|
|
1579
|
-
const effectiveClientId =
|
|
1580
|
-
typeof body.clientId === "string" && body.clientId.length > 0
|
|
1581
|
-
? body.clientId
|
|
1582
|
-
: `synthetic:${sourceInterface}`;
|
|
1583
|
-
getClientRegistry().register({
|
|
1584
|
-
clientId: effectiveClientId,
|
|
1585
|
-
interfaceId: sourceInterface,
|
|
1586
|
-
hostHomeDir: body.hostHomeDir,
|
|
1587
|
-
hostUsername: body.hostUsername,
|
|
1588
|
-
});
|
|
1589
|
-
|
|
1590
1679
|
const conversation = await smDeps.getOrCreateConversation(
|
|
1591
1680
|
mapping.conversationId,
|
|
1592
1681
|
{ transport },
|
|
1593
1682
|
);
|
|
1594
1683
|
|
|
1684
|
+
if (requestedInferenceProfile !== undefined) {
|
|
1685
|
+
setConversationInferenceProfile(
|
|
1686
|
+
mapping.conversationId,
|
|
1687
|
+
requestedInferenceProfile,
|
|
1688
|
+
);
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1595
1691
|
// Store pre-chat onboarding context on the conversation when this is the
|
|
1596
1692
|
// very first message (no prior messages loaded). Artifact persistence
|
|
1597
1693
|
// (IDENTITY.md, USER.md, sidecar) is deferred: on the canned greeting
|
|
@@ -1607,11 +1703,11 @@ export async function handleSendMessage(
|
|
|
1607
1703
|
// Resolve guardian context from the AuthContext's actorPrincipalId.
|
|
1608
1704
|
// The JWT-verified principal is used as the sender identity through
|
|
1609
1705
|
// the same trust resolution pipeline that channel ingress uses.
|
|
1610
|
-
if (
|
|
1706
|
+
if (actorPrincipalId) {
|
|
1611
1707
|
// Dev bypass (HTTP auth disabled): the synthetic "dev-bypass" principal
|
|
1612
1708
|
// won't match any guardian binding. Resolve from the local guardian
|
|
1613
1709
|
// binding instead, which produces the correct guardian trust context.
|
|
1614
|
-
if (isHttpAuthDisabled() &&
|
|
1710
|
+
if (isHttpAuthDisabled() && actorPrincipalId === "dev-bypass") {
|
|
1615
1711
|
conversation.setTrustContext(resolveLocalTrustContext(sourceChannel));
|
|
1616
1712
|
} else {
|
|
1617
1713
|
const assistantId = DAEMON_INTERNAL_ASSISTANT_ID;
|
|
@@ -1619,24 +1715,24 @@ export async function handleSendMessage(
|
|
|
1619
1715
|
assistantId,
|
|
1620
1716
|
sourceChannel: "vellum",
|
|
1621
1717
|
conversationExternalId: "local",
|
|
1622
|
-
actorExternalId:
|
|
1718
|
+
actorExternalId: actorPrincipalId,
|
|
1623
1719
|
});
|
|
1624
1720
|
if (trustCtx.trustClass === "unknown") {
|
|
1625
1721
|
// Attempt to heal guardian binding drift: after a DB reset the
|
|
1626
1722
|
// guardian binding gets a new vellum-principal-* UUID while the
|
|
1627
1723
|
// client still holds a valid JWT with the old one. The signing
|
|
1628
1724
|
// key survives the reset, so the JWT is authentic — just stale.
|
|
1629
|
-
const healed = healGuardianBindingDrift(
|
|
1725
|
+
const healed = healGuardianBindingDrift(actorPrincipalId);
|
|
1630
1726
|
if (healed) {
|
|
1631
1727
|
trustCtx = resolveTrustContext({
|
|
1632
1728
|
assistantId,
|
|
1633
1729
|
sourceChannel: "vellum",
|
|
1634
1730
|
conversationExternalId: "local",
|
|
1635
|
-
actorExternalId:
|
|
1731
|
+
actorExternalId: actorPrincipalId,
|
|
1636
1732
|
});
|
|
1637
1733
|
log.info(
|
|
1638
1734
|
{
|
|
1639
|
-
actorPrincipalId:
|
|
1735
|
+
actorPrincipalId: actorPrincipalId,
|
|
1640
1736
|
trustClass: trustCtx.trustClass,
|
|
1641
1737
|
},
|
|
1642
1738
|
"Trust re-resolved after guardian binding drift heal",
|
|
@@ -1644,10 +1740,10 @@ export async function handleSendMessage(
|
|
|
1644
1740
|
} else {
|
|
1645
1741
|
log.warn(
|
|
1646
1742
|
{
|
|
1647
|
-
actorPrincipalId:
|
|
1743
|
+
actorPrincipalId: actorPrincipalId,
|
|
1648
1744
|
sourceChannel,
|
|
1649
1745
|
trustClass: trustCtx.trustClass,
|
|
1650
|
-
principalType:
|
|
1746
|
+
principalType: principalType,
|
|
1651
1747
|
},
|
|
1652
1748
|
"JWT-verified actor resolved to unknown trust class — possible guardian binding drift (e.g. DB reset without re-bootstrap)",
|
|
1653
1749
|
);
|
|
@@ -1686,17 +1782,19 @@ export async function handleSendMessage(
|
|
|
1686
1782
|
conversation.setHostBashProxy(undefined);
|
|
1687
1783
|
}
|
|
1688
1784
|
// Resolve the host_browser sender — registry-routed when the guardian has
|
|
1689
|
-
// an active extension connection, SSE hub
|
|
1690
|
-
//
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1785
|
+
// an active WS extension connection, SSE hub when a chrome-extension is
|
|
1786
|
+
// connected via SSE (cloud mode), or SSE hub as default for macOS.
|
|
1787
|
+
const {
|
|
1788
|
+
sender: browserProxySendToClient,
|
|
1789
|
+
isRegistryRouted,
|
|
1790
|
+
hasSseExtension,
|
|
1791
|
+
} = resolveHostBrowserSender(
|
|
1792
|
+
conversation,
|
|
1793
|
+
mapping.conversationId,
|
|
1794
|
+
actorPrincipalId,
|
|
1795
|
+
onEvent,
|
|
1796
|
+
sourceInterface,
|
|
1797
|
+
);
|
|
1700
1798
|
|
|
1701
1799
|
// Stash the registry-routed sender on the conversation so queue-drain
|
|
1702
1800
|
// restores (which run outside of conversation-routes.ts and only have
|
|
@@ -1711,16 +1809,18 @@ export async function handleSendMessage(
|
|
|
1711
1809
|
conversation.hostBrowserSenderOverride = undefined;
|
|
1712
1810
|
}
|
|
1713
1811
|
|
|
1714
|
-
// Provision the host browser proxy
|
|
1715
|
-
// natively
|
|
1716
|
-
//
|
|
1717
|
-
//
|
|
1718
|
-
//
|
|
1719
|
-
//
|
|
1720
|
-
//
|
|
1812
|
+
// Provision the host browser proxy when a viable transport exists:
|
|
1813
|
+
// - macOS: natively supports host_browser via its own SSE path
|
|
1814
|
+
// - WS registry: extension connected via direct WebSocket
|
|
1815
|
+
// - SSE extension: chrome extension connected via SSE (cloud mode)
|
|
1816
|
+
//
|
|
1817
|
+
// For chrome-extension, require an active transport (WS or SSE). Without
|
|
1818
|
+
// one, host_browser_request frames would be emitted to the SSE hub with
|
|
1819
|
+
// no consumer, causing a 30s proxy timeout instead of failing fast.
|
|
1721
1820
|
const shouldProvisionBrowserProxy =
|
|
1722
|
-
supportsHostProxy(sourceInterface
|
|
1723
|
-
(canServiceRegistryBrowser(sourceInterface) && isRegistryRouted)
|
|
1821
|
+
supportsHostProxy(sourceInterface) ||
|
|
1822
|
+
(canServiceRegistryBrowser(sourceInterface) && isRegistryRouted) ||
|
|
1823
|
+
hasSseExtension;
|
|
1724
1824
|
if (shouldProvisionBrowserProxy) {
|
|
1725
1825
|
if (!conversation.isProcessing() || !conversation.hostBrowserProxy) {
|
|
1726
1826
|
const browserProxy = new HostBrowserProxy(
|
|
@@ -1741,8 +1841,15 @@ export async function handleSendMessage(
|
|
|
1741
1841
|
});
|
|
1742
1842
|
conversation.setHostFileProxy(fileProxy);
|
|
1743
1843
|
}
|
|
1844
|
+
if (!conversation.isProcessing() || !conversation.getHostTransferProxy()) {
|
|
1845
|
+
const transferProxy = new HostTransferProxy(onEvent, (requestId) => {
|
|
1846
|
+
pendingInteractions.resolve(requestId);
|
|
1847
|
+
});
|
|
1848
|
+
conversation.setHostTransferProxy(transferProxy);
|
|
1849
|
+
}
|
|
1744
1850
|
} else if (!conversation.isProcessing()) {
|
|
1745
1851
|
conversation.setHostFileProxy(undefined);
|
|
1852
|
+
conversation.setHostTransferProxy(undefined);
|
|
1746
1853
|
}
|
|
1747
1854
|
if (supportsHostProxy(sourceInterface, "host_cu")) {
|
|
1748
1855
|
if (!conversation.isProcessing() || !conversation.hostCuProxy) {
|
|
@@ -1847,10 +1954,11 @@ export async function handleSendMessage(
|
|
|
1847
1954
|
);
|
|
1848
1955
|
conversation.getMessages().push(assistantMsg);
|
|
1849
1956
|
|
|
1850
|
-
const response =
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1957
|
+
const response = {
|
|
1958
|
+
accepted: true,
|
|
1959
|
+
messageId: persisted.id,
|
|
1960
|
+
conversationId,
|
|
1961
|
+
};
|
|
1854
1962
|
|
|
1855
1963
|
setTimeout(() => {
|
|
1856
1964
|
onEvent({
|
|
@@ -1926,16 +2034,13 @@ export async function handleSendMessage(
|
|
|
1926
2034
|
verifiedActorPrincipalId,
|
|
1927
2035
|
});
|
|
1928
2036
|
if (inlineReplyResult.consumed) {
|
|
1929
|
-
return
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
},
|
|
1937
|
-
{ status: 202 },
|
|
1938
|
-
);
|
|
2037
|
+
return {
|
|
2038
|
+
accepted: true,
|
|
2039
|
+
conversationId: mapping.conversationId,
|
|
2040
|
+
...(inlineReplyResult.messageId
|
|
2041
|
+
? { messageId: inlineReplyResult.messageId }
|
|
2042
|
+
: {}),
|
|
2043
|
+
};
|
|
1939
2044
|
}
|
|
1940
2045
|
} catch (err) {
|
|
1941
2046
|
log.warn(
|
|
@@ -1967,9 +2072,10 @@ export async function handleSendMessage(
|
|
|
1967
2072
|
clientMessageId,
|
|
1968
2073
|
);
|
|
1969
2074
|
if (enqueueResult.rejected) {
|
|
1970
|
-
return
|
|
1971
|
-
{ accepted: false, error: "queue_full" },
|
|
1972
|
-
{
|
|
2075
|
+
return new RouteResponse(
|
|
2076
|
+
JSON.stringify({ accepted: false, error: "queue_full" }),
|
|
2077
|
+
{ "content-type": "application/json" },
|
|
2078
|
+
429,
|
|
1973
2079
|
);
|
|
1974
2080
|
}
|
|
1975
2081
|
|
|
@@ -2018,10 +2124,11 @@ export async function handleSendMessage(
|
|
|
2018
2124
|
);
|
|
2019
2125
|
}
|
|
2020
2126
|
|
|
2021
|
-
return
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2127
|
+
return {
|
|
2128
|
+
accepted: true,
|
|
2129
|
+
queued: true,
|
|
2130
|
+
conversationId: mapping.conversationId,
|
|
2131
|
+
};
|
|
2025
2132
|
}
|
|
2026
2133
|
|
|
2027
2134
|
// Auto-deny pending confirmations for idle conversations. The legacy
|
|
@@ -2142,14 +2249,11 @@ export async function handleSendMessage(
|
|
|
2142
2249
|
? await buildModelInfoEvent()
|
|
2143
2250
|
: null;
|
|
2144
2251
|
|
|
2145
|
-
const response =
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
},
|
|
2151
|
-
{ status: 202 },
|
|
2152
|
-
);
|
|
2252
|
+
const response = {
|
|
2253
|
+
accepted: true,
|
|
2254
|
+
messageId: persisted.id,
|
|
2255
|
+
conversationId: mapping.conversationId,
|
|
2256
|
+
};
|
|
2153
2257
|
|
|
2154
2258
|
// Defer event publishing to next tick so the HTTP response reaches the
|
|
2155
2259
|
// client first. This ensures the client's serverToLocalConversationMap is
|
|
@@ -2263,14 +2367,11 @@ export async function handleSendMessage(
|
|
|
2263
2367
|
}
|
|
2264
2368
|
})();
|
|
2265
2369
|
|
|
2266
|
-
return
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
},
|
|
2272
|
-
{ status: 202 },
|
|
2273
|
-
);
|
|
2370
|
+
return {
|
|
2371
|
+
accepted: true,
|
|
2372
|
+
messageId: persisted.id,
|
|
2373
|
+
conversationId,
|
|
2374
|
+
};
|
|
2274
2375
|
}
|
|
2275
2376
|
|
|
2276
2377
|
const resolvedContent = slashResult.content;
|
|
@@ -2310,10 +2411,11 @@ export async function handleSendMessage(
|
|
|
2310
2411
|
);
|
|
2311
2412
|
});
|
|
2312
2413
|
|
|
2313
|
-
return
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2414
|
+
return {
|
|
2415
|
+
accepted: true,
|
|
2416
|
+
messageId,
|
|
2417
|
+
conversationId: mapping.conversationId,
|
|
2418
|
+
};
|
|
2317
2419
|
}
|
|
2318
2420
|
|
|
2319
2421
|
function escapeXmlContent(text: string): string {
|
|
@@ -2400,54 +2502,39 @@ async function generateLlmSuggestion(
|
|
|
2400
2502
|
}
|
|
2401
2503
|
|
|
2402
2504
|
export async function handleGetSuggestion(
|
|
2403
|
-
|
|
2505
|
+
{ queryParams }: RouteHandlerArgs,
|
|
2404
2506
|
deps: {
|
|
2405
2507
|
suggestionCache: Map<string, string>;
|
|
2406
2508
|
suggestionInFlight: Map<string, Promise<string | null>>;
|
|
2407
2509
|
},
|
|
2408
|
-
): Promise<
|
|
2409
|
-
const
|
|
2510
|
+
): Promise<Record<string, unknown>> {
|
|
2511
|
+
const noSuggestion = {
|
|
2512
|
+
suggestion: null,
|
|
2513
|
+
messageId: null,
|
|
2514
|
+
source: "none" as const,
|
|
2515
|
+
};
|
|
2516
|
+
|
|
2517
|
+
const conversationKey = queryParams?.conversationKey;
|
|
2410
2518
|
if (!conversationKey) {
|
|
2411
|
-
|
|
2412
|
-
"BAD_REQUEST",
|
|
2413
|
-
"conversationKey query parameter is required",
|
|
2414
|
-
400,
|
|
2415
|
-
);
|
|
2519
|
+
throw new BadRequestError("conversationKey query parameter is required");
|
|
2416
2520
|
}
|
|
2417
2521
|
|
|
2418
2522
|
const mapping = getConversationByKey(conversationKey);
|
|
2419
|
-
if (!mapping)
|
|
2420
|
-
return Response.json({
|
|
2421
|
-
suggestion: null,
|
|
2422
|
-
messageId: null,
|
|
2423
|
-
source: "none" as const,
|
|
2424
|
-
});
|
|
2425
|
-
}
|
|
2523
|
+
if (!mapping) return noSuggestion;
|
|
2426
2524
|
|
|
2427
2525
|
const rawMessages = getMessages(mapping.conversationId);
|
|
2428
|
-
if (rawMessages.length === 0)
|
|
2429
|
-
return Response.json({
|
|
2430
|
-
suggestion: null,
|
|
2431
|
-
messageId: null,
|
|
2432
|
-
source: "none" as const,
|
|
2433
|
-
});
|
|
2434
|
-
}
|
|
2526
|
+
if (rawMessages.length === 0) return noSuggestion;
|
|
2435
2527
|
|
|
2436
2528
|
// Staleness check: compare requested messageId against the latest
|
|
2437
2529
|
// assistant message BEFORE filtering by text content. This ensures
|
|
2438
2530
|
// that a newer tool-only assistant turn (empty text) still causes
|
|
2439
2531
|
// older messageId requests to be correctly marked as stale.
|
|
2440
|
-
const requestedMessageId =
|
|
2532
|
+
const requestedMessageId = queryParams?.messageId;
|
|
2441
2533
|
if (requestedMessageId) {
|
|
2442
2534
|
for (let i = rawMessages.length - 1; i >= 0; i--) {
|
|
2443
2535
|
if (rawMessages[i].role === "assistant") {
|
|
2444
2536
|
if (rawMessages[i].id !== requestedMessageId) {
|
|
2445
|
-
return
|
|
2446
|
-
suggestion: null,
|
|
2447
|
-
messageId: null,
|
|
2448
|
-
source: "none" as const,
|
|
2449
|
-
stale: true,
|
|
2450
|
-
});
|
|
2537
|
+
return { ...noSuggestion, stale: true };
|
|
2451
2538
|
}
|
|
2452
2539
|
break;
|
|
2453
2540
|
}
|
|
@@ -2475,22 +2562,13 @@ export async function handleGetSuggestion(
|
|
|
2475
2562
|
// If a messageId was requested and the first text-bearing assistant
|
|
2476
2563
|
// message is a *different* message, the request is stale.
|
|
2477
2564
|
if (requestedMessageId && msg.id !== requestedMessageId) {
|
|
2478
|
-
return
|
|
2479
|
-
suggestion: null,
|
|
2480
|
-
messageId: null,
|
|
2481
|
-
source: "none" as const,
|
|
2482
|
-
stale: true,
|
|
2483
|
-
});
|
|
2565
|
+
return { ...noSuggestion, stale: true };
|
|
2484
2566
|
}
|
|
2485
2567
|
|
|
2486
2568
|
// Return cached suggestion if we already generated one for this message
|
|
2487
2569
|
const cached = suggestionCache.get(msg.id);
|
|
2488
2570
|
if (cached !== undefined) {
|
|
2489
|
-
return
|
|
2490
|
-
suggestion: cached,
|
|
2491
|
-
messageId: msg.id,
|
|
2492
|
-
source: "llm" as const,
|
|
2493
|
-
});
|
|
2571
|
+
return { suggestion: cached, messageId: msg.id, source: "llm" as const };
|
|
2494
2572
|
}
|
|
2495
2573
|
|
|
2496
2574
|
// Find the most recent user message preceding this assistant turn so the
|
|
@@ -2534,11 +2612,11 @@ export async function handleGetSuggestion(
|
|
|
2534
2612
|
}
|
|
2535
2613
|
suggestionCache.set(msg.id, llmSuggestion);
|
|
2536
2614
|
|
|
2537
|
-
return
|
|
2615
|
+
return {
|
|
2538
2616
|
suggestion: llmSuggestion,
|
|
2539
2617
|
messageId: msg.id,
|
|
2540
2618
|
source: "llm" as const,
|
|
2541
|
-
}
|
|
2619
|
+
};
|
|
2542
2620
|
}
|
|
2543
2621
|
} catch (err) {
|
|
2544
2622
|
suggestionInFlight.delete(msg.id);
|
|
@@ -2554,18 +2632,10 @@ export async function handleGetSuggestion(
|
|
|
2554
2632
|
);
|
|
2555
2633
|
}
|
|
2556
2634
|
|
|
2557
|
-
return
|
|
2558
|
-
suggestion: null,
|
|
2559
|
-
messageId: null,
|
|
2560
|
-
source: "none" as const,
|
|
2561
|
-
});
|
|
2635
|
+
return noSuggestion;
|
|
2562
2636
|
}
|
|
2563
2637
|
|
|
2564
|
-
return
|
|
2565
|
-
suggestion: null,
|
|
2566
|
-
messageId: null,
|
|
2567
|
-
source: "none" as const,
|
|
2568
|
-
});
|
|
2638
|
+
return noSuggestion;
|
|
2569
2639
|
}
|
|
2570
2640
|
|
|
2571
2641
|
/**
|
|
@@ -2574,19 +2644,17 @@ export async function handleGetSuggestion(
|
|
|
2574
2644
|
* Full-text search across all conversations (message content + titles).
|
|
2575
2645
|
* Returns ranked results grouped by conversation, each with matching message excerpts.
|
|
2576
2646
|
*/
|
|
2577
|
-
function handleSearchConversations(
|
|
2578
|
-
|
|
2647
|
+
function handleSearchConversations({
|
|
2648
|
+
queryParams,
|
|
2649
|
+
}: RouteHandlerArgs): Record<string, unknown> {
|
|
2650
|
+
const query = queryParams?.q ?? "";
|
|
2579
2651
|
if (!query.trim()) {
|
|
2580
|
-
|
|
2652
|
+
throw new BadRequestError("q query parameter is required");
|
|
2581
2653
|
}
|
|
2582
2654
|
|
|
2583
|
-
const limit =
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
const maxMessagesPerConversation = url.searchParams.has(
|
|
2587
|
-
"maxMessagesPerConversation",
|
|
2588
|
-
)
|
|
2589
|
-
? Number(url.searchParams.get("maxMessagesPerConversation"))
|
|
2655
|
+
const limit = queryParams?.limit ? Number(queryParams.limit) : undefined;
|
|
2656
|
+
const maxMessagesPerConversation = queryParams?.maxMessagesPerConversation
|
|
2657
|
+
? Number(queryParams.maxMessagesPerConversation)
|
|
2590
2658
|
: undefined;
|
|
2591
2659
|
|
|
2592
2660
|
const results = searchConversations(query, {
|
|
@@ -2597,105 +2665,125 @@ function handleSearchConversations(url: URL): Response {
|
|
|
2597
2665
|
: {}),
|
|
2598
2666
|
});
|
|
2599
2667
|
|
|
2600
|
-
return
|
|
2668
|
+
return { query, results };
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
// ---------------------------------------------------------------------------
|
|
2672
|
+
// Module-level state
|
|
2673
|
+
// ---------------------------------------------------------------------------
|
|
2674
|
+
|
|
2675
|
+
const suggestionCache = new Map<string, string>();
|
|
2676
|
+
const suggestionInFlight = new Map<string, Promise<string | null>>();
|
|
2677
|
+
|
|
2678
|
+
function resolveAttachments(attachmentIds: string[]) {
|
|
2679
|
+
const resolved = getAttachmentsByIds(attachmentIds, {
|
|
2680
|
+
hydrateFileData: true,
|
|
2681
|
+
});
|
|
2682
|
+
const sourcePaths = getSourcePathsForAttachments(attachmentIds);
|
|
2683
|
+
return resolved.map((a) => ({
|
|
2684
|
+
id: a.id,
|
|
2685
|
+
filename: a.originalFilename,
|
|
2686
|
+
mimeType: a.mimeType,
|
|
2687
|
+
data: a.dataBase64,
|
|
2688
|
+
...(sourcePaths.has(a.id) ? { filePath: sourcePaths.get(a.id) } : {}),
|
|
2689
|
+
}));
|
|
2601
2690
|
}
|
|
2602
2691
|
|
|
2603
2692
|
// ---------------------------------------------------------------------------
|
|
2604
2693
|
// Route definitions
|
|
2605
2694
|
// ---------------------------------------------------------------------------
|
|
2606
2695
|
|
|
2607
|
-
export
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
{
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
"
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
.describe("Whether older messages exist beyond this page"),
|
|
2629
|
-
oldestTimestamp: z
|
|
2630
|
-
.number()
|
|
2631
|
-
.optional()
|
|
2632
|
-
.describe(
|
|
2633
|
-
"Timestamp of the oldest message in this page (ms since epoch)",
|
|
2634
|
-
),
|
|
2635
|
-
oldestMessageId: z
|
|
2636
|
-
.string()
|
|
2637
|
-
.optional()
|
|
2638
|
-
.describe("ID of the oldest message in this page"),
|
|
2639
|
-
}),
|
|
2640
|
-
handler: ({ url }) => handleListMessages(url, deps.interfacesDir),
|
|
2641
|
-
},
|
|
2642
|
-
{
|
|
2643
|
-
endpoint: "messages",
|
|
2644
|
-
method: "POST",
|
|
2645
|
-
summary: "Send a message",
|
|
2646
|
-
description:
|
|
2647
|
-
"Send a user message to a conversation and trigger the assistant response.",
|
|
2648
|
-
tags: ["messages"],
|
|
2649
|
-
requestBody: z.object({
|
|
2650
|
-
conversationKey: z.string().optional(),
|
|
2651
|
-
content: z.string().describe("Message text content"),
|
|
2652
|
-
attachments: z
|
|
2653
|
-
.array(z.unknown())
|
|
2654
|
-
.describe("Optional file attachments")
|
|
2655
|
-
.optional(),
|
|
2656
|
-
conversationType: z.string().optional(),
|
|
2657
|
-
slashCommand: z.string().optional(),
|
|
2658
|
-
}),
|
|
2659
|
-
handler: async ({ req, authContext }) =>
|
|
2660
|
-
handleSendMessage(
|
|
2661
|
-
req,
|
|
2662
|
-
{
|
|
2663
|
-
sendMessageDeps: deps.sendMessageDeps,
|
|
2664
|
-
approvalConversationGenerator: deps.approvalConversationGenerator,
|
|
2665
|
-
heartbeatService: deps.getHeartbeatService?.(),
|
|
2666
|
-
},
|
|
2667
|
-
authContext,
|
|
2696
|
+
export const ROUTES: RouteDefinition[] = [
|
|
2697
|
+
{
|
|
2698
|
+
operationId: "messages_get",
|
|
2699
|
+
endpoint: "messages",
|
|
2700
|
+
method: "GET",
|
|
2701
|
+
summary: "List messages",
|
|
2702
|
+
description:
|
|
2703
|
+
"Return messages for a conversation, including attachments and interface file metadata.",
|
|
2704
|
+
tags: ["messages"],
|
|
2705
|
+
responseBody: z.object({
|
|
2706
|
+
messages: z.array(z.unknown()).describe("Array of message objects"),
|
|
2707
|
+
hasMore: z
|
|
2708
|
+
.boolean()
|
|
2709
|
+
.optional()
|
|
2710
|
+
.describe("Whether older messages exist beyond this page"),
|
|
2711
|
+
oldestTimestamp: z
|
|
2712
|
+
.number()
|
|
2713
|
+
.nullable()
|
|
2714
|
+
.optional()
|
|
2715
|
+
.describe(
|
|
2716
|
+
"Timestamp of the oldest message in this page (ms since epoch). Null when page=latest is used on an empty conversation.",
|
|
2668
2717
|
),
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2718
|
+
oldestMessageId: z
|
|
2719
|
+
.string()
|
|
2720
|
+
.nullable()
|
|
2721
|
+
.optional()
|
|
2722
|
+
.describe("ID of the oldest message in this page"),
|
|
2723
|
+
}),
|
|
2724
|
+
handler: (args) => handleListMessages(args, getInterfacesDir()),
|
|
2725
|
+
},
|
|
2726
|
+
{
|
|
2727
|
+
operationId: "messages_post",
|
|
2728
|
+
endpoint: "messages",
|
|
2729
|
+
method: "POST",
|
|
2730
|
+
summary: "Send a message",
|
|
2731
|
+
description:
|
|
2732
|
+
"Send a user message to a conversation and trigger the assistant response.",
|
|
2733
|
+
tags: ["messages"],
|
|
2734
|
+
responseStatus: "202",
|
|
2735
|
+
requestBody: z.object({
|
|
2736
|
+
conversationKey: z.string().optional(),
|
|
2737
|
+
content: z.string().describe("Message text content"),
|
|
2738
|
+
attachments: z
|
|
2739
|
+
.array(z.unknown())
|
|
2740
|
+
.describe("Optional file attachments")
|
|
2741
|
+
.optional(),
|
|
2742
|
+
conversationType: z.string().optional(),
|
|
2743
|
+
slashCommand: z.string().optional(),
|
|
2744
|
+
inferenceProfile: z.string().nullable().optional(),
|
|
2745
|
+
riskThreshold: z.enum(VALID_RISK_THRESHOLDS).optional(),
|
|
2746
|
+
}),
|
|
2747
|
+
handler: async (args) =>
|
|
2748
|
+
handleSendMessage(args, {
|
|
2749
|
+
sendMessageDeps: {
|
|
2750
|
+
getOrCreateConversation: getOrCreateConversationInstance,
|
|
2751
|
+
assistantEventHub,
|
|
2752
|
+
resolveAttachments,
|
|
2753
|
+
},
|
|
2754
|
+
approvalConversationGenerator: createApprovalConversationGenerator(),
|
|
2679
2755
|
}),
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2756
|
+
},
|
|
2757
|
+
{
|
|
2758
|
+
operationId: "search_get",
|
|
2759
|
+
endpoint: "search",
|
|
2760
|
+
method: "GET",
|
|
2761
|
+
summary: "Search conversations",
|
|
2762
|
+
description: "Full-text search across all conversations.",
|
|
2763
|
+
tags: ["conversations"],
|
|
2764
|
+
responseBody: z.object({
|
|
2765
|
+
query: z.string(),
|
|
2766
|
+
results: z.array(z.unknown()),
|
|
2767
|
+
}),
|
|
2768
|
+
handler: handleSearchConversations,
|
|
2769
|
+
},
|
|
2770
|
+
{
|
|
2771
|
+
operationId: "suggestion_get",
|
|
2772
|
+
endpoint: "suggestion",
|
|
2773
|
+
method: "GET",
|
|
2774
|
+
summary: "Get reply suggestion",
|
|
2775
|
+
description:
|
|
2776
|
+
"Return an LLM-generated follow-up suggestion for the most recent assistant message.",
|
|
2777
|
+
tags: ["messages"],
|
|
2778
|
+
responseBody: z.object({
|
|
2779
|
+
suggestion: z.string(),
|
|
2780
|
+
messageId: z.string(),
|
|
2781
|
+
source: z.string(),
|
|
2782
|
+
}),
|
|
2783
|
+
handler: async (args) =>
|
|
2784
|
+
handleGetSuggestion(args, {
|
|
2785
|
+
suggestionCache,
|
|
2786
|
+
suggestionInFlight,
|
|
2693
2787
|
}),
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
suggestionCache: deps.suggestionCache,
|
|
2697
|
-
suggestionInFlight: deps.suggestionInFlight,
|
|
2698
|
-
}),
|
|
2699
|
-
},
|
|
2700
|
-
];
|
|
2701
|
-
}
|
|
2788
|
+
},
|
|
2789
|
+
];
|