@sentry/junior 0.186.0 → 0.188.0

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 (77) hide show
  1. package/dist/{agent-hooks-4B3Z4WRK.js → agent-hooks-5RQEVLQD.js} +11 -11
  2. package/dist/api.js +32 -32
  3. package/dist/app.js +67 -91
  4. package/dist/{catalog-runtime-AFJCAOHC.js → catalog-runtime-L4A6BJ3U.js} +4 -4
  5. package/dist/chat/agent/types.d.ts +16 -17
  6. package/dist/chat/agent-invocations/types.d.ts +72 -0
  7. package/dist/chat/api-turns/{accepted-reply.d.ts → assistant-message.d.ts} +3 -2
  8. package/dist/chat/api-turns/cancellation.d.ts +0 -1
  9. package/dist/chat/api-turns/mailbox-input.d.ts +0 -3
  10. package/dist/chat/api-turns/routing.d.ts +22 -21
  11. package/dist/chat/api-turns/work.d.ts +2 -2
  12. package/dist/chat/conversations/location.d.ts +4 -9
  13. package/dist/chat/conversations/store.d.ts +17 -7
  14. package/dist/chat/event-tasks/tool-support.d.ts +6 -0
  15. package/dist/chat/resource-events/actor.d.ts +7 -0
  16. package/dist/chat/services/turn-session-routing.d.ts +10 -9
  17. package/dist/chat/task-execution/slack-resource-event.d.ts +13 -5
  18. package/dist/chat/task-input.d.ts +22 -0
  19. package/dist/{chunk-YXSBZRP7.js → chunk-32XSSFZV.js} +1 -1
  20. package/dist/{chunk-HKFLRIBD.js → chunk-3HEZWDS5.js} +2 -2
  21. package/dist/{chunk-INQHUE72.js → chunk-6FGN7ZEG.js} +6 -2
  22. package/dist/{chunk-TXLBLGNQ.js → chunk-6JZGXLL2.js} +5 -5
  23. package/dist/{chunk-H7X2G2KS.js → chunk-6YGFBU3A.js} +12 -12
  24. package/dist/{chunk-MCLWOBPN.js → chunk-AW77HH54.js} +23 -19
  25. package/dist/{chunk-2U7EPTRZ.js → chunk-CDSLOYOR.js} +5 -5
  26. package/dist/{chunk-CM6RTYSO.js → chunk-CIG6WI7Q.js} +9 -6
  27. package/dist/{chunk-7EOWT62G.js → chunk-CVBDVIF4.js} +1 -1
  28. package/dist/{chunk-QBL2AVFF.js → chunk-CZRWU4ZM.js} +2 -2
  29. package/dist/{chunk-GQMQCY7H.js → chunk-ERZMACYA.js} +3 -3
  30. package/dist/{chunk-FFYDRLXW.js → chunk-FIUCHYT6.js} +1 -1
  31. package/dist/{chunk-VQIWBJOP.js → chunk-HCIVBCP5.js} +1 -1
  32. package/dist/{chunk-43LODHJM.js → chunk-IUUQWIG2.js} +14 -31
  33. package/dist/{chunk-7EU4YSZ4.js → chunk-LODJKINF.js} +140 -123
  34. package/dist/{chunk-2IBDVE62.js → chunk-MQDIIFZM.js} +4 -4
  35. package/dist/{chunk-NRMAOGRS.js → chunk-NZLZ4KYZ.js} +1 -1
  36. package/dist/{chunk-PZZOGHVR.js → chunk-PSHMPRIU.js} +1 -1
  37. package/dist/{chunk-AD64YMEC.js → chunk-Q7O74WOO.js} +2 -2
  38. package/dist/{chunk-JFPY6XFF.js → chunk-QCGNHSMA.js} +6 -6
  39. package/dist/{chunk-OZG7E22Y.js → chunk-QDHJTKPE.js} +5 -5
  40. package/dist/{chunk-3CVEE6LA.js → chunk-QIMN3FXL.js} +1 -1
  41. package/dist/{chunk-64WF2GQ3.js → chunk-QIOUTXTZ.js} +1 -1
  42. package/dist/{chunk-VXL2LBPK.js → chunk-QVH6FW3T.js} +13 -3
  43. package/dist/{chunk-GSB3NTNS.js → chunk-RMB7CERI.js} +34 -36
  44. package/dist/{chunk-EWRPUXE3.js → chunk-SC67CH3C.js} +18 -14
  45. package/dist/{chunk-VQZYIVYN.js → chunk-UVUXFRYN.js} +6 -6
  46. package/dist/{chunk-DHYZ4VKG.js → chunk-VFZAUQ5V.js} +97 -47
  47. package/dist/{chunk-QU3URVWG.js → chunk-W2DDJCPS.js} +8 -8
  48. package/dist/{chunk-STOCCPWH.js → chunk-W42ENMJW.js} +1 -1
  49. package/dist/{chunk-BRKB5R7P.js → chunk-WGZJ5SU4.js} +1 -1
  50. package/dist/{chunk-O6GQO7VP.js → chunk-WW2Y7JIA.js} +26 -23
  51. package/dist/{chunk-HWXP6RHG.js → chunk-X55FOVZO.js} +3 -3
  52. package/dist/{chunk-ACGWTJ74.js → chunk-XI4PVY2T.js} +3 -3
  53. package/dist/{chunk-CV5CPRVG.js → chunk-XJIPMHKI.js} +3 -3
  54. package/dist/{chunk-VOGOTEW7.js → chunk-Z5SKZE5B.js} +2 -2
  55. package/dist/{chunk-DOP3FIQC.js → chunk-ZX7RSBQ6.js} +1 -1
  56. package/dist/cli/chat.js +33 -33
  57. package/dist/cli/check.js +5 -5
  58. package/dist/cli/plugins.js +12 -12
  59. package/dist/cli/snapshot-create.js +9 -9
  60. package/dist/cli/upgrade.js +6 -6
  61. package/dist/db/schema/agent-invocations.d.ts +36 -0
  62. package/dist/db/schema.d.ts +36 -0
  63. package/dist/{db-7XL4UPAE.js → db-YPRZAA2T.js} +6 -6
  64. package/dist/instrumentation.js +3 -3
  65. package/dist/nitro.js +6 -6
  66. package/dist/{oauth-callback-server-RAOYHWDI.js → oauth-callback-server-DBBIR3XG.js} +28 -28
  67. package/dist/{runner-KMPBWRPM.js → runner-FKVFFPLO.js} +20 -20
  68. package/dist/{skills-IPCALGLQ.js → skills-4RBAZEMV.js} +5 -5
  69. package/dist/spawn-CO7QFCNJ.js +41 -0
  70. package/dist/task-runner-DUGZGI7V.js +34 -0
  71. package/dist/{validation-BSRCCX6N.js → validation-E6Z5LHZM.js} +5 -5
  72. package/dist/version.js +1 -1
  73. package/dist/{work-T6UFTOJY.js → work-OFTXWOK4.js} +21 -21
  74. package/dist/{worker-L35OG7VA.js → worker-OMWNOKTJ.js} +10 -10
  75. package/package.json +4 -4
  76. package/dist/spawn-OSOWTMBG.js +0 -41
  77. package/dist/task-runner-IQNBA3RY.js +0 -34
