@vellumai/assistant 0.9.0 → 0.10.0-staging.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +18 -34
- package/bun.lock +7 -8
- package/docs/activation-funnel-telemetry.md +28 -22
- package/docs/architecture/security.md +29 -28
- package/docs/stt-provider-onboarding.md +3 -5
- package/docs/workflows-testing.md +13 -44
- package/docs/workflows.md +3 -5
- package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +47 -0
- package/node_modules/@vellumai/ces-client/src/rpc-client.ts +28 -5
- package/node_modules/@vellumai/environments/src/seeds.ts +2 -5
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +32 -6
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +119 -0
- package/node_modules/@vellumai/gateway-client/src/types.ts +15 -84
- package/openapi.yaml +976 -63
- package/package.json +2 -1
- package/scripts/sync-llm-catalog.ts +6 -15
- package/scripts/sync-web-search-catalog.ts +3 -11
- package/src/__tests__/access-request-card-view.test.ts +98 -0
- package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +72 -32
- package/src/__tests__/agent-loop-compaction-strip.test.ts +241 -0
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
- package/src/__tests__/agent-loop-output-hooks.test.ts +69 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +25 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -3
- package/src/__tests__/app-compiler.test.ts +15 -1
- package/src/__tests__/app-dir-path-guard.test.ts +0 -1
- package/src/__tests__/assistant-feature-flag-guard.test.ts +1 -4
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
- package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
- package/src/__tests__/avatar-identity-sync.test.ts +2 -27
- package/src/__tests__/btw-routes.test.ts +6 -8
- package/src/__tests__/call-pointer-messages.test.ts +28 -0
- package/src/__tests__/cancel-clears-processing.test.ts +89 -0
- package/src/__tests__/channel-approval-routes.test.ts +0 -4
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
- package/src/__tests__/checker.test.ts +0 -3
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
- package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
- package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
- package/src/__tests__/config-loader-backfill.test.ts +268 -27
- package/src/__tests__/config-schema.test.ts +35 -0
- package/src/__tests__/config-watcher.test.ts +0 -18
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +0 -6
- package/src/__tests__/contacts-tools.test.ts +29 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +58 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-lifecycle.test.ts +7 -9
- package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
- package/src/__tests__/conversation-title-service.test.ts +62 -0
- package/src/__tests__/credential-broker.test.ts +449 -1
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
- package/src/__tests__/credential-execution-tools.test.ts +0 -1
- package/src/__tests__/credential-prompt-route.test.ts +4 -4
- package/src/__tests__/credential-routes.test.ts +360 -0
- package/src/__tests__/credential-security-invariants.test.ts +4 -13
- package/src/__tests__/disk-pressure-policy.test.ts +12 -0
- package/src/__tests__/disk-usage.test.ts +65 -0
- package/src/__tests__/dynamic-page-surface.test.ts +152 -1
- package/src/__tests__/fixtures/credential-security-fixtures.ts +2 -33
- package/src/__tests__/gateway-flag-listener.test.ts +110 -1
- package/src/__tests__/gateway-only-guard.test.ts +3 -7
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
- package/src/__tests__/guardian-grant-minting.test.ts +3 -35
- package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
- package/src/__tests__/guardian-routing-state.test.ts +0 -1
- package/src/__tests__/headless-browser-mode.test.ts +10 -0
- package/src/__tests__/headless-browser-navigate.test.ts +8 -3
- package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
- package/src/__tests__/host-browser-proxy.test.ts +87 -0
- package/src/__tests__/identity-routes.test.ts +0 -189
- package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
- package/src/__tests__/injector-v3-suppression.test.ts +27 -20
- package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
- package/src/__tests__/invite-redemption-service.test.ts +4 -7
- package/src/__tests__/llm-callsite-catalog.test.ts +5 -6
- package/src/__tests__/llm-catalog-parity.test.ts +30 -23
- package/src/__tests__/llm-resolver.test.ts +70 -24
- package/src/__tests__/llm-schema.test.ts +1 -0
- package/src/__tests__/managed-profile-guard.test.ts +163 -4
- package/src/__tests__/mcp-health-check.test.ts +6 -7
- package/src/__tests__/media-stream-server-integration.test.ts +317 -13
- package/src/__tests__/oauth-provider-seed-logos.test.ts +4 -6
- package/src/__tests__/onboarding-persona-write.test.ts +1 -1
- package/src/__tests__/path-policy.test.ts +34 -0
- package/src/__tests__/persona-resolver.test.ts +49 -14
- package/src/__tests__/plugin-api-model-profiles.test.ts +178 -0
- package/src/__tests__/plugin-api-provider.test.ts +24 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
- package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
- package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
- package/src/__tests__/reaction-persistence.test.ts +150 -29
- package/src/__tests__/registry.test.ts +2 -7
- package/src/__tests__/relay-server.test.ts +285 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -10
- package/src/__tests__/schedule-routes.test.ts +0 -30
- package/src/__tests__/schedule-tools.test.ts +2 -18
- package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
- package/src/__tests__/skill-execute-input.test.ts +51 -1
- package/src/__tests__/skill-runtime-path.test.ts +2 -3
- package/src/__tests__/skills.test.ts +51 -0
- package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
- package/src/__tests__/subagent-tools.test.ts +266 -0
- package/src/__tests__/surface-completion-nudge-hook.test.ts +367 -0
- package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
- package/src/__tests__/title-generate-hook.test.ts +100 -3
- package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -29
- package/src/__tests__/token-manager.test.ts +519 -0
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
- package/src/__tests__/tool-audit-listener.test.ts +7 -7
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
- package/src/__tests__/tool-executor.test.ts +0 -79
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
- package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
- package/src/__tests__/trusted-contact-verification.test.ts +8 -10
- package/src/__tests__/twilio-routes.test.ts +81 -1
- package/src/__tests__/voice-invite-redemption.test.ts +2 -3
- package/src/__tests__/weak-open-model.test.ts +30 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +6 -25
- package/src/__tests__/workspace-greetings.test.ts +152 -0
- package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
- package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
- package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
- package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
- package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
- package/src/agent/loop.ts +49 -29
- package/src/api/README.md +6 -6
- package/src/api/events/tool-result.ts +6 -0
- package/src/api/events/workflow-completed.ts +53 -0
- package/src/api/events/workflow-leaf-finished.ts +38 -0
- package/src/api/events/workflow-leaf-started.ts +35 -0
- package/src/api/events/workflow-progress.ts +32 -0
- package/src/api/events/workflow-started.ts +31 -0
- package/src/api/index.ts +40 -0
- package/src/api/responses/conversation-message.ts +28 -4
- package/src/api/responses/home.ts +26 -4
- package/src/api/responses/workflow-journal.ts +53 -0
- package/src/approvals/guardian-card-withdrawal.ts +145 -0
- package/src/approvals/guardian-decision-primitive.ts +26 -3
- package/src/approvals/guardian-request-resolvers.ts +183 -80
- package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
- package/src/calls/call-pointer-messages.ts +10 -4
- package/src/calls/channel-admission-reader.ts +104 -0
- package/src/calls/guardian-dispatch.ts +17 -45
- package/src/calls/media-stream-server.ts +84 -2
- package/src/calls/relay-access-wait.ts +1 -1
- package/src/calls/relay-server.ts +66 -0
- package/src/calls/relay-setup-router.ts +82 -1
- package/src/calls/twilio-routes.ts +17 -8
- package/src/calls/voice-session-bridge.ts +2 -2
- package/src/cli/commands/clients.ts +3 -0
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
- package/src/cli/commands/memory/index.ts +30 -0
- package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
- package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
- package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
- package/src/cli/commands/oauth/status.test.ts +36 -0
- package/src/cli/commands/oauth/status.ts +23 -3
- package/src/cli/commands/plugins.ts +197 -4
- package/src/cli/lib/__tests__/diff-plugin.test.ts +443 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
- package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +295 -2
- package/src/cli/lib/diff-plugin.ts +346 -0
- package/src/cli/lib/inspect-plugin.ts +12 -1
- package/src/cli/lib/install-from-github.ts +105 -17
- package/src/cli/lib/merge-plugin-tree.ts +328 -0
- package/src/cli/lib/plugin-fingerprint.ts +14 -0
- package/src/cli/lib/plugin-surfaces.ts +104 -0
- package/src/cli/lib/upgrade-plugin.ts +298 -10
- package/src/cli/program.ts +2 -6
- package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
- package/src/config/assistant-feature-flags.ts +22 -7
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
- package/src/config/bundled-skills/messaging/SKILL.md +6 -4
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
- package/src/config/bundled-skills/subagent/SKILL.md +4 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +4 -0
- package/src/config/bundled-skills/workflows/SKILL.md +14 -8
- package/src/config/bundled-tool-registry.ts +2 -7
- package/src/config/call-site-defaults.ts +15 -2
- package/src/config/feature-flag-registry.json +46 -31
- package/src/config/inference-profile-validation.ts +26 -0
- package/src/config/llm-resolver.ts +3 -0
- package/src/config/loader.ts +4 -0
- package/src/config/memory-v3-gate.ts +11 -0
- package/src/config/profile-order.ts +28 -0
- package/src/config/schema.ts +8 -6
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/channels.ts +11 -0
- package/src/config/schemas/elevenlabs.ts +0 -1
- package/src/config/schemas/llm.ts +31 -0
- package/src/config/schemas/memory-lifecycle.ts +3 -7
- package/src/config/schemas/memory-v3.ts +6 -0
- package/src/config/schemas/platform.ts +0 -8
- package/src/config/schemas/services.ts +18 -0
- package/src/config/seed-inference-profiles.ts +109 -44
- package/src/config/skills.ts +21 -0
- package/src/config/sync-gated-profiles.ts +220 -0
- package/src/contacts/contact-store.ts +89 -106
- package/src/contacts/contacts-write.ts +5 -22
- package/src/contacts/types.ts +0 -1
- package/src/context/compactor.ts +88 -54
- package/src/context/strip-injections.ts +58 -10
- package/src/context/token-estimator.ts +1 -1
- package/src/credential-execution/process-manager.ts +55 -14
- package/src/credential-execution/prompted-credential.ts +2 -3
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
- package/src/daemon/config-watcher.ts +0 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
- package/src/daemon/conversation-agent-loop.ts +114 -22
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +3 -5
- package/src/daemon/conversation-process.ts +13 -5
- package/src/daemon/conversation-runtime-assembly.ts +13 -15
- package/src/daemon/conversation-slash.ts +2 -23
- package/src/daemon/conversation-surfaces.ts +26 -0
- package/src/daemon/conversation-tool-setup.ts +27 -14
- package/src/daemon/conversation.ts +66 -14
- package/src/daemon/disk-pressure-policy.ts +5 -3
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
- package/src/daemon/handlers/config-a2a.ts +0 -2
- package/src/daemon/handlers/config-channels.ts +15 -16
- package/src/daemon/handlers/config-slack-channel.ts +22 -3
- package/src/daemon/handlers/conversations.ts +107 -0
- package/src/daemon/host-browser-proxy.ts +41 -0
- package/src/daemon/lifecycle.ts +55 -27
- package/src/daemon/message-provenance.ts +2 -0
- package/src/daemon/message-types/contacts.ts +0 -1
- package/src/daemon/message-types/conversations.ts +3 -3
- package/src/daemon/message-types/sync.ts +0 -1
- package/src/daemon/message-types/web-activity.ts +7 -1
- package/src/daemon/message-types/workflows.ts +83 -1
- package/src/daemon/orphan-reaper.test.ts +0 -19
- package/src/daemon/orphan-reaper.ts +2 -24
- package/src/daemon/server.ts +0 -10
- package/src/daemon/tool-setup-types.ts +4 -0
- package/src/daemon/trust-context.ts +1 -1
- package/src/events/tool-audit-listener.ts +2 -2
- package/src/home/feed-source-enrichment.test.ts +151 -0
- package/src/home/feed-source-enrichment.ts +176 -0
- package/src/home/relationship-state.ts +2 -4
- package/src/instrument.ts +18 -6
- package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
- package/src/ipc/assistant-server.ts +37 -4
- package/src/ipc/gateway-flag-listener.ts +18 -2
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
- package/src/memory/__tests__/memory-retrospective-job.test.ts +229 -401
- package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
- package/src/memory/auth-fallback-events-store.ts +2 -2
- package/src/memory/auto-analysis-enqueue.ts +3 -5
- package/src/memory/bookmark-crud.ts +1 -2
- package/src/memory/canonical-guardian-store.ts +39 -1
- package/src/memory/conversation-crud.ts +9 -4
- package/src/memory/conversation-key-store.ts +17 -2
- package/src/memory/conversation-title-service.ts +64 -7
- package/src/memory/db-init.ts +17 -17
- package/src/memory/embedding-backend.ts +38 -1
- package/src/memory/embedding-billing-breaker.ts +96 -0
- package/src/memory/jobs-store.ts +25 -13
- package/src/memory/jobs-worker.ts +54 -1
- package/src/memory/lifecycle-events-store.ts +2 -2
- package/src/memory/memory-retrospective-constants.ts +4 -4
- package/src/memory/memory-retrospective-enqueue.ts +31 -6
- package/src/memory/memory-retrospective-job.ts +28 -227
- package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
- package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
- package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
- package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +72 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
- package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
- package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
- package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
- package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
- package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
- package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +341 -0
- package/src/memory/migrations/__tests__/run-migrations.test.ts +52 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/run-migrations.ts +41 -0
- package/src/memory/migrations/validate-migration-state.ts +1 -1
- package/src/memory/onboarding-events-store.ts +3 -3
- package/src/memory/schema/contacts.ts +0 -5
- package/src/memory/skill-loaded-events-store.test.ts +7 -15
- package/src/memory/skill-loaded-events-store.ts +2 -2
- package/src/memory/tool-executed-events-store.test.ts +7 -7
- package/src/memory/turn-trace-store.test.ts +736 -0
- package/src/memory/turn-trace-store.ts +364 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
- package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
- package/src/memory/v2/consolidation-job.ts +2 -2
- package/src/memory/v2/skill-content.ts +25 -7
- package/src/memory/v2/skill-store.ts +7 -1
- package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
- package/src/memory/v3-eval/eval-packets.ts +546 -0
- package/src/messaging/providers/slack/adapter.ts +1 -1
- package/src/messaging/providers/slack/api.ts +31 -0
- package/src/messaging/providers/slack/send.test.ts +114 -2
- package/src/messaging/providers/slack/send.ts +30 -7
- package/src/messaging/providers/slack/withdraw.test.ts +200 -0
- package/src/messaging/providers/slack/withdraw.ts +161 -0
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/access-request-copy.ts +72 -59
- package/src/notifications/adapters/shared.ts +29 -0
- package/src/notifications/adapters/slack.ts +58 -103
- package/src/notifications/adapters/telegram.ts +2 -20
- package/src/notifications/approval-card-data.ts +333 -0
- package/src/notifications/broadcaster.ts +16 -3
- package/src/notifications/canonical-delivery-recorder.ts +139 -0
- package/src/notifications/copy-composer.ts +3 -3
- package/src/notifications/decision-engine.ts +4 -2
- package/src/notifications/destination-resolver.ts +4 -6
- package/src/notifications/guardian-question-mode.ts +10 -0
- package/src/notifications/home-feed-side-effect.ts +7 -16
- package/src/notifications/notification-utils.ts +19 -20
- package/src/notifications/signal.ts +79 -43
- package/src/notifications/types.ts +98 -121
- package/src/oauth/AGENTS.md +5 -24
- package/src/permissions/checker.test.ts +51 -0
- package/src/permissions/checker.ts +185 -26
- package/src/permissions/ipc-risk-types.ts +24 -0
- package/src/permissions/question-prompter.test.ts +27 -0
- package/src/permissions/question-prompter.ts +4 -0
- package/src/platform/client.test.ts +119 -0
- package/src/platform/client.ts +66 -0
- package/src/platform/consent-cache.test.ts +267 -0
- package/src/platform/consent-cache.ts +174 -0
- package/src/plugin-api/constants.ts +1 -1
- package/src/plugin-api/index.ts +33 -1
- package/src/plugin-api/model-profiles.ts +33 -0
- package/src/plugin-api/types.ts +50 -2
- package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
- package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
- package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
- package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
- package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
- package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
- package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
- package/src/plugins/defaults/advisor/config.ts +21 -0
- package/src/plugins/defaults/advisor/consult.ts +93 -0
- package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
- package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
- package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/advisor/package.json +14 -0
- package/src/plugins/defaults/advisor/steering.ts +67 -0
- package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
- package/src/plugins/defaults/advisor/transcript.ts +76 -0
- package/src/plugins/defaults/index.ts +60 -0
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +129 -9
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +144 -11
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
- package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +276 -0
- package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +22 -0
- package/src/plugins/defaults/surface-completion-nudge/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/surface-completion-nudge/package.json +14 -0
- package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +3 -13
- package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
- package/src/prompts/persona-resolver.ts +14 -4
- package/src/prompts/templates/system-sections.ts +7 -2
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
- package/src/providers/__tests__/retry-callsite.test.ts +176 -0
- package/src/providers/atlascloud/client.ts +85 -0
- package/src/providers/fetch-provider-catalog.ts +85 -0
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/model-catalog.ts +58 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
- package/src/providers/openai/chat-completions-provider.ts +7 -0
- package/src/providers/openai/responses-provider.ts +10 -0
- package/src/providers/provider-send-message.ts +11 -3
- package/src/providers/retry.ts +53 -12
- package/src/providers/search-provider-catalog.ts +10 -0
- package/src/providers/weak-open-model.ts +22 -0
- package/src/runtime/AGENTS.md +0 -1
- package/src/runtime/__tests__/agent-wake.test.ts +181 -0
- package/src/runtime/__tests__/client-health.test.ts +44 -0
- package/src/runtime/access-request-helper.ts +21 -53
- package/src/runtime/actor-trust-resolver.ts +59 -63
- package/src/runtime/agent-wake.ts +52 -0
- package/src/runtime/assistant-event-hub.ts +18 -4
- package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
- package/src/runtime/auth/require-bound-guardian.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -6
- package/src/runtime/capabilities.test.ts +120 -0
- package/src/runtime/capabilities.ts +197 -0
- package/src/runtime/channel-approval-types.ts +22 -45
- package/src/runtime/channel-invite-transports/telegram.ts +4 -4
- package/src/runtime/channel-retry-sweep.ts +1 -0
- package/src/runtime/channel-verification-service.ts +3 -3
- package/src/runtime/client-health.ts +26 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
- package/src/runtime/effective-capabilities.test.ts +128 -0
- package/src/runtime/effective-capabilities.ts +84 -0
- package/src/runtime/guardian-reply-router.ts +106 -21
- package/src/runtime/invite-redemption-service.ts +9 -25
- package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +123 -0
- package/src/runtime/migrations/vbundle-builder.ts +49 -20
- package/src/runtime/pending-interactions.ts +15 -0
- package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +240 -1
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -2
- package/src/runtime/routes/assets/vellum-design-system.css +1959 -0
- package/src/runtime/routes/browser-tabs-routes.ts +9 -0
- package/src/runtime/routes/btw-routes.ts +1 -27
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
- package/src/runtime/routes/client-routes.ts +10 -0
- package/src/runtime/routes/contact-routes.ts +31 -8
- package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
- package/src/runtime/routes/conversation-management-routes.ts +80 -1
- package/src/runtime/routes/conversation-query-routes.ts +68 -22
- package/src/runtime/routes/conversation-routes.ts +39 -14
- package/src/runtime/routes/credential-routes.ts +40 -16
- package/src/runtime/routes/empty-state-greeting-cache.ts +1 -2
- package/src/runtime/routes/events-routes.ts +1 -3
- package/src/runtime/routes/guardian-approval-interception.ts +14 -73
- package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
- package/src/runtime/routes/home-feed-routes.ts +8 -3
- package/src/runtime/routes/identity-routes.ts +1 -296
- package/src/runtime/routes/inbound-message-handler.ts +214 -228
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +89 -7
- package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
- package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
- package/src/runtime/routes/integrations/slack/channel.ts +36 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
- package/src/runtime/routes/mcp-auth-routes.ts +233 -41
- package/src/runtime/routes/memory-eval-routes.ts +87 -0
- package/src/runtime/routes/notification-routes.ts +122 -133
- package/src/runtime/routes/platform-routes.ts +2 -2
- package/src/runtime/routes/plugins-routes.ts +202 -3
- package/src/runtime/routes/schedule-routes.ts +0 -22
- package/src/runtime/routes/secret-routes.ts +10 -0
- package/src/runtime/routes/surface-action-routes.ts +2 -1
- package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
- package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
- package/src/runtime/routes/workflow-routes.test.ts +229 -44
- package/src/runtime/routes/workflow-routes.ts +131 -29
- package/src/runtime/routes/workspace-greetings.ts +55 -0
- package/src/runtime/sync/resource-sync-events.ts +1 -11
- package/src/runtime/tool-grant-request-helper.ts +18 -16
- package/src/runtime/trust-context-resolver.ts +8 -5
- package/src/schedule/inference-profile.ts +2 -14
- package/src/schedule/schedule-store.ts +1 -1
- package/src/schedule/scheduler-types.ts +5 -1
- package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
- package/src/security/secret-patterns.ts +3 -0
- package/src/subagent/manager.ts +17 -4
- package/src/subagent/types.ts +6 -0
- package/src/telemetry/trace-collection-policy.test.ts +28 -0
- package/src/telemetry/trace-collection-policy.ts +30 -0
- package/src/telemetry/types.ts +89 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
- package/src/telemetry/usage-telemetry-reporter.ts +148 -41
- package/src/tools/AGENTS.md +3 -3
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
- package/src/tools/browser/browser-execution.ts +30 -19
- package/src/tools/document/document-tool.ts +2 -3
- package/src/tools/executor.ts +5 -3
- package/src/tools/host-terminal/host-shell.ts +5 -4
- package/src/tools/memory/register.ts +2 -2
- package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
- package/src/tools/network/__tests__/web-search.test.ts +143 -0
- package/src/tools/network/web-fetch.ts +372 -1
- package/src/tools/network/web-search-error.ts +1 -1
- package/src/tools/network/web-search.ts +213 -10
- package/src/tools/permission-checker.ts +4 -3
- package/src/tools/registry.ts +20 -0
- package/src/tools/schedule/create.ts +7 -12
- package/src/tools/schedule/update.ts +4 -11
- package/src/tools/shared/filesystem/path-policy.ts +39 -13
- package/src/tools/side-effects.ts +2 -17
- package/src/tools/skills/execute.ts +33 -0
- package/src/tools/subagent/spawn.ts +61 -12
- package/src/tools/terminal/shell.ts +10 -4
- package/src/tools/tool-approval-handler.ts +18 -13
- package/src/tools/tool-manifest.ts +0 -2
- package/src/tools/types.ts +9 -0
- package/src/tools/ui-surface/definitions.ts +64 -3
- package/src/tools/verification-control-plane-policy.ts +3 -1
- package/src/tools/workflows/run-workflow.test.ts +8 -18
- package/src/tools/workflows/run-workflow.ts +1 -0
- package/src/util/disk-usage.ts +78 -23
- package/src/util/platform.ts +10 -3
- package/src/watcher/telemetry.ts +2 -2
- package/src/workflows/capabilities.ts +2 -3
- package/src/workflows/engine.test.ts +175 -1
- package/src/workflows/engine.ts +82 -0
- package/src/workflows/journal-store.test.ts +70 -0
- package/src/workflows/journal-store.ts +18 -3
- package/src/workflows/run-manager.test.ts +171 -28
- package/src/workflows/run-manager.ts +66 -24
- package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
- package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
- package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
- package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +0 -98
- package/src/__tests__/credential-security-e2e.test.ts +0 -362
- package/src/__tests__/credential-vault-unit.test.ts +0 -1528
- package/src/__tests__/credential-vault.test.ts +0 -1706
- package/src/__tests__/identity-intro-cache.test.ts +0 -315
- package/src/__tests__/secret-onetime-send.test.ts +0 -182
- package/src/cli/commands/__tests__/task.test.ts +0 -914
- package/src/cli/commands/task.ts +0 -771
- package/src/config/bundled-skills/personal-page/SKILL.md +0 -57
- package/src/config/bundled-skills/personal-page/TOOLS.json +0 -27
- package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +0 -17
- package/src/config/preloaded-apps/personal-page/src/components/About.tsx +0 -22
- package/src/config/preloaded-apps/personal-page/src/components/App.tsx +0 -16
- package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +0 -77
- package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +0 -57
- package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +0 -28
- package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +0 -234
- package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +0 -48
- package/src/config/preloaded-apps/personal-page/src/components/media.ts +0 -16
- package/src/config/preloaded-apps/personal-page/src/index.html +0 -20
- package/src/config/preloaded-apps/personal-page/src/main.tsx +0 -7
- package/src/config/preloaded-apps/personal-page/src/profile-data.ts +0 -82
- package/src/config/preloaded-apps/personal-page/src/styles.css +0 -759
- package/src/memory/__tests__/preloaded-apps.test.ts +0 -85
- package/src/memory/preloaded-apps.ts +0 -116
- package/src/notifications/tool-approval-copy.ts +0 -142
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
- package/src/runtime/routes/identity-intro-cache.ts +0 -172
- package/src/tools/credentials/vault.ts +0 -712
|
@@ -22,57 +22,6 @@ mock.module("../util/logger.js", () => ({
|
|
|
22
22
|
}),
|
|
23
23
|
}));
|
|
24
24
|
|
|
25
|
-
const checkpointStore = new Map<string, string>();
|
|
26
|
-
|
|
27
|
-
mock.module("../memory/checkpoints.js", () => ({
|
|
28
|
-
getMemoryCheckpoint: (key: string) => checkpointStore.get(key) ?? null,
|
|
29
|
-
setMemoryCheckpoint: (key: string, value: string) => {
|
|
30
|
-
checkpointStore.set(key, value);
|
|
31
|
-
},
|
|
32
|
-
}));
|
|
33
|
-
|
|
34
|
-
const getConfiguredProviderCalls: string[] = [];
|
|
35
|
-
const mockProvider = { name: "mock-provider" };
|
|
36
|
-
|
|
37
|
-
mock.module("../providers/provider-send-message.js", () => ({
|
|
38
|
-
getConfiguredProvider: mock(async (callSite: string) => {
|
|
39
|
-
getConfiguredProviderCalls.push(callSite);
|
|
40
|
-
return mockProvider;
|
|
41
|
-
}),
|
|
42
|
-
}));
|
|
43
|
-
|
|
44
|
-
type SidechainCall = {
|
|
45
|
-
callSite?: string;
|
|
46
|
-
content: string;
|
|
47
|
-
maxTokens?: number;
|
|
48
|
-
systemPrompt?: string;
|
|
49
|
-
tools: unknown[];
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
type SidechainResult = {
|
|
53
|
-
text: string;
|
|
54
|
-
hadTextDeltas: false;
|
|
55
|
-
response: { content: [] };
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const sidechainCalls: SidechainCall[] = [];
|
|
59
|
-
let sidechainText = "";
|
|
60
|
-
let sidechainResultPromise: Promise<SidechainResult> | null = null;
|
|
61
|
-
|
|
62
|
-
mock.module("../runtime/btw-sidechain.js", () => ({
|
|
63
|
-
runBtwSidechain: mock(async (params: SidechainCall) => {
|
|
64
|
-
sidechainCalls.push(params);
|
|
65
|
-
if (sidechainResultPromise) {
|
|
66
|
-
return sidechainResultPromise;
|
|
67
|
-
}
|
|
68
|
-
return {
|
|
69
|
-
text: sidechainText,
|
|
70
|
-
hadTextDeltas: false,
|
|
71
|
-
response: { content: [] },
|
|
72
|
-
};
|
|
73
|
-
}),
|
|
74
|
-
}));
|
|
75
|
-
|
|
76
25
|
import {
|
|
77
26
|
handleDetailedHealth,
|
|
78
27
|
handleReadyz,
|
|
@@ -86,17 +35,6 @@ import {
|
|
|
86
35
|
selectHatchedAtFromStats,
|
|
87
36
|
} from "../workspace/hatched-date.js";
|
|
88
37
|
|
|
89
|
-
function createDeferred<T>(): {
|
|
90
|
-
promise: Promise<T>;
|
|
91
|
-
resolve: (value: T) => void;
|
|
92
|
-
} {
|
|
93
|
-
let resolve!: (value: T) => void;
|
|
94
|
-
const promise = new Promise<T>((res) => {
|
|
95
|
-
resolve = res;
|
|
96
|
-
});
|
|
97
|
-
return { promise, resolve };
|
|
98
|
-
}
|
|
99
|
-
|
|
100
38
|
// ── Env helpers ─────────────────────────────────────────────────────────
|
|
101
39
|
|
|
102
40
|
let savedEnv: Record<string, string | undefined>;
|
|
@@ -194,11 +132,6 @@ beforeEach(() => {
|
|
|
194
132
|
rmSync(getHatchedSidecarPath(), { force: true });
|
|
195
133
|
rmSync(join(getWorkspaceDir(), "IDENTITY.md"), { force: true });
|
|
196
134
|
rmSync(join(getWorkspaceDir(), "SOUL.md"), { force: true });
|
|
197
|
-
checkpointStore.clear();
|
|
198
|
-
getConfiguredProviderCalls.length = 0;
|
|
199
|
-
sidechainCalls.length = 0;
|
|
200
|
-
sidechainText = "";
|
|
201
|
-
sidechainResultPromise = null;
|
|
202
135
|
});
|
|
203
136
|
|
|
204
137
|
afterEach(() => {
|
|
@@ -564,125 +497,3 @@ describe("identity routes — createdAt selection", () => {
|
|
|
564
497
|
expect(existsSync(getHatchedSidecarPath())).toBe(false);
|
|
565
498
|
});
|
|
566
499
|
});
|
|
567
|
-
|
|
568
|
-
describe("identity routes — intro greetings", () => {
|
|
569
|
-
test("returns fallback immediately, generates personalized greetings in the background, then reuses the cache", async () => {
|
|
570
|
-
const workspaceDir = getWorkspaceDir();
|
|
571
|
-
writeFileSync(
|
|
572
|
-
join(workspaceDir, "IDENTITY.md"),
|
|
573
|
-
[
|
|
574
|
-
"# Identity",
|
|
575
|
-
"",
|
|
576
|
-
"- **Name:** Example Assistant",
|
|
577
|
-
"- **Personality:** enjoys crisp, useful hellos",
|
|
578
|
-
"",
|
|
579
|
-
"Identity sentinel: chartreuse compass.",
|
|
580
|
-
].join("\n"),
|
|
581
|
-
"utf-8",
|
|
582
|
-
);
|
|
583
|
-
writeFileSync(
|
|
584
|
-
join(workspaceDir, "SOUL.md"),
|
|
585
|
-
[
|
|
586
|
-
"# Soul",
|
|
587
|
-
"",
|
|
588
|
-
"Soul sentinel: copper lighthouse.",
|
|
589
|
-
"",
|
|
590
|
-
"Keep greetings warm and specific.",
|
|
591
|
-
].join("\n"),
|
|
592
|
-
"utf-8",
|
|
593
|
-
);
|
|
594
|
-
const deferredSidechain = createDeferred<SidechainResult>();
|
|
595
|
-
sidechainResultPromise = deferredSidechain.promise;
|
|
596
|
-
|
|
597
|
-
const route = ROUTES.find(
|
|
598
|
-
(candidate) => candidate.operationId === "identity_intro",
|
|
599
|
-
);
|
|
600
|
-
expect(route).toBeDefined();
|
|
601
|
-
|
|
602
|
-
const body = route!.handler({
|
|
603
|
-
queryParams: { localHour: "8", localMinute: "15" },
|
|
604
|
-
}) as {
|
|
605
|
-
greetings: string[];
|
|
606
|
-
text: string;
|
|
607
|
-
source: string;
|
|
608
|
-
refreshing: boolean;
|
|
609
|
-
};
|
|
610
|
-
|
|
611
|
-
expect(body).toEqual({
|
|
612
|
-
greetings: [
|
|
613
|
-
"What are we working on?",
|
|
614
|
-
"I'm here whenever you need me.",
|
|
615
|
-
"What's on your mind?",
|
|
616
|
-
"Ready when you are.",
|
|
617
|
-
],
|
|
618
|
-
text: "What are we working on?",
|
|
619
|
-
source: "fallback",
|
|
620
|
-
refreshing: true,
|
|
621
|
-
});
|
|
622
|
-
expect(getConfiguredProviderCalls).toEqual([]);
|
|
623
|
-
expect(sidechainCalls).toEqual([]);
|
|
624
|
-
|
|
625
|
-
await Promise.resolve();
|
|
626
|
-
await Promise.resolve();
|
|
627
|
-
|
|
628
|
-
expect(getConfiguredProviderCalls).toEqual(["emptyStateGreeting"]);
|
|
629
|
-
expect(sidechainCalls).toHaveLength(1);
|
|
630
|
-
expect(sidechainCalls[0]?.callSite).toBe("emptyStateGreeting");
|
|
631
|
-
expect(sidechainCalls[0]?.tools).toEqual([]);
|
|
632
|
-
expect(sidechainCalls[0]?.content).toContain("Generate 5 short");
|
|
633
|
-
expect(sidechainCalls[0]?.content).not.toContain("Current time of day:");
|
|
634
|
-
expect(sidechainCalls[0]?.content).toContain(
|
|
635
|
-
"do not mention the current time",
|
|
636
|
-
);
|
|
637
|
-
expect(sidechainCalls[0]?.content).toMatch(
|
|
638
|
-
/Current user-local time for subtle tone only: morning \(08:15\)\.$/,
|
|
639
|
-
);
|
|
640
|
-
expect(sidechainCalls[0]?.content).toContain("JSON array");
|
|
641
|
-
expect(sidechainCalls[0]?.systemPrompt).toContain(
|
|
642
|
-
"Identity sentinel: chartreuse compass.",
|
|
643
|
-
);
|
|
644
|
-
expect(sidechainCalls[0]?.systemPrompt).toContain(
|
|
645
|
-
"Soul sentinel: copper lighthouse.",
|
|
646
|
-
);
|
|
647
|
-
deferredSidechain.resolve({
|
|
648
|
-
text: JSON.stringify([
|
|
649
|
-
"Charting the next useful thing?",
|
|
650
|
-
"I brought the compass. Where to?",
|
|
651
|
-
"Ready to make this lighter.",
|
|
652
|
-
"Morning momentum?",
|
|
653
|
-
"Five options, one good start.",
|
|
654
|
-
"A useful next step?",
|
|
655
|
-
]),
|
|
656
|
-
hadTextDeltas: false,
|
|
657
|
-
response: { content: [] },
|
|
658
|
-
});
|
|
659
|
-
|
|
660
|
-
await sidechainResultPromise;
|
|
661
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
662
|
-
|
|
663
|
-
sidechainCalls.length = 0;
|
|
664
|
-
getConfiguredProviderCalls.length = 0;
|
|
665
|
-
|
|
666
|
-
const cachedBody = (await route!.handler({})) as {
|
|
667
|
-
greetings: string[];
|
|
668
|
-
text: string;
|
|
669
|
-
source: string;
|
|
670
|
-
refreshing: boolean;
|
|
671
|
-
};
|
|
672
|
-
|
|
673
|
-
expect(cachedBody).toEqual({
|
|
674
|
-
greetings: [
|
|
675
|
-
"Charting the next useful thing?",
|
|
676
|
-
"I brought the compass. Where to?",
|
|
677
|
-
"Ready to make this lighter.",
|
|
678
|
-
"Five options, one good start.",
|
|
679
|
-
"A useful next step?",
|
|
680
|
-
],
|
|
681
|
-
text: "Charting the next useful thing?",
|
|
682
|
-
source: "cache",
|
|
683
|
-
refreshing: false,
|
|
684
|
-
});
|
|
685
|
-
expect(getConfiguredProviderCalls).toEqual([]);
|
|
686
|
-
expect(sidechainCalls).toEqual([]);
|
|
687
|
-
});
|
|
688
|
-
});
|
|
@@ -173,7 +173,7 @@ describe("inbound invite redemption intercept", () => {
|
|
|
173
173
|
// Verify the user is now an active member
|
|
174
174
|
const result = findContactChannel({
|
|
175
175
|
channelType: "telegram",
|
|
176
|
-
|
|
176
|
+
address: "user-invite-123",
|
|
177
177
|
});
|
|
178
178
|
expect(result).not.toBeNull();
|
|
179
179
|
expect(result!.channel.status).toBe("active");
|
|
@@ -203,7 +203,7 @@ describe("inbound invite redemption intercept", () => {
|
|
|
203
203
|
// Verify the user was NOT made a member
|
|
204
204
|
const result = findContactChannel({
|
|
205
205
|
channelType: "telegram",
|
|
206
|
-
|
|
206
|
+
address: "user-invite-123",
|
|
207
207
|
});
|
|
208
208
|
expect(result).toBeNull();
|
|
209
209
|
});
|
|
@@ -400,7 +400,7 @@ describe("inbound invite redemption intercept", () => {
|
|
|
400
400
|
// its ID as the invite's contactId (satisfies the FK constraint).
|
|
401
401
|
const existing = findContactChannel({
|
|
402
402
|
channelType: "telegram",
|
|
403
|
-
|
|
403
|
+
address: "user-invite-123",
|
|
404
404
|
externalChatId: "chat-invite-test",
|
|
405
405
|
});
|
|
406
406
|
const targetContactId = existing!.contact.id;
|
|
@@ -422,7 +422,7 @@ describe("inbound invite redemption intercept", () => {
|
|
|
422
422
|
|
|
423
423
|
const result = findContactChannel({
|
|
424
424
|
channelType: "telegram",
|
|
425
|
-
|
|
425
|
+
address: "user-invite-123",
|
|
426
426
|
externalChatId: "chat-invite-test",
|
|
427
427
|
});
|
|
428
428
|
expect(result).not.toBeNull();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Tests for the memory-v3 step-0 branch in `applyRuntimeInjections`:
|
|
3
3
|
* spotlight strip + v2 tail suppression.
|
|
4
4
|
*
|
|
5
|
-
* When
|
|
5
|
+
* When `memory.v3.live` is on AND the v3 injector (id `memory-v3`,
|
|
6
6
|
* placement `after-memory-prefix`) produces a block — possibly EMPTY-TEXT on
|
|
7
7
|
* an all-repeat turn — runtime assembly strips the v2 `<memory>` prefix from
|
|
8
8
|
* the TAIL user message only before splicing the v3 block. Historical user
|
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
* block lands at the tail.
|
|
17
17
|
*
|
|
18
18
|
* v2 suppression stays keyed off whether v3 produced a block, NOT off the
|
|
19
|
-
*
|
|
20
|
-
* (fallback-to-v2). The
|
|
19
|
+
* gate alone: a v3 failure (`produce()` → null) leaves v2's block intact
|
|
20
|
+
* (fallback-to-v2). The v3-off path must be byte-for-byte identical to
|
|
21
21
|
* today — that is the load-bearing regression guard. `applyRuntimeInjections`
|
|
22
|
-
* reads the
|
|
22
|
+
* reads the v3-live gate itself, so these tests drive it through the
|
|
23
|
+
* `isMemoryV3Live` mock slot.
|
|
23
24
|
*
|
|
24
25
|
* The strip discriminates v2's dynamic block by IDENTITY, not by prefix: v2's
|
|
25
26
|
* `INJECTION_HEADER` and v3's `V3_CARDS_INJECTION_HEADER` are deliberately
|
|
@@ -42,7 +43,6 @@ import type {
|
|
|
42
43
|
TurnContext,
|
|
43
44
|
} from "../plugins/types.js";
|
|
44
45
|
import type { Message } from "../providers/types.js";
|
|
45
|
-
import { setOverridesForTesting } from "./feature-flag-test-helpers.js";
|
|
46
46
|
|
|
47
47
|
// Drive the suppression branch by controlling the static injector chain that
|
|
48
48
|
// `applyRuntimeInjections` walks. The slot is mutated per-test to stand in for
|
|
@@ -52,6 +52,13 @@ mock.module("../plugins/defaults/memory-retrieval/injector-chain.js", () => ({
|
|
|
52
52
|
getInjectorChain: () => injectorChainSlot,
|
|
53
53
|
}));
|
|
54
54
|
|
|
55
|
+
// `applyRuntimeInjections` reads the v3-live gate (`config.memory.v3.live`)
|
|
56
|
+
// via `isMemoryV3Live`; drive it directly through this slot per-test.
|
|
57
|
+
let memoryV3LiveSlot = false;
|
|
58
|
+
mock.module("../config/memory-v3-gate.js", () => ({
|
|
59
|
+
isMemoryV3Live: () => memoryV3LiveSlot,
|
|
60
|
+
}));
|
|
61
|
+
|
|
55
62
|
const { applyRuntimeInjections } =
|
|
56
63
|
await import("../daemon/conversation-runtime-assembly.js");
|
|
57
64
|
|
|
@@ -141,9 +148,9 @@ function tailTexts(messages: Message[]): string[] {
|
|
|
141
148
|
describe("memory-v3-live v2 suppression", () => {
|
|
142
149
|
beforeEach(() => {
|
|
143
150
|
injectorChainSlot.length = 0;
|
|
144
|
-
// Clean baseline:
|
|
145
|
-
//
|
|
146
|
-
|
|
151
|
+
// Clean baseline: v3-live off (registry/config default). Each test seeds
|
|
152
|
+
// the gate value it needs.
|
|
153
|
+
memoryV3LiveSlot = false;
|
|
147
154
|
});
|
|
148
155
|
|
|
149
156
|
afterEach(() => {
|
|
@@ -152,7 +159,7 @@ describe("memory-v3-live v2 suppression", () => {
|
|
|
152
159
|
});
|
|
153
160
|
|
|
154
161
|
test("flag ON + v3 produced a block → TAIL v2 stripped, historical memory blocks frozen in place", async () => {
|
|
155
|
-
|
|
162
|
+
memoryV3LiveSlot = true;
|
|
156
163
|
injectorChainSlot.push(v3Injector("net-new cards"));
|
|
157
164
|
seedV2Identity("fresh recalled fact");
|
|
158
165
|
|
|
@@ -194,7 +201,7 @@ describe("memory-v3-live v2 suppression", () => {
|
|
|
194
201
|
});
|
|
195
202
|
|
|
196
203
|
test("flag ON + EMPTY-TEXT v3 block (all-repeat turn) → tail v2 stripped, nothing attached", async () => {
|
|
197
|
-
|
|
204
|
+
memoryV3LiveSlot = true;
|
|
198
205
|
injectorChainSlot.push(v3Injector(""));
|
|
199
206
|
seedV2Identity("fresh recalled fact");
|
|
200
207
|
|
|
@@ -217,7 +224,7 @@ describe("memory-v3-live v2 suppression", () => {
|
|
|
217
224
|
});
|
|
218
225
|
|
|
219
226
|
test("stale spotlight blocks are stripped from EVERY user message; the new spotlight lands at the tail", async () => {
|
|
220
|
-
|
|
227
|
+
memoryV3LiveSlot = true;
|
|
221
228
|
injectorChainSlot.push(v3Injector(""), spotlightInjector("fresh sections"));
|
|
222
229
|
|
|
223
230
|
const staleSpotlight = {
|
|
@@ -253,7 +260,7 @@ describe("memory-v3-live v2 suppression", () => {
|
|
|
253
260
|
});
|
|
254
261
|
|
|
255
262
|
test("convergence re-entry: a tail leading with this turn's frozen v3 cards (and <info>) is NOT stripped", async () => {
|
|
256
|
-
|
|
263
|
+
memoryV3LiveSlot = true;
|
|
257
264
|
// Re-entry shape: the memo returns the same selections, every slug is now
|
|
258
265
|
// in the everInjected store, so the injector produces an EMPTY block —
|
|
259
266
|
// while the tail still carries the v3 card block frozen on first entry
|
|
@@ -292,7 +299,7 @@ describe("memory-v3-live v2 suppression", () => {
|
|
|
292
299
|
});
|
|
293
300
|
|
|
294
301
|
test("first entry with a v2 prefix AND a frozen v3 block strips ONLY the v2 block", async () => {
|
|
295
|
-
|
|
302
|
+
memoryV3LiveSlot = true;
|
|
296
303
|
injectorChainSlot.push(v3Injector(""));
|
|
297
304
|
seedV2Identity("fresh recalled fact");
|
|
298
305
|
|
|
@@ -319,7 +326,7 @@ describe("memory-v3-live v2 suppression", () => {
|
|
|
319
326
|
});
|
|
320
327
|
|
|
321
328
|
test("REGRESSION: a v2 block leading with the REAL summary header (byte-identical to v3's) is stripped; v3 cards and <info> survive (first entry)", async () => {
|
|
322
|
-
|
|
329
|
+
memoryV3LiveSlot = true;
|
|
323
330
|
injectorChainSlot.push(v3Injector(""));
|
|
324
331
|
|
|
325
332
|
// The collision this guards: v2's router block leads with
|
|
@@ -358,7 +365,7 @@ describe("memory-v3-live v2 suppression", () => {
|
|
|
358
365
|
});
|
|
359
366
|
|
|
360
367
|
test("REGRESSION: re-entry with a header-bearing v2 identity keeps the first entry's frozen v3 cards", async () => {
|
|
361
|
-
|
|
368
|
+
memoryV3LiveSlot = true;
|
|
362
369
|
// Re-entry: produce() returns the EMPTY block (cards already claimed by
|
|
363
370
|
// the store) while the tail carries the FIRST entry's v3 block — and the
|
|
364
371
|
// graph handle still holds the summary-bearing v2 identity from this
|
|
@@ -391,7 +398,7 @@ describe("memory-v3-live v2 suppression", () => {
|
|
|
391
398
|
});
|
|
392
399
|
|
|
393
400
|
test("v2 memory-image groups and legacy <memory __injected> blocks are stripped even without an identity", async () => {
|
|
394
|
-
|
|
401
|
+
memoryV3LiveSlot = true;
|
|
395
402
|
injectorChainSlot.push(v3Injector("net-new cards"));
|
|
396
403
|
// No live graph handle: identity unknown (null). Image groups and legacy
|
|
397
404
|
// blocks are unambiguously v2's and are stripped regardless; the shared
|
|
@@ -430,7 +437,7 @@ describe("memory-v3-live v2 suppression", () => {
|
|
|
430
437
|
});
|
|
431
438
|
|
|
432
439
|
test("the v3 block's attachment-commit callback fires on a user tail", async () => {
|
|
433
|
-
|
|
440
|
+
memoryV3LiveSlot = true;
|
|
434
441
|
const commit = mock(() => {});
|
|
435
442
|
injectorChainSlot.push(v3Injector("net-new cards", commit));
|
|
436
443
|
|
|
@@ -443,7 +450,7 @@ describe("memory-v3-live v2 suppression", () => {
|
|
|
443
450
|
});
|
|
444
451
|
|
|
445
452
|
test("the commit callback is SKIPPED when the tail is not a user message (block never attaches)", async () => {
|
|
446
|
-
|
|
453
|
+
memoryV3LiveSlot = true;
|
|
447
454
|
const commit = mock(() => {});
|
|
448
455
|
injectorChainSlot.push(v3Injector("net-new cards", commit));
|
|
449
456
|
|
|
@@ -465,7 +472,7 @@ describe("memory-v3-live v2 suppression", () => {
|
|
|
465
472
|
});
|
|
466
473
|
|
|
467
474
|
test("flag ON but v3 produced NOTHING → v2 block left intact (fallback-to-v2)", async () => {
|
|
468
|
-
|
|
475
|
+
memoryV3LiveSlot = true;
|
|
469
476
|
injectorChainSlot.push(v3Injector(null));
|
|
470
477
|
|
|
471
478
|
const runMessages: Message[] = [
|
|
@@ -524,7 +531,7 @@ describe("memory-v3-live v2 suppression", () => {
|
|
|
524
531
|
test("no v3 injector registered + flag ON → no stripping, messages untouched", async () => {
|
|
525
532
|
// No injector named memory-v3 at all (e.g. plugin not loaded): the
|
|
526
533
|
// suppression branch keys off the produced block, so nothing is stripped.
|
|
527
|
-
|
|
534
|
+
memoryV3LiveSlot = true;
|
|
528
535
|
expect(injectorChainSlot).toHaveLength(0);
|
|
529
536
|
|
|
530
537
|
const runMessages: Message[] = [
|
|
@@ -7,23 +7,15 @@ mock.module("../util/logger.js", () => ({
|
|
|
7
7
|
}),
|
|
8
8
|
}));
|
|
9
9
|
|
|
10
|
-
// Toggle for the
|
|
10
|
+
// Toggle for the share_analytics opt-out the real store consults. The store
|
|
11
11
|
// module is intentionally NOT mocked here — it has its own DB-backed tests, and
|
|
12
12
|
// Bun's `mock.module` is process-global, so mocking it would leak into those
|
|
13
13
|
// tests when files share an invocation. Exercising the real store keeps every
|
|
14
14
|
// auth-fallback test order-independent.
|
|
15
|
-
let
|
|
15
|
+
let shareAnalytics = true;
|
|
16
16
|
|
|
17
|
-
mock.module("../
|
|
18
|
-
|
|
19
|
-
ui: {},
|
|
20
|
-
model: "test",
|
|
21
|
-
provider: "test",
|
|
22
|
-
memory: { enabled: false },
|
|
23
|
-
rateLimit: { maxRequestsPerMinute: 0 },
|
|
24
|
-
secretDetection: { enabled: false },
|
|
25
|
-
collectUsageData,
|
|
26
|
-
}),
|
|
17
|
+
mock.module("../platform/consent-cache.js", () => ({
|
|
18
|
+
getCachedShareAnalytics: () => shareAnalytics,
|
|
27
19
|
}));
|
|
28
20
|
|
|
29
21
|
import { queryUnreportedAuthFallbackEvents } from "../memory/auth-fallback-events-store.js";
|
|
@@ -61,7 +53,7 @@ const VALID_BODY = {
|
|
|
61
53
|
|
|
62
54
|
describe("internal-telemetry-routes: auth-fallback", () => {
|
|
63
55
|
beforeEach(() => {
|
|
64
|
-
|
|
56
|
+
shareAnalytics = true;
|
|
65
57
|
getDb().delete(authFallbackEvents).run();
|
|
66
58
|
});
|
|
67
59
|
|
|
@@ -90,7 +82,7 @@ describe("internal-telemetry-routes: auth-fallback", () => {
|
|
|
90
82
|
});
|
|
91
83
|
|
|
92
84
|
test("returns skipped and persists nothing under the opt-out", () => {
|
|
93
|
-
|
|
85
|
+
shareAnalytics = false;
|
|
94
86
|
expect(call(VALID_BODY)).toEqual({ skipped: true });
|
|
95
87
|
expect(queryUnreportedAuthFallbackEvents(0, undefined, 100).length).toBe(0);
|
|
96
88
|
});
|
|
@@ -83,7 +83,7 @@ describe("invite-redemption-service", () => {
|
|
|
83
83
|
|
|
84
84
|
const result = findContactChannel({
|
|
85
85
|
channelType: "telegram",
|
|
86
|
-
|
|
86
|
+
address: "user-1",
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
expect(result).not.toBeNull();
|
|
@@ -112,7 +112,7 @@ describe("invite-redemption-service", () => {
|
|
|
112
112
|
|
|
113
113
|
const result = findContactChannel({
|
|
114
114
|
channelType: "telegram",
|
|
115
|
-
|
|
115
|
+
address: "code-user-1",
|
|
116
116
|
});
|
|
117
117
|
|
|
118
118
|
expect(result).not.toBeNull();
|
|
@@ -292,7 +292,6 @@ describe("invite-redemption-service", () => {
|
|
|
292
292
|
{
|
|
293
293
|
type: "telegram",
|
|
294
294
|
address: "guardian-tg-id",
|
|
295
|
-
externalUserId: "guardian-tg-id",
|
|
296
295
|
status: "revoked",
|
|
297
296
|
},
|
|
298
297
|
],
|
|
@@ -325,7 +324,7 @@ describe("invite-redemption-service", () => {
|
|
|
325
324
|
// Verify the redeemer's Telegram ID is now bound to Mom's contact
|
|
326
325
|
const result = findContactChannel({
|
|
327
326
|
channelType: "telegram",
|
|
328
|
-
|
|
327
|
+
address: "guardian-tg-id",
|
|
329
328
|
});
|
|
330
329
|
expect(result).not.toBeNull();
|
|
331
330
|
expect(result!.contact.id).toBe(momContact.id);
|
|
@@ -346,7 +345,6 @@ describe("invite-redemption-service", () => {
|
|
|
346
345
|
{
|
|
347
346
|
type: "telegram",
|
|
348
347
|
address: "guardian-own-id",
|
|
349
|
-
externalUserId: "guardian-own-id",
|
|
350
348
|
status: "revoked",
|
|
351
349
|
},
|
|
352
350
|
],
|
|
@@ -381,7 +379,6 @@ describe("invite-redemption-service", () => {
|
|
|
381
379
|
{
|
|
382
380
|
type: "telegram",
|
|
383
381
|
address: "guardian-code-id",
|
|
384
|
-
externalUserId: "guardian-code-id",
|
|
385
382
|
status: "revoked",
|
|
386
383
|
},
|
|
387
384
|
],
|
|
@@ -417,7 +414,7 @@ describe("invite-redemption-service", () => {
|
|
|
417
414
|
// Verify the redeemer's Telegram ID is now bound to Mom's contact
|
|
418
415
|
const result = findContactChannel({
|
|
419
416
|
channelType: "telegram",
|
|
420
|
-
|
|
417
|
+
address: "guardian-code-id",
|
|
421
418
|
});
|
|
422
419
|
expect(result).not.toBeNull();
|
|
423
420
|
expect(result!.contact.id).toBe(momContact.id);
|
|
@@ -54,9 +54,7 @@ describe("LLM call-site catalog", () => {
|
|
|
54
54
|
|
|
55
55
|
test("CALL_SITE_DEFAULTS covers every LLMCallSite enum value", () => {
|
|
56
56
|
const defaultIds = new Set(Object.keys(CALL_SITE_DEFAULTS));
|
|
57
|
-
const missing = LLMCallSiteEnum.options.filter(
|
|
58
|
-
(id) => !defaultIds.has(id),
|
|
59
|
-
);
|
|
57
|
+
const missing = LLMCallSiteEnum.options.filter((id) => !defaultIds.has(id));
|
|
60
58
|
expect(missing).toEqual([]);
|
|
61
59
|
});
|
|
62
60
|
|
|
@@ -68,11 +66,12 @@ describe("LLM call-site catalog", () => {
|
|
|
68
66
|
expect(extra).toEqual([]);
|
|
69
67
|
});
|
|
70
68
|
|
|
71
|
-
test("every CALL_SITE_DEFAULTS
|
|
69
|
+
test("every CALL_SITE_DEFAULTS profile, when present, is a non-empty string", () => {
|
|
72
70
|
for (const [, config] of Object.entries(CALL_SITE_DEFAULTS)) {
|
|
73
|
-
|
|
71
|
+
// A call site may omit `profile` to inherit the workspace default config.
|
|
72
|
+
if (config.profile === undefined) continue;
|
|
74
73
|
expect(typeof config.profile).toBe("string");
|
|
75
|
-
expect(config.profile
|
|
74
|
+
expect(config.profile.length).toBeGreaterThan(0);
|
|
76
75
|
}
|
|
77
76
|
});
|
|
78
77
|
});
|
|
@@ -2,7 +2,10 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { describe, expect, test } from "bun:test";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
isModelInCatalog,
|
|
7
|
+
PROVIDER_CATALOG,
|
|
8
|
+
} from "../providers/model-catalog.js";
|
|
6
9
|
import { PLATFORM_PROVIDER_META } from "../providers/platform-proxy/constants.js";
|
|
7
10
|
import { resolvePricing, resolvePricingForUsage } from "../util/pricing.js";
|
|
8
11
|
|
|
@@ -30,13 +33,6 @@ function getRepoRoot(): string {
|
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
const META_JSON_PATH = join(getRepoRoot(), "meta", "llm-provider-catalog.json");
|
|
33
|
-
const SWIFTPM_MIRROR_PATH = join(
|
|
34
|
-
getRepoRoot(),
|
|
35
|
-
"clients",
|
|
36
|
-
"shared",
|
|
37
|
-
"Resources",
|
|
38
|
-
"llm-provider-catalog.json",
|
|
39
|
-
);
|
|
40
36
|
|
|
41
37
|
interface ClientCatalogCredentialsGuide {
|
|
42
38
|
description: string;
|
|
@@ -309,6 +305,32 @@ describe("LLM catalog parity: daemon vs client", () => {
|
|
|
309
305
|
});
|
|
310
306
|
});
|
|
311
307
|
|
|
308
|
+
test("Fireworks catalog includes GLM 5.2", () => {
|
|
309
|
+
expect(
|
|
310
|
+
isModelInCatalog("fireworks", "accounts/fireworks/models/glm-5p2"),
|
|
311
|
+
).toBe(true);
|
|
312
|
+
|
|
313
|
+
const fireworks = PROVIDER_CATALOG.find(
|
|
314
|
+
(entry) => entry.id === "fireworks",
|
|
315
|
+
);
|
|
316
|
+
expect(
|
|
317
|
+
fireworks?.models.find(
|
|
318
|
+
(model) => model.id === "accounts/fireworks/models/glm-5p2",
|
|
319
|
+
),
|
|
320
|
+
).toMatchObject({
|
|
321
|
+
displayName: "GLM 5.2",
|
|
322
|
+
contextWindowTokens: 1040000,
|
|
323
|
+
maxOutputTokens: 131072,
|
|
324
|
+
supportsToolUse: true,
|
|
325
|
+
supportsVision: false,
|
|
326
|
+
pricing: {
|
|
327
|
+
inputPer1mTokens: 1.4,
|
|
328
|
+
outputPer1mTokens: 4.4,
|
|
329
|
+
cacheReadPer1mTokens: 0.26,
|
|
330
|
+
},
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
|
|
312
334
|
test("MiniMax catalog includes MiniMax M3", () => {
|
|
313
335
|
const minimax = PROVIDER_CATALOG.find((entry) => entry.id === "minimax");
|
|
314
336
|
expect(
|
|
@@ -457,19 +479,4 @@ describe("LLM catalog parity: daemon vs client", () => {
|
|
|
457
479
|
longContextMode: "native-model",
|
|
458
480
|
});
|
|
459
481
|
});
|
|
460
|
-
|
|
461
|
-
// -----------------------------------------------------------------------
|
|
462
|
-
// Mirror byte-equality
|
|
463
|
-
// -----------------------------------------------------------------------
|
|
464
|
-
|
|
465
|
-
test("SwiftPM mirror is byte-identical to meta/ copy", () => {
|
|
466
|
-
// `sync-llm-catalog.ts` writes both files from the same serializer; this
|
|
467
|
-
// guard catches any case where one copy is regenerated without the other.
|
|
468
|
-
// Byte equality is required because SwiftPM bundles the resource verbatim
|
|
469
|
-
// into `VellumAssistantShared` while the meta/ JSON is consumed as a
|
|
470
|
-
// cross-package artifact (web codegen, etc.).
|
|
471
|
-
const metaBytes = readFileSync(META_JSON_PATH);
|
|
472
|
-
const swiftPmBytes = readFileSync(SWIFTPM_MIRROR_PATH);
|
|
473
|
-
expect(swiftPmBytes.equals(metaBytes)).toBe(true);
|
|
474
|
-
});
|
|
475
482
|
});
|