@zhivex-ai/core 1.18.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.
- package/README.md +4 -0
- package/dist/agent/approvals.d.ts +7 -0
- package/dist/agent/approvals.d.ts.map +1 -0
- package/dist/agent/approvals.js +97 -0
- package/dist/agent/approvals.js.map +1 -0
- package/dist/agent/cancellation.d.ts +4 -0
- package/dist/agent/cancellation.d.ts.map +1 -0
- package/dist/agent/cancellation.js +69 -0
- package/dist/agent/cancellation.js.map +1 -0
- package/dist/agent/common.d.ts +20 -0
- package/dist/agent/common.d.ts.map +1 -0
- package/dist/agent/common.js +150 -0
- package/dist/agent/common.js.map +1 -0
- package/dist/agent/compaction.d.ts +6 -0
- package/dist/agent/compaction.d.ts.map +1 -0
- package/dist/agent/compaction.js +156 -0
- package/dist/agent/compaction.js.map +1 -0
- package/dist/agent/context.d.ts +58 -0
- package/dist/agent/context.d.ts.map +1 -0
- package/dist/agent/context.js +267 -0
- package/dist/agent/context.js.map +1 -0
- package/dist/agent/definition.d.ts +4 -0
- package/dist/agent/definition.d.ts.map +1 -0
- package/dist/agent/definition.js +35 -0
- package/dist/agent/definition.js.map +1 -0
- package/dist/agent/execution.d.ts +14 -0
- package/dist/agent/execution.d.ts.map +1 -0
- package/dist/agent/execution.js +1062 -0
- package/dist/agent/execution.js.map +1 -0
- package/dist/agent/groups.d.ts +3 -0
- package/dist/agent/groups.d.ts.map +1 -0
- package/dist/agent/groups.js +130 -0
- package/dist/agent/groups.js.map +1 -0
- package/dist/agent/guardrails.d.ts +4 -0
- package/dist/agent/guardrails.d.ts.map +1 -0
- package/dist/agent/guardrails.js +29 -0
- package/dist/agent/guardrails.js.map +1 -0
- package/dist/agent/instance.d.ts +42 -0
- package/dist/agent/instance.d.ts.map +1 -0
- package/dist/agent/instance.js +82 -0
- package/dist/agent/instance.js.map +1 -0
- package/dist/agent/lifecycle.d.ts +31 -0
- package/dist/agent/lifecycle.d.ts.map +1 -0
- package/dist/agent/lifecycle.js +184 -0
- package/dist/agent/lifecycle.js.map +1 -0
- package/dist/agent/state.d.ts +6 -0
- package/dist/agent/state.d.ts.map +1 -0
- package/dist/agent/state.js +119 -0
- package/dist/agent/state.js.map +1 -0
- package/dist/agent/telemetry.d.ts +12 -0
- package/dist/agent/telemetry.d.ts.map +1 -0
- package/dist/agent/telemetry.js +176 -0
- package/dist/agent/telemetry.js.map +1 -0
- package/dist/agent/tool-execution.d.ts +6 -0
- package/dist/agent/tool-execution.d.ts.map +1 -0
- package/dist/agent/tool-execution.js +176 -0
- package/dist/agent/tool-execution.js.map +1 -0
- package/dist/agent-run-view.d.ts +9 -0
- package/dist/agent-run-view.d.ts.map +1 -0
- package/dist/agent-run-view.js +42 -0
- package/dist/agent-run-view.js.map +1 -0
- package/dist/agent-store/file.d.ts +11 -0
- package/dist/agent-store/file.d.ts.map +1 -0
- package/dist/agent-store/file.js +534 -0
- package/dist/agent-store/file.js.map +1 -0
- package/dist/agent-store/memory.d.ts +9 -0
- package/dist/agent-store/memory.d.ts.map +1 -0
- package/dist/agent-store/memory.js +198 -0
- package/dist/agent-store/memory.js.map +1 -0
- package/dist/agent-store/postgres.d.ts +4 -0
- package/dist/agent-store/postgres.d.ts.map +1 -0
- package/dist/agent-store/postgres.js +374 -0
- package/dist/agent-store/postgres.js.map +1 -0
- package/dist/agent-store/shared.d.ts +19 -0
- package/dist/agent-store/shared.d.ts.map +1 -0
- package/dist/agent-store/shared.js +137 -0
- package/dist/agent-store/shared.js.map +1 -0
- package/dist/agent-store/sqlite.d.ts +4 -0
- package/dist/agent-store/sqlite.d.ts.map +1 -0
- package/dist/agent-store/sqlite.js +362 -0
- package/dist/agent-store/sqlite.js.map +1 -0
- package/dist/agent-store.d.ts +5 -21
- package/dist/agent-store.d.ts.map +1 -1
- package/dist/agent-store.js +5 -1588
- package/dist/agent-store.js.map +1 -1
- package/dist/agent.d.ts +6 -57
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +6 -2631
- package/dist/agent.js.map +1 -1
- package/dist/agents-entry.d.ts +19 -0
- package/dist/agents-entry.d.ts.map +1 -0
- package/dist/agents-entry.js +14 -0
- package/dist/agents-entry.js.map +1 -0
- package/dist/artifact/file.d.ts +6 -0
- package/dist/artifact/file.d.ts.map +1 -0
- package/dist/artifact/file.js +380 -0
- package/dist/artifact/file.js.map +1 -0
- package/dist/artifact/memory.d.ts +3 -0
- package/dist/artifact/memory.d.ts.map +1 -0
- package/dist/artifact/memory.js +80 -0
- package/dist/artifact/memory.js.map +1 -0
- package/dist/artifact/postgres.d.ts +3 -0
- package/dist/artifact/postgres.d.ts.map +1 -0
- package/dist/artifact/postgres.js +283 -0
- package/dist/artifact/postgres.js.map +1 -0
- package/dist/artifact/shared.d.ts +208 -0
- package/dist/artifact/shared.d.ts.map +1 -0
- package/dist/artifact/shared.js +523 -0
- package/dist/artifact/shared.js.map +1 -0
- package/dist/artifact/sqlite.d.ts +3 -0
- package/dist/artifact/sqlite.d.ts.map +1 -0
- package/dist/artifact/sqlite.js +283 -0
- package/dist/artifact/sqlite.js.map +1 -0
- package/dist/artifact.d.ts +6 -186
- package/dist/artifact.d.ts.map +1 -1
- package/dist/artifact.js +6 -1536
- package/dist/artifact.js.map +1 -1
- package/dist/catalog-contracts.d.ts +52 -0
- package/dist/catalog-contracts.d.ts.map +1 -0
- package/dist/catalog-contracts.js +250 -0
- package/dist/catalog-contracts.js.map +1 -0
- package/dist/catalog.d.ts +3 -52
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +3 -249
- package/dist/catalog.js.map +1 -1
- package/dist/generate-cache-file.d.ts +11 -0
- package/dist/generate-cache-file.d.ts.map +1 -0
- package/dist/generate-cache-file.js +124 -0
- package/dist/generate-cache-file.js.map +1 -0
- package/dist/generate-text.d.ts +2 -5
- package/dist/generate-text.d.ts.map +1 -1
- package/dist/generate-text.js +3 -18
- package/dist/generate-text.js.map +1 -1
- package/dist/generation-entry.d.ts +6 -0
- package/dist/generation-entry.d.ts.map +1 -0
- package/dist/generation-entry.js +6 -0
- package/dist/generation-entry.js.map +1 -0
- package/dist/middleware-runtime.d.ts +35 -0
- package/dist/middleware-runtime.d.ts.map +1 -0
- package/dist/middleware-runtime.js +532 -0
- package/dist/middleware-runtime.js.map +1 -0
- package/dist/middleware.d.ts +3 -43
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +3 -653
- package/dist/middleware.js.map +1 -1
- package/dist/normalize-messages.d.ts +3 -0
- package/dist/normalize-messages.d.ts.map +1 -0
- package/dist/normalize-messages.js +16 -0
- package/dist/normalize-messages.js.map +1 -0
- package/dist/provider-entry.d.ts +17 -0
- package/dist/provider-entry.d.ts.map +1 -0
- package/dist/provider-entry.js +13 -0
- package/dist/provider-entry.js.map +1 -0
- package/dist/realtime.d.ts +2 -0
- package/dist/realtime.d.ts.map +1 -1
- package/dist/realtime.js +6 -0
- package/dist/realtime.js.map +1 -1
- package/dist/store-key.d.ts +3 -0
- package/dist/store-key.d.ts.map +1 -0
- package/dist/store-key.js +5 -0
- package/dist/store-key.js.map +1 -0
- package/dist/store-security.d.ts +1 -2
- package/dist/store-security.d.ts.map +1 -1
- package/dist/store-security.js +2 -4
- package/dist/store-security.js.map +1 -1
- package/dist/types/agent-state.d.ts +236 -0
- package/dist/types/agent-state.d.ts.map +1 -0
- package/dist/types/agent-state.js +2 -0
- package/dist/types/agent-state.js.map +1 -0
- package/dist/types/agents.d.ts +429 -0
- package/dist/types/agents.d.ts.map +1 -0
- package/dist/types/agents.js +2 -0
- package/dist/types/agents.js.map +1 -0
- package/dist/types/common.d.ts +179 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +2 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/generation.d.ts +109 -0
- package/dist/types/generation.d.ts.map +1 -0
- package/dist/types/generation.js +2 -0
- package/dist/types/generation.js.map +1 -0
- package/dist/types/media-data.d.ts +65 -0
- package/dist/types/media-data.d.ts.map +1 -0
- package/dist/types/media-data.js +2 -0
- package/dist/types/media-data.js.map +1 -0
- package/dist/types/media.d.ts +141 -0
- package/dist/types/media.d.ts.map +1 -0
- package/dist/types/media.js +2 -0
- package/dist/types/media.js.map +1 -0
- package/dist/types/messages.d.ts +82 -0
- package/dist/types/messages.d.ts.map +1 -0
- package/dist/types/messages.js +2 -0
- package/dist/types/messages.js.map +1 -0
- package/dist/types/middleware.d.ts +130 -0
- package/dist/types/middleware.d.ts.map +1 -0
- package/dist/types/middleware.js +2 -0
- package/dist/types/middleware.js.map +1 -0
- package/dist/types/model-tools.d.ts +409 -0
- package/dist/types/model-tools.d.ts.map +1 -0
- package/dist/types/model-tools.js +2 -0
- package/dist/types/model-tools.js.map +1 -0
- package/dist/types/persistence.d.ts +168 -0
- package/dist/types/persistence.d.ts.map +1 -0
- package/dist/types/persistence.js +2 -0
- package/dist/types/persistence.js.map +1 -0
- package/dist/types/provider-resources.d.ts +336 -0
- package/dist/types/provider-resources.d.ts.map +1 -0
- package/dist/types/provider-resources.js +2 -0
- package/dist/types/provider-resources.js.map +1 -0
- package/dist/types/provider.d.ts +23 -0
- package/dist/types/provider.d.ts.map +1 -0
- package/dist/types/provider.js +2 -0
- package/dist/types/provider.js.map +1 -0
- package/dist/types/resource-options.d.ts +88 -0
- package/dist/types/resource-options.d.ts.map +1 -0
- package/dist/types/resource-options.js +2 -0
- package/dist/types/resource-options.js.map +1 -0
- package/dist/types/stream.d.ts +70 -0
- package/dist/types/stream.d.ts.map +1 -0
- package/dist/types/stream.js +2 -0
- package/dist/types/stream.js.map +1 -0
- package/dist/types/ui.d.ts +110 -0
- package/dist/types/ui.d.ts.map +1 -0
- package/dist/types/ui.js +2 -0
- package/dist/types/ui.js.map +1 -0
- package/dist/types.d.ts +16 -2480
- package/dist/types.d.ts.map +1 -1
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +2 -0
- package/dist/ui.js.map +1 -1
- package/dist/workflow-state-service/file.d.ts +5 -0
- package/dist/workflow-state-service/file.d.ts.map +1 -0
- package/dist/workflow-state-service/file.js +142 -0
- package/dist/workflow-state-service/file.js.map +1 -0
- package/dist/workflow-state-service/memory.d.ts +3 -0
- package/dist/workflow-state-service/memory.d.ts.map +1 -0
- package/dist/workflow-state-service/memory.js +27 -0
- package/dist/workflow-state-service/memory.js.map +1 -0
- package/dist/workflow-state-service/postgres.d.ts +4 -0
- package/dist/workflow-state-service/postgres.d.ts.map +1 -0
- package/dist/workflow-state-service/postgres.js +179 -0
- package/dist/workflow-state-service/postgres.js.map +1 -0
- package/dist/workflow-state-service/shared.d.ts +43 -0
- package/dist/workflow-state-service/shared.d.ts.map +1 -0
- package/dist/workflow-state-service/shared.js +107 -0
- package/dist/workflow-state-service/shared.js.map +1 -0
- package/dist/workflow-state-service/sqlite.d.ts +4 -0
- package/dist/workflow-state-service/sqlite.d.ts.map +1 -0
- package/dist/workflow-state-service/sqlite.js +183 -0
- package/dist/workflow-state-service/sqlite.js.map +1 -0
- package/dist/workflow-state-service.d.ts +6 -33
- package/dist/workflow-state-service.d.ts.map +1 -1
- package/dist/workflow-state-service.js +6 -626
- package/dist/workflow-state-service.js.map +1 -1
- 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
|