@vellumai/assistant 0.11.8 → 0.11.9-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 +2 -2
- package/Dockerfile +8 -48
- package/docker-entrypoint.sh +5 -1
- package/docker-kata-apt-env.sh +3 -0
- package/docker-kata-apt-shims.sh +127 -0
- package/docker-kata-apt-wrapper.sh +45 -0
- package/docker-kata-chroot-exec.sh +35 -0
- package/docker-kata-pip.sh +8 -2
- package/docs/architecture/memory.md +8 -4
- package/docs/guardian-request-flow.md +18 -14
- package/docs/trusted-contact-access.md +1 -7
- package/node_modules/@vellumai/avatar-catalog/src/catalog.ts +7 -1
- package/node_modules/@vellumai/avatar-catalog/src/index.ts +1 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +4 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/guardian-requests.ts +18 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/platform-credential.ts +41 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/reactions.ts +60 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +4 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/guardian-requests.ts +18 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/platform-credential.ts +41 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/reactions.ts +60 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-request-contract.test.ts +0 -18
- package/node_modules/@vellumai/gateway-client/src/__tests__/inbound-event-kind.test.ts +110 -5
- package/node_modules/@vellumai/gateway-client/src/guardian-request-contract.ts +5 -33
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +3 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-event-kind.ts +100 -9
- package/node_modules/@vellumai/gateway-client/src/index.ts +1 -2
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +9 -0
- package/node_modules/@vellumai/service-contracts/package.json +4 -1
- package/node_modules/@vellumai/service-contracts/src/guardian-requests.ts +18 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/platform-credential.ts +41 -0
- package/node_modules/@vellumai/service-contracts/src/reactions.ts +60 -0
- package/openapi.yaml +193 -4
- package/package.json +2 -2
- package/src/__tests__/access-request-card-view.test.ts +6 -5
- package/src/__tests__/access-request-seed-content-blocks.test.ts +5 -2
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +43 -82
- package/src/__tests__/always-loaded-tools-guard.test.ts +8 -2
- package/src/__tests__/attachment-stored-path-annotation.test.ts +80 -0
- package/src/__tests__/attachments-store.test.ts +27 -0
- package/src/__tests__/attachments.test.ts +43 -0
- package/src/__tests__/canned-reply-release.test.ts +48 -5
- package/src/__tests__/channel-delivery-store.test.ts +129 -18
- package/src/__tests__/channel-reply-delivery.test.ts +553 -93
- package/src/__tests__/channel-retry-sweep.test.ts +199 -0
- package/src/__tests__/client-os-metadata-persistence.test.ts +32 -3
- package/src/__tests__/conversation-error.test.ts +15 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +118 -0
- package/src/__tests__/conversation-pairing.test.ts +141 -1
- package/src/__tests__/conversation-routes-disk-view.test.ts +28 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +125 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +79 -0
- package/src/__tests__/conversation-store-ephemeral.test.ts +323 -10
- package/src/__tests__/conversation-sync-tags.test.ts +2 -37
- package/src/__tests__/credential-health-service.test.ts +98 -10
- package/src/__tests__/delete-propagation.test.ts +469 -0
- package/src/__tests__/dm-persistence.test.ts +16 -0
- package/src/__tests__/docker-kata-apt-shims.test.ts +135 -0
- package/src/__tests__/forbidden-legacy-symbols.test.ts +12 -0
- package/src/__tests__/gemini-provider.test.ts +46 -0
- package/src/__tests__/guardian-card-withdrawal.test.ts +0 -22
- package/src/__tests__/guardian-gateway-sim.ts +0 -23
- package/src/__tests__/guardian-question-mode.test.ts +108 -0
- package/src/__tests__/guardian-reply-router-answer-mode.test.ts +0 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +26 -12
- package/src/__tests__/host-proxy-interface.test.ts +10 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +16 -0
- package/src/__tests__/injector-v3-suppression.test.ts +43 -9
- package/src/__tests__/list-messages-page-latest.test.ts +127 -0
- package/src/__tests__/list-messages-system-card.test.ts +103 -0
- package/src/__tests__/media-resolve-image-validation.test.ts +77 -0
- package/src/__tests__/notification-decision-fallback.test.ts +199 -77
- package/src/__tests__/notification-decision-strategy.test.ts +198 -213
- package/src/__tests__/notification-discord-adapter.test.ts +25 -0
- package/src/__tests__/notification-slack-adapter.test.ts +133 -0
- package/src/__tests__/notification-telegram-adapter.test.ts +36 -0
- package/src/__tests__/openai-provider.test.ts +5 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +85 -72
- package/src/__tests__/persist-user-message-set-processing-failure.test.ts +83 -65
- package/src/__tests__/platform-client-verify-credential.test.ts +100 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +1 -1
- package/src/__tests__/pricing.test.ts +11 -0
- package/src/__tests__/process-message-display-content.test.ts +20 -9
- package/src/__tests__/processing-acquire-fenced-guard.test.ts +56 -0
- package/src/__tests__/provider-meta-persistence.test.ts +67 -0
- package/src/__tests__/reaction-persistence.test.ts +22 -198
- package/src/__tests__/run-conversation-turn-persistence.test.ts +5 -2
- package/src/__tests__/scripted-turn-metadata-persistence.test.ts +16 -0
- package/src/__tests__/skill-load-tool.test.ts +27 -0
- package/src/__tests__/skills.test.ts +34 -1
- package/src/__tests__/strip-memory-injections.test.ts +3 -4
- package/src/__tests__/terminal-tools.test.ts +9 -0
- package/src/__tests__/thread-backfill.test.ts +5 -3
- package/src/__tests__/unified-turn-context-location.test.ts +76 -0
- package/src/__tests__/voice-session-bridge.test.ts +18 -0
- package/src/__tests__/watch-retro-report-payload.test.ts +185 -0
- package/src/__tests__/watch-retro-tool-availability.test.ts +82 -0
- package/src/__tests__/workspace-migration-151-repair-renamed-fireworks-deepseek-pro-model-id.test.ts +235 -0
- package/src/__tests__/workspace-migration-152-repair-retired-fireworks-minimax-m2p7-model-id.test.ts +233 -0
- package/src/agent/attachments.ts +13 -2
- package/src/agent/loop.ts +3 -19
- package/src/api/README.md +9 -5
- package/src/api/index.ts +9 -8
- package/src/api/package.json +1 -0
- package/src/api/responses/conversation-message.ts +8 -0
- package/src/api/responses/home.ts +7 -18
- package/src/api/surfaces.ts +114 -7
- package/src/approvals/AGENTS.md +1 -1
- package/src/channels/__tests__/gateway-guardian-requests.test.ts +1 -23
- package/src/channels/__tests__/types.test.ts +22 -1
- package/src/channels/gateway-guardian-requests.ts +0 -22
- package/src/channels/types.ts +8 -6
- package/src/cli/__tests__/catalog-search-help.test.ts +18 -0
- package/src/cli/commands/channels/__tests__/channels.test.ts +26 -0
- package/src/cli/commands/channels/index.help.ts +19 -6
- package/src/cli/commands/channels/index.ts +6 -2
- package/src/cli/commands/db/__tests__/status.test.ts +22 -0
- package/src/cli/commands/db/index.help.ts +1 -1
- package/src/cli/commands/db/status.ts +172 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +29 -0
- package/src/cli/commands/platform/connect.ts +14 -5
- package/src/cli/commands/plugins.help.ts +6 -5
- package/src/cli/lib/__tests__/install-from-github.test.ts +0 -8
- package/src/cli/lib/__tests__/install-from-platform.test.ts +72 -0
- package/src/cli/lib/__tests__/plugin-catalog-local.test.ts +33 -0
- package/src/cli/lib/bundled-marketplace.json +14 -0
- package/src/cli/lib/install-from-github.ts +9 -5
- package/src/cli/lib/install-from-platform.ts +12 -1
- package/src/config/__tests__/assistant-initiated-threads-gate.test.ts +61 -0
- package/src/config/assistant-initiated-threads-gate.ts +50 -0
- package/src/config/bundled-skills/acp/SKILL.md +10 -3
- package/src/config/bundled-skills/schedule/SKILL.md +25 -11
- package/src/config/bundled-skills/schedule/references/SCRIPT_MODE_PATTERNS.md +3 -1
- package/src/config/call-site-defaults.ts +4 -1
- package/src/config/feature-flag-registry.json +21 -4
- package/src/config/schemas/memory-v3.ts +4 -3
- package/src/context/strip-injections.ts +17 -56
- package/src/conversations/__tests__/message-consolidation.test.ts +39 -0
- package/src/conversations/message-consolidation.ts +4 -3
- package/src/credential-health/credential-health-service.ts +130 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +31 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +55 -59
- package/src/daemon/conversation-error.ts +2 -0
- package/src/daemon/conversation-messaging.ts +195 -47
- package/src/daemon/conversation-process.ts +20 -5
- package/src/daemon/conversation-runtime-assembly.ts +48 -39
- package/src/daemon/conversation-store.ts +159 -11
- package/src/daemon/conversation-tool-setup.ts +9 -2
- package/src/daemon/conversation.ts +290 -19
- package/src/daemon/dictation-text-processing.ts +2 -7
- package/src/daemon/handlers/config-channels.ts +33 -3
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/shared.ts +9 -0
- package/src/daemon/port-oversized-content.test.ts +117 -0
- package/src/daemon/port-oversized-content.ts +110 -0
- package/src/daemon/process-message.ts +87 -16
- package/src/daemon/reaction-record.test.ts +23 -11
- package/src/daemon/reaction-record.ts +6 -9
- package/src/documents/document-store.ts +1 -5
- package/src/home/conversation-starter-validation.ts +1 -5
- package/src/live-voice/__tests__/live-voice-photo.test.ts +910 -50
- package/src/live-voice/__tests__/live-voice-sight-frame-inline.test.ts +31 -25
- package/src/live-voice/__tests__/live-voice-sight-frame.test.ts +70 -1
- package/src/live-voice/live-voice-photo.ts +544 -61
- package/src/live-voice/live-voice-session.ts +6 -2
- package/src/live-voice/protocol.ts +20 -1
- package/src/messaging/provider-message-metadata.ts +40 -1
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +10 -2
- package/src/messaging/providers/channel-transport.ts +28 -0
- package/src/messaging/providers/discord/send.ts +3 -2
- package/src/messaging/providers/slack/api.ts +11 -1
- package/src/messaging/providers/slack/message-metadata.test.ts +133 -0
- package/src/messaging/providers/slack/message-metadata.ts +141 -1
- package/src/messaging/providers/slack/send.test.ts +58 -0
- package/src/messaging/providers/slack/send.ts +4 -4
- package/src/messaging/providers/slack/transport.ts +28 -2
- package/src/messaging/providers/telegram-bot/send.test.ts +159 -0
- package/src/messaging/providers/telegram-bot/send.ts +93 -0
- package/src/messaging/providers/telegram-bot/transport.ts +71 -0
- package/src/messaging/reaction-envelopes.test.ts +73 -0
- package/src/messaging/reaction-envelopes.ts +33 -5
- package/src/messaging/read-provider-metadata.ts +4 -3
- package/src/monitoring/recovery/__tests__/stranded-delivery-events.test.ts +208 -0
- package/src/monitoring/recovery/db.ts +35 -0
- package/src/monitoring/recovery/orphaned-channel-events.ts +3 -22
- package/src/monitoring/recovery/run-recovery.ts +6 -2
- package/src/monitoring/recovery/stale-processing.ts +3 -20
- package/src/monitoring/recovery/stranded-delivery-events.ts +68 -0
- package/src/notifications/AGENTS.md +2 -2
- package/src/notifications/README.md +2 -2
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +11 -9
- package/src/notifications/__tests__/broadcaster.test.ts +35 -4
- package/src/notifications/__tests__/notification-utils.test.ts +31 -0
- package/src/notifications/access-request-copy.ts +126 -114
- package/src/notifications/adapters/discord.ts +9 -5
- package/src/notifications/adapters/shared.ts +17 -4
- package/src/notifications/adapters/slack.ts +14 -4
- package/src/notifications/adapters/telegram.ts +8 -4
- package/src/notifications/approval-card-data.ts +5 -2
- package/src/notifications/assistant-reply-producer.ts +7 -7
- package/src/notifications/broadcaster.ts +57 -25
- package/src/notifications/conversation-pairing.ts +68 -2
- package/src/notifications/copy-composer.ts +13 -32
- package/src/notifications/decision-engine.ts +56 -237
- package/src/notifications/guardian-delivery-recorder.ts +5 -9
- package/src/notifications/guardian-feed-projection.ts +0 -15
- package/src/notifications/guardian-question-mode.ts +147 -6
- package/src/notifications/notification-utils.ts +117 -1
- package/src/permissions/confirmation-guardian-request.ts +2 -2
- package/src/permissions/prompter.ts +1 -1
- package/src/persistence/conversation-crud.ts +93 -14
- package/src/persistence/conversation-queries.ts +144 -17
- package/src/persistence/conversation-types.ts +39 -5
- package/src/persistence/delivery-crud.ts +224 -28
- package/src/persistence/delivery-status.ts +21 -2
- package/src/persistence/migrations/374-channel-inbound-message-id-index.ts +26 -0
- package/src/persistence/migrations/375-create-channel-outbound-posts.ts +52 -0
- package/src/persistence/migrations/__tests__/375-create-channel-outbound-posts.test.ts +84 -0
- package/src/persistence/schema/conversations.ts +71 -2
- package/src/persistence/schema-contract.test.ts +78 -0
- package/src/persistence/schema-contract.ts +96 -0
- package/src/persistence/steps.ts +4 -0
- package/src/platform/client.ts +55 -0
- package/src/plugins/__tests__/mcp-servers.test.ts +46 -0
- package/src/plugins/defaults/injector-order.ts +2 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +2 -2
- package/src/plugins/defaults/memory/context-search/sources/conversations.ts +13 -15
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +10 -0
- package/src/plugins/defaults/memory/injectors.ts +1 -1
- package/src/plugins/defaults/memory/memory-marker.ts +17 -7
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-prompt-flag-gating-guard.test.ts +1 -5
- package/src/plugins/defaults/memory/substrate/__tests__/skill-content.test.ts +17 -0
- package/src/plugins/defaults/memory/substrate/skill-content.ts +7 -0
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +54 -41
- package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +3 -3
- package/src/plugins/defaults/memory/v3/__tests__/render-injection.test.ts +22 -0
- package/src/plugins/defaults/memory/v3/injector.ts +14 -15
- package/src/plugins/defaults/memory/v3/prune.test.ts +20 -2
- package/src/plugins/defaults/memory/v3/render-injection.ts +10 -1
- package/src/plugins/defaults/memory/v3/types.ts +15 -4
- package/src/plugins/defaults/turn-context/injectors.ts +3 -0
- package/src/plugins/defaults/turn-context/unified-turn-context.ts +24 -0
- package/src/plugins/mcp-servers.ts +14 -2
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +50 -0
- package/src/providers/__tests__/registry-native-web-search.test.ts +49 -2
- package/src/providers/anthropic/client.ts +21 -24
- package/src/providers/call-site-routing.ts +5 -4
- package/src/providers/connection-resolution.ts +29 -1
- package/src/providers/content-block-size.test.ts +82 -0
- package/src/providers/content-block-size.ts +99 -0
- package/src/providers/file-block-text.test.ts +64 -0
- package/src/providers/file-block-text.ts +28 -0
- package/src/providers/gemini/client.ts +15 -9
- package/src/providers/inference/auth.ts +6 -6
- package/src/providers/media-resolve.ts +14 -0
- package/src/providers/model-catalog.ts +47 -34
- package/src/providers/openai/chat-completions-provider.ts +9 -25
- package/src/providers/openai/responses-provider.ts +11 -18
- package/src/providers/registry.ts +10 -7
- package/src/providers/routing-identity.ts +2 -1
- package/src/providers/types.ts +1 -4
- package/src/providers/vellum-model-routing.ts +3 -2
- package/src/runtime/AGENTS.md +40 -15
- package/src/runtime/approval-message-composer.ts +1 -6
- package/src/runtime/assistant-event-hub.ts +2 -39
- package/src/runtime/channel-approval-types.ts +1 -5
- package/src/runtime/channel-reply-delivery.ts +182 -115
- package/src/runtime/{slack-reply-session.test.ts → channel-reply-session.test.ts} +294 -156
- package/src/runtime/{slack-reply-session.ts → channel-reply-session.ts} +107 -86
- package/src/runtime/channel-retry-sweep.ts +102 -1
- package/src/runtime/finalize-event-delivery.ts +4 -4
- package/src/runtime/guardian-action-message-composer.ts +1 -4
- package/src/runtime/guardian-reply-router.ts +4 -75
- package/src/runtime/http-router.ts +1 -5
- package/src/runtime/question-request-guardian-bridge.ts +2 -3
- package/src/runtime/routes/__tests__/conversation-list-assistant-section.test.ts +359 -0
- package/src/runtime/routes/__tests__/dictation-command-mode.test.ts +120 -0
- package/src/runtime/routes/__tests__/sight-frame-routes.test.ts +487 -0
- package/src/runtime/routes/acp-routes.ts +1 -1
- package/src/runtime/routes/canned-reply-release.ts +19 -9
- package/src/runtime/routes/channel-route-shared.ts +0 -39
- package/src/runtime/routes/channel-verification-routes.ts +4 -1
- package/src/runtime/routes/conversation-list-routes.ts +44 -3
- package/src/runtime/routes/conversation-management-routes.ts +2 -1
- package/src/runtime/routes/conversation-routes.ts +138 -59
- package/src/runtime/routes/diagnostics-routes.ts +111 -60
- package/src/runtime/routes/guardian-action-routes.ts +10 -14
- package/src/runtime/routes/guardian-approval-interception.ts +0 -5
- package/src/runtime/routes/inbound-message-handler.ts +170 -48
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +4 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +169 -8
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +82 -14
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +23 -48
- package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +454 -94
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +309 -102
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/platform-routes.ts +99 -10
- package/src/runtime/routes/sight-frame-routes.ts +136 -0
- package/src/runtime/sync/resource-sync-events.ts +14 -37
- package/src/runtime/sync/sync-publisher.test.ts +5 -4
- package/src/tools/__tests__/tool-input-schemas.test.ts +2 -0
- package/src/tools/client-os.ts +11 -1
- package/src/tools/host-filesystem/edit.ts +2 -2
- package/src/tools/host-filesystem/read.ts +2 -2
- package/src/tools/host-filesystem/transfer.ts +2 -2
- package/src/tools/host-filesystem/write.ts +2 -2
- package/src/tools/host-terminal/host-shell.ts +2 -2
- package/src/tools/skills/load.ts +1 -1
- package/src/tools/terminal/safe-env.ts +4 -0
- package/src/tools/tool-input-schemas.ts +2 -0
- package/src/tools/tool-manifest.ts +2 -0
- package/src/tools/ui-surface/definitions.ts +4 -3
- package/src/tools/watch/watch-retro-report.ts +205 -0
- package/src/watch/__tests__/watch-retro.test.ts +268 -40
- package/src/watch/watch-retro.ts +190 -77
- package/src/workspace/migrations/151-repair-renamed-fireworks-deepseek-pro-model-id.ts +195 -0
- package/src/workspace/migrations/152-repair-retired-fireworks-minimax-m2p7-model-id.ts +198 -0
- package/src/workspace/migrations/__tests__/150-stt-flux-provider-to-model-family.test.ts +0 -10
- package/src/workspace/migrations/registry.ts +4 -0
- package/docker-kata-pip-chroot.sh +0 -22
- package/src/__tests__/slack-reaction-approvals.test.ts +0 -97
- package/src/__tests__/slack-reaction-guardian-approval.test.ts +0 -307
- package/src/api/events/conversation-list-invalidated.ts +0 -38
|
@@ -85,9 +85,7 @@ describe("conversation sync tags", () => {
|
|
|
85
85
|
// (`patchConversation` in `metadata-handlers.ts`) and the per-
|
|
86
86
|
// conversation `sync_changed` metadata tag is included as a belt-and-
|
|
87
87
|
// suspenders signal for sibling-tab consumers that missed the typed
|
|
88
|
-
// event.
|
|
89
|
-
// scoped to `targetInterfaceId: "macos"` and therefore not visible to
|
|
90
|
-
// this process-type subscriber.
|
|
88
|
+
// event. No `conversation_list_invalidated` broadcast is emitted.
|
|
91
89
|
const conversation = createConversation("Old title");
|
|
92
90
|
const route = findRoute(
|
|
93
91
|
CONVERSATION_MANAGEMENT_ROUTES,
|
|
@@ -115,13 +113,6 @@ describe("conversation sync tags", () => {
|
|
|
115
113
|
expect((received[1]!.message as { tags: string[] }).tags).not.toContain(
|
|
116
114
|
SYNC_TAGS.conversationsList,
|
|
117
115
|
);
|
|
118
|
-
// The legacy invalidation broadcast is macOS-scoped and must not
|
|
119
|
-
// reach this process-type subscriber.
|
|
120
|
-
expect(
|
|
121
|
-
received.some(
|
|
122
|
-
(event) => event.message.type === "conversation_list_invalidated",
|
|
123
|
-
),
|
|
124
|
-
).toBe(false);
|
|
125
116
|
});
|
|
126
117
|
|
|
127
118
|
test("auto-title generation emits the typed title event and a metadata-only sync tag (no list umbrella)", async () => {
|
|
@@ -159,8 +150,7 @@ describe("conversation sync tags", () => {
|
|
|
159
150
|
// fetched). The umbrella `conversationsList` tag is the signal for
|
|
160
151
|
// that redrain. Per-conversation metadata is included so any future
|
|
161
152
|
// single-row consumer can patch the freshly added row in place
|
|
162
|
-
// without an extra GET.
|
|
163
|
-
// is not visible to process subscribers.
|
|
153
|
+
// without an extra GET.
|
|
164
154
|
const route = findRoute(
|
|
165
155
|
CONVERSATION_MANAGEMENT_ROUTES,
|
|
166
156
|
"createConversation",
|
|
@@ -185,11 +175,6 @@ describe("conversation sync tags", () => {
|
|
|
185
175
|
conversationMetadataSyncTag(conversationId!),
|
|
186
176
|
],
|
|
187
177
|
});
|
|
188
|
-
expect(
|
|
189
|
-
received.some(
|
|
190
|
-
(event) => event.message.type === "conversation_list_invalidated",
|
|
191
|
-
),
|
|
192
|
-
).toBe(false);
|
|
193
178
|
});
|
|
194
179
|
|
|
195
180
|
test("reorder emits a sync_changed with the umbrella tag and per-conversation metadata tags", async () => {
|
|
@@ -228,11 +213,6 @@ describe("conversation sync tags", () => {
|
|
|
228
213
|
conversationMetadataSyncTag(second.id),
|
|
229
214
|
],
|
|
230
215
|
});
|
|
231
|
-
expect(
|
|
232
|
-
received.some(
|
|
233
|
-
(event) => event.message.type === "conversation_list_invalidated",
|
|
234
|
-
),
|
|
235
|
-
).toBe(false);
|
|
236
216
|
});
|
|
237
217
|
|
|
238
218
|
test("record seen emits only a per-conversation metadata sync tag (no list umbrella)", async () => {
|
|
@@ -245,11 +225,6 @@ describe("conversation sync tags", () => {
|
|
|
245
225
|
// single `sync_changed` with only the per-conversation
|
|
246
226
|
// `conversation:<id>:metadata` tag, which web consumes by GET-and-
|
|
247
227
|
// patching the single cached row via `refreshConversationRow`.
|
|
248
|
-
//
|
|
249
|
-
// The legacy `conversation_list_invalidated` broadcast is still
|
|
250
|
-
// emitted for macOS (which has no per-row patcher) but is scoped
|
|
251
|
-
// to `targetInterfaceId: "macos"` and therefore not visible to
|
|
252
|
-
// this process-type subscriber.
|
|
253
228
|
const conversation = createConversation("Attention");
|
|
254
229
|
projectAssistantMessage({
|
|
255
230
|
conversationId: conversation.id,
|
|
@@ -283,11 +258,6 @@ describe("conversation sync tags", () => {
|
|
|
283
258
|
expect((received[0]!.message as { tags: string[] }).tags).not.toContain(
|
|
284
259
|
SYNC_TAGS.conversationsList,
|
|
285
260
|
);
|
|
286
|
-
expect(
|
|
287
|
-
received.some(
|
|
288
|
-
(event) => event.message.type === "conversation_list_invalidated",
|
|
289
|
-
),
|
|
290
|
-
).toBe(false);
|
|
291
261
|
});
|
|
292
262
|
|
|
293
263
|
test("mark unread emits only a per-conversation metadata sync tag (no list umbrella)", async () => {
|
|
@@ -327,11 +297,6 @@ describe("conversation sync tags", () => {
|
|
|
327
297
|
expect((received[0]!.message as { tags: string[] }).tags).not.toContain(
|
|
328
298
|
SYNC_TAGS.conversationsList,
|
|
329
299
|
);
|
|
330
|
-
expect(
|
|
331
|
-
received.some(
|
|
332
|
-
(event) => event.message.type === "conversation_list_invalidated",
|
|
333
|
-
),
|
|
334
|
-
).toBe(false);
|
|
335
300
|
});
|
|
336
301
|
|
|
337
302
|
test("addMessage('assistant') emits a metadata sync tag when attention state transitions", async () => {
|
|
@@ -53,6 +53,12 @@ let managedPingOutcome:
|
|
|
53
53
|
| { kind: "credential_required" }
|
|
54
54
|
| { kind: "throw"; message: string } = { kind: "status", status: 200 };
|
|
55
55
|
|
|
56
|
+
// Managed assistant-credential mock state. The verdict is what the platform
|
|
57
|
+
// answers about the stored assistant API key; `platformClientAvailable` covers
|
|
58
|
+
// the case where the client cannot be built at all.
|
|
59
|
+
let assistantKeyVerdict: "valid" | "rejected" | "unknown" = "valid";
|
|
60
|
+
let platformClientAvailable = true;
|
|
61
|
+
|
|
56
62
|
// ── Module mocks ─────────────────────────────────────────────────────
|
|
57
63
|
|
|
58
64
|
mock.module("../security/secure-keys.js", () => ({
|
|
@@ -123,14 +129,20 @@ mock.module("../security/token-manager.js", () => ({
|
|
|
123
129
|
// seeded into the real workspace config via `seedGoogleOAuthMode` below.
|
|
124
130
|
mock.module("../platform/client.js", () => ({
|
|
125
131
|
VellumPlatformClient: {
|
|
126
|
-
create: async () =>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
create: async () => {
|
|
133
|
+
if (!platformClientAvailable) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
platformAssistantId: "test-assistant",
|
|
138
|
+
fetch: async (_path: string) => ({
|
|
139
|
+
ok: managedListResponse.ok,
|
|
140
|
+
status: managedListResponse.status,
|
|
141
|
+
json: async () => managedListResponse.body ?? { results: [] },
|
|
142
|
+
}),
|
|
143
|
+
verifyCredential: async () => assistantKeyVerdict,
|
|
144
|
+
};
|
|
145
|
+
},
|
|
134
146
|
},
|
|
135
147
|
}));
|
|
136
148
|
|
|
@@ -164,8 +176,12 @@ mock.module("../oauth/platform-connection.js", () => ({
|
|
|
164
176
|
|
|
165
177
|
import { setConfig } from "./helpers/set-config.js";
|
|
166
178
|
|
|
167
|
-
const {
|
|
168
|
-
|
|
179
|
+
const {
|
|
180
|
+
checkAllCredentials,
|
|
181
|
+
checkAssistantApiKey,
|
|
182
|
+
checkCredentialForProvider,
|
|
183
|
+
_setFetchFn,
|
|
184
|
+
} = await import("../credential-health/credential-health-service.js");
|
|
169
185
|
|
|
170
186
|
/** Seed the real workspace config's `services.google-oauth.mode`. */
|
|
171
187
|
function seedGoogleOAuthMode(mode: "managed" | "your-own"): void {
|
|
@@ -259,6 +275,8 @@ describe("credential-health-service", () => {
|
|
|
259
275
|
seedGoogleOAuthMode("your-own");
|
|
260
276
|
managedListResponse = { ok: true, status: 200, body: { results: [] } };
|
|
261
277
|
managedPingOutcome = { kind: "status", status: 200 };
|
|
278
|
+
assistantKeyVerdict = "valid";
|
|
279
|
+
platformClientAvailable = true;
|
|
262
280
|
});
|
|
263
281
|
|
|
264
282
|
test("returns empty report when no providers exist", async () => {
|
|
@@ -763,4 +781,74 @@ describe("credential-health-service", () => {
|
|
|
763
781
|
expect(result!.status).toBe("missing_token");
|
|
764
782
|
});
|
|
765
783
|
});
|
|
784
|
+
|
|
785
|
+
describe("managed assistant credential", () => {
|
|
786
|
+
const KEY = "credential/vellum/assistant_api_key";
|
|
787
|
+
const BASE_URL = "credential/vellum/platform_base_url";
|
|
788
|
+
|
|
789
|
+
// Checked directly rather than through `checkAllCredentials`: the managed
|
|
790
|
+
// credential is not enrolled in the heartbeat pass yet, because the alert
|
|
791
|
+
// that pass raises has nowhere to send the reader until the notification
|
|
792
|
+
// carries the repair.
|
|
793
|
+
const assistantKeyResult = checkAssistantApiKey;
|
|
794
|
+
|
|
795
|
+
test("is not reported when the workspace was never connected", async () => {
|
|
796
|
+
expect(await assistantKeyResult()).toBeNull();
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
test("is missing_token when a platform identity exists without a key", async () => {
|
|
800
|
+
secureKeyValues.set(BASE_URL, "https://platform.example");
|
|
801
|
+
|
|
802
|
+
const result = await assistantKeyResult();
|
|
803
|
+
expect(result!.status).toBe("missing_token");
|
|
804
|
+
expect(result!.canAutoRecover).toBe(true);
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
test("is healthy when the platform accepts the stored key", async () => {
|
|
808
|
+
secureKeyValues.set(BASE_URL, "https://platform.example");
|
|
809
|
+
secureKeyValues.set(KEY, "stored-key");
|
|
810
|
+
assistantKeyVerdict = "valid";
|
|
811
|
+
|
|
812
|
+
expect((await assistantKeyResult())!.status).toBe("healthy");
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
test("is revoked when the platform rejects the stored key", async () => {
|
|
816
|
+
secureKeyValues.set(BASE_URL, "https://platform.example");
|
|
817
|
+
secureKeyValues.set(KEY, "stored-key");
|
|
818
|
+
assistantKeyVerdict = "rejected";
|
|
819
|
+
|
|
820
|
+
const result = await assistantKeyResult();
|
|
821
|
+
expect(result!.status).toBe("revoked");
|
|
822
|
+
// Recovery needs a signed-in client to rotate the key, but no
|
|
823
|
+
// re-authorization from the user.
|
|
824
|
+
expect(result!.canAutoRecover).toBe(true);
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
// The anti-churn invariant: only a settled rejection may read as revoked,
|
|
828
|
+
// because `revoked` is what drives a rotation. An unsettled answer (server
|
|
829
|
+
// error, transport failure) must degrade to `unreachable`, which the
|
|
830
|
+
// heartbeat drops before notifying.
|
|
831
|
+
test("an unsettled platform answer is unreachable, never revoked", async () => {
|
|
832
|
+
secureKeyValues.set(BASE_URL, "https://platform.example");
|
|
833
|
+
secureKeyValues.set(KEY, "stored-key");
|
|
834
|
+
assistantKeyVerdict = "unknown";
|
|
835
|
+
|
|
836
|
+
expect((await assistantKeyResult())!.status).toBe("unreachable");
|
|
837
|
+
});
|
|
838
|
+
|
|
839
|
+
test("an unreadable credential store is unreachable, never revoked", async () => {
|
|
840
|
+
secureKeyValues.set(BASE_URL, "https://platform.example");
|
|
841
|
+
markUnreachable(KEY);
|
|
842
|
+
|
|
843
|
+
expect((await assistantKeyResult())!.status).toBe("unreachable");
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
test("is unreachable when the platform client cannot be built", async () => {
|
|
847
|
+
secureKeyValues.set(BASE_URL, "https://platform.example");
|
|
848
|
+
secureKeyValues.set(KEY, "stored-key");
|
|
849
|
+
platformClientAvailable = false;
|
|
850
|
+
|
|
851
|
+
expect((await assistantKeyResult())!.status).toBe("unreachable");
|
|
852
|
+
});
|
|
853
|
+
});
|
|
766
854
|
});
|