@sentry/junior 0.146.0 → 0.148.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 (227) hide show
  1. package/dist/{agent-hooks-SLJADYE5.js → agent-hooks-VAUYT6PD.js} +10 -10
  2. package/dist/api/conversations/access.d.ts +2 -1
  3. package/dist/api/conversations/archive.d.ts +3 -5
  4. package/dist/api/conversations/create.d.ts +6 -0
  5. package/dist/api/conversations/detail.d.ts +2 -295
  6. package/dist/api/conversations/event-list.d.ts +2 -192
  7. package/dist/api/conversations/list.d.ts +4 -66
  8. package/dist/api/conversations/routes.d.ts +1 -1
  9. package/dist/api/conversations/stats.d.ts +0 -54
  10. package/dist/api/http.d.ts +2 -6
  11. package/dist/api/locations/detail.d.ts +3 -111
  12. package/dist/api/locations/list.d.ts +0 -45
  13. package/dist/api/locations/query.d.ts +2 -1
  14. package/dist/api/locations/routes.d.ts +1 -1
  15. package/dist/api/people/list.d.ts +0 -29
  16. package/dist/api/people/profile.d.ts +2 -106
  17. package/dist/api/people/profile.query.d.ts +2 -1
  18. package/dist/api/people/routes.d.ts +1 -1
  19. package/dist/api/people/shared.d.ts +1 -1
  20. package/dist/api/people/spend.d.ts +3 -4
  21. package/dist/api/personal-tokens/routes.d.ts +2 -2
  22. package/dist/api/route.d.ts +8 -14
  23. package/dist/api/schema/conversation.d.ts +64 -29
  24. package/dist/api/schema/location.d.ts +4 -0
  25. package/dist/api/schema/person.d.ts +7 -3
  26. package/dist/api/schema.d.ts +2 -2
  27. package/dist/api/schema.js +7 -1
  28. package/dist/api/stats.d.ts +0 -13
  29. package/dist/api/validation.d.ts +7 -0
  30. package/dist/api/viewer.d.ts +3 -0
  31. package/dist/api.d.ts +2 -1
  32. package/dist/api.js +630 -564
  33. package/dist/app.js +369 -309
  34. package/dist/{catalog-runtime-RQIMSDPR.js → catalog-runtime-WADOZVTB.js} +5 -5
  35. package/dist/chat/actor.d.ts +4 -1
  36. package/dist/chat/agent/prompt.d.ts +0 -2
  37. package/dist/chat/agent/request.d.ts +4 -5
  38. package/dist/chat/agent/resume.d.ts +1 -0
  39. package/dist/chat/agent/sandbox.d.ts +2 -2
  40. package/dist/chat/agent/tools.d.ts +0 -2
  41. package/dist/chat/agent-dispatch/context.d.ts +2 -2
  42. package/dist/chat/agent-dispatch/types.d.ts +2 -2
  43. package/dist/chat/agent-invocations/types.d.ts +52 -0
  44. package/dist/chat/api-turns/work.d.ts +103 -0
  45. package/dist/chat/capabilities/jr-rpc-command.d.ts +2 -2
  46. package/dist/chat/configuration/service.d.ts +5 -2
  47. package/dist/chat/configuration/sql.d.ts +9 -0
  48. package/dist/chat/configuration/types.d.ts +17 -13
  49. package/dist/chat/conversations/history.d.ts +63 -0
  50. package/dist/chat/conversations/projection.d.ts +10 -0
  51. package/dist/chat/conversations/provenance.d.ts +6 -0
  52. package/dist/chat/conversations/sql/actor-identity.d.ts +19 -0
  53. package/dist/chat/conversations/store.d.ts +1 -1
  54. package/dist/chat/credentials/unlink-provider.d.ts +2 -1
  55. package/dist/chat/credentials/user-token-store.d.ts +2 -0
  56. package/dist/chat/event-tasks/tool-support.d.ts +2 -0
  57. package/dist/chat/identities/sql.d.ts +8 -0
  58. package/dist/chat/logging.d.ts +2 -0
  59. package/dist/chat/mcp/auth-store.d.ts +0 -2
  60. package/dist/chat/mcp/oauth.d.ts +0 -2
  61. package/dist/chat/oauth-flow.d.ts +3 -1
  62. package/dist/chat/pi/client.d.ts +2 -0
  63. package/dist/chat/plugins/credential-hooks.d.ts +2 -0
  64. package/dist/chat/prompt.d.ts +0 -2
  65. package/dist/chat/resource-events/notification.d.ts +2 -1
  66. package/dist/chat/resource-events/store.d.ts +1 -1
  67. package/dist/chat/runtime/delivered-turn-state.d.ts +1 -4
  68. package/dist/chat/runtime/reply-executor.d.ts +1 -1
  69. package/dist/chat/runtime/slack-runtime.d.ts +2 -1
  70. package/dist/chat/runtime/thread-state.d.ts +8 -11
  71. package/dist/chat/runtime/turn-input.d.ts +4 -2
  72. package/dist/chat/runtime/turn-preparation.d.ts +11 -4
  73. package/dist/chat/sandbox/command-result.d.ts +2 -0
  74. package/dist/chat/sandbox/egress/schemas.d.ts +6 -0
  75. package/dist/chat/scheduled-tasks/tool-support.d.ts +7 -5
  76. package/dist/chat/scheduled-tasks/tools/create.d.ts +4 -2
  77. package/dist/chat/scheduled-tasks/tools/delete.d.ts +4 -2
  78. package/dist/chat/scheduled-tasks/tools/list.d.ts +4 -2
  79. package/dist/chat/scheduled-tasks/tools/run-now.d.ts +4 -2
  80. package/dist/chat/scheduled-tasks/tools/update.d.ts +4 -2
  81. package/dist/chat/services/mcp-auth-orchestration.d.ts +0 -3
  82. package/dist/chat/services/plugin-auth-orchestration.d.ts +2 -1
  83. package/dist/chat/services/provider-default-config.d.ts +2 -2
  84. package/dist/chat/services/subscribed-decision.d.ts +3 -0
  85. package/dist/chat/services/subscribed-reply-policy.d.ts +1 -0
  86. package/dist/chat/services/turn-result.d.ts +0 -3
  87. package/dist/chat/services/turn-router.d.ts +3 -0
  88. package/dist/chat/slack/assistant-thread/lifecycle.d.ts +0 -1
  89. package/dist/chat/slack/assistant-thread/title.d.ts +0 -3
  90. package/dist/chat/slack/channel.d.ts +26 -0
  91. package/dist/chat/slack/dispatch-turn.d.ts +2 -1
  92. package/dist/chat/slack/timestamp-param.d.ts +0 -2
  93. package/dist/chat/slack/{tools → tool-support}/canvas/api.d.ts +1 -1
  94. package/dist/chat/slack/tool-support/canvas/context.d.ts +11 -0
  95. package/dist/chat/slack/tool-support/channel-access.d.ts +42 -0
  96. package/dist/chat/slack/tool-support/channel-target.d.ts +27 -0
  97. package/dist/chat/slack/{tools → tool-support}/list/api.d.ts +8 -1
  98. package/dist/chat/slack/tool-support/list/params.d.ts +5 -0
  99. package/dist/chat/slack/tools/canvas/create.d.ts +3 -1
  100. package/dist/chat/slack/tools/canvas/edit.d.ts +2 -0
  101. package/dist/chat/slack/tools/canvas/read.d.ts +2 -0
  102. package/dist/chat/slack/tools/canvas/write.d.ts +2 -0
  103. package/dist/chat/slack/tools/{user-lookup.d.ts → channel-join.d.ts} +6 -5
  104. package/dist/chat/slack/tools/channel-list-messages.d.ts +5 -2
  105. package/dist/chat/slack/tools/conversation-message-search.d.ts +4 -8
  106. package/dist/chat/slack/tools/list/add-items.d.ts +4 -1
  107. package/dist/chat/slack/tools/list/create.d.ts +2 -0
  108. package/dist/chat/slack/tools/list/get-items.d.ts +5 -3
  109. package/dist/chat/slack/tools/list/update-item.d.ts +5 -1
  110. package/dist/chat/slack/tools/message-add-reaction.d.ts +3 -1
  111. package/dist/chat/slack/tools/public-search.d.ts +65 -2
  112. package/dist/chat/slack/tools/send-files.d.ts +3 -1
  113. package/dist/chat/slack/tools/thread-read.d.ts +4 -5
  114. package/dist/chat/slack/vision-cache.d.ts +5 -0
  115. package/dist/chat/source.d.ts +2 -0
  116. package/dist/chat/state/conversation.d.ts +4 -5
  117. package/dist/chat/task-execution/checkpoint.d.ts +1 -0
  118. package/dist/chat/task-execution/state.d.ts +9 -4
  119. package/dist/chat/task-execution/store.d.ts +3 -2
  120. package/dist/chat/task-execution/turn-cursor.d.ts +2 -0
  121. package/dist/chat/task-execution/worker.d.ts +2 -0
  122. package/dist/chat/tasks/read.d.ts +1 -1
  123. package/dist/chat/tool-support/structured-result.d.ts +1 -0
  124. package/dist/chat/tool-support/timed-out-tool-result.d.ts +11 -0
  125. package/dist/chat/tools/create-event-task.d.ts +2 -0
  126. package/dist/chat/tools/delete-event-task.d.ts +2 -0
  127. package/dist/chat/tools/handoff/tool.d.ts +2 -0
  128. package/dist/chat/tools/list-event-tasks.d.ts +2 -0
  129. package/dist/chat/tools/list-resource-event-subscriptions.d.ts +2 -0
  130. package/dist/chat/tools/runtime/report-progress.d.ts +2 -0
  131. package/dist/chat/tools/runtime/spawn-agent.d.ts +2 -0
  132. package/dist/chat/tools/search-conversation-events.d.ts +3 -1
  133. package/dist/chat/tools/search-resource-event-types.d.ts +2 -0
  134. package/dist/chat/tools/search-tools.d.ts +2 -0
  135. package/dist/chat/tools/skill/load-skill.d.ts +2 -0
  136. package/dist/chat/tools/skill/search-mcp-tools.d.ts +2 -0
  137. package/dist/chat/tools/stop-watching-resources.d.ts +2 -0
  138. package/dist/chat/tools/system-time.d.ts +2 -0
  139. package/dist/chat/tools/types.d.ts +11 -10
  140. package/dist/chat/tools/update-event-task.d.ts +2 -0
  141. package/dist/chat/tools/user-lookup.d.ts +29 -0
  142. package/dist/chat/tools/watch-resource-events.d.ts +4 -2
  143. package/dist/chat/tools/web/fetch-tool.d.ts +2 -0
  144. package/dist/chat/tools/web/image-generate.d.ts +2 -0
  145. package/dist/chat/tools/web/search.d.ts +2 -0
  146. package/dist/{chunk-GYEKOX7N.js → chunk-2B3PT3V2.js} +1 -1
  147. package/dist/{chunk-JLMVCNXL.js → chunk-45LOR4PU.js} +22 -4
  148. package/dist/{chunk-FGHADGIC.js → chunk-4AQZYNHM.js} +2 -2
  149. package/dist/{chunk-W65V465O.js → chunk-4EA2SFK2.js} +66 -4
  150. package/dist/{chunk-MKRIZ4VG.js → chunk-4GXJUYJV.js} +4 -2
  151. package/dist/{chunk-F7REGDKO.js → chunk-55F4QU2V.js} +2 -1
  152. package/dist/{chunk-M6ZWP4RI.js → chunk-7OEIXFC3.js} +2 -2
  153. package/dist/{chunk-MCFIXAV5.js → chunk-D3WPMGEX.js} +55 -37
  154. package/dist/{chunk-AISNSNDV.js → chunk-D6YX4NNN.js} +22 -10
  155. package/dist/chunk-DUY5CDAM.js +36 -0
  156. package/dist/{chunk-B63BF443.js → chunk-EAI67NTM.js} +9 -1
  157. package/dist/{chunk-FEKQHPVA.js → chunk-EINWQFXI.js} +9 -8
  158. package/dist/chunk-GDFF3BQG.js +136 -0
  159. package/dist/{chunk-X22KCSCO.js → chunk-GXYDVZKM.js} +7 -5
  160. package/dist/{chunk-X2WMBTS3.js → chunk-HLPLT3NY.js} +8 -5
  161. package/dist/{chunk-PB222GIA.js → chunk-HWQGBIH7.js} +1 -1
  162. package/dist/chunk-IL4EDBMV.js +566 -0
  163. package/dist/{chunk-HQE6EJS5.js → chunk-LAZGHEYU.js} +1 -1
  164. package/dist/{chunk-QG7OOKIN.js → chunk-LE5H7LMT.js} +1 -1
  165. package/dist/chunk-LNVEIJ2L.js +48 -0
  166. package/dist/{chunk-JUA6VU2Z.js → chunk-OJCP3C3J.js} +12 -23
  167. package/dist/{chunk-37JJDS4H.js → chunk-POSZWRGL.js} +1 -1
  168. package/dist/{chunk-TCEJ7XXM.js → chunk-QOWHHM3F.js} +1 -1
  169. package/dist/{chunk-H6U2U3EP.js → chunk-RRJV5UR5.js} +304 -65
  170. package/dist/{chunk-OFPYOC3M.js → chunk-ULAU5ZGU.js} +127 -120
  171. package/dist/{chunk-V6SRLKUB.js → chunk-V2FXMOEA.js} +2 -2
  172. package/dist/{chunk-GDQEU4I7.js → chunk-VCYSOXON.js} +296 -526
  173. package/dist/{chunk-BLETMLRX.js → chunk-VMNRXKAH.js} +1374 -989
  174. package/dist/{chunk-37EVZP66.js → chunk-VRHTNBA6.js} +167 -92
  175. package/dist/{chunk-FXDDDSPL.js → chunk-VY6W3T43.js} +4 -4
  176. package/dist/{chunk-ZDGHGY74.js → chunk-WCN4YSH7.js} +13 -6
  177. package/dist/{chunk-PH4Q3A6W.js → chunk-WOONT5ZP.js} +1 -1
  178. package/dist/{chunk-47OSH2ZO.js → chunk-XJ42NBP5.js} +395 -206
  179. package/dist/{chunk-SCGVWUZX.js → chunk-ZCHIC2GM.js} +92 -75
  180. package/dist/chunk-ZPL2RR7F.js +798 -0
  181. package/dist/cli/chat.js +33 -35
  182. package/dist/cli/check.js +6 -6
  183. package/dist/cli/plugins.js +13 -13
  184. package/dist/cli/snapshot-create.js +9 -9
  185. package/dist/cli/upgrade.js +7 -7
  186. package/dist/db/schema/agent-invocations.d.ts +20 -0
  187. package/dist/db/schema/conversation-annotations.d.ts +2 -2
  188. package/dist/db/schema/location-configurations.d.ts +127 -0
  189. package/dist/db/schema.d.ts +150 -3
  190. package/dist/{db-WWOMXWTT.js → db-XUKZRFFK.js} +7 -7
  191. package/dist/instrumentation.js +4 -4
  192. package/dist/nitro.js +2 -2
  193. package/dist/{oauth-callback-server-A6ZZX74U.js → oauth-callback-server-LPZMMGFI.js} +25 -26
  194. package/dist/{runner-KSGB2UAV.js → runner-DGKUTMPX.js} +22 -41
  195. package/dist/{skills-26QPWKVS.js → skills-P7YUFSXM.js} +6 -6
  196. package/dist/spawn-DSK3ZEVD.js +38 -0
  197. package/dist/{validation-OPSRGFGH.js → validation-S7U5M5NR.js} +6 -6
  198. package/dist/version.js +1 -1
  199. package/dist/{work-VMSW7STJ.js → work-GAA7TVAD.js} +18 -19
  200. package/dist/{worker-2JNFB7C7.js → worker-JXPJH3QB.js} +11 -10
  201. package/migrations/0024_misty_typhoid_mary.sql +12 -0
  202. package/migrations/meta/0024_snapshot.json +2275 -0
  203. package/migrations/meta/_journal.json +7 -0
  204. package/package.json +6 -5
  205. package/dist/api/health.d.ts +0 -7
  206. package/dist/api/personal-tokens/create.d.ts +0 -11
  207. package/dist/api/personal-tokens/list.d.ts +0 -12
  208. package/dist/api/personal-tokens/revoke.d.ts +0 -5
  209. package/dist/api/plugin-reports.d.ts +0 -63
  210. package/dist/api/plugins.d.ts +0 -8
  211. package/dist/api/runtime.d.ts +0 -24
  212. package/dist/api/skills.d.ts +0 -6
  213. package/dist/chat/slack/tools/canvas/context.d.ts +0 -18
  214. package/dist/chat/slack/tools/channel-access.d.ts +0 -30
  215. package/dist/chat/state/artifacts.d.ts +0 -30
  216. package/dist/chat/tool-support/turn-deadline-result.d.ts +0 -3
  217. package/dist/chunk-HLXXQI5Q.js +0 -238
  218. package/dist/chunk-LVW7BLLT.js +0 -115
  219. package/dist/chunk-Q6QZTTLS.js +0 -55
  220. package/dist/chunk-QSXZ42KX.js +0 -285
  221. package/dist/chunk-R776HKPK.js +0 -81
  222. package/dist/chunk-T5GXFFLA.js +0 -67
  223. package/dist/spawn-5LAJXZ2P.js +0 -39
  224. /package/dist/chat/slack/{tools → tool-support}/canvas/markdown.d.ts +0 -0
  225. /package/dist/chat/slack/{tools → tool-support}/channel-capabilities.d.ts +0 -0
  226. /package/dist/chat/slack/{tools → tool-support}/context.d.ts +0 -0
  227. /package/dist/chat/slack/{tools → tool-support}/slack-message-url.d.ts +0 -0
