@vellumai/assistant 0.10.3 → 0.10.4-staging.1
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/openapi.yaml +73 -56
- package/package.json +1 -1
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +83 -31
- package/src/__tests__/assistant-stream-state.test.ts +3 -76
- package/src/__tests__/background-workers-disk-pressure.test.ts +4 -2
- package/src/__tests__/channel-approval-routes.test.ts +21 -26
- package/src/__tests__/channel-delivery-store.test.ts +28 -0
- package/src/__tests__/channel-guardian.test.ts +82 -32
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +11 -19
- package/src/__tests__/channel-reply-delivery.test.ts +6 -2
- package/src/__tests__/compaction-ledger-store.test.ts +128 -0
- package/src/__tests__/config-loader-backfill.test.ts +148 -0
- package/src/__tests__/consult-deadline.test.ts +60 -0
- package/src/__tests__/contact-store-interaction-info.test.ts +156 -0
- package/src/__tests__/contact-store-user-file.test.ts +7 -10
- package/src/__tests__/contacts-relay-reads.test.ts +6 -9
- package/src/__tests__/contacts-write.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +4 -2
- package/src/__tests__/conversation-agent-loop.test.ts +98 -7
- package/src/__tests__/conversation-attention-telegram.test.ts +9 -11
- package/src/__tests__/conversation-error.test.ts +18 -0
- package/src/__tests__/conversation-fork-crud.test.ts +354 -24
- package/src/__tests__/conversation-title-service.test.ts +222 -201
- package/src/__tests__/db-compaction-events-migration.test.ts +129 -0
- package/src/__tests__/delete-propagation.test.ts +5 -3
- package/src/__tests__/dm-backfill.test.ts +6 -4
- package/src/__tests__/emit-signal-routing-intent.test.ts +2 -6
- package/src/__tests__/guardian-binding-drift-heal.test.ts +43 -23
- package/src/__tests__/guardian-dispatch.test.ts +50 -5
- package/src/__tests__/guardian-routing-state.test.ts +6 -10
- package/src/__tests__/helpers/channel-test-adapter.ts +45 -12
- package/src/__tests__/helpers/create-guardian-binding.ts +15 -23
- package/src/__tests__/helpers/mock-logger.ts +1 -0
- package/src/__tests__/helpers/seed-contact-channel.ts +96 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +87 -10
- package/src/__tests__/invite-redemption-service.test.ts +273 -53
- package/src/__tests__/invite-routes-http.test.ts +34 -0
- package/src/__tests__/invite-service-ipc.test.ts +65 -2
- package/src/__tests__/list-messages-page-latest.test.ts +173 -4
- package/src/__tests__/mcp-config-secret-boundary.test.ts +3 -0
- package/src/__tests__/non-member-access-request.test.ts +15 -13
- package/src/__tests__/onboarding-persona-write.test.ts +52 -22
- package/src/__tests__/persist-onboarding-artifacts.test.ts +1 -0
- package/src/__tests__/persona-resolver.test.ts +75 -45
- package/src/__tests__/plugin-bootstrap.test.ts +13 -5
- package/src/__tests__/plugin-disabled-state.test.ts +190 -0
- package/src/__tests__/provider-usage-tracking.test.ts +1 -1
- package/src/__tests__/reaction-intercept-cold-cache-warm.test.ts +135 -0
- package/src/__tests__/reaction-intercept-member-verdict-warm.test.ts +158 -0
- package/src/__tests__/reaction-persistence.test.ts +51 -4
- package/src/__tests__/relay-server.test.ts +88 -31
- package/src/__tests__/runtime-attachment-metadata.test.ts +9 -11
- package/src/__tests__/settings-routes.test.ts +32 -0
- package/src/__tests__/slack-block-formatting.test.ts +1 -38
- package/src/__tests__/sse-actor-principal-guardian-source.test.ts +13 -36
- package/src/__tests__/stt-hints.test.ts +6 -3
- package/src/__tests__/subagent-fork-prompt-role.test.ts +195 -0
- package/src/__tests__/subagent-fork-spawn.test.ts +6 -7
- package/src/__tests__/subagent-role-registry.test.ts +17 -4
- package/src/__tests__/subagent-spawn-and-await.test.ts +546 -0
- package/src/__tests__/subagent-tools.test.ts +398 -3
- package/src/__tests__/thread-backfill.test.ts +3 -3
- package/src/__tests__/tool-preview-lifecycle.test.ts +26 -10
- package/src/__tests__/tool-start-timestamp.test.ts +4 -3
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +37 -51
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -2
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -7
- package/src/__tests__/trusted-contact-multichannel.test.ts +16 -7
- package/src/__tests__/trusted-contact-verification.test.ts +79 -54
- package/src/__tests__/voice-guardian-cold-cache-warm.test.ts +137 -0
- package/src/__tests__/voice-invite-redemption.test.ts +183 -20
- package/src/__tests__/workspace-migration-102-preserve-heartbeat-enabled-for-existing-workspaces.test.ts +3 -3
- package/src/__tests__/workspace-migration-111-prune-seeded-callsite-defaults.test.ts +2 -2
- package/src/__tests__/workspace-migration-112-remove-advisor-callsite-override.test.ts +170 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +196 -238
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +35 -47
- package/src/agent/loop-exclusive-tool.test.ts +19 -15
- package/src/agent/loop-native-web-search.test.ts +200 -0
- package/src/agent/loop.ts +108 -1
- package/src/api/responses/conversation-message.ts +9 -0
- package/src/approvals/guardian-request-resolvers.ts +16 -4
- package/src/calls/__tests__/relay-setup-router.test.ts +10 -18
- package/src/calls/guardian-dispatch.ts +14 -11
- package/src/calls/inbound-trust-reader.ts +7 -1
- package/src/calls/relay-access-wait.ts +6 -6
- package/src/calls/relay-server.ts +22 -2
- package/src/calls/relay-setup-router.ts +10 -10
- package/src/cli/commands/__tests__/conversations-slack.test.ts +1 -0
- package/src/cli/commands/contacts.ts +10 -7
- package/src/cli/commands/memory/__tests__/worker.test.ts +147 -17
- package/src/cli/commands/memory/worker.ts +97 -30
- package/src/cli/commands/plugins.ts +3 -146
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +17 -17
- package/src/cli/lib/__tests__/publish-plugin.test.ts +98 -0
- package/src/cli/lib/publish-plugin.ts +231 -1
- package/src/config/__tests__/sync-gated-profiles.test.ts +5 -7
- package/src/config/bundled-skills/subagent/SKILL.md +16 -1
- package/src/config/bundled-skills/subagent/TOOLS.json +5 -4
- package/src/config/call-site-defaults.ts +0 -6
- package/src/config/llm-resolver.ts +0 -3
- package/src/config/schemas/call-site-catalog.ts +0 -7
- package/src/config/schemas/heartbeat.ts +2 -5
- package/src/config/schemas/llm.ts +3 -12
- package/src/config/schemas/memory-lifecycle.ts +1 -1
- package/src/config/seed-inference-profiles.ts +76 -35
- package/src/config/sync-gated-profiles.ts +0 -3
- package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +7 -8
- package/src/contacts/__tests__/member-write-relay.test.ts +35 -11
- package/src/contacts/contact-store.ts +27 -237
- package/src/contacts/contacts-write.ts +18 -58
- package/src/contacts/gateway-channel-read.ts +51 -0
- package/src/contacts/member-write-relay.ts +25 -31
- package/src/contacts/types.ts +3 -15
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +0 -44
- package/src/daemon/conversation-agent-loop-handlers.ts +29 -10
- package/src/daemon/conversation-agent-loop.ts +68 -61
- package/src/daemon/conversation-error.ts +7 -10
- package/src/daemon/conversation-tool-setup.ts +0 -10
- package/src/daemon/conversation.ts +10 -0
- package/src/daemon/external-plugins-bootstrap.ts +8 -2
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +0 -1
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -2
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -2
- package/src/daemon/handlers/__tests__/config-channels.test.ts +9 -14
- package/src/daemon/handlers/config-channels.ts +14 -29
- package/src/daemon/lifecycle.ts +16 -4
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/heartbeat/heartbeat-service.ts +5 -0
- package/src/home/relationship-state-writer.ts +5 -0
- package/src/memory/__tests__/embedding-cache.test.ts +136 -0
- package/src/memory/compaction-ledger-store.ts +107 -0
- package/src/memory/conversation-crud.ts +136 -61
- package/src/memory/conversation-title-service.ts +173 -24
- package/src/memory/embedding-backend.ts +8 -1
- package/src/memory/embedding-cache.ts +139 -0
- package/src/memory/jobs-worker.ts +75 -29
- package/src/memory/memory-retrospective-job.ts +5 -0
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +27 -5
- package/src/memory/migrations/302-create-compaction-events.ts +107 -0
- package/src/memory/migrations/303-add-conversation-creation-seq.ts +33 -0
- package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +79 -6
- package/src/memory/schema/contacts.ts +6 -2
- package/src/memory/schema/conversations.ts +39 -0
- package/src/memory/steps.ts +1090 -367
- package/src/memory/worker-control.ts +104 -18
- package/src/memory/worker-process.ts +17 -0
- package/src/messaging/channel-binding-metadata.ts +31 -0
- package/src/messaging/channel-binding-schema.ts +51 -0
- package/src/messaging/providers/__tests__/callback-routing.test.ts +45 -0
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +195 -0
- package/src/messaging/providers/a2a/__tests__/deliver.test.ts +11 -0
- package/src/messaging/providers/a2a/deliver.ts +5 -1
- package/src/messaging/providers/a2a/transport.ts +10 -0
- package/src/messaging/providers/callback-routing.ts +48 -0
- package/src/messaging/providers/channel-transport.ts +55 -0
- package/src/messaging/providers/index.ts +65 -241
- package/src/messaging/providers/slack/binding-metadata.ts +62 -0
- package/src/messaging/providers/slack/transport.ts +92 -0
- package/src/messaging/providers/telegram-bot/transport.ts +51 -0
- package/src/messaging/providers/whatsapp/transport.ts +38 -0
- package/src/notifications/__tests__/broadcaster.test.ts +0 -8
- package/src/notifications/__tests__/connected-channels.test.ts +8 -36
- package/src/notifications/__tests__/destination-resolver.test.ts +12 -117
- package/src/notifications/destination-resolver.ts +7 -23
- package/src/notifications/emit-signal.ts +5 -11
- package/src/plugins/defaults/index.ts +0 -35
- package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +11 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +243 -2
- package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +167 -14
- package/src/plugins/disabled-state.ts +31 -0
- package/src/plugins/registry.ts +55 -12
- package/src/prompts/persona-resolver.ts +43 -11
- package/src/providers/call-site-routing.ts +41 -0
- package/src/providers/provider-send-message.ts +6 -0
- package/src/providers/ratelimit.ts +6 -0
- package/src/providers/registry.ts +1 -1
- package/src/providers/retry.ts +6 -0
- package/src/providers/types.ts +13 -0
- package/src/providers/usage-tracking.ts +6 -0
- package/src/runtime/__tests__/guardian-vellum-migration.test.ts +30 -27
- package/src/runtime/__tests__/local-principal-trust.test.ts +16 -18
- package/src/runtime/__tests__/member-verdict-cache.test.ts +119 -0
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +115 -168
- package/src/runtime/access-request-helper.ts +1 -2
- package/src/runtime/actor-trust-resolver.ts +44 -17
- package/src/runtime/anchored-guardian.test.ts +7 -54
- package/src/runtime/anchored-guardian.ts +4 -53
- package/src/runtime/assistant-stream-state.ts +12 -74
- package/src/runtime/channel-reply-delivery.ts +3 -8
- package/src/runtime/guardian-vellum-migration.ts +18 -16
- package/src/runtime/invite-redemption-service.ts +25 -10
- package/src/runtime/local-actor-identity.test.ts +108 -0
- package/src/runtime/local-actor-identity.ts +27 -20
- package/src/runtime/member-verdict-cache.ts +0 -0
- package/src/runtime/routes/__tests__/contact-routes.test.ts +100 -7
- package/src/runtime/routes/__tests__/global-search-routes.test.ts +1 -2
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +2 -1
- package/src/runtime/routes/contact-routes.ts +40 -25
- package/src/runtime/routes/conversation-list-routes.ts +1 -29
- package/src/runtime/routes/conversation-routes.ts +27 -7
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -10
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -8
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +19 -0
- package/src/runtime/routes/settings-routes.ts +8 -3
- package/src/runtime/services/conversation-serializer.ts +6 -49
- package/src/runtime/slack-block-formatting.ts +0 -15
- package/src/runtime/trust-verdict-consumer.ts +36 -41
- package/src/subagent/__tests__/consult-prompt.test.ts +35 -0
- package/src/{plugins/defaults/advisor/__tests__/transcript.test.ts → subagent/__tests__/consult-transcript.test.ts} +47 -10
- package/src/{plugins/defaults/advisor/steering.ts → subagent/consult-prompt.ts} +17 -39
- package/src/{plugins/defaults/advisor/transcript.ts → subagent/consult-transcript.ts} +18 -8
- package/src/subagent/index.ts +1 -1
- package/src/subagent/manager.ts +245 -33
- package/src/subagent/types.ts +8 -1
- package/src/tools/registry.ts +10 -3
- package/src/tools/subagent/consult-deadline.ts +49 -0
- package/src/tools/subagent/spawn.ts +234 -5
- package/src/util/logger.ts +9 -0
- package/src/util/platform.ts +14 -0
- package/src/workspace/migrations/031-drop-user-md.ts +232 -148
- package/src/workspace/migrations/112-remove-advisor-callsite-override.ts +64 -0
- package/src/workspace/migrations/registry.ts +2 -0
- package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +0 -56
- package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +0 -43
- package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +0 -137
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +0 -314
- package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +0 -106
- package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +0 -60
- package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +0 -138
- package/src/plugins/defaults/advisor/advisor-gate.ts +0 -29
- package/src/plugins/defaults/advisor/advisor-state-store.ts +0 -94
- package/src/plugins/defaults/advisor/config.ts +0 -21
- package/src/plugins/defaults/advisor/consult.ts +0 -197
- package/src/plugins/defaults/advisor/context-pack.ts +0 -288
- package/src/plugins/defaults/advisor/hooks/post-model-call.ts +0 -34
- package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +0 -30
- package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +0 -19
- package/src/plugins/defaults/advisor/package.json +0 -14
- package/src/plugins/defaults/advisor/tools/advisor.ts +0 -92
package/openapi.yaml
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
openapi: 3.1.0
|
|
4
4
|
info:
|
|
5
5
|
title: Vellum Assistant API
|
|
6
|
-
version: 0.10.
|
|
6
|
+
version: 0.10.4
|
|
7
7
|
description: Auto-generated OpenAPI specification for the Vellum Assistant runtime HTTP server.
|
|
8
8
|
servers:
|
|
9
9
|
- url: http://127.0.0.1:7821
|
|
@@ -4841,14 +4841,18 @@ paths:
|
|
|
4841
4841
|
type: string
|
|
4842
4842
|
role:
|
|
4843
4843
|
type: string
|
|
4844
|
+
enum:
|
|
4845
|
+
- guardian
|
|
4846
|
+
- contact
|
|
4844
4847
|
notes:
|
|
4845
4848
|
anyOf:
|
|
4846
4849
|
- type: string
|
|
4847
4850
|
- type: "null"
|
|
4848
4851
|
contactType:
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
-
|
|
4852
|
+
type: string
|
|
4853
|
+
enum:
|
|
4854
|
+
- human
|
|
4855
|
+
- assistant
|
|
4852
4856
|
lastInteraction:
|
|
4853
4857
|
anyOf:
|
|
4854
4858
|
- type: number
|
|
@@ -4915,20 +4919,15 @@ paths:
|
|
|
4915
4919
|
- address
|
|
4916
4920
|
- isPrimary
|
|
4917
4921
|
- externalUserId
|
|
4918
|
-
- status
|
|
4919
|
-
- policy
|
|
4920
|
-
- verifiedAt
|
|
4921
|
-
- verifiedVia
|
|
4922
4922
|
- lastSeenAt
|
|
4923
4923
|
- interactionCount
|
|
4924
4924
|
- lastInteraction
|
|
4925
|
-
- revokedReason
|
|
4926
|
-
- blockedReason
|
|
4927
4925
|
additionalProperties: false
|
|
4928
4926
|
required:
|
|
4929
4927
|
- id
|
|
4930
4928
|
- displayName
|
|
4931
4929
|
- role
|
|
4930
|
+
- contactType
|
|
4932
4931
|
- interactionCount
|
|
4933
4932
|
- createdAt
|
|
4934
4933
|
- updatedAt
|
|
@@ -5002,14 +5001,18 @@ paths:
|
|
|
5002
5001
|
type: string
|
|
5003
5002
|
role:
|
|
5004
5003
|
type: string
|
|
5004
|
+
enum:
|
|
5005
|
+
- guardian
|
|
5006
|
+
- contact
|
|
5005
5007
|
notes:
|
|
5006
5008
|
anyOf:
|
|
5007
5009
|
- type: string
|
|
5008
5010
|
- type: "null"
|
|
5009
5011
|
contactType:
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
-
|
|
5012
|
+
type: string
|
|
5013
|
+
enum:
|
|
5014
|
+
- human
|
|
5015
|
+
- assistant
|
|
5013
5016
|
lastInteraction:
|
|
5014
5017
|
anyOf:
|
|
5015
5018
|
- type: number
|
|
@@ -5076,20 +5079,15 @@ paths:
|
|
|
5076
5079
|
- address
|
|
5077
5080
|
- isPrimary
|
|
5078
5081
|
- externalUserId
|
|
5079
|
-
- status
|
|
5080
|
-
- policy
|
|
5081
|
-
- verifiedAt
|
|
5082
|
-
- verifiedVia
|
|
5083
5082
|
- lastSeenAt
|
|
5084
5083
|
- interactionCount
|
|
5085
5084
|
- lastInteraction
|
|
5086
|
-
- revokedReason
|
|
5087
|
-
- blockedReason
|
|
5088
5085
|
additionalProperties: false
|
|
5089
5086
|
required:
|
|
5090
5087
|
- id
|
|
5091
5088
|
- displayName
|
|
5092
5089
|
- role
|
|
5090
|
+
- contactType
|
|
5093
5091
|
- interactionCount
|
|
5094
5092
|
- createdAt
|
|
5095
5093
|
- updatedAt
|
|
@@ -5132,14 +5130,18 @@ paths:
|
|
|
5132
5130
|
type: string
|
|
5133
5131
|
role:
|
|
5134
5132
|
type: string
|
|
5133
|
+
enum:
|
|
5134
|
+
- guardian
|
|
5135
|
+
- contact
|
|
5135
5136
|
notes:
|
|
5136
5137
|
anyOf:
|
|
5137
5138
|
- type: string
|
|
5138
5139
|
- type: "null"
|
|
5139
5140
|
contactType:
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
-
|
|
5141
|
+
type: string
|
|
5142
|
+
enum:
|
|
5143
|
+
- human
|
|
5144
|
+
- assistant
|
|
5143
5145
|
lastInteraction:
|
|
5144
5146
|
anyOf:
|
|
5145
5147
|
- type: number
|
|
@@ -5206,20 +5208,15 @@ paths:
|
|
|
5206
5208
|
- address
|
|
5207
5209
|
- isPrimary
|
|
5208
5210
|
- externalUserId
|
|
5209
|
-
- status
|
|
5210
|
-
- policy
|
|
5211
|
-
- verifiedAt
|
|
5212
|
-
- verifiedVia
|
|
5213
5211
|
- lastSeenAt
|
|
5214
5212
|
- interactionCount
|
|
5215
5213
|
- lastInteraction
|
|
5216
|
-
- revokedReason
|
|
5217
|
-
- blockedReason
|
|
5218
5214
|
additionalProperties: false
|
|
5219
5215
|
required:
|
|
5220
5216
|
- id
|
|
5221
5217
|
- displayName
|
|
5222
5218
|
- role
|
|
5219
|
+
- contactType
|
|
5223
5220
|
- interactionCount
|
|
5224
5221
|
- createdAt
|
|
5225
5222
|
- updatedAt
|
|
@@ -5507,14 +5504,18 @@ paths:
|
|
|
5507
5504
|
type: string
|
|
5508
5505
|
role:
|
|
5509
5506
|
type: string
|
|
5507
|
+
enum:
|
|
5508
|
+
- guardian
|
|
5509
|
+
- contact
|
|
5510
5510
|
notes:
|
|
5511
5511
|
anyOf:
|
|
5512
5512
|
- type: string
|
|
5513
5513
|
- type: "null"
|
|
5514
5514
|
contactType:
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
-
|
|
5515
|
+
type: string
|
|
5516
|
+
enum:
|
|
5517
|
+
- human
|
|
5518
|
+
- assistant
|
|
5518
5519
|
lastInteraction:
|
|
5519
5520
|
anyOf:
|
|
5520
5521
|
- type: number
|
|
@@ -5581,20 +5582,15 @@ paths:
|
|
|
5581
5582
|
- address
|
|
5582
5583
|
- isPrimary
|
|
5583
5584
|
- externalUserId
|
|
5584
|
-
- status
|
|
5585
|
-
- policy
|
|
5586
|
-
- verifiedAt
|
|
5587
|
-
- verifiedVia
|
|
5588
5585
|
- lastSeenAt
|
|
5589
5586
|
- interactionCount
|
|
5590
5587
|
- lastInteraction
|
|
5591
|
-
- revokedReason
|
|
5592
|
-
- blockedReason
|
|
5593
5588
|
additionalProperties: false
|
|
5594
5589
|
required:
|
|
5595
5590
|
- id
|
|
5596
5591
|
- displayName
|
|
5597
5592
|
- role
|
|
5593
|
+
- contactType
|
|
5598
5594
|
- interactionCount
|
|
5599
5595
|
- createdAt
|
|
5600
5596
|
- updatedAt
|
|
@@ -5702,14 +5698,18 @@ paths:
|
|
|
5702
5698
|
type: string
|
|
5703
5699
|
role:
|
|
5704
5700
|
type: string
|
|
5701
|
+
enum:
|
|
5702
|
+
- guardian
|
|
5703
|
+
- contact
|
|
5705
5704
|
notes:
|
|
5706
5705
|
anyOf:
|
|
5707
5706
|
- type: string
|
|
5708
5707
|
- type: "null"
|
|
5709
5708
|
contactType:
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
-
|
|
5709
|
+
type: string
|
|
5710
|
+
enum:
|
|
5711
|
+
- human
|
|
5712
|
+
- assistant
|
|
5713
5713
|
lastInteraction:
|
|
5714
5714
|
anyOf:
|
|
5715
5715
|
- type: number
|
|
@@ -5776,20 +5776,15 @@ paths:
|
|
|
5776
5776
|
- address
|
|
5777
5777
|
- isPrimary
|
|
5778
5778
|
- externalUserId
|
|
5779
|
-
- status
|
|
5780
|
-
- policy
|
|
5781
|
-
- verifiedAt
|
|
5782
|
-
- verifiedVia
|
|
5783
5779
|
- lastSeenAt
|
|
5784
5780
|
- interactionCount
|
|
5785
5781
|
- lastInteraction
|
|
5786
|
-
- revokedReason
|
|
5787
|
-
- blockedReason
|
|
5788
5782
|
additionalProperties: false
|
|
5789
5783
|
required:
|
|
5790
5784
|
- id
|
|
5791
5785
|
- displayName
|
|
5792
5786
|
- role
|
|
5787
|
+
- contactType
|
|
5793
5788
|
- interactionCount
|
|
5794
5789
|
- createdAt
|
|
5795
5790
|
- updatedAt
|
|
@@ -17431,6 +17426,30 @@ paths:
|
|
|
17431
17426
|
webUrl:
|
|
17432
17427
|
type: string
|
|
17433
17428
|
additionalProperties: false
|
|
17429
|
+
eventKind:
|
|
17430
|
+
type: string
|
|
17431
|
+
enum:
|
|
17432
|
+
- message
|
|
17433
|
+
- reaction
|
|
17434
|
+
reaction:
|
|
17435
|
+
type: object
|
|
17436
|
+
properties:
|
|
17437
|
+
emoji:
|
|
17438
|
+
type: string
|
|
17439
|
+
op:
|
|
17440
|
+
type: string
|
|
17441
|
+
enum:
|
|
17442
|
+
- added
|
|
17443
|
+
- removed
|
|
17444
|
+
actorDisplayName:
|
|
17445
|
+
type: string
|
|
17446
|
+
targetChannelTs:
|
|
17447
|
+
type: string
|
|
17448
|
+
required:
|
|
17449
|
+
- emoji
|
|
17450
|
+
- op
|
|
17451
|
+
- targetChannelTs
|
|
17452
|
+
additionalProperties: false
|
|
17434
17453
|
required:
|
|
17435
17454
|
- channelId
|
|
17436
17455
|
- channelTs
|
|
@@ -17467,6 +17486,14 @@ paths:
|
|
|
17467
17486
|
anyOf:
|
|
17468
17487
|
- type: number
|
|
17469
17488
|
- type: "null"
|
|
17489
|
+
processing:
|
|
17490
|
+
description:
|
|
17491
|
+
"Whether the agent is currently mid-turn for this conversation, sourced authoritatively from the persisted
|
|
17492
|
+
`processing_started_at` column. `true` means a turn is in flight; `false` means the conversation
|
|
17493
|
+
is idle. Clients use this to recover from a dropped SSE stream: if a turn appears to be running
|
|
17494
|
+
locally but the server reports `processing: false`, the turn has ended (or died) and the UI should
|
|
17495
|
+
stop waiting rather than spin indefinitely. Absent on older daemons that predate this field."
|
|
17496
|
+
type: boolean
|
|
17470
17497
|
required:
|
|
17471
17498
|
- messages
|
|
17472
17499
|
additionalProperties: false
|
|
@@ -29688,12 +29715,6 @@ components:
|
|
|
29688
29715
|
- $ref: "#/components/schemas/ProfileStatus"
|
|
29689
29716
|
- type: "null"
|
|
29690
29717
|
- type: "null"
|
|
29691
|
-
advisorEnabled:
|
|
29692
|
-
anyOf:
|
|
29693
|
-
- anyOf:
|
|
29694
|
-
- type: boolean
|
|
29695
|
-
- type: "null"
|
|
29696
|
-
- type: "null"
|
|
29697
29718
|
mix:
|
|
29698
29719
|
anyOf:
|
|
29699
29720
|
- minItems: 2
|
|
@@ -30421,10 +30442,6 @@ components:
|
|
|
30421
30442
|
anyOf:
|
|
30422
30443
|
- $ref: "#/components/schemas/ProfileStatus"
|
|
30423
30444
|
- type: "null"
|
|
30424
|
-
advisorEnabled:
|
|
30425
|
-
anyOf:
|
|
30426
|
-
- type: boolean
|
|
30427
|
-
- type: "null"
|
|
30428
30445
|
mix:
|
|
30429
30446
|
minItems: 2
|
|
30430
30447
|
type: array
|
package/package.json
CHANGED
|
@@ -7,12 +7,18 @@
|
|
|
7
7
|
* and are discovered through the same path as every other channel.
|
|
8
8
|
*
|
|
9
9
|
* This suite verifies that address-based lookup returns the correct
|
|
10
|
-
* `memberRecord` with the right
|
|
10
|
+
* `memberRecord` with the right ACL status so relay-setup-router
|
|
11
11
|
* can emit the appropriate outcome (e.g. `unverified_caller`).
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
15
15
|
|
|
16
|
+
import type {
|
|
17
|
+
ChannelPolicy,
|
|
18
|
+
ChannelStatus,
|
|
19
|
+
ContactRole,
|
|
20
|
+
} from "../contacts/types.js";
|
|
21
|
+
|
|
16
22
|
// ── Logger mock (suppress output) ───────────────────────────────────────────
|
|
17
23
|
mock.module("../util/logger.js", () => ({
|
|
18
24
|
getLogger: () =>
|
|
@@ -23,18 +29,45 @@ mock.module("../util/logger.js", () => ({
|
|
|
23
29
|
let _byAddress: ReturnType<
|
|
24
30
|
(typeof import("../contacts/contact-store.js"))["findContactByAddress"]
|
|
25
31
|
> = null;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
// ACL view is carried on memberRecord, sourced from the member-verdict cache.
|
|
33
|
+
// Seed it per test instead of seeding the DB.
|
|
34
|
+
let _acl: { status: ChannelStatus; policy: ChannelPolicy; role: ContactRole } =
|
|
35
|
+
{ status: "unverified", policy: "allow", role: "contact" };
|
|
29
36
|
|
|
30
37
|
mock.module("../contacts/contact-store.js", () => ({
|
|
31
38
|
findContactByAddress: (_type: string, _addr: string) => _byAddress,
|
|
32
|
-
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
// Guardian resolution reads the gateway delivery cache; these suites only
|
|
42
|
+
// exercise the member/address path, so the cache peek stays empty.
|
|
43
|
+
mock.module("../contacts/guardian-delivery-reader.js", () => ({
|
|
44
|
+
peekCachedGuardianDelivery: () => undefined,
|
|
45
|
+
guardianForChannel: () => undefined,
|
|
33
46
|
}));
|
|
34
47
|
|
|
35
48
|
// ── Real import after mocks ───────────────────────────────────────────────────
|
|
36
49
|
import type { ContactWithChannels } from "../contacts/types.js";
|
|
37
50
|
import { resolveActorTrust } from "../runtime/actor-trust-resolver.js";
|
|
51
|
+
import {
|
|
52
|
+
__resetMemberVerdictCacheForTest,
|
|
53
|
+
setMemberVerdict,
|
|
54
|
+
} from "../runtime/member-verdict-cache.js";
|
|
55
|
+
|
|
56
|
+
const CHANNEL_ID = "ch-test";
|
|
57
|
+
const CONTACT_ID = "contact-test";
|
|
58
|
+
|
|
59
|
+
// Seed the member-verdict cache so the sync fallback resolves the member with
|
|
60
|
+
// the configured ACL view (mirrors a warmed gateway verdict).
|
|
61
|
+
function seedAcl(): void {
|
|
62
|
+
setMemberVerdict("phone", PHONE, {
|
|
63
|
+
trustClass: _acl.role === "guardian" ? "guardian" : "unknown",
|
|
64
|
+
canonicalSenderId: PHONE,
|
|
65
|
+
contactId: CONTACT_ID,
|
|
66
|
+
channelId: CHANNEL_ID,
|
|
67
|
+
status: _acl.status,
|
|
68
|
+
policy: _acl.policy,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
38
71
|
|
|
39
72
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
40
73
|
|
|
@@ -44,13 +77,14 @@ function makeContact(
|
|
|
44
77
|
role: "guardian" | "contact" = "contact",
|
|
45
78
|
status: "unverified" | "active" = "unverified",
|
|
46
79
|
): ContactWithChannels {
|
|
47
|
-
|
|
80
|
+
// ACL lives on memberRecord (carrier), sourced from the member-verdict cache —
|
|
81
|
+
// record the intended view so seedAcl() warms it before resolution.
|
|
82
|
+
_acl = { status, policy: "allow", role };
|
|
48
83
|
return {
|
|
49
|
-
id:
|
|
84
|
+
id: CONTACT_ID,
|
|
50
85
|
displayName: "Patrick Test",
|
|
51
|
-
role,
|
|
52
|
-
principalId: null,
|
|
53
86
|
notes: null,
|
|
87
|
+
role,
|
|
54
88
|
lastInteraction: null,
|
|
55
89
|
interactionCount: 0,
|
|
56
90
|
contactType: "human" as const,
|
|
@@ -59,22 +93,16 @@ function makeContact(
|
|
|
59
93
|
updatedAt: 0,
|
|
60
94
|
channels: [
|
|
61
95
|
{
|
|
62
|
-
id:
|
|
63
|
-
contactId:
|
|
96
|
+
id: CHANNEL_ID,
|
|
97
|
+
contactId: CONTACT_ID,
|
|
64
98
|
type: "phone",
|
|
65
99
|
address: PHONE,
|
|
66
100
|
externalChatId: null,
|
|
67
101
|
isPrimary: true,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
verifiedAt: null,
|
|
71
|
-
verifiedVia: null,
|
|
72
|
-
revokedReason: null,
|
|
73
|
-
blockedReason: null,
|
|
102
|
+
inviteId: null,
|
|
103
|
+
lastSeenAt: null,
|
|
74
104
|
interactionCount: 0,
|
|
75
105
|
lastInteraction: null,
|
|
76
|
-
lastSeenAt: null,
|
|
77
|
-
inviteId: null,
|
|
78
106
|
createdAt: 0,
|
|
79
107
|
updatedAt: 0,
|
|
80
108
|
},
|
|
@@ -87,12 +115,14 @@ function makeContact(
|
|
|
87
115
|
describe("resolveActorTrust — address fallback", () => {
|
|
88
116
|
beforeEach(() => {
|
|
89
117
|
_byAddress = null;
|
|
90
|
-
|
|
118
|
+
_acl = { status: "unverified", policy: "allow", role: "contact" };
|
|
119
|
+
__resetMemberVerdictCacheForTest();
|
|
91
120
|
});
|
|
92
121
|
|
|
93
122
|
test("finds unverified channel via address when externalUserId is null", () => {
|
|
94
123
|
// Simulate a contact registered by name-capture: address set, externalUserId null.
|
|
95
124
|
_byAddress = makeContact("contact", "unverified");
|
|
125
|
+
seedAcl();
|
|
96
126
|
|
|
97
127
|
const result = resolveActorTrust({
|
|
98
128
|
assistantId: "asst-1",
|
|
@@ -103,7 +133,7 @@ describe("resolveActorTrust — address fallback", () => {
|
|
|
103
133
|
|
|
104
134
|
expect(result.memberRecord).not.toBeNull();
|
|
105
135
|
expect(result.memberRecord?.contact.displayName).toBe("Patrick Test");
|
|
106
|
-
expect(result.memberRecord?.
|
|
136
|
+
expect(result.memberRecord?.status).toBe("unverified");
|
|
107
137
|
// trustClass is 'unverified_contact' for a member whose channel is
|
|
108
138
|
// pending or unverified — known to the guardian but not yet verified.
|
|
109
139
|
expect(result.trustClass).toBe("unverified_contact");
|
|
@@ -111,6 +141,7 @@ describe("resolveActorTrust — address fallback", () => {
|
|
|
111
141
|
|
|
112
142
|
test("address lookup is the sole member resolution path", () => {
|
|
113
143
|
_byAddress = makeContact("contact", "active");
|
|
144
|
+
seedAcl();
|
|
114
145
|
|
|
115
146
|
const result = resolveActorTrust({
|
|
116
147
|
assistantId: "asst-1",
|
|
@@ -119,7 +150,7 @@ describe("resolveActorTrust — address fallback", () => {
|
|
|
119
150
|
actorExternalId: PHONE,
|
|
120
151
|
});
|
|
121
152
|
|
|
122
|
-
expect(result.memberRecord?.
|
|
153
|
+
expect(result.memberRecord?.status).toBe("active");
|
|
123
154
|
expect(result.memberRecord?.channel.address).toBe(PHONE);
|
|
124
155
|
});
|
|
125
156
|
|
|
@@ -137,10 +168,28 @@ describe("resolveActorTrust — address fallback", () => {
|
|
|
137
168
|
expect(result.trustClass).toBe("unknown");
|
|
138
169
|
});
|
|
139
170
|
|
|
171
|
+
test("fail-closed: contact found but verdict cache miss → unknown", () => {
|
|
172
|
+
// The sync fallback runs only when there is no live verdict; with no cached
|
|
173
|
+
// verdict either, the member stays unresolved and trust is fail-closed.
|
|
174
|
+
_byAddress = makeContact("contact", "active");
|
|
175
|
+
// No seedAcl() — the cache is a miss for this sender.
|
|
176
|
+
|
|
177
|
+
const result = resolveActorTrust({
|
|
178
|
+
assistantId: "asst-1",
|
|
179
|
+
sourceChannel: "phone",
|
|
180
|
+
conversationExternalId: PHONE,
|
|
181
|
+
actorExternalId: PHONE,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
expect(result.memberRecord).toBeNull();
|
|
185
|
+
expect(result.trustClass).toBe("unknown");
|
|
186
|
+
});
|
|
187
|
+
|
|
140
188
|
test("address-found active channel elevates trust to trusted_contact", () => {
|
|
141
189
|
// An active channel found via address (e.g. after manual verify without externalUserId set)
|
|
142
190
|
// should still yield trusted_contact trust class.
|
|
143
191
|
_byAddress = makeContact("contact", "active");
|
|
192
|
+
seedAcl();
|
|
144
193
|
|
|
145
194
|
const result = resolveActorTrust({
|
|
146
195
|
assistantId: "asst-1",
|
|
@@ -150,7 +199,7 @@ describe("resolveActorTrust — address fallback", () => {
|
|
|
150
199
|
});
|
|
151
200
|
|
|
152
201
|
expect(result.memberRecord).not.toBeNull();
|
|
153
|
-
expect(result.memberRecord?.
|
|
202
|
+
expect(result.memberRecord?.status).toBe("active");
|
|
154
203
|
expect(result.trustClass).toBe("trusted_contact");
|
|
155
204
|
});
|
|
156
205
|
|
|
@@ -158,9 +207,10 @@ describe("resolveActorTrust — address fallback", () => {
|
|
|
158
207
|
// Mirrors the unverified branch but for `pending` status (e.g. a phone
|
|
159
208
|
// contact registered by name-capture awaiting the DTMF challenge).
|
|
160
209
|
const contact = makeContact("contact", "unverified");
|
|
161
|
-
// Override status to "pending" — makeContact only accepts unverified/active
|
|
162
|
-
|
|
210
|
+
// Override ACL status to "pending" — makeContact only accepts unverified/active.
|
|
211
|
+
_acl = { ..._acl, status: "pending" };
|
|
163
212
|
_byAddress = contact;
|
|
213
|
+
seedAcl();
|
|
164
214
|
|
|
165
215
|
const result = resolveActorTrust({
|
|
166
216
|
assistantId: "asst-1",
|
|
@@ -169,16 +219,17 @@ describe("resolveActorTrust — address fallback", () => {
|
|
|
169
219
|
actorExternalId: PHONE,
|
|
170
220
|
});
|
|
171
221
|
|
|
172
|
-
expect(result.memberRecord?.
|
|
222
|
+
expect(result.memberRecord?.status).toBe("pending");
|
|
173
223
|
expect(result.trustClass).toBe("unverified_contact");
|
|
174
224
|
});
|
|
175
225
|
|
|
176
226
|
test("blocked-status member is classified as unknown (not unverified_contact)", () => {
|
|
177
227
|
// Hard-deny statuses (blocked, revoked) stay `unknown` — admission-layer
|
|
178
|
-
// re-checks channel
|
|
228
|
+
// re-checks channel status and emits the hard-deny reasons.
|
|
179
229
|
const contact = makeContact("contact", "unverified");
|
|
180
|
-
|
|
230
|
+
_acl = { ..._acl, status: "blocked" };
|
|
181
231
|
_byAddress = contact;
|
|
232
|
+
seedAcl();
|
|
182
233
|
|
|
183
234
|
const result = resolveActorTrust({
|
|
184
235
|
assistantId: "asst-1",
|
|
@@ -187,14 +238,15 @@ describe("resolveActorTrust — address fallback", () => {
|
|
|
187
238
|
actorExternalId: PHONE,
|
|
188
239
|
});
|
|
189
240
|
|
|
190
|
-
expect(result.memberRecord?.
|
|
241
|
+
expect(result.memberRecord?.status).toBe("blocked");
|
|
191
242
|
expect(result.trustClass).toBe("unknown");
|
|
192
243
|
});
|
|
193
244
|
|
|
194
245
|
test("revoked-status member is classified as unknown", () => {
|
|
195
246
|
const contact = makeContact("contact", "unverified");
|
|
196
|
-
|
|
247
|
+
_acl = { ..._acl, status: "revoked" };
|
|
197
248
|
_byAddress = contact;
|
|
249
|
+
seedAcl();
|
|
198
250
|
|
|
199
251
|
const result = resolveActorTrust({
|
|
200
252
|
assistantId: "asst-1",
|
|
@@ -203,7 +255,7 @@ describe("resolveActorTrust — address fallback", () => {
|
|
|
203
255
|
actorExternalId: PHONE,
|
|
204
256
|
});
|
|
205
257
|
|
|
206
|
-
expect(result.memberRecord?.
|
|
258
|
+
expect(result.memberRecord?.status).toBe("revoked");
|
|
207
259
|
expect(result.trustClass).toBe("unknown");
|
|
208
260
|
});
|
|
209
261
|
});
|
|
@@ -12,9 +12,7 @@ import {
|
|
|
12
12
|
_resetStreamStateForTesting,
|
|
13
13
|
_simulateRestartForTesting,
|
|
14
14
|
getCurrentSeq,
|
|
15
|
-
getPersistedSeq,
|
|
16
15
|
getReplayWindow,
|
|
17
|
-
recordPersistedSeq,
|
|
18
16
|
stampAndBuffer,
|
|
19
17
|
} from "../runtime/assistant-stream-state.js";
|
|
20
18
|
|
|
@@ -571,80 +569,9 @@ describe("assistant-stream-state", () => {
|
|
|
571
569
|
});
|
|
572
570
|
});
|
|
573
571
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
});
|
|
578
|
-
|
|
579
|
-
test("records and retrieves a per-conversation value", () => {
|
|
580
|
-
recordPersistedSeq("conv_a", 7);
|
|
581
|
-
expect(getPersistedSeq("conv_a")).toBe(7);
|
|
582
|
-
expect(getPersistedSeq("conv_b")).toBeNull();
|
|
583
|
-
});
|
|
584
|
-
|
|
585
|
-
test("tracks conversations independently", () => {
|
|
586
|
-
recordPersistedSeq("conv_a", 3);
|
|
587
|
-
recordPersistedSeq("conv_b", 9);
|
|
588
|
-
expect(getPersistedSeq("conv_a")).toBe(3);
|
|
589
|
-
expect(getPersistedSeq("conv_b")).toBe(9);
|
|
590
|
-
});
|
|
591
|
-
|
|
592
|
-
test("advances monotonically and never regresses", () => {
|
|
593
|
-
recordPersistedSeq("conv_a", 5);
|
|
594
|
-
recordPersistedSeq("conv_a", 12);
|
|
595
|
-
expect(getPersistedSeq("conv_a")).toBe(12);
|
|
596
|
-
|
|
597
|
-
// A lower seq (e.g. an out-of-order async commit) is clamped.
|
|
598
|
-
recordPersistedSeq("conv_a", 8);
|
|
599
|
-
expect(getPersistedSeq("conv_a")).toBe(12);
|
|
600
|
-
});
|
|
601
|
-
|
|
602
|
-
test("ignores non-positive and non-finite seq values", () => {
|
|
603
|
-
recordPersistedSeq("conv_a", 0);
|
|
604
|
-
recordPersistedSeq("conv_a", -3);
|
|
605
|
-
recordPersistedSeq("conv_a", Number.NaN);
|
|
606
|
-
recordPersistedSeq("conv_a", Number.POSITIVE_INFINITY);
|
|
607
|
-
expect(getPersistedSeq("conv_a")).toBeNull();
|
|
608
|
-
});
|
|
609
|
-
|
|
610
|
-
test("is cleared by reset", () => {
|
|
611
|
-
recordPersistedSeq("conv_a", 4);
|
|
612
|
-
_resetStreamStateForTesting();
|
|
613
|
-
expect(getPersistedSeq("conv_a")).toBeNull();
|
|
614
|
-
});
|
|
615
|
-
|
|
616
|
-
test("evicts the least-recently-recorded conversation past the cap", () => {
|
|
617
|
-
// The map is LRU-bounded at 1024 conversations. Fill to the cap,
|
|
618
|
-
// then one more insert evicts the oldest key.
|
|
619
|
-
const CAP = 1024;
|
|
620
|
-
for (let i = 0; i < CAP; i++) {
|
|
621
|
-
recordPersistedSeq(`conv_${i}`, i + 1);
|
|
622
|
-
}
|
|
623
|
-
// All present at the cap.
|
|
624
|
-
expect(getPersistedSeq("conv_0")).toBe(1);
|
|
625
|
-
expect(getPersistedSeq(`conv_${CAP - 1}`)).toBe(CAP);
|
|
626
|
-
|
|
627
|
-
// One more distinct conversation evicts the oldest (conv_0).
|
|
628
|
-
recordPersistedSeq("conv_overflow", 9999);
|
|
629
|
-
expect(getPersistedSeq("conv_0")).toBeNull();
|
|
630
|
-
expect(getPersistedSeq("conv_1")).toBe(2);
|
|
631
|
-
expect(getPersistedSeq("conv_overflow")).toBe(9999);
|
|
632
|
-
});
|
|
633
|
-
|
|
634
|
-
test("re-recording refreshes recency so a kept key is not evicted first", () => {
|
|
635
|
-
const CAP = 1024;
|
|
636
|
-
for (let i = 0; i < CAP; i++) {
|
|
637
|
-
recordPersistedSeq(`conv_${i}`, i + 1);
|
|
638
|
-
}
|
|
639
|
-
// Touch the oldest key so it moves to the most-recent end.
|
|
640
|
-
recordPersistedSeq("conv_0", 5000);
|
|
641
|
-
|
|
642
|
-
// The next insert now evicts conv_1 (the new oldest), not conv_0.
|
|
643
|
-
recordPersistedSeq("conv_overflow", 9999);
|
|
644
|
-
expect(getPersistedSeq("conv_0")).toBe(5000);
|
|
645
|
-
expect(getPersistedSeq("conv_1")).toBeNull();
|
|
646
|
-
});
|
|
647
|
-
});
|
|
572
|
+
// Per-conversation persisted seq now lives on the `conversations.seq`
|
|
573
|
+
// column (see conversation-crud `getConversationPersistedSeq` /
|
|
574
|
+
// `recordConversationPersistedSeq`); its tests live with that module.
|
|
648
575
|
|
|
649
576
|
describe("seq persistence across restarts", () => {
|
|
650
577
|
test("counter resumes above the persisted reservation after a restart", () => {
|
|
@@ -100,8 +100,10 @@ mock.module("../daemon/process-message.js", () => ({
|
|
|
100
100
|
|
|
101
101
|
const createdConversations: Array<{ conversationType: string }> = [];
|
|
102
102
|
mock.module("../memory/conversation-crud.js", () => ({
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
setConversationProcessingStartedAt: () => {},
|
|
104
|
+
isConversationProcessing: () => false,
|
|
105
|
+
recordConversationPersistedSeq: () => {},
|
|
106
|
+
getConversationPersistedSeq: () => null,
|
|
105
107
|
addMessage: mock(() => ({ id: "msg-1" })),
|
|
106
108
|
archiveConversation: mock(() => true),
|
|
107
109
|
batchSetDisplayOrders: mock(() => {}),
|