@vellumai/assistant 0.4.33 → 0.4.34

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 (137) hide show
  1. package/package.json +1 -1
  2. package/src/__tests__/access-request-decision.test.ts +2 -3
  3. package/src/__tests__/actor-token-service.test.ts +4 -11
  4. package/src/__tests__/approval-primitive.test.ts +0 -45
  5. package/src/__tests__/assistant-id-boundary-guard.test.ts +150 -0
  6. package/src/__tests__/callback-handoff-copy.test.ts +0 -1
  7. package/src/__tests__/channel-approval-routes.test.ts +5 -45
  8. package/src/__tests__/channel-guardian.test.ts +122 -345
  9. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +4 -3
  10. package/src/__tests__/contacts-tools.test.ts +4 -5
  11. package/src/__tests__/conversation-attention-store.test.ts +2 -65
  12. package/src/__tests__/conversation-attention-telegram.test.ts +0 -2
  13. package/src/__tests__/conversation-pairing.test.ts +0 -1
  14. package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -2
  15. package/src/__tests__/guardian-action-conversation-turn.test.ts +1 -7
  16. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -74
  17. package/src/__tests__/guardian-action-late-reply.test.ts +1 -8
  18. package/src/__tests__/guardian-grant-minting.test.ts +0 -1
  19. package/src/__tests__/guardian-routing-state.test.ts +0 -3
  20. package/src/__tests__/inbound-invite-redemption.test.ts +0 -3
  21. package/src/__tests__/non-member-access-request.test.ts +0 -7
  22. package/src/__tests__/notification-broadcaster.test.ts +1 -2
  23. package/src/__tests__/notification-decision-fallback.test.ts +0 -2
  24. package/src/__tests__/notification-decision-strategy.test.ts +0 -1
  25. package/src/__tests__/relay-server.test.ts +11 -83
  26. package/src/__tests__/scoped-approval-grants.test.ts +9 -40
  27. package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -36
  28. package/src/__tests__/send-endpoint-busy.test.ts +0 -1
  29. package/src/__tests__/send-notification-tool.test.ts +0 -1
  30. package/src/__tests__/slack-inbound-verification.test.ts +2 -4
  31. package/src/__tests__/thread-seed-composer.test.ts +0 -1
  32. package/src/__tests__/tool-approval-handler.test.ts +0 -1
  33. package/src/__tests__/tool-grant-request-escalation.test.ts +0 -4
  34. package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -5
  35. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +1 -17
  36. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -13
  37. package/src/__tests__/trusted-contact-verification.test.ts +3 -15
  38. package/src/__tests__/twilio-routes.test.ts +2 -2
  39. package/src/__tests__/voice-invite-redemption.test.ts +0 -1
  40. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -37
  41. package/src/approvals/approval-primitive.ts +0 -15
  42. package/src/approvals/guardian-decision-primitive.ts +0 -3
  43. package/src/approvals/guardian-request-resolvers.ts +0 -5
  44. package/src/calls/call-domain.ts +0 -3
  45. package/src/calls/call-store.ts +0 -3
  46. package/src/calls/guardian-action-sweep.ts +2 -1
  47. package/src/calls/guardian-dispatch.ts +1 -2
  48. package/src/calls/relay-access-wait.ts +0 -4
  49. package/src/calls/relay-server.ts +3 -11
  50. package/src/calls/relay-setup-router.ts +1 -2
  51. package/src/calls/relay-verification.ts +0 -1
  52. package/src/calls/twilio-routes.ts +0 -3
  53. package/src/calls/types.ts +0 -1
  54. package/src/calls/voice-session-bridge.ts +0 -1
  55. package/src/config/bundled-skills/notifications/tools/send-notification.ts +0 -1
  56. package/src/contacts/contact-store.ts +13 -88
  57. package/src/contacts/contacts-write.ts +3 -11
  58. package/src/contacts/types.ts +0 -1
  59. package/src/daemon/handlers/config-channels.ts +16 -42
  60. package/src/daemon/handlers/config-inbox.ts +6 -6
  61. package/src/daemon/handlers/contacts.ts +3 -11
  62. package/src/daemon/handlers/index.ts +0 -2
  63. package/src/daemon/session-process.ts +0 -4
  64. package/src/memory/conversation-attention-store.ts +4 -19
  65. package/src/memory/conversation-crud.ts +0 -2
  66. package/src/memory/db-init.ts +4 -0
  67. package/src/memory/guardian-action-store.ts +0 -12
  68. package/src/memory/guardian-approvals.ts +35 -80
  69. package/src/memory/guardian-rate-limits.ts +1 -14
  70. package/src/memory/guardian-verification.ts +6 -34
  71. package/src/memory/invite-store.ts +5 -14
  72. package/src/memory/migrations/134-contacts-notes-column.ts +64 -45
  73. package/src/memory/migrations/136-drop-assistant-id-columns.ts +263 -0
  74. package/src/memory/migrations/index.ts +1 -0
  75. package/src/memory/migrations/registry.ts +14 -1
  76. package/src/memory/schema/calls.ts +0 -7
  77. package/src/memory/schema/contacts.ts +0 -8
  78. package/src/memory/schema/guardian.ts +0 -5
  79. package/src/memory/schema/infrastructure.ts +0 -2
  80. package/src/memory/schema/notifications.ts +3 -17
  81. package/src/memory/scoped-approval-grants.ts +2 -24
  82. package/src/notifications/adapters/sms.ts +2 -1
  83. package/src/notifications/broadcaster.ts +1 -6
  84. package/src/notifications/decision-engine.ts +3 -4
  85. package/src/notifications/deliveries-store.ts +0 -4
  86. package/src/notifications/destination-resolver.ts +4 -6
  87. package/src/notifications/deterministic-checks.ts +1 -6
  88. package/src/notifications/emit-signal.ts +4 -11
  89. package/src/notifications/events-store.ts +7 -17
  90. package/src/notifications/preference-summary.ts +2 -2
  91. package/src/notifications/preferences-store.ts +2 -9
  92. package/src/notifications/signal.ts +0 -1
  93. package/src/notifications/thread-candidates.ts +1 -11
  94. package/src/notifications/types.ts +0 -3
  95. package/src/runtime/access-request-helper.ts +3 -10
  96. package/src/runtime/actor-refresh-token-store.ts +0 -6
  97. package/src/runtime/actor-token-store.ts +3 -16
  98. package/src/runtime/actor-trust-resolver.ts +1 -4
  99. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -9
  100. package/src/runtime/auth/credential-service.ts +1 -15
  101. package/src/runtime/auth/require-bound-guardian.ts +1 -4
  102. package/src/runtime/channel-guardian-service.ts +15 -46
  103. package/src/runtime/channel-invite-transport.ts +8 -0
  104. package/src/runtime/channel-invite-transports/email.ts +4 -0
  105. package/src/runtime/channel-invite-transports/slack.ts +6 -0
  106. package/src/runtime/channel-invite-transports/sms.ts +4 -0
  107. package/src/runtime/channel-invite-transports/telegram.ts +6 -0
  108. package/src/runtime/confirmation-request-guardian-bridge.ts +0 -1
  109. package/src/runtime/guardian-action-followup-executor.ts +3 -2
  110. package/src/runtime/guardian-action-grant-minter.ts +0 -1
  111. package/src/runtime/guardian-outbound-actions.ts +2 -12
  112. package/src/runtime/guardian-vellum-migration.ts +2 -3
  113. package/src/runtime/http-server.ts +0 -1
  114. package/src/runtime/invite-redemption-service.ts +1 -14
  115. package/src/runtime/local-actor-identity.ts +2 -5
  116. package/src/runtime/routes/access-request-decision.ts +0 -1
  117. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +0 -9
  118. package/src/runtime/routes/channel-readiness-routes.ts +29 -18
  119. package/src/runtime/routes/contact-routes.ts +15 -40
  120. package/src/runtime/routes/conversation-attention-routes.ts +0 -2
  121. package/src/runtime/routes/global-search-routes.ts +0 -2
  122. package/src/runtime/routes/guardian-bootstrap-routes.ts +5 -6
  123. package/src/runtime/routes/guardian-expiry-sweep.ts +3 -2
  124. package/src/runtime/routes/inbound-message-handler.ts +0 -3
  125. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +7 -43
  126. package/src/runtime/routes/inbound-stages/background-dispatch.ts +1 -4
  127. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +1 -6
  128. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +0 -1
  129. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +0 -1
  130. package/src/runtime/routes/inbound-stages/verification-intercept.ts +3 -7
  131. package/src/runtime/routes/pairing-routes.ts +4 -4
  132. package/src/runtime/tool-grant-request-helper.ts +0 -1
  133. package/src/tools/browser/browser-manager.ts +22 -21
  134. package/src/tools/browser/runtime-check.ts +111 -6
  135. package/src/tools/calls/call-start.ts +1 -3
  136. package/src/tools/followups/followup_create.ts +1 -2
  137. package/src/tools/tool-approval-handler.ts +0 -2