@@ -1,45 +1,46 @@
1
1
  import {
2
2
  createWebAuthorization,
3
3
  deleteWebAuthorization
4
- } from "./chunk-PZZOGHVR.js";
4
+ } from "./chunk-PSHMPRIU.js";
5
5
  import {
6
6
  AgentRunError,
7
7
  executeTurn
8
- } from "./chunk-GQMQCY7H.js";
8
+ } from "./chunk-ERZMACYA.js";
9
9
  import {
10
10
  buildDeliveredTurnStatePatch,
11
11
  completeAuthPauseTurn,
12
12
  finalizeFailedTurnReplyWithEvent,
13
13
  getTurnUserMessage
14
- } from "./chunk-OZG7E22Y.js";
14
+ } from "./chunk-QDHJTKPE.js";
15
15
  import {
16
16
  processPluginTask,
17
17
  scheduleSessionCompletedPluginTasks
18
- } from "./chunk-MCLWOBPN.js";
18
+ } from "./chunk-AW77HH54.js";
19
19
  import {
20
20
  ConversationTurnLifecycleService
21
- } from "./chunk-STOCCPWH.js";
21
+ } from "./chunk-W42ENMJW.js";
22
22
  import {
23
23
  coerceThreadConversationState,
24
24
  getPersistedSandboxState,
25
25
  getPersistedThreadState,
26
26
  persistThreadStateById
27
- } from "./chunk-CM6RTYSO.js";
27
+ } from "./chunk-CIG6WI7Q.js";
28
28
  import {
29
29
  healthReportSchema
30
30
  } from "./chunk-UTL3MHPC.js";
