@sentry/junior 0.203.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 +8 -8
  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
@@ -1,692 +0,0 @@
1
- import {
2
- AgentRunError,
3
- executeTurn
4
- } from "./chunk-XRW44VGM.js";
5
- import {
6
- ConversationTurnLifecycleService
7
- } from "./chunk-EDKUFGPL.js";
8
- import {
9
- getPersistedSandboxState,
10
- getPersistedThreadState,
11
- persistThreadStateById
12
- } from "./chunk-ASTEMBKJ.js";
13
- import {
14
- AgentInvocationBusyError,
15
- AgentInvocationLimitError,
16
- AuthorizationFlowDisabledError,
17
- PluginCredentialFailureError,
18
- agentBindingSchema,
19
- agentInvocationSchema,
20
- createAgentInvocationSchema
21
- } from "./chunk-352OWAZH.js";
22
- import {
23
- TurnInputCommitLostError,
24
- getAssistantReplyText,
25
- getConversationTurnBoundaryError,
26
- isTurnInputCommitLostError
27
- } from "./chunk-5PDAG6O3.js";
28
- import {
29
- failTurnRecord,
30
- getTerminalAssistantMessages,
31
- getTurnRecord,
32
- openConversationProjection,
33
- saveTurnCheckpoint
34
- } from "./chunk-F4MGCZOX.js";
35
- import {
36
- appendAndEnqueueInboundMessage
37
- } from "./chunk-KIIEUXD3.js";
38
- import {
39
- getConversationEventStore,
40
- getConversationStore,
41
- getSqlExecutor
42
- } from "./chunk-GKEOHJL5.js";
43
- import {
44
- juniorAgentBindings,
45
- juniorAgentInvocations
46
- } from "./chunk-IE2VPG7O.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
- };