@vellumai/assistant 0.8.4 → 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 +3 -3
- package/bunfig.toml +6 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/docs/credential-execution-service.md +6 -6
- package/docs/plugins.md +4 -3
- package/knip.json +2 -1
- 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 +2748 -216
- 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__/anthropic-provider.test.ts +34 -37
- 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-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
- package/src/__tests__/audit-log-rotation.test.ts +72 -18
- package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
- package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
- package/src/__tests__/browser-skill-endstate.test.ts +3 -3
- package/src/__tests__/btw-routes.test.ts +5 -5
- package/src/__tests__/call-controller.test.ts +3 -3
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +3 -2
- package/src/__tests__/channel-guardian.test.ts +6 -5
- 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 +18 -27
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/compaction-trail-store.test.ts +264 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
- package/src/__tests__/computer-use-tools.test.ts +14 -18
- 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__/confirmation-request-guardian-bridge.test.ts +0 -1
- 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 +2 -1
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
- package/src/__tests__/conversation-agent-loop.test.ts +581 -54
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
- package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
- 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-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +61 -0
- package/src/__tests__/conversation-fork-crud.test.ts +239 -15
- 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 +53 -11
- 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-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
- 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 +6 -0
- package/src/__tests__/conversation-queue.test.ts +333 -291
- package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
- package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
- package/src/__tests__/conversation-skill-tools.test.ts +40 -147
- 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-store.test.ts +1 -1
- 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 +218 -35
- 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 +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
- 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 +19 -19
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-health-service.test.ts +252 -3
- package/src/__tests__/credential-security-invariants.test.ts +6 -5
- package/src/__tests__/credential-vault-unit.test.ts +21 -21
- 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-page-surface.test.ts +2 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- 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 +236 -0
- package/src/__tests__/gemini-provider.test.ts +104 -0
- package/src/__tests__/guardian-action-sweep.test.ts +3 -2
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +10 -7
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
- package/src/__tests__/heartbeat-service.test.ts +5 -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 +6 -5
- 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__/init-feature-flag-overrides.test.ts +5 -6
- 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__/list-messages-tool-merge.test.ts +70 -11
- package/src/__tests__/llm-context-normalization.test.ts +42 -0
- package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
- package/src/__tests__/llm-resolver.test.ts +408 -9
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
- package/src/__tests__/mcp-abort-signal.test.ts +16 -2
- package/src/__tests__/mcp-client-auth.test.ts +14 -0
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- 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 +4 -6
- package/src/__tests__/native-web-search.test.ts +30 -2
- package/src/__tests__/notification-deep-link.test.ts +62 -0
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- 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 +4 -3
- package/src/__tests__/openai-provider.test.ts +54 -9
- package/src/__tests__/openai-responses-provider.test.ts +176 -14
- package/src/__tests__/openrouter-provider-only.test.ts +27 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
- package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
- package/src/__tests__/persistence-pipeline.test.ts +139 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -2
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +11 -13
- package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
- package/src/__tests__/plugin-types.test.ts +3 -2
- package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
- package/src/__tests__/pricing.test.ts +12 -0
- 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__/prune-jobs-changes-parser.test.ts +61 -0
- 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 +84 -84
- package/src/__tests__/relay-server.test.ts +10 -10
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- 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__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
- package/src/__tests__/skill-feature-flags.test.ts +16 -18
- package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
- package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
- package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
- package/src/__tests__/skill-tool-factory.test.ts +97 -96
- 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 +6 -5
- 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 +2 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +183 -131
- package/src/__tests__/terminal-tools.test.ts +1 -1
- package/src/__tests__/test-preload-verifier.ts +68 -0
- package/src/__tests__/test-preload.ts +32 -39
- package/src/__tests__/tool-approval-handler.test.ts +1 -5
- package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
- package/src/__tests__/tool-executor.test.ts +64 -72
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +3 -2
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/validate-input.test.ts +381 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
- 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-git-service.test.ts +6 -5
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- 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/__tests__/prepare-agent-env.test.ts +146 -0
- package/src/acp/prepare-agent-env.ts +78 -0
- package/src/acp/session-manager.ts +6 -7
- package/src/agent/loop.ts +88 -0
- package/src/api/README.md +127 -0
- 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/api/events/relationship-state-updated.ts +25 -0
- package/src/api/events/tool-use-start.ts +32 -0
- package/src/api/index.ts +129 -0
- package/src/api/package.json +10 -0
- 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 +868 -0
- 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 +24 -0
- 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__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/__tests__/notifications.test.ts +184 -40
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
- package/src/cli/commands/channels/index.ts +229 -0
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +176 -1
- package/src/cli/commands/memory-v3-render.ts +491 -0
- package/src/cli/commands/memory-v3.ts +567 -0
- package/src/cli/commands/notifications.ts +365 -55
- package/src/cli/lib/open-browser.ts +7 -2
- package/src/cli/program.ts +4 -0
- package/src/config/assistant-feature-flags.ts +39 -46
- package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
- package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- 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/bundled-tool-registry.ts +2 -0
- package/src/config/call-site-defaults.ts +8 -7
- package/src/config/feature-flag-cache.ts +86 -0
- package/src/config/feature-flag-registry.json +33 -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 +228 -1
- package/src/config/schemas/call-site-catalog.ts +21 -7
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +102 -2
- package/src/config/schemas/memory-v2.ts +272 -0
- package/src/config/schemas/memory.ts +2 -1
- package/src/config/schemas/services.ts +6 -2
- package/src/config/seed-inference-profiles.ts +36 -16
- package/src/context/compactor.ts +52 -0
- package/src/context/token-estimator.ts +10 -5
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- 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 +2 -3
- 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 +390 -80
- package/src/daemon/conversation-agent-loop.ts +244 -90
- package/src/daemon/conversation-error.ts +64 -6
- package/src/daemon/conversation-lifecycle.ts +27 -22
- package/src/daemon/conversation-messaging.ts +84 -43
- package/src/daemon/conversation-process.ts +74 -37
- package/src/daemon/conversation-runtime-assembly.ts +38 -17
- package/src/daemon/conversation-skill-tools.ts +14 -30
- package/src/daemon/conversation-surfaces.ts +69 -34
- package/src/daemon/conversation-tool-setup.ts +77 -32
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +40 -75
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/daemon-skill-host.ts +9 -2
- package/src/daemon/disk-pressure-guard.ts +39 -29
- package/src/daemon/first-greeting.ts +31 -13
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/conversations.ts +11 -3
- package/src/daemon/handlers/shared.ts +6 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +4 -4
- package/src/daemon/host-file-proxy.ts +4 -4
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +10 -10
- package/src/daemon/lifecycle.ts +29 -26
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/meet-manifest-loader.ts +11 -24
- package/src/daemon/message-types/conversations.ts +22 -27
- package/src/daemon/message-types/document-comments.ts +8 -44
- package/src/daemon/message-types/home.ts +2 -14
- package/src/daemon/message-types/integrations.ts +2 -7
- package/src/daemon/message-types/messages.ts +25 -48
- package/src/daemon/message-types/subagents.ts +6 -0
- package/src/daemon/message-types/sync.ts +14 -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/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +62 -0
- package/src/daemon/tool-setup-types.ts +7 -0
- 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 +30 -1
- 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/home-greeting.ts +0 -9
- package/src/home/suggested-prompts.ts +27 -154
- package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
- package/src/ipc/gateway-client.test.ts +4 -1
- package/src/ipc/gateway-flag-listener.ts +123 -0
- 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 +35 -40
- package/src/memory/__tests__/db-async-query.test.ts +165 -0
- package/src/memory/__tests__/db-maintenance.test.ts +115 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- 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 +8 -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/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-attention-store.ts +17 -3
- package/src/memory/conversation-crud.ts +423 -182
- package/src/memory/conversation-starters-cadence.ts +3 -1
- package/src/memory/conversation-title-service.ts +19 -3
- package/src/memory/db-async-query.ts +214 -0
- package/src/memory/db-connection.ts +29 -19
- package/src/memory/db-init.ts +14 -0
- package/src/memory/db-maintenance.ts +30 -21
- 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/bootstrap.ts +8 -1
- package/src/memory/graph/capability-seed.ts +7 -3
- package/src/memory/graph/conversation-graph-memory.ts +100 -17
- package/src/memory/graph/extraction.ts +1 -5
- package/src/memory/graph/graph-search.ts +7 -1
- package/src/memory/graph/retriever.test.ts +3 -3
- package/src/memory/indexer.ts +28 -18
- package/src/memory/job-handlers/cleanup.ts +76 -18
- package/src/memory/job-handlers/conversation-starters.ts +1 -4
- 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/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +66 -22
- package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
- package/src/memory/llm-request-log-source-local.ts +31 -0
- package/src/memory/llm-request-log-source.ts +40 -2
- package/src/memory/llm-request-log-store.ts +228 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-enqueue.ts +8 -1
- package/src/memory/memory-retrospective-job.ts +5 -0
- package/src/memory/memory-v2-activation-log-store.ts +110 -7
- package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
- package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
- package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
- 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 +19 -0
- package/src/memory/migrations/registry.ts +33 -0
- package/src/memory/schema/conversations.ts +10 -2
- package/src/memory/schema/inference.ts +0 -1
- package/src/memory/schema/infrastructure.ts +21 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
- package/src/memory/v2/__tests__/injection.test.ts +127 -98
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +171 -3
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +128 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +240 -0
- package/src/memory/v2/harness/retriever.ts +74 -0
- package/src/memory/v2/harness/router-retriever.ts +43 -0
- package/src/memory/v2/harness/runner.ts +112 -0
- package/src/memory/v2/harness/trace.ts +64 -0
- package/src/memory/v2/injection.ts +21 -15
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +171 -18
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +706 -0
- package/src/memory/v3/__tests__/filter.test.ts +560 -0
- package/src/memory/v3/__tests__/gate.test.ts +637 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
- package/src/memory/v3/__tests__/loop.test.ts +775 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +489 -0
- package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +508 -0
- package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
- package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
- package/src/memory/v3/__tests__/validate.test.ts +277 -0
- package/src/memory/v3/auto-edges.ts +223 -0
- package/src/memory/v3/coactivation-store.ts +124 -0
- package/src/memory/v3/consolidation-job.ts +323 -0
- package/src/memory/v3/coretrieval-seed.ts +240 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +286 -0
- package/src/memory/v3/filter.ts +286 -0
- package/src/memory/v3/gate.ts +349 -0
- package/src/memory/v3/index-composition.ts +126 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +430 -0
- package/src/memory/v3/maintenance.ts +144 -0
- package/src/memory/v3/prompt-context.ts +33 -0
- package/src/memory/v3/prompts/consolidation.ts +458 -0
- package/src/memory/v3/prompts/system-prompts.ts +196 -0
- package/src/memory/v3/retriever.ts +33 -0
- package/src/memory/v3/scouts.ts +431 -0
- package/src/memory/v3/shadow-diff.ts +287 -0
- package/src/memory/v3/shadow-middleware.ts +347 -0
- package/src/memory/v3/traversal.ts +211 -0
- package/src/memory/v3/tree-index.ts +237 -0
- package/src/memory/v3/tree-store.ts +394 -0
- package/src/memory/v3/tree-walk.ts +356 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +323 -0
- 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/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- 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/decision-engine.ts +1 -4
- 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 +40 -50
- 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/permissions/prompter.ts +3 -3
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +2 -2
- 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/plugin-api/index.ts +4 -0
- package/src/plugin-api/types.ts +7 -33
- package/src/plugins/defaults/index.ts +6 -0
- package/src/plugins/defaults/injectors.ts +20 -19
- package/src/plugins/defaults/persistence.ts +25 -6
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +68 -29
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/proactive-artifact/job.test.ts +1 -0
- package/src/prompts/__tests__/system-prompt.test.ts +4 -4
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +39 -7
- package/src/prompts/system-prompt.ts +84 -221
- package/src/prompts/template-detection.ts +10 -4
- package/src/prompts/templates/BOOTSTRAP.md +9 -13
- package/src/prompts/templates/IDENTITY.md +0 -2
- package/src/prompts/templates/system-sections.ts +230 -8
- package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
- package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +32 -66
- package/src/providers/call-site-routing.ts +42 -6
- package/src/providers/connection-model-compat.ts +61 -0
- package/src/providers/connection-resolution.ts +47 -14
- package/src/providers/fireworks/client.ts +1 -0
- package/src/providers/gemini/client.ts +70 -6
- 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/adapter-factory.ts +3 -0
- 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/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +78 -1
- package/src/providers/model-intents.ts +4 -4
- 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 +116 -15
- package/src/providers/openai/codex-models.ts +20 -0
- package/src/providers/openai/responses-provider.ts +87 -30
- package/src/providers/openrouter/client.ts +13 -8
- package/src/providers/provider-send-message.ts +20 -5
- package/src/providers/registry.ts +48 -8
- package/src/providers/retry.ts +50 -7
- package/src/providers/search-provider-catalog.ts +17 -9
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +9 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- 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/agent-wake.ts +1 -0
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +46 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- 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/http-types.ts +0 -2
- package/src/runtime/migrations/vbundle-builder.ts +12 -4
- package/src/runtime/pending-interactions.ts +0 -1
- 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 +204 -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 +76 -9
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -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/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/app-management-routes.ts +111 -4
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +356 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +4 -10
- package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
- package/src/runtime/routes/conversation-list-routes.ts +159 -4
- package/src/runtime/routes/conversation-management-routes.ts +108 -26
- package/src/runtime/routes/conversation-query-routes.ts +200 -44
- package/src/runtime/routes/conversation-routes.ts +409 -521
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/conversations-import-routes.ts +19 -6
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/documents-routes.ts +10 -1
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +35 -8
- package/src/runtime/routes/home-feed-routes.ts +129 -0
- package/src/runtime/routes/host-browser-routes.ts +10 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- 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/acl-enforcement.ts +96 -3
- 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 +10 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- 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-call-sites-routes.ts +32 -5
- package/src/runtime/routes/llm-context-normalization.ts +7 -2
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +215 -5
- package/src/runtime/routes/memory-v3-routes.ts +474 -0
- package/src/runtime/routes/migration-routes.ts +32 -28
- package/src/runtime/routes/notification-routes.ts +63 -1
- package/src/runtime/routes/oauth-commands-routes.ts +6 -1
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +5 -4
- 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/routes/workspace-routes.ts +25 -10
- 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 +106 -38
- package/src/runtime/sync/sync-publisher.test.ts +49 -0
- package/src/runtime/sync/sync-publisher.ts +2 -1
- package/src/runtime/tool-grant-request-helper.ts +1 -0
- package/src/runtime/verification-outbound-actions.ts +73 -1
- 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/telemetry/types.ts +12 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/acp/spawn.test.ts +119 -0
- package/src/tools/acp/spawn.ts +15 -2
- package/src/tools/apps/definitions.ts +36 -28
- package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
- package/src/tools/ask-question/ask-question-tool.ts +38 -45
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
- package/src/tools/browser/browser-execution.ts +16 -3
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
- package/src/tools/browser/cdp-client/factory.ts +100 -17
- package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
- package/src/tools/browser/cdp-client/types.ts +65 -0
- package/src/tools/browser/pinned-tabs.ts +96 -40
- package/src/tools/computer-use/definitions.ts +282 -336
- package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
- package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
- package/src/tools/credentials/vault.ts +3 -9
- package/src/tools/document/document-tool.ts +189 -7
- package/src/tools/execution-target.ts +18 -23
- package/src/tools/executor.ts +24 -56
- package/src/tools/filesystem/edit.ts +3 -9
- package/src/tools/filesystem/list.ts +3 -9
- package/src/tools/filesystem/read.ts +3 -9
- package/src/tools/filesystem/write.ts +3 -9
- package/src/tools/host-filesystem/edit.test.ts +1 -0
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.test.ts +1 -0
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.test.ts +31 -6
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.test.ts +1 -0
- package/src/tools/host-filesystem/write.ts +3 -9
- package/src/tools/host-terminal/host-shell.ts +3 -9
- package/src/tools/mcp/mcp-tool-factory.ts +1 -10
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- 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-fetch.ts +3 -9
- package/src/tools/network/web-search.ts +224 -76
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/registry.ts +150 -123
- package/src/tools/schedule/create.ts +1 -1
- package/src/tools/schema-transforms.ts +1 -1
- package/src/tools/skills/execute.ts +3 -9
- package/src/tools/skills/load.ts +3 -9
- package/src/tools/skills/skill-tool-factory.ts +18 -44
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/subagent/spawn.ts +3 -0
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +10 -4
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/tool-name-aliases.ts +72 -14
- package/src/tools/types.ts +32 -101
- package/src/tools/ui-surface/definitions.ts +104 -108
- package/src/types/onboarding-context.ts +6 -0
- package/src/usage/attribution.ts +32 -1
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/browser.ts +7 -2
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -2
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- 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 +6 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/daemon/query-complexity-router.ts +0 -75
- package/src/prompts/cache-boundary.ts +0 -8
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure JSON-schema input validator for skill tool calls.
|
|
3
|
+
*
|
|
4
|
+
* Deliberate strict subset of JSON Schema: it covers only the keywords
|
|
5
|
+
* actually used by `assistant/src/config/bundled-skills/**\/TOOLS.json`
|
|
6
|
+
* (required / type / enum / items.type) plus unknown-key detection. Anything
|
|
7
|
+
* else (`$ref`, `oneOf`, `anyOf`, `allOf`, `format`, `pattern`, `minimum`,
|
|
8
|
+
* `maximum`, object-shape `additionalProperties`, etc.) is silently skipped so
|
|
9
|
+
* a richer schema can never cause us to reject a legitimate call.
|
|
10
|
+
*
|
|
11
|
+
* Each error message is written to be agent-readable and self-correcting
|
|
12
|
+
* (e.g. `surface_id is required`, `mode must be one of "replace", "append"`).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { isPlainObject } from "../util/object.js";
|
|
16
|
+
|
|
17
|
+
export interface InputValidationSuccess {
|
|
18
|
+
ok: true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface InputValidationFailure {
|
|
22
|
+
ok: false;
|
|
23
|
+
/** Human-readable messages, one per problem. */
|
|
24
|
+
errors: string[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type InputValidationResult =
|
|
28
|
+
| InputValidationSuccess
|
|
29
|
+
| InputValidationFailure;
|
|
30
|
+
|
|
31
|
+
type SupportedType =
|
|
32
|
+
| "string"
|
|
33
|
+
| "number"
|
|
34
|
+
| "integer"
|
|
35
|
+
| "boolean"
|
|
36
|
+
| "array"
|
|
37
|
+
| "object";
|
|
38
|
+
|
|
39
|
+
const SUPPORTED_TYPES: ReadonlySet<string> = new Set([
|
|
40
|
+
"string",
|
|
41
|
+
"number",
|
|
42
|
+
"integer",
|
|
43
|
+
"boolean",
|
|
44
|
+
"array",
|
|
45
|
+
"object",
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
function matchesType(value: unknown, type: SupportedType): boolean {
|
|
49
|
+
switch (type) {
|
|
50
|
+
case "string":
|
|
51
|
+
return typeof value === "string";
|
|
52
|
+
case "number":
|
|
53
|
+
return typeof value === "number";
|
|
54
|
+
case "integer":
|
|
55
|
+
return typeof value === "number" && Number.isInteger(value);
|
|
56
|
+
case "boolean":
|
|
57
|
+
return typeof value === "boolean";
|
|
58
|
+
case "array":
|
|
59
|
+
return Array.isArray(value);
|
|
60
|
+
case "object":
|
|
61
|
+
return isPlainObject(value);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function quoteList(values: readonly string[]): string {
|
|
66
|
+
return values.map((v) => `"${v}"`).join(", ");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Validate a tool input object against the (optional) JSON-schema definition
|
|
71
|
+
* declared on the tool entry. Returns `{ ok: true }` if the input is valid (or
|
|
72
|
+
* if there is nothing actionable to validate); otherwise returns a list of
|
|
73
|
+
* human-readable error strings.
|
|
74
|
+
*
|
|
75
|
+
* Pure: never mutates `input` or `schema`, no I/O.
|
|
76
|
+
*/
|
|
77
|
+
export function validateInputAgainstSchema(
|
|
78
|
+
_toolName: string,
|
|
79
|
+
input: Record<string, unknown>,
|
|
80
|
+
schema: Record<string, unknown> | undefined,
|
|
81
|
+
): InputValidationResult {
|
|
82
|
+
// Skip when there's no schema or no properties block — matches today's
|
|
83
|
+
// lenient behaviour for tools that declare only `{ type: "object" }`.
|
|
84
|
+
if (!schema) return { ok: true };
|
|
85
|
+
const properties = schema.properties;
|
|
86
|
+
if (!isPlainObject(properties)) return { ok: true };
|
|
87
|
+
|
|
88
|
+
const errors: string[] = [];
|
|
89
|
+
const knownKeys = Object.keys(properties);
|
|
90
|
+
const knownKeySet = new Set(knownKeys);
|
|
91
|
+
|
|
92
|
+
// 1. Required fields — presence-only check per JSON Schema spec.
|
|
93
|
+
// `required` only requires the property to be present; `null` is a valid
|
|
94
|
+
// value when the schema allows it (e.g. `type: ["string", "null"]`).
|
|
95
|
+
const required = schema.required;
|
|
96
|
+
if (Array.isArray(required)) {
|
|
97
|
+
for (const key of required) {
|
|
98
|
+
if (typeof key !== "string") continue;
|
|
99
|
+
if (!(key in input)) {
|
|
100
|
+
errors.push(`${key} is required`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 2. Per-property checks: type, enum, items.type.
|
|
106
|
+
for (const [key, rawSubSchema] of Object.entries(properties)) {
|
|
107
|
+
if (!(key in input)) continue;
|
|
108
|
+
const value = input[key];
|
|
109
|
+
// Skip type-checking for absent values; presence is enforced by the
|
|
110
|
+
// `required` check above. Note: `null` IS a present value and is
|
|
111
|
+
// type-checked below — only schemas that explicitly opt in to null via
|
|
112
|
+
// a union type (`type: ["string","null"]`) bypass the check, handled
|
|
113
|
+
// by the `Array.isArray(declaredType)` skip immediately below.
|
|
114
|
+
if (value === undefined) continue;
|
|
115
|
+
if (!isPlainObject(rawSubSchema)) continue;
|
|
116
|
+
|
|
117
|
+
const declaredType = rawSubSchema.type;
|
|
118
|
+
// Skip union types (e.g. `["string", "null"]`) — same lenient treatment
|
|
119
|
+
// we give `oneOf`/`anyOf`/`$ref`. We only validate single-type schemas.
|
|
120
|
+
if (Array.isArray(declaredType)) continue;
|
|
121
|
+
if (typeof declaredType === "string" && SUPPORTED_TYPES.has(declaredType)) {
|
|
122
|
+
const type = declaredType as SupportedType;
|
|
123
|
+
if (!matchesType(value, type)) {
|
|
124
|
+
errors.push(`${key} must be ${typeArticle(type)} ${type}`);
|
|
125
|
+
// No point checking enum/items if the base type is wrong.
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 2a. Enum (string enums are the only shape used today).
|
|
130
|
+
const enumValues = rawSubSchema.enum;
|
|
131
|
+
if (Array.isArray(enumValues) && enumValues.length > 0) {
|
|
132
|
+
if (!enumValues.includes(value)) {
|
|
133
|
+
errors.push(
|
|
134
|
+
`${key} must be one of ${quoteList(enumValues.map(String))}`,
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// 2b. Array items.type — per-element check.
|
|
140
|
+
if (type === "array" && isPlainObject(rawSubSchema.items)) {
|
|
141
|
+
const itemType = rawSubSchema.items.type;
|
|
142
|
+
if (
|
|
143
|
+
typeof itemType === "string" &&
|
|
144
|
+
SUPPORTED_TYPES.has(itemType) &&
|
|
145
|
+
Array.isArray(value)
|
|
146
|
+
) {
|
|
147
|
+
const itemTypeName = itemType as SupportedType;
|
|
148
|
+
value.forEach((element, index) => {
|
|
149
|
+
if (!matchesType(element, itemTypeName)) {
|
|
150
|
+
errors.push(
|
|
151
|
+
`${key}[${index}] must be ${typeArticle(itemTypeName)} ${itemTypeName}`,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// 3. Unknown keys — parity with the previous `validateNoUnknownParams`.
|
|
161
|
+
const unknownKeys = Object.keys(input).filter((k) => !knownKeySet.has(k));
|
|
162
|
+
for (const key of unknownKeys) {
|
|
163
|
+
errors.push(
|
|
164
|
+
`Unknown parameter "${key}". Supported: ${quoteList(knownKeys)}`,
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (errors.length === 0) return { ok: true };
|
|
169
|
+
return { ok: false, errors };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function typeArticle(type: SupportedType): "a" | "an" {
|
|
173
|
+
// `integer`, `array`, `object` start with a vowel sound.
|
|
174
|
+
return type === "integer" || type === "array" || type === "object"
|
|
175
|
+
? "an"
|
|
176
|
+
: "a";
|
|
177
|
+
}
|
package/src/subagent/manager.ts
CHANGED
|
@@ -365,6 +365,7 @@ export class SubagentManager {
|
|
|
365
365
|
label: config.label,
|
|
366
366
|
objective: config.objective,
|
|
367
367
|
isFork: config.fork ?? false,
|
|
368
|
+
parentToolUseId: config.parentToolUseId,
|
|
368
369
|
} as ServerMessage);
|
|
369
370
|
|
|
370
371
|
log.info(
|
|
@@ -435,7 +436,9 @@ export class SubagentManager {
|
|
|
435
436
|
"⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯",
|
|
436
437
|
].join("\n")
|
|
437
438
|
: objective;
|
|
438
|
-
const messageId = await conversation.persistUserMessage(
|
|
439
|
+
const { id: messageId } = await conversation.persistUserMessage({
|
|
440
|
+
content: message,
|
|
441
|
+
});
|
|
439
442
|
await conversation.runAgentLoop(message, messageId, undefined, {
|
|
440
443
|
callSite: "subagentSpawn",
|
|
441
444
|
...(managed.state.config.overrideProfile
|
|
@@ -609,7 +612,7 @@ export class SubagentManager {
|
|
|
609
612
|
return "terminal";
|
|
610
613
|
|
|
611
614
|
// If the conversation is busy, queue the message; otherwise process immediately.
|
|
612
|
-
const result = managed.conversation.enqueueMessage(trimmed
|
|
615
|
+
const result = managed.conversation.enqueueMessage({ content: trimmed });
|
|
613
616
|
if (result.rejected) {
|
|
614
617
|
return "sent"; // error event already delivered via sendToClient
|
|
615
618
|
}
|
|
@@ -620,7 +623,9 @@ export class SubagentManager {
|
|
|
620
623
|
// Capture conversation before the await — managed.conversation may be
|
|
621
624
|
// nulled by an external dispose() while persistUserMessage is awaited.
|
|
622
625
|
const conversation = managed.conversation;
|
|
623
|
-
const messageId = await conversation.persistUserMessage(
|
|
626
|
+
const { id: messageId } = await conversation.persistUserMessage({
|
|
627
|
+
content: trimmed,
|
|
628
|
+
});
|
|
624
629
|
conversation
|
|
625
630
|
.runAgentLoop(trimmed, messageId, undefined, {
|
|
626
631
|
callSite: "subagentSpawn",
|
|
@@ -984,19 +989,14 @@ export class SubagentManager {
|
|
|
984
989
|
);
|
|
985
990
|
return;
|
|
986
991
|
}
|
|
987
|
-
const enqueueResult = parentConversation.enqueueMessage(
|
|
988
|
-
message,
|
|
989
|
-
[],
|
|
990
|
-
undefined,
|
|
991
|
-
undefined,
|
|
992
|
-
undefined,
|
|
993
|
-
undefined,
|
|
992
|
+
const enqueueResult = parentConversation.enqueueMessage({
|
|
993
|
+
content: message,
|
|
994
994
|
metadata,
|
|
995
|
-
);
|
|
995
|
+
});
|
|
996
996
|
if (!enqueueResult.queued && !enqueueResult.rejected) {
|
|
997
997
|
parentConversation
|
|
998
|
-
.persistUserMessage(
|
|
999
|
-
.then((messageId) =>
|
|
998
|
+
.persistUserMessage({ content: message, metadata })
|
|
999
|
+
.then(({ id: messageId }) =>
|
|
1000
1000
|
parentConversation.runAgentLoop(message, messageId),
|
|
1001
1001
|
)
|
|
1002
1002
|
.catch((err) => {
|
package/src/subagent/types.ts
CHANGED
|
@@ -69,6 +69,12 @@ export interface SubagentConfig {
|
|
|
69
69
|
* profile, every spawned subagent inherits it automatically.
|
|
70
70
|
*/
|
|
71
71
|
overrideProfile?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Tool-use id of the `skill_execute` call that spawned this subagent.
|
|
74
|
+
* Forwarded into the `subagent_spawned` event so the client can anchor the
|
|
75
|
+
* inline subagent card to the exact spawn tool call.
|
|
76
|
+
*/
|
|
77
|
+
parentToolUseId?: string;
|
|
72
78
|
}
|
|
73
79
|
|
|
74
80
|
// ── State (runtime) ─────────────────────────────────────────────────────
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getAllTools, getTool } from "../tools/registry.js";
|
|
1
|
+
import { getAllTools, getTool, getToolOwner } from "../tools/registry.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Deduplicate and sort a list of tool names, validating against the live
|
|
@@ -24,7 +24,7 @@ export function sanitizeToolList(tools: string[]): string[] {
|
|
|
24
24
|
*/
|
|
25
25
|
export function getRegisteredToolNames(): string[] {
|
|
26
26
|
return getAllTools()
|
|
27
|
-
.filter((t) => t.
|
|
27
|
+
.filter((t) => getToolOwner(t.name)?.kind !== "skill")
|
|
28
28
|
.map((t) => t.name)
|
|
29
29
|
.sort();
|
|
30
30
|
}
|
package/src/telemetry/types.ts
CHANGED
|
@@ -38,6 +38,18 @@ export interface LlmUsageTelemetryEvent extends TelemetryEventBase {
|
|
|
38
38
|
output_tokens: number;
|
|
39
39
|
cache_creation_input_tokens: number | null;
|
|
40
40
|
cache_read_input_tokens: number | null;
|
|
41
|
+
/**
|
|
42
|
+
* The provider's untouched `usage` block. Anthropic surfaces a TTL
|
|
43
|
+
* breakdown under `cache_creation.ephemeral_{5m,1h}_input_tokens`;
|
|
44
|
+
* OpenAI surfaces cached-read counts under
|
|
45
|
+
* `prompt_tokens_details.cached_tokens` (and reasoning tokens under
|
|
46
|
+
* `completion_tokens_details`). Both shapes are forwarded verbatim so
|
|
47
|
+
* downstream consumers (admin charts, dbt models) can extract any
|
|
48
|
+
* provider-specific detail without requiring a schema change here.
|
|
49
|
+
* Null when the provider did not return a usage payload, and for
|
|
50
|
+
* daemons that predate `260-llm-usage-add-raw-usage`.
|
|
51
|
+
*/
|
|
52
|
+
raw_usage: Record<string, unknown> | null;
|
|
41
53
|
actor: string;
|
|
42
54
|
llm_call_site: LLMCallSite | null;
|
|
43
55
|
inference_profile: string | null;
|
|
@@ -159,6 +159,7 @@ function makeUsageEvent(
|
|
|
159
159
|
outputTokens: 50,
|
|
160
160
|
cacheCreationInputTokens: 10,
|
|
161
161
|
cacheReadInputTokens: 5,
|
|
162
|
+
rawUsage: null,
|
|
162
163
|
actor: "main_agent",
|
|
163
164
|
callSite: null,
|
|
164
165
|
inferenceProfile: null,
|
|
@@ -435,6 +436,53 @@ describe("UsageTelemetryReporter", () => {
|
|
|
435
436
|
expect(e.inference_profile_source).toBe("conversation");
|
|
436
437
|
expect(e.cost).toBe(0.001);
|
|
437
438
|
expect(e.recorded_at).toBe(1700000099000);
|
|
439
|
+
// raw_usage defaults to null on this fixture (the makeUsageEvent default),
|
|
440
|
+
// confirming the wire shape carries the key as `null` rather than
|
|
441
|
+
// dropping it for legacy rows or providers that did not return a
|
|
442
|
+
// usage block.
|
|
443
|
+
expect(e.raw_usage).toBeNull();
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
test("payload forwards the provider's raw_usage block verbatim", async () => {
|
|
447
|
+
// The reporter must surface the literal usage object the provider
|
|
448
|
+
// returned (Anthropic nests TTL breakdown under `cache_creation`,
|
|
449
|
+
// OpenAI nests cached-read counts under `prompt_tokens_details`,
|
|
450
|
+
// etc.) so downstream consumers can extract any provider-specific
|
|
451
|
+
// detail without a wire-level schema change. Anything that
|
|
452
|
+
// transforms, summarises, or strips fields here destroys data the
|
|
453
|
+
// admin charts and dbt models depend on.
|
|
454
|
+
const rawUsage = {
|
|
455
|
+
input_tokens: 200,
|
|
456
|
+
output_tokens: 100,
|
|
457
|
+
cache_creation_input_tokens: 750,
|
|
458
|
+
cache_creation: {
|
|
459
|
+
ephemeral_5m_input_tokens: 250,
|
|
460
|
+
ephemeral_1h_input_tokens: 500,
|
|
461
|
+
},
|
|
462
|
+
cache_read_input_tokens: 15,
|
|
463
|
+
service_tier: "standard",
|
|
464
|
+
};
|
|
465
|
+
const event = makeUsageEvent({
|
|
466
|
+
id: "evt-raw-usage",
|
|
467
|
+
provider: "anthropic",
|
|
468
|
+
model: "claude-sonnet-4-20250514",
|
|
469
|
+
cacheCreationInputTokens: 750,
|
|
470
|
+
rawUsage,
|
|
471
|
+
});
|
|
472
|
+
mockQueryUnreportedUsageEvents.mockReturnValue([event]);
|
|
473
|
+
mockFetch.mockImplementation(() =>
|
|
474
|
+
Promise.resolve(new Response('{"accepted":1}', { status: 200 })),
|
|
475
|
+
);
|
|
476
|
+
|
|
477
|
+
const reporter = new UsageTelemetryReporter();
|
|
478
|
+
await reporter.flush();
|
|
479
|
+
|
|
480
|
+
const body = JSON.parse(
|
|
481
|
+
(mockFetch.mock.calls[0] as [string, RequestInit])[1].body as string,
|
|
482
|
+
);
|
|
483
|
+
const e = body.events[0];
|
|
484
|
+
expect(e.cache_creation_input_tokens).toBe(750);
|
|
485
|
+
expect(e.raw_usage).toEqual(rawUsage);
|
|
438
486
|
});
|
|
439
487
|
|
|
440
488
|
test("payload preserves null attribution for historical usage rows", async () => {
|
|
@@ -234,6 +234,7 @@ export class UsageTelemetryReporter {
|
|
|
234
234
|
output_tokens: e.outputTokens,
|
|
235
235
|
cache_creation_input_tokens: e.cacheCreationInputTokens ?? null,
|
|
236
236
|
cache_read_input_tokens: e.cacheReadInputTokens ?? null,
|
|
237
|
+
raw_usage: e.rawUsage,
|
|
237
238
|
actor: e.actor,
|
|
238
239
|
llm_call_site: e.callSite,
|
|
239
240
|
inference_profile: e.inferenceProfile,
|
|
@@ -82,6 +82,25 @@ mock.module("../../util/logger.js", () => ({
|
|
|
82
82
|
}),
|
|
83
83
|
}));
|
|
84
84
|
|
|
85
|
+
// Stub secure-keys so the `prepareAgentEnv` preflight finds a token without
|
|
86
|
+
// the test having to populate the real OS keyring. Driven via `secureKeyStore`
|
|
87
|
+
// per test in beforeEach; the default seeds a vault token so existing tests
|
|
88
|
+
// (which assume claude spawns succeed) keep passing.
|
|
89
|
+
//
|
|
90
|
+
// The real module's other exports are spread in so transitive importers
|
|
91
|
+
// (e.g. session-manager → pending-interactions → credential-routes, which
|
|
92
|
+
// imports `getSecureKeyResultAsync`) still resolve at parse time. Bun's
|
|
93
|
+
// `mock.module` is process-global and returns *exactly* the keys the factory
|
|
94
|
+
// returns — without the spread, any consumer pulling a non-`getSecureKeyAsync`
|
|
95
|
+
// export errors with "Export named '<X>' not found".
|
|
96
|
+
const secureKeyStore = new Map<string, string>();
|
|
97
|
+
const realSecureKeys = await import("../../security/secure-keys.js");
|
|
98
|
+
|
|
99
|
+
mock.module("../../security/secure-keys.js", () => ({
|
|
100
|
+
...realSecureKeys,
|
|
101
|
+
getSecureKeyAsync: async (key: string) => secureKeyStore.get(key),
|
|
102
|
+
}));
|
|
103
|
+
|
|
85
104
|
// Stub session manager so we don't actually spawn child processes.
|
|
86
105
|
const spawnMock = mock(
|
|
87
106
|
async (
|
|
@@ -131,6 +150,14 @@ beforeEach(() => {
|
|
|
131
150
|
_resetAdapterVersionCacheForTests();
|
|
132
151
|
config.setConfig({ agents: DEFAULT_TEST_AGENTS });
|
|
133
152
|
which.setWhich((cmd) => `/usr/local/bin/${cmd}`);
|
|
153
|
+
// Default: vault has a claude token so the preflight in `prepareAgentEnv`
|
|
154
|
+
// succeeds for tests that don't care about env injection. Env-injection
|
|
155
|
+
// tests below clear/override this explicitly.
|
|
156
|
+
secureKeyStore.clear();
|
|
157
|
+
secureKeyStore.set(
|
|
158
|
+
"credential/acp/claude_oauth_token",
|
|
159
|
+
"default-test-token",
|
|
160
|
+
);
|
|
134
161
|
});
|
|
135
162
|
|
|
136
163
|
// ---------------------------------------------------------------------------
|
|
@@ -376,3 +403,95 @@ describe("executeAcpSpawn — per-agent resume hint", () => {
|
|
|
376
403
|
expect(payload.message).not.toContain("To resume this session later");
|
|
377
404
|
});
|
|
378
405
|
});
|
|
406
|
+
|
|
407
|
+
// ---------------------------------------------------------------------------
|
|
408
|
+
// executeAcpSpawn — CLAUDE_CODE_OAUTH_TOKEN env injection + preflight
|
|
409
|
+
//
|
|
410
|
+
// Mirrors the HTTP-route test block in
|
|
411
|
+
// `runtime/routes/acp-routes.test.ts` — the skill tool calls into the same
|
|
412
|
+
// `prepareAgentEnv` helper, and the contract must be identical so a
|
|
413
|
+
// missing token fails the spawn at the tool boundary (`isError: true`)
|
|
414
|
+
// instead of letting a token-less subprocess zombie out. PR-history
|
|
415
|
+
// context: the inline env-injection used to live in the route only; this
|
|
416
|
+
// tool path was bypassing it entirely, causing every skill-driven ACP
|
|
417
|
+
// spawn to die on first prompt with "Authentication required". Pin both
|
|
418
|
+
// the happy paths and the throw path here so future drift on either
|
|
419
|
+
// caller fails the suite loudly.
|
|
420
|
+
// ---------------------------------------------------------------------------
|
|
421
|
+
|
|
422
|
+
describe("executeAcpSpawn — CLAUDE_CODE_OAUTH_TOKEN injection", () => {
|
|
423
|
+
test("injects CLAUDE_CODE_OAUTH_TOKEN from the secure store for the claude agent", async () => {
|
|
424
|
+
secureKeyStore.clear();
|
|
425
|
+
secureKeyStore.set(
|
|
426
|
+
"credential/acp/claude_oauth_token",
|
|
427
|
+
"tool-vault-token-abc",
|
|
428
|
+
);
|
|
429
|
+
execScripts.set("npm ls", { error: new Error("npm not installed") });
|
|
430
|
+
execScripts.set("npm view", { error: new Error("npm not installed") });
|
|
431
|
+
|
|
432
|
+
const result = await executeAcpSpawn(
|
|
433
|
+
{ agent: "claude", task: "do something" },
|
|
434
|
+
makeContext(),
|
|
435
|
+
);
|
|
436
|
+
|
|
437
|
+
expect(result.isError).toBe(false);
|
|
438
|
+
expect(spawnMock).toHaveBeenCalledTimes(1);
|
|
439
|
+
const agentConfigArg = spawnMock.mock.calls[0][1] as {
|
|
440
|
+
env?: Record<string, string>;
|
|
441
|
+
};
|
|
442
|
+
expect(agentConfigArg.env?.CLAUDE_CODE_OAUTH_TOKEN).toBe(
|
|
443
|
+
"tool-vault-token-abc",
|
|
444
|
+
);
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
test("accepts CLAUDE_CODE_OAUTH_TOKEN from config.json agent.env without a vault entry", async () => {
|
|
448
|
+
// Mirrors the route-level precedence test: a config.json env override
|
|
449
|
+
// is the first-priority provisioning route. The resolver surfaces it
|
|
450
|
+
// on `resolved.agent.env`, which the helper preserves.
|
|
451
|
+
secureKeyStore.clear();
|
|
452
|
+
config.setConfig({
|
|
453
|
+
agents: {
|
|
454
|
+
claude: {
|
|
455
|
+
command: "claude-agent-acp",
|
|
456
|
+
args: [],
|
|
457
|
+
env: { CLAUDE_CODE_OAUTH_TOKEN: "tool-config-token-xyz" },
|
|
458
|
+
},
|
|
459
|
+
codex: { command: "codex-acp", args: [] },
|
|
460
|
+
"unknown-agent": { command: "some-other-binary", args: [] },
|
|
461
|
+
},
|
|
462
|
+
});
|
|
463
|
+
execScripts.set("npm ls", { error: new Error("npm not installed") });
|
|
464
|
+
execScripts.set("npm view", { error: new Error("npm not installed") });
|
|
465
|
+
|
|
466
|
+
const result = await executeAcpSpawn(
|
|
467
|
+
{ agent: "claude", task: "do something" },
|
|
468
|
+
makeContext(),
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
expect(result.isError).toBe(false);
|
|
472
|
+
const agentConfigArg = spawnMock.mock.calls[0][1] as {
|
|
473
|
+
env?: Record<string, string>;
|
|
474
|
+
};
|
|
475
|
+
expect(agentConfigArg.env?.CLAUDE_CODE_OAUTH_TOKEN).toBe(
|
|
476
|
+
"tool-config-token-xyz",
|
|
477
|
+
);
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
test("returns isError when no token is available from either route (preflight throw mapped to tool result)", async () => {
|
|
481
|
+
// Both routes empty. The helper throws `FailedDependencyError`; the
|
|
482
|
+
// tool catches it and returns `{ isError: true, content: <msg> }`
|
|
483
|
+
// rather than letting it propagate (the tool boundary is a sync
|
|
484
|
+
// ToolExecutionResult, not an HTTP response).
|
|
485
|
+
secureKeyStore.clear();
|
|
486
|
+
|
|
487
|
+
const result = await executeAcpSpawn(
|
|
488
|
+
{ agent: "claude", task: "do something" },
|
|
489
|
+
makeContext(),
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
expect(result.isError).toBe(true);
|
|
493
|
+
expect(result.content).toContain("CLAUDE_CODE_OAUTH_TOKEN");
|
|
494
|
+
// Spawn was NEVER called — preflight fired before the subprocess started.
|
|
495
|
+
expect(spawnMock).not.toHaveBeenCalled();
|
|
496
|
+
});
|
|
497
|
+
});
|
package/src/tools/acp/spawn.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { execFile } from "node:child_process";
|
|
2
2
|
|
|
3
3
|
import { getAcpSessionManager } from "../../acp/index.js";
|
|
4
|
+
import { prepareAgentEnv } from "../../acp/prepare-agent-env.js";
|
|
4
5
|
import { resolveAcpAgent } from "../../acp/resolve-agent.js";
|
|
5
6
|
import { DEFAULT_AGENT_NPM_PACKAGES } from "../../config/acp-defaults.js";
|
|
6
7
|
import { getLogger } from "../../util/logger.js";
|
|
@@ -159,8 +160,6 @@ export async function executeAcpSpawn(
|
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
}
|
|
162
|
-
const agentConfig = resolved.agent;
|
|
163
|
-
|
|
164
163
|
const sendToClient = context.sendToClient as
|
|
165
164
|
| ((msg: { type: string; [key: string]: unknown }) => void)
|
|
166
165
|
| undefined;
|
|
@@ -171,6 +170,20 @@ export async function executeAcpSpawn(
|
|
|
171
170
|
};
|
|
172
171
|
}
|
|
173
172
|
|
|
173
|
+
// Inject required env vars and preflight via the shared helper. Mirrors
|
|
174
|
+
// the HTTP route at `runtime/routes/acp-routes.ts:spawnSession` — both
|
|
175
|
+
// call sites MUST go through `prepareAgentEnv` before `manager.spawn`,
|
|
176
|
+
// otherwise the spawned subprocess starts with no auth and dies as a
|
|
177
|
+
// zombie after the first prompt. See `acp/prepare-agent-env.ts` for
|
|
178
|
+
// the full rationale.
|
|
179
|
+
let agentConfig;
|
|
180
|
+
try {
|
|
181
|
+
agentConfig = await prepareAgentEnv(resolved.agent);
|
|
182
|
+
} catch (err) {
|
|
183
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
184
|
+
return { content: msg, isError: true };
|
|
185
|
+
}
|
|
186
|
+
|
|
174
187
|
// Best-effort version check — never blocks the spawn. If outdated, we
|
|
175
188
|
// append a non-blocking warning to the success payload.
|
|
176
189
|
const versionInfo = await checkAdapterVersion(agentConfig.command);
|
|
@@ -9,17 +9,31 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { RiskLevel } from "../../permissions/types.js";
|
|
12
|
-
import type {
|
|
13
|
-
import type { Tool, ToolExecutionResult } from "../types.js";
|
|
12
|
+
import type { Tool, ToolContext, ToolExecutionResult } from "../types.js";
|
|
14
13
|
|
|
15
14
|
// ---------------------------------------------------------------------------
|
|
16
15
|
// Helpers
|
|
17
16
|
// ---------------------------------------------------------------------------
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Forward execution to the connected macOS client via the request-bound
|
|
20
|
+
* `proxyToolResolver`. Returns a structured error when no resolver is
|
|
21
|
+
* configured (e.g. no client connected) so callers see a normal tool
|
|
22
|
+
* failure rather than an unhandled throw.
|
|
23
|
+
*/
|
|
24
|
+
function proxyExecute(toolName: string) {
|
|
25
|
+
return async (
|
|
26
|
+
input: Record<string, unknown>,
|
|
27
|
+
context: ToolContext,
|
|
28
|
+
): Promise<ToolExecutionResult> => {
|
|
29
|
+
if (!context.proxyToolResolver) {
|
|
30
|
+
return {
|
|
31
|
+
content: `No proxy resolver configured for proxy tool "${toolName}". This tool requires an external resolver (e.g. a connected macOS client).`,
|
|
32
|
+
isError: true,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return context.proxyToolResolver(toolName, input);
|
|
36
|
+
};
|
|
23
37
|
}
|
|
24
38
|
|
|
25
39
|
// ---------------------------------------------------------------------------
|
|
@@ -32,32 +46,26 @@ const appOpenTool: Tool = {
|
|
|
32
46
|
"Open a persistent app in a dynamic_page surface on the connected client.",
|
|
33
47
|
category: "apps",
|
|
34
48
|
defaultRiskLevel: RiskLevel.Low,
|
|
35
|
-
|
|
49
|
+
executionTarget: "host",
|
|
36
50
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
type: "string",
|
|
50
|
-
enum: ["preview", "workspace"],
|
|
51
|
-
description:
|
|
52
|
-
"Display mode. 'preview' shows an inline preview card in chat. 'workspace' opens the full app in a workspace panel. Defaults to 'workspace'.",
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
required: ["app_id"],
|
|
51
|
+
input_schema: {
|
|
52
|
+
type: "object",
|
|
53
|
+
properties: {
|
|
54
|
+
app_id: {
|
|
55
|
+
type: "string",
|
|
56
|
+
description: "The ID of the app to open",
|
|
57
|
+
},
|
|
58
|
+
open_mode: {
|
|
59
|
+
type: "string",
|
|
60
|
+
enum: ["preview", "workspace"],
|
|
61
|
+
description:
|
|
62
|
+
"Display mode. 'preview' shows an inline preview card in chat. 'workspace' opens the full app in a workspace panel. Defaults to 'workspace'.",
|
|
56
63
|
},
|
|
57
|
-
}
|
|
64
|
+
},
|
|
65
|
+
required: ["app_id"],
|
|
58
66
|
},
|
|
59
67
|
|
|
60
|
-
execute: proxyExecute,
|
|
68
|
+
execute: proxyExecute("app_open"),
|
|
61
69
|
};
|
|
62
70
|
|
|
63
71
|
// ---------------------------------------------------------------------------
|
|
@@ -51,7 +51,7 @@ const singleQ = {
|
|
|
51
51
|
|
|
52
52
|
describe("AskQuestionTool definition", () => {
|
|
53
53
|
test("exposes the expected schema shape and description language", () => {
|
|
54
|
-
const def = new AskQuestionTool()
|
|
54
|
+
const def = new AskQuestionTool();
|
|
55
55
|
expect(def.name).toBe("ask_question");
|
|
56
56
|
expect(def.description).toContain("free-text fallback is always added");
|
|
57
57
|
expect(def.description).toContain("do not");
|
|
@@ -463,8 +463,8 @@ describe("AskQuestionTool batched input", () => {
|
|
|
463
463
|
|
|
464
464
|
describe("AskQuestionTool definition (batched schema)", () => {
|
|
465
465
|
test("exposes `questions[]` shape, keeps legacy fields, omits per-question id", () => {
|
|
466
|
-
const def = new AskQuestionTool()
|
|
467
|
-
const schema = def.input_schema as {
|
|
466
|
+
const def = new AskQuestionTool();
|
|
467
|
+
const schema = def.input_schema as unknown as {
|
|
468
468
|
properties: Record<
|
|
469
469
|
string,
|
|
470
470
|
{
|