@vellumai/assistant 0.10.2-dev.202606250318.5e7cfb0 → 0.10.2
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/bun.lock +0 -20
- package/docs/workspace-tools.md +33 -42
- package/eslint-rules/cli-no-daemon-internals.js +0 -6
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +0 -31
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +0 -44
- package/node_modules/@vellumai/gateway-client/src/index.ts +0 -14
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +0 -17
- package/node_modules/@vellumai/service-contracts/package.json +0 -1
- package/node_modules/@vellumai/service-contracts/src/index.ts +0 -1
- package/openapi.yaml +0 -155
- package/package.json +1 -4
- package/scripts/test.sh +15 -36
- package/src/__tests__/actor-token-service.test.ts +14 -36
- package/src/__tests__/agent-loop-override-profile.test.ts +0 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -2
- package/src/__tests__/agent-wake-override-profile.test.ts +0 -2
- package/src/__tests__/annotate-activity-metadata.test.ts +0 -2
- package/src/__tests__/annotate-risk-options.test.ts +0 -2
- package/src/__tests__/approval-cascade.test.ts +0 -2
- package/src/__tests__/assistant-attachments.test.ts +0 -42
- package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
- package/src/__tests__/btw-routes.test.ts +0 -2
- package/src/__tests__/build-persisted-content.test.ts +0 -2
- package/src/__tests__/call-controller.test.ts +0 -19
- package/src/__tests__/channel-guardian.test.ts +58 -94
- package/src/__tests__/channel-reply-delivery.test.ts +0 -2
- package/src/__tests__/compaction-events.test.ts +0 -2
- package/src/__tests__/compaction.benchmark.test.ts +0 -2
- package/src/__tests__/compactor-call-site-logging.test.ts +0 -2
- package/src/__tests__/compactor-low-watermark-cut.test.ts +0 -2
- package/src/__tests__/compactor-preserved-tail-count.test.ts +0 -2
- package/src/__tests__/compactor-summary-call-truncation.test.ts +0 -2
- package/src/__tests__/compactor-web-search-strip.test.ts +0 -2
- package/src/__tests__/config-loader-backfill.test.ts +10 -123
- package/src/__tests__/config-schema.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +29 -31
- package/src/__tests__/contacts-relay-reads.test.ts +15 -13
- package/src/__tests__/conversation-abort-tool-results.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop.test.ts +0 -134
- package/src/__tests__/conversation-analysis-routes.test.ts +0 -2
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +0 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -2
- package/src/__tests__/conversation-history-web-search.test.ts +0 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +0 -2
- package/src/__tests__/conversation-load-history-stripped.test.ts +0 -2
- package/src/__tests__/conversation-pairing.test.ts +0 -2
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +0 -2
- package/src/__tests__/conversation-process-callsite.test.ts +0 -2
- package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -2
- package/src/__tests__/conversation-queue.test.ts +0 -91
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -14
- package/src/__tests__/conversation-routes-slash-commands.test.ts +0 -14
- package/src/__tests__/conversation-slash-queue.test.ts +0 -2
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -2
- package/src/__tests__/conversation-speed-override.test.ts +0 -2
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +0 -29
- package/src/__tests__/conversation-title-service.test.ts +0 -2
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +0 -47
- package/src/__tests__/conversation-usage.test.ts +0 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -2
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -2
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -2
- package/src/__tests__/credential-security-invariants.test.ts +1 -1
- package/src/__tests__/db-migration-rollback.test.ts +171 -205
- package/src/__tests__/db-test-helpers.ts +4 -5
- package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -4
- package/src/__tests__/disk-pressure-guard.test.ts +0 -41
- package/src/__tests__/dm-persistence.test.ts +0 -2
- package/src/__tests__/emit-signal-routing-intent.test.ts +5 -10
- package/src/__tests__/events-dev-bypass-actor.test.ts +1 -7
- package/src/__tests__/exploration-drift-hook.test.ts +2 -3
- package/src/__tests__/filing-service.test.ts +0 -2
- package/src/__tests__/guardian-binding-drift-heal.test.ts +10 -75
- package/src/__tests__/guardian-dispatch.test.ts +1 -95
- package/src/__tests__/guardian-outbound-http.test.ts +0 -13
- package/src/__tests__/heartbeat-disk-pressure.test.ts +0 -2
- package/src/__tests__/heartbeat-service.test.ts +0 -2
- package/src/__tests__/helpers/channel-test-adapter.ts +7 -1
- package/src/__tests__/host-app-control-routes.test.ts +30 -24
- package/src/__tests__/host-bash-routes.test.ts +41 -31
- package/src/__tests__/host-browser-routes.test.ts +32 -26
- package/src/__tests__/host-cu-routes-targeted.test.ts +33 -25
- package/src/__tests__/host-file-routes-targeted.test.ts +52 -40
- package/src/__tests__/host-transfer-routes-targeted.test.ts +43 -31
- package/src/__tests__/http-user-message-parity.test.ts +8 -290
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -28
- package/src/__tests__/inbound-slack-persistence.test.ts +0 -2
- package/src/__tests__/invite-redemption-service.test.ts +0 -198
- package/src/__tests__/llm-context-normalization.test.ts +0 -105
- package/src/__tests__/llm-request-log-error-payload.test.ts +9 -71
- package/src/__tests__/llm-usage-store.test.ts +0 -25
- package/src/__tests__/mcp-health-check.test.ts +1 -2
- package/src/__tests__/media-stream-server-integration.test.ts +0 -127
- package/src/__tests__/memory-retrieval-hook.test.ts +0 -2
- package/src/__tests__/messaging-send-tool.test.ts +0 -2
- package/src/__tests__/migration-import-from-url.test.ts +2 -2
- package/src/__tests__/mtime-cache.test.ts +5 -146
- package/src/__tests__/native-web-search.test.ts +0 -2
- package/src/__tests__/non-member-access-request.test.ts +17 -189
- package/src/__tests__/notification-broadcaster.test.ts +0 -4
- package/src/__tests__/notification-decision-recipient-context.test.ts +32 -33
- package/src/__tests__/notification-deep-link.test.ts +0 -6
- package/src/__tests__/notification-guardian-path.test.ts +0 -19
- package/src/__tests__/openai-provider.test.ts +12 -22
- package/src/__tests__/openai-responses-provider.test.ts +2 -12
- package/src/__tests__/outbound-slack-persistence.test.ts +0 -2
- package/src/__tests__/pending-interactions-resolved-event.test.ts +4 -7
- package/src/__tests__/persistence-secret-redaction.test.ts +0 -2
- package/src/__tests__/plugin-bootstrap.test.ts +73 -3
- package/src/__tests__/plugin-route-contribution.test.ts +17 -4
- package/src/__tests__/plugin-tool-contribution.test.ts +18 -3
- package/src/__tests__/plugin-types.test.ts +2 -0
- package/src/__tests__/process-message-background-slack.test.ts +0 -2
- package/src/__tests__/process-message-display-content.test.ts +0 -2
- package/src/__tests__/provider-error-scenarios.test.ts +4 -5
- package/src/__tests__/provider-usage-tracking.test.ts +0 -39
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +0 -2
- package/src/__tests__/registry.test.ts +1 -4
- package/src/__tests__/relay-server.test.ts +25 -694
- package/src/__tests__/runtime-attachment-metadata.test.ts +1 -0
- package/src/__tests__/secret-ingress-http.test.ts +0 -14
- package/src/__tests__/send-endpoint-busy.test.ts +8 -30
- package/src/__tests__/skills.test.ts +0 -44
- package/src/__tests__/slack-inbound-verification.test.ts +2 -47
- package/src/__tests__/stt-hints.test.ts +13 -44
- package/src/__tests__/subagent-detail.test.ts +0 -27
- package/src/__tests__/subagent-disposal.test.ts +0 -65
- package/src/__tests__/subagent-notify-parent.test.ts +0 -2
- package/src/__tests__/subagent-role-registry.test.ts +2 -7
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +0 -2
- package/src/__tests__/subagent-tools.test.ts +0 -2
- package/src/__tests__/suggestion-routes.test.ts +0 -2
- package/src/__tests__/title-generate-hook.test.ts +0 -2
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -2
- package/src/__tests__/tool-executor.test.ts +11 -16
- package/src/__tests__/tool-preview-lifecycle.test.ts +0 -2
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +0 -2
- package/src/__tests__/tool-start-timestamp.test.ts +0 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +10 -10
- package/src/__tests__/twilio-routes.test.ts +0 -96
- package/src/__tests__/ui-file-upload-surface.test.ts +0 -86
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/__tests__/voice-invite-redemption.test.ts +0 -33
- package/src/__tests__/web-search-backend-failure.test.ts +0 -2
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +35 -14
- package/src/__tests__/workspace-tool-loader.test.ts +2 -195
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
- package/src/agent/loop.ts +0 -56
- package/src/api/index.ts +1 -19
- package/src/api/responses/llm-request-log-entry.ts +0 -29
- package/src/api/responses/subagent-detail.ts +0 -17
- package/src/api/surfaces.ts +3 -39
- package/src/approvals/guardian-request-resolvers.ts +11 -1
- package/src/calls/__tests__/relay-setup-router.test.ts +4 -262
- package/src/calls/call-domain.ts +3 -3
- package/src/calls/guardian-dispatch.ts +8 -10
- package/src/calls/inbound-trust-reader.ts +1 -17
- package/src/calls/media-stream-server.ts +0 -21
- package/src/calls/relay-server.ts +50 -167
- package/src/calls/relay-setup-router.ts +7 -37
- package/src/calls/relay-verification.ts +4 -4
- package/src/calls/stt-hints.ts +12 -9
- package/src/calls/twilio-routes.ts +4 -14
- package/src/channels/types.ts +20 -10
- package/src/cli/commands/__tests__/cache.test.ts +1 -8
- package/src/cli/commands/cache.ts +181 -194
- package/src/cli/commands/db/__tests__/repair.test.ts +5 -6
- package/src/cli/commands/db/status.ts +1 -37
- package/src/cli/commands/mcp.ts +218 -252
- package/src/cli/commands/memory/index.ts +0 -2
- package/src/cli/commands/plugins.ts +3 -75
- package/src/cli/lib/__tests__/install-from-github.test.ts +0 -102
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +1 -160
- package/src/cli/lib/list-installed-plugins.ts +1 -179
- package/src/config/__tests__/sync-gated-profiles.test.ts +3 -11
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +17 -27
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +3 -13
- package/src/config/bundled-skills/subagent/SKILL.md +1 -1
- package/src/config/bundled-skills/subagent/TOOLS.json +1 -1
- package/src/config/feature-flag-registry.json +13 -5
- package/src/config/loader.ts +5 -38
- package/src/config/schemas/__tests__/memory-v3.test.ts +0 -1
- package/src/config/schemas/memory-lifecycle.ts +0 -12
- package/src/config/schemas/memory-v3.ts +0 -7
- package/src/config/schemas/memory.ts +0 -4
- package/src/config/schemas/timeouts.ts +0 -8
- package/src/config/seed-inference-profiles.ts +11 -21
- package/src/config/skills.ts +5 -27
- package/src/config/sync-gated-profiles.ts +13 -12
- package/src/contacts/contacts-write.ts +0 -3
- package/src/daemon/assistant-attachments.ts +4 -27
- package/src/daemon/conversation-agent-loop.ts +0 -28
- package/src/daemon/conversation-process.ts +16 -35
- package/src/daemon/conversation-surfaces.ts +38 -111
- package/src/daemon/conversation-tool-setup.ts +16 -50
- package/src/daemon/conversation.ts +1 -13
- package/src/daemon/disk-pressure-guard.ts +2 -12
- package/src/daemon/event-loop-watchdog.ts +1 -28
- package/src/daemon/external-plugins-bootstrap.ts +34 -4
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -25
- package/src/daemon/handlers/config-a2a.ts +14 -6
- package/src/daemon/handlers/config-channels.ts +22 -78
- package/src/daemon/handlers/conversations.ts +0 -77
- package/src/daemon/lifecycle.ts +0 -4
- package/src/daemon/mcp-reload-service.ts +0 -10
- package/src/daemon/memory-v2-startup.test.ts +0 -72
- package/src/daemon/memory-v2-startup.ts +19 -87
- package/src/daemon/message-types/conversations.ts +0 -2
- package/src/daemon/message-types/surfaces.ts +12 -12
- package/src/daemon/server.ts +4 -0
- package/src/daemon/shutdown-handlers.ts +0 -20
- package/src/daemon/tool-setup-types.ts +0 -9
- package/src/daemon/workspace-tools-watcher.ts +328 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
- package/src/ipc/assistant-server.ts +2 -2
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
- package/src/mcp/client.ts +1 -15
- package/src/mcp/mcp-auth-orchestrator.ts +1 -6
- package/src/mcp/mcp-oauth-provider.ts +8 -19
- package/src/memory/__tests__/memory-retrospective-job.test.ts +0 -8
- package/src/memory/conversation-crud.ts +0 -38
- package/src/memory/db-connection.ts +3 -22
- package/src/memory/db-init.ts +502 -36
- package/src/memory/db-singleton.ts +4 -6
- package/src/memory/jobs-worker.ts +0 -58
- package/src/memory/llm-request-log-store.ts +1 -26
- package/src/memory/llm-usage-store.ts +20 -48
- package/src/memory/memory-retrospective-job.ts +8 -9
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +56 -130
- package/src/memory/migrations/__tests__/run-migrations.test.ts +2 -2
- package/src/memory/migrations/registry.ts +573 -0
- package/src/memory/migrations/run-migrations.ts +6 -90
- package/src/memory/migrations/validate-migration-state.ts +66 -101
- package/src/memory/schema/conversations.ts +0 -9
- package/src/memory/schema/infrastructure.ts +0 -20
- package/src/memory/v2/__tests__/cli-command-store.test.ts +0 -25
- package/src/memory/v2/__tests__/skill-store.test.ts +0 -80
- package/src/memory/v2/cli-command-store.ts +38 -75
- package/src/memory/v2/prompts/consolidation.ts +82 -13
- package/src/memory/v2/prompts/router.ts +93 -21
- package/src/memory/v2/skill-store.ts +31 -68
- package/src/notifications/__tests__/broadcaster.test.ts +8 -16
- package/src/notifications/__tests__/decision-engine.test.ts +9 -78
- package/src/notifications/broadcaster.ts +1 -8
- package/src/notifications/decision-engine.ts +7 -15
- package/src/notifications/destination-resolver.ts +24 -68
- package/src/notifications/emit-signal.ts +14 -39
- package/src/permissions/question-prompter.test.ts +1 -1
- package/src/permissions/question-prompter.ts +4 -7
- package/src/plugin-api/index.ts +6 -6
- package/src/plugin-api/types.ts +5 -3
- package/src/plugin-api/vision-support.test.ts +4 -28
- package/src/plugin-api/vision-support.ts +31 -66
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +0 -161
- package/src/plugins/defaults/advisor/consult.ts +6 -110
- package/src/plugins/defaults/advisor/steering.ts +2 -14
- package/src/plugins/defaults/advisor/tools/advisor.ts +5 -32
- package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +1 -2
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +7 -47
- package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +11 -10
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +20 -12
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +11 -42
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +3 -33
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +4 -48
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +8 -4
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +15 -43
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +2 -11
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +13 -77
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +11 -12
- package/src/plugins/mtime-cache.ts +291 -76
- package/src/plugins/pipeline.ts +13 -111
- package/src/plugins/types.ts +2 -0
- package/src/providers/anthropic/client.ts +0 -5
- package/src/providers/call-site-routing.ts +0 -4
- package/src/providers/model-catalog.ts +0 -16
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/chat-completions-provider.ts +83 -37
- package/src/providers/openai/responses-provider.ts +46 -50
- package/src/providers/openrouter/client.ts +0 -5
- package/src/providers/provider-send-message.ts +0 -4
- package/src/providers/ratelimit.ts +0 -4
- package/src/providers/retry.ts +0 -4
- package/src/providers/types.ts +0 -9
- package/src/providers/usage-tracking.ts +0 -4
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +3 -335
- package/src/runtime/access-request-helper.ts +39 -19
- package/src/runtime/actor-trust-resolver.ts +2 -2
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/assistant-stream-state.ts +2 -9
- package/src/runtime/auth/require-bound-guardian.ts +11 -21
- package/src/runtime/channel-verification-service.ts +31 -56
- package/src/runtime/confirmation-request-guardian-bridge.ts +3 -3
- package/src/runtime/guardian-vellum-migration.ts +7 -66
- package/src/runtime/invite-redemption-service.ts +187 -198
- package/src/runtime/local-actor-identity.ts +11 -76
- package/src/runtime/pending-interactions.ts +1 -11
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +5 -56
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +0 -187
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +5 -13
- package/src/runtime/routes/channel-verification-routes.ts +3 -3
- package/src/runtime/routes/contact-routes.ts +32 -8
- package/src/runtime/routes/conversation-cli-routes.ts +5 -4
- package/src/runtime/routes/conversation-list-routes.ts +7 -4
- package/src/runtime/routes/conversation-query-routes.ts +0 -72
- package/src/runtime/routes/conversation-routes.ts +85 -84
- package/src/runtime/routes/events-routes.ts +2 -2
- package/src/runtime/routes/global-search-routes.ts +1 -3
- package/src/runtime/routes/guardian-action-routes.ts +5 -4
- package/src/runtime/routes/host-app-control-routes.ts +4 -5
- package/src/runtime/routes/host-bash-routes.ts +4 -5
- package/src/runtime/routes/host-browser-routes.ts +11 -9
- package/src/runtime/routes/host-cu-routes.ts +4 -5
- package/src/runtime/routes/host-file-routes.ts +4 -5
- package/src/runtime/routes/host-transfer-routes.ts +6 -6
- package/src/runtime/routes/http-adapter.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +2 -3
- package/src/runtime/routes/inbound-message-handler.ts +5 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +5 -97
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +49 -61
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -16
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +8 -21
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +3 -14
- package/src/runtime/routes/index.ts +0 -2
- package/src/runtime/routes/llm-context-normalization.ts +0 -83
- package/src/runtime/routes/mcp-auth-routes.ts +19 -171
- package/src/runtime/routes/migration-rollback-routes.ts +3 -4
- package/src/runtime/routes/migration-routes.ts +1 -4
- package/src/runtime/routes/subagents-routes.ts +0 -5
- package/src/runtime/routes/surface-action-routes.ts +56 -42
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -1
- package/src/runtime/services/conversation-serializer.ts +9 -7
- package/src/runtime/tool-grant-request-helper.ts +3 -3
- package/src/runtime/trust-verdict-consumer.ts +9 -85
- package/src/runtime/verification-outbound-actions.ts +18 -18
- package/src/signals/user-message.ts +0 -16
- package/src/subagent/manager.ts +0 -9
- package/src/subagent/types.ts +3 -3
- package/src/telemetry/types.ts +1 -34
- package/src/telemetry/usage-telemetry-reporter.test.ts +2 -3
- package/src/telemetry/usage-telemetry-reporter.ts +3 -87
- package/src/tools/ask-question/ask-question-tool.test.ts +0 -29
- package/src/tools/ask-question/ask-question-tool.ts +0 -13
- package/src/tools/executor.ts +4 -4
- package/src/tools/registry.ts +0 -18
- package/src/tools/shared/filesystem/path-policy.ts +5 -12
- package/src/tools/tool-approval-handler.ts +1 -1
- package/src/tools/tool-defaults.ts +2 -9
- package/src/tools/tool-manifest.ts +0 -3
- package/src/tools/types.ts +2 -17
- package/src/tools/workspace-tools/loader.ts +244 -348
- package/src/util/errors.ts +1 -26
- package/src/util/platform.ts +0 -5
- package/src/workflows/library.test.ts +0 -140
- package/src/workflows/library.ts +28 -82
- package/src/workspace/migrations/017-seed-persona-dirs.ts +34 -3
- package/src/workspace/migrations/019-scope-journal-to-guardian.ts +24 -3
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +66 -14
- package/src/workspace/migrations/registry.ts +0 -2
- package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +0 -91
- package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +0 -48
- package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +0 -28
- package/node_modules/@vellumai/service-contracts/src/channels.ts +0 -41
- package/src/__tests__/code-search-tool.test.ts +0 -585
- package/src/__tests__/guardian-expiry-notifier.test.ts +0 -282
- package/src/__tests__/mcp-config-secret-boundary.test.ts +0 -390
- package/src/__tests__/plugin-pipeline.test.ts +0 -96
- package/src/__tests__/sse-actor-principal-guardian-source.test.ts +0 -102
- package/src/__tests__/steer-on-enqueue-question.test.ts +0 -181
- package/src/__tests__/workspace-migration-111-prune-seeded-callsite-defaults.test.ts +0 -208
- package/src/agent/loop-exclusive-tool.test.ts +0 -150
- package/src/api/constants/sse-replay.ts +0 -41
- package/src/api/events/conversation-notice.ts +0 -26
- package/src/approvals/guardian-channel-delivery.ts +0 -30
- package/src/approvals/guardian-expiry-notifier.ts +0 -148
- package/src/cli/commands/memory/__tests__/worker.test.ts +0 -302
- package/src/cli/commands/memory/worker.ts +0 -175
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +0 -143
- package/src/config/prune-seeded-callsite-defaults.ts +0 -110
- package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +0 -129
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +0 -312
- package/src/contacts/__tests__/member-write-relay.test.ts +0 -202
- package/src/contacts/guardian-delivery-reader.ts +0 -223
- package/src/contacts/member-write-relay.ts +0 -189
- package/src/daemon/conversation-notices.ts +0 -60
- package/src/daemon/handlers/__tests__/config-channels.test.ts +0 -225
- package/src/hooks/hook-loader.ts +0 -341
- package/src/mcp/mcp-header-store.ts +0 -134
- package/src/memory/__tests__/301-create-watchdog-events.test.ts +0 -110
- package/src/memory/__tests__/prompt-override.test.ts +0 -192
- package/src/memory/__tests__/watchdog-events-store.test.ts +0 -161
- package/src/memory/migrations/300-add-processing-started-at.ts +0 -30
- package/src/memory/migrations/301-create-watchdog-events.ts +0 -45
- package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +0 -224
- package/src/memory/prompt-override.ts +0 -129
- package/src/memory/steps.ts +0 -573
- package/src/memory/watchdog-events-store.ts +0 -87
- package/src/memory/worker-control.ts +0 -118
- package/src/memory/worker-process.ts +0 -72
- package/src/notifications/__tests__/connected-channels.test.ts +0 -114
- package/src/notifications/__tests__/destination-resolver.test.ts +0 -256
- package/src/onboarding/checkin-event.test.ts +0 -222
- package/src/onboarding/checkin-event.ts +0 -321
- package/src/onboarding/schedule-checkin.ts +0 -190
- package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +0 -106
- package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +0 -60
- package/src/plugins/defaults/advisor/context-pack.ts +0 -288
- package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +0 -146
- package/src/plugins/surface-import.ts +0 -121
- package/src/providers/openai/__tests__/api-error-normalization.test.ts +0 -321
- package/src/providers/openai/api-error-normalization.ts +0 -270
- package/src/runtime/__tests__/channel-verification-service.test.ts +0 -133
- package/src/runtime/__tests__/guardian-vellum-migration.test.ts +0 -181
- package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +0 -66
- package/src/runtime/__tests__/local-principal-trust.test.ts +0 -164
- package/src/runtime/anchored-guardian.test.ts +0 -156
- package/src/runtime/anchored-guardian.ts +0 -135
- package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +0 -99
- package/src/runtime/local-principal-trust.ts +0 -52
- package/src/runtime/routes/__tests__/contact-routes.test.ts +0 -212
- package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -93
- package/src/runtime/routes/onboarding-checkin-routes.ts +0 -86
- package/src/tools/filesystem/search.ts +0 -543
- package/src/util/telemetry-db-path.ts +0 -24
- package/src/workspace/migrations/111-prune-seeded-callsite-defaults.ts +0 -134
|
@@ -9,17 +9,23 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { z } from "zod";
|
|
11
11
|
|
|
12
|
+
import type { ChannelId } from "../../channels/types.js";
|
|
12
13
|
import { isHttpAuthDisabled } from "../../config/env.js";
|
|
13
|
-
import
|
|
14
|
+
import { findGuardianForChannel } from "../../contacts/contact-store.js";
|
|
14
15
|
import { getLogger } from "../../util/logger.js";
|
|
16
|
+
import type { TrustClass } from "../actor-trust-resolver.js";
|
|
17
|
+
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
|
|
15
18
|
import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
16
19
|
import { processGuardianDecision } from "../guardian-action-service.js";
|
|
17
|
-
import {
|
|
20
|
+
import { healGuardianBindingDrift } from "../guardian-vellum-migration.js";
|
|
18
21
|
import {
|
|
19
|
-
findLocalGuardianPrincipalId,
|
|
20
22
|
resolveActorPrincipalIdForLocalGuardian,
|
|
23
|
+
resolveLocalTrustContext,
|
|
21
24
|
} from "../local-actor-identity.js";
|
|
22
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
resolveTrustContext,
|
|
27
|
+
withSourceChannel,
|
|
28
|
+
} from "../trust-context-resolver.js";
|
|
23
29
|
import { parseCallbackData } from "./channel-route-shared.js";
|
|
24
30
|
import {
|
|
25
31
|
BadRequestError,
|
|
@@ -37,51 +43,58 @@ const log = getLogger("surface-action-routes");
|
|
|
37
43
|
// ---------------------------------------------------------------------------
|
|
38
44
|
|
|
39
45
|
/**
|
|
40
|
-
* Resolve trust context
|
|
41
|
-
*
|
|
42
|
-
*
|
|
46
|
+
* Resolve trust context from the actor principal ID and set it on the
|
|
47
|
+
* conversation, following the same pattern as POST /v1/messages. This ensures
|
|
48
|
+
* surface actions inherit the correct trust class (guardian vs trusted_contact)
|
|
49
|
+
* rather than defaulting to unknown.
|
|
43
50
|
*/
|
|
44
|
-
|
|
51
|
+
function applyTrustContext(
|
|
45
52
|
conversation: {
|
|
46
|
-
setTrustContext?(ctx:
|
|
53
|
+
setTrustContext?(ctx: {
|
|
54
|
+
trustClass: TrustClass;
|
|
55
|
+
sourceChannel: ChannelId;
|
|
56
|
+
}): void;
|
|
47
57
|
},
|
|
48
58
|
actorPrincipalId: string | undefined,
|
|
49
|
-
):
|
|
59
|
+
): void {
|
|
50
60
|
if (!conversation.setTrustContext) return;
|
|
51
61
|
|
|
52
62
|
const sourceChannel = "vellum";
|
|
53
63
|
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
64
|
+
if (actorPrincipalId) {
|
|
65
|
+
if (isHttpAuthDisabled() && actorPrincipalId === "dev-bypass") {
|
|
66
|
+
conversation.setTrustContext(resolveLocalTrustContext(sourceChannel));
|
|
67
|
+
} else {
|
|
68
|
+
const assistantId = DAEMON_INTERNAL_ASSISTANT_ID;
|
|
69
|
+
let trustCtx = resolveTrustContext({
|
|
70
|
+
assistantId,
|
|
71
|
+
sourceChannel,
|
|
72
|
+
conversationExternalId: "local",
|
|
73
|
+
actorExternalId: actorPrincipalId,
|
|
74
|
+
});
|
|
75
|
+
if (trustCtx.trustClass === "unknown") {
|
|
76
|
+
const healed = healGuardianBindingDrift(actorPrincipalId);
|
|
77
|
+
if (healed) {
|
|
78
|
+
trustCtx = resolveTrustContext({
|
|
79
|
+
assistantId,
|
|
80
|
+
sourceChannel,
|
|
81
|
+
conversationExternalId: "local",
|
|
82
|
+
actorExternalId: actorPrincipalId,
|
|
83
|
+
});
|
|
84
|
+
log.info(
|
|
85
|
+
{
|
|
86
|
+
actorPrincipalId,
|
|
87
|
+
trustClass: trustCtx.trustClass,
|
|
88
|
+
},
|
|
89
|
+
"Trust re-resolved after guardian binding drift heal (surface action)",
|
|
90
|
+
);
|
|
91
|
+
}
|
|
81
92
|
}
|
|
93
|
+
conversation.setTrustContext(withSourceChannel(sourceChannel, trustCtx));
|
|
82
94
|
}
|
|
95
|
+
} else {
|
|
96
|
+
conversation.setTrustContext({ trustClass: "guardian", sourceChannel });
|
|
83
97
|
}
|
|
84
|
-
conversation.setTrustContext(trustCtx);
|
|
85
98
|
}
|
|
86
99
|
|
|
87
100
|
// ---------------------------------------------------------------------------
|
|
@@ -119,15 +132,16 @@ async function handleSurfaceAction({
|
|
|
119
132
|
const aprDecision = parseCallbackData(actionId, "vellum");
|
|
120
133
|
if (aprDecision) {
|
|
121
134
|
// Resolve the actor's guardian principal ID. In dev mode the synthetic
|
|
122
|
-
// "dev-bypass" principal won't match the real guardian binding, so
|
|
123
|
-
// the local guardian
|
|
135
|
+
// "dev-bypass" principal won't match the real guardian binding, so fall
|
|
136
|
+
// back to the local guardian binding — mirrors guardian-action-routes.ts.
|
|
124
137
|
let guardianPrincipalId: string | undefined =
|
|
125
138
|
headers?.["x-vellum-actor-principal-id"] ?? undefined;
|
|
126
139
|
if (
|
|
127
140
|
isHttpAuthDisabled() &&
|
|
128
141
|
headers?.["x-vellum-actor-principal-id"] === "dev-bypass"
|
|
129
142
|
) {
|
|
130
|
-
|
|
143
|
+
const binding = findGuardianForChannel("vellum");
|
|
144
|
+
guardianPrincipalId = binding?.contact.principalId ?? undefined;
|
|
131
145
|
}
|
|
132
146
|
|
|
133
147
|
const result = await processGuardianDecision({
|
|
@@ -175,7 +189,7 @@ async function handleSurfaceAction({
|
|
|
175
189
|
}
|
|
176
190
|
|
|
177
191
|
const actorPrincipalId = headers?.["x-vellum-actor-principal-id"];
|
|
178
|
-
|
|
192
|
+
applyTrustContext(conversation, actorPrincipalId);
|
|
179
193
|
|
|
180
194
|
// Translate dev-bypass → real guardian so the surface turn's principal matches
|
|
181
195
|
// the SSE host-proxy client's registered principal; otherwise CU/app-control
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { parseChannelId } from "../../channels/types.js";
|
|
11
11
|
import { getConfig } from "../../config/loader.js";
|
|
12
|
+
import { findConversation } from "../../daemon/conversation-registry.js";
|
|
12
13
|
import { normalizeConversationType } from "../../daemon/message-types/shared.js";
|
|
13
14
|
import {
|
|
14
15
|
type AttentionState,
|
|
@@ -20,7 +21,6 @@ import {
|
|
|
20
21
|
type ConversationRow,
|
|
21
22
|
getConversation,
|
|
22
23
|
getDisplayMetaForConversations,
|
|
23
|
-
isConversationProcessing,
|
|
24
24
|
} from "../../memory/conversation-crud.js";
|
|
25
25
|
import type { ExternalConversationBinding } from "../../memory/external-conversation-store.js";
|
|
26
26
|
import { getBindingsForConversations } from "../../memory/external-conversation-store.js";
|
|
@@ -196,9 +196,9 @@ export function serializeConversationSummary(params: {
|
|
|
196
196
|
parentCache: Map<string, ConversationRow | null>;
|
|
197
197
|
/**
|
|
198
198
|
* Whether the agent loop is currently mid-turn for this conversation.
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
199
|
+
* Sourced from the in-memory daemon `Conversation.isProcessing()` flag
|
|
200
|
+
* — callers resolve via `findConversation(id)?.isProcessing() ?? false`
|
|
201
|
+
* so cold (evicted / never-loaded) rows report `false`. Plumbed in
|
|
202
202
|
* rather than read here so the serializer stays a pure shape mapper
|
|
203
203
|
* with no daemon-store coupling.
|
|
204
204
|
*/
|
|
@@ -286,9 +286,11 @@ export function buildConversationDetailResponse(
|
|
|
286
286
|
attentionState: attentionStates.get(conversation.id),
|
|
287
287
|
displayMeta: displayMeta.get(conversation.id),
|
|
288
288
|
parentCache,
|
|
289
|
-
//
|
|
290
|
-
//
|
|
291
|
-
isProcessing:
|
|
289
|
+
// Cold (evicted / never-loaded) rows aren't in the in-memory
|
|
290
|
+
// store, so `findConversation` returns `undefined` and they
|
|
291
|
+
// report `isProcessing: false` — by definition they aren't
|
|
292
|
+
// mid-turn since the agent loop only runs on resident convs.
|
|
293
|
+
isProcessing: findConversation(conversation.id)?.isProcessing() ?? false,
|
|
292
294
|
}),
|
|
293
295
|
};
|
|
294
296
|
}
|
|
@@ -59,9 +59,9 @@ export type ToolGrantRequestResult =
|
|
|
59
59
|
* Returns a result indicating whether a new request was created, an existing
|
|
60
60
|
* one was deduped, or the escalation failed (no binding, missing identity).
|
|
61
61
|
*/
|
|
62
|
-
export
|
|
62
|
+
export function createOrReuseToolGrantRequest(
|
|
63
63
|
params: ToolGrantRequestParams,
|
|
64
|
-
):
|
|
64
|
+
): ToolGrantRequestResult {
|
|
65
65
|
const {
|
|
66
66
|
assistantId,
|
|
67
67
|
sourceChannel,
|
|
@@ -78,7 +78,7 @@ export async function createOrReuseToolGrantRequest(
|
|
|
78
78
|
return { failed: true, reason: "missing_identity" };
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
const binding =
|
|
81
|
+
const binding = getGuardianBinding(assistantId, sourceChannel);
|
|
82
82
|
if (!binding) {
|
|
83
83
|
log.debug(
|
|
84
84
|
{ sourceChannel, assistantId },
|
|
@@ -33,17 +33,16 @@ export interface TrustVerdictTransport {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
37
|
-
* identity (mirroring `resolveActorTrust`), without any local DB/IPC reads.
|
|
36
|
+
* Build a {@link TrustContext} from a gateway verdict + transport identity.
|
|
38
37
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
38
|
+
* Reassembles an {@link ActorTrustContext} (mirroring `resolveActorTrust`) and
|
|
39
|
+
* routes it through {@link toTrustContext}, so the output is byte-identical to
|
|
40
|
+
* the local resolution path.
|
|
42
41
|
*/
|
|
43
|
-
export function
|
|
42
|
+
export function trustContextFromVerdict(
|
|
44
43
|
verdict: TrustVerdict,
|
|
45
44
|
input: TrustVerdictTransport,
|
|
46
|
-
):
|
|
45
|
+
): TrustContext {
|
|
47
46
|
const canonicalSenderId = verdict.canonicalSenderId;
|
|
48
47
|
const memberDisplayName = verdict.memberDisplayName;
|
|
49
48
|
const senderDisplayName = input.actorDisplayName;
|
|
@@ -52,7 +51,7 @@ export function actorTrustContextFromVerdict(
|
|
|
52
51
|
? `@${username}`
|
|
53
52
|
: (canonicalSenderId ?? undefined);
|
|
54
53
|
|
|
55
|
-
|
|
54
|
+
const actorTrustContext: ActorTrustContext = {
|
|
56
55
|
canonicalSenderId,
|
|
57
56
|
guardianBindingMatch: verdict.guardianExternalUserId
|
|
58
57
|
? {
|
|
@@ -61,12 +60,7 @@ export function actorTrustContextFromVerdict(
|
|
|
61
60
|
}
|
|
62
61
|
: null,
|
|
63
62
|
guardianPrincipalId: verdict.guardianPrincipalId,
|
|
64
|
-
|
|
65
|
-
// actorTrust.memberRecord.channel status/policy) enforce blocked/revoked/
|
|
66
|
-
// deny/escalate. Null for memberless verdicts. Text path is unaffected:
|
|
67
|
-
// toTrustContext derives the same member fields trustContextFromVerdict
|
|
68
|
-
// already stamps.
|
|
69
|
-
memberRecord: resolvedMemberFromVerdict(verdict),
|
|
63
|
+
memberRecord: null,
|
|
70
64
|
trustClass: verdict.trustClass,
|
|
71
65
|
actorMetadata: {
|
|
72
66
|
identifier,
|
|
@@ -78,21 +72,9 @@ export function actorTrustContextFromVerdict(
|
|
|
78
72
|
trustStatus: verdict.trustClass,
|
|
79
73
|
},
|
|
80
74
|
};
|
|
81
|
-
}
|
|
82
75
|
|
|
83
|
-
/**
|
|
84
|
-
* Build a {@link TrustContext} from a gateway verdict + transport identity.
|
|
85
|
-
*
|
|
86
|
-
* Reassembles an {@link ActorTrustContext} (mirroring `resolveActorTrust`) and
|
|
87
|
-
* routes it through {@link toTrustContext}, so the output is byte-identical to
|
|
88
|
-
* the local resolution path.
|
|
89
|
-
*/
|
|
90
|
-
export function trustContextFromVerdict(
|
|
91
|
-
verdict: TrustVerdict,
|
|
92
|
-
input: TrustVerdictTransport,
|
|
93
|
-
): TrustContext {
|
|
94
76
|
const context = toTrustContext(
|
|
95
|
-
|
|
77
|
+
actorTrustContext,
|
|
96
78
|
input.conversationExternalId,
|
|
97
79
|
);
|
|
98
80
|
|
|
@@ -109,26 +91,6 @@ export function trustContextFromVerdict(
|
|
|
109
91
|
return context;
|
|
110
92
|
}
|
|
111
93
|
|
|
112
|
-
/**
|
|
113
|
-
* True when the verdict carries a member identity (contactId or channelId),
|
|
114
|
-
* regardless of whether that member resolves to a usable {@link ResolvedMember}.
|
|
115
|
-
*/
|
|
116
|
-
export function verdictHasMemberIdentity(verdict: TrustVerdict): boolean {
|
|
117
|
-
return !!(verdict.contactId || verdict.channelId);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* True when the verdict claims a member identity but that member can't be
|
|
122
|
-
* synthesized (partial/mixed-version verdict). Such a verdict is unusable —
|
|
123
|
-
* callers fall back to local resolution.
|
|
124
|
-
*/
|
|
125
|
-
export function verdictMemberUnresolvable(verdict: TrustVerdict): boolean {
|
|
126
|
-
return (
|
|
127
|
-
verdictHasMemberIdentity(verdict) &&
|
|
128
|
-
resolvedMemberFromVerdict(verdict) === null
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
94
|
// Allowed ACL enum values, kept in sync with the ContactChannel union types.
|
|
133
95
|
const CHANNEL_STATUS_VALUES: readonly ChannelStatus[] = [
|
|
134
96
|
"active",
|
|
@@ -151,44 +113,6 @@ function isChannelPolicy(value: string): value is ChannelPolicy {
|
|
|
151
113
|
return (CHANNEL_POLICY_VALUES as readonly string[]).includes(value);
|
|
152
114
|
}
|
|
153
115
|
|
|
154
|
-
/**
|
|
155
|
-
* The ACL fields a gateway verdict carries for a resolved member, decoupled
|
|
156
|
-
* from the schema-derived {@link ContactChannel}.
|
|
157
|
-
*/
|
|
158
|
-
export interface VerdictMember {
|
|
159
|
-
contactId: string;
|
|
160
|
-
channelId: string;
|
|
161
|
-
status: ChannelStatus;
|
|
162
|
-
policy: ChannelPolicy;
|
|
163
|
-
verifiedAt: number | null;
|
|
164
|
-
displayName: string | null;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Extract the narrow {@link VerdictMember} ACL view from a gateway verdict.
|
|
169
|
-
*
|
|
170
|
-
* Mirrors {@link resolvedMemberFromVerdict}'s guards (contactId/channelId
|
|
171
|
-
* present + known status/policy enums), failing closed to null otherwise.
|
|
172
|
-
*/
|
|
173
|
-
export function verdictMemberFromVerdict(
|
|
174
|
-
verdict: TrustVerdict,
|
|
175
|
-
): VerdictMember | null {
|
|
176
|
-
if (!verdict.contactId || !verdict.channelId) return null;
|
|
177
|
-
if (!verdict.status || !verdict.policy) return null;
|
|
178
|
-
if (!isChannelStatus(verdict.status) || !isChannelPolicy(verdict.policy)) {
|
|
179
|
-
return null;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return {
|
|
183
|
-
contactId: verdict.contactId,
|
|
184
|
-
channelId: verdict.channelId,
|
|
185
|
-
status: verdict.status,
|
|
186
|
-
policy: verdict.policy,
|
|
187
|
-
verifiedAt: verdict.verifiedAt ?? null,
|
|
188
|
-
displayName: verdict.memberDisplayName ?? null,
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
116
|
/**
|
|
193
117
|
* Build a synthetic {@link ResolvedMember} from a gateway verdict.
|
|
194
118
|
*
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
countRecentSendsToDestination,
|
|
22
22
|
createOutboundSession,
|
|
23
23
|
findActiveSession,
|
|
24
|
-
|
|
24
|
+
getGuardianBinding,
|
|
25
25
|
updateSessionDelivery,
|
|
26
26
|
updateSessionStatus,
|
|
27
27
|
} from "./channel-verification-service.js";
|
|
@@ -224,7 +224,7 @@ export async function startOutbound(
|
|
|
224
224
|
originConversationId,
|
|
225
225
|
);
|
|
226
226
|
} else if (channel === "phone") {
|
|
227
|
-
return
|
|
227
|
+
return startOutboundVoice(
|
|
228
228
|
params.destination,
|
|
229
229
|
assistantId,
|
|
230
230
|
channel,
|
|
@@ -232,7 +232,7 @@ export async function startOutbound(
|
|
|
232
232
|
originConversationId,
|
|
233
233
|
);
|
|
234
234
|
} else if (channel === "slack") {
|
|
235
|
-
return
|
|
235
|
+
return startOutboundSlack(
|
|
236
236
|
params.destination,
|
|
237
237
|
assistantId,
|
|
238
238
|
channel,
|
|
@@ -240,7 +240,7 @@ export async function startOutbound(
|
|
|
240
240
|
originConversationId,
|
|
241
241
|
);
|
|
242
242
|
} else if (channel === "email") {
|
|
243
|
-
return
|
|
243
|
+
return startOutboundEmail(
|
|
244
244
|
params.destination,
|
|
245
245
|
assistantId,
|
|
246
246
|
channel,
|
|
@@ -274,8 +274,8 @@ async function startOutboundTelegram(
|
|
|
274
274
|
};
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
-
const
|
|
278
|
-
if (
|
|
277
|
+
const existingBinding = getGuardianBinding(assistantId, channel);
|
|
278
|
+
if (existingBinding && !rebind) {
|
|
279
279
|
return {
|
|
280
280
|
success: false,
|
|
281
281
|
error: "already_bound",
|
|
@@ -394,13 +394,13 @@ async function startOutboundTelegram(
|
|
|
394
394
|
};
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
-
|
|
397
|
+
function startOutboundVoice(
|
|
398
398
|
rawDestination: string | undefined,
|
|
399
399
|
assistantId: string,
|
|
400
400
|
channel: ChannelId,
|
|
401
401
|
rebind?: boolean,
|
|
402
402
|
originConversationId?: string,
|
|
403
|
-
):
|
|
403
|
+
): OutboundActionResult {
|
|
404
404
|
if (!rawDestination) {
|
|
405
405
|
return {
|
|
406
406
|
success: false,
|
|
@@ -422,8 +422,8 @@ async function startOutboundVoice(
|
|
|
422
422
|
};
|
|
423
423
|
}
|
|
424
424
|
|
|
425
|
-
const
|
|
426
|
-
if (
|
|
425
|
+
const existingBinding = getGuardianBinding(assistantId, channel);
|
|
426
|
+
if (existingBinding && !rebind) {
|
|
427
427
|
return {
|
|
428
428
|
success: false,
|
|
429
429
|
error: "already_bound",
|
|
@@ -591,13 +591,13 @@ export function deliverVerificationEmail(
|
|
|
591
591
|
})();
|
|
592
592
|
}
|
|
593
593
|
|
|
594
|
-
|
|
594
|
+
function startOutboundSlack(
|
|
595
595
|
destination: string | undefined,
|
|
596
596
|
assistantId: string,
|
|
597
597
|
channel: ChannelId,
|
|
598
598
|
rebind?: boolean,
|
|
599
599
|
originConversationId?: string,
|
|
600
|
-
):
|
|
600
|
+
): OutboundActionResult {
|
|
601
601
|
if (!destination) {
|
|
602
602
|
return {
|
|
603
603
|
success: false,
|
|
@@ -607,8 +607,8 @@ async function startOutboundSlack(
|
|
|
607
607
|
};
|
|
608
608
|
}
|
|
609
609
|
|
|
610
|
-
const
|
|
611
|
-
if (
|
|
610
|
+
const existingBinding = getGuardianBinding(assistantId, channel);
|
|
611
|
+
if (existingBinding && !rebind) {
|
|
612
612
|
return {
|
|
613
613
|
success: false,
|
|
614
614
|
error: "already_bound",
|
|
@@ -669,13 +669,13 @@ async function startOutboundSlack(
|
|
|
669
669
|
};
|
|
670
670
|
}
|
|
671
671
|
|
|
672
|
-
|
|
672
|
+
function startOutboundEmail(
|
|
673
673
|
destination: string | undefined,
|
|
674
674
|
assistantId: string,
|
|
675
675
|
channel: ChannelId,
|
|
676
676
|
rebind?: boolean,
|
|
677
677
|
originConversationId?: string,
|
|
678
|
-
):
|
|
678
|
+
): OutboundActionResult {
|
|
679
679
|
if (!destination) {
|
|
680
680
|
return {
|
|
681
681
|
success: false,
|
|
@@ -688,8 +688,8 @@ async function startOutboundEmail(
|
|
|
688
688
|
|
|
689
689
|
const normalizedEmail = destination.trim().toLowerCase();
|
|
690
690
|
|
|
691
|
-
const
|
|
692
|
-
if (
|
|
691
|
+
const existingBinding = getGuardianBinding(assistantId, channel);
|
|
692
|
+
if (existingBinding && !rebind) {
|
|
693
693
|
return {
|
|
694
694
|
success: false,
|
|
695
695
|
error: "already_bound",
|
|
@@ -15,7 +15,6 @@ import { readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
|
15
15
|
import { join } from "node:path";
|
|
16
16
|
|
|
17
17
|
import { getOrCreateConversation } from "../daemon/conversation-store.js";
|
|
18
|
-
import { supersedePendingInteractionsOnEnqueue } from "../daemon/handlers/conversations.js";
|
|
19
18
|
import type { UserMessageAttachment } from "../daemon/message-types/shared.js";
|
|
20
19
|
import {
|
|
21
20
|
processMessageInBackground,
|
|
@@ -132,21 +131,6 @@ async function dispatchUserMessage(params: {
|
|
|
132
131
|
assistantMessageInterface: resolvedInterface,
|
|
133
132
|
},
|
|
134
133
|
});
|
|
135
|
-
if (!result.rejected) {
|
|
136
|
-
// Mirror the HTTP send path: a follow-up enqueued while the turn is busy
|
|
137
|
-
// auto-denies pending confirmations and supersedes a parked ask_question
|
|
138
|
-
// so it isn't stranded behind the prompt until the response backstop.
|
|
139
|
-
// Best-effort — the message is already queued, so a cleanup failure must
|
|
140
|
-
// not surface as an error that makes the CLI retry and enqueue a duplicate.
|
|
141
|
-
try {
|
|
142
|
-
supersedePendingInteractionsOnEnqueue(conversationId, requestId);
|
|
143
|
-
} catch (err) {
|
|
144
|
-
log.warn(
|
|
145
|
-
{ err, conversationId },
|
|
146
|
-
"Post-enqueue supersession failed — queued message unaffected",
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
134
|
return { accepted: !result.rejected };
|
|
151
135
|
}
|
|
152
136
|
|
package/src/subagent/manager.ts
CHANGED
|
@@ -553,15 +553,6 @@ export class SubagentManager {
|
|
|
553
553
|
),
|
|
554
554
|
);
|
|
555
555
|
managed.state.completedAt = Date.now();
|
|
556
|
-
// Capture the conversation's latest usage before emitting the terminal
|
|
557
|
-
// status. `subagent_status_changed` ships `state.usage`, and the abort path
|
|
558
|
-
// (unlike the completion/failure paths, which sync at agent-loop exit) would
|
|
559
|
-
// otherwise send the {0,0,0} init usage — zeroing the client's token counts
|
|
560
|
-
// even though those tokens were already spent. `usageStats` accrues per LLM
|
|
561
|
-
// turn (see conversation-usage.ts), so this is the most recent total.
|
|
562
|
-
if (managed.conversation) {
|
|
563
|
-
managed.state.usage = { ...managed.conversation.usageStats };
|
|
564
|
-
}
|
|
565
556
|
if (parentSendToClient) {
|
|
566
557
|
// Route the status update through the stored parent sender so the
|
|
567
558
|
// owning conversation's UI chip updates, even when the abort comes from a
|
package/src/subagent/types.ts
CHANGED
|
@@ -180,7 +180,7 @@ export const SUBAGENT_ROLE_REGISTRY: Record<SubagentRole, SubagentRoleConfig> =
|
|
|
180
180
|
},
|
|
181
181
|
investigator: {
|
|
182
182
|
allowedTools: [
|
|
183
|
-
"
|
|
183
|
+
"bash",
|
|
184
184
|
"file_read",
|
|
185
185
|
"file_list",
|
|
186
186
|
"web_search",
|
|
@@ -191,8 +191,8 @@ export const SUBAGENT_ROLE_REGISTRY: Record<SubagentRole, SubagentRoleConfig> =
|
|
|
191
191
|
skillIds: [],
|
|
192
192
|
systemPromptPreamble: [
|
|
193
193
|
"You are an investigation-focused subagent for root-cause analysis: debugging, log forensics, and tracing behavior across code.",
|
|
194
|
-
"
|
|
195
|
-
"Working method: read whole files instead of many small line-range slices; prefer broad
|
|
194
|
+
"Your shell access is for read-only investigation (grep, find, reading files and logs) — do not modify files or system state.",
|
|
195
|
+
"Working method: read whole files instead of many small line-range slices; prefer broad searches (e.g. grep -rn across a directory) over one-symbol-at-a-time queries.",
|
|
196
196
|
"Send notify_parent (urgency 'important') as soon as each finding is confirmed, so progress survives interruption.",
|
|
197
197
|
"Your final message must be a compact root-cause report with these sections: Symptom, Root cause, Evidence (file:line references), Suggested fix, Open questions.",
|
|
198
198
|
"If you approach context limits, stop investigating and produce the report from what you have — a partial report delivered is worth more than a complete investigation lost.",
|
package/src/telemetry/types.ts
CHANGED
|
@@ -391,38 +391,6 @@ export interface SkillLoadedTelemetryEvent extends ModelTelemetryEventBase {
|
|
|
391
391
|
conversation_id: string | null;
|
|
392
392
|
}
|
|
393
393
|
|
|
394
|
-
/**
|
|
395
|
-
* Watchdog health event — one per watchdog check firing. The daemon's
|
|
396
|
-
* watchdog observes liveness/health signals (event-loop block, stream-idle
|
|
397
|
-
* stalls, restarts, ...) and emits one event per check firing.
|
|
398
|
-
*
|
|
399
|
-
* Deliberately minimal and forward-compatible, mirroring the platform
|
|
400
|
-
* `WatchdogTelemetryEventSerializer`:
|
|
401
|
-
*
|
|
402
|
-
* - `check_name` — which watchdog check fired. Open string set (not a
|
|
403
|
-
* closed enum) so the daemon can introduce a new check without a
|
|
404
|
-
* coordinated serializer release; it is the primary group-by dimension
|
|
405
|
-
* downstream. The infrastructure admin chart filters this to
|
|
406
|
-
* `event_loop_blocked`.
|
|
407
|
-
* - `value` — the single measured magnitude for the check (block ms, idle
|
|
408
|
-
* ms, ...). Nullable: not every check carries a scalar. The platform
|
|
409
|
-
* coerces ints to float, so the daemon need not distinguish.
|
|
410
|
-
* - `detail` — open JSON bag for any extra fields the daemon attaches
|
|
411
|
-
* (reason codes, secondary numbers, a human message) without a
|
|
412
|
-
* platform-coordinated schema change. Null when the daemon attaches
|
|
413
|
-
* nothing. Bounded server-side (4096 bytes serialized); an oversize bag
|
|
414
|
-
* rejects only the single event, never the batch.
|
|
415
|
-
*
|
|
416
|
-
* Metadata only — no conversation content. Dedupe downstream on
|
|
417
|
-
* `daemon_event_id` (the daemon retries a batch on transient POST failure).
|
|
418
|
-
*/
|
|
419
|
-
export interface WatchdogTelemetryEvent extends TelemetryEventBase {
|
|
420
|
-
type: "watchdog";
|
|
421
|
-
check_name: string;
|
|
422
|
-
value: number | null;
|
|
423
|
-
detail: Record<string, unknown> | null;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
394
|
/** Discriminated union of all telemetry event types. */
|
|
427
395
|
export type TelemetryEvent =
|
|
428
396
|
| LlmUsageTelemetryEvent
|
|
@@ -431,5 +399,4 @@ export type TelemetryEvent =
|
|
|
431
399
|
| OnboardingTelemetryEvent
|
|
432
400
|
| AuthFallbackTelemetryEvent
|
|
433
401
|
| ToolExecutedTelemetryEvent
|
|
434
|
-
| SkillLoadedTelemetryEvent
|
|
435
|
-
| WatchdogTelemetryEvent;
|
|
402
|
+
| SkillLoadedTelemetryEvent;
|
|
@@ -1547,11 +1547,11 @@ describe("UsageTelemetryReporter", () => {
|
|
|
1547
1547
|
// No HTTP call should have been made
|
|
1548
1548
|
expect(mockFetch).not.toHaveBeenCalled();
|
|
1549
1549
|
|
|
1550
|
-
// All
|
|
1550
|
+
// All 7 timestamp watermarks should have been advanced, and all 7 ID
|
|
1551
1551
|
// watermarks pinned to the high-sorting sentinel (a truthy value keeps
|
|
1552
1552
|
// the compound-cursor branch active while closing its same-millisecond
|
|
1553
1553
|
// arm against opt-out rows).
|
|
1554
|
-
expect(mockSetMemoryCheckpoint).toHaveBeenCalledTimes(
|
|
1554
|
+
expect(mockSetMemoryCheckpoint).toHaveBeenCalledTimes(14);
|
|
1555
1555
|
|
|
1556
1556
|
const calls = mockSetMemoryCheckpoint.mock.calls;
|
|
1557
1557
|
const keys = calls.map((c) => c[0]);
|
|
@@ -1563,7 +1563,6 @@ describe("UsageTelemetryReporter", () => {
|
|
|
1563
1563
|
"auth_fallback",
|
|
1564
1564
|
"tool_executed",
|
|
1565
1565
|
"skill_loaded",
|
|
1566
|
-
"watchdog",
|
|
1567
1566
|
];
|
|
1568
1567
|
for (const eventType of eventTypes) {
|
|
1569
1568
|
expect(keys).toContain(`telemetry:${eventType}:last_reported_at`);
|