@vellumai/assistant 0.5.7 → 0.5.8

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.
Files changed (197) hide show
  1. package/Dockerfile +2 -1
  2. package/docker-entrypoint.sh +9 -0
  3. package/docs/architecture/memory.md +13 -11
  4. package/node_modules/@vellumai/ces-contracts/src/error.ts +1 -1
  5. package/node_modules/@vellumai/ces-contracts/src/grants.ts +1 -1
  6. package/node_modules/@vellumai/ces-contracts/src/handles.ts +1 -1
  7. package/node_modules/@vellumai/ces-contracts/src/index.ts +1 -1
  8. package/node_modules/@vellumai/ces-contracts/src/rpc.ts +1 -1
  9. package/package.json +1 -1
  10. package/src/__tests__/approval-cascade.test.ts +0 -1
  11. package/src/__tests__/browser-fill-credential.test.ts +1 -1
  12. package/src/__tests__/call-controller.test.ts +0 -1
  13. package/src/__tests__/ces-rpc-credential-backend.test.ts +3 -3
  14. package/src/__tests__/ces-startup-timeout.test.ts +40 -0
  15. package/src/__tests__/config-schema-cmd.test.ts +0 -1
  16. package/src/__tests__/config-schema.test.ts +2 -0
  17. package/src/__tests__/conversation-abort-tool-results.test.ts +0 -1
  18. package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -2
  19. package/src/__tests__/conversation-agent-loop.test.ts +2 -4
  20. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -1
  21. package/src/__tests__/conversation-error.test.ts +15 -1
  22. package/src/__tests__/conversation-messaging-secret-redirect.test.ts +1 -1
  23. package/src/__tests__/conversation-pre-run-repair.test.ts +0 -1
  24. package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -1
  25. package/src/__tests__/conversation-queue.test.ts +0 -1
  26. package/src/__tests__/conversation-slash-queue.test.ts +0 -1
  27. package/src/__tests__/conversation-slash-unknown.test.ts +0 -1
  28. package/src/__tests__/conversation-workspace-injection.test.ts +0 -1
  29. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -1
  30. package/src/__tests__/credential-execution-client.test.ts +5 -2
  31. package/src/__tests__/credential-execution-feature-gates.test.ts +31 -16
  32. package/src/__tests__/credential-execution-managed-contract.test.ts +2 -2
  33. package/src/__tests__/credential-security-e2e.test.ts +1 -1
  34. package/src/__tests__/credential-security-invariants.test.ts +2 -5
  35. package/src/__tests__/credentials-cli.test.ts +4 -3
  36. package/src/__tests__/daemon-credential-client.test.ts +123 -0
  37. package/src/__tests__/deterministic-verification-control-plane.test.ts +1 -0
  38. package/src/__tests__/gateway-client-managed-outbound.test.ts +79 -1
  39. package/src/__tests__/journal-context.test.ts +335 -0
  40. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -3
  41. package/src/__tests__/memory-lifecycle-e2e.test.ts +70 -25
  42. package/src/__tests__/memory-recall-quality.test.ts +48 -17
  43. package/src/__tests__/memory-regressions.test.ts +408 -363
  44. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -3
  45. package/src/__tests__/non-member-access-request.test.ts +2 -2
  46. package/src/__tests__/notification-decision-strategy.test.ts +71 -0
  47. package/src/__tests__/oauth-cli.test.ts +5 -1
  48. package/src/__tests__/provider-commit-message-generator.test.ts +0 -37
  49. package/src/__tests__/provider-error-scenarios.test.ts +0 -267
  50. package/src/__tests__/provider-streaming.benchmark.test.ts +2 -81
  51. package/src/__tests__/relay-server.test.ts +1 -2
  52. package/src/__tests__/script-proxy-injection-runtime.test.ts +1 -1
  53. package/src/__tests__/secret-onetime-send.test.ts +1 -1
  54. package/src/__tests__/secure-keys.test.ts +18 -15
  55. package/src/__tests__/skill-memory.test.ts +17 -3
  56. package/src/__tests__/stale-approval-dedup.test.ts +171 -0
  57. package/src/__tests__/stt-hints.test.ts +437 -0
  58. package/src/__tests__/task-memory-cleanup.test.ts +14 -0
  59. package/src/__tests__/twilio-routes-twiml.test.ts +139 -1
  60. package/src/__tests__/voice-quality.test.ts +58 -0
  61. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
  62. package/src/__tests__/workspace-migration-016-migrate-credentials-from-keychain.test.ts +5 -3
  63. package/src/acp/agent-process.ts +9 -1
  64. package/src/agent/loop.ts +1 -1
  65. package/src/approvals/guardian-request-resolvers.ts +164 -38
  66. package/src/calls/__tests__/tts-text-sanitizer.test.ts +254 -0
  67. package/src/calls/call-controller.ts +9 -5
  68. package/src/calls/fish-audio-client.ts +26 -14
  69. package/src/calls/stt-hints.ts +189 -0
  70. package/src/calls/tts-text-sanitizer.ts +61 -0
  71. package/src/calls/twilio-routes.ts +32 -4
  72. package/src/calls/voice-quality.ts +15 -3
  73. package/src/calls/voice-session-bridge.ts +1 -0
  74. package/src/cli/commands/avatar.ts +2 -2
  75. package/src/cli/commands/credentials.ts +110 -94
  76. package/src/cli/commands/doctor.ts +2 -2
  77. package/src/cli/commands/keys.ts +7 -7
  78. package/src/cli/commands/memory.ts +1 -1
  79. package/src/cli/commands/oauth/connections.ts +11 -29
  80. package/src/cli/commands/oauth/platform.ts +389 -43
  81. package/src/cli/lib/daemon-credential-client.ts +284 -0
  82. package/src/cli.ts +1 -1
  83. package/src/config/bundled-skills/AGENTS.md +34 -0
  84. package/src/config/bundled-skills/acp/SKILL.md +10 -0
  85. package/src/config/bundled-skills/app-builder/SKILL.md +0 -4
  86. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -2
  87. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +1 -0
  88. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +1 -0
  89. package/src/config/bundled-skills/settings/SKILL.md +15 -2
  90. package/src/config/bundled-skills/settings/TOOLS.json +46 -1
  91. package/src/config/bundled-skills/settings/tools/avatar-remove.ts +59 -0
  92. package/src/config/bundled-skills/settings/tools/avatar-update.ts +80 -0
  93. package/src/config/bundled-skills/slack/SKILL.md +1 -1
  94. package/src/config/bundled-tool-registry.ts +4 -0
  95. package/src/config/defaults.ts +0 -2
  96. package/src/config/env-registry.ts +4 -4
  97. package/src/config/env.ts +14 -1
  98. package/src/config/feature-flag-registry.json +1 -1
  99. package/src/config/loader.ts +8 -11
  100. package/src/config/schema.ts +5 -16
  101. package/src/config/schemas/calls.ts +17 -0
  102. package/src/config/schemas/inference.ts +2 -2
  103. package/src/config/schemas/journal.ts +16 -0
  104. package/src/config/schemas/memory-processing.ts +2 -2
  105. package/src/config/types.ts +1 -0
  106. package/src/contacts/contact-store.ts +2 -2
  107. package/src/credential-execution/executable-discovery.ts +1 -1
  108. package/src/credential-execution/startup-timeout.ts +36 -0
  109. package/src/daemon/approval-generators.ts +3 -9
  110. package/src/daemon/conversation-error.ts +13 -1
  111. package/src/daemon/conversation-memory.ts +1 -2
  112. package/src/daemon/conversation-process.ts +18 -1
  113. package/src/daemon/conversation-surfaces.ts +30 -1
  114. package/src/daemon/conversation.ts +20 -9
  115. package/src/daemon/guardian-action-generators.ts +3 -9
  116. package/src/daemon/lifecycle.ts +18 -11
  117. package/src/daemon/message-types/conversations.ts +1 -0
  118. package/src/daemon/server.ts +2 -3
  119. package/src/memory/app-store.ts +31 -0
  120. package/src/memory/db-init.ts +4 -0
  121. package/src/memory/indexer.ts +19 -10
  122. package/src/memory/items-extractor.ts +315 -322
  123. package/src/memory/job-handlers/summarization.ts +26 -16
  124. package/src/memory/jobs-store.ts +33 -1
  125. package/src/memory/journal-memory.ts +214 -0
  126. package/src/memory/migrations/193-add-source-type-columns.ts +81 -0
  127. package/src/memory/migrations/index.ts +1 -0
  128. package/src/memory/migrations/registry.ts +8 -0
  129. package/src/memory/retriever.test.ts +37 -25
  130. package/src/memory/retriever.ts +24 -49
  131. package/src/memory/schema/memory-core.ts +2 -0
  132. package/src/memory/search/formatting.ts +7 -44
  133. package/src/memory/search/staleness.ts +4 -0
  134. package/src/memory/search/tier-classifier.ts +10 -2
  135. package/src/memory/search/types.ts +2 -5
  136. package/src/memory/task-memory-cleanup.ts +4 -3
  137. package/src/notifications/adapters/slack.ts +168 -6
  138. package/src/notifications/broadcaster.ts +1 -0
  139. package/src/notifications/copy-composer.ts +59 -2
  140. package/src/notifications/signal.ts +2 -0
  141. package/src/notifications/types.ts +2 -0
  142. package/src/prompts/journal-context.ts +133 -0
  143. package/src/prompts/persona-resolver.ts +80 -24
  144. package/src/prompts/system-prompt.ts +8 -0
  145. package/src/prompts/templates/SOUL.md +10 -0
  146. package/src/providers/provider-send-message.ts +3 -32
  147. package/src/providers/registry.ts +2 -139
  148. package/src/providers/types.ts +1 -1
  149. package/src/runtime/access-request-helper.ts +4 -0
  150. package/src/runtime/auth/__tests__/guard-tests.test.ts +9 -50
  151. package/src/runtime/auth/route-policy.ts +2 -0
  152. package/src/runtime/gateway-client.ts +47 -4
  153. package/src/runtime/guardian-decision-types.ts +45 -4
  154. package/src/runtime/http-server.ts +5 -2
  155. package/src/runtime/routes/access-request-decision.ts +2 -2
  156. package/src/runtime/routes/app-management-routes.ts +2 -1
  157. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +219 -30
  158. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +37 -14
  159. package/src/runtime/routes/channel-readiness-routes.ts +9 -4
  160. package/src/runtime/routes/debug-routes.ts +12 -9
  161. package/src/runtime/routes/guardian-approval-interception.ts +168 -11
  162. package/src/runtime/routes/guardian-approval-prompt.ts +6 -1
  163. package/src/runtime/routes/guardian-approval-reply-helpers.ts +103 -21
  164. package/src/runtime/routes/identity-routes.ts +1 -1
  165. package/src/runtime/routes/inbound-message-handler.ts +31 -1
  166. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +64 -5
  167. package/src/runtime/routes/inbound-stages/background-dispatch.ts +52 -40
  168. package/src/runtime/routes/integrations/twilio.ts +52 -10
  169. package/src/runtime/routes/memory-item-routes.test.ts +3 -3
  170. package/src/runtime/routes/memory-item-routes.ts +25 -11
  171. package/src/runtime/routes/secret-routes.ts +141 -10
  172. package/src/runtime/routes/tts-routes.ts +11 -1
  173. package/src/security/ces-credential-client.ts +18 -9
  174. package/src/security/ces-rpc-credential-backend.ts +4 -3
  175. package/src/security/credential-backend.ts +10 -4
  176. package/src/security/secure-keys.ts +21 -4
  177. package/src/skills/catalog-install.ts +4 -36
  178. package/src/skills/skill-memory.ts +1 -0
  179. package/src/subagent/manager.ts +2 -5
  180. package/src/tools/acp/spawn.ts +78 -1
  181. package/src/tools/credentials/vault.ts +5 -3
  182. package/src/tools/memory/definitions.ts +3 -2
  183. package/src/tools/memory/handlers.ts +10 -7
  184. package/src/tools/terminal/safe-env.ts +1 -0
  185. package/src/util/browser.ts +15 -0
  186. package/src/util/platform.ts +1 -1
  187. package/src/workspace/migrations/016-migrate-credentials-from-keychain.ts +4 -4
  188. package/src/workspace/migrations/017-seed-persona-dirs.ts +2 -1
  189. package/src/workspace/migrations/018-rekey-compound-credential-keys.ts +184 -0
  190. package/src/workspace/migrations/019-scope-journal-to-guardian.ts +103 -0
  191. package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -4
  192. package/src/workspace/migrations/registry.ts +4 -0
  193. package/src/workspace/provider-commit-message-generator.ts +12 -21
  194. package/src/__tests__/provider-fail-open-selection.test.ts +0 -271
  195. package/src/__tests__/provider-failover-actual-provider.test.ts +0 -66
  196. package/src/memory/search/lexical.ts +0 -48
  197. package/src/providers/failover.ts +0 -186