@@ -1,14 +1,6 @@
1
1
  import {
2
- JUNIOR_THREAD_STATE_TTL_MS
3
- } from "./chunk-3Y47VMHV.js";
4
- import {
5
- JUNIOR_NATIVE_EVENT_NAMESPACE,
6
- ToolInputError,
7
- addAgentTurnUsage,
8
- agentsInstructionsUpdatedEvent,
9
- authenticationLinkedEvent,
10
- authenticationUnlinkedEvent
11
- } from "./chunk-HLXXQI5Q.js";
2
+ usageSchema
3
+ } from "./chunk-PDO5BLNM.js";
12
4
  import {
13
5
  agentHistoryItemSchema,
14
6
  bindProviderConversation,
@@ -21,7 +13,7 @@ import {
21
13
  instructionProvenanceFor,
22
14
  sanitizePostgresJson,
23
15
  withConversationEventLock
24
- } from "./chunk-37EVZP66.js";
16
+ } from "./chunk-VRHTNBA6.js";
25
17
  import {
26
18
  SANDBOX_WORKSPACE_ROOT,
27
19
  sleep
@@ -31,21 +23,18 @@ import {
31
23
  fenceLock,
32
24
  getStateAdapter,
33
25
  withLock
34
- } from "./chunk-GYEKOX7N.js";
26
+ } from "./chunk-2B3PT3V2.js";
35
27
  import {
36
28
  botConfig,
37
29
  unwrapCurrentInstruction
38
- } from "./chunk-MKRIZ4VG.js";
30
+ } from "./chunk-4GXJUYJV.js";
39
31
  import {
40
32
  toStoredSlackActor
41
33
  } from "./chunk-HZF5P5UN.js";
