@vellumai/assistant 0.8.5 → 0.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +33 -1
- package/ARCHITECTURE.md +1 -1
- package/bunfig.toml +6 -1
- package/docs/credential-execution-service.md +6 -6
- package/docs/plugins.md +4 -3
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
- package/openapi.yaml +1900 -166
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +3 -2
- package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
- package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/annotate-risk-options.test.ts +1 -0
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +9 -13
- package/src/__tests__/assert-not-live-db.ts +79 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +9 -25
- package/src/__tests__/audit-log-rotation.test.ts +2 -2
- package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
- package/src/__tests__/background-workers-disk-pressure.test.ts +5 -8
- package/src/__tests__/browser-skill-endstate.test.ts +3 -3
- package/src/__tests__/btw-routes.test.ts +3 -2
- package/src/__tests__/call-controller.test.ts +3 -2
- package/src/__tests__/channel-approval-routes.test.ts +3 -2
- package/src/__tests__/channel-guardian.test.ts +3 -2
- package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
- package/src/__tests__/channel-reply-delivery.test.ts +35 -0
- package/src/__tests__/channel-retry-sweep.test.ts +320 -3
- package/src/__tests__/checker.test.ts +12 -12
- package/src/__tests__/compaction-events.test.ts +1 -0
- package/src/__tests__/compaction-trail-store.test.ts +264 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +1 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +7 -5
- package/src/__tests__/computer-use-tools.test.ts +12 -14
- package/src/__tests__/config-loader-backfill.test.ts +13 -28
- package/src/__tests__/config-loader-corrupt.test.ts +5 -5
- package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
- package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
- package/src/__tests__/config-schema.test.ts +10 -10
- package/src/__tests__/connection-model-compat.test.ts +83 -0
- package/src/__tests__/contacts-tools.test.ts +3 -2
- package/src/__tests__/context-token-estimator.test.ts +22 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +34 -0
- package/src/__tests__/conversation-agent-loop.test.ts +488 -2
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
- package/src/__tests__/conversation-app-control-instantiation.test.ts +29 -19
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
- package/src/__tests__/conversation-attention-store.test.ts +101 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-error.test.ts +30 -0
- package/src/__tests__/conversation-fork-crud.test.ts +69 -8
- package/src/__tests__/conversation-fork-route.test.ts +3 -2
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
- package/src/__tests__/conversation-lifecycle.test.ts +1 -0
- package/src/__tests__/conversation-list-source.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
- package/src/__tests__/conversation-load-history-stripped.test.ts +1 -0
- package/src/__tests__/conversation-pairing.test.ts +53 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -0
- package/src/__tests__/conversation-queue.test.ts +333 -291
- package/src/__tests__/conversation-routes-disk-view.test.ts +3 -18
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
- package/src/__tests__/conversation-routes-slash-commands.test.ts +33 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
- package/src/__tests__/conversation-skill-tools.test.ts +38 -142
- package/src/__tests__/conversation-slash-queue.test.ts +84 -32
- package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
- package/src/__tests__/conversation-sync-tags.test.ts +128 -12
- package/src/__tests__/conversation-title-service.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
- package/src/__tests__/conversation-usage.test.ts +1 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -0
- package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
- package/src/__tests__/credential-broker-server-use.test.ts +5 -5
- package/src/__tests__/credential-execution-client.test.ts +72 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +10 -12
- package/src/__tests__/credential-health-service.test.ts +252 -3
- package/src/__tests__/credential-security-invariants.test.ts +5 -5
- package/src/__tests__/credential-vault-unit.test.ts +19 -19
- package/src/__tests__/credential-vault.test.ts +5 -5
- package/src/__tests__/cross-provider-web-search.test.ts +56 -2
- package/src/__tests__/db-connection-isolation.test.ts +7 -6
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
- package/src/__tests__/db-test-helpers.ts +58 -0
- package/src/__tests__/disk-pressure-guard.test.ts +58 -41
- package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
- package/src/__tests__/disk-pressure-routes.test.ts +0 -33
- package/src/__tests__/disk-pressure-tools.test.ts +0 -4
- package/src/__tests__/dm-persistence.test.ts +26 -40
- package/src/__tests__/document-create-dedupe.test.ts +189 -0
- package/src/__tests__/document-find-replace.test.ts +3 -2
- package/src/__tests__/document-tool-security.test.ts +81 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
- package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
- package/src/__tests__/encrypted-store.test.ts +11 -9
- package/src/__tests__/feature-flag-test-helpers.ts +53 -0
- package/src/__tests__/filing-service.test.ts +1 -0
- package/src/__tests__/first-greeting.test.ts +62 -12
- package/src/__tests__/gateway-flag-listener.test.ts +0 -1
- package/src/__tests__/gemini-provider.test.ts +26 -0
- package/src/__tests__/guardian-action-sweep.test.ts +3 -2
- package/src/__tests__/guardian-outbound-http.test.ts +3 -2
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/helpers/mock-logger.ts +26 -0
- package/src/__tests__/host-bash-routes.test.ts +1 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-shell-tool.test.ts +5 -4
- package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
- package/src/__tests__/http-conversation-lineage.test.ts +3 -2
- package/src/__tests__/http-user-message-parity.test.ts +29 -7
- package/src/__tests__/identity-intro-cache.test.ts +133 -22
- package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
- package/src/__tests__/inference-profile-reaper.test.ts +3 -2
- package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
- package/src/__tests__/injector-disk-pressure.test.ts +3 -17
- package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
- package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
- package/src/__tests__/llm-context-normalization.test.ts +42 -0
- package/src/__tests__/llm-resolver.test.ts +331 -0
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
- package/src/__tests__/mcp-abort-signal.test.ts +14 -0
- package/src/__tests__/mcp-client-auth.test.ts +14 -0
- package/src/__tests__/messaging-send-tool.test.ts +1 -0
- package/src/__tests__/migration-import-from-url.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +18 -2
- package/src/__tests__/model-intents.test.ts +3 -3
- package/src/__tests__/native-web-search.test.ts +30 -2
- package/src/__tests__/notification-deep-link.test.ts +62 -0
- package/src/__tests__/oauth-commands-routes.test.ts +37 -0
- package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
- package/src/__tests__/oauth-store.test.ts +3 -2
- package/src/__tests__/onboarding-template-contract.test.ts +3 -2
- package/src/__tests__/openai-provider.test.ts +8 -9
- package/src/__tests__/openai-responses-provider.test.ts +70 -10
- package/src/__tests__/openrouter-provider-only.test.ts +27 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
- package/src/__tests__/persistence-pipeline.test.ts +139 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
- package/src/__tests__/plugin-bootstrap.test.ts +9 -11
- package/src/__tests__/plugin-tool-contribution.test.ts +41 -38
- package/src/__tests__/process-message-background-slack.test.ts +21 -16
- package/src/__tests__/process-message-display-content.test.ts +19 -22
- package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
- package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
- package/src/__tests__/provider-registry-ollama.test.ts +45 -22
- package/src/__tests__/recording-handler.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +82 -76
- package/src/__tests__/relay-server.test.ts +10 -10
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
- package/src/__tests__/schedule-store.test.ts +16 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
- package/src/__tests__/secret-ingress-http.test.ts +5 -1
- package/src/__tests__/secure-keys.test.ts +3 -3
- package/src/__tests__/send-endpoint-busy.test.ts +81 -42
- package/src/__tests__/server-history-render.test.ts +4 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
- package/src/__tests__/skill-feature-flags.test.ts +14 -16
- package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
- package/src/__tests__/skill-projection-feature-flag.test.ts +44 -30
- package/src/__tests__/skill-projection.benchmark.test.ts +5 -7
- package/src/__tests__/skill-tool-factory.test.ts +96 -95
- package/src/__tests__/slack-channel-config.test.ts +3 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
- package/src/__tests__/subagent-disposal.test.ts +27 -8
- package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
- package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
- package/src/__tests__/subagent-manager-notify.test.ts +20 -8
- package/src/__tests__/subagent-notify-parent.test.ts +5 -4
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
- package/src/__tests__/subagent-tools.test.ts +2 -1
- package/src/__tests__/suggestion-routes.test.ts +1 -0
- package/src/__tests__/system-prompt.test.ts +38 -0
- package/src/__tests__/test-preload-verifier.ts +68 -0
- package/src/__tests__/test-preload.ts +32 -39
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +20 -7
- package/src/__tests__/tool-executor.test.ts +55 -10
- package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/twilio-routes.test.ts +3 -2
- package/src/__tests__/validate-input.test.ts +381 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -0
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
- package/src/__tests__/voice-session-bridge.test.ts +37 -28
- package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
- package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
- package/src/acp/session-manager.ts +5 -6
- package/src/agent/loop.ts +80 -0
- package/src/api/README.md +124 -2
- package/src/api/constants/call-sites.ts +27 -0
- package/src/api/events/assistant-outbound-attachment.ts +51 -0
- package/src/api/events/assistant-text-delta.ts +32 -0
- package/src/api/events/assistant-turn-start.ts +33 -0
- package/src/api/events/document-comment-created.ts +48 -0
- package/src/api/events/document-comment-deleted.ts +24 -0
- package/src/api/events/document-comment-reopened.ts +25 -0
- package/src/api/events/document-comment-resolved.ts +27 -0
- package/src/api/events/generation-cancelled.ts +24 -0
- package/src/api/events/generation-handoff.ts +41 -0
- package/src/api/events/message-complete.ts +42 -0
- package/src/api/events/open-url.ts +30 -0
- package/src/{events → api/events}/relationship-state-updated.ts +3 -3
- package/src/api/events/tool-use-start.ts +32 -0
- package/src/api/index.ts +128 -3
- package/src/api/responses/llm-context-response.ts +39 -0
- package/src/api/responses/llm-request-log-entry.ts +93 -0
- package/src/api/responses/memory-recall-log.ts +65 -0
- package/src/api/responses/memory-v2-activation-log.ts +78 -0
- package/src/background-wake/background-wake-routes.test.ts +687 -52
- package/src/background-wake/platform-client.test.ts +308 -0
- package/src/background-wake/platform-client.ts +167 -0
- package/src/background-wake/publisher.ts +91 -0
- package/src/background-wake/runtime-registry.ts +2 -2
- package/src/background-wake/wake-intent-hooks.test.ts +282 -0
- package/src/calls/guardian-dispatch.ts +1 -0
- package/src/calls/voice-session-bridge.ts +4 -4
- package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
- package/src/cli/commands/__tests__/notifications.test.ts +184 -40
- package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
- package/src/cli/commands/channels/index.ts +229 -0
- package/src/cli/commands/memory-v3-render.ts +147 -0
- package/src/cli/commands/memory-v3.ts +255 -4
- package/src/cli/commands/notifications.ts +365 -55
- package/src/cli/lib/open-browser.ts +7 -2
- package/src/cli/program.ts +2 -0
- package/src/config/assistant-feature-flags.ts +23 -42
- package/src/config/bundled-skills/document-editor/SKILL.md +5 -1
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
- package/src/config/call-site-defaults.ts +1 -1
- package/src/config/feature-flag-cache.ts +86 -0
- package/src/config/feature-flag-registry.json +17 -17
- package/src/config/llm-context-resolution.ts +10 -1
- package/src/config/llm-resolver.ts +121 -15
- package/src/config/loader.ts +4 -5
- package/src/config/schemas/__tests__/memory-v2.test.ts +15 -0
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +90 -1
- package/src/config/schemas/memory-v2.ts +26 -0
- package/src/config/schemas/services.ts +6 -2
- package/src/config/seed-inference-profiles.ts +36 -16
- package/src/context/token-estimator.ts +10 -5
- package/src/credential-execution/executable-discovery.ts +40 -0
- package/src/credential-execution/process-manager.ts +6 -2
- package/src/credential-health/credential-health-service.ts +125 -40
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -2
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +389 -68
- package/src/daemon/conversation-agent-loop.ts +132 -28
- package/src/daemon/conversation-error.ts +33 -5
- package/src/daemon/conversation-messaging.ts +84 -43
- package/src/daemon/conversation-process.ts +74 -37
- package/src/daemon/conversation-runtime-assembly.ts +29 -9
- package/src/daemon/conversation-skill-tools.ts +14 -30
- package/src/daemon/conversation-surfaces.ts +69 -34
- package/src/daemon/conversation-tool-setup.ts +33 -48
- package/src/daemon/conversation.ts +26 -46
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/daemon-skill-host.ts +9 -2
- package/src/daemon/disk-pressure-guard.ts +27 -29
- package/src/daemon/first-greeting.ts +31 -13
- package/src/daemon/handlers/shared.ts +6 -1
- package/src/daemon/lifecycle.ts +12 -12
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/meet-manifest-loader.ts +10 -17
- package/src/daemon/message-types/conversations.ts +20 -22
- package/src/daemon/message-types/document-comments.ts +8 -44
- package/src/daemon/message-types/home.ts +2 -2
- package/src/daemon/message-types/integrations.ts +2 -7
- package/src/daemon/message-types/messages.ts +23 -38
- package/src/daemon/message-types/subagents.ts +6 -0
- package/src/daemon/process-message.ts +9 -9
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/server.ts +16 -0
- package/src/daemon/switch-inference-profile-tool.ts +13 -3
- package/src/daemon/tool-setup-types.ts +0 -6
- package/src/daemon/wake-target-adapter.ts +10 -0
- package/src/documents/document-store.ts +38 -0
- package/src/export/__tests__/transcript-formatter.test.ts +1 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +29 -0
- package/src/heartbeat/heartbeat-service.ts +63 -0
- package/src/home/__tests__/feed-writer.test.ts +161 -0
- package/src/home/__tests__/post-connect-feed.test.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +55 -59
- package/src/home/feed-writer.ts +146 -7
- package/src/home/suggested-prompts.ts +27 -145
- package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
- package/src/ipc/gateway-client.test.ts +4 -1
- package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
- package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
- package/src/ipc/skill-routes/memory.ts +4 -3
- package/src/ipc/skill-routes/registries.ts +28 -29
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +1 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +1 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
- package/src/memory/conversation-attention-store.ts +17 -3
- package/src/memory/conversation-crud.ts +352 -112
- package/src/memory/db-connection.ts +29 -19
- package/src/memory/db-init.ts +4 -0
- package/src/memory/db-singleton.ts +77 -0
- package/src/memory/delivery-channels.ts +82 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
- package/src/memory/graph/retriever.test.ts +3 -3
- package/src/memory/job-handlers/embedding.test.ts +3 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
- package/src/memory/jobs-worker.ts +12 -1
- package/src/memory/llm-request-log-source-clickhouse.ts +80 -0
- package/src/memory/llm-request-log-source-local.ts +24 -0
- package/src/memory/llm-request-log-source.ts +31 -0
- package/src/memory/llm-request-log-store.ts +188 -3
- package/src/memory/memory-v2-activation-log-store.ts +95 -1
- package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
- package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
- package/src/memory/migrations/index.ts +2 -0
- package/src/memory/schema/conversations.ts +9 -1
- package/src/memory/schema/inference.ts +0 -1
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
- package/src/memory/v2/__tests__/harness-metrics.test.ts +9 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +9 -4
- package/src/memory/v2/__tests__/harness-runner.test.ts +26 -0
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
- package/src/memory/v2/harness/metrics.ts +5 -1
- package/src/memory/v2/harness/replay-input.ts +19 -3
- package/src/memory/v2/harness/runner.ts +6 -0
- package/src/memory/v2/harness/trace.ts +6 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +2 -4
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
- package/src/memory/v3/__tests__/edges.test.ts +144 -1
- package/src/memory/v3/__tests__/filter.test.ts +48 -0
- package/src/memory/v3/__tests__/gate.test.ts +96 -33
- package/src/memory/v3/__tests__/index-composition.test.ts +58 -0
- package/src/memory/v3/__tests__/loop.test.ts +250 -5
- package/src/memory/v3/__tests__/scouts.test.ts +49 -0
- package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +88 -2
- package/src/memory/v3/__tests__/traversal.test.ts +39 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +77 -0
- package/src/memory/v3/__tests__/validate.test.ts +32 -0
- package/src/memory/v3/coretrieval-seed.ts +240 -0
- package/src/memory/v3/edges.ts +58 -21
- package/src/memory/v3/filter.ts +27 -22
- package/src/memory/v3/gate.ts +51 -36
- package/src/memory/v3/index-composition.ts +18 -5
- package/src/memory/v3/loop.ts +65 -17
- package/src/memory/v3/scouts.ts +15 -4
- package/src/memory/v3/shadow-diff.ts +287 -0
- package/src/memory/v3/shadow-middleware.ts +44 -2
- package/src/memory/v3/traversal.ts +6 -1
- package/src/memory/v3/tree-walk.ts +6 -1
- package/src/memory/v3/validate.ts +56 -33
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
- package/src/notifications/adapters/slack.ts +45 -11
- package/src/notifications/broadcaster.ts +114 -63
- package/src/notifications/conversation-pairing.ts +23 -3
- package/src/notifications/decisions-store.ts +32 -1
- package/src/notifications/deliveries-store.ts +45 -0
- package/src/notifications/edit-notification.ts +201 -0
- package/src/notifications/emit-signal.ts +11 -1
- package/src/notifications/signal.ts +10 -0
- package/src/notifications/types.ts +37 -0
- package/src/oauth/byo-connection.test.ts +67 -3
- package/src/oauth/byo-connection.ts +32 -5
- package/src/oauth/connect-orchestrator.ts +9 -0
- package/src/oauth/connection-resolver.test.ts +76 -0
- package/src/oauth/connection-resolver.ts +49 -10
- package/src/oauth/manual-token-connection.ts +51 -3
- package/src/oauth/seed-providers.ts +3 -0
- package/src/permissions/approval-policy.test.ts +19 -5
- package/src/permissions/approval-policy.ts +14 -3
- package/src/permissions/checker.ts +21 -8
- package/src/platform/client.test.ts +24 -1
- package/src/platform/client.ts +8 -0
- package/src/platform/feature-gate.ts +15 -0
- package/src/plugins/defaults/injectors.ts +2 -8
- package/src/plugins/defaults/persistence.ts +25 -6
- package/src/plugins/types.ts +57 -13
- package/src/proactive-artifact/job.test.ts +1 -0
- package/src/prompts/__tests__/system-prompt.test.ts +4 -4
- package/src/prompts/system-prompt.ts +38 -40
- package/src/prompts/template-detection.ts +10 -4
- package/src/prompts/templates/BOOTSTRAP.md +7 -11
- package/src/prompts/templates/IDENTITY.md +0 -2
- package/src/providers/__tests__/connection-model-compat.test.ts +3 -4
- package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
- package/src/providers/call-site-routing.ts +33 -9
- package/src/providers/connection-model-compat.ts +23 -0
- package/src/providers/connection-resolution.ts +39 -20
- package/src/providers/fireworks/client.ts +1 -0
- package/src/providers/gemini/client.ts +24 -3
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
- package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
- package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
- package/src/providers/inference/auth.ts +0 -8
- package/src/providers/inference/connections.ts +3 -66
- package/src/providers/inference/resolve-auth.ts +2 -3
- package/src/providers/model-catalog.ts +35 -1
- package/src/providers/model-intents.ts +3 -3
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
- package/src/providers/openai/chat-completions-provider.ts +110 -12
- package/src/providers/openai/codex-models.ts +2 -0
- package/src/providers/openai/responses-provider.ts +53 -53
- package/src/providers/openrouter/client.ts +13 -8
- package/src/providers/provider-send-message.ts +18 -9
- package/src/providers/registry.ts +48 -8
- package/src/providers/retry.ts +16 -4
- package/src/providers/search-provider-catalog.ts +17 -9
- package/src/providers/types.ts +9 -0
- package/src/runtime/__tests__/agent-wake.test.ts +1 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
- package/src/runtime/access-request-helper.ts +1 -0
- package/src/runtime/auth/route-policy.ts +10 -0
- package/src/runtime/channel-readiness-service.ts +68 -0
- package/src/runtime/channel-reply-delivery.ts +23 -0
- package/src/runtime/channel-retry-sweep.ts +47 -14
- package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
- package/src/runtime/migrations/vbundle-builder.ts +3 -2
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +51 -3
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
- package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
- package/src/runtime/routes/acp-routes-list.test.ts +3 -0
- package/src/runtime/routes/app-management-routes.ts +111 -4
- package/src/runtime/routes/background-wake-routes.ts +188 -20
- package/src/runtime/routes/btw-routes.ts +4 -4
- package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
- package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
- package/src/runtime/routes/conversation-list-routes.ts +147 -0
- package/src/runtime/routes/conversation-management-routes.ts +39 -14
- package/src/runtime/routes/conversation-query-routes.ts +60 -10
- package/src/runtime/routes/conversation-routes.ts +186 -140
- package/src/runtime/routes/conversations-import-routes.ts +19 -6
- package/src/runtime/routes/documents-routes.ts +10 -1
- package/src/runtime/routes/group-routes.ts +11 -0
- package/src/runtime/routes/home-feed-routes.ts +129 -0
- package/src/runtime/routes/identity-intro-cache.ts +61 -16
- package/src/runtime/routes/identity-routes.ts +30 -9
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
- package/src/runtime/routes/integrations/vercel.ts +15 -0
- package/src/runtime/routes/llm-context-normalization.ts +7 -2
- package/src/runtime/routes/memory-v3-routes.ts +160 -2
- package/src/runtime/routes/migration-routes.ts +20 -13
- package/src/runtime/routes/notification-routes.ts +63 -1
- package/src/runtime/routes/oauth-commands-routes.ts +6 -1
- package/src/runtime/routes/surface-action-routes.ts +1 -38
- package/src/runtime/routes/surface-content-routes.ts +12 -5
- package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
- package/src/runtime/slack-dm-text-delivery.ts +177 -0
- package/src/runtime/sync/resource-sync-events.ts +1 -1
- package/src/runtime/tool-grant-request-helper.ts +1 -0
- package/src/schedule/schedule-store.ts +8 -1
- package/src/schedule/scheduler.ts +111 -15
- package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
- package/src/security/encrypted-store.ts +7 -16
- package/src/security/store-path-override.ts +61 -0
- package/src/signals/user-message.ts +5 -8
- package/src/skills/validate-input.ts +177 -0
- package/src/subagent/manager.ts +13 -13
- package/src/subagent/types.ts +6 -0
- package/src/tasks/tool-sanitizer.ts +2 -2
- package/src/tools/apps/definitions.ts +35 -21
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
- package/src/tools/computer-use/definitions.ts +268 -266
- package/src/tools/document/document-tool.ts +131 -8
- package/src/tools/execution-target.ts +2 -5
- package/src/tools/executor.ts +18 -55
- package/src/tools/host-filesystem/edit.test.ts +1 -0
- package/src/tools/host-filesystem/read.test.ts +1 -0
- package/src/tools/host-filesystem/transfer.test.ts +31 -6
- package/src/tools/host-filesystem/write.test.ts +1 -0
- package/src/tools/mcp/mcp-tool-factory.ts +0 -2
- package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
- package/src/tools/network/__tests__/web-search.test.ts +211 -3
- package/src/tools/network/managed-search-proxy.ts +183 -0
- package/src/tools/network/web-search.ts +199 -44
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/registry.ts +146 -103
- package/src/tools/schedule/create.ts +1 -1
- package/src/tools/skills/skill-tool-factory.ts +17 -36
- package/src/tools/subagent/spawn.ts +3 -0
- package/src/tools/tool-approval-handler.ts +10 -4
- package/src/tools/tool-name-aliases.ts +72 -14
- package/src/tools/types.ts +17 -15
- package/src/tools/ui-surface/definitions.ts +98 -86
- package/src/types/onboarding-context.ts +6 -0
- package/src/usage/attribution.ts +32 -1
- package/src/util/browser.ts +7 -2
- package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
- package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
- package/src/workspace/migrations/registry.ts +4 -0
|
@@ -20,18 +20,14 @@ import type { SecretPrompter } from "../permissions/secret-prompter.js";
|
|
|
20
20
|
import type { Message, ToolDefinition } from "../providers/types.js";
|
|
21
21
|
import type { TrustClass } from "../runtime/actor-trust-resolver.js";
|
|
22
22
|
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
23
|
-
import { coreAppProxyTools } from "../tools/apps/definitions.js";
|
|
24
23
|
import { registerConversationSender } from "../tools/browser/browser-screencast.js";
|
|
25
24
|
import type { ToolExecutor } from "../tools/executor.js";
|
|
26
|
-
import {
|
|
27
|
-
getAllToolDefinitions,
|
|
28
|
-
getMcpToolDefinitions,
|
|
29
|
-
} from "../tools/registry.js";
|
|
25
|
+
import { getMcpToolDefinitions } from "../tools/registry.js";
|
|
30
26
|
import {
|
|
31
27
|
ACTIVITY_SKIP_SET,
|
|
32
28
|
injectActivityField,
|
|
33
29
|
} from "../tools/schema-transforms.js";
|
|
34
|
-
import {
|
|
30
|
+
import { resolveToolInvocationAlias } from "../tools/tool-name-aliases.js";
|
|
35
31
|
import {
|
|
36
32
|
isDiskPressureCleanupToolName,
|
|
37
33
|
type ProxyApprovalCallback,
|
|
@@ -40,7 +36,6 @@ import {
|
|
|
40
36
|
type ToolExecutionResult,
|
|
41
37
|
type ToolLifecycleEventHandler,
|
|
42
38
|
} from "../tools/types.js";
|
|
43
|
-
import { allUiSurfaceTools } from "../tools/ui-surface/definitions.js";
|
|
44
39
|
import { getLogger } from "../util/logger.js";
|
|
45
40
|
import {
|
|
46
41
|
projectSkillTools,
|
|
@@ -75,6 +70,7 @@ export function resolveTrustClass(
|
|
|
75
70
|
}
|
|
76
71
|
|
|
77
72
|
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
73
|
+
import { AUTO_PROFILE_KEY } from "../config/seed-inference-profiles.js";
|
|
78
74
|
import {
|
|
79
75
|
buildSwitchInferenceProfileToolDef,
|
|
80
76
|
SWITCH_INFERENCE_PROFILE_TOOL_NAME,
|
|
@@ -82,20 +78,6 @@ import {
|
|
|
82
78
|
import type { ToolSetupContext } from "./tool-setup-types.js";
|
|
83
79
|
export type { ToolSetupContext } from "./tool-setup-types.js";
|
|
84
80
|
|
|
85
|
-
// ── buildToolDefinitions ─────────────────────────────────────────────
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Collect all tool definitions for the agent loop: built-in tools,
|
|
89
|
-
* UI surface proxy tools, and app proxy tools.
|
|
90
|
-
*/
|
|
91
|
-
export function buildToolDefinitions(): ToolDefinition[] {
|
|
92
|
-
return [
|
|
93
|
-
...getAllToolDefinitions(),
|
|
94
|
-
...allUiSurfaceTools,
|
|
95
|
-
...coreAppProxyTools,
|
|
96
|
-
];
|
|
97
|
-
}
|
|
98
|
-
|
|
99
81
|
// ── createToolExecutor ───────────────────────────────────────────────
|
|
100
82
|
|
|
101
83
|
/**
|
|
@@ -129,10 +111,11 @@ export function createToolExecutor(
|
|
|
129
111
|
toolUseId?: string,
|
|
130
112
|
turnContext?: import("../plugins/types.js").TurnContext,
|
|
131
113
|
) => {
|
|
132
|
-
const
|
|
114
|
+
const { name: executionName, input: executionInput } =
|
|
115
|
+
resolveToolInvocationAlias(name, input, ctx.allowedToolNames);
|
|
133
116
|
|
|
134
|
-
if (isDoordashCommand(executionName,
|
|
135
|
-
markDoordashStepInProgress(ctx,
|
|
117
|
+
if (isDoordashCommand(executionName, executionInput)) {
|
|
118
|
+
markDoordashStepInProgress(ctx, executionInput);
|
|
136
119
|
}
|
|
137
120
|
|
|
138
121
|
// Build the context object shared by both the skill_execute interception
|
|
@@ -218,7 +201,10 @@ export function createToolExecutor(
|
|
|
218
201
|
// model self-select a different inference profile mid-turn. No permission
|
|
219
202
|
// checks — this is a control-flow signal, not a user-visible tool.
|
|
220
203
|
if (executionName === SWITCH_INFERENCE_PROFILE_TOOL_NAME) {
|
|
221
|
-
const profile =
|
|
204
|
+
const profile =
|
|
205
|
+
typeof executionInput.profile === "string"
|
|
206
|
+
? executionInput.profile
|
|
207
|
+
: "";
|
|
222
208
|
const config = getConfig();
|
|
223
209
|
const profileEntry = config.llm.profiles?.[profile];
|
|
224
210
|
if (!profileEntry) {
|
|
@@ -246,15 +232,19 @@ export function createToolExecutor(
|
|
|
246
232
|
// risk level, permission checks, hooks, and lifecycle events all fire
|
|
247
233
|
// with the real tool name.
|
|
248
234
|
if (executionName === "skill_execute") {
|
|
249
|
-
const rawToolName =
|
|
250
|
-
|
|
235
|
+
const rawToolName =
|
|
236
|
+
typeof executionInput.tool === "string" ? executionInput.tool : "";
|
|
251
237
|
const rawToolInput =
|
|
252
|
-
|
|
253
|
-
? (
|
|
238
|
+
executionInput.input != null && typeof executionInput.input === "object"
|
|
239
|
+
? (executionInput.input as Record<string, unknown>)
|
|
254
240
|
: {};
|
|
255
241
|
|
|
256
242
|
// Clone to avoid mutating shared input objects
|
|
257
|
-
const
|
|
243
|
+
const { name: toolName, input: toolInput } = resolveToolInvocationAlias(
|
|
244
|
+
rawToolName,
|
|
245
|
+
{ ...rawToolInput },
|
|
246
|
+
ctx.allowedToolNames,
|
|
247
|
+
);
|
|
258
248
|
|
|
259
249
|
if (!toolName) {
|
|
260
250
|
return {
|
|
@@ -281,7 +271,7 @@ export function createToolExecutor(
|
|
|
281
271
|
|
|
282
272
|
const result = await executor.execute(
|
|
283
273
|
executionName,
|
|
284
|
-
|
|
274
|
+
executionInput,
|
|
285
275
|
toolContext,
|
|
286
276
|
turnContext,
|
|
287
277
|
);
|
|
@@ -289,7 +279,7 @@ export function createToolExecutor(
|
|
|
289
279
|
ctx.approvedViaPromptThisTurn = true;
|
|
290
280
|
}
|
|
291
281
|
|
|
292
|
-
runPostExecutionSideEffects(executionName,
|
|
282
|
+
runPostExecutionSideEffects(executionName, executionInput, result, { ctx });
|
|
293
283
|
|
|
294
284
|
return result;
|
|
295
285
|
};
|
|
@@ -360,12 +350,6 @@ export interface SkillProjectionContext {
|
|
|
360
350
|
readonly transportInterface?: InterfaceId;
|
|
361
351
|
/** Per-turn override profile, read by the switch_inference_profile tool injection. */
|
|
362
352
|
currentTurnOverrideProfile?: string;
|
|
363
|
-
/**
|
|
364
|
-
* True when the user has explicitly selected an inference profile for this
|
|
365
|
-
* conversation (via the composer profile picker). When set, tool-based
|
|
366
|
-
* auto-routing is suppressed — the user's explicit choice takes precedence.
|
|
367
|
-
*/
|
|
368
|
-
hasExplicitProfileOverride?: boolean;
|
|
369
353
|
}
|
|
370
354
|
|
|
371
355
|
// ── Conditional tool sets ────────────────────────────────────────────
|
|
@@ -658,18 +642,19 @@ export function createResolveToolsCallback(
|
|
|
658
642
|
const config = getConfig();
|
|
659
643
|
if (
|
|
660
644
|
isAssistantFeatureFlagEnabled("query-complexity-routing", config) &&
|
|
661
|
-
config.llm
|
|
662
|
-
!ctx.hasExplicitProfileOverride
|
|
645
|
+
config.llm
|
|
663
646
|
) {
|
|
664
|
-
const
|
|
647
|
+
const effectiveProfile =
|
|
665
648
|
ctx.currentTurnOverrideProfile ?? config.llm.activeProfile;
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
649
|
+
if (effectiveProfile === AUTO_PROFILE_KEY) {
|
|
650
|
+
const toolDef = buildSwitchInferenceProfileToolDef(
|
|
651
|
+
config.llm.profiles ?? {},
|
|
652
|
+
effectiveProfile,
|
|
653
|
+
);
|
|
654
|
+
if (toolDef) {
|
|
655
|
+
turnAllowed.add(SWITCH_INFERENCE_PROFILE_TOOL_NAME);
|
|
656
|
+
return [...baseDefs, toolDef];
|
|
657
|
+
}
|
|
673
658
|
}
|
|
674
659
|
}
|
|
675
660
|
|
|
@@ -68,6 +68,7 @@ import { broadcastMessage } from "../runtime/assistant-event-hub.js";
|
|
|
68
68
|
import type { AuthContext } from "../runtime/auth/types.js";
|
|
69
69
|
import type { InteractiveUiResult } from "../runtime/interactive-ui.js";
|
|
70
70
|
import { ToolExecutor } from "../tools/executor.js";
|
|
71
|
+
import { getAllToolDefinitions } from "../tools/registry.js";
|
|
71
72
|
import type { ToolLifecycleEvent } from "../tools/types.js";
|
|
72
73
|
import type { OnboardingContext } from "../types/onboarding-context.js";
|
|
73
74
|
import type { AbortReason } from "../util/abort-reasons.js";
|
|
@@ -85,7 +86,11 @@ import {
|
|
|
85
86
|
disposeConversation,
|
|
86
87
|
loadFromDb as loadFromDbImpl,
|
|
87
88
|
} from "./conversation-lifecycle.js";
|
|
88
|
-
import type {
|
|
89
|
+
import type {
|
|
90
|
+
EnqueueMessageOptions,
|
|
91
|
+
PersistMessageOptions,
|
|
92
|
+
RedirectToSecurePromptOptions,
|
|
93
|
+
} from "./conversation-messaging.js";
|
|
89
94
|
import {
|
|
90
95
|
enqueueMessage as enqueueMessageImpl,
|
|
91
96
|
persistUserMessage as persistUserMessageImpl,
|
|
@@ -116,7 +121,6 @@ import {
|
|
|
116
121
|
} from "./conversation-surfaces.js";
|
|
117
122
|
import type { ToolSetupContext } from "./conversation-tool-setup.js";
|
|
118
123
|
import {
|
|
119
|
-
buildToolDefinitions,
|
|
120
124
|
createResolveToolsCallback,
|
|
121
125
|
createToolExecutor,
|
|
122
126
|
resolveTrustClass,
|
|
@@ -326,7 +330,12 @@ export class Conversation {
|
|
|
326
330
|
surfaceType: SurfaceType;
|
|
327
331
|
title?: string;
|
|
328
332
|
data: SurfaceData;
|
|
329
|
-
actions?: Array<{
|
|
333
|
+
actions?: Array<{
|
|
334
|
+
id: string;
|
|
335
|
+
label: string;
|
|
336
|
+
style?: string;
|
|
337
|
+
data?: Record<string, unknown>;
|
|
338
|
+
}>;
|
|
330
339
|
display?: string;
|
|
331
340
|
persistent?: boolean;
|
|
332
341
|
}> = [];
|
|
@@ -451,7 +460,7 @@ export class Conversation {
|
|
|
451
460
|
return publishToolDomainEvent(event);
|
|
452
461
|
};
|
|
453
462
|
|
|
454
|
-
const toolDefs =
|
|
463
|
+
const toolDefs = getAllToolDefinitions();
|
|
455
464
|
this.coreToolNames = new Set(toolDefs.map((d) => d.name));
|
|
456
465
|
const toolExecutor = createToolExecutor(
|
|
457
466
|
this.executor,
|
|
@@ -581,7 +590,7 @@ export class Conversation {
|
|
|
581
590
|
channelCapabilities: this.currentTurnChannelCapabilities,
|
|
582
591
|
onboardingContext: this.getOnboardingContext(),
|
|
583
592
|
});
|
|
584
|
-
const tools =
|
|
593
|
+
const tools = getAllToolDefinitions();
|
|
585
594
|
const provider = this.provider;
|
|
586
595
|
|
|
587
596
|
const warmMessage: Message = {
|
|
@@ -823,33 +832,15 @@ export class Conversation {
|
|
|
823
832
|
);
|
|
824
833
|
}
|
|
825
834
|
|
|
826
|
-
enqueueMessage(
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
displayContent?: string,
|
|
836
|
-
transport?: ConversationTransportMetadata,
|
|
837
|
-
clientMessageId?: string,
|
|
838
|
-
): { queued: boolean; requestId: string; rejected?: boolean } {
|
|
839
|
-
return enqueueMessageImpl(
|
|
840
|
-
this,
|
|
841
|
-
content,
|
|
842
|
-
attachments,
|
|
843
|
-
onEvent ?? this.sendToClient,
|
|
844
|
-
requestId ?? crypto.randomUUID(),
|
|
845
|
-
activeSurfaceId,
|
|
846
|
-
currentPage,
|
|
847
|
-
metadata,
|
|
848
|
-
options,
|
|
849
|
-
displayContent,
|
|
850
|
-
transport,
|
|
851
|
-
clientMessageId,
|
|
852
|
-
);
|
|
835
|
+
enqueueMessage(options: EnqueueMessageOptions): {
|
|
836
|
+
queued: boolean;
|
|
837
|
+
requestId: string;
|
|
838
|
+
rejected?: boolean;
|
|
839
|
+
} {
|
|
840
|
+
return enqueueMessageImpl(this, {
|
|
841
|
+
...options,
|
|
842
|
+
onEvent: options.onEvent ?? this.sendToClient,
|
|
843
|
+
});
|
|
853
844
|
}
|
|
854
845
|
|
|
855
846
|
getQueueDepth(): number {
|
|
@@ -1278,23 +1269,12 @@ export class Conversation {
|
|
|
1278
1269
|
}
|
|
1279
1270
|
|
|
1280
1271
|
async persistUserMessage(
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
requestId?: string,
|
|
1284
|
-
metadata?: Record<string, unknown>,
|
|
1285
|
-
displayContent?: string,
|
|
1286
|
-
): Promise<string> {
|
|
1272
|
+
options: PersistMessageOptions,
|
|
1273
|
+
): Promise<{ id: string; deduplicated: boolean }> {
|
|
1287
1274
|
if (!this.processing) {
|
|
1288
1275
|
await this.ensureActorScopedHistory();
|
|
1289
1276
|
}
|
|
1290
|
-
return persistUserMessageImpl(
|
|
1291
|
-
this,
|
|
1292
|
-
content,
|
|
1293
|
-
attachments,
|
|
1294
|
-
requestId,
|
|
1295
|
-
metadata,
|
|
1296
|
-
displayContent,
|
|
1297
|
-
);
|
|
1277
|
+
return persistUserMessageImpl(this, options);
|
|
1298
1278
|
}
|
|
1299
1279
|
|
|
1300
1280
|
// ── Agent Loop ───────────────────────────────────────────────────
|
|
@@ -33,7 +33,7 @@ const DAEMON_TIMEOUT_DEFAULTS = {
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
const HEALTH_CHECK_TIMEOUT_MS = 1500;
|
|
36
|
-
const STARTUP_LOCK_STALE_MS =
|
|
36
|
+
const STARTUP_LOCK_STALE_MS = 120_000;
|
|
37
37
|
|
|
38
38
|
function isPositiveInteger(v: unknown): v is number {
|
|
39
39
|
return typeof v === "number" && Number.isInteger(v) && v > 0;
|
|
@@ -219,8 +219,15 @@ function buildRegistriesFacet(skillId: string): RegistriesFacet {
|
|
|
219
219
|
// overlay (`assistant/src/tools/types.ts`); the assistant-side
|
|
220
220
|
// registry accepts the daemon flavor. Skills construct tools via
|
|
221
221
|
// helpers that already produce the daemon shape, so a cast at this
|
|
222
|
-
// boundary is safe.
|
|
223
|
-
|
|
222
|
+
// boundary is safe. The contract's `registerTools(provider)` stays
|
|
223
|
+
// single-arg — skill code never needs to know its own id — and this
|
|
224
|
+
// adapter pairs the provider with the owner derived from the
|
|
225
|
+
// surrounding {@link buildRegistriesFacet} closure.
|
|
226
|
+
registerTools: (provider) =>
|
|
227
|
+
registerExternalTools(
|
|
228
|
+
{ kind: "skill", id: skillId },
|
|
229
|
+
provider as never,
|
|
230
|
+
),
|
|
224
231
|
registerSkillRoute: (route: SkillRoute): SkillRouteHandle =>
|
|
225
232
|
registerSkillRoute(route) as unknown as SkillRouteHandle,
|
|
226
233
|
// Namespace hook names by skillId so two skills using the same label
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
2
|
-
import { getConfig } from "../config/loader.js";
|
|
3
1
|
import { buildAssistantEvent } from "../runtime/assistant-event.js";
|
|
4
2
|
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
5
3
|
import { cancelBackgroundTools } from "../tools/background-tool-registry.js";
|
|
@@ -8,6 +6,12 @@ import { getLogger } from "../util/logger.js";
|
|
|
8
6
|
|
|
9
7
|
export const DISK_PRESSURE_WARNING_THRESHOLD_PERCENT = 80;
|
|
10
8
|
export const DISK_PRESSURE_THRESHOLD_PERCENT = 95;
|
|
9
|
+
// Hysteresis lower bound: once locked, the guard stays locked until usage
|
|
10
|
+
// falls below this clear threshold. The deadband between this and the
|
|
11
|
+
// critical threshold stops the lock from flapping when usage hovers near
|
|
12
|
+
// 95% — otherwise clearing the lock immediately resumes background work,
|
|
13
|
+
// which can refill the disk and re-trip the lock on the next sample.
|
|
14
|
+
export const DISK_PRESSURE_CLEAR_THRESHOLD_PERCENT = 90;
|
|
11
15
|
export const DISK_PRESSURE_CHECK_INTERVAL_MS = 60_000;
|
|
12
16
|
export const DISK_PRESSURE_OVERRIDE_CONFIRMATION = "I understand the risks";
|
|
13
17
|
export const DISK_PRESSURE_BLOCKED_CAPABILITIES = [
|
|
@@ -16,7 +20,12 @@ export const DISK_PRESSURE_BLOCKED_CAPABILITIES = [
|
|
|
16
20
|
"remote-ingress",
|
|
17
21
|
] as const;
|
|
18
22
|
|
|
19
|
-
export type DiskPressureState =
|
|
23
|
+
export type DiskPressureState =
|
|
24
|
+
| "disabled"
|
|
25
|
+
| "ok"
|
|
26
|
+
| "warning"
|
|
27
|
+
| "critical"
|
|
28
|
+
| "unknown";
|
|
20
29
|
|
|
21
30
|
export type DiskPressureBlockedCapability =
|
|
22
31
|
(typeof DISK_PRESSURE_BLOCKED_CAPABILITIES)[number];
|
|
@@ -119,24 +128,10 @@ function replaceStatus(next: DiskPressureStatus): DiskPressureStatus {
|
|
|
119
128
|
return cloneStatus(state.status);
|
|
120
129
|
}
|
|
121
130
|
|
|
122
|
-
function
|
|
123
|
-
return isAssistantFeatureFlagEnabled("safe-storage-limits", getConfig());
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function resetToDisabled(): DiskPressureStatus {
|
|
127
|
-
const previous = cloneStatus(state.status);
|
|
128
|
-
stopDiskPressureGuard();
|
|
129
|
-
state.status = cloneStatus(DISABLED_STATUS);
|
|
130
|
-
publishStatusChangedIfNeeded(previous);
|
|
131
|
-
return cloneStatus(state.status);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function ensureEnabledStatus(): DiskPressureStatus | null {
|
|
135
|
-
if (!isEnabled()) return resetToDisabled();
|
|
131
|
+
function ensureEnabledStatus(): void {
|
|
136
132
|
if (!state.status.enabled) {
|
|
137
133
|
state.status = cloneStatus(OPEN_STATUS);
|
|
138
134
|
}
|
|
139
|
-
return null;
|
|
140
135
|
}
|
|
141
136
|
|
|
142
137
|
function nextLockId(): string {
|
|
@@ -192,8 +187,7 @@ function rejectTransition(
|
|
|
192
187
|
}
|
|
193
188
|
|
|
194
189
|
export function startDiskPressureGuard(): DiskPressureStatus {
|
|
195
|
-
|
|
196
|
-
if (disabledStatus) return disabledStatus;
|
|
190
|
+
ensureEnabledStatus();
|
|
197
191
|
|
|
198
192
|
if (!state.timer) {
|
|
199
193
|
state.timer = setInterval(() => {
|
|
@@ -212,8 +206,7 @@ export function stopDiskPressureGuard(): void {
|
|
|
212
206
|
}
|
|
213
207
|
|
|
214
208
|
export function evaluateDiskPressureNow(): DiskPressureStatus {
|
|
215
|
-
|
|
216
|
-
if (disabledStatus) return disabledStatus;
|
|
209
|
+
ensureEnabledStatus();
|
|
217
210
|
|
|
218
211
|
let usageInfo: ReturnType<typeof getDiskUsageInfo>;
|
|
219
212
|
try {
|
|
@@ -229,8 +222,14 @@ export function evaluateDiskPressureNow(): DiskPressureStatus {
|
|
|
229
222
|
const usagePercent = roundPercent(
|
|
230
223
|
(usageInfo.usedMb / usageInfo.totalMb) * 100,
|
|
231
224
|
);
|
|
232
|
-
|
|
233
|
-
|
|
225
|
+
// Hysteresis: while locked, hold until usage drops below the lower clear
|
|
226
|
+
// threshold; otherwise lock at the critical threshold.
|
|
227
|
+
const criticalThreshold = state.status.locked
|
|
228
|
+
? DISK_PRESSURE_CLEAR_THRESHOLD_PERCENT
|
|
229
|
+
: DISK_PRESSURE_THRESHOLD_PERCENT;
|
|
230
|
+
const isCritical = usagePercent >= criticalThreshold;
|
|
231
|
+
const isWarning =
|
|
232
|
+
!isCritical && usagePercent >= DISK_PRESSURE_WARNING_THRESHOLD_PERCENT;
|
|
234
233
|
const lastCheckedAt = new Date().toISOString();
|
|
235
234
|
|
|
236
235
|
if (!isCritical && !isWarning) {
|
|
@@ -277,14 +276,13 @@ export function evaluateDiskPressureNow(): DiskPressureStatus {
|
|
|
277
276
|
}
|
|
278
277
|
|
|
279
278
|
export function getDiskPressureStatus(): DiskPressureStatus {
|
|
280
|
-
if (!isEnabled()) return cloneStatus(DISABLED_STATUS);
|
|
281
279
|
if (!state.status.enabled) return cloneStatus(OPEN_STATUS);
|
|
282
280
|
return cloneStatus(state.status);
|
|
283
281
|
}
|
|
284
282
|
|
|
285
283
|
export function acknowledgeDiskPressureLock(): DiskPressureTransitionResult {
|
|
286
|
-
|
|
287
|
-
const status =
|
|
284
|
+
ensureEnabledStatus();
|
|
285
|
+
const status = cloneStatus(state.status);
|
|
288
286
|
if (!status.locked) {
|
|
289
287
|
return rejectTransition(
|
|
290
288
|
"not_locked",
|
|
@@ -310,8 +308,8 @@ export function acknowledgeDiskPressureLock(): DiskPressureTransitionResult {
|
|
|
310
308
|
export function overrideDiskPressureLock(
|
|
311
309
|
confirmation: string,
|
|
312
310
|
): DiskPressureTransitionResult {
|
|
313
|
-
|
|
314
|
-
const status =
|
|
311
|
+
ensureEnabledStatus();
|
|
312
|
+
const status = cloneStatus(state.status);
|
|
315
313
|
if (!status.locked) {
|
|
316
314
|
return rejectTransition(
|
|
317
315
|
"not_locked",
|
|
@@ -14,12 +14,6 @@ export interface OnboardingGreetingContext {
|
|
|
14
14
|
googleConnected?: boolean;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export const CANNED_FIRST_GREETING = [
|
|
18
|
-
"Hey,",
|
|
19
|
-
"",
|
|
20
|
-
"We can get into whatever you've got, or just talk first — that tends to go better. Up to you.",
|
|
21
|
-
].join("\n");
|
|
22
|
-
|
|
23
17
|
/**
|
|
24
18
|
* Returns `true` when all of the following are true:
|
|
25
19
|
* - `conversationMessageCount === 0` (no prior messages in this conversation)
|
|
@@ -67,30 +61,54 @@ function buildIntroLine(
|
|
|
67
61
|
return [greeting, who, close].filter(Boolean).join(" ");
|
|
68
62
|
}
|
|
69
63
|
|
|
70
|
-
|
|
64
|
+
// Every greeting variant — the no-onboarding CANNED greeting and all four
|
|
65
|
+
// personalized tones — ends with a migration offer. The opener (task-vs-talk)
|
|
66
|
+
// and the migration offer are kept as separate per-tone maps and composed in
|
|
67
|
+
// `buildInvite`, rather than inlined as one full sentence per variant, so the
|
|
68
|
+
// offer cannot be silently dropped from a variant when the opener copy is
|
|
69
|
+
// edited. The first-greeting test asserts every variant still includes it.
|
|
70
|
+
const TONE_INVITE_OPENER: Record<Tone, string> = {
|
|
71
71
|
grounded:
|
|
72
72
|
"We can get into whatever you've got, or just talk first — that tends to go better. Up to you.",
|
|
73
73
|
warm: "We can start on something specific, or just talk for a bit first — honestly that tends to work out better. Either way, I'm here.",
|
|
74
74
|
energetic:
|
|
75
|
-
"We can jump straight into whatever you've got, or take a few minutes to just talk first.
|
|
75
|
+
"We can jump straight into whatever you've got, or take a few minutes to just talk first.",
|
|
76
76
|
poetic:
|
|
77
77
|
"We can start with whatever's in front of you, or just talk for a bit first. Either way.",
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
+
const TONE_MIGRATION_OFFER: Record<Tone, string> = {
|
|
81
|
+
grounded:
|
|
82
|
+
"If you have context or workflows from another assistant or harness, bring them over early and I'll help port them.",
|
|
83
|
+
warm: "If you have context or workflows from another assistant or harness, bring them over early and I can help port them.",
|
|
84
|
+
energetic:
|
|
85
|
+
"If you've got context or workflows from another assistant or harness, bring them over early and I'll port them with you. What sounds right?",
|
|
86
|
+
poetic:
|
|
87
|
+
"If there's old context or workflows from another assistant or harness, bring them over early and I'll help port them.",
|
|
88
|
+
};
|
|
89
|
+
|
|
80
90
|
const TONE_GOOGLE_SCAN: Record<Tone, string> = {
|
|
81
91
|
grounded:
|
|
82
|
-
"I can scan
|
|
83
|
-
warm: "Also — I can scan
|
|
92
|
+
"I can scan Gmail in the background while we talk — just say the word.",
|
|
93
|
+
warm: "Also — I can scan Gmail in the background while we chat, if you'd like. Just let me know.",
|
|
84
94
|
energetic:
|
|
85
|
-
"Oh, and I can scan
|
|
95
|
+
"Oh, and I can scan Gmail in the background right now — want me to?",
|
|
86
96
|
poetic:
|
|
87
|
-
"I can also look through
|
|
97
|
+
"I can also look through Gmail quietly in the background — say the word.",
|
|
88
98
|
};
|
|
89
99
|
|
|
90
100
|
function buildInvite(tone: Tone = "grounded"): string {
|
|
91
|
-
return
|
|
101
|
+
return `${TONE_INVITE_OPENER[tone]} ${TONE_MIGRATION_OFFER[tone]}`;
|
|
92
102
|
}
|
|
93
103
|
|
|
104
|
+
// Composed from the grounded opener + migration offer so the no-onboarding
|
|
105
|
+
// greeting reuses the same source as the personalized grounded greeting rather
|
|
106
|
+
// than duplicating the copy. Defined after the tone maps so they are
|
|
107
|
+
// initialized before this module-level evaluation runs.
|
|
108
|
+
export const CANNED_FIRST_GREETING = ["Hey,", "", buildInvite("grounded")].join(
|
|
109
|
+
"\n",
|
|
110
|
+
);
|
|
111
|
+
|
|
94
112
|
const VALID_TONES = new Set<string>([
|
|
95
113
|
"grounded",
|
|
96
114
|
"warm",
|
|
@@ -85,7 +85,12 @@ export interface HistorySurface {
|
|
|
85
85
|
surfaceType: string;
|
|
86
86
|
title?: string;
|
|
87
87
|
data: Record<string, unknown>;
|
|
88
|
-
actions?: Array<{
|
|
88
|
+
actions?: Array<{
|
|
89
|
+
id: string;
|
|
90
|
+
label: string;
|
|
91
|
+
style?: string;
|
|
92
|
+
data?: Record<string, unknown>;
|
|
93
|
+
}>;
|
|
89
94
|
display?: string;
|
|
90
95
|
persistent?: boolean;
|
|
91
96
|
completed?: boolean;
|
package/src/daemon/lifecycle.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { join } from "node:path";
|
|
|
2
2
|
|
|
3
3
|
import { config as dotenvConfig } from "dotenv";
|
|
4
4
|
|
|
5
|
+
import { refreshBackgroundWakeIntent } from "../background-wake/publisher.js";
|
|
5
6
|
import { registerBackgroundWakeRuntime } from "../background-wake/runtime-registry.js";
|
|
6
7
|
import { setPointerMessageProcessor } from "../calls/call-pointer-messages.js";
|
|
7
8
|
import { reconcileCallsOnStartup } from "../calls/call-recovery.js";
|
|
@@ -73,6 +74,7 @@ import {
|
|
|
73
74
|
import { RuntimeHttpServer } from "../runtime/http-server.js";
|
|
74
75
|
import { recoverInterruptedImport } from "../runtime/migrations/vbundle-streaming-importer.js";
|
|
75
76
|
import { registerSecretsDeps } from "../runtime/routes/secrets-deps.js";
|
|
77
|
+
import { publishConversationListChanged } from "../runtime/sync/resource-sync-events.js";
|
|
76
78
|
import { recoverStaleSchedules } from "../schedule/schedule-recovery.js";
|
|
77
79
|
import { startScheduler } from "../schedule/scheduler.js";
|
|
78
80
|
import {
|
|
@@ -1018,6 +1020,7 @@ export async function runDaemon(): Promise<void> {
|
|
|
1018
1020
|
scheduleJobId: info.scheduleJobId,
|
|
1019
1021
|
title: info.title,
|
|
1020
1022
|
});
|
|
1023
|
+
publishConversationListChanged("created");
|
|
1021
1024
|
},
|
|
1022
1025
|
);
|
|
1023
1026
|
|
|
@@ -1082,13 +1085,11 @@ export async function runDaemon(): Promise<void> {
|
|
|
1082
1085
|
// its own finally block.
|
|
1083
1086
|
conversation.toolsDisabledDepth++;
|
|
1084
1087
|
try {
|
|
1085
|
-
const messageId = await conversation.persistUserMessage(
|
|
1086
|
-
instruction,
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
"[Call status event]",
|
|
1091
|
-
);
|
|
1088
|
+
const { id: messageId } = await conversation.persistUserMessage({
|
|
1089
|
+
content: instruction,
|
|
1090
|
+
metadata: { pointerInstruction: true },
|
|
1091
|
+
displayContent: "[Call status event]",
|
|
1092
|
+
});
|
|
1092
1093
|
|
|
1093
1094
|
// Helper: roll back persisted messages on failure, then reload
|
|
1094
1095
|
// in-memory history from the (now cleaned) DB. Reloading avoids
|
|
@@ -1271,11 +1272,9 @@ export async function runDaemon(): Promise<void> {
|
|
|
1271
1272
|
})();
|
|
1272
1273
|
|
|
1273
1274
|
if (config.auditLog.retentionDays > 0) {
|
|
1274
|
-
void rotateToolInvocations(config.auditLog.retentionDays).catch(
|
|
1275
|
-
(err
|
|
1276
|
-
|
|
1277
|
-
},
|
|
1278
|
-
);
|
|
1275
|
+
void rotateToolInvocations(config.auditLog.retentionDays).catch((err) => {
|
|
1276
|
+
log.warn({ err }, "Audit log rotation failed");
|
|
1277
|
+
});
|
|
1279
1278
|
}
|
|
1280
1279
|
|
|
1281
1280
|
const workspaceHeartbeat = new WorkspaceHeartbeatService();
|
|
@@ -1293,6 +1292,7 @@ export async function runDaemon(): Promise<void> {
|
|
|
1293
1292
|
});
|
|
1294
1293
|
heartbeat.start();
|
|
1295
1294
|
registerBackgroundWakeRuntime({ scheduler, heartbeat });
|
|
1295
|
+
refreshBackgroundWakeIntent("daemon-startup");
|
|
1296
1296
|
log.info(
|
|
1297
1297
|
{
|
|
1298
1298
|
enabled: heartbeatConfig.enabled,
|
|
@@ -82,7 +82,7 @@ async function doReload(): Promise<McpReloadResult> {
|
|
|
82
82
|
serverConfig,
|
|
83
83
|
manager,
|
|
84
84
|
);
|
|
85
|
-
const accepted = registerMcpTools(mcpTools);
|
|
85
|
+
const accepted = registerMcpTools(serverId, mcpTools);
|
|
86
86
|
const acceptedNames = accepted.map((t) => t.name);
|
|
87
87
|
toolCount += accepted.length;
|
|
88
88
|
servers.push({
|