@vellumai/assistant 0.4.41 → 0.4.43
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/.env.example +1 -6
- package/.prettierignore +3 -0
- package/ARCHITECTURE.md +131 -393
- package/Dockerfile +0 -1
- package/README.md +73 -83
- package/bun.lock +8 -2
- package/docs/architecture/integrations.md +16 -21
- package/docs/architecture/memory.md +1 -1
- package/docs/architecture/scheduling.md +63 -63
- package/docs/architecture/security.md +3 -3
- package/docs/runbook-trusted-contacts.md +11 -12
- package/docs/trusted-contact-access.md +39 -39
- package/package.json +5 -8
- package/src/__tests__/access-request-decision.test.ts +4 -4
- package/src/__tests__/active-skill-tools.test.ts +49 -34
- package/src/__tests__/actor-token-service.test.ts +55 -85
- package/src/__tests__/amazon-cdp-integration.test.ts +14 -26
- package/src/__tests__/app-bundler.test.ts +14 -368
- package/src/__tests__/app-compiler.test.ts +0 -1
- package/src/__tests__/app-executors.test.ts +10 -1
- package/src/__tests__/approval-hardcoded-copy-guard.test.ts +1 -1
- package/src/__tests__/approval-primitive.test.ts +2 -4
- package/src/__tests__/approval-routes-http.test.ts +1 -1
- package/src/__tests__/asset-materialize-tool.test.ts +1 -4
- package/src/__tests__/asset-search-tool.test.ts +1 -4
- package/src/__tests__/assistant-attachments.test.ts +23 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +4 -8
- package/src/__tests__/assistant-id-boundary-guard.test.ts +5 -5
- package/src/__tests__/attachments-store.test.ts +1 -4
- package/src/__tests__/avatar-e2e.test.ts +43 -23
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +2 -9
- package/src/__tests__/call-controller.test.ts +4 -8
- package/src/__tests__/call-conversation-messages.test.ts +1 -1
- package/src/__tests__/call-domain.test.ts +250 -8
- package/src/__tests__/call-pointer-message-composer.test.ts +14 -14
- package/src/__tests__/call-pointer-messages.test.ts +7 -11
- package/src/__tests__/call-recovery.test.ts +47 -0
- package/src/__tests__/call-routes-http.test.ts +13 -0
- package/src/__tests__/call-start-guardian-guard.test.ts +1 -1
- package/src/__tests__/callback-handoff-copy.test.ts +5 -5
- package/src/__tests__/canonical-guardian-store.test.ts +3 -3
- package/src/__tests__/channel-approval-routes.test.ts +101 -134
- package/src/__tests__/channel-approval.test.ts +0 -201
- package/src/__tests__/channel-approvals.test.ts +2 -2
- package/src/__tests__/channel-delivery-store.test.ts +16 -24
- package/src/__tests__/channel-guardian.test.ts +641 -740
- package/src/__tests__/channel-invite-transport.test.ts +1 -2
- package/src/__tests__/channel-policy.test.ts +9 -12
- package/src/__tests__/channel-readiness-service.test.ts +156 -45
- package/src/__tests__/channel-reply-delivery.test.ts +3 -3
- package/src/__tests__/channel-retry-sweep.test.ts +7 -7
- package/src/__tests__/checker.test.ts +10 -7
- package/src/__tests__/chrome-cdp.test.ts +57 -17
- package/src/__tests__/cli-help-reference-sync.test.ts +26 -0
- package/src/__tests__/compaction.benchmark.test.ts +25 -5
- package/src/__tests__/computer-use-session-lifecycle.test.ts +1 -1
- package/src/__tests__/computer-use-session-working-dir.test.ts +2 -6
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +1 -1
- package/src/__tests__/config-loader-backfill.test.ts +310 -0
- package/src/__tests__/config-watcher.test.ts +1 -5
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +3 -5
- package/src/__tests__/connection-policy.test.ts +3 -62
- package/src/__tests__/contacts-tools.test.ts +0 -2
- package/src/__tests__/context-memory-e2e.test.ts +11 -7
- package/src/__tests__/context-overflow-policy.test.ts +2 -2
- package/src/__tests__/context-window-manager.test.ts +220 -61
- package/src/__tests__/conversation-attention-store.test.ts +178 -2
- package/src/__tests__/conversation-attention-telegram.test.ts +8 -11
- package/src/__tests__/conversation-pairing.test.ts +14 -14
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +1 -1
- package/src/__tests__/conversation-store.test.ts +2 -2
- package/src/__tests__/conversation-unread-route.test.ts +155 -0
- package/src/__tests__/credential-metadata-store.test.ts +0 -2
- package/src/__tests__/credential-security-invariants.test.ts +9 -16
- package/src/__tests__/credentials-cli.test.ts +49 -5
- package/src/__tests__/daemon-assistant-events.test.ts +4 -22
- package/src/__tests__/db-migration-rollback.test.ts +2 -2
- package/src/__tests__/deterministic-verification-control-plane.test.ts +19 -19
- package/src/__tests__/dictation-mode-detection.test.ts +1 -1
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +2 -6
- package/src/__tests__/email-cli.test.ts +12 -12
- package/src/__tests__/email-service-config-fallback.test.ts +1 -1
- package/src/__tests__/emit-signal-routing-intent.test.ts +3 -18
- package/src/__tests__/event-bus.test.ts +0 -1
- package/src/__tests__/followup-tools.test.ts +0 -2
- package/src/__tests__/gateway-client-managed-outbound.test.ts +6 -6
- package/src/__tests__/gateway-only-enforcement.test.ts +13 -77
- package/src/__tests__/gateway-only-guard.test.ts +5 -0
- package/src/__tests__/guardian-action-conversation-turn.test.ts +3 -3
- package/src/__tests__/guardian-action-followup-executor.test.ts +29 -94
- package/src/__tests__/guardian-action-followup-store.test.ts +2 -12
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +48 -194
- package/src/__tests__/guardian-action-late-reply.test.ts +12 -12
- package/src/__tests__/guardian-action-store.test.ts +2 -2
- package/src/__tests__/guardian-action-sweep.test.ts +5 -5
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +1 -3
- package/src/__tests__/guardian-dispatch.test.ts +5 -46
- package/src/__tests__/guardian-grant-minting.test.ts +5 -44
- package/src/__tests__/guardian-outbound-http.test.ts +95 -114
- package/src/__tests__/guardian-question-mode.test.ts +1 -4
- package/src/__tests__/guardian-routing-invariants.test.ts +5 -13
- package/src/__tests__/guardian-routing-state.test.ts +3 -3
- package/src/__tests__/guardian-verification-voice-binding.test.ts +64 -7
- package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +2 -2
- package/src/__tests__/handle-user-message-secret-resume.test.ts +3 -5
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +16 -34
- package/src/__tests__/headless-browser-interactions.test.ts +1 -1
- package/src/__tests__/headless-browser-navigate.test.ts +1 -1
- package/src/__tests__/headless-browser-read-tools.test.ts +1 -1
- package/src/__tests__/headless-browser-snapshot.test.ts +1 -1
- package/src/__tests__/heartbeat-service.test.ts +1 -1
- package/src/__tests__/home-base-bootstrap.test.ts +0 -2
- package/src/__tests__/host-shell-tool.test.ts +3 -12
- package/src/__tests__/inbound-invite-redemption.test.ts +2 -2
- package/src/__tests__/ingress-url-consistency.test.ts +0 -64
- package/src/__tests__/integration-status.test.ts +8 -8
- package/src/__tests__/intent-routing.test.ts +9 -13
- package/src/__tests__/invite-redemption-service.test.ts +4 -4
- package/src/__tests__/invite-routes-http.test.ts +10 -10
- package/src/__tests__/llm-usage-store.test.ts +45 -9
- package/src/__tests__/local-gateway-health.test.ts +209 -0
- package/src/__tests__/managed-avatar-client.test.ts +23 -12
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -2
- package/src/__tests__/managed-store.test.ts +29 -12
- package/src/__tests__/managed-twitter-guardrails.test.ts +353 -0
- package/src/__tests__/mcp-cli.test.ts +1 -1
- package/src/__tests__/mcp-health-check.test.ts +1 -1
- package/src/__tests__/media-generate-image.test.ts +1 -1
- package/src/__tests__/media-reuse-story.e2e.test.ts +1 -4
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +9 -6
- package/src/__tests__/memory-regressions.test.ts +1 -166
- package/src/__tests__/messaging-send-tool.test.ts +8 -4
- package/src/__tests__/migration-export-http.test.ts +2 -2
- package/src/__tests__/migration-transport.test.ts +44 -0
- package/src/__tests__/non-member-access-request.test.ts +49 -36
- package/src/__tests__/notification-broadcaster.test.ts +15 -15
- package/src/__tests__/notification-decision-fallback.test.ts +2 -2
- package/src/__tests__/notification-decision-strategy.test.ts +4 -4
- package/src/__tests__/notification-deep-link.test.ts +3 -3
- package/src/__tests__/notification-guardian-path.test.ts +6 -44
- package/src/__tests__/notification-routing-intent.test.ts +11 -7
- package/src/__tests__/oauth-cli.test.ts +1 -1
- package/src/__tests__/onboarding-starter-tasks.test.ts +2 -6
- package/src/__tests__/onboarding-template-contract.test.ts +2 -2
- package/src/__tests__/platform.test.ts +168 -5
- package/src/__tests__/playbook-execution.test.ts +0 -2
- package/src/__tests__/playbook-tools.test.ts +0 -2
- package/src/__tests__/pricing.test.ts +125 -0
- package/src/__tests__/provider-error-scenarios.test.ts +9 -3
- package/src/__tests__/recording-handler.test.ts +46 -80
- package/src/__tests__/recording-state-machine.test.ts +112 -183
- package/src/__tests__/registry.test.ts +1 -1
- package/src/__tests__/relay-server.test.ts +69 -71
- package/src/__tests__/reminder-store.test.ts +3 -3
- package/src/__tests__/request-file-tool.test.ts +2 -2
- package/src/__tests__/ride-shotgun-handler.test.ts +2 -33
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -3
- package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +4 -4
- package/src/__tests__/schedule-store.test.ts +13 -4
- package/src/__tests__/schedule-tools.test.ts +0 -2
- package/src/__tests__/scheduler-recurrence.test.ts +3 -4
- package/src/__tests__/scoped-approval-grants.test.ts +3 -5
- package/src/__tests__/scoped-grant-security-matrix.test.ts +6 -8
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +1 -1
- package/src/__tests__/secret-response-routing.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +1 -1
- package/src/__tests__/sequence-store.test.ts +0 -2
- package/src/__tests__/server-history-render.test.ts +2 -199
- package/src/__tests__/session-abort-tool-results.test.ts +9 -3
- package/src/__tests__/session-agent-loop.test.ts +107 -3
- package/src/__tests__/session-confirmation-signals.test.ts +10 -4
- package/src/__tests__/session-conflict-gate.test.ts +9 -3
- package/src/__tests__/session-init.benchmark.test.ts +22 -13
- package/src/__tests__/session-load-history-repair.test.ts +6 -3
- package/src/__tests__/session-pre-run-repair.test.ts +9 -3
- package/src/__tests__/session-profile-injection.test.ts +9 -3
- package/src/__tests__/session-provider-retry-repair.test.ts +10 -4
- package/src/__tests__/session-queue.test.ts +10 -4
- package/src/__tests__/session-runtime-assembly.test.ts +28 -18
- package/src/__tests__/session-skill-tools.test.ts +2 -3
- package/src/__tests__/session-slash-known.test.ts +11 -4
- package/src/__tests__/session-slash-queue.test.ts +11 -4
- package/src/__tests__/session-slash-unknown.test.ts +12 -4
- package/src/__tests__/session-surfaces-deselection.test.ts +2 -2
- package/src/__tests__/session-surfaces-task-progress.test.ts +3 -3
- package/src/__tests__/session-tool-setup-app-refresh.test.ts +1 -1
- package/src/__tests__/session-tool-setup-memory-scope.test.ts +1 -1
- package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +1 -1
- package/src/__tests__/session-usage.test.ts +180 -0
- package/src/__tests__/session-workspace-cache-state.test.ts +8 -2
- package/src/__tests__/session-workspace-injection.test.ts +8 -2
- package/src/__tests__/session-workspace-tool-tracking.test.ts +8 -2
- package/src/__tests__/skill-feature-flags-integration.test.ts +5 -11
- package/src/__tests__/skill-feature-flags.test.ts +1 -0
- package/src/__tests__/skill-include-graph.test.ts +1 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +3 -9
- package/src/__tests__/skill-load-tool.test.ts +90 -12
- package/src/__tests__/skill-projection-feature-flag.test.ts +14 -15
- package/src/__tests__/skills-uninstall.test.ts +131 -0
- package/src/__tests__/skills.test.ts +32 -16
- package/src/__tests__/slack-block-formatting.test.ts +1 -1
- package/src/__tests__/slack-channel-config.test.ts +71 -12
- package/src/__tests__/slack-inbound-verification.test.ts +7 -7
- package/src/__tests__/slack-share-routes.test.ts +1 -1
- package/src/__tests__/slack-skill.test.ts +2 -2
- package/src/__tests__/slash-commands-catalog.test.ts +1 -0
- package/src/__tests__/slash-commands-resolver.test.ts +1 -0
- package/src/__tests__/starter-task-flow.test.ts +1 -1
- package/src/__tests__/subagent-manager-notify.test.ts +1 -1
- package/src/__tests__/subagent-tools.test.ts +2 -2
- package/src/__tests__/system-prompt.test.ts +4 -8
- package/src/__tests__/task-compiler.test.ts +0 -2
- package/src/__tests__/task-management-tools.test.ts +0 -2
- package/src/__tests__/task-runner.test.ts +0 -2
- package/src/__tests__/task-scheduler.test.ts +2 -2
- package/src/__tests__/telegram-bot-username-resolution.test.ts +46 -44
- package/src/__tests__/terminal-tools.test.ts +1 -11
- package/src/__tests__/thread-seed-composer.test.ts +3 -1
- package/src/__tests__/tool-approval-handler.test.ts +5 -7
- package/src/__tests__/tool-executor.test.ts +2 -2
- package/src/__tests__/tool-grant-request-escalation.test.ts +3 -5
- package/src/__tests__/tool-notification-listener.test.ts +1 -1
- package/src/__tests__/tool-profiling-listener.test.ts +1 -1
- package/src/__tests__/tool-trace-listener.test.ts +1 -2
- package/src/__tests__/trace-emitter.test.ts +1 -1
- package/src/__tests__/trust-context-guards.test.ts +1 -1
- package/src/__tests__/trust-store.test.ts +44 -395
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +6 -8
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +5 -7
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +6 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +54 -47
- package/src/__tests__/trusted-contact-verification.test.ts +12 -12
- package/src/__tests__/twilio-config.test.ts +11 -2
- package/src/__tests__/twilio-provider.test.ts +6 -4
- package/src/__tests__/twilio-routes.test.ts +408 -86
- package/src/__tests__/twitter-platform-proxy-client.test.ts +450 -0
- package/src/__tests__/update-bulletin-format.test.ts +1 -1
- package/src/__tests__/update-bulletin-state.test.ts +1 -1
- package/src/__tests__/update-bulletin.test.ts +4 -8
- package/src/__tests__/update-template-contract.test.ts +1 -1
- package/src/__tests__/usage-cache-backfill-migration.test.ts +406 -0
- package/src/__tests__/usage-routes.test.ts +23 -5
- package/src/__tests__/user-reference.test.ts +1 -1
- package/src/__tests__/{guardian-control-plane-policy.test.ts → verification-control-plane-policy.test.ts} +142 -170
- package/src/__tests__/{guardian-verification-intent-routing.test.ts → verification-session-intent-routing.test.ts} +16 -16
- package/src/__tests__/view-image-tool.test.ts +0 -2
- package/src/__tests__/voice-ingress-preflight.test.ts +36 -0
- package/src/__tests__/voice-invite-redemption.test.ts +18 -18
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +7 -7
- package/src/__tests__/voice-session-bridge.test.ts +14 -16
- package/src/__tests__/workspace-policy.test.ts +1 -1
- package/src/approvals/AGENTS.md +4 -4
- package/src/approvals/approval-primitive.ts +2 -2
- package/src/approvals/guardian-decision-primitive.ts +1 -1
- package/src/approvals/guardian-request-resolvers.ts +3 -4
- package/src/bundler/app-bundler.ts +29 -217
- package/src/bundler/app-compiler.ts +131 -103
- package/src/bundler/compiler-tools.ts +248 -0
- package/src/calls/active-call-lease.ts +207 -0
- package/src/calls/call-constants.ts +0 -7
- package/src/calls/call-controller.ts +1 -1
- package/src/calls/call-conversation-messages.ts +6 -6
- package/src/calls/call-domain.ts +73 -38
- package/src/calls/call-pointer-message-composer.ts +6 -6
- package/src/calls/call-pointer-messages.ts +14 -13
- package/src/calls/call-recovery.ts +2 -0
- package/src/calls/call-store.ts +21 -28
- package/src/calls/guardian-action-sweep.ts +6 -8
- package/src/calls/guardian-dispatch.ts +2 -6
- package/src/calls/relay-access-wait.ts +4 -4
- package/src/calls/relay-server.ts +69 -80
- package/src/calls/relay-setup-router.ts +16 -21
- package/src/calls/relay-verification.ts +27 -28
- package/src/calls/twilio-config.ts +28 -3
- package/src/calls/twilio-provider.ts +5 -5
- package/src/calls/twilio-rest.ts +26 -27
- package/src/calls/twilio-routes.ts +67 -54
- package/src/calls/types.ts +8 -8
- package/src/calls/voice-ingress-preflight.ts +110 -0
- package/src/calls/voice-session-bridge.ts +7 -7
- package/src/channels/config.ts +1 -10
- package/src/{config/channel-permission-profiles.ts → channels/permission-profiles.ts} +1 -1
- package/src/channels/types.ts +2 -13
- package/src/cli/__tests__/notifications.test.ts +1 -1
- package/src/{amazon → cli/commands/amazon}/client.ts +99 -42
- package/src/cli/{amazon.ts → commands/amazon/index.ts} +12 -17
- package/src/{amazon → cli/commands/amazon}/request-extractor.ts +39 -3
- package/src/cli/commands/amazon/session.ts +116 -0
- package/src/cli/{audit.ts → commands/audit.ts} +2 -4
- package/src/cli/{autonomy.ts → commands/autonomy.ts} +1 -3
- package/src/cli/commands/browser-relay.ts +520 -0
- package/src/cli/commands/channel-verification-sessions.ts +442 -0
- package/src/cli/{completions.ts → commands/completions.ts} +1 -3
- package/src/cli/{config.ts → commands/config.ts} +3 -5
- package/src/cli/{contacts.ts → commands/contacts.ts} +263 -16
- package/src/cli/{credentials.ts → commands/credentials.ts} +9 -10
- package/src/cli/{default-action.ts → commands/default-action.ts} +3 -3
- package/src/cli/{dev.ts → commands/dev.ts} +4 -6
- package/src/cli/{doctor.ts → commands/doctor.ts} +36 -60
- package/src/cli/{email.ts → commands/email.ts} +2 -2
- package/src/cli/{keys.ts → commands/keys.ts} +6 -6
- package/src/cli/{map.ts → commands/map.ts} +85 -93
- package/src/cli/{mcp.ts → commands/mcp.ts} +5 -7
- package/src/cli/{memory.ts → commands/memory.ts} +6 -7
- package/src/cli/{notifications.ts → commands/notifications.ts} +8 -10
- package/src/cli/{oauth.ts → commands/oauth.ts} +2 -2
- package/src/cli/commands/platform.ts +176 -0
- package/src/cli/{sequence.ts → commands/sequence.ts} +3 -3
- package/src/cli/{sessions.ts → commands/sessions.ts} +32 -52
- package/src/cli/commands/skills.ts +498 -0
- package/src/cli/{trust.ts → commands/trust.ts} +2 -4
- package/src/{__tests__/twitter-cli-error-shaping.test.ts → cli/commands/twitter/__tests__/cli-error-shaping.test.ts} +43 -2
- package/src/cli/commands/twitter/__tests__/cli-read-routing.test.ts +483 -0
- package/src/{__tests__/twitter-cli-routing.test.ts → cli/commands/twitter/__tests__/cli-routing.test.ts} +130 -4
- package/src/{__tests__/twitter-oauth-client.test.ts → cli/commands/twitter/__tests__/oauth-client.test.ts} +2 -2
- package/src/{twitter → cli/commands/twitter}/client.ts +17 -7
- package/src/cli/{twitter.ts → commands/twitter/index.ts} +322 -273
- package/src/cli/commands/twitter/router.ts +396 -0
- package/src/cli/commands/twitter/session.ts +121 -0
- package/src/cli/db.ts +1 -0
- package/src/cli/http-client.ts +87 -0
- package/src/cli/logger.ts +6 -0
- package/src/cli/main-screen.tsx +4 -3
- package/src/cli/output.ts +19 -0
- package/src/cli/program.ts +29 -27
- package/src/cli/reference.ts +27 -37
- package/src/cli.ts +452 -240
- package/src/config/assistant-feature-flags.ts +3 -15
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +3 -6
- package/src/config/bundled-skills/agentmail/SKILL.md +4 -4
- package/src/config/bundled-skills/amazon/SKILL.md +15 -5
- package/src/config/bundled-skills/api-mapping/SKILL.md +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +21 -6
- package/src/config/bundled-skills/browser/SKILL.md +4 -5
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +4 -4
- package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +1 -1
- package/src/config/bundled-skills/claude-code/SKILL.md +4 -4
- package/src/config/bundled-skills/cli-discover/SKILL.md +4 -4
- package/src/config/bundled-skills/computer-use/SKILL.md +4 -4
- package/src/config/bundled-skills/contacts/SKILL.md +87 -229
- package/src/config/bundled-skills/deploy-fullstack-vercel/SKILL.md +4 -4
- package/src/config/bundled-skills/document/SKILL.md +4 -3
- package/src/config/bundled-skills/document-writer/SKILL.md +4 -4
- package/src/config/bundled-skills/doordash/SKILL.md +4 -11
- package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +8 -16
- package/src/config/bundled-skills/doordash/doordash-cli.ts +120 -86
- package/src/config/bundled-skills/doordash/lib/session.ts +1 -2
- package/src/config/bundled-skills/doordash/lib/shared/platform.ts +26 -9
- package/src/config/bundled-skills/elevenlabs-voice/SKILL.md +140 -0
- package/src/config/bundled-skills/email-setup/SKILL.md +4 -4
- package/src/config/bundled-skills/followups/SKILL.md +4 -3
- package/src/config/bundled-skills/frontend-design/SKILL.md +2 -0
- package/src/config/bundled-skills/google-calendar/SKILL.md +4 -4
- package/src/config/bundled-skills/google-oauth-setup/SKILL.md +4 -6
- package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +26 -41
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -5
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +1 -1
- package/src/config/bundled-skills/influencer/SKILL.md +19 -19
- package/src/{influencer → config/bundled-skills/influencer/scripts}/client.ts +73 -56
- package/src/config/bundled-skills/influencer/scripts/influencer.ts +267 -0
- package/src/config/bundled-skills/knowledge-graph/SKILL.md +4 -2
- package/src/config/bundled-skills/macos-automation/SKILL.md +4 -5
- package/src/config/bundled-skills/mcp-setup/SKILL.md +4 -4
- package/src/config/bundled-skills/media-processing/SKILL.md +3 -2
- package/src/config/bundled-skills/messaging/SKILL.md +6 -33
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -5
- package/src/config/bundled-skills/notifications/SKILL.md +4 -4
- package/src/config/bundled-skills/notion/SKILL.md +4 -4
- package/src/config/bundled-skills/notion-oauth-setup/SKILL.md +4 -5
- package/src/config/bundled-skills/oauth-setup/SKILL.md +4 -5
- package/src/config/bundled-skills/phone-calls/SKILL.md +24 -458
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +83 -0
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +57 -0
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +67 -0
- package/src/config/bundled-skills/playbooks/SKILL.md +4 -3
- package/src/config/bundled-skills/public-ingress/SKILL.md +65 -14
- package/src/config/bundled-skills/reminder/SKILL.md +4 -3
- package/src/config/bundled-skills/restaurant-reservation/SKILL.md +4 -6
- package/src/config/bundled-skills/schedule/SKILL.md +4 -3
- package/src/config/bundled-skills/screen-recording/SKILL.md +4 -3
- package/src/config/bundled-skills/self-upgrade/SKILL.md +4 -4
- package/src/config/bundled-skills/skills-catalog/SKILL.md +4 -4
- package/src/config/bundled-skills/slack/SKILL.md +4 -8
- package/src/config/bundled-skills/slack/tools/slack-channel-permissions.ts +1 -1
- package/src/config/bundled-skills/slack-app-setup/SKILL.md +66 -88
- package/src/config/bundled-skills/slack-digest-setup/SKILL.md +4 -5
- package/src/config/bundled-skills/slack-oauth-setup/SKILL.md +4 -5
- package/src/config/bundled-skills/start-the-day/SKILL.md +4 -4
- package/src/config/bundled-skills/subagent/SKILL.md +4 -3
- package/src/config/bundled-skills/tasks/SKILL.md +4 -3
- package/src/config/bundled-skills/telegram-setup/SKILL.md +63 -112
- package/src/config/bundled-skills/time-based-actions/SKILL.md +4 -3
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -3
- package/src/config/bundled-skills/twilio-setup/SKILL.md +23 -50
- package/src/config/bundled-skills/twitter/SKILL.md +56 -14
- package/src/config/bundled-skills/typescript-eval/SKILL.md +4 -4
- package/src/config/bundled-skills/vercel-token-setup/SKILL.md +4 -5
- package/src/config/bundled-skills/voice-setup/SKILL.md +19 -45
- package/src/config/bundled-skills/watcher/SKILL.md +4 -3
- package/src/config/env-registry.ts +1 -10
- package/src/config/feature-flag-registry.json +0 -16
- package/src/config/loader.ts +78 -38
- package/src/config/schema.ts +143 -106
- package/src/config/schemas/channels.ts +80 -0
- package/src/config/schemas/heartbeat.ts +51 -0
- package/src/config/schemas/inference.ts +136 -0
- package/src/config/schemas/ingress.ts +81 -0
- package/src/config/schemas/logging.ts +21 -0
- package/src/config/schemas/memory-lifecycle.ts +67 -0
- package/src/config/schemas/memory-processing.ts +215 -0
- package/src/config/schemas/memory-retrieval.ts +222 -0
- package/src/config/schemas/memory-storage.ts +83 -0
- package/src/config/schemas/memory.ts +58 -0
- package/src/config/schemas/platform.ts +64 -0
- package/src/config/schemas/security.ts +54 -0
- package/src/config/schemas/swarm.ts +50 -0
- package/src/config/schemas/timeouts.ts +47 -0
- package/src/config/{agent-schema.ts → schemas/workspace-git.ts} +0 -97
- package/src/config/skill-state.ts +3 -13
- package/src/config/skills.ts +233 -75
- package/src/config/types.ts +1 -20
- package/src/contacts/contact-store.ts +12 -49
- package/src/contacts/contacts-write.ts +1 -5
- package/src/contacts/index.ts +0 -2
- package/src/contacts/types.ts +0 -8
- package/src/context/window-manager.ts +73 -14
- package/src/daemon/assistant-attachments.ts +9 -0
- package/src/daemon/computer-use-session.ts +3 -3
- package/src/daemon/connection-policy.ts +6 -21
- package/src/daemon/context-overflow-policy.ts +1 -1
- package/src/daemon/daemon-control.ts +46 -54
- package/src/daemon/doordash-steps.ts +1 -1
- package/src/daemon/handlers/config-channels.ts +407 -71
- package/src/daemon/handlers/config-ingress.ts +17 -85
- package/src/daemon/handlers/config-model.ts +145 -123
- package/src/daemon/handlers/config-slack-channel.ts +43 -29
- package/src/daemon/handlers/config-telegram.ts +32 -27
- package/src/daemon/handlers/config-voice.ts +1 -4
- package/src/daemon/handlers/dictation.ts +11 -16
- package/src/daemon/handlers/identity.ts +5 -6
- package/src/daemon/handlers/pairing.ts +5 -13
- package/src/daemon/handlers/recording.ts +97 -199
- package/src/daemon/handlers/session-history.ts +110 -96
- package/src/daemon/handlers/session-user-message.ts +29 -57
- package/src/daemon/handlers/sessions.ts +240 -137
- package/src/daemon/handlers/shared.ts +62 -95
- package/src/daemon/handlers/skills.ts +492 -543
- package/src/daemon/lifecycle.ts +168 -55
- package/src/daemon/main.ts +1 -0
- package/src/daemon/{ipc-contract.ts → message-protocol.ts} +49 -49
- package/src/daemon/{ipc-contract → message-types}/computer-use.ts +0 -3
- package/src/daemon/{ipc-contract → message-types}/diagnostics.ts +0 -16
- package/src/daemon/{ipc-contract → message-types}/integrations.ts +29 -13
- package/src/daemon/{ipc-contract → message-types}/memory.ts +8 -0
- package/src/daemon/{ipc-contract → message-types}/notifications.ts +15 -1
- package/src/daemon/{ipc-contract → message-types}/sessions.ts +1 -0
- package/src/daemon/{ipc-contract → message-types}/shared.ts +0 -8
- package/src/daemon/{ipc-contract → message-types}/workspace.ts +2 -2
- package/src/daemon/providers-setup.ts +0 -5
- package/src/daemon/recording-executor.ts +0 -7
- package/src/daemon/ride-shotgun-handler.ts +9 -13
- package/src/daemon/server.ts +136 -510
- package/src/daemon/session-agent-loop-handlers.ts +22 -7
- package/src/daemon/session-agent-loop.ts +86 -24
- package/src/daemon/session-attachments.ts +1 -1
- package/src/daemon/session-error.ts +1 -1
- package/src/daemon/session-history.ts +20 -15
- package/src/daemon/session-lifecycle.ts +9 -7
- package/src/daemon/session-memory.ts +15 -1
- package/src/daemon/session-messaging.ts +10 -6
- package/src/daemon/session-notifiers.ts +10 -8
- package/src/daemon/session-process.ts +34 -25
- package/src/daemon/session-queue-manager.ts +1 -1
- package/src/daemon/session-runtime-assembly.ts +6 -25
- package/src/daemon/session-surfaces.ts +2 -2
- package/src/daemon/session-tool-setup.ts +1 -1
- package/src/daemon/session-usage.ts +119 -18
- package/src/daemon/session.ts +13 -9
- package/src/daemon/tool-side-effects.ts +6 -5
- package/src/daemon/trace-emitter.ts +1 -1
- package/src/daemon/{guardian-verification-intent.ts → verification-session-intent.ts} +16 -16
- package/src/daemon/watch-handler.ts +2 -5
- package/src/email/service.ts +8 -8
- package/src/events/domain-events.ts +0 -1
- package/src/events/tool-notification-listener.ts +1 -1
- package/src/followups/followup-store.ts +1 -2
- package/src/followups/types.ts +0 -6
- package/src/heartbeat/heartbeat-service.ts +1 -1
- package/src/inbound/platform-callback-registration.ts +1 -1
- package/src/inbound/public-ingress-urls.ts +0 -8
- package/src/index.ts +12 -0
- package/src/mcp/client.ts +1 -1
- package/src/mcp/manager.ts +1 -1
- package/src/memory/app-store.ts +1 -42
- package/src/memory/{guardian-verification.ts → channel-verification-sessions.ts} +110 -93
- package/src/memory/conversation-attention-store.ts +154 -0
- package/src/memory/conversation-bootstrap.ts +1 -1
- package/src/memory/conversation-crud.ts +53 -1
- package/src/memory/conversation-display-order-migration.ts +2 -3
- package/src/memory/conversation-queries.ts +1 -29
- package/src/memory/conversation-title-service.ts +26 -21
- package/src/memory/db-connection.ts +1 -8
- package/src/memory/db-init.ts +20 -0
- package/src/memory/delivery-crud.ts +4 -34
- package/src/memory/external-conversation-store.ts +1 -1
- package/src/memory/format-recall.ts +47 -0
- package/src/memory/guardian-action-store.ts +4 -5
- package/src/memory/guardian-rate-limits.ts +0 -3
- package/src/memory/invite-store.ts +1 -1
- package/src/memory/job-handlers/backfill.ts +9 -2
- package/src/memory/job-handlers/extraction.ts +2 -7
- package/src/memory/job-handlers/summarization.ts +1 -1
- package/src/memory/llm-usage-store.ts +11 -0
- package/src/memory/migrations/114-notifications.ts +12 -40
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +357 -0
- package/src/memory/migrations/141-rename-verification-table.ts +55 -0
- package/src/memory/migrations/142-rename-verification-session-id-column.ts +32 -0
- package/src/memory/migrations/143-rename-guardian-verification-values.ts +48 -0
- package/src/memory/migrations/144-rename-voice-to-phone.ts +147 -0
- package/src/memory/migrations/index.ts +5 -0
- package/src/memory/migrations/registry.ts +30 -0
- package/src/memory/qdrant-circuit-breaker.ts +5 -0
- package/src/memory/retriever.test.ts +707 -0
- package/src/memory/retriever.ts +120 -116
- package/src/memory/schema/calls.ts +3 -7
- package/src/memory/schema/guardian.ts +2 -2
- package/src/memory/search/lexical.ts +4 -1
- package/src/memory/search/query-expansion.test.ts +70 -0
- package/src/memory/search/query-expansion.ts +118 -0
- package/src/memory/search/types.ts +18 -17
- package/src/messaging/providers/telegram-bot/adapter.ts +1 -1
- package/src/messaging/providers/whatsapp/adapter.ts +1 -4
- package/src/messaging/registry.ts +0 -1
- package/src/notifications/README.md +13 -22
- package/src/notifications/adapters/macos.ts +1 -1
- package/src/notifications/conversation-pairing.ts +2 -2
- package/src/notifications/copy-composer.ts +2 -2
- package/src/notifications/decision-engine.ts +1 -10
- package/src/notifications/destination-resolver.ts +2 -3
- package/src/notifications/emit-signal.ts +2 -8
- package/src/notifications/guardian-question-mode.ts +5 -8
- package/src/notifications/signal.ts +1 -2
- package/src/notifications/types.ts +1 -1
- package/src/oauth/token-persistence.ts +25 -1
- package/src/permissions/checker.ts +4 -29
- package/src/permissions/defaults.ts +6 -6
- package/src/permissions/prompter.ts +1 -1
- package/src/permissions/secret-prompter.ts +1 -1
- package/src/permissions/shell-identity.ts +1 -1
- package/src/permissions/trust-store.ts +13 -76
- package/src/permissions/workspace-policy.ts +1 -1
- package/src/{config → prompts}/computer-use-prompt.ts +1 -1
- package/src/{config → prompts}/system-prompt.ts +40 -21
- package/src/runtime/AGENTS.md +6 -8
- package/src/runtime/access-request-helper.ts +36 -55
- package/src/runtime/actor-trust-resolver.ts +1 -24
- package/src/runtime/approval-message-composer.ts +6 -2
- package/src/runtime/assistant-event.ts +1 -1
- package/src/runtime/auth/__tests__/ipc-auth-context.test.ts +1 -1
- package/src/runtime/auth/__tests__/subject.test.ts +32 -0
- package/src/runtime/auth/route-policy.ts +140 -24
- package/src/runtime/auth/subject.ts +9 -0
- package/src/runtime/auth/token-service.ts +11 -0
- package/src/runtime/auth/types.ts +1 -1
- package/src/runtime/channel-approval-types.ts +1 -1
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/channel-invite-transport.ts +0 -2
- package/src/runtime/channel-invite-transports/slack.ts +5 -19
- package/src/runtime/channel-invite-transports/telegram.ts +17 -34
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-readiness-service.ts +24 -159
- package/src/runtime/channel-readiness-types.ts +5 -1
- package/src/runtime/channel-reply-delivery.ts +43 -3
- package/src/runtime/channel-retry-sweep.ts +14 -22
- package/src/runtime/{channel-guardian-service.ts → channel-verification-service.ts} +50 -53
- package/src/runtime/confirmation-request-guardian-bridge.ts +2 -3
- package/src/runtime/gateway-client.ts +12 -15
- package/src/runtime/guardian-action-followup-executor.ts +8 -73
- package/src/runtime/guardian-action-grant-minter.ts +45 -61
- package/src/runtime/guardian-action-message-composer.ts +4 -4
- package/src/runtime/guardian-reply-router.ts +3 -3
- package/src/runtime/http-server.ts +133 -24
- package/src/runtime/http-types.ts +34 -1
- package/src/runtime/invite-instruction-generator.ts +1 -3
- package/src/runtime/invite-redemption-service.ts +5 -5
- package/src/runtime/invite-service.ts +7 -7
- package/src/runtime/local-actor-identity.ts +28 -2
- package/src/runtime/local-gateway-health.ts +275 -0
- package/src/runtime/middleware/twilio-validation.ts +3 -3
- package/src/runtime/migrations/migration-transport.ts +18 -3
- package/src/runtime/migrations/rebind-secrets-screen.ts +2 -2
- package/src/runtime/nl-approval-parser.ts +2 -3
- package/src/runtime/routes/access-request-decision.ts +2 -2
- package/src/runtime/routes/app-management-routes.ts +921 -0
- package/src/runtime/routes/approval-routes.ts +76 -7
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +38 -203
- package/src/runtime/routes/channel-delivery-routes.ts +5 -4
- package/src/runtime/routes/channel-route-shared.ts +1 -3
- package/src/runtime/routes/channel-routes.ts +1 -4
- package/src/runtime/routes/channel-verification-routes.ts +257 -0
- package/src/runtime/routes/computer-use-routes.ts +595 -0
- package/src/runtime/routes/contact-routes.ts +1 -317
- package/src/runtime/routes/conversation-attention-routes.ts +6 -5
- package/src/runtime/routes/conversation-routes.ts +11 -18
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/diagnostics-routes.ts +813 -0
- package/src/runtime/routes/documents-routes.ts +227 -0
- package/src/runtime/routes/guardian-approval-interception.ts +25 -48
- package/src/runtime/routes/guardian-bootstrap-routes.ts +3 -3
- package/src/runtime/routes/guardian-expiry-sweep.ts +2 -2
- package/src/runtime/routes/guardian-refresh-routes.ts +11 -6
- package/src/runtime/routes/inbound-conversation.ts +3 -10
- package/src/runtime/routes/inbound-message-handler.ts +7 -6
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +22 -22
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +44 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +140 -22
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +4 -4
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +5 -5
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +3 -3
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -4
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +13 -14
- package/src/runtime/routes/integrations/slack/channel.ts +72 -0
- package/src/runtime/routes/{slack-share-routes.ts → integrations/slack/share.ts} +9 -9
- package/src/runtime/routes/integrations/telegram.ts +111 -0
- package/src/runtime/routes/integrations/twilio.ts +451 -0
- package/src/runtime/routes/invite-routes.ts +2 -2
- package/src/runtime/routes/pairing-routes.ts +1 -1
- package/src/runtime/routes/recording-routes.ts +332 -0
- package/src/{daemon/handlers/config-scheduling.ts → runtime/routes/schedule-routes.ts} +91 -106
- package/src/runtime/routes/session-management-routes.ts +167 -0
- package/src/runtime/routes/session-query-routes.ts +204 -0
- package/src/runtime/routes/settings-routes.ts +977 -0
- package/src/runtime/routes/skills-routes.ts +266 -0
- package/src/runtime/routes/subagents-routes.ts +246 -0
- package/src/runtime/routes/surface-action-routes.ts +100 -10
- package/src/runtime/routes/surface-content-routes.ts +1 -1
- package/src/runtime/routes/work-items-routes.ts +809 -0
- package/src/runtime/routes/workspace-routes.test.ts +778 -0
- package/src/runtime/routes/workspace-routes.ts +410 -0
- package/src/runtime/routes/workspace-utils.ts +88 -0
- package/src/runtime/telegram-streaming-delivery.test.ts +597 -0
- package/src/runtime/telegram-streaming-delivery.ts +380 -0
- package/src/runtime/tool-grant-request-helper.ts +1 -2
- package/src/runtime/trust-context-resolver.ts +0 -1
- package/src/runtime/{guardian-outbound-actions.ts → verification-outbound-actions.ts} +23 -188
- package/src/runtime/verification-rate-limiter.ts +2 -2
- package/src/runtime/{guardian-verification-templates.ts → verification-templates.ts} +2 -28
- package/src/schedule/integration-status.ts +2 -2
- package/src/schedule/schedule-store.ts +7 -9
- package/src/sequence/engine.ts +1 -1
- package/src/skills/active-skill-tools.ts +0 -8
- package/src/skills/clawhub.ts +1 -10
- package/src/skills/managed-store.ts +14 -4
- package/src/skills/slash-commands.ts +1 -1
- package/src/subagent/manager.ts +1 -1
- package/src/subagent/types.ts +1 -1
- package/src/tasks/SPEC.md +10 -10
- package/src/tasks/task-scheduler.ts +1 -1
- package/src/telegram/bot-username.ts +13 -0
- package/src/tools/assets/materialize.ts +1 -1
- package/src/tools/assets/search.ts +1 -1
- package/src/tools/browser/browser-execution.ts +2 -2
- package/src/tools/browser/browser-manager.ts +88 -11
- package/src/tools/browser/browser-screencast.ts +1 -1
- package/src/tools/browser/headless-browser.ts +0 -17
- package/src/tools/browser/jit-auth.ts +1 -1
- package/src/tools/browser/recording-store.ts +19 -1
- package/src/tools/browser/runtime-check.ts +4 -2
- package/src/tools/calls/call-start.ts +3 -3
- package/src/tools/credentials/metadata-store.ts +0 -13
- package/src/tools/credentials/vault.ts +7 -31
- package/src/tools/followups/followup_create.ts +0 -8
- package/src/tools/mcp/mcp-tool-factory.ts +1 -1
- package/src/tools/memory/definitions.ts +32 -10
- package/src/tools/memory/handlers.test.ts +573 -0
- package/src/tools/memory/handlers.ts +222 -65
- package/src/tools/memory/register.ts +53 -24
- package/src/tools/network/script-proxy/session-manager.ts +1 -12
- package/src/tools/schedule/update.ts +0 -8
- package/src/tools/skills/load.ts +3 -3
- package/src/tools/subagent/read.ts +1 -1
- package/src/tools/system/voice-config.ts +2 -14
- package/src/tools/terminal/safe-env.ts +5 -18
- package/src/tools/tool-approval-handler.ts +4 -4
- package/src/tools/tool-manifest.ts +4 -2
- package/src/tools/types.ts +1 -1
- package/src/tools/{guardian-control-plane-policy.ts → verification-control-plane-policy.ts} +37 -39
- package/src/twitter/platform-proxy-client.ts +405 -0
- package/src/usage/types.ts +21 -0
- package/src/util/canonicalize-identity.ts +2 -6
- package/src/util/cookie-session.ts +35 -51
- package/src/util/platform.ts +93 -86
- package/src/util/pricing.ts +180 -43
- package/src/work-items/work-item-runner.ts +1 -1
- package/scripts/ipc/check-contract-inventory.ts +0 -107
- package/scripts/ipc/check-swift-decoder-drift.ts +0 -184
- package/scripts/ipc/generate-swift.ts +0 -528
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +0 -3043
- package/src/__tests__/app-migration.test.ts +0 -148
- package/src/__tests__/config-loader-migration.test.ts +0 -85
- package/src/__tests__/daemon-lifecycle.test.ts +0 -715
- package/src/__tests__/daemon-server-session-init.test.ts +0 -864
- package/src/__tests__/guardian-actions-endpoint.test.ts +0 -1452
- package/src/__tests__/handlers-add-trust-rule-metadata.test.ts +0 -228
- package/src/__tests__/handlers-cu-observation-blob.test.ts +0 -397
- package/src/__tests__/handlers-ipc-blob-probe.test.ts +0 -218
- package/src/__tests__/handlers-slack-config.test.ts +0 -140
- package/src/__tests__/handlers-telegram-config.test.ts +0 -1317
- package/src/__tests__/handlers-twitter-config.test.ts +0 -1145
- package/src/__tests__/ingress-reconcile.test.ts +0 -606
- package/src/__tests__/integrations-cli.test.ts +0 -232
- package/src/__tests__/ipc-blob-store.test.ts +0 -329
- package/src/__tests__/ipc-contract-inventory.test.ts +0 -69
- package/src/__tests__/ipc-contract.test.ts +0 -76
- package/src/__tests__/ipc-protocol.test.ts +0 -120
- package/src/__tests__/ipc-roundtrip.benchmark.test.ts +0 -250
- package/src/__tests__/ipc-snapshot.test.ts +0 -2197
- package/src/__tests__/ipc-validate.test.ts +0 -471
- package/src/__tests__/migration-cli-flows.test.ts +0 -186
- package/src/__tests__/migration-ordering.test.ts +0 -267
- package/src/__tests__/oauth-connect-handler.test.ts +0 -361
- package/src/__tests__/platform-move-helper.test.ts +0 -108
- package/src/__tests__/platform-socket-path.test.ts +0 -52
- package/src/__tests__/platform-workspace-migration.test.ts +0 -1051
- package/src/__tests__/recording-intent-handler.test.ts +0 -1155
- package/src/__tests__/script-proxy-profile-template-fallback.test.ts +0 -127
- package/src/__tests__/sms-messaging-provider.test.ts +0 -156
- package/src/__tests__/tool-permission-simulate-handler.test.ts +0 -367
- package/src/__tests__/twitter-auth-handler.test.ts +0 -561
- package/src/__tests__/work-item-output.test.ts +0 -150
- package/src/amazon/session.ts +0 -58
- package/src/cli/channels.ts +0 -51
- package/src/cli/influencer.ts +0 -319
- package/src/cli/integrations.ts +0 -372
- package/src/cli/ipc-client.ts +0 -88
- package/src/config/bundled-skills/configure-settings/SKILL.md +0 -86
- package/src/config/bundled-skills/doordash/lib/shared/ipc.ts +0 -32
- package/src/config/bundled-skills/sms-setup/SKILL.md +0 -210
- package/src/config/core-schema.ts +0 -434
- package/src/config/memory-schema.ts +0 -617
- package/src/daemon/auth-manager.ts +0 -106
- package/src/daemon/handlers/apps.ts +0 -758
- package/src/daemon/handlers/avatar.ts +0 -73
- package/src/daemon/handlers/browser.ts +0 -3
- package/src/daemon/handlers/computer-use.ts +0 -231
- package/src/daemon/handlers/config-dispatch.ts +0 -29
- package/src/daemon/handlers/config-heartbeat.ts +0 -299
- package/src/daemon/handlers/config-inbox.ts +0 -457
- package/src/daemon/handlers/config-integrations.ts +0 -409
- package/src/daemon/handlers/config-platform.ts +0 -77
- package/src/daemon/handlers/config-slack.ts +0 -41
- package/src/daemon/handlers/config-tools.ts +0 -226
- package/src/daemon/handlers/config-trust.ts +0 -135
- package/src/daemon/handlers/config.ts +0 -64
- package/src/daemon/handlers/contacts.ts +0 -193
- package/src/daemon/handlers/diagnostics.ts +0 -382
- package/src/daemon/handlers/documents.ts +0 -188
- package/src/daemon/handlers/guardian-actions.ts +0 -82
- package/src/daemon/handlers/home-base.ts +0 -82
- package/src/daemon/handlers/index.ts +0 -222
- package/src/daemon/handlers/misc.ts +0 -1139
- package/src/daemon/handlers/navigate-settings.ts +0 -29
- package/src/daemon/handlers/oauth-connect.ts +0 -202
- package/src/daemon/handlers/open-bundle-handler.ts +0 -88
- package/src/daemon/handlers/publish.ts +0 -176
- package/src/daemon/handlers/signing.ts +0 -56
- package/src/daemon/handlers/subagents.ts +0 -286
- package/src/daemon/handlers/twitter-auth.ts +0 -220
- package/src/daemon/handlers/work-items.ts +0 -796
- package/src/daemon/handlers/workspace-files.ts +0 -84
- package/src/daemon/handlers.ts +0 -16
- package/src/daemon/ipc-blob-store.ts +0 -246
- package/src/daemon/ipc-contract-inventory.json +0 -348
- package/src/daemon/ipc-contract-inventory.ts +0 -202
- package/src/daemon/ipc-handler.ts +0 -120
- package/src/daemon/ipc-protocol.ts +0 -85
- package/src/daemon/ipc-validate.ts +0 -254
- package/src/memory/app-migration.ts +0 -114
- package/src/memory/channel-delivery-store.ts +0 -40
- package/src/memory/channel-guardian-store.ts +0 -83
- package/src/memory/conversation-store.ts +0 -102
- package/src/memory/schema-migration.ts +0 -38
- package/src/messaging/providers/sms/adapter.ts +0 -232
- package/src/messaging/providers/sms/client.ts +0 -93
- package/src/messaging/providers/sms/types.ts +0 -7
- package/src/migrations/config-merge.ts +0 -62
- package/src/migrations/data-layout.ts +0 -89
- package/src/migrations/data-merge.ts +0 -44
- package/src/migrations/hooks-merge.ts +0 -118
- package/src/migrations/index.ts +0 -6
- package/src/migrations/log.ts +0 -28
- package/src/migrations/skills-merge.ts +0 -44
- package/src/migrations/workspace-layout.ts +0 -94
- package/src/notifications/adapters/sms.ts +0 -94
- package/src/runtime/channel-approval-parser.ts +0 -123
- package/src/runtime/channel-invite-transports/sms.ts +0 -53
- package/src/runtime/routes/approval-strategies/guardian-legacy-fallback-strategy.ts +0 -82
- package/src/runtime/routes/integration-routes.ts +0 -381
- package/src/runtime/routes/twilio-routes.ts +0 -1251
- package/src/twitter/router.ts +0 -131
- package/src/twitter/session.ts +0 -54
- package/src/watcher/providers/slack.ts +0 -282
- /package/src/{amazon → cli/commands/amazon}/cart.ts +0 -0
- /package/src/{amazon → cli/commands/amazon}/checkout.ts +0 -0
- /package/src/{amazon → cli/commands/amazon}/product-details.ts +0 -0
- /package/src/{amazon → cli/commands/amazon}/search.ts +0 -0
- /package/src/{twitter → cli/commands/twitter}/oauth-client.ts +0 -0
- /package/src/config/{calls-schema.ts → schemas/calls.ts} +0 -0
- /package/src/config/{elevenlabs-schema.ts → schemas/elevenlabs.ts} +0 -0
- /package/src/config/{mcp-schema.ts → schemas/mcp.ts} +0 -0
- /package/src/config/{notifications-schema.ts → schemas/notifications.ts} +0 -0
- /package/src/config/{sandbox-schema.ts → schemas/sandbox.ts} +0 -0
- /package/src/config/{skills-schema.ts → schemas/skills.ts} +0 -0
- /package/src/daemon/{ipc-contract → message-types}/apps.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/browser.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/contacts.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/documents.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/guardian-actions.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/inbox.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/messages.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/pairing.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/schedules.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/settings.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/skills.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/subagents.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/surfaces.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/trust.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/work-items.ts +0 -0
- /package/src/{cli/email-guardrails.ts → email/guardrails.ts} +0 -0
- /package/src/{config → prompts}/__tests__/build-cli-reference-section.test.ts +0 -0
- /package/src/{config → prompts}/templates/BOOTSTRAP.md +0 -0
- /package/src/{config → prompts}/templates/IDENTITY.md +0 -0
- /package/src/{config → prompts}/templates/SOUL.md +0 -0
- /package/src/{config → prompts}/templates/UPDATES.md +0 -0
- /package/src/{config → prompts}/templates/USER.md +0 -0
- /package/src/{config → prompts}/update-bulletin-format.ts +0 -0
- /package/src/{config → prompts}/update-bulletin-state.ts +0 -0
- /package/src/{config → prompts}/update-bulletin-template-path.ts +0 -0
- /package/src/{config → prompts}/update-bulletin.ts +0 -0
- /package/src/{config → prompts}/user-reference.ts +0 -0
package/src/daemon/server.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as net from "node:net";
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
2
|
import { join } from "node:path";
|
|
4
|
-
import * as tls from "node:tls";
|
|
5
3
|
|
|
6
4
|
import {
|
|
7
5
|
createAssistantMessage,
|
|
@@ -14,7 +12,6 @@ import {
|
|
|
14
12
|
parseInterfaceId,
|
|
15
13
|
} from "../channels/types.js";
|
|
16
14
|
import { getConfig } from "../config/loader.js";
|
|
17
|
-
import { buildSystemPrompt } from "../config/system-prompt.js";
|
|
18
15
|
import { onContactChange } from "../contacts/contact-events.js";
|
|
19
16
|
import type { HeartbeatService } from "../heartbeat/heartbeat-service.js";
|
|
20
17
|
import { bootstrapHomeBaseAppLink } from "../home-base/bootstrap.js";
|
|
@@ -23,52 +20,44 @@ import {
|
|
|
23
20
|
createCanonicalGuardianRequest,
|
|
24
21
|
generateCanonicalRequestCode,
|
|
25
22
|
} from "../memory/canonical-guardian-store.js";
|
|
26
|
-
import
|
|
27
|
-
|
|
23
|
+
import {
|
|
24
|
+
addMessage,
|
|
25
|
+
getConversationMemoryScopeId,
|
|
26
|
+
getConversationThreadType,
|
|
27
|
+
provenanceFromTrustContext,
|
|
28
|
+
setConversationOriginChannelIfUnset,
|
|
29
|
+
setConversationOriginInterfaceIfUnset,
|
|
30
|
+
} from "../memory/conversation-crud.js";
|
|
31
|
+
import { buildSystemPrompt } from "../prompts/system-prompt.js";
|
|
28
32
|
import { RateLimitProvider } from "../providers/ratelimit.js";
|
|
29
33
|
import {
|
|
30
34
|
getFailoverProvider,
|
|
31
35
|
initializeProviders,
|
|
32
36
|
} from "../providers/registry.js";
|
|
37
|
+
import { buildAssistantEvent } from "../runtime/assistant-event.js";
|
|
38
|
+
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
33
39
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
|
|
40
|
+
import { getSigningKeyFingerprint } from "../runtime/auth/token-service.js";
|
|
34
41
|
import { bridgeConfirmationRequestToGuardian } from "../runtime/confirmation-request-guardian-bridge.js";
|
|
35
42
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
36
43
|
import { checkIngressForSecrets } from "../security/secret-ingress.js";
|
|
37
44
|
import { getSubagentManager } from "../subagent/index.js";
|
|
38
45
|
import { IngressBlockedError } from "../util/errors.js";
|
|
39
46
|
import { getLogger } from "../util/logger.js";
|
|
40
|
-
import { getLocalIPv4 } from "../util/network-info.js";
|
|
41
47
|
import {
|
|
42
48
|
getSandboxWorkingDir,
|
|
43
|
-
getSocketPath,
|
|
44
|
-
getTCPHost,
|
|
45
|
-
getTCPPort,
|
|
46
49
|
getWorkspacePromptPath,
|
|
47
|
-
isIOSPairingEnabled,
|
|
48
|
-
isTCPEnabled,
|
|
49
|
-
removeSocketFile,
|
|
50
50
|
} from "../util/platform.js";
|
|
51
51
|
import { registerDaemonCallbacks } from "../work-items/work-item-runner.js";
|
|
52
|
-
import { AuthManager } from "./auth-manager.js";
|
|
53
52
|
import { ComputerUseSession } from "./computer-use-session.js";
|
|
54
53
|
import { ConfigWatcher } from "./config-watcher.js";
|
|
55
|
-
import {
|
|
56
|
-
handleMessage,
|
|
57
|
-
type HandlerContext,
|
|
58
|
-
type SessionCreateOptions,
|
|
59
|
-
} from "./handlers.js";
|
|
60
54
|
import { parseIdentityFields } from "./handlers/identity.js";
|
|
61
|
-
import {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
normalizeThreadType,
|
|
68
|
-
serialize,
|
|
69
|
-
type ServerMessage,
|
|
70
|
-
} from "./ipc-protocol.js";
|
|
71
|
-
import { validateClientMessage } from "./ipc-validate.js";
|
|
55
|
+
import type {
|
|
56
|
+
HandlerContext,
|
|
57
|
+
SessionCreateOptions,
|
|
58
|
+
} from "./handlers/shared.js";
|
|
59
|
+
import type { SkillOperationContext } from "./handlers/skills.js";
|
|
60
|
+
import type { ServerMessage } from "./message-protocol.js";
|
|
72
61
|
import {
|
|
73
62
|
DEFAULT_MEMORY_POLICY,
|
|
74
63
|
Session,
|
|
@@ -77,7 +66,6 @@ import {
|
|
|
77
66
|
import { SessionEvictor } from "./session-evictor.js";
|
|
78
67
|
import { resolveChannelCapabilities } from "./session-runtime-assembly.js";
|
|
79
68
|
import { resolveSlash } from "./session-slash.js";
|
|
80
|
-
import { ensureTlsCert } from "./tls-certs.js";
|
|
81
69
|
|
|
82
70
|
const log = getLogger("server");
|
|
83
71
|
|
|
@@ -132,7 +120,7 @@ function resolveTurnInterface(sourceInterface?: string): InterfaceId {
|
|
|
132
120
|
function resolveCanonicalRequestSourceType(
|
|
133
121
|
sourceChannel: string | undefined,
|
|
134
122
|
): "desktop" | "channel" | "voice" {
|
|
135
|
-
if (sourceChannel === "
|
|
123
|
+
if (sourceChannel === "phone") {
|
|
136
124
|
return "voice";
|
|
137
125
|
}
|
|
138
126
|
if (sourceChannel === "vellum") {
|
|
@@ -168,7 +156,7 @@ function makePendingInteractionRegistrar(
|
|
|
168
156
|
},
|
|
169
157
|
});
|
|
170
158
|
|
|
171
|
-
// Create a canonical guardian request so
|
|
159
|
+
// Create a canonical guardian request so HTTP handlers can find it
|
|
172
160
|
// via applyCanonicalGuardianDecision.
|
|
173
161
|
try {
|
|
174
162
|
const trustContext = session.trustContext;
|
|
@@ -217,29 +205,19 @@ function makePendingInteractionRegistrar(
|
|
|
217
205
|
}
|
|
218
206
|
|
|
219
207
|
export class DaemonServer {
|
|
220
|
-
private server: net.Server | null = null;
|
|
221
|
-
private tcpServer: tls.Server | null = null;
|
|
222
208
|
private sessions = new Map<string, Session>();
|
|
223
|
-
private socketToSession = new Map<net.Socket, string>();
|
|
224
209
|
private cuSessions = new Map<string, ComputerUseSession>();
|
|
225
|
-
private socketToCuSession = new Map<net.Socket, Set<string>>();
|
|
226
|
-
private connectedSockets = new Set<net.Socket>();
|
|
227
|
-
private socketSandboxOverride = new Map<net.Socket, boolean>();
|
|
228
210
|
private cuObservationParseSequence = new Map<string, number>();
|
|
229
211
|
private sessionOptions = new Map<string, SessionCreateOptions>();
|
|
230
212
|
private sessionCreating = new Map<string, Promise<Session>>();
|
|
231
213
|
private sharedRequestTimestamps: number[] = [];
|
|
232
|
-
private socketPath: string;
|
|
233
214
|
private httpPort: number | undefined;
|
|
234
|
-
private blobSweepTimer: ReturnType<typeof setInterval> | null = null;
|
|
235
215
|
private unsubscribeContactChange: (() => void) | null = null;
|
|
236
|
-
private static readonly MAX_CONNECTIONS = 50;
|
|
237
216
|
private evictor: SessionEvictor;
|
|
217
|
+
private _hubChain: Promise<void> = Promise.resolve();
|
|
238
218
|
|
|
239
219
|
// Composed subsystems
|
|
240
|
-
private auth = new AuthManager();
|
|
241
220
|
private configWatcher = new ConfigWatcher();
|
|
242
|
-
private ipc = new IpcSender();
|
|
243
221
|
|
|
244
222
|
/**
|
|
245
223
|
* Logical assistant identifier used when publishing to the assistant-events hub.
|
|
@@ -254,11 +232,10 @@ export class DaemonServer {
|
|
|
254
232
|
}
|
|
255
233
|
|
|
256
234
|
private deriveMemoryPolicy(conversationId: string): SessionMemoryPolicy {
|
|
257
|
-
const threadType =
|
|
258
|
-
conversationStore.getConversationThreadType(conversationId);
|
|
235
|
+
const threadType = getConversationThreadType(conversationId);
|
|
259
236
|
if (threadType === "private") {
|
|
260
237
|
return {
|
|
261
|
-
scopeId:
|
|
238
|
+
scopeId: getConversationMemoryScopeId(conversationId),
|
|
262
239
|
includeDefaultFallback: true,
|
|
263
240
|
strictSideEffects: true,
|
|
264
241
|
};
|
|
@@ -279,7 +256,6 @@ export class DaemonServer {
|
|
|
279
256
|
}
|
|
280
257
|
|
|
281
258
|
constructor() {
|
|
282
|
-
this.socketPath = getSocketPath();
|
|
283
259
|
this.evictor = new SessionEvictor(this.sessions);
|
|
284
260
|
getSubagentManager().sharedRequestTimestamps = this.sharedRequestTimestamps;
|
|
285
261
|
this.evictor.onEvict = (sessionId: string) => {
|
|
@@ -342,20 +318,32 @@ export class DaemonServer {
|
|
|
342
318
|
};
|
|
343
319
|
}
|
|
344
320
|
|
|
345
|
-
// ──
|
|
321
|
+
// ── Broadcast / Event publishing ──────────────────────────────────
|
|
346
322
|
|
|
347
|
-
|
|
348
|
-
|
|
323
|
+
/**
|
|
324
|
+
* Publish `msg` as an `AssistantEvent` to the process-level hub.
|
|
325
|
+
* Publications are serialized via a promise chain so subscribers
|
|
326
|
+
* always observe events in send order.
|
|
327
|
+
*/
|
|
328
|
+
private publishAssistantEvent(
|
|
329
|
+
msg: ServerMessage,
|
|
330
|
+
sessionId?: string,
|
|
331
|
+
): void {
|
|
332
|
+
const id = this.assistantId ?? "default";
|
|
333
|
+
const event = buildAssistantEvent(id, msg, sessionId);
|
|
334
|
+
this._hubChain = this._hubChain
|
|
335
|
+
.then(() => assistantEventHub.publish(event))
|
|
336
|
+
.catch((err: unknown) => {
|
|
337
|
+
log.warn(
|
|
338
|
+
{ err },
|
|
339
|
+
"assistant-events hub subscriber threw during broadcast",
|
|
340
|
+
);
|
|
341
|
+
});
|
|
349
342
|
}
|
|
350
343
|
|
|
351
|
-
broadcast(msg: ServerMessage
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
msg,
|
|
355
|
-
this.socketToSession,
|
|
356
|
-
this.assistantId,
|
|
357
|
-
excludeSocket,
|
|
358
|
-
);
|
|
344
|
+
broadcast(msg: ServerMessage): void {
|
|
345
|
+
const sessionId = extractSessionId(msg);
|
|
346
|
+
this.publishAssistantEvent(msg, sessionId);
|
|
359
347
|
}
|
|
360
348
|
|
|
361
349
|
private broadcastIdentityChanged(): void {
|
|
@@ -381,8 +369,6 @@ export class DaemonServer {
|
|
|
381
369
|
// ── Server lifecycle ────────────────────────────────────────────────
|
|
382
370
|
|
|
383
371
|
async start(): Promise<void> {
|
|
384
|
-
removeSocketFile(this.socketPath);
|
|
385
|
-
|
|
386
372
|
const config = getConfig();
|
|
387
373
|
initializeProviders(config);
|
|
388
374
|
this.configWatcher.initFingerprint(config);
|
|
@@ -404,16 +390,6 @@ export class DaemonServer {
|
|
|
404
390
|
broadcast: (msg) => this.broadcast(msg),
|
|
405
391
|
});
|
|
406
392
|
|
|
407
|
-
ensureBlobDir();
|
|
408
|
-
this.blobSweepTimer = setInterval(
|
|
409
|
-
() => {
|
|
410
|
-
sweepStaleBlobs(30 * 60 * 1000).catch((err) => {
|
|
411
|
-
log.warn({ err }, "Blob sweep failed");
|
|
412
|
-
});
|
|
413
|
-
},
|
|
414
|
-
5 * 60 * 1000,
|
|
415
|
-
);
|
|
416
|
-
|
|
417
393
|
this.configWatcher.start(
|
|
418
394
|
() => this.evictSessionsForReload(),
|
|
419
395
|
() => this.broadcastIdentityChanged(),
|
|
@@ -424,140 +400,17 @@ export class DaemonServer {
|
|
|
424
400
|
this.broadcast({ type: "contacts_changed" });
|
|
425
401
|
});
|
|
426
402
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
let tlsCreds: { cert: string; key: string; fingerprint: string } | null =
|
|
430
|
-
null;
|
|
431
|
-
if (isTCPEnabled()) {
|
|
432
|
-
try {
|
|
433
|
-
tlsCreds = await ensureTlsCert();
|
|
434
|
-
} catch (err) {
|
|
435
|
-
log.error(
|
|
436
|
-
{ err },
|
|
437
|
-
"Failed to generate TLS certificate — TCP listener will not start",
|
|
438
|
-
);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
return new Promise((resolve, reject) => {
|
|
443
|
-
this.server = net.createServer((socket) => {
|
|
444
|
-
this.handleConnection(socket);
|
|
445
|
-
});
|
|
446
|
-
|
|
447
|
-
const oldUmask = process.umask(0o177);
|
|
448
|
-
|
|
449
|
-
this.server.once("error", (err) => {
|
|
450
|
-
process.umask(oldUmask);
|
|
451
|
-
log.error(
|
|
452
|
-
{ err, socketPath: this.socketPath },
|
|
453
|
-
"Server failed to start (is another daemon already running?)",
|
|
454
|
-
);
|
|
455
|
-
reject(err);
|
|
456
|
-
});
|
|
457
|
-
|
|
458
|
-
this.server.listen(this.socketPath, () => {
|
|
459
|
-
process.umask(oldUmask);
|
|
460
|
-
this.server!.removeAllListeners("error");
|
|
461
|
-
this.server!.on("error", (err) => {
|
|
462
|
-
log.error(
|
|
463
|
-
{ err, socketPath: this.socketPath },
|
|
464
|
-
"Server socket error while running",
|
|
465
|
-
);
|
|
466
|
-
});
|
|
467
|
-
chmodSync(this.socketPath, 0o600);
|
|
468
|
-
// Validate the chmod actually took effect — some filesystems
|
|
469
|
-
// (e.g. FAT32 mounts, container overlays) silently ignore chmod.
|
|
470
|
-
const socketStat = statSync(this.socketPath);
|
|
471
|
-
if ((socketStat.mode & 0o077) !== 0) {
|
|
472
|
-
const actual = "0o" + (socketStat.mode & 0o777).toString(8);
|
|
473
|
-
log.error(
|
|
474
|
-
{ socketPath: this.socketPath, mode: actual },
|
|
475
|
-
"IPC socket is accessible by other users (expected 0600) — filesystem may not support Unix permissions",
|
|
476
|
-
);
|
|
477
|
-
}
|
|
478
|
-
log.info({ socketPath: this.socketPath }, "Daemon server listening");
|
|
479
|
-
|
|
480
|
-
if (tlsCreds) {
|
|
481
|
-
const tcpPort = getTCPPort();
|
|
482
|
-
const tcpHost = getTCPHost();
|
|
483
|
-
this.tcpServer = tls.createServer(
|
|
484
|
-
{ cert: tlsCreds.cert, key: tlsCreds.key },
|
|
485
|
-
(socket) => {
|
|
486
|
-
this.handleConnection(socket);
|
|
487
|
-
},
|
|
488
|
-
);
|
|
489
|
-
this.tcpServer.on("error", (err) => {
|
|
490
|
-
log.error({ err, tcpPort }, "TLS TCP server error");
|
|
491
|
-
});
|
|
492
|
-
const fingerprint = tlsCreds.fingerprint;
|
|
493
|
-
this.tcpServer.listen(tcpPort, tcpHost, () => {
|
|
494
|
-
const localIP = getLocalIPv4();
|
|
495
|
-
log.info(
|
|
496
|
-
{
|
|
497
|
-
tcpPort,
|
|
498
|
-
tcpHost,
|
|
499
|
-
fingerprint,
|
|
500
|
-
localIP,
|
|
501
|
-
iosPairing: isIOSPairingEnabled(),
|
|
502
|
-
},
|
|
503
|
-
"TLS TCP listener started",
|
|
504
|
-
);
|
|
505
|
-
if (isIOSPairingEnabled() && localIP) {
|
|
506
|
-
log.warn(
|
|
507
|
-
{ localIP, tcpPort },
|
|
508
|
-
"iOS pairing enabled — daemon is reachable on the local network at %s:%d",
|
|
509
|
-
localIP,
|
|
510
|
-
tcpPort,
|
|
511
|
-
);
|
|
512
|
-
}
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
resolve();
|
|
517
|
-
});
|
|
518
|
-
});
|
|
403
|
+
log.info("DaemonServer started (HTTP-only mode)");
|
|
519
404
|
}
|
|
520
405
|
|
|
521
406
|
async stop(): Promise<void> {
|
|
522
407
|
getSubagentManager().disposeAll();
|
|
523
408
|
this.evictor.stop();
|
|
524
|
-
if (this.blobSweepTimer) {
|
|
525
|
-
clearInterval(this.blobSweepTimer);
|
|
526
|
-
this.blobSweepTimer = null;
|
|
527
|
-
}
|
|
528
409
|
this.configWatcher.stop();
|
|
529
410
|
if (this.unsubscribeContactChange) {
|
|
530
411
|
this.unsubscribeContactChange();
|
|
531
412
|
this.unsubscribeContactChange = null;
|
|
532
413
|
}
|
|
533
|
-
this.auth.cleanupAll();
|
|
534
|
-
|
|
535
|
-
const serverClosed = new Promise<void>((resolve) => {
|
|
536
|
-
if (this.server) {
|
|
537
|
-
this.server.close(() => {
|
|
538
|
-
try {
|
|
539
|
-
removeSocketFile(this.socketPath);
|
|
540
|
-
} catch (err) {
|
|
541
|
-
log.warn(
|
|
542
|
-
{ err, socketPath: this.socketPath },
|
|
543
|
-
"Failed to remove socket file during shutdown",
|
|
544
|
-
);
|
|
545
|
-
}
|
|
546
|
-
resolve();
|
|
547
|
-
});
|
|
548
|
-
} else {
|
|
549
|
-
resolve();
|
|
550
|
-
}
|
|
551
|
-
});
|
|
552
|
-
|
|
553
|
-
const tcpServerClosed = new Promise<void>((resolve) => {
|
|
554
|
-
if (this.tcpServer) {
|
|
555
|
-
this.tcpServer.close(() => resolve());
|
|
556
|
-
this.tcpServer = null;
|
|
557
|
-
} else {
|
|
558
|
-
resolve();
|
|
559
|
-
}
|
|
560
|
-
});
|
|
561
414
|
|
|
562
415
|
for (const session of this.sessions.values()) {
|
|
563
416
|
session.dispose();
|
|
@@ -568,225 +421,10 @@ export class DaemonServer {
|
|
|
568
421
|
cuSession.abort();
|
|
569
422
|
}
|
|
570
423
|
this.cuSessions.clear();
|
|
571
|
-
this.socketToCuSession.clear();
|
|
572
424
|
|
|
573
|
-
for (const socket of this.connectedSockets) {
|
|
574
|
-
socket.destroy();
|
|
575
|
-
}
|
|
576
|
-
this.connectedSockets.clear();
|
|
577
|
-
this.socketToSession.clear();
|
|
578
|
-
this.socketSandboxOverride.clear();
|
|
579
|
-
this.cuObservationParseSequence.clear();
|
|
580
|
-
|
|
581
|
-
await Promise.all([serverClosed, tcpServerClosed]);
|
|
582
425
|
log.info("Daemon server stopped");
|
|
583
426
|
}
|
|
584
427
|
|
|
585
|
-
// ── Connection handling ─────────────────────────────────────────────
|
|
586
|
-
|
|
587
|
-
private handleConnection(socket: net.Socket): void {
|
|
588
|
-
if (this.connectedSockets.size >= DaemonServer.MAX_CONNECTIONS) {
|
|
589
|
-
log.warn(
|
|
590
|
-
{
|
|
591
|
-
current: this.connectedSockets.size,
|
|
592
|
-
max: DaemonServer.MAX_CONNECTIONS,
|
|
593
|
-
},
|
|
594
|
-
"Connection limit reached, rejecting client",
|
|
595
|
-
);
|
|
596
|
-
socket.once("error", (err) => {
|
|
597
|
-
log.error({ err }, "Socket error while rejecting connection");
|
|
598
|
-
});
|
|
599
|
-
socket.write(
|
|
600
|
-
serialize({
|
|
601
|
-
type: "error",
|
|
602
|
-
message: `Connection limit reached (max ${DaemonServer.MAX_CONNECTIONS})`,
|
|
603
|
-
}),
|
|
604
|
-
);
|
|
605
|
-
socket.destroy();
|
|
606
|
-
return;
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
log.info("Client connected");
|
|
610
|
-
this.connectedSockets.add(socket);
|
|
611
|
-
const parser = createMessageParser({ maxLineSize: MAX_LINE_SIZE });
|
|
612
|
-
|
|
613
|
-
if (this.auth.shouldAutoAuth()) {
|
|
614
|
-
this.auth.markAuthenticated(socket);
|
|
615
|
-
log.warn(
|
|
616
|
-
"Auto-authenticated client (VELLUM_DAEMON_NOAUTH is set — token auth bypassed)",
|
|
617
|
-
);
|
|
618
|
-
this.send(socket, { type: "auth_result", success: true });
|
|
619
|
-
this.sendInitialSession(socket).catch((err) => {
|
|
620
|
-
log.error(
|
|
621
|
-
{ err },
|
|
622
|
-
"Failed to send initial session info after auto-auth",
|
|
623
|
-
);
|
|
624
|
-
});
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
this.auth.startTimeout(socket, () => {
|
|
628
|
-
this.send(socket, { type: "error", message: "Authentication timeout" });
|
|
629
|
-
socket.destroy();
|
|
630
|
-
});
|
|
631
|
-
|
|
632
|
-
socket.on("data", (data) => {
|
|
633
|
-
const chunkReceivedAtMs = Date.now();
|
|
634
|
-
const parseStartNs = process.hrtime.bigint();
|
|
635
|
-
let parsed;
|
|
636
|
-
try {
|
|
637
|
-
parsed = parser.feedRaw(data.toString());
|
|
638
|
-
} catch (err) {
|
|
639
|
-
log.error(
|
|
640
|
-
{ err },
|
|
641
|
-
"IPC parse error (malformed JSON or message exceeded size limit), dropping client",
|
|
642
|
-
);
|
|
643
|
-
socket.write(
|
|
644
|
-
serialize({
|
|
645
|
-
type: "error",
|
|
646
|
-
message: `IPC parse error: ${(err as Error).message}`,
|
|
647
|
-
}),
|
|
648
|
-
);
|
|
649
|
-
socket.destroy();
|
|
650
|
-
return;
|
|
651
|
-
}
|
|
652
|
-
const parsedAtMs = Date.now();
|
|
653
|
-
const parseDurationMs =
|
|
654
|
-
Number(process.hrtime.bigint() - parseStartNs) / 1_000_000;
|
|
655
|
-
for (const entry of parsed) {
|
|
656
|
-
const msg = entry.msg;
|
|
657
|
-
if (
|
|
658
|
-
typeof msg === "object" &&
|
|
659
|
-
msg != null &&
|
|
660
|
-
(msg as { type?: unknown }).type === "cu_observation"
|
|
661
|
-
) {
|
|
662
|
-
const maybeSessionId = (msg as { sessionId?: unknown }).sessionId;
|
|
663
|
-
const sessionId =
|
|
664
|
-
typeof maybeSessionId === "string" ? maybeSessionId : "unknown";
|
|
665
|
-
const previousSequence =
|
|
666
|
-
this.cuObservationParseSequence.get(sessionId) ?? 0;
|
|
667
|
-
const sequence = previousSequence + 1;
|
|
668
|
-
this.cuObservationParseSequence.set(sessionId, sequence);
|
|
669
|
-
log.info(
|
|
670
|
-
{
|
|
671
|
-
sessionId,
|
|
672
|
-
sequence,
|
|
673
|
-
chunkReceivedAtMs,
|
|
674
|
-
parsedAtMs,
|
|
675
|
-
parseDurationMs,
|
|
676
|
-
messageBytes: entry.rawByteLength,
|
|
677
|
-
},
|
|
678
|
-
"IPC_METRIC cu_observation_parse",
|
|
679
|
-
);
|
|
680
|
-
}
|
|
681
|
-
const result = validateClientMessage(msg);
|
|
682
|
-
if (!result.valid) {
|
|
683
|
-
log.warn(
|
|
684
|
-
{ reason: result.reason },
|
|
685
|
-
"Invalid IPC message, dropping client",
|
|
686
|
-
);
|
|
687
|
-
socket.write(
|
|
688
|
-
serialize({
|
|
689
|
-
type: "error",
|
|
690
|
-
message: `Invalid message: ${result.reason}`,
|
|
691
|
-
}),
|
|
692
|
-
);
|
|
693
|
-
socket.destroy();
|
|
694
|
-
return;
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
// Auth gate
|
|
698
|
-
if (!this.auth.isAuthenticated(socket)) {
|
|
699
|
-
this.auth.clearTimeout(socket);
|
|
700
|
-
|
|
701
|
-
if (result.message.type === "auth") {
|
|
702
|
-
const authMsg = result.message as { type: "auth"; token: string };
|
|
703
|
-
if (this.auth.authenticate(socket, authMsg.token)) {
|
|
704
|
-
this.send(socket, { type: "auth_result", success: true });
|
|
705
|
-
this.sendInitialSession(socket).catch((err) => {
|
|
706
|
-
log.error(
|
|
707
|
-
{ err },
|
|
708
|
-
"Failed to send initial session info after auth",
|
|
709
|
-
);
|
|
710
|
-
});
|
|
711
|
-
} else {
|
|
712
|
-
this.send(socket, {
|
|
713
|
-
type: "auth_result",
|
|
714
|
-
success: false,
|
|
715
|
-
message: "Invalid token",
|
|
716
|
-
});
|
|
717
|
-
socket.destroy();
|
|
718
|
-
}
|
|
719
|
-
continue;
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
log.warn(
|
|
723
|
-
{ type: result.message.type },
|
|
724
|
-
"Unauthenticated client sent non-auth message, disconnecting",
|
|
725
|
-
);
|
|
726
|
-
this.send(socket, {
|
|
727
|
-
type: "error",
|
|
728
|
-
message: "Authentication required",
|
|
729
|
-
});
|
|
730
|
-
socket.destroy();
|
|
731
|
-
return;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
// Already-authenticated socket sending auth (e.g. auto-auth'd + local token)
|
|
735
|
-
if (result.message.type === "auth") {
|
|
736
|
-
this.send(socket, { type: "auth_result", success: true });
|
|
737
|
-
continue;
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
this.dispatchMessage(result.message, socket);
|
|
741
|
-
}
|
|
742
|
-
});
|
|
743
|
-
|
|
744
|
-
socket.on("close", () => {
|
|
745
|
-
this.auth.cleanupSocket(socket);
|
|
746
|
-
this.connectedSockets.delete(socket);
|
|
747
|
-
this.socketSandboxOverride.delete(socket);
|
|
748
|
-
const sessionId = this.socketToSession.get(socket);
|
|
749
|
-
if (sessionId) {
|
|
750
|
-
const session = this.sessions.get(sessionId);
|
|
751
|
-
if (session) {
|
|
752
|
-
session.abort();
|
|
753
|
-
}
|
|
754
|
-
getSubagentManager().abortAllForParent(sessionId);
|
|
755
|
-
}
|
|
756
|
-
// Clean up recording state for recordings whose owning conversation is
|
|
757
|
-
// bound to the disconnecting socket. Runs outside the sessionId check
|
|
758
|
-
// because recordings may be keyed to a different conversation than the
|
|
759
|
-
// socket's current session.
|
|
760
|
-
cleanupRecordingsOnDisconnect(socket, (convId) => {
|
|
761
|
-
for (const [s, sid] of this.socketToSession.entries()) {
|
|
762
|
-
if (sid === convId) return s;
|
|
763
|
-
}
|
|
764
|
-
return undefined;
|
|
765
|
-
});
|
|
766
|
-
this.socketToSession.delete(socket);
|
|
767
|
-
const cuSessionIds = this.socketToCuSession.get(socket);
|
|
768
|
-
if (cuSessionIds) {
|
|
769
|
-
for (const cuSessionId of cuSessionIds) {
|
|
770
|
-
this.cuObservationParseSequence.delete(cuSessionId);
|
|
771
|
-
const cuSession = this.cuSessions.get(cuSessionId);
|
|
772
|
-
if (cuSession) {
|
|
773
|
-
cuSession.abort();
|
|
774
|
-
this.cuSessions.delete(cuSessionId);
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
this.socketToCuSession.delete(socket);
|
|
779
|
-
log.info("Client disconnected");
|
|
780
|
-
});
|
|
781
|
-
|
|
782
|
-
socket.on("error", (err) => {
|
|
783
|
-
log.error(
|
|
784
|
-
{ err, remoteAddress: socket.remoteAddress },
|
|
785
|
-
"Client socket error",
|
|
786
|
-
);
|
|
787
|
-
});
|
|
788
|
-
}
|
|
789
|
-
|
|
790
428
|
// ── Session management ──────────────────────────────────────────────
|
|
791
429
|
|
|
792
430
|
setHttpPort(port: number): void {
|
|
@@ -795,6 +433,7 @@ export class DaemonServer {
|
|
|
795
433
|
type: "daemon_status",
|
|
796
434
|
httpPort: port,
|
|
797
435
|
version: daemonVersion,
|
|
436
|
+
keyFingerprint: getSigningKeyFingerprint(),
|
|
798
437
|
});
|
|
799
438
|
}
|
|
800
439
|
|
|
@@ -841,49 +480,12 @@ export class DaemonServer {
|
|
|
841
480
|
return changed;
|
|
842
481
|
}
|
|
843
482
|
|
|
844
|
-
private async sendInitialSession(socket: net.Socket): Promise<void> {
|
|
845
|
-
const conversation = conversationStore.getLatestConversation();
|
|
846
|
-
if (!conversation) {
|
|
847
|
-
this.send(socket, {
|
|
848
|
-
type: "daemon_status",
|
|
849
|
-
httpPort: this.httpPort,
|
|
850
|
-
version: daemonVersion,
|
|
851
|
-
});
|
|
852
|
-
return;
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
await this.getOrCreateSession(conversation.id, undefined, false);
|
|
856
|
-
|
|
857
|
-
this.send(socket, {
|
|
858
|
-
type: "session_info",
|
|
859
|
-
sessionId: conversation.id,
|
|
860
|
-
title: conversation.title ?? "New Conversation",
|
|
861
|
-
threadType: normalizeThreadType(conversation.threadType),
|
|
862
|
-
});
|
|
863
|
-
|
|
864
|
-
this.send(socket, {
|
|
865
|
-
type: "daemon_status",
|
|
866
|
-
httpPort: this.httpPort,
|
|
867
|
-
version: daemonVersion,
|
|
868
|
-
});
|
|
869
|
-
}
|
|
870
|
-
|
|
871
483
|
private async getOrCreateSession(
|
|
872
484
|
conversationId: string,
|
|
873
|
-
socket?: net.Socket,
|
|
874
|
-
rebindClient = true,
|
|
875
485
|
options?: SessionCreateOptions,
|
|
876
486
|
): Promise<Session> {
|
|
877
487
|
let session = this.sessions.get(conversationId);
|
|
878
|
-
const sendToClient =
|
|
879
|
-
? (msg: ServerMessage) => this.send(socket, msg)
|
|
880
|
-
: () => {};
|
|
881
|
-
const maybeBindClient = (target: Session): void => {
|
|
882
|
-
if (!rebindClient || !socket) return;
|
|
883
|
-
target.updateClient(sendToClient);
|
|
884
|
-
target.setSandboxOverride(this.socketSandboxOverride.get(socket));
|
|
885
|
-
getSubagentManager().updateParentSender(conversationId, sendToClient);
|
|
886
|
-
};
|
|
488
|
+
const sendToClient = () => {};
|
|
887
489
|
|
|
888
490
|
if (options && Object.values(options).some((v) => v !== undefined)) {
|
|
889
491
|
this.sessionOptions.set(conversationId, {
|
|
@@ -901,7 +503,6 @@ export class DaemonServer {
|
|
|
901
503
|
const pending = this.sessionCreating.get(conversationId);
|
|
902
504
|
if (pending) {
|
|
903
505
|
session = await pending;
|
|
904
|
-
maybeBindClient(session);
|
|
905
506
|
return session;
|
|
906
507
|
}
|
|
907
508
|
|
|
@@ -936,19 +537,14 @@ export class DaemonServer {
|
|
|
936
537
|
provider,
|
|
937
538
|
systemPrompt,
|
|
938
539
|
maxTokens,
|
|
939
|
-
|
|
540
|
+
sendToClient,
|
|
940
541
|
workingDir,
|
|
941
|
-
(msg) => this.broadcast(msg
|
|
542
|
+
(msg) => this.broadcast(msg),
|
|
942
543
|
memoryPolicy,
|
|
943
544
|
);
|
|
944
|
-
|
|
945
|
-
newSession.updateClient(sendToClient, true);
|
|
946
|
-
}
|
|
545
|
+
newSession.updateClient(sendToClient, true);
|
|
947
546
|
await newSession.loadFromDb();
|
|
948
547
|
this.applyTransportMetadata(newSession, storedOptions);
|
|
949
|
-
if (rebindClient && socket) {
|
|
950
|
-
newSession.setSandboxOverride(this.socketSandboxOverride.get(socket));
|
|
951
|
-
}
|
|
952
548
|
this.sessions.set(conversationId, newSession);
|
|
953
549
|
return newSession;
|
|
954
550
|
})();
|
|
@@ -961,23 +557,19 @@ export class DaemonServer {
|
|
|
961
557
|
}
|
|
962
558
|
this.evictor.touch(conversationId);
|
|
963
559
|
} else {
|
|
964
|
-
maybeBindClient(session);
|
|
965
560
|
this.applyTransportMetadata(session, options);
|
|
966
561
|
this.evictor.touch(conversationId);
|
|
967
562
|
}
|
|
968
563
|
return session;
|
|
969
564
|
}
|
|
970
565
|
|
|
971
|
-
// ──
|
|
566
|
+
// ── Handler context ────────────────────────────────────────────────
|
|
972
567
|
|
|
973
568
|
private handlerContext(): HandlerContext {
|
|
974
569
|
return {
|
|
975
570
|
sessions: this.sessions,
|
|
976
|
-
socketToSession: this.socketToSession,
|
|
977
571
|
cuSessions: this.cuSessions,
|
|
978
|
-
socketToCuSession: this.socketToCuSession,
|
|
979
572
|
cuObservationParseSequence: this.cuObservationParseSequence,
|
|
980
|
-
socketSandboxOverride: this.socketSandboxOverride,
|
|
981
573
|
sharedRequestTimestamps: this.sharedRequestTimestamps,
|
|
982
574
|
debounceTimers: this.configWatcher.timers,
|
|
983
575
|
suppressConfigReload: this.configWatcher.suppressConfigReload,
|
|
@@ -987,39 +579,28 @@ export class DaemonServer {
|
|
|
987
579
|
updateConfigFingerprint: () => {
|
|
988
580
|
this.configWatcher.updateFingerprint();
|
|
989
581
|
},
|
|
990
|
-
send: (
|
|
582
|
+
send: (msg) => this.broadcast(msg),
|
|
991
583
|
broadcast: (msg) => this.broadcast(msg),
|
|
992
584
|
clearAllSessions: () => this.clearAllSessions(),
|
|
993
|
-
getOrCreateSession: (id,
|
|
994
|
-
this.getOrCreateSession(id,
|
|
585
|
+
getOrCreateSession: (id, options?) =>
|
|
586
|
+
this.getOrCreateSession(id, options),
|
|
995
587
|
touchSession: (id) => this.evictor.touch(id),
|
|
996
588
|
heartbeatService: this._heartbeatService,
|
|
997
589
|
};
|
|
998
590
|
}
|
|
999
591
|
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
if (changed) this.evictSessionsForReload();
|
|
1013
|
-
this.configWatcher.lastConfigRefreshTime = now;
|
|
1014
|
-
} catch (err) {
|
|
1015
|
-
log.warn(
|
|
1016
|
-
{ err },
|
|
1017
|
-
"Failed to refresh config from secure sources before handling IPC message",
|
|
1018
|
-
);
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
handleMessage(msg, socket, this.handlerContext());
|
|
592
|
+
/** Public subset of handler context for skill management HTTP routes. */
|
|
593
|
+
getSkillContext(): SkillOperationContext {
|
|
594
|
+
return {
|
|
595
|
+
debounceTimers: this.configWatcher.timers,
|
|
596
|
+
setSuppressConfigReload: (value: boolean) => {
|
|
597
|
+
this.configWatcher.suppressConfigReload = value;
|
|
598
|
+
},
|
|
599
|
+
updateConfigFingerprint: () => {
|
|
600
|
+
this.configWatcher.updateFingerprint();
|
|
601
|
+
},
|
|
602
|
+
broadcast: (msg) => this.broadcast(msg),
|
|
603
|
+
};
|
|
1023
604
|
}
|
|
1024
605
|
|
|
1025
606
|
// ── HTTP message processing ─────────────────────────────────────────
|
|
@@ -1050,8 +631,6 @@ export class DaemonServer {
|
|
|
1050
631
|
|
|
1051
632
|
const session = await this.getOrCreateSession(
|
|
1052
633
|
conversationId,
|
|
1053
|
-
undefined,
|
|
1054
|
-
true,
|
|
1055
634
|
options,
|
|
1056
635
|
);
|
|
1057
636
|
|
|
@@ -1121,12 +700,21 @@ export class DaemonServer {
|
|
|
1121
700
|
|
|
1122
701
|
// Register pending interactions so channel approval interception can
|
|
1123
702
|
// find the session by requestId when confirmation/secret events fire.
|
|
1124
|
-
const
|
|
703
|
+
const registrar = makePendingInteractionRegistrar(session, conversationId);
|
|
704
|
+
const onEvent = options?.onEvent
|
|
705
|
+
? (msg: ServerMessage) => {
|
|
706
|
+
registrar(msg);
|
|
707
|
+
try {
|
|
708
|
+
options.onEvent!(msg);
|
|
709
|
+
} catch (err) {
|
|
710
|
+
log.error(
|
|
711
|
+
{ err, conversationId },
|
|
712
|
+
"onEvent callback failed; continuing agent loop",
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
: registrar;
|
|
1125
717
|
if (options?.isInteractive === true) {
|
|
1126
|
-
// Interactive HTTP paths (e.g. channel ingress) still run without an IPC
|
|
1127
|
-
// socket. Route prompter events through the registrar callback so
|
|
1128
|
-
// confirmation_request/secret_request events are tracked, and mark the
|
|
1129
|
-
// session interactive so prompt decisions are not auto-denied.
|
|
1130
718
|
session.updateClient(onEvent, false);
|
|
1131
719
|
}
|
|
1132
720
|
|
|
@@ -1136,8 +724,6 @@ export class DaemonServer {
|
|
|
1136
724
|
isUserMessage: true,
|
|
1137
725
|
})
|
|
1138
726
|
.finally(() => {
|
|
1139
|
-
// Only reset if no other caller (e.g. a real IPC client) has rebound
|
|
1140
|
-
// the session's sender while the agent loop was running.
|
|
1141
727
|
if (
|
|
1142
728
|
options?.isInteractive === true &&
|
|
1143
729
|
session.getCurrentSender() === onEvent
|
|
@@ -1192,7 +778,7 @@ export class DaemonServer {
|
|
|
1192
778
|
: {}),
|
|
1193
779
|
};
|
|
1194
780
|
const userMsg = createUserMessage(content, attachments);
|
|
1195
|
-
const persisted = await
|
|
781
|
+
const persisted = await addMessage(
|
|
1196
782
|
conversationId,
|
|
1197
783
|
"user",
|
|
1198
784
|
JSON.stringify(userMsg.content),
|
|
@@ -1202,7 +788,7 @@ export class DaemonServer {
|
|
|
1202
788
|
|
|
1203
789
|
if (serverTurnCtx) {
|
|
1204
790
|
try {
|
|
1205
|
-
|
|
791
|
+
setConversationOriginChannelIfUnset(
|
|
1206
792
|
conversationId,
|
|
1207
793
|
serverTurnCtx.userMessageChannel,
|
|
1208
794
|
);
|
|
@@ -1215,7 +801,7 @@ export class DaemonServer {
|
|
|
1215
801
|
}
|
|
1216
802
|
if (serverInterfaceCtx) {
|
|
1217
803
|
try {
|
|
1218
|
-
|
|
804
|
+
setConversationOriginInterfaceIfUnset(
|
|
1219
805
|
conversationId,
|
|
1220
806
|
serverInterfaceCtx.userMessageInterface,
|
|
1221
807
|
);
|
|
@@ -1228,7 +814,7 @@ export class DaemonServer {
|
|
|
1228
814
|
}
|
|
1229
815
|
|
|
1230
816
|
const assistantMsg = createAssistantMessage(slashResult.message);
|
|
1231
|
-
await
|
|
817
|
+
await addMessage(
|
|
1232
818
|
conversationId,
|
|
1233
819
|
"assistant",
|
|
1234
820
|
JSON.stringify(assistantMsg.content),
|
|
@@ -1259,12 +845,21 @@ export class DaemonServer {
|
|
|
1259
845
|
|
|
1260
846
|
// Register pending interactions so channel approval interception can
|
|
1261
847
|
// find the session by requestId when confirmation/secret events fire.
|
|
1262
|
-
const
|
|
848
|
+
const registrar = makePendingInteractionRegistrar(session, conversationId);
|
|
849
|
+
const onEvent = options?.onEvent
|
|
850
|
+
? (msg: ServerMessage) => {
|
|
851
|
+
registrar(msg);
|
|
852
|
+
try {
|
|
853
|
+
options.onEvent!(msg);
|
|
854
|
+
} catch (err) {
|
|
855
|
+
log.error(
|
|
856
|
+
{ err, conversationId },
|
|
857
|
+
"onEvent callback failed; continuing agent loop",
|
|
858
|
+
);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
: registrar;
|
|
1263
862
|
if (options?.isInteractive === true) {
|
|
1264
|
-
// Interactive HTTP paths (e.g. channel ingress) still run without an IPC
|
|
1265
|
-
// socket. Route prompter events through the registrar callback so
|
|
1266
|
-
// confirmation_request/secret_request events are tracked, and mark the
|
|
1267
|
-
// session interactive so prompt decisions are not auto-denied.
|
|
1268
863
|
session.updateClient(onEvent, false);
|
|
1269
864
|
}
|
|
1270
865
|
|
|
@@ -1274,8 +869,6 @@ export class DaemonServer {
|
|
|
1274
869
|
isUserMessage: true,
|
|
1275
870
|
});
|
|
1276
871
|
} finally {
|
|
1277
|
-
// Only reset if no other caller (e.g. a real IPC client) has rebound
|
|
1278
|
-
// the session's sender while the agent loop was running.
|
|
1279
872
|
if (
|
|
1280
873
|
options?.isInteractive === true &&
|
|
1281
874
|
session.getCurrentSender() === onEvent
|
|
@@ -1292,15 +885,48 @@ export class DaemonServer {
|
|
|
1292
885
|
* The handler manages busy-state checking and queueing itself.
|
|
1293
886
|
*/
|
|
1294
887
|
async getSessionForMessages(conversationId: string): Promise<Session> {
|
|
1295
|
-
return this.getOrCreateSession(conversationId
|
|
888
|
+
return this.getOrCreateSession(conversationId);
|
|
1296
889
|
}
|
|
1297
890
|
|
|
1298
891
|
/**
|
|
1299
892
|
* Look up an active session by ID without creating one.
|
|
1300
893
|
* Checks both normal sessions and computer-use sessions so the HTTP
|
|
1301
|
-
* surface-action path is consistent with
|
|
894
|
+
* surface-action path is consistent with dispatch.
|
|
1302
895
|
*/
|
|
1303
896
|
findSession(sessionId: string): Session | ComputerUseSession | undefined {
|
|
1304
897
|
return this.cuSessions.get(sessionId) ?? this.sessions.get(sessionId);
|
|
1305
898
|
}
|
|
899
|
+
|
|
900
|
+
/**
|
|
901
|
+
* Look up an active session that owns a given surfaceId.
|
|
902
|
+
* Falls back across both normal and computer-use sessions.
|
|
903
|
+
*/
|
|
904
|
+
findSessionBySurfaceId(
|
|
905
|
+
surfaceId: string,
|
|
906
|
+
): Session | ComputerUseSession | undefined {
|
|
907
|
+
for (const s of this.cuSessions.values()) {
|
|
908
|
+
if (s.surfaceState.has(surfaceId)) return s;
|
|
909
|
+
}
|
|
910
|
+
for (const s of this.sessions.values()) {
|
|
911
|
+
if (s.surfaceState.has(surfaceId)) return s;
|
|
912
|
+
}
|
|
913
|
+
return undefined;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
/**
|
|
917
|
+
* Expose the handler context for use by session management HTTP routes.
|
|
918
|
+
* The context is built on-the-fly so it always reflects the current server state.
|
|
919
|
+
*/
|
|
920
|
+
getHandlerContext(): HandlerContext {
|
|
921
|
+
return this.handlerContext();
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/** Extract sessionId from a ServerMessage if present. */
|
|
926
|
+
function extractSessionId(msg: ServerMessage): string | undefined {
|
|
927
|
+
const record = msg as unknown as Record<string, unknown>;
|
|
928
|
+
if ("sessionId" in msg && typeof record.sessionId === "string") {
|
|
929
|
+
return record.sessionId as string;
|
|
930
|
+
}
|
|
931
|
+
return undefined;
|
|
1306
932
|
}
|