@openrouter/agent 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +732 -7
- package/THIRD_PARTY_NOTICES.md +25 -0
- package/esm/index.d.ts +20 -5
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +10 -3
- package/esm/index.js.map +1 -1
- package/esm/inner-loop/call-model.d.ts.map +1 -1
- package/esm/inner-loop/call-model.js +63 -46
- package/esm/inner-loop/call-model.js.map +1 -1
- package/esm/inner-loop/resume-tool-results.d.ts +128 -0
- package/esm/inner-loop/resume-tool-results.d.ts.map +1 -0
- package/esm/inner-loop/resume-tool-results.js +244 -0
- package/esm/inner-loop/resume-tool-results.js.map +1 -0
- package/esm/lib/agent-tool.d.ts +92 -0
- package/esm/lib/agent-tool.d.ts.map +1 -0
- package/esm/lib/agent-tool.js +211 -0
- package/esm/lib/agent-tool.js.map +1 -0
- package/esm/lib/async-params.d.ts +96 -0
- package/esm/lib/async-params.d.ts.map +1 -1
- package/esm/lib/async-params.js +30 -1
- package/esm/lib/async-params.js.map +1 -1
- package/esm/lib/async-tool-registry.d.ts +134 -0
- package/esm/lib/async-tool-registry.d.ts.map +1 -0
- package/esm/lib/async-tool-registry.js +352 -0
- package/esm/lib/async-tool-registry.js.map +1 -0
- package/esm/lib/async-tools.d.ts +23 -0
- package/esm/lib/async-tools.d.ts.map +1 -0
- package/esm/lib/async-tools.js +19 -0
- package/esm/lib/async-tools.js.map +1 -0
- package/esm/lib/conversation-state.d.ts +1 -0
- package/esm/lib/conversation-state.d.ts.map +1 -1
- package/esm/lib/conversation-state.js +8 -0
- package/esm/lib/conversation-state.js.map +1 -1
- package/esm/lib/doom-loop.d.ts +533 -0
- package/esm/lib/doom-loop.d.ts.map +1 -0
- package/esm/lib/doom-loop.js +1221 -0
- package/esm/lib/doom-loop.js.map +1 -0
- package/esm/lib/hooks-schemas.d.ts +33 -0
- package/esm/lib/hooks-schemas.d.ts.map +1 -1
- package/esm/lib/hooks-schemas.js +54 -0
- package/esm/lib/hooks-schemas.js.map +1 -1
- package/esm/lib/hooks-types.d.ts +6 -2
- package/esm/lib/hooks-types.d.ts.map +1 -1
- package/esm/lib/hooks-types.js.map +1 -1
- package/esm/lib/model-result.d.ts +648 -12
- package/esm/lib/model-result.d.ts.map +1 -1
- package/esm/lib/model-result.js +2784 -164
- package/esm/lib/model-result.js.map +1 -1
- package/esm/lib/next-turn-params.d.ts.map +1 -1
- package/esm/lib/next-turn-params.js +3 -1
- package/esm/lib/next-turn-params.js.map +1 -1
- package/esm/lib/next-turn-params.test.js +72 -0
- package/esm/lib/next-turn-params.test.js.map +1 -1
- package/esm/lib/reusable-stream.d.ts +9 -0
- package/esm/lib/reusable-stream.d.ts.map +1 -1
- package/esm/lib/reusable-stream.js +17 -0
- package/esm/lib/reusable-stream.js.map +1 -1
- package/esm/lib/stream-transformers.d.ts +21 -1
- package/esm/lib/stream-transformers.d.ts.map +1 -1
- package/esm/lib/stream-transformers.js +45 -0
- package/esm/lib/stream-transformers.js.map +1 -1
- package/esm/lib/tool-check.d.ts +76 -0
- package/esm/lib/tool-check.d.ts.map +1 -0
- package/esm/lib/tool-check.js +241 -0
- package/esm/lib/tool-check.js.map +1 -0
- package/esm/lib/tool-concurrency.d.ts +42 -0
- package/esm/lib/tool-concurrency.d.ts.map +1 -0
- package/esm/lib/tool-concurrency.js +80 -0
- package/esm/lib/tool-concurrency.js.map +1 -0
- package/esm/lib/tool-context.d.ts +45 -1
- package/esm/lib/tool-context.d.ts.map +1 -1
- package/esm/lib/tool-context.js +60 -1
- package/esm/lib/tool-context.js.map +1 -1
- package/esm/lib/tool-executor.d.ts +52 -9
- package/esm/lib/tool-executor.d.ts.map +1 -1
- package/esm/lib/tool-executor.js +253 -21
- package/esm/lib/tool-executor.js.map +1 -1
- package/esm/lib/tool-orchestrator.d.ts.map +1 -1
- package/esm/lib/tool-orchestrator.js +87 -50
- package/esm/lib/tool-orchestrator.js.map +1 -1
- package/esm/lib/tool-set-types.d.ts +298 -0
- package/esm/lib/tool-set-types.d.ts.map +1 -0
- package/esm/lib/tool-set-types.js +2 -0
- package/esm/lib/tool-set-types.js.map +1 -0
- package/esm/lib/tool-set.d.ts +157 -0
- package/esm/lib/tool-set.d.ts.map +1 -0
- package/esm/lib/tool-set.js +473 -0
- package/esm/lib/tool-set.js.map +1 -0
- package/esm/lib/tool-task.d.ts +157 -0
- package/esm/lib/tool-task.d.ts.map +1 -0
- package/esm/lib/tool-task.js +206 -0
- package/esm/lib/tool-task.js.map +1 -0
- package/esm/lib/tool-types.d.ts +667 -38
- package/esm/lib/tool-types.d.ts.map +1 -1
- package/esm/lib/tool-types.js +59 -10
- package/esm/lib/tool-types.js.map +1 -1
- package/esm/lib/tool.d.ts +227 -19
- package/esm/lib/tool.d.ts.map +1 -1
- package/esm/lib/tool.js +206 -6
- package/esm/lib/tool.js.map +1 -1
- package/esm/mcp/auth/auth-resolver.d.ts +14 -0
- package/esm/mcp/auth/auth-resolver.d.ts.map +1 -0
- package/esm/mcp/auth/auth-resolver.js +27 -0
- package/esm/mcp/auth/auth-resolver.js.map +1 -0
- package/esm/mcp/auth/auth-types.d.ts +33 -0
- package/esm/mcp/auth/auth-types.d.ts.map +1 -0
- package/esm/mcp/auth/auth-types.js +4 -0
- package/esm/mcp/auth/auth-types.js.map +1 -0
- package/esm/mcp/build-tools.d.ts +29 -0
- package/esm/mcp/build-tools.d.ts.map +1 -0
- package/esm/mcp/build-tools.js +80 -0
- package/esm/mcp/build-tools.js.map +1 -0
- package/esm/mcp/cache/cache-store.d.ts +24 -0
- package/esm/mcp/cache/cache-store.d.ts.map +1 -0
- package/esm/mcp/cache/cache-store.js +20 -0
- package/esm/mcp/cache/cache-store.js.map +1 -0
- package/esm/mcp/cache/cache-types.d.ts +71 -0
- package/esm/mcp/cache/cache-types.d.ts.map +1 -0
- package/esm/mcp/cache/cache-types.js +49 -0
- package/esm/mcp/cache/cache-types.js.map +1 -0
- package/esm/mcp/cache/serialize.d.ts +25 -0
- package/esm/mcp/cache/serialize.d.ts.map +1 -0
- package/esm/mcp/cache/serialize.js +96 -0
- package/esm/mcp/cache/serialize.js.map +1 -0
- package/esm/mcp/close-quietly.d.ts +24 -0
- package/esm/mcp/close-quietly.d.ts.map +1 -0
- package/esm/mcp/close-quietly.js +30 -0
- package/esm/mcp/close-quietly.js.map +1 -0
- package/esm/mcp/create-mcp-tools.d.ts +13 -0
- package/esm/mcp/create-mcp-tools.d.ts.map +1 -0
- package/esm/mcp/create-mcp-tools.js +87 -0
- package/esm/mcp/create-mcp-tools.js.map +1 -0
- package/esm/mcp/elicitation.d.ts +11 -0
- package/esm/mcp/elicitation.d.ts.map +1 -0
- package/esm/mcp/elicitation.js +51 -0
- package/esm/mcp/elicitation.js.map +1 -0
- package/esm/mcp/errors.d.ts +91 -0
- package/esm/mcp/errors.d.ts.map +1 -0
- package/esm/mcp/errors.js +91 -0
- package/esm/mcp/errors.js.map +1 -0
- package/esm/mcp/handle.d.ts +66 -0
- package/esm/mcp/handle.d.ts.map +1 -0
- package/esm/mcp/handle.js +323 -0
- package/esm/mcp/handle.js.map +1 -0
- package/esm/mcp/index.d.ts +13 -0
- package/esm/mcp/index.d.ts.map +1 -0
- package/esm/mcp/index.js +11 -0
- package/esm/mcp/index.js.map +1 -0
- package/esm/mcp/mcp-connection.d.ts +150 -0
- package/esm/mcp/mcp-connection.d.ts.map +1 -0
- package/esm/mcp/mcp-connection.js +478 -0
- package/esm/mcp/mcp-connection.js.map +1 -0
- package/esm/mcp/mcp-sdk.d.ts +10 -0
- package/esm/mcp/mcp-sdk.d.ts.map +1 -0
- package/esm/mcp/mcp-sdk.js +37 -0
- package/esm/mcp/mcp-sdk.js.map +1 -0
- package/esm/mcp/rehydrate.d.ts +76 -0
- package/esm/mcp/rehydrate.d.ts.map +1 -0
- package/esm/mcp/rehydrate.js +505 -0
- package/esm/mcp/rehydrate.js.map +1 -0
- package/esm/mcp/resource-tools.d.ts +17 -0
- package/esm/mcp/resource-tools.d.ts.map +1 -0
- package/esm/mcp/resource-tools.js +155 -0
- package/esm/mcp/resource-tools.js.map +1 -0
- package/esm/mcp/result-mapper.d.ts +19 -0
- package/esm/mcp/result-mapper.d.ts.map +1 -0
- package/esm/mcp/result-mapper.js +40 -0
- package/esm/mcp/result-mapper.js.map +1 -0
- package/esm/mcp/schema/json-schema-guards.d.ts +14 -0
- package/esm/mcp/schema/json-schema-guards.d.ts.map +1 -0
- package/esm/mcp/schema/json-schema-guards.js +19 -0
- package/esm/mcp/schema/json-schema-guards.js.map +1 -0
- package/esm/mcp/schema/json-schema-to-zod.d.ts +20 -0
- package/esm/mcp/schema/json-schema-to-zod.d.ts.map +1 -0
- package/esm/mcp/schema/json-schema-to-zod.js +72 -0
- package/esm/mcp/schema/json-schema-to-zod.js.map +1 -0
- package/esm/mcp/tool-wrapper.d.ts +41 -0
- package/esm/mcp/tool-wrapper.d.ts.map +1 -0
- package/esm/mcp/tool-wrapper.js +131 -0
- package/esm/mcp/tool-wrapper.js.map +1 -0
- package/esm/mcp/transport-types.d.ts +45 -0
- package/esm/mcp/transport-types.d.ts.map +1 -0
- package/esm/mcp/transport-types.js +2 -0
- package/esm/mcp/transport-types.js.map +1 -0
- package/esm/mcp/types.d.ts +119 -0
- package/esm/mcp/types.d.ts.map +1 -0
- package/esm/mcp/types.js +2 -0
- package/esm/mcp/types.js.map +1 -0
- package/esm/mcp/version.d.ts +3 -0
- package/esm/mcp/version.d.ts.map +1 -0
- package/esm/mcp/version.js +5 -0
- package/esm/mcp/version.js.map +1 -0
- package/package.json +70 -5
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { appendToMessages, updateState } from '../lib/conversation-state.js';
|
|
2
|
+
import { validateToolOutput } from '../lib/tool-executor.js';
|
|
3
|
+
import { TASK_RESULT_BOUNDARY } from '../lib/tool-task.js';
|
|
4
|
+
import { isClientTool, isUnifiedTool } from '../lib/tool-types.js';
|
|
5
|
+
import { callModel } from './call-model.js';
|
|
6
|
+
/**
|
|
7
|
+
* Thrown by {@link resumeToolResults} (and the deferred tool `.resolve()` /
|
|
8
|
+
* `.fail()` / `.cancel()` methods) when the target task was already settled —
|
|
9
|
+
* the at-most-once guard against double resolution and replayed webhooks.
|
|
10
|
+
* Opt out per call with `ifSettled: 'ignore'`.
|
|
11
|
+
*/
|
|
12
|
+
export class ToolTaskAlreadySettledError extends Error {
|
|
13
|
+
constructor(taskId, callId) {
|
|
14
|
+
super(`Tool task "${taskId}" (call ${callId}) has already been settled`);
|
|
15
|
+
this.name = 'ToolTaskAlreadySettledError';
|
|
16
|
+
this.taskId = taskId;
|
|
17
|
+
this.callId = callId;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** Build the user-role message carrying a task-result envelope. */
|
|
21
|
+
export function buildTaskResultMessage(envelope) {
|
|
22
|
+
return {
|
|
23
|
+
role: 'user',
|
|
24
|
+
content: `${TASK_RESULT_BOUNDARY}\n${JSON.stringify(envelope)}`,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Find the pending task an incoming result belongs to, or `null` when the entry
|
|
29
|
+
* is already settled and the caller asked to ignore that.
|
|
30
|
+
*
|
|
31
|
+
* Settled tasks deliberately STAY in `pendingAsyncTools` with a terminal
|
|
32
|
+
* status, so a replayed webhook resolves to `ToolTaskAlreadySettledError`
|
|
33
|
+
* rather than "not found".
|
|
34
|
+
*
|
|
35
|
+
* @throws ToolTaskAlreadySettledError when the task already settled and
|
|
36
|
+
* `ifSettled` is `'throw'` (the default).
|
|
37
|
+
* @throws Error when no pending task matches the entry at all.
|
|
38
|
+
*/
|
|
39
|
+
function resolvePendingTask({ entry, pending, settledIds, ifSettled, }) {
|
|
40
|
+
const task = pending.find((t) => 'taskId' in entry && entry.taskId !== undefined
|
|
41
|
+
? t.taskId === entry.taskId
|
|
42
|
+
: t.callId === entry.callId);
|
|
43
|
+
if (!task) {
|
|
44
|
+
// The callId fallback covers states persisted by older SDK versions whose
|
|
45
|
+
// in-process delivery REMOVED the entry, leaving only the callId on
|
|
46
|
+
// settledAsyncCallIds.
|
|
47
|
+
if (entry.callId !== undefined && settledIds.has(entry.callId)) {
|
|
48
|
+
if (ifSettled === 'ignore') {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
throw new ToolTaskAlreadySettledError(entry.taskId ?? entry.callId, entry.callId);
|
|
52
|
+
}
|
|
53
|
+
throw new Error(`resumeToolResults: no pending async tool task found for "${entry.taskId ?? entry.callId}"`);
|
|
54
|
+
}
|
|
55
|
+
if (settledIds.has(task.callId) || task.status !== 'working') {
|
|
56
|
+
if (ifSettled === 'ignore') {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
throw new ToolTaskAlreadySettledError(task.taskId, task.callId);
|
|
60
|
+
}
|
|
61
|
+
return task;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Deliver results for pending async tool tasks (started by `tool.deferred`,
|
|
65
|
+
* or background tasks orphaned across a run boundary) into a persisted
|
|
66
|
+
* conversation — typically from a different process than the one that
|
|
67
|
+
* started them (a webhook handler, a queue worker).
|
|
68
|
+
*
|
|
69
|
+
* This is the low-level, untyped entry point; prefer the typed `.resolve()`
|
|
70
|
+
* / `.fail()` / `.cancel()` methods on the deferred tool itself, which
|
|
71
|
+
* check `output` against the tool's `outputSchema` at compile time.
|
|
72
|
+
*
|
|
73
|
+
* Behavior:
|
|
74
|
+
* 1. Loads the conversation via `state`, resolves each entry to a pending
|
|
75
|
+
* task (by `taskId` or `callId`).
|
|
76
|
+
* 2. Enforces at-most-once settlement: an already-settled task throws
|
|
77
|
+
* {@link ToolTaskAlreadySettledError} (or is skipped with
|
|
78
|
+
* `ifSettled: 'ignore'`).
|
|
79
|
+
* 3. Validates each `output` against the named tool's `outputSchema` when
|
|
80
|
+
* the tool is present in `tools` — an invalid payload throws before
|
|
81
|
+
* anything is persisted or dispatched.
|
|
82
|
+
* 4. Appends a `tool_task_result` envelope (user-role message) per entry,
|
|
83
|
+
* marks the tasks settled, and persists the state. The conversation
|
|
84
|
+
* status becomes `'in_progress'` (or stays `'awaiting_async_tools'` when
|
|
85
|
+
* other tasks are still pending).
|
|
86
|
+
* 5. With `run` config: continues the conversation immediately and returns
|
|
87
|
+
* the `ModelResult`. Without: returns `null` — the recorded results ride
|
|
88
|
+
* along on the next `callModel({ state })`. When every entry was skipped
|
|
89
|
+
* under `ifSettled: 'ignore'` there is nothing new to deliver, so the
|
|
90
|
+
* function returns `null` WITHOUT running — a replayed webhook never
|
|
91
|
+
* triggers a duplicate continuation.
|
|
92
|
+
*
|
|
93
|
+
* SECURITY: this call injects a value the model will treat as a tool
|
|
94
|
+
* result. Authenticate the webhook/caller BEFORE invoking it — the SDK
|
|
95
|
+
* cannot do that for you. And PASS `tools`: without it the output is
|
|
96
|
+
* appended UNVALIDATED (no outputSchema to check against) — prefer the
|
|
97
|
+
* typed `.resolve()` methods, which always carry the tool's schema.
|
|
98
|
+
*
|
|
99
|
+
* CONCURRENCY: this is a read-modify-write over the StateAccessor. Two
|
|
100
|
+
* concurrent calls for the SAME conversation (e.g. two webhooks resolving
|
|
101
|
+
* two different tasks) can interleave load/save and the later save wins,
|
|
102
|
+
* silently dropping the earlier envelope. Serialize calls per conversation
|
|
103
|
+
* — a per-conversation lock or queue in your StateAccessor, or batch
|
|
104
|
+
* concurrent completions into one call via `results: [...]` (which settles
|
|
105
|
+
* any number of tasks atomically).
|
|
106
|
+
*
|
|
107
|
+
* HOOKS: PostToolUse / PostToolUseFailure do NOT fire here — hooks are
|
|
108
|
+
* run-scoped (a HooksManager passed to `callModel`), and this entry point
|
|
109
|
+
* runs outside any run, typically in another process. Deployments that
|
|
110
|
+
* audit tool outputs via hooks should scan webhook payloads in the webhook
|
|
111
|
+
* handler itself. In-process settlements (background tasks) DO fire these
|
|
112
|
+
* hooks at delivery.
|
|
113
|
+
*/
|
|
114
|
+
export async function resumeToolResults(client, request, options) {
|
|
115
|
+
const state = await request.state.load();
|
|
116
|
+
if (!state) {
|
|
117
|
+
throw new Error('resumeToolResults: no conversation state found for the given StateAccessor');
|
|
118
|
+
}
|
|
119
|
+
const pending = state.pendingAsyncTools ?? [];
|
|
120
|
+
const settledIds = new Set(state.settledAsyncCallIds ?? []);
|
|
121
|
+
const envelopes = [];
|
|
122
|
+
/** callId → the terminal lifecycle status persisted for that entry. */
|
|
123
|
+
const settledNow = new Map();
|
|
124
|
+
for (const entry of request.results) {
|
|
125
|
+
const task = resolvePendingTask({
|
|
126
|
+
entry,
|
|
127
|
+
pending,
|
|
128
|
+
settledIds,
|
|
129
|
+
ifSettled: request.ifSettled,
|
|
130
|
+
});
|
|
131
|
+
if (!task) {
|
|
132
|
+
continue; // already settled and the caller asked to ignore it
|
|
133
|
+
}
|
|
134
|
+
// Ownership guard: a taskId is an external identifier handed to
|
|
135
|
+
// third-party systems — a lower-trust webhook must not be able to
|
|
136
|
+
// settle a DIFFERENT tool's task through a tool-bound completion
|
|
137
|
+
// method (confused deputy; it would also skip that tool's
|
|
138
|
+
// outputSchema validation).
|
|
139
|
+
if (request.expectToolName !== undefined && task.name !== request.expectToolName) {
|
|
140
|
+
throw new Error(`resumeToolResults: task "${task.taskId}" belongs to tool "${task.name}", not "${request.expectToolName}" — use the owning tool's completion methods (or the untyped resumeToolResults entry point).`);
|
|
141
|
+
}
|
|
142
|
+
const envelope = buildResumeEnvelope(entry, task, request.tools);
|
|
143
|
+
envelopes.push(buildTaskResultMessage(envelope));
|
|
144
|
+
// Persist the entry's real terminal status. 'expired' / 'timed_out'
|
|
145
|
+
// have no ToolTaskStatus member — they persist as 'failed'.
|
|
146
|
+
settledNow.set(task.callId, envelope.status === 'completed' || envelope.status === 'cancelled'
|
|
147
|
+
? envelope.status
|
|
148
|
+
: 'failed');
|
|
149
|
+
settledIds.add(task.callId);
|
|
150
|
+
}
|
|
151
|
+
if (envelopes.length === 0) {
|
|
152
|
+
// Every entry was already settled and ignored — nothing to record.
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
// Keep settled entries with a terminal status (rather than dropping them)
|
|
156
|
+
// so a replayed resolution surfaces as ToolTaskAlreadySettledError.
|
|
157
|
+
const nextPending = pending.map((t) => {
|
|
158
|
+
const terminalStatus = settledNow.get(t.callId);
|
|
159
|
+
return terminalStatus !== undefined
|
|
160
|
+
? {
|
|
161
|
+
...t,
|
|
162
|
+
status: terminalStatus,
|
|
163
|
+
}
|
|
164
|
+
: t;
|
|
165
|
+
});
|
|
166
|
+
// Status transition rules:
|
|
167
|
+
// - Orphaned (detached) tasks never settle — counting them as working
|
|
168
|
+
// would leave the conversation reporting 'awaiting_async_tools' forever.
|
|
169
|
+
// - Only advance a status this delivery OWNS. A conversation can hold a
|
|
170
|
+
// non-async pause (awaiting_approval / awaiting_hitl /
|
|
171
|
+
// awaiting_client_tools) while async tasks are outstanding; clobbering
|
|
172
|
+
// it to 'in_progress' would make the engine skip the decision-resume
|
|
173
|
+
// path and drop the caller's approvals.
|
|
174
|
+
// - A 'complete' conversation is only reopened when the caller asked to
|
|
175
|
+
// continue (`run` config). Record-only delivery on a finished
|
|
176
|
+
// conversation keeps it finished — the envelope rides along if the
|
|
177
|
+
// caller ever resumes it.
|
|
178
|
+
const stillWorking = nextPending.some((t) => t.status === 'working' && t.orphaned !== true);
|
|
179
|
+
const statusOwnedByAsyncDelivery = state.status === 'awaiting_async_tools' ||
|
|
180
|
+
state.status === 'in_progress' ||
|
|
181
|
+
(state.status === 'complete' && request.run !== undefined) ||
|
|
182
|
+
state.status === undefined;
|
|
183
|
+
const updated = updateState(state, {
|
|
184
|
+
messages: appendToMessages(state.messages, envelopes),
|
|
185
|
+
settledAsyncCallIds: [
|
|
186
|
+
...(state.settledAsyncCallIds ?? []),
|
|
187
|
+
...settledNow.keys(),
|
|
188
|
+
],
|
|
189
|
+
...(statusOwnedByAsyncDelivery && {
|
|
190
|
+
status: stillWorking ? 'awaiting_async_tools' : 'in_progress',
|
|
191
|
+
}),
|
|
192
|
+
pendingAsyncTools: nextPending,
|
|
193
|
+
});
|
|
194
|
+
await request.state.save(updated);
|
|
195
|
+
if (!request.run) {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
// Continue the conversation: the envelopes are already in persisted
|
|
199
|
+
// history, so no fresh input is supplied.
|
|
200
|
+
return callModel(client, {
|
|
201
|
+
...request.run,
|
|
202
|
+
input: [],
|
|
203
|
+
tools: request.run.tools ?? request.tools,
|
|
204
|
+
state: request.state,
|
|
205
|
+
}, options);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Build the `tool_task_result` envelope for one resume entry. Successful
|
|
209
|
+
* outputs are validated against the owning tool's `outputSchema` when the
|
|
210
|
+
* tool is available; error entries carry the caller's refined status
|
|
211
|
+
* (default `'failed'`).
|
|
212
|
+
*/
|
|
213
|
+
function buildResumeEnvelope(entry, task, tools) {
|
|
214
|
+
if ('output' in entry && entry.error === undefined) {
|
|
215
|
+
const tool = tools?.find((t) => isClientTool(t) && t.function.name === task.name);
|
|
216
|
+
// Fail closed: when a tools list was supplied but the owning tool is
|
|
217
|
+
// not in it, the caller expected validation — appending the output
|
|
218
|
+
// unvalidated would silently void that expectation.
|
|
219
|
+
if (tools !== undefined && tool === undefined) {
|
|
220
|
+
throw new Error(`resumeToolResults: task "${task.taskId}" belongs to tool "${task.name}", which is not in the supplied tools list — its output cannot be validated. Include the tool, or omit \`tools\` to skip validation explicitly.`);
|
|
221
|
+
}
|
|
222
|
+
let output = entry.output;
|
|
223
|
+
if (tool && isUnifiedTool(tool) && tool.function.outputSchema !== undefined) {
|
|
224
|
+
output = validateToolOutput(tool.function.outputSchema, output);
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
type: 'tool_task_result',
|
|
228
|
+
tool: task.name,
|
|
229
|
+
taskId: task.taskId,
|
|
230
|
+
callId: task.callId,
|
|
231
|
+
status: 'completed',
|
|
232
|
+
result: output,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
type: 'tool_task_result',
|
|
237
|
+
tool: task.name,
|
|
238
|
+
taskId: task.taskId,
|
|
239
|
+
callId: task.callId,
|
|
240
|
+
status: entry.status ?? 'failed',
|
|
241
|
+
error: entry.error ?? 'Task failed',
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=resume-tool-results.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume-tool-results.js","sourceRoot":"","sources":["../../src/inner-loop/resume-tool-results.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { $ZodObject, $ZodShape, $ZodType, infer as zodInfer } from 'zod/v4/core';
|
|
2
|
+
import type { CallModelInput } from './async-params.js';
|
|
3
|
+
import type { ModelResult } from './model-result.js';
|
|
4
|
+
import type { TaskTranscriptSource } from './tool-task.js';
|
|
5
|
+
import type { AsyncToolAck, ContextFromSchema, ConversationState, NextTurnParamsFunctions, Tool, ToolApprovalCheck, ToolCheckConfig, ToolExecuteContext, ToolLoopKey, UnifiedTool } from './tool-types.js';
|
|
6
|
+
/**
|
|
7
|
+
* The child run spec an agent tool produces per call.
|
|
8
|
+
*
|
|
9
|
+
* Exclusions and why:
|
|
10
|
+
* - `state`: the engine supplies an internal in-memory accessor (it is what
|
|
11
|
+
* makes the live transcript possible). A child persisting to the parent's
|
|
12
|
+
* accessor would clobber the parent conversation; durable child sessions
|
|
13
|
+
* are a separate feature.
|
|
14
|
+
* - `signal`: the engine supplies it (parent abort / timeout / cancelTask
|
|
15
|
+
* propagate into the child).
|
|
16
|
+
* - `approveToolCalls`/`rejectToolCalls`: approval decisions belong to a
|
|
17
|
+
* durable session.
|
|
18
|
+
*
|
|
19
|
+
* `hooks` IS allowed — a child may declare its own hooks explicitly. The
|
|
20
|
+
* parent's hooks are never inherited (they are written against the parent's
|
|
21
|
+
* tool vocabulary and their session accounting would double-fire per child).
|
|
22
|
+
*/
|
|
23
|
+
export type AgentRunSpec<TChildTools extends readonly Tool[] = readonly Tool[]> = Omit<CallModelInput<TChildTools>, 'state' | 'approveToolCalls' | 'rejectToolCalls' | 'signal'>;
|
|
24
|
+
/**
|
|
25
|
+
* Live transcript over an agent child's conversation, rendered from the
|
|
26
|
+
* child's (internal, in-memory) conversation state — the actual message
|
|
27
|
+
* history, robust regardless of streaming vs non-streaming transport.
|
|
28
|
+
*/
|
|
29
|
+
export declare class AgentTranscriptSource implements TaskTranscriptSource {
|
|
30
|
+
private readonly readState;
|
|
31
|
+
private turnsStarted;
|
|
32
|
+
private turnsEnded;
|
|
33
|
+
private currentActivity;
|
|
34
|
+
constructor(readState: () => ConversationState | null);
|
|
35
|
+
noteTurnStart(): void;
|
|
36
|
+
noteTurnEnd(lastText: string): void;
|
|
37
|
+
setActivity(activity: string): void;
|
|
38
|
+
statusExtras(): Record<string, unknown>;
|
|
39
|
+
render(maxChars: number): string;
|
|
40
|
+
}
|
|
41
|
+
/** Configuration for `tool.agent()`. */
|
|
42
|
+
export type AgentToolConfig<TInput extends $ZodObject<$ZodShape>, TOutput extends $ZodType, TChildTools extends readonly Tool[] = readonly Tool[], TCtx extends $ZodObject<$ZodShape> = $ZodObject<$ZodShape>, TName extends string = string> = {
|
|
43
|
+
name: TName;
|
|
44
|
+
description?: string;
|
|
45
|
+
inputSchema: TInput;
|
|
46
|
+
/**
|
|
47
|
+
* Whether providers should enforce strict schema adherence for this agent
|
|
48
|
+
* tool's generated arguments. OpenAI-style strict mode requires every
|
|
49
|
+
* property to be required; those providers may reject `.optional()` fields,
|
|
50
|
+
* so use `.nullable()` when the key may conceptually have no value.
|
|
51
|
+
*/
|
|
52
|
+
strict?: boolean | null;
|
|
53
|
+
/**
|
|
54
|
+
* Required. The mapped child result is validated against it — the same
|
|
55
|
+
* rule every long-running tool obeys (results settle after the round).
|
|
56
|
+
*/
|
|
57
|
+
outputSchema: TOutput;
|
|
58
|
+
/** Build the child run spec from this call's arguments. */
|
|
59
|
+
agent: (params: zodInfer<TInput>, context?: ToolExecuteContext<TName, ContextFromSchema<TCtx>>) => AgentRunSpec<TChildTools> | Promise<AgentRunSpec<TChildTools>>;
|
|
60
|
+
/**
|
|
61
|
+
* Map the finished child run to this tool's output. Default:
|
|
62
|
+
* `{ text: await child.getText() }` — so the natural outputSchema is
|
|
63
|
+
* `z.object({ text: z.string() })`.
|
|
64
|
+
*/
|
|
65
|
+
result?: (child: ModelResult<TChildTools>) => Promise<zodInfer<TOutput>> | zodInfer<TOutput>;
|
|
66
|
+
/** Hold the round this long before placeholdering. Default 250ms. */
|
|
67
|
+
graceMs?: number;
|
|
68
|
+
/** Deadline for the whole child run, in ms. */
|
|
69
|
+
timeoutMs?: number;
|
|
70
|
+
/** Max simultaneous child runs of this tool. */
|
|
71
|
+
maxConcurrency?: number;
|
|
72
|
+
/** Model-facing acknowledgement merged into the pending placeholder. */
|
|
73
|
+
ack?: AsyncToolAck<zodInfer<TInput>>;
|
|
74
|
+
/** Check-in config (the SDK default reports turns + activity). */
|
|
75
|
+
check?: ToolCheckConfig;
|
|
76
|
+
contextSchema?: TCtx;
|
|
77
|
+
nextTurnParams?: NextTurnParamsFunctions<zodInfer<TInput>>;
|
|
78
|
+
requireApproval?: boolean | ToolApprovalCheck<zodInfer<TInput>>;
|
|
79
|
+
loopKey?: ToolLoopKey<zodInfer<TInput>>;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Create an agent tool: a long-running tool whose work IS a child
|
|
83
|
+
* `callModel` conversation. The child runs as a background task — the
|
|
84
|
+
* parent loop keeps going, its per-turn activity feeds the task log (one
|
|
85
|
+
* entry per child turn), its conversation is the check-in transcript, and
|
|
86
|
+
* its final answer (via the `result` mapper) is delivered like any
|
|
87
|
+
* background result. Steering messages (`sendToTask`, or a check call's
|
|
88
|
+
* `task.send`) are injected into the child as user messages at its next
|
|
89
|
+
* turn boundary. `cancelTask` / parent abort cancel the child run.
|
|
90
|
+
*/
|
|
91
|
+
export declare function agentToolBuilder<TInput extends $ZodObject<$ZodShape>, TOutput extends $ZodType, TChildTools extends readonly Tool[] = readonly Tool[], TCtx extends $ZodObject<$ZodShape> = $ZodObject<$ZodShape>, TName extends string = string>(config: AgentToolConfig<TInput, TOutput, TChildTools, TCtx, TName>): UnifiedTool<TInput, TOutput, $ZodType<unknown>, Record<string, unknown>, TCtx, TName>;
|
|
92
|
+
//# sourceMappingURL=agent-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-tool.d.ts","sourceRoot":"","sources":["../../src/lib/agent-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { extractTextFromResponse } from './conversation-state.js';
|
|
2
|
+
import { TASK_TOOL_NAME } from './tool-check.js';
|
|
3
|
+
import { truncateTranscriptTail } from './tool-task.js';
|
|
4
|
+
import { SHARED_CONTEXT_KEY, ToolType } from './tool-types.js';
|
|
5
|
+
const TEXT_PREVIEW_CHARS = 200;
|
|
6
|
+
const ARGS_PREVIEW_CHARS = 80;
|
|
7
|
+
function preview(value, maxChars) {
|
|
8
|
+
const text = typeof value === 'string' ? value : (JSON.stringify(value) ?? String(value));
|
|
9
|
+
return text.length > maxChars ? `${text.slice(0, maxChars)}…` : text;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Live transcript over an agent child's conversation, rendered from the
|
|
13
|
+
* child's (internal, in-memory) conversation state — the actual message
|
|
14
|
+
* history, robust regardless of streaming vs non-streaming transport.
|
|
15
|
+
*/
|
|
16
|
+
export class AgentTranscriptSource {
|
|
17
|
+
constructor(readState) {
|
|
18
|
+
this.readState = readState;
|
|
19
|
+
this.turnsStarted = 0;
|
|
20
|
+
this.turnsEnded = 0;
|
|
21
|
+
this.currentActivity = 'starting';
|
|
22
|
+
}
|
|
23
|
+
noteTurnStart() {
|
|
24
|
+
this.turnsStarted++;
|
|
25
|
+
this.currentActivity = `turn ${this.turnsStarted} in progress`;
|
|
26
|
+
}
|
|
27
|
+
noteTurnEnd(lastText) {
|
|
28
|
+
this.turnsEnded++;
|
|
29
|
+
this.currentActivity = lastText ? `responded: ${preview(lastText, 80)}` : 'thinking';
|
|
30
|
+
}
|
|
31
|
+
setActivity(activity) {
|
|
32
|
+
this.currentActivity = activity;
|
|
33
|
+
}
|
|
34
|
+
statusExtras() {
|
|
35
|
+
return {
|
|
36
|
+
// Ended turns only — an in-flight turn shows up in turnsStarted and
|
|
37
|
+
// currentActivity, but is not counted as completed.
|
|
38
|
+
turnsCompleted: this.turnsEnded,
|
|
39
|
+
turnsStarted: this.turnsStarted,
|
|
40
|
+
currentActivity: this.currentActivity,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
render(maxChars) {
|
|
44
|
+
const state = this.readState();
|
|
45
|
+
if (!state || !Array.isArray(state.messages)) {
|
|
46
|
+
return '';
|
|
47
|
+
}
|
|
48
|
+
const lines = [];
|
|
49
|
+
for (const item of state.messages) {
|
|
50
|
+
const type = item['type'];
|
|
51
|
+
const role = item['role'];
|
|
52
|
+
if (role === 'user' && typeof item['content'] === 'string') {
|
|
53
|
+
lines.push(`user: ${preview(item['content'], TEXT_PREVIEW_CHARS)}`);
|
|
54
|
+
}
|
|
55
|
+
else if (type === 'message' && role === 'assistant') {
|
|
56
|
+
const content = item['content'];
|
|
57
|
+
const text = Array.isArray(content)
|
|
58
|
+
? content
|
|
59
|
+
.map((c) => c.text ?? '')
|
|
60
|
+
.join('')
|
|
61
|
+
.trim()
|
|
62
|
+
: '';
|
|
63
|
+
if (text) {
|
|
64
|
+
lines.push(`assistant: ${preview(text, TEXT_PREVIEW_CHARS)}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else if (type === 'function_call') {
|
|
68
|
+
lines.push(`→ ${String(item['name'])}(${preview(item['arguments'], ARGS_PREVIEW_CHARS)})`);
|
|
69
|
+
}
|
|
70
|
+
else if (type === 'function_call_output') {
|
|
71
|
+
lines.push(` ⇒ ${preview(item['output'], ARGS_PREVIEW_CHARS)}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const full = lines.join('\n');
|
|
75
|
+
return truncateTranscriptTail(full, maxChars);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Paused child statuses that an in-memory agent child cannot recover from. */
|
|
79
|
+
const CHILD_PAUSE_STATUSES = new Set([
|
|
80
|
+
'awaiting_approval',
|
|
81
|
+
'awaiting_hitl',
|
|
82
|
+
'awaiting_client_tools',
|
|
83
|
+
'awaiting_async_tools',
|
|
84
|
+
]);
|
|
85
|
+
/**
|
|
86
|
+
* Create an agent tool: a long-running tool whose work IS a child
|
|
87
|
+
* `callModel` conversation. The child runs as a background task — the
|
|
88
|
+
* parent loop keeps going, its per-turn activity feeds the task log (one
|
|
89
|
+
* entry per child turn), its conversation is the check-in transcript, and
|
|
90
|
+
* its final answer (via the `result` mapper) is delivered like any
|
|
91
|
+
* background result. Steering messages (`sendToTask`, or a check call's
|
|
92
|
+
* `task.send`) are injected into the child as user messages at its next
|
|
93
|
+
* turn boundary. `cancelTask` / parent abort cancel the child run.
|
|
94
|
+
*/
|
|
95
|
+
export function agentToolBuilder(config) {
|
|
96
|
+
// Same reserved-name guards as tool() — a subagent named 'shared' would
|
|
97
|
+
// collide with the shared-context store key, one named 'task' would
|
|
98
|
+
// disable the built-in task-interaction tool.
|
|
99
|
+
if (config.name === SHARED_CONTEXT_KEY) {
|
|
100
|
+
throw new Error(`Tool name "${SHARED_CONTEXT_KEY}" is reserved for shared context. Choose a different name.`);
|
|
101
|
+
}
|
|
102
|
+
if (config.name === TASK_TOOL_NAME) {
|
|
103
|
+
throw new Error(`Tool name "${TASK_TOOL_NAME}" is reserved for the built-in task-interaction tool. Choose a different name.`);
|
|
104
|
+
}
|
|
105
|
+
if (config.outputSchema === undefined) {
|
|
106
|
+
throw new Error(`Agent tool "${config.name}" must declare an outputSchema. The child's mapped result is validated when it settles.`);
|
|
107
|
+
}
|
|
108
|
+
const defaultResult = async (child) => ({
|
|
109
|
+
text: await child.getText(),
|
|
110
|
+
});
|
|
111
|
+
const mapResult = config.result ?? defaultResult;
|
|
112
|
+
// The synthesized run: a plain async fn driving the child to completion.
|
|
113
|
+
// Turn activity surfaces through ctx.log (task log + preliminary events);
|
|
114
|
+
// the transcript reads the child's live in-memory conversation state.
|
|
115
|
+
async function run(params, ctx) {
|
|
116
|
+
const client = ctx?.client;
|
|
117
|
+
if (!client) {
|
|
118
|
+
throw new Error(`Agent tool "${config.name}": no client available on the run context. Agent tools must execute inside a callModel run.`);
|
|
119
|
+
}
|
|
120
|
+
const spec = await config.agent(params, ctx);
|
|
121
|
+
// Internal in-memory accessor: the child's message history IS the
|
|
122
|
+
// transcript, and getState() enables the pause-detection below. Never
|
|
123
|
+
// the caller's accessor — a child persisting there would clobber the
|
|
124
|
+
// parent conversation.
|
|
125
|
+
let childState = null;
|
|
126
|
+
const childAccessor = {
|
|
127
|
+
load: async () => childState,
|
|
128
|
+
save: async (state) => {
|
|
129
|
+
childState = state;
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
const transcript = new AgentTranscriptSource(() => childState);
|
|
133
|
+
if (ctx?.taskTranscript) {
|
|
134
|
+
ctx.taskTranscript.transcriptSource = transcript;
|
|
135
|
+
}
|
|
136
|
+
// Lazy import: agent-tool → call-model → model-result would otherwise
|
|
137
|
+
// be a static cycle (same pattern as bindDeferredCompletion).
|
|
138
|
+
const { callModel } = await import('../inner-loop/call-model.js');
|
|
139
|
+
const userOnTurnStart = spec.onTurnStart;
|
|
140
|
+
const userOnTurnEnd = spec.onTurnEnd;
|
|
141
|
+
const child = callModel(client, {
|
|
142
|
+
...spec,
|
|
143
|
+
state: childAccessor,
|
|
144
|
+
...(ctx?.signal !== undefined && {
|
|
145
|
+
signal: ctx.signal,
|
|
146
|
+
}),
|
|
147
|
+
onTurnStart: async (turnContext) => {
|
|
148
|
+
transcript.noteTurnStart();
|
|
149
|
+
await userOnTurnStart?.(turnContext);
|
|
150
|
+
},
|
|
151
|
+
onTurnEnd: async (turnContext, response) => {
|
|
152
|
+
const text = extractTextFromResponse(response);
|
|
153
|
+
transcript.noteTurnEnd(text);
|
|
154
|
+
// One log entry per child turn — feeds tailLogs and preliminary
|
|
155
|
+
// results on the parent stream.
|
|
156
|
+
ctx?.log?.({
|
|
157
|
+
turn: turnContext.numberOfTurns,
|
|
158
|
+
textPreview: preview(text.trim(), TEXT_PREVIEW_CHARS),
|
|
159
|
+
});
|
|
160
|
+
await userOnTurnEnd?.(turnContext, response);
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
// Steering: forward inbound task messages into the child conversation
|
|
164
|
+
// as user messages at its next safe turn boundary.
|
|
165
|
+
ctx?.onMessage?.((message) => {
|
|
166
|
+
child.queueUserMessage(typeof message === 'string' ? message : JSON.stringify(message));
|
|
167
|
+
});
|
|
168
|
+
// Drive the child to completion.
|
|
169
|
+
await child.getResponse();
|
|
170
|
+
transcript.setActivity('finished');
|
|
171
|
+
// In-memory children cannot pause durably: a paused child means a tool
|
|
172
|
+
// inside it awaits input that will never arrive. Fail loudly instead of
|
|
173
|
+
// silently returning a partial answer.
|
|
174
|
+
const finalStatus = childState !== null ? childState.status : undefined;
|
|
175
|
+
if (finalStatus !== undefined && CHILD_PAUSE_STATUSES.has(finalStatus)) {
|
|
176
|
+
throw new Error(`Agent tool "${config.name}": the child run paused with status '${finalStatus}'. Agent children run in-memory and cannot pause — avoid HITL/manual/deferred/approval tools inside agents (use lifecycle: 'deferred' on the parent tool instead).`);
|
|
177
|
+
}
|
|
178
|
+
return await mapResult(child);
|
|
179
|
+
}
|
|
180
|
+
const fn = {
|
|
181
|
+
lifecycle: 'background',
|
|
182
|
+
kind: 'agent',
|
|
183
|
+
name: config.name,
|
|
184
|
+
inputSchema: config.inputSchema,
|
|
185
|
+
outputSchema: config.outputSchema,
|
|
186
|
+
run,
|
|
187
|
+
};
|
|
188
|
+
const optionalFields = [
|
|
189
|
+
'description',
|
|
190
|
+
'strict',
|
|
191
|
+
'contextSchema',
|
|
192
|
+
'nextTurnParams',
|
|
193
|
+
'requireApproval',
|
|
194
|
+
'loopKey',
|
|
195
|
+
'timeoutMs',
|
|
196
|
+
'maxConcurrency',
|
|
197
|
+
'ack',
|
|
198
|
+
'graceMs',
|
|
199
|
+
'check',
|
|
200
|
+
];
|
|
201
|
+
for (const field of optionalFields) {
|
|
202
|
+
if (config[field] !== undefined) {
|
|
203
|
+
fn[field] = config[field];
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
type: ToolType.Function,
|
|
208
|
+
function: fn,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=agent-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-tool.js","sourceRoot":"","sources":["../../src/lib/agent-tool.ts"],"names":[],"mappings":"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"}
|