@@ -214,10 +214,11 @@ describe("secure-keys", () => {
214
214
  encryptedStore.setKey("enc-key-1", "val1");
215
215
  encryptedStore.setKey("enc-key-2", "val2");
216
216
 
217
- const keys = await listSecureKeysAsync();
218
- expect(keys).toContain("enc-key-1");
219
- expect(keys).toContain("enc-key-2");
220
- expect(keys.length).toBe(2);
217
+ const result = await listSecureKeysAsync();
218
+ expect(result.unreachable).toBe(false);
219
+ expect(result.accounts).toContain("enc-key-1");
220
+ expect(result.accounts).toContain("enc-key-2");
221
+ expect(result.accounts.length).toBe(2);
221
222
  });
222
223
 
223
224
  test("returns encrypted store keys with VELLUM_DEV=1", async () => {
@@ -227,10 +228,11 @@ describe("secure-keys", () => {
227
228
  encryptedStore.setKey("dev-key-1", "val2");
228
229
  encryptedStore.setKey("dev-key-2", "val3");
229
230
 
230
- const keys = await listSecureKeysAsync();
231
- expect(keys).toContain("dev-key-1");
232
- expect(keys).toContain("dev-key-2");
233
- expect(keys.length).toBe(2);
231
+ const result = await listSecureKeysAsync();
232
+ expect(result.unreachable).toBe(false);
233
+ expect(result.accounts).toContain("dev-key-1");
234
+ expect(result.accounts).toContain("dev-key-2");
235
+ expect(result.accounts.length).toBe(2);
234
236
  });
235
237
 
236
238
  test("returns encrypted store keys with VELLUM_DESKTOP_APP=1", async () => {
@@ -240,15 +242,16 @@ describe("secure-keys", () => {
240
242
  encryptedStore.setKey("desktop-key-1", "val1");
241
243
  encryptedStore.setKey("desktop-key-2", "val2");
242
244
 
243
- const keys = await listSecureKeysAsync();
244
- expect(keys).toContain("desktop-key-1");
245
- expect(keys).toContain("desktop-key-2");
246
- expect(keys.length).toBe(2);
245
+ const result = await listSecureKeysAsync();
246
+ expect(result.unreachable).toBe(false);
247
+ expect(result.accounts).toContain("desktop-key-1");
248
+ expect(result.accounts).toContain("desktop-key-2");
249
+ expect(result.accounts.length).toBe(2);
247
250
  });
248
251
 
249
- test("returns empty array when store is empty", async () => {
250
- const keys = await listSecureKeysAsync();
251
- expect(keys).toEqual([]);
252
+ test("returns empty accounts when store is empty", async () => {
253
+ const result = await listSecureKeysAsync();
254
+ expect(result).toEqual({ accounts: [], unreachable: false });
252
255
  });
253
256
  });
254
257
 
@@ -276,8 +276,14 @@ describe("upsertSkillCapabilityMemory", () => {
276
276
  upsertSkillCapabilityMemory("test-skill", makeSkill());
277
277
  }).not.toThrow();
278
278
 
279
- // Restore DB state for subsequent tests
279
+ // Restore DB state for subsequent tests.
280
+ // Delete the entire DB so initializeDb recreates it from scratch — just
281
+ // resetting the connection leaves stale migration checkpoints that skip
282
+ // checkpoint-guarded ALTER TABLE migrations (e.g. source_type column).
280
283
  resetDb();
284
+ for (const ext of ["", "-wal", "-shm"]) {
285
+ rmSync(join(testDir, `test.db${ext}`), { force: true });
286
+ }
281
287
  initializeDb();
282
288
  });
283
289
  });
