@sentry/junior 0.202.0 → 0.204.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-CMyTD4DD.js +17509 -0
  2. package/dist/agent-hooks-Bbcp9e33.js +4040 -0
  3. package/dist/agent-runner-DNb1A49M.js +678 -0
  4. package/dist/api/schema.d.ts +2728 -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-B1TOqBI8.d.ts +246 -0
  9. package/dist/app.d.ts +4 -520
  10. package/dist/app.js +9522 -11875
  11. package/dist/auth-pause-state-DosEalIG.js +168 -0
  12. package/dist/catalog-runtime-BReos-D4.js +7 -0
  13. package/dist/checkpoint-CNrPyRJN.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-nGCW1OTG.js +941 -0
  33. package/dist/context-B45_WqVX.js +298 -0
  34. package/dist/conversation-privacy-B4voFRSm.js +182 -0
  35. package/dist/conversation-work-C6y3T5Hx.js +51 -0
  36. package/dist/credential-sync-kXr1hvO1.js +2660 -0
  37. package/dist/db-BeyXKJOI.d.ts +5 -0
  38. package/dist/destinations-BeBiJeEM.js +29 -0
  39. package/dist/execution-stats-DWfSihcH.js +373 -0
  40. package/dist/executor-DcMSlI5c.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-Drn_LXlM.js +63 -0
  47. package/dist/logging-BzAk1S_s.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-JiftokvA.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-CWmSdZVg.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-CrT5nXbw.js +861 -0
  60. package/dist/registry-DH1xUo2N.js +1419 -0
  61. package/dist/reporting-schema-DosTN__Q.js +105 -0
  62. package/dist/resolve-CZHnfxaS.js +546 -0
  63. package/dist/rolldown-runtime-B4FMCO8f.js +28 -0
  64. package/dist/runner-CZV2sC46.js +392 -0
  65. package/dist/sandbox-egress-signals-bHZfmhbd.js +46 -0
  66. package/dist/schema-Rn8-XEaN.js +1140 -0
  67. package/dist/sentry-CD3SdJl-.js +26 -0
  68. package/dist/skills-CIcDQSgM.js +316 -0
  69. package/dist/spawn-DdkUFRmq.js +29 -0
  70. package/dist/stats-DTUbAb88.js +2634 -0
  71. package/dist/store-C5qxF2ac.d.ts +208 -0
  72. package/dist/task-queue-CJIR4RF7.js +136 -0
  73. package/dist/task-runner-D-O3A-Cp.js +639 -0
  74. package/dist/thread-state-CRc9jTJS.js +431 -0
  75. package/dist/turn-execution-BkinIdJF.js +47 -0
  76. package/dist/turn-lifecycle-DQV19VTW.js +54 -0
  77. package/dist/usage-D3EbSO7w.js +296 -0
  78. package/dist/usage-schema-CKaDkH_j.js +20 -0
  79. package/dist/validation-C2CR-OX3.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-DxcWdoKa.js +8 -0
  85. package/dist/version.d.ts +2 -4
  86. package/dist/version.js +2 -6
  87. package/dist/web-authorization-RMBxAR_t.js +76 -0
  88. package/dist/web-input-3EPfpf55.js +494 -0
  89. package/dist/work-fGofI7Op.js +509 -0
  90. package/dist/worker-CsOLq-mR.js +625 -0
  91. package/package.json +9 -9
  92. package/dist/agent-hooks-UXITLYOK.js +0 -51
  93. package/dist/catalog-runtime-BG3JLLK2.js +0 -14
  94. package/dist/chunk-2LYHWMR4.js +0 -46
  95. package/dist/chunk-2MK3QBGA.js +0 -321
  96. package/dist/chunk-3PGQSKJV.js +0 -692
  97. package/dist/chunk-3UI3WFTX.js +0 -519
  98. package/dist/chunk-3Y47VMHV.js +0 -6
  99. package/dist/chunk-4UO6FK4G.js +0 -64
  100. package/dist/chunk-5NOPO64K.js +0 -198
  101. package/dist/chunk-5PKWYPFT.js +0 -2943
  102. package/dist/chunk-63NKKFJL.js +0 -1228
  103. package/dist/chunk-6AYH6252.js +0 -787
  104. package/dist/chunk-6Y5B5PEX.js +0 -80
  105. package/dist/chunk-7DHZP5KJ.js +0 -333
  106. package/dist/chunk-7H2VZTWN.js +0 -103
  107. package/dist/chunk-7NL7T6VU.js +0 -406
  108. package/dist/chunk-A76OIMYN.js +0 -102
  109. package/dist/chunk-AWMS3SPP.js +0 -58
  110. package/dist/chunk-B3LY5RCL.js +0 -229
  111. package/dist/chunk-BD2KT3OB.js +0 -36
  112. package/dist/chunk-BXCX5QKA.js +0 -2086
  113. package/dist/chunk-C6VVF43U.js +0 -81
  114. package/dist/chunk-CEMMLV5L.js +0 -98
  115. package/dist/chunk-CM5HNV2W.js +0 -131
  116. package/dist/chunk-DA2KGZZI.js +0 -13
  117. package/dist/chunk-DBVY6HLX.js +0 -64
  118. package/dist/chunk-DIB4GX3G.js +0 -8
  119. package/dist/chunk-DKIJ2RP5.js +0 -68
  120. package/dist/chunk-DL2KLKVH.js +0 -931
  121. package/dist/chunk-DWPN6SCH.js +0 -172
  122. package/dist/chunk-ELWOYVOY.js +0 -206
  123. package/dist/chunk-EWT7H65X.js +0 -506
  124. package/dist/chunk-FA6POGLH.js +0 -70
  125. package/dist/chunk-HMREVIO2.js +0 -135
  126. package/dist/chunk-IIWUT4FO.js +0 -820
  127. package/dist/chunk-JAL3CH4G.js +0 -27
  128. package/dist/chunk-JSJQEWBJ.js +0 -3295
  129. package/dist/chunk-KHKKHDLD.js +0 -387
  130. package/dist/chunk-LA6R4A7Q.js +0 -706
  131. package/dist/chunk-LOOU2DUR.js +0 -20428
  132. package/dist/chunk-M6FHWXE3.js +0 -700
  133. package/dist/chunk-M76HMB7M.js +0 -1856
  134. package/dist/chunk-MAGNK5J4.js +0 -1520
  135. package/dist/chunk-MTM5IFCY.js +0 -1190
  136. package/dist/chunk-N7TMSOZH.js +0 -235
  137. package/dist/chunk-NHJU2ZAL.js +0 -56
  138. package/dist/chunk-NSXKRGRT.js +0 -717
  139. package/dist/chunk-OWMPFXJA.js +0 -1764
  140. package/dist/chunk-PDO5BLNM.js +0 -22
  141. package/dist/chunk-PEQXYSSE.js +0 -45
  142. package/dist/chunk-PW4P4JYF.js +0 -1135
  143. package/dist/chunk-QB54UQUS.js +0 -320
  144. package/dist/chunk-QP3OGJXF.js +0 -105
  145. package/dist/chunk-RC745GGZ.js +0 -122
  146. package/dist/chunk-REOIRYPR.js +0 -37
  147. package/dist/chunk-SCOZRLZ4.js +0 -164
  148. package/dist/chunk-TXJSXBV5.js +0 -1433
  149. package/dist/chunk-TXKUKMVO.js +0 -417
  150. package/dist/chunk-U2GPUYAL.js +0 -3656
  151. package/dist/chunk-UIE3R5XU.js +0 -17
  152. package/dist/chunk-UXPG6ZIN.js +0 -84
  153. package/dist/chunk-VFUK3X5B.js +0 -50
  154. package/dist/chunk-WQSHDTTI.js +0 -1163
  155. package/dist/chunk-X6GDDWQH.js +0 -60
  156. package/dist/chunk-Y2CM7HXH.js +0 -111
  157. package/dist/chunk-Y7X25LFY.js +0 -15
  158. package/dist/chunk-YDUR3ZYW.js +0 -10
  159. package/dist/conversation-work-VIOQ5ZF3.js +0 -54
  160. package/dist/db-3L2MCVRI.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-YVV6C6T2.js +0 -243
  164. package/dist/oauth-relay-5XPVRPYB.js +0 -8
  165. package/dist/plugins-YTYJMMJF.js +0 -14
  166. package/dist/runner-LQ7RETDP.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-XRWYEDCD.js +0 -27
  170. package/dist/spawn-RC6SJUAI.js +0 -42
  171. package/dist/task-runner-7DY7ARYH.js +0 -36
  172. package/dist/validation-7MNQGCJA.js +0 -17
  173. package/dist/work-COALHUCG.js +0 -51
  174. package/dist/worker-6MURZIPD.js +0 -24
