@vellumai/assistant 0.6.5 → 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 +29 -1
- package/ARCHITECTURE.md +60 -53
- package/Dockerfile +25 -3
- package/README.md +8 -10
- package/__tests__/permissions/gateway-threshold-reader.test.ts +277 -0
- package/bun.lock +306 -119
- package/docs/architecture/integrations.md +32 -39
- package/docs/architecture/memory.md +26 -120
- package/docs/architecture/security.md +22 -36
- package/docs/browser-use-architecture-phase2.md +63 -20
- package/docs/credential-execution-service.md +7 -5
- package/docs/plugins.md +761 -0
- package/docs/skills.md +10 -10
- package/docs/stt-provider-onboarding.md +17 -45
- package/examples/plugins/echo/README.md +132 -0
- package/examples/plugins/echo/bun.lock +25 -0
- package/examples/plugins/echo/package.json +17 -0
- package/examples/plugins/echo/register.ts +187 -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/egress-proxy/src/types.ts +19 -0
- 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 +3135 -692
- 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} +28 -28
- 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-compiler.test.ts +57 -0
- package/src/__tests__/app-routes-csp.test.ts +106 -55
- package/src/__tests__/approval-cascade.test.ts +10 -357
- 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 +9 -20
- package/src/__tests__/avatar-generator.test.ts +4 -2
- 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__/bundled-asset.test.ts +6 -6
- 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-cache.test.ts +69 -0
- 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 +447 -3806
- package/src/__tests__/circuit-breaker-pipeline.test.ts +406 -0
- 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 +500 -0
- package/src/__tests__/compaction-pipeline.test.ts +210 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +181 -0
- package/src/__tests__/compaction-timeout-recovery.test.ts +262 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -7
- package/src/__tests__/config-model-image-provider.test.ts +109 -0
- package/src/__tests__/config-schema-cmd.test.ts +1 -1
- package/src/__tests__/config-schema.test.ts +25 -203
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -4
- 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 +71 -18
- package/src/__tests__/contacts-write.test.ts +6 -61
- package/src/__tests__/context-overflow-policy.test.ts +7 -7
- 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 +380 -4
- package/src/__tests__/conversation-abort-tool-results.test.ts +14 -2
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +631 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +41 -32
- package/src/__tests__/conversation-agent-loop.test.ts +54 -143
- 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 +7 -40
- 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-history-web-search.test.ts +1 -0
- 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 -95
- 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 +174 -11
- package/src/__tests__/conversation-pre-run-repair.test.ts +137 -294
- package/src/__tests__/conversation-process-callsite.test.ts +3 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +22 -8
- package/src/__tests__/conversation-queue.test.ts +30 -47
- package/src/__tests__/conversation-routes-disk-view.test.ts +131 -103
- 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 +196 -194
- package/src/__tests__/conversation-runtime-workspace.test.ts +23 -38
- package/src/__tests__/conversation-seed-composer.test.ts +2 -2
- package/src/__tests__/conversation-slash-commands.test.ts +6 -43
- package/src/__tests__/conversation-slash-queue.test.ts +7 -3
- package/src/__tests__/conversation-slash-unknown.test.ts +25 -3
- package/src/__tests__/conversation-speed-override.test.ts +6 -2
- 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-title-service.test.ts +116 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +42 -3
- 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 +3 -2
- package/src/__tests__/conversation-wipe.test.ts +2 -103
- package/src/__tests__/conversation-workspace-cache-state.test.ts +4 -2
- package/src/__tests__/conversation-workspace-injection.test.ts +3 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +4 -2
- 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-health-service.test.ts +78 -9
- package/src/__tests__/credential-security-invariants.test.ts +16 -2
- 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 +2 -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 +305 -0
- 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__/first-greeting.test.ts +247 -5
- 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__/headless-browser-mode.test.ts +57 -0
- 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 +399 -0
- package/src/__tests__/home-state-routes.test.ts +10 -31
- package/src/__tests__/host-browser-e2e-cloud.test.ts +309 -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 +38 -4
- 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__/image-credentials.test.ts +137 -0
- package/src/__tests__/image-service-dispatcher.test.ts +186 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +3 -2
- package/src/__tests__/injector-chain.test.ts +525 -0
- package/src/__tests__/inline-skill-load-permissions.test.ts +41 -206
- package/src/__tests__/install-skill-routing.test.ts +1 -1
- package/src/__tests__/intent-routing.test.ts +0 -26
- 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 +284 -0
- 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 +56 -0
- 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__/media-generate-image.test.ts +119 -13
- 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 +399 -0
- package/src/__tests__/memory-upsert-concurrency.test.ts +3 -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 +21 -91
- 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 +16 -1
- 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-broadcaster.test.ts +3 -3
- package/src/__tests__/notification-decision-strategy.test.ts +0 -11
- package/src/__tests__/notification-guardian-path.test.ts +15 -8
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +109 -0
- package/src/__tests__/notification-telegram-adapter.test.ts +57 -55
- package/src/__tests__/oauth-apps-routes.test.ts +77 -123
- package/src/__tests__/oauth-cli.test.ts +28 -13
- package/src/__tests__/oauth-connect-orchestrator.test.ts +4 -13
- package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
- package/src/__tests__/oauth-provider-serializer.test.ts +6 -4
- package/src/__tests__/oauth-provider-visibility.test.ts +6 -6
- package/src/__tests__/oauth-providers-routes.test.ts +81 -103
- package/src/__tests__/oauth-store.test.ts +44 -77
- package/src/__tests__/oauth2-gateway-transport.test.ts +6 -3
- package/src/__tests__/onboarding-template-contract.test.ts +16 -64
- package/src/__tests__/openai-image-service.test.ts +368 -0
- 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 +671 -0
- package/src/__tests__/permission-types.test.ts +3 -18
- package/src/__tests__/persist-onboarding-artifacts.test.ts +266 -0
- package/src/__tests__/persistence-pipeline.test.ts +378 -0
- package/src/__tests__/pipeline-runner.test.ts +565 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +27 -20
- package/src/__tests__/platform.test.ts +10 -59
- 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 +529 -0
- package/src/__tests__/plugin-registry.test.ts +303 -0
- package/src/__tests__/plugin-route-contribution.test.ts +294 -0
- package/src/__tests__/plugin-skill-contribution.test.ts +367 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +292 -0
- package/src/__tests__/plugin-types.test.ts +320 -0
- package/src/__tests__/pricing.test.ts +195 -14
- 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 -493
- package/src/__tests__/qdrant-collection-migration.test.ts +7 -7
- package/src/__tests__/reaction-persistence.test.ts +4 -2
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
- package/src/__tests__/recording-handler.test.ts +0 -2
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +1 -2
- 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 +304 -77
- 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 +16 -71
- package/src/__tests__/scheduler-reuse-conversation.test.ts +12 -51
- 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 -19
- 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 +149 -57
- 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 +3 -1
- package/src/__tests__/task-scheduler.test.ts +5 -16
- package/src/__tests__/telegram-config.test.ts +0 -1
- package/src/__tests__/terminal-tools.test.ts +5 -314
- package/src/__tests__/thread-backfill.test.ts +3 -2
- package/src/__tests__/title-generate-pipeline.test.ts +224 -0
- package/src/__tests__/token-estimate-pipeline.test.ts +484 -0
- 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 +244 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +429 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +61 -4
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +28 -56
- package/src/__tests__/tool-executor.test.ts +434 -1604
- package/src/__tests__/tool-grant-request-escalation.test.ts +90 -311
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +356 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -110
- 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 +233 -0
- 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-046-seed-conversation-starters-callsite.test.ts +185 -0
- package/src/__tests__/workspace-migration-049-release-notes-default-sonnet.test.ts +100 -0
- package/src/__tests__/workspace-migration-050-seed-main-agent-opus-callsite.test.ts +171 -0
- package/src/__tests__/workspace-migration-051-seed-conversation-summarization-callsite.test.ts +252 -0
- 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/__tests__/workspace-migration-remove-hooks.test.ts +99 -0
- package/src/__tests__/workspace-policy.test.ts +21 -3
- 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 +365 -104
- package/src/agent/message-types.ts +0 -2
- package/src/approvals/AGENTS.md +1 -1
- package/src/approvals/__tests__/guardian-feed-event.test.ts +296 -0
- package/src/approvals/approval-primitive.ts +3 -20
- package/src/approvals/guardian-decision-primitive.ts +37 -68
- package/src/approvals/guardian-request-resolvers.ts +109 -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 +2 -15
- package/src/backup/__tests__/paths.test.ts +3 -2
- package/src/backup/backup-worker.ts +3 -24
- 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/app-compiler.ts +84 -1
- 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-state.ts +2 -2
- 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 +28 -6
- package/src/channels/permission-profiles.ts +2 -72
- package/src/channels/types.ts +48 -30
- package/src/cli/AGENTS.md +1 -0
- package/src/cli/__tests__/notifications.test.ts +92 -214
- package/src/cli/commands/__tests__/attachment.test.ts +14 -8
- package/src/cli/commands/__tests__/backup.test.ts +4 -15
- 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__/image-generation.test.ts +255 -35
- package/src/cli/commands/__tests__/inference-send.test.ts +12 -0
- 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__/tts-synthesize.test.ts +12 -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 +16 -46
- 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 +137 -0
- package/src/cli/commands/completions.ts +3 -10
- 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 +115 -57
- 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 +33 -34
- 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 +87 -121
- 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__/providers-register.test.ts +1 -1
- package/src/cli/commands/oauth/__tests__/providers-update.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 +4 -4
- package/src/cli/commands/oauth/providers.ts +176 -8
- package/src/cli/commands/oauth/shared.ts +29 -2
- package/src/cli/commands/oauth/status.ts +46 -36
- 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 +189 -84
- 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 +29 -29
- package/src/cli.ts +1 -61
- package/src/config/__tests__/backup-schema.test.ts +7 -2
- 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/{screen-watch/tools/start-screen-watch.ts → acp/tools/acp-list-agents.ts} +2 -2
- package/src/config/bundled-skills/acp/tools/acp-steer.ts +12 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +10 -10
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +66 -87
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +25 -51
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +31 -44
- package/src/config/bundled-skills/image-studio/SKILL.md +2 -1
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +23 -39
- 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/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +207 -0
- 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/messaging/tools/messaging-archive-by-sender.ts +12 -0
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +58 -0
- 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/schedule/SKILL.md +8 -3
- package/src/config/bundled-skills/schedule/TOOLS.json +15 -7
- package/src/config/bundled-skills/schedule/references/SCRIPT_MODE_PATTERNS.md +59 -0
- 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 -21
- package/src/config/env.ts +7 -8
- package/src/config/feature-flag-registry.json +25 -17
- package/src/config/llm-resolver.ts +51 -33
- package/src/config/loader.ts +12 -15
- package/src/config/schema.ts +22 -70
- 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/backup.ts +1 -1
- package/src/config/schemas/conversations.ts +16 -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 -10
- 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/schemas/tts.ts +11 -0
- package/src/config/skill-state.ts +6 -2
- package/src/config/skills.ts +95 -6
- 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/__tests__/compact-prompt.test.ts +27 -9
- package/src/context/prompts/compact.md +26 -12
- package/src/context/token-estimator.ts +1 -1
- package/src/context/tool-result-truncation.ts +4 -64
- package/src/context/window-manager.ts +191 -17
- 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 +20 -7
- package/src/daemon/__tests__/conversation-feed-event.test.ts +304 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +4 -12
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +1 -1
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +14 -15
- 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 -56
- package/src/daemon/connection-policy.ts +0 -14
- package/src/daemon/context-overflow-policy.ts +4 -13
- package/src/daemon/conversation-agent-loop-handlers.ts +120 -28
- package/src/daemon/conversation-agent-loop.ts +1113 -701
- package/src/daemon/conversation-attachments.ts +5 -81
- package/src/daemon/conversation-error.ts +9 -5
- package/src/daemon/conversation-history.ts +11 -20
- package/src/daemon/conversation-launch.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +37 -19
- package/src/daemon/conversation-messaging.ts +1 -1
- package/src/daemon/conversation-notifiers.ts +3 -111
- package/src/daemon/conversation-process.ts +23 -20
- package/src/daemon/conversation-runtime-assembly.ts +530 -471
- 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 +49 -161
- package/src/daemon/conversation.ts +126 -217
- package/src/daemon/daemon-control.ts +3 -3
- package/src/daemon/daemon-skill-host.ts +262 -0
- package/src/daemon/external-plugins-bootstrap.ts +532 -0
- package/src/daemon/first-greeting.ts +191 -14
- 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 +18 -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 +20 -24
- package/src/daemon/host-transfer-proxy.ts +500 -0
- package/src/daemon/lifecycle.ts +56 -326
- 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/computer-use.ts +2 -34
- package/src/daemon/message-types/conversations.ts +65 -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 +26 -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 -1272
- package/src/daemon/shutdown-handlers.ts +3 -13
- package/src/daemon/startup-error.ts +1 -1
- package/src/daemon/tool-side-effects.ts +14 -56
- 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 +228 -0
- package/src/heartbeat/heartbeat-service.ts +52 -8
- package/src/home/__tests__/feed-population-integration.test.ts +312 -0
- 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/emit-feed-event.ts +7 -0
- package/src/home/feed-types.ts +42 -3
- package/src/home/relationship-state-writer.ts +1 -1
- package/src/home/rewrite-command-preview.ts +66 -0
- 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 +44 -37
- 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 -120
- 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 +55 -48
- 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/app-icon-generator.ts +23 -46
- package/src/media/avatar-router.ts +26 -41
- package/src/media/gemini-image-service.ts +8 -41
- package/src/media/image-credentials.ts +73 -0
- package/src/media/image-service.ts +85 -0
- package/src/media/openai-image-service.ts +131 -0
- package/src/media/types.ts +46 -0
- 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 +117 -145
- 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 +69 -29
- 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 +27 -1
- package/src/memory/db-init.ts +22 -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 +44 -5
- package/src/memory/embedding-gemini.ts +6 -1
- 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 +277 -0
- package/src/memory/graph/bootstrap.ts +10 -6
- 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 +63 -23
- package/src/memory/graph/graph-memory-state-store.ts +1 -1
- package/src/memory/graph/graph-search.test.ts +95 -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 +27 -8
- 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/041-approval-prompt-ts-tracker.ts +26 -0
- package/src/memory/migrations/149-oauth-tables.ts +1 -0
- package/src/memory/migrations/223-schedule-script-column.ts +11 -0
- package/src/memory/migrations/224-oauth-providers-managed-service-is-paid.ts +24 -0
- package/src/memory/migrations/225-oauth-providers-available-scopes.ts +13 -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 +14 -0
- package/src/memory/migrations/registry.ts +7 -0
- package/src/memory/pkb/pkb-index.test.ts +5 -5
- package/src/memory/pkb/pkb-reconcile.test.ts +5 -5
- package/src/memory/pkb/pkb-search.test.ts +148 -7
- package/src/memory/pkb/pkb-search.ts +65 -30
- package/src/memory/published-pages-store.ts +1 -1
- package/src/memory/qdrant-client.test.ts +60 -0
- package/src/memory/qdrant-client.ts +25 -0
- 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 +2 -32
- package/src/memory/schema/memory-graph.ts +36 -14
- package/src/memory/schema/oauth.ts +4 -1
- 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/render-transcript.test.ts +77 -29
- package/src/messaging/providers/slack/render-transcript.ts +58 -0
- 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-pairing.ts +78 -19
- package/src/notifications/conversation-seed-composer.ts +12 -6
- package/src/notifications/copy-composer.ts +1 -6
- 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/emit-signal.ts +1 -1
- package/src/notifications/events-store.ts +1 -13
- package/src/notifications/preferences-store.ts +1 -1
- package/src/notifications/signal.ts +1 -11
- package/src/oauth/AGENTS.md +1 -1
- package/src/oauth/__tests__/identity-verifier.test.ts +2 -1
- package/src/oauth/connect-orchestrator.ts +8 -34
- package/src/oauth/connect-types.ts +6 -10
- package/src/oauth/connection-resolver.ts +11 -2
- package/src/oauth/manual-token-connection.ts +23 -0
- package/src/oauth/oauth-store.ts +32 -15
- package/src/oauth/provider-serializer.ts +6 -1
- package/src/oauth/seed-providers.ts +56 -108
- package/src/outbound-proxy/http-forwarder.ts +9 -0
- package/src/outbound-proxy/index.ts +0 -1
- package/src/permissions/approval-policy.test.ts +398 -106
- package/src/permissions/approval-policy.ts +134 -108
- package/src/permissions/checker.test.ts +632 -0
- package/src/permissions/checker.ts +280 -345
- package/src/permissions/gateway-threshold-reader.ts +177 -0
- package/src/permissions/ipc-risk-types.ts +95 -0
- package/src/permissions/prompter.ts +8 -9
- package/src/permissions/risk-types.ts +24 -153
- package/src/permissions/types.ts +19 -47
- package/src/permissions/workspace-policy.ts +10 -7
- package/src/playbooks/playbook-compiler.ts +1 -1
- package/src/plugins/defaults/circuit-breaker.ts +146 -0
- package/src/plugins/defaults/compaction.ts +145 -0
- package/src/plugins/defaults/empty-response.ts +126 -0
- package/src/plugins/defaults/history-repair.ts +85 -0
- package/src/plugins/defaults/index.ts +116 -0
- package/src/plugins/defaults/injectors.ts +488 -0
- package/src/plugins/defaults/llm-call.ts +79 -0
- package/src/plugins/defaults/memory-retrieval.ts +221 -0
- package/src/plugins/defaults/overflow-reduce.ts +185 -0
- package/src/plugins/defaults/persistence.ts +129 -0
- package/src/plugins/defaults/title-generate.ts +95 -0
- package/src/plugins/defaults/token-estimate.ts +103 -0
- package/src/plugins/defaults/tool-error.ts +126 -0
- package/src/plugins/defaults/tool-execute.ts +89 -0
- package/src/plugins/defaults/tool-result-truncate.ts +88 -0
- package/src/plugins/pipeline.ts +316 -0
- package/src/plugins/plugin-skill-contributions.ts +292 -0
- package/src/plugins/registry.ts +301 -0
- package/src/plugins/types.ts +1133 -0
- package/src/plugins/user-loader.ts +203 -0
- 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/BOOTSTRAP.md +27 -77
- 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 +123 -25
- package/src/providers/model-intents.ts +6 -7
- 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 +9 -6
- 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/deepgram-realtime.test.ts +61 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +57 -0
- 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-realtime.test.ts +72 -4
- package/src/providers/speech-to-text/xai-realtime.ts +39 -14
- 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 +27 -17
- package/src/runtime/__tests__/agent-wake.test.ts +33 -9
- package/src/runtime/__tests__/client-registry.test.ts +271 -0
- 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 +254 -0
- 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 -1041
- package/src/runtime/http-types.ts +15 -100
- 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 +4 -26
- 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-prompt-ts-tracker.ts +51 -31
- package/src/runtime/routes/approval-routes.ts +133 -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 +652 -457
- 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 +162 -123
- 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 +153 -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 -377
- 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 +224 -0
- package/src/runtime/routes/playground/__tests__/guard.test.ts +60 -0
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +250 -0
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +195 -0
- package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +159 -0
- package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +207 -0
- package/src/runtime/routes/playground/__tests__/state.test.ts +175 -0
- package/src/runtime/routes/playground/conversation-not-found.ts +27 -0
- package/src/runtime/routes/playground/force-compact.ts +60 -0
- package/src/runtime/routes/playground/guard.ts +36 -0
- package/src/runtime/routes/playground/helpers.ts +103 -0
- package/src/runtime/routes/playground/index.ts +18 -0
- package/src/runtime/routes/playground/inject-failures.ts +143 -0
- package/src/runtime/routes/playground/reset-circuit.ts +89 -0
- package/src/runtime/routes/playground/seed-conversation.ts +113 -0
- package/src/runtime/routes/playground/seeded-conversations.ts +74 -0
- package/src/runtime/routes/playground/state.ts +77 -0
- 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 +284 -207
- 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/skill-route-registry.ts +75 -15
- package/src/runtime/trust-context-resolver.ts +3 -2
- package/src/runtime/verification-outbound-actions.ts +13 -49
- package/src/schedule/run-script.ts +68 -0
- package/src/schedule/schedule-store.ts +70 -2
- package/src/schedule/scheduler.ts +149 -8
- 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 +19 -5
- 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/__tests__/browser-status.test.ts +189 -0
- package/src/tools/browser/browser-execution.ts +122 -26
- package/src/tools/browser/browser-manager.ts +1 -8
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +230 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +146 -3
- 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/extension-cdp-client.ts +54 -3
- package/src/tools/browser/cdp-client/factory.ts +15 -4
- 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 +123 -76
- 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/network/script-proxy/session-manager.ts +37 -1
- package/src/tools/permission-checker.ts +103 -255
- package/src/tools/policy-context.ts +5 -8
- package/src/tools/registry.ts +156 -4
- package/src/tools/schedule/create.ts +23 -8
- package/src/tools/schedule/update.ts +3 -1
- package/src/tools/secret-detection-handler.ts +13 -154
- 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/system/avatar-generator.ts +6 -2
- 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 +157 -151
- 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 -119
- package/src/util/pricing.ts +135 -9
- 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 +11 -4
- 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/022-move-hooks-to-workspace.ts +2 -3
- 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/041-backfill-google-gmail-settings-scope.ts +3 -4
- package/src/workspace/migrations/045-release-notes-meet-avatar.ts +3 -4
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +108 -0
- package/src/workspace/migrations/047-remove-watch-callsites.ts +54 -0
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +81 -0
- package/src/workspace/migrations/049-release-notes-default-sonnet.ts +80 -0
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +86 -0
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +128 -0
- 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 +30 -0
- package/src/workspace/migrations/runner.ts +2 -2
- package/src/workspace/provider-commit-message-generator.ts +1 -1
- package/tsconfig.json +1 -1
- package/hook-templates/debug-prompt-logger/hook.json +0 -7
- package/hook-templates/debug-prompt-logger/run.sh +0 -66
- 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__/compaction-circuit-breaker.test.ts +0 -336
- package/src/__tests__/config-watcher-feature-flags.test.ts +0 -211
- package/src/__tests__/context-overflow-approval.test.ts +0 -156
- 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__/hooks-blocking.test.ts +0 -178
- package/src/__tests__/hooks-cli.test.ts +0 -182
- package/src/__tests__/hooks-config.test.ts +0 -108
- package/src/__tests__/hooks-discovery.test.ts +0 -211
- package/src/__tests__/hooks-integration.test.ts +0 -196
- package/src/__tests__/hooks-manager.test.ts +0 -226
- package/src/__tests__/hooks-runner.test.ts +0 -175
- package/src/__tests__/hooks-settings.test.ts +0 -160
- package/src/__tests__/hooks-templates.test.ts +0 -169
- package/src/__tests__/hooks-ts-runner.test.ts +0 -170
- package/src/__tests__/hooks-watch.test.ts +0 -112
- 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__/notification-schedule-dedup.test.ts +0 -213
- package/src/__tests__/oauth-scope-policy.test.ts +0 -180
- 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 -512
- 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__/send-notification-tool.test.ts +0 -83
- package/src/__tests__/shell-identity.test.ts +0 -370
- 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 -357
- 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/commands/shotgun.ts +0 -266
- package/src/cli/db.ts +0 -1
- package/src/config/bundled-skills/conversations/SKILL.md +0 -20
- package/src/config/bundled-skills/conversations/TOOLS.json +0 -23
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +0 -88
- package/src/config/bundled-skills/heartbeat/SKILL.md +0 -43
- package/src/config/bundled-skills/notifications/SKILL.md +0 -40
- package/src/config/bundled-skills/notifications/TOOLS.json +0 -80
- package/src/config/bundled-skills/notifications/tools/send-notification.ts +0 -152
- package/src/config/bundled-skills/notifications/tools/shared.ts +0 -13
- package/src/config/bundled-skills/screen-watch/SKILL.md +0 -27
- package/src/config/bundled-skills/screen-watch/TOOLS.json +0 -35
- 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/config/bundled-skills/skills-catalog/SKILL.md +0 -84
- package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +0 -127
- package/src/daemon/approved-devices-store.ts +0 -110
- package/src/daemon/context-overflow-approval.ts +0 -52
- 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/daemon/watch-handler.ts +0 -399
- package/src/hooks/cli.ts +0 -253
- package/src/hooks/config.ts +0 -100
- package/src/hooks/discovery.ts +0 -135
- package/src/hooks/manager.ts +0 -179
- package/src/hooks/runner.ts +0 -117
- package/src/hooks/templates.ts +0 -77
- package/src/hooks/types.ts +0 -75
- package/src/ipc/cli-server.ts +0 -252
- package/src/ipc/routes/attachment.ts +0 -114
- package/src/ipc/routes/browser-context.ts +0 -61
- package/src/ipc/routes/browser.ts +0 -96
- package/src/ipc/routes/cache.ts +0 -96
- package/src/ipc/routes/index.ts +0 -21
- package/src/ipc/routes/task-queue.ts +0 -226
- package/src/ipc/routes/task.ts +0 -173
- package/src/ipc/routes/wake-conversation.ts +0 -19
- package/src/memory/db.ts +0 -23
- package/src/oauth/scope-policy.ts +0 -89
- package/src/permissions/bash-risk-classifier.test.ts +0 -1208
- package/src/permissions/bash-risk-classifier.ts +0 -707
- package/src/permissions/command-registry.test.ts +0 -535
- package/src/permissions/command-registry.ts +0 -825
- package/src/permissions/defaults.ts +0 -313
- 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/shell-identity.ts +0 -337
- 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/gateway-internal-client.ts +0 -94
- package/src/runtime/routes/browser-extension-pair-routes.ts +0 -556
- 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/watch-routes.ts +0 -156
- package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +0 -67
- package/src/runtime/services/analyze-deps-singleton.ts +0 -32
- package/src/signals/shotgun.ts +0 -203
- package/src/tasks/ephemeral-permissions.ts +0 -55
- package/src/tools/terminal/parser.ts +0 -623
- package/src/tools/watch/screen-watch.ts +0 -144
- package/src/tools/watch/watch-state.ts +0 -142
- 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
package/src/daemon/server.ts
CHANGED
|
@@ -6,78 +6,37 @@ import {
|
|
|
6
6
|
getAcpSessionManager,
|
|
7
7
|
setBroadcastToAllClients,
|
|
8
8
|
} from "../acp/index.js";
|
|
9
|
-
import { enrichMessageWithSourcePaths } from "../agent/attachments.js";
|
|
10
|
-
import type { AgentEvent } from "../agent/loop.js";
|
|
11
|
-
import {
|
|
12
|
-
createAssistantMessage,
|
|
13
|
-
createUserMessage,
|
|
14
|
-
} from "../agent/message-types.js";
|
|
15
9
|
import { compileApp } from "../bundler/app-compiler.js";
|
|
16
|
-
import {
|
|
17
|
-
type ChannelId,
|
|
18
|
-
type InterfaceId,
|
|
19
|
-
parseChannelId,
|
|
20
|
-
parseInterfaceId,
|
|
21
|
-
supportsHostProxy,
|
|
22
|
-
} from "../channels/types.js";
|
|
10
|
+
import { supportsHostProxy } from "../channels/types.js";
|
|
23
11
|
import { getConfig } from "../config/loader.js";
|
|
24
12
|
import { onContactChange } from "../contacts/contact-events.js";
|
|
25
13
|
import type { CesClient } from "../credential-execution/client.js";
|
|
26
14
|
import type { CesProcessManager } from "../credential-execution/process-manager.js";
|
|
27
|
-
import
|
|
28
|
-
import
|
|
29
|
-
import { CliIpcServer } from "../ipc/cli-server.js";
|
|
30
|
-
import { registerBrowserIpcContextResolver } from "../ipc/routes/browser-context.js";
|
|
15
|
+
import { AssistantIpcServer } from "../ipc/assistant-server.js";
|
|
16
|
+
import { SkillIpcServer } from "../ipc/skill-server.js";
|
|
31
17
|
import { getApp, getAppDirPath, isMultifileApp } from "../memory/app-store.js";
|
|
32
|
-
import * as attachmentsStore from "../memory/attachments-store.js";
|
|
33
|
-
import {
|
|
34
|
-
createCanonicalGuardianRequest,
|
|
35
|
-
generateCanonicalRequestCode,
|
|
36
|
-
} from "../memory/canonical-guardian-store.js";
|
|
37
18
|
import {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
getConversationType,
|
|
42
|
-
provenanceFromTrustContext,
|
|
43
|
-
setConversationOriginChannelIfUnset,
|
|
44
|
-
setConversationOriginInterfaceIfUnset,
|
|
45
|
-
} from "../memory/conversation-crud.js";
|
|
46
|
-
import {
|
|
47
|
-
syncMessageToDisk,
|
|
48
|
-
updateMetaFile,
|
|
49
|
-
} from "../memory/conversation-disk-view.js";
|
|
19
|
+
uploadFileBackedAttachment,
|
|
20
|
+
validateAttachmentUpload,
|
|
21
|
+
} from "../memory/attachments-store.js";
|
|
50
22
|
import { getOrCreateConversation } from "../memory/conversation-key-store.js";
|
|
51
23
|
import { syncIdentityNameToPlatform } from "../platform/sync-identity.js";
|
|
52
|
-
import {
|
|
53
|
-
import { CallSiteRoutingProvider } from "../providers/call-site-routing.js";
|
|
54
|
-
import { RateLimitProvider } from "../providers/ratelimit.js";
|
|
55
|
-
import { getProvider, initializeProviders } from "../providers/registry.js";
|
|
56
|
-
import {
|
|
57
|
-
registerDefaultWakeResolver,
|
|
58
|
-
type WakeTarget,
|
|
59
|
-
} from "../runtime/agent-wake.js";
|
|
24
|
+
import { initializeProviders } from "../providers/registry.js";
|
|
60
25
|
import { buildAssistantEvent } from "../runtime/assistant-event.js";
|
|
61
26
|
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
62
27
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
|
|
63
28
|
import { getSigningKeyFingerprint } from "../runtime/auth/token-service.js";
|
|
64
|
-
import { bridgeConfirmationRequestToGuardian } from "../runtime/confirmation-request-guardian-bridge.js";
|
|
65
|
-
import { registerInteractiveUiResolver } from "../runtime/interactive-ui.js";
|
|
66
|
-
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
67
29
|
import { checkIngressForSecrets } from "../security/secret-ingress.js";
|
|
68
|
-
import { redactSecrets } from "../security/secret-scanner.js";
|
|
69
30
|
import { updatePublishedAppDeployment } from "../services/published-app-updater.js";
|
|
70
31
|
import { registerCancelCallback } from "../signals/cancel.js";
|
|
71
32
|
import { registerConversationUndoCallback } from "../signals/conversation-undo.js";
|
|
72
33
|
import { appendEventToStream } from "../signals/event-stream.js";
|
|
73
34
|
import { registerUserMessageCallback } from "../signals/user-message.js";
|
|
74
35
|
import { getSubagentManager } from "../subagent/index.js";
|
|
75
|
-
import { summarizeToolInput } from "../tools/tool-input-summary.js";
|
|
76
36
|
import { createAbortReason } from "../util/abort-reasons.js";
|
|
77
37
|
import { getLogger } from "../util/logger.js";
|
|
78
38
|
import {
|
|
79
39
|
getAvatarImagePath,
|
|
80
|
-
getSandboxWorkingDir,
|
|
81
40
|
getWorkspacePromptPath,
|
|
82
41
|
} from "../util/platform.js";
|
|
83
42
|
import { registerDaemonCallbacks } from "../work-items/work-item-runner.js";
|
|
@@ -85,38 +44,40 @@ import {
|
|
|
85
44
|
AppSourceWatcher,
|
|
86
45
|
setEnsureAppSourceWatcher,
|
|
87
46
|
} from "./app-source-watcher.js";
|
|
88
|
-
import {
|
|
89
|
-
import {
|
|
90
|
-
Conversation,
|
|
91
|
-
type ConversationMemoryPolicy,
|
|
92
|
-
DEFAULT_MEMORY_POLICY,
|
|
93
|
-
} from "./conversation.js";
|
|
47
|
+
import { getConfigWatcher } from "./config-watcher.js";
|
|
48
|
+
import { Conversation } from "./conversation.js";
|
|
94
49
|
import { ConversationEvictor } from "./conversation-evictor.js";
|
|
95
50
|
import { registerLaunchConversationDeps } from "./conversation-launch.js";
|
|
96
|
-
import { buildSlackMetaForPersistence } from "./conversation-messaging.js";
|
|
97
|
-
import { formatCompactResult } from "./conversation-process.js";
|
|
98
|
-
import { resolveChannelCapabilities } from "./conversation-runtime-assembly.js";
|
|
99
|
-
import { resolveSlash, type SlashContext } from "./conversation-slash.js";
|
|
100
51
|
import {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
52
|
+
allConversations,
|
|
53
|
+
clearAllActiveConversations,
|
|
54
|
+
clearConversations,
|
|
55
|
+
conversationEntries,
|
|
56
|
+
deleteConversation,
|
|
57
|
+
findConversation,
|
|
58
|
+
getConversationMap,
|
|
59
|
+
getOrCreateConversation as getOrCreateActiveConversation,
|
|
60
|
+
initConversationLifecycle,
|
|
61
|
+
setCesClientPromise,
|
|
62
|
+
} from "./conversation-store.js";
|
|
63
|
+
import { refreshSurfacesForApp } from "./conversation-surfaces.js";
|
|
104
64
|
import { undoLastMessage } from "./handlers/conversations.js";
|
|
105
65
|
import { parseIdentityFields } from "./handlers/identity.js";
|
|
106
|
-
import
|
|
107
|
-
ConversationCreateOptions,
|
|
108
|
-
HandlerContext,
|
|
66
|
+
import {
|
|
67
|
+
type ConversationCreateOptions,
|
|
68
|
+
type HandlerContext,
|
|
109
69
|
} from "./handlers/shared.js";
|
|
110
|
-
import
|
|
111
|
-
import { HostBashProxy } from "./host-bash-proxy.js";
|
|
112
|
-
import { HostBrowserProxy } from "./host-browser-proxy.js";
|
|
113
|
-
import { HostCuProxy } from "./host-cu-proxy.js";
|
|
114
|
-
import { HostFileProxy } from "./host-file-proxy.js";
|
|
70
|
+
import { setGlobalSkillIpcSender } from "./meet-host-supervisor.js";
|
|
115
71
|
import type {
|
|
116
72
|
ServerMessage,
|
|
117
73
|
UserMessageAttachment,
|
|
118
74
|
} from "./message-protocol.js";
|
|
119
|
-
import {
|
|
75
|
+
import {
|
|
76
|
+
makePendingInteractionRegistrar,
|
|
77
|
+
prepareConversationForMessage,
|
|
78
|
+
resolveTurnChannel,
|
|
79
|
+
resolveTurnInterface,
|
|
80
|
+
} from "./process-message.js";
|
|
120
81
|
|
|
121
82
|
const log = getLogger("server");
|
|
122
83
|
|
|
@@ -134,181 +95,17 @@ function readPackageVersion(): string | undefined {
|
|
|
134
95
|
|
|
135
96
|
const daemonVersion = readPackageVersion();
|
|
136
97
|
|
|
137
|
-
function resolveTurnChannel(
|
|
138
|
-
sourceChannel?: string,
|
|
139
|
-
transportChannelId?: string,
|
|
140
|
-
): ChannelId {
|
|
141
|
-
if (sourceChannel != null) {
|
|
142
|
-
const parsed = parseChannelId(sourceChannel);
|
|
143
|
-
if (!parsed) {
|
|
144
|
-
throw new Error(`Invalid sourceChannel: ${sourceChannel}`);
|
|
145
|
-
}
|
|
146
|
-
return parsed;
|
|
147
|
-
}
|
|
148
|
-
if (transportChannelId != null) {
|
|
149
|
-
const parsed = parseChannelId(transportChannelId);
|
|
150
|
-
if (!parsed) {
|
|
151
|
-
throw new Error(`Invalid transport.channelId: ${transportChannelId}`);
|
|
152
|
-
}
|
|
153
|
-
return parsed;
|
|
154
|
-
}
|
|
155
|
-
return "vellum";
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function resolveTurnInterface(sourceInterface?: string): InterfaceId {
|
|
159
|
-
if (sourceInterface != null) {
|
|
160
|
-
const parsed = parseInterfaceId(sourceInterface);
|
|
161
|
-
if (!parsed) {
|
|
162
|
-
throw new Error(`Invalid sourceInterface: ${sourceInterface}`);
|
|
163
|
-
}
|
|
164
|
-
return parsed;
|
|
165
|
-
}
|
|
166
|
-
// Interface and channel are orthogonal dimensions; default explicitly
|
|
167
|
-
// instead of deriving interface from channel.
|
|
168
|
-
return "vellum";
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
function resolveCanonicalRequestSourceType(
|
|
172
|
-
sourceChannel: string | undefined,
|
|
173
|
-
): "desktop" | "channel" | "voice" {
|
|
174
|
-
if (sourceChannel === "phone") {
|
|
175
|
-
return "voice";
|
|
176
|
-
}
|
|
177
|
-
if (sourceChannel === "vellum") {
|
|
178
|
-
return "desktop";
|
|
179
|
-
}
|
|
180
|
-
return "channel";
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Build an onEvent callback that registers pending interactions when the agent
|
|
185
|
-
* loop emits confirmation_request, secret_request, host_bash_request,
|
|
186
|
-
* host_browser_request, host_file_request, or host_cu_request events. This
|
|
187
|
-
* ensures that channel approval interception can look up the conversation by
|
|
188
|
-
* requestId.
|
|
189
|
-
*/
|
|
190
|
-
function makePendingInteractionRegistrar(
|
|
191
|
-
conversation: Conversation,
|
|
192
|
-
conversationId: string,
|
|
193
|
-
): (msg: ServerMessage) => void {
|
|
194
|
-
return (msg: ServerMessage) => {
|
|
195
|
-
if (msg.type === "confirmation_request") {
|
|
196
|
-
pendingInteractions.register(msg.requestId, {
|
|
197
|
-
conversation,
|
|
198
|
-
conversationId,
|
|
199
|
-
kind: "confirmation",
|
|
200
|
-
confirmationDetails: {
|
|
201
|
-
toolName: msg.toolName,
|
|
202
|
-
input: msg.input,
|
|
203
|
-
riskLevel: msg.riskLevel,
|
|
204
|
-
executionTarget: msg.executionTarget,
|
|
205
|
-
allowlistOptions: msg.allowlistOptions,
|
|
206
|
-
scopeOptions: msg.scopeOptions,
|
|
207
|
-
persistentDecisionsAllowed: msg.persistentDecisionsAllowed,
|
|
208
|
-
temporaryOptionsAvailable: msg.temporaryOptionsAvailable,
|
|
209
|
-
},
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
// Create a canonical guardian request so HTTP handlers can find it
|
|
213
|
-
// via applyCanonicalGuardianDecision.
|
|
214
|
-
try {
|
|
215
|
-
const trustContext = conversation.trustContext;
|
|
216
|
-
const sourceChannel = trustContext?.sourceChannel ?? "vellum";
|
|
217
|
-
const inputRecord = msg.input as Record<string, unknown>;
|
|
218
|
-
const activityRaw =
|
|
219
|
-
(typeof inputRecord.activity === "string"
|
|
220
|
-
? inputRecord.activity
|
|
221
|
-
: undefined) ??
|
|
222
|
-
(typeof inputRecord.reason === "string"
|
|
223
|
-
? inputRecord.reason
|
|
224
|
-
: undefined);
|
|
225
|
-
const canonicalRequest = createCanonicalGuardianRequest({
|
|
226
|
-
id: msg.requestId,
|
|
227
|
-
kind: "tool_approval",
|
|
228
|
-
sourceType: resolveCanonicalRequestSourceType(sourceChannel),
|
|
229
|
-
sourceChannel,
|
|
230
|
-
conversationId,
|
|
231
|
-
requesterExternalUserId: trustContext?.requesterExternalUserId,
|
|
232
|
-
requesterChatId: trustContext?.requesterChatId,
|
|
233
|
-
guardianExternalUserId: trustContext?.guardianExternalUserId,
|
|
234
|
-
guardianPrincipalId: trustContext?.guardianPrincipalId ?? undefined,
|
|
235
|
-
toolName: msg.toolName,
|
|
236
|
-
commandPreview:
|
|
237
|
-
redactSecrets(summarizeToolInput(msg.toolName, inputRecord)) ||
|
|
238
|
-
undefined,
|
|
239
|
-
riskLevel: msg.riskLevel,
|
|
240
|
-
activityText: activityRaw ? redactSecrets(activityRaw) : undefined,
|
|
241
|
-
executionTarget: msg.executionTarget,
|
|
242
|
-
status: "pending",
|
|
243
|
-
requestCode: generateCanonicalRequestCode(),
|
|
244
|
-
expiresAt: Date.now() + 5 * 60 * 1000,
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
// For trusted-contact sessions, bridge to guardian.question so the
|
|
248
|
-
// guardian gets notified and can approve via callback/request-code.
|
|
249
|
-
if (trustContext) {
|
|
250
|
-
bridgeConfirmationRequestToGuardian({
|
|
251
|
-
canonicalRequest,
|
|
252
|
-
trustContext,
|
|
253
|
-
conversationId,
|
|
254
|
-
toolName: msg.toolName,
|
|
255
|
-
assistantId:
|
|
256
|
-
conversation.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID,
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
} catch (err) {
|
|
260
|
-
log.debug(
|
|
261
|
-
{ err, requestId: msg.requestId, conversationId },
|
|
262
|
-
"Failed to create canonical request from pending interaction registrar",
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
|
-
} else if (msg.type === "secret_request") {
|
|
266
|
-
pendingInteractions.register(msg.requestId, {
|
|
267
|
-
conversation,
|
|
268
|
-
conversationId,
|
|
269
|
-
kind: "secret",
|
|
270
|
-
});
|
|
271
|
-
} else if (msg.type === "host_bash_request") {
|
|
272
|
-
pendingInteractions.register(msg.requestId, {
|
|
273
|
-
conversation,
|
|
274
|
-
conversationId,
|
|
275
|
-
kind: "host_bash",
|
|
276
|
-
});
|
|
277
|
-
} else if (msg.type === "host_browser_request") {
|
|
278
|
-
pendingInteractions.register(msg.requestId, {
|
|
279
|
-
conversation,
|
|
280
|
-
conversationId,
|
|
281
|
-
kind: "host_browser",
|
|
282
|
-
});
|
|
283
|
-
} else if (msg.type === "host_file_request") {
|
|
284
|
-
pendingInteractions.register(msg.requestId, {
|
|
285
|
-
conversation,
|
|
286
|
-
conversationId,
|
|
287
|
-
kind: "host_file",
|
|
288
|
-
});
|
|
289
|
-
} else if (msg.type === "host_cu_request") {
|
|
290
|
-
pendingInteractions.register(msg.requestId, {
|
|
291
|
-
conversation,
|
|
292
|
-
conversationId,
|
|
293
|
-
kind: "host_cu",
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
|
|
299
98
|
export class DaemonServer {
|
|
300
|
-
private conversations = new Map<string, Conversation>();
|
|
301
|
-
private conversationOptions = new Map<string, ConversationCreateOptions>();
|
|
302
|
-
private conversationCreating = new Map<string, Promise<Conversation>>();
|
|
303
99
|
private sharedRequestTimestamps: number[] = [];
|
|
304
100
|
private unsubscribeContactChange: (() => void) | null = null;
|
|
305
101
|
private evictor: ConversationEvictor;
|
|
306
102
|
private _hubChain: Promise<void> = Promise.resolve();
|
|
307
103
|
|
|
308
104
|
// Composed subsystems
|
|
309
|
-
private configWatcher =
|
|
105
|
+
private configWatcher = getConfigWatcher();
|
|
310
106
|
private appSourceWatcher = new AppSourceWatcher();
|
|
311
|
-
private cliIpc = new
|
|
107
|
+
private cliIpc = new AssistantIpcServer();
|
|
108
|
+
private skillIpc = new SkillIpcServer();
|
|
312
109
|
|
|
313
110
|
// CES (Credential Execution Service) — process-level singleton.
|
|
314
111
|
// Lifecycle is managed by startCesProcess() in lifecycle.ts; the server
|
|
@@ -352,6 +149,7 @@ export class DaemonServer {
|
|
|
352
149
|
}
|
|
353
150
|
return client;
|
|
354
151
|
});
|
|
152
|
+
setCesClientPromise(this.cesClientPromise);
|
|
355
153
|
}
|
|
356
154
|
}
|
|
357
155
|
|
|
@@ -374,68 +172,22 @@ export class DaemonServer {
|
|
|
374
172
|
this.cesClientRef = client;
|
|
375
173
|
}
|
|
376
174
|
|
|
377
|
-
/** Optional heartbeat service reference for "Run Now" from the UI. */
|
|
378
|
-
private _heartbeatService?: HeartbeatService;
|
|
379
|
-
|
|
380
|
-
setHeartbeatService(service: HeartbeatService): void {
|
|
381
|
-
this._heartbeatService = service;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
getHeartbeatService(): HeartbeatService | undefined {
|
|
385
|
-
return this._heartbeatService;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
/** Optional filing service reference for "Run Now" from the UI. */
|
|
389
|
-
private _filingService?: FilingService;
|
|
390
|
-
|
|
391
|
-
setFilingService(service: FilingService): void {
|
|
392
|
-
this._filingService = service;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
getFilingService(): FilingService | undefined {
|
|
396
|
-
return this._filingService;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
private deriveMemoryPolicy(conversationId: string): ConversationMemoryPolicy {
|
|
400
|
-
const conversationType = getConversationType(conversationId);
|
|
401
|
-
if (conversationType === "private") {
|
|
402
|
-
return {
|
|
403
|
-
scopeId: getConversationMemoryScopeId(conversationId),
|
|
404
|
-
includeDefaultFallback: true,
|
|
405
|
-
strictSideEffects: true,
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
return DEFAULT_MEMORY_POLICY;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
private applyTransportMetadata(
|
|
412
|
-
conversation: Conversation,
|
|
413
|
-
options: ConversationCreateOptions | undefined,
|
|
414
|
-
): void {
|
|
415
|
-
const transport = options?.transport;
|
|
416
|
-
if (!transport) return;
|
|
417
|
-
log.debug(
|
|
418
|
-
{ channelId: transport.channelId },
|
|
419
|
-
"Transport metadata received",
|
|
420
|
-
);
|
|
421
|
-
conversation.setTransportHints(buildTransportHints(transport));
|
|
422
|
-
// Route client-reported host env through the capability-gated setter on
|
|
423
|
-
// Conversation so both the create/reuse path here and the queue-drain
|
|
424
|
-
// path in conversation-process share one implementation. The method
|
|
425
|
-
// gates on `supportsHostProxy` (not a specific interface name), so any
|
|
426
|
-
// new host-capable client added to `HostProxyInterfaceId` will flow its
|
|
427
|
-
// host env through automatically.
|
|
428
|
-
conversation.applyHostEnvFromTransport(transport);
|
|
429
|
-
}
|
|
430
|
-
|
|
431
175
|
constructor() {
|
|
432
|
-
this.evictor = new ConversationEvictor(
|
|
176
|
+
this.evictor = new ConversationEvictor(getConversationMap());
|
|
433
177
|
getSubagentManager().sharedRequestTimestamps = this.sharedRequestTimestamps;
|
|
434
178
|
getSubagentManager().broadcastToAllClients = (msg) => this.broadcast(msg);
|
|
435
|
-
|
|
436
|
-
this.
|
|
179
|
+
initConversationLifecycle({
|
|
180
|
+
evictor: this.evictor,
|
|
181
|
+
sharedRequestTimestamps: this.sharedRequestTimestamps,
|
|
182
|
+
});
|
|
437
183
|
setBroadcastToAllClients((msg) => this.broadcast(msg));
|
|
438
184
|
setEnsureAppSourceWatcher(() => this.appSourceWatcher.ensureStarted());
|
|
185
|
+
// Wire the skill IPC server into the meet-host supervisor's lazy
|
|
186
|
+
// dispatch path. The supervisor is constructed in
|
|
187
|
+
// `initializeProvidersAndTools()` (via `startMeetHost`), which can run
|
|
188
|
+
// before or after this DaemonServer instance, so the sender flows
|
|
189
|
+
// through a module-level global rather than constructor injection.
|
|
190
|
+
setGlobalSkillIpcSender(this.skillIpc);
|
|
439
191
|
this.evictor.onEvict = (conversationId: string) => {
|
|
440
192
|
getSubagentManager().abortAllForParent(conversationId);
|
|
441
193
|
};
|
|
@@ -451,7 +203,7 @@ export class DaemonServer {
|
|
|
451
203
|
sendToClient,
|
|
452
204
|
notification,
|
|
453
205
|
) => {
|
|
454
|
-
const parentConversation =
|
|
206
|
+
const parentConversation = findConversation(parentConversationId);
|
|
455
207
|
if (!parentConversation) {
|
|
456
208
|
log.warn(
|
|
457
209
|
{ parentConversationId },
|
|
@@ -492,7 +244,7 @@ export class DaemonServer {
|
|
|
492
244
|
message,
|
|
493
245
|
sendToClient,
|
|
494
246
|
) => {
|
|
495
|
-
const parentConversation =
|
|
247
|
+
const parentConversation = findConversation(parentConversationId);
|
|
496
248
|
if (!parentConversation) {
|
|
497
249
|
log.warn(
|
|
498
250
|
{ parentConversationId },
|
|
@@ -611,10 +363,6 @@ export class DaemonServer {
|
|
|
611
363
|
this.broadcast({ type: "sounds_config_updated" });
|
|
612
364
|
}
|
|
613
365
|
|
|
614
|
-
private broadcastFeatureFlagsChanged(): void {
|
|
615
|
-
this.broadcast({ type: "feature_flags_changed" });
|
|
616
|
-
}
|
|
617
|
-
|
|
618
366
|
private broadcastAvatarUpdated(): void {
|
|
619
367
|
this.broadcast({
|
|
620
368
|
type: "avatar_updated",
|
|
@@ -631,7 +379,7 @@ export class DaemonServer {
|
|
|
631
379
|
if (!app) return;
|
|
632
380
|
|
|
633
381
|
const doRefresh = () => {
|
|
634
|
-
for (const conversation of
|
|
382
|
+
for (const conversation of allConversations()) {
|
|
635
383
|
refreshSurfacesForApp(conversation, appId, { fileChange: true });
|
|
636
384
|
}
|
|
637
385
|
this.broadcast({ type: "app_files_changed", appId });
|
|
@@ -671,12 +419,12 @@ export class DaemonServer {
|
|
|
671
419
|
|
|
672
420
|
registerDaemonCallbacks({
|
|
673
421
|
getOrCreateConversation: (conversationId) =>
|
|
674
|
-
|
|
422
|
+
getOrCreateActiveConversation(conversationId),
|
|
675
423
|
broadcast: (msg) => this.broadcast(msg),
|
|
676
424
|
});
|
|
677
425
|
|
|
678
426
|
registerCancelCallback((conversationId) => {
|
|
679
|
-
const conversation =
|
|
427
|
+
const conversation = findConversation(conversationId);
|
|
680
428
|
if (!conversation) return false;
|
|
681
429
|
this.evictor.touch(conversationId);
|
|
682
430
|
conversation.abort(
|
|
@@ -691,7 +439,7 @@ export class DaemonServer {
|
|
|
691
439
|
});
|
|
692
440
|
|
|
693
441
|
registerConversationUndoCallback((conversationId) =>
|
|
694
|
-
undoLastMessage(conversationId
|
|
442
|
+
undoLastMessage(conversationId),
|
|
695
443
|
);
|
|
696
444
|
|
|
697
445
|
registerUserMessageCallback(async (params) => {
|
|
@@ -710,7 +458,7 @@ export class DaemonServer {
|
|
|
710
458
|
const { conversationId } = getOrCreateConversation(
|
|
711
459
|
params.conversationKey,
|
|
712
460
|
);
|
|
713
|
-
const conversation = await
|
|
461
|
+
const conversation = await getOrCreateActiveConversation(conversationId);
|
|
714
462
|
|
|
715
463
|
// Register file-backed attachments so they flow through the send
|
|
716
464
|
// pipeline as images the LLM can see directly.
|
|
@@ -719,10 +467,7 @@ export class DaemonServer {
|
|
|
719
467
|
if (params.attachments && params.attachments.length > 0) {
|
|
720
468
|
for (const a of params.attachments) {
|
|
721
469
|
try {
|
|
722
|
-
const validation =
|
|
723
|
-
a.filename,
|
|
724
|
-
a.mimeType,
|
|
725
|
-
);
|
|
470
|
+
const validation = validateAttachmentUpload(a.filename, a.mimeType);
|
|
726
471
|
if (!validation.ok) {
|
|
727
472
|
log.warn(
|
|
728
473
|
{ error: validation.error, path: a.path },
|
|
@@ -731,7 +476,7 @@ export class DaemonServer {
|
|
|
731
476
|
continue;
|
|
732
477
|
}
|
|
733
478
|
const size = statSync(a.path).size;
|
|
734
|
-
const stored =
|
|
479
|
+
const stored = uploadFileBackedAttachment(
|
|
735
480
|
a.filename,
|
|
736
481
|
a.mimeType,
|
|
737
482
|
a.path,
|
|
@@ -812,93 +557,19 @@ export class DaemonServer {
|
|
|
812
557
|
return { accepted: true };
|
|
813
558
|
});
|
|
814
559
|
|
|
815
|
-
|
|
816
|
-
// internal subsystems (e.g. the Meet chat-opportunity detector wired
|
|
817
|
-
// up in `MeetSessionManager`) can invoke it without having to build
|
|
818
|
-
// a `WakeTarget` adapter themselves. The adapter wraps a live
|
|
819
|
-
// `Conversation` fetched from the in-memory map / hydrated from the
|
|
820
|
-
// DB, exposing only the narrow surface the wake helper needs.
|
|
821
|
-
registerDefaultWakeResolver(async (conversationId) => {
|
|
822
|
-
try {
|
|
823
|
-
// Only resolve existing conversations — don't create ghost
|
|
824
|
-
// conversations for stale targets (e.g. meetings that ended
|
|
825
|
-
// but a delayed opportunity callback still fires).
|
|
826
|
-
const existing = getConversation(conversationId);
|
|
827
|
-
if (!existing) return null;
|
|
828
|
-
const conversation = await this.getOrCreateConversation(conversationId);
|
|
829
|
-
return conversationToWakeTarget(conversation);
|
|
830
|
-
} catch (err) {
|
|
831
|
-
log.warn(
|
|
832
|
-
{ err, conversationId },
|
|
833
|
-
"agent-wake default resolver: failed to hydrate conversation",
|
|
834
|
-
);
|
|
835
|
-
return null;
|
|
836
|
-
}
|
|
837
|
-
});
|
|
838
|
-
|
|
839
|
-
// Install the interactive UI resolver so skills and IPC handlers can
|
|
840
|
-
// present ad-hoc UI surfaces (confirmations, forms) to the user via
|
|
841
|
-
// `requestInteractiveUi()`. Interactive UI requires a client to be
|
|
842
|
-
// actively connected to the conversation (via SSE), which means the
|
|
843
|
-
// conversation must be in the in-memory map. If the conversation was
|
|
844
|
-
// evicted from memory the client is definitely disconnected, so
|
|
845
|
-
// hydration from persistent storage is pointless — the hydrated
|
|
846
|
-
// conversation would have hasNoClient=true, causing
|
|
847
|
-
// canShowInteractiveUi() to return false and the surface to be
|
|
848
|
-
// cancelled with no_interactive_surface. We skip that wasted work
|
|
849
|
-
// and return conversation_not_found directly.
|
|
850
|
-
registerInteractiveUiResolver(async (request) => {
|
|
851
|
-
const conversation = this.conversations.get(request.conversationId);
|
|
852
|
-
|
|
853
|
-
if (!conversation) {
|
|
854
|
-
log.warn(
|
|
855
|
-
{
|
|
856
|
-
conversationId: request.conversationId,
|
|
857
|
-
surfaceType: request.surfaceType,
|
|
858
|
-
},
|
|
859
|
-
"interactive-ui resolver: conversation not in memory (client not connected); failing closed",
|
|
860
|
-
);
|
|
861
|
-
return {
|
|
862
|
-
status: "cancelled" as const,
|
|
863
|
-
surfaceId: `ui-resolver-${Date.now()}`,
|
|
864
|
-
cancellationReason: "conversation_not_found" as const,
|
|
865
|
-
};
|
|
866
|
-
}
|
|
560
|
+
await this.cliIpc.start();
|
|
867
561
|
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
});
|
|
874
|
-
|
|
875
|
-
// Allow `browser_execute` IPC calls to reuse live conversation browser
|
|
876
|
-
// proxy wiring (when a caller passes a conversationId from
|
|
877
|
-
// __CONVERSATION_ID / __SKILL_CONTEXT_JSON). This keeps nested
|
|
878
|
-
// `assistant browser status` checks consistent with the parent turn's
|
|
879
|
-
// extension connectivity instead of always falling back to a synthetic
|
|
880
|
-
// browser-cli session that has no hostBrowserProxy.
|
|
881
|
-
registerBrowserIpcContextResolver((conversationId) => {
|
|
882
|
-
const conversation = this.conversations.get(conversationId);
|
|
883
|
-
if (!conversation) return null;
|
|
884
|
-
return {
|
|
885
|
-
conversationId,
|
|
886
|
-
trustClass: conversation.trustContext?.trustClass ?? "guardian",
|
|
887
|
-
hostBrowserProxy: conversation.hostBrowserProxy,
|
|
888
|
-
transportInterface: conversation.transportInterface,
|
|
889
|
-
};
|
|
890
|
-
});
|
|
891
|
-
|
|
892
|
-
// Start the CLI IPC server. Built-in methods (wake_conversation) are
|
|
893
|
-
// registered by the constructor; CLI commands connect to this socket to
|
|
894
|
-
// invoke daemon-side operations that require in-process state.
|
|
895
|
-
this.cliIpc.start();
|
|
562
|
+
// Start the skill IPC server. First-party skill processes connect to this
|
|
563
|
+
// socket to access host capabilities (host.log, host.config.*,
|
|
564
|
+
// host.events.*, host.registries.*). Route registry is populated by
|
|
565
|
+
// subsequent PRs in the skill-isolation plan.
|
|
566
|
+
await this.skillIpc.start();
|
|
896
567
|
|
|
897
568
|
// Wire the launchConversation helper to daemon-side state so
|
|
898
569
|
// handleSurfaceAction can spawn conversations through it.
|
|
899
570
|
registerLaunchConversationDeps({
|
|
900
571
|
getOrCreateConversation: (id, options) =>
|
|
901
|
-
|
|
572
|
+
getOrCreateActiveConversation(id, options),
|
|
902
573
|
persistAndProcessMessage: (
|
|
903
574
|
conversationId,
|
|
904
575
|
content,
|
|
@@ -926,7 +597,6 @@ export class DaemonServer {
|
|
|
926
597
|
() => this.broadcastSoundsConfigUpdated(),
|
|
927
598
|
() => this.broadcastAvatarUpdated(),
|
|
928
599
|
() => this.broadcastConfigChanged(),
|
|
929
|
-
() => this.broadcastFeatureFlagsChanged(),
|
|
930
600
|
);
|
|
931
601
|
|
|
932
602
|
this.syncIdentityToPlatform();
|
|
@@ -948,15 +618,16 @@ export class DaemonServer {
|
|
|
948
618
|
this.configWatcher.stop();
|
|
949
619
|
this.appSourceWatcher.stop();
|
|
950
620
|
this.cliIpc.stop();
|
|
621
|
+
this.skillIpc.stop();
|
|
951
622
|
if (this.unsubscribeContactChange) {
|
|
952
623
|
this.unsubscribeContactChange();
|
|
953
624
|
this.unsubscribeContactChange = null;
|
|
954
625
|
}
|
|
955
626
|
|
|
956
|
-
for (const conversation of
|
|
627
|
+
for (const conversation of allConversations()) {
|
|
957
628
|
conversation.dispose();
|
|
958
629
|
}
|
|
959
|
-
|
|
630
|
+
clearConversations();
|
|
960
631
|
|
|
961
632
|
// Abort any in-flight CES initialization so it fails fast instead of
|
|
962
633
|
// blocking shutdown for up to ~15s (socket connect + handshake timeouts).
|
|
@@ -981,6 +652,7 @@ export class DaemonServer {
|
|
|
981
652
|
if (this.cesClientPromise) {
|
|
982
653
|
await this.cesClientPromise.catch(() => undefined);
|
|
983
654
|
this.cesClientPromise = undefined;
|
|
655
|
+
setCesClientPromise(undefined);
|
|
984
656
|
}
|
|
985
657
|
if (this.cesProcessManager) {
|
|
986
658
|
this.cesProcessManager = undefined;
|
|
@@ -999,42 +671,13 @@ export class DaemonServer {
|
|
|
999
671
|
});
|
|
1000
672
|
}
|
|
1001
673
|
|
|
1002
|
-
clearAllConversations(): number {
|
|
1003
|
-
const count = this.conversations.size;
|
|
1004
|
-
const subagentManager = getSubagentManager();
|
|
1005
|
-
for (const id of this.conversations.keys()) {
|
|
1006
|
-
this.evictor.remove(id);
|
|
1007
|
-
subagentManager.abortAllForParent(id);
|
|
1008
|
-
}
|
|
1009
|
-
for (const conversation of this.conversations.values()) {
|
|
1010
|
-
conversation.dispose();
|
|
1011
|
-
}
|
|
1012
|
-
this.conversations.clear();
|
|
1013
|
-
this.conversationOptions.clear();
|
|
1014
|
-
return count;
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
/**
|
|
1018
|
-
* Abort and dispose a single in-memory conversation, removing it from the
|
|
1019
|
-
* conversation map. No-op if no conversation exists for the given ID.
|
|
1020
|
-
*/
|
|
1021
|
-
destroyConversation(conversationId: string): void {
|
|
1022
|
-
const conversation = this.conversations.get(conversationId);
|
|
1023
|
-
if (!conversation) return;
|
|
1024
|
-
this.evictor.remove(conversationId);
|
|
1025
|
-
getSubagentManager().abortAllForParent(conversationId);
|
|
1026
|
-
conversation.dispose();
|
|
1027
|
-
this.conversations.delete(conversationId);
|
|
1028
|
-
this.conversationOptions.delete(conversationId);
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
674
|
private evictConversationsForReload(): void {
|
|
1032
675
|
const subagentManager = getSubagentManager();
|
|
1033
|
-
for (const [id, conversation] of
|
|
676
|
+
for (const [id, conversation] of conversationEntries()) {
|
|
1034
677
|
if (!conversation.isProcessing()) {
|
|
1035
678
|
subagentManager.abortAllForParent(id);
|
|
1036
679
|
conversation.dispose();
|
|
1037
|
-
|
|
680
|
+
deleteConversation(id);
|
|
1038
681
|
this.evictor.remove(id);
|
|
1039
682
|
} else {
|
|
1040
683
|
conversation.markStale();
|
|
@@ -1064,144 +707,10 @@ export class DaemonServer {
|
|
|
1064
707
|
this.evictConversationsForReload();
|
|
1065
708
|
}
|
|
1066
709
|
|
|
1067
|
-
private async getOrCreateConversation(
|
|
1068
|
-
conversationId: string,
|
|
1069
|
-
options?: ConversationCreateOptions,
|
|
1070
|
-
): Promise<Conversation> {
|
|
1071
|
-
let conversation = this.conversations.get(conversationId);
|
|
1072
|
-
const sendToClient = () => {};
|
|
1073
|
-
|
|
1074
|
-
const { taskRunId: _taskRunId, ...persistentOptions } = options ?? {};
|
|
1075
|
-
if (Object.values(persistentOptions).some((v) => v !== undefined)) {
|
|
1076
|
-
this.conversationOptions.set(conversationId, {
|
|
1077
|
-
...this.conversationOptions.get(conversationId),
|
|
1078
|
-
...persistentOptions,
|
|
1079
|
-
});
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
if (
|
|
1083
|
-
!conversation ||
|
|
1084
|
-
(conversation.isStale() && !conversation.isProcessing())
|
|
1085
|
-
) {
|
|
1086
|
-
if (conversation) {
|
|
1087
|
-
getSubagentManager().abortAllForParent(conversationId);
|
|
1088
|
-
conversation.dispose();
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
const pending = this.conversationCreating.get(conversationId);
|
|
1092
|
-
if (pending) {
|
|
1093
|
-
conversation = await pending;
|
|
1094
|
-
return conversation;
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
const storedOptions = this.conversationOptions.get(conversationId);
|
|
1098
|
-
|
|
1099
|
-
const createPromise = (async () => {
|
|
1100
|
-
const config = getConfig();
|
|
1101
|
-
let provider = getProvider(config.llm.default.provider);
|
|
1102
|
-
// Per-call `options.config.callSite` can resolve to a provider name
|
|
1103
|
-
// that differs from `llm.default.provider`. Wrap the default
|
|
1104
|
-
// provider so the actual transport routes correctly per call,
|
|
1105
|
-
// rather than only forwarding metadata to the default's HTTP
|
|
1106
|
-
// client. See `providers/call-site-routing.ts`.
|
|
1107
|
-
provider = new CallSiteRoutingProvider(provider, (name) => {
|
|
1108
|
-
try {
|
|
1109
|
-
return getProvider(name);
|
|
1110
|
-
} catch {
|
|
1111
|
-
return undefined;
|
|
1112
|
-
}
|
|
1113
|
-
});
|
|
1114
|
-
const { rateLimit } = config;
|
|
1115
|
-
if (rateLimit.maxRequestsPerMinute > 0) {
|
|
1116
|
-
provider = new RateLimitProvider(
|
|
1117
|
-
provider,
|
|
1118
|
-
rateLimit,
|
|
1119
|
-
this.sharedRequestTimestamps,
|
|
1120
|
-
);
|
|
1121
|
-
}
|
|
1122
|
-
const workingDir = getSandboxWorkingDir();
|
|
1123
|
-
|
|
1124
|
-
const systemPrompt =
|
|
1125
|
-
storedOptions?.systemPromptOverride ?? buildSystemPrompt();
|
|
1126
|
-
const maxTokens =
|
|
1127
|
-
storedOptions?.maxResponseTokens ?? config.llm.default.maxTokens;
|
|
1128
|
-
|
|
1129
|
-
const memoryPolicy = this.deriveMemoryPolicy(conversationId);
|
|
1130
|
-
// Resolve the shared CES client (may still be initializing).
|
|
1131
|
-
const sharedCesClient = this.cesClientPromise
|
|
1132
|
-
? await this.cesClientPromise
|
|
1133
|
-
: undefined;
|
|
1134
|
-
const newConversation = new Conversation(
|
|
1135
|
-
conversationId,
|
|
1136
|
-
provider,
|
|
1137
|
-
systemPrompt,
|
|
1138
|
-
maxTokens,
|
|
1139
|
-
sendToClient,
|
|
1140
|
-
workingDir,
|
|
1141
|
-
(msg) => this.broadcast(msg),
|
|
1142
|
-
memoryPolicy,
|
|
1143
|
-
sharedCesClient,
|
|
1144
|
-
storedOptions?.speed,
|
|
1145
|
-
undefined,
|
|
1146
|
-
storedOptions?.modelOverride,
|
|
1147
|
-
);
|
|
1148
|
-
newConversation.updateClient(sendToClient, true);
|
|
1149
|
-
await newConversation.loadFromDb();
|
|
1150
|
-
// Restore trust/auth context and assistant ID from stored options so
|
|
1151
|
-
// that evicted sessions rehydrated by undo/regenerate don't run with
|
|
1152
|
-
// unscoped history. Without this, an untrusted actor could operate
|
|
1153
|
-
// on the full conversation after eviction.
|
|
1154
|
-
if (storedOptions?.assistantId) {
|
|
1155
|
-
newConversation.setAssistantId(storedOptions.assistantId);
|
|
1156
|
-
}
|
|
1157
|
-
if (storedOptions?.trustContext) {
|
|
1158
|
-
newConversation.setTrustContext(storedOptions.trustContext);
|
|
1159
|
-
}
|
|
1160
|
-
if (storedOptions?.authContext) {
|
|
1161
|
-
newConversation.setAuthContext(storedOptions.authContext);
|
|
1162
|
-
}
|
|
1163
|
-
if (storedOptions?.trustContext || storedOptions?.authContext) {
|
|
1164
|
-
await newConversation.ensureActorScopedHistory();
|
|
1165
|
-
}
|
|
1166
|
-
this.applyTransportMetadata(newConversation, storedOptions);
|
|
1167
|
-
this.conversations.set(conversationId, newConversation);
|
|
1168
|
-
return newConversation;
|
|
1169
|
-
})();
|
|
1170
|
-
|
|
1171
|
-
this.conversationCreating.set(conversationId, createPromise);
|
|
1172
|
-
try {
|
|
1173
|
-
conversation = await createPromise;
|
|
1174
|
-
} finally {
|
|
1175
|
-
this.conversationCreating.delete(conversationId);
|
|
1176
|
-
}
|
|
1177
|
-
this.evictor.touch(conversationId);
|
|
1178
|
-
} else {
|
|
1179
|
-
// Only apply transport metadata when the conversation is idle.
|
|
1180
|
-
// When processing, the hints are stored on the queued message and
|
|
1181
|
-
// will be applied at dequeue time — applying them here would
|
|
1182
|
-
// overwrite the in-flight conversation's transportHints.
|
|
1183
|
-
if (!conversation.isProcessing()) {
|
|
1184
|
-
this.applyTransportMetadata(conversation, options);
|
|
1185
|
-
// trustContext is reapplied here only when the conversation is idle,
|
|
1186
|
-
// so concurrent requests cannot overwrite an in-flight turn's guardian
|
|
1187
|
-
// scope. Direct callers (e.g. schedule-routes run-now) that invoke
|
|
1188
|
-
// processMessage without going through prepareConversationForMessage
|
|
1189
|
-
// rely on this to pick up the trustContext passed in options.
|
|
1190
|
-
// prepareConversationForMessage also reapplies after its own idle check.
|
|
1191
|
-
if (options?.trustContext !== undefined) {
|
|
1192
|
-
conversation.setTrustContext(options.trustContext);
|
|
1193
|
-
}
|
|
1194
|
-
}
|
|
1195
|
-
this.evictor.touch(conversationId);
|
|
1196
|
-
}
|
|
1197
|
-
return conversation;
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
710
|
// ── Handler context ────────────────────────────────────────────────
|
|
1201
711
|
|
|
1202
712
|
private handlerContext(): HandlerContext {
|
|
1203
713
|
return {
|
|
1204
|
-
conversations: this.conversations,
|
|
1205
714
|
sharedRequestTimestamps: this.sharedRequestTimestamps,
|
|
1206
715
|
debounceTimers: this.configWatcher.timers,
|
|
1207
716
|
suppressConfigReload: this.configWatcher.suppressConfigReload,
|
|
@@ -1213,198 +722,15 @@ export class DaemonServer {
|
|
|
1213
722
|
},
|
|
1214
723
|
send: (msg) => this.broadcast(msg),
|
|
1215
724
|
broadcast: (msg) => this.broadcast(msg),
|
|
1216
|
-
clearAllConversations: () =>
|
|
725
|
+
clearAllConversations: () => clearAllActiveConversations(),
|
|
1217
726
|
getOrCreateConversation: (id, options?) =>
|
|
1218
|
-
|
|
727
|
+
getOrCreateActiveConversation(id, options),
|
|
1219
728
|
touchConversation: (id) => this.evictor.touch(id),
|
|
1220
|
-
heartbeatService: this._heartbeatService,
|
|
1221
|
-
};
|
|
1222
|
-
}
|
|
1223
|
-
|
|
1224
|
-
/** Public subset of handler context for skill management HTTP routes. */
|
|
1225
|
-
getSkillContext(): SkillOperationContext {
|
|
1226
|
-
return {
|
|
1227
|
-
debounceTimers: this.configWatcher.timers,
|
|
1228
|
-
setSuppressConfigReload: (value: boolean) => {
|
|
1229
|
-
this.configWatcher.suppressConfigReload = value;
|
|
1230
|
-
},
|
|
1231
|
-
updateConfigFingerprint: () => {
|
|
1232
|
-
this.configWatcher.updateFingerprint();
|
|
1233
|
-
},
|
|
1234
|
-
broadcast: (msg) => this.broadcast(msg),
|
|
1235
729
|
};
|
|
1236
730
|
}
|
|
1237
731
|
|
|
1238
732
|
// ── HTTP message processing ─────────────────────────────────────────
|
|
1239
733
|
|
|
1240
|
-
private async prepareConversationForMessage(
|
|
1241
|
-
conversationId: string,
|
|
1242
|
-
content: string,
|
|
1243
|
-
attachmentIds: string[] | undefined,
|
|
1244
|
-
options: ConversationCreateOptions | undefined,
|
|
1245
|
-
sourceChannel: string | undefined,
|
|
1246
|
-
sourceInterface: string | undefined,
|
|
1247
|
-
): Promise<{
|
|
1248
|
-
conversation: Conversation;
|
|
1249
|
-
attachments: {
|
|
1250
|
-
id: string;
|
|
1251
|
-
filename: string;
|
|
1252
|
-
mimeType: string;
|
|
1253
|
-
data: string;
|
|
1254
|
-
filePath?: string;
|
|
1255
|
-
}[];
|
|
1256
|
-
}> {
|
|
1257
|
-
const conversation = await this.getOrCreateConversation(
|
|
1258
|
-
conversationId,
|
|
1259
|
-
options,
|
|
1260
|
-
);
|
|
1261
|
-
|
|
1262
|
-
if (conversation.isProcessing()) {
|
|
1263
|
-
throw new Error("Conversation is already processing a message");
|
|
1264
|
-
}
|
|
1265
|
-
|
|
1266
|
-
const resolvedChannel = resolveTurnChannel(
|
|
1267
|
-
sourceChannel,
|
|
1268
|
-
options?.transport?.channelId,
|
|
1269
|
-
);
|
|
1270
|
-
const resolvedInterface = resolveTurnInterface(sourceInterface);
|
|
1271
|
-
conversation.setAssistantId(
|
|
1272
|
-
options?.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID,
|
|
1273
|
-
);
|
|
1274
|
-
conversation.taskRunId = options?.taskRunId;
|
|
1275
|
-
// Only overwrite trust/auth context when explicitly provided. Callers that
|
|
1276
|
-
// don't supply a trust context (e.g. signal-injected messages) should
|
|
1277
|
-
// inherit whatever the conversation already has from a prior session.
|
|
1278
|
-
if (options?.trustContext !== undefined) {
|
|
1279
|
-
conversation.setTrustContext(options.trustContext);
|
|
1280
|
-
}
|
|
1281
|
-
if (options?.authContext !== undefined) {
|
|
1282
|
-
conversation.setAuthContext(options.authContext);
|
|
1283
|
-
}
|
|
1284
|
-
await conversation.ensureActorScopedHistory();
|
|
1285
|
-
|
|
1286
|
-
// Persist the conversation's current trust/auth context so it survives
|
|
1287
|
-
// eviction and recreation. The restore path in getOrCreateConversation
|
|
1288
|
-
// reads from storedOptions.trustContext / storedOptions.authContext.
|
|
1289
|
-
// Always write — including null — so explicit clearing isn't lost.
|
|
1290
|
-
this.conversationOptions.set(conversationId, {
|
|
1291
|
-
...this.conversationOptions.get(conversationId),
|
|
1292
|
-
trustContext: conversation.trustContext,
|
|
1293
|
-
authContext: conversation.authContext,
|
|
1294
|
-
});
|
|
1295
|
-
conversation.setChannelCapabilities(
|
|
1296
|
-
resolveChannelCapabilities(
|
|
1297
|
-
sourceChannel,
|
|
1298
|
-
sourceInterface,
|
|
1299
|
-
options?.transport?.chatType,
|
|
1300
|
-
),
|
|
1301
|
-
);
|
|
1302
|
-
// Chrome-extension host_browser wiring is intentionally not supported
|
|
1303
|
-
// through this entry point. `prepareConversationForMessage` constructs
|
|
1304
|
-
// host_browser proxies that capture `conversation.getCurrentSender()`
|
|
1305
|
-
// directly, which would route browser frames through the daemon SSE
|
|
1306
|
-
// channel instead of the `ChromeExtensionRegistry`. Chrome-extension
|
|
1307
|
-
// flows reach host_browser exclusively through the
|
|
1308
|
-
// `/v1/messages` flow in `conversation-routes.ts`, which wires a
|
|
1309
|
-
// registry-aware sender and sets `hostBrowserSenderOverride`.
|
|
1310
|
-
//
|
|
1311
|
-
// Fail loudly rather than silently returning a mis-wired proxy so that
|
|
1312
|
-
// any future caller that tries to route chrome-extension through this
|
|
1313
|
-
// path discovers the gap immediately. When the time comes, factor the
|
|
1314
|
-
// wiring in conversation-routes.ts (registry lookup + override) into a
|
|
1315
|
-
// shared helper and call it from both sites.
|
|
1316
|
-
if (resolvedInterface === "chrome-extension") {
|
|
1317
|
-
throw new Error(
|
|
1318
|
-
"prepareConversationForMessage does not yet support chrome-extension transport — " +
|
|
1319
|
-
"use the conversation-routes.ts /v1/messages flow which routes host_browser through " +
|
|
1320
|
-
"the ChromeExtensionRegistry. If you need chrome-extension here, factor out the " +
|
|
1321
|
-
"wiring in conversation-routes.ts into a shared helper.",
|
|
1322
|
-
);
|
|
1323
|
-
}
|
|
1324
|
-
// Only create each host proxy for interfaces that support the matching
|
|
1325
|
-
// capability. macOS supports all four; the chrome-extension interface only
|
|
1326
|
-
// supports host_browser. Non-desktop conversations (CLI, channels, headless)
|
|
1327
|
-
// fall back to local execution.
|
|
1328
|
-
// Guard: don't replace an active proxy during concurrent turn races —
|
|
1329
|
-
// another request may have started processing between the isProcessing()
|
|
1330
|
-
// check above and the await on ensureActorScopedHistory().
|
|
1331
|
-
if (supportsHostProxy(resolvedInterface, "host_bash")) {
|
|
1332
|
-
if (!conversation.isProcessing() || !conversation.hostBashProxy) {
|
|
1333
|
-
conversation.setHostBashProxy(
|
|
1334
|
-
new HostBashProxy(conversation.getCurrentSender(), (requestId) => {
|
|
1335
|
-
pendingInteractions.resolve(requestId);
|
|
1336
|
-
}),
|
|
1337
|
-
);
|
|
1338
|
-
}
|
|
1339
|
-
} else if (!conversation.isProcessing()) {
|
|
1340
|
-
conversation.setHostBashProxy(undefined);
|
|
1341
|
-
}
|
|
1342
|
-
if (supportsHostProxy(resolvedInterface, "host_browser")) {
|
|
1343
|
-
if (!conversation.isProcessing() || !conversation.hostBrowserProxy) {
|
|
1344
|
-
conversation.setHostBrowserProxy(
|
|
1345
|
-
new HostBrowserProxy(conversation.getCurrentSender(), (requestId) => {
|
|
1346
|
-
pendingInteractions.resolve(requestId);
|
|
1347
|
-
}),
|
|
1348
|
-
);
|
|
1349
|
-
}
|
|
1350
|
-
} else if (!conversation.isProcessing()) {
|
|
1351
|
-
conversation.setHostBrowserProxy(undefined);
|
|
1352
|
-
}
|
|
1353
|
-
if (supportsHostProxy(resolvedInterface, "host_file")) {
|
|
1354
|
-
if (!conversation.isProcessing() || !conversation.hostFileProxy) {
|
|
1355
|
-
conversation.setHostFileProxy(
|
|
1356
|
-
new HostFileProxy(conversation.getCurrentSender(), (requestId) => {
|
|
1357
|
-
pendingInteractions.resolve(requestId);
|
|
1358
|
-
}),
|
|
1359
|
-
);
|
|
1360
|
-
}
|
|
1361
|
-
} else if (!conversation.isProcessing()) {
|
|
1362
|
-
conversation.setHostFileProxy(undefined);
|
|
1363
|
-
}
|
|
1364
|
-
if (supportsHostProxy(resolvedInterface, "host_cu")) {
|
|
1365
|
-
if (!conversation.isProcessing() || !conversation.hostCuProxy) {
|
|
1366
|
-
conversation.setHostCuProxy(
|
|
1367
|
-
new HostCuProxy(conversation.getCurrentSender(), (requestId) => {
|
|
1368
|
-
pendingInteractions.resolve(requestId);
|
|
1369
|
-
}),
|
|
1370
|
-
);
|
|
1371
|
-
}
|
|
1372
|
-
conversation.addPreactivatedSkillId("computer-use");
|
|
1373
|
-
} else if (!conversation.isProcessing()) {
|
|
1374
|
-
conversation.setHostCuProxy(undefined);
|
|
1375
|
-
}
|
|
1376
|
-
conversation.setCommandIntent(options?.commandIntent ?? null);
|
|
1377
|
-
conversation.setTurnChannelContext({
|
|
1378
|
-
userMessageChannel: resolvedChannel,
|
|
1379
|
-
assistantMessageChannel: resolvedChannel,
|
|
1380
|
-
});
|
|
1381
|
-
conversation.setTurnInterfaceContext({
|
|
1382
|
-
userMessageInterface: resolvedInterface,
|
|
1383
|
-
assistantMessageInterface: resolvedInterface,
|
|
1384
|
-
});
|
|
1385
|
-
|
|
1386
|
-
const attachments = attachmentIds
|
|
1387
|
-
? (() => {
|
|
1388
|
-
const resolved = attachmentsStore.getAttachmentsByIds(attachmentIds, {
|
|
1389
|
-
hydrateFileData: true,
|
|
1390
|
-
});
|
|
1391
|
-
const sourcePaths =
|
|
1392
|
-
attachmentsStore.getSourcePathsForAttachments(attachmentIds);
|
|
1393
|
-
return resolved.map((a) => ({
|
|
1394
|
-
id: a.id,
|
|
1395
|
-
filename: a.originalFilename,
|
|
1396
|
-
mimeType: a.mimeType,
|
|
1397
|
-
data: a.dataBase64,
|
|
1398
|
-
...(sourcePaths.has(a.id)
|
|
1399
|
-
? { filePath: sourcePaths.get(a.id) }
|
|
1400
|
-
: {}),
|
|
1401
|
-
}));
|
|
1402
|
-
})()
|
|
1403
|
-
: [];
|
|
1404
|
-
|
|
1405
|
-
return { conversation, attachments };
|
|
1406
|
-
}
|
|
1407
|
-
|
|
1408
734
|
async persistAndProcessMessage(
|
|
1409
735
|
conversationId: string,
|
|
1410
736
|
content: string,
|
|
@@ -1413,15 +739,14 @@ export class DaemonServer {
|
|
|
1413
739
|
sourceChannel?: string,
|
|
1414
740
|
sourceInterface?: string,
|
|
1415
741
|
): Promise<{ messageId: string }> {
|
|
1416
|
-
const { conversation, attachments } =
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
);
|
|
742
|
+
const { conversation, attachments } = await prepareConversationForMessage(
|
|
743
|
+
conversationId,
|
|
744
|
+
content,
|
|
745
|
+
attachmentIds,
|
|
746
|
+
options,
|
|
747
|
+
sourceChannel,
|
|
748
|
+
sourceInterface,
|
|
749
|
+
);
|
|
1425
750
|
|
|
1426
751
|
const requestId = crypto.randomUUID();
|
|
1427
752
|
const messageId = await conversation.persistUserMessage(
|
|
@@ -1491,259 +816,6 @@ export class DaemonServer {
|
|
|
1491
816
|
return { messageId };
|
|
1492
817
|
}
|
|
1493
818
|
|
|
1494
|
-
async processMessage(
|
|
1495
|
-
conversationId: string,
|
|
1496
|
-
content: string,
|
|
1497
|
-
attachmentIds?: string[],
|
|
1498
|
-
options?: ConversationCreateOptions,
|
|
1499
|
-
sourceChannel?: string,
|
|
1500
|
-
sourceInterface?: string,
|
|
1501
|
-
): Promise<{ messageId: string }> {
|
|
1502
|
-
const { conversation, attachments } =
|
|
1503
|
-
await this.prepareConversationForMessage(
|
|
1504
|
-
conversationId,
|
|
1505
|
-
content,
|
|
1506
|
-
attachmentIds,
|
|
1507
|
-
options,
|
|
1508
|
-
sourceChannel,
|
|
1509
|
-
sourceInterface,
|
|
1510
|
-
);
|
|
1511
|
-
|
|
1512
|
-
const config = getConfig();
|
|
1513
|
-
const serverInterfaceCtx = conversation.getTurnInterfaceContext();
|
|
1514
|
-
const slashContext: SlashContext = {
|
|
1515
|
-
messageCount: conversation.getMessages().length,
|
|
1516
|
-
inputTokens: conversation.usageStats.inputTokens,
|
|
1517
|
-
outputTokens: conversation.usageStats.outputTokens,
|
|
1518
|
-
maxInputTokens: config.llm.default.contextWindow.maxInputTokens,
|
|
1519
|
-
model: config.llm.default.model,
|
|
1520
|
-
provider: config.llm.default.provider,
|
|
1521
|
-
estimatedCost: conversation.usageStats.estimatedCost,
|
|
1522
|
-
userMessageInterface: serverInterfaceCtx?.userMessageInterface,
|
|
1523
|
-
};
|
|
1524
|
-
const slashResult = await resolveSlash(content, slashContext);
|
|
1525
|
-
|
|
1526
|
-
// Slack inbound metadata is materialized once here for the slash-command
|
|
1527
|
-
// bypass paths (unknown-slash and /compact), which persist the user row
|
|
1528
|
-
// directly via `addMessage` and would otherwise drop the envelope. The
|
|
1529
|
-
// agent-loop path does not consume this variable — it forwards
|
|
1530
|
-
// `options.slackInbound` through `persistMetadata` and the envelope is
|
|
1531
|
-
// built internally by `buildSlackMetaForPersistence` inside
|
|
1532
|
-
// `persistQueuedMessageBody`.
|
|
1533
|
-
const slackMeta = buildSlackMetaForPersistence({
|
|
1534
|
-
slackInbound: options?.slackInbound,
|
|
1535
|
-
turnChannel: conversation.getTurnChannelContext()?.userMessageChannel,
|
|
1536
|
-
});
|
|
1537
|
-
|
|
1538
|
-
if (slashResult.kind === "unknown") {
|
|
1539
|
-
const serverTurnCtx = conversation.getTurnChannelContext();
|
|
1540
|
-
const serverProvenance = provenanceFromTrustContext(
|
|
1541
|
-
conversation.trustContext,
|
|
1542
|
-
);
|
|
1543
|
-
const imageSourcePaths: Record<string, string> = {};
|
|
1544
|
-
for (let i = 0; i < attachments.length; i++) {
|
|
1545
|
-
const a = attachments[i];
|
|
1546
|
-
if (a.filePath && a.mimeType.toLowerCase().startsWith("image/")) {
|
|
1547
|
-
imageSourcePaths[`${i}:${a.filename}`] = a.filePath;
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1550
|
-
const serverChannelMeta = {
|
|
1551
|
-
...serverProvenance,
|
|
1552
|
-
...(serverTurnCtx
|
|
1553
|
-
? {
|
|
1554
|
-
userMessageChannel: serverTurnCtx.userMessageChannel,
|
|
1555
|
-
assistantMessageChannel: serverTurnCtx.assistantMessageChannel,
|
|
1556
|
-
}
|
|
1557
|
-
: {}),
|
|
1558
|
-
...(serverInterfaceCtx
|
|
1559
|
-
? {
|
|
1560
|
-
userMessageInterface: serverInterfaceCtx.userMessageInterface,
|
|
1561
|
-
assistantMessageInterface:
|
|
1562
|
-
serverInterfaceCtx.assistantMessageInterface,
|
|
1563
|
-
}
|
|
1564
|
-
: {}),
|
|
1565
|
-
...(Object.keys(imageSourcePaths).length > 0
|
|
1566
|
-
? { imageSourcePaths }
|
|
1567
|
-
: {}),
|
|
1568
|
-
};
|
|
1569
|
-
// slackMeta encodes the inbound user message's ts/thread — it attaches
|
|
1570
|
-
// to the user row only. The assistant's slash-command response does not
|
|
1571
|
-
// originate from Slack and must not inherit the user's channelTs, which
|
|
1572
|
-
// would break ordering in the chronological renderer.
|
|
1573
|
-
const userMetaWithSlack = slackMeta
|
|
1574
|
-
? { ...serverChannelMeta, slackMeta }
|
|
1575
|
-
: serverChannelMeta;
|
|
1576
|
-
const cleanMsg = createUserMessage(content, attachments);
|
|
1577
|
-
const llmMsg = enrichMessageWithSourcePaths(cleanMsg, attachments);
|
|
1578
|
-
const persisted = await addMessage(
|
|
1579
|
-
conversationId,
|
|
1580
|
-
"user",
|
|
1581
|
-
JSON.stringify(cleanMsg.content),
|
|
1582
|
-
userMetaWithSlack,
|
|
1583
|
-
);
|
|
1584
|
-
conversation.getMessages().push(llmMsg);
|
|
1585
|
-
|
|
1586
|
-
if (serverTurnCtx) {
|
|
1587
|
-
try {
|
|
1588
|
-
setConversationOriginChannelIfUnset(
|
|
1589
|
-
conversationId,
|
|
1590
|
-
serverTurnCtx.userMessageChannel,
|
|
1591
|
-
);
|
|
1592
|
-
} catch (err) {
|
|
1593
|
-
log.warn(
|
|
1594
|
-
{ err, conversationId },
|
|
1595
|
-
"Failed to set origin channel (best-effort)",
|
|
1596
|
-
);
|
|
1597
|
-
}
|
|
1598
|
-
}
|
|
1599
|
-
if (serverInterfaceCtx) {
|
|
1600
|
-
try {
|
|
1601
|
-
setConversationOriginInterfaceIfUnset(
|
|
1602
|
-
conversationId,
|
|
1603
|
-
serverInterfaceCtx.userMessageInterface,
|
|
1604
|
-
);
|
|
1605
|
-
} catch (err) {
|
|
1606
|
-
log.warn(
|
|
1607
|
-
{ err, conversationId },
|
|
1608
|
-
"Failed to set origin interface (best-effort)",
|
|
1609
|
-
);
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
|
|
1613
|
-
// Rewrite meta.json so the on-disk metadata reflects the origin channel
|
|
1614
|
-
if (serverTurnCtx || serverInterfaceCtx) {
|
|
1615
|
-
try {
|
|
1616
|
-
const convForMeta = getConversation(conversationId);
|
|
1617
|
-
if (convForMeta) {
|
|
1618
|
-
updateMetaFile(convForMeta);
|
|
1619
|
-
}
|
|
1620
|
-
} catch (err) {
|
|
1621
|
-
log.warn(
|
|
1622
|
-
{ err, conversationId },
|
|
1623
|
-
"Failed to update disk meta (best-effort)",
|
|
1624
|
-
);
|
|
1625
|
-
}
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
|
-
const assistantMsg = createAssistantMessage(slashResult.message);
|
|
1629
|
-
await addMessage(
|
|
1630
|
-
conversationId,
|
|
1631
|
-
"assistant",
|
|
1632
|
-
JSON.stringify(assistantMsg.content),
|
|
1633
|
-
serverChannelMeta,
|
|
1634
|
-
);
|
|
1635
|
-
conversation.getMessages().push(assistantMsg);
|
|
1636
|
-
return { messageId: persisted.id };
|
|
1637
|
-
}
|
|
1638
|
-
|
|
1639
|
-
if (slashResult.kind === "compact") {
|
|
1640
|
-
const serverTurnCtx = conversation.getTurnChannelContext();
|
|
1641
|
-
const serverProvenance = provenanceFromTrustContext(
|
|
1642
|
-
conversation.trustContext,
|
|
1643
|
-
);
|
|
1644
|
-
const compactChannelMeta = {
|
|
1645
|
-
...serverProvenance,
|
|
1646
|
-
...(serverTurnCtx
|
|
1647
|
-
? {
|
|
1648
|
-
userMessageChannel: serverTurnCtx.userMessageChannel,
|
|
1649
|
-
assistantMessageChannel: serverTurnCtx.assistantMessageChannel,
|
|
1650
|
-
}
|
|
1651
|
-
: {}),
|
|
1652
|
-
...(serverInterfaceCtx
|
|
1653
|
-
? {
|
|
1654
|
-
userMessageInterface: serverInterfaceCtx.userMessageInterface,
|
|
1655
|
-
assistantMessageInterface:
|
|
1656
|
-
serverInterfaceCtx.assistantMessageInterface,
|
|
1657
|
-
}
|
|
1658
|
-
: {}),
|
|
1659
|
-
};
|
|
1660
|
-
const compactUserMeta = slackMeta
|
|
1661
|
-
? { ...compactChannelMeta, slackMeta }
|
|
1662
|
-
: compactChannelMeta;
|
|
1663
|
-
const cleanMsg = createUserMessage(content, attachments);
|
|
1664
|
-
const persisted = await addMessage(
|
|
1665
|
-
conversationId,
|
|
1666
|
-
"user",
|
|
1667
|
-
JSON.stringify(cleanMsg.content),
|
|
1668
|
-
compactUserMeta,
|
|
1669
|
-
);
|
|
1670
|
-
conversation.getMessages().push(cleanMsg);
|
|
1671
|
-
|
|
1672
|
-
conversation.emitActivityState(
|
|
1673
|
-
"thinking",
|
|
1674
|
-
"context_compacting",
|
|
1675
|
-
"assistant_turn",
|
|
1676
|
-
);
|
|
1677
|
-
const result = await conversation.forceCompact();
|
|
1678
|
-
const responseText = formatCompactResult(result);
|
|
1679
|
-
const assistantMsg = createAssistantMessage(responseText);
|
|
1680
|
-
await addMessage(
|
|
1681
|
-
conversationId,
|
|
1682
|
-
"assistant",
|
|
1683
|
-
JSON.stringify(assistantMsg.content),
|
|
1684
|
-
compactChannelMeta,
|
|
1685
|
-
);
|
|
1686
|
-
conversation.getMessages().push(assistantMsg);
|
|
1687
|
-
return { messageId: persisted.id };
|
|
1688
|
-
}
|
|
1689
|
-
|
|
1690
|
-
const resolvedContent = slashResult.content;
|
|
1691
|
-
|
|
1692
|
-
const requestId = crypto.randomUUID();
|
|
1693
|
-
// Slack inbound metadata captured at the channel ingress boundary is
|
|
1694
|
-
// forwarded into the persistence call so `persistQueuedMessageBody` can
|
|
1695
|
-
// emit a `slackMeta` envelope on the row's metadata column.
|
|
1696
|
-
const persistMetadata = options?.slackInbound
|
|
1697
|
-
? { slackInbound: options.slackInbound }
|
|
1698
|
-
: undefined;
|
|
1699
|
-
const messageId = await conversation.persistUserMessage(
|
|
1700
|
-
resolvedContent,
|
|
1701
|
-
attachments,
|
|
1702
|
-
requestId,
|
|
1703
|
-
persistMetadata,
|
|
1704
|
-
);
|
|
1705
|
-
|
|
1706
|
-
// Register pending interactions so channel approval interception can
|
|
1707
|
-
// find the conversation by requestId when confirmation/secret events fire.
|
|
1708
|
-
const registrar = makePendingInteractionRegistrar(
|
|
1709
|
-
conversation,
|
|
1710
|
-
conversationId,
|
|
1711
|
-
);
|
|
1712
|
-
const onEvent = options?.onEvent
|
|
1713
|
-
? (msg: ServerMessage) => {
|
|
1714
|
-
registrar(msg);
|
|
1715
|
-
try {
|
|
1716
|
-
options.onEvent!(msg);
|
|
1717
|
-
} catch (err) {
|
|
1718
|
-
log.error(
|
|
1719
|
-
{ err, conversationId },
|
|
1720
|
-
"onEvent callback failed; continuing agent loop",
|
|
1721
|
-
);
|
|
1722
|
-
}
|
|
1723
|
-
}
|
|
1724
|
-
: registrar;
|
|
1725
|
-
if (options?.isInteractive === true) {
|
|
1726
|
-
conversation.updateClient(onEvent, false);
|
|
1727
|
-
}
|
|
1728
|
-
|
|
1729
|
-
try {
|
|
1730
|
-
await conversation.runAgentLoop(resolvedContent, messageId, onEvent, {
|
|
1731
|
-
isInteractive: options?.isInteractive ?? false,
|
|
1732
|
-
isUserMessage: true,
|
|
1733
|
-
...(options?.callSite ? { callSite: options.callSite } : {}),
|
|
1734
|
-
});
|
|
1735
|
-
} finally {
|
|
1736
|
-
if (
|
|
1737
|
-
options?.isInteractive === true &&
|
|
1738
|
-
conversation.getCurrentSender() === onEvent
|
|
1739
|
-
) {
|
|
1740
|
-
conversation.updateClient(() => {}, true);
|
|
1741
|
-
}
|
|
1742
|
-
}
|
|
1743
|
-
|
|
1744
|
-
return { messageId };
|
|
1745
|
-
}
|
|
1746
|
-
|
|
1747
819
|
/**
|
|
1748
820
|
* Expose conversation lookup for the POST /v1/messages handler.
|
|
1749
821
|
* The handler manages busy-state checking and queueing itself.
|
|
@@ -1752,44 +824,7 @@ export class DaemonServer {
|
|
|
1752
824
|
conversationId: string,
|
|
1753
825
|
options?: ConversationCreateOptions,
|
|
1754
826
|
): Promise<Conversation> {
|
|
1755
|
-
return
|
|
1756
|
-
}
|
|
1757
|
-
|
|
1758
|
-
/**
|
|
1759
|
-
* Look up an active conversation by ID without creating one.
|
|
1760
|
-
*/
|
|
1761
|
-
findConversation(conversationId: string): Conversation | undefined {
|
|
1762
|
-
return this.conversations.get(conversationId);
|
|
1763
|
-
}
|
|
1764
|
-
|
|
1765
|
-
/**
|
|
1766
|
-
* Look up an active conversation that owns a given surfaceId.
|
|
1767
|
-
*/
|
|
1768
|
-
findConversationBySurfaceId(surfaceId: string): Conversation | undefined {
|
|
1769
|
-
// Fast path: exact surfaceId match in surfaceState
|
|
1770
|
-
for (const c of this.conversations.values()) {
|
|
1771
|
-
if (c.surfaceState.has(surfaceId)) return c;
|
|
1772
|
-
}
|
|
1773
|
-
|
|
1774
|
-
// Fallback: standalone app surfaces use "app-open-{appId}" IDs that
|
|
1775
|
-
// were never part of any conversation. Extract the appId and find
|
|
1776
|
-
// a conversation whose surfaceState has a surface for that app.
|
|
1777
|
-
const appOpenPrefix = "app-open-";
|
|
1778
|
-
if (surfaceId.startsWith(appOpenPrefix)) {
|
|
1779
|
-
const appId = surfaceId.slice(appOpenPrefix.length);
|
|
1780
|
-
for (const c of this.conversations.values()) {
|
|
1781
|
-
for (const [, state] of c.surfaceState.entries()) {
|
|
1782
|
-
const data = state.data as unknown as Record<string, unknown>;
|
|
1783
|
-
if (data?.appId === appId) {
|
|
1784
|
-
// Register this surfaceId so subsequent lookups are O(1)
|
|
1785
|
-
c.surfaceState.set(surfaceId, state);
|
|
1786
|
-
return c;
|
|
1787
|
-
}
|
|
1788
|
-
}
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
|
|
1792
|
-
return undefined;
|
|
827
|
+
return getOrCreateActiveConversation(conversationId, options);
|
|
1793
828
|
}
|
|
1794
829
|
|
|
1795
830
|
/**
|
|
@@ -1809,231 +844,3 @@ function extractConversationId(msg: ServerMessage): string | undefined {
|
|
|
1809
844
|
}
|
|
1810
845
|
return undefined;
|
|
1811
846
|
}
|
|
1812
|
-
|
|
1813
|
-
/**
|
|
1814
|
-
* Translate a raw {@link AgentEvent} from the agent loop into the
|
|
1815
|
-
* corresponding {@link ServerMessage} wire frame. The normal user-turn
|
|
1816
|
-
* path does this via the full state-aware handler in
|
|
1817
|
-
* `conversation-agent-loop-handlers.ts`; the wake path has no tool
|
|
1818
|
-
* accounting, title generation, or activity-state tracking to worry
|
|
1819
|
-
* about, so we only need the subset that produces client-visible
|
|
1820
|
-
* frames. Events that have no client-visible wire shape (usage, error,
|
|
1821
|
-
* preview/input-json deltas, etc.) are dropped — they produce no UI.
|
|
1822
|
-
*
|
|
1823
|
-
* Keeping this translator co-located with the wake adapter preserves
|
|
1824
|
-
* the runtime/daemon layering: `runtime/agent-wake.ts` never imports
|
|
1825
|
-
* `message-protocol.ts` or wire shapes, and the daemon owns all
|
|
1826
|
-
* translation from agent-loop semantics to client frames.
|
|
1827
|
-
*/
|
|
1828
|
-
function translateAgentEventToServerMessage(
|
|
1829
|
-
event: AgentEvent,
|
|
1830
|
-
conversationId: string,
|
|
1831
|
-
): ServerMessage | null {
|
|
1832
|
-
switch (event.type) {
|
|
1833
|
-
case "text_delta":
|
|
1834
|
-
return {
|
|
1835
|
-
type: "assistant_text_delta",
|
|
1836
|
-
text: event.text,
|
|
1837
|
-
conversationId,
|
|
1838
|
-
};
|
|
1839
|
-
case "thinking_delta":
|
|
1840
|
-
return {
|
|
1841
|
-
type: "assistant_thinking_delta",
|
|
1842
|
-
thinking: event.thinking,
|
|
1843
|
-
conversationId,
|
|
1844
|
-
};
|
|
1845
|
-
case "tool_use":
|
|
1846
|
-
return {
|
|
1847
|
-
type: "tool_use_start",
|
|
1848
|
-
toolName: event.name,
|
|
1849
|
-
input: event.input,
|
|
1850
|
-
conversationId,
|
|
1851
|
-
toolUseId: event.id,
|
|
1852
|
-
};
|
|
1853
|
-
case "tool_use_preview_start":
|
|
1854
|
-
return {
|
|
1855
|
-
type: "tool_use_preview_start",
|
|
1856
|
-
toolUseId: event.toolUseId,
|
|
1857
|
-
toolName: event.toolName,
|
|
1858
|
-
conversationId,
|
|
1859
|
-
};
|
|
1860
|
-
case "tool_output_chunk":
|
|
1861
|
-
return {
|
|
1862
|
-
type: "tool_output_chunk",
|
|
1863
|
-
chunk: event.chunk,
|
|
1864
|
-
conversationId,
|
|
1865
|
-
toolUseId: event.toolUseId,
|
|
1866
|
-
};
|
|
1867
|
-
case "tool_result": {
|
|
1868
|
-
const imageBlocks = event.contentBlocks?.filter(
|
|
1869
|
-
(b): b is Extract<typeof b, { type: "image" }> => b.type === "image",
|
|
1870
|
-
);
|
|
1871
|
-
const imageDataList = imageBlocks?.length
|
|
1872
|
-
? imageBlocks.map((b) => b.source.data)
|
|
1873
|
-
: undefined;
|
|
1874
|
-
return {
|
|
1875
|
-
type: "tool_result",
|
|
1876
|
-
toolName: "",
|
|
1877
|
-
result: event.content,
|
|
1878
|
-
isError: event.isError,
|
|
1879
|
-
diff: event.diff,
|
|
1880
|
-
status: event.status,
|
|
1881
|
-
conversationId,
|
|
1882
|
-
imageData: imageDataList?.[0],
|
|
1883
|
-
imageDataList,
|
|
1884
|
-
toolUseId: event.toolUseId,
|
|
1885
|
-
};
|
|
1886
|
-
}
|
|
1887
|
-
case "server_tool_start":
|
|
1888
|
-
return {
|
|
1889
|
-
type: "tool_use_start",
|
|
1890
|
-
toolName: event.name,
|
|
1891
|
-
input: event.input,
|
|
1892
|
-
conversationId,
|
|
1893
|
-
toolUseId: event.toolUseId,
|
|
1894
|
-
};
|
|
1895
|
-
case "server_tool_complete": {
|
|
1896
|
-
let resultText = "";
|
|
1897
|
-
if (Array.isArray(event.content) && event.content.length > 0) {
|
|
1898
|
-
resultText = (event.content as unknown[])
|
|
1899
|
-
.filter(
|
|
1900
|
-
(r): r is { type: string; title: string; url: string } =>
|
|
1901
|
-
typeof r === "object" &&
|
|
1902
|
-
r != null &&
|
|
1903
|
-
(r as { type?: string }).type === "web_search_result",
|
|
1904
|
-
)
|
|
1905
|
-
.map((r) => `${r.title}\n${r.url}`)
|
|
1906
|
-
.join("\n\n");
|
|
1907
|
-
}
|
|
1908
|
-
return {
|
|
1909
|
-
type: "tool_result",
|
|
1910
|
-
toolName: "web_search",
|
|
1911
|
-
result: resultText,
|
|
1912
|
-
isError: event.isError,
|
|
1913
|
-
conversationId,
|
|
1914
|
-
toolUseId: event.toolUseId,
|
|
1915
|
-
};
|
|
1916
|
-
}
|
|
1917
|
-
case "message_complete":
|
|
1918
|
-
return {
|
|
1919
|
-
type: "message_complete",
|
|
1920
|
-
conversationId,
|
|
1921
|
-
};
|
|
1922
|
-
// No wire frame for these — usage/error/input_json_delta are either
|
|
1923
|
-
// server-internal (accounting/classification) or app-only debug
|
|
1924
|
-
// streams the client doesn't surface for wake-originated turns.
|
|
1925
|
-
case "input_json_delta":
|
|
1926
|
-
case "usage":
|
|
1927
|
-
case "error":
|
|
1928
|
-
return null;
|
|
1929
|
-
}
|
|
1930
|
-
}
|
|
1931
|
-
|
|
1932
|
-
/**
|
|
1933
|
-
* Adapt a live {@link Conversation} to the narrow {@link WakeTarget}
|
|
1934
|
-
* surface expected by `wakeAgentForOpportunity()`. Kept here so the
|
|
1935
|
-
* runtime-level wake helper stays decoupled from the heavyweight
|
|
1936
|
-
* conversation class (see `registerDefaultWakeResolver` above).
|
|
1937
|
-
*
|
|
1938
|
-
* Routing notes:
|
|
1939
|
-
* - `emitAgentEvent` dispatches via `broadcastToAllClients` rather
|
|
1940
|
-
* than `sendToClient`. Several signal-injected paths reset
|
|
1941
|
-
* `sendToClient` to a no-op in their `finally` blocks (see the
|
|
1942
|
-
* `updateClient(() => {}, true)` calls in `persistAndProcessMessage`
|
|
1943
|
-
* / `processMessage`), so a wake fired on such a conversation would
|
|
1944
|
-
* find a silent sink. `broadcastToAllClients` is wired to
|
|
1945
|
-
* `this.broadcast(msg)` at construction time and always reaches the
|
|
1946
|
-
* hub, regardless of which sender the most-recent user turn left
|
|
1947
|
-
* behind.
|
|
1948
|
-
* - `persistTailMessage` mirrors the canonical user-turn handlers
|
|
1949
|
-
* (`handleMessageComplete` / the tool-result block in
|
|
1950
|
-
* `conversation-agent-loop-handlers.ts`): builds channel/interface
|
|
1951
|
-
* metadata via `provenanceFromTrustContext` plus the live turn
|
|
1952
|
-
* channel/interface contexts, persists with metadata, and syncs the
|
|
1953
|
-
* resulting row to the disk view so wake-produced messages appear
|
|
1954
|
-
* in the on-disk transcript and carry provenance tags.
|
|
1955
|
-
* - `drainQueue` delegates to the conversation so any user messages
|
|
1956
|
-
* queued while the wake was running are processed. The wake helper
|
|
1957
|
-
* calls this in its finally AFTER `markProcessing(false)`; the
|
|
1958
|
-
* order matters because `enqueueMessage` only queues when
|
|
1959
|
-
* `processing === true`.
|
|
1960
|
-
*/
|
|
1961
|
-
function conversationToWakeTarget(conversation: Conversation): WakeTarget {
|
|
1962
|
-
return {
|
|
1963
|
-
conversationId: conversation.conversationId,
|
|
1964
|
-
agentLoop: conversation.agentLoop,
|
|
1965
|
-
getMessages: () => conversation.getMessages(),
|
|
1966
|
-
pushMessage: (msg) => {
|
|
1967
|
-
conversation.messages.push(msg);
|
|
1968
|
-
},
|
|
1969
|
-
emitAgentEvent: (event) => {
|
|
1970
|
-
const frame = translateAgentEventToServerMessage(
|
|
1971
|
-
event,
|
|
1972
|
-
conversation.conversationId,
|
|
1973
|
-
);
|
|
1974
|
-
if (!frame) return;
|
|
1975
|
-
// Prefer `broadcastToAllClients` (wired to the hub at construction
|
|
1976
|
-
// time and always live) over `sendToClient` (which several
|
|
1977
|
-
// signal-injected paths reset to `() => {}` in their finally
|
|
1978
|
-
// blocks). Fall back to `sendToClient` when the broadcaster is
|
|
1979
|
-
// missing (e.g. in tests that construct a Conversation directly).
|
|
1980
|
-
if (conversation.broadcastToAllClients) {
|
|
1981
|
-
conversation.broadcastToAllClients(frame);
|
|
1982
|
-
} else {
|
|
1983
|
-
conversation.sendToClient(frame);
|
|
1984
|
-
}
|
|
1985
|
-
},
|
|
1986
|
-
isProcessing: () => conversation.isProcessing(),
|
|
1987
|
-
markProcessing: (on) => {
|
|
1988
|
-
conversation.processing = on;
|
|
1989
|
-
},
|
|
1990
|
-
persistTailMessage: async (message) => {
|
|
1991
|
-
// Build metadata that mirrors the canonical handlers in
|
|
1992
|
-
// `conversation-agent-loop-handlers.ts`. If the live turn channel
|
|
1993
|
-
// / interface contexts are missing (a wake can fire on a
|
|
1994
|
-
// conversation that has never run a user turn), fall back to the
|
|
1995
|
-
// conversation's origin channel/interface defaults (`"vellum"`)
|
|
1996
|
-
// so persisted rows still carry valid channel/interface ids.
|
|
1997
|
-
const turnChannelCtx = conversation.getTurnChannelContext();
|
|
1998
|
-
const turnInterfaceCtx = conversation.getTurnInterfaceContext();
|
|
1999
|
-
const metadata: Record<string, unknown> = {
|
|
2000
|
-
...provenanceFromTrustContext(conversation.trustContext),
|
|
2001
|
-
userMessageChannel: turnChannelCtx?.userMessageChannel ?? "vellum",
|
|
2002
|
-
assistantMessageChannel:
|
|
2003
|
-
turnChannelCtx?.assistantMessageChannel ?? "vellum",
|
|
2004
|
-
userMessageInterface:
|
|
2005
|
-
turnInterfaceCtx?.userMessageInterface ?? "vellum",
|
|
2006
|
-
assistantMessageInterface:
|
|
2007
|
-
turnInterfaceCtx?.assistantMessageInterface ?? "vellum",
|
|
2008
|
-
};
|
|
2009
|
-
const persisted = await addMessage(
|
|
2010
|
-
conversation.conversationId,
|
|
2011
|
-
message.role,
|
|
2012
|
-
JSON.stringify(message.content),
|
|
2013
|
-
metadata,
|
|
2014
|
-
);
|
|
2015
|
-
// Sync the persisted row to the disk view so wake-produced
|
|
2016
|
-
// messages appear in the on-disk transcript and tools that read
|
|
2017
|
-
// from disk (e.g. `messages.jsonl`-based diagnostics) see them.
|
|
2018
|
-
// Mirrors the `syncMessageToDisk(...)` calls in the canonical
|
|
2019
|
-
// handlers — best-effort because a sync failure must not strand
|
|
2020
|
-
// the in-memory tail.
|
|
2021
|
-
try {
|
|
2022
|
-
const convRow = getConversation(conversation.conversationId);
|
|
2023
|
-
if (convRow) {
|
|
2024
|
-
syncMessageToDisk(
|
|
2025
|
-
conversation.conversationId,
|
|
2026
|
-
persisted.id,
|
|
2027
|
-
convRow.createdAt,
|
|
2028
|
-
);
|
|
2029
|
-
}
|
|
2030
|
-
} catch (err) {
|
|
2031
|
-
log.warn(
|
|
2032
|
-
{ err, conversationId: conversation.conversationId },
|
|
2033
|
-
"wake adapter: syncMessageToDisk failed (non-fatal)",
|
|
2034
|
-
);
|
|
2035
|
-
}
|
|
2036
|
-
},
|
|
2037
|
-
drainQueue: () => conversation.drainQueue(),
|
|
2038
|
-
};
|
|
2039
|
-
}
|