@cognipeer/agent-sdk 0.6.6 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +868 -188
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +148 -3
- package/dist/index.d.ts +148 -3
- package/dist/index.mjs +867 -189
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -42,7 +42,7 @@ function getTokenCounter() {
|
|
|
42
42
|
function countApproxTokens(text) {
|
|
43
43
|
return activeTokenCounter(text || "");
|
|
44
44
|
}
|
|
45
|
-
function
|
|
45
|
+
function extractMessageText2(m) {
|
|
46
46
|
if (!m) return "";
|
|
47
47
|
const parts = [];
|
|
48
48
|
parts.push(m.role || "");
|
|
@@ -92,7 +92,7 @@ function extractMessageText(m) {
|
|
|
92
92
|
}
|
|
93
93
|
function countMessagesTokens(messages) {
|
|
94
94
|
if (!Array.isArray(messages) || messages.length === 0) return 0;
|
|
95
|
-
const allText = messages.map(
|
|
95
|
+
const allText = messages.map(extractMessageText2).join("\n");
|
|
96
96
|
return countApproxTokens(allText) + messages.length * 4;
|
|
97
97
|
}
|
|
98
98
|
var activeTokenCounter;
|
|
@@ -1262,6 +1262,7 @@ function eventToOtlpSpan(event) {
|
|
|
1262
1262
|
stringAttr("cognipeer.actor.role", event.actor?.role),
|
|
1263
1263
|
stringAttr("cognipeer.model", event.model),
|
|
1264
1264
|
stringAttr("cognipeer.provider", event.provider),
|
|
1265
|
+
stringAttr("cognipeer.tool.details", event.toolDetails ? JSON.stringify(event.toolDetails) : void 0),
|
|
1265
1266
|
intAttr("cognipeer.tokens.input", event.inputTokens),
|
|
1266
1267
|
intAttr("cognipeer.tokens.output", event.outputTokens),
|
|
1267
1268
|
intAttr("cognipeer.tokens.total", event.totalTokens),
|
|
@@ -1733,6 +1734,7 @@ function recordTraceEvent(session, event) {
|
|
|
1733
1734
|
responseBytes,
|
|
1734
1735
|
model: resolvedModel,
|
|
1735
1736
|
provider: resolvedProvider,
|
|
1737
|
+
toolDetails: session.resolvedConfig.logData ? sanitizeTracePayload(event.toolDetails) : void 0,
|
|
1736
1738
|
toolExecutionId: event.toolExecutionId,
|
|
1737
1739
|
retryOf: event.retryOf,
|
|
1738
1740
|
error: event.error ?? (status === "error" ? { message: "Unknown error" } : void 0) ?? void 0,
|
|
@@ -2183,16 +2185,99 @@ function createAgentCoreNode(opts) {
|
|
|
2183
2185
|
};
|
|
2184
2186
|
}
|
|
2185
2187
|
|
|
2188
|
+
// src/utils/content.ts
|
|
2189
|
+
function contentToString(content) {
|
|
2190
|
+
try {
|
|
2191
|
+
if (content == null) return "";
|
|
2192
|
+
if (typeof content === "string") return content;
|
|
2193
|
+
if (Array.isArray(content)) {
|
|
2194
|
+
return content.map((p) => {
|
|
2195
|
+
if (!p || typeof p !== "object") return String(p);
|
|
2196
|
+
if (p.type === "text") return String(p.text ?? "");
|
|
2197
|
+
if (p.type === "image_url") {
|
|
2198
|
+
const img = p.image_url;
|
|
2199
|
+
const url = typeof img === "string" ? img : img?.url;
|
|
2200
|
+
const detail = typeof img === "string" ? void 0 : img?.detail;
|
|
2201
|
+
return `[image:${url || "unknown"}${detail ? ` detail=${detail}` : ""}]`;
|
|
2202
|
+
}
|
|
2203
|
+
return JSON.stringify(p);
|
|
2204
|
+
}).join("\n");
|
|
2205
|
+
}
|
|
2206
|
+
return JSON.stringify(content);
|
|
2207
|
+
} catch {
|
|
2208
|
+
return String(content);
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
function mergeContentsToString(contents) {
|
|
2212
|
+
return contents.map((c) => contentToString(c)).join("\n");
|
|
2213
|
+
}
|
|
2214
|
+
function safeStringify(value, pretty = false) {
|
|
2215
|
+
if (value == null) return "";
|
|
2216
|
+
if (typeof value === "string") return value;
|
|
2217
|
+
try {
|
|
2218
|
+
return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
|
|
2219
|
+
} catch {
|
|
2220
|
+
return String(value);
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
function extractMessageText(message) {
|
|
2224
|
+
if (!message) return "";
|
|
2225
|
+
const content = message.content;
|
|
2226
|
+
if (typeof content === "string") return content;
|
|
2227
|
+
if (Array.isArray(content)) {
|
|
2228
|
+
return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
|
|
2229
|
+
}
|
|
2230
|
+
return "";
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
// src/utils/traceSections.ts
|
|
2234
|
+
function truncate(text, max = 500) {
|
|
2235
|
+
if (!text) return "";
|
|
2236
|
+
return text.length > max ? `${text.slice(0, max)}\u2026` : text;
|
|
2237
|
+
}
|
|
2238
|
+
function summarizeToolOutput(output) {
|
|
2239
|
+
if (output == null) return "";
|
|
2240
|
+
if (typeof output === "string") return truncate(output.trim());
|
|
2241
|
+
if (Array.isArray(output)) {
|
|
2242
|
+
const preview = output.slice(0, 3).map((item, index) => `${index + 1}. ${truncate(safeStringify(item))}`).join("\n");
|
|
2243
|
+
const suffix = output.length > 3 ? `
|
|
2244
|
+
\u2026 (+${output.length - 3} more)` : "";
|
|
2245
|
+
return `${preview}${suffix}`.trim();
|
|
2246
|
+
}
|
|
2247
|
+
if (typeof output === "object") {
|
|
2248
|
+
if (Array.isArray(output.items)) {
|
|
2249
|
+
return summarizeToolOutput(output.items);
|
|
2250
|
+
}
|
|
2251
|
+
return truncate(safeStringify(output));
|
|
2252
|
+
}
|
|
2253
|
+
return truncate(String(output));
|
|
2254
|
+
}
|
|
2255
|
+
function extractToolItems(output) {
|
|
2256
|
+
const source = Array.isArray(output) ? output : Array.isArray(output?.items) ? output.items : void 0;
|
|
2257
|
+
if (!Array.isArray(source) || source.length === 0) return void 0;
|
|
2258
|
+
return source.slice(0, 5).map((item) => {
|
|
2259
|
+
if (item && typeof item === "object") {
|
|
2260
|
+
const snippetSource = item.content ?? item.snippet ?? item.description ?? item.text ?? item.summary ?? item;
|
|
2261
|
+
return {
|
|
2262
|
+
title: typeof item.title === "string" ? item.title : void 0,
|
|
2263
|
+
url: typeof item.url === "string" ? item.url : void 0,
|
|
2264
|
+
snippet: truncate(safeStringify(snippetSource))
|
|
2265
|
+
};
|
|
2266
|
+
}
|
|
2267
|
+
return { snippet: truncate(safeStringify(item)) };
|
|
2268
|
+
});
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2186
2271
|
// src/smart/runtimeConfig.ts
|
|
2187
2272
|
var DEFAULT_CRITICAL_TOOLS = ["response", "manage_todo_list", "get_tool_response"];
|
|
2188
2273
|
var BASE_DEFAULTS = {
|
|
2189
|
-
limits: { maxToolCalls:
|
|
2274
|
+
limits: { maxToolCalls: 20, maxParallelTools: 5, maxContextTokens: 96e3, maxTotalOutputTokens: 0, maxCostUsd: 0, maxWallClockMs: 0 },
|
|
2190
2275
|
summarization: {
|
|
2191
2276
|
enable: true,
|
|
2192
|
-
maxTokens:
|
|
2193
|
-
summaryTriggerTokens:
|
|
2194
|
-
summaryPromptMaxTokens:
|
|
2195
|
-
summaryCompressionRatioTarget: 0.
|
|
2277
|
+
maxTokens: 96e3,
|
|
2278
|
+
summaryTriggerTokens: 72e3,
|
|
2279
|
+
summaryPromptMaxTokens: 12e3,
|
|
2280
|
+
summaryCompressionRatioTarget: 0.45,
|
|
2196
2281
|
summaryMode: "incremental",
|
|
2197
2282
|
promptTemplate: "",
|
|
2198
2283
|
toolFreeCall: true,
|
|
@@ -2200,13 +2285,13 @@ var BASE_DEFAULTS = {
|
|
|
2200
2285
|
},
|
|
2201
2286
|
context: {
|
|
2202
2287
|
policy: "hybrid",
|
|
2203
|
-
lastTurnsToKeep:
|
|
2288
|
+
lastTurnsToKeep: 16,
|
|
2204
2289
|
toolResponsePolicy: "summarize_archive",
|
|
2205
2290
|
budget: {
|
|
2206
|
-
systemReserveTokens:
|
|
2207
|
-
goalsReserveTokens:
|
|
2208
|
-
recentTurnsReserveTokens:
|
|
2209
|
-
toolResponseReserveTokens:
|
|
2291
|
+
systemReserveTokens: 2e3,
|
|
2292
|
+
goalsReserveTokens: 2e3,
|
|
2293
|
+
recentTurnsReserveTokens: 18e3,
|
|
2294
|
+
toolResponseReserveTokens: 9e3
|
|
2210
2295
|
}
|
|
2211
2296
|
},
|
|
2212
2297
|
planning: {
|
|
@@ -2223,14 +2308,14 @@ var BASE_DEFAULTS = {
|
|
|
2223
2308
|
delegation: {
|
|
2224
2309
|
mode: "role_based",
|
|
2225
2310
|
maxDelegationDepth: 2,
|
|
2226
|
-
maxChildCalls:
|
|
2227
|
-
maxParallelChild:
|
|
2311
|
+
maxChildCalls: 6,
|
|
2312
|
+
maxParallelChild: 3,
|
|
2228
2313
|
childContextPolicy: "scoped",
|
|
2229
2314
|
requireJsonOutputContract: true
|
|
2230
2315
|
},
|
|
2231
2316
|
toolResponses: {
|
|
2232
|
-
maxToolResponseChars:
|
|
2233
|
-
maxToolResponseTokens:
|
|
2317
|
+
maxToolResponseChars: 32e3,
|
|
2318
|
+
maxToolResponseTokens: 8e3,
|
|
2234
2319
|
defaultPolicy: "summarize_archive",
|
|
2235
2320
|
toolResponseRetentionByTool: {},
|
|
2236
2321
|
criticalTools: [...DEFAULT_CRITICAL_TOOLS],
|
|
@@ -2259,54 +2344,54 @@ function buildProfile(overrides) {
|
|
|
2259
2344
|
}
|
|
2260
2345
|
var DEFAULT_PROFILE_CONFIGS = {
|
|
2261
2346
|
fast: buildProfile({
|
|
2262
|
-
limits: { maxToolCalls:
|
|
2347
|
+
limits: { maxToolCalls: 8, maxParallelTools: 3, maxContextTokens: 32e3 },
|
|
2263
2348
|
summarization: {
|
|
2264
|
-
maxTokens:
|
|
2265
|
-
summaryTriggerTokens:
|
|
2266
|
-
summaryPromptMaxTokens:
|
|
2267
|
-
summaryCompressionRatioTarget: 0.
|
|
2349
|
+
maxTokens: 32e3,
|
|
2350
|
+
summaryTriggerTokens: 24e3,
|
|
2351
|
+
summaryPromptMaxTokens: 6e3,
|
|
2352
|
+
summaryCompressionRatioTarget: 0.5
|
|
2268
2353
|
},
|
|
2269
2354
|
context: {
|
|
2270
|
-
lastTurnsToKeep:
|
|
2355
|
+
lastTurnsToKeep: 8,
|
|
2271
2356
|
toolResponsePolicy: "keep_structured",
|
|
2272
|
-
budget: { systemReserveTokens:
|
|
2357
|
+
budget: { systemReserveTokens: 1500, goalsReserveTokens: 1200, recentTurnsReserveTokens: 6e3, toolResponseReserveTokens: 3500 }
|
|
2273
2358
|
},
|
|
2274
2359
|
memory: { readPolicy: "recent_only" },
|
|
2275
2360
|
delegation: { mode: "off", maxDelegationDepth: 1, maxChildCalls: 2, maxParallelChild: 1, childContextPolicy: "minimal" },
|
|
2276
|
-
toolResponses: { maxToolResponseChars:
|
|
2361
|
+
toolResponses: { maxToolResponseChars: 16e3, maxToolResponseTokens: 4e3 }
|
|
2277
2362
|
}),
|
|
2278
2363
|
balanced: buildProfile({}),
|
|
2279
2364
|
deep: buildProfile({
|
|
2280
|
-
limits: { maxToolCalls:
|
|
2365
|
+
limits: { maxToolCalls: 40, maxParallelTools: 8, maxContextTokens: 2e5 },
|
|
2281
2366
|
summarization: {
|
|
2282
|
-
maxTokens:
|
|
2283
|
-
summaryTriggerTokens:
|
|
2284
|
-
summaryPromptMaxTokens:
|
|
2285
|
-
summaryCompressionRatioTarget: 0.
|
|
2367
|
+
maxTokens: 2e5,
|
|
2368
|
+
summaryTriggerTokens: 15e4,
|
|
2369
|
+
summaryPromptMaxTokens: 16e3,
|
|
2370
|
+
summaryCompressionRatioTarget: 0.4
|
|
2286
2371
|
},
|
|
2287
2372
|
context: {
|
|
2288
|
-
lastTurnsToKeep:
|
|
2289
|
-
budget: { systemReserveTokens:
|
|
2373
|
+
lastTurnsToKeep: 30,
|
|
2374
|
+
budget: { systemReserveTokens: 2500, goalsReserveTokens: 2500, recentTurnsReserveTokens: 36e3, toolResponseReserveTokens: 18e3 }
|
|
2290
2375
|
},
|
|
2291
2376
|
memory: { scope: "workspace" },
|
|
2292
|
-
delegation: { maxDelegationDepth: 3, maxChildCalls:
|
|
2293
|
-
toolResponses: { maxToolResponseChars:
|
|
2377
|
+
delegation: { maxDelegationDepth: 3, maxChildCalls: 10, maxParallelChild: 4 },
|
|
2378
|
+
toolResponses: { maxToolResponseChars: 64e3, maxToolResponseTokens: 16e3 }
|
|
2294
2379
|
}),
|
|
2295
2380
|
research: buildProfile({
|
|
2296
|
-
limits: { maxToolCalls:
|
|
2381
|
+
limits: { maxToolCalls: 80, maxParallelTools: 10, maxContextTokens: 4e5 },
|
|
2297
2382
|
summarization: {
|
|
2298
|
-
maxTokens:
|
|
2299
|
-
summaryTriggerTokens:
|
|
2300
|
-
summaryPromptMaxTokens:
|
|
2301
|
-
summaryCompressionRatioTarget: 0.
|
|
2383
|
+
maxTokens: 4e5,
|
|
2384
|
+
summaryTriggerTokens: 3e5,
|
|
2385
|
+
summaryPromptMaxTokens: 24e3,
|
|
2386
|
+
summaryCompressionRatioTarget: 0.35
|
|
2302
2387
|
},
|
|
2303
2388
|
context: {
|
|
2304
|
-
lastTurnsToKeep:
|
|
2305
|
-
budget: { systemReserveTokens:
|
|
2389
|
+
lastTurnsToKeep: 60,
|
|
2390
|
+
budget: { systemReserveTokens: 3e3, goalsReserveTokens: 3e3, recentTurnsReserveTokens: 72e3, toolResponseReserveTokens: 32e3 }
|
|
2306
2391
|
},
|
|
2307
2392
|
memory: { scope: "workspace" },
|
|
2308
|
-
delegation: { mode: "automatic", maxDelegationDepth: 4, maxChildCalls:
|
|
2309
|
-
toolResponses: { maxToolResponseChars:
|
|
2393
|
+
delegation: { mode: "automatic", maxDelegationDepth: 4, maxChildCalls: 16, maxParallelChild: 6, childContextPolicy: "full" },
|
|
2394
|
+
toolResponses: { maxToolResponseChars: 96e3, maxToolResponseTokens: 24e3 }
|
|
2310
2395
|
})
|
|
2311
2396
|
};
|
|
2312
2397
|
function mergeLimits(base, override) {
|
|
@@ -2396,53 +2481,6 @@ function getResolvedSmartConfig(opts, runtime) {
|
|
|
2396
2481
|
|
|
2397
2482
|
// src/smart/toolResponses.ts
|
|
2398
2483
|
init_utilTokens();
|
|
2399
|
-
|
|
2400
|
-
// src/utils/content.ts
|
|
2401
|
-
function contentToString(content) {
|
|
2402
|
-
try {
|
|
2403
|
-
if (content == null) return "";
|
|
2404
|
-
if (typeof content === "string") return content;
|
|
2405
|
-
if (Array.isArray(content)) {
|
|
2406
|
-
return content.map((p) => {
|
|
2407
|
-
if (!p || typeof p !== "object") return String(p);
|
|
2408
|
-
if (p.type === "text") return String(p.text ?? "");
|
|
2409
|
-
if (p.type === "image_url") {
|
|
2410
|
-
const img = p.image_url;
|
|
2411
|
-
const url = typeof img === "string" ? img : img?.url;
|
|
2412
|
-
const detail = typeof img === "string" ? void 0 : img?.detail;
|
|
2413
|
-
return `[image:${url || "unknown"}${detail ? ` detail=${detail}` : ""}]`;
|
|
2414
|
-
}
|
|
2415
|
-
return JSON.stringify(p);
|
|
2416
|
-
}).join("\n");
|
|
2417
|
-
}
|
|
2418
|
-
return JSON.stringify(content);
|
|
2419
|
-
} catch {
|
|
2420
|
-
return String(content);
|
|
2421
|
-
}
|
|
2422
|
-
}
|
|
2423
|
-
function mergeContentsToString(contents) {
|
|
2424
|
-
return contents.map((c) => contentToString(c)).join("\n");
|
|
2425
|
-
}
|
|
2426
|
-
function safeStringify(value, pretty = false) {
|
|
2427
|
-
if (value == null) return "";
|
|
2428
|
-
if (typeof value === "string") return value;
|
|
2429
|
-
try {
|
|
2430
|
-
return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
|
|
2431
|
-
} catch {
|
|
2432
|
-
return String(value);
|
|
2433
|
-
}
|
|
2434
|
-
}
|
|
2435
|
-
function extractMessageText2(message) {
|
|
2436
|
-
if (!message) return "";
|
|
2437
|
-
const content = message.content;
|
|
2438
|
-
if (typeof content === "string") return content;
|
|
2439
|
-
if (Array.isArray(content)) {
|
|
2440
|
-
return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
|
|
2441
|
-
}
|
|
2442
|
-
return "";
|
|
2443
|
-
}
|
|
2444
|
-
|
|
2445
|
-
// src/smart/toolResponses.ts
|
|
2446
2484
|
function summarizeObject(value) {
|
|
2447
2485
|
if (value == null) return "null";
|
|
2448
2486
|
if (typeof value === "string") {
|
|
@@ -2557,6 +2595,97 @@ function normalizeToolCall(call) {
|
|
|
2557
2595
|
args: call.args ?? call.arguments ?? call.input ?? call.function?.arguments ?? call.function_call?.arguments
|
|
2558
2596
|
};
|
|
2559
2597
|
}
|
|
2598
|
+
function normalizeToolSchema(tool, toolName) {
|
|
2599
|
+
const schema = tool.schema;
|
|
2600
|
+
if (!schema) return void 0;
|
|
2601
|
+
if (typeof schema === "object" && schema._def) {
|
|
2602
|
+
try {
|
|
2603
|
+
return sanitizeTracePayload(zodToJsonSchema(schema, { name: toolName }));
|
|
2604
|
+
} catch {
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
if (schema && typeof schema === "object" && typeof schema.toJSON === "function") {
|
|
2608
|
+
try {
|
|
2609
|
+
return sanitizeTracePayload(schema.toJSON());
|
|
2610
|
+
} catch {
|
|
2611
|
+
}
|
|
2612
|
+
}
|
|
2613
|
+
return sanitizeTracePayload(schema);
|
|
2614
|
+
}
|
|
2615
|
+
function buildToolDetails(tool, toolName) {
|
|
2616
|
+
if (!tool) return void 0;
|
|
2617
|
+
const details = { name: toolName };
|
|
2618
|
+
if (typeof tool.description === "string" && tool.description.trim().length > 0) {
|
|
2619
|
+
details.description = tool.description;
|
|
2620
|
+
}
|
|
2621
|
+
const inputSchema = normalizeToolSchema(tool, toolName);
|
|
2622
|
+
if (inputSchema !== void 0) details.inputSchema = inputSchema;
|
|
2623
|
+
const needsApproval = typeof tool.needsApproval === "boolean" ? tool.needsApproval : void 0;
|
|
2624
|
+
if (needsApproval !== void 0 || tool.approvalPrompt !== void 0 || tool.approvalDefaults !== void 0) {
|
|
2625
|
+
details.approval = {
|
|
2626
|
+
required: needsApproval,
|
|
2627
|
+
prompt: typeof tool.approvalPrompt === "string" ? tool.approvalPrompt : void 0,
|
|
2628
|
+
defaults: tool.approvalDefaults !== void 0 ? sanitizeTracePayload(tool.approvalDefaults) : void 0
|
|
2629
|
+
};
|
|
2630
|
+
}
|
|
2631
|
+
const cache = tool.cache;
|
|
2632
|
+
if (cache !== void 0) {
|
|
2633
|
+
details.cache = {
|
|
2634
|
+
enabled: Boolean(cache),
|
|
2635
|
+
scope: cache && typeof cache === "object" && typeof cache.scope === "string" ? cache.scope : void 0,
|
|
2636
|
+
ttlMs: cache && typeof cache === "object" && typeof cache.ttlMs === "number" ? cache.ttlMs : void 0,
|
|
2637
|
+
hasKeyFn: Boolean(cache && typeof cache === "object" && typeof cache.keyFn === "function")
|
|
2638
|
+
};
|
|
2639
|
+
}
|
|
2640
|
+
const retry = tool.retry;
|
|
2641
|
+
if (retry && typeof retry === "object") {
|
|
2642
|
+
details.retry = {
|
|
2643
|
+
maxRetries: typeof retry.maxRetries === "number" ? retry.maxRetries : void 0,
|
|
2644
|
+
backoffMs: typeof retry.backoffMs === "number" ? retry.backoffMs : void 0,
|
|
2645
|
+
circuitBreakerThreshold: typeof retry.circuitBreakerThreshold === "number" ? retry.circuitBreakerThreshold : void 0,
|
|
2646
|
+
hasShouldRetry: typeof retry.shouldRetry === "function"
|
|
2647
|
+
};
|
|
2648
|
+
}
|
|
2649
|
+
if (tool.maxExecutionsPerRun !== void 0) {
|
|
2650
|
+
details.limits = { maxExecutionsPerRun: tool.maxExecutionsPerRun };
|
|
2651
|
+
}
|
|
2652
|
+
if (typeof tool.__source === "string") {
|
|
2653
|
+
details.source = tool.__source;
|
|
2654
|
+
}
|
|
2655
|
+
return details;
|
|
2656
|
+
}
|
|
2657
|
+
function buildToolTraceSections(params) {
|
|
2658
|
+
const sanitizedArgs = sanitizeTracePayload(params.args ?? {});
|
|
2659
|
+
const sanitizedOutput = sanitizeTracePayload(params.output);
|
|
2660
|
+
const summary = params.summary ?? summarizeToolOutput(sanitizedOutput);
|
|
2661
|
+
const items = extractToolItems(sanitizedOutput);
|
|
2662
|
+
return [
|
|
2663
|
+
{
|
|
2664
|
+
kind: "tool_call",
|
|
2665
|
+
label: `Tool Call: ${params.toolName}`,
|
|
2666
|
+
tool: params.toolName,
|
|
2667
|
+
arguments: sanitizedArgs,
|
|
2668
|
+
toolDetails: params.toolDetails
|
|
2669
|
+
},
|
|
2670
|
+
{
|
|
2671
|
+
kind: "tool_result",
|
|
2672
|
+
label: `Tool Result: ${params.toolName}`,
|
|
2673
|
+
tool: params.toolName,
|
|
2674
|
+
summary,
|
|
2675
|
+
items,
|
|
2676
|
+
output: sanitizedOutput,
|
|
2677
|
+
toolDetails: params.toolDetails,
|
|
2678
|
+
execution: {
|
|
2679
|
+
id: params.executionId,
|
|
2680
|
+
status: params.status,
|
|
2681
|
+
durationMs: params.durationMs,
|
|
2682
|
+
fromCache: params.fromCache
|
|
2683
|
+
},
|
|
2684
|
+
classification: params.classification,
|
|
2685
|
+
retentionPolicy: params.retentionPolicy
|
|
2686
|
+
}
|
|
2687
|
+
];
|
|
2688
|
+
}
|
|
2560
2689
|
function createToolsNode(initialTools, opts) {
|
|
2561
2690
|
return async (state) => {
|
|
2562
2691
|
const runtime = state.agent || {
|
|
@@ -2665,6 +2794,7 @@ function createToolsNode(initialTools, opts) {
|
|
|
2665
2794
|
args = validatedArgs.value;
|
|
2666
2795
|
}
|
|
2667
2796
|
const toolName = tool.name || tc.name;
|
|
2797
|
+
const toolDetails = buildToolDetails(tool, toolName);
|
|
2668
2798
|
const toolStateRef = tool._stateRef && typeof tool._stateRef === "object" ? tool._stateRef : null;
|
|
2669
2799
|
if (toolStateRef) {
|
|
2670
2800
|
toolStateRef.pendingApprovals = pendingApprovals;
|
|
@@ -2685,21 +2815,17 @@ function createToolsNode(initialTools, opts) {
|
|
|
2685
2815
|
label: `Tool Skipped - ${toolName}`,
|
|
2686
2816
|
actor: { scope: "tool", name: toolName, role: "tool" },
|
|
2687
2817
|
status: "skipped",
|
|
2818
|
+
toolDetails,
|
|
2688
2819
|
toolExecutionId: tc.id,
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
function: { name: toolName, arguments: sanitizeTracePayload(args) }
|
|
2699
|
-
}
|
|
2700
|
-
]
|
|
2701
|
-
}
|
|
2702
|
-
]
|
|
2820
|
+
sections: buildToolTraceSections({
|
|
2821
|
+
args,
|
|
2822
|
+
executionId: tc.id,
|
|
2823
|
+
output: limitMessage,
|
|
2824
|
+
status: "skipped",
|
|
2825
|
+
summary: limitMessage,
|
|
2826
|
+
toolDetails,
|
|
2827
|
+
toolName
|
|
2828
|
+
})
|
|
2703
2829
|
});
|
|
2704
2830
|
toolCount += 1;
|
|
2705
2831
|
return { status: "error" };
|
|
@@ -2786,6 +2912,25 @@ function createToolsNode(initialTools, opts) {
|
|
|
2786
2912
|
push({ role: "tool", content: breakerMsg, tool_call_id: toolCallId, name: tc.name });
|
|
2787
2913
|
markToolFailure(breakerMsg, toolName, toolCallId);
|
|
2788
2914
|
onEvent?.({ type: "tool_call", phase: "error", name: toolName, id: tc.id, args, error: { message: breakerMsg } });
|
|
2915
|
+
recordTraceEvent(traceSession, {
|
|
2916
|
+
type: "tool_call",
|
|
2917
|
+
label: `Tool Error - ${toolName}`,
|
|
2918
|
+
actor: { scope: "tool", name: toolName, role: "tool" },
|
|
2919
|
+
status: "error",
|
|
2920
|
+
requestBytes: inputBytes,
|
|
2921
|
+
toolDetails,
|
|
2922
|
+
toolExecutionId: toolCallId,
|
|
2923
|
+
error: { message: breakerMsg },
|
|
2924
|
+
sections: buildToolTraceSections({
|
|
2925
|
+
args,
|
|
2926
|
+
executionId: toolCallId,
|
|
2927
|
+
output: { message: breakerMsg },
|
|
2928
|
+
status: "error",
|
|
2929
|
+
summary: breakerMsg,
|
|
2930
|
+
toolDetails,
|
|
2931
|
+
toolName
|
|
2932
|
+
})
|
|
2933
|
+
});
|
|
2789
2934
|
toolCount += 1;
|
|
2790
2935
|
return { status: "error" };
|
|
2791
2936
|
}
|
|
@@ -2810,6 +2955,38 @@ function createToolsNode(initialTools, opts) {
|
|
|
2810
2955
|
});
|
|
2811
2956
|
push({ role: "tool", content: responsePolicy2.content, tool_call_id: tc.id || `${tc.name}_${toolCount}`, name: tc.name });
|
|
2812
2957
|
onEvent?.({ type: "tool_call", phase: "success", name: toolName, id: tc.id, args, result: cachedHit, durationMs: 0 });
|
|
2958
|
+
const sanitizedCachedHit = sanitizeTracePayload(cachedHit);
|
|
2959
|
+
const outputBytes2 = traceSession?.resolvedConfig.logData ? estimatePayloadBytes(sanitizedCachedHit) : void 0;
|
|
2960
|
+
recordTraceEvent(traceSession, {
|
|
2961
|
+
type: "tool_call",
|
|
2962
|
+
label: `Tool Execution - ${toolName}`,
|
|
2963
|
+
actor: { scope: "tool", name: toolName, role: "tool" },
|
|
2964
|
+
durationMs: 0,
|
|
2965
|
+
requestBytes: inputBytes,
|
|
2966
|
+
responseBytes: outputBytes2,
|
|
2967
|
+
toolDetails,
|
|
2968
|
+
toolExecutionId: executionId2,
|
|
2969
|
+
sections: buildToolTraceSections({
|
|
2970
|
+
args,
|
|
2971
|
+
classification: responsePolicy2.classification,
|
|
2972
|
+
durationMs: 0,
|
|
2973
|
+
executionId: executionId2,
|
|
2974
|
+
fromCache: true,
|
|
2975
|
+
output: sanitizedCachedHit,
|
|
2976
|
+
retentionPolicy: "keep_full",
|
|
2977
|
+
status: "cached",
|
|
2978
|
+
summary: responsePolicy2.content,
|
|
2979
|
+
toolDetails,
|
|
2980
|
+
toolName
|
|
2981
|
+
}),
|
|
2982
|
+
debug: {
|
|
2983
|
+
classification: responsePolicy2.classification,
|
|
2984
|
+
retentionPolicy: "keep_full",
|
|
2985
|
+
originalTokenCount: responsePolicy2.tokenCount,
|
|
2986
|
+
truncated: responsePolicy2.truncated,
|
|
2987
|
+
fromCache: true
|
|
2988
|
+
}
|
|
2989
|
+
});
|
|
2813
2990
|
toolCount += 1;
|
|
2814
2991
|
return { status: "success" };
|
|
2815
2992
|
}
|
|
@@ -2930,28 +3107,6 @@ function createToolsNode(initialTools, opts) {
|
|
|
2930
3107
|
}
|
|
2931
3108
|
const sanitizedOutput = sanitizeTracePayload(output);
|
|
2932
3109
|
const outputBytes = traceSession?.resolvedConfig.logData ? estimatePayloadBytes(sanitizedOutput) : void 0;
|
|
2933
|
-
const messageList = [
|
|
2934
|
-
{
|
|
2935
|
-
role: "assistant",
|
|
2936
|
-
name: toolName,
|
|
2937
|
-
content: "",
|
|
2938
|
-
tool_calls: [
|
|
2939
|
-
{
|
|
2940
|
-
id: tc.id || executionId,
|
|
2941
|
-
type: "function",
|
|
2942
|
-
function: {
|
|
2943
|
-
name: toolName,
|
|
2944
|
-
arguments: sanitizedArgs
|
|
2945
|
-
}
|
|
2946
|
-
}
|
|
2947
|
-
]
|
|
2948
|
-
},
|
|
2949
|
-
{
|
|
2950
|
-
role: "tool",
|
|
2951
|
-
name: toolName,
|
|
2952
|
-
content: responsePolicy.content
|
|
2953
|
-
}
|
|
2954
|
-
];
|
|
2955
3110
|
recordTraceEvent(traceSession, {
|
|
2956
3111
|
type: "tool_call",
|
|
2957
3112
|
label: `Tool Execution - ${toolName}`,
|
|
@@ -2959,8 +3114,20 @@ function createToolsNode(initialTools, opts) {
|
|
|
2959
3114
|
durationMs,
|
|
2960
3115
|
requestBytes: inputBytes,
|
|
2961
3116
|
responseBytes: outputBytes,
|
|
3117
|
+
toolDetails,
|
|
2962
3118
|
toolExecutionId: executionId,
|
|
2963
|
-
|
|
3119
|
+
sections: buildToolTraceSections({
|
|
3120
|
+
args: sanitizedArgs,
|
|
3121
|
+
classification: responsePolicy.classification,
|
|
3122
|
+
durationMs,
|
|
3123
|
+
executionId,
|
|
3124
|
+
output: sanitizedOutput,
|
|
3125
|
+
retentionPolicy: "keep_full",
|
|
3126
|
+
status: "success",
|
|
3127
|
+
summary: responsePolicy.content,
|
|
3128
|
+
toolDetails,
|
|
3129
|
+
toolName
|
|
3130
|
+
}),
|
|
2964
3131
|
debug: {
|
|
2965
3132
|
classification: responsePolicy.classification,
|
|
2966
3133
|
retentionPolicy: "keep_full",
|
|
@@ -2979,6 +3146,7 @@ function createToolsNode(initialTools, opts) {
|
|
|
2979
3146
|
markToolFailure(message, toolName, toolCallId);
|
|
2980
3147
|
onEvent?.({ type: "tool_call", phase: "error", name: toolName, id: tc.id, args, error: { message } });
|
|
2981
3148
|
onProgress?.({ stage: "tools", message: `Tool ${tc.name} failed`, detail: { error: message } });
|
|
3149
|
+
const errorOutput = { message, stack: error?.stack };
|
|
2982
3150
|
recordTraceEvent(traceSession, {
|
|
2983
3151
|
type: "tool_call",
|
|
2984
3152
|
label: `Tool Error - ${toolName}`,
|
|
@@ -2986,27 +3154,20 @@ function createToolsNode(initialTools, opts) {
|
|
|
2986
3154
|
status: "error",
|
|
2987
3155
|
durationMs,
|
|
2988
3156
|
requestBytes: inputBytes,
|
|
3157
|
+
responseBytes: traceSession?.resolvedConfig.logData ? estimatePayloadBytes(errorOutput) : void 0,
|
|
3158
|
+
toolDetails,
|
|
2989
3159
|
toolExecutionId: executionId,
|
|
2990
3160
|
error: { message, stack: error?.stack },
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
}
|
|
3002
|
-
]
|
|
3003
|
-
},
|
|
3004
|
-
{
|
|
3005
|
-
role: "tool",
|
|
3006
|
-
name: toolName,
|
|
3007
|
-
content: `Error executing tool: ${message}`
|
|
3008
|
-
}
|
|
3009
|
-
]
|
|
3161
|
+
sections: buildToolTraceSections({
|
|
3162
|
+
args: sanitizedArgs,
|
|
3163
|
+
durationMs,
|
|
3164
|
+
executionId,
|
|
3165
|
+
output: errorOutput,
|
|
3166
|
+
status: "error",
|
|
3167
|
+
summary: `Error executing tool: ${message}`,
|
|
3168
|
+
toolDetails,
|
|
3169
|
+
toolName
|
|
3170
|
+
})
|
|
3010
3171
|
});
|
|
3011
3172
|
toolCount += 1;
|
|
3012
3173
|
return { status: "error", approval: approvalEntry };
|
|
@@ -3083,29 +3244,26 @@ function createToolsNode(initialTools, opts) {
|
|
|
3083
3244
|
}
|
|
3084
3245
|
for (const tc of skipped) {
|
|
3085
3246
|
onEvent?.({ type: "tool_call", phase: "skipped", name: tc.name, id: tc.id, args: tc.args });
|
|
3086
|
-
const
|
|
3247
|
+
const toolDetails = buildToolDetails(toolByName.get(tc.name), tc.name);
|
|
3248
|
+
const skipMessage = `Skipped tool due to tool-call limit: ${tc.name}`;
|
|
3087
3249
|
recordTraceEvent(traceSession, {
|
|
3088
3250
|
type: "tool_call",
|
|
3089
3251
|
label: `Tool Skipped - ${tc.name}`,
|
|
3090
3252
|
actor: { scope: "tool", name: tc.name, role: "tool" },
|
|
3091
3253
|
status: "skipped",
|
|
3254
|
+
toolDetails,
|
|
3092
3255
|
toolExecutionId: tc.id,
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
function: { name: tc.name, arguments: sanitizedArgs }
|
|
3103
|
-
}
|
|
3104
|
-
]
|
|
3105
|
-
}
|
|
3106
|
-
]
|
|
3256
|
+
sections: buildToolTraceSections({
|
|
3257
|
+
args: tc.args,
|
|
3258
|
+
executionId: tc.id,
|
|
3259
|
+
output: skipMessage,
|
|
3260
|
+
status: "skipped",
|
|
3261
|
+
summary: skipMessage,
|
|
3262
|
+
toolDetails,
|
|
3263
|
+
toolName: tc.name
|
|
3264
|
+
})
|
|
3107
3265
|
});
|
|
3108
|
-
appended.push({ role: "tool", content:
|
|
3266
|
+
appended.push({ role: "tool", content: skipMessage, tool_call_id: tc.id || `${tc.name}_${appended.length}`, name: tc.name });
|
|
3109
3267
|
toolCount += 1;
|
|
3110
3268
|
}
|
|
3111
3269
|
if (!awaitingApproval && state.ctx?.__awaitingApproval) {
|
|
@@ -3177,15 +3335,40 @@ function countToolCallsInLastTurn(state) {
|
|
|
3177
3335
|
function stripReflectionAskMessages(messages) {
|
|
3178
3336
|
return messages.filter((m) => !(m?.role === "user" && m?.name === REFLECTION_ASK_NAME));
|
|
3179
3337
|
}
|
|
3338
|
+
function lastTwoToolTurns(state) {
|
|
3339
|
+
const groups = [];
|
|
3340
|
+
let cur = [];
|
|
3341
|
+
let sawTool = false;
|
|
3342
|
+
for (let i = state.messages.length - 1; i >= 0; i--) {
|
|
3343
|
+
const m = state.messages[i];
|
|
3344
|
+
if (m?.role === "tool") {
|
|
3345
|
+
if (m.name) cur.push(m.name);
|
|
3346
|
+
sawTool = true;
|
|
3347
|
+
} else if (m?.role === "assistant") {
|
|
3348
|
+
if (sawTool) {
|
|
3349
|
+
groups.push(cur);
|
|
3350
|
+
cur = [];
|
|
3351
|
+
sawTool = false;
|
|
3352
|
+
if (groups.length >= 2) break;
|
|
3353
|
+
}
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
if (sawTool && cur.length) groups.push(cur);
|
|
3357
|
+
return { current: groups[0] ?? [], previous: groups[1] ?? [] };
|
|
3358
|
+
}
|
|
3180
3359
|
function shouldRunReflection(cadence, state, ranToolsThisTurn) {
|
|
3181
3360
|
if (cadence === "off") return false;
|
|
3182
3361
|
if (cadence === "every_turn") return true;
|
|
3183
3362
|
if (cadence === "after_tool") return ranToolsThisTurn;
|
|
3363
|
+
if (cadence === "initial_then_after_tool") return ranToolsThisTurn;
|
|
3184
3364
|
if (cadence === "on_branch") {
|
|
3185
|
-
const
|
|
3186
|
-
|
|
3187
|
-
const
|
|
3188
|
-
|
|
3365
|
+
const { current, previous } = lastTwoToolTurns(state);
|
|
3366
|
+
if (previous.length === 0) return true;
|
|
3367
|
+
const a = new Set(current);
|
|
3368
|
+
const b = new Set(previous);
|
|
3369
|
+
for (const n of a) if (!b.has(n)) return true;
|
|
3370
|
+
for (const n of b) if (!a.has(n)) return true;
|
|
3371
|
+
return false;
|
|
3189
3372
|
}
|
|
3190
3373
|
return false;
|
|
3191
3374
|
}
|
|
@@ -3202,7 +3385,10 @@ function createReflectionNode(opts, resolved) {
|
|
|
3202
3385
|
const onEvent = state.ctx?.__onEvent;
|
|
3203
3386
|
const traceSession = state.ctx?.__traceSession;
|
|
3204
3387
|
const maxChars = resolved.maxChars;
|
|
3205
|
-
const
|
|
3388
|
+
const turnNow = state.toolCallCount ?? 0;
|
|
3389
|
+
const hookCtx = { state, turn: turnNow, trigger, ranToolsThisTurn: true };
|
|
3390
|
+
const defaultPrompt = (resolved.promptTemplate || DEFAULT_REFLECT_PROMPT).replace(/\$\{maxChars\}/g, String(maxChars));
|
|
3391
|
+
const promptBody = resolved.buildPrompt ? String(resolved.buildPrompt({ ...hookCtx, defaultPrompt, maxChars }) ?? defaultPrompt) : defaultPrompt;
|
|
3206
3392
|
const baseMessages = stripReflectionAskMessages([...state.messages]);
|
|
3207
3393
|
const askMessage = {
|
|
3208
3394
|
role: "user",
|
|
@@ -3236,6 +3422,8 @@ function createReflectionNode(opts, resolved) {
|
|
|
3236
3422
|
const rawText = extractText(response);
|
|
3237
3423
|
const text = trimToChars(String(rawText ?? "").trim(), maxChars);
|
|
3238
3424
|
if (!text) return {};
|
|
3425
|
+
const prevText = (state.reflections?.[state.reflections.length - 1]?.text || "").trim();
|
|
3426
|
+
if (prevText && isNearDuplicate(prevText, text)) return {};
|
|
3239
3427
|
const rawUsage = response?.usage_metadata || response?.response_metadata?.usage || response?.usage || response?.additional_kwargs?.usage;
|
|
3240
3428
|
const usage = normalizeUsage(rawUsage);
|
|
3241
3429
|
const { ids, names } = countToolCallsInLastTurn(state);
|
|
@@ -3284,6 +3472,12 @@ function createReflectionNode(opts, resolved) {
|
|
|
3284
3472
|
} catch (e) {
|
|
3285
3473
|
}
|
|
3286
3474
|
}
|
|
3475
|
+
if (resolved.onReflection) {
|
|
3476
|
+
try {
|
|
3477
|
+
resolved.onReflection(record, hookCtx);
|
|
3478
|
+
} catch {
|
|
3479
|
+
}
|
|
3480
|
+
}
|
|
3287
3481
|
const nextMessages = stripReflectionAskMessages([...state.messages]);
|
|
3288
3482
|
const reflections = [...state.reflections || [], record];
|
|
3289
3483
|
const kept = reflections.slice(-Math.max(1, resolved.keepLast));
|
|
@@ -3300,7 +3494,20 @@ ${r.text}
|
|
|
3300
3494
|
metadata: { reflectionId: r.id, reflectionTurn: r.turn, reflectionTrigger: r.trigger }
|
|
3301
3495
|
});
|
|
3302
3496
|
}
|
|
3303
|
-
|
|
3497
|
+
const patch = { messages: prunedMessages, reflections };
|
|
3498
|
+
if (resolved.feedTo === "memory") {
|
|
3499
|
+
const fact = {
|
|
3500
|
+
key: `reflection_turn_${turn}`,
|
|
3501
|
+
value: text,
|
|
3502
|
+
sourceTurn: turn,
|
|
3503
|
+
confidence: 0.3,
|
|
3504
|
+
tags: ["reflection"]
|
|
3505
|
+
};
|
|
3506
|
+
patch.memoryFacts = [...state.memoryFacts || [], fact];
|
|
3507
|
+
} else if (resolved.feedTo === "plan" && state.plan) {
|
|
3508
|
+
patch.plan = { ...state.plan, lastReflection: text };
|
|
3509
|
+
}
|
|
3510
|
+
return patch;
|
|
3304
3511
|
};
|
|
3305
3512
|
}
|
|
3306
3513
|
function extractText(chunk) {
|
|
@@ -3329,24 +3536,75 @@ function safeRandomId() {
|
|
|
3329
3536
|
return `r_${Math.random().toString(36).slice(2, 10)}_${Date.now().toString(36)}`;
|
|
3330
3537
|
}
|
|
3331
3538
|
}
|
|
3539
|
+
function isNearDuplicate(a, b) {
|
|
3540
|
+
const norm = (s) => s.toLowerCase().replace(/\s+/g, " ").trim();
|
|
3541
|
+
const na = norm(a);
|
|
3542
|
+
const nb = norm(b);
|
|
3543
|
+
if (na === nb) return true;
|
|
3544
|
+
const tokensA = new Set(na.split(" ").filter(Boolean));
|
|
3545
|
+
const tokensB = new Set(nb.split(" ").filter(Boolean));
|
|
3546
|
+
if (tokensA.size === 0 || tokensB.size === 0) return false;
|
|
3547
|
+
let inter = 0;
|
|
3548
|
+
for (const t of tokensA) if (tokensB.has(t)) inter++;
|
|
3549
|
+
const union = tokensA.size + tokensB.size - inter;
|
|
3550
|
+
return union > 0 && inter / union >= 0.9;
|
|
3551
|
+
}
|
|
3332
3552
|
|
|
3333
3553
|
// src/smart/reasoning.ts
|
|
3334
3554
|
var LEVEL_DEFAULTS = {
|
|
3555
|
+
minimal: {
|
|
3556
|
+
native: { effort: "minimal" },
|
|
3557
|
+
reflection: { maxTokens: 150, maxChars: 400, cadence: "off" }
|
|
3558
|
+
},
|
|
3335
3559
|
low: {
|
|
3336
3560
|
native: { effort: "low" },
|
|
3337
3561
|
reflection: { maxTokens: 200, maxChars: 600, cadence: "on_branch" }
|
|
3338
3562
|
},
|
|
3339
3563
|
medium: {
|
|
3340
3564
|
native: { effort: "medium" },
|
|
3341
|
-
reflection: { maxTokens: 350, maxChars: 1200, cadence: "
|
|
3565
|
+
reflection: { maxTokens: 350, maxChars: 1200, cadence: "initial_then_after_tool" }
|
|
3342
3566
|
},
|
|
3343
3567
|
high: {
|
|
3344
3568
|
native: { effort: "high" },
|
|
3345
|
-
reflection: { maxTokens: 600, maxChars: 2e3, cadence: "
|
|
3569
|
+
reflection: { maxTokens: 600, maxChars: 2e3, cadence: "initial_then_after_tool" }
|
|
3346
3570
|
}
|
|
3347
3571
|
};
|
|
3572
|
+
var VALID_LEVELS = ["minimal", "low", "medium", "high"];
|
|
3573
|
+
var VALID_CADENCES = ["off", "every_turn", "after_tool", "on_branch", "initial_then_after_tool"];
|
|
3574
|
+
var VALID_EFFORTS = ["minimal", "low", "medium", "high"];
|
|
3575
|
+
function validateReasoningConfig(input) {
|
|
3576
|
+
if (!input) return;
|
|
3577
|
+
if (input.level !== void 0 && !VALID_LEVELS.includes(input.level)) {
|
|
3578
|
+
throw new Error(`reasoning.level must be one of ${VALID_LEVELS.join(", ")} (got "${input.level}")`);
|
|
3579
|
+
}
|
|
3580
|
+
if (input.native) {
|
|
3581
|
+
const n = input.native;
|
|
3582
|
+
if (n.effort !== void 0 && !VALID_EFFORTS.includes(n.effort)) {
|
|
3583
|
+
throw new Error(`reasoning.native.effort must be one of ${VALID_EFFORTS.join(", ")} (got "${n.effort}")`);
|
|
3584
|
+
}
|
|
3585
|
+
if (n.budgetTokens !== void 0 && (!Number.isFinite(n.budgetTokens) || n.budgetTokens < 0)) {
|
|
3586
|
+
throw new Error(`reasoning.native.budgetTokens must be a non-negative number (got ${n.budgetTokens})`);
|
|
3587
|
+
}
|
|
3588
|
+
}
|
|
3589
|
+
if (input.reflection) {
|
|
3590
|
+
const r = input.reflection;
|
|
3591
|
+
if (r.cadence !== void 0 && !VALID_CADENCES.includes(r.cadence)) {
|
|
3592
|
+
throw new Error(`reasoning.reflection.cadence must be one of ${VALID_CADENCES.join(", ")} (got "${r.cadence}")`);
|
|
3593
|
+
}
|
|
3594
|
+
if (r.maxPerRun !== void 0 && (!Number.isFinite(r.maxPerRun) || r.maxPerRun < 0)) {
|
|
3595
|
+
throw new Error(`reasoning.reflection.maxPerRun must be a non-negative number (got ${r.maxPerRun})`);
|
|
3596
|
+
}
|
|
3597
|
+
if (r.everyNTurns !== void 0 && (!Number.isFinite(r.everyNTurns) || r.everyNTurns < 1)) {
|
|
3598
|
+
throw new Error(`reasoning.reflection.everyNTurns must be >= 1 (got ${r.everyNTurns})`);
|
|
3599
|
+
}
|
|
3600
|
+
if (r.feedTo !== void 0 && !["memory", "plan", "none"].includes(r.feedTo)) {
|
|
3601
|
+
throw new Error(`reasoning.reflection.feedTo must be "memory", "plan", or "none" (got "${r.feedTo}")`);
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
}
|
|
3348
3605
|
function resolveReasoning(input) {
|
|
3349
3606
|
if (!input || input.enabled === false) return void 0;
|
|
3607
|
+
validateReasoningConfig(input);
|
|
3350
3608
|
const enabled = input.enabled ?? (input.native !== void 0 || input.reflection !== void 0 || input.level !== void 0);
|
|
3351
3609
|
if (!enabled) return void 0;
|
|
3352
3610
|
const level = input.level ?? "medium";
|
|
@@ -3371,7 +3629,8 @@ function resolveReflection(input, preset) {
|
|
|
3371
3629
|
keepLast: 3,
|
|
3372
3630
|
summarize: false,
|
|
3373
3631
|
emitEvents: true,
|
|
3374
|
-
everyNTurns: 1
|
|
3632
|
+
everyNTurns: 1,
|
|
3633
|
+
feedTo: "none"
|
|
3375
3634
|
};
|
|
3376
3635
|
}
|
|
3377
3636
|
const cfg = input ?? {};
|
|
@@ -3388,7 +3647,11 @@ function resolveReflection(input, preset) {
|
|
|
3388
3647
|
promptTemplate: cfg.promptTemplate,
|
|
3389
3648
|
emitEvents: cfg.emitEvents ?? true,
|
|
3390
3649
|
maxPerRun: typeof cfg.maxPerRun === "number" && cfg.maxPerRun >= 0 ? cfg.maxPerRun : void 0,
|
|
3391
|
-
everyNTurns: Math.max(1, Math.trunc(cfg.everyNTurns ?? 1))
|
|
3650
|
+
everyNTurns: Math.max(1, Math.trunc(cfg.everyNTurns ?? 1)),
|
|
3651
|
+
feedTo: cfg.feedTo ?? "none",
|
|
3652
|
+
shouldReflect: cfg.shouldReflect,
|
|
3653
|
+
buildPrompt: cfg.buildPrompt,
|
|
3654
|
+
onReflection: cfg.onReflection
|
|
3392
3655
|
};
|
|
3393
3656
|
}
|
|
3394
3657
|
function ensureArray(value) {
|
|
@@ -4114,12 +4377,14 @@ function createAgent(opts) {
|
|
|
4114
4377
|
if (summarizationThreshold === void 0) {
|
|
4115
4378
|
state = clearNeedsSummarization(state);
|
|
4116
4379
|
}
|
|
4117
|
-
if (resolvedReasoning
|
|
4380
|
+
if (resolvedReasoning) {
|
|
4118
4381
|
const ctx = { ...state.ctx || {} };
|
|
4119
|
-
if (
|
|
4382
|
+
if (resolvedReasoning.native) {
|
|
4120
4383
|
ctx.__reasoning = resolvedReasoning.native;
|
|
4121
|
-
|
|
4384
|
+
} else {
|
|
4385
|
+
delete ctx.__reasoning;
|
|
4122
4386
|
}
|
|
4387
|
+
state = { ...state, ctx: Object.keys(ctx).length > 0 ? ctx : void 0 };
|
|
4123
4388
|
}
|
|
4124
4389
|
const mergedLimits = {
|
|
4125
4390
|
...opts.limits || {},
|
|
@@ -4167,6 +4432,7 @@ function createAgent(opts) {
|
|
|
4167
4432
|
return { breached: false };
|
|
4168
4433
|
};
|
|
4169
4434
|
let iterations = 0;
|
|
4435
|
+
let reflectionsThisRun = 0;
|
|
4170
4436
|
const onStateChange = config?.onStateChange;
|
|
4171
4437
|
const checkpointReason = config?.checkpointReason;
|
|
4172
4438
|
let pausedStage = null;
|
|
@@ -4212,6 +4478,16 @@ function createAgent(opts) {
|
|
|
4212
4478
|
pausedStage = stage;
|
|
4213
4479
|
return true;
|
|
4214
4480
|
};
|
|
4481
|
+
if (reflectNode && resolvedReasoning?.reflection.enabled && resolvedReasoning.reflection.cadence === "initial_then_after_tool" && resumeStage === null && !state.ctx?.__awaitingApproval && !state.ctx?.__awaitingUserQuestion && !state.messages.some((m) => m?.role === "assistant")) {
|
|
4482
|
+
try {
|
|
4483
|
+
const patch = await reflectNode(state, "initial_then_after_tool");
|
|
4484
|
+
if (patch && Object.keys(patch).length > 0) {
|
|
4485
|
+
state = { ...state, ...patch };
|
|
4486
|
+
reflectionsThisRun++;
|
|
4487
|
+
}
|
|
4488
|
+
} catch {
|
|
4489
|
+
}
|
|
4490
|
+
}
|
|
4215
4491
|
while (iterations < iterationLimit) {
|
|
4216
4492
|
iterations++;
|
|
4217
4493
|
const budget = checkBudgetBreached();
|
|
@@ -4356,7 +4632,7 @@ function createAgent(opts) {
|
|
|
4356
4632
|
if (toolCalls.length === 0) {
|
|
4357
4633
|
if (soManager && !state.ctx?.__finalizedDueToStructuredOutput && !state.ctx?.__structuredOutputForceFinalize) {
|
|
4358
4634
|
if (soManager.strategy.kind === "native") {
|
|
4359
|
-
const assistantText =
|
|
4635
|
+
const assistantText = extractMessageText(lastMsg);
|
|
4360
4636
|
if (assistantText) {
|
|
4361
4637
|
const parsed = soManager.parseFromContent(assistantText);
|
|
4362
4638
|
if (parsed.success) {
|
|
@@ -4388,16 +4664,18 @@ function createAgent(opts) {
|
|
|
4388
4664
|
if (reflectNode && resolvedReasoning?.reflection.enabled) {
|
|
4389
4665
|
const cadence = resolvedReasoning.reflection.cadence;
|
|
4390
4666
|
const refl = resolvedReasoning.reflection;
|
|
4391
|
-
const reflectionsSoFar = state.reflections?.length ?? 0;
|
|
4392
4667
|
const lastTurn = state.reflections?.at(-1)?.turn ?? -Infinity;
|
|
4393
4668
|
const currentTurn = state.toolCallCount || 0;
|
|
4394
|
-
const budgetExceeded = typeof refl.maxPerRun === "number" &&
|
|
4395
|
-
const
|
|
4396
|
-
|
|
4669
|
+
const budgetExceeded = typeof refl.maxPerRun === "number" && reflectionsThisRun >= refl.maxPerRun;
|
|
4670
|
+
const sinceLast = currentTurn - (Number.isFinite(lastTurn) ? lastTurn : -refl.everyNTurns);
|
|
4671
|
+
const cadenceGap = sinceLast < refl.everyNTurns;
|
|
4672
|
+
const cadenceWantsIt = refl.shouldReflect ? !!refl.shouldReflect({ state, turn: currentTurn, trigger: cadence, ranToolsThisTurn: true }) : shouldRunReflection(cadence, state, true);
|
|
4673
|
+
if (!budgetExceeded && !cadenceGap && cadenceWantsIt) {
|
|
4397
4674
|
try {
|
|
4398
4675
|
const patch = await reflectNode(state, cadence);
|
|
4399
4676
|
if (patch && Object.keys(patch).length > 0) {
|
|
4400
4677
|
state = { ...state, ...patch };
|
|
4678
|
+
reflectionsThisRun++;
|
|
4401
4679
|
}
|
|
4402
4680
|
} catch {
|
|
4403
4681
|
}
|
|
@@ -4407,7 +4685,7 @@ function createAgent(opts) {
|
|
|
4407
4685
|
if (soManager && !state.ctx?.__finalizedDueToStructuredOutput) {
|
|
4408
4686
|
const lastForParse = state.messages[state.messages.length - 1];
|
|
4409
4687
|
if (lastForParse?.role === "assistant") {
|
|
4410
|
-
const assistantText =
|
|
4688
|
+
const assistantText = extractMessageText(lastForParse);
|
|
4411
4689
|
if (assistantText) {
|
|
4412
4690
|
const parsed = soManager.parseFromContent(assistantText);
|
|
4413
4691
|
if (parsed.success) {
|
|
@@ -4560,7 +4838,7 @@ function createAgent(opts) {
|
|
|
4560
4838
|
const isTransientSummarizationExit = !!res.ctx?.__needsSummarization;
|
|
4561
4839
|
const finalAssistantMsg = isTransientSummarizationExit ? void 0 : getLastAssistantMessage(res.messages);
|
|
4562
4840
|
const finalIsSyntheticSummary = !isTransientSummarizationExit && finalAssistantMsg && isSyntheticSummaryMessage(finalAssistantMsg);
|
|
4563
|
-
const content = isTransientSummarizationExit || finalIsSyntheticSummary ? "" :
|
|
4841
|
+
const content = isTransientSummarizationExit || finalIsSyntheticSummary ? "" : extractMessageText(finalAssistantMsg);
|
|
4564
4842
|
let parsed = void 0;
|
|
4565
4843
|
let outputError = void 0;
|
|
4566
4844
|
if (soManager) {
|
|
@@ -4868,7 +5146,7 @@ function renderMemoryBlock(facts) {
|
|
|
4868
5146
|
function clampToBudget(messages, maxContextTokens) {
|
|
4869
5147
|
let working = [...messages];
|
|
4870
5148
|
while (working.length > 2) {
|
|
4871
|
-
const tokenCount = countApproxTokens(working.map(
|
|
5149
|
+
const tokenCount = countApproxTokens(working.map(extractMessageText).join("\n"));
|
|
4872
5150
|
if (tokenCount <= maxContextTokens) return working;
|
|
4873
5151
|
const firstNonSystem = working.findIndex((message, index) => !(index === 0 && message.role === "system"));
|
|
4874
5152
|
if (firstNonSystem < 0) break;
|
|
@@ -5971,7 +6249,7 @@ function createSmartAgent(opts) {
|
|
|
5971
6249
|
].join("\n");
|
|
5972
6250
|
function latestUserPrompt(messages) {
|
|
5973
6251
|
const latest = [...messages].reverse().find((message) => message.role === "user");
|
|
5974
|
-
return latest ?
|
|
6252
|
+
return latest ? extractMessageText(latest) : "";
|
|
5975
6253
|
}
|
|
5976
6254
|
async function syncMemory(state) {
|
|
5977
6255
|
const query = latestUserPrompt(state.messages || []);
|
|
@@ -6660,6 +6938,20 @@ function parseSSEBlock(block) {
|
|
|
6660
6938
|
}
|
|
6661
6939
|
|
|
6662
6940
|
// src/providers/utils/reasoning.ts
|
|
6941
|
+
var ANTHROPIC_EFFORT_BUDGET = {
|
|
6942
|
+
minimal: 1024,
|
|
6943
|
+
low: 2048,
|
|
6944
|
+
medium: 8192,
|
|
6945
|
+
high: 16384
|
|
6946
|
+
};
|
|
6947
|
+
var GEMINI_EFFORT_BUDGET = {
|
|
6948
|
+
minimal: 512,
|
|
6949
|
+
low: 1024,
|
|
6950
|
+
medium: 4096,
|
|
6951
|
+
high: 12e3
|
|
6952
|
+
};
|
|
6953
|
+
var THINKING_OUTPUT_RESERVE = 1024;
|
|
6954
|
+
var THINKING_MIN_MAX_TOKENS = 4096;
|
|
6663
6955
|
function applyOpenAIReasoning(body, reasoning, mode = "legacy_effort") {
|
|
6664
6956
|
if (!reasoning) return;
|
|
6665
6957
|
const effort = normalizeEffort(reasoning.effort);
|
|
@@ -6676,21 +6968,56 @@ function applyOpenAIReasoning(body, reasoning, mode = "legacy_effort") {
|
|
|
6676
6968
|
}
|
|
6677
6969
|
function applyAnthropicReasoning(body, reasoning) {
|
|
6678
6970
|
if (!reasoning) return;
|
|
6679
|
-
|
|
6971
|
+
let budget = resolveBudget(reasoning, ANTHROPIC_EFFORT_BUDGET);
|
|
6680
6972
|
if (!budget) return;
|
|
6973
|
+
const currentMax = typeof body.max_tokens === "number" ? body.max_tokens : 0;
|
|
6974
|
+
const requiredMax = Math.max(THINKING_MIN_MAX_TOKENS, budget + THINKING_OUTPUT_RESERVE);
|
|
6975
|
+
if (currentMax < requiredMax) {
|
|
6976
|
+
body.max_tokens = requiredMax;
|
|
6977
|
+
}
|
|
6978
|
+
budget = clampBudget(budget, body.max_tokens);
|
|
6681
6979
|
const thinking = { type: "enabled", budget_tokens: budget };
|
|
6682
6980
|
if (reasoning.providerExtras) Object.assign(thinking, reasoning.providerExtras);
|
|
6683
6981
|
body.thinking = thinking;
|
|
6982
|
+
stripSamplingParams(body, ["temperature", "top_p", "top_k"]);
|
|
6983
|
+
}
|
|
6984
|
+
function applyBedrockReasoning(body, reasoning) {
|
|
6985
|
+
if (!reasoning) return;
|
|
6986
|
+
let budget = resolveBudget(reasoning, ANTHROPIC_EFFORT_BUDGET);
|
|
6987
|
+
if (!budget) return;
|
|
6988
|
+
const inference = body.inferenceConfig ?? (body.inferenceConfig = {});
|
|
6989
|
+
const currentMax = typeof inference.maxTokens === "number" ? inference.maxTokens : 0;
|
|
6990
|
+
const requiredMax = Math.max(THINKING_MIN_MAX_TOKENS, budget + THINKING_OUTPUT_RESERVE);
|
|
6991
|
+
if (currentMax < requiredMax) {
|
|
6992
|
+
inference.maxTokens = requiredMax;
|
|
6993
|
+
}
|
|
6994
|
+
budget = clampBudget(budget, inference.maxTokens);
|
|
6995
|
+
const extra = body.additionalModelRequestFields ?? (body.additionalModelRequestFields = {});
|
|
6996
|
+
const thinking = { type: "enabled", budget_tokens: budget };
|
|
6997
|
+
if (reasoning.providerExtras) Object.assign(thinking, reasoning.providerExtras);
|
|
6998
|
+
extra.thinking = thinking;
|
|
6999
|
+
stripSamplingParams(inference, ["temperature", "topP"]);
|
|
6684
7000
|
}
|
|
6685
7001
|
function applyGeminiReasoning(generationConfig, reasoning) {
|
|
6686
7002
|
if (!reasoning) return;
|
|
6687
|
-
const budget = resolveBudget(reasoning,
|
|
7003
|
+
const budget = resolveBudget(reasoning, GEMINI_EFFORT_BUDGET);
|
|
6688
7004
|
if (budget == null) return;
|
|
6689
7005
|
const thinkingConfig = { thinkingBudget: budget };
|
|
6690
7006
|
if (reasoning.includeThoughts) thinkingConfig.includeThoughts = true;
|
|
6691
7007
|
if (reasoning.providerExtras) Object.assign(thinkingConfig, reasoning.providerExtras);
|
|
6692
7008
|
generationConfig.thinkingConfig = thinkingConfig;
|
|
6693
7009
|
}
|
|
7010
|
+
function stripSamplingParams(target, keys) {
|
|
7011
|
+
for (const k of keys) {
|
|
7012
|
+
if (k in target) delete target[k];
|
|
7013
|
+
}
|
|
7014
|
+
}
|
|
7015
|
+
function clampBudget(budget, maxTokens) {
|
|
7016
|
+
if (typeof maxTokens !== "number" || maxTokens <= 0) return budget;
|
|
7017
|
+
const ceiling = maxTokens - THINKING_OUTPUT_RESERVE;
|
|
7018
|
+
if (ceiling < 1024) return Math.max(1024, Math.floor(maxTokens / 2));
|
|
7019
|
+
return Math.min(budget, ceiling);
|
|
7020
|
+
}
|
|
6694
7021
|
function normalizeEffort(effort) {
|
|
6695
7022
|
if (!effort) return void 0;
|
|
6696
7023
|
const allowed = ["minimal", "low", "medium", "high"];
|
|
@@ -6719,13 +7046,38 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
6719
7046
|
};
|
|
6720
7047
|
if (config.retry) this.retryPolicy = { ...this.retryPolicy, ...config.retry };
|
|
6721
7048
|
}
|
|
7049
|
+
/** True when the request targets a reasoning model (o-series / gpt-5) so we
|
|
7050
|
+
* should route through the Responses API, which exposes `reasoning.effort`
|
|
7051
|
+
* and reasoning summaries. Chat Completions silently drops these. */
|
|
7052
|
+
useResponsesApi(request) {
|
|
7053
|
+
if (!request.reasoning) return false;
|
|
7054
|
+
return isReasoningModel(request.model || this.defaultModel);
|
|
7055
|
+
}
|
|
6722
7056
|
async complete(request) {
|
|
7057
|
+
if (this.useResponsesApi(request)) {
|
|
7058
|
+
return this.completeResponses(request);
|
|
7059
|
+
}
|
|
6723
7060
|
const body = this.buildRequestBody(request, false);
|
|
6724
7061
|
const res = await this.doFetch(body);
|
|
6725
7062
|
const json = await res.json();
|
|
6726
7063
|
return this.parseResponse(json);
|
|
6727
7064
|
}
|
|
6728
7065
|
async *completeStream(request) {
|
|
7066
|
+
if (this.useResponsesApi(request)) {
|
|
7067
|
+
const response = await this.completeResponses(request);
|
|
7068
|
+
yield {
|
|
7069
|
+
id: response.id,
|
|
7070
|
+
model: response.model,
|
|
7071
|
+
delta: {
|
|
7072
|
+
content: response.content ?? void 0,
|
|
7073
|
+
toolCalls: response.toolCalls.length > 0 ? response.toolCalls : void 0,
|
|
7074
|
+
reasoning: response.reasoning
|
|
7075
|
+
},
|
|
7076
|
+
usage: response.usage,
|
|
7077
|
+
finishReason: response.finishReason
|
|
7078
|
+
};
|
|
7079
|
+
return;
|
|
7080
|
+
}
|
|
6729
7081
|
const body = this.buildRequestBody(request, true);
|
|
6730
7082
|
const res = await this.doFetch(body);
|
|
6731
7083
|
if (!res.body) throw new ProviderError("No response body for stream", this.providerName);
|
|
@@ -6824,6 +7176,156 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
6824
7176
|
applyOpenAIReasoning(body, request.reasoning, "legacy_effort");
|
|
6825
7177
|
return body;
|
|
6826
7178
|
}
|
|
7179
|
+
// ─── Responses API (reasoning models) ──────────────────────────────────────
|
|
7180
|
+
async completeResponses(request) {
|
|
7181
|
+
const body = this.buildResponsesBody(request);
|
|
7182
|
+
const res = await this.responsesFetch(body);
|
|
7183
|
+
const json = await res.json();
|
|
7184
|
+
return this.parseResponsesResponse(json, request.model || this.defaultModel);
|
|
7185
|
+
}
|
|
7186
|
+
buildResponsesBody(request) {
|
|
7187
|
+
const body = {
|
|
7188
|
+
model: request.model || this.defaultModel,
|
|
7189
|
+
input: request.messages.map((m) => this.toResponsesInput(m))
|
|
7190
|
+
};
|
|
7191
|
+
if (request.maxTokens != null) body.max_output_tokens = request.maxTokens;
|
|
7192
|
+
if (request.topP != null) body.top_p = request.topP;
|
|
7193
|
+
if (request.tools?.length) {
|
|
7194
|
+
body.tools = request.tools.map((t) => ({
|
|
7195
|
+
type: "function",
|
|
7196
|
+
name: t.name,
|
|
7197
|
+
description: t.description,
|
|
7198
|
+
parameters: t.parameters,
|
|
7199
|
+
...t.strict ? { strict: true } : {}
|
|
7200
|
+
}));
|
|
7201
|
+
}
|
|
7202
|
+
if (request.toolChoice != null && request.tools?.length) {
|
|
7203
|
+
if (typeof request.toolChoice === "string") {
|
|
7204
|
+
body.tool_choice = request.toolChoice;
|
|
7205
|
+
} else {
|
|
7206
|
+
body.tool_choice = { type: "function", name: request.toolChoice.name };
|
|
7207
|
+
}
|
|
7208
|
+
}
|
|
7209
|
+
if (request.responseFormat) {
|
|
7210
|
+
if (request.responseFormat.type === "json_schema") {
|
|
7211
|
+
body.text = {
|
|
7212
|
+
format: {
|
|
7213
|
+
type: "json_schema",
|
|
7214
|
+
name: request.responseFormat.name ?? "response",
|
|
7215
|
+
schema: request.responseFormat.schema,
|
|
7216
|
+
strict: true
|
|
7217
|
+
}
|
|
7218
|
+
};
|
|
7219
|
+
} else if (request.responseFormat.type === "json_object") {
|
|
7220
|
+
body.text = { format: { type: "json_object" } };
|
|
7221
|
+
}
|
|
7222
|
+
}
|
|
7223
|
+
if (request.extra) Object.assign(body, request.extra);
|
|
7224
|
+
applyOpenAIReasoning(body, request.reasoning, "responses");
|
|
7225
|
+
return body;
|
|
7226
|
+
}
|
|
7227
|
+
/** Maps a unified message to a Responses API `input` item. */
|
|
7228
|
+
toResponsesInput(m) {
|
|
7229
|
+
if (m.role === "tool" && m.toolCallId) {
|
|
7230
|
+
const output = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
|
|
7231
|
+
return { type: "function_call_output", call_id: m.toolCallId, output };
|
|
7232
|
+
}
|
|
7233
|
+
if (m.role === "assistant" && m.toolCalls?.length) {
|
|
7234
|
+
return {
|
|
7235
|
+
__assistantWithCalls: true,
|
|
7236
|
+
text: typeof m.content === "string" ? m.content : "",
|
|
7237
|
+
calls: m.toolCalls.map((tc) => ({
|
|
7238
|
+
type: "function_call",
|
|
7239
|
+
call_id: tc.id,
|
|
7240
|
+
name: tc.name,
|
|
7241
|
+
arguments: tc.arguments
|
|
7242
|
+
}))
|
|
7243
|
+
};
|
|
7244
|
+
}
|
|
7245
|
+
const role = m.role === "system" ? "system" : m.role === "assistant" ? "assistant" : "user";
|
|
7246
|
+
const textType = role === "assistant" ? "output_text" : "input_text";
|
|
7247
|
+
if (typeof m.content === "string") {
|
|
7248
|
+
return { role, content: [{ type: textType, text: m.content }] };
|
|
7249
|
+
}
|
|
7250
|
+
const content = m.content.map((part) => {
|
|
7251
|
+
if (part.type === "text") return { type: textType, text: part.text };
|
|
7252
|
+
if (part.type === "image") {
|
|
7253
|
+
const src = part.source;
|
|
7254
|
+
const url = src.type === "url" ? src.url : `data:${src.mediaType};base64,${src.data}`;
|
|
7255
|
+
return { type: "input_image", image_url: url };
|
|
7256
|
+
}
|
|
7257
|
+
return { type: textType, text: "" };
|
|
7258
|
+
});
|
|
7259
|
+
return { role, content };
|
|
7260
|
+
}
|
|
7261
|
+
async responsesFetch(body) {
|
|
7262
|
+
body.input = expandResponsesInput(body.input);
|
|
7263
|
+
const url = `${this.baseURL}/responses`;
|
|
7264
|
+
const headers = {
|
|
7265
|
+
"Content-Type": "application/json",
|
|
7266
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
7267
|
+
...this.defaultHeaders
|
|
7268
|
+
};
|
|
7269
|
+
const payload = JSON.stringify(body);
|
|
7270
|
+
const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload }));
|
|
7271
|
+
if (!res.ok) {
|
|
7272
|
+
const text = await res.text().catch(() => "");
|
|
7273
|
+
throw new ProviderError(
|
|
7274
|
+
`OpenAI Responses API error ${res.status}: ${text}`,
|
|
7275
|
+
this.providerName,
|
|
7276
|
+
res.status,
|
|
7277
|
+
text
|
|
7278
|
+
);
|
|
7279
|
+
}
|
|
7280
|
+
return res;
|
|
7281
|
+
}
|
|
7282
|
+
parseResponsesResponse(json, modelId) {
|
|
7283
|
+
const textParts = [];
|
|
7284
|
+
const toolCalls = [];
|
|
7285
|
+
const summaryParts = [];
|
|
7286
|
+
for (const item of json.output ?? []) {
|
|
7287
|
+
if (item.type === "message") {
|
|
7288
|
+
for (const c of item.content ?? []) {
|
|
7289
|
+
if (c.type === "output_text" && typeof c.text === "string") textParts.push(c.text);
|
|
7290
|
+
}
|
|
7291
|
+
} else if (item.type === "function_call") {
|
|
7292
|
+
toolCalls.push({
|
|
7293
|
+
id: item.call_id ?? item.id ?? "",
|
|
7294
|
+
name: item.name ?? "",
|
|
7295
|
+
arguments: typeof item.arguments === "string" ? item.arguments : JSON.stringify(item.arguments ?? {})
|
|
7296
|
+
});
|
|
7297
|
+
} else if (item.type === "reasoning") {
|
|
7298
|
+
for (const s of item.summary ?? []) {
|
|
7299
|
+
if (typeof s.text === "string") summaryParts.push(s.text);
|
|
7300
|
+
}
|
|
7301
|
+
}
|
|
7302
|
+
}
|
|
7303
|
+
if (textParts.length === 0 && typeof json.output_text === "string") {
|
|
7304
|
+
textParts.push(json.output_text);
|
|
7305
|
+
}
|
|
7306
|
+
const usage = json.usage ?? {};
|
|
7307
|
+
const reasoningTokens = usage.output_tokens_details?.reasoning_tokens ?? 0;
|
|
7308
|
+
const tokenUsage = {
|
|
7309
|
+
inputTokens: usage.input_tokens ?? 0,
|
|
7310
|
+
outputTokens: usage.output_tokens ?? 0,
|
|
7311
|
+
totalTokens: usage.total_tokens ?? (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0),
|
|
7312
|
+
cachedInputTokens: usage.input_tokens_details?.cached_tokens ?? 0,
|
|
7313
|
+
cachedWriteTokens: 0,
|
|
7314
|
+
cachedOutputTokens: 0,
|
|
7315
|
+
reasoningTokens
|
|
7316
|
+
};
|
|
7317
|
+
const finishReason = toolCalls.length > 0 ? "tool_calls" : json.status === "incomplete" ? "length" : "stop";
|
|
7318
|
+
return {
|
|
7319
|
+
id: json.id ?? "",
|
|
7320
|
+
model: json.model ?? modelId,
|
|
7321
|
+
content: textParts.join("") || null,
|
|
7322
|
+
toolCalls,
|
|
7323
|
+
usage: tokenUsage,
|
|
7324
|
+
finishReason,
|
|
7325
|
+
reasoning: summaryParts.length > 0 ? { summary: summaryParts.join("\n").trim() || void 0 } : void 0,
|
|
7326
|
+
raw: json
|
|
7327
|
+
};
|
|
7328
|
+
}
|
|
6827
7329
|
toOpenAIMessage(m) {
|
|
6828
7330
|
const msg = { role: m.role };
|
|
6829
7331
|
if (typeof m.content === "string") {
|
|
@@ -6916,6 +7418,25 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
6916
7418
|
};
|
|
6917
7419
|
}
|
|
6918
7420
|
};
|
|
7421
|
+
function isReasoningModel(model) {
|
|
7422
|
+
if (!model) return false;
|
|
7423
|
+
const m = model.toLowerCase();
|
|
7424
|
+
return /(^|[/_-])o[0-9]/.test(m) || m.startsWith("o1") || m.startsWith("o3") || m.startsWith("o4") || m.includes("gpt-5") || m.includes("gpt5");
|
|
7425
|
+
}
|
|
7426
|
+
function expandResponsesInput(input) {
|
|
7427
|
+
const out = [];
|
|
7428
|
+
for (const item of input) {
|
|
7429
|
+
if (item && item.__assistantWithCalls) {
|
|
7430
|
+
if (item.text) {
|
|
7431
|
+
out.push({ role: "assistant", content: [{ type: "output_text", text: item.text }] });
|
|
7432
|
+
}
|
|
7433
|
+
for (const call of item.calls) out.push(call);
|
|
7434
|
+
} else {
|
|
7435
|
+
out.push(item);
|
|
7436
|
+
}
|
|
7437
|
+
}
|
|
7438
|
+
return out;
|
|
7439
|
+
}
|
|
6919
7440
|
function mapFinishReason(reason) {
|
|
6920
7441
|
switch (reason) {
|
|
6921
7442
|
case "stop":
|
|
@@ -6961,6 +7482,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
6961
7482
|
let cacheReadInputTokens = 0;
|
|
6962
7483
|
let cacheCreationInputTokens = 0;
|
|
6963
7484
|
const currentToolCalls = /* @__PURE__ */ new Map();
|
|
7485
|
+
const reasoningBlocks = /* @__PURE__ */ new Map();
|
|
6964
7486
|
for await (const event of parseSSEStream(res.body)) {
|
|
6965
7487
|
let data;
|
|
6966
7488
|
try {
|
|
@@ -6990,6 +7512,10 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
6990
7512
|
name: block.name ?? "",
|
|
6991
7513
|
arguments: ""
|
|
6992
7514
|
});
|
|
7515
|
+
} else if (block?.type === "thinking") {
|
|
7516
|
+
reasoningBlocks.set(idx, { type: "thinking", text: block.thinking ?? "", signature: block.signature });
|
|
7517
|
+
} else if (block?.type === "redacted_thinking") {
|
|
7518
|
+
reasoningBlocks.set(idx, { type: "redacted_thinking", data: block.data });
|
|
6993
7519
|
}
|
|
6994
7520
|
break;
|
|
6995
7521
|
}
|
|
@@ -7002,6 +7528,19 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7002
7528
|
model,
|
|
7003
7529
|
delta: { content: delta.text }
|
|
7004
7530
|
};
|
|
7531
|
+
} else if (delta?.type === "thinking_delta" && delta.thinking) {
|
|
7532
|
+
const blk = reasoningBlocks.get(idx) ?? { type: "thinking", text: "" };
|
|
7533
|
+
blk.text = (blk.text ?? "") + delta.thinking;
|
|
7534
|
+
reasoningBlocks.set(idx, blk);
|
|
7535
|
+
yield {
|
|
7536
|
+
id,
|
|
7537
|
+
model,
|
|
7538
|
+
delta: { reasoning: { summary: delta.thinking } }
|
|
7539
|
+
};
|
|
7540
|
+
} else if (delta?.type === "signature_delta" && delta.signature) {
|
|
7541
|
+
const blk = reasoningBlocks.get(idx) ?? { type: "thinking", text: "" };
|
|
7542
|
+
blk.signature = (blk.signature ?? "") + delta.signature;
|
|
7543
|
+
reasoningBlocks.set(idx, blk);
|
|
7005
7544
|
} else if (delta?.type === "input_json_delta" && delta.partial_json) {
|
|
7006
7545
|
const tc = currentToolCalls.get(idx);
|
|
7007
7546
|
if (tc) {
|
|
@@ -7034,10 +7573,13 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7034
7573
|
cachedOutputTokens: 0,
|
|
7035
7574
|
reasoningTokens: 0
|
|
7036
7575
|
};
|
|
7576
|
+
const blocks = [...reasoningBlocks.values()].filter(
|
|
7577
|
+
(b) => b.type === "thinking" && b.signature || b.type === "redacted_thinking" && b.data
|
|
7578
|
+
);
|
|
7037
7579
|
yield {
|
|
7038
7580
|
id,
|
|
7039
7581
|
model,
|
|
7040
|
-
delta: {},
|
|
7582
|
+
delta: blocks.length > 0 ? { reasoning: { blocks } } : {},
|
|
7041
7583
|
finishReason,
|
|
7042
7584
|
usage
|
|
7043
7585
|
};
|
|
@@ -7129,6 +7671,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7129
7671
|
}
|
|
7130
7672
|
if (m.role === "assistant" && m.toolCalls?.length) {
|
|
7131
7673
|
const content = [];
|
|
7674
|
+
appendReasoningBlocks(content, m.reasoning?.blocks);
|
|
7132
7675
|
if (typeof m.content === "string" && m.content) {
|
|
7133
7676
|
content.push({ type: "text", text: m.content });
|
|
7134
7677
|
}
|
|
@@ -7142,6 +7685,13 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7142
7685
|
}
|
|
7143
7686
|
return { role: "assistant", content };
|
|
7144
7687
|
}
|
|
7688
|
+
if (m.role === "assistant" && m.reasoning?.blocks?.length) {
|
|
7689
|
+
const content = [];
|
|
7690
|
+
appendReasoningBlocks(content, m.reasoning.blocks);
|
|
7691
|
+
const text = typeof m.content === "string" ? m.content : "";
|
|
7692
|
+
if (text) content.push({ type: "text", text });
|
|
7693
|
+
return { role: "assistant", content };
|
|
7694
|
+
}
|
|
7145
7695
|
const msg = { role: m.role };
|
|
7146
7696
|
if (typeof m.content === "string") {
|
|
7147
7697
|
msg.content = m.content;
|
|
@@ -7197,9 +7747,20 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7197
7747
|
parseResponse(json) {
|
|
7198
7748
|
const textParts = [];
|
|
7199
7749
|
const toolCalls = [];
|
|
7750
|
+
const reasoningBlocks = [];
|
|
7751
|
+
const summaryParts = [];
|
|
7200
7752
|
for (const block of json.content ?? []) {
|
|
7201
7753
|
if (block.type === "text") {
|
|
7202
7754
|
textParts.push(block.text);
|
|
7755
|
+
} else if (block.type === "thinking") {
|
|
7756
|
+
reasoningBlocks.push({
|
|
7757
|
+
type: "thinking",
|
|
7758
|
+
text: block.thinking ?? "",
|
|
7759
|
+
signature: block.signature
|
|
7760
|
+
});
|
|
7761
|
+
if (block.thinking) summaryParts.push(block.thinking);
|
|
7762
|
+
} else if (block.type === "redacted_thinking") {
|
|
7763
|
+
reasoningBlocks.push({ type: "redacted_thinking", data: block.data });
|
|
7203
7764
|
} else if (block.type === "tool_use") {
|
|
7204
7765
|
toolCalls.push({
|
|
7205
7766
|
id: block.id,
|
|
@@ -7216,6 +7777,9 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7216
7777
|
cachedInputTokens: usage.cache_read_input_tokens ?? 0,
|
|
7217
7778
|
cachedWriteTokens: usage.cache_creation_input_tokens ?? 0,
|
|
7218
7779
|
cachedOutputTokens: 0,
|
|
7780
|
+
// Anthropic bills thinking tokens inside `output_tokens` and does not
|
|
7781
|
+
// expose a separate count, so reasoningTokens stays 0 here (cost is still
|
|
7782
|
+
// captured via outputTokens). See docs for the limitation.
|
|
7219
7783
|
reasoningTokens: 0
|
|
7220
7784
|
};
|
|
7221
7785
|
return {
|
|
@@ -7225,6 +7789,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
7225
7789
|
toolCalls,
|
|
7226
7790
|
usage: tokenUsage,
|
|
7227
7791
|
finishReason: mapAnthropicStopReason(json.stop_reason),
|
|
7792
|
+
reasoning: reasoningBlocks.length > 0 ? { blocks: reasoningBlocks, summary: summaryParts.join("\n").trim() || void 0 } : void 0,
|
|
7228
7793
|
raw: json
|
|
7229
7794
|
};
|
|
7230
7795
|
}
|
|
@@ -7249,6 +7814,18 @@ function safeJsonParse(str) {
|
|
|
7249
7814
|
return {};
|
|
7250
7815
|
}
|
|
7251
7816
|
}
|
|
7817
|
+
function appendReasoningBlocks(content, blocks) {
|
|
7818
|
+
if (!blocks?.length) return;
|
|
7819
|
+
for (const b of blocks) {
|
|
7820
|
+
if (b.type === "redacted_thinking") {
|
|
7821
|
+
if (b.data) content.push({ type: "redacted_thinking", data: b.data });
|
|
7822
|
+
} else if (b.type === "thinking") {
|
|
7823
|
+
if (b.signature) {
|
|
7824
|
+
content.push({ type: "thinking", thinking: b.text ?? "", signature: b.signature });
|
|
7825
|
+
}
|
|
7826
|
+
}
|
|
7827
|
+
}
|
|
7828
|
+
}
|
|
7252
7829
|
|
|
7253
7830
|
// src/providers/azure.ts
|
|
7254
7831
|
var AzureProvider = class extends OpenAIProvider {
|
|
@@ -7292,7 +7869,52 @@ var AzureProvider = class extends OpenAIProvider {
|
|
|
7292
7869
|
}
|
|
7293
7870
|
return res;
|
|
7294
7871
|
}
|
|
7872
|
+
/** Azure exposes the Responses API at /openai/responses with api-key auth.
|
|
7873
|
+
* Reasoning summaries require a preview api-version; callers can override via
|
|
7874
|
+
* the `apiVersion` config. */
|
|
7875
|
+
async responsesFetch(body) {
|
|
7876
|
+
body.input = expandAzureResponsesInput(body.input);
|
|
7877
|
+
const deployment = this.deploymentName ?? body.model;
|
|
7878
|
+
if (!deployment) {
|
|
7879
|
+
throw new ProviderError("Azure requires a deploymentName or model", this.providerName);
|
|
7880
|
+
}
|
|
7881
|
+
const url = `${this.endpoint}/openai/responses?api-version=${this.apiVersion}`;
|
|
7882
|
+
const payload = JSON.stringify({ ...body, model: deployment });
|
|
7883
|
+
const res = await fetch(url, {
|
|
7884
|
+
method: "POST",
|
|
7885
|
+
headers: {
|
|
7886
|
+
"Content-Type": "application/json",
|
|
7887
|
+
"api-key": this.azureApiKey,
|
|
7888
|
+
...this.defaultHeaders
|
|
7889
|
+
},
|
|
7890
|
+
body: payload
|
|
7891
|
+
});
|
|
7892
|
+
if (!res.ok) {
|
|
7893
|
+
const text = await res.text().catch(() => "");
|
|
7894
|
+
throw new ProviderError(
|
|
7895
|
+
`Azure OpenAI Responses API error ${res.status}: ${text}`,
|
|
7896
|
+
this.providerName,
|
|
7897
|
+
res.status,
|
|
7898
|
+
text
|
|
7899
|
+
);
|
|
7900
|
+
}
|
|
7901
|
+
return res;
|
|
7902
|
+
}
|
|
7295
7903
|
};
|
|
7904
|
+
function expandAzureResponsesInput(input) {
|
|
7905
|
+
const out = [];
|
|
7906
|
+
for (const item of input) {
|
|
7907
|
+
if (item && item.__assistantWithCalls) {
|
|
7908
|
+
if (item.text) {
|
|
7909
|
+
out.push({ role: "assistant", content: [{ type: "output_text", text: item.text }] });
|
|
7910
|
+
}
|
|
7911
|
+
for (const call of item.calls) out.push(call);
|
|
7912
|
+
} else {
|
|
7913
|
+
out.push(item);
|
|
7914
|
+
}
|
|
7915
|
+
}
|
|
7916
|
+
return out;
|
|
7917
|
+
}
|
|
7296
7918
|
|
|
7297
7919
|
// src/providers/openaiCompatible.ts
|
|
7298
7920
|
var OpenAICompatibleProvider = class extends OpenAIProvider {
|
|
@@ -7465,6 +8087,7 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7465
8087
|
if (request.extra) {
|
|
7466
8088
|
Object.assign(body, request.extra);
|
|
7467
8089
|
}
|
|
8090
|
+
applyBedrockReasoning(body, request.reasoning);
|
|
7468
8091
|
return body;
|
|
7469
8092
|
}
|
|
7470
8093
|
splitSystemMessages(messages) {
|
|
@@ -7498,6 +8121,7 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7498
8121
|
}
|
|
7499
8122
|
if (m.role === "assistant" && m.toolCalls?.length) {
|
|
7500
8123
|
const content2 = [];
|
|
8124
|
+
appendBedrockReasoning(content2, m.reasoning?.blocks);
|
|
7501
8125
|
if (typeof m.content === "string" && m.content) {
|
|
7502
8126
|
content2.push({ text: m.content });
|
|
7503
8127
|
}
|
|
@@ -7578,9 +8202,23 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7578
8202
|
const output = json.output?.message;
|
|
7579
8203
|
const textParts = [];
|
|
7580
8204
|
const toolCalls = [];
|
|
8205
|
+
const reasoningBlocks = [];
|
|
8206
|
+
const summaryParts = [];
|
|
7581
8207
|
for (const block of output?.content ?? []) {
|
|
7582
8208
|
if (block.text) {
|
|
7583
8209
|
textParts.push(block.text);
|
|
8210
|
+
} else if (block.reasoningContent) {
|
|
8211
|
+
const rc = block.reasoningContent;
|
|
8212
|
+
if (rc.reasoningText) {
|
|
8213
|
+
reasoningBlocks.push({
|
|
8214
|
+
type: "thinking",
|
|
8215
|
+
text: rc.reasoningText.text ?? "",
|
|
8216
|
+
signature: rc.reasoningText.signature
|
|
8217
|
+
});
|
|
8218
|
+
if (rc.reasoningText.text) summaryParts.push(rc.reasoningText.text);
|
|
8219
|
+
} else if (rc.redactedContent) {
|
|
8220
|
+
reasoningBlocks.push({ type: "redacted_thinking", data: rc.redactedContent });
|
|
8221
|
+
}
|
|
7584
8222
|
} else if (block.toolUse) {
|
|
7585
8223
|
toolCalls.push({
|
|
7586
8224
|
id: block.toolUse.toolUseId,
|
|
@@ -7597,6 +8235,7 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7597
8235
|
cachedInputTokens: usage.cacheReadInputTokenCount ?? 0,
|
|
7598
8236
|
cachedWriteTokens: usage.cacheWriteInputTokenCount ?? 0,
|
|
7599
8237
|
cachedOutputTokens: 0,
|
|
8238
|
+
// Bedrock bills thinking tokens inside outputTokens; no separate count.
|
|
7600
8239
|
reasoningTokens: 0
|
|
7601
8240
|
};
|
|
7602
8241
|
return {
|
|
@@ -7606,10 +8245,25 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
7606
8245
|
toolCalls,
|
|
7607
8246
|
usage: tokenUsage,
|
|
7608
8247
|
finishReason: mapBedrockStopReason(json.stopReason),
|
|
8248
|
+
reasoning: reasoningBlocks.length > 0 ? { blocks: reasoningBlocks, summary: summaryParts.join("\n").trim() || void 0 } : void 0,
|
|
7609
8249
|
raw: json
|
|
7610
8250
|
};
|
|
7611
8251
|
}
|
|
7612
8252
|
};
|
|
8253
|
+
function appendBedrockReasoning(content, blocks) {
|
|
8254
|
+
if (!blocks?.length) return;
|
|
8255
|
+
for (const b of blocks) {
|
|
8256
|
+
if (b.type === "redacted_thinking") {
|
|
8257
|
+
if (b.data) content.push({ reasoningContent: { redactedContent: b.data } });
|
|
8258
|
+
} else if (b.type === "thinking") {
|
|
8259
|
+
if (b.signature) {
|
|
8260
|
+
content.push({
|
|
8261
|
+
reasoningContent: { reasoningText: { text: b.text ?? "", signature: b.signature } }
|
|
8262
|
+
});
|
|
8263
|
+
}
|
|
8264
|
+
}
|
|
8265
|
+
}
|
|
8266
|
+
}
|
|
7613
8267
|
function mapBedrockStopReason(reason) {
|
|
7614
8268
|
switch (reason) {
|
|
7615
8269
|
case "end_turn":
|
|
@@ -7932,10 +8586,15 @@ var VertexProvider = class extends BaseProvider {
|
|
|
7932
8586
|
const parts = candidate?.content?.parts ?? [];
|
|
7933
8587
|
const textParts = [];
|
|
7934
8588
|
const toolCalls = [];
|
|
8589
|
+
const thoughtParts = [];
|
|
7935
8590
|
let toolCallIdx = 0;
|
|
7936
8591
|
for (const part of parts) {
|
|
7937
8592
|
if (part.text) {
|
|
7938
|
-
|
|
8593
|
+
if (part.thought === true) {
|
|
8594
|
+
thoughtParts.push(part.text);
|
|
8595
|
+
} else {
|
|
8596
|
+
textParts.push(part.text);
|
|
8597
|
+
}
|
|
7939
8598
|
} else if (part.functionCall) {
|
|
7940
8599
|
toolCalls.push({
|
|
7941
8600
|
id: `call_${toolCallIdx++}`,
|
|
@@ -7961,6 +8620,7 @@ var VertexProvider = class extends BaseProvider {
|
|
|
7961
8620
|
toolCalls,
|
|
7962
8621
|
usage: tokenUsage,
|
|
7963
8622
|
finishReason: mapGeminiFinishReason(candidate?.finishReason),
|
|
8623
|
+
reasoning: thoughtParts.length > 0 ? { summary: thoughtParts.join("\n").trim() || void 0 } : void 0,
|
|
7964
8624
|
raw: json
|
|
7965
8625
|
};
|
|
7966
8626
|
}
|
|
@@ -7970,7 +8630,11 @@ var VertexProvider = class extends BaseProvider {
|
|
|
7970
8630
|
const delta = {};
|
|
7971
8631
|
for (const part of parts) {
|
|
7972
8632
|
if (part.text) {
|
|
7973
|
-
|
|
8633
|
+
if (part.thought === true) {
|
|
8634
|
+
delta.reasoning = { summary: (delta.reasoning?.summary ?? "") + part.text };
|
|
8635
|
+
} else {
|
|
8636
|
+
delta.content = (delta.content ?? "") + part.text;
|
|
8637
|
+
}
|
|
7974
8638
|
} else if (part.functionCall) {
|
|
7975
8639
|
if (!delta.toolCalls) delta.toolCalls = [];
|
|
7976
8640
|
delta.toolCalls.push({
|
|
@@ -8044,12 +8708,16 @@ function fromNativeProvider(provider, options) {
|
|
|
8044
8708
|
let fullContent = "";
|
|
8045
8709
|
let allToolCalls = [];
|
|
8046
8710
|
let lastUsage;
|
|
8711
|
+
let reasoningBlocks;
|
|
8047
8712
|
const toolCallBuffers = /* @__PURE__ */ new Map();
|
|
8048
8713
|
for await (const chunk of provider.completeStream(request)) {
|
|
8049
8714
|
if (chunk.delta.content) {
|
|
8050
8715
|
fullContent += chunk.delta.content;
|
|
8051
8716
|
yield chunk.delta.content;
|
|
8052
8717
|
}
|
|
8718
|
+
if (chunk.delta.reasoning?.blocks?.length) {
|
|
8719
|
+
reasoningBlocks = chunk.delta.reasoning.blocks;
|
|
8720
|
+
}
|
|
8053
8721
|
if (chunk.delta.toolCalls) {
|
|
8054
8722
|
for (const tc of chunk.delta.toolCalls) {
|
|
8055
8723
|
if (tc.id) {
|
|
@@ -8070,6 +8738,9 @@ function fromNativeProvider(provider, options) {
|
|
|
8070
8738
|
}
|
|
8071
8739
|
allToolCalls = [...toolCallBuffers.values()];
|
|
8072
8740
|
const finalMessage = assembleMessage(fullContent, allToolCalls, lastUsage);
|
|
8741
|
+
if (reasoningBlocks?.length) {
|
|
8742
|
+
finalMessage.reasoning = { blocks: reasoningBlocks };
|
|
8743
|
+
}
|
|
8073
8744
|
yield finalMessage;
|
|
8074
8745
|
},
|
|
8075
8746
|
bindTools: (tools, _bindOptions) => {
|
|
@@ -8132,6 +8803,10 @@ function toUnifiedMessage(msg) {
|
|
|
8132
8803
|
arguments: tc.function?.arguments ?? tc.arguments ?? "{}"
|
|
8133
8804
|
}));
|
|
8134
8805
|
}
|
|
8806
|
+
const reasoning = msg.reasoning;
|
|
8807
|
+
if (reasoning && (reasoning.blocks?.length || reasoning.summary)) {
|
|
8808
|
+
unified.reasoning = reasoning;
|
|
8809
|
+
}
|
|
8135
8810
|
return unified;
|
|
8136
8811
|
}
|
|
8137
8812
|
function convertContent(content) {
|
|
@@ -8340,6 +9015,9 @@ function toBaseChatMessage(response) {
|
|
|
8340
9015
|
function: { name: tc.name, arguments: tc.arguments }
|
|
8341
9016
|
}));
|
|
8342
9017
|
}
|
|
9018
|
+
if (response.reasoning && (response.reasoning.blocks?.length || response.reasoning.summary)) {
|
|
9019
|
+
msg.reasoning = response.reasoning;
|
|
9020
|
+
}
|
|
8343
9021
|
return msg;
|
|
8344
9022
|
}
|
|
8345
9023
|
function assembleMessage(content, toolCalls, usage) {
|
|
@@ -8436,6 +9114,6 @@ function createProvider(config) {
|
|
|
8436
9114
|
}
|
|
8437
9115
|
}
|
|
8438
9116
|
|
|
8439
|
-
export { AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, DEFAULT_PROFILE_CONFIGS, GuardrailPhase, InMemoryMemoryStore, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, ProviderError, StructuredOutputManager, ToolBasedStrategy, VertexProvider, agentVerdictRule, buildSystemPrompt, captureSnapshot, codePresenceRule, cognipeerSink, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createCodeGuardrail, createContextSummarizeNode, createContextTools, createGetToolResponseTool, createGuardrail, createJsonGuardrail, createManageTodoTool, createProvider, createRegexGuardrail, createResolverNode, createSmartAgent, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customSink, defaultTokenCounter, emptyUsage, evaluateGuardrails, fileSink, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasToolResponseRecoveryReference, httpSink, isSmartModel, jsonSchemaRule, normalizeSmartAgentOptions, otlpSink, readMemoryFacts, regexRule, resolveMemoryStore, resolveStrategy, resolveToolApprovalState, resolveUserQuestionState, restoreSnapshot, runSmartAgentEvalHarness, setTokenCounter, startStreamingSession, traceSessionToOtlp, withTools, writeSummaryFactsToMemory };
|
|
9117
|
+
export { AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, DEFAULT_PROFILE_CONFIGS, GuardrailPhase, InMemoryMemoryStore, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, ProviderError, StructuredOutputManager, ToolBasedStrategy, VertexProvider, agentVerdictRule, buildSystemPrompt, captureSnapshot, codePresenceRule, cognipeerSink, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createCodeGuardrail, createContextSummarizeNode, createContextTools, createGetToolResponseTool, createGuardrail, createJsonGuardrail, createManageTodoTool, createProvider, createRegexGuardrail, createResolverNode, createSmartAgent, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customSink, defaultTokenCounter, emptyUsage, evaluateGuardrails, fileSink, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasToolResponseRecoveryReference, httpSink, isSmartModel, jsonSchemaRule, normalizeSmartAgentOptions, otlpSink, readMemoryFacts, regexRule, resolveMemoryStore, resolveReasoning, resolveStrategy, resolveToolApprovalState, resolveUserQuestionState, restoreSnapshot, runSmartAgentEvalHarness, setTokenCounter, startStreamingSession, traceSessionToOtlp, validateReasoningConfig, withTools, writeSummaryFactsToMemory };
|
|
8440
9118
|
//# sourceMappingURL=index.mjs.map
|
|
8441
9119
|
//# sourceMappingURL=index.mjs.map
|