31
31
  import {
32
- RESOURCE_EVENT_AUTHOR_ID,
32
+ RESOURCE_EVENT_MESSAGE_AUTHOR,
33
+ RESOURCE_EVENT_SYSTEM_ACTOR,
33
34
  isResourceEventConversationMessage,
34
35
  isResourceEventMailboxMetadata
35
- } from "./chunk-DHYZ4VKG.js";
36
+ } from "./chunk-VFZAUQ5V.js";
36
37
  import {
37
38
  parseSlackThreadId
38
- } from "./chunk-7EOWT62G.js";
39
+ } from "./chunk-CVBDVIF4.js";
39
40
  import {
40
41
  appendAndEnqueueExclusiveInboundMessage,
41
42
  appendAndEnqueueInboundMessage
42
- } from "./chunk-2IBDVE62.js";
43
+ } from "./chunk-MQDIIFZM.js";
43
44
  import {
44
45
  TurnInputCommitLostError,
45
46
  buildDeterministicTurnId,
@@ -50,7 +51,7 @@ import {
50
51
  markTurnClosed,
51
52
  markTurnFailed,
52
53
  startActiveTurn
53
- } from "./chunk-VOGOTEW7.js";
54
+ } from "./chunk-Z5SKZE5B.js";
54
55
  import {
55
56
  abandonTurnRecord,
56
57
  buildConversationContext,
@@ -66,39 +67,42 @@ import {
66
67
  recordDeliveredAssistantMessage,
67
68
  saveTurnCheckpoint,
68
69
  upsertConversationMessage
69
- } from "./chunk-H7X2G2KS.js";
70
+ } from "./chunk-6YGFBU3A.js";
70
71
  import {
71
72
  normalizeSlackConversationId
72
- } from "./chunk-JFPY6XFF.js";
73
+ } from "./chunk-QCGNHSMA.js";
73
74
  import {
74
75
  getConversationEventStore,
75
76
  getConversationStore,
76
77
  getDb
77
- } from "./chunk-43LODHJM.js";
78
+ } from "./chunk-IUUQWIG2.js";
78
79
  import {
79
80
  juniorConversationParticipants,
80
81
  juniorConversations,
81
82
  juniorIdentities,
82
83
  juniorUsers
83
- } from "./chunk-VXL2LBPK.js";
84
+ } from "./chunk-QVH6FW3T.js";
84
85
  import {
85
86
  juniorDestinations
86
87
  } from "./chunk-VFUK3X5B.js";
87
88
  import {
88
89
  getSlackBotToken
89
- } from "./chunk-AD64YMEC.js";
90
+ } from "./chunk-Q7O74WOO.js";
90
91
  import {
91
92
  canExposeConversationPayload
92
- } from "./chunk-FFYDRLXW.js";
93
+ } from "./chunk-FIUCHYT6.js";
93
94
  import {
94
95
  credentialContextForActor
95
96
  } from "./chunk-CEMMLV5L.js";
97
+ import {
98
+ createActor
99
+ } from "./chunk-N7TMSOZH.js";
96
100
  import {
97
101
  logException,
98
102
  logWarn,
99
103
  setTags,
100
104
  withLogContext
101
- } from "./chunk-3CVEE6LA.js";
105
+ } from "./chunk-QIMN3FXL.js";
102
106
 
103
107
  // src/handlers/health.ts
