@zhivex-ai/core 1.17.0 → 1.19.1

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 (272) hide show
  1. package/README.md +4 -0
  2. package/dist/agent/approvals.d.ts +7 -0
  3. package/dist/agent/approvals.d.ts.map +1 -0
  4. package/dist/agent/approvals.js +97 -0
  5. package/dist/agent/approvals.js.map +1 -0
  6. package/dist/agent/cancellation.d.ts +4 -0
  7. package/dist/agent/cancellation.d.ts.map +1 -0
  8. package/dist/agent/cancellation.js +69 -0
  9. package/dist/agent/cancellation.js.map +1 -0
  10. package/dist/agent/common.d.ts +20 -0
  11. package/dist/agent/common.d.ts.map +1 -0
  12. package/dist/agent/common.js +150 -0
  13. package/dist/agent/common.js.map +1 -0
  14. package/dist/agent/compaction.d.ts +6 -0
  15. package/dist/agent/compaction.d.ts.map +1 -0
  16. package/dist/agent/compaction.js +156 -0
  17. package/dist/agent/compaction.js.map +1 -0
  18. package/dist/agent/context.d.ts +58 -0
  19. package/dist/agent/context.d.ts.map +1 -0
  20. package/dist/agent/context.js +267 -0
  21. package/dist/agent/context.js.map +1 -0
  22. package/dist/agent/definition.d.ts +4 -0
  23. package/dist/agent/definition.d.ts.map +1 -0
  24. package/dist/agent/definition.js +35 -0
  25. package/dist/agent/definition.js.map +1 -0
  26. package/dist/agent/execution.d.ts +14 -0
  27. package/dist/agent/execution.d.ts.map +1 -0
  28. package/dist/agent/execution.js +1062 -0
  29. package/dist/agent/execution.js.map +1 -0
  30. package/dist/agent/groups.d.ts +3 -0
  31. package/dist/agent/groups.d.ts.map +1 -0
  32. package/dist/agent/groups.js +130 -0
  33. package/dist/agent/groups.js.map +1 -0
  34. package/dist/agent/guardrails.d.ts +4 -0
  35. package/dist/agent/guardrails.d.ts.map +1 -0
  36. package/dist/agent/guardrails.js +29 -0
  37. package/dist/agent/guardrails.js.map +1 -0
  38. package/dist/agent/instance.d.ts +42 -0
  39. package/dist/agent/instance.d.ts.map +1 -0
  40. package/dist/agent/instance.js +82 -0
  41. package/dist/agent/instance.js.map +1 -0
  42. package/dist/agent/lifecycle.d.ts +31 -0
  43. package/dist/agent/lifecycle.d.ts.map +1 -0
  44. package/dist/agent/lifecycle.js +184 -0
  45. package/dist/agent/lifecycle.js.map +1 -0
  46. package/dist/agent/state.d.ts +6 -0
  47. package/dist/agent/state.d.ts.map +1 -0
  48. package/dist/agent/state.js +119 -0
  49. package/dist/agent/state.js.map +1 -0
  50. package/dist/agent/telemetry.d.ts +12 -0
  51. package/dist/agent/telemetry.d.ts.map +1 -0
  52. package/dist/agent/telemetry.js +176 -0
  53. package/dist/agent/telemetry.js.map +1 -0
  54. package/dist/agent/tool-execution.d.ts +6 -0
  55. package/dist/agent/tool-execution.d.ts.map +1 -0
  56. package/dist/agent/tool-execution.js +176 -0
  57. package/dist/agent/tool-execution.js.map +1 -0
  58. package/dist/agent-evaluation.d.ts.map +1 -1
  59. package/dist/agent-evaluation.js +2 -0
  60. package/dist/agent-evaluation.js.map +1 -1
  61. package/dist/agent-reconciliation.d.ts +12 -0
  62. package/dist/agent-reconciliation.d.ts.map +1 -0
  63. package/dist/agent-reconciliation.js +87 -0
  64. package/dist/agent-reconciliation.js.map +1 -0
  65. package/dist/agent-run-view.d.ts +9 -0
  66. package/dist/agent-run-view.d.ts.map +1 -0
  67. package/dist/agent-run-view.js +42 -0
  68. package/dist/agent-run-view.js.map +1 -0
  69. package/dist/agent-state.d.ts.map +1 -1
  70. package/dist/agent-state.js +34 -0
  71. package/dist/agent-state.js.map +1 -1
  72. package/dist/agent-store/file.d.ts +11 -0
  73. package/dist/agent-store/file.d.ts.map +1 -0
  74. package/dist/agent-store/file.js +534 -0
  75. package/dist/agent-store/file.js.map +1 -0
  76. package/dist/agent-store/memory.d.ts +9 -0
  77. package/dist/agent-store/memory.d.ts.map +1 -0
  78. package/dist/agent-store/memory.js +198 -0
  79. package/dist/agent-store/memory.js.map +1 -0
  80. package/dist/agent-store/postgres.d.ts +4 -0
  81. package/dist/agent-store/postgres.d.ts.map +1 -0
  82. package/dist/agent-store/postgres.js +374 -0
  83. package/dist/agent-store/postgres.js.map +1 -0
  84. package/dist/agent-store/shared.d.ts +19 -0
  85. package/dist/agent-store/shared.d.ts.map +1 -0
  86. package/dist/agent-store/shared.js +137 -0
  87. package/dist/agent-store/shared.js.map +1 -0
  88. package/dist/agent-store/sqlite.d.ts +4 -0
  89. package/dist/agent-store/sqlite.d.ts.map +1 -0
  90. package/dist/agent-store/sqlite.js +362 -0
  91. package/dist/agent-store/sqlite.js.map +1 -0
  92. package/dist/agent-store.d.ts +5 -21
  93. package/dist/agent-store.d.ts.map +1 -1
  94. package/dist/agent-store.js +5 -1540
  95. package/dist/agent-store.js.map +1 -1
  96. package/dist/agent.d.ts +6 -57
  97. package/dist/agent.d.ts.map +1 -1
  98. package/dist/agent.js +6 -2622
  99. package/dist/agent.js.map +1 -1
  100. package/dist/agents-entry.d.ts +19 -0
  101. package/dist/agents-entry.d.ts.map +1 -0
  102. package/dist/agents-entry.js +14 -0
  103. package/dist/agents-entry.js.map +1 -0
  104. package/dist/api-stability.d.ts.map +1 -1
  105. package/dist/api-stability.js +1 -0
  106. package/dist/api-stability.js.map +1 -1
  107. package/dist/artifact/file.d.ts +6 -0
  108. package/dist/artifact/file.d.ts.map +1 -0
  109. package/dist/artifact/file.js +380 -0
  110. package/dist/artifact/file.js.map +1 -0
  111. package/dist/artifact/memory.d.ts +3 -0
  112. package/dist/artifact/memory.d.ts.map +1 -0
  113. package/dist/artifact/memory.js +80 -0
  114. package/dist/artifact/memory.js.map +1 -0
  115. package/dist/artifact/postgres.d.ts +3 -0
  116. package/dist/artifact/postgres.d.ts.map +1 -0
  117. package/dist/artifact/postgres.js +283 -0
  118. package/dist/artifact/postgres.js.map +1 -0
  119. package/dist/artifact/shared.d.ts +208 -0
  120. package/dist/artifact/shared.d.ts.map +1 -0
  121. package/dist/artifact/shared.js +523 -0
  122. package/dist/artifact/shared.js.map +1 -0
  123. package/dist/artifact/sqlite.d.ts +3 -0
  124. package/dist/artifact/sqlite.d.ts.map +1 -0
  125. package/dist/artifact/sqlite.js +283 -0
  126. package/dist/artifact/sqlite.js.map +1 -0
  127. package/dist/artifact.d.ts +6 -186
  128. package/dist/artifact.d.ts.map +1 -1
  129. package/dist/artifact.js +6 -1536
  130. package/dist/artifact.js.map +1 -1
  131. package/dist/catalog-contracts.d.ts +52 -0
  132. package/dist/catalog-contracts.d.ts.map +1 -0
  133. package/dist/catalog-contracts.js +250 -0
  134. package/dist/catalog-contracts.js.map +1 -0
  135. package/dist/catalog.d.ts +3 -52
  136. package/dist/catalog.d.ts.map +1 -1
  137. package/dist/catalog.js +3 -249
  138. package/dist/catalog.js.map +1 -1
  139. package/dist/generate-cache-file.d.ts +11 -0
  140. package/dist/generate-cache-file.d.ts.map +1 -0
  141. package/dist/generate-cache-file.js +124 -0
  142. package/dist/generate-cache-file.js.map +1 -0
  143. package/dist/generate-text.d.ts +2 -5
  144. package/dist/generate-text.d.ts.map +1 -1
  145. package/dist/generate-text.js +3 -18
  146. package/dist/generate-text.js.map +1 -1
  147. package/dist/generation-entry.d.ts +6 -0
  148. package/dist/generation-entry.d.ts.map +1 -0
  149. package/dist/generation-entry.js +6 -0
  150. package/dist/generation-entry.js.map +1 -0
  151. package/dist/index.d.ts +3 -0
  152. package/dist/index.d.ts.map +1 -1
  153. package/dist/index.js +1 -0
  154. package/dist/index.js.map +1 -1
  155. package/dist/middleware-runtime.d.ts +35 -0
  156. package/dist/middleware-runtime.d.ts.map +1 -0
  157. package/dist/middleware-runtime.js +532 -0
  158. package/dist/middleware-runtime.js.map +1 -0
  159. package/dist/middleware.d.ts +3 -43
  160. package/dist/middleware.d.ts.map +1 -1
  161. package/dist/middleware.js +3 -653
  162. package/dist/middleware.js.map +1 -1
  163. package/dist/normalize-messages.d.ts +3 -0
  164. package/dist/normalize-messages.d.ts.map +1 -0
  165. package/dist/normalize-messages.js +16 -0
  166. package/dist/normalize-messages.js.map +1 -0
  167. package/dist/provider-entry.d.ts +17 -0
  168. package/dist/provider-entry.d.ts.map +1 -0
  169. package/dist/provider-entry.js +13 -0
  170. package/dist/provider-entry.js.map +1 -0
  171. package/dist/realtime.d.ts +2 -0
  172. package/dist/realtime.d.ts.map +1 -1
  173. package/dist/realtime.js +6 -0
  174. package/dist/realtime.js.map +1 -1
  175. package/dist/store-key.d.ts +3 -0
  176. package/dist/store-key.d.ts.map +1 -0
  177. package/dist/store-key.js +5 -0
  178. package/dist/store-key.js.map +1 -0
  179. package/dist/store-security.d.ts +1 -2
  180. package/dist/store-security.d.ts.map +1 -1
  181. package/dist/store-security.js +2 -4
  182. package/dist/store-security.js.map +1 -1
  183. package/dist/types/agent-state.d.ts +236 -0
  184. package/dist/types/agent-state.d.ts.map +1 -0
  185. package/dist/types/agent-state.js +2 -0
  186. package/dist/types/agent-state.js.map +1 -0
  187. package/dist/types/agents.d.ts +429 -0
  188. package/dist/types/agents.d.ts.map +1 -0
  189. package/dist/types/agents.js +2 -0
  190. package/dist/types/agents.js.map +1 -0
  191. package/dist/types/common.d.ts +179 -0
  192. package/dist/types/common.d.ts.map +1 -0
  193. package/dist/types/common.js +2 -0
  194. package/dist/types/common.js.map +1 -0
  195. package/dist/types/generation.d.ts +109 -0
  196. package/dist/types/generation.d.ts.map +1 -0
  197. package/dist/types/generation.js +2 -0
  198. package/dist/types/generation.js.map +1 -0
  199. package/dist/types/media-data.d.ts +65 -0
  200. package/dist/types/media-data.d.ts.map +1 -0
  201. package/dist/types/media-data.js +2 -0
  202. package/dist/types/media-data.js.map +1 -0
  203. package/dist/types/media.d.ts +141 -0
  204. package/dist/types/media.d.ts.map +1 -0
  205. package/dist/types/media.js +2 -0
  206. package/dist/types/media.js.map +1 -0
  207. package/dist/types/messages.d.ts +82 -0
  208. package/dist/types/messages.d.ts.map +1 -0
  209. package/dist/types/messages.js +2 -0
  210. package/dist/types/messages.js.map +1 -0
  211. package/dist/types/middleware.d.ts +130 -0
  212. package/dist/types/middleware.d.ts.map +1 -0
  213. package/dist/types/middleware.js +2 -0
  214. package/dist/types/middleware.js.map +1 -0
  215. package/dist/types/model-tools.d.ts +409 -0
  216. package/dist/types/model-tools.d.ts.map +1 -0
  217. package/dist/types/model-tools.js +2 -0
  218. package/dist/types/model-tools.js.map +1 -0
  219. package/dist/types/persistence.d.ts +168 -0
  220. package/dist/types/persistence.d.ts.map +1 -0
  221. package/dist/types/persistence.js +2 -0
  222. package/dist/types/persistence.js.map +1 -0
  223. package/dist/types/provider-resources.d.ts +336 -0
  224. package/dist/types/provider-resources.d.ts.map +1 -0
  225. package/dist/types/provider-resources.js +2 -0
  226. package/dist/types/provider-resources.js.map +1 -0
  227. package/dist/types/provider.d.ts +23 -0
  228. package/dist/types/provider.d.ts.map +1 -0
  229. package/dist/types/provider.js +2 -0
  230. package/dist/types/provider.js.map +1 -0
  231. package/dist/types/resource-options.d.ts +88 -0
  232. package/dist/types/resource-options.d.ts.map +1 -0
  233. package/dist/types/resource-options.js +2 -0
  234. package/dist/types/resource-options.js.map +1 -0
  235. package/dist/types/stream.d.ts +70 -0
  236. package/dist/types/stream.d.ts.map +1 -0
  237. package/dist/types/stream.js +2 -0
  238. package/dist/types/stream.js.map +1 -0
  239. package/dist/types/ui.d.ts +110 -0
  240. package/dist/types/ui.d.ts.map +1 -0
  241. package/dist/types/ui.js +2 -0
  242. package/dist/types/ui.js.map +1 -0
  243. package/dist/types.d.ts +16 -2442
  244. package/dist/types.d.ts.map +1 -1
  245. package/dist/ui.d.ts.map +1 -1
  246. package/dist/ui.js +2 -0
  247. package/dist/ui.js.map +1 -1
  248. package/dist/workflow-state-service/file.d.ts +5 -0
  249. package/dist/workflow-state-service/file.d.ts.map +1 -0
  250. package/dist/workflow-state-service/file.js +142 -0
  251. package/dist/workflow-state-service/file.js.map +1 -0
  252. package/dist/workflow-state-service/memory.d.ts +3 -0
  253. package/dist/workflow-state-service/memory.d.ts.map +1 -0
  254. package/dist/workflow-state-service/memory.js +27 -0
  255. package/dist/workflow-state-service/memory.js.map +1 -0
  256. package/dist/workflow-state-service/postgres.d.ts +4 -0
  257. package/dist/workflow-state-service/postgres.d.ts.map +1 -0
  258. package/dist/workflow-state-service/postgres.js +179 -0
  259. package/dist/workflow-state-service/postgres.js.map +1 -0
  260. package/dist/workflow-state-service/shared.d.ts +43 -0
  261. package/dist/workflow-state-service/shared.d.ts.map +1 -0
  262. package/dist/workflow-state-service/shared.js +107 -0
  263. package/dist/workflow-state-service/shared.js.map +1 -0
  264. package/dist/workflow-state-service/sqlite.d.ts +4 -0
  265. package/dist/workflow-state-service/sqlite.d.ts.map +1 -0
  266. package/dist/workflow-state-service/sqlite.js +183 -0
  267. package/dist/workflow-state-service/sqlite.js.map +1 -0
  268. package/dist/workflow-state-service.d.ts +6 -33
  269. package/dist/workflow-state-service.d.ts.map +1 -1
  270. package/dist/workflow-state-service.js +6 -626
  271. package/dist/workflow-state-service.js.map +1 -1
  272. package/package.json +17 -1
