@vellumai/assistant 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +6 -7
- package/Dockerfile +1 -0
- package/README.md +2 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +79 -139
- package/bun.lock +3 -0
- package/docs/architecture/security.md +18 -16
- package/knip.json +1 -0
- package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -5
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
- package/node_modules/@vellumai/slack-text/bun.lock +24 -0
- package/node_modules/@vellumai/slack-text/package.json +18 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
- package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
- package/openapi.yaml +294 -107
- package/package.json +4 -2
- package/scripts/generate-openapi.ts +16 -111
- package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
- package/src/__tests__/anthropic-provider.test.ts +56 -13
- package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
- package/src/__tests__/app-conversation-ids.test.ts +151 -0
- package/src/__tests__/approval-cascade.test.ts +0 -15
- package/src/__tests__/approval-routes-http.test.ts +6 -17
- package/src/__tests__/assistant-event-hub.test.ts +126 -77
- package/src/__tests__/assistant-event.test.ts +0 -5
- package/src/__tests__/assistant-events-sse-hardening.test.ts +37 -15
- package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -29
- package/src/__tests__/background-shell-host-bash.test.ts +34 -43
- package/src/__tests__/call-controller.test.ts +1 -1
- package/src/__tests__/call-site-routing-provider.test.ts +193 -0
- package/src/__tests__/channel-approval-routes.test.ts +10 -296
- package/src/__tests__/channel-approvals.test.ts +25 -17
- package/src/__tests__/channel-guardian.test.ts +100 -146
- package/src/__tests__/checker.test.ts +20 -34
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/config-schema.test.ts +6 -48
- package/src/__tests__/config-watcher.test.ts +12 -0
- package/src/__tests__/connection-policy.test.ts +1 -52
- package/src/__tests__/contacts-write.test.ts +2 -64
- package/src/__tests__/context-image-dimensions.test.ts +1 -1
- package/src/__tests__/context-search-memory-source.test.ts +120 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
- package/src/__tests__/context-search-pkb-source.test.ts +49 -0
- package/src/__tests__/context-search-workspace-source.test.ts +9 -22
- package/src/__tests__/context-window-manager.test.ts +46 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
- package/src/__tests__/conversation-agent-loop.test.ts +980 -13
- package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
- package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
- package/src/__tests__/conversation-history-web-search.test.ts +4 -3
- package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
- package/src/__tests__/conversation-lifecycle.test.ts +4 -4
- package/src/__tests__/conversation-process-callsite.test.ts +79 -2
- package/src/__tests__/conversation-queue.test.ts +3 -8
- package/src/__tests__/conversation-routes-disk-view.test.ts +1 -161
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -32
- package/src/__tests__/conversation-routes-slash-commands.test.ts +75 -66
- package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
- package/src/__tests__/conversation-slash-commands.test.ts +24 -4
- package/src/__tests__/conversation-slash-queue.test.ts +2 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-starter-routes.test.ts +79 -2
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
- package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
- package/src/__tests__/conversation-usage.test.ts +253 -3
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
- package/src/__tests__/credential-health-service.test.ts +68 -0
- package/src/__tests__/credential-security-e2e.test.ts +4 -3
- package/src/__tests__/credential-security-invariants.test.ts +1 -5
- package/src/__tests__/credential-token-resolver.test.ts +180 -0
- package/src/__tests__/cu-unified-flow.test.ts +33 -16
- package/src/__tests__/daemon-assistant-events.test.ts +34 -21
- package/src/__tests__/daemon-credential-client.test.ts +4 -1
- package/src/__tests__/db-connection-isolation.test.ts +125 -0
- package/src/__tests__/db-migration-rollback.test.ts +101 -0
- package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
- package/src/__tests__/document-conversations.test.ts +332 -0
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
- package/src/__tests__/emit-event-signal.test.ts +4 -6
- package/src/__tests__/events-client-registration.test.ts +193 -49
- package/src/__tests__/filing-service.test.ts +58 -7
- package/src/__tests__/first-greeting.test.ts +156 -150
- package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
- package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -1
- package/src/__tests__/guardian-grant-minting.test.ts +7 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
- package/src/__tests__/guardian-routing-state.test.ts +1 -1
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +32 -11
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -83
- package/src/__tests__/headless-browser-mode.test.ts +4 -9
- package/src/__tests__/headless-browser-navigate.test.ts +21 -20
- package/src/__tests__/heartbeat-service.test.ts +289 -7
- package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
- package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
- package/src/__tests__/host-bash-proxy.test.ts +46 -122
- package/src/__tests__/host-browser-e2e-cloud.test.ts +36 -497
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +26 -96
- package/src/__tests__/host-browser-proxy.test.ts +111 -185
- package/src/__tests__/host-browser-routes.test.ts +45 -75
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +26 -30
- package/src/__tests__/host-cu-proxy.test.ts +56 -111
- package/src/__tests__/host-file-proxy.test.ts +44 -98
- package/src/__tests__/host-file-read-tool.test.ts +42 -21
- package/src/__tests__/host-shell-tool.test.ts +33 -68
- package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
- package/src/__tests__/host-transfer-proxy.test.ts +43 -53
- package/src/__tests__/http-user-message-parity.test.ts +0 -6
- package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
- package/src/__tests__/injector-chain.test.ts +10 -5
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -66
- package/src/__tests__/inline-skill-load-permissions.test.ts +0 -2
- package/src/__tests__/install-skill-routing.test.ts +1 -13
- package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
- package/src/__tests__/llm-catalog-parity.test.ts +90 -0
- package/src/__tests__/llm-context-resolution.test.ts +180 -0
- package/src/__tests__/llm-resolver.test.ts +80 -12
- package/src/__tests__/llm-usage-store.test.ts +269 -4
- package/src/__tests__/log-export-routes.test.ts +89 -0
- package/src/__tests__/managed-profile-guard.test.ts +225 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -10
- package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
- package/src/__tests__/migration-export-http.test.ts +33 -26
- package/src/__tests__/migration-export-streaming.test.ts +18 -10
- package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
- package/src/__tests__/migration-import-commit-http.test.ts +66 -21
- package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
- package/src/__tests__/migration-import-from-url.test.ts +20 -6
- package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
- package/src/__tests__/migration-parity-persistence.test.ts +62 -25
- package/src/__tests__/migration-transport.test.ts +115 -23
- package/src/__tests__/migration-validate-http.test.ts +105 -80
- package/src/__tests__/migration-wizard.test.ts +133 -27
- package/src/__tests__/non-member-access-request.test.ts +1 -1
- package/src/__tests__/notification-guardian-path.test.ts +1 -1
- package/src/__tests__/oauth-store.test.ts +19 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +21 -12
- package/src/__tests__/prechat-onboarding-contract.test.ts +31 -7
- package/src/__tests__/pricing.test.ts +68 -4
- package/src/__tests__/process-message-background-slack.test.ts +331 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
- package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
- package/src/__tests__/provider-usage-tracking.test.ts +208 -0
- package/src/__tests__/reaction-persistence.test.ts +9 -6
- package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
- package/src/__tests__/recording-handler.test.ts +64 -81
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
- package/src/__tests__/relay-server.test.ts +18 -13
- package/src/__tests__/require-fresh-approval.test.ts +13 -22
- package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
- package/src/__tests__/runtime-events-sse.test.ts +3 -12
- package/src/__tests__/search-skills-unified.test.ts +9 -15
- package/src/__tests__/secret-ingress-cli.test.ts +2 -5
- package/src/__tests__/secret-ingress-http.test.ts +0 -4
- package/src/__tests__/secret-onetime-send.test.ts +4 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
- package/src/__tests__/secret-response-routing.test.ts +29 -15
- package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
- package/src/__tests__/secret-scanner.test.ts +2 -545
- package/src/__tests__/send-endpoint-busy.test.ts +9 -24
- package/src/__tests__/settings-routes.test.ts +1 -1
- package/src/__tests__/shell-credential-ref.test.ts +0 -8
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -56
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -11
- package/src/__tests__/skill-tool-factory.test.ts +97 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
- package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
- package/src/__tests__/slack-inbound-verification.test.ts +1 -62
- package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
- package/src/__tests__/subagent-manager-notify.test.ts +70 -70
- package/src/__tests__/subagent-notify-parent.test.ts +80 -83
- package/src/__tests__/system-prompt.test.ts +115 -13
- package/src/__tests__/terminal-tools.test.ts +0 -89
- package/src/__tests__/thread-backfill.test.ts +945 -31
- package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -6
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -16
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -7
- package/src/__tests__/tool-executor.test.ts +12 -19
- package/src/__tests__/tool-metrics-listener.test.ts +0 -35
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/tool-trace-listener.test.ts +0 -17
- package/src/__tests__/transfer-progress-screen.test.ts +63 -26
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
- package/src/__tests__/trusted-contact-verification.test.ts +1 -1
- package/src/__tests__/tts-catalog-parity.test.ts +16 -5
- package/src/__tests__/usage-attribution.test.ts +247 -0
- package/src/__tests__/usage-cli.test.ts +143 -0
- package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
- package/src/__tests__/usage-routes.test.ts +150 -0
- package/src/__tests__/validation-results-screen.test.ts +39 -16
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +49 -137
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -7
- package/src/__tests__/voice-session-bridge.test.ts +5 -5
- package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
- package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
- package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
- package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
- package/src/acp/index.ts +0 -15
- package/src/acp/session-manager.ts +37 -34
- package/src/agent/loop.ts +16 -1
- package/src/approvals/AGENTS.md +4 -0
- package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
- package/src/approvals/guardian-request-resolvers.ts +10 -2
- package/src/backup/__tests__/backup-worker.test.ts +36 -8
- package/src/backup/__tests__/paths.test.ts +2 -2
- package/src/backup/__tests__/restore.test.ts +45 -28
- package/src/backup/backup-worker.ts +36 -2
- package/src/backup/paths.ts +9 -6
- package/src/browser-session/events.ts +0 -9
- package/src/calls/call-store.ts +1 -34
- package/src/calls/guardian-question-copy.ts +0 -108
- package/src/calls/relay-server.ts +0 -24
- package/src/calls/twilio-rest.ts +0 -38
- package/src/calls/twilio-routes.ts +1 -1
- package/src/calls/voice-session-bridge.ts +7 -38
- package/src/channels/types.ts +1 -36
- package/src/cli/commands/__tests__/cache.test.ts +152 -5
- package/src/cli/commands/__tests__/memory-v2.test.ts +14 -28
- package/src/cli/commands/__tests__/trust.test.ts +21 -387
- package/src/cli/commands/backup.ts +4 -4
- package/src/cli/commands/cache-fs.ts +8 -0
- package/src/cli/commands/cache.ts +153 -82
- package/src/cli/commands/clients.ts +63 -5
- package/src/cli/commands/completions.ts +3 -3
- package/src/cli/commands/contacts.ts +231 -76
- package/src/cli/commands/keys.ts +4 -1
- package/src/cli/commands/memory-v2.ts +24 -52
- package/src/cli/commands/oauth/shared.ts +2 -29
- package/src/cli/commands/pending.ts +102 -0
- package/src/cli/commands/skills.ts +77 -35
- package/src/cli/commands/trust.ts +70 -430
- package/src/cli/commands/usage.ts +25 -16
- package/src/cli/lib/daemon-credential-client.ts +14 -0
- package/src/cli/program.ts +2 -0
- package/src/cli.ts +0 -21
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/bundled-skills/messaging/TOOLS.json +14 -4
- package/src/config/env-registry.ts +12 -2
- package/src/config/env.ts +3 -14
- package/src/config/feature-flag-registry.json +30 -30
- package/src/config/llm-callsite-catalog.ts +12 -0
- package/src/config/llm-context-resolution.ts +80 -0
- package/src/config/llm-resolver.ts +58 -22
- package/src/config/loader.ts +3 -3
- package/src/config/schema.ts +2 -158
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +271 -0
- package/src/config/schemas/calls.ts +5 -5
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/ingress.ts +1 -1
- package/src/config/schemas/llm.ts +31 -3
- package/src/config/schemas/memory-retrieval.ts +2 -2
- package/src/config/schemas/memory-v2.ts +9 -0
- package/src/config/schemas/security.ts +1 -42
- package/src/config/schemas/services.ts +6 -6
- package/src/config/schemas/skills.ts +5 -5
- package/src/config/schemas/tts.ts +1 -1
- package/src/config/seed-inference-profiles.ts +117 -0
- package/src/config/skills.ts +0 -90
- package/src/config/types.ts +3 -6
- package/src/contacts/contact-store.ts +0 -17
- package/src/contacts/contacts-write.ts +1 -105
- package/src/context/window-manager.ts +44 -5
- package/src/credential-execution/process-manager.ts +34 -10
- package/src/credential-health/credential-health-service.ts +21 -16
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
- package/src/daemon/connection-policy.ts +1 -26
- package/src/daemon/conversation-agent-loop-handlers.ts +53 -4
- package/src/daemon/conversation-agent-loop.ts +277 -36
- package/src/daemon/conversation-history.ts +8 -8
- package/src/daemon/conversation-launch.ts +20 -135
- package/src/daemon/conversation-lifecycle.ts +1 -1
- package/src/daemon/conversation-messaging.ts +1 -0
- package/src/daemon/conversation-process.ts +83 -163
- package/src/daemon/conversation-runtime-assembly.ts +219 -76
- package/src/daemon/conversation-slash.ts +47 -5
- package/src/daemon/conversation-store.ts +7 -31
- package/src/daemon/conversation-surfaces.ts +22 -28
- package/src/daemon/conversation-tool-setup.ts +3 -33
- package/src/daemon/conversation-usage.ts +36 -0
- package/src/daemon/conversation.ts +117 -233
- package/src/daemon/daemon-control.ts +3 -71
- package/src/daemon/daemon-skill-host.ts +8 -11
- package/src/daemon/dictation-profile-store.ts +2 -26
- package/src/daemon/first-greeting.ts +44 -156
- package/src/daemon/handlers/config-channels.ts +12 -12
- package/src/daemon/handlers/config-ingress.ts +4 -165
- package/src/daemon/handlers/config-model.ts +1 -1
- package/src/daemon/handlers/config-voice.ts +0 -42
- package/src/daemon/handlers/conversations.ts +11 -190
- package/src/daemon/handlers/recording.ts +26 -158
- package/src/daemon/handlers/shared.ts +23 -71
- package/src/daemon/handlers/skills.ts +42 -93
- package/src/daemon/host-bash-proxy.ts +67 -45
- package/src/daemon/host-browser-proxy.ts +65 -27
- package/src/daemon/host-cu-proxy.ts +40 -39
- package/src/daemon/host-file-proxy.ts +58 -37
- package/src/daemon/host-transfer-proxy.ts +84 -46
- package/src/daemon/lifecycle.ts +49 -15
- package/src/daemon/message-types/conversations.ts +7 -0
- package/src/daemon/message-types/host-bash.ts +1 -0
- package/src/daemon/message-types/host-cu.ts +1 -0
- package/src/daemon/message-types/host-file.ts +1 -0
- package/src/daemon/message-types/host-transfer.ts +1 -0
- package/src/daemon/message-types/messages.ts +10 -9
- package/src/daemon/message-types/workspace.ts +1 -1
- package/src/daemon/process-message.ts +102 -239
- package/src/daemon/server.ts +13 -462
- package/src/daemon/shutdown-handlers.ts +2 -2
- package/src/daemon/tool-side-effects.ts +125 -107
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +4 -9
- package/src/events/domain-events.ts +0 -8
- package/src/events/tool-audit-listener.ts +3 -1
- package/src/events/tool-domain-event-publisher.ts +0 -10
- package/src/events/tool-metrics-listener.ts +0 -17
- package/src/events/tool-trace-listener.ts +0 -14
- package/src/filing/filing-service.ts +13 -1
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +6 -2
- package/src/heartbeat/heartbeat-service.ts +23 -5
- package/src/home/__tests__/feed-writer.test.ts +0 -4
- package/src/home/__tests__/relationship-state-writer.test.ts +30 -0
- package/src/home/feed-writer.ts +1 -2
- package/src/home/relationship-state-writer.ts +16 -3
- package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
- package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
- package/src/ipc/assistant-server.ts +3 -10
- package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
- package/src/ipc/routes/route-adapter.ts +1 -1
- package/src/ipc/routes/trust-rules.test.ts +0 -95
- package/src/ipc/skill-ipc-types.ts +41 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
- package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
- package/src/ipc/skill-routes/events.ts +12 -23
- package/src/ipc/skill-routes/identity.ts +4 -17
- package/src/ipc/skill-routes/index.ts +1 -1
- package/src/ipc/skill-server.ts +6 -39
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
- package/src/live-voice/protocol.ts +4 -13
- package/src/mcp/manager.ts +0 -5
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
- package/src/memory/app-git-service.ts +0 -32
- package/src/memory/app-store.ts +154 -0
- package/src/memory/attachments-store.ts +6 -0
- package/src/memory/context-search/sources/memory-v2.ts +578 -0
- package/src/memory/context-search/sources/memory.ts +5 -0
- package/src/memory/context-search/sources/pkb.ts +10 -1
- package/src/memory/context-search/sources/workspace.ts +3 -2
- package/src/memory/conversation-crud.ts +29 -4
- package/src/memory/conversation-disk-view.ts +1 -5
- package/src/memory/conversation-starter-checkpoints.ts +63 -0
- package/src/memory/db-connection.ts +62 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +3 -21
- package/src/memory/embedding-gemini.ts +0 -2
- package/src/memory/embedding-local.ts +6 -6
- package/src/memory/embedding-ollama.ts +6 -6
- package/src/memory/embedding-openai.ts +6 -6
- package/src/memory/embedding-types.ts +21 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +3 -7
- package/src/memory/graph/conversation-graph-memory.ts +35 -13
- package/src/memory/graph/injection.test.ts +2 -2
- package/src/memory/graph/injection.ts +1 -1
- package/src/memory/guardian-action-store.ts +0 -83
- package/src/memory/guardian-approvals.ts +0 -48
- package/src/memory/indexer.ts +1 -15
- package/src/memory/job-handlers/conversation-starters.ts +36 -53
- package/src/memory/job-utils.ts +0 -6
- package/src/memory/jobs-store.ts +0 -1
- package/src/memory/jobs-worker.ts +2 -16
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +129 -43
- package/src/memory/memory-v2-activation-log-store.ts +115 -0
- package/src/memory/migrations/233-document-conversations.ts +54 -0
- package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
- package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
- package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
- package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
- package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
- package/src/memory/migrations/index.ts +14 -0
- package/src/memory/migrations/registry.ts +24 -0
- package/src/memory/raw-query.ts +2 -68
- package/src/memory/schema/conversations.ts +7 -0
- package/src/memory/schema/infrastructure.ts +25 -0
- package/src/memory/search/semantic.ts +5 -16
- package/src/memory/tool-usage-store.ts +2 -0
- package/src/memory/usage-buckets.ts +40 -1
- package/src/memory/usage-grouped-buckets.ts +127 -0
- package/src/memory/v2/__tests__/activation.test.ts +289 -90
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
- package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
- package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
- package/src/memory/v2/__tests__/injection.test.ts +384 -15
- package/src/memory/v2/__tests__/migration.test.ts +64 -36
- package/src/memory/v2/__tests__/page-store.test.ts +191 -8
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
- package/src/memory/v2/__tests__/static-context.test.ts +153 -0
- package/src/memory/v2/activation.ts +168 -97
- package/src/memory/v2/backfill-jobs.ts +15 -100
- package/src/memory/v2/consolidation-job.ts +14 -12
- package/src/memory/v2/edge-index.ts +191 -0
- package/src/memory/v2/injection.ts +182 -58
- package/src/memory/v2/migration.ts +57 -64
- package/src/memory/v2/now-text.ts +2 -3
- package/src/memory/v2/page-store.ts +168 -31
- package/src/memory/v2/prompts/consolidation.ts +118 -42
- package/src/memory/v2/prompts/sweep.ts +3 -3
- package/src/memory/v2/skill-store.ts +55 -7
- package/src/memory/v2/static-context.ts +62 -0
- package/src/memory/v2/types.ts +10 -20
- package/src/memory/validation.ts +0 -11
- package/src/messaging/draft-store.ts +0 -6
- package/src/messaging/provider-types.ts +8 -0
- package/src/messaging/provider.ts +7 -0
- package/src/messaging/providers/gmail/client.ts +1 -121
- package/src/messaging/providers/outlook/client.ts +0 -73
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
- package/src/messaging/providers/slack/adapter.ts +122 -21
- package/src/messaging/providers/slack/backfill.test.ts +95 -6
- package/src/messaging/providers/slack/backfill.ts +89 -11
- package/src/messaging/providers/slack/client.ts +10 -124
- package/src/messaging/providers/slack/message-metadata.ts +12 -2
- package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
- package/src/messaging/providers/slack/render-transcript.ts +126 -25
- package/src/messaging/providers/slack/types.ts +1 -0
- package/src/oauth/connection-resolver.test.ts +8 -0
- package/src/oauth/connection-resolver.ts +8 -16
- package/src/oauth/credential-token-resolver.ts +97 -0
- package/src/oauth/manual-token-connection.ts +30 -34
- package/src/oauth/oauth-store.ts +6 -4
- package/src/outbound-proxy/certs.ts +0 -7
- package/src/outbound-proxy/config.ts +0 -74
- package/src/outbound-proxy/health.ts +0 -44
- package/src/outbound-proxy/index.ts +0 -22
- package/src/permissions/approval-provenance.test.ts +184 -0
- package/src/permissions/approval-provenance.ts +70 -0
- package/src/permissions/checker.ts +4 -1
- package/src/permissions/gateway-threshold-reader.ts +4 -1
- package/src/permissions/prompter.ts +9 -2
- package/src/permissions/secret-prompter.ts +21 -48
- package/src/permissions/types.ts +33 -0
- package/src/permissions/workspace-policy.ts +0 -5
- package/src/platform/sync-identity.ts +0 -8
- package/src/plugins/defaults/injectors.ts +69 -2
- package/src/plugins/defaults/overflow-reduce.ts +3 -2
- package/src/plugins/types.ts +8 -0
- package/src/prompts/system-prompt.ts +34 -70
- package/src/prompts/templates/BOOTSTRAP.md +52 -6
- package/src/prompts/update-bulletin-job.ts +2 -0
- package/src/providers/__tests__/retry-callsite.test.ts +138 -1
- package/src/providers/anthropic/client.ts +72 -33
- package/src/providers/call-site-routing.ts +42 -3
- package/src/providers/gemini/client.ts +18 -2
- package/src/providers/managed-proxy/context.ts +0 -5
- package/src/providers/model-catalog.ts +105 -19
- package/src/providers/openai/chat-completions-provider.ts +6 -0
- package/src/providers/openai/responses-provider.ts +7 -1
- package/src/providers/provider-send-message.ts +45 -2
- package/src/providers/ratelimit.ts +7 -2
- package/src/providers/registry.ts +14 -9
- package/src/providers/retry.ts +96 -8
- package/src/providers/types.ts +13 -0
- package/src/providers/usage-tracking.ts +96 -0
- package/src/runtime/AGENTS.md +10 -6
- package/src/runtime/__tests__/agent-wake.test.ts +89 -0
- package/src/runtime/agent-wake.ts +39 -2
- package/src/runtime/assistant-event-hub.ts +541 -45
- package/src/runtime/assistant-event.ts +1 -6
- package/src/runtime/auth/context.ts +0 -9
- package/src/runtime/auth/middleware.ts +1 -1
- package/src/runtime/auth/route-policy.ts +11 -9
- package/src/runtime/auth/token-service.ts +0 -11
- package/src/runtime/channel-approvals.ts +6 -2
- package/src/runtime/channel-verification-service.ts +3 -5
- package/src/runtime/http-errors.ts +0 -34
- package/src/runtime/http-router.ts +6 -3
- package/src/runtime/http-server.ts +22 -82
- package/src/runtime/http-types.ts +5 -0
- package/src/runtime/interactive-ui.ts +0 -1
- package/src/runtime/middleware/auth.ts +0 -20
- package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
- package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +143 -79
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +371 -0
- package/src/runtime/migrations/migration-transport.ts +46 -13
- package/src/runtime/migrations/migration-wizard.ts +2 -2
- package/src/runtime/migrations/origin-mode.ts +40 -0
- package/src/runtime/migrations/vbundle-builder.ts +133 -79
- package/src/runtime/migrations/vbundle-import-analyzer.ts +9 -7
- package/src/runtime/migrations/vbundle-importer.ts +7 -7
- package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
- package/src/runtime/migrations/vbundle-streaming-importer.ts +3 -3
- package/src/runtime/migrations/vbundle-streaming-validator.ts +48 -26
- package/src/runtime/migrations/vbundle-validator.ts +214 -41
- package/src/runtime/pending-interactions.ts +13 -4
- package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
- package/src/runtime/routes/__tests__/backup-routes.test.ts +28 -19
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +235 -0
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
- package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
- package/src/runtime/routes/acp-routes.test.ts +0 -3
- package/src/runtime/routes/acp-routes.ts +3 -7
- package/src/runtime/routes/app-management-routes.ts +18 -9
- package/src/runtime/routes/approval-routes.ts +55 -14
- package/src/runtime/routes/avatar-routes.ts +3 -5
- package/src/runtime/routes/browser-routes.ts +1 -15
- package/src/runtime/routes/channel-guardian-routes.ts +1 -5
- package/src/runtime/routes/channel-readiness-routes.ts +3 -7
- package/src/runtime/routes/channel-route-shared.ts +2 -28
- package/src/runtime/routes/client-routes.ts +45 -12
- package/src/runtime/routes/consolidation-routes.ts +115 -0
- package/src/runtime/routes/conversation-list-routes.ts +12 -29
- package/src/runtime/routes/conversation-management-routes.ts +14 -51
- package/src/runtime/routes/conversation-query-routes.ts +120 -8
- package/src/runtime/routes/conversation-routes.ts +44 -528
- package/src/runtime/routes/conversation-starter-routes.ts +19 -40
- package/src/runtime/routes/documents-routes.ts +53 -18
- package/src/runtime/routes/events-routes.ts +59 -91
- package/src/runtime/routes/filing-routes.ts +18 -1
- package/src/runtime/routes/guardian-action-routes.ts +4 -9
- package/src/runtime/routes/host-bash-routes.ts +3 -2
- package/src/runtime/routes/host-browser-routes.ts +9 -33
- package/src/runtime/routes/host-cu-routes.ts +6 -1
- package/src/runtime/routes/host-file-routes.ts +3 -2
- package/src/runtime/routes/host-transfer-routes.ts +11 -15
- package/src/runtime/routes/identity-routes.ts +78 -6
- package/src/runtime/routes/inbound-message-handler.ts +580 -137
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -88
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
- package/src/runtime/routes/index.ts +4 -0
- package/src/runtime/routes/integrations/slack/channel.ts +0 -24
- package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
- package/src/runtime/routes/memory-v2-routes.ts +10 -15
- package/src/runtime/routes/migration-routes.ts +188 -31
- package/src/runtime/routes/playground/guard.ts +1 -1
- package/src/runtime/routes/playground/index.ts +0 -2
- package/src/runtime/routes/recording-routes.ts +4 -24
- package/src/runtime/routes/rename-conversation-routes.ts +2 -6
- package/src/runtime/routes/schedule-routes.ts +3 -6
- package/src/runtime/routes/secret-routes.ts +87 -18
- package/src/runtime/routes/settings-routes.ts +29 -28
- package/src/runtime/routes/skills-routes.ts +12 -31
- package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
- package/src/runtime/routes/task-routes.ts +6 -6
- package/src/runtime/routes/trust-rules-routes.ts +3 -94
- package/src/runtime/routes/types.ts +4 -4
- package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
- package/src/runtime/routes/usage-routes.ts +87 -10
- package/src/runtime/routes/user-routes.ts +17 -31
- package/src/runtime/routes/work-items-routes.ts +1 -4
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
- package/src/runtime/services/analyze-conversation.ts +7 -17
- package/src/runtime/services/conversation-serializer.ts +2 -4
- package/src/runtime/verification-outbound-actions.ts +1 -1
- package/src/runtime/verification-rate-limiter.ts +1 -1
- package/src/schedule/schedule-store.ts +0 -16
- package/src/security/secret-scanner.ts +14 -547
- package/src/security/secure-keys.ts +31 -11
- package/src/security/token-manager.ts +7 -3
- package/src/signals/cancel.ts +16 -25
- package/src/signals/conversation-undo.ts +2 -27
- package/src/signals/emit-event.ts +1 -2
- package/src/signals/user-message.ts +108 -22
- package/src/skills/catalog-install.ts +1 -0
- package/src/skills/clawhub.ts +2 -2
- package/src/skills/inline-command-runner.ts +1 -7
- package/src/subagent/manager.ts +67 -84
- package/src/tasks/task-store.ts +1 -28
- package/src/telemetry/types.ts +6 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +38 -15
- package/src/telemetry/usage-telemetry-reporter.ts +3 -5
- package/src/tools/acp/spawn.test.ts +1 -2
- package/src/tools/acp/steer.test.ts +1 -2
- package/src/tools/browser/__tests__/browser-status.test.ts +44 -127
- package/src/tools/browser/browser-execution.ts +31 -147
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +92 -68
- package/src/tools/browser/cdp-client/factory.ts +48 -76
- package/src/tools/browser/cdp-client/index.ts +1 -14
- package/src/tools/executor.ts +44 -31
- package/src/tools/host-filesystem/edit.ts +3 -2
- package/src/tools/host-filesystem/read.ts +3 -2
- package/src/tools/host-filesystem/transfer.test.ts +45 -42
- package/src/tools/host-filesystem/transfer.ts +4 -3
- package/src/tools/host-filesystem/write.ts +3 -2
- package/src/tools/host-terminal/host-shell.ts +4 -3
- package/src/tools/network/script-proxy/index.ts +1 -10
- package/src/tools/permission-checker.ts +66 -1
- package/src/tools/skills/sandbox-runner.ts +1 -6
- package/src/tools/skills/skill-tool-factory.ts +32 -0
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/terminal/shell.ts +2 -78
- package/src/tools/types.ts +12 -39
- package/src/tts/__tests__/provider-catalog.test.ts +2 -2
- package/src/tts/provider-catalog.ts +1 -1
- package/src/usage/actors.ts +2 -1
- package/src/usage/attribution.ts +185 -0
- package/src/usage/pricing.ts +166 -0
- package/src/usage/types.ts +14 -0
- package/src/util/json.ts +13 -0
- package/src/util/logger.ts +3 -3
- package/src/util/pricing.ts +50 -3
- package/src/work-items/work-item-runner.ts +15 -42
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +4 -3
- package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
- package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +59 -0
- package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
- package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
- package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/provider-commit-message-generator.ts +3 -3
- package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
- package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
- package/src/__tests__/secret-detection-handler.test.ts +0 -67
- package/src/__tests__/secret-scanner-executor.test.ts +0 -450
- package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
- package/src/__tests__/terminal-sandbox.test.ts +0 -374
- package/src/__tests__/tool-notification-listener.test.ts +0 -65
- package/src/context/__tests__/microcompact.test.ts +0 -805
- package/src/context/microcompact.ts +0 -443
- package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
- package/src/events/tool-notification-listener.ts +0 -17
- package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
- package/src/memory/v2/__tests__/edges.test.ts +0 -435
- package/src/memory/v2/edges.ts +0 -217
- package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
- package/src/runtime/__tests__/client-registry.test.ts +0 -271
- package/src/runtime/chrome-extension-registry.ts +0 -368
- package/src/runtime/client-registry.ts +0 -254
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
- package/src/tools/secret-detection-handler.ts +0 -269
- package/src/tools/terminal/backends/native.ts +0 -327
- package/src/tools/terminal/backends/types.ts +0 -37
- package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
- package/src/tools/terminal/sandbox.ts +0 -40
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
import {
|
|
15
15
|
isCredentialError,
|
|
16
16
|
isTokenExpired,
|
|
17
|
-
oauthConnectionAccessTokenPath,
|
|
18
17
|
oauthConnectionRefreshTokenPath,
|
|
19
18
|
persistRefreshedTokens,
|
|
20
19
|
RefreshCircuitBreaker,
|
|
@@ -22,6 +21,7 @@ import {
|
|
|
22
21
|
type SecureKeyBackend,
|
|
23
22
|
} from "@vellumai/credential-storage";
|
|
24
23
|
|
|
24
|
+
import { getConnectionAccessTokenResult } from "../oauth/credential-token-resolver.js";
|
|
25
25
|
import {
|
|
26
26
|
getApp,
|
|
27
27
|
getConnection,
|
|
@@ -321,9 +321,13 @@ export async function withValidToken<T>(
|
|
|
321
321
|
opts && typeof opts === "object"
|
|
322
322
|
? getConnection(opts.connectionId)
|
|
323
323
|
: getConnectionByProvider(service, opts);
|
|
324
|
-
|
|
325
|
-
? await
|
|
324
|
+
const tokenResult = conn
|
|
325
|
+
? await getConnectionAccessTokenResult({
|
|
326
|
+
provider: conn.provider,
|
|
327
|
+
connectionId: conn.id,
|
|
328
|
+
})
|
|
326
329
|
: undefined;
|
|
330
|
+
let token = tokenResult?.value;
|
|
327
331
|
if (!token || !conn) {
|
|
328
332
|
throw new TokenExpiredError(
|
|
329
333
|
service,
|
package/src/signals/cancel.ts
CHANGED
|
@@ -5,34 +5,23 @@
|
|
|
5
5
|
* HTTP POST to `/v1/conversations/:id/cancel`. The daemon's ConfigWatcher
|
|
6
6
|
* detects the file change and invokes {@link handleCancelSignal}, which
|
|
7
7
|
* reads the payload and aborts the target conversation.
|
|
8
|
-
*
|
|
9
|
-
* Because the signal handler needs access to the daemon's conversation map, the
|
|
10
|
-
* daemon registers a callback at startup via {@link registerCancelCallback}.
|
|
11
8
|
*/
|
|
12
9
|
|
|
13
10
|
import { readFileSync } from "node:fs";
|
|
14
11
|
import { join } from "node:path";
|
|
15
12
|
|
|
16
13
|
import { getIsContainerized } from "../config/env-registry.js";
|
|
14
|
+
import {
|
|
15
|
+
findConversation,
|
|
16
|
+
touchConversation,
|
|
17
|
+
} from "../daemon/conversation-store.js";
|
|
18
|
+
import { getSubagentManager } from "../subagent/index.js";
|
|
19
|
+
import { createAbortReason } from "../util/abort-reasons.js";
|
|
17
20
|
import { getLogger } from "../util/logger.js";
|
|
18
21
|
import { getSignalsDir } from "../util/platform.js";
|
|
19
22
|
|
|
20
23
|
const log = getLogger("signal:cancel");
|
|
21
24
|
|
|
22
|
-
// ── Daemon callback registry ─────────────────────────────────────────
|
|
23
|
-
|
|
24
|
-
type CancelCallback = (conversationId: string) => boolean;
|
|
25
|
-
|
|
26
|
-
let _cancelGeneration: CancelCallback | null = null;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Register the cancel-generation callback. Called once by the daemon
|
|
30
|
-
* server at startup so the signal handler can reach the conversation map.
|
|
31
|
-
*/
|
|
32
|
-
export function registerCancelCallback(cb: CancelCallback): void {
|
|
33
|
-
_cancelGeneration = cb;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
25
|
// ── Signal handler ───────────────────────────────────────────────────
|
|
37
26
|
|
|
38
27
|
/**
|
|
@@ -52,17 +41,19 @@ export function handleCancelSignal(): void {
|
|
|
52
41
|
return;
|
|
53
42
|
}
|
|
54
43
|
|
|
55
|
-
|
|
56
|
-
|
|
44
|
+
const conversation = findConversation(conversationId);
|
|
45
|
+
if (!conversation) {
|
|
46
|
+
log.warn({ conversationId }, "No active conversation for cancel signal");
|
|
57
47
|
return;
|
|
58
48
|
}
|
|
59
49
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
50
|
+
touchConversation(conversationId);
|
|
51
|
+
conversation.abort(
|
|
52
|
+
createAbortReason("signal_cancel", "handleCancelSignal", conversationId),
|
|
53
|
+
);
|
|
54
|
+
getSubagentManager().abortAllForParent(conversationId);
|
|
55
|
+
|
|
56
|
+
log.info({ conversationId }, "Generation cancelled via signal file");
|
|
66
57
|
} catch (err) {
|
|
67
58
|
log.error({ err }, "Failed to handle cancel signal");
|
|
68
59
|
}
|
|
@@ -7,37 +7,18 @@
|
|
|
7
7
|
* {@link handleConversationUndoSignal}, which reads the payload, performs
|
|
8
8
|
* the undo, and writes `signals/conversation-undo.result` so the CLI
|
|
9
9
|
* receives feedback.
|
|
10
|
-
*
|
|
11
|
-
* Because the signal handler needs access to the daemon's conversation map, the
|
|
12
|
-
* daemon registers a callback at startup via
|
|
13
|
-
* {@link registerConversationUndoCallback}.
|
|
14
10
|
*/
|
|
15
11
|
|
|
16
12
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
17
13
|
import { join } from "node:path";
|
|
18
14
|
|
|
19
15
|
import { getIsContainerized } from "../config/env-registry.js";
|
|
16
|
+
import { undoLastMessage } from "../daemon/handlers/conversations.js";
|
|
20
17
|
import { getLogger } from "../util/logger.js";
|
|
21
18
|
import { getSignalsDir } from "../util/platform.js";
|
|
22
19
|
|
|
23
20
|
const log = getLogger("signal:conversation-undo");
|
|
24
21
|
|
|
25
|
-
// ── Daemon callback registry ─────────────────────────────────────────
|
|
26
|
-
|
|
27
|
-
type UndoCallback = (
|
|
28
|
-
conversationId: string,
|
|
29
|
-
) => Promise<{ removedCount: number } | null>;
|
|
30
|
-
|
|
31
|
-
let _undoLastMessage: UndoCallback | null = null;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Register the undo callback. Called once by the daemon server at startup
|
|
35
|
-
* so the signal handler can reach the conversation map.
|
|
36
|
-
*/
|
|
37
|
-
export function registerConversationUndoCallback(cb: UndoCallback): void {
|
|
38
|
-
_undoLastMessage = cb;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
22
|
// ── Signal handler ───────────────────────────────────────────────────
|
|
42
23
|
|
|
43
24
|
/**
|
|
@@ -93,13 +74,7 @@ export async function handleConversationUndoSignal(): Promise<void> {
|
|
|
93
74
|
return;
|
|
94
75
|
}
|
|
95
76
|
|
|
96
|
-
|
|
97
|
-
log.warn("Undo callback not registered; daemon may not be ready");
|
|
98
|
-
writeResult({ ok: false, error: "Assistant not ready", requestId });
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const result = await _undoLastMessage(conversationId);
|
|
77
|
+
const result = await undoLastMessage(conversationId);
|
|
103
78
|
if (!result) {
|
|
104
79
|
log.warn({ conversationId }, "No active conversation for undo signal");
|
|
105
80
|
writeResult({ ok: false, error: "No active conversation", requestId });
|
|
@@ -18,7 +18,6 @@ import { join } from "node:path";
|
|
|
18
18
|
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
19
19
|
import { buildAssistantEvent } from "../runtime/assistant-event.js";
|
|
20
20
|
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
21
|
-
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
|
|
22
21
|
import { getLogger } from "../util/logger.js";
|
|
23
22
|
import { getSignalsDir } from "../util/platform.js";
|
|
24
23
|
|
|
@@ -30,7 +29,7 @@ export function handleEmitEventSignal(): void {
|
|
|
30
29
|
const message = JSON.parse(content) as ServerMessage;
|
|
31
30
|
|
|
32
31
|
assistantEventHub
|
|
33
|
-
.publish(buildAssistantEvent(
|
|
32
|
+
.publish(buildAssistantEvent(message))
|
|
34
33
|
.catch((err: unknown) => {
|
|
35
34
|
log.error({ err }, "Failed to publish event from signal");
|
|
36
35
|
});
|
|
@@ -9,15 +9,24 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Per-request filenames avoid dropped messages when overlapping invocations
|
|
11
11
|
* race on the same signal file.
|
|
12
|
-
*
|
|
13
|
-
* Because the signal handler needs access to the daemon's conversation map and
|
|
14
|
-
* event hub, the daemon registers a callback at startup via
|
|
15
|
-
* {@link registerUserMessageCallback}.
|
|
16
12
|
*/
|
|
17
13
|
|
|
18
|
-
import { readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
14
|
+
import { readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
19
15
|
import { join } from "node:path";
|
|
20
16
|
|
|
17
|
+
import { getOrCreateConversation } from "../daemon/conversation-store.js";
|
|
18
|
+
import type { UserMessageAttachment } from "../daemon/message-types/shared.js";
|
|
19
|
+
import {
|
|
20
|
+
processMessageInBackground,
|
|
21
|
+
resolveTurnChannel,
|
|
22
|
+
resolveTurnInterface,
|
|
23
|
+
} from "../daemon/process-message.js";
|
|
24
|
+
import {
|
|
25
|
+
uploadFileBackedAttachment,
|
|
26
|
+
validateAttachmentUpload,
|
|
27
|
+
} from "../memory/attachments-store.js";
|
|
28
|
+
import { getOrCreateConversation as getOrCreateConversationKey } from "../memory/conversation-key-store.js";
|
|
29
|
+
import { checkIngressForSecrets } from "../security/secret-ingress.js";
|
|
21
30
|
import { getLogger } from "../util/logger.js";
|
|
22
31
|
import { getSignalsDir } from "../util/platform.js";
|
|
23
32
|
|
|
@@ -35,25 +44,108 @@ export interface SignalAttachment {
|
|
|
35
44
|
mimeType: string;
|
|
36
45
|
}
|
|
37
46
|
|
|
38
|
-
// ──
|
|
47
|
+
// ── Dispatch helper ──────────────────────────────────────────────────
|
|
39
48
|
|
|
40
|
-
|
|
49
|
+
async function dispatchUserMessage(params: {
|
|
41
50
|
conversationKey: string;
|
|
42
51
|
content: string;
|
|
43
52
|
sourceChannel: string;
|
|
44
53
|
sourceInterface: string;
|
|
45
54
|
bypassSecretCheck?: boolean;
|
|
46
55
|
attachments?: SignalAttachment[];
|
|
47
|
-
})
|
|
56
|
+
}): Promise<{ accepted: boolean; error?: string; message?: string }> {
|
|
57
|
+
if (!params.bypassSecretCheck) {
|
|
58
|
+
const ingressResult = checkIngressForSecrets(params.content);
|
|
59
|
+
if (ingressResult.blocked) {
|
|
60
|
+
return {
|
|
61
|
+
accepted: false,
|
|
62
|
+
error: "secret_blocked" as const,
|
|
63
|
+
message: ingressResult.userNotice,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
48
67
|
|
|
49
|
-
|
|
68
|
+
const { conversationId } = getOrCreateConversationKey(params.conversationKey);
|
|
69
|
+
const conversation = await getOrCreateConversation(conversationId);
|
|
50
70
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
71
|
+
const attachmentIds: string[] = [];
|
|
72
|
+
const resolvedAttachments: UserMessageAttachment[] = [];
|
|
73
|
+
if (params.attachments && params.attachments.length > 0) {
|
|
74
|
+
for (const a of params.attachments) {
|
|
75
|
+
try {
|
|
76
|
+
const validation = validateAttachmentUpload(a.filename, a.mimeType);
|
|
77
|
+
if (!validation.ok) {
|
|
78
|
+
log.warn(
|
|
79
|
+
{ error: validation.error, path: a.path },
|
|
80
|
+
"Signal attachment rejected by validation",
|
|
81
|
+
);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const size = statSync(a.path).size;
|
|
85
|
+
const stored = uploadFileBackedAttachment(
|
|
86
|
+
a.filename,
|
|
87
|
+
a.mimeType,
|
|
88
|
+
a.path,
|
|
89
|
+
size,
|
|
90
|
+
);
|
|
91
|
+
attachmentIds.push(stored.id);
|
|
92
|
+
resolvedAttachments.push({
|
|
93
|
+
id: stored.id,
|
|
94
|
+
filename: a.filename,
|
|
95
|
+
mimeType: a.mimeType,
|
|
96
|
+
data: "",
|
|
97
|
+
filePath: a.path,
|
|
98
|
+
});
|
|
99
|
+
} catch (err) {
|
|
100
|
+
log.warn({ err, path: a.path }, "Failed to register signal attachment");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (conversation.isProcessing()) {
|
|
106
|
+
for (let i = resolvedAttachments.length - 1; i >= 0; i--) {
|
|
107
|
+
const att = resolvedAttachments[i];
|
|
108
|
+
if (att.filePath && !att.data) {
|
|
109
|
+
try {
|
|
110
|
+
att.data = readFileSync(att.filePath).toString("base64");
|
|
111
|
+
} catch (err) {
|
|
112
|
+
log.warn(
|
|
113
|
+
{ err, path: att.filePath },
|
|
114
|
+
"Failed to read queued signal attachment, skipping",
|
|
115
|
+
);
|
|
116
|
+
resolvedAttachments.splice(i, 1);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const requestId = crypto.randomUUID();
|
|
121
|
+
const resolvedChannel = resolveTurnChannel(params.sourceChannel);
|
|
122
|
+
const resolvedInterface = resolveTurnInterface(params.sourceInterface);
|
|
123
|
+
const result = conversation.enqueueMessage(
|
|
124
|
+
params.content,
|
|
125
|
+
resolvedAttachments,
|
|
126
|
+
undefined,
|
|
127
|
+
requestId,
|
|
128
|
+
undefined,
|
|
129
|
+
undefined,
|
|
130
|
+
{
|
|
131
|
+
userMessageChannel: resolvedChannel,
|
|
132
|
+
assistantMessageChannel: resolvedChannel,
|
|
133
|
+
userMessageInterface: resolvedInterface,
|
|
134
|
+
assistantMessageInterface: resolvedInterface,
|
|
135
|
+
},
|
|
136
|
+
);
|
|
137
|
+
return { accepted: !result.rejected };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
await processMessageInBackground(
|
|
141
|
+
conversationId,
|
|
142
|
+
params.content,
|
|
143
|
+
attachmentIds.length > 0 ? attachmentIds : undefined,
|
|
144
|
+
undefined,
|
|
145
|
+
params.sourceChannel,
|
|
146
|
+
params.sourceInterface,
|
|
147
|
+
);
|
|
148
|
+
return { accepted: true };
|
|
57
149
|
}
|
|
58
150
|
|
|
59
151
|
// ── Signal handler ───────────────────────────────────────────────────
|
|
@@ -143,12 +235,6 @@ export async function handleUserMessageSignal(filename: string): Promise<void> {
|
|
|
143
235
|
return;
|
|
144
236
|
}
|
|
145
237
|
|
|
146
|
-
if (!_sendUserMessage) {
|
|
147
|
-
log.warn("User-message callback not registered; daemon may not be ready");
|
|
148
|
-
writeResult({ ok: false, error: "Assistant not ready", requestId });
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
238
|
// Validate and normalize attachments
|
|
153
239
|
const attachments: SignalAttachment[] = [];
|
|
154
240
|
if (Array.isArray(parsed.attachments)) {
|
|
@@ -167,7 +253,7 @@ export async function handleUserMessageSignal(filename: string): Promise<void> {
|
|
|
167
253
|
}
|
|
168
254
|
}
|
|
169
255
|
|
|
170
|
-
const result = await
|
|
256
|
+
const result = await dispatchUserMessage({
|
|
171
257
|
conversationKey: parsed.conversationKey,
|
|
172
258
|
content: parsed.content,
|
|
173
259
|
sourceChannel: parsed.sourceChannel ?? "vellum",
|
package/src/skills/clawhub.ts
CHANGED
|
@@ -181,7 +181,7 @@ async function runClawhub(
|
|
|
181
181
|
const { mkdirSync } = await import("node:fs");
|
|
182
182
|
mkdirSync(cwd, { recursive: true });
|
|
183
183
|
|
|
184
|
-
log.
|
|
184
|
+
log.debug({ args, cwd }, "Running clawhub command");
|
|
185
185
|
|
|
186
186
|
const proc = Bun.spawn(["npx", "clawhub", ...args], {
|
|
187
187
|
cwd,
|
|
@@ -211,7 +211,7 @@ async function runClawhub(
|
|
|
211
211
|
|
|
212
212
|
const exitCode = await proc.exited;
|
|
213
213
|
|
|
214
|
-
log.
|
|
214
|
+
log.debug(
|
|
215
215
|
{ exitCode, stdoutLen: stdout.length, stderrLen: stderr.length },
|
|
216
216
|
"clawhub command completed",
|
|
217
217
|
);
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
import { spawn } from "node:child_process";
|
|
25
25
|
|
|
26
26
|
import { buildSanitizedEnv } from "../tools/terminal/safe-env.js";
|
|
27
|
-
import { wrapCommand } from "../tools/terminal/sandbox.js";
|
|
28
27
|
import { getLogger } from "../util/logger.js";
|
|
29
28
|
|
|
30
29
|
const log = getLogger("inline-command-runner");
|
|
@@ -105,12 +104,7 @@ export async function runInlineCommand(
|
|
|
105
104
|
const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
106
105
|
const maxChars = options?.maxOutputChars ?? MAX_OUTPUT_CHARS;
|
|
107
106
|
|
|
108
|
-
|
|
109
|
-
// environments where the container provides isolation. The networkMode
|
|
110
|
-
// option is a no-op when sandbox is disabled (wrapCommand returns a plain
|
|
111
|
-
// bash invocation); network isolation is handled at the container level.
|
|
112
|
-
const sandboxConfig = { enabled: false } as const;
|
|
113
|
-
const wrapped = wrapCommand(command, workingDir, sandboxConfig);
|
|
107
|
+
const wrapped = { command: "bash", args: ["-c", "--", command] };
|
|
114
108
|
|
|
115
109
|
// Build a minimal, sanitized environment. Explicitly exclude gateway URL,
|
|
116
110
|
// workspace dir, and data dir since inline commands have no business calling
|
package/src/subagent/manager.ts
CHANGED
|
@@ -116,13 +116,6 @@ export interface SubagentNotificationInfo {
|
|
|
116
116
|
conversationId?: string;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
export type ParentNotifyCallback = (
|
|
120
|
-
parentConversationId: string,
|
|
121
|
-
message: string,
|
|
122
|
-
sendToClient: (msg: ServerMessage) => void,
|
|
123
|
-
notification: SubagentNotificationInfo,
|
|
124
|
-
) => void;
|
|
125
|
-
|
|
126
119
|
export class SubagentManager {
|
|
127
120
|
/** subagentId → ManagedSubagent */
|
|
128
121
|
private subagents = new Map<string, ManagedSubagent>();
|
|
@@ -131,26 +124,12 @@ export class SubagentManager {
|
|
|
131
124
|
/** `${parentConversationId}:${normalizedLabel}` → subagentId */
|
|
132
125
|
private labelIndex = new Map<string, string>();
|
|
133
126
|
|
|
134
|
-
/**
|
|
135
|
-
* Optional callback to inject a completion/failure message into the parent
|
|
136
|
-
* conversation so the LLM can automatically inform the user.
|
|
137
|
-
* Wired by DaemonServer at startup.
|
|
138
|
-
*/
|
|
139
|
-
onSubagentFinished?: ParentNotifyCallback;
|
|
140
|
-
|
|
141
127
|
/**
|
|
142
128
|
* Shared rate-limit timestamps array from the daemon server.
|
|
143
129
|
* Set by DaemonServer at startup so subagents share the global rate limit.
|
|
144
130
|
*/
|
|
145
131
|
sharedRequestTimestamps: number[] = [];
|
|
146
132
|
|
|
147
|
-
/**
|
|
148
|
-
* Broadcast callback from the daemon server.
|
|
149
|
-
* Set by DaemonServer at startup so subagent conversations can broadcast
|
|
150
|
-
* to all connected clients (e.g. app_files_changed side-effects).
|
|
151
|
-
*/
|
|
152
|
-
broadcastToAllClients?: (msg: ServerMessage) => void;
|
|
153
|
-
|
|
154
133
|
// ── Spawn ───────────────────────────────────────────────────────────
|
|
155
134
|
|
|
156
135
|
/**
|
|
@@ -310,7 +289,6 @@ export class SubagentManager {
|
|
|
310
289
|
maxTokens,
|
|
311
290
|
wrappedSendToClient,
|
|
312
291
|
workingDir,
|
|
313
|
-
this.broadcastToAllClients, // forward parent's broadcast so tool side-effects (e.g. app_files_changed) reach all clients
|
|
314
292
|
memoryPolicy,
|
|
315
293
|
undefined, // sharedCesClient
|
|
316
294
|
undefined, // speedOverride
|
|
@@ -427,8 +405,6 @@ export class SubagentManager {
|
|
|
427
405
|
this.setStatus(subagentId, "running", getSender());
|
|
428
406
|
managed.state.startedAt = Date.now();
|
|
429
407
|
|
|
430
|
-
const onEvent = conversation.sendToClient;
|
|
431
|
-
|
|
432
408
|
try {
|
|
433
409
|
// For forks, inject the parent's message history before the first message.
|
|
434
410
|
// This prepends the inherited context so the fork has full conversational
|
|
@@ -462,7 +438,7 @@ export class SubagentManager {
|
|
|
462
438
|
].join("\n")
|
|
463
439
|
: objective;
|
|
464
440
|
const messageId = await conversation.persistUserMessage(message, []);
|
|
465
|
-
await conversation.runAgentLoop(message, messageId,
|
|
441
|
+
await conversation.runAgentLoop(message, messageId, undefined, {
|
|
466
442
|
callSite: "subagentSpawn",
|
|
467
443
|
...(managed.state.config.overrideProfile
|
|
468
444
|
? { overrideProfile: managed.state.config.overrideProfile }
|
|
@@ -480,7 +456,7 @@ export class SubagentManager {
|
|
|
480
456
|
log.info({ subagentId }, "Subagent completed");
|
|
481
457
|
|
|
482
458
|
// Notify the parent conversation so the LLM can call subagent_read.
|
|
483
|
-
this.notifyParentTerminal(managed, "completed"
|
|
459
|
+
this.notifyParentTerminal(managed, "completed");
|
|
484
460
|
}
|
|
485
461
|
} catch (err) {
|
|
486
462
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -493,7 +469,7 @@ export class SubagentManager {
|
|
|
493
469
|
// Only update status if not already terminal (e.g. aborted).
|
|
494
470
|
if (!TERMINAL_STATUSES.has(managed.state.status)) {
|
|
495
471
|
this.setStatus(subagentId, "failed", getSender(), errorMsg);
|
|
496
|
-
this.notifyParentTerminal(managed, "failed"
|
|
472
|
+
this.notifyParentTerminal(managed, "failed");
|
|
497
473
|
}
|
|
498
474
|
|
|
499
475
|
log.error({ subagentId, err }, "Subagent failed");
|
|
@@ -566,30 +542,24 @@ export class SubagentManager {
|
|
|
566
542
|
this.setStatus(subagentId, "aborted", statusSender);
|
|
567
543
|
// Notify parent that the subagent was explicitly aborted — tell it NOT to re-spawn.
|
|
568
544
|
// Skip when the parent LLM itself called subagent_abort (it already has the tool result).
|
|
569
|
-
if (
|
|
545
|
+
if (!options?.suppressNotification) {
|
|
570
546
|
const label = managed.state.config.label;
|
|
571
547
|
const prefix = managed.state.isFork ? "Fork" : "Subagent";
|
|
572
548
|
const message =
|
|
573
549
|
`[${prefix} "${label}" was explicitly aborted]\n\n` +
|
|
574
550
|
`This ${prefix.toLowerCase()} was cancelled on purpose. Do NOT re-spawn or retry it.`;
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
managed.state.config.parentConversationId,
|
|
581
|
-
message,
|
|
582
|
-
managed.parentSendToClient,
|
|
583
|
-
{
|
|
551
|
+
this.injectMessageIntoParent(
|
|
552
|
+
managed.state.config.parentConversationId,
|
|
553
|
+
message,
|
|
554
|
+
{
|
|
555
|
+
subagentNotification: {
|
|
584
556
|
subagentId,
|
|
585
557
|
label,
|
|
586
|
-
status: "aborted",
|
|
558
|
+
status: "aborted" as const,
|
|
587
559
|
conversationId: managed.state.conversationId,
|
|
588
560
|
},
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
log.error({ subagentId, err }, "Failed to notify parent about abort");
|
|
592
|
-
}
|
|
561
|
+
},
|
|
562
|
+
);
|
|
593
563
|
}
|
|
594
564
|
} else {
|
|
595
565
|
managed.state.status = "aborted";
|
|
@@ -640,18 +610,10 @@ export class SubagentManager {
|
|
|
640
610
|
if (TERMINAL_STATUSES.has(managed.state.status) || !managed.conversation)
|
|
641
611
|
return "terminal";
|
|
642
612
|
|
|
643
|
-
const onEvent = managed.conversation.sendToClient;
|
|
644
|
-
const requestId = uuid();
|
|
645
|
-
|
|
646
613
|
// If the conversation is busy, queue the message; otherwise process immediately.
|
|
647
|
-
const result = managed.conversation.enqueueMessage(
|
|
648
|
-
trimmed,
|
|
649
|
-
[],
|
|
650
|
-
onEvent,
|
|
651
|
-
requestId,
|
|
652
|
-
);
|
|
614
|
+
const result = managed.conversation.enqueueMessage(trimmed, []);
|
|
653
615
|
if (result.rejected) {
|
|
654
|
-
return "sent"; // error event already delivered via
|
|
616
|
+
return "sent"; // error event already delivered via sendToClient
|
|
655
617
|
}
|
|
656
618
|
if (result.queued) {
|
|
657
619
|
managed.hadEnqueuedMessages = true;
|
|
@@ -662,7 +624,7 @@ export class SubagentManager {
|
|
|
662
624
|
const conversation = managed.conversation;
|
|
663
625
|
const messageId = await conversation.persistUserMessage(trimmed, []);
|
|
664
626
|
conversation
|
|
665
|
-
.runAgentLoop(trimmed, messageId,
|
|
627
|
+
.runAgentLoop(trimmed, messageId, undefined, {
|
|
666
628
|
callSite: "subagentSpawn",
|
|
667
629
|
...(managed.state.config.overrideProfile
|
|
668
630
|
? { overrideProfile: managed.state.config.overrideProfile }
|
|
@@ -928,7 +890,6 @@ export class SubagentManager {
|
|
|
928
890
|
|
|
929
891
|
const managed = this.subagents.get(info.subagentId);
|
|
930
892
|
if (!managed || TERMINAL_STATUSES.has(managed.state.status)) return false;
|
|
931
|
-
if (!this.onSubagentFinished) return false;
|
|
932
893
|
|
|
933
894
|
const prefix = managed.state.isFork ? "Fork" : "Subagent";
|
|
934
895
|
let notificationString = `[${prefix} "${info.label}" — ${urgency}] ${message}`;
|
|
@@ -936,25 +897,18 @@ export class SubagentManager {
|
|
|
936
897
|
notificationString += `\nUse subagent_message to send guidance to this ${prefix.toLowerCase()}.`;
|
|
937
898
|
}
|
|
938
899
|
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
{
|
|
900
|
+
this.injectMessageIntoParent(
|
|
901
|
+
info.parentConversationId,
|
|
902
|
+
notificationString,
|
|
903
|
+
{
|
|
904
|
+
subagentNotification: {
|
|
945
905
|
subagentId: info.subagentId,
|
|
946
906
|
label: info.label,
|
|
947
|
-
status: "running",
|
|
907
|
+
status: "running" as const,
|
|
948
908
|
},
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
log.error(
|
|
953
|
-
{ subagentId: info.subagentId, err },
|
|
954
|
-
"Failed to notify parent from subagent",
|
|
955
|
-
);
|
|
956
|
-
return false;
|
|
957
|
-
}
|
|
909
|
+
},
|
|
910
|
+
);
|
|
911
|
+
return true;
|
|
958
912
|
}
|
|
959
913
|
|
|
960
914
|
/**
|
|
@@ -964,10 +918,7 @@ export class SubagentManager {
|
|
|
964
918
|
private notifyParentTerminal(
|
|
965
919
|
managed: ManagedSubagent,
|
|
966
920
|
outcome: "completed" | "failed",
|
|
967
|
-
parentSendToClient: (msg: ServerMessage) => void,
|
|
968
921
|
): void {
|
|
969
|
-
if (!this.onSubagentFinished) return;
|
|
970
|
-
|
|
971
922
|
const { config } = managed.state;
|
|
972
923
|
const isFork = managed.state.isFork;
|
|
973
924
|
let message: string;
|
|
@@ -1009,18 +960,50 @@ export class SubagentManager {
|
|
|
1009
960
|
: {}),
|
|
1010
961
|
};
|
|
1011
962
|
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
963
|
+
this.injectMessageIntoParent(config.parentConversationId, message, {
|
|
964
|
+
subagentNotification: notification,
|
|
965
|
+
});
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* Inject a notification message into the parent conversation so the LLM
|
|
970
|
+
* sees subagent lifecycle events. Relies on the parent conversation's
|
|
971
|
+
* sendToClient (backed by broadcastMessage) for event delivery.
|
|
972
|
+
*/
|
|
973
|
+
private injectMessageIntoParent(
|
|
974
|
+
parentConversationId: string,
|
|
975
|
+
message: string,
|
|
976
|
+
metadata?: Record<string, unknown>,
|
|
977
|
+
): void {
|
|
978
|
+
const parentConversation = findConversation(parentConversationId);
|
|
979
|
+
if (!parentConversation) {
|
|
980
|
+
log.warn(
|
|
981
|
+
{ parentConversationId },
|
|
982
|
+
"Subagent finished but parent conversation not found",
|
|
1023
983
|
);
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
const enqueueResult = parentConversation.enqueueMessage(
|
|
987
|
+
message,
|
|
988
|
+
[],
|
|
989
|
+
undefined,
|
|
990
|
+
undefined,
|
|
991
|
+
undefined,
|
|
992
|
+
undefined,
|
|
993
|
+
metadata,
|
|
994
|
+
);
|
|
995
|
+
if (!enqueueResult.queued && !enqueueResult.rejected) {
|
|
996
|
+
parentConversation
|
|
997
|
+
.persistUserMessage(message, [], undefined, metadata)
|
|
998
|
+
.then((messageId) =>
|
|
999
|
+
parentConversation.runAgentLoop(message, messageId),
|
|
1000
|
+
)
|
|
1001
|
+
.catch((err) => {
|
|
1002
|
+
log.error(
|
|
1003
|
+
{ parentConversationId, err },
|
|
1004
|
+
"Failed to process subagent notification in parent",
|
|
1005
|
+
);
|
|
1006
|
+
});
|
|
1024
1007
|
}
|
|
1025
1008
|
}
|
|
1026
1009
|
}
|