@vellumai/assistant 0.5.13 → 0.5.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +1 -6
- package/AGENTS.md +4 -0
- package/ARCHITECTURE.md +0 -1
- package/bunfig.toml +1 -0
- package/docs/architecture/memory.md +3 -3
- package/openapi.yaml +127 -22
- package/package.json +1 -1
- package/src/__tests__/access-request-decision.test.ts +2 -32
- package/src/__tests__/actor-token-service.test.ts +1 -31
- package/src/__tests__/anthropic-provider.test.ts +53 -40
- package/src/__tests__/app-git-history.test.ts +9 -17
- package/src/__tests__/app-git-service.test.ts +14 -20
- package/src/__tests__/app-store-dir-names.test.ts +10 -20
- package/src/__tests__/approval-cascade.test.ts +2 -19
- package/src/__tests__/approval-primitive.test.ts +2 -27
- package/src/__tests__/approval-routes-http.test.ts +2 -30
- package/src/__tests__/assistant-events-sse-hardening.test.ts +2 -28
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -45
- package/src/__tests__/attachments-store.test.ts +5 -32
- package/src/__tests__/audit-log-rotation.test.ts +5 -36
- package/src/__tests__/avatar-e2e.test.ts +1 -9
- package/src/__tests__/avatar-generator.test.ts +1 -7
- package/src/__tests__/browser-fill-credential.test.ts +0 -4
- package/src/__tests__/browser-manager.test.ts +0 -6
- package/src/__tests__/call-controller.test.ts +1 -22
- package/src/__tests__/call-conversation-messages.test.ts +0 -21
- package/src/__tests__/call-domain.test.ts +0 -25
- package/src/__tests__/call-pointer-messages.test.ts +0 -21
- package/src/__tests__/call-recovery.test.ts +0 -22
- package/src/__tests__/call-routes-http.test.ts +0 -24
- package/src/__tests__/call-store.test.ts +0 -21
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +0 -24
- package/src/__tests__/canonical-guardian-store.test.ts +48 -21
- package/src/__tests__/channel-approval-routes.test.ts +6 -26
- package/src/__tests__/channel-approvals.test.ts +1 -38
- package/src/__tests__/channel-delivery-store.test.ts +0 -21
- package/src/__tests__/channel-guardian.test.ts +0 -26
- package/src/__tests__/channel-reply-delivery.test.ts +5 -0
- package/src/__tests__/channel-retry-sweep.test.ts +0 -21
- package/src/__tests__/checker.test.ts +26 -61
- package/src/__tests__/clawhub.test.ts +9 -25
- package/src/__tests__/cli-command-risk-guard.test.ts +0 -18
- package/src/__tests__/config-loader-backfill.test.ts +9 -28
- package/src/__tests__/config-schema-cmd.test.ts +5 -25
- package/src/__tests__/config-schema.test.ts +21 -40
- package/src/__tests__/config-watcher.test.ts +4 -91
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -21
- package/src/__tests__/contacts-tools.test.ts +0 -21
- package/src/__tests__/context-memory-e2e.test.ts +0 -21
- package/src/__tests__/context-window-manager.test.ts +130 -3
- package/src/__tests__/conversation-abort-tool-results.test.ts +0 -4
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -4
- package/src/__tests__/conversation-agent-loop.test.ts +0 -4
- package/src/__tests__/conversation-attachments.test.ts +1 -24
- package/src/__tests__/conversation-attention-store.test.ts +0 -21
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -22
- package/src/__tests__/conversation-clear-safety.test.ts +0 -22
- package/src/__tests__/conversation-confirmation-signals.test.ts +2 -21
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -24
- package/src/__tests__/conversation-disk-view-integration.test.ts +1 -23
- package/src/__tests__/conversation-disk-view.test.ts +5 -27
- package/src/__tests__/conversation-error.test.ts +1 -1
- package/src/__tests__/conversation-fork-crud.test.ts +1 -33
- package/src/__tests__/conversation-fork-route.test.ts +0 -27
- package/src/__tests__/conversation-history-web-search.test.ts +23 -16
- package/src/__tests__/conversation-init.benchmark.test.ts +22 -43
- package/src/__tests__/conversation-key-store-disk-view.test.ts +8 -34
- package/src/__tests__/conversation-load-history-repair.test.ts +0 -4
- package/src/__tests__/conversation-pre-run-repair.test.ts +0 -4
- package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -4
- package/src/__tests__/conversation-queue.test.ts +8 -8
- package/src/__tests__/conversation-routes-disk-view.test.ts +13 -51
- package/src/__tests__/conversation-runtime-assembly.test.ts +64 -38
- package/src/__tests__/conversation-slash-commands.test.ts +5 -0
- package/src/__tests__/conversation-slash-queue.test.ts +0 -4
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -4
- package/src/__tests__/conversation-speed-override.test.ts +326 -0
- package/src/__tests__/conversation-starter-routes.test.ts +0 -23
- package/src/__tests__/conversation-store.test.ts +0 -21
- package/src/__tests__/conversation-unread-route.test.ts +0 -24
- package/src/__tests__/conversation-usage.test.ts +56 -21
- package/src/__tests__/conversation-wipe.test.ts +0 -21
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -4
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -4
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +8 -5
- package/src/__tests__/credential-vault-unit.test.ts +9 -428
- package/src/__tests__/credentials-cli.test.ts +10 -10
- package/src/__tests__/daemon-assistant-events.test.ts +0 -19
- package/src/__tests__/date-context.test.ts +77 -97
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +7 -24
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +29 -42
- package/src/__tests__/delete-managed-skill-tool.test.ts +2 -10
- package/src/__tests__/deterministic-verification-control-plane.test.ts +1 -26
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +61 -15
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +2 -36
- package/src/__tests__/email-cli.test.ts +6 -6
- package/src/__tests__/ephemeral-permissions.test.ts +5 -17
- package/src/__tests__/first-greeting.test.ts +4 -32
- package/src/__tests__/followup-tools.test.ts +0 -21
- package/src/__tests__/gateway-only-enforcement.test.ts +0 -20
- package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -23
- package/src/__tests__/guardian-action-followup-executor.test.ts +0 -23
- package/src/__tests__/guardian-action-followup-store.test.ts +0 -21
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -21
- package/src/__tests__/guardian-action-late-reply.test.ts +0 -21
- package/src/__tests__/guardian-action-store.test.ts +0 -21
- package/src/__tests__/guardian-action-sweep.test.ts +0 -21
- package/src/__tests__/guardian-binding-drift-heal.test.ts +0 -23
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +172 -22
- package/src/__tests__/guardian-dispatch.test.ts +0 -21
- package/src/__tests__/guardian-grant-minting.test.ts +0 -22
- package/src/__tests__/guardian-outbound-http.test.ts +0 -22
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -23
- package/src/__tests__/guardian-routing-invariants.test.ts +0 -22
- package/src/__tests__/guardian-routing-state.test.ts +0 -22
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -24
- package/src/__tests__/headless-browser-interactions.test.ts +0 -4
- package/src/__tests__/headless-browser-navigate.test.ts +0 -4
- package/src/__tests__/headless-browser-read-tools.test.ts +0 -4
- package/src/__tests__/headless-browser-snapshot.test.ts +0 -4
- package/src/__tests__/heartbeat-service.test.ts +99 -26
- package/src/__tests__/hooks-blocking.test.ts +3 -3
- package/src/__tests__/hooks-config.test.ts +7 -7
- package/src/__tests__/hooks-discovery.test.ts +3 -3
- package/src/__tests__/hooks-integration.test.ts +5 -5
- package/src/__tests__/hooks-manager.test.ts +3 -3
- package/src/__tests__/hooks-runner.test.ts +5 -23
- package/src/__tests__/hooks-settings.test.ts +3 -3
- package/src/__tests__/hooks-templates.test.ts +3 -3
- package/src/__tests__/http-conversation-lineage.test.ts +0 -27
- package/src/__tests__/identity-intro-cache.test.ts +0 -4
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -22
- package/src/__tests__/inline-skill-load-permissions.test.ts +5 -16
- package/src/__tests__/intent-routing.test.ts +2 -55
- package/src/__tests__/invite-redemption-service.test.ts +0 -21
- package/src/__tests__/invite-routes-http.test.ts +0 -21
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +0 -17
- package/src/__tests__/journal-context.test.ts +8 -75
- package/src/__tests__/list-messages-attachments.test.ts +0 -22
- package/src/__tests__/llm-context-route-provider.test.ts +0 -21
- package/src/__tests__/llm-request-log-turn-query.test.ts +46 -28
- package/src/__tests__/llm-usage-store.test.ts +0 -21
- package/src/__tests__/log-export-workspace.test.ts +1 -1
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -1
- package/src/__tests__/managed-store.test.ts +1 -1
- package/src/__tests__/mcp-cli.test.ts +7 -10
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -21
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +0 -11
- package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -21
- package/src/__tests__/memory-recall-log-store.test.ts +0 -27
- package/src/__tests__/memory-recall-quality.test.ts +0 -21
- package/src/__tests__/memory-regressions.experimental.test.ts +31 -30
- package/src/__tests__/memory-regressions.test.ts +282 -70
- package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -21
- package/src/__tests__/memory-upsert-concurrency.test.ts +0 -21
- package/src/__tests__/messaging-send-tool.test.ts +201 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +18 -13
- package/src/__tests__/migration-export-http.test.ts +7 -1
- package/src/__tests__/migration-import-commit-http.test.ts +16 -14
- package/src/__tests__/migration-import-preflight-http.test.ts +27 -44
- package/src/__tests__/migration-validate-http.test.ts +1 -28
- package/src/__tests__/native-web-search.test.ts +25 -22
- package/src/__tests__/non-member-access-request.test.ts +0 -22
- package/src/__tests__/notification-guardian-path.test.ts +0 -21
- package/src/__tests__/notification-schedule-dedup.test.ts +1 -25
- package/src/__tests__/oauth-apps-routes.test.ts +103 -2
- package/src/__tests__/oauth-cli.test.ts +52 -0
- package/src/__tests__/oauth-provider-profiles.test.ts +0 -16
- package/src/__tests__/oauth-provider-serializer.test.ts +232 -0
- package/src/__tests__/oauth-providers-routes.test.ts +257 -0
- package/src/__tests__/oauth-store.test.ts +0 -21
- package/src/__tests__/onboarding-template-contract.test.ts +2 -2
- package/src/__tests__/openai-provider.test.ts +261 -0
- package/src/__tests__/pairing-concurrent.test.ts +6 -6
- package/src/__tests__/pairing-routes.test.ts +7 -1
- package/src/__tests__/path-policy.test.ts +1 -1
- package/src/__tests__/platform.test.ts +64 -88
- package/src/__tests__/playbook-execution.test.ts +0 -21
- package/src/__tests__/playbook-tools.test.ts +0 -21
- package/src/__tests__/pricing.test.ts +100 -0
- package/src/__tests__/relay-server.test.ts +1 -25
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -24
- package/src/__tests__/runtime-events-sse-parity.test.ts +2 -24
- package/src/__tests__/runtime-events-sse.test.ts +0 -24
- package/src/__tests__/sandbox-diagnostics.test.ts +2 -1
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +1 -1
- package/src/__tests__/schedule-store.test.ts +0 -21
- package/src/__tests__/schedule-tools.test.ts +0 -21
- package/src/__tests__/scheduler-recurrence.test.ts +0 -21
- package/src/__tests__/scoped-approval-grants.test.ts +0 -21
- package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -21
- package/src/__tests__/secret-allowlist.test.ts +1 -1
- package/src/__tests__/secret-ingress-channel.test.ts +0 -5
- package/src/__tests__/secret-ingress-cli.test.ts +0 -6
- package/src/__tests__/secret-ingress-http.test.ts +0 -5
- package/src/__tests__/secret-ingress.test.ts +0 -5
- package/src/__tests__/send-endpoint-busy.test.ts +0 -24
- package/src/__tests__/sequence-store.test.ts +0 -21
- package/src/__tests__/server-history-render.test.ts +0 -24
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -4
- package/src/__tests__/skill-load-inline-command.test.ts +9 -0
- package/src/__tests__/skill-load-inline-includes.test.ts +9 -0
- package/src/__tests__/skill-load-tool.test.ts +11 -0
- package/src/__tests__/skills-uninstall.test.ts +10 -8
- package/src/__tests__/skills.test.ts +1 -1
- package/src/__tests__/slack-channel-config.test.ts +1 -1
- package/src/__tests__/slack-inbound-verification.test.ts +0 -22
- package/src/__tests__/starter-bundle.test.ts +4 -1
- package/src/__tests__/suggestion-routes.test.ts +2 -0
- package/src/__tests__/system-prompt.test.ts +1 -1
- package/src/__tests__/terminal-tools.test.ts +1 -1
- package/src/__tests__/test-preload.ts +31 -0
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -1
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -1
- package/src/__tests__/tool-executor.test.ts +0 -20
- package/src/__tests__/tool-input-summary.test.ts +124 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +2 -1
- package/src/__tests__/trust-store.test.ts +7 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -1
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +1 -1
- package/src/__tests__/trusted-contact-multichannel.test.ts +1 -1
- package/src/__tests__/trusted-contact-verification.test.ts +1 -1
- package/src/__tests__/turn-boundary-resolution.test.ts +1 -1
- package/src/__tests__/twilio-routes.test.ts +1 -1
- package/src/__tests__/update-bulletin.test.ts +1 -1
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +1 -1
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -0
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +1 -1
- package/src/__tests__/voice-session-bridge.test.ts +1 -1
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +4 -4
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -1
- package/src/__tests__/workspace-migration-down-functions.test.ts +15 -3
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +40 -4
- package/src/agent/loop.ts +6 -9
- package/src/approvals/guardian-decision-primitive.ts +46 -18
- package/src/approvals/guardian-request-resolvers.ts +19 -2
- package/src/calls/active-call-lease.ts +2 -2
- package/src/cli/AGENTS.md +1 -1
- package/src/cli/commands/doctor.ts +9 -9
- package/src/cli/commands/memory.ts +142 -0
- package/src/cli/commands/oauth/__tests__/connect.test.ts +13 -11
- package/src/cli/commands/oauth/__tests__/ping.test.ts +1 -1
- package/src/cli/commands/oauth/connect.ts +13 -12
- package/src/cli/commands/oauth/index.ts +1 -1
- package/src/cli/commands/oauth/providers.ts +47 -62
- package/src/cli/commands/platform/__tests__/connect.test.ts +72 -46
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +54 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +36 -0
- package/src/cli/commands/platform/connect.ts +17 -7
- package/src/cli/commands/platform/disconnect.ts +28 -3
- package/src/cli/commands/platform/index.ts +3 -3
- package/src/cli.ts +1 -299
- package/src/config/assistant-feature-flags.ts +23 -15
- package/src/config/bundled-skills/app-builder/TOOLS.json +16 -0
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +4 -0
- package/src/config/bundled-skills/app-builder/tools/app-delete.ts +5 -1
- package/src/config/bundled-skills/app-builder/tools/app-generate-icon.ts +9 -1
- package/src/config/bundled-skills/app-builder/tools/app-refresh.ts +5 -1
- package/src/config/bundled-skills/contacts/TOOLS.json +8 -0
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +10 -1
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +16 -2
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +1 -0
- package/src/config/bundled-skills/messaging/SKILL.md +7 -7
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +37 -0
- package/src/config/bundled-skills/slack/SKILL.md +18 -0
- package/src/config/env-registry.ts +15 -11
- package/src/config/env.ts +1 -11
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/heartbeat.ts +6 -1
- package/src/config/schemas/inference.ts +14 -3
- package/src/config/schemas/memory-processing.ts +16 -8
- package/src/config/schemas/memory-retrieval.ts +3 -3
- package/src/config/skills.ts +1 -1
- package/src/context/window-manager.ts +174 -51
- package/src/credential-execution/executable-discovery.ts +2 -2
- package/src/daemon/approved-devices-store.ts +2 -2
- package/src/daemon/assistant-attachments.ts +2 -0
- package/src/daemon/config-watcher.ts +4 -50
- package/src/daemon/conversation-agent-loop-handlers.ts +9 -1
- package/src/daemon/conversation-agent-loop.ts +12 -0
- package/src/daemon/conversation-error.ts +3 -5
- package/src/daemon/conversation-history.ts +7 -3
- package/src/daemon/conversation-lifecycle.ts +16 -0
- package/src/daemon/conversation-messaging.ts +1 -0
- package/src/daemon/conversation-notifiers.ts +67 -30
- package/src/daemon/conversation-process.ts +161 -2
- package/src/daemon/conversation-queue-manager.ts +2 -0
- package/src/daemon/conversation-runtime-assembly.ts +33 -11
- package/src/daemon/conversation-slash.ts +14 -3
- package/src/daemon/conversation-tool-setup.ts +2 -0
- package/src/daemon/conversation-usage.ts +32 -4
- package/src/daemon/conversation.ts +33 -1
- package/src/daemon/daemon-control.ts +32 -16
- package/src/daemon/date-context.ts +47 -45
- package/src/daemon/dictation-profile-store.ts +2 -2
- package/src/daemon/handlers/conversations.ts +19 -0
- package/src/daemon/handlers/shared.ts +14 -21
- package/src/daemon/lifecycle.ts +5 -7
- package/src/daemon/message-types/conversations.ts +2 -0
- package/src/daemon/message-types/guardian-actions.ts +3 -17
- package/src/daemon/message-types/integrations.ts +11 -1
- package/src/daemon/message-types/messages.ts +1 -0
- package/src/daemon/pairing-store.ts +2 -79
- package/src/daemon/server.ts +154 -8
- package/src/daemon/watch-handler.ts +65 -21
- package/src/email/guardrails.ts +3 -3
- package/src/heartbeat/heartbeat-service.ts +14 -7
- package/src/hooks/cli.ts +2 -2
- package/src/hooks/config.ts +2 -2
- package/src/hooks/discovery.ts +2 -2
- package/src/hooks/manager.ts +2 -2
- package/src/hooks/runner.ts +5 -2
- package/src/hooks/templates.ts +2 -2
- package/src/memory/admin.ts +181 -2
- package/src/memory/app-git-service.ts +61 -4
- package/src/memory/attachments-store.ts +2 -0
- package/src/memory/canonical-guardian-store.ts +16 -0
- package/src/memory/db-init.ts +8 -0
- package/src/memory/embedding-local.ts +5 -2
- package/src/memory/indexer.ts +44 -26
- package/src/memory/items-extractor.ts +34 -82
- package/src/memory/job-handlers/batch-extraction.ts +741 -0
- package/src/memory/job-handlers/journal-carry-forward.test.ts +383 -0
- package/src/memory/job-handlers/journal-carry-forward.ts +255 -0
- package/src/memory/jobs-store.ts +28 -0
- package/src/memory/jobs-worker.ts +56 -9
- package/src/memory/lifecycle-events-store.ts +4 -2
- package/src/memory/llm-request-log-store.ts +40 -2
- package/src/memory/llm-usage-store.ts +4 -3
- package/src/memory/migrations/199-guardian-request-enrichment-columns.ts +71 -0
- package/src/memory/migrations/200-usage-llm-call-count.ts +20 -0
- package/src/memory/migrations/index.ts +2 -0
- package/src/memory/query-expansion.ts +83 -0
- package/src/memory/retriever.test.ts +119 -0
- package/src/memory/retriever.ts +513 -105
- package/src/memory/schema/guardian.ts +4 -0
- package/src/memory/schema/infrastructure.ts +1 -0
- package/src/memory/search/formatting.test.ts +140 -0
- package/src/memory/search/formatting.ts +143 -198
- package/src/memory/search/mmr.ts +136 -0
- package/src/memory/search/staleness.ts +0 -15
- package/src/memory/search/tier-classifier.ts +10 -21
- package/src/memory/search/types.ts +17 -0
- package/src/messaging/providers/slack/adapter.ts +51 -5
- package/src/notifications/broadcaster.ts +13 -0
- package/src/notifications/copy-composer.ts +8 -0
- package/src/oauth/connect-orchestrator.ts +1 -1
- package/src/oauth/connection-resolver.ts +2 -2
- package/src/oauth/provider-serializer.ts +116 -0
- package/src/permissions/trust-store.ts +24 -7
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +5 -0
- package/src/prompts/journal-context.ts +50 -35
- package/src/prompts/persona-resolver.ts +1 -1
- package/src/prompts/system-prompt.ts +27 -28
- package/src/prompts/templates/BOOTSTRAP.md +14 -1
- package/src/prompts/templates/HEARTBEAT.md +10 -0
- package/src/prompts/templates/NOW.md +19 -25
- package/src/prompts/templates/SOUL.md +13 -1
- package/src/prompts/templates/UPDATES.md +12 -0
- package/src/prompts/update-bulletin.ts +1 -1
- package/src/providers/anthropic/client.ts +89 -18
- package/src/providers/model-catalog.ts +22 -2
- package/src/providers/model-intents.ts +2 -2
- package/src/providers/openai/client.ts +40 -1
- package/src/providers/retry.ts +23 -4
- package/src/providers/types.ts +2 -0
- package/src/runtime/assistant-scope.ts +1 -1
- package/src/runtime/auth/__tests__/credential-service.test.ts +1 -0
- package/src/runtime/auth/route-policy.ts +1 -0
- package/src/runtime/auth/token-service.ts +51 -29
- package/src/runtime/confirmation-request-guardian-bridge.ts +3 -1
- package/src/runtime/guardian-decision-types.ts +16 -10
- package/src/runtime/http-server.ts +3 -14
- package/src/runtime/http-types.ts +1 -0
- package/src/runtime/migrations/vbundle-builder.ts +7 -4
- package/src/runtime/migrations/vbundle-import-analyzer.ts +0 -4
- package/src/runtime/migrations/vbundle-importer.ts +1 -1
- package/src/runtime/routes/conversation-query-routes.ts +40 -8
- package/src/runtime/routes/conversation-routes.ts +125 -3
- package/src/runtime/routes/guardian-action-routes.ts +9 -3
- package/src/runtime/routes/identity-routes.ts +25 -4
- package/src/runtime/routes/llm-context-normalization.ts +1 -0
- package/src/runtime/routes/log-export-routes.ts +34 -12
- package/src/runtime/routes/migration-routes.ts +6 -10
- package/src/runtime/routes/oauth-apps.ts +2 -9
- package/src/runtime/routes/oauth-providers.ts +60 -0
- package/src/runtime/routes/pairing-routes.ts +0 -8
- package/src/runtime/routes/settings-routes.ts +0 -1
- package/src/runtime/routes/telemetry-routes.ts +16 -4
- package/src/security/encrypted-store.ts +2 -2
- package/src/security/secret-allowlist.ts +3 -3
- package/src/signals/emit-event.ts +42 -0
- package/src/signals/user-message.ts +37 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +83 -19
- package/src/telemetry/usage-telemetry-reporter.ts +23 -17
- package/src/tools/browser/runtime-check.ts +2 -2
- package/src/tools/credentials/vault.ts +2 -249
- package/src/tools/memory/definitions.ts +1 -1
- package/src/tools/memory/handlers.test.ts +50 -8
- package/src/tools/memory/handlers.ts +3 -1
- package/src/tools/side-effects.ts +1 -6
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +11 -14
- package/src/tools/tool-approval-handler.ts +20 -1
- package/src/tools/tool-input-summary.ts +66 -0
- package/src/tools/types.ts +4 -0
- package/src/usage/types.ts +4 -0
- package/src/util/device-id.ts +10 -10
- package/src/util/platform.ts +71 -33
- package/src/util/pricing.ts +19 -6
- package/src/util/strip-comment-lines.ts +28 -0
- package/src/workspace/git-service.ts +8 -18
- package/src/workspace/migrations/003-seed-device-id.ts +6 -4
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +7 -1
- package/src/workspace/migrations/017-seed-persona-dirs.ts +2 -4
- package/src/workspace/migrations/021-move-signals-to-workspace.ts +84 -0
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +94 -0
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +86 -0
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +126 -0
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +3 -6
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/signals/confirm.ts +0 -82
- package/src/signals/trust-rule.ts +0 -174
package/.env.example
CHANGED
|
@@ -21,12 +21,7 @@ VELLUM_PLATFORM_URL=https://dev-platform.vellum.ai
|
|
|
21
21
|
|
|
22
22
|
# --- Sentry (crash reporting) ---
|
|
23
23
|
# Omit to disable Sentry.
|
|
24
|
-
SENTRY_DSN_ASSISTANT=
|
|
25
|
-
|
|
26
|
-
# --- Telemetry ---
|
|
27
|
-
# Omit to disable telemetry reporting.
|
|
28
|
-
TELEMETRY_PLATFORM_URL=https://platform.vellum.ai
|
|
29
|
-
TELEMETRY_APP_TOKEN=e01cf85768cc3617e986f0a7f1966b72e25316526c5db54c8b94a9c3c5c9eaed
|
|
24
|
+
SENTRY_DSN_ASSISTANT=
|
|
30
25
|
|
|
31
26
|
# --- Network proxy ---
|
|
32
27
|
# Comma-separated host patterns allowed through the proxy.
|
package/AGENTS.md
CHANGED
|
@@ -11,3 +11,7 @@ When you introduce a new env var that the assistant process needs to read at run
|
|
|
11
11
|
`safe-env.ts` maintains the allowlist of env vars that are forwarded to agent-spawned child processes (bash tool, skill sandbox, etc.). Anything not on the list is stripped to prevent credential leakage. If your new var is needed by commands the agent runs, it must be added.
|
|
12
12
|
|
|
13
13
|
**Default to including it.** If the var doesn't contain secrets (e.g. a URL, a feature flag, a path, a mode string), add it. Only omit it if it carries credential material (tokens, passwords, private keys) — those must stay isolated to CES.
|
|
14
|
+
|
|
15
|
+
## Code comments
|
|
16
|
+
|
|
17
|
+
When writing or updating comments, **do not reference code that has been removed.** Comments should describe the current state of the codebase, not narrate its history. Avoid phrases like "no longer does X", "previously used Y", or "was removed in PR Z" — future readers should not need to understand past implementations to understand the current code.
|
package/ARCHITECTURE.md
CHANGED
package/bunfig.toml
CHANGED
|
@@ -260,10 +260,10 @@ The key distinction: normal compaction is a cost-optimized background process th
|
|
|
260
260
|
| Config key | Default | Purpose |
|
|
261
261
|
| ----------------------------------------------------- | ------------------------: | -------------------------------------------------------------------- |
|
|
262
262
|
| `memory.retrieval.dynamicBudget.enabled` | `true` | Toggle per-turn recall budget calculation from live prompt headroom. |
|
|
263
|
-
| `memory.retrieval.dynamicBudget.minInjectTokens` | `
|
|
264
|
-
| `memory.retrieval.dynamicBudget.maxInjectTokens` | `
|
|
263
|
+
| `memory.retrieval.dynamicBudget.minInjectTokens` | `2400` | Lower clamp for computed recall injection budget. |
|
|
264
|
+
| `memory.retrieval.dynamicBudget.maxInjectTokens` | `16000` | Upper clamp for computed recall injection budget. |
|
|
265
265
|
| `memory.retrieval.dynamicBudget.targetHeadroomTokens` | `10000` | Reserved headroom to keep free for response generation/tool traces. |
|
|
266
|
-
| `memory.retrieval.maxInjectTokens` | `
|
|
266
|
+
| `memory.retrieval.maxInjectTokens` | `16000` | Static fallback when dynamic budget is disabled. |
|
|
267
267
|
| `memory.retrieval.scopePolicy` | `'allow_global_fallback'` | Scope filtering strategy: `'strict'` or `'allow_global_fallback'`. |
|
|
268
268
|
|
|
269
269
|
### Memory Recall Debugging Playbook
|
package/openapi.yaml
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
openapi: 3.0.0
|
|
4
4
|
info:
|
|
5
5
|
title: Vellum Assistant API
|
|
6
|
-
version: 0.5.
|
|
6
|
+
version: 0.5.13
|
|
7
7
|
description: Auto-generated OpenAPI specification for the Vellum Assistant runtime HTTP server.
|
|
8
8
|
servers:
|
|
9
9
|
- url: http://127.0.0.1:7821
|
|
@@ -3144,7 +3144,7 @@ paths:
|
|
|
3144
3144
|
post:
|
|
3145
3145
|
operationId: export_post
|
|
3146
3146
|
summary: Export logs and audit data
|
|
3147
|
-
description: Export audit records,
|
|
3147
|
+
description: Export audit records, assistant logs, workspace contents, and config as a tar.gz archive.
|
|
3148
3148
|
tags:
|
|
3149
3149
|
- export
|
|
3150
3150
|
responses:
|
|
@@ -3158,24 +3158,19 @@ paths:
|
|
|
3158
3158
|
type: object
|
|
3159
3159
|
properties:
|
|
3160
3160
|
auditLimit:
|
|
3161
|
+
description: Max audit records (default 1000)
|
|
3161
3162
|
type: integer
|
|
3162
3163
|
minimum: -9007199254740991
|
|
3163
3164
|
maximum: 9007199254740991
|
|
3164
|
-
description: Max audit records (default 1000)
|
|
3165
3165
|
conversationId:
|
|
3166
|
-
type: string
|
|
3167
3166
|
description: Scope to a single conversation
|
|
3167
|
+
type: string
|
|
3168
3168
|
startTime:
|
|
3169
|
-
type: number
|
|
3170
3169
|
description: Lower bound epoch ms
|
|
3171
|
-
endTime:
|
|
3172
3170
|
type: number
|
|
3171
|
+
endTime:
|
|
3173
3172
|
description: Upper bound epoch ms
|
|
3174
|
-
|
|
3175
|
-
- auditLimit
|
|
3176
|
-
- conversationId
|
|
3177
|
-
- startTime
|
|
3178
|
-
- endTime
|
|
3173
|
+
type: number
|
|
3179
3174
|
additionalProperties: false
|
|
3180
3175
|
/v1/guardian-actions/decision:
|
|
3181
3176
|
post:
|
|
@@ -3316,6 +3311,52 @@ paths:
|
|
|
3316
3311
|
- cpu
|
|
3317
3312
|
- migrations
|
|
3318
3313
|
additionalProperties: false
|
|
3314
|
+
/v1/healthz:
|
|
3315
|
+
get:
|
|
3316
|
+
operationId: healthz_get
|
|
3317
|
+
summary: Detailed health check (alias)
|
|
3318
|
+
description: Alias for /v1/health. Returns runtime health including version, disk, memory, CPU, and migration status.
|
|
3319
|
+
tags:
|
|
3320
|
+
- system
|
|
3321
|
+
responses:
|
|
3322
|
+
"200":
|
|
3323
|
+
description: Successful response
|
|
3324
|
+
content:
|
|
3325
|
+
application/json:
|
|
3326
|
+
schema:
|
|
3327
|
+
type: object
|
|
3328
|
+
properties:
|
|
3329
|
+
status:
|
|
3330
|
+
type: string
|
|
3331
|
+
timestamp:
|
|
3332
|
+
type: string
|
|
3333
|
+
version:
|
|
3334
|
+
type: string
|
|
3335
|
+
disk:
|
|
3336
|
+
type: object
|
|
3337
|
+
properties: {}
|
|
3338
|
+
additionalProperties: {}
|
|
3339
|
+
memory:
|
|
3340
|
+
type: object
|
|
3341
|
+
properties: {}
|
|
3342
|
+
additionalProperties: {}
|
|
3343
|
+
cpu:
|
|
3344
|
+
type: object
|
|
3345
|
+
properties: {}
|
|
3346
|
+
additionalProperties: {}
|
|
3347
|
+
migrations:
|
|
3348
|
+
type: object
|
|
3349
|
+
properties: {}
|
|
3350
|
+
additionalProperties: {}
|
|
3351
|
+
required:
|
|
3352
|
+
- status
|
|
3353
|
+
- timestamp
|
|
3354
|
+
- version
|
|
3355
|
+
- disk
|
|
3356
|
+
- memory
|
|
3357
|
+
- cpu
|
|
3358
|
+
- migrations
|
|
3359
|
+
additionalProperties: false
|
|
3319
3360
|
/v1/heartbeat/checklist:
|
|
3320
3361
|
get:
|
|
3321
3362
|
operationId: heartbeat_checklist_get
|
|
@@ -3968,6 +4009,38 @@ paths:
|
|
|
3968
4009
|
responses:
|
|
3969
4010
|
"200":
|
|
3970
4011
|
description: Successful response
|
|
4012
|
+
/v1/logs/export:
|
|
4013
|
+
post:
|
|
4014
|
+
operationId: logs_export_post
|
|
4015
|
+
summary: Export logs and audit data (alias)
|
|
4016
|
+
description: Alias for /v1/export. Export audit records, assistant logs, workspace contents, and config as a tar.gz archive.
|
|
4017
|
+
tags:
|
|
4018
|
+
- export
|
|
4019
|
+
responses:
|
|
4020
|
+
"200":
|
|
4021
|
+
description: Successful response
|
|
4022
|
+
requestBody:
|
|
4023
|
+
required: true
|
|
4024
|
+
content:
|
|
4025
|
+
application/json:
|
|
4026
|
+
schema:
|
|
4027
|
+
type: object
|
|
4028
|
+
properties:
|
|
4029
|
+
auditLimit:
|
|
4030
|
+
description: Max audit records (default 1000)
|
|
4031
|
+
type: integer
|
|
4032
|
+
minimum: -9007199254740991
|
|
4033
|
+
maximum: 9007199254740991
|
|
4034
|
+
conversationId:
|
|
4035
|
+
description: Scope to a single conversation
|
|
4036
|
+
type: string
|
|
4037
|
+
startTime:
|
|
4038
|
+
description: Lower bound epoch ms
|
|
4039
|
+
type: number
|
|
4040
|
+
endTime:
|
|
4041
|
+
description: Upper bound epoch ms
|
|
4042
|
+
type: number
|
|
4043
|
+
additionalProperties: false
|
|
3971
4044
|
/v1/memory-items:
|
|
3972
4045
|
get:
|
|
3973
4046
|
operationId: memoryitems_get
|
|
@@ -4644,6 +4717,28 @@ paths:
|
|
|
4644
4717
|
required: true
|
|
4645
4718
|
schema:
|
|
4646
4719
|
type: string
|
|
4720
|
+
/v1/oauth/providers:
|
|
4721
|
+
get:
|
|
4722
|
+
operationId: oauth_providers_get
|
|
4723
|
+
tags:
|
|
4724
|
+
- oauth-providers
|
|
4725
|
+
responses:
|
|
4726
|
+
"200":
|
|
4727
|
+
description: Successful response
|
|
4728
|
+
/v1/oauth/providers/{providerKey}:
|
|
4729
|
+
get:
|
|
4730
|
+
operationId: oauth_providers_by_providerKey_get
|
|
4731
|
+
tags:
|
|
4732
|
+
- oauth-providers
|
|
4733
|
+
responses:
|
|
4734
|
+
"200":
|
|
4735
|
+
description: Successful response
|
|
4736
|
+
parameters:
|
|
4737
|
+
- name: providerKey
|
|
4738
|
+
in: path
|
|
4739
|
+
required: true
|
|
4740
|
+
schema:
|
|
4741
|
+
type: string
|
|
4647
4742
|
/v1/oauth/start:
|
|
4648
4743
|
post:
|
|
4649
4744
|
operationId: oauth_start_post
|
|
@@ -6281,17 +6376,27 @@ paths:
|
|
|
6281
6376
|
content:
|
|
6282
6377
|
application/json:
|
|
6283
6378
|
schema:
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6379
|
+
anyOf:
|
|
6380
|
+
- type: object
|
|
6381
|
+
properties:
|
|
6382
|
+
id:
|
|
6383
|
+
type: string
|
|
6384
|
+
description: Event ID
|
|
6385
|
+
event_name:
|
|
6386
|
+
type: string
|
|
6387
|
+
required:
|
|
6388
|
+
- id
|
|
6389
|
+
- event_name
|
|
6390
|
+
additionalProperties: false
|
|
6391
|
+
- type: object
|
|
6392
|
+
properties:
|
|
6393
|
+
skipped:
|
|
6394
|
+
type: boolean
|
|
6395
|
+
const: true
|
|
6396
|
+
description: Event skipped due to usage data collection being disabled
|
|
6397
|
+
required:
|
|
6398
|
+
- skipped
|
|
6399
|
+
additionalProperties: false
|
|
6295
6400
|
requestBody:
|
|
6296
6401
|
required: true
|
|
6297
6402
|
content:
|
package/package.json
CHANGED
|
@@ -8,28 +8,7 @@
|
|
|
8
8
|
* - Stale: handles already-resolved requests gracefully.
|
|
9
9
|
* - Idempotent: approving same request twice does not create duplicate sessions.
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
12
|
-
import { tmpdir } from "node:os";
|
|
13
|
-
import { join } from "node:path";
|
|
14
|
-
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
15
|
-
|
|
16
|
-
// ---------------------------------------------------------------------------
|
|
17
|
-
// Test isolation: in-memory SQLite via temp directory
|
|
18
|
-
// ---------------------------------------------------------------------------
|
|
19
|
-
|
|
20
|
-
const testDir = mkdtempSync(join(tmpdir(), "access-request-decision-test-"));
|
|
21
|
-
|
|
22
|
-
mock.module("../util/platform.js", () => ({
|
|
23
|
-
getRootDir: () => testDir,
|
|
24
|
-
getDataDir: () => testDir,
|
|
25
|
-
isMacOS: () => process.platform === "darwin",
|
|
26
|
-
isLinux: () => process.platform === "linux",
|
|
27
|
-
isWindows: () => process.platform === "win32",
|
|
28
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
29
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
30
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
31
|
-
ensureDataDir: () => {},
|
|
32
|
-
}));
|
|
11
|
+
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
33
12
|
|
|
34
13
|
mock.module("../util/logger.js", () => ({
|
|
35
14
|
getLogger: () =>
|
|
@@ -56,7 +35,7 @@ mock.module("../runtime/gateway-client.js", () => ({
|
|
|
56
35
|
},
|
|
57
36
|
}));
|
|
58
37
|
|
|
59
|
-
import { getDb, initializeDb
|
|
38
|
+
import { getDb, initializeDb } from "../memory/db.js";
|
|
60
39
|
import {
|
|
61
40
|
createApprovalRequest,
|
|
62
41
|
getApprovalRequestById,
|
|
@@ -72,15 +51,6 @@ import {
|
|
|
72
51
|
|
|
73
52
|
initializeDb();
|
|
74
53
|
|
|
75
|
-
afterAll(() => {
|
|
76
|
-
resetDb();
|
|
77
|
-
try {
|
|
78
|
-
rmSync(testDir, { recursive: true });
|
|
79
|
-
} catch {
|
|
80
|
-
/* best effort */
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
|
|
84
54
|
// ---------------------------------------------------------------------------
|
|
85
55
|
// Helpers
|
|
86
56
|
// ---------------------------------------------------------------------------
|
|
@@ -6,25 +6,7 @@
|
|
|
6
6
|
* that middleware is replaced by the JWT auth middleware in
|
|
7
7
|
* runtime/auth/middleware.ts (tested in auth/middleware.test.ts).
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
10
|
-
import { tmpdir } from "node:os";
|
|
11
|
-
import { join } from "node:path";
|
|
12
|
-
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
13
|
-
|
|
14
|
-
const testDir = realpathSync(mkdtempSync(join(tmpdir(), "actor-token-test-")));
|
|
15
|
-
|
|
16
|
-
mock.module("../util/platform.js", () => ({
|
|
17
|
-
getRootDir: () => testDir,
|
|
18
|
-
getDataDir: () => testDir,
|
|
19
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
20
|
-
normalizeAssistantId: (id: string) => (id === "self" ? "self" : id),
|
|
21
|
-
isMacOS: () => process.platform === "darwin",
|
|
22
|
-
isLinux: () => process.platform === "linux",
|
|
23
|
-
isWindows: () => process.platform === "win32",
|
|
24
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
25
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
26
|
-
ensureDataDir: () => {},
|
|
27
|
-
}));
|
|
9
|
+
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
28
10
|
|
|
29
11
|
mock.module("../util/logger.js", () => ({
|
|
30
12
|
getLogger: () =>
|
|
@@ -40,7 +22,6 @@ mock.module("../config/env.js", () => ({
|
|
|
40
22
|
getRuntimeGatewayOriginSecret: () => undefined,
|
|
41
23
|
isHttpAuthDisabledWithoutSafetyGate: () => false,
|
|
42
24
|
checkUnrecognizedEnvVars: () => {},
|
|
43
|
-
getBaseDataDir: () => testDir,
|
|
44
25
|
}));
|
|
45
26
|
|
|
46
27
|
import { findGuardianForChannel } from "../contacts/contact-store.js";
|
|
@@ -110,12 +91,6 @@ beforeEach(() => {
|
|
|
110
91
|
db.run("DELETE FROM contacts");
|
|
111
92
|
});
|
|
112
93
|
|
|
113
|
-
afterAll(() => {
|
|
114
|
-
try {
|
|
115
|
-
rmSync(testDir, { recursive: true, force: true });
|
|
116
|
-
} catch {}
|
|
117
|
-
});
|
|
118
|
-
|
|
119
94
|
// ---------------------------------------------------------------------------
|
|
120
95
|
// Hash-only storage
|
|
121
96
|
// ---------------------------------------------------------------------------
|
|
@@ -462,7 +437,6 @@ describe("pairing credential flow", () => {
|
|
|
462
437
|
const ctx = {
|
|
463
438
|
pairingStore: store,
|
|
464
439
|
bearerToken,
|
|
465
|
-
featureFlagToken: undefined,
|
|
466
440
|
pairingBroadcast: () => {},
|
|
467
441
|
};
|
|
468
442
|
|
|
@@ -520,7 +494,6 @@ describe("pairing credential flow", () => {
|
|
|
520
494
|
const ctx = {
|
|
521
495
|
pairingStore: store,
|
|
522
496
|
bearerToken,
|
|
523
|
-
featureFlagToken: undefined,
|
|
524
497
|
pairingBroadcast: () => {},
|
|
525
498
|
};
|
|
526
499
|
|
|
@@ -577,7 +550,6 @@ describe("pairing credential flow", () => {
|
|
|
577
550
|
const ctx = {
|
|
578
551
|
pairingStore: store,
|
|
579
552
|
bearerToken,
|
|
580
|
-
featureFlagToken: undefined,
|
|
581
553
|
pairingBroadcast: () => {},
|
|
582
554
|
};
|
|
583
555
|
|
|
@@ -637,7 +609,6 @@ describe("pairing credential flow", () => {
|
|
|
637
609
|
const ctx = {
|
|
638
610
|
pairingStore: store,
|
|
639
611
|
bearerToken,
|
|
640
|
-
featureFlagToken: undefined,
|
|
641
612
|
pairingBroadcast: () => {},
|
|
642
613
|
};
|
|
643
614
|
|
|
@@ -727,4 +698,3 @@ describe("bootstrap private-network guard", () => {
|
|
|
727
698
|
expect(res.status).toBe(200);
|
|
728
699
|
});
|
|
729
700
|
});
|
|
730
|
-
|
|
@@ -37,25 +37,37 @@ mock.module("@anthropic-ai/sdk", () => ({
|
|
|
37
37
|
constructor(args: Record<string, unknown>) {
|
|
38
38
|
lastConstructorArgs = { ...args };
|
|
39
39
|
}
|
|
40
|
+
#streamImpl = (
|
|
41
|
+
params: Record<string, unknown>,
|
|
42
|
+
options?: Record<string, unknown>,
|
|
43
|
+
) => {
|
|
44
|
+
lastStreamParams = JSON.parse(JSON.stringify(params));
|
|
45
|
+
_lastStreamOptions = options ?? null;
|
|
46
|
+
const handlers: Record<string, ((...args: unknown[]) => void)[]> = {};
|
|
47
|
+
return {
|
|
48
|
+
on(event: string, cb: (...args: unknown[]) => void) {
|
|
49
|
+
(handlers[event] ??= []).push(cb);
|
|
50
|
+
return this;
|
|
51
|
+
},
|
|
52
|
+
async finalMessage() {
|
|
53
|
+
// Fire text events
|
|
54
|
+
for (const cb of handlers["text"] ?? []) cb("Hello");
|
|
55
|
+
return fakeResponse;
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
};
|
|
40
59
|
messages = {
|
|
41
60
|
stream: (
|
|
42
61
|
params: Record<string, unknown>,
|
|
43
62
|
options?: Record<string, unknown>,
|
|
44
|
-
) =>
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
},
|
|
53
|
-
async finalMessage() {
|
|
54
|
-
// Fire text events
|
|
55
|
-
for (const cb of handlers["text"] ?? []) cb("Hello");
|
|
56
|
-
return fakeResponse;
|
|
57
|
-
},
|
|
58
|
-
};
|
|
63
|
+
) => this.#streamImpl(params, options),
|
|
64
|
+
};
|
|
65
|
+
beta = {
|
|
66
|
+
messages: {
|
|
67
|
+
stream: (
|
|
68
|
+
params: Record<string, unknown>,
|
|
69
|
+
options?: Record<string, unknown>,
|
|
70
|
+
) => this.#streamImpl(params, options),
|
|
59
71
|
},
|
|
60
72
|
};
|
|
61
73
|
},
|
|
@@ -138,16 +150,16 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
138
150
|
// -----------------------------------------------------------------------
|
|
139
151
|
// System prompt cache control
|
|
140
152
|
// -----------------------------------------------------------------------
|
|
141
|
-
test("system prompt has cache_control ephemeral", async () => {
|
|
153
|
+
test("system prompt has cache_control ephemeral with 1h TTL", async () => {
|
|
142
154
|
await provider.sendMessage([userMsg("Hi")], undefined, "You are helpful.");
|
|
143
155
|
|
|
144
156
|
const system = lastStreamParams!.system as Array<{
|
|
145
157
|
type: string;
|
|
146
158
|
text: string;
|
|
147
|
-
cache_control?: { type: string };
|
|
159
|
+
cache_control?: { type: string; ttl?: string };
|
|
148
160
|
}>;
|
|
149
161
|
expect(system).toHaveLength(1);
|
|
150
|
-
expect(system[0].cache_control).toEqual({ type: "ephemeral" });
|
|
162
|
+
expect(system[0].cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
|
|
151
163
|
});
|
|
152
164
|
|
|
153
165
|
test("no system param when system prompt is omitted", async () => {
|
|
@@ -166,13 +178,13 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
166
178
|
const system = lastStreamParams!.system as Array<{
|
|
167
179
|
type: string;
|
|
168
180
|
text: string;
|
|
169
|
-
cache_control?: { type: string };
|
|
181
|
+
cache_control?: { type: string; ttl?: string };
|
|
170
182
|
}>;
|
|
171
183
|
expect(system).toHaveLength(2);
|
|
172
184
|
expect(system[0].text).toBe(staticBlock);
|
|
173
|
-
expect(system[0].cache_control).toEqual({ type: "ephemeral" });
|
|
185
|
+
expect(system[0].cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
|
|
174
186
|
expect(system[1].text).toBe(dynamicBlock);
|
|
175
|
-
expect(system[1].cache_control).toEqual({ type: "ephemeral" });
|
|
187
|
+
expect(system[1].cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
|
|
176
188
|
});
|
|
177
189
|
|
|
178
190
|
// -----------------------------------------------------------------------
|
|
@@ -183,7 +195,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
183
195
|
|
|
184
196
|
const tools = lastStreamParams!.tools as Array<{
|
|
185
197
|
name: string;
|
|
186
|
-
cache_control?: { type: string };
|
|
198
|
+
cache_control?: { type: string; ttl?: string };
|
|
187
199
|
}>;
|
|
188
200
|
expect(tools).toHaveLength(3);
|
|
189
201
|
|
|
@@ -192,7 +204,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
192
204
|
expect(tools[1].cache_control).toBeUndefined();
|
|
193
205
|
|
|
194
206
|
// Last tool: cache_control ephemeral
|
|
195
|
-
expect(tools[2].cache_control).toEqual({ type: "ephemeral" });
|
|
207
|
+
expect(tools[2].cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
|
|
196
208
|
});
|
|
197
209
|
|
|
198
210
|
test("single tool gets cache_control", async () => {
|
|
@@ -200,10 +212,10 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
200
212
|
|
|
201
213
|
const tools = lastStreamParams!.tools as Array<{
|
|
202
214
|
name: string;
|
|
203
|
-
cache_control?: { type: string };
|
|
215
|
+
cache_control?: { type: string; ttl?: string };
|
|
204
216
|
}>;
|
|
205
217
|
expect(tools).toHaveLength(1);
|
|
206
|
-
expect(tools[0].cache_control).toEqual({ type: "ephemeral" });
|
|
218
|
+
expect(tools[0].cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
|
|
207
219
|
});
|
|
208
220
|
|
|
209
221
|
test("no tools param when tools are omitted", async () => {
|
|
@@ -223,7 +235,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
223
235
|
content: Array<{
|
|
224
236
|
type: string;
|
|
225
237
|
text: string;
|
|
226
|
-
cache_control?: { type: string };
|
|
238
|
+
cache_control?: { type: string; ttl?: string };
|
|
227
239
|
}>;
|
|
228
240
|
}>;
|
|
229
241
|
const lastUser = messages[messages.length - 1];
|
|
@@ -248,7 +260,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
248
260
|
content: Array<{
|
|
249
261
|
type: string;
|
|
250
262
|
text: string;
|
|
251
|
-
cache_control?: { type: string };
|
|
263
|
+
cache_control?: { type: string; ttl?: string };
|
|
252
264
|
}>;
|
|
253
265
|
}>;
|
|
254
266
|
|
|
@@ -264,7 +276,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
264
276
|
// Second user turn (second-to-last): cache_control ephemeral
|
|
265
277
|
const secondUserLastBlock =
|
|
266
278
|
userMessages[1].content[userMessages[1].content.length - 1];
|
|
267
|
-
expect(secondUserLastBlock.cache_control).toEqual({ type: "ephemeral" });
|
|
279
|
+
expect(secondUserLastBlock.cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
|
|
268
280
|
|
|
269
281
|
// Third user turn (last): no cache_control
|
|
270
282
|
const thirdUserLastBlock =
|
|
@@ -280,7 +292,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
280
292
|
content: Array<{
|
|
281
293
|
type: string;
|
|
282
294
|
text: string;
|
|
283
|
-
cache_control?: { type: string };
|
|
295
|
+
cache_control?: { type: string; ttl?: string };
|
|
284
296
|
}>;
|
|
285
297
|
}>;
|
|
286
298
|
const userMessages = sent.filter((m) => m.role === "user");
|
|
@@ -303,12 +315,12 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
303
315
|
|
|
304
316
|
const sent = lastStreamParams!.messages as Array<{
|
|
305
317
|
role: string;
|
|
306
|
-
content: Array<{ type: string; cache_control?: { type: string } }>;
|
|
318
|
+
content: Array<{ type: string; cache_control?: { type: string; ttl?: string } }>;
|
|
307
319
|
}>;
|
|
308
320
|
const userMsgs = sent.filter((m) => m.role === "user");
|
|
309
321
|
// First user msg (second-to-last) should get cache
|
|
310
322
|
const firstLast = userMsgs[0].content[userMsgs[0].content.length - 1];
|
|
311
|
-
expect(firstLast.cache_control).toEqual({ type: "ephemeral" });
|
|
323
|
+
expect(firstLast.cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
|
|
312
324
|
// tool_result msg (last) should NOT get cache
|
|
313
325
|
const secondLast = userMsgs[1].content[userMsgs[1].content.length - 1];
|
|
314
326
|
expect(secondLast.cache_control).toBeUndefined();
|
|
@@ -330,7 +342,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
330
342
|
content: Array<{
|
|
331
343
|
type: string;
|
|
332
344
|
text: string;
|
|
333
|
-
cache_control?: { type: string };
|
|
345
|
+
cache_control?: { type: string; ttl?: string };
|
|
334
346
|
}>;
|
|
335
347
|
}>;
|
|
336
348
|
const assistantMsgs = sent.filter((m) => m.role === "assistant");
|
|
@@ -361,7 +373,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
361
373
|
content: Array<{
|
|
362
374
|
type: string;
|
|
363
375
|
text: string;
|
|
364
|
-
cache_control?: { type: string };
|
|
376
|
+
cache_control?: { type: string; ttl?: string };
|
|
365
377
|
}>;
|
|
366
378
|
}>;
|
|
367
379
|
const user = sent[0];
|
|
@@ -402,7 +414,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
402
414
|
content: Array<{
|
|
403
415
|
type: string;
|
|
404
416
|
text: string;
|
|
405
|
-
cache_control?: { type: string };
|
|
417
|
+
cache_control?: { type: string; ttl?: string };
|
|
406
418
|
}>;
|
|
407
419
|
}>;
|
|
408
420
|
const user = sent[0];
|
|
@@ -436,7 +448,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
436
448
|
content: Array<{
|
|
437
449
|
type: string;
|
|
438
450
|
text: string;
|
|
439
|
-
cache_control?: { type: string };
|
|
451
|
+
cache_control?: { type: string; ttl?: string };
|
|
440
452
|
}>;
|
|
441
453
|
}>;
|
|
442
454
|
const user = sent[0];
|
|
@@ -1309,7 +1321,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
1309
1321
|
content: Array<{
|
|
1310
1322
|
type: string;
|
|
1311
1323
|
text: string;
|
|
1312
|
-
cache_control?: { type: string };
|
|
1324
|
+
cache_control?: { type: string; ttl?: string };
|
|
1313
1325
|
}>;
|
|
1314
1326
|
}>;
|
|
1315
1327
|
const userMsgs = sent.filter((m) => m.role === "user");
|
|
@@ -1321,7 +1333,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
|
|
|
1321
1333
|
|
|
1322
1334
|
// Turn 2 (second-to-last): cache on last block only
|
|
1323
1335
|
expect(userMsgs[1].content[0].cache_control).toBeUndefined();
|
|
1324
|
-
expect(userMsgs[1].content[1].cache_control).toEqual({ type: "ephemeral" });
|
|
1336
|
+
expect(userMsgs[1].content[1].cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
|
|
1325
1337
|
|
|
1326
1338
|
// Turn 3 (last): no cache
|
|
1327
1339
|
expect(userMsgs[2].content[0].cache_control).toBeUndefined();
|
|
@@ -1548,16 +1560,17 @@ describe("AnthropicProvider — Managed Proxy Fallback", () => {
|
|
|
1548
1560
|
|
|
1549
1561
|
// System prompt cache control
|
|
1550
1562
|
const system = lastStreamParams!.system as Array<{
|
|
1551
|
-
cache_control?: { type: string };
|
|
1563
|
+
cache_control?: { type: string; ttl?: string };
|
|
1552
1564
|
}>;
|
|
1553
|
-
expect(system[0].cache_control).toEqual({ type: "ephemeral" });
|
|
1565
|
+
expect(system[0].cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
|
|
1554
1566
|
|
|
1555
1567
|
// Last tool cache control
|
|
1556
1568
|
const tools = lastStreamParams!.tools as Array<{
|
|
1557
|
-
cache_control?: { type: string };
|
|
1569
|
+
cache_control?: { type: string; ttl?: string };
|
|
1558
1570
|
}>;
|
|
1559
1571
|
expect(tools[tools.length - 1].cache_control).toEqual({
|
|
1560
1572
|
type: "ephemeral",
|
|
1573
|
+
ttl: "1h",
|
|
1561
1574
|
});
|
|
1562
1575
|
});
|
|
1563
1576
|
});
|