@sentry/junior 0.203.0 → 0.205.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 (174) hide show
  1. package/dist/agent-D4nu8MQV.js +17521 -0
  2. package/dist/agent-hooks-DXHpTJ4m.js +4042 -0
  3. package/dist/agent-runner-C04colea.js +678 -0
  4. package/dist/api/schema.d.ts +2736 -2639
  5. package/dist/api/schema.js +4 -169
  6. package/dist/api.d.ts +23 -17
  7. package/dist/api.js +3881 -5326
  8. package/dist/app-Cb776lL8.d.ts +247 -0
  9. package/dist/app.d.ts +4 -520
  10. package/dist/app.js +9524 -11875
  11. package/dist/auth-pause-state-C2P3guS1.js +168 -0
  12. package/dist/catalog-runtime-CXw3asJD.js +7 -0
  13. package/dist/checkpoint-CrViJ8Ps.js +2450 -0
  14. package/dist/cli/chat.d.ts +20 -0
  15. package/dist/cli/chat.js +229 -336
  16. package/dist/cli/check.d.ts +8 -0
  17. package/dist/cli/check.js +513 -806
  18. package/dist/cli/env.d.ts +13 -0
  19. package/dist/cli/env.js +63 -12
  20. package/dist/cli/init.d.ts +3 -0
  21. package/dist/cli/init.js +90 -159
  22. package/dist/cli/main.d.ts +6 -0
  23. package/dist/cli/main.js +43 -64
  24. package/dist/cli/plugins.d.ts +13 -0
  25. package/dist/cli/plugins.js +148 -227
  26. package/dist/cli/run.d.ts +16 -0
  27. package/dist/cli/run.js +52 -8
  28. package/dist/cli/snapshot-create.d.ts +4 -0
  29. package/dist/cli/snapshot-create.js +71 -125
  30. package/dist/cli/upgrade.d.ts +15 -0
  31. package/dist/cli/upgrade.js +232 -335
  32. package/dist/config-BOtJQ7Pc.js +941 -0
  33. package/dist/context-B45_WqVX.js +298 -0
  34. package/dist/conversation-privacy-BZRA6Pes.js +182 -0
  35. package/dist/conversation-work-C6y3T5Hx.js +51 -0
  36. package/dist/credential-sync-Bep34IB_.js +2661 -0
  37. package/dist/db-BeyXKJOI.d.ts +5 -0
  38. package/dist/destinations-BeBiJeEM.js +29 -0
  39. package/dist/execution-stats-B6lgWxCK.js +373 -0
  40. package/dist/executor-BlUhFL7_.js +721 -0
  41. package/dist/experimental-CIXf7Uye.js +46 -0
  42. package/dist/history-ClE4toxe.d.ts +32 -0
  43. package/dist/history-CqTuSAdI.js +441 -0
  44. package/dist/instrumentation.d.ts +3 -3
  45. package/dist/instrumentation.js +130 -176
  46. package/dist/job-queue-DLMqIK74.js +63 -0
  47. package/dist/logging-BMJzdDlP.js +1210 -0
  48. package/dist/model-profile-CZmVoGdX.js +49 -0
  49. package/dist/nitro.d.ts +31 -36
  50. package/dist/nitro.js +275 -456
  51. package/dist/oauth-callback-server-WwG5_Zgm.js +130 -0
  52. package/dist/oauth-relay-CdCnu80W.js +62 -0
  53. package/dist/package-discovery-7a9YqLhE.js +455 -0
  54. package/dist/pending-auth-CUbXq06G.js +185 -0
  55. package/dist/plugin-module-BKGOXca2.js +81 -0
  56. package/dist/plugins-BI9A1vKA.d.ts +95 -0
  57. package/dist/plugins-egKWjgue.js +99 -0
  58. package/dist/private-trace-result-BLvBjy_e.js +16 -0
  59. package/dist/profile-T0tXE4zu.js +861 -0
  60. package/dist/registry-BA0__8ai.js +1419 -0
  61. package/dist/reporting-schema-DosTN__Q.js +105 -0
  62. package/dist/resolve-bvD1ORdv.js +546 -0
  63. package/dist/rolldown-runtime-B4FMCO8f.js +28 -0
  64. package/dist/runner-BXYxfIUL.js +392 -0
  65. package/dist/sandbox-egress-signals-ngEPjSEW.js +46 -0
  66. package/dist/schema-Rn8-XEaN.js +1140 -0
  67. package/dist/sentry-CD3SdJl-.js +26 -0
  68. package/dist/skills-DJOlYdBs.js +316 -0
  69. package/dist/spawn-h0R1bTEo.js +29 -0
  70. package/dist/stats-3YZn-Swi.js +2648 -0
  71. package/dist/store-C5qxF2ac.d.ts +208 -0
  72. package/dist/task-queue-CoXwd2eq.js +136 -0
  73. package/dist/task-runner-B2_mJZj0.js +639 -0
  74. package/dist/thread-state-CqZ1m-es.js +431 -0
  75. package/dist/turn-execution-fI6PZ0iI.js +47 -0
  76. package/dist/turn-lifecycle-CcnwrOcp.js +54 -0
  77. package/dist/usage-B5SfMb3H.js +296 -0
  78. package/dist/usage-schema-CKaDkH_j.js +20 -0
  79. package/dist/validation-DfWcvhuS.js +40 -0
  80. package/dist/vercel-queue-DIkVcfK4.js +167 -0
  81. package/dist/vercel.d.ts +6 -6
  82. package/dist/vercel.js +14 -6
  83. package/dist/version-CnXZ614E.d.ts +5 -0
  84. package/dist/version-oD-oPrbO.js +8 -0
  85. package/dist/version.d.ts +2 -4
  86. package/dist/version.js +2 -6
  87. package/dist/web-authorization-Crbzlmzo.js +76 -0
  88. package/dist/web-input-BOuq3oKK.js +494 -0
  89. package/dist/work-B91LQKHr.js +509 -0
  90. package/dist/worker-BcRRTe6k.js +625 -0
  91. package/package.json +9 -9
  92. package/dist/agent-hooks-GB2VPTNA.js +0 -51
  93. package/dist/catalog-runtime-UBLIWD3O.js +0 -14
  94. package/dist/chunk-2LYHWMR4.js +0 -46
  95. package/dist/chunk-352OWAZH.js +0 -320
  96. package/dist/chunk-3Y47VMHV.js +0 -6
  97. package/dist/chunk-3YJSKOWF.js +0 -164
  98. package/dist/chunk-4KSSKTQ5.js +0 -229
  99. package/dist/chunk-4UO6FK4G.js +0 -64
  100. package/dist/chunk-5AHX53NQ.js +0 -717
  101. package/dist/chunk-5J3E5FWA.js +0 -700
  102. package/dist/chunk-5PDAG6O3.js +0 -206
  103. package/dist/chunk-6Y5B5PEX.js +0 -80
  104. package/dist/chunk-7GWQ5S5R.js +0 -2086
  105. package/dist/chunk-7H2VZTWN.js +0 -103
  106. package/dist/chunk-7NL7T6VU.js +0 -406
  107. package/dist/chunk-A5L27LE4.js +0 -387
  108. package/dist/chunk-ADIAWL34.js +0 -81
  109. package/dist/chunk-ASTEMBKJ.js +0 -519
  110. package/dist/chunk-CEMMLV5L.js +0 -98
  111. package/dist/chunk-CM5HNV2W.js +0 -131
  112. package/dist/chunk-CRTRBBRI.js +0 -105
  113. package/dist/chunk-DA2KGZZI.js +0 -13
  114. package/dist/chunk-DIB4GX3G.js +0 -8
  115. package/dist/chunk-DKIJ2RP5.js +0 -68
  116. package/dist/chunk-DWPN6SCH.js +0 -172
  117. package/dist/chunk-EDKUFGPL.js +0 -64
  118. package/dist/chunk-ENY6SKIU.js +0 -1228
  119. package/dist/chunk-F4MGCZOX.js +0 -2943
  120. package/dist/chunk-FA6POGLH.js +0 -70
  121. package/dist/chunk-FSUR7GTG.js +0 -20475
  122. package/dist/chunk-GKEOHJL5.js +0 -1856
  123. package/dist/chunk-GMCB6W5Y.js +0 -333
  124. package/dist/chunk-IE2VPG7O.js +0 -1135
  125. package/dist/chunk-IZ5B5IHQ.js +0 -3656
  126. package/dist/chunk-JAL3CH4G.js +0 -27
  127. package/dist/chunk-KIIEUXD3.js +0 -1764
  128. package/dist/chunk-KXU4NIL7.js +0 -692
  129. package/dist/chunk-MTM5IFCY.js +0 -1190
  130. package/dist/chunk-N7TMSOZH.js +0 -235
  131. package/dist/chunk-NCEBK6PH.js +0 -36
  132. package/dist/chunk-NHJU2ZAL.js +0 -56
  133. package/dist/chunk-P6KTRNVC.js +0 -321
  134. package/dist/chunk-PDO5BLNM.js +0 -22
  135. package/dist/chunk-PDRNLLFT.js +0 -3295
  136. package/dist/chunk-PEQXYSSE.js +0 -45
  137. package/dist/chunk-PKEX2AQX.js +0 -198
  138. package/dist/chunk-PSJCGIGO.js +0 -1163
  139. package/dist/chunk-PZUSUL55.js +0 -506
  140. package/dist/chunk-R45M4TUS.js +0 -37
  141. package/dist/chunk-RC745GGZ.js +0 -122
  142. package/dist/chunk-SP3QKZXJ.js +0 -820
  143. package/dist/chunk-TXKUKMVO.js +0 -417
  144. package/dist/chunk-UE4GPWSD.js +0 -931
  145. package/dist/chunk-UIE3R5XU.js +0 -17
  146. package/dist/chunk-UXPG6ZIN.js +0 -84
  147. package/dist/chunk-VFUK3X5B.js +0 -50
  148. package/dist/chunk-VNMJWREK.js +0 -787
  149. package/dist/chunk-VZ7CSOX2.js +0 -706
  150. package/dist/chunk-WCNQJKFT.js +0 -10
  151. package/dist/chunk-WDZR3QQM.js +0 -135
  152. package/dist/chunk-WLYVJCHV.js +0 -1433
  153. package/dist/chunk-WS7NAFTM.js +0 -1520
  154. package/dist/chunk-X6GDDWQH.js +0 -60
  155. package/dist/chunk-XPDEYNQI.js +0 -102
  156. package/dist/chunk-XRW44VGM.js +0 -58
  157. package/dist/chunk-Y2CM7HXH.js +0 -111
  158. package/dist/chunk-Y7X25LFY.js +0 -15
  159. package/dist/conversation-work-VIOQ5ZF3.js +0 -54
  160. package/dist/db-NGDJV7YH.js +0 -26
  161. package/dist/discovery-DWVDM7UK.js +0 -44
  162. package/dist/experimental-P5FZM4CU.js +0 -12
  163. package/dist/oauth-callback-server-YFY7YEGK.js +0 -243
  164. package/dist/oauth-relay-5XPVRPYB.js +0 -8
  165. package/dist/plugins-YTYJMMJF.js +0 -14
  166. package/dist/runner-ORTNSB2Q.js +0 -522
  167. package/dist/sandbox-egress-signals-FIL7EGPR.js +0 -73
  168. package/dist/sentry-MB3NL3IR.js +0 -42
  169. package/dist/skills-H376WQOH.js +0 -27
  170. package/dist/spawn-T43WHLOS.js +0 -42
  171. package/dist/task-runner-LBZWF32V.js +0 -36
  172. package/dist/validation-REJLRKI6.js +0 -17
  173. package/dist/work-3KJ3RE76.js +0 -51
  174. package/dist/worker-QFEBU72E.js +0 -24