@@ -9,7 +9,6 @@
9
9
  import { and, count, desc, eq, gt, lte } from "drizzle-orm";
10
10
  import { v4 as uuid } from "uuid";
11
11
 
12
- import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
13
12
  import { getDb } from "./db.js";
14
13
  import { channelGuardianApprovalRequests } from "./schema.js";
15
14
 
@@ -29,7 +28,6 @@ export interface GuardianApprovalRequest {
29
28
  runId: string;
30
29
  requestId: string;
31
30
  conversationId: string;
32
- assistantId: string;
33
31
  channel: string;
34
32
  requesterExternalUserId: string;
35
33
  requesterChatId: string;
@@ -57,7 +55,6 @@ function rowToApprovalRequest(
57
55
  runId: row.runId,
58
56
  requestId: row.requestId ?? row.runId,
59
57
  conversationId: row.conversationId,
60
- assistantId: row.assistantId,
61
58
  channel: row.channel,
62
59
  requesterExternalUserId: row.requesterExternalUserId,
63
60
  requesterChatId: row.requesterChatId,
@@ -88,7 +85,6 @@ export function createApprovalRequest(params: {
88
85
  runId: string;
89
86
  requestId?: string;
90
87
  conversationId: string;
91
- assistantId?: string;
92
88
  channel: string;
93
89
  requesterExternalUserId: string;
94
90
  requesterChatId: string;
@@ -108,7 +104,6 @@ export function createApprovalRequest(params: {
108
104
  runId: params.runId,
109
105
  requestId: params.requestId ?? null,
110
106
  conversationId: params.conversationId,
111
- assistantId: params.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID,
112
107
  channel: params.channel,
113
108
  requesterExternalUserId: params.requesterExternalUserId,
114
109
  requesterChatId: params.requesterChatId,
@@ -172,34 +167,25 @@ export function getUnresolvedApprovalForRequest(
172
167
  /**
173
168
  * Find a pending guardian approval request by the guardian's chat ID.
174
169
  * Used when the guardian sends a decision from their chat.
175
- *
176
- * When `assistantId` is provided, the lookup is scoped to that assistant,
177
- * preventing cross-assistant approval consumption in shared guardian chats.
178
170
  */
179
171
  export function getPendingApprovalByGuardianChat(
180
172
  channel: string,
181
173
  guardianChatId: string,
182
- assistantId?: string,
183
174
  ): GuardianApprovalRequest | null {
184
175
  const db = getDb();
185
176
  const now = Date.now();
186
177
 
187
- const conditions = [
188
- eq(channelGuardianApprovalRequests.channel, channel),
189
- eq(channelGuardianApprovalRequests.guardianChatId, guardianChatId),
190
- eq(channelGuardianApprovalRequests.status, "pending"),
191
- gt(channelGuardianApprovalRequests.expiresAt, now),
192
- ];
193
- if (assistantId) {
194
- conditions.push(
195
- eq(channelGuardianApprovalRequests.assistantId, assistantId),
196
- );
197
- }
198
-
199
178
  const row = db
200
179
  .select()
201
180
  .from(channelGuardianApprovalRequests)
202
- .where(and(...conditions))
181
+ .where(
182
+ and(
183
+ eq(channelGuardianApprovalRequests.channel, channel),
184
+ eq(channelGuardianApprovalRequests.guardianChatId, guardianChatId),
185
+ eq(channelGuardianApprovalRequests.status, "pending"),
186
+ gt(channelGuardianApprovalRequests.expiresAt, now),
187
+ ),
188
+ )
203
189
  .orderBy(desc(channelGuardianApprovalRequests.createdAt))
204
190
  .get();
205
191
 
@@ -216,28 +202,22 @@ export function getPendingApprovalByRequestAndGuardianChat(
216
202
  requestId: string,
217
203
  channel: string,
218
204
  guardianChatId: string,
219
- assistantId?: string,
220
205
  ): GuardianApprovalRequest | null {
221
206
  const db = getDb();
222
207
  const now = Date.now();
223
208
 
224
- const conditions = [
225
- eq(channelGuardianApprovalRequests.requestId, requestId),
226
- eq(channelGuardianApprovalRequests.channel, channel),
227
- eq(channelGuardianApprovalRequests.guardianChatId, guardianChatId),
228
- eq(channelGuardianApprovalRequests.status, "pending"),
229
- gt(channelGuardianApprovalRequests.expiresAt, now),
230
- ];
231
- if (assistantId) {
232
- conditions.push(
233
- eq(channelGuardianApprovalRequests.assistantId, assistantId),
234
- );
235
- }
236
-
237
209
  const row = db
238
210
  .select()
239
211
  .from(channelGuardianApprovalRequests)
240
- .where(and(...conditions))
212
+ .where(
213
+ and(
214
+ eq(channelGuardianApprovalRequests.requestId, requestId),
215
+ eq(channelGuardianApprovalRequests.channel, channel),
216
+ eq(channelGuardianApprovalRequests.guardianChatId, guardianChatId),
217
+ eq(channelGuardianApprovalRequests.status, "pending"),
218
+ gt(channelGuardianApprovalRequests.expiresAt, now),
219
+ ),
220
+ )
241
221
  .get();
242
222
 
243
223
  return row ? rowToApprovalRequest(row) : null;
@@ -247,34 +227,25 @@ export function getPendingApprovalByRequestAndGuardianChat(
247
227
  * Return all pending (non-expired) guardian approval requests for a given
248
228
  * guardian chat and channel. Used to detect ambiguity when a guardian sends
249
229
  * a plain-text decision while multiple approvals are pending.
250
- *
251
- * When `assistantId` is provided, the results are scoped to that assistant
252
- * to prevent cross-assistant approval consumption.
253
230
  */
254
231
  export function getAllPendingApprovalsByGuardianChat(
255
232
  channel: string,
256
233
  guardianChatId: string,
257
- assistantId?: string,
258
234
  ): GuardianApprovalRequest[] {
259
235
  const db = getDb();
260
236
  const now = Date.now();
261
237
 
262
- const conditions = [
263
- eq(channelGuardianApprovalRequests.channel, channel),
264
- eq(channelGuardianApprovalRequests.guardianChatId, guardianChatId),
265
- eq(channelGuardianApprovalRequests.status, "pending"),
266
- gt(channelGuardianApprovalRequests.expiresAt, now),
267
- ];
268
- if (assistantId) {
269
- conditions.push(
270
- eq(channelGuardianApprovalRequests.assistantId, assistantId),
271
- );
272
- }
273
-
274
238
  const rows = db
275
239
  .select()
276
240
  .from(channelGuardianApprovalRequests)
277
- .where(and(...conditions))
241
+ .where(
242
+ and(
243
+ eq(channelGuardianApprovalRequests.channel, channel),
244
+ eq(channelGuardianApprovalRequests.guardianChatId, guardianChatId),
245
+ eq(channelGuardianApprovalRequests.status, "pending"),
246
+ gt(channelGuardianApprovalRequests.expiresAt, now),
247
+ ),
248
+ )
278
249
  .orderBy(desc(channelGuardianApprovalRequests.createdAt))
279
250
  .all();
280
251
 
@@ -326,11 +297,10 @@ export function updateApprovalDecision(
326
297
  // ---------------------------------------------------------------------------
327
298
 
328
299
  /**
329
- * List approval requests filtered by assistant, and optionally by channel,
330
- * conversation, and status. Returns a paginated list of escalations.
300
+ * List approval requests optionally filtered by channel, conversation, and
301
+ * status. Returns a paginated list of escalations.
331
302
  */
332
303
  export function listPendingApprovalRequests(params: {
333
- assistantId?: string;
334
304
  channel?: string;
335
305
  conversationId?: string;
336
306
  status?: ApprovalRequestStatus;
@@ -339,12 +309,7 @@ export function listPendingApprovalRequests(params: {
339
309
  }): GuardianApprovalRequest[] {
340
310
  const db = getDb();
341
311
 
342
- const conditions = [
343
- eq(
344
- channelGuardianApprovalRequests.assistantId,
345
- params.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID,
346
- ),
347
- ];
312
+ const conditions: ReturnType<typeof eq>[] = [];
348
313
  if (params.channel) {
349
314
  conditions.push(
350
315
  eq(channelGuardianApprovalRequests.channel, params.channel),
@@ -447,26 +412,18 @@ export function resolveApprovalRequest(
447
412
  * Count pending approval requests for a given conversation.
448
413
  * Used by thread state projection to compute `pending_escalation_count`.
449
414
  */
450
- export function countPendingByConversation(
451
- conversationId: string,
452
- assistantId?: string,
453
- ): number {
415
+ export function countPendingByConversation(conversationId: string): number {
454
416
  const db = getDb();
455
417
 
456
- const conditions = [
457
- eq(channelGuardianApprovalRequests.conversationId, conversationId),
458
- eq(channelGuardianApprovalRequests.status, "pending"),
459
- ];
460
- if (assistantId) {
461
- conditions.push(
462
- eq(channelGuardianApprovalRequests.assistantId, assistantId),
463
- );
464
- }
465
-
466
418
  const result = db
467
419
  .select({ count: count() })
468
420
  .from(channelGuardianApprovalRequests)
469
- .where(and(...conditions))
421
+ .where(
422
+ and(
423
+ eq(channelGuardianApprovalRequests.conversationId, conversationId),
424
+ eq(channelGuardianApprovalRequests.status, "pending"),
425
+ ),
426
+ )
470
427
  .get();
471
428
 
472
429
  return result?.count ?? 0;
@@ -478,7 +435,6 @@ export function countPendingByConversation(
478
435
  * Retained for existing test fixtures that check legacy approval dedup.
479
436
  */
480
437
  export function findPendingAccessRequestForRequester(
481
- assistantId: string,
482
438
  channel: string,
483
439
  requesterExternalUserId: string,
484
440
  toolName: string,
@@ -491,7 +447,6 @@ export function findPendingAccessRequestForRequester(
491
447
  .from(channelGuardianApprovalRequests)
492
448
  .where(
493
449
  and(
494
- eq(channelGuardianApprovalRequests.assistantId, assistantId),
495
450
  eq(channelGuardianApprovalRequests.channel, channel),
496
451
  eq(
497
452
  channelGuardianApprovalRequests.requesterExternalUserId,
@@ -17,7 +17,6 @@ import { channelGuardianRateLimits } from "./schema.js";
17
17
 
18
18
  export interface VerificationRateLimit {
19
19
  id: string;
20
- assistantId: string;
21
20
  channel: string;
22
21
  actorExternalUserId: string;
23
22
  actorChatId: string;
@@ -49,7 +48,6 @@ function rowToRateLimit(
49
48
  const timestamps = parseTimestamps(row.attemptTimestampsJson);
50
49
  return {
51
50
  id: row.id,
52
- assistantId: row.assistantId,
53
51
  channel: row.channel,
54
52
  actorExternalUserId: row.actorExternalUserId,
55
53
  actorChatId: row.actorChatId,
@@ -69,7 +67,6 @@ function rowToRateLimit(
69
67
  * Get the rate-limit record for a given actor on a specific channel.
70
68
  */
71
69
  export function getRateLimit(
72
- assistantId: string,
73
70
  channel: string,
74
71
  actorExternalUserId: string,
75
72
  actorChatId: string,
@@ -80,7 +77,6 @@ export function getRateLimit(
80
77
  .from(channelGuardianRateLimits)
81
78
  .where(
82
79
  and(
83
- eq(channelGuardianRateLimits.assistantId, assistantId),
84
80
  eq(channelGuardianRateLimits.channel, channel),
85
81
  eq(channelGuardianRateLimits.actorExternalUserId, actorExternalUserId),
86
82
  eq(channelGuardianRateLimits.actorChatId, actorChatId),
@@ -101,7 +97,6 @@ export function getRateLimit(
101
97
  * accumulate indefinitely.
102
98
  */
103
99
  export function recordInvalidAttempt(
104
- assistantId: string,
105
100
  channel: string,
106
101
  actorExternalUserId: string,
107
102
  actorChatId: string,
@@ -113,12 +108,7 @@ export function recordInvalidAttempt(
113
108
  const now = Date.now();
114
109
  const cutoff = now - windowMs;
115
110
 
116
- const existing = getRateLimit(
117
- assistantId,
118
- channel,
119
- actorExternalUserId,
120
- actorChatId,
121
- );
111
+ const existing = getRateLimit(channel, actorExternalUserId, actorChatId);
122
112
 
123
113
  if (existing) {
124
114
  // Keep only timestamps within the sliding window, then add the new one
@@ -158,7 +148,6 @@ export function recordInvalidAttempt(
158
148
  const lockedUntil = 1 >= maxAttempts ? now + lockoutMs : null;
159
149
  const row = {
160
150
  id,
161
- assistantId,
162
151
  channel,
163
152
  actorExternalUserId,
164
153
  actorChatId,
@@ -181,7 +170,6 @@ export function recordInvalidAttempt(
181
170
  * successful verification).
182
171
  */
183
172
  export function resetRateLimit(
184
- assistantId: string,
185
173
  channel: string,
186
174
  actorExternalUserId: string,
187
175
  actorChatId: string,
@@ -197,7 +185,6 @@ export function resetRateLimit(
197
185
  })
198
186
  .where(
199
187
  and(
200
- eq(channelGuardianRateLimits.assistantId, assistantId),
201
188
  eq(channelGuardianRateLimits.channel, channel),
202
189
  eq(channelGuardianRateLimits.actorExternalUserId, actorExternalUserId),
203
190
  eq(channelGuardianRateLimits.actorChatId, actorChatId),
@@ -30,7 +30,6 @@ export type VerificationPurpose = "guardian" | "trusted_contact";
30
30
 
31
31
  export interface VerificationChallenge {
32
32
  id: string;
33
- assistantId: string;
34
33
  channel: string;
35
34
  challengeHash: string;
36
35
  expiresAt: number;
@@ -68,7 +67,6 @@ function rowToChallenge(
68
67
  ): VerificationChallenge {
69
68
  return {
70
69
  id: row.id,
71
- assistantId: row.assistantId,
72
70
  channel: row.channel,
73
71
  challengeHash: row.challengeHash,
74
72
  expiresAt: row.expiresAt,
@@ -101,7 +99,6 @@ function rowToChallenge(
101
99
 
102
100
  export function createChallenge(params: {
103
101
  id: string;
104
- assistantId: string;
105
102
  channel: string;
106
103
  challengeHash: string;
107
104
  expiresAt: number;
@@ -110,16 +107,12 @@ export function createChallenge(params: {
110
107
  const db = getDb();
111
108
  const now = Date.now();
112
109
 
113
- // Revoke any prior pending challenges for the same (assistantId, channel)
110
+ // Revoke any prior pending challenges for the same channel
114
111
  // to close the replay window — only the latest challenge should be valid.
115
112
  db.update(channelGuardianVerificationChallenges)
116
113
  .set({ status: "revoked", updatedAt: now })
117
114
  .where(
118
115
  and(
119
- eq(
120
- channelGuardianVerificationChallenges.assistantId,
121
- params.assistantId,
122
- ),
123
116
  eq(channelGuardianVerificationChallenges.channel, params.channel),
124
117
  eq(channelGuardianVerificationChallenges.status, "pending"),
125
118
  ),
@@ -128,7 +121,6 @@ export function createChallenge(params: {
128
121
 
129
122
  const row = {
130
123
  id: params.id,
131
- assistantId: params.assistantId,
132
124
  channel: params.channel,
133
125
  challengeHash: params.challengeHash,
134
126
  expiresAt: params.expiresAt,
@@ -157,16 +149,12 @@ export function createChallenge(params: {
157
149
  return rowToChallenge(row);
158
150
  }
159
151
 
160
- export function revokePendingChallenges(
161
- assistantId: string,
162
- channel: string,
163
- ): void {
152
+ export function revokePendingChallenges(channel: string): void {
164
153
  const db = getDb();
165
154
  db.update(channelGuardianVerificationChallenges)
166
155
  .set({ status: "revoked", updatedAt: Date.now() })
167
156
  .where(
168
157
  and(
169
- eq(channelGuardianVerificationChallenges.assistantId, assistantId),
170
158
  eq(channelGuardianVerificationChallenges.channel, channel),
171
159
  eq(channelGuardianVerificationChallenges.status, "pending"),
172
160
  ),
@@ -175,7 +163,6 @@ export function revokePendingChallenges(
175
163
  }
176
164
 
177
165
  export function findPendingChallengeByHash(
178
- assistantId: string,
179
166
  channel: string,
180
167
  challengeHash: string,
181
168
  ): VerificationChallenge | null {
@@ -188,7 +175,6 @@ export function findPendingChallengeByHash(
188
175
  .from(channelGuardianVerificationChallenges)
189
176
  .where(
190
177
  and(
191
- eq(channelGuardianVerificationChallenges.assistantId, assistantId),
192
178
  eq(channelGuardianVerificationChallenges.channel, channel),
193
179
  eq(channelGuardianVerificationChallenges.challengeHash, challengeHash),
194
180
  inArray(channelGuardianVerificationChallenges.status, [
@@ -205,7 +191,7 @@ export function findPendingChallengeByHash(
205
191
  }
206
192
 
207
193
  /**
208
- * Find any pending inbound (non-expired) challenge for a given (assistantId, channel).
194
+ * Find any pending inbound (non-expired) challenge for a given channel.
209
195
  * Scoped to 'pending' status only — this is the inbound verification path used by
210
196
  * the relay-server to gate incoming voice calls. Outbound session states
211
197
  * (pending_bootstrap, awaiting_response) are excluded so that an active outbound
@@ -213,7 +199,6 @@ export function findPendingChallengeByHash(
213
199
  * guardian verification flow.
214
200
  */
215
201
  export function findPendingChallengeForChannel(
216
- assistantId: string,
217
202
  channel: string,
218
203
  ): VerificationChallenge | null {
219
204
  const db = getDb();
@@ -224,7 +209,6 @@ export function findPendingChallengeForChannel(
224
209
  .from(channelGuardianVerificationChallenges)
225
210
  .where(
226
211
  and(
227
- eq(channelGuardianVerificationChallenges.assistantId, assistantId),
228
212
  eq(channelGuardianVerificationChallenges.channel, channel),
229
213
  eq(channelGuardianVerificationChallenges.status, "pending"),
230
214
  gt(channelGuardianVerificationChallenges.expiresAt, now),
@@ -261,11 +245,10 @@ export function consumeChallenge(
261
245
  /**
262
246
  * Create an outbound verification session with expected-identity binding.
263
247
  * Auto-revokes prior pending/awaiting_response sessions for the same
264
- * (assistantId, channel) to close the replay window.
248
+ * channel to close the replay window.
265
249
  */
266
250
  export function createVerificationSession(params: {
267
251
  id: string;
268
- assistantId: string;
269
252
  channel: string;
270
253
  challengeHash: string;
271
254
  expiresAt: number;
@@ -284,15 +267,11 @@ export function createVerificationSession(params: {
284
267
  const db = getDb();
285
268
  const now = Date.now();
286
269
 
287
- // Revoke any prior pending/awaiting_response sessions for the same (assistantId, channel)
270
+ // Revoke any prior pending/awaiting_response sessions for the same channel
288
271
  db.update(channelGuardianVerificationChallenges)
289
272
  .set({ status: "revoked", updatedAt: now })
290
273
  .where(
291
274
  and(
292
- eq(
293
- channelGuardianVerificationChallenges.assistantId,
294
- params.assistantId,
295
- ),
296
275
  eq(channelGuardianVerificationChallenges.channel, params.channel),
297
276
  inArray(channelGuardianVerificationChallenges.status, [
298
277
  "pending",
@@ -305,7 +284,6 @@ export function createVerificationSession(params: {
305
284
 
306
285
  const row = {
307
286
  id: params.id,
308
- assistantId: params.assistantId,
309
287
  channel: params.channel,
310
288
  challengeHash: params.challengeHash,
311
289
  expiresAt: params.expiresAt,
@@ -336,10 +314,9 @@ export function createVerificationSession(params: {
336
314
 
337
315
  /**
338
316
  * Find the most recent pending_bootstrap or awaiting_response session
339
- * for a given (assistantId, channel).
317
+ * for a given channel.
340
318
  */
341
319
  export function findActiveSession(
342
- assistantId: string,
343
320
  channel: string,
344
321
  ): VerificationChallenge | null {
345
322
  const db = getDb();
@@ -350,7 +327,6 @@ export function findActiveSession(
350
327
  .from(channelGuardianVerificationChallenges)
351
328
  .where(
352
329
  and(
353
- eq(channelGuardianVerificationChallenges.assistantId, assistantId),
354
330
  eq(channelGuardianVerificationChallenges.channel, channel),
355
331
  inArray(channelGuardianVerificationChallenges.status, [
356
332
  "pending_bootstrap",
@@ -370,7 +346,6 @@ export function findActiveSession(
370
346
  * Used by the Telegram /start gv_<token> bootstrap flow.
371
347
  */
372
348
  export function findSessionByBootstrapTokenHash(
373
- assistantId: string,
374
349
  channel: string,
375
350
  tokenHash: string,
376
351
  ): VerificationChallenge | null {
@@ -382,7 +357,6 @@ export function findSessionByBootstrapTokenHash(
382
357
  .from(channelGuardianVerificationChallenges)
383
358
  .where(
384
359
  and(
385
- eq(channelGuardianVerificationChallenges.assistantId, assistantId),
386
360
  eq(channelGuardianVerificationChallenges.channel, channel),
387
361
  eq(channelGuardianVerificationChallenges.bootstrapTokenHash, tokenHash),
388
362
  eq(channelGuardianVerificationChallenges.status, "pending_bootstrap"),
@@ -399,7 +373,6 @@ export function findSessionByBootstrapTokenHash(
399
373
  * given identity fields with an active status.
400
374
  */
401
375
  export function findSessionByIdentity(
402
- assistantId: string,
403
376
  channel: string,
404
377
  externalUserId?: string,
405
378
  chatId?: string,
@@ -415,7 +388,6 @@ export function findSessionByIdentity(
415
388
  const now = Date.now();
416
389
 
417
390
  const conditions = [
418
- eq(channelGuardianVerificationChallenges.assistantId, assistantId),
419
391
  eq(channelGuardianVerificationChallenges.channel, channel),
420
392
  inArray(channelGuardianVerificationChallenges.status, [
421
393
  "pending_bootstrap",
@@ -10,7 +10,6 @@ import { createHash, randomBytes, randomUUID } from "node:crypto";
10
10
 
11
11
  import { and, desc, eq, gt } from "drizzle-orm";
12
12
 
13
- import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
14
13
  import { getDb } from "./db.js";
15
14
  import { assistantIngressInvites } from "./schema.js";
16
15
 
@@ -22,7 +21,6 @@ export type InviteStatus = "active" | "redeemed" | "revoked" | "expired";
22
21
 
23
22
  export interface IngressInvite {
24
23
  id: string;
25
- assistantId: string;
26
24
  sourceChannel: string;
27
25
  tokenHash: string;
28
26
  createdBySessionId: string | null;
@@ -71,7 +69,6 @@ function rowToInvite(
71
69
  ): IngressInvite {
72
70
  return {
73
71
  id: row.id,
74
- assistantId: row.assistantId,
75
72
  sourceChannel: row.sourceChannel,
76
73
  tokenHash: row.tokenHash,
77
74
  createdBySessionId: row.createdBySessionId,
@@ -99,7 +96,6 @@ function rowToInvite(
99
96
  // ---------------------------------------------------------------------------
100
97
 
101
98
  export function createInvite(params: {
102
- assistantId?: string;
103
99
  sourceChannel: string;
104
100
  createdBySessionId?: string;
105
101
  note?: string;
@@ -122,7 +118,6 @@ export function createInvite(params: {
122
118
 
123
119
  const row = {
124
120
  id,
125
- assistantId: params.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID,
126
121
  sourceChannel: params.sourceChannel,
127
122
  tokenHash: tokenH,
128
123
  createdBySessionId: params.createdBySessionId ?? null,
@@ -154,16 +149,15 @@ export function createInvite(params: {
154
149
  // ---------------------------------------------------------------------------
155
150
 
156
151
  export function listInvites(params: {
157
- assistantId?: string;
158
152
  sourceChannel?: string;
159
153
  status?: InviteStatus;
160
154
  limit?: number;
161
155
  offset?: number;
162
156
  }): IngressInvite[] {
163
157
  const db = getDb();
164
- const assistantId = params.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID;
165
158
 
166
- const conditions = [eq(assistantIngressInvites.assistantId, assistantId)];
159
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
160
+ const conditions: any[] = [];
167
161
 
168
162
  if (params.sourceChannel) {
169
163
  conditions.push(
@@ -174,10 +168,9 @@ export function listInvites(params: {
174
168
  conditions.push(eq(assistantIngressInvites.status, params.status));
175
169
  }
176
170
 
177
- const rows = db
178
- .select()
179
- .from(assistantIngressInvites)
180
- .where(and(...conditions))
171
+ const query = db.select().from(assistantIngressInvites);
172
+
173
+ const rows = (conditions.length > 0 ? query.where(and(...conditions)) : query)
181
174
  .orderBy(desc(assistantIngressInvites.createdAt))
182
175
  .limit(params.limit ?? 100)
183
176
  .offset(params.offset ?? 0)
@@ -329,7 +322,6 @@ export function findByTokenHash(tokenHash: string): IngressInvite | null {
329
322
  * before code hash matching.
330
323
  */
331
324
  export function findActiveVoiceInvites(params: {
332
- assistantId: string;
333
325
  expectedExternalUserId: string;
334
326
  }): IngressInvite[] {
335
327
  const db = getDb();
@@ -339,7 +331,6 @@ export function findActiveVoiceInvites(params: {
339
331
  .from(assistantIngressInvites)
340
332
  .where(
341
333
  and(
342
- eq(assistantIngressInvites.assistantId, params.assistantId),
343
334
  eq(assistantIngressInvites.sourceChannel, "voice"),
344
335
  eq(assistantIngressInvites.status, "active"),
345
336
  eq(