@vellumai/assistant 0.5.13 → 0.5.14
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
|
@@ -24,9 +24,9 @@ describe("buildTemporalContext", () => {
|
|
|
24
24
|
expect(result).toEndWith("</temporal_context>");
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
test("includes today date and
|
|
27
|
+
test("includes today date, weekday, time and offset on one line", () => {
|
|
28
28
|
const result = buildTemporalContext({ nowMs: WED_FEB_18, timeZone: "UTC" });
|
|
29
|
-
expect(result).toContain("Today: 2026-02-18 (
|
|
29
|
+
expect(result).toContain("Today: 2026-02-18 (Wed) 12:00 +00:00");
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
test("includes timezone", () => {
|
|
@@ -34,22 +34,16 @@ describe("buildTemporalContext", () => {
|
|
|
34
34
|
nowMs: WED_FEB_18,
|
|
35
35
|
timeZone: "America/New_York",
|
|
36
36
|
});
|
|
37
|
-
expect(result).toContain("
|
|
37
|
+
expect(result).toContain("TZ: America/New_York");
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
test("
|
|
40
|
+
test("does not include UTC time, timezone source, or seconds", () => {
|
|
41
41
|
const result = buildTemporalContext({ nowMs: WED_FEB_18, timeZone: "UTC" });
|
|
42
|
-
expect(result).toContain("Current
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
expect(result).toContain("Current UTC time: 2026-02-18T12:00:00.000Z");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test("includes timezone source", () => {
|
|
51
|
-
const result = buildTemporalContext({ nowMs: WED_FEB_18, timeZone: "UTC" });
|
|
52
|
-
expect(result).toContain("Timezone source:");
|
|
42
|
+
expect(result).not.toContain("Current UTC time");
|
|
43
|
+
expect(result).not.toContain("Current local time");
|
|
44
|
+
expect(result).not.toContain("Timezone source:");
|
|
45
|
+
// No seconds in the time
|
|
46
|
+
expect(result).not.toContain("12:00:00");
|
|
53
47
|
});
|
|
54
48
|
|
|
55
49
|
test("does not include week definitions, next weekend, next work week, or horizon dates", () => {
|
|
@@ -60,25 +54,25 @@ describe("buildTemporalContext", () => {
|
|
|
60
54
|
expect(result).not.toContain("Upcoming dates");
|
|
61
55
|
});
|
|
62
56
|
|
|
63
|
-
test("uses user timezone when provided
|
|
57
|
+
test("uses user timezone when provided", () => {
|
|
64
58
|
const result = buildTemporalContext({
|
|
65
59
|
nowMs: WED_FEB_18,
|
|
66
60
|
hostTimeZone: "UTC",
|
|
67
61
|
userTimeZone: "America/New_York",
|
|
68
62
|
});
|
|
69
|
-
expect(result).toContain("
|
|
70
|
-
expect(result).toContain("
|
|
71
|
-
expect(result).toContain("
|
|
63
|
+
expect(result).toContain("TZ: America/New_York");
|
|
64
|
+
expect(result).toContain("Today: 2026-02-18 (Wed) 07:00 -05:00");
|
|
65
|
+
expect(result).not.toContain("(host fallback)");
|
|
72
66
|
});
|
|
73
67
|
|
|
74
|
-
test("shows user
|
|
68
|
+
test("shows user TZ only when different from primary timezone", () => {
|
|
75
69
|
// When user timezone equals the primary timezone, omit it
|
|
76
70
|
const sameResult = buildTemporalContext({
|
|
77
71
|
nowMs: WED_FEB_18,
|
|
78
72
|
hostTimeZone: "UTC",
|
|
79
73
|
configuredUserTimeZone: "UTC",
|
|
80
74
|
});
|
|
81
|
-
expect(sameResult).not.toContain("User
|
|
75
|
+
expect(sameResult).not.toContain("User TZ:");
|
|
82
76
|
|
|
83
77
|
// When user timezone differs from host, it becomes the primary timezone
|
|
84
78
|
// and the host timezone is shown as a secondary annotation
|
|
@@ -87,19 +81,19 @@ describe("buildTemporalContext", () => {
|
|
|
87
81
|
hostTimeZone: "UTC",
|
|
88
82
|
userTimeZone: "America/New_York",
|
|
89
83
|
});
|
|
90
|
-
expect(diffResult).toContain("
|
|
91
|
-
expect(diffResult).toContain("
|
|
92
|
-
expect(diffResult).not.toContain("User
|
|
84
|
+
expect(diffResult).toContain("TZ: America/New_York");
|
|
85
|
+
expect(diffResult).toContain("Host TZ: UTC");
|
|
86
|
+
expect(diffResult).not.toContain("User TZ:");
|
|
93
87
|
});
|
|
94
88
|
|
|
95
|
-
test("shows
|
|
89
|
+
test("shows host TZ only when different from primary timezone", () => {
|
|
96
90
|
// When host timezone equals the primary timezone, omit it
|
|
97
91
|
const sameResult = buildTemporalContext({
|
|
98
92
|
nowMs: WED_FEB_18,
|
|
99
93
|
hostTimeZone: "UTC",
|
|
100
94
|
timeZone: "UTC",
|
|
101
95
|
});
|
|
102
|
-
expect(sameResult).not.toContain("
|
|
96
|
+
expect(sameResult).not.toContain("Host TZ:");
|
|
103
97
|
|
|
104
98
|
// When different, include it
|
|
105
99
|
const diffResult = buildTemporalContext({
|
|
@@ -107,7 +101,7 @@ describe("buildTemporalContext", () => {
|
|
|
107
101
|
hostTimeZone: "UTC",
|
|
108
102
|
userTimeZone: "America/New_York",
|
|
109
103
|
});
|
|
110
|
-
expect(diffResult).toContain("
|
|
104
|
+
expect(diffResult).toContain("Host TZ: UTC");
|
|
111
105
|
});
|
|
112
106
|
|
|
113
107
|
test("uses configured user timezone when profile timezone is unavailable", () => {
|
|
@@ -117,9 +111,9 @@ describe("buildTemporalContext", () => {
|
|
|
117
111
|
configuredUserTimeZone: "America/Chicago",
|
|
118
112
|
userTimeZone: null,
|
|
119
113
|
});
|
|
120
|
-
expect(result).toContain("
|
|
121
|
-
expect(result).toContain("
|
|
122
|
-
expect(result).toContain("
|
|
114
|
+
expect(result).toContain("TZ: America/Chicago");
|
|
115
|
+
expect(result).toContain("Today: 2026-02-18 (Wed) 06:00 -06:00");
|
|
116
|
+
expect(result).not.toContain("(host fallback)");
|
|
123
117
|
});
|
|
124
118
|
|
|
125
119
|
test("configured user timezone takes precedence over profile timezone", () => {
|
|
@@ -129,19 +123,17 @@ describe("buildTemporalContext", () => {
|
|
|
129
123
|
configuredUserTimeZone: "America/Los_Angeles",
|
|
130
124
|
userTimeZone: "America/New_York",
|
|
131
125
|
});
|
|
132
|
-
expect(result).toContain("
|
|
133
|
-
expect(result).toContain("
|
|
134
|
-
expect(result).toContain("Timezone source: user_settings");
|
|
126
|
+
expect(result).toContain("TZ: America/Los_Angeles");
|
|
127
|
+
expect(result).toContain("Today: 2026-02-18 (Wed) 04:00 -08:00");
|
|
135
128
|
});
|
|
136
129
|
|
|
137
|
-
test("falls back to host timezone
|
|
130
|
+
test("falls back to host timezone with (host fallback) suffix", () => {
|
|
138
131
|
const result = buildTemporalContext({
|
|
139
132
|
nowMs: WED_FEB_18,
|
|
140
133
|
hostTimeZone: "UTC",
|
|
141
134
|
userTimeZone: null,
|
|
142
135
|
});
|
|
143
|
-
expect(result).toContain("
|
|
144
|
-
expect(result).toContain("Timezone source: assistant_host_fallback");
|
|
136
|
+
expect(result).toContain("TZ: UTC (host fallback)");
|
|
145
137
|
});
|
|
146
138
|
|
|
147
139
|
test("accepts UTC/GMT offset-style user timezone values", () => {
|
|
@@ -150,9 +142,9 @@ describe("buildTemporalContext", () => {
|
|
|
150
142
|
hostTimeZone: "UTC",
|
|
151
143
|
userTimeZone: "UTC+2",
|
|
152
144
|
});
|
|
153
|
-
expect(result).toContain("
|
|
154
|
-
expect(result).toContain("
|
|
155
|
-
expect(result).toContain("
|
|
145
|
+
expect(result).toContain("TZ: Etc/GMT-2");
|
|
146
|
+
expect(result).toContain("Today: 2026-02-18 (Wed) 14:00 +02:00");
|
|
147
|
+
expect(result).not.toContain("(host fallback)");
|
|
156
148
|
});
|
|
157
149
|
|
|
158
150
|
test("accepts fractional UTC/GMT offset-style user timezone values", () => {
|
|
@@ -161,30 +153,30 @@ describe("buildTemporalContext", () => {
|
|
|
161
153
|
hostTimeZone: "UTC",
|
|
162
154
|
userTimeZone: "UTC+5:30",
|
|
163
155
|
});
|
|
164
|
-
expect(result).toContain("
|
|
165
|
-
expect(result).toContain("
|
|
166
|
-
expect(result).toContain("
|
|
156
|
+
expect(result).toContain("TZ: +05:30");
|
|
157
|
+
expect(result).toContain("Today: 2026-02-18 (Wed) 17:30 +05:30");
|
|
158
|
+
expect(result).not.toContain("(host fallback)");
|
|
167
159
|
});
|
|
168
160
|
|
|
169
|
-
test("formats midnight hours as 00 (never 24)
|
|
161
|
+
test("formats midnight hours as 00 (never 24)", () => {
|
|
170
162
|
const justAfterMidnight = Date.UTC(2026, 1, 19, 0, 5, 0);
|
|
171
163
|
const result = buildTemporalContext({
|
|
172
164
|
nowMs: justAfterMidnight,
|
|
173
165
|
timeZone: "UTC",
|
|
174
166
|
});
|
|
175
|
-
expect(result).toContain("
|
|
176
|
-
expect(result).not.toContain("
|
|
167
|
+
expect(result).toContain("00:05 +00:00");
|
|
168
|
+
expect(result).not.toContain("24:05");
|
|
177
169
|
});
|
|
178
170
|
|
|
179
171
|
test("Today line includes full YYYY-MM-DD format with year", () => {
|
|
180
172
|
const result = buildTemporalContext({ nowMs: WED_FEB_18, timeZone: "UTC" });
|
|
181
|
-
expect(result).toMatch(/Today: \d{4}-\d{2}-\d{2} \(\w
|
|
173
|
+
expect(result).toMatch(/Today: \d{4}-\d{2}-\d{2} \(\w{3}\) \d{2}:\d{2}/);
|
|
182
174
|
expect(result).toContain("2026-02-18");
|
|
183
175
|
});
|
|
184
176
|
|
|
185
177
|
test("handles year boundary correctly", () => {
|
|
186
178
|
const result = buildTemporalContext({ nowMs: TUE_DEC_29, timeZone: "UTC" });
|
|
187
|
-
expect(result).toContain("Today: 2026-12-29 (
|
|
179
|
+
expect(result).toContain("Today: 2026-12-29 (Tue)");
|
|
188
180
|
});
|
|
189
181
|
});
|
|
190
182
|
|
|
@@ -198,8 +190,7 @@ describe("DST-safe timezone behavior", () => {
|
|
|
198
190
|
nowMs: WED_FEB_18,
|
|
199
191
|
timeZone: "America/New_York",
|
|
200
192
|
});
|
|
201
|
-
expect(result).toContain("Today: 2026-02-18 (
|
|
202
|
-
expect(result).toContain("Current local time: 2026-02-18T07:00:00-05:00");
|
|
193
|
+
expect(result).toContain("Today: 2026-02-18 (Wed) 07:00 -05:00");
|
|
203
194
|
});
|
|
204
195
|
|
|
205
196
|
test("date labels are correct in timezone ahead of UTC", () => {
|
|
@@ -209,7 +200,7 @@ describe("DST-safe timezone behavior", () => {
|
|
|
209
200
|
nowMs: nearMidnight,
|
|
210
201
|
timeZone: "Asia/Tokyo",
|
|
211
202
|
});
|
|
212
|
-
expect(result).toContain("Today: 2026-02-19 (
|
|
203
|
+
expect(result).toContain("Today: 2026-02-19 (Thu) 08:00 +09:00");
|
|
213
204
|
});
|
|
214
205
|
|
|
215
206
|
test("local offset tracks daylight saving changes", () => {
|
|
@@ -219,7 +210,7 @@ describe("DST-safe timezone behavior", () => {
|
|
|
219
210
|
nowMs: summer,
|
|
220
211
|
timeZone: "America/New_York",
|
|
221
212
|
});
|
|
222
|
-
expect(result).toContain("
|
|
213
|
+
expect(result).toContain("Today: 2026-07-01 (Wed) 08:00 -04:00");
|
|
223
214
|
});
|
|
224
215
|
});
|
|
225
216
|
|
|
@@ -233,83 +224,72 @@ describe("extractUserTimeZoneFromRecall", () => {
|
|
|
233
224
|
expect(extractUserTimeZoneFromRecall(" ")).toBeNull();
|
|
234
225
|
});
|
|
235
226
|
|
|
236
|
-
test("extracts IANA timezone from
|
|
227
|
+
test("extracts IANA timezone from identity item", () => {
|
|
237
228
|
const text = `<memory_context __injected>
|
|
238
|
-
|
|
239
|
-
<
|
|
240
|
-
User
|
|
241
|
-
|
|
242
|
-
</user_identity>
|
|
243
|
-
|
|
229
|
+
<recalled>
|
|
230
|
+
<item id="item:1" kind="identity" importance="0.90" timestamp="2026-03-01 10:00 PST">User's timezone is America/New_York</item>
|
|
231
|
+
<item id="item:2" kind="identity" importance="0.80" timestamp="2026-03-01 10:00 PST">User works as a software engineer</item>
|
|
232
|
+
</recalled>
|
|
244
233
|
</memory_context>`;
|
|
245
234
|
expect(extractUserTimeZoneFromRecall(text)).toBe("America/New_York");
|
|
246
235
|
});
|
|
247
236
|
|
|
248
|
-
test("extracts timezone from 'timezone: ...'
|
|
237
|
+
test("extracts timezone from 'timezone: ...' in identity item", () => {
|
|
249
238
|
const text = `<memory_context __injected>
|
|
250
|
-
|
|
251
|
-
<
|
|
252
|
-
- name: Alice
|
|
253
|
-
|
|
254
|
-
- role: designer
|
|
255
|
-
</user_identity>
|
|
256
|
-
|
|
239
|
+
<recalled>
|
|
240
|
+
<item id="item:1" kind="identity" importance="0.90" timestamp="2026-03-01 10:00 PST">timezone: Europe/London</item>
|
|
241
|
+
<item id="item:2" kind="identity" importance="0.80" timestamp="2026-03-01 10:00 PST">name: Alice</item>
|
|
242
|
+
</recalled>
|
|
257
243
|
</memory_context>`;
|
|
258
244
|
expect(extractUserTimeZoneFromRecall(text)).toBe("Europe/London");
|
|
259
245
|
});
|
|
260
246
|
|
|
261
247
|
test("extracts UTC offset timezone", () => {
|
|
262
248
|
const text = `<memory_context __injected>
|
|
263
|
-
|
|
264
|
-
<
|
|
265
|
-
|
|
266
|
-
</user_identity>
|
|
267
|
-
|
|
249
|
+
<recalled>
|
|
250
|
+
<item id="item:1" kind="identity" importance="0.90" timestamp="2026-03-01 10:00 PST">User's time zone is UTC+5:30</item>
|
|
251
|
+
</recalled>
|
|
268
252
|
</memory_context>`;
|
|
269
253
|
const result = extractUserTimeZoneFromRecall(text);
|
|
270
254
|
expect(result).not.toBeNull();
|
|
271
255
|
expect(result).toBe("+05:30");
|
|
272
256
|
});
|
|
273
257
|
|
|
274
|
-
test("falls back to scanning full text when no identity
|
|
258
|
+
test("falls back to scanning full text when no identity items", () => {
|
|
275
259
|
const text = `<memory_context __injected>
|
|
276
|
-
|
|
277
|
-
<
|
|
278
|
-
|
|
279
|
-
User mentioned their timezone is Asia/Tokyo
|
|
280
|
-
</episode>
|
|
281
|
-
</relevant_context>
|
|
282
|
-
|
|
260
|
+
<recalled>
|
|
261
|
+
<segment id="seg:1" timestamp="2026-03-05 10:00 PST">User mentioned their timezone is Asia/Tokyo</segment>
|
|
262
|
+
</recalled>
|
|
283
263
|
</memory_context>`;
|
|
284
264
|
expect(extractUserTimeZoneFromRecall(text)).toBe("Asia/Tokyo");
|
|
285
265
|
});
|
|
286
266
|
|
|
287
267
|
test("returns null when no timezone info present", () => {
|
|
288
268
|
const text = `<memory_context __injected>
|
|
289
|
-
|
|
290
|
-
<
|
|
291
|
-
User
|
|
292
|
-
|
|
293
|
-
</user_identity>
|
|
294
|
-
|
|
269
|
+
<recalled>
|
|
270
|
+
<item id="item:1" kind="identity" importance="0.90" timestamp="2026-03-01 10:00 PST">User's name is Bob</item>
|
|
271
|
+
<item id="item:2" kind="identity" importance="0.80" timestamp="2026-03-01 10:00 PST">User works at Acme Corp</item>
|
|
272
|
+
</recalled>
|
|
295
273
|
</memory_context>`;
|
|
296
274
|
expect(extractUserTimeZoneFromRecall(text)).toBeNull();
|
|
297
275
|
});
|
|
298
276
|
|
|
299
|
-
test("prefers identity
|
|
277
|
+
test("prefers identity items over other recalled content", () => {
|
|
300
278
|
const text = `<memory_context __injected>
|
|
301
|
-
|
|
302
|
-
<
|
|
303
|
-
|
|
304
|
-
</
|
|
305
|
-
|
|
306
|
-
<relevant_context>
|
|
307
|
-
<episode source="Mar 5">
|
|
308
|
-
Discussed timezone America/Los_Angeles for the deployment
|
|
309
|
-
</episode>
|
|
310
|
-
</relevant_context>
|
|
311
|
-
|
|
279
|
+
<recalled>
|
|
280
|
+
<item id="item:1" kind="identity" importance="0.90" timestamp="2026-03-01 10:00 PST">User's timezone is America/Chicago</item>
|
|
281
|
+
<segment id="seg:1" timestamp="2026-03-05 10:00 PST">Discussed timezone America/Los_Angeles for the deployment</segment>
|
|
282
|
+
</recalled>
|
|
312
283
|
</memory_context>`;
|
|
313
284
|
expect(extractUserTimeZoneFromRecall(text)).toBe("America/Chicago");
|
|
314
285
|
});
|
|
286
|
+
|
|
287
|
+
test("extracts timezone from identity item without timezone keyword via second pass", () => {
|
|
288
|
+
const text = `<memory_context __injected>
|
|
289
|
+
<recalled>
|
|
290
|
+
<item id="item:1" kind="identity" importance="0.90" timestamp="2026-03-01 10:00 PST">America/Denver</item>
|
|
291
|
+
</recalled>
|
|
292
|
+
</memory_context>`;
|
|
293
|
+
expect(extractUserTimeZoneFromRecall(text)).toBe("America/Denver");
|
|
294
|
+
});
|
|
315
295
|
});
|
|
@@ -1,26 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { tmpdir } from "node:os";
|
|
3
|
-
import { join } from "node:path";
|
|
1
|
+
import { rmSync } from "node:fs";
|
|
4
2
|
import { Database } from "bun:sqlite";
|
|
5
3
|
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
6
4
|
|
|
7
5
|
import { drizzle } from "drizzle-orm/bun-sqlite";
|
|
8
|
-
|
|
9
|
-
const testDir = mkdtempSync(join(tmpdir(), "conversation-fork-lineage-"));
|
|
10
|
-
const dbPath = join(testDir, "test.db");
|
|
11
6
|
const originalBunTest = process.env.BUN_TEST;
|
|
12
7
|
|
|
13
|
-
mock.module("../util/platform.js", () => ({
|
|
14
|
-
getDataDir: () => testDir,
|
|
15
|
-
isMacOS: () => process.platform === "darwin",
|
|
16
|
-
isLinux: () => process.platform === "linux",
|
|
17
|
-
isWindows: () => process.platform === "win32",
|
|
18
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
19
|
-
getDbPath: () => dbPath,
|
|
20
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
21
|
-
ensureDataDir: () => {},
|
|
22
|
-
}));
|
|
23
|
-
|
|
24
8
|
mock.module("../util/logger.js", () => ({
|
|
25
9
|
getLogger: () =>
|
|
26
10
|
new Proxy({} as Record<string, unknown>, {
|
|
@@ -32,6 +16,7 @@ import { initializeDb, resetDb } from "../memory/db.js";
|
|
|
32
16
|
import { getSqliteFrom } from "../memory/db-connection.js";
|
|
33
17
|
import { migrateConversationForkLineage } from "../memory/migrations/183-add-conversation-fork-lineage.js";
|
|
34
18
|
import * as schema from "../memory/schema.js";
|
|
19
|
+
import { getDbPath } from "../util/platform.js";
|
|
35
20
|
|
|
36
21
|
function createTestDb() {
|
|
37
22
|
const sqlite = new Database(":memory:");
|
|
@@ -42,7 +27,9 @@ function createTestDb() {
|
|
|
42
27
|
|
|
43
28
|
function getColumnNames(raw: Database): string[] {
|
|
44
29
|
return (
|
|
45
|
-
raw.query(`PRAGMA table_info(conversations)`).all() as Array<{
|
|
30
|
+
raw.query(`PRAGMA table_info(conversations)`).all() as Array<{
|
|
31
|
+
name: string;
|
|
32
|
+
}>
|
|
46
33
|
).map((column) => column.name);
|
|
47
34
|
}
|
|
48
35
|
|
|
@@ -79,6 +66,7 @@ function bootstrapPreLineageConversations(raw: Database): void {
|
|
|
79
66
|
|
|
80
67
|
function removeTestDbFiles(): void {
|
|
81
68
|
resetDb();
|
|
69
|
+
const dbPath = getDbPath();
|
|
82
70
|
rmSync(dbPath, { force: true });
|
|
83
71
|
rmSync(`${dbPath}-shm`, { force: true });
|
|
84
72
|
rmSync(`${dbPath}-wal`, { force: true });
|
|
@@ -93,17 +81,12 @@ describe("conversation fork lineage migration", () => {
|
|
|
93
81
|
afterAll(() => {
|
|
94
82
|
process.env.BUN_TEST = originalBunTest;
|
|
95
83
|
removeTestDbFiles();
|
|
96
|
-
try {
|
|
97
|
-
rmSync(testDir, { recursive: true });
|
|
98
|
-
} catch {
|
|
99
|
-
/* best effort */
|
|
100
|
-
}
|
|
101
84
|
});
|
|
102
85
|
|
|
103
86
|
test("fresh DB initialization includes nullable lineage columns and parent lookup index", () => {
|
|
104
87
|
initializeDb();
|
|
105
88
|
|
|
106
|
-
const raw = new Database(
|
|
89
|
+
const raw = new Database(getDbPath());
|
|
107
90
|
const columns = getColumnNames(raw);
|
|
108
91
|
|
|
109
92
|
expect(columns).toContain("fork_parent_conversation_id");
|
|
@@ -1,26 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { tmpdir } from "node:os";
|
|
3
|
-
import { join } from "node:path";
|
|
1
|
+
import { rmSync } from "node:fs";
|
|
4
2
|
import { Database } from "bun:sqlite";
|
|
5
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
afterAll,
|
|
5
|
+
afterEach,
|
|
6
|
+
beforeEach,
|
|
7
|
+
describe,
|
|
8
|
+
expect,
|
|
9
|
+
mock,
|
|
10
|
+
test,
|
|
11
|
+
} from "bun:test";
|
|
6
12
|
|
|
7
13
|
import { drizzle } from "drizzle-orm/bun-sqlite";
|
|
8
|
-
|
|
9
|
-
const testDir = mkdtempSync(join(tmpdir(), "llm-request-log-provider-"));
|
|
10
|
-
const dbPath = join(testDir, "test.db");
|
|
11
14
|
const originalBunTest = process.env.BUN_TEST;
|
|
12
15
|
|
|
13
|
-
mock.module("../util/platform.js", () => ({
|
|
14
|
-
getDataDir: () => testDir,
|
|
15
|
-
isMacOS: () => process.platform === "darwin",
|
|
16
|
-
isLinux: () => process.platform === "linux",
|
|
17
|
-
isWindows: () => process.platform === "win32",
|
|
18
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
19
|
-
getDbPath: () => dbPath,
|
|
20
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
21
|
-
ensureDataDir: () => {},
|
|
22
|
-
}));
|
|
23
|
-
|
|
24
16
|
mock.module("../util/logger.js", () => ({
|
|
25
17
|
getLogger: () =>
|
|
26
18
|
new Proxy({} as Record<string, unknown>, {
|
|
@@ -32,6 +24,7 @@ import { initializeDb, resetDb } from "../memory/db.js";
|
|
|
32
24
|
import { getSqliteFrom } from "../memory/db-connection.js";
|
|
33
25
|
import { migrateLlmRequestLogProvider } from "../memory/migrations/184-llm-request-log-provider.js";
|
|
34
26
|
import * as schema from "../memory/schema.js";
|
|
27
|
+
import { getDbPath } from "../util/platform.js";
|
|
35
28
|
|
|
36
29
|
function createTestDb() {
|
|
37
30
|
const sqlite = new Database(":memory:");
|
|
@@ -40,7 +33,9 @@ function createTestDb() {
|
|
|
40
33
|
return drizzle(sqlite, { schema });
|
|
41
34
|
}
|
|
42
35
|
|
|
43
|
-
function getColumnInfo(
|
|
36
|
+
function getColumnInfo(
|
|
37
|
+
raw: Database,
|
|
38
|
+
): Array<{ name: string; notnull: number }> {
|
|
44
39
|
return raw.query(`PRAGMA table_info(llm_request_logs)`).all() as Array<{
|
|
45
40
|
name: string;
|
|
46
41
|
notnull: number;
|
|
@@ -61,6 +56,7 @@ function bootstrapPreProviderLlmRequestLogs(raw: Database): void {
|
|
|
61
56
|
}
|
|
62
57
|
|
|
63
58
|
function removeTestDbFiles(): void {
|
|
59
|
+
const dbPath = getDbPath();
|
|
64
60
|
rmSync(dbPath, { force: true });
|
|
65
61
|
rmSync(`${dbPath}-shm`, { force: true });
|
|
66
62
|
rmSync(`${dbPath}-wal`, { force: true });
|
|
@@ -86,17 +82,12 @@ describe("llm_request_logs provider migration", () => {
|
|
|
86
82
|
}
|
|
87
83
|
resetDb();
|
|
88
84
|
removeTestDbFiles();
|
|
89
|
-
try {
|
|
90
|
-
rmSync(testDir, { recursive: true });
|
|
91
|
-
} catch {
|
|
92
|
-
/* best effort */
|
|
93
|
-
}
|
|
94
85
|
});
|
|
95
86
|
|
|
96
87
|
test("fresh DB initialization includes llm_request_logs.provider", () => {
|
|
97
88
|
initializeDb();
|
|
98
89
|
|
|
99
|
-
const raw = new Database(
|
|
90
|
+
const raw = new Database(getDbPath());
|
|
100
91
|
const columns = getColumnInfo(raw);
|
|
101
92
|
|
|
102
93
|
expect(columns.some((column) => column.name === "provider")).toBe(true);
|
|
@@ -132,9 +123,9 @@ describe("llm_request_logs provider migration", () => {
|
|
|
132
123
|
|
|
133
124
|
migrateLlmRequestLogProvider(db);
|
|
134
125
|
|
|
135
|
-
expect(
|
|
136
|
-
|
|
137
|
-
);
|
|
126
|
+
expect(
|
|
127
|
+
getColumnInfo(raw).some((column) => column.name === "provider"),
|
|
128
|
+
).toBe(true);
|
|
138
129
|
|
|
139
130
|
const row = raw
|
|
140
131
|
.query(
|
|
@@ -142,17 +133,15 @@ describe("llm_request_logs provider migration", () => {
|
|
|
142
133
|
FROM llm_request_logs
|
|
143
134
|
WHERE id = 'log-upgrade'`,
|
|
144
135
|
)
|
|
145
|
-
.get() as
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
| null;
|
|
136
|
+
.get() as {
|
|
137
|
+
id: string;
|
|
138
|
+
conversation_id: string;
|
|
139
|
+
message_id: string | null;
|
|
140
|
+
provider: string | null;
|
|
141
|
+
request_payload: string;
|
|
142
|
+
response_payload: string;
|
|
143
|
+
created_at: number;
|
|
144
|
+
} | null;
|
|
156
145
|
|
|
157
146
|
expect(row).toEqual({
|
|
158
147
|
id: "log-upgrade",
|
|
@@ -200,9 +189,7 @@ describe("llm_request_logs provider migration", () => {
|
|
|
200
189
|
expect(() => migrateLlmRequestLogProvider(db)).not.toThrow();
|
|
201
190
|
|
|
202
191
|
const row = raw
|
|
203
|
-
.query(
|
|
204
|
-
`SELECT provider FROM llm_request_logs WHERE id = 'log-rerun'`,
|
|
205
|
-
)
|
|
192
|
+
.query(`SELECT provider FROM llm_request_logs WHERE id = 'log-rerun'`)
|
|
206
193
|
.get() as { provider: string | null } | null;
|
|
207
194
|
|
|
208
195
|
expect(row).toEqual({
|
|
@@ -5,17 +5,10 @@ import {
|
|
|
5
5
|
rmSync,
|
|
6
6
|
writeFileSync,
|
|
7
7
|
} from "node:fs";
|
|
8
|
-
import { mkdtempSync } from "node:fs";
|
|
9
|
-
import { tmpdir } from "node:os";
|
|
10
8
|
import { join } from "node:path";
|
|
11
9
|
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
mock.module("../util/platform.js", () => ({
|
|
16
|
-
getRootDir: () => TEST_DIR,
|
|
17
|
-
getWorkspaceSkillsDir: () => join(TEST_DIR, "skills"),
|
|
18
|
-
}));
|
|
11
|
+
const TEST_DIR = process.env.VELLUM_WORKSPACE_DIR!;
|
|
19
12
|
|
|
20
13
|
mock.module("../util/logger.js", () => ({
|
|
21
14
|
getLogger: () =>
|
|
@@ -51,12 +44,11 @@ function createSkill(id: string): void {
|
|
|
51
44
|
}
|
|
52
45
|
|
|
53
46
|
beforeEach(() => {
|
|
54
|
-
TEST_DIR = mkdtempSync(join(tmpdir(), "delete-tool-test-"));
|
|
55
47
|
mkdirSync(join(TEST_DIR, "skills"), { recursive: true });
|
|
56
48
|
});
|
|
57
49
|
|
|
58
50
|
afterEach(() => {
|
|
59
|
-
rmSync(TEST_DIR, { recursive: true, force: true });
|
|
51
|
+
rmSync(join(TEST_DIR, "skills"), { recursive: true, force: true });
|
|
60
52
|
});
|
|
61
53
|
|
|
62
54
|
describe("delete_managed_skill tool", () => {
|
|
@@ -9,29 +9,12 @@
|
|
|
9
9
|
* 4. Channel verification reply templates are non-empty and deterministic.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {
|
|
13
|
-
import { tmpdir } from "node:os";
|
|
14
|
-
import { join } from "node:path";
|
|
15
|
-
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
12
|
+
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
16
13
|
|
|
17
14
|
// ---------------------------------------------------------------------------
|
|
18
15
|
// Test isolation: in-memory SQLite via temp directory
|
|
19
16
|
// ---------------------------------------------------------------------------
|
|
20
17
|
|
|
21
|
-
const testDir = mkdtempSync(join(tmpdir(), "deterministic-verify-test-"));
|
|
22
|
-
|
|
23
|
-
mock.module("../util/platform.js", () => ({
|
|
24
|
-
getRootDir: () => testDir,
|
|
25
|
-
getDataDir: () => testDir,
|
|
26
|
-
isMacOS: () => process.platform === "darwin",
|
|
27
|
-
isLinux: () => process.platform === "linux",
|
|
28
|
-
isWindows: () => process.platform === "win32",
|
|
29
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
30
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
31
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
32
|
-
ensureDataDir: () => {},
|
|
33
|
-
}));
|
|
34
|
-
|
|
35
18
|
mock.module("../util/logger.js", () => ({
|
|
36
19
|
getLogger: () =>
|
|
37
20
|
new Proxy({} as Record<string, unknown>, {
|
|
@@ -63,14 +46,6 @@ beforeEach(() => {
|
|
|
63
46
|
initializeDb();
|
|
64
47
|
});
|
|
65
48
|
|
|
66
|
-
afterAll(() => {
|
|
67
|
-
try {
|
|
68
|
-
rmSync(testDir, { recursive: true, force: true });
|
|
69
|
-
} catch {
|
|
70
|
-
/* best effort */
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
|
|
74
49
|
// ---------------------------------------------------------------------------
|
|
75
50
|
// Template tests: channel verification reply templates are deterministic
|
|
76
51
|
// ---------------------------------------------------------------------------
|