104
108
  function readHealthReport() {
@@ -138,6 +142,10 @@ function createVercelAttachmentStorage() {
138
142
 
139
143
  // src/chat/api-turns/routing.ts
140
144
  import { z } from "zod";
145
+ import {
146
+ createLocalSource,
147
+ createWebSource
148
+ } from "@sentry/junior-plugin-api";
141
149
  var apiTurnMailboxMetadataSchema = z.object({
142
150
  authorEmail: z.string().email(),
143
151
  authorFullName: z.string().min(1).optional(),
@@ -146,6 +154,38 @@ var apiTurnMailboxMetadataSchema = z.object({
146
154
  kind: z.literal("api_turn"),
147
155
  messageId: z.string().min(1)
148
156
  }).strict();
157
+ function turnIdentityFromConversationMessage(message) {
158
+ if (isResourceEventConversationMessage(message)) {
159
+ return {
160
+ actor: RESOURCE_EVENT_SYSTEM_ACTOR,
161
+ author: message.author ?? RESOURCE_EVENT_MESSAGE_AUTHOR,
162
+ source: "resource_event"
163
+ };
164
+ }
165
+ const actor = createActor(message.author, {
166
+ platform: "web",
167
+ userId: message.author?.userId
168
+ });
169
+ if (actor?.platform !== "web") {
170
+ return void 0;
171
+ }
172
+ return {
173
+ actor,
174
+ author: message.author ?? { userId: actor.userId },
175
+ source: "web"
176
+ };
177
+ }
178
+ function sourceFromTurnInput(args) {
179
+ switch (args.source) {
180
+ case "resource_event":
181
+ return createLocalSource(args.conversationId);
182
+ case "web":
183
+ return createWebSource(
184
+ args.conversationId,
185
+ args.visibility === "private" ? "private" : "public"
186
+ );
187
+ }
188
+ }
149
189
  async function getActiveApiTurnId(conversationId) {
150
190
  const summaries = await listTurnSummaries(conversationId);
151
191
  const active = summaries.filter(
@@ -179,16 +219,34 @@ function parseApiTurnMessages(messages) {
179
219
  return [];
180
220
  }
181
221
  if (parsed.some((entry) => !entry.metadata.success)) {
182
- throw new Error("Conversation mailbox mixes web turns and other input");
222
+ throw new Error("A Turn cannot combine different kinds of input");
183
223
  }
184
224
  return parsed.map((entry) => {
185
225
  if (!entry.metadata.success) {
186
- throw new Error("API turn mailbox metadata failed validation");
226
+ throw new Error("User message has invalid metadata");
187
227
  }
188
- return { message: entry.message, metadata: entry.metadata.data };
228
+ const metadata = entry.metadata.data;
229
+ const actor = {
230
+ platform: "web",
231
+ userId: metadata.authorUserId,
232
+ email: metadata.authorEmail.trim().toLowerCase(),
233
+ ...metadata.authorFullName ? { fullName: metadata.authorFullName } : void 0,
234
+ ...metadata.authorUserName ? { userName: metadata.authorUserName } : void 0
235
+ };
236
+ return {
237
+ actor,
238
+ author: {
239
+ email: actor.email,
240
+ ...actor.fullName ? { fullName: actor.fullName } : void 0,
241
+ userId: actor.userId,
242
+ ...actor.userName ? { userName: actor.userName } : void 0
243
+ },
244
+ message: entry.message,
245
+ source: "web"
246
+ };
189
247
  });
190
248
  }
191
- function parseLocalResourceEventMessages(messages) {
249
+ function parseResourceEventMessages(messages) {
192
250
  if (messages.length === 0) {
193
251
  return [];
194
252
  }
@@ -197,10 +255,17 @@ function parseLocalResourceEventMessages(messages) {
197
255
  )) {
198
256
  return [];
199
257
  }
200
- return messages.map((message) => ({
201
- message,
202
- kind: "resource_event"
203
- }));
258
+ return messages.map((message) => {
259
+ if (!isResourceEventMailboxMetadata(message.input.metadata)) {
260
+ throw new Error("Resource event has invalid metadata");
261
+ }
262
+ return {
263
+ actor: RESOURCE_EVENT_SYSTEM_ACTOR,
264
+ author: RESOURCE_EVENT_MESSAGE_AUTHOR,
265
+ message,
266
+ source: "resource_event"
267
+ };
268
+ });
204
269
  }
205
270
  async function resolveApiTurnWork(context) {
206
271
  const batch = parseApiTurnMessages(context.attempt.messages);
@@ -208,11 +273,9 @@ async function resolveApiTurnWork(context) {
208
273
  return { kind: "mailbox", batch };
209
274
  }
210
275
  if (context.destination?.platform === "local") {
211
- const resourceBatch = parseLocalResourceEventMessages(
212
- context.attempt.messages
213
- );
276
+ const resourceBatch = parseResourceEventMessages(context.attempt.messages);
214
277
  if (resourceBatch.length > 0) {
215
- return { kind: "resource_event", batch: resourceBatch };
278
+ return { kind: "mailbox", batch: resourceBatch };
216
279
  }
217
280
  }
218
281
  if (context.attempt.messages.length > 0) {
@@ -228,17 +291,15 @@ async function isApiTurnWork(context) {
228
291
  // src/chat/api-turns/work.ts
229
292
  import { createHash } from "crypto";
230
293
  import {
231
- createLocalSource,
232
- createWebSource,
233
294
  localDestinationSchema
234
295
  } from "@sentry/junior-plugin-api";
235
296
 
236
- // src/chat/api-turns/accepted-reply.ts
237
- async function commitWebAcceptedReply(args) {
297
+ // src/chat/api-turns/assistant-message.ts
298
+ async function commitAssistantMessage(args) {
238
299
  const conversationMessageId = recordDeliveredAssistantMessage({
239
300
  conversation: args.conversation,
240
301
  sessionId: args.sessionId,
241
- source: "web",
302
+ source: args.source,
242
303
  text: args.text,
243
304
  userMessageId: args.userMessageId
244
305
  });
@@ -253,8 +314,8 @@ async function commitWebAcceptedReply(args) {
253
314
  );
254
315
  } catch (error) {
255
316
  logException(
256
- new Error("Accepted assistant message persistence failed"),
257
- "api.assistant.message_post_delivery_persist.failed",
317
+ new Error("Assistant message persistence failed"),
318
+ "conversation.assistant.message_persist.failed",
258
319
  {
259
320
  "error.type": error instanceof Error ? error.name : typeof error
260
321
  }
@@ -319,7 +380,7 @@ function createApiTurnCancellation() {
319
380
  }
320
381
  async function completeCancelledApiTurn(args) {
321
382
  try {
322
- const ownsPendingAuthorization = args.conversation.processing.pendingAuth?.sessionId === args.turnId;
383
+ const pendingAuthorization = args.conversation.processing.pendingAuth?.sessionId === args.turnId ? args.conversation.processing.pendingAuth : void 0;
323
384
  await abandonTurnRecord({
324
385
  conversationId: args.conversationId,
325
386
  turnId: args.turnId,
@@ -335,9 +396,9 @@ async function completeCancelledApiTurn(args) {
335
396
  nowMs: Date.now(),
336
397
  sessionId: args.turnId
337
398
  });
338
- if (ownsPendingAuthorization) {
399
+ if (pendingAuthorization) {
339
400
  await deleteWebAuthorization({
340
- actorId: args.actorId,
401
+ actorId: pendingAuthorization.actorId,
341
402
  conversationId: args.conversationId
342
403
  });
343
404
  }
@@ -365,14 +426,6 @@ async function completeCancelledApiTurn(args) {
365
426
  function joinMailboxText(messages) {
366
427
  return messages.map((message) => message.input.text.trim()).filter(Boolean).join("\n\n");
367
428
  }
368
- function localResourceEventActor() {
369
- return {
370
- platform: "local",
371
- userId: RESOURCE_EVENT_AUTHOR_ID,
372
- userName: "junior-event",
373
- fullName: "Junior event"
374
- };
375
- }
376
429
 
377
430
  // src/chat/api-turns/work.ts
378
431
  function normalizeEmail(email) {
@@ -409,21 +462,6 @@ function resolveApiTurnDestination(args) {
409
462
  }
410
463
  return requireLocalDestination(args.conversationId);
411
464
  }
412
- function webSourceForConversation(args) {
413
- return createWebSource(
414
- args.conversationId,
415
- args.visibility === "private" ? "private" : "public"
416
- );
417
- }
418
- function actorFromMetadata(metadata) {
419
- return {
420
- platform: "web",
421
- userId: metadata.authorUserId,
422
- email: normalizeEmail(metadata.authorEmail),
423
- ...metadata.authorFullName ? { fullName: metadata.authorFullName } : void 0,
424
- ...metadata.authorUserName ? { userName: metadata.authorUserName } : void 0
425
- };
426
- }
427
465
  function storedActorFromApi(actor) {
428
466
  return {
429
467
  ...actor.email ? { email: normalizeEmail(actor.email) } : void 0,
@@ -440,16 +478,6 @@ function webActorFromEmail(email, profile) {
440
478
  ...profile?.userName ? { userName: profile.userName } : void 0
441
479
  };
442
480
  }
443
- function actorFromStoredConversation(stored) {
444
- const email = stored?.email?.trim().toLowerCase();
445
- if (!email) {
446
- return void 0;
447
- }
448
- return webActorFromEmail(
449
- email,
450
- stored?.fullName ? { fullName: stored.fullName } : void 0
451
- );
452
- }
453
481
  function buildApiTurnInboundMessage(args) {
454
482
  const text = args.message.trim();
455
483
  if (!text) {
@@ -495,8 +523,9 @@ async function recordApiConversationActivity(args) {
495
523
  });
496
524
  const isNewRoot = !existing;
497
525
  const visibility = args.rootVisibility === "private" ? "private" : "public";
498
- const source = isNewRoot ? webSourceForConversation({
526
+ const source = isNewRoot ? sourceFromTurnInput({
499
527
  conversationId: args.conversationId,
528
+ source: "web",
500
529
  visibility
501
530
  }) : void 0;
502
531
  await store.recordActivity({
@@ -590,20 +619,19 @@ function createApiTurnWorker(agentRunner, cancellation) {
590
619
  const resolved = await resolveApiTurnWork(context);
591
620
  if (!resolved) {
592
621
  throw new Error(
593
- `Conversation API worker received other work for ${context.conversationId}`
622
+ `Unsupported input for Conversation ${context.conversationId}`
594
623
  );
595
624
  }
596
625
  if (context.publishExternally) {
597
626
  throw new Error(
598
- `Conversation API work cannot publish to a provider for ${context.conversationId}`
627
+ `publishExternally must be false for Conversation ${context.conversationId}`
599
628
  );
600
629
  }
601
630
  const lifecycle = new ConversationTurnLifecycleService(
602
631
  getConversationEventStore()
603
632
  );
604
633
  const isResume = resolved.kind === "resume";
605
- let isResourceEvent = resolved.kind === "resource_event";
606
- let actor;
634
+ let turnIdentity;
607
635
  let text = "";
608
636
  let turnId = "";
609
637
  let userMessageId = "";
@@ -612,37 +640,23 @@ function createApiTurnWorker(agentRunner, cancellation) {
612
640
  const storedConversation = await getConversationStore().get({
613
641
  conversationId: context.conversationId
614
642
  });
615
- const mailboxDestination = resolved.kind === "mailbox" || resolved.kind === "resource_event" ? resolved.batch[0]?.message.destination : void 0;
643
+ const mailboxDestination = resolved.kind === "mailbox" ? resolved.batch[0]?.message.destination : void 0;
616
644
  const destination = resolveApiTurnDestination({
617
645
  conversationId: context.conversationId,
618
646
  existing: context.destination ?? mailboxDestination ?? storedConversation?.destination
619
647
  });
620
- const sourceFor = (resourceEvent) => resourceEvent ? createLocalSource(context.conversationId) : webSourceForConversation({
621
- conversationId: context.conversationId,
622
- visibility: storedConversation?.visibility
623
- });
624
- let source = sourceFor(isResourceEvent);
625
648
  if (resolved.kind === "mailbox") {
626
649
  const first = resolved.batch[0];
627
650
  text = joinMailboxText(resolved.batch.map((entry) => entry.message));
628
- actor = actorFromMetadata(first.metadata);
629
- turnId = apiTurnIdForMessage(first.metadata.messageId);
630
- userMessageId = first.metadata.messageId;
631
651
  startedAtMs = first.message.createdAtMs;
632
- inputMessageIds = resolved.batch.map((entry) => entry.metadata.messageId);
633
- } else if (resolved.kind === "resource_event") {
634
- const first = resolved.batch[0];
635
- text = joinMailboxText(resolved.batch.map((entry) => entry.message));
636
- actor = localResourceEventActor();
637
- turnId = apiTurnIdForMessage(first.message.inboundMessageId);
638
652
  userMessageId = first.message.inboundMessageId;
639
- startedAtMs = first.message.createdAtMs;
653
+ turnId = apiTurnIdForMessage(userMessageId);
640
654
  inputMessageIds = resolved.batch.map(
641
655
  (entry) => entry.message.inboundMessageId
642
656
  );
657
+ turnIdentity = first;
643
658
  } else {
644
659
  turnId = resolved.turnId;
645
- actor = actorFromStoredConversation(storedConversation?.actor);
646
660
  }
647
661
  const persisted = await getPersistedThreadState(context.conversationId);
648
662
  const conversation = coerceThreadConversationState(persisted);
@@ -657,27 +671,32 @@ function createApiTurnWorker(agentRunner, cancellation) {
657
671
  `Unable to locate the persisted user message for Turn "${turnId}"`
658
672
  );
659
673
  }
660
- if (isResourceEventConversationMessage(userMessage)) {
661
- isResourceEvent = true;
662
- actor = localResourceEventActor();
663
- source = sourceFor(true);
664
- }
674
+ turnIdentity = turnIdentityFromConversationMessage(userMessage);
665
675
  userMessageId = userMessage.id;
666
676
  text = userMessage.text;
667
677
  startedAtMs = userMessage.createdAtMs;
668
678
  inputMessageIds = [userMessageId];
669
679
  }
670
- if (!actor) {
680
+ if (!turnIdentity) {
671
681
  throw new Error(
672
- `Conversation API resume missing actor for ${context.conversationId}`
682
+ `Resumed Turn is missing an Actor for Conversation ${context.conversationId}`
673
683
  );
674
684
  }
685
+ const { actor, author } = turnIdentity;
686
+ const source = sourceFromTurnInput({
687
+ conversationId: context.conversationId,
688
+ source: turnIdentity.source,
689
+ visibility: storedConversation?.visibility
690
+ });
691
+ const webActor = actor.platform === "web" ? actor : void 0;
675
692
  return await withLogContext(
676
693
  {
677
694
  conversationId: context.conversationId,
678
- platform: isResourceEvent ? "local" : "web",
679
- userId: actor.userId,
680
- ...actor.userName ? { userName: actor.userName } : void 0
695
+ platform: actor.platform,
696
+ ...webActor ? {
697
+ userId: webActor.userId,
698
+ ...webActor.userName ? { userName: webActor.userName } : void 0
699
+ } : void 0
681
700
  },
682
701
  async () => {
683
702
  let acknowledged = isResume || context.attempt.messages.length === 0;
@@ -708,7 +727,6 @@ function createApiTurnWorker(agentRunner, cancellation) {
708
727
  try {
709
728
  await completeCancelledApiTurn({
710
729
  acknowledge,
711
- actorId: actor.userId,
712
730
  cancellation,
713
731
  conversation,
714
732
  conversationId: context.conversationId,
@@ -735,16 +753,11 @@ function createApiTurnWorker(agentRunner, cancellation) {
735
753
  role: "user",
736
754
  text: normalizeConversationText(text),
737
755
  createdAtMs: startedAtMs,
738
- author: {
739
- ...actor.email ? { email: actor.email } : void 0,
740
- ...actor.fullName ? { fullName: actor.fullName } : void 0,
741
- userId: actor.userId,
742
- ...actor.userName ? { userName: actor.userName } : void 0
743
- },
756
+ author,
744
757
  meta: {
745
758
  explicitMention: true,
746
759
  replied: false,
747
- ...isResourceEvent ? void 0 : { source: "web" }
760
+ ...turnIdentity.source === "web" ? { source: "web" } : void 0
748
761
  }
749
762
  });
750
763
  await persistConversationMessages({
@@ -780,11 +793,12 @@ function createApiTurnWorker(agentRunner, cancellation) {
780
793
  }
781
794
  failureCode = "delivery_failed";
782
795
  assistantMessageDelivered = true;
783
- await commitWebAcceptedReply({
796
+ await commitAssistantMessage({
784
797
  ...agentMessage ? { agentMessage } : void 0,
785
798
  conversation,
786
799
  conversationId: context.conversationId,
787
800
  sessionId: turnId,
801
+ ...turnIdentity.source === "web" ? { source: "web" } : void 0,
788
802
  text: replyText,
789
803
  userMessageId
790
804
  });
@@ -795,6 +809,7 @@ function createApiTurnWorker(agentRunner, cancellation) {
795
809
  return await completeCancelledTurn();
796
810
  }
797
811
  if (!isResume) {
812
+ const pendingAuthorizationActorId = conversation.processing.pendingAuth?.actorId;
798
813
  const authParked = (await listTurnSummaries(context.conversationId)).filter(
799
814
  (summary) => summary.surface === "api" && !summary.dispatchId && summary.state === "paused" && summary.resumeReason === "auth"
800
815
  );
@@ -805,7 +820,7 @@ function createApiTurnWorker(agentRunner, cancellation) {
805
820
  await abandonTurnRecord({
806
821
  conversationId: context.conversationId,
807
822
  turnId: parked.turnId,
808
- errorMessage: "Auth-parked session superseded by a new user message"
823
+ errorMessage: "Auth-paused Turn superseded by new input"
809
824
  });
810
825
  markTurnClosed({
811
826
  conversation,
@@ -813,9 +828,9 @@ function createApiTurnWorker(agentRunner, cancellation) {
813
828
  sessionId: parked.turnId
814
829
  });
815
830
  }
816
- if (authParked.length > 0) {
831
+ if (authParked.length > 0 && pendingAuthorizationActorId) {
817
832
  await deleteWebAuthorization({
818
- actorId: actor.userId,
833
+ actorId: pendingAuthorizationActorId,
819
834
  conversationId: context.conversationId
820
835
  });
821
836
  }
@@ -849,18 +864,20 @@ function createApiTurnWorker(agentRunner, cancellation) {
849
864
  credentialContext: credentialContextForActor(actor),
850
865
  destination,
851
866
  publishExternally: false,
852
- source,
867
+ source: storedConversation?.location ? { ...source, location: storedConversation.location } : source,
853
868
  surface: "api",
854
869
  ...cancellationSignal ? { signal: cancellationSignal } : void 0,
855
- authorization: createWebAuthorization({
856
- actorId: actor.userId,
857
- conversationId: context.conversationId
858
- }),
870
+ ...webActor ? {
871
+ authorization: createWebAuthorization({
872
+ actorId: webActor.userId,
873
+ conversationId: context.conversationId
874
+ })
875
+ } : { disabledFeatures: ["interactive-auth"] },
859
876
  state: {
860
877
  pendingAuth: conversation.processing.pendingAuth,
861
878
  sandboxRef
862
879
  },
863
- delivery: deliverAssistantMessage,
880
+ delivery: { send: deliverAssistantMessage },
864
881
  durability: {
865
882
  onInputCommitted: acknowledge,
866
883
  shouldYield: context.shouldYield,
@@ -8,14 +8,14 @@ import {
8
8
  getConversationStore,
9
9
  parseDestination,
10
10
  sameDestination
11
- } from "./chunk-43LODHJM.js";
11
+ } from "./chunk-IUUQWIG2.js";
12
12
  import {
13
13
  getDefaultRedisStateAdapterFor,
14
14
  getStateAdapter
15
- } from "./chunk-DOP3FIQC.js";
15
+ } from "./chunk-ZX7RSBQ6.js";
16
16
  import {
17
17
  getChatConfig
18
- } from "./chunk-AD64YMEC.js";
18
+ } from "./chunk-Q7O74WOO.js";
19
19
  import {
20
20
  parseStoredSlackActor
21
21
  } from "./chunk-N7TMSOZH.js";
@@ -23,7 +23,7 @@ import {
23
23
  isRecord,
24
24
  toOptionalNumber,
25
25
  toOptionalString
26
- } from "./chunk-3CVEE6LA.js";
26
+ } from "./chunk-QIMN3FXL.js";
27
27
 
28
28
  // src/chat/task-execution/state.ts
29
29
  import { randomUUID } from "crypto";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createPluginCatalogRuntime
3
- } from "./chunk-64WF2GQ3.js";
3
+ } from "./chunk-QIOUTXTZ.js";
4
4
 
5
5
  // src/chat/plugins/catalog-runtime.ts
6
6
  var pluginCatalogRuntime = createPluginCatalogRuntime();
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getStateAdapter
3
- } from "./chunk-DOP3FIQC.js";
3
+ } from "./chunk-ZX7RSBQ6.js";
4
4
  import {
5
5
  getClient
6
6
  } from "./chunk-PEQXYSSE.js";
@@ -7,7 +7,7 @@ import {
7
7
  toCanonicalInputMessage,
8
8
  toCanonicalOutputMessage,
9
9
  toGenAiMessagesTraceAttributes
10
- } from "./chunk-FFYDRLXW.js";
10
+ } from "./chunk-FIUCHYT6.js";
11
11
  import {
12
12
  extractGenAiUsageAttributes,
13
13
  logException,
@@ -15,7 +15,7 @@ import {
15
15
  normalizeGenAiFinishReason,
16
16
  serializeGenAiAttribute,
17
17
  withSpan
18
- } from "./chunk-3CVEE6LA.js";
18
+ } from "./chunk-QIMN3FXL.js";
19
19
 
20
20
  // src/chat/services/provider-error.ts
21
21
  var ProviderError = class extends Error {
@@ -5,7 +5,7 @@ import {
5
5
  getConversationEventStore,
6
6
  getDb,
7
7
  getSqlExecutor
8
- } from "./chunk-43LODHJM.js";
8
+ } from "./chunk-IUUQWIG2.js";
9
9
  import {
10
10
  juniorCodeChanges,
11
11
  juniorCodeRepositories,
@@ -16,7 +16,7 @@ import {
16
16
  juniorUsers,
17
17
  juniorWorkspaceRepos,
18
18
  juniorWorkspaces
19
- } from "./chunk-VXL2LBPK.js";
19
+ } from "./chunk-QVH6FW3T.js";
20
20
  import {
21
21
  SANDBOX_WORKSPACE_ROOT,
22
22
  getVercelSandboxCredentials,
@@ -24,16 +24,16 @@ import {
24
24
  isSandboxMissingError,
25
25
  runNonInteractiveCommand,
26
26
  sleep
27
- } from "./chunk-HWXP6RHG.js";
27
+ } from "./chunk-X55FOVZO.js";
28
28
  import {
29
29
  getStateAdapter
30
- } from "./chunk-DOP3FIQC.js";
30
+ } from "./chunk-ZX7RSBQ6.js";
31
31
  import {
32
32
  botConfig,
33
33
  completeObject,
34
34
  embedTexts,
35
35
  getSlackBotToken
36
- } from "./chunk-AD64YMEC.js";
36
+ } from "./chunk-Q7O74WOO.js";
37
37
  import {
38
38
  defaultModelId
39
39
  } from "./chunk-D4YV5TDV.js";
@@ -52,7 +52,7 @@ import {
52
52
  setSpanAttributes,
53
53
  setSpanStatus,
54
54
  withSpan
55
- } from "./chunk-3CVEE6LA.js";
55
+ } from "./chunk-QIMN3FXL.js";
56
56
 
57
57
  // src/chat/plugins/agent-hooks.ts
58
58
  import {