@@ -324,8 +330,12 @@ describe("deleteSkillCapabilityMemory", () => {
324
330
  deleteSkillCapabilityMemory("test-skill");
325
331
  }).not.toThrow();
326
332
 
327
- // Restore DB state for subsequent tests
333
+ // Restore DB state for subsequent tests (see upsert "does not throw" test
334
+ // for rationale on why we delete the DB file).
328
335
  resetDb();
336
+ for (const ext of ["", "-wal", "-shm"]) {
337
+ rmSync(join(testDir, `test.db${ext}`), { force: true });
338
+ }
329
339
  initializeDb();
330
340
  });
331
341
  });
@@ -542,8 +552,12 @@ describe("seedCatalogSkillMemories", () => {
542
552
 
543
553
  await expect(seedCatalogSkillMemories()).resolves.toBeUndefined();
544
554
 
545
- // Restore DB state for subsequent tests
555
+ // Restore DB state for subsequent tests (see upsert "does not throw" test
556
+ // for rationale on why we delete the DB file).
546
557
  resetDb();
558
+ for (const ext of ["", "-wal", "-shm"]) {
559
+ rmSync(join(testDir, `test.db${ext}`), { force: true });
560
+ }
547
561
  initializeDb();
548
562
  });
549
563
  });
@@ -0,0 +1,171 @@
1
+ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // Mocks — must be declared before importing the module under test
5
+ // ---------------------------------------------------------------------------
6
+
7
+ mock.module("../util/logger.js", () => ({
8
+ getLogger: () =>
9
+ new Proxy({} as Record<string, unknown>, {
10
+ get: () => () => {},
11
+ }),
12
+ }));
13
+
14
+ const deliveredMessages: Array<{
15
+ url: string;
16
+ body: Record<string, unknown>;
17
+ }> = [];
18
+
19
+ let deliveryShouldFail = false;
20
+
21
+ mock.module("../runtime/gateway-client.js", () => ({
22
+ deliverChannelReply: async (url: string, body: Record<string, unknown>) => {
23
+ if (deliveryShouldFail) {
24
+ throw new Error("simulated delivery failure");
25
+ }
26
+ deliveredMessages.push({ url, body });
27
+ },
28
+ }));
29
+
30
+ mock.module("../runtime/approval-message-composer.js", () => ({
31
+ composeApprovalMessageGenerative: async () => "Already resolved.",
32
+ }));
33
+
34
+ // ---------------------------------------------------------------------------
35
+ // Import the module under test after mocks are set up
36
+ // ---------------------------------------------------------------------------
37
+
38
+ import type pino from "pino";
39
+
40
+ import {
41
+ clearStaleNotificationCache,
42
+ deliverStaleApprovalReply,
43
+ } from "../runtime/routes/guardian-approval-reply-helpers.js";
44
+
45
+ const noopLogger = new Proxy({} as pino.Logger, {
46
+ get: () => () => {},
47
+ });
48
+
49
+ // ---------------------------------------------------------------------------
50
+ // Tests
51
+ // ---------------------------------------------------------------------------
52
+
53
+ describe("deliverStaleApprovalReply deduplication", () => {
54
+ beforeEach(() => {
55
+ deliveredMessages.length = 0;
56
+ deliveryShouldFail = false;
57
+ clearStaleNotificationCache();
58
+ });
59
+
60
+ afterEach(() => {
61
+ clearStaleNotificationCache();
62
+ });
63
+
64
+ test("sends the first 'approval_already_resolved' notification", async () => {
65
+ await deliverStaleApprovalReply({
66
+ scenario: "approval_already_resolved",
67
+ sourceChannel: "slack",
68
+ replyCallbackUrl: "https://example.com/reply",
69
+ chatId: "chat-1",
70
+ assistantId: "asst-1",
71
+ logger: noopLogger,
72
+ errorLogMessage: "test",
73
+ });
74
+
75
+ expect(deliveredMessages).toHaveLength(1);
76
+ });
77
+
78
+ test("suppresses duplicate 'approval_already_resolved' for the same chat", async () => {
79
+ const params = {
80
+ scenario: "approval_already_resolved" as const,
81
+ sourceChannel: "slack" as const,
82
+ replyCallbackUrl: "https://example.com/reply",
83
+ chatId: "chat-1",
84
+ assistantId: "asst-1",
85
+ logger: noopLogger,
86
+ errorLogMessage: "test",
87
+ };
88
+
89
+ await deliverStaleApprovalReply(params);
90
+ await deliverStaleApprovalReply(params);
91
+ await deliverStaleApprovalReply(params);
92
+
93
+ expect(deliveredMessages).toHaveLength(1);
94
+ });
95
+
96
+ test("allows 'approval_already_resolved' for different chats", async () => {
97
+ const base = {
98
+ scenario: "approval_already_resolved" as const,
99
+ sourceChannel: "slack" as const,
100
+ replyCallbackUrl: "https://example.com/reply",
101
+ assistantId: "asst-1",
102
+ logger: noopLogger,
103
+ errorLogMessage: "test",
104
+ };
105
+
106
+ await deliverStaleApprovalReply({ ...base, chatId: "chat-1" });
107
+ await deliverStaleApprovalReply({ ...base, chatId: "chat-2" });
108
+
109
+ expect(deliveredMessages).toHaveLength(2);
110
+ });
111
+
112
+ test("does not deduplicate non-'approval_already_resolved' scenarios", async () => {
113
+ const params = {
114
+ scenario: "reminder_prompt" as const,
115
+ sourceChannel: "slack" as const,
116
+ replyCallbackUrl: "https://example.com/reply",
117
+ chatId: "chat-1",
118
+ assistantId: "asst-1",
119
+ logger: noopLogger,
120
+ errorLogMessage: "test",
121
+ };
122
+
123
+ await deliverStaleApprovalReply(params);
124
+ await deliverStaleApprovalReply(params);
125
+
126
+ expect(deliveredMessages).toHaveLength(2);
127
+ });
128
+
129
+ test("allows re-send after cache is cleared (simulates TTL expiry)", async () => {
130
+ const params = {
131
+ scenario: "approval_already_resolved" as const,
132
+ sourceChannel: "slack" as const,
133
+ replyCallbackUrl: "https://example.com/reply",
134
+ chatId: "chat-1",
135
+ assistantId: "asst-1",
136
+ logger: noopLogger,
137
+ errorLogMessage: "test",
138
+ };
139
+
140
+ await deliverStaleApprovalReply(params);
141
+ expect(deliveredMessages).toHaveLength(1);
142
+
143
+ // Simulate TTL expiry
144
+ clearStaleNotificationCache();
145
+
146
+ await deliverStaleApprovalReply(params);
147
+ expect(deliveredMessages).toHaveLength(2);
148
+ });
149
+
150
+ test("does not cache dedup key when delivery fails, allowing retries", async () => {
151
+ const params = {
152
+ scenario: "approval_already_resolved" as const,
153
+ sourceChannel: "slack" as const,
154
+ replyCallbackUrl: "https://example.com/reply",
155
+ chatId: "chat-1",
156
+ assistantId: "asst-1",
157
+ logger: noopLogger,
158
+ errorLogMessage: "test",
159
+ };
160
+
161
+ // First attempt fails — should not cache the dedup key
162
+ deliveryShouldFail = true;
163
+ await deliverStaleApprovalReply(params);
164
+ expect(deliveredMessages).toHaveLength(0);
165
+
166
+ // Second attempt succeeds — should not be suppressed by dedup
167
+ deliveryShouldFail = false;
168
+ await deliverStaleApprovalReply(params);
169
+ expect(deliveredMessages).toHaveLength(1);
170
+ });
171
+ });