@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
|
@@ -208,8 +208,8 @@ import { initializeDb } from "../../persistence/db-init.js";
|
|
|
208
208
|
import { attachments } from "../../persistence/schema.js";
|
|
209
209
|
import { mediaBlockAttachmentId, type Message } from "../../providers/types.js";
|
|
210
210
|
import {
|
|
211
|
+
persistAmbientSightFrame,
|
|
211
212
|
persistLiveVoicePhoto,
|
|
212
|
-
persistLiveVoiceSightFrame,
|
|
213
213
|
} from "../live-voice-photo.js";
|
|
214
214
|
|
|
215
215
|
await initializeDb();
|
|
@@ -291,9 +291,9 @@ describe("a camera frame that falls back to inline bytes", () => {
|
|
|
291
291
|
try {
|
|
292
292
|
const inlineFrame = await uploadUnstorableFrame("inline.png");
|
|
293
293
|
|
|
294
|
-
expect(
|
|
295
|
-
|
|
296
|
-
);
|
|
294
|
+
expect(
|
|
295
|
+
(await persistAmbientSightFrame(live.id, inlineFrame, "voice")).ok,
|
|
296
|
+
).toBe(true);
|
|
297
297
|
|
|
298
298
|
const [row] = getMessages(live.id);
|
|
299
299
|
// The scenario really fired: bytes in the row, no reference to a row of
|
|
@@ -321,14 +321,14 @@ describe("a camera frame that falls back to inline bytes", () => {
|
|
|
321
321
|
const live = liveConversation("Live voice inline fallback retention");
|
|
322
322
|
try {
|
|
323
323
|
const inlineFrame = await uploadUnstorableFrame("inline-aged.png");
|
|
324
|
-
expect(
|
|
325
|
-
|
|
326
|
-
);
|
|
324
|
+
expect(
|
|
325
|
+
(await persistAmbientSightFrame(live.id, inlineFrame, "voice")).ok,
|
|
326
|
+
).toBe(true);
|
|
327
327
|
for (const name of ["fresh-a.png", "fresh-b.png"]) {
|
|
328
328
|
const fresh = await uploadFrame(name);
|
|
329
|
-
expect(
|
|
330
|
-
|
|
331
|
-
);
|
|
329
|
+
expect(
|
|
330
|
+
(await persistAmbientSightFrame(live.id, fresh, "voice")).ok,
|
|
331
|
+
).toBe(true);
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
const assembled: Message[] = getMessages(live.id).map((row) => ({
|
|
@@ -372,9 +372,9 @@ describe("a camera frame whose message link fails", () => {
|
|
|
372
372
|
realStore.linkAttachmentToMessage(elsewhere.id, arrivedAs, 0);
|
|
373
373
|
|
|
374
374
|
failNextLink = true;
|
|
375
|
-
expect(
|
|
376
|
-
|
|
377
|
-
);
|
|
375
|
+
expect(
|
|
376
|
+
(await persistAmbientSightFrame(live.id, arrivedAs, "voice")).ok,
|
|
377
|
+
).toBe(true);
|
|
378
378
|
expect(failNextLink).toBe(false);
|
|
379
379
|
|
|
380
380
|
const [row] = getMessages(live.id);
|
|
@@ -411,7 +411,7 @@ describe("a camera frame whose persist throws", () => {
|
|
|
411
411
|
messagesChangedFor.length = 0;
|
|
412
412
|
failNextLink = true;
|
|
413
413
|
failNextContentUpdate = true;
|
|
414
|
-
const result = await
|
|
414
|
+
const result = await persistAmbientSightFrame(live.id, frame, "voice");
|
|
415
415
|
expect(failNextLink).toBe(false);
|
|
416
416
|
expect(failNextContentUpdate).toBe(false);
|
|
417
417
|
|
|
@@ -469,7 +469,7 @@ describe("a camera frame whose persist throws", () => {
|
|
|
469
469
|
const frame = await uploadFrame("throws-early.png");
|
|
470
470
|
|
|
471
471
|
failNextResolve = true;
|
|
472
|
-
expect(await
|
|
472
|
+
expect(await persistAmbientSightFrame(live.id, frame, "voice")).toEqual({
|
|
473
473
|
ok: false,
|
|
474
474
|
});
|
|
475
475
|
expect(failNextResolve).toBe(false);
|
|
@@ -492,7 +492,7 @@ describe("a camera frame whose persist throws", () => {
|
|
|
492
492
|
failNextResolve = true;
|
|
493
493
|
failNextMessageLookup = true;
|
|
494
494
|
// No success claim either: doubt blocks the delete and the ok alike.
|
|
495
|
-
expect(await
|
|
495
|
+
expect(await persistAmbientSightFrame(live.id, frame, "voice")).toEqual({
|
|
496
496
|
ok: false,
|
|
497
497
|
});
|
|
498
498
|
expect(failNextMessageLookup).toBe(false);
|
|
@@ -535,7 +535,9 @@ describe("attachments a failed persist attempt cloned for itself", () => {
|
|
|
535
535
|
scopedAttachmentIds.length = 0;
|
|
536
536
|
|
|
537
537
|
failNextAddMessage = true;
|
|
538
|
-
expect(
|
|
538
|
+
expect(
|
|
539
|
+
await persistAmbientSightFrame(live.id, arrivedAs, "voice"),
|
|
540
|
+
).toEqual({
|
|
539
541
|
ok: false,
|
|
540
542
|
});
|
|
541
543
|
expect(failNextAddMessage).toBe(false);
|
|
@@ -571,9 +573,9 @@ describe("attachments a failed persist attempt cloned for itself", () => {
|
|
|
571
573
|
failNextLink = true;
|
|
572
574
|
failNextContentUpdate = true;
|
|
573
575
|
// Committed despite the throw, which is what makes the clone the row's.
|
|
574
|
-
expect(
|
|
575
|
-
|
|
576
|
-
);
|
|
576
|
+
expect(
|
|
577
|
+
(await persistAmbientSightFrame(live.id, arrivedAs, "voice")).ok,
|
|
578
|
+
).toBe(true);
|
|
577
579
|
expect(failNextLink).toBe(false);
|
|
578
580
|
expect(failNextContentUpdate).toBe(false);
|
|
579
581
|
|
|
@@ -605,7 +607,9 @@ describe("attachments a failed persist attempt cloned for itself", () => {
|
|
|
605
607
|
scopedAttachmentIds.length = 0;
|
|
606
608
|
|
|
607
609
|
failNextContentRead = true;
|
|
608
|
-
expect(
|
|
610
|
+
expect(
|
|
611
|
+
await persistAmbientSightFrame(live.id, arrivedAs, "voice"),
|
|
612
|
+
).toEqual({
|
|
609
613
|
ok: false,
|
|
610
614
|
});
|
|
611
615
|
expect(failNextContentRead).toBe(false);
|
|
@@ -692,9 +696,9 @@ describe("a clone whose materialization fails", () => {
|
|
|
692
696
|
mkdirSync(dirname(attachDir), { recursive: true });
|
|
693
697
|
writeFileSync(attachDir, "");
|
|
694
698
|
|
|
695
|
-
expect(
|
|
696
|
-
|
|
697
|
-
);
|
|
699
|
+
expect(
|
|
700
|
+
(await persistAmbientSightFrame(live.id, arrivedAs, "voice")).ok,
|
|
701
|
+
).toBe(true);
|
|
698
702
|
|
|
699
703
|
// The recovery is unchanged: the frame still lands, inline.
|
|
700
704
|
const [row] = getMessages(live.id);
|
|
@@ -756,7 +760,9 @@ describe("ambient frames stay out of the indexing pipeline", () => {
|
|
|
756
760
|
const frame = await uploadFrame("not-indexed.png");
|
|
757
761
|
|
|
758
762
|
lexicallyIndexed.length = 0;
|
|
759
|
-
expect((await
|
|
763
|
+
expect((await persistAmbientSightFrame(live.id, frame, "voice")).ok).toBe(
|
|
764
|
+
true,
|
|
765
|
+
);
|
|
760
766
|
|
|
761
767
|
const [row] = getMessages(live.id);
|
|
762
768
|
expect(row).toBeDefined();
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
* The two neighbouring contracts are pinned by their own suites: a deliberate
|
|
10
10
|
* snap persists standalone and untagged (`live-voice-attach-image.test.ts`), a
|
|
11
11
|
* parked frame persists nothing and rides the next turn
|
|
12
|
-
* (`live-voice-attach-frame.test.ts`).
|
|
12
|
+
* (`live-voice-attach-frame.test.ts`). One photo case does live here, because
|
|
13
|
+
* it pins the edge of something this suite owns: the refusal's attachment
|
|
14
|
+
* echo, which is the keep stream's alone.
|
|
13
15
|
*/
|
|
14
16
|
|
|
15
17
|
import { describe, expect, mock, test } from "bun:test";
|
|
@@ -276,6 +278,9 @@ describe("live-voice camera frames kept mid-call", () => {
|
|
|
276
278
|
).toMatchObject({
|
|
277
279
|
type: "error",
|
|
278
280
|
frameType: "sight_frame",
|
|
281
|
+
// The id it refused, so the client retires that keep rather than
|
|
282
|
+
// guessing among the sends it has not heard back on.
|
|
283
|
+
attachmentId: "att-missing",
|
|
279
284
|
recoverable: true,
|
|
280
285
|
});
|
|
281
286
|
// Nothing landed and the call carries on.
|
|
@@ -286,6 +291,70 @@ describe("live-voice camera frames kept mid-call", () => {
|
|
|
286
291
|
}
|
|
287
292
|
});
|
|
288
293
|
|
|
294
|
+
test("each refused keep names its own attachment", async () => {
|
|
295
|
+
// The point of the echo: keeps overlap, so a shared `frameType` cannot
|
|
296
|
+
// tell two outstanding sends apart.
|
|
297
|
+
const harness = createSessionHarness("Sight keep two refusals");
|
|
298
|
+
try {
|
|
299
|
+
await harness.session.start();
|
|
300
|
+
const before = harness.frames.length;
|
|
301
|
+
|
|
302
|
+
await harness.session.handleClientFrame({
|
|
303
|
+
type: "sight_frame",
|
|
304
|
+
attachmentId: "att-missing-1",
|
|
305
|
+
});
|
|
306
|
+
await harness.session.handleClientFrame({
|
|
307
|
+
type: "sight_frame",
|
|
308
|
+
attachmentId: "att-missing-2",
|
|
309
|
+
});
|
|
310
|
+
await waitFor(
|
|
311
|
+
() =>
|
|
312
|
+
harness.frames.slice(before).filter((frame) => frame.type === "error")
|
|
313
|
+
.length === 2,
|
|
314
|
+
{ message: "Timed out waiting for both refusals" },
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
const refused = harness.frames
|
|
318
|
+
.slice(before)
|
|
319
|
+
.filter((frame) => frame.type === "error")
|
|
320
|
+
.map((frame) => frame.attachmentId);
|
|
321
|
+
expect(refused.sort()).toEqual(["att-missing-1", "att-missing-2"]);
|
|
322
|
+
} finally {
|
|
323
|
+
harness.dispose();
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
test("a photo that cannot be stored names no attachment", async () => {
|
|
328
|
+
// Scope pin: the echo is the keep stream's, where sends overlap. A photo
|
|
329
|
+
// is one deliberate snap at a time, and its receipt strip already knows
|
|
330
|
+
// which one it is waiting on.
|
|
331
|
+
const harness = createSessionHarness("Sight keep photo scope");
|
|
332
|
+
try {
|
|
333
|
+
await harness.session.start();
|
|
334
|
+
const before = harness.frames.length;
|
|
335
|
+
|
|
336
|
+
await harness.session.handleClientFrame({
|
|
337
|
+
type: "attach_image",
|
|
338
|
+
attachmentId: "att-missing",
|
|
339
|
+
});
|
|
340
|
+
await waitFor(() => harness.frames.length > before, {
|
|
341
|
+
message: "Timed out waiting for the rejected photo's error",
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
const error = harness.frames
|
|
345
|
+
.slice(before)
|
|
346
|
+
.find((frame) => frame.type === "error");
|
|
347
|
+
expect(error).toMatchObject({
|
|
348
|
+
type: "error",
|
|
349
|
+
frameType: "attach_image",
|
|
350
|
+
recoverable: true,
|
|
351
|
+
});
|
|
352
|
+
expect(error?.attachmentId).toBeUndefined();
|
|
353
|
+
} finally {
|
|
354
|
+
harness.dispose();
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
|
|
289
358
|
test("refuses an unknown id while a turn is running, without waiting it out", async () => {
|
|
290
359
|
// The id is checked before the persist is scheduled. Behind the persist it
|
|
291
360
|
// would be answered only once the turn released the lock, long after the
|