@rowan-agent/agent 0.10.0 → 0.10.2
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/dist/index.d.ts +121 -90
- package/dist/index.js +529 -142
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -55,78 +55,6 @@ type ToolResult = {
|
|
|
55
55
|
error?: string;
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
-
interface BeforePhaseEvent {
|
|
59
|
-
type: "before_phase";
|
|
60
|
-
phaseId: string;
|
|
61
|
-
input: PhaseContext;
|
|
62
|
-
}
|
|
63
|
-
interface AfterPhaseEvent {
|
|
64
|
-
type: "after_phase";
|
|
65
|
-
phaseId: string;
|
|
66
|
-
output: PhaseOutput;
|
|
67
|
-
}
|
|
68
|
-
interface BeforePromptEvent {
|
|
69
|
-
type: "before_prompt";
|
|
70
|
-
phaseId: string;
|
|
71
|
-
input: PhaseContext;
|
|
72
|
-
}
|
|
73
|
-
interface BeforeToolCallEvent {
|
|
74
|
-
type: "before_tool_call";
|
|
75
|
-
tool: Tool$1;
|
|
76
|
-
args: unknown;
|
|
77
|
-
}
|
|
78
|
-
interface AfterToolCallEvent {
|
|
79
|
-
type: "after_tool_call";
|
|
80
|
-
tool: Tool$1;
|
|
81
|
-
result: ToolResult;
|
|
82
|
-
}
|
|
83
|
-
type HookEvent = BeforePhaseEvent | AfterPhaseEvent | BeforePromptEvent | BeforeToolCallEvent | AfterToolCallEvent;
|
|
84
|
-
interface BeforePhaseResult {
|
|
85
|
-
abort?: Outcome$1;
|
|
86
|
-
skip?: {
|
|
87
|
-
route: string;
|
|
88
|
-
message: string;
|
|
89
|
-
};
|
|
90
|
-
input?: PhaseContext;
|
|
91
|
-
}
|
|
92
|
-
interface AfterPhaseResult {
|
|
93
|
-
abort?: Outcome$1;
|
|
94
|
-
retry?: PhaseContext;
|
|
95
|
-
output?: PhaseOutput;
|
|
96
|
-
}
|
|
97
|
-
interface BeforePromptResult {
|
|
98
|
-
input?: PhaseContext;
|
|
99
|
-
}
|
|
100
|
-
interface BeforeToolCallResult {
|
|
101
|
-
allow: boolean;
|
|
102
|
-
reason?: string;
|
|
103
|
-
}
|
|
104
|
-
interface AfterToolCallResult {
|
|
105
|
-
result?: ToolResult;
|
|
106
|
-
}
|
|
107
|
-
interface HookResultMap {
|
|
108
|
-
before_phase: BeforePhaseResult | undefined;
|
|
109
|
-
after_phase: AfterPhaseResult | undefined;
|
|
110
|
-
before_prompt: BeforePromptResult | undefined;
|
|
111
|
-
before_tool_call: BeforeToolCallResult | undefined;
|
|
112
|
-
after_tool_call: AfterToolCallResult | undefined;
|
|
113
|
-
}
|
|
114
|
-
type HookEventType = HookEvent["type"];
|
|
115
|
-
type HookHandler<K extends HookEventType> = (event: Extract<HookEvent, {
|
|
116
|
-
type: K;
|
|
117
|
-
}>) => HookResultMap[K] | Promise<HookResultMap[K]> | void | Promise<void>;
|
|
118
|
-
declare class HooksManager {
|
|
119
|
-
private handlers;
|
|
120
|
-
on<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
|
|
121
|
-
off<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
|
|
122
|
-
emit<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
|
|
123
|
-
type: K;
|
|
124
|
-
}>): Promise<void>;
|
|
125
|
-
emitFirst<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
|
|
126
|
-
type: K;
|
|
127
|
-
}>): Promise<HookResultMap[K] | undefined>;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
58
|
type LoopMetrics = {
|
|
131
59
|
/** Number of phase iterations executed. */
|
|
132
60
|
iterations: number;
|
|
@@ -194,6 +122,8 @@ type PhaseInteractionDriver = Readonly<{
|
|
|
194
122
|
}>): PhaseInteraction;
|
|
195
123
|
pending(): readonly PhaseInteraction[];
|
|
196
124
|
answers(): ReadonlyMap<string, JsonValue>;
|
|
125
|
+
checkpoint(): JsonValue | undefined;
|
|
126
|
+
clearCheckpoint(): void;
|
|
197
127
|
suspend(input?: Readonly<{
|
|
198
128
|
checkpoint?: JsonValue;
|
|
199
129
|
}>): never;
|
|
@@ -1115,6 +1045,95 @@ interface PhaseRegistry {
|
|
|
1115
1045
|
entryPhaseId: string | null;
|
|
1116
1046
|
}
|
|
1117
1047
|
|
|
1048
|
+
type ToolCallInteractionKind = PhaseInteractionKind;
|
|
1049
|
+
interface ToolCallInteractionRequest$1 {
|
|
1050
|
+
id?: string;
|
|
1051
|
+
kind: ToolCallInteractionKind;
|
|
1052
|
+
prompt: string;
|
|
1053
|
+
payload?: JsonValue;
|
|
1054
|
+
}
|
|
1055
|
+
interface BeforePhaseEvent {
|
|
1056
|
+
type: "before_phase";
|
|
1057
|
+
phaseId: string;
|
|
1058
|
+
input: PhaseContext;
|
|
1059
|
+
}
|
|
1060
|
+
interface AfterPhaseEvent {
|
|
1061
|
+
type: "after_phase";
|
|
1062
|
+
phaseId: string;
|
|
1063
|
+
output: PhaseOutput;
|
|
1064
|
+
}
|
|
1065
|
+
interface BeforePromptEvent {
|
|
1066
|
+
type: "before_prompt";
|
|
1067
|
+
phaseId: string;
|
|
1068
|
+
input: PhaseContext;
|
|
1069
|
+
}
|
|
1070
|
+
interface BeforeToolCallEvent {
|
|
1071
|
+
type: "before_tool_call";
|
|
1072
|
+
tool: Tool$1;
|
|
1073
|
+
args: unknown;
|
|
1074
|
+
readonly runId?: string;
|
|
1075
|
+
readonly agentId?: string;
|
|
1076
|
+
readonly toolCallId?: string;
|
|
1077
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
1078
|
+
readonly answer?: unknown;
|
|
1079
|
+
}
|
|
1080
|
+
interface AfterToolCallEvent {
|
|
1081
|
+
type: "after_tool_call";
|
|
1082
|
+
tool: Tool$1;
|
|
1083
|
+
result: ToolResult;
|
|
1084
|
+
readonly runId?: string;
|
|
1085
|
+
readonly agentId?: string;
|
|
1086
|
+
readonly toolCallId?: string;
|
|
1087
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
1088
|
+
}
|
|
1089
|
+
type HookEvent = BeforePhaseEvent | AfterPhaseEvent | BeforePromptEvent | BeforeToolCallEvent | AfterToolCallEvent;
|
|
1090
|
+
interface BeforePhaseResult {
|
|
1091
|
+
abort?: Outcome$1;
|
|
1092
|
+
skip?: {
|
|
1093
|
+
route: string;
|
|
1094
|
+
message: string;
|
|
1095
|
+
};
|
|
1096
|
+
input?: PhaseContext;
|
|
1097
|
+
}
|
|
1098
|
+
interface AfterPhaseResult {
|
|
1099
|
+
abort?: Outcome$1;
|
|
1100
|
+
retry?: PhaseContext;
|
|
1101
|
+
output?: PhaseOutput;
|
|
1102
|
+
}
|
|
1103
|
+
interface BeforePromptResult {
|
|
1104
|
+
input?: PhaseContext;
|
|
1105
|
+
}
|
|
1106
|
+
interface BeforeToolCallResult {
|
|
1107
|
+
allow?: boolean;
|
|
1108
|
+
reason?: string;
|
|
1109
|
+
interaction?: ToolCallInteractionRequest$1;
|
|
1110
|
+
}
|
|
1111
|
+
interface AfterToolCallResult {
|
|
1112
|
+
result?: ToolResult;
|
|
1113
|
+
}
|
|
1114
|
+
interface HookResultMap {
|
|
1115
|
+
before_phase: BeforePhaseResult | undefined;
|
|
1116
|
+
after_phase: AfterPhaseResult | undefined;
|
|
1117
|
+
before_prompt: BeforePromptResult | undefined;
|
|
1118
|
+
before_tool_call: BeforeToolCallResult | undefined;
|
|
1119
|
+
after_tool_call: AfterToolCallResult | undefined;
|
|
1120
|
+
}
|
|
1121
|
+
type HookEventType = HookEvent["type"];
|
|
1122
|
+
type HookHandler<K extends HookEventType> = (event: Extract<HookEvent, {
|
|
1123
|
+
type: K;
|
|
1124
|
+
}>) => HookResultMap[K] | Promise<HookResultMap[K]> | void | Promise<void>;
|
|
1125
|
+
declare class HooksManager {
|
|
1126
|
+
private handlers;
|
|
1127
|
+
on<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
|
|
1128
|
+
off<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
|
|
1129
|
+
emit<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
|
|
1130
|
+
type: K;
|
|
1131
|
+
}>): Promise<void>;
|
|
1132
|
+
emitFirst<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
|
|
1133
|
+
type: K;
|
|
1134
|
+
}>): Promise<HookResultMap[K] | undefined>;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1118
1137
|
type ToolContext = Pick<AgentContext, "skills"> & {
|
|
1119
1138
|
toolCallId: string;
|
|
1120
1139
|
};
|
|
@@ -1406,11 +1425,19 @@ declare class ExtensionRunner {
|
|
|
1406
1425
|
output?: PhaseOutput;
|
|
1407
1426
|
}>;
|
|
1408
1427
|
emitBeforePrompt(phaseId: string, input: PhaseContext): Promise<PhaseContext>;
|
|
1409
|
-
emitBeforeToolCall(tool: Tool$1, args: unknown
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1428
|
+
emitBeforeToolCall(tool: Tool$1, args: unknown, context?: {
|
|
1429
|
+
runId?: string;
|
|
1430
|
+
agentId?: string;
|
|
1431
|
+
toolCallId?: string;
|
|
1432
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
1433
|
+
answer?: unknown;
|
|
1434
|
+
}): Promise<BeforeToolCallResult>;
|
|
1435
|
+
emitAfterToolCall(tool: Tool$1, result: ToolResult, context?: {
|
|
1436
|
+
runId?: string;
|
|
1437
|
+
agentId?: string;
|
|
1438
|
+
toolCallId?: string;
|
|
1439
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
1440
|
+
}): Promise<ToolResult>;
|
|
1414
1441
|
/**
|
|
1415
1442
|
* Create an ExtensionAPI for a specific extension.
|
|
1416
1443
|
* Registration methods write to the extension tracking object.
|
|
@@ -1574,22 +1601,27 @@ type ContextCandidate = Readonly<{
|
|
|
1574
1601
|
name: string;
|
|
1575
1602
|
value: JsonValue;
|
|
1576
1603
|
}>;
|
|
1577
|
-
type
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
}
|
|
1604
|
+
type ToolCallInteractionRequest = Readonly<{
|
|
1605
|
+
id?: string;
|
|
1606
|
+
kind: PhaseInteractionKind;
|
|
1607
|
+
prompt: string;
|
|
1608
|
+
payload?: JsonValue;
|
|
1609
|
+
}>;
|
|
1610
|
+
type BeforeToolCallDecision = Readonly<{
|
|
1583
1611
|
allow: true;
|
|
1584
1612
|
}> | Readonly<{
|
|
1585
1613
|
allow: false;
|
|
1586
1614
|
reason: string;
|
|
1587
|
-
}> | Promise<Readonly<{
|
|
1588
|
-
allow: true;
|
|
1589
1615
|
}> | Readonly<{
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1616
|
+
interaction: ToolCallInteractionRequest;
|
|
1617
|
+
}>;
|
|
1618
|
+
type BeforeToolCall = (input: Readonly<{
|
|
1619
|
+
tool: Tool;
|
|
1620
|
+
args: JsonValue;
|
|
1621
|
+
context: ToolInvocationContext;
|
|
1622
|
+
signal: AbortSignal;
|
|
1623
|
+
answer?: JsonValue;
|
|
1624
|
+
}>) => BeforeToolCallDecision | Promise<BeforeToolCallDecision>;
|
|
1593
1625
|
type AfterToolCall = (input: Readonly<{
|
|
1594
1626
|
tool: Tool;
|
|
1595
1627
|
result: ToolExecutionResult$1;
|
|
@@ -2169,7 +2201,6 @@ declare class AgentRuntime implements AgentRuntime$1 {
|
|
|
2169
2201
|
private resolveContextWindow;
|
|
2170
2202
|
private executeTool;
|
|
2171
2203
|
private executeToolBatch;
|
|
2172
|
-
private executeReservedTool;
|
|
2173
2204
|
private requireAgent;
|
|
2174
2205
|
private archiveDirFor;
|
|
2175
2206
|
private runConsumer;
|
|
@@ -2782,4 +2813,4 @@ declare function parseFrontmatter<T = Record<string, unknown>>(raw: string): Fro
|
|
|
2782
2813
|
|
|
2783
2814
|
declare function createCoreTools(input?: CoreToolContext): Tool[];
|
|
2784
2815
|
|
|
2785
|
-
export { type AfterToolCall, type AgentConfiguration, type AgentDefinition, type AgentId, type AgentListCursor, type AgentRecord, type AgentRun, AgentRuntime, type AgentRuntimeOptions, type AgentSummary, type AnyRuntimeError, type AssistantContent, type AssistantMessage, type BeforeToolCall, COMPACT_PHASE_ID, type ConfigProvider, type ConfigPutResult, type ConfigResolution, type ConfigToken, type ConfigurationSnapshot, type ContextCandidate, type ContextCompactionRecord, type ContextStatus, type CoreToolContext, DEFAULT_PHASE_ID, type DefinitionLayer, type DurableConsumer, type DurableRunEvent, type DurableStore, type DurableToolResult, type EventCursor, type EventId, type ExecutionCheckpoint, type ExecutionId, type ExecutionToken, type ExtensionAPI, type ExtensionActivationError, type ExtensionActivationResult, type ExtensionContribution, type ExtensionDisposer, type ExtensionFactory, type ExtensionFactoryResult, ExtensionLifetimeError, type ExtensionLifetimeErrorCode, type ExtensionLoadInput, type FrontmatterResult, type HistorySeed, type HookEvent, type HookEventType, type HookHandler, InMemoryConfigProvider, InMemoryStore, type InputRequest, type InputRequestId, type InputRequiredCommit, type InvocationCatalogEntry, type InvocationSource, type JsonObject, type JsonPrimitive, type JsonValue, type LoadExtensionsResult, type LoadInput, type LoadResult, type LoadedExtension, type Message, type MessageBase, type MessageCommitted, type MessageContent, type MessageDelta, type MessageId, type MessageRevised, type MessageRevisionResult, type Metadata, type OpaqueId, type Outcome, type OwnerLease, type OwnerToken, type Page, type Phase, type PhaseContext, type PhaseContribution, type PhaseExecution, type PhaseExecutionIdentity, type PhaseInput, type PhaseInteraction, PhaseInteractionBoundary, PhaseInteractionCancelledError, type PhaseInteractionDriver, type PhaseInteractionKind, type PhaseInteractionState, type PhaseInteractionStatus, type PhaseInvocation, type PhaseMessageManager, type PhaseOutput, type PhaseRegistry, type PhaseRegistrySelection, type PhaseSettingsBadge, type PhaseSettingsContext, type PhaseSettingsControl, type PhaseSettingsDefinition, type PhaseSettingsItem, type PhaseSettingsOption, type PhaseSettingsProvider, type PhaseSettingsSection, type PhaseState, type PhaseStatus, type PhaseStatusState, type ResolvedResourceView, type ResourceDiagnostic, type ResourceKind, type ResourceRef, ResourceRegistry, ResourceRegistryError, type ResourceRegistryErrorCode, type ResourceSourceId, type ResourceView, type RetentionResult, type RunBoundary, type RunClaim, type RunEvent, type RunFailure, type RunId, type RunListCursor, type RunRecord, type RunSnapshot, type RunState, type RunStateChanged, type RunSummary, RuntimeBootstrapRegistry, RuntimeError, type RuntimeErrorCode, type RuntimeErrorDetails, RuntimeExtensionLifetime, STOP_PHASE_ID, type Skill, SqliteStore, type TextContent, type ThinkingContent, type ThinkingDelta, type Tool, type ToolCallId, type ToolCallSnapshot, type ToolCallState, type ToolContribution, type ToolDefinition, type ToolExecutionResult$1 as ToolExecutionResult, type ToolInvocationContext, type ToolMessage, type ToolMessageContent, type ToolProgress, type ToolResultContent, type ToolStateChanged, type ToolUseContent, type UserContent, type UserInput, type UserMessage, brandConfigToken, createCompactPhase, createCorePhases, createCoreTools, createDefaultPhase, createStopPhase, isConfigurationSnapshot, isRuntimeError, loadExtensionsFromPath as loadExtensions, loadPhase, loadPhaseSettings, loadPhases, loadSkill, loadSkills, parseAgentDefinition, parseFrontmatter, resolveConfigurationSnapshot };
|
|
2816
|
+
export { type AfterToolCall, type AgentConfiguration, type AgentDefinition, type AgentId, type AgentListCursor, type AgentRecord, type AgentRun, AgentRuntime, type AgentRuntimeOptions, type AgentSummary, type AnyRuntimeError, type AssistantContent, type AssistantMessage, type BeforeToolCall, COMPACT_PHASE_ID, type ConfigProvider, type ConfigPutResult, type ConfigResolution, type ConfigToken, type ConfigurationSnapshot, type ContextCandidate, type ContextCompactionRecord, type ContextStatus, type CoreToolContext, DEFAULT_PHASE_ID, type DefinitionLayer, type DurableConsumer, type DurableRunEvent, type DurableStore, type DurableToolResult, type EventCursor, type EventId, type ExecutionCheckpoint, type ExecutionId, type ExecutionToken, type ExtensionAPI, type ExtensionActivationError, type ExtensionActivationResult, type ExtensionContribution, type ExtensionDisposer, type ExtensionFactory, type ExtensionFactoryResult, ExtensionLifetimeError, type ExtensionLifetimeErrorCode, type ExtensionLoadInput, type FrontmatterResult, type HistorySeed, type HookEvent, type HookEventType, type HookHandler, InMemoryConfigProvider, InMemoryStore, type InputRequest, type InputRequestId, type InputRequiredCommit, type InvocationCatalogEntry, type InvocationSource, type JsonObject, type JsonPrimitive, type JsonValue, type LoadExtensionsResult, type LoadInput, type LoadResult, type LoadedExtension, type Message, type MessageBase, type MessageCommitted, type MessageContent, type MessageDelta, type MessageId, type MessageRevised, type MessageRevisionResult, type Metadata, type OpaqueId, type Outcome, type OwnerLease, type OwnerToken, type Page, type Phase, type PhaseContext, type PhaseContribution, type PhaseExecution, type PhaseExecutionIdentity, type PhaseInput, type PhaseInteraction, PhaseInteractionBoundary, PhaseInteractionCancelledError, type PhaseInteractionDriver, type PhaseInteractionKind, type PhaseInteractionState, type PhaseInteractionStatus, type PhaseInvocation, type PhaseMessageManager, type PhaseOutput, type PhaseRegistry, type PhaseRegistrySelection, type PhaseSettingsBadge, type PhaseSettingsContext, type PhaseSettingsControl, type PhaseSettingsDefinition, type PhaseSettingsItem, type PhaseSettingsOption, type PhaseSettingsProvider, type PhaseSettingsSection, type PhaseState, type PhaseStatus, type PhaseStatusState, type ResolvedResourceView, type ResourceDiagnostic, type ResourceKind, type ResourceRef, ResourceRegistry, ResourceRegistryError, type ResourceRegistryErrorCode, type ResourceSourceId, type ResourceView, type RetentionResult, type RunBoundary, type RunClaim, type RunEvent, type RunFailure, type RunId, type RunListCursor, type RunRecord, type RunSnapshot, type RunState, type RunStateChanged, type RunSummary, RuntimeBootstrapRegistry, RuntimeError, type RuntimeErrorCode, type RuntimeErrorDetails, RuntimeExtensionLifetime, STOP_PHASE_ID, type Skill, SqliteStore, type TextContent, type ThinkingContent, type ThinkingDelta, type Tool, type ToolCallId, type ToolCallInteractionRequest, type ToolCallSnapshot, type ToolCallState, type ToolContribution, type ToolDefinition, type ToolExecutionResult$1 as ToolExecutionResult, type ToolInvocationContext, type ToolMessage, type ToolMessageContent, type ToolProgress, type ToolResultContent, type ToolStateChanged, type ToolUseContent, type UserContent, type UserInput, type UserMessage, brandConfigToken, createCompactPhase, createCorePhases, createCoreTools, createDefaultPhase, createStopPhase, isConfigurationSnapshot, isRuntimeError, loadExtensionsFromPath as loadExtensions, loadPhase, loadPhaseSettings, loadPhases, loadSkill, loadSkills, parseAgentDefinition, parseFrontmatter, resolveConfigurationSnapshot };
|
package/dist/index.js
CHANGED
|
@@ -518,15 +518,32 @@ async function executeRuntimeToolCall(input) {
|
|
|
518
518
|
let decision;
|
|
519
519
|
if (input.beforeToolCall) {
|
|
520
520
|
await input.observe?.({ type: "approval_requested", tool, args });
|
|
521
|
-
decision = await input.beforeToolCall({
|
|
522
|
-
await input.observe?.({
|
|
523
|
-
type: "approval_result",
|
|
521
|
+
decision = await input.beforeToolCall({
|
|
524
522
|
tool,
|
|
525
523
|
args,
|
|
526
|
-
|
|
524
|
+
toolCallId: input.toolCall.id
|
|
527
525
|
});
|
|
526
|
+
if (decision && "allow" in decision) {
|
|
527
|
+
await input.observe?.({
|
|
528
|
+
type: "approval_result",
|
|
529
|
+
tool,
|
|
530
|
+
args,
|
|
531
|
+
decision
|
|
532
|
+
});
|
|
533
|
+
}
|
|
528
534
|
}
|
|
529
|
-
if (decision &&
|
|
535
|
+
if (decision && "interaction" in decision) {
|
|
536
|
+
const result = toolResult({
|
|
537
|
+
context: input.toolContext,
|
|
538
|
+
toolName: tool.name,
|
|
539
|
+
ok: false,
|
|
540
|
+
content: null,
|
|
541
|
+
error: `Tool interaction required: ${decision.interaction.prompt}`
|
|
542
|
+
});
|
|
543
|
+
await input.observe?.({ type: "tool_blocked", tool, reason: decision.interaction.prompt });
|
|
544
|
+
return result;
|
|
545
|
+
}
|
|
546
|
+
if (decision && "allow" in decision && !decision.allow) {
|
|
530
547
|
const result = toolResult({
|
|
531
548
|
context: input.toolContext,
|
|
532
549
|
toolName: tool.name,
|
|
@@ -1377,6 +1394,13 @@ function createPhaseInteractionDriver(state, phase, signal) {
|
|
|
1377
1394
|
answers() {
|
|
1378
1395
|
return new Map(answers);
|
|
1379
1396
|
},
|
|
1397
|
+
checkpoint() {
|
|
1398
|
+
return checkpoint;
|
|
1399
|
+
},
|
|
1400
|
+
clearCheckpoint() {
|
|
1401
|
+
checkpoint = void 0;
|
|
1402
|
+
sync();
|
|
1403
|
+
},
|
|
1380
1404
|
suspend(input = {}) {
|
|
1381
1405
|
assertActive();
|
|
1382
1406
|
const pending = this.pending();
|
|
@@ -2488,34 +2512,48 @@ async function executePhaseWithModel(ctx) {
|
|
|
2488
2512
|
...ctx.context,
|
|
2489
2513
|
messages: ctx.messageManager.visible()
|
|
2490
2514
|
};
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
// but do not let the route escape the error/re-decision boundary.
|
|
2498
|
-
toolCalls: collected.toolCalls.some((candidate) => candidate.name === PhaseRouteTool) && collected.toolCalls.some((candidate) => candidate.name !== PhaseRouteTool) ? collected.toolCalls.filter((candidate) => candidate.name !== PhaseRouteTool) : collected.toolCalls
|
|
2499
|
-
};
|
|
2500
|
-
for (const toolCall of collected.toolCalls) {
|
|
2501
|
-
if (toolCall.name !== PhaseRouteTool) continue;
|
|
2502
|
-
const messageId = ctx.messageManager.start(
|
|
2503
|
-
"tool",
|
|
2504
|
-
createRouteToolResultContent(
|
|
2505
|
-
toolCall,
|
|
2506
|
-
collected.toolCalls.some((candidate) => candidate.name !== PhaseRouteTool) ? "Route must be called separately after ordinary tools finish; this route decision was ignored." : void 0
|
|
2507
|
-
),
|
|
2508
|
-
{
|
|
2509
|
-
phase: ctx.phase.name
|
|
2510
|
-
}
|
|
2515
|
+
let executableToolCalls;
|
|
2516
|
+
const checkpoint = ctx.execution.interaction.checkpoint();
|
|
2517
|
+
if (checkpoint && typeof checkpoint === "object" && checkpoint.kind === "tool_call_suspension") {
|
|
2518
|
+
const toolSuspension = checkpoint;
|
|
2519
|
+
executableToolCalls = toolSuspension.toolCalls.filter(
|
|
2520
|
+
(toolCall) => executableToolNames.has(toolCall.name)
|
|
2511
2521
|
);
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2522
|
+
output = {
|
|
2523
|
+
message: "",
|
|
2524
|
+
phase: ctx.phase.name,
|
|
2525
|
+
toolCalls: [...toolSuspension.toolCalls]
|
|
2526
|
+
};
|
|
2527
|
+
} else {
|
|
2528
|
+
const collected = await ctx.execution.invokeModel(roundContext);
|
|
2529
|
+
output = {
|
|
2530
|
+
message: collected.text,
|
|
2531
|
+
phase: ctx.phase.name,
|
|
2532
|
+
// A route decision sharing a model response with an ordinary Tool is
|
|
2533
|
+
// rejected for this round. Keep ordinary calls visible so they can run,
|
|
2534
|
+
// but do not let the route escape the error/re-decision boundary.
|
|
2535
|
+
toolCalls: collected.toolCalls.some((candidate) => candidate.name === PhaseRouteTool) && collected.toolCalls.some((candidate) => candidate.name !== PhaseRouteTool) ? collected.toolCalls.filter((candidate) => candidate.name !== PhaseRouteTool) : collected.toolCalls
|
|
2536
|
+
};
|
|
2537
|
+
for (const toolCall of collected.toolCalls) {
|
|
2538
|
+
if (toolCall.name !== PhaseRouteTool) continue;
|
|
2539
|
+
const messageId = ctx.messageManager.start(
|
|
2540
|
+
"tool",
|
|
2541
|
+
createRouteToolResultContent(
|
|
2542
|
+
toolCall,
|
|
2543
|
+
collected.toolCalls.some((candidate) => candidate.name !== PhaseRouteTool) ? "Route must be called separately after ordinary tools finish; this route decision was ignored." : void 0
|
|
2544
|
+
),
|
|
2545
|
+
{
|
|
2546
|
+
phase: ctx.phase.name
|
|
2547
|
+
}
|
|
2548
|
+
);
|
|
2549
|
+
await ctx.messageManager.end(messageId);
|
|
2550
|
+
}
|
|
2551
|
+
executableToolCalls = collected.toolCalls.filter(
|
|
2552
|
+
(toolCall) => executableToolNames.has(toolCall.name)
|
|
2553
|
+
);
|
|
2554
|
+
if (executableToolCalls.length === 0) {
|
|
2555
|
+
return output;
|
|
2556
|
+
}
|
|
2519
2557
|
}
|
|
2520
2558
|
const results = await ctx.execution.executeTools(roundContext, executableToolCalls);
|
|
2521
2559
|
for (const result of results) {
|
|
@@ -2991,7 +3029,8 @@ async function executeToolCall(input) {
|
|
|
2991
3029
|
if (input.config.runtime?.tools) {
|
|
2992
3030
|
result = await input.config.runtime.tools({
|
|
2993
3031
|
config: input.config,
|
|
2994
|
-
toolCall: input.toolCall
|
|
3032
|
+
toolCall: input.toolCall,
|
|
3033
|
+
driver: input.driver
|
|
2995
3034
|
});
|
|
2996
3035
|
} else {
|
|
2997
3036
|
const toolContext = {
|
|
@@ -3017,7 +3056,8 @@ async function executeToolCalls(input) {
|
|
|
3017
3056
|
if (input.config.runtime?.toolsBatch) {
|
|
3018
3057
|
const results2 = await input.config.runtime.toolsBatch({
|
|
3019
3058
|
config: input.config,
|
|
3020
|
-
toolCalls: input.toolCalls
|
|
3059
|
+
toolCalls: input.toolCalls,
|
|
3060
|
+
driver: input.driver
|
|
3021
3061
|
});
|
|
3022
3062
|
if (results2.length !== input.toolCalls.length) throw new Error("Runtime returned an invalid Tool batch result");
|
|
3023
3063
|
return results2.map((result, index) => ({
|
|
@@ -3115,7 +3155,8 @@ function createPhaseExecution(config, state, phase, messageManager, toolExecutio
|
|
|
3115
3155
|
}
|
|
3116
3156
|
},
|
|
3117
3157
|
tools,
|
|
3118
|
-
toolCall
|
|
3158
|
+
toolCall,
|
|
3159
|
+
driver: interaction
|
|
3119
3160
|
});
|
|
3120
3161
|
await toolExecutionManager.end(result.toolCallId, result.toolName, result, !result.ok);
|
|
3121
3162
|
return result;
|
|
@@ -3137,7 +3178,8 @@ function createPhaseExecution(config, state, phase, messageManager, toolExecutio
|
|
|
3137
3178
|
}
|
|
3138
3179
|
},
|
|
3139
3180
|
tools,
|
|
3140
|
-
toolCalls
|
|
3181
|
+
toolCalls,
|
|
3182
|
+
driver: interaction
|
|
3141
3183
|
});
|
|
3142
3184
|
for (const result of results) {
|
|
3143
3185
|
await toolExecutionManager.end(result.toolCallId, result.toolName, result, !result.ok);
|
|
@@ -3447,9 +3489,9 @@ var THINKING_LEVELS = [
|
|
|
3447
3489
|
];
|
|
3448
3490
|
function thinkingLevelFromMetadata(metadata) {
|
|
3449
3491
|
const record = isRecord3(metadata) ? metadata : void 0;
|
|
3450
|
-
const
|
|
3451
|
-
if (!isRecord3(
|
|
3452
|
-
const level =
|
|
3492
|
+
const mori = record?.mori;
|
|
3493
|
+
if (!isRecord3(mori)) return void 0;
|
|
3494
|
+
const level = mori.thinkingLevel;
|
|
3453
3495
|
return typeof level === "string" && THINKING_LEVELS.includes(level) ? level : void 0;
|
|
3454
3496
|
}
|
|
3455
3497
|
function thinkingLevelFromMessages(messages) {
|
|
@@ -4222,12 +4264,30 @@ function assembleRegisteredExtensions(snapshot, runner, options = {}) {
|
|
|
4222
4264
|
beforePrompt: (phaseId, input) => runner.emitBeforePrompt(phaseId, input),
|
|
4223
4265
|
beforeToolCall: async (input) => {
|
|
4224
4266
|
const tool = projectTool(input.tool, input.context.agentId, input.context.runId);
|
|
4225
|
-
const decision = await runner.emitBeforeToolCall(tool, input.args
|
|
4267
|
+
const decision = await runner.emitBeforeToolCall(tool, input.args, {
|
|
4268
|
+
runId: input.context.runId,
|
|
4269
|
+
agentId: input.context.agentId,
|
|
4270
|
+
toolCallId: input.context.toolCallId,
|
|
4271
|
+
metadata: input.context.runMetadata,
|
|
4272
|
+
answer: input.answer
|
|
4273
|
+
});
|
|
4274
|
+
if (decision.interaction !== void 0) {
|
|
4275
|
+
return { interaction: decision.interaction };
|
|
4276
|
+
}
|
|
4226
4277
|
return decision.allow ? { allow: true } : { allow: false, reason: decision.reason ?? "Extension hook rejected the Tool." };
|
|
4227
4278
|
},
|
|
4228
4279
|
afterToolCall: async (input) => {
|
|
4229
4280
|
const tool = projectTool(input.tool, input.context.agentId, input.context.runId);
|
|
4230
|
-
const result = await runner.emitAfterToolCall(
|
|
4281
|
+
const result = await runner.emitAfterToolCall(
|
|
4282
|
+
tool,
|
|
4283
|
+
toLoopResult(input.result, input.context.toolCallId, input.tool.name),
|
|
4284
|
+
{
|
|
4285
|
+
runId: input.context.runId,
|
|
4286
|
+
agentId: input.context.agentId,
|
|
4287
|
+
toolCallId: input.context.toolCallId,
|
|
4288
|
+
metadata: input.context.runMetadata
|
|
4289
|
+
}
|
|
4290
|
+
);
|
|
4231
4291
|
return fromLoopResult(result);
|
|
4232
4292
|
},
|
|
4233
4293
|
setContext: (context2) => {
|
|
@@ -4873,19 +4933,28 @@ var ExtensionRunner = class {
|
|
|
4873
4933
|
});
|
|
4874
4934
|
return result?.input ?? input;
|
|
4875
4935
|
}
|
|
4876
|
-
async emitBeforeToolCall(tool, args) {
|
|
4936
|
+
async emitBeforeToolCall(tool, args, context) {
|
|
4877
4937
|
const result = await this.emitHook("before_tool_call", {
|
|
4878
4938
|
type: "before_tool_call",
|
|
4879
4939
|
tool,
|
|
4880
|
-
args
|
|
4940
|
+
args,
|
|
4941
|
+
...context?.runId !== void 0 ? { runId: context.runId } : {},
|
|
4942
|
+
...context?.agentId !== void 0 ? { agentId: context.agentId } : {},
|
|
4943
|
+
...context?.toolCallId !== void 0 ? { toolCallId: context.toolCallId } : {},
|
|
4944
|
+
...context?.metadata !== void 0 ? { metadata: context.metadata } : {},
|
|
4945
|
+
...context?.answer !== void 0 ? { answer: context.answer } : {}
|
|
4881
4946
|
});
|
|
4882
4947
|
return result ?? { allow: true };
|
|
4883
4948
|
}
|
|
4884
|
-
async emitAfterToolCall(tool, result) {
|
|
4949
|
+
async emitAfterToolCall(tool, result, context) {
|
|
4885
4950
|
const hookResult = await this.emitHook("after_tool_call", {
|
|
4886
4951
|
type: "after_tool_call",
|
|
4887
4952
|
tool,
|
|
4888
|
-
result
|
|
4953
|
+
result,
|
|
4954
|
+
...context?.runId !== void 0 ? { runId: context.runId } : {},
|
|
4955
|
+
...context?.agentId !== void 0 ? { agentId: context.agentId } : {},
|
|
4956
|
+
...context?.toolCallId !== void 0 ? { toolCallId: context.toolCallId } : {},
|
|
4957
|
+
...context?.metadata !== void 0 ? { metadata: context.metadata } : {}
|
|
4889
4958
|
});
|
|
4890
4959
|
return hookResult?.result ?? result;
|
|
4891
4960
|
}
|
|
@@ -6235,7 +6304,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6235
6304
|
},
|
|
6236
6305
|
onContext: assembly.setContext,
|
|
6237
6306
|
runtime: {
|
|
6238
|
-
tools: ({ toolCall }) => {
|
|
6307
|
+
tools: ({ toolCall, driver }) => {
|
|
6239
6308
|
const task = toolQueue.then(async () => {
|
|
6240
6309
|
const execution = await this.executeToolBatch({
|
|
6241
6310
|
run,
|
|
@@ -6244,7 +6313,11 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6244
6313
|
expectedRevision: executionRevision,
|
|
6245
6314
|
toolConfig: executionTools,
|
|
6246
6315
|
toolCalls: [toolCall],
|
|
6247
|
-
signal: controller.signal
|
|
6316
|
+
signal: controller.signal,
|
|
6317
|
+
driver,
|
|
6318
|
+
onRevision: (rev) => {
|
|
6319
|
+
executionRevision = rev;
|
|
6320
|
+
}
|
|
6248
6321
|
});
|
|
6249
6322
|
executionRevision = execution.revision;
|
|
6250
6323
|
return execution.results[0];
|
|
@@ -6252,7 +6325,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6252
6325
|
toolQueue = task.then(() => void 0, () => void 0);
|
|
6253
6326
|
return task;
|
|
6254
6327
|
},
|
|
6255
|
-
toolsBatch: ({ toolCalls }) => {
|
|
6328
|
+
toolsBatch: ({ toolCalls, driver }) => {
|
|
6256
6329
|
const task = toolQueue.then(async () => {
|
|
6257
6330
|
const execution = await this.executeToolBatch({
|
|
6258
6331
|
run,
|
|
@@ -6261,7 +6334,11 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6261
6334
|
expectedRevision: executionRevision,
|
|
6262
6335
|
toolConfig: executionTools,
|
|
6263
6336
|
toolCalls,
|
|
6264
|
-
signal: controller.signal
|
|
6337
|
+
signal: controller.signal,
|
|
6338
|
+
driver,
|
|
6339
|
+
onRevision: (rev) => {
|
|
6340
|
+
executionRevision = rev;
|
|
6341
|
+
}
|
|
6265
6342
|
});
|
|
6266
6343
|
executionRevision = execution.revision;
|
|
6267
6344
|
return execution.results;
|
|
@@ -6303,7 +6380,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6303
6380
|
return;
|
|
6304
6381
|
}
|
|
6305
6382
|
if (result.type === "input_required") {
|
|
6306
|
-
const output = latestAssistant(
|
|
6383
|
+
const output = result.interactions && result.interactions.length > 0 ? void 0 : latestAssistant(
|
|
6307
6384
|
run,
|
|
6308
6385
|
result.messages.slice(modelMessages.length),
|
|
6309
6386
|
modelMessages.length
|
|
@@ -6387,109 +6464,419 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6387
6464
|
return { result: batch.results[0], revision: batch.revision };
|
|
6388
6465
|
}
|
|
6389
6466
|
async executeToolBatch(input) {
|
|
6390
|
-
const
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
expectedRevision: input.expectedRevision,
|
|
6394
|
-
requestMessageId: createId("msg"),
|
|
6395
|
-
calls: input.toolCalls.map((toolCall) => ({
|
|
6396
|
-
providerToolCallId: toolCall.id,
|
|
6397
|
-
name: toolCall.name,
|
|
6398
|
-
args: toJsonValue(toolCall.args)
|
|
6399
|
-
}))
|
|
6400
|
-
});
|
|
6401
|
-
let revision = reserved.run.revision;
|
|
6402
|
-
const results = [];
|
|
6403
|
-
for (let index = 0; index < input.toolCalls.length; index += 1) {
|
|
6404
|
-
const toolCall = input.toolCalls[index];
|
|
6405
|
-
const tool = reserved.toolCalls[index];
|
|
6406
|
-
const execution = await this.executeReservedTool({
|
|
6407
|
-
...input,
|
|
6408
|
-
toolCall,
|
|
6409
|
-
tool,
|
|
6410
|
-
expectedRevision: revision
|
|
6411
|
-
});
|
|
6412
|
-
revision = execution.revision;
|
|
6413
|
-
results.push(execution.result);
|
|
6414
|
-
}
|
|
6415
|
-
return { results, revision };
|
|
6416
|
-
}
|
|
6417
|
-
async executeReservedTool(input) {
|
|
6418
|
-
const durableTool = input.toolConfig.tools.find((candidate) => candidate.name === input.toolCall.name);
|
|
6419
|
-
const providerToolCallId = input.toolCall.id;
|
|
6420
|
-
const toolCallId = input.tool.id;
|
|
6467
|
+
const checkpoint = input.driver?.checkpoint();
|
|
6468
|
+
const isSuspensionResume = checkpoint && typeof checkpoint === "object" && checkpoint.kind === "tool_call_suspension";
|
|
6469
|
+
const suspension = isSuspensionResume ? checkpoint : void 0;
|
|
6421
6470
|
let revision = input.expectedRevision;
|
|
6422
|
-
const
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6471
|
+
const setRevision = (newRevision) => {
|
|
6472
|
+
revision = newRevision;
|
|
6473
|
+
input.onRevision?.(revision);
|
|
6474
|
+
};
|
|
6475
|
+
if (!suspension && input.toolCalls.length > 1) {
|
|
6476
|
+
let hasInteraction = false;
|
|
6477
|
+
const preDecisions = [];
|
|
6478
|
+
const toolCallIds = input.toolCalls.map(() => createId("tool"));
|
|
6479
|
+
for (let i = 0; i < input.toolCalls.length; i++) {
|
|
6480
|
+
const toolCall = input.toolCalls[i];
|
|
6481
|
+
const durableTool = input.toolConfig.tools.find((c) => c.name === toolCall.name);
|
|
6482
|
+
if (!durableTool || !input.toolConfig.beforeToolCall) {
|
|
6483
|
+
preDecisions.push({ allow: true });
|
|
6484
|
+
continue;
|
|
6485
|
+
}
|
|
6486
|
+
const toolCallId = toolCallIds[i];
|
|
6487
|
+
const context = {
|
|
6488
|
+
agentId: input.run.agentId,
|
|
6489
|
+
runId: input.run.id,
|
|
6490
|
+
...input.agentMetadata === void 0 ? {} : { agentMetadata: input.agentMetadata },
|
|
6491
|
+
...input.run.metadata === void 0 ? {} : { runMetadata: input.run.metadata },
|
|
6492
|
+
toolCallId,
|
|
6493
|
+
reportProgress: () => {
|
|
6494
|
+
}
|
|
6495
|
+
};
|
|
6438
6496
|
try {
|
|
6439
|
-
|
|
6440
|
-
|
|
6497
|
+
const decision = await input.toolConfig.beforeToolCall({
|
|
6498
|
+
tool: durableTool,
|
|
6499
|
+
args: toJsonValue(toolCall.args),
|
|
6500
|
+
context,
|
|
6501
|
+
signal: input.signal
|
|
6502
|
+
});
|
|
6503
|
+
if ("interaction" in decision && decision.interaction !== void 0) {
|
|
6504
|
+
hasInteraction = true;
|
|
6505
|
+
break;
|
|
6506
|
+
}
|
|
6507
|
+
preDecisions.push(decision);
|
|
6441
6508
|
} catch {
|
|
6442
|
-
|
|
6509
|
+
preDecisions.push({ allow: true });
|
|
6443
6510
|
}
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6511
|
+
}
|
|
6512
|
+
if (!hasInteraction) {
|
|
6513
|
+
const reserved = await this.owned.reserveToolCalls({
|
|
6447
6514
|
runId: input.run.id,
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6515
|
+
execution: input.execution,
|
|
6516
|
+
expectedRevision: revision,
|
|
6517
|
+
requestMessageId: createId("msg"),
|
|
6518
|
+
calls: input.toolCalls.map((tc, i) => ({
|
|
6519
|
+
toolCallId: toolCallIds[i],
|
|
6520
|
+
providerToolCallId: tc.id,
|
|
6521
|
+
name: tc.name,
|
|
6522
|
+
args: toJsonValue(tc.args)
|
|
6523
|
+
}))
|
|
6451
6524
|
});
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
const
|
|
6459
|
-
|
|
6525
|
+
setRevision(reserved.run.revision);
|
|
6526
|
+
const results2 = [];
|
|
6527
|
+
for (let i = 0; i < input.toolCalls.length; i++) {
|
|
6528
|
+
const toolCall = input.toolCalls[i];
|
|
6529
|
+
const durableTool = input.toolConfig.tools.find((c) => c.name === toolCall.name);
|
|
6530
|
+
const providerToolCallId = toolCall.id;
|
|
6531
|
+
const toolCallId = toolCallIds[i];
|
|
6532
|
+
const protocolFailure = (error) => ({
|
|
6533
|
+
toolCallId: providerToolCallId,
|
|
6534
|
+
toolName: toolCall.name,
|
|
6535
|
+
ok: false,
|
|
6536
|
+
content: null,
|
|
6537
|
+
error
|
|
6538
|
+
});
|
|
6539
|
+
if (!durableTool) {
|
|
6540
|
+
const failed = await this.owned.commitToolResult({
|
|
6541
|
+
runId: input.run.id,
|
|
6542
|
+
execution: input.execution,
|
|
6543
|
+
expectedRevision: revision,
|
|
6544
|
+
toolCallId,
|
|
6545
|
+
state: "failed",
|
|
6546
|
+
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available.` }
|
|
6547
|
+
});
|
|
6548
|
+
setRevision(failed.run.revision);
|
|
6549
|
+
results2.push(protocolFailure(`Tool ${toolCall.name} is not available.`));
|
|
6550
|
+
continue;
|
|
6551
|
+
}
|
|
6552
|
+
const decision = preDecisions[i] ?? { allow: true };
|
|
6553
|
+
if ("allow" in decision && !decision.allow) {
|
|
6554
|
+
const failed = await this.owned.commitToolResult({
|
|
6555
|
+
runId: input.run.id,
|
|
6556
|
+
execution: input.execution,
|
|
6557
|
+
expectedRevision: revision,
|
|
6558
|
+
toolCallId,
|
|
6559
|
+
state: "failed",
|
|
6560
|
+
result: { ok: false, content: null, error: decision.reason }
|
|
6561
|
+
});
|
|
6562
|
+
setRevision(failed.run.revision);
|
|
6563
|
+
results2.push(protocolFailure(decision.reason));
|
|
6564
|
+
continue;
|
|
6565
|
+
}
|
|
6566
|
+
let progressActive = false;
|
|
6567
|
+
const context = {
|
|
6568
|
+
agentId: input.run.agentId,
|
|
6569
|
+
runId: input.run.id,
|
|
6570
|
+
...input.agentMetadata === void 0 ? {} : { agentMetadata: input.agentMetadata },
|
|
6571
|
+
...input.run.metadata === void 0 ? {} : { runMetadata: input.run.metadata },
|
|
6572
|
+
toolCallId,
|
|
6573
|
+
reportProgress: (progress) => {
|
|
6574
|
+
const active = this.executions.get(input.run.id);
|
|
6575
|
+
if (!progressActive || this.closed || input.signal.aborted || active?.executionId !== input.execution.executionId || !isJsonValue(progress)) return;
|
|
6576
|
+
let copy;
|
|
6577
|
+
try {
|
|
6578
|
+
if (JSON.stringify(progress).length > 64 * 1024) return;
|
|
6579
|
+
copy = structuredClone(progress);
|
|
6580
|
+
} catch {
|
|
6581
|
+
return;
|
|
6582
|
+
}
|
|
6583
|
+
this.transientEvents.publish({
|
|
6584
|
+
kind: "tool_progress",
|
|
6585
|
+
durability: "transient",
|
|
6586
|
+
runId: input.run.id,
|
|
6587
|
+
executionId: input.execution.executionId,
|
|
6588
|
+
toolCallId,
|
|
6589
|
+
progress: copy
|
|
6590
|
+
});
|
|
6591
|
+
}
|
|
6592
|
+
};
|
|
6593
|
+
const started = await this.owned.startToolCall({
|
|
6594
|
+
runId: input.run.id,
|
|
6595
|
+
execution: input.execution,
|
|
6596
|
+
expectedRevision: revision,
|
|
6597
|
+
toolCallId
|
|
6598
|
+
});
|
|
6599
|
+
setRevision(started.run.revision);
|
|
6600
|
+
progressActive = true;
|
|
6601
|
+
try {
|
|
6602
|
+
let result = await durableTool.execute(toJsonValue(toolCall.args), context, input.signal);
|
|
6603
|
+
assertToolExecutionResult(result);
|
|
6604
|
+
if (input.toolConfig.afterToolCall) {
|
|
6605
|
+
result = await input.toolConfig.afterToolCall({
|
|
6606
|
+
tool: durableTool,
|
|
6607
|
+
result,
|
|
6608
|
+
context,
|
|
6609
|
+
signal: input.signal
|
|
6610
|
+
});
|
|
6611
|
+
}
|
|
6612
|
+
assertToolExecutionResult(result);
|
|
6613
|
+
result = await spillLargeToolResult(
|
|
6614
|
+
result,
|
|
6615
|
+
this.archiveDirFor(input.run.agentId),
|
|
6616
|
+
toolCall.name
|
|
6617
|
+
);
|
|
6618
|
+
const committed = await this.owned.commitToolResult({
|
|
6619
|
+
runId: input.run.id,
|
|
6620
|
+
execution: input.execution,
|
|
6621
|
+
expectedRevision: revision,
|
|
6622
|
+
toolCallId,
|
|
6623
|
+
state: result.ok ? "completed" : "failed",
|
|
6624
|
+
result
|
|
6625
|
+
});
|
|
6626
|
+
setRevision(committed.run.revision);
|
|
6627
|
+
results2.push({
|
|
6628
|
+
toolCallId: providerToolCallId,
|
|
6629
|
+
toolName: toolCall.name,
|
|
6630
|
+
...result
|
|
6631
|
+
});
|
|
6632
|
+
} catch (error) {
|
|
6633
|
+
const reason = error instanceof Error ? error.message : "Tool execution outcome is indeterminate.";
|
|
6634
|
+
const indeterminate = await this.owned.commitToolResult({
|
|
6635
|
+
runId: input.run.id,
|
|
6636
|
+
execution: input.execution,
|
|
6637
|
+
expectedRevision: revision,
|
|
6638
|
+
toolCallId,
|
|
6639
|
+
state: "indeterminate",
|
|
6640
|
+
reason,
|
|
6641
|
+
result: { ok: false, content: null, error: reason }
|
|
6642
|
+
});
|
|
6643
|
+
setRevision(indeterminate.run.revision);
|
|
6644
|
+
results2.push(protocolFailure(reason));
|
|
6645
|
+
} finally {
|
|
6646
|
+
progressActive = false;
|
|
6647
|
+
this.transientEvents.clearTool(input.run.id, toolCallId);
|
|
6648
|
+
}
|
|
6460
6649
|
}
|
|
6650
|
+
return { results: results2, revision };
|
|
6461
6651
|
}
|
|
6462
|
-
} catch (error) {
|
|
6463
|
-
const reason = error instanceof Error ? error.message : "Tool policy rejected the call.";
|
|
6464
|
-
const failed = await this.owned.commitToolResult({ runId: input.run.id, execution: input.execution, expectedRevision: revision, toolCallId, state: "failed", result: { ok: false, content: null, error: reason } });
|
|
6465
|
-
return { result: protocolFailure(reason), revision: failed.run.revision };
|
|
6466
6652
|
}
|
|
6467
|
-
const
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6653
|
+
const results = suspension ? [...suspension.completedResults] : [];
|
|
6654
|
+
const startIndex = suspension ? suspension.pendingIndex : 0;
|
|
6655
|
+
for (let index = startIndex; index < input.toolCalls.length; index += 1) {
|
|
6656
|
+
const toolCall = input.toolCalls[index];
|
|
6657
|
+
const durableTool = input.toolConfig.tools.find((candidate) => candidate.name === toolCall.name);
|
|
6658
|
+
const providerToolCallId = toolCall.id;
|
|
6659
|
+
const toolCallId = suspension && index === suspension.pendingIndex && suspension.toolCallId ? suspension.toolCallId : createId("tool");
|
|
6660
|
+
const protocolFailure = (error) => ({
|
|
6661
|
+
toolCallId: providerToolCallId,
|
|
6662
|
+
toolName: toolCall.name,
|
|
6663
|
+
ok: false,
|
|
6664
|
+
content: null,
|
|
6665
|
+
error
|
|
6666
|
+
});
|
|
6667
|
+
if (!durableTool) {
|
|
6668
|
+
const reserved2 = await this.owned.reserveToolCalls({
|
|
6669
|
+
runId: input.run.id,
|
|
6670
|
+
execution: input.execution,
|
|
6671
|
+
expectedRevision: revision,
|
|
6672
|
+
requestMessageId: createId("msg"),
|
|
6673
|
+
calls: [{
|
|
6674
|
+
toolCallId,
|
|
6675
|
+
providerToolCallId,
|
|
6676
|
+
name: toolCall.name,
|
|
6677
|
+
args: toJsonValue(toolCall.args)
|
|
6678
|
+
}]
|
|
6679
|
+
});
|
|
6680
|
+
setRevision(reserved2.run.revision);
|
|
6681
|
+
const failed = await this.owned.commitToolResult({
|
|
6682
|
+
runId: input.run.id,
|
|
6683
|
+
execution: input.execution,
|
|
6684
|
+
expectedRevision: revision,
|
|
6685
|
+
toolCallId,
|
|
6686
|
+
state: "failed",
|
|
6687
|
+
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available.` }
|
|
6688
|
+
});
|
|
6689
|
+
setRevision(failed.run.revision);
|
|
6690
|
+
results.push(protocolFailure(`Tool ${toolCall.name} is not available.`));
|
|
6691
|
+
continue;
|
|
6692
|
+
}
|
|
6693
|
+
let progressActive = false;
|
|
6694
|
+
const context = {
|
|
6695
|
+
agentId: input.run.agentId,
|
|
6696
|
+
runId: input.run.id,
|
|
6697
|
+
...input.agentMetadata === void 0 ? {} : { agentMetadata: input.agentMetadata },
|
|
6698
|
+
...input.run.metadata === void 0 ? {} : { runMetadata: input.run.metadata },
|
|
6699
|
+
toolCallId,
|
|
6700
|
+
reportProgress: (progress) => {
|
|
6701
|
+
const active = this.executions.get(input.run.id);
|
|
6702
|
+
if (!progressActive || this.closed || input.signal.aborted || active?.executionId !== input.execution.executionId || !isJsonValue(progress)) return;
|
|
6703
|
+
let copy;
|
|
6704
|
+
try {
|
|
6705
|
+
if (JSON.stringify(progress).length > 64 * 1024) return;
|
|
6706
|
+
copy = structuredClone(progress);
|
|
6707
|
+
} catch {
|
|
6708
|
+
return;
|
|
6709
|
+
}
|
|
6710
|
+
this.transientEvents.publish({
|
|
6711
|
+
kind: "tool_progress",
|
|
6712
|
+
durability: "transient",
|
|
6713
|
+
runId: input.run.id,
|
|
6714
|
+
executionId: input.execution.executionId,
|
|
6715
|
+
toolCallId,
|
|
6716
|
+
progress: copy
|
|
6717
|
+
});
|
|
6718
|
+
}
|
|
6484
6719
|
};
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6720
|
+
const answer = suspension && index === suspension.pendingIndex && suspension.interactionId ? input.driver?.answers().get(suspension.interactionId) : void 0;
|
|
6721
|
+
try {
|
|
6722
|
+
if (input.toolConfig.beforeToolCall) {
|
|
6723
|
+
const decision = await input.toolConfig.beforeToolCall({
|
|
6724
|
+
tool: durableTool,
|
|
6725
|
+
args: toJsonValue(toolCall.args),
|
|
6726
|
+
context,
|
|
6727
|
+
signal: input.signal,
|
|
6728
|
+
answer
|
|
6729
|
+
});
|
|
6730
|
+
if ("interaction" in decision && decision.interaction !== void 0) {
|
|
6731
|
+
if (!input.driver) {
|
|
6732
|
+
throw new Error("Tool call requested interaction but no interaction driver is active.");
|
|
6733
|
+
}
|
|
6734
|
+
const interactionRequest = input.driver.request({
|
|
6735
|
+
id: decision.interaction.id,
|
|
6736
|
+
kind: decision.interaction.kind,
|
|
6737
|
+
prompt: decision.interaction.prompt,
|
|
6738
|
+
payload: decision.interaction.payload
|
|
6739
|
+
});
|
|
6740
|
+
input.driver.suspend({
|
|
6741
|
+
checkpoint: {
|
|
6742
|
+
kind: "tool_call_suspension",
|
|
6743
|
+
toolCalls: input.toolCalls,
|
|
6744
|
+
pendingIndex: index,
|
|
6745
|
+
toolCallId,
|
|
6746
|
+
interactionId: interactionRequest.id,
|
|
6747
|
+
completedResults: results
|
|
6748
|
+
}
|
|
6749
|
+
});
|
|
6750
|
+
}
|
|
6751
|
+
if ("allow" in decision && !decision.allow) {
|
|
6752
|
+
const reserved2 = await this.owned.reserveToolCalls({
|
|
6753
|
+
runId: input.run.id,
|
|
6754
|
+
execution: input.execution,
|
|
6755
|
+
expectedRevision: revision,
|
|
6756
|
+
requestMessageId: createId("msg"),
|
|
6757
|
+
calls: [{
|
|
6758
|
+
toolCallId,
|
|
6759
|
+
providerToolCallId,
|
|
6760
|
+
name: toolCall.name,
|
|
6761
|
+
args: toJsonValue(toolCall.args)
|
|
6762
|
+
}]
|
|
6763
|
+
});
|
|
6764
|
+
setRevision(reserved2.run.revision);
|
|
6765
|
+
const failed = await this.owned.commitToolResult({
|
|
6766
|
+
runId: input.run.id,
|
|
6767
|
+
execution: input.execution,
|
|
6768
|
+
expectedRevision: revision,
|
|
6769
|
+
toolCallId,
|
|
6770
|
+
state: "failed",
|
|
6771
|
+
result: { ok: false, content: null, error: decision.reason }
|
|
6772
|
+
});
|
|
6773
|
+
setRevision(failed.run.revision);
|
|
6774
|
+
results.push(protocolFailure(decision.reason));
|
|
6775
|
+
continue;
|
|
6776
|
+
}
|
|
6777
|
+
}
|
|
6778
|
+
} catch (error) {
|
|
6779
|
+
if (error instanceof PhaseInteractionBoundary || error instanceof PhaseInteractionCancelledError) {
|
|
6780
|
+
throw error;
|
|
6781
|
+
}
|
|
6782
|
+
const reason = error instanceof Error ? error.message : "Tool policy rejected the call.";
|
|
6783
|
+
const reserved2 = await this.owned.reserveToolCalls({
|
|
6784
|
+
runId: input.run.id,
|
|
6785
|
+
execution: input.execution,
|
|
6786
|
+
expectedRevision: revision,
|
|
6787
|
+
requestMessageId: createId("msg"),
|
|
6788
|
+
calls: [{
|
|
6789
|
+
toolCallId,
|
|
6790
|
+
providerToolCallId,
|
|
6791
|
+
name: toolCall.name,
|
|
6792
|
+
args: toJsonValue(toolCall.args)
|
|
6793
|
+
}]
|
|
6794
|
+
});
|
|
6795
|
+
setRevision(reserved2.run.revision);
|
|
6796
|
+
const failed = await this.owned.commitToolResult({
|
|
6797
|
+
runId: input.run.id,
|
|
6798
|
+
execution: input.execution,
|
|
6799
|
+
expectedRevision: revision,
|
|
6800
|
+
toolCallId,
|
|
6801
|
+
state: "failed",
|
|
6802
|
+
result: { ok: false, content: null, error: reason }
|
|
6803
|
+
});
|
|
6804
|
+
setRevision(failed.run.revision);
|
|
6805
|
+
results.push(protocolFailure(reason));
|
|
6806
|
+
continue;
|
|
6807
|
+
}
|
|
6808
|
+
const reserved = await this.owned.reserveToolCalls({
|
|
6809
|
+
runId: input.run.id,
|
|
6810
|
+
execution: input.execution,
|
|
6811
|
+
expectedRevision: revision,
|
|
6812
|
+
requestMessageId: createId("msg"),
|
|
6813
|
+
calls: [{
|
|
6814
|
+
toolCallId,
|
|
6815
|
+
providerToolCallId,
|
|
6816
|
+
name: toolCall.name,
|
|
6817
|
+
args: toJsonValue(toolCall.args)
|
|
6818
|
+
}]
|
|
6819
|
+
});
|
|
6820
|
+
setRevision(reserved.run.revision);
|
|
6821
|
+
const started = await this.owned.startToolCall({
|
|
6822
|
+
runId: input.run.id,
|
|
6823
|
+
execution: input.execution,
|
|
6824
|
+
expectedRevision: revision,
|
|
6825
|
+
toolCallId
|
|
6826
|
+
});
|
|
6827
|
+
setRevision(started.run.revision);
|
|
6828
|
+
progressActive = true;
|
|
6829
|
+
try {
|
|
6830
|
+
let result = await durableTool.execute(toJsonValue(toolCall.args), context, input.signal);
|
|
6831
|
+
assertToolExecutionResult(result);
|
|
6832
|
+
if (input.toolConfig.afterToolCall) {
|
|
6833
|
+
result = await input.toolConfig.afterToolCall({
|
|
6834
|
+
tool: durableTool,
|
|
6835
|
+
result,
|
|
6836
|
+
context,
|
|
6837
|
+
signal: input.signal
|
|
6838
|
+
});
|
|
6839
|
+
}
|
|
6840
|
+
assertToolExecutionResult(result);
|
|
6841
|
+
result = await spillLargeToolResult(
|
|
6842
|
+
result,
|
|
6843
|
+
this.archiveDirFor(input.run.agentId),
|
|
6844
|
+
toolCall.name
|
|
6845
|
+
);
|
|
6846
|
+
const committed = await this.owned.commitToolResult({
|
|
6847
|
+
runId: input.run.id,
|
|
6848
|
+
execution: input.execution,
|
|
6849
|
+
expectedRevision: revision,
|
|
6850
|
+
toolCallId,
|
|
6851
|
+
state: result.ok ? "completed" : "failed",
|
|
6852
|
+
result
|
|
6853
|
+
});
|
|
6854
|
+
setRevision(committed.run.revision);
|
|
6855
|
+
results.push({
|
|
6856
|
+
toolCallId: providerToolCallId,
|
|
6857
|
+
toolName: toolCall.name,
|
|
6858
|
+
...result
|
|
6859
|
+
});
|
|
6860
|
+
} catch (error) {
|
|
6861
|
+
const reason = error instanceof Error ? error.message : "Tool execution outcome is indeterminate.";
|
|
6862
|
+
const indeterminate = await this.owned.commitToolResult({
|
|
6863
|
+
runId: input.run.id,
|
|
6864
|
+
execution: input.execution,
|
|
6865
|
+
expectedRevision: revision,
|
|
6866
|
+
toolCallId,
|
|
6867
|
+
state: "indeterminate",
|
|
6868
|
+
reason,
|
|
6869
|
+
result: { ok: false, content: null, error: reason }
|
|
6870
|
+
});
|
|
6871
|
+
setRevision(indeterminate.run.revision);
|
|
6872
|
+
results.push(protocolFailure(reason));
|
|
6873
|
+
} finally {
|
|
6874
|
+
progressActive = false;
|
|
6875
|
+
this.transientEvents.clearTool(input.run.id, toolCallId);
|
|
6876
|
+
}
|
|
6492
6877
|
}
|
|
6878
|
+
input.driver?.clearCheckpoint();
|
|
6879
|
+
return { results, revision };
|
|
6493
6880
|
}
|
|
6494
6881
|
async requireAgent(agentId) {
|
|
6495
6882
|
const agent = (await this.owned.listAgents()).find((candidate) => candidate.id === agentId);
|