42
34
  import {
43
35
  getActiveTraceId,
44
- isRecord,
45
- logException,
46
- toOptionalNumber,
47
- toOptionalString
48
- } from "./chunk-B63BF443.js";
36
+ logException
37
+ } from "./chunk-EAI67NTM.js";
49
38
 
50
39
  // src/chat/turn-context-tag.ts
51
40
  var TURN_CONTEXT_TAG = "runtime-turn-context";
@@ -403,6 +392,131 @@ var piContentMessageSchema = z.object({
403
392
  role: z.string().min(1)
404
393
  }).passthrough().transform((value) => value);
405
394
 
395
+ // src/chat/conversations/structured-events.ts
396
+ import {
397
+ conversationEventPresentationSchema,
398
+ defineConversationEvent
399
+ } from "@sentry/junior-plugin-api";
400
+ import { z as z2 } from "zod";
401
+ var JUNIOR_NATIVE_EVENT_NAMESPACE = "junior";
402
+ var authenticationEventContentSchema = z2.object({
403
+ accountLabel: z2.string().trim().min(1).max(120).optional(),
404
+ actorId: z2.string().min(1),
405
+ authorizationId: z2.string().min(1).optional(),
406
+ provider: z2.string().regex(/^[a-z][a-z0-9-]*$/),
407
+ providerLabel: z2.string().trim().min(1).max(80).optional()
408
+ }).strict();
409
+ var agentsInstructionsUpdatedContentSchema = z2.object({
410
+ action: z2.enum(["loaded", "replaced", "cleared"]),
411
+ directory: z2.string().trim().min(1).max(500).optional(),
412
+ fingerprint: z2.string().trim().min(1).max(128),
413
+ sources: z2.array(
414
+ z2.object({
415
+ content: z2.string().min(1).max(32 * 1024),
416
+ path: z2.string().trim().min(1).max(500)
417
+ }).strict()
418
+ ).max(32),
419
+ textBytes: z2.number().int().nonnegative().optional()
420
+ }).strict();
421
+ function providerTitle(content) {
422
+ return content.providerLabel?.trim() || content.provider;
423
+ }
424
+ function agentsInstructionsTitle(action) {
425
+ if (action === "loaded") return "Loaded AGENTS.md";
426
+ if (action === "replaced") return "Updated AGENTS.md";
427
+ return "Cleared AGENTS.md";
428
+ }
429
+ function sourceFilename(sourcePath) {
430
+ return sourcePath.split("/").at(-1) || sourcePath;
431
+ }
432
+ function formatBytes(bytes) {
433
+ if (bytes < 1024) return `${bytes} bytes`;
434
+ const kilobytes = bytes / 1024;
435
+ return `${Number.isInteger(kilobytes) ? kilobytes : kilobytes.toFixed(1)} KB`;
436
+ }
437
+ function agentsInstructionsPreview(content) {
438
+ const source = content.sources[0];
439
+ if (!source) return void 0;
440
+ const filename = sourceFilename(source.path);
441
+ const label = content.sources.length === 1 ? filename : `${content.sources.length} AGENTS.md files`;
442
+ return typeof content.textBytes === "number" ? `${label} \xB7 ${formatBytes(content.textBytes)}` : label;
443
+ }
444
+ var authenticationLinkedEvent = defineConversationEvent({
445
+ name: "authentication_linked",
446
+ version: 1,
447
+ schema: authenticationEventContentSchema,
448
+ renderEvent(event) {
449
+ const provider = providerTitle(event);
450
+ return {
451
+ icon: "link",
452
+ title: `${provider} connected`,
453
+ ...event.accountLabel ? { preview: `Connected as \`${event.accountLabel}\`` } : {},
454
+ details: [
455
+ {
456
+ title: `${provider} connected`,
457
+ ...event.accountLabel ? { description: `Connected as \`${event.accountLabel}\`` } : {},
458
+ metadata: [event.provider]
459
+ }
460
+ ]
461
+ };
462
+ }
463
+ });
464
+ var authenticationUnlinkedEvent = defineConversationEvent({
465
+ name: "authentication_unlinked",
466
+ version: 1,
467
+ schema: authenticationEventContentSchema,
468
+ renderEvent(event) {
469
+ const provider = providerTitle(event);
470
+ return {
471
+ icon: "key",
472
+ title: `${provider} disconnected`,
473
+ details: [
474
+ {
475
+ title: `${provider} disconnected`,
476
+ metadata: [event.provider]
477
+ }
478
+ ]
479
+ };
480
+ }
481
+ });
482
+ var agentsInstructionsUpdatedEvent = defineConversationEvent({
483
+ name: "agents_instructions_updated",
484
+ version: 1,
485
+ schema: agentsInstructionsUpdatedContentSchema,
486
+ renderEvent(event) {
487
+ const title = agentsInstructionsTitle(event.action);
488
+ const preview = agentsInstructionsPreview(event);
489
+ return {
490
+ icon: "brain",
491
+ title,
492
+ ...preview ? { preview } : {},
493
+ ...event.sources.length > 0 ? {
494
+ details: event.sources.map((source) => ({
495
+ title: sourceFilename(source.path),
496
+ content: source.content
497
+ }))
498
+ } : {}
499
+ };
500
+ }
501
+ });
502
+ var NATIVE_EVENT_DEFINITIONS = [
503
+ authenticationLinkedEvent,
504
+ authenticationUnlinkedEvent,
505
+ agentsInstructionsUpdatedEvent
506
+ ];
507
+ function getJuniorNativeEventDefinition(args) {
508
+ return NATIVE_EVENT_DEFINITIONS.find(
509
+ (definition) => definition.eventName === args.name && definition.version === args.version
510
+ );
511
+ }
512
+ function renderJuniorNativeConversationEvent(args) {
513
+ if (args.namespace !== JUNIOR_NATIVE_EVENT_NAMESPACE) return void 0;
514
+ const definition = getJuniorNativeEventDefinition(args);
515
+ if (!definition) return void 0;
516
+ const presentation = definition.renderEvent(definition.parse(args.content));
517
+ return presentation === void 0 ? void 0 : conversationEventPresentationSchema.parse(presentation);
518
+ }
519
+
406
520
  // src/chat/pi/conversation-events.ts