@@ -0,0 +1,1062 @@
1
+ import { createRunViewSink, runViewSink, runViewParent } from "../agent-run-view.js";
2
+ import { createHash } from "node:crypto";
3
+ import { getAgentApprovalRequests } from "../agent-approval.js";
4
+ import { fingerprintAgentHarness } from "../agent-harness.js";
5
+ import { normalizeAgentRunState } from "../agent-state.js";
6
+ import { BoundedReplayBroadcast } from "../bounded-broadcast.js";
7
+ import { ConflictError, GuardrailTriggeredError, ValidationError } from "../errors.js";
8
+ import { aggregateTokenUsage, generateText, getGenerateTextStepTiming, streamText } from "../generate-text.js";
9
+ import { isCallableToolDefinition, serializeJsonValue } from "../messages.js";
10
+ import { evaluateAgentBudgetPreflight, getAgentBudgetStatus } from "../safety-policy.js";
11
+ import { ToolExecutionSuspendedError } from "../tool-execution-suspension.js";
12
+ import { toToolSet } from "../tool-registry.js";
13
+ import { z } from "zod";
14
+ import { approvalsFromEvents, cloneMetadata, cloneState, countToolCallsInSteps, countToolErrors, createFailedState, createTerminalState, joinInstructions, mapSteps, messagePrefixLength, normalizeApprovalStatus, randomId, resolveAgentOutputMode, snapshotRequest, snapshotResponse, toOutput } from "./common.js";
15
+ import { AgentPolicyTimeoutError, acquireAgentExecutionLease, createAgentAbortContext, resolveRunPolicy, withAgentPolicyTimeout } from "./lifecycle.js";
16
+ import { claimAgentExecution, finalizeState, persistState } from "./state.js";
17
+ import { resolveContext } from "./context.js";
18
+ import { emitApprovalTelemetry, emitFinalizedStepTelemetry, emitInvocationFinishTelemetry, emitInvocationStartTelemetry, emitRunFinishTelemetry, emitRunStartTelemetry, emitTelemetryEvent, emitToolApprovalTelemetry, withAgentTelemetryRunContext } from "./telemetry.js";
19
+ import { applyGuardrailFailure, runGuardrails } from "./guardrails.js";
20
+ import { acquireExecutionEnvironment, durableToolCallId, wrapToolWithExecutionEnvironment, wrapToolWithJournal } from "./tool-execution.js";
21
+ import { compactAgentMessages } from "./compaction.js";
22
+ const subAgentToolInputSchema = z.object({
23
+ prompt: z.string().min(1),
24
+ system: z.string().optional()
25
+ });
26
+ const defaultSubAgentToolName = (agent) => {
27
+ const id = agent.id ?? `${agent.model.provider}_${agent.model.modelId}`;
28
+ const normalized = id.replace(/[^A-Za-z0-9_]+/g, "_");
29
+ let start = 0;
30
+ let end = normalized.length;
31
+ // Scan the edges once to avoid regex backtracking on long underscore runs.
32
+ while (start < end && normalized[start] === "_")
33
+ start++;
34
+ while (end > start && normalized[end - 1] === "_")
35
+ end--;
36
+ return `subagent_${normalized.slice(start, end) || "agent"}`;
37
+ };
38
+ export const createSubAgentTool = (options) => {
39
+ const runtimeState = options.runtimeState;
40
+ const toolName = options.toolName ?? options.name ?? defaultSubAgentToolName(options.agent);
41
+ const metadata = {
42
+ type: "subagent"
43
+ };
44
+ if (options.agent.id) {
45
+ metadata.childAgentId = options.agent.id;
46
+ }
47
+ if (options.parentRunId) {
48
+ metadata.parentRunId = options.parentRunId;
49
+ }
50
+ if (options.parentAgentId) {
51
+ metadata.parentAgentId = options.parentAgentId;
52
+ }
53
+ return {
54
+ name: toolName,
55
+ description: options.description ??
56
+ `Delegate the task to ${options.agent.id ? `subagent "${options.agent.id}"` : "a subagent"} and return its result.`,
57
+ schema: subAgentToolInputSchema,
58
+ requiresApproval: options.requiresApproval,
59
+ metadata: cloneMetadata(metadata, options.metadata),
60
+ execute: async (input, executionContext) => {
61
+ await options.onStart?.({
62
+ toolName,
63
+ childAgentId: options.agent.id,
64
+ parentRunId: options.parentRunId
65
+ });
66
+ const childMetadata = {
67
+ subagentToolName: toolName
68
+ };
69
+ if (options.parentRunId) {
70
+ childMetadata.parentRunId = options.parentRunId;
71
+ }
72
+ if (options.parentAgentId) {
73
+ childMetadata.parentAgentId = options.parentAgentId;
74
+ }
75
+ const toolCallId = executionContext?.toolCall.id;
76
+ const childIdempotencyKey = options.parentRunId &&
77
+ toolCallId &&
78
+ executionContext &&
79
+ options.agent.store?.claimIdempotencyKey
80
+ ? `subagent:${durableToolCallId(options.parentRunId, executionContext.step, toolCallId, toolName, serializeJsonValue(input))}`
81
+ : undefined;
82
+ const checkpoint = runtimeState?.childRuns?.find((childRun) => childRun.toolCallId === toolCallId && childRun.resumeState);
83
+ const childApprovalResponses = checkpoint
84
+ ? (runtimeState?.approvalHistory ?? [])
85
+ .filter((resolution) => resolution.kind === "subagent" &&
86
+ resolution.toolCallId === toolCallId &&
87
+ resolution.childRunId === checkpoint.runId &&
88
+ resolution.childApprovalRequestId)
89
+ .map((resolution) => ({
90
+ provider: resolution.provider,
91
+ approvalRequestId: resolution.childApprovalRequestId,
92
+ approve: resolution.approve,
93
+ reason: resolution.reason
94
+ }))
95
+ : [];
96
+ const output = checkpoint?.resumeState
97
+ ? await resumeAgent(options.agent, {
98
+ state: checkpoint.resumeState,
99
+ approvals: childApprovalResponses,
100
+ scope: options.scope,
101
+ context: executionContext?.context,
102
+ maxSteps: options.maxSteps
103
+ })
104
+ : await runAgent(options.agent, {
105
+ prompt: input.prompt,
106
+ system: joinInstructions(options.system, input.system),
107
+ parentRunId: options.parentRunId,
108
+ idempotencyKey: childIdempotencyKey,
109
+ scope: options.scope,
110
+ context: executionContext?.context,
111
+ maxSteps: options.maxSteps,
112
+ metadata: cloneMetadata(options.metadata, childMetadata)
113
+ });
114
+ const childRun = {
115
+ runId: output.state.runId,
116
+ status: output.status,
117
+ outputText: output.outputText,
118
+ steps: output.state.currentStep,
119
+ toolCalls: countToolCallsInSteps(output.steps),
120
+ toolErrors: countToolErrors(output.toolResults)
121
+ };
122
+ if (toolCallId) {
123
+ childRun.toolCallId = toolCallId;
124
+ }
125
+ if (output.state.agentId) {
126
+ childRun.agentId = output.state.agentId;
127
+ }
128
+ if (options.parentRunId) {
129
+ childRun.parentRunId = options.parentRunId;
130
+ }
131
+ childRun.toolName = toolName;
132
+ if (output.usage) {
133
+ childRun.usage = output.usage;
134
+ }
135
+ if (output.state.startedAt !== undefined) {
136
+ childRun.startedAt = output.state.startedAt;
137
+ }
138
+ if (output.state.updatedAt !== undefined) {
139
+ childRun.updatedAt = output.state.updatedAt;
140
+ }
141
+ if (output.error) {
142
+ childRun.error = output.error;
143
+ }
144
+ if (output.state.metadata) {
145
+ childRun.metadata = output.state.metadata;
146
+ }
147
+ if (output.status === "waiting_approval" && output.state.pendingApprovals.length) {
148
+ childRun.resumeState = output.state;
149
+ }
150
+ await options.onFinish?.(childRun);
151
+ if (childRun.resumeState) {
152
+ const approvals = childRun.resumeState.pendingApprovals.map((approval) => {
153
+ const id = `subapproval_${createHash("sha256")
154
+ .update(`${options.parentRunId ?? ""}\0${toolCallId ?? ""}\0${childRun.runId}\0${approval.id}`)
155
+ .digest("hex")}`;
156
+ return {
157
+ kind: "subagent",
158
+ provider: approval.provider,
159
+ id,
160
+ name: approval.name,
161
+ arguments: approval.arguments,
162
+ serverLabel: approval.serverLabel,
163
+ toolCallId,
164
+ step: executionContext?.step,
165
+ childRunId: childRun.runId,
166
+ childAgentId: childRun.agentId,
167
+ childApprovalRequestId: approval.id,
168
+ rawData: {
169
+ type: "subagent_approval_request",
170
+ childRunId: childRun.runId,
171
+ childAgentId: childRun.agentId ?? null,
172
+ childApprovalRequestId: approval.id,
173
+ approval: approval.rawData
174
+ }
175
+ };
176
+ });
177
+ throw new ToolExecutionSuspendedError(approvals);
178
+ }
179
+ return serializeJsonValue(childRun);
180
+ }
181
+ };
182
+ };
183
+ const createGenerateOptions = (agent, state, input, messages, maxSteps, context, executionEnvironmentSession, abortSignal = input.abortSignal, onCompaction) => {
184
+ const tools = { ...(toToolSet(input.tools ?? agent.tools) ?? {}) };
185
+ for (const subagent of agent.subagents ?? []) {
186
+ const subagentTool = createSubAgentTool({
187
+ ...subagent,
188
+ agent: {
189
+ ...subagent.agent,
190
+ ...(agent[runViewSink] ? { [runViewSink]: agent[runViewSink], [runViewParent]: state.runId } : {}),
191
+ store: subagent.agent.store ?? agent.store,
192
+ memory: subagent.agent.memory ?? agent.memory,
193
+ executionEnvironment: subagent.agent.executionEnvironment ??
194
+ input.executionEnvironment ??
195
+ agent.executionEnvironment,
196
+ compaction: subagent.agent.compaction ?? (input.compaction === false
197
+ ? undefined
198
+ : input.compaction ?? agent.compaction)
199
+ },
200
+ parentRunId: state.runId,
201
+ parentAgentId: state.agentId,
202
+ scope: state.scope,
203
+ runtimeState: state,
204
+ onStart: async ({ toolName, childAgentId }) => {
205
+ await emitTelemetryEvent(agent, {
206
+ type: "subagent-start",
207
+ runId: state.runId,
208
+ agentId: state.agentId,
209
+ childAgentId,
210
+ toolName
211
+ });
212
+ },
213
+ onFinish: async (childRun) => {
214
+ state.childRuns = [
215
+ ...(state.childRuns ?? []).filter((existing) => childRun.toolCallId
216
+ ? existing.toolCallId !== childRun.toolCallId
217
+ : existing.runId !== childRun.runId),
218
+ childRun
219
+ ];
220
+ await emitTelemetryEvent(agent, {
221
+ type: "subagent-finish",
222
+ runId: state.runId,
223
+ agentId: state.agentId,
224
+ childRun
225
+ });
226
+ }
227
+ });
228
+ if (tools[subagentTool.name]) {
229
+ throw new ValidationError(`Subagent tool "${subagentTool.name}" conflicts with an existing tool.`);
230
+ }
231
+ tools[subagentTool.name] = subagentTool;
232
+ }
233
+ for (const [name, tool] of Object.entries(tools)) {
234
+ if (isCallableToolDefinition(tool)) {
235
+ const environmentTool = executionEnvironmentSession
236
+ ? wrapToolWithExecutionEnvironment(tool, executionEnvironmentSession)
237
+ : tool;
238
+ tools[name] = tool.metadata?.type === "subagent"
239
+ ? environmentTool
240
+ : wrapToolWithJournal(agent, state, environmentTool);
241
+ }
242
+ }
243
+ const finalTools = Object.keys(tools).length ? tools : undefined;
244
+ const budget = input.policy?.budget ?? agent.policy?.budget;
245
+ const runPolicy = resolveRunPolicy(agent, input);
246
+ const compaction = input.compaction === false
247
+ ? undefined
248
+ : input.compaction ?? agent.compaction;
249
+ let checkpointState = cloneState(state);
250
+ let liveUsage = state.usage;
251
+ const liveToolResults = [...state.toolResults];
252
+ let reservedToolCalls = 0;
253
+ const requestedMaxTokens = input.maxTokens ?? agent.maxTokens;
254
+ const budgetStatus = budget ? getAgentBudgetStatus(state, budget) : undefined;
255
+ const tokenCeilings = [
256
+ requestedMaxTokens,
257
+ budgetStatus?.remaining.outputTokens,
258
+ budgetStatus?.remaining.totalTokens
259
+ ].filter((value) => value !== undefined);
260
+ const maxTokens = tokenCeilings.length ? Math.min(...tokenCeilings) : undefined;
261
+ const requestedToolExecution = input.toolExecution ?? agent.toolExecution;
262
+ const toolExecution = agent.subagents?.length && !(requestedToolExecution?.parallel && requestedToolExecution.independentOnly)
263
+ ? {
264
+ ...requestedToolExecution,
265
+ parallel: false,
266
+ maxConcurrency: 1
267
+ }
268
+ : requestedToolExecution;
269
+ return {
270
+ model: agent.model,
271
+ messages,
272
+ tools: finalTools,
273
+ toolChoice: input.toolChoice,
274
+ toolExecution,
275
+ toolApprovalPolicy: input.toolApprovalPolicy ?? agent.toolApprovalPolicy,
276
+ toolApprovalSigner: agent.toolApprovalSigner,
277
+ toolApprovalResolutions: state.approvalHistory,
278
+ toolContext: {
279
+ context,
280
+ runId: state.runId,
281
+ agentId: state.agentId,
282
+ agentName: agent.name,
283
+ scope: state.scope,
284
+ metadata: state.metadata,
285
+ executionEnvironment: executionEnvironmentSession
286
+ },
287
+ onToolApprovalDecision: async (event) => {
288
+ await emitToolApprovalTelemetry(agent, state, event);
289
+ },
290
+ prepareModelMessages: compaction
291
+ ? async ({ messages: activeMessages, step }) => {
292
+ const compacted = await compactAgentMessages(compaction, checkpointState, activeMessages, step, context, abortSignal);
293
+ if (!compacted) {
294
+ return undefined;
295
+ }
296
+ checkpointState = {
297
+ ...checkpointState,
298
+ messages: compacted.messages,
299
+ usage: aggregateTokenUsage([
300
+ checkpointState.usage,
301
+ compacted.record.usage
302
+ ]),
303
+ compactions: [
304
+ ...(checkpointState.compactions ?? []).filter((existing) => existing.id !== compacted.record.id),
305
+ compacted.record
306
+ ],
307
+ updatedAt: Date.now()
308
+ };
309
+ state.messages = compacted.messages;
310
+ // Finalization adds this invocation's model usage. Only add the
311
+ // compactor here; checkpoint usage already includes model responses.
312
+ state.usage = aggregateTokenUsage([state.usage, compacted.record.usage]);
313
+ liveUsage = aggregateTokenUsage([liveUsage, compacted.record.usage]);
314
+ state.compactions = checkpointState.compactions;
315
+ await persistState(agent, checkpointState, runPolicy);
316
+ state.revision = checkpointState.revision;
317
+ await onCompaction?.(compacted.record);
318
+ return compacted.messages;
319
+ }
320
+ : undefined,
321
+ onBeforeModelStep: async ({ step }) => {
322
+ if (budget) {
323
+ const trigger = evaluateAgentBudgetPreflight({ ...state, usage: liveUsage, toolResults: liveToolResults }, budget, {
324
+ operation: "model",
325
+ requiredSteps: Math.max(1, step - state.currentStep),
326
+ requestedOutputTokens: maxTokens
327
+ });
328
+ if (trigger) {
329
+ throw new GuardrailTriggeredError("input", trigger.reason ?? "Agent model budget preflight failed.", {
330
+ metadata: trigger.metadata
331
+ });
332
+ }
333
+ }
334
+ await emitTelemetryEvent(agent, {
335
+ type: "step-start",
336
+ runId: state.runId,
337
+ agentId: state.agentId,
338
+ agentName: agent.name,
339
+ stepIndex: step,
340
+ startedAt: Date.now()
341
+ });
342
+ },
343
+ onModelStep: async ({ request, response, step, toolCalls, approvalRequests, failedToolResults }) => {
344
+ liveUsage = aggregateTokenUsage([liveUsage, response.usage]);
345
+ const responseSnapshot = snapshotResponse(response);
346
+ const approvals = [
347
+ ...approvalRequests,
348
+ ...getAgentApprovalRequests(responseSnapshot.messages)
349
+ ];
350
+ const crossedCompactionBoundary = checkpointState.compactions?.some((record) => record.beforeStep === step &&
351
+ record.resultDigest === fingerprintAgentHarness(request.messages));
352
+ const requestOffset = crossedCompactionBoundary
353
+ ? 0
354
+ : messagePrefixLength(checkpointState.messages, request.messages);
355
+ const timing = getGenerateTextStepTiming(request);
356
+ const finishedAt = timing?.finishedAt ?? Date.now();
357
+ const checkpointStep = {
358
+ index: step,
359
+ status: failedToolResults ? "failed" : approvals.length ? "waiting_approval" : "completed",
360
+ startedAt: timing?.startedAt ?? finishedAt,
361
+ finishedAt,
362
+ request: snapshotRequest(request, requestOffset, request.messages.slice(requestOffset)),
363
+ response: responseSnapshot,
364
+ toolResults: failedToolResults ?? []
365
+ };
366
+ checkpointState = {
367
+ ...checkpointState,
368
+ status: approvals.length ? "waiting_approval" : toolCalls.length ? "running" : "completed",
369
+ messages: [...request.messages, ...responseSnapshot.messages,
370
+ ...(failedToolResults ?? []).map(toolResult => ({ role: "tool", parts: [{ type: "tool-result", toolResult }] }))],
371
+ toolResults: [...checkpointState.toolResults, ...(failedToolResults ?? [])],
372
+ steps: [...checkpointState.steps.filter((existing) => existing.index !== step), checkpointStep],
373
+ currentStep: step,
374
+ outputText: response.text ?? checkpointState.outputText,
375
+ finishReason: response.finishReason,
376
+ providerFinishReason: response.providerFinishReason,
377
+ usage: aggregateTokenUsage([checkpointState.usage, response.usage]),
378
+ pendingApprovals: approvals,
379
+ error: undefined,
380
+ updatedAt: Date.now()
381
+ };
382
+ if (agent.store) {
383
+ await persistState(agent, checkpointState, runPolicy);
384
+ state.revision = checkpointState.revision;
385
+ }
386
+ if (failedToolResults)
387
+ Object.assign(state, checkpointState);
388
+ },
389
+ onToolExecutionComplete: async ({ toolResults }) => {
390
+ liveToolResults.push(...toolResults);
391
+ const lastStep = checkpointState.steps.at(-1);
392
+ if (lastStep) {
393
+ lastStep.toolResults = [...lastStep.toolResults, ...toolResults];
394
+ }
395
+ checkpointState = {
396
+ ...checkpointState,
397
+ status: "running",
398
+ messages: [
399
+ ...checkpointState.messages,
400
+ ...toolResults.map((toolResult) => ({
401
+ role: "tool",
402
+ parts: [{ type: "tool-result", toolResult }]
403
+ }))
404
+ ],
405
+ toolResults: [...checkpointState.toolResults, ...toolResults],
406
+ updatedAt: Date.now()
407
+ };
408
+ if (agent.store) {
409
+ await persistState(agent, checkpointState, runPolicy);
410
+ state.revision = checkpointState.revision;
411
+ }
412
+ },
413
+ stepOffset: state.currentStep,
414
+ onBeforeToolExecution: async ({ step, toolCalls }) => {
415
+ if (budget) {
416
+ reservedToolCalls += toolCalls.length;
417
+ const trigger = evaluateAgentBudgetPreflight({ ...state, usage: liveUsage, toolResults: liveToolResults }, budget, {
418
+ operation: "tool",
419
+ requiredToolCalls: reservedToolCalls
420
+ });
421
+ if (trigger) {
422
+ throw new GuardrailTriggeredError("input", trigger.reason ?? "Agent tool budget preflight failed.", {
423
+ metadata: trigger.metadata
424
+ });
425
+ }
426
+ }
427
+ for (const toolCall of toolCalls) {
428
+ await emitTelemetryEvent(agent, {
429
+ type: "tool-start",
430
+ runId: state.runId,
431
+ agentId: state.agentId,
432
+ agentName: agent.name,
433
+ stepIndex: step,
434
+ toolCall,
435
+ startedAt: Date.now()
436
+ });
437
+ }
438
+ },
439
+ maxSteps,
440
+ temperature: input.temperature ?? agent.temperature,
441
+ maxTokens,
442
+ reasoning: input.reasoning ?? agent.reasoning,
443
+ structuredOutput: agent.outputSchema && resolveAgentOutputMode(agent) === "native"
444
+ ? {
445
+ schema: agent.outputSchema,
446
+ mode: "native",
447
+ name: agent.outputName,
448
+ description: agent.outputDescription
449
+ }
450
+ : undefined,
451
+ providerOptions: input.providerOptions ?? agent.providerOptions,
452
+ abortSignal,
453
+ timeoutMs: input.timeoutMs,
454
+ maxRetries: input.maxRetries,
455
+ retryBackoffMs: input.retryBackoffMs
456
+ };
457
+ };
458
+ const emptyAsyncIterable = async function* () {
459
+ return;
460
+ };
461
+ export const runAgent = async (agent, input = {}) => {
462
+ const invocationStartedAt = Date.now();
463
+ const telemetryRunId = input.runId ?? input.state?.runId ?? randomId("run");
464
+ const invocationInput = input.runId || input.state
465
+ ? input
466
+ : { ...input, runId: telemetryRunId };
467
+ let invocationStatus = "completed";
468
+ let invocationError;
469
+ const returnInvocationOutput = (output) => {
470
+ invocationStatus = output.status;
471
+ if (output.status === "failed" || output.status === "timed_out") {
472
+ invocationError = new Error(output.error?.message ?? `Agent invocation ${output.status}.`);
473
+ if (output.status === "timed_out")
474
+ invocationError.name = "TimeoutError";
475
+ }
476
+ else {
477
+ invocationError = undefined;
478
+ }
479
+ return output;
480
+ };
481
+ await emitInvocationStartTelemetry(agent, telemetryRunId, invocationStartedAt, Math.max(1, input.maxSteps ?? input.state?.maxSteps ?? agent.maxSteps ?? 1));
482
+ try {
483
+ const context = await resolveContext(agent, invocationInput);
484
+ const currentStatus = normalizeApprovalStatus(context.state.status);
485
+ const policy = resolveRunPolicy(agent, input);
486
+ if (currentStatus === "completed" ||
487
+ currentStatus === "cancelled" ||
488
+ currentStatus === "cancel_requested" ||
489
+ currentStatus === "timed_out") {
490
+ context.state.status = currentStatus;
491
+ invocationStatus = currentStatus;
492
+ return returnInvocationOutput(toOutput(context.state));
493
+ }
494
+ if (currentStatus === "waiting_approval" && context.state.pendingApprovals.length > 0) {
495
+ context.state.status = currentStatus;
496
+ invocationStatus = currentStatus;
497
+ return returnInvocationOutput(toOutput(context.state));
498
+ }
499
+ const supportsLeases = Boolean(agent.store?.acquireLease && agent.store.renewLease && agent.store.releaseLease);
500
+ if (!context.fresh && currentStatus === "running" && !supportsLeases) {
501
+ invocationStatus = currentStatus;
502
+ return returnInvocationOutput(toOutput(context.state));
503
+ }
504
+ const freshRequiresExistingClaim = context.fresh && Boolean(context.state.idempotencyKey);
505
+ if (context.fresh && !freshRequiresExistingClaim) {
506
+ await claimAgentExecution(agent, context.state);
507
+ }
508
+ const executionLease = await acquireAgentExecutionLease(agent, context.state, policy);
509
+ if (!executionLease) {
510
+ if (input.state) {
511
+ throw new ConflictError(`Agent run "${context.state.runId}" is already owned by another worker.`);
512
+ }
513
+ const activeState = await agent.store?.load(context.state.runId, context.state.scope);
514
+ const outputState = activeState ? normalizeAgentRunState(activeState) : context.state;
515
+ invocationStatus = outputState.status;
516
+ return returnInvocationOutput(toOutput(outputState));
517
+ }
518
+ try {
519
+ if (!context.fresh || freshRequiresExistingClaim) {
520
+ await claimAgentExecution(agent, context.state);
521
+ }
522
+ await emitRunStartTelemetry(agent, context.state, context.memoryMessages, input.approvals, invocationStartedAt);
523
+ }
524
+ catch (error) {
525
+ await executionLease.release();
526
+ throw error;
527
+ }
528
+ if (context.remainingSteps === 0) {
529
+ const state = createFailedState(context.state, "Agent exhausted maxSteps before reaching a terminal response.");
530
+ await persistState(agent, state, policy);
531
+ await emitRunFinishTelemetry(agent, state);
532
+ await executionLease.release();
533
+ return returnInvocationOutput(toOutput(state));
534
+ }
535
+ let inputGuardrail;
536
+ try {
537
+ inputGuardrail = await runGuardrails(agent, context.state, "input", agent.inputGuardrails, () => ({
538
+ runId: context.state.runId,
539
+ agentId: context.state.agentId,
540
+ context: context.context,
541
+ state: cloneState(context.state),
542
+ messages: context.messages,
543
+ metadata: context.state.metadata
544
+ }));
545
+ }
546
+ catch (error) {
547
+ await executionLease.release();
548
+ throw error;
549
+ }
550
+ if (inputGuardrail) {
551
+ const failedState = applyGuardrailFailure(context.state, "input", inputGuardrail);
552
+ await persistState(agent, failedState, policy);
553
+ await emitRunFinishTelemetry(agent, failedState);
554
+ await executionLease.release();
555
+ return returnInvocationOutput(toOutput(failedState));
556
+ }
557
+ const abortContext = createAgentAbortContext(input.abortSignal, policy, executionLease.signal);
558
+ let executionEnvironmentSession;
559
+ let executionEnvironmentStatus = "failed";
560
+ let executionEnvironmentError;
561
+ try {
562
+ executionEnvironmentSession = await acquireExecutionEnvironment(context.executionEnvironment, context.state, context.context, abortContext.signal);
563
+ }
564
+ catch (error) {
565
+ abortContext.cleanup();
566
+ await executionLease.release();
567
+ throw error;
568
+ }
569
+ try {
570
+ const result = await withAgentTelemetryRunContext(agent, context.state.runId, () => withAgentPolicyTimeout(generateText(createGenerateOptions(agent, context.state, input, context.messages, context.remainingSteps, context.context, executionEnvironmentSession, abortContext.signal)), abortContext));
571
+ const cancelled = executionLease.cancelledState();
572
+ if (cancelled) {
573
+ executionEnvironmentStatus = cancelled.status;
574
+ await emitRunFinishTelemetry(agent, cancelled);
575
+ return returnInvocationOutput(toOutput(cancelled));
576
+ }
577
+ if (executionLease.leaseLost()) {
578
+ throw new ConflictError(`Agent run "${context.state.runId}" lost its worker lease.`);
579
+ }
580
+ const newSteps = mapSteps(result.steps, context.state.currentStep, result.toolResults);
581
+ let output = finalizeState(agent, context.state, result, newSteps, result.toolResults);
582
+ const outputGuardrail = await runGuardrails(agent, output.state, "output", agent.outputGuardrails, () => ({
583
+ runId: output.state.runId,
584
+ agentId: output.state.agentId,
585
+ context: context.context,
586
+ state: cloneState(output.state),
587
+ output,
588
+ metadata: output.state.metadata
589
+ }));
590
+ if (outputGuardrail) {
591
+ output = toOutput(applyGuardrailFailure(output.state, "output", outputGuardrail));
592
+ }
593
+ await emitFinalizedStepTelemetry(agent, output.state, newSteps);
594
+ await emitApprovalTelemetry(agent, output.state, [
595
+ ...(result.approvalRequests ?? []),
596
+ ...approvalsFromEvents(newSteps.flatMap((step) => step.response?.messages ?? []))
597
+ ]);
598
+ await persistState(agent, output.state, policy);
599
+ output.taskOutcome = output.state.taskOutcome;
600
+ await emitRunFinishTelemetry(agent, output.state);
601
+ executionEnvironmentStatus = output.status;
602
+ return returnInvocationOutput(output);
603
+ }
604
+ catch (error) {
605
+ executionEnvironmentError = {
606
+ message: error instanceof Error ? error.message : String(error)
607
+ };
608
+ const cancelled = executionLease.cancelledState();
609
+ if (cancelled) {
610
+ executionEnvironmentStatus = cancelled.status;
611
+ await emitRunFinishTelemetry(agent, cancelled);
612
+ return returnInvocationOutput(toOutput(cancelled));
613
+ }
614
+ if (executionLease.leaseLost()) {
615
+ throw new ConflictError(`Agent run "${context.state.runId}" lost its worker lease.`);
616
+ }
617
+ if (error instanceof AgentPolicyTimeoutError || abortContext.isTimedOut()) {
618
+ const status = policy?.onTimeout === "cancel-requested" ? "cancel_requested" : "timed_out";
619
+ const message = error instanceof Error ? error.message : `Agent run timed out after ${policy?.timeoutMs}ms.`;
620
+ const durableState = agent.store
621
+ ? normalizeAgentRunState((await agent.store.load(context.state.runId, context.state.scope)) ?? context.state)
622
+ : context.state;
623
+ const timedOutState = createTerminalState(durableState, status, message);
624
+ await persistState(agent, timedOutState, policy);
625
+ await emitRunFinishTelemetry(agent, timedOutState);
626
+ executionEnvironmentStatus = timedOutState.status;
627
+ return returnInvocationOutput(toOutput(timedOutState));
628
+ }
629
+ const durableState = agent.store
630
+ ? normalizeAgentRunState((await agent.store.load(context.state.runId, context.state.scope)) ?? context.state)
631
+ : context.state;
632
+ const failedState = createFailedState(durableState, error);
633
+ await persistState(agent, failedState, policy);
634
+ await emitRunFinishTelemetry(agent, failedState);
635
+ executionEnvironmentStatus = failedState.status;
636
+ throw error;
637
+ }
638
+ finally {
639
+ await executionEnvironmentSession?.release?.({
640
+ status: executionEnvironmentStatus,
641
+ error: executionEnvironmentError
642
+ });
643
+ await executionLease.release();
644
+ }
645
+ }
646
+ catch (error) {
647
+ invocationStatus = "failed";
648
+ invocationError = error instanceof Error ? error : new Error(String(error));
649
+ throw error;
650
+ }
651
+ finally {
652
+ await emitInvocationFinishTelemetry(agent, telemetryRunId, invocationStatus, invocationError);
653
+ }
654
+ };
655
+ export const streamAgent = (agent, input = {}) => {
656
+ const invocationStartedAt = Date.now();
657
+ const telemetryRunId = input.runId ?? input.state?.runId ?? randomId("run");
658
+ const invocationInput = input.runId || input.state
659
+ ? input
660
+ : { ...input, runId: telemetryRunId };
661
+ const policy = resolveRunPolicy(agent, input);
662
+ const broadcast = new BoundedReplayBroadcast({
663
+ maxHistory: policy?.maxStreamEvents ?? 4096
664
+ });
665
+ let viewReady = false;
666
+ const pendingViews = new Map();
667
+ const publish = async (event, terminal = false) => {
668
+ await broadcast.publish(event, { terminal });
669
+ if (event.type === "agent-run-start") {
670
+ viewReady = true;
671
+ for (const run of pendingViews.values())
672
+ await broadcast.publish({ type: "agent-run-update", run });
673
+ pendingViews.clear();
674
+ }
675
+ };
676
+ agent = { ...agent, policy: { ...agent.policy, ...input.policy },
677
+ [runViewParent]: input.parentRunId ?? input.state?.parentRunId,
678
+ [runViewSink]: createRunViewSink(async (run) => {
679
+ if (broadcast.isClosed)
680
+ return;
681
+ if (!viewReady) {
682
+ pendingViews.set(run.runId, run);
683
+ return;
684
+ }
685
+ await publish({ type: "agent-run-update", run });
686
+ })
687
+ };
688
+ let activeLease;
689
+ let activeExecutionEnvironment;
690
+ let invocationFinishPromise;
691
+ const finishInvocation = (status, error) => {
692
+ invocationFinishPromise ??= emitInvocationFinishTelemetry(agent, telemetryRunId, status, error);
693
+ return invocationFinishPromise;
694
+ };
695
+ const runner = (async () => {
696
+ await emitInvocationStartTelemetry(agent, telemetryRunId, invocationStartedAt, Math.max(1, input.maxSteps ?? input.state?.maxSteps ?? agent.maxSteps ?? 1));
697
+ const context = await resolveContext(agent, invocationInput);
698
+ const currentStatus = normalizeApprovalStatus(context.state.status);
699
+ const supportsLeases = Boolean(agent.store?.acquireLease && agent.store.renewLease && agent.store.releaseLease);
700
+ if (!context.fresh && currentStatus === "running" && !supportsLeases) {
701
+ broadcast.close();
702
+ await finishInvocation(currentStatus);
703
+ return {
704
+ output: toOutput(context.state),
705
+ textStream: emptyAsyncIterable()
706
+ };
707
+ }
708
+ if (currentStatus === "completed" ||
709
+ currentStatus === "cancelled" ||
710
+ currentStatus === "cancel_requested" ||
711
+ currentStatus === "timed_out") {
712
+ context.state.status = currentStatus;
713
+ broadcast.close();
714
+ await finishInvocation(currentStatus);
715
+ return {
716
+ output: toOutput(context.state),
717
+ textStream: emptyAsyncIterable()
718
+ };
719
+ }
720
+ if (currentStatus === "waiting_approval" && context.state.pendingApprovals.length > 0) {
721
+ context.state.status = currentStatus;
722
+ broadcast.close();
723
+ await finishInvocation(currentStatus);
724
+ return {
725
+ output: toOutput(context.state),
726
+ textStream: emptyAsyncIterable()
727
+ };
728
+ }
729
+ const freshRequiresExistingClaim = context.fresh && Boolean(context.state.idempotencyKey);
730
+ if (context.fresh && !freshRequiresExistingClaim) {
731
+ await claimAgentExecution(agent, context.state);
732
+ }
733
+ const executionLease = await acquireAgentExecutionLease(agent, context.state, policy);
734
+ if (!executionLease) {
735
+ if (input.state) {
736
+ throw new ConflictError(`Agent run "${context.state.runId}" is already owned by another worker.`);
737
+ }
738
+ const activeState = await agent.store?.load(context.state.runId, context.state.scope);
739
+ broadcast.close();
740
+ const outputState = activeState ? normalizeAgentRunState(activeState) : context.state;
741
+ await finishInvocation(outputState.status);
742
+ return {
743
+ output: toOutput(outputState),
744
+ textStream: emptyAsyncIterable()
745
+ };
746
+ }
747
+ activeLease = executionLease;
748
+ try {
749
+ if (!context.fresh || freshRequiresExistingClaim) {
750
+ await claimAgentExecution(agent, context.state);
751
+ }
752
+ await emitRunStartTelemetry(agent, context.state, context.memoryMessages, input.approvals, invocationStartedAt);
753
+ }
754
+ catch (error) {
755
+ await executionLease.release();
756
+ throw error;
757
+ }
758
+ if (context.remainingSteps === 0) {
759
+ const state = createFailedState(context.state, "Agent exhausted maxSteps before reaching a terminal response.");
760
+ await persistState(agent, state, policy);
761
+ await emitRunFinishTelemetry(agent, state);
762
+ await executionLease.release();
763
+ broadcast.close();
764
+ await finishInvocation(state.status);
765
+ return {
766
+ output: toOutput(state),
767
+ textStream: emptyAsyncIterable()
768
+ };
769
+ }
770
+ let inputGuardrail;
771
+ try {
772
+ inputGuardrail = await runGuardrails(agent, context.state, "input", agent.inputGuardrails, () => ({
773
+ runId: context.state.runId,
774
+ agentId: context.state.agentId,
775
+ context: context.context,
776
+ state: cloneState(context.state),
777
+ messages: context.messages,
778
+ metadata: context.state.metadata
779
+ }));
780
+ }
781
+ catch (error) {
782
+ await executionLease.release();
783
+ throw error;
784
+ }
785
+ if (inputGuardrail) {
786
+ const failedState = applyGuardrailFailure(context.state, "input", inputGuardrail);
787
+ await persistState(agent, failedState, policy);
788
+ await emitRunFinishTelemetry(agent, failedState);
789
+ await publish({
790
+ type: "error",
791
+ error: new GuardrailTriggeredError("input", failedState.error?.message ?? "Agent input guardrail triggered.", {
792
+ metadata: inputGuardrail.metadata
793
+ })
794
+ }, true);
795
+ await publish({
796
+ type: "agent-run-finish",
797
+ status: failedState.status,
798
+ state: failedState
799
+ }, true);
800
+ broadcast.close();
801
+ await executionLease.release();
802
+ await finishInvocation(failedState.status);
803
+ return {
804
+ output: toOutput(failedState),
805
+ textStream: emptyAsyncIterable()
806
+ };
807
+ }
808
+ await publish({
809
+ type: "agent-run-start",
810
+ currentStep: context.state.currentStep + 1,
811
+ maxSteps: context.state.maxSteps
812
+ });
813
+ for (const approval of input.approvals ?? []) {
814
+ await publish({
815
+ type: "agent-approval-resolved",
816
+ approval
817
+ });
818
+ }
819
+ await publish({
820
+ type: "agent-step-start",
821
+ stepIndex: context.state.currentStep + 1
822
+ });
823
+ const abortContext = createAgentAbortContext(input.abortSignal, policy, executionLease.signal);
824
+ let executionEnvironmentSession;
825
+ try {
826
+ executionEnvironmentSession = await acquireExecutionEnvironment(context.executionEnvironment, context.state, context.context, abortContext.signal);
827
+ }
828
+ catch (error) {
829
+ abortContext.cleanup();
830
+ await executionLease.release();
831
+ throw error;
832
+ }
833
+ activeExecutionEnvironment = executionEnvironmentSession;
834
+ let executionEnvironmentStatus = "failed";
835
+ let executionEnvironmentError;
836
+ let streamResult;
837
+ try {
838
+ streamResult = streamText(createGenerateOptions(agent, context.state, input, context.messages, context.remainingSteps, context.context, executionEnvironmentSession, abortContext.signal, async (record) => {
839
+ await publish({
840
+ type: "agent-compaction",
841
+ compaction: record
842
+ });
843
+ }));
844
+ }
845
+ catch (error) {
846
+ abortContext.cleanup();
847
+ executionEnvironmentError = {
848
+ message: error instanceof Error ? error.message : String(error)
849
+ };
850
+ await executionEnvironmentSession?.release?.({
851
+ status: "failed",
852
+ error: executionEnvironmentError
853
+ });
854
+ activeExecutionEnvironment = undefined;
855
+ await executionLease.release();
856
+ throw error;
857
+ }
858
+ const approvalRequests = [];
859
+ const eventRelay = withAgentTelemetryRunContext(agent, context.state.runId, async () => {
860
+ for await (const event of streamResult.eventStream) {
861
+ await publish(event);
862
+ if (event.type === "tool-approval-request") {
863
+ approvalRequests.push(event.approval);
864
+ await publish({
865
+ type: "agent-approval-request",
866
+ approval: event.approval
867
+ });
868
+ await emitTelemetryEvent(agent, {
869
+ type: "approval-request",
870
+ runId: context.state.runId,
871
+ agentId: context.state.agentId,
872
+ approval: event.approval
873
+ });
874
+ }
875
+ if (event.type === "provider-data" &&
876
+ typeof event.data === "object" &&
877
+ event.data !== null &&
878
+ !Array.isArray(event.data) &&
879
+ event.data.type === "mcp_approval_request" &&
880
+ typeof event.data.id === "string" &&
881
+ typeof event.data.name === "string" &&
882
+ typeof event.data.arguments === "string") {
883
+ const approval = {
884
+ provider: event.provider,
885
+ id: event.data.id,
886
+ name: event.data.name,
887
+ arguments: event.data.arguments,
888
+ serverLabel: typeof event.data.server_label === "string" ? event.data.server_label : undefined,
889
+ rawData: event.data
890
+ };
891
+ approvalRequests.push(approval);
892
+ await publish({
893
+ type: "agent-approval-request",
894
+ approval
895
+ });
896
+ await emitTelemetryEvent(agent, {
897
+ type: "approval-request",
898
+ runId: context.state.runId,
899
+ agentId: context.state.agentId,
900
+ approval
901
+ });
902
+ }
903
+ }
904
+ });
905
+ const output = (async () => {
906
+ try {
907
+ const final = await withAgentPolicyTimeout(eventRelay.then(() => streamResult.collect()), abortContext);
908
+ const cancelled = executionLease.cancelledState();
909
+ if (cancelled) {
910
+ executionEnvironmentStatus = cancelled.status;
911
+ await emitRunFinishTelemetry(agent, cancelled);
912
+ await publish({
913
+ type: "agent-run-finish",
914
+ status: cancelled.status,
915
+ state: cancelled
916
+ }, true);
917
+ broadcast.close();
918
+ return toOutput(cancelled);
919
+ }
920
+ if (executionLease.leaseLost()) {
921
+ const conflict = new ConflictError(`Agent run "${context.state.runId}" lost its worker lease.`);
922
+ broadcast.fail(conflict);
923
+ throw conflict;
924
+ }
925
+ const newSteps = mapSteps(final.steps, context.state.currentStep, final.toolResults);
926
+ let result = finalizeState(agent, context.state, final, newSteps, final.toolResults);
927
+ const outputGuardrail = await runGuardrails(agent, result.state, "output", agent.outputGuardrails, () => ({
928
+ runId: result.state.runId,
929
+ agentId: result.state.agentId,
930
+ context: context.context,
931
+ state: cloneState(result.state),
932
+ output: result,
933
+ metadata: result.state.metadata
934
+ }));
935
+ if (outputGuardrail) {
936
+ result = toOutput(applyGuardrailFailure(result.state, "output", outputGuardrail));
937
+ await publish({
938
+ type: "error",
939
+ error: new GuardrailTriggeredError("output", result.state.error?.message ?? "Agent output guardrail triggered.", { metadata: outputGuardrail.metadata })
940
+ }, true);
941
+ }
942
+ for (const step of newSteps) {
943
+ await publish({
944
+ type: "agent-step-finish",
945
+ step
946
+ });
947
+ }
948
+ await emitFinalizedStepTelemetry(agent, result.state, newSteps);
949
+ if (!approvalRequests.length) {
950
+ await emitApprovalTelemetry(agent, result.state, approvalsFromEvents(newSteps.flatMap((step) => step.response?.messages ?? [])));
951
+ }
952
+ await persistState(agent, result.state, policy);
953
+ result.taskOutcome = result.state.taskOutcome;
954
+ await emitRunFinishTelemetry(agent, result.state);
955
+ await publish({
956
+ type: "agent-run-finish",
957
+ status: result.status,
958
+ state: result.state
959
+ }, true);
960
+ broadcast.close();
961
+ executionEnvironmentStatus = result.status;
962
+ return result;
963
+ }
964
+ catch (error) {
965
+ executionEnvironmentError = {
966
+ message: error instanceof Error ? error.message : String(error)
967
+ };
968
+ const cancelled = executionLease.cancelledState();
969
+ if (cancelled) {
970
+ executionEnvironmentStatus = cancelled.status;
971
+ await emitRunFinishTelemetry(agent, cancelled);
972
+ await publish({
973
+ type: "agent-run-finish",
974
+ status: cancelled.status,
975
+ state: cancelled
976
+ }, true);
977
+ broadcast.close();
978
+ return toOutput(cancelled);
979
+ }
980
+ if (executionLease.leaseLost()) {
981
+ const conflict = new ConflictError(`Agent run "${context.state.runId}" lost its worker lease.`);
982
+ broadcast.fail(conflict);
983
+ throw conflict;
984
+ }
985
+ if (error instanceof AgentPolicyTimeoutError || abortContext.isTimedOut()) {
986
+ const status = policy?.onTimeout === "cancel-requested" ? "cancel_requested" : "timed_out";
987
+ const message = error instanceof Error ? error.message : `Agent run timed out after ${policy?.timeoutMs}ms.`;
988
+ const durableState = agent.store
989
+ ? normalizeAgentRunState((await agent.store.load(context.state.runId, context.state.scope)) ?? context.state)
990
+ : context.state;
991
+ const timedOutState = createTerminalState(durableState, status, message);
992
+ await persistState(agent, timedOutState, policy);
993
+ await emitRunFinishTelemetry(agent, timedOutState);
994
+ await publish({
995
+ type: "error",
996
+ error: new AgentPolicyTimeoutError(policy?.timeoutMs ?? 0)
997
+ }, true);
998
+ await publish({
999
+ type: "agent-run-finish",
1000
+ status: timedOutState.status,
1001
+ state: timedOutState
1002
+ }, true);
1003
+ broadcast.close();
1004
+ executionEnvironmentStatus = timedOutState.status;
1005
+ return toOutput(timedOutState);
1006
+ }
1007
+ const durableState = agent.store
1008
+ ? normalizeAgentRunState((await agent.store.load(context.state.runId, context.state.scope)) ?? context.state)
1009
+ : context.state;
1010
+ const failedState = createFailedState(durableState, error);
1011
+ await persistState(agent, failedState, policy);
1012
+ await emitRunFinishTelemetry(agent, failedState);
1013
+ await publish({
1014
+ type: "error",
1015
+ error: error instanceof Error ? error : new Error(String(error))
1016
+ }, true);
1017
+ await publish({
1018
+ type: "agent-run-finish",
1019
+ status: failedState.status,
1020
+ state: failedState
1021
+ }, true);
1022
+ broadcast.close();
1023
+ executionEnvironmentStatus = failedState.status;
1024
+ throw error;
1025
+ }
1026
+ finally {
1027
+ await executionEnvironmentSession?.release?.({
1028
+ status: executionEnvironmentStatus,
1029
+ error: executionEnvironmentError
1030
+ });
1031
+ activeExecutionEnvironment = undefined;
1032
+ await executionLease.release();
1033
+ }
1034
+ })().finally(() => finishInvocation(executionEnvironmentStatus, executionEnvironmentError ? new Error(executionEnvironmentError.message) : undefined));
1035
+ return {
1036
+ output,
1037
+ textStream: streamResult.textStream
1038
+ };
1039
+ })().catch(async (error) => {
1040
+ await finishInvocation("failed", error instanceof Error ? error : new Error(String(error)));
1041
+ await activeExecutionEnvironment?.release?.({
1042
+ status: "failed",
1043
+ error: { message: error instanceof Error ? error.message : String(error) }
1044
+ });
1045
+ activeExecutionEnvironment = undefined;
1046
+ await activeLease?.release();
1047
+ broadcast.fail(error);
1048
+ throw error;
1049
+ });
1050
+ return {
1051
+ eventStream: broadcast.stream(),
1052
+ textStream: (async function* () {
1053
+ const started = await runner;
1054
+ for await (const chunk of started.textStream) {
1055
+ yield chunk;
1056
+ }
1057
+ })(),
1058
+ collect: async () => (await runner).output
1059
+ };
1060
+ };
1061
+ export const resumeAgent = async (agent, input) => runAgent(agent, input);
1062
+ //# sourceMappingURL=execution.js.map