toolnexus 0.22.0 → 0.24.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 +73 -4
- package/dist/agents/loop.js +4 -1
- package/dist/agents/runtime.js +4 -1
- package/dist/client.d.ts +26 -1
- package/dist/client.js +56 -16
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/media.d.ts +126 -0
- package/dist/media.js +540 -0
- package/dist/toolconcurrency.d.ts +16 -0
- package/dist/toolconcurrency.js +59 -0
- package/dist/toolkit.d.ts +5 -2
- package/dist/toolkit.js +3 -3
- package/dist/types.d.ts +4 -1
- package/package.json +5 -3
- package/src/agents/loop.ts +4 -1
- package/src/agents/runtime.ts +4 -1
- package/src/client.ts +77 -19
- package/src/index.ts +2 -0
- package/src/media.ts +604 -0
- package/src/toolconcurrency.ts +67 -0
- package/src/toolkit.ts +6 -3
- package/src/types.ts +4 -1
package/dist/types.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export type JSONSchema = {
|
|
|
9
9
|
[k: string]: unknown;
|
|
10
10
|
};
|
|
11
11
|
import type { ContentPart } from "./content.js";
|
|
12
|
-
export type ToolSource = "mcp" | "skill" | "builtin" | "native" | "http" | "a2a" | "custom";
|
|
12
|
+
export type ToolSource = "mcp" | "skill" | "builtin" | "native" | "http" | "a2a" | "media" | "custom";
|
|
13
13
|
export interface ToolResult {
|
|
14
14
|
output: string;
|
|
15
15
|
isError: boolean;
|
|
@@ -96,6 +96,9 @@ export interface Tool {
|
|
|
96
96
|
/** What the tool may do (§4C). Builtins always carry hints; MCP tools carry them when the
|
|
97
97
|
* server sends annotations. Advisory: a server can mislabel its tools. */
|
|
98
98
|
hints?: ToolHints;
|
|
99
|
+
/** Decides per call whether this tool may run alongside other safe calls of the same model
|
|
100
|
+
* response (SPEC §8 "Tool scheduling"). Absent ⇒ safe only when `hints.readOnly`. */
|
|
101
|
+
concurrencySafe?: (args: Record<string, unknown>) => boolean;
|
|
99
102
|
}
|
|
100
103
|
export type McpStatus = "connected" | "disabled" | "failed";
|
|
101
104
|
/** Replace anything outside [a-zA-Z0-9_-] with "_" (same as opencode). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolnexus",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Dynamic MCP servers + agent skills as uniform tools for any LLM (opencode-style).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,10 +17,12 @@
|
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "tsc -p tsconfig.json",
|
|
20
|
-
"test": "npm run build && node --experimental-strip-types --test test/unit.test.ts test/agents.test.ts test/agent-hooks.test.ts test/agent-inprocess.test.ts test/home.test.ts test/compaction.test.ts test/loop.test.ts test/in-process.test.ts test/translate.test.ts test/multimodal.test.ts test/classifier.test.ts test/acp.test.ts test/issues.test.ts test/host-boundary.test.ts test/judge.test.ts test/batteries.test.ts test/host-engine.test.ts test/host-turn-durability.test.ts test/host-engine-asks.test.ts",
|
|
20
|
+
"test": "npm run build && node --experimental-strip-types --test test/unit.test.ts test/agents.test.ts test/agent-hooks.test.ts test/agent-inprocess.test.ts test/home.test.ts test/compaction.test.ts test/loop.test.ts test/in-process.test.ts test/translate.test.ts test/multimodal.test.ts test/classifier.test.ts test/acp.test.ts test/issues.test.ts test/host-boundary.test.ts test/judge.test.ts test/batteries.test.ts test/host-engine.test.ts test/host-turn-durability.test.ts test/host-engine-asks.test.ts test/tool-concurrency.test.ts test/media.test.ts test/examples.test.ts",
|
|
21
21
|
"example": "node --experimental-strip-types examples/basic.ts",
|
|
22
22
|
"example:judge": "node --experimental-strip-types examples/judge.ts",
|
|
23
|
-
"example:multimodal": "node --experimental-strip-types examples/multimodal.ts"
|
|
23
|
+
"example:multimodal": "node --experimental-strip-types examples/multimodal.ts",
|
|
24
|
+
"example:media": "node --experimental-strip-types examples/media.ts",
|
|
25
|
+
"example:prompt-cache": "node --experimental-strip-types examples/prompt_cache.ts"
|
|
24
26
|
},
|
|
25
27
|
"keywords": [
|
|
26
28
|
"mcp",
|
package/src/agents/loop.ts
CHANGED
|
@@ -141,6 +141,7 @@ export async function runGated(
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
let accumulated: RunResult["toolCalls"] = []
|
|
144
|
+
let accFiles: RunResult["files"] = []
|
|
144
145
|
let last: RunResult | undefined
|
|
145
146
|
let reason = ""
|
|
146
147
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
@@ -149,7 +150,9 @@ export async function runGated(
|
|
|
149
150
|
// The gate judges the ACCUMULATED work, so an agent cannot escape it by
|
|
150
151
|
// declining to re-declare its plan on a retry.
|
|
151
152
|
accumulated = [...accumulated, ...r.toolCalls]
|
|
152
|
-
|
|
153
|
+
// RunResult.files is derived from toolCalls, so it accumulates with them (§8).
|
|
154
|
+
accFiles = [...accFiles, ...(r.files ?? [])]
|
|
155
|
+
const judged: RunResult = { ...r, toolCalls: accumulated, files: accFiles }
|
|
153
156
|
last = judged
|
|
154
157
|
|
|
155
158
|
if (r.status && r.status !== "done") {
|
package/src/agents/runtime.ts
CHANGED
|
@@ -1012,7 +1012,7 @@ export class AgentRuntime {
|
|
|
1012
1012
|
const team = [...(parent.def.team ?? [])].sort()
|
|
1013
1013
|
const advertised = team.map((n) => (this.registry[n] ? `${n}: ${this.registry[n].does}` : n)).join("; ")
|
|
1014
1014
|
const rt = this
|
|
1015
|
-
|
|
1015
|
+
const tool = defineTool({
|
|
1016
1016
|
name: "task",
|
|
1017
1017
|
description: `Delegate a subtask to an isolated subagent (it runs on a fresh transcript and returns only its final answer). Available agents — ${advertised}`,
|
|
1018
1018
|
inputSchema: {
|
|
@@ -1068,5 +1068,8 @@ export class AgentRuntime {
|
|
|
1068
1068
|
}
|
|
1069
1069
|
},
|
|
1070
1070
|
})
|
|
1071
|
+
// Each subagent is isolated and the runtime's own gate schedules the children,
|
|
1072
|
+
// so a fan-out of task calls runs concurrently (SPEC §8 "Tool scheduling").
|
|
1073
|
+
return { ...tool, concurrencySafe: () => true }
|
|
1071
1074
|
}
|
|
1072
1075
|
}
|
package/src/client.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { toOpenAI, toAnthropic } from "./adapters.js"
|
|
|
10
10
|
import { applyPromptCache, type PromptCacheOptions } from "./promptcache.js"
|
|
11
11
|
import { buildToolPlan, toolSearch, unwrapCallTool, type ToolPlan, type ToolTier, type ToolTierOptions } from "./tooltiers.js"
|
|
12
12
|
import { isRetryableStatus, retryAfterMs } from "./retry.js"
|
|
13
|
+
import { isConcurrencySafe, resolveMaxToolConcurrency, scheduleCalls } from "./toolconcurrency.js"
|
|
13
14
|
import type { ContentPart, PromptInput, UnsupportedPartMode } from "./content.js"
|
|
14
15
|
import { toOpenAIWire, toAnthropicWire, checkPromptParts, type WireOptions } from "./wire.js"
|
|
15
16
|
import type { TranslateRequest, TranslateResult, TranslatedToolCall } from "./translate.js"
|
|
@@ -41,6 +42,10 @@ export interface ClientOptions {
|
|
|
41
42
|
headers?: Record<string, string>
|
|
42
43
|
systemPrompt?: string
|
|
43
44
|
maxTurns?: number
|
|
45
|
+
/** Cap on concurrency-safe tool calls of one response running at once (SPEC §8 "Tool
|
|
46
|
+
* scheduling"). Absent ⇒ env `TOOLNEXUS_MAX_TOOL_CONCURRENCY` when a positive integer, else 10.
|
|
47
|
+
* Unsafe calls (anything not read-only) always run alone. */
|
|
48
|
+
maxToolConcurrency?: number
|
|
44
49
|
hooks?: Hooks
|
|
45
50
|
/** Retries on transient LLM errors (`429`/`500`/`502`/`503`/`504`/`529` + network). Default 2.
|
|
46
51
|
* Widen the status set with `retryableStatuses`. */
|
|
@@ -318,6 +323,26 @@ export interface ToolCallRecord {
|
|
|
318
323
|
output: string
|
|
319
324
|
isError: boolean
|
|
320
325
|
metadata?: Record<string, unknown>
|
|
326
|
+
/** §8: the ToolResult's parts — present iff the result had parts. */
|
|
327
|
+
parts?: ContentPart[]
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** §8 RunResult.files entry: a non-text part a tool call produced this run. */
|
|
331
|
+
export type RunFile = { type: "image" | "file" | "audio"; mimeType: string; url?: string; data?: string; name?: string; from: string; callId: string }
|
|
332
|
+
|
|
333
|
+
/** Model tool-call id of each record, kept off the record itself (§8 shape has no id). */
|
|
334
|
+
const callIds = new WeakMap<ToolCallRecord, string>()
|
|
335
|
+
|
|
336
|
+
/** RunResult.files: every non-text part of every tool call, in call order (§8). */
|
|
337
|
+
function runFiles(toolCalls: ToolCallRecord[]): RunFile[] {
|
|
338
|
+
const out: RunFile[] = []
|
|
339
|
+
for (const r of toolCalls) {
|
|
340
|
+
for (const p of r.parts ?? []) {
|
|
341
|
+
if (p.type === "text") continue
|
|
342
|
+
out.push({ ...p, from: r.name, callId: callIds.get(r) ?? "" })
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return out
|
|
321
346
|
}
|
|
322
347
|
|
|
323
348
|
/** Token usage, summed across every LLM round trip in the run. */
|
|
@@ -340,6 +365,8 @@ export interface RunResult {
|
|
|
340
365
|
messages: any[]
|
|
341
366
|
/** Every tool call made, with its output, error flag, and metadata. */
|
|
342
367
|
toolCalls: ToolCallRecord[]
|
|
368
|
+
/** Every non-text part produced by tool calls this run, in call order (§8). Always present. */
|
|
369
|
+
files: RunFile[]
|
|
343
370
|
/** Total number of tool calls (= toolCalls.length). */
|
|
344
371
|
toolCallCount: number
|
|
345
372
|
/** Number of LLM round trips. */
|
|
@@ -990,11 +1017,42 @@ export class Client {
|
|
|
990
1017
|
return { args: a, result }
|
|
991
1018
|
}
|
|
992
1019
|
|
|
1020
|
+
/** Runs one response's calls under the tool schedule (SPEC §8 "Tool scheduling"). */
|
|
1021
|
+
private schedule<T, R>(
|
|
1022
|
+
toolkit: Toolkit | undefined,
|
|
1023
|
+
items: T[],
|
|
1024
|
+
key: (item: T) => [string, Record<string, unknown>],
|
|
1025
|
+
fn: (item: T) => Promise<R>,
|
|
1026
|
+
): Promise<R[]> {
|
|
1027
|
+
return scheduleCalls(items, (item) => {
|
|
1028
|
+
const [name, args] = key(item)
|
|
1029
|
+
return this.callSafe(toolkit, name, args)
|
|
1030
|
+
}, resolveMaxToolConcurrency(this.opts.maxToolConcurrency), fn)
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
/** One call's safety; looks through `call_tool` to the tool it names. Unknown ⇒ unsafe. */
|
|
1034
|
+
private callSafe(toolkit: Toolkit | undefined, name: string, args: Record<string, unknown>): boolean {
|
|
1035
|
+
if (this.opts.toolTiers && name === "tool_search") return true
|
|
1036
|
+
const inner = this.unwrapCall(name, args ?? {})
|
|
1037
|
+
const tool = toolkit?.get(inner ? inner.name : name)
|
|
1038
|
+
return tool ? isConcurrencySafe(tool, inner ? inner.args : (args ?? {})) : false
|
|
1039
|
+
}
|
|
1040
|
+
|
|
993
1041
|
/** ToolTiers `call_tool {name, arguments}` -> the real call; undefined when tiers are off. */
|
|
994
1042
|
private unwrapCall(name: string, args: Record<string, unknown>): { name: string; args: Record<string, unknown> } | undefined {
|
|
995
1043
|
return this.opts.toolTiers ? unwrapCallTool(name, args) : undefined
|
|
996
1044
|
}
|
|
997
1045
|
|
|
1046
|
+
/** The RunResult.toolCalls entry: a `call_tool` call is recorded as the real tool with its
|
|
1047
|
+
* inner arguments, the name hooks and stream events see (the transcript keeps the wrapper). */
|
|
1048
|
+
private toolCallRecord(name: string, args: Record<string, unknown>, result: ToolResult, callId?: string): ToolCallRecord {
|
|
1049
|
+
const inner = this.unwrapCall(name, args)
|
|
1050
|
+
const rec: ToolCallRecord = { name: inner ? inner.name : name, args: inner ? inner.args : args, output: result.output, isError: result.isError, metadata: result.metadata }
|
|
1051
|
+
if (result.parts?.length) rec.parts = result.parts
|
|
1052
|
+
callIds.set(rec, callId ?? "")
|
|
1053
|
+
return rec
|
|
1054
|
+
}
|
|
1055
|
+
|
|
998
1056
|
/** The stream's tool_call event, naming the real tool for a `call_tool` call. */
|
|
999
1057
|
private callEvent(id: string, name: string, args: Record<string, unknown>): StreamEvent {
|
|
1000
1058
|
const inner = this.unwrapCall(name, args)
|
|
@@ -1150,8 +1208,8 @@ export class Client {
|
|
|
1150
1208
|
if (calls.length === 0) return this.endRun(runStart, lastModel, msg.content ?? "", messages, toolCalls, turns, usage)
|
|
1151
1209
|
// execute all tool calls in this turn concurrently (true parallel tool calling)
|
|
1152
1210
|
done.clear()
|
|
1153
|
-
const settled = await untilAborted(signal,
|
|
1154
|
-
calls.
|
|
1211
|
+
const settled = await untilAborted(signal, this.schedule(toolkit,
|
|
1212
|
+
calls, (call: any) => [call.function.name, safeJson(call.function.arguments)], async (call: any) => {
|
|
1155
1213
|
let { args, result } = await this.runTool(toolkit, call.function.name, safeJson(call.function.arguments), call.id, turn, signal)
|
|
1156
1214
|
let halted: Request | undefined
|
|
1157
1215
|
const req = pendingOf(result)
|
|
@@ -1162,13 +1220,13 @@ export class Client {
|
|
|
1162
1220
|
}
|
|
1163
1221
|
if (!halted && call.id) done.set(call.id, result)
|
|
1164
1222
|
return { call, args, result, halted }
|
|
1165
|
-
}
|
|
1223
|
+
},
|
|
1166
1224
|
))
|
|
1167
1225
|
// Record in tool-call order; on the FIRST durable halt, surface it and stop — deterministic,
|
|
1168
1226
|
// and the later suspensions' placeholder results never enter the transcript (they re-suspend
|
|
1169
1227
|
// on resume). Mirrors the streaming path.
|
|
1170
1228
|
for (const s of settled) {
|
|
1171
|
-
toolCalls.push(
|
|
1229
|
+
toolCalls.push(this.toolCallRecord(s.call.function.name, s.args, s.result, s.call.id))
|
|
1172
1230
|
messages.push(toolMessage(s.call.id, s.call.function.name, s.result))
|
|
1173
1231
|
if (s.halted) return this.pendingRun(runStart, lastModel, s.halted, messages, toolCalls, turns, usage)
|
|
1174
1232
|
}
|
|
@@ -1183,7 +1241,7 @@ export class Client {
|
|
|
1183
1241
|
|
|
1184
1242
|
private result(model: string, text: string, messages: any[], toolCalls: ToolCallRecord[], turns: number, usage: Usage, exhausted = false): RunResult {
|
|
1185
1243
|
const incomplete = exhausted && text === ""
|
|
1186
|
-
const r: RunResult = { text, messages, toolCalls, toolCallCount: toolCalls.length, turns, usage, model, status: incomplete ? "incomplete" : "done" }
|
|
1244
|
+
const r: RunResult = { text, messages, toolCalls, files: runFiles(toolCalls), toolCallCount: toolCalls.length, turns, usage, model, status: incomplete ? "incomplete" : "done" }
|
|
1187
1245
|
if (incomplete) r.limit = "maxTurns"
|
|
1188
1246
|
return r
|
|
1189
1247
|
}
|
|
@@ -1191,7 +1249,7 @@ export class Client {
|
|
|
1191
1249
|
/** §10: a run halted because a tool suspended and no `waitFor` was configured. */
|
|
1192
1250
|
private pendingRun(runStart: number, model: string, request: Request, messages: any[], toolCalls: ToolCallRecord[], turns: number, usage: Usage): RunResult {
|
|
1193
1251
|
this.emit({ event: "run", model, turns, toolCalls: toolCalls.length, totalTokens: usage.totalTokens, ms: Date.now() - runStart })
|
|
1194
|
-
return { text: request.prompt, messages, toolCalls, toolCallCount: toolCalls.length, turns, usage, model, status: "pending", pending: request }
|
|
1252
|
+
return { text: request.prompt, messages, toolCalls, files: runFiles(toolCalls), toolCallCount: toolCalls.length, turns, usage, model, status: "pending", pending: request }
|
|
1195
1253
|
}
|
|
1196
1254
|
|
|
1197
1255
|
/**
|
|
@@ -1268,8 +1326,8 @@ export class Client {
|
|
|
1268
1326
|
}
|
|
1269
1327
|
// execute all tool_use blocks in this turn concurrently (true parallel tool calling)
|
|
1270
1328
|
done.clear()
|
|
1271
|
-
const settled = await untilAborted(signal,
|
|
1272
|
-
uses.
|
|
1329
|
+
const settled = await untilAborted(signal, this.schedule(toolkit,
|
|
1330
|
+
uses, (use: any) => [use.name, use.input ?? {}], async (use: any) => {
|
|
1273
1331
|
let { args, result } = await this.runTool(toolkit, use.name, use.input ?? {}, use.id, turn, signal)
|
|
1274
1332
|
let halted: Request | undefined
|
|
1275
1333
|
const req = pendingOf(result)
|
|
@@ -1280,7 +1338,7 @@ export class Client {
|
|
|
1280
1338
|
}
|
|
1281
1339
|
if (!halted && use.id) done.set(use.id, result)
|
|
1282
1340
|
return { use, args, result, halted }
|
|
1283
|
-
}
|
|
1341
|
+
},
|
|
1284
1342
|
))
|
|
1285
1343
|
// Record in tool-call order; on the FIRST durable halt, include that tool_result block, stop
|
|
1286
1344
|
// building the content, and surface it — deterministic (G3), later suspensions re-suspend on
|
|
@@ -1288,7 +1346,7 @@ export class Client {
|
|
|
1288
1346
|
const content: any[] = []
|
|
1289
1347
|
let halted: Request | undefined
|
|
1290
1348
|
for (const s of settled) {
|
|
1291
|
-
toolCalls.push(
|
|
1349
|
+
toolCalls.push(this.toolCallRecord(s.use.name, s.args, s.result, s.use.id))
|
|
1292
1350
|
content.push(toolResultBlock(s.use.id, s.result))
|
|
1293
1351
|
if (s.halted) { halted = s.halted; break }
|
|
1294
1352
|
}
|
|
@@ -1378,11 +1436,11 @@ export class Client {
|
|
|
1378
1436
|
messages.push({ role: "assistant", content: content || null, tool_calls: calls.map((c) => ({ id: c.id, type: "function", function: { name: c.name, arguments: c.args } })) })
|
|
1379
1437
|
for (const c of calls) yield this.callEvent(c.id, c.name, safeJson(c.args))
|
|
1380
1438
|
done.clear()
|
|
1381
|
-
const settled = await untilAborted(signal,
|
|
1439
|
+
const settled = await untilAborted(signal, this.schedule(toolkit, calls, (c) => [c.name, safeJson(c.args)], async (c) => {
|
|
1382
1440
|
const r = await this.runTool(toolkit, c.name, safeJson(c.args), c.id, turn, signal)
|
|
1383
|
-
|
|
1441
|
+
if (!pendingOf(r.result) && c.id) done.set(c.id, r.result)
|
|
1384
1442
|
return r
|
|
1385
|
-
}))
|
|
1443
|
+
}))
|
|
1386
1444
|
for (let i = 0; i < calls.length; i++) {
|
|
1387
1445
|
const c = calls[i]
|
|
1388
1446
|
let { args, result } = settled[i]
|
|
@@ -1392,13 +1450,13 @@ export class Client {
|
|
|
1392
1450
|
const r = await this.resolvePending(toolkit, c.name, args, req, c.id, turn, signal)
|
|
1393
1451
|
result = r.result
|
|
1394
1452
|
if (r.halted) {
|
|
1395
|
-
toolCalls.push(
|
|
1453
|
+
toolCalls.push(this.toolCallRecord(c.name, args, result, c.id))
|
|
1396
1454
|
messages.push(toolMessage(c.id, c.name, result))
|
|
1397
1455
|
yield { type: "done", result: this.pendingRun(runStart, lastModel, r.halted, messages, toolCalls, turns, usage) }
|
|
1398
1456
|
return
|
|
1399
1457
|
}
|
|
1400
1458
|
}
|
|
1401
|
-
toolCalls.push(
|
|
1459
|
+
toolCalls.push(this.toolCallRecord(c.name, args, result, c.id))
|
|
1402
1460
|
messages.push(toolMessage(c.id, c.name, result))
|
|
1403
1461
|
yield this.resultEvent(c.id, c.name, safeJson(c.args), result)
|
|
1404
1462
|
}
|
|
@@ -1480,11 +1538,11 @@ export class Client {
|
|
|
1480
1538
|
}
|
|
1481
1539
|
for (const u of uses as any[]) yield this.callEvent(u.id, u.name, u.input)
|
|
1482
1540
|
done.clear()
|
|
1483
|
-
const settled = await untilAborted(signal,
|
|
1541
|
+
const settled = await untilAborted(signal, this.schedule(toolkit, uses as any[], (u: any) => [u.name, u.input ?? {}], async (u: any) => {
|
|
1484
1542
|
const r = await this.runTool(toolkit, u.name, u.input ?? {}, u.id, turn, signal)
|
|
1485
1543
|
if (!pendingOf(r.result) && u.id) done.set(u.id, r.result)
|
|
1486
1544
|
return r
|
|
1487
|
-
}))
|
|
1545
|
+
}))
|
|
1488
1546
|
const results: any[] = []
|
|
1489
1547
|
for (let i = 0; i < uses.length; i++) {
|
|
1490
1548
|
const u = uses[i] as any
|
|
@@ -1495,14 +1553,14 @@ export class Client {
|
|
|
1495
1553
|
const r = await this.resolvePending(toolkit, u.name, args, req, u.id, turn, signal)
|
|
1496
1554
|
result = r.result
|
|
1497
1555
|
if (r.halted) {
|
|
1498
|
-
toolCalls.push(
|
|
1556
|
+
toolCalls.push(this.toolCallRecord(u.name, args, result, u.id))
|
|
1499
1557
|
results.push(toolResultBlock(u.id, result))
|
|
1500
1558
|
messages.push({ role: "user", content: results })
|
|
1501
1559
|
yield { type: "done", result: this.pendingRun(runStart, lastModel, r.halted, messages, toolCalls, turns, usage) }
|
|
1502
1560
|
return
|
|
1503
1561
|
}
|
|
1504
1562
|
}
|
|
1505
|
-
toolCalls.push(
|
|
1563
|
+
toolCalls.push(this.toolCallRecord(u.name, args, result, u.id))
|
|
1506
1564
|
results.push(toolResultBlock(u.id, result))
|
|
1507
1565
|
yield this.resultEvent(u.id, u.name, u.input, result)
|
|
1508
1566
|
}
|
package/src/index.ts
CHANGED