407
521
  function authorizationObservationMessage(data, createdAtMs) {
408
522
  const label = data.kind === "mcp" ? "MCP authorization" : "Authorization";
@@ -914,6 +1028,26 @@ async function recordAgentsInstructionsUpdated(args) {
914
1028
  }
915
1029
  ]);
916
1030
  }
1031
+ async function recordSubscribedReplyRoute(args) {
1032
+ await getConversationEventStore().append(args.conversationId, [
1033
+ {
1034
+ idempotencyKey: `native:${JUNIOR_NATIVE_EVENT_NAMESPACE}:passive_reply_routed:${args.runId}`,
1035
+ createdAtMs: Date.now(),
1036
+ data: {
1037
+ type: "structured_event",
1038
+ namespace: JUNIOR_NATIVE_EVENT_NAMESPACE,
1039
+ name: "passive_reply_routed",
1040
+ version: 1,
1041
+ content: {
1042
+ costUsd: args.costUsd,
1043
+ reason: args.reason,
1044
+ shouldReply: args.shouldReply,
1045
+ ...args.shouldUnsubscribe !== void 0 ? { shouldUnsubscribe: args.shouldUnsubscribe } : {}
1046
+ }
1047
+ }
1048
+ }
1049
+ ]);
1050
+ }
917
1051
  async function loadTurnRoute(args) {
918
1052
  const event = await getConversationEventStore().loadByIdempotencyKey(
919
1053
  args.conversationId,
@@ -937,6 +1071,7 @@ async function recordTurnRoute(args) {
937
1071
  turnId: args.turnId,
938
1072
  modelProfile: args.modelProfile,
939
1073
  modelId: args.modelId,
1074
+ ...args.costUsd !== void 0 ? { costUsd: args.costUsd } : {},
940
1075
  reasoningLevel: args.reasoningLevel,
941
1076
  ...args.confidence !== void 0 ? { confidence: args.confidence } : {},
942
1077
  source: args.source
@@ -1116,7 +1251,7 @@ async function persistWithRetry(persist) {
1116
1251
  }
1117
1252
 
1118
1253
  // src/chat/task-execution/turn-cursor.ts
1119
- import { z as z2 } from "zod";
1254
+ import { z as z3 } from "zod";
1120
1255
 
1121
1256
  // src/chat/repository-instructions.ts
1122
1257
  import { createHash as createHash2 } from "crypto";
@@ -1124,6 +1259,16 @@ import path2 from "path";
1124
1259
 
1125
1260
  // src/chat/tools/sandbox/file-utils.ts
1126
1261
  import path from "path";
1262
+
1263
+ // src/chat/tools/execution/tool-input-error.ts
1264
+ var ToolInputError = class extends Error {
1265
+ constructor(message, options) {
1266
+ super(message, options);
1267
+ this.name = "ToolInputError";
1268
+ }
1269
+ };
1270
+
1271
+ // src/chat/tools/sandbox/file-utils.ts
1127
1272
  var MAX_TEXT_CHARS = 6e4;
1128
1273
  var RIPGREP_EXCLUDED_GLOBS = [
1129
1274
  "!**/.git/**",
@@ -1509,63 +1654,64 @@ function definedProps(values) {
1509
1654
  Object.entries(values).filter(([, value]) => value !== void 0)
1510
1655
  );
1511
1656
  }
1512
- var turnStatusSchema = z2.enum([
1657
+ var turnStatusSchema = z3.enum([
1513
1658
  "running",
1514
1659
  "paused",
1515
1660
  "completed",
1516
1661
  "failed",
1517
1662
  "abandoned"
1518
1663
  ]);
1519
- var turnSurfaceSchema = z2.enum([
1664
+ var turnSurfaceSchema = z3.enum([
1520
1665
  "slack",
1521
1666
  "api",
1522
1667
  "scheduler",
1523
1668
  "internal"
1524
1669
  ]);
1525
- var turnPauseReasonSchema = z2.enum([
1670
+ var turnPauseReasonSchema = z3.enum([
1526
1671
  "timeout",
1527
1672
  "auth",
1528
1673
  "yield",
1529
1674
  "retry"
1530
1675
  ]);
1531
- var nonNegativeNumberSchema = z2.number().finite().nonnegative();
1532
- var seqCursorSchema = z2.number().int().min(-1);
1533
- var storedTurnSummarySchema = z2.object({
1534
- schemaVersion: z2.literal(TURN_CURSOR_SCHEMA_VERSION),
1535
- version: z2.number().int().nonnegative(),
1536
- conversationId: z2.string().min(1),
1537
- dispatchId: z2.string().min(1).optional(),
1538
- dispatchOutcome: z2.enum(["blocked", "completed", "failed"]).optional(),
1539
- resultMessageId: z2.string().min(1).optional(),
1676
+ var nonNegativeNumberSchema = z3.number().finite().nonnegative();
1677
+ var seqCursorSchema = z3.number().int().min(-1);
1678
+ var storedTurnSummarySchema = z3.object({
1679
+ schemaVersion: z3.literal(TURN_CURSOR_SCHEMA_VERSION),
1680
+ version: z3.number().int().nonnegative(),
1681
+ conversationId: z3.string().min(1),
1682
+ dispatchId: z3.string().min(1).optional(),
1683
+ dispatchOutcome: z3.enum(["blocked", "completed", "failed"]).optional(),
1684
+ resultMessageId: z3.string().min(1).optional(),
1540
1685
  resumeReason: turnPauseReasonSchema.optional(),
1541
- turnId: z2.string().min(1),
1542
- sliceId: z2.number().int().nonnegative(),
1686
+ turnId: z3.string().min(1),
1687
+ sliceId: z3.number().int().nonnegative(),
1543
1688
  state: turnStatusSchema,
1544
1689
  surface: turnSurfaceSchema.optional(),
1545
1690
  updatedAtMs: nonNegativeNumberSchema
1546
1691
  }).strip();
1547
- var storedTurnRecordSchema = z2.object({
1548
- schemaVersion: z2.literal(TURN_CURSOR_SCHEMA_VERSION),
1549
- version: z2.number().int().nonnegative(),
1550
- conversationId: z2.string().min(1),
1551
- dispatchId: z2.string().min(1).optional(),
1552
- dispatchOutcome: z2.enum(["blocked", "completed", "failed"]).optional(),
1553
- resultMessageId: z2.string().min(1).optional(),
1692
+ var storedTurnRecordSchema = z3.object({
1693
+ schemaVersion: z3.literal(TURN_CURSOR_SCHEMA_VERSION),
1694
+ version: z3.number().int().nonnegative(),
1695
+ conversationId: z3.string().min(1),
1696
+ dispatchId: z3.string().min(1).optional(),
1697
+ dispatchOutcome: z3.enum(["blocked", "completed", "failed"]).optional(),
1698
+ resultMessageId: z3.string().min(1).optional(),
1554
1699
  lastProgressAtMs: nonNegativeNumberSchema,
1555
1700
  resumeReason: turnPauseReasonSchema.optional(),
1556
- resumedFromSliceId: z2.number().int().nonnegative().optional(),
1557
- turnId: z2.string().min(1),
1558
- sliceId: z2.number().int().nonnegative(),
1701
+ publishExternally: z3.boolean().optional(),
1702
+ resumedFromSliceId: z3.number().int().nonnegative().optional(),
1703
+ turnId: z3.string().min(1),
1704
+ sliceId: z3.number().int().nonnegative(),
1559
1705
  startedAtMs: nonNegativeNumberSchema,
1560
1706
  state: turnStatusSchema,
1561
1707
  surface: turnSurfaceSchema.optional(),
1562
- traceId: z2.string().optional(),
1708
+ traceId: z3.string().optional(),
1563
1709
  updatedAtMs: nonNegativeNumberSchema,
1564
1710
  committedSeq: seqCursorSchema,
1565
- historyVersion: z2.number().int().nonnegative().optional(),
1566
- errorMessage: z2.string().optional(),
1711
+ historyVersion: z3.number().int().nonnegative().optional(),
1712
+ errorMessage: z3.string().optional(),
1567
1713
  turnStartSeq: seqCursorSchema.optional(),
1568
- runtimeContext: z2.array(piMessageSchema).optional()
1714
+ runtimeContext: z3.array(piMessageSchema).optional()
1569
1715
  }).strip();
1570
1716
  function conversationExecutionFromSummary(summary) {
1571
1717
  const status = summary.state === "completed" || summary.state === "abandoned" ? "idle" : summary.state;
@@ -1614,7 +1760,7 @@ async function recordConversationActivityMetadata(args) {
1614
1760
  });
1615
1761
  const isChild = Boolean(conversation?.lineage);
1616
1762
  const destination = isChild ? void 0 : args.destination;
1617
- const activitySource = isChild ? "internal" : destination?.platform === "local" ? "local" : destination ? args.summary.surface : void 0;
1763
+ const activitySource = isChild ? "internal" : args.source?.platform === "web" ? "web" : destination?.platform === "local" ? "local" : destination ? args.summary.surface : void 0;
1618
1764
  await conversationStore.recordActivity({
1619
1765
  activityAtMs: args.summary.updatedAtMs,
1620
1766
  channelName: args.summary.channelName,
@@ -1666,6 +1812,7 @@ function materializeTurnRecord(stored, piProjection, turnStartMessageIndex, rest
1666
1812
  dispatchOutcome: stored.dispatchOutcome,
1667
1813
  errorMessage: stored.errorMessage,
1668
1814
  resumeReason: stored.resumeReason,
1815
+ publishExternally: stored.publishExternally,
1669
1816
  resultMessageId: stored.resultMessageId,
1670
1817
  resumedFromSliceId: stored.resumedFromSliceId,
1671
1818
  surface: stored.surface,
@@ -1775,6 +1922,7 @@ function buildStoredRecord(args) {
1775
1922
  errorMessage: args.errorMessage,
1776
1923
  historyVersion: args.historyVersion,
1777
1924
  resumeReason: args.resumeReason,
1925
+ publishExternally: args.publishExternally,
1778
1926
  resultMessageId: args.resultMessageId,
1779
1927
  resumedFromSliceId: args.resumedFromSliceId,
1780
1928
  runtimeContext: args.runtimeContext && args.runtimeContext.length > 0 ? args.runtimeContext : void 0,
@@ -1862,6 +2010,7 @@ async function updateTurnState(args) {
1862
2010
  errorMessage: args.errorMessage ?? args.existing.errorMessage,
1863
2011
  historyVersion: parsed.historyVersion,
1864
2012
  resumeReason: args.existing.resumeReason,
2013
+ publishExternally: args.existing.publishExternally,
1865
2014
  resultMessageId: args.resultMessageId ?? args.existing.resultMessageId,
1866
2015
  resumedFromSliceId: args.existing.resumedFromSliceId,
1867
2016
  surface: args.existing.surface,
@@ -1949,6 +2098,7 @@ async function upsertTurnRecordLocked(args, fence) {
1949
2098
  errorMessage: args.errorMessage,
1950
2099
  lastProgressAtMs: args.lastProgressAtMs,
1951
2100
  resumeReason: args.resumeReason,
2101
+ publishExternally: args.publishExternally ?? existingRecord?.publishExternally,
1952
2102
  resultMessageId: args.resultMessageId ?? existingRecord?.resultMessageId,
1953
2103
  resumedFromSliceId: args.resumedFromSliceId,
1954
2104
  runtimeContext: args.state === "running" || args.state === "paused" ? retainedRuntimeContext : void 0,
@@ -2105,6 +2255,96 @@ async function failTurnRecord(args) {
2105
2255
  );
2106
2256
  }
2107
2257
 
2258
+ // src/chat/usage.ts
2259
+ var agentTurnUsageSchema = usageSchema;
2260
+ var COMPONENT_USAGE_FIELDS = [
2261
+ "inputTokens",
2262
+ "outputTokens",
2263
+ "cachedInputTokens",
2264
+ "cacheCreationTokens"
2265
+ ];
2266
+ var COST_COMPONENT_FIELDS = [
2267
+ "input",
2268
+ "output",
2269
+ "cacheRead",
2270
+ "cacheWrite"
2271
+ ];
2272
+ function hasAgentTurnUsage(usage) {
2273
+ return Boolean(
2274
+ usage && (Object.entries(usage).some(
2275
+ ([field, value]) => field !== "cost" && typeof value === "number" && Number.isFinite(value)
2276
+ ) || Object.values(usage.cost ?? {}).some(
2277
+ (value) => typeof value === "number" && Number.isFinite(value)
2278
+ ))
2279
+ );
2280
+ }
2281
+ function getFiniteCount(value) {
2282
+ return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.floor(value)) : void 0;
2283
+ }
2284
+ function getFiniteCost(value) {
2285
+ return typeof value === "number" && Number.isFinite(value) ? Math.max(0, value) : void 0;
2286
+ }
2287
+ function addCost(left, right) {
2288
+ return Math.round(((left ?? 0) + right) * 1e12) / 1e12;
2289
+ }
2290
+ function getComponentTotal(usage) {
2291
+ let total;
2292
+ for (const field of COMPONENT_USAGE_FIELDS) {
2293
+ const value = getFiniteCount(usage[field]);
2294
+ if (value === void 0) continue;
2295
+ total = (total ?? 0) + value;
2296
+ }
2297
+ return total;
2298
+ }
2299
+ function addAgentTurnUsage(...usages) {
2300
+ const components = {};
2301
+ let componentTotal;
2302
+ let totalOnlyTokens;
2303
+ let reasoningTokens;
2304
+ const cost = {};
2305
+ for (const usage of usages) {
2306
+ if (!usage) continue;
2307
+ const reasoning = getFiniteCount(usage.reasoningTokens);
2308
+ if (reasoning !== void 0) {
2309
+ reasoningTokens = (reasoningTokens ?? 0) + reasoning;
2310
+ }
2311
+ if (usage.cost) {
2312
+ for (const field of [...COST_COMPONENT_FIELDS, "total"]) {
2313
+ const value = getFiniteCost(usage.cost[field]);
2314
+ if (value === void 0) continue;
2315
+ cost[field] = addCost(cost[field], value);
2316
+ }
2317
+ }
2318
+ const usageComponentTotal = getComponentTotal(usage);
2319
+ if (usageComponentTotal !== void 0) {
2320
+ componentTotal = (componentTotal ?? 0) + usageComponentTotal;
2321
+ for (const field of COMPONENT_USAGE_FIELDS) {
2322
+ const value = getFiniteCount(usage[field]);
2323
+ if (value === void 0) continue;
2324
+ components[field] = (components[field] ?? 0) + value;
2325
+ }
2326
+ continue;
2327
+ }
2328
+ const totalTokens = getFiniteCount(usage.totalTokens);
2329
+ if (totalTokens !== void 0) {
2330
+ totalOnlyTokens = (totalOnlyTokens ?? 0) + totalTokens;
2331
+ }
2332
+ }
2333
+ if (totalOnlyTokens !== void 0) {
2334
+ return {
2335
+ totalTokens: totalOnlyTokens + (componentTotal ?? 0),
2336
+ ...reasoningTokens !== void 0 ? { reasoningTokens } : {},
2337
+ ...Object.keys(cost).length > 0 ? { cost } : {}
2338
+ };
2339
+ }
2340
+ const result = {
2341
+ ...components,
2342
+ ...reasoningTokens !== void 0 ? { reasoningTokens } : {},
2343
+ ...Object.keys(cost).length > 0 ? { cost } : {}
2344
+ };
2345
+ return hasAgentTurnUsage(result) ? result : void 0;
2346
+ }
2347
+
2108
2348
  // src/chat/services/turn-limit.ts
2109
2349
  var TurnSliceLimitExceededError = class extends Error {
2110
2350
  constructor(maxSlices) {
@@ -2165,6 +2405,7 @@ function sharedWrite(args, latest) {
2165
2405
  destination: args.destination,
2166
2406
  destinationVisibility: args.destinationVisibility,
2167
2407
  dispatchId: args.dispatchId ?? latest?.dispatchId,
2408
+ publishExternally: args.publishExternally ?? latest?.publishExternally,
2168
2409
  source: args.source,
2169
2410
  surface: args.surface ?? latest?.surface,
2170
2411
  traceId: getActiveTraceId() ?? latest?.traceId,
@@ -2292,473 +2533,6 @@ async function saveDone(args) {
2292
2533
  });
2293
2534
  }
2294
2535
 
2295
- // src/chat/state/conversation.ts
2296
- function defaultConversationState() {
2297
- return {
2298
- schemaVersion: 1,
2299
- messages: [],
2300
- compactions: [],
2301
- processing: {},
2302
- vision: {
2303
- byFileId: {}
2304
- }
2305
- };
2306
- }
2307
- function coercePendingAuthState(value) {
2308
- if (!isRecord(value)) {
2309
- return void 0;
2310
- }
2311
- const kind = value.kind;
2312
- const provider = toOptionalString(value.provider);
2313
- const actorId = toOptionalString(value.actorId);
2314
- const authSessionId = toOptionalString(value.authSessionId);
2315
- const scope = toOptionalString(value.scope);
2316
- const sessionId = toOptionalString(value.sessionId);
2317
- const linkSentAtMs = toOptionalNumber(value.linkSentAtMs);
2318
- if (kind !== "mcp" && kind !== "plugin" || !provider || !actorId || kind === "mcp" && !authSessionId || !sessionId || typeof linkSentAtMs !== "number") {
2319
- return void 0;
2320
- }
2321
- const base = {
2322
- provider,
2323
- actorId,
2324
- ...scope ? { scope } : {},
2325
- sessionId,
2326
- linkSentAtMs
2327
- };
2328
- return kind === "mcp" ? { ...base, authSessionId, kind } : { ...base, kind };
2329
- }
2330
- function coerceThreadConversationState(value) {
2331
- if (!isRecord(value)) {
2332
- return defaultConversationState();
2333
- }
2334
- const root = value;
2335
- const rawConversation = isRecord(root.conversation) ? root.conversation : {};
2336
- const messages = [];
2337
- const compactions = [];
2338
- const rawProcessing = isRecord(rawConversation.processing) ? rawConversation.processing : {};
2339
- const processing = {
2340
- activeTurnId: toOptionalString(rawProcessing.activeTurnId),
2341
- lastCompletedAtMs: toOptionalNumber(rawProcessing.lastCompletedAtMs),
2342
- pendingAuth: coercePendingAuthState(rawProcessing.pendingAuth)
2343
- };
2344
- const rawVision = isRecord(rawConversation.vision) ? rawConversation.vision : {};
2345
- const rawVisionByFileId = isRecord(rawVision.byFileId) ? rawVision.byFileId : {};
2346
- const byFileId = {};
2347
- for (const [fileId, value2] of Object.entries(rawVisionByFileId)) {
2348
- if (typeof fileId !== "string" || fileId.trim().length === 0) continue;
2349
- if (!isRecord(value2)) continue;
2350
- const summary = toOptionalString(value2.summary);
2351
- const analyzedAtMs = toOptionalNumber(value2.analyzedAtMs);
2352
- if (!summary || !analyzedAtMs) continue;
2353
- byFileId[fileId] = {
2354
- summary,
2355
- analyzedAtMs
2356
- };
2357
- }
2358
- return {
2359
- schemaVersion: 1,
2360
- messages,
2361
- compactions,
2362
- processing,
2363
- vision: {
2364
- backfillCompletedAtMs: toOptionalNumber(rawVision.backfillCompletedAtMs),
2365
- byFileId
2366
- }
2367
- };
2368
- }
2369
- function buildConversationStatePatch(conversation) {
2370
- return {
2371
- conversation: {
2372
- schemaVersion: 1,
2373
- processing: { ...conversation.processing },
2374
- vision: {
2375
- backfillCompletedAtMs: conversation.vision.backfillCompletedAtMs,
2376
- byFileId: { ...conversation.vision.byFileId }
2377
- }
2378
- }
2379
- };
2380
- }
2381
-
2382
- // src/chat/state/artifacts.ts
2383
- function coerceThreadArtifactsState(value) {
2384
- if (!value || typeof value !== "object") {
2385
- return {};
2386
- }
2387
- const raw = value;
2388
- const artifacts = raw.artifacts ?? {};
2389
- const listColumnMap = artifacts.listColumnMap ?? {};
2390
- const recentCanvases = [];
2391
- if (Array.isArray(artifacts.recentCanvases)) {
2392
- for (const entry of artifacts.recentCanvases) {
2393
- if (!entry || typeof entry !== "object") {
2394
- continue;
2395
- }
2396
- const candidate = entry;
2397
- if (typeof candidate.id !== "string" || candidate.id.trim().length === 0) {
2398
- continue;
2399
- }
2400
- recentCanvases.push({
2401
- id: candidate.id,
2402
- title: typeof candidate.title === "string" ? candidate.title : void 0,
2403
- url: typeof candidate.url === "string" ? candidate.url : void 0,
2404
- createdAt: typeof candidate.createdAt === "string" ? candidate.createdAt : void 0
2405
- });
2406
- }
2407
- }
2408
- return {
2409
- assistantContextChannelId: typeof artifacts.assistantContextChannelId === "string" ? artifacts.assistantContextChannelId : void 0,
2410
- assistantTitle: typeof artifacts.assistantTitle === "string" ? artifacts.assistantTitle : void 0,
2411
- assistantTitleSourceMessageId: typeof artifacts.assistantTitleSourceMessageId === "string" ? artifacts.assistantTitleSourceMessageId : void 0,
2412
- lastCanvasId: typeof artifacts.lastCanvasId === "string" ? artifacts.lastCanvasId : void 0,
2413
- lastCanvasUrl: typeof artifacts.lastCanvasUrl === "string" ? artifacts.lastCanvasUrl : void 0,
2414
- recentCanvases,
2415
- lastListId: typeof artifacts.lastListId === "string" ? artifacts.lastListId : void 0,
2416
- lastListUrl: typeof artifacts.lastListUrl === "string" ? artifacts.lastListUrl : void 0,
2417
- listColumnMap: {
2418
- titleColumnId: typeof listColumnMap.titleColumnId === "string" ? listColumnMap.titleColumnId : void 0,
2419
- completedColumnId: typeof listColumnMap.completedColumnId === "string" ? listColumnMap.completedColumnId : void 0,
2420
- assigneeColumnId: typeof listColumnMap.assigneeColumnId === "string" ? listColumnMap.assigneeColumnId : void 0,
2421
- dueDateColumnId: typeof listColumnMap.dueDateColumnId === "string" ? listColumnMap.dueDateColumnId : void 0
2422
- },
2423
- updatedAt: typeof artifacts.updatedAt === "string" ? artifacts.updatedAt : void 0
2424
- };
2425
- }
2426
- function buildArtifactStatePatch(patch) {
2427
- return {
2428
- artifacts: {
2429
- ...patch,
2430
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
2431
- }
2432
- };
2433
- }
2434
-
2435
- // src/chat/configuration/validation.ts
2436
- var CONFIG_KEY_RE = /^[a-z0-9]+(?:\.[a-z0-9-]+)+$/;
2437
- var SECRET_KEY_RE = /(?:^|[_.-])(token|secret|password|passphrase|api[-_]?key|private[-_]?key|credential|auth)(?:$|[_.-])/i;
2438
- var SECRET_VALUE_PATTERNS = [
2439
- /\bBearer\s+[A-Za-z0-9._-]{16,}\b/i,
2440
- /-----BEGIN [A-Z ]*PRIVATE KEY-----/,
2441
- /\b(?:ghp|ghs|github_pat)_[A-Za-z0-9_]{20,}\b/,
2442
- /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/i,
2443
- /\bsk-[A-Za-z0-9]{20,}\b/,
2444
- /\bAIza[0-9A-Za-z\-_]{30,}\b/,
2445
- /\bAKIA[0-9A-Z]{16}\b/,
2446
- /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/
2447
- ];
2448
- function validateConfigKey(key) {
2449
- const trimmed = key.trim();
2450
- if (!trimmed) {
2451
- return "Configuration key must not be empty";
2452
- }
2453
- if (!CONFIG_KEY_RE.test(trimmed)) {
2454
- return `Invalid configuration key "${key}"; expected dotted lowercase namespace (for example "provider.repo")`;
2455
- }
2456
- if (SECRET_KEY_RE.test(trimmed)) {
2457
- return `Configuration key "${key}" appears to be secret-related and is not allowed`;
2458
- }
2459
- return void 0;
2460
- }
2461
- function collectStringValues(value, output, depth = 0) {
2462
- if (depth > 5) {
2463
- return;
2464
- }
2465
- if (typeof value === "string") {
2466
- output.push(value);
2467
- return;
2468
- }
2469
- if (Array.isArray(value)) {
2470
- for (const item of value) {
2471
- collectStringValues(item, output, depth + 1);
2472
- }
2473
- return;
2474
- }
2475
- if (value && typeof value === "object") {
2476
- for (const [key, nested] of Object.entries(
2477
- value
2478
- )) {
2479
- output.push(key);
2480
- collectStringValues(nested, output, depth + 1);
2481
- }
2482
- }
2483
- }
2484
- function validateConfigValue(value) {
2485
- const stringValues = [];
2486
- collectStringValues(value, stringValues);
2487
- for (const text of stringValues) {
2488
- for (const pattern of SECRET_VALUE_PATTERNS) {
2489
- if (pattern.test(text)) {
2490
- return "Configuration value appears to contain secret material and is not allowed";
2491
- }
2492
- }
2493
- }
2494
- return void 0;
2495
- }
2496
-
2497
- // src/chat/configuration/service.ts
2498
- function defaultState() {
2499
- return {
2500
- schemaVersion: 1,
2501
- entries: {}
2502
- };
2503
- }
2504
- function sanitizeEntry(value) {
2505
- if (!isRecord(value)) {
2506
- return void 0;
2507
- }
2508
- const key = toOptionalString(value.key);
2509
- if (!key) {
2510
- return void 0;
2511
- }
2512
- if (validateConfigKey(key)) {
2513
- return void 0;
2514
- }
2515
- const updatedAt = toOptionalString(value.updatedAt);
2516
- if (!updatedAt) {
2517
- return void 0;
2518
- }
2519
- if (value.scope !== "channel" && value.scope !== "conversation") {
2520
- return void 0;
2521
- }
2522
- const scope = "conversation";
2523
- return {
2524
- key,
2525
- value: value.value,
2526
- scope,
2527
- updatedAt,
2528
- updatedBy: toOptionalString(value.updatedBy),
2529
- source: toOptionalString(value.source),
2530
- expiresAt: toOptionalString(value.expiresAt)
2531
- };
2532
- }
2533
- function coerceState(raw) {
2534
- if (!isRecord(raw)) {
2535
- return defaultState();
2536
- }
2537
- const rawConfig = isRecord(raw.configuration) ? raw.configuration : {};
2538
- const rawEntries = isRecord(rawConfig.entries) ? rawConfig.entries : {};
2539
- const entries = {};
2540
- for (const [key, value] of Object.entries(rawEntries)) {
2541
- const entry = sanitizeEntry(value);
2542
- if (!entry) {
2543
- continue;
2544
- }
2545
- entries[key] = entry;
2546
- }
2547
- return {
2548
- schemaVersion: 1,
2549
- entries
2550
- };
2551
- }
2552
- function createChannelConfigurationService(storage) {
2553
- const getState = async () => {
2554
- const loaded = await storage.load();
2555
- return coerceState(loaded);
2556
- };
2557
- const saveState = async (state) => {
2558
- await storage.save({
2559
- schemaVersion: 1,
2560
- entries: state.entries
2561
- });
2562
- };
2563
- const get = async (key) => {
2564
- const normalizedKey = key.trim();
2565
- const state = await getState();
2566
- return state.entries[normalizedKey];
2567
- };
2568
- const set = async (input) => {
2569
- const normalizedKey = input.key.trim();
2570
- const keyError = validateConfigKey(normalizedKey);
2571
- if (keyError) {
2572
- throw new Error(keyError);
2573
- }
2574
- const valueError = validateConfigValue(input.value);
2575
- if (valueError) {
2576
- throw new Error(valueError);
2577
- }
2578
- const state = await getState();
2579
- const nextEntry = {
2580
- key: normalizedKey,
2581
- value: input.value,
2582
- scope: "conversation",
2583
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
2584
- updatedBy: toOptionalString(input.updatedBy),
2585
- source: toOptionalString(input.source),
2586
- expiresAt: toOptionalString(input.expiresAt)
2587
- };
2588
- state.entries[normalizedKey] = nextEntry;
2589
- await saveState(state);
2590
- return nextEntry;
2591
- };
2592
- const unset = async (key) => {
2593
- const normalizedKey = key.trim();
2594
- const state = await getState();
2595
- if (!state.entries[normalizedKey]) {
2596
- return false;
2597
- }
2598
- delete state.entries[normalizedKey];
2599
- await saveState(state);
2600
- return true;
2601
- };
2602
- const list = async (options = {}) => {
2603
- const state = await getState();
2604
- const prefix = options.prefix?.trim();
2605
- return Object.values(state.entries).filter((entry) => prefix ? entry.key.startsWith(prefix) : true).sort((a, b) => a.key.localeCompare(b.key));
2606
- };
2607
- const resolve = async (key) => {
2608
- const entry = await get(key);
2609
- return entry?.value;
2610
- };
2611
- const resolveValues = async (options = {}) => {
2612
- const keys = Array.isArray(options.keys) ? options.keys.map((entry) => entry.trim()).filter((entry) => entry.length > 0) : void 0;
2613
- const entries = options.prefix ? await list({ prefix: options.prefix }) : await list({});
2614
- const filtered = keys ? entries.filter((entry) => keys.includes(entry.key)) : entries;
2615
- const resolved = {};
2616
- for (const entry of filtered) {
2617
- resolved[entry.key] = entry.value;
2618
- }
2619
- return resolved;
2620
- };
2621
- return {
2622
- get,
2623
- set,
2624
- unset,
2625
- list,
2626
- resolve,
2627
- resolveValues
2628
- };
2629
- }
2630
-
2631
- // src/chat/runtime/thread-state.ts
2632
- function threadStateKey(threadId) {
2633
- return `thread-state:${threadId}`;
2634
- }
2635
- function channelStateKey(channelId) {
2636
- return `channel-state:${channelId}`;
2637
- }
2638
- function buildThreadStatePayload(patch) {
2639
- const payload = {};
2640
- if (patch.artifacts) {
2641
- Object.assign(payload, buildArtifactStatePatch(patch.artifacts));
2642
- }
2643
- if (patch.conversation) {
2644
- Object.assign(payload, buildConversationStatePatch(patch.conversation));
2645
- }
2646
- if (patch.sandboxRef !== void 0) {
2647
- payload.app_sandbox_id = patch.sandboxRef?.id ?? "";
2648
- payload.app_sandbox_dependency_profile_hash = patch.sandboxRef?.profileHash ?? "";
2649
- }
2650
- return payload;
2651
- }
2652
- async function mergePersistedState(key, payload) {
2653
- if (Object.keys(payload).length === 0) {
2654
- return;
2655
- }
2656
- const stateAdapter = getStateAdapter();
2657
- await stateAdapter.connect();
2658
- const existing = await stateAdapter.get(key) ?? {};
2659
- await stateAdapter.set(
2660
- key,
2661
- { ...existing, ...payload },
2662
- JUNIOR_THREAD_STATE_TTL_MS
2663
- );
2664
- }
2665
- function mergeArtifactsState(artifacts, patch) {
2666
- if (!patch) {
2667
- return artifacts;
2668
- }
2669
- return {
2670
- ...artifacts,
2671
- ...patch,
2672
- listColumnMap: {
2673
- ...artifacts.listColumnMap,
2674
- ...patch.listColumnMap
2675
- }
2676
- };
2677
- }
2678
- function getPersistedSandboxState(state) {
2679
- const id = toOptionalString(state.app_sandbox_id);
2680
- if (!id) {
2681
- return void 0;
2682
- }
2683
- const profileHash = toOptionalString(
2684
- state.app_sandbox_dependency_profile_hash
2685
- );
2686
- return {
2687
- id,
2688
- ...profileHash ? { profileHash } : {}
2689
- };
2690
- }
2691
- async function persistThreadState(thread, patch) {
2692
- if (patch.conversation) {
2693
- await persistConversationMessages({
2694
- conversation: patch.conversation,
2695
- conversationId: toOptionalString(thread.id) ?? toOptionalString(thread.runId)
2696
- });
2697
- }
2698
- await persistThreadRuntimeState(thread, patch);
2699
- }
2700
- async function persistThreadRuntimeState(thread, patch) {
2701
- const threadId = toOptionalString(thread.id) ?? toOptionalString(thread.runId);
2702
- if (!threadId) {
2703
- throw new Error("thread id is required to persist runtime scratch");
2704
- }
2705
- await mergePersistedState(
2706
- threadStateKey(threadId),
2707
- buildThreadStatePayload(patch)
2708
- );
2709
- }
2710
- async function getPersistedThreadState(threadId) {
2711
- const stateAdapter = getStateAdapter();
2712
- await stateAdapter.connect();
2713
- return await stateAdapter.get(
2714
- threadStateKey(threadId)
2715
- ) ?? {};
2716
- }
2717
- async function getPersistedChannelState(channelId) {
2718
- const stateAdapter = getStateAdapter();
2719
- await stateAdapter.connect();
2720
- return await stateAdapter.get(
2721
- channelStateKey(channelId)
2722
- ) ?? {};
2723
- }
2724
- async function persistThreadStateById(threadId, patch) {
2725
- if (patch.conversation) {
2726
- await persistConversationMessages({
2727
- conversation: patch.conversation,
2728
- conversationId: threadId
2729
- });
2730
- }
2731
- await mergePersistedState(
2732
- threadStateKey(threadId),
2733
- buildThreadStatePayload(patch)
2734
- );
2735
- }
2736
- function getChannelConfigurationService(thread) {
2737
- const channel = thread.channel;
2738
- const channelId = toOptionalString(thread.channelId) ?? toOptionalString(channel.id);
2739
- if (!channelId) {
2740
- throw new Error("channel id is required to load channel configuration");
2741
- }
2742
- return createChannelConfigurationService({
2743
- load: async () => await channel.state,
2744
- save: async (state) => {
2745
- await mergePersistedState(channelStateKey(channelId), {
2746
- configuration: state
2747
- });
2748
- }
2749
- });
2750
- }
2751
- function getChannelConfigurationServiceById(channelId) {
2752
- return createChannelConfigurationService({
2753
- load: async () => await getPersistedChannelState(channelId),
2754
- save: async (state) => {
2755
- await mergePersistedState(channelStateKey(channelId), {
2756
- configuration: state
2757
- });
2758
- }
2759
- });
2760
- }
2761
-
2762
2536
  // src/chat/services/pending-auth.ts
2763
2537
  var AUTH_LINK_REUSE_WINDOW_MS = 10 * 60 * 1e3;
2764
2538
  var NON_REQUEST_SKIPPED_REASON_PREFIXES = [
@@ -2823,6 +2597,7 @@ function isPendingAuthLatestRequest(conversation, pendingAuth) {
2823
2597
  }
2824
2598
 
2825
2599
  export {
2600
+ renderJuniorNativeConversationEvent,
2826
2601
  TURN_CONTEXT_TAG,
2827
2602
  isAssistantMessage,
2828
2603
  isToolResultMessage,
@@ -2854,10 +2629,12 @@ export {
2854
2629
  recordAuthorizationCompleted,
2855
2630
  recordAuthenticationLinked,
2856
2631
  recordAgentsInstructionsUpdated,
2632
+ recordSubscribedReplyRoute,
2857
2633
  loadTurnRoute,
2858
2634
  recordTurnRoute,
2859
2635
  recordToolExecutionStarted,
2860
2636
  recordGuardianActionReviewed,
2637
+ ToolInputError,
2861
2638
  MAX_TEXT_CHARS,
2862
2639
  RIPGREP_EXCLUDED_GLOBS,
2863
2640
  DEFAULT_SEARCH_COMMAND_TIMEOUT_MS,
@@ -2896,6 +2673,9 @@ export {
2896
2673
  sanitizeAssistantText,
2897
2674
  decideReply,
2898
2675
  getAssistantReplyText,
2676
+ agentTurnUsageSchema,
2677
+ hasAgentTurnUsage,
2678
+ addAgentTurnUsage,
2899
2679
  TurnSliceLimitExceededError,
2900
2680
  buildTurnLimitResponse,
2901
2681
  persistWithRetry,
@@ -2913,15 +2693,5 @@ export {
2913
2693
  getConversationPendingAuth,
2914
2694
  clearPendingAuth,
2915
2695
  abandonReplacedPendingAuth,
2916
- isPendingAuthLatestRequest,
2917
- coerceThreadConversationState,
2918
- coerceThreadArtifactsState,
2919
- mergeArtifactsState,
2920
- getPersistedSandboxState,
2921
- persistThreadState,
2922
- persistThreadRuntimeState,
2923
- getPersistedThreadState,
2924
- persistThreadStateById,
2925
- getChannelConfigurationService,
2926
- getChannelConfigurationServiceById
2696
+ isPendingAuthLatestRequest
2927
2697
  };