@@ -1,692 +0,0 @@
1
- import {
2
- AgentRunError,
3
- executeTurn
4
- } from "./chunk-AWMS3SPP.js";
5
- import {
6
- ConversationTurnLifecycleService
7
- } from "./chunk-DBVY6HLX.js";
8
- import {
9
- getPersistedSandboxState,
10
- getPersistedThreadState,
11
- persistThreadStateById
12
- } from "./chunk-3UI3WFTX.js";
13
- import {
14
- AgentInvocationBusyError,
15
- AgentInvocationLimitError,
16
- AuthorizationFlowDisabledError,
17
- PluginCredentialFailureError,
18
- agentBindingSchema,
19
- agentInvocationSchema,
20
- createAgentInvocationSchema
21
- } from "./chunk-QB54UQUS.js";
22
- import {
23
- TurnInputCommitLostError,
24
- getAssistantReplyText,
25
- getConversationTurnBoundaryError,
26
- isTurnInputCommitLostError
27
- } from "./chunk-ELWOYVOY.js";
28
- import {
29
- failTurnRecord,
30
- getTerminalAssistantMessages,
31
- getTurnRecord,
32
- openConversationProjection,
33
- saveTurnCheckpoint
34
- } from "./chunk-5PKWYPFT.js";
35
- import {
36
- appendAndEnqueueInboundMessage
37
- } from "./chunk-OWMPFXJA.js";
38
- import {
39
- getConversationEventStore,
40
- getConversationStore,
41
- getSqlExecutor
42
- } from "./chunk-M76HMB7M.js";
43
- import {
44
- juniorAgentBindings,
45
- juniorAgentInvocations
46
- } from "./chunk-PW4P4JYF.js";
47
-
48
- // src/chat/agent-invocations/work.ts
49
- import { z } from "zod";
50
-
51
- // src/chat/agent-invocations/store.ts
52
- import { createHash } from "crypto";
53
- import { and, asc, count, eq, inArray } from "drizzle-orm";
54
- var CREATE_LOCK_PREFIX = "junior:agent_invocation:create";
55
- var MAX_ACTIVE_AGENT_INVOCATIONS_PER_PARENT = 8;
56
- var TERMINAL_AGENT_INVOCATION_STATUSES = [
57
- "blocked",
58
- "completed",
59
- "failed"
60
- ];
61
- var NON_TERMINAL_AGENT_INVOCATION_STATUSES = [
62
- "pending",
63
- "running",
64
- "awaiting_resume"
65
- ];
66
- function stableId(prefix, ...parts) {
67
- const digest = createHash("sha256").update(parts.join("\0")).digest("hex").slice(0, 32);
68
- return `${prefix}:${digest}`;
69
- }
70
- function getAgentInvocationId(parentConversationId, idempotencyKey) {
71
- return stableId("agent-invocation", parentConversationId, idempotencyKey);
72
- }
73
- function getUnnamedAgentConversationId(invocationId) {
74
- return stableId("agent", invocationId);
75
- }
76
- function getNamedAgentConversationId(parentConversationId, name) {
77
- return stableId("agent", parentConversationId, name);
78
- }
79
- function getAgentInvocationTurnId(invocationId) {
80
- return `agent-invocation:${invocationId}`;
81
- }
82
- function getAgentInvocationMessageId(invocationId) {
83
- return `agent-invocation:${invocationId}:input`;
84
- }
85
- function bindingFromRow(row) {
86
- return agentBindingSchema.parse({
87
- childConversationId: row.childConversationId,
88
- name: row.name,
89
- parentConversationId: row.parentConversationId
90
- });
91
- }
92
- function invocationFromRow(row) {
93
- return agentInvocationSchema.parse({
94
- actor: row.actor,
95
- ...row.agentName ? { agentName: row.agentName } : void 0,
96
- childConversationId: row.childConversationId,
97
- createdAtMs: row.createdAt.getTime(),
98
- ...row.credentialContext ? { credentialContext: row.credentialContext } : void 0,
99
- destination: row.destination,
100
- ...row.errorMessage !== null ? { errorMessage: row.errorMessage } : void 0,
101
- input: row.input,
102
- invocationId: row.invocationId,
103
- mailboxStatus: row.mailboxStatus,
104
- parentConversationId: row.parentConversationId,
105
- ...row.reasoningLevel ? { reasoningLevel: row.reasoningLevel } : void 0,
106
- ...row.result !== null ? { result: row.result } : void 0,
107
- source: row.source,
108
- status: row.status,
109
- ...row.terminalAt ? { terminalAtMs: row.terminalAt.getTime() } : void 0,
110
- updatedAtMs: row.updatedAt.getTime()
111
- });
112
- }
113
- function sameCreateInput(invocation, input) {
114
- 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);
115
- }
116
- async function getAgentBinding(args) {
117
- const rows = await getSqlExecutor().db().select().from(juniorAgentBindings).where(
118
- and(
119
- eq(juniorAgentBindings.parentConversationId, args.parentConversationId),
120
- eq(juniorAgentBindings.name, args.name)
121
- )
122
- );
123
- return rows[0] ? bindingFromRow(rows[0]) : void 0;
124
- }
125
- async function getAgentInvocation(invocationId) {
126
- const rows = await getSqlExecutor().db().select().from(juniorAgentInvocations).where(eq(juniorAgentInvocations.invocationId, invocationId));
127
- return rows[0] ? invocationFromRow(rows[0]) : void 0;
128
- }
129
- async function getActiveAgentInvocationForConversation(childConversationId) {
130
- const rows = await getSqlExecutor().db().select().from(juniorAgentInvocations).where(
131
- and(
132
- eq(juniorAgentInvocations.childConversationId, childConversationId),
133
- inArray(juniorAgentInvocations.status, ["running", "awaiting_resume"])
134
- )
135
- ).orderBy(asc(juniorAgentInvocations.createdAt)).limit(2);
136
- if (rows.length > 1) {
137
- throw new Error(
138
- `Child conversation ${childConversationId} has multiple active agent invocations`
139
- );
140
- }
141
- return rows[0] ? invocationFromRow(rows[0]) : void 0;
142
- }
143
- async function getNonTerminalAgentInvocationForConversation(childConversationId) {
144
- const rows = await getSqlExecutor().db().select().from(juniorAgentInvocations).where(
145
- and(
146
- eq(juniorAgentInvocations.childConversationId, childConversationId),
147
- inArray(
148
- juniorAgentInvocations.status,
149
- NON_TERMINAL_AGENT_INVOCATION_STATUSES
150
- )
151
- )
152
- ).orderBy(asc(juniorAgentInvocations.createdAt)).limit(1);
153
- return rows[0] ? invocationFromRow(rows[0]) : void 0;
154
- }
155
- async function countNonTerminalAgentInvocationsForParent(parentConversationId) {
156
- const rows = await getSqlExecutor().db().select({ value: count() }).from(juniorAgentInvocations).where(
157
- and(
158
- eq(juniorAgentInvocations.parentConversationId, parentConversationId),
159
- inArray(
160
- juniorAgentInvocations.status,
161
- NON_TERMINAL_AGENT_INVOCATION_STATUSES
162
- )
163
- )
164
- );
165
- return rows[0]?.value ?? 0;
166
- }
167
- async function createAgentInvocation(rawInput, nowMs = Date.now()) {
168
- const input = createAgentInvocationSchema.parse(rawInput);
169
- const invocationId = getAgentInvocationId(
170
- input.parentConversationId,
171
- input.idempotencyKey
172
- );
173
- const childConversationId = input.agentName ? getNamedAgentConversationId(input.parentConversationId, input.agentName) : getUnnamedAgentConversationId(invocationId);
174
- const lockName = `${CREATE_LOCK_PREFIX}:${input.parentConversationId}`;
175
- return await getSqlExecutor().withLock(lockName, async () => {
176
- const existing = await getAgentInvocation(invocationId);
177
- if (existing) {
178
- if (!sameCreateInput(existing, input)) {
179
- throw new Error(
180
- `Agent invocation idempotency key was reused with different input for ${invocationId}`
181
- );
182
- }
183
- return existing;
184
- }
185
- const activeCount = await countNonTerminalAgentInvocationsForParent(
186
- input.parentConversationId
187
- );
188
- if (activeCount >= MAX_ACTIVE_AGENT_INVOCATIONS_PER_PARENT) {
189
- throw new AgentInvocationLimitError(
190
- MAX_ACTIVE_AGENT_INVOCATIONS_PER_PARENT
191
- );
192
- }
193
- await getConversationStore().createChild({
194
- childConversationId,
195
- parentConversationId: input.parentConversationId,
196
- nowMs,
197
- source: "internal"
198
- });
199
- if (input.agentName) {
200
- await getSqlExecutor().db().insert(juniorAgentBindings).values({
201
- childConversationId,
202
- name: input.agentName,
203
- parentConversationId: input.parentConversationId
204
- }).onConflictDoNothing();
205
- const binding = await getAgentBinding({
206
- name: input.agentName,
207
- parentConversationId: input.parentConversationId
208
- });
209
- if (!binding || binding.childConversationId !== childConversationId) {
210
- throw new Error(
211
- `Named agent binding did not resolve to ${childConversationId}`
212
- );
213
- }
214
- if (await getNonTerminalAgentInvocationForConversation(childConversationId)) {
215
- throw new AgentInvocationBusyError(input.agentName);
216
- }
217
- }
218
- await getSqlExecutor().db().insert(juniorAgentInvocations).values({
219
- invocationId,
220
- parentConversationId: input.parentConversationId,
221
- childConversationId,
222
- agentName: input.agentName ?? null,
223
- input: input.input,
224
- actor: input.actor,
225
- credentialContext: input.credentialContext ?? null,
226
- source: { kind: "agent_invocation" },
227
- destination: input.destination,
228
- reasoningLevel: input.reasoningLevel ?? null,
229
- status: "pending",
230
- mailboxStatus: "pending",
231
- createdAt: new Date(nowMs),
232
- updatedAt: new Date(nowMs),
233
- terminalAt: null
234
- }).onConflictDoNothing();
235
- const invocation = await getAgentInvocation(invocationId);
236
- if (!invocation || !sameCreateInput(invocation, input)) {
237
- throw new Error(`Agent invocation creation raced for ${invocationId}`);
238
- }
239
- return invocation;
240
- });
241
- }
242
- async function listPendingAgentInvocationMailboxAppends(limit = 100) {
243
- const rows = await getSqlExecutor().db().select().from(juniorAgentInvocations).where(eq(juniorAgentInvocations.mailboxStatus, "pending")).orderBy(asc(juniorAgentInvocations.createdAt)).limit(limit);
244
- return rows.map(invocationFromRow);
245
- }
246
- async function markAgentInvocationMailboxAppended(invocationId, nowMs = Date.now()) {
247
- await getSqlExecutor().db().update(juniorAgentInvocations).set({ mailboxStatus: "appended", updatedAt: new Date(nowMs) }).where(eq(juniorAgentInvocations.invocationId, invocationId));
248
- }
249
- async function markAgentInvocationRunning(invocationId, nowMs = Date.now()) {
250
- await getSqlExecutor().db().update(juniorAgentInvocations).set({ status: "running", updatedAt: new Date(nowMs) }).where(
251
- and(
252
- eq(juniorAgentInvocations.invocationId, invocationId),
253
- inArray(
254
- juniorAgentInvocations.status,
255
- NON_TERMINAL_AGENT_INVOCATION_STATUSES
256
- )
257
- )
258
- );
259
- return await getAgentInvocation(invocationId);
260
- }
261
- async function markAgentInvocationAwaitingResume(invocationId, nowMs = Date.now()) {
262
- await getSqlExecutor().db().update(juniorAgentInvocations).set({ status: "awaiting_resume", updatedAt: new Date(nowMs) }).where(
263
- and(
264
- eq(juniorAgentInvocations.invocationId, invocationId),
265
- inArray(
266
- juniorAgentInvocations.status,
267
- NON_TERMINAL_AGENT_INVOCATION_STATUSES
268
- )
269
- )
270
- );
271
- }
272
- async function completeAgentInvocation(args) {
273
- const nowMs = args.nowMs ?? Date.now();
274
- await getSqlExecutor().db().update(juniorAgentInvocations).set({
275
- status: args.status,
276
- result: args.status === "completed" ? args.result : null,
277
- errorMessage: args.status === "completed" ? null : args.errorMessage,
278
- terminalAt: new Date(nowMs),
279
- updatedAt: new Date(nowMs)
280
- }).where(
281
- and(
282
- eq(juniorAgentInvocations.invocationId, args.invocationId),
283
- inArray(
284
- juniorAgentInvocations.status,
285
- NON_TERMINAL_AGENT_INVOCATION_STATUSES
286
- )
287
- )
288
- );
289
- return await getAgentInvocation(args.invocationId);
290
- }
291
- function isTerminalAgentInvocation(invocation) {
292
- return TERMINAL_AGENT_INVOCATION_STATUSES.includes(
293
- invocation.status
294
- );
295
- }
296
-
297
- // src/chat/agent-invocations/work.ts
298
- var agentInvocationMailboxMetadataSchema = z.object({
299
- agentInvocationId: z.string().min(1),
300
- kind: z.literal("agent_invocation")
301
- }).strict();
302
- function buildAgentInvocationInboundMessage(invocation, nowMs = Date.now()) {
303
- return {
304
- conversationId: invocation.childConversationId,
305
- createdAtMs: invocation.createdAtMs,
306
- delivery: "defer",
307
- inboundMessageId: getAgentInvocationMessageId(invocation.invocationId),
308
- input: {
309
- authorId: invocation.invocationId,
310
- text: "[agent invocation]",
311
- metadata: {
312
- agentInvocationId: invocation.invocationId,
313
- kind: "agent_invocation"
314
- }
315
- },
316
- receivedAtMs: nowMs,
317
- source: "internal"
318
- };
319
- }
320
- async function enqueueAgentInvocation(invocation, options) {
321
- if (invocation.mailboxStatus === "appended") {
322
- return;
323
- }
324
- const nowMs = options.nowMs ?? Date.now();
325
- await appendAndEnqueueInboundMessage({
326
- message: buildAgentInvocationInboundMessage(invocation, nowMs),
327
- conversationStore: options.conversationStore,
328
- nowMs,
329
- queue: options.queue,
330
- state: options.state
331
- });
332
- await markAgentInvocationMailboxAppended(invocation.invocationId, nowMs);
333
- }
334
- async function createAndEnqueueAgentInvocation(input, options) {
335
- const invocation = await createAgentInvocation(input, options.nowMs);
336
- await enqueueAgentInvocation(invocation, options);
337
- return await getAgentInvocation(invocation.invocationId) ?? invocation;
338
- }
339
- function invocationIdFromMessages(messages) {
340
- if (messages.length === 0) {
341
- return void 0;
342
- }
343
- const parsed = messages.map(
344
- (message) => agentInvocationMailboxMetadataSchema.safeParse(message.input.metadata)
345
- );
346
- if (parsed.every((result) => !result.success)) {
347
- return void 0;
348
- }
349
- if (parsed.some((result) => !result.success)) {
350
- throw new Error(
351
- "Conversation mailbox mixes agent invocation and other input"
352
- );
353
- }
354
- const invocationIds = new Set(
355
- parsed.map((result) => {
356
- if (!result.success) {
357
- throw new Error("Agent invocation mailbox metadata failed validation");
358
- }
359
- return result.data.agentInvocationId;
360
- })
361
- );
362
- if (invocationIds.size !== 1) {
363
- throw new Error(
364
- "Conversation mailbox contains multiple agent invocations in one attempt"
365
- );
366
- }
367
- return invocationIds.values().next().value;
368
- }
369
- async function resolveAgentInvocationId(context) {
370
- const mailboxInvocationId = invocationIdFromMessages(
371
- context.attempt.messages
372
- );
373
- if (mailboxInvocationId) {
374
- return mailboxInvocationId;
375
- }
376
- if (context.attempt.messages.length > 0) {
377
- return void 0;
378
- }
379
- return (await getActiveAgentInvocationForConversation(context.conversationId))?.invocationId;
380
- }
381
- async function persistTerminalLifecycle(invocation) {
382
- const lifecycle = new ConversationTurnLifecycleService(
383
- getConversationEventStore()
384
- );
385
- const common = {
386
- conversationId: invocation.childConversationId,
387
- createdAtMs: "terminalAtMs" in invocation ? invocation.terminalAtMs : invocation.updatedAtMs,
388
- turnId: getAgentInvocationTurnId(invocation.invocationId)
389
- };
390
- if (invocation.status === "completed") {
391
- await lifecycle.complete({
392
- ...common,
393
- outcome: invocation.result?.trim() ? "success" : "no_reply"
394
- });
395
- } else if (invocation.status === "blocked" || invocation.status === "failed") {
396
- await lifecycle.fail({
397
- ...common,
398
- failureCode: "model_execution_failed"
399
- });
400
- }
401
- }
402
- async function projectTerminalTurn(invocation) {
403
- let turn = await getTurnRecord(
404
- invocation.childConversationId,
405
- getAgentInvocationTurnId(invocation.invocationId)
406
- );
407
- if (!turn) {
408
- return void 0;
409
- }
410
- if (turn.state === "running") {
411
- turn = await failTurnRecord({
412
- conversationId: turn.conversationId,
413
- expectedVersion: turn.version,
414
- turnId: turn.turnId,
415
- errorMessage: "Agent invocation lost its worker before it could pause"
416
- });
417
- if (!turn) {
418
- return void 0;
419
- }
420
- }
421
- if (turn.state === "paused") {
422
- return void 0;
423
- }
424
- const result = getTerminalAssistantMessages(turn.piMessages).map(getAssistantReplyText).filter((text) => text !== void 0).join("\n\n");
425
- const failed = turn.state !== "completed" || Boolean(turn.errorMessage);
426
- return await completeAgentInvocation({
427
- invocationId: invocation.invocationId,
428
- ...failed ? {
429
- errorMessage: turn.errorMessage ?? "Agent invocation failed",
430
- status: "failed"
431
- } : {
432
- result,
433
- status: "completed"
434
- }
435
- });
436
- }
437
- function blockingInvocationError(error) {
438
- const cause = getConversationTurnBoundaryError(error)?.cause ?? error;
439
- return cause instanceof AuthorizationFlowDisabledError || cause instanceof PluginCredentialFailureError ? cause : void 0;
440
- }
441
- function isInvocationInputCommitLost(error) {
442
- const cause = getConversationTurnBoundaryError(error)?.cause ?? error;
443
- return isTurnInputCommitLostError(cause);
444
- }
445
- async function saveAgentInvocationResult(args) {
446
- const failed = args.result.diagnostics.outcome !== "success";
447
- await persistThreadStateById(args.invocation.childConversationId, {
448
- sandboxRef: args.result.sandboxRef ?? args.sandboxRef
449
- });
450
- if (args.result.piMessages?.length) {
451
- await saveTurnCheckpoint({
452
- mode: "completed",
453
- conversationId: args.invocation.childConversationId,
454
- turnId: args.turnId,
455
- durationMs: args.result.diagnostics.durationMs,
456
- usage: args.result.diagnostics.usage,
457
- destination: args.invocation.destination,
458
- ...failed ? {
459
- errorMessage: args.result.diagnostics.errorMessage ?? "Agent invocation failed"
460
- } : void 0,
461
- messages: args.result.piMessages,
462
- actor: args.invocation.actor,
463
- source: args.invocation.source,
464
- surface: "internal"
465
- });
466
- }
467
- const terminal = await completeAgentInvocation({
468
- invocationId: args.invocation.invocationId,
469
- ...failed ? {
470
- errorMessage: args.result.diagnostics.errorMessage ?? "Agent invocation failed",
471
- status: "failed"
472
- } : {
473
- result: args.result.text,
474
- status: "completed"
475
- }
476
- });
477
- if (!terminal || !isTerminalAgentInvocation(terminal)) {
478
- throw new Error(
479
- `Agent invocation did not finish for ${args.invocation.invocationId}`
480
- );
481
- }
482
- return terminal.status === "completed" ? {
483
- finishedAtMs: terminal.terminalAtMs,
484
- outcome: terminal.result.trim() ? "success" : "no_reply"
485
- } : {
486
- finishedAtMs: terminal.terminalAtMs,
487
- failureCode: "model_execution_failed",
488
- outcome: "failed"
489
- };
490
- }
491
- function createAgentInvocationWorker(agentRunner) {
492
- return async (context, invocationId) => {
493
- let invocation = await getAgentInvocation(invocationId);
494
- if (!invocation) {
495
- throw new Error(`Agent invocation is missing for ${invocationId}`);
496
- }
497
- let acknowledged = context.attempt.messages.length === 0;
498
- const acknowledge = async () => {
499
- if (acknowledged) {
500
- return;
501
- }
502
- try {
503
- await context.attempt.ack();
504
- } catch {
505
- throw new TurnInputCommitLostError(
506
- `Conversation work lease lost before invocation inbox ack for ${context.conversationId}`
507
- );
508
- }
509
- acknowledged = true;
510
- };
511
- const turnId = getAgentInvocationTurnId(invocation.invocationId);
512
- const lifecycle = new ConversationTurnLifecycleService(
513
- getConversationEventStore()
514
- );
515
- let sandboxRef;
516
- let history;
517
- let location;
518
- try {
519
- if (invocation.childConversationId !== context.conversationId) {
520
- throw new Error(
521
- `Agent invocation ${invocationId} belongs to ${invocation.childConversationId}, not ${context.conversationId}`
522
- );
523
- }
524
- if (context.destination) {
525
- throw new Error(
526
- `Agent invocation conversation ${context.conversationId} must not own a provider destination`
527
- );
528
- }
529
- if (isTerminalAgentInvocation(invocation)) {
530
- await persistTerminalLifecycle(invocation);
531
- await acknowledge();
532
- return { status: "completed" };
533
- }
534
- const projected = await projectTerminalTurn(invocation);
535
- if (projected && isTerminalAgentInvocation(projected)) {
536
- await persistTerminalLifecycle(projected);
537
- await acknowledge();
538
- return { status: "completed" };
539
- }
540
- invocation = await markAgentInvocationRunning(invocation.invocationId) ?? invocation;
541
- await lifecycle.start({
542
- conversationId: invocation.childConversationId,
543
- createdAtMs: invocation.createdAtMs,
544
- inputMessageIds: [getAgentInvocationMessageId(invocation.invocationId)],
545
- surface: "internal",
546
- turnId
547
- });
548
- const [persisted, projection] = await Promise.all([
549
- getPersistedThreadState(invocation.childConversationId),
550
- openConversationProjection({
551
- conversationId: invocation.childConversationId
552
- })
553
- ]);
554
- sandboxRef = getPersistedSandboxState(persisted);
555
- history = projection.messages;
556
- location = (await getConversationStore().get({
557
- conversationId: invocation.parentConversationId
558
- }))?.location;
559
- } catch (error) {
560
- if (isInvocationInputCommitLost(error)) {
561
- return { status: "lost_lease" };
562
- }
563
- if (!context.attempt.isFinalAttempt) {
564
- throw error;
565
- }
566
- const terminal = await completeAgentInvocation({
567
- invocationId: invocation.invocationId,
568
- errorMessage: error instanceof Error ? error.message : "Agent invocation failed",
569
- status: "failed"
570
- });
571
- if (terminal) {
572
- await persistTerminalLifecycle(terminal);
573
- }
574
- await acknowledge();
575
- return { status: "completed" };
576
- }
577
- let outcome;
578
- try {
579
- outcome = await executeTurn(
580
- agentRunner,
581
- {
582
- conversationId: invocation.childConversationId,
583
- turnId,
584
- runId: invocation.invocationId,
585
- instruction: {
586
- text: invocation.input
587
- },
588
- history,
589
- actor: invocation.actor,
590
- credentialContext: invocation.credentialContext,
591
- destination: invocation.destination,
592
- source: invocation.source,
593
- ...location ? { location } : void 0,
594
- surface: "internal",
595
- // TODO(dcramer): Issues #881 and #883 track a path for child runs to
596
- // force interactive auth when a delegated tool requires credentials
597
- // the parent can request. Today background children hard-fail instead
598
- // of pausing for an OAuth link.
599
- disabledFeatures: ["handoff", "interactive-auth", "subagents"],
600
- reasoning: invocation.reasoningLevel,
601
- state: {
602
- sandboxRef
603
- },
604
- durability: {
605
- onInputCommitted: acknowledge,
606
- shouldYield: context.shouldYield,
607
- onSandboxRefChanged: async (nextSandboxRef) => {
608
- sandboxRef = nextSandboxRef;
609
- await persistThreadStateById(invocation.childConversationId, {
610
- sandboxRef
611
- });
612
- }
613
- }
614
- },
615
- async (result) => await saveAgentInvocationResult({
616
- invocation,
617
- result,
618
- sandboxRef,
619
- turnId
620
- })
621
- );
622
- } catch (error) {
623
- if (!(error instanceof AgentRunError)) {
624
- throw error;
625
- }
626
- const runError = error.cause;
627
- if (isInvocationInputCommitLost(runError)) {
628
- return { status: "lost_lease" };
629
- }
630
- const blocking = blockingInvocationError(runError);
631
- if (blocking) {
632
- const terminal2 = await completeAgentInvocation({
633
- invocationId: invocation.invocationId,
634
- errorMessage: blocking.message,
635
- status: "blocked"
636
- });
637
- if (terminal2) {
638
- await persistTerminalLifecycle(terminal2);
639
- }
640
- await acknowledge();
641
- return { status: "completed" };
642
- }
643
- if (!context.attempt.isFinalAttempt) {
644
- throw runError;
645
- }
646
- const terminal = await completeAgentInvocation({
647
- invocationId: invocation.invocationId,
648
- errorMessage: runError instanceof Error ? runError.message : "Agent invocation failed",
649
- status: "failed"
650
- });
651
- if (terminal) {
652
- await persistTerminalLifecycle(terminal);
653
- }
654
- await acknowledge();
655
- return { status: "completed" };
656
- }
657
- if (outcome.status === "suspended") {
658
- await markAgentInvocationAwaitingResume(invocation.invocationId);
659
- return { status: "yielded" };
660
- }
661
- if (outcome.status === "awaiting_auth") {
662
- const terminal = await completeAgentInvocation({
663
- invocationId: invocation.invocationId,
664
- errorMessage: `Agent invocation requires ${outcome.providerDisplayName} authorization`,
665
- status: "blocked"
666
- });
667
- if (terminal) {
668
- await persistTerminalLifecycle(terminal);
669
- }
670
- await acknowledge();
671
- return { status: "completed" };
672
- }
673
- await acknowledge();
674
- return { status: "completed" };
675
- };
676
- }
677
- function routeAgentInvocationWork(options) {
678
- return async (context) => {
679
- const invocationId = await resolveAgentInvocationId(context);
680
- return invocationId ? await options.invocationWorker(context, invocationId) : await options.fallbackWorker(context);
681
- };
682
- }
683
-
684
- export {
685
- listPendingAgentInvocationMailboxAppends,
686
- buildAgentInvocationInboundMessage,
687
- enqueueAgentInvocation,
688
- createAndEnqueueAgentInvocation,
689
- resolveAgentInvocationId,
690
- createAgentInvocationWorker,
691
- routeAgentInvocationWork
692
- };