@@ -0,0 +1,509 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
2
+ import { A as createAgentInvocationSchema, M as AgentInvocationLimitError, O as agentBindingSchema, f as PluginCredentialFailureError, j as AgentInvocationBusyError, k as agentInvocationSchema, tt as AuthorizationFlowDisabledError } from "./agent-D4nu8MQV.js";
3
+ import { Ct as getConversationEventStore, Dt as getSqlExecutor, Tt as getConversationStore } from "./agent-hooks-DXHpTJ4m.js";
4
+ import { f as juniorAgentBindings, p as juniorAgentInvocations } from "./executor-BlUhFL7_.js";
5
+ import { B as openConversationProjection, o as failTurnRecord, r as saveTurnCheckpoint, s as getTurnRecord, xt as getTerminalAssistantMessages } from "./checkpoint-CrViJ8Ps.js";
6
+ import { pt as appendAndEnqueueInboundMessage } from "./stats-3YZn-Swi.js";
7
+ import { _ as isTurnInputCommitLostError, h as getConversationTurnBoundaryError, p as TurnInputCommitLostError, s as getAssistantReplyText } from "./pending-auth-CUbXq06G.js";
8
+ import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-CcnwrOcp.js";
9
+ import { n as executeTurn, t as AgentRunError } from "./turn-execution-fI6PZ0iI.js";
10
+ import { n as getPersistedSandboxState, o as persistThreadStateById, r as getPersistedThreadState } from "./thread-state-CqZ1m-es.js";
11
+ import { z } from "zod";
12
+ import { createHash } from "node:crypto";
13
+ import { and, asc, count, eq, inArray } from "drizzle-orm";
14
+ //#region src/chat/agent-invocations/store.ts
15
+ const CREATE_LOCK_PREFIX = "junior:agent_invocation:create";
16
+ const TERMINAL_AGENT_INVOCATION_STATUSES = [
17
+ "blocked",
18
+ "completed",
19
+ "failed"
20
+ ];
21
+ const NON_TERMINAL_AGENT_INVOCATION_STATUSES = [
22
+ "pending",
23
+ "running",
24
+ "awaiting_resume"
25
+ ];
26
+ function stableId(prefix, ...parts) {
27
+ return `${prefix}:${createHash("sha256").update(parts.join("\0")).digest("hex").slice(0, 32)}`;
28
+ }
29
+ /** Return the stable identity for one retry-safe delegated task. */
30
+ function getAgentInvocationId(parentConversationId, idempotencyKey) {
31
+ return stableId("agent-invocation", parentConversationId, idempotencyKey);
32
+ }
33
+ /** Return the stable child identity for one invocation without a named binding. */
34
+ function getUnnamedAgentConversationId(invocationId) {
35
+ return stableId("agent", invocationId);
36
+ }
37
+ /** Return the stable child identity for one named binding. */
38
+ function getNamedAgentConversationId(parentConversationId, name) {
39
+ return stableId("agent", parentConversationId, name);
40
+ }
41
+ /** Return the stable turn identity advanced by one agent invocation. */
42
+ function getAgentInvocationTurnId(invocationId) {
43
+ return `agent-invocation:${invocationId}`;
44
+ }
45
+ /** Return the stable mailbox identity for one agent invocation. */
46
+ function getAgentInvocationMessageId(invocationId) {
47
+ return `agent-invocation:${invocationId}:input`;
48
+ }
49
+ function bindingFromRow(row) {
50
+ return agentBindingSchema.parse({
51
+ childConversationId: row.childConversationId,
52
+ name: row.name,
53
+ parentConversationId: row.parentConversationId
54
+ });
55
+ }
56
+ function invocationFromRow(row) {
57
+ return agentInvocationSchema.parse({
58
+ actor: row.actor,
59
+ ...row.agentName ? { agentName: row.agentName } : void 0,
60
+ childConversationId: row.childConversationId,
61
+ createdAtMs: row.createdAt.getTime(),
62
+ ...row.credentialContext ? { credentialContext: row.credentialContext } : void 0,
63
+ destination: row.destination,
64
+ ...row.errorMessage !== null ? { errorMessage: row.errorMessage } : void 0,
65
+ input: row.input,
66
+ invocationId: row.invocationId,
67
+ mailboxStatus: row.mailboxStatus,
68
+ parentConversationId: row.parentConversationId,
69
+ ...row.reasoningLevel ? { reasoningLevel: row.reasoningLevel } : void 0,
70
+ ...row.result !== null ? { result: row.result } : void 0,
71
+ source: row.source,
72
+ status: row.status,
73
+ ...row.terminalAt ? { terminalAtMs: row.terminalAt.getTime() } : void 0,
74
+ updatedAtMs: row.updatedAt.getTime()
75
+ });
76
+ }
77
+ /** Require every durable creation input to match before replaying one key. */
78
+ function sameCreateInput(invocation, input) {
79
+ return invocation.parentConversationId === input.parentConversationId && invocation.agentName === input.agentName && invocation.input === input.input && invocation.reasoningLevel === input.reasoningLevel && JSON.stringify(invocation.actor) === JSON.stringify(input.actor) && JSON.stringify(invocation.credentialContext) === JSON.stringify(input.credentialContext) && JSON.stringify(invocation.destination) === JSON.stringify(input.destination);
80
+ }
81
+ /** Read one named child binding in its parent-agent scope. */
82
+ async function getAgentBinding(args) {
83
+ const rows = await getSqlExecutor().db().select().from(juniorAgentBindings).where(and(eq(juniorAgentBindings.parentConversationId, args.parentConversationId), eq(juniorAgentBindings.name, args.name)));
84
+ return rows[0] ? bindingFromRow(rows[0]) : void 0;
85
+ }
86
+ /** Read one durable agent invocation. */
87
+ async function getAgentInvocation(invocationId) {
88
+ const rows = await getSqlExecutor().db().select().from(juniorAgentInvocations).where(eq(juniorAgentInvocations.invocationId, invocationId));
89
+ return rows[0] ? invocationFromRow(rows[0]) : void 0;
90
+ }
91
+ /** Resolve the single invocation that may resume for one child conversation. */
92
+ async function getActiveAgentInvocationForConversation(childConversationId) {
93
+ const rows = await getSqlExecutor().db().select().from(juniorAgentInvocations).where(and(eq(juniorAgentInvocations.childConversationId, childConversationId), inArray(juniorAgentInvocations.status, ["running", "awaiting_resume"]))).orderBy(asc(juniorAgentInvocations.createdAt)).limit(2);
94
+ if (rows.length > 1) throw new Error(`Child conversation ${childConversationId} has multiple active agent invocations`);
95
+ return rows[0] ? invocationFromRow(rows[0]) : void 0;
96
+ }
97
+ async function getNonTerminalAgentInvocationForConversation(childConversationId) {
98
+ const rows = await getSqlExecutor().db().select().from(juniorAgentInvocations).where(and(eq(juniorAgentInvocations.childConversationId, childConversationId), inArray(juniorAgentInvocations.status, NON_TERMINAL_AGENT_INVOCATION_STATUSES))).orderBy(asc(juniorAgentInvocations.createdAt)).limit(1);
99
+ return rows[0] ? invocationFromRow(rows[0]) : void 0;
100
+ }
101
+ async function countNonTerminalAgentInvocationsForParent(parentConversationId) {
102
+ return (await getSqlExecutor().db().select({ value: count() }).from(juniorAgentInvocations).where(and(eq(juniorAgentInvocations.parentConversationId, parentConversationId), inArray(juniorAgentInvocations.status, NON_TERMINAL_AGENT_INVOCATION_STATUSES))))[0]?.value ?? 0;
103
+ }
104
+ /**
105
+ * Create or replay one invocation, reusing named child conversations and
106
+ * keeping unnamed child identities scoped to the invocation.
107
+ */
108
+ async function createAgentInvocation(rawInput, nowMs = Date.now()) {
109
+ const input = createAgentInvocationSchema.parse(rawInput);
110
+ const invocationId = getAgentInvocationId(input.parentConversationId, input.idempotencyKey);
111
+ const childConversationId = input.agentName ? getNamedAgentConversationId(input.parentConversationId, input.agentName) : getUnnamedAgentConversationId(invocationId);
112
+ const lockName = `${CREATE_LOCK_PREFIX}:${input.parentConversationId}`;
113
+ return await getSqlExecutor().withLock(lockName, async () => {
114
+ const existing = await getAgentInvocation(invocationId);
115
+ if (existing) {
116
+ if (!sameCreateInput(existing, input)) throw new Error(`Agent invocation idempotency key was reused with different input for ${invocationId}`);
117
+ return existing;
118
+ }
119
+ if (await countNonTerminalAgentInvocationsForParent(input.parentConversationId) >= 8) throw new AgentInvocationLimitError(8);
120
+ await getConversationStore().createChild({
121
+ childConversationId,
122
+ parentConversationId: input.parentConversationId,
123
+ nowMs,
124
+ source: "internal"
125
+ });
126
+ if (input.agentName) {
127
+ await getSqlExecutor().db().insert(juniorAgentBindings).values({
128
+ childConversationId,
129
+ name: input.agentName,
130
+ parentConversationId: input.parentConversationId
131
+ }).onConflictDoNothing();
132
+ const binding = await getAgentBinding({
133
+ name: input.agentName,
134
+ parentConversationId: input.parentConversationId
135
+ });
136
+ if (!binding || binding.childConversationId !== childConversationId) throw new Error(`Named agent binding did not resolve to ${childConversationId}`);
137
+ if (await getNonTerminalAgentInvocationForConversation(childConversationId)) throw new AgentInvocationBusyError(input.agentName);
138
+ }
139
+ await getSqlExecutor().db().insert(juniorAgentInvocations).values({
140
+ invocationId,
141
+ parentConversationId: input.parentConversationId,
142
+ childConversationId,
143
+ agentName: input.agentName ?? null,
144
+ input: input.input,
145
+ actor: input.actor,
146
+ credentialContext: input.credentialContext ?? null,
147
+ source: { kind: "agent_invocation" },
148
+ destination: input.destination,
149
+ reasoningLevel: input.reasoningLevel ?? null,
150
+ status: "pending",
151
+ mailboxStatus: "pending",
152
+ createdAt: new Date(nowMs),
153
+ updatedAt: new Date(nowMs),
154
+ terminalAt: null
155
+ }).onConflictDoNothing();
156
+ const invocation = await getAgentInvocation(invocationId);
157
+ if (!invocation || !sameCreateInput(invocation, input)) throw new Error(`Agent invocation creation raced for ${invocationId}`);
158
+ return invocation;
159
+ });
160
+ }
161
+ /** List bounded invocation records whose mailbox append still needs repair. */
162
+ async function listPendingAgentInvocationMailboxAppends(limit = 100) {
163
+ return (await getSqlExecutor().db().select().from(juniorAgentInvocations).where(eq(juniorAgentInvocations.mailboxStatus, "pending")).orderBy(asc(juniorAgentInvocations.createdAt)).limit(limit)).map(invocationFromRow);
164
+ }
165
+ /** Record that the invocation's idempotent mailbox append completed. */
166
+ async function markAgentInvocationMailboxAppended(invocationId, nowMs = Date.now()) {
167
+ await getSqlExecutor().db().update(juniorAgentInvocations).set({
168
+ mailboxStatus: "appended",
169
+ updatedAt: new Date(nowMs)
170
+ }).where(eq(juniorAgentInvocations.invocationId, invocationId));
171
+ }
172
+ /** Mark one non-terminal invocation as actively executing. */
173
+ async function markAgentInvocationRunning(invocationId, nowMs = Date.now()) {
174
+ await getSqlExecutor().db().update(juniorAgentInvocations).set({
175
+ status: "running",
176
+ updatedAt: new Date(nowMs)
177
+ }).where(and(eq(juniorAgentInvocations.invocationId, invocationId), inArray(juniorAgentInvocations.status, NON_TERMINAL_AGENT_INVOCATION_STATUSES)));
178
+ return await getAgentInvocation(invocationId);
179
+ }
180
+ /** Mark one invocation as waiting for another shared execution slice. */
181
+ async function markAgentInvocationAwaitingResume(invocationId, nowMs = Date.now()) {
182
+ await getSqlExecutor().db().update(juniorAgentInvocations).set({
183
+ status: "awaiting_resume",
184
+ updatedAt: new Date(nowMs)
185
+ }).where(and(eq(juniorAgentInvocations.invocationId, invocationId), inArray(juniorAgentInvocations.status, NON_TERMINAL_AGENT_INVOCATION_STATUSES)));
186
+ }
187
+ /** Persist one terminal invocation result without overwriting an earlier result. */
188
+ async function completeAgentInvocation(args) {
189
+ const nowMs = args.nowMs ?? Date.now();
190
+ await getSqlExecutor().db().update(juniorAgentInvocations).set({
191
+ status: args.status,
192
+ result: args.status === "completed" ? args.result : null,
193
+ errorMessage: args.status === "completed" ? null : args.errorMessage,
194
+ terminalAt: new Date(nowMs),
195
+ updatedAt: new Date(nowMs)
196
+ }).where(and(eq(juniorAgentInvocations.invocationId, args.invocationId), inArray(juniorAgentInvocations.status, NON_TERMINAL_AGENT_INVOCATION_STATUSES)));
197
+ return await getAgentInvocation(args.invocationId);
198
+ }
199
+ /** Return whether an agent invocation has finished. */
200
+ function isTerminalAgentInvocation(invocation) {
201
+ return TERMINAL_AGENT_INVOCATION_STATUSES.includes(invocation.status);
202
+ }
203
+ //#endregion
204
+ //#region src/chat/agent-invocations/work.ts
205
+ var work_exports = /* @__PURE__ */ __exportAll({
206
+ buildAgentInvocationInboundMessage: () => buildAgentInvocationInboundMessage,
207
+ createAgentInvocationWorker: () => createAgentInvocationWorker,
208
+ createAndEnqueueAgentInvocation: () => createAndEnqueueAgentInvocation,
209
+ enqueueAgentInvocation: () => enqueueAgentInvocation,
210
+ resolveAgentInvocationId: () => resolveAgentInvocationId,
211
+ routeAgentInvocationWork: () => routeAgentInvocationWork
212
+ });
213
+ const agentInvocationMailboxMetadataSchema = z.object({
214
+ agentInvocationId: z.string().min(1),
215
+ kind: z.literal("agent_invocation")
216
+ }).strict();
217
+ /** Build destinationless mailbox work that references one durable invocation. */
218
+ function buildAgentInvocationInboundMessage(invocation, nowMs = Date.now()) {
219
+ return {
220
+ conversationId: invocation.childConversationId,
221
+ createdAtMs: invocation.createdAtMs,
222
+ delivery: "defer",
223
+ inboundMessageId: getAgentInvocationMessageId(invocation.invocationId),
224
+ input: {
225
+ authorId: invocation.invocationId,
226
+ text: "[agent invocation]",
227
+ metadata: {
228
+ agentInvocationId: invocation.invocationId,
229
+ kind: "agent_invocation"
230
+ }
231
+ },
232
+ receivedAtMs: nowMs,
233
+ source: "internal"
234
+ };
235
+ }
236
+ /** Append one invocation to its child mailbox and send the normal queue wake. */
237
+ async function enqueueAgentInvocation(invocation, options) {
238
+ if (invocation.mailboxStatus === "appended") return;
239
+ const nowMs = options.nowMs ?? Date.now();
240
+ await appendAndEnqueueInboundMessage({
241
+ message: buildAgentInvocationInboundMessage(invocation, nowMs),
242
+ conversationStore: options.conversationStore,
243
+ nowMs,
244
+ queue: options.queue,
245
+ state: options.state
246
+ });
247
+ await markAgentInvocationMailboxAppended(invocation.invocationId, nowMs);
248
+ }
249
+ /** Create or replay an invocation, then durably schedule its child work. */
250
+ async function createAndEnqueueAgentInvocation(input, options) {
251
+ const invocation = await createAgentInvocation(input, options.nowMs);
252
+ await enqueueAgentInvocation(invocation, options);
253
+ return await getAgentInvocation(invocation.invocationId) ?? invocation;
254
+ }
255
+ /** Require one invocation metadata reference for one leased mailbox attempt. */
256
+ function invocationIdFromMessages(messages) {
257
+ if (messages.length === 0) return;
258
+ const parsed = messages.map((message) => agentInvocationMailboxMetadataSchema.safeParse(message.input.metadata));
259
+ if (parsed.every((result) => !result.success)) return;
260
+ if (parsed.some((result) => !result.success)) throw new Error("Conversation mailbox mixes agent invocation and other input");
261
+ const invocationIds = new Set(parsed.map((result) => {
262
+ if (!result.success) throw new Error("Agent invocation mailbox metadata failed validation");
263
+ return result.data.agentInvocationId;
264
+ }));
265
+ if (invocationIds.size !== 1) throw new Error("Conversation mailbox contains multiple agent invocations in one attempt");
266
+ return invocationIds.values().next().value;
267
+ }
268
+ /** Resolve invocation execution from mailbox input or durable active state. */
269
+ async function resolveAgentInvocationId(context) {
270
+ const mailboxInvocationId = invocationIdFromMessages(context.attempt.messages);
271
+ if (mailboxInvocationId) return mailboxInvocationId;
272
+ if (context.attempt.messages.length > 0) return;
273
+ return (await getActiveAgentInvocationForConversation(context.conversationId))?.invocationId;
274
+ }
275
+ /** Project the terminal invocation into the idempotent turn lifecycle. */
276
+ async function persistTerminalLifecycle(invocation) {
277
+ const lifecycle = new ConversationTurnLifecycleService(getConversationEventStore());
278
+ const common = {
279
+ conversationId: invocation.childConversationId,
280
+ createdAtMs: "terminalAtMs" in invocation ? invocation.terminalAtMs : invocation.updatedAtMs,
281
+ turnId: getAgentInvocationTurnId(invocation.invocationId)
282
+ };
283
+ if (invocation.status === "completed") await lifecycle.complete({
284
+ ...common,
285
+ outcome: invocation.result?.trim() ? "success" : "no_reply"
286
+ });
287
+ else if (invocation.status === "blocked" || invocation.status === "failed") await lifecycle.fail({
288
+ ...common,
289
+ failureCode: "model_execution_failed"
290
+ });
291
+ }
292
+ /** Stop an invocation whose worker died, or project its terminal turn result. */
293
+ async function projectTerminalTurn(invocation) {
294
+ let turn = await getTurnRecord(invocation.childConversationId, getAgentInvocationTurnId(invocation.invocationId));
295
+ if (!turn) return;
296
+ if (turn.state === "running") {
297
+ turn = await failTurnRecord({
298
+ conversationId: turn.conversationId,
299
+ expectedVersion: turn.version,
300
+ turnId: turn.turnId,
301
+ errorMessage: "Agent invocation lost its worker before it could pause"
302
+ });
303
+ if (!turn) return;
304
+ }
305
+ if (turn.state === "paused") return;
306
+ const result = getTerminalAssistantMessages(turn.piMessages).map(getAssistantReplyText).filter((text) => text !== void 0).join("\n\n");
307
+ const failed = turn.state !== "completed" || Boolean(turn.errorMessage);
308
+ return await completeAgentInvocation({
309
+ invocationId: invocation.invocationId,
310
+ ...failed ? {
311
+ errorMessage: turn.errorMessage ?? "Agent invocation failed",
312
+ status: "failed"
313
+ } : {
314
+ result,
315
+ status: "completed"
316
+ }
317
+ });
318
+ }
319
+ /** Classify authorization failures that terminally block background work. */
320
+ function blockingInvocationError(error) {
321
+ const cause = getConversationTurnBoundaryError(error)?.cause ?? error;
322
+ return cause instanceof AuthorizationFlowDisabledError || cause instanceof PluginCredentialFailureError ? cause : void 0;
323
+ }
324
+ function isInvocationInputCommitLost(error) {
325
+ const cause = getConversationTurnBoundaryError(error)?.cause ?? error;
326
+ return isTurnInputCommitLostError(cause);
327
+ }
328
+ /** Save one completed agent result on its child agent invocation. */
329
+ async function saveAgentInvocationResult(args) {
330
+ const failed = args.result.diagnostics.outcome !== "success";
331
+ await persistThreadStateById(args.invocation.childConversationId, { sandboxRef: args.result.sandboxRef ?? args.sandboxRef });
332
+ if (args.result.piMessages?.length) await saveTurnCheckpoint({
333
+ mode: "completed",
334
+ conversationId: args.invocation.childConversationId,
335
+ turnId: args.turnId,
336
+ durationMs: args.result.diagnostics.durationMs,
337
+ usage: args.result.diagnostics.usage,
338
+ destination: args.invocation.destination,
339
+ ...failed ? { errorMessage: args.result.diagnostics.errorMessage ?? "Agent invocation failed" } : void 0,
340
+ messages: args.result.piMessages,
341
+ actor: args.invocation.actor,
342
+ source: args.invocation.source,
343
+ surface: "internal"
344
+ });
345
+ const terminal = await completeAgentInvocation({
346
+ invocationId: args.invocation.invocationId,
347
+ ...failed ? {
348
+ errorMessage: args.result.diagnostics.errorMessage ?? "Agent invocation failed",
349
+ status: "failed"
350
+ } : {
351
+ result: args.result.text,
352
+ status: "completed"
353
+ }
354
+ });
355
+ if (!terminal || !isTerminalAgentInvocation(terminal)) throw new Error(`Agent invocation did not finish for ${args.invocation.invocationId}`);
356
+ return terminal.status === "completed" ? {
357
+ finishedAtMs: terminal.terminalAtMs,
358
+ outcome: terminal.result.trim() ? "success" : "no_reply"
359
+ } : {
360
+ finishedAtMs: terminal.terminalAtMs,
361
+ failureCode: "model_execution_failed",
362
+ outcome: "failed"
363
+ };
364
+ }
365
+ /** Build the invocation consumer that advances work through the shared runner. */
366
+ function createAgentInvocationWorker(agentRunner) {
367
+ return async (context, invocationId) => {
368
+ let invocation = await getAgentInvocation(invocationId);
369
+ if (!invocation) throw new Error(`Agent invocation is missing for ${invocationId}`);
370
+ let acknowledged = context.attempt.messages.length === 0;
371
+ const acknowledge = async () => {
372
+ if (acknowledged) return;
373
+ try {
374
+ await context.attempt.ack();
375
+ } catch {
376
+ throw new TurnInputCommitLostError(`Conversation work lease lost before invocation inbox ack for ${context.conversationId}`);
377
+ }
378
+ acknowledged = true;
379
+ };
380
+ const turnId = getAgentInvocationTurnId(invocation.invocationId);
381
+ const lifecycle = new ConversationTurnLifecycleService(getConversationEventStore());
382
+ let sandboxRef;
383
+ let history;
384
+ let location;
385
+ try {
386
+ if (invocation.childConversationId !== context.conversationId) throw new Error(`Agent invocation ${invocationId} belongs to ${invocation.childConversationId}, not ${context.conversationId}`);
387
+ if (context.destination) throw new Error(`Agent invocation conversation ${context.conversationId} must not own a provider destination`);
388
+ if (isTerminalAgentInvocation(invocation)) {
389
+ await persistTerminalLifecycle(invocation);
390
+ await acknowledge();
391
+ return { status: "completed" };
392
+ }
393
+ const projected = await projectTerminalTurn(invocation);
394
+ if (projected && isTerminalAgentInvocation(projected)) {
395
+ await persistTerminalLifecycle(projected);
396
+ await acknowledge();
397
+ return { status: "completed" };
398
+ }
399
+ invocation = await markAgentInvocationRunning(invocation.invocationId) ?? invocation;
400
+ await lifecycle.start({
401
+ conversationId: invocation.childConversationId,
402
+ createdAtMs: invocation.createdAtMs,
403
+ inputMessageIds: [getAgentInvocationMessageId(invocation.invocationId)],
404
+ surface: "internal",
405
+ turnId
406
+ });
407
+ const [persisted, projection] = await Promise.all([getPersistedThreadState(invocation.childConversationId), openConversationProjection({ conversationId: invocation.childConversationId })]);
408
+ sandboxRef = getPersistedSandboxState(persisted);
409
+ history = projection.messages;
410
+ location = (await getConversationStore().get({ conversationId: invocation.parentConversationId }))?.location;
411
+ } catch (error) {
412
+ if (isInvocationInputCommitLost(error)) return { status: "lost_lease" };
413
+ if (!context.attempt.isFinalAttempt) throw error;
414
+ const terminal = await completeAgentInvocation({
415
+ invocationId: invocation.invocationId,
416
+ errorMessage: error instanceof Error ? error.message : "Agent invocation failed",
417
+ status: "failed"
418
+ });
419
+ if (terminal) await persistTerminalLifecycle(terminal);
420
+ await acknowledge();
421
+ return { status: "completed" };
422
+ }
423
+ let outcome;
424
+ try {
425
+ outcome = await executeTurn(agentRunner, {
426
+ conversationId: invocation.childConversationId,
427
+ turnId,
428
+ runId: invocation.invocationId,
429
+ instruction: { text: invocation.input },
430
+ history,
431
+ actor: invocation.actor,
432
+ credentialContext: invocation.credentialContext,
433
+ destination: invocation.destination,
434
+ source: invocation.source,
435
+ ...location ? { location } : void 0,
436
+ surface: "internal",
437
+ disabledFeatures: [
438
+ "handoff",
439
+ "interactive-auth",
440
+ "subagents"
441
+ ],
442
+ reasoning: invocation.reasoningLevel,
443
+ state: { sandboxRef },
444
+ durability: {
445
+ onInputCommitted: acknowledge,
446
+ shouldYield: context.shouldYield,
447
+ onSandboxRefChanged: async (nextSandboxRef) => {
448
+ sandboxRef = nextSandboxRef;
449
+ await persistThreadStateById(invocation.childConversationId, { sandboxRef });
450
+ }
451
+ }
452
+ }, async (result) => await saveAgentInvocationResult({
453
+ invocation,
454
+ result,
455
+ sandboxRef,
456
+ turnId
457
+ }));
458
+ } catch (error) {
459
+ if (!(error instanceof AgentRunError)) throw error;
460
+ const runError = error.cause;
461
+ if (isInvocationInputCommitLost(runError)) return { status: "lost_lease" };
462
+ const blocking = blockingInvocationError(runError);
463
+ if (blocking) {
464
+ const terminal = await completeAgentInvocation({
465
+ invocationId: invocation.invocationId,
466
+ errorMessage: blocking.message,
467
+ status: "blocked"
468
+ });
469
+ if (terminal) await persistTerminalLifecycle(terminal);
470
+ await acknowledge();
471
+ return { status: "completed" };
472
+ }
473
+ if (!context.attempt.isFinalAttempt) throw runError;
474
+ const terminal = await completeAgentInvocation({
475
+ invocationId: invocation.invocationId,
476
+ errorMessage: runError instanceof Error ? runError.message : "Agent invocation failed",
477
+ status: "failed"
478
+ });
479
+ if (terminal) await persistTerminalLifecycle(terminal);
480
+ await acknowledge();
481
+ return { status: "completed" };
482
+ }
483
+ if (outcome.status === "suspended") {
484
+ await markAgentInvocationAwaitingResume(invocation.invocationId);
485
+ return { status: "yielded" };
486
+ }
487
+ if (outcome.status === "awaiting_auth") {
488
+ const terminal = await completeAgentInvocation({
489
+ invocationId: invocation.invocationId,
490
+ errorMessage: `Agent invocation requires ${outcome.providerDisplayName} authorization`,
491
+ status: "blocked"
492
+ });
493
+ if (terminal) await persistTerminalLifecycle(terminal);
494
+ await acknowledge();
495
+ return { status: "completed" };
496
+ }
497
+ await acknowledge();
498
+ return { status: "completed" };
499
+ };
500
+ }
501
+ /** Route invocation-backed work before falling through to existing consumers. */
502
+ function routeAgentInvocationWork(options) {
503
+ return async (context) => {
504
+ const invocationId = await resolveAgentInvocationId(context);
505
+ return invocationId ? await options.invocationWorker(context, invocationId) : await options.fallbackWorker(context);
506
+ };
507
+ }
508
+ //#endregion
509
+ export { work_exports as a, resolveAgentInvocationId as i, createAndEnqueueAgentInvocation as n, listPendingAgentInvocationMailboxAppends as o, enqueueAgentInvocation as r, createAgentInvocationWorker as t };