@cognipeer/agent-sdk 0.6.5 → 0.7.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 +7 -2
- package/dist/index.cjs +630 -175
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +149 -2
- package/dist/index.d.ts +149 -2
- package/dist/index.mjs +629 -176
- 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;
|
|
@@ -743,6 +743,7 @@ function createResolverNode() {
|
|
|
743
743
|
toolHistory: state.toolHistory || [],
|
|
744
744
|
toolHistoryArchived: state.toolHistoryArchived || [],
|
|
745
745
|
pendingApprovals: state.pendingApprovals || [],
|
|
746
|
+
pendingUserQuestions: state.pendingUserQuestions || [],
|
|
746
747
|
plan: state.plan || null,
|
|
747
748
|
planVersion: state.planVersion || 0
|
|
748
749
|
};
|
|
@@ -1261,6 +1262,7 @@ function eventToOtlpSpan(event) {
|
|
|
1261
1262
|
stringAttr("cognipeer.actor.role", event.actor?.role),
|
|
1262
1263
|
stringAttr("cognipeer.model", event.model),
|
|
1263
1264
|
stringAttr("cognipeer.provider", event.provider),
|
|
1265
|
+
stringAttr("cognipeer.tool.details", event.toolDetails ? JSON.stringify(event.toolDetails) : void 0),
|
|
1264
1266
|
intAttr("cognipeer.tokens.input", event.inputTokens),
|
|
1265
1267
|
intAttr("cognipeer.tokens.output", event.outputTokens),
|
|
1266
1268
|
intAttr("cognipeer.tokens.total", event.totalTokens),
|
|
@@ -1732,6 +1734,7 @@ function recordTraceEvent(session, event) {
|
|
|
1732
1734
|
responseBytes,
|
|
1733
1735
|
model: resolvedModel,
|
|
1734
1736
|
provider: resolvedProvider,
|
|
1737
|
+
toolDetails: session.resolvedConfig.logData ? sanitizeTracePayload(event.toolDetails) : void 0,
|
|
1735
1738
|
toolExecutionId: event.toolExecutionId,
|
|
1736
1739
|
retryOf: event.retryOf,
|
|
1737
1740
|
error: event.error ?? (status === "error" ? { message: "Unknown error" } : void 0) ?? void 0,
|
|
@@ -2182,16 +2185,99 @@ function createAgentCoreNode(opts) {
|
|
|
2182
2185
|
};
|
|
2183
2186
|
}
|
|
2184
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
|
+
|
|
2185
2271
|
// src/smart/runtimeConfig.ts
|
|
2186
2272
|
var DEFAULT_CRITICAL_TOOLS = ["response", "manage_todo_list", "get_tool_response"];
|
|
2187
2273
|
var BASE_DEFAULTS = {
|
|
2188
|
-
limits: { maxToolCalls:
|
|
2274
|
+
limits: { maxToolCalls: 20, maxParallelTools: 5, maxContextTokens: 96e3, maxTotalOutputTokens: 0, maxCostUsd: 0, maxWallClockMs: 0 },
|
|
2189
2275
|
summarization: {
|
|
2190
2276
|
enable: true,
|
|
2191
|
-
maxTokens:
|
|
2192
|
-
summaryTriggerTokens:
|
|
2193
|
-
summaryPromptMaxTokens:
|
|
2194
|
-
summaryCompressionRatioTarget: 0.
|
|
2277
|
+
maxTokens: 96e3,
|
|
2278
|
+
summaryTriggerTokens: 72e3,
|
|
2279
|
+
summaryPromptMaxTokens: 12e3,
|
|
2280
|
+
summaryCompressionRatioTarget: 0.45,
|
|
2195
2281
|
summaryMode: "incremental",
|
|
2196
2282
|
promptTemplate: "",
|
|
2197
2283
|
toolFreeCall: true,
|
|
@@ -2199,13 +2285,13 @@ var BASE_DEFAULTS = {
|
|
|
2199
2285
|
},
|
|
2200
2286
|
context: {
|
|
2201
2287
|
policy: "hybrid",
|
|
2202
|
-
lastTurnsToKeep:
|
|
2288
|
+
lastTurnsToKeep: 16,
|
|
2203
2289
|
toolResponsePolicy: "summarize_archive",
|
|
2204
2290
|
budget: {
|
|
2205
|
-
systemReserveTokens:
|
|
2206
|
-
goalsReserveTokens:
|
|
2207
|
-
recentTurnsReserveTokens:
|
|
2208
|
-
toolResponseReserveTokens:
|
|
2291
|
+
systemReserveTokens: 2e3,
|
|
2292
|
+
goalsReserveTokens: 2e3,
|
|
2293
|
+
recentTurnsReserveTokens: 18e3,
|
|
2294
|
+
toolResponseReserveTokens: 9e3
|
|
2209
2295
|
}
|
|
2210
2296
|
},
|
|
2211
2297
|
planning: {
|
|
@@ -2222,14 +2308,14 @@ var BASE_DEFAULTS = {
|
|
|
2222
2308
|
delegation: {
|
|
2223
2309
|
mode: "role_based",
|
|
2224
2310
|
maxDelegationDepth: 2,
|
|
2225
|
-
maxChildCalls:
|
|
2226
|
-
maxParallelChild:
|
|
2311
|
+
maxChildCalls: 6,
|
|
2312
|
+
maxParallelChild: 3,
|
|
2227
2313
|
childContextPolicy: "scoped",
|
|
2228
2314
|
requireJsonOutputContract: true
|
|
2229
2315
|
},
|
|
2230
2316
|
toolResponses: {
|
|
2231
|
-
maxToolResponseChars:
|
|
2232
|
-
maxToolResponseTokens:
|
|
2317
|
+
maxToolResponseChars: 32e3,
|
|
2318
|
+
maxToolResponseTokens: 8e3,
|
|
2233
2319
|
defaultPolicy: "summarize_archive",
|
|
2234
2320
|
toolResponseRetentionByTool: {},
|
|
2235
2321
|
criticalTools: [...DEFAULT_CRITICAL_TOOLS],
|
|
@@ -2258,54 +2344,54 @@ function buildProfile(overrides) {
|
|
|
2258
2344
|
}
|
|
2259
2345
|
var DEFAULT_PROFILE_CONFIGS = {
|
|
2260
2346
|
fast: buildProfile({
|
|
2261
|
-
limits: { maxToolCalls:
|
|
2347
|
+
limits: { maxToolCalls: 8, maxParallelTools: 3, maxContextTokens: 32e3 },
|
|
2262
2348
|
summarization: {
|
|
2263
|
-
maxTokens:
|
|
2264
|
-
summaryTriggerTokens:
|
|
2265
|
-
summaryPromptMaxTokens:
|
|
2266
|
-
summaryCompressionRatioTarget: 0.
|
|
2349
|
+
maxTokens: 32e3,
|
|
2350
|
+
summaryTriggerTokens: 24e3,
|
|
2351
|
+
summaryPromptMaxTokens: 6e3,
|
|
2352
|
+
summaryCompressionRatioTarget: 0.5
|
|
2267
2353
|
},
|
|
2268
2354
|
context: {
|
|
2269
|
-
lastTurnsToKeep:
|
|
2355
|
+
lastTurnsToKeep: 8,
|
|
2270
2356
|
toolResponsePolicy: "keep_structured",
|
|
2271
|
-
budget: { systemReserveTokens:
|
|
2357
|
+
budget: { systemReserveTokens: 1500, goalsReserveTokens: 1200, recentTurnsReserveTokens: 6e3, toolResponseReserveTokens: 3500 }
|
|
2272
2358
|
},
|
|
2273
2359
|
memory: { readPolicy: "recent_only" },
|
|
2274
2360
|
delegation: { mode: "off", maxDelegationDepth: 1, maxChildCalls: 2, maxParallelChild: 1, childContextPolicy: "minimal" },
|
|
2275
|
-
toolResponses: { maxToolResponseChars:
|
|
2361
|
+
toolResponses: { maxToolResponseChars: 16e3, maxToolResponseTokens: 4e3 }
|
|
2276
2362
|
}),
|
|
2277
2363
|
balanced: buildProfile({}),
|
|
2278
2364
|
deep: buildProfile({
|
|
2279
|
-
limits: { maxToolCalls:
|
|
2365
|
+
limits: { maxToolCalls: 40, maxParallelTools: 8, maxContextTokens: 2e5 },
|
|
2280
2366
|
summarization: {
|
|
2281
|
-
maxTokens:
|
|
2282
|
-
summaryTriggerTokens:
|
|
2283
|
-
summaryPromptMaxTokens:
|
|
2284
|
-
summaryCompressionRatioTarget: 0.
|
|
2367
|
+
maxTokens: 2e5,
|
|
2368
|
+
summaryTriggerTokens: 15e4,
|
|
2369
|
+
summaryPromptMaxTokens: 16e3,
|
|
2370
|
+
summaryCompressionRatioTarget: 0.4
|
|
2285
2371
|
},
|
|
2286
2372
|
context: {
|
|
2287
|
-
lastTurnsToKeep:
|
|
2288
|
-
budget: { systemReserveTokens:
|
|
2373
|
+
lastTurnsToKeep: 30,
|
|
2374
|
+
budget: { systemReserveTokens: 2500, goalsReserveTokens: 2500, recentTurnsReserveTokens: 36e3, toolResponseReserveTokens: 18e3 }
|
|
2289
2375
|
},
|
|
2290
2376
|
memory: { scope: "workspace" },
|
|
2291
|
-
delegation: { maxDelegationDepth: 3, maxChildCalls:
|
|
2292
|
-
toolResponses: { maxToolResponseChars:
|
|
2377
|
+
delegation: { maxDelegationDepth: 3, maxChildCalls: 10, maxParallelChild: 4 },
|
|
2378
|
+
toolResponses: { maxToolResponseChars: 64e3, maxToolResponseTokens: 16e3 }
|
|
2293
2379
|
}),
|
|
2294
2380
|
research: buildProfile({
|
|
2295
|
-
limits: { maxToolCalls:
|
|
2381
|
+
limits: { maxToolCalls: 80, maxParallelTools: 10, maxContextTokens: 4e5 },
|
|
2296
2382
|
summarization: {
|
|
2297
|
-
maxTokens:
|
|
2298
|
-
summaryTriggerTokens:
|
|
2299
|
-
summaryPromptMaxTokens:
|
|
2300
|
-
summaryCompressionRatioTarget: 0.
|
|
2383
|
+
maxTokens: 4e5,
|
|
2384
|
+
summaryTriggerTokens: 3e5,
|
|
2385
|
+
summaryPromptMaxTokens: 24e3,
|
|
2386
|
+
summaryCompressionRatioTarget: 0.35
|
|
2301
2387
|
},
|
|
2302
2388
|
context: {
|
|
2303
|
-
lastTurnsToKeep:
|
|
2304
|
-
budget: { systemReserveTokens:
|
|
2389
|
+
lastTurnsToKeep: 60,
|
|
2390
|
+
budget: { systemReserveTokens: 3e3, goalsReserveTokens: 3e3, recentTurnsReserveTokens: 72e3, toolResponseReserveTokens: 32e3 }
|
|
2305
2391
|
},
|
|
2306
2392
|
memory: { scope: "workspace" },
|
|
2307
|
-
delegation: { mode: "automatic", maxDelegationDepth: 4, maxChildCalls:
|
|
2308
|
-
toolResponses: { maxToolResponseChars:
|
|
2393
|
+
delegation: { mode: "automatic", maxDelegationDepth: 4, maxChildCalls: 16, maxParallelChild: 6, childContextPolicy: "full" },
|
|
2394
|
+
toolResponses: { maxToolResponseChars: 96e3, maxToolResponseTokens: 24e3 }
|
|
2309
2395
|
})
|
|
2310
2396
|
};
|
|
2311
2397
|
function mergeLimits(base, override) {
|
|
@@ -2395,53 +2481,6 @@ function getResolvedSmartConfig(opts, runtime) {
|
|
|
2395
2481
|
|
|
2396
2482
|
// src/smart/toolResponses.ts
|
|
2397
2483
|
init_utilTokens();
|
|
2398
|
-
|
|
2399
|
-
// src/utils/content.ts
|
|
2400
|
-
function contentToString(content) {
|
|
2401
|
-
try {
|
|
2402
|
-
if (content == null) return "";
|
|
2403
|
-
if (typeof content === "string") return content;
|
|
2404
|
-
if (Array.isArray(content)) {
|
|
2405
|
-
return content.map((p) => {
|
|
2406
|
-
if (!p || typeof p !== "object") return String(p);
|
|
2407
|
-
if (p.type === "text") return String(p.text ?? "");
|
|
2408
|
-
if (p.type === "image_url") {
|
|
2409
|
-
const img = p.image_url;
|
|
2410
|
-
const url = typeof img === "string" ? img : img?.url;
|
|
2411
|
-
const detail = typeof img === "string" ? void 0 : img?.detail;
|
|
2412
|
-
return `[image:${url || "unknown"}${detail ? ` detail=${detail}` : ""}]`;
|
|
2413
|
-
}
|
|
2414
|
-
return JSON.stringify(p);
|
|
2415
|
-
}).join("\n");
|
|
2416
|
-
}
|
|
2417
|
-
return JSON.stringify(content);
|
|
2418
|
-
} catch {
|
|
2419
|
-
return String(content);
|
|
2420
|
-
}
|
|
2421
|
-
}
|
|
2422
|
-
function mergeContentsToString(contents) {
|
|
2423
|
-
return contents.map((c) => contentToString(c)).join("\n");
|
|
2424
|
-
}
|
|
2425
|
-
function safeStringify(value, pretty = false) {
|
|
2426
|
-
if (value == null) return "";
|
|
2427
|
-
if (typeof value === "string") return value;
|
|
2428
|
-
try {
|
|
2429
|
-
return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
|
|
2430
|
-
} catch {
|
|
2431
|
-
return String(value);
|
|
2432
|
-
}
|
|
2433
|
-
}
|
|
2434
|
-
function extractMessageText2(message) {
|
|
2435
|
-
if (!message) return "";
|
|
2436
|
-
const content = message.content;
|
|
2437
|
-
if (typeof content === "string") return content;
|
|
2438
|
-
if (Array.isArray(content)) {
|
|
2439
|
-
return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
|
|
2440
|
-
}
|
|
2441
|
-
return "";
|
|
2442
|
-
}
|
|
2443
|
-
|
|
2444
|
-
// src/smart/toolResponses.ts
|
|
2445
2484
|
function summarizeObject(value) {
|
|
2446
2485
|
if (value == null) return "null";
|
|
2447
2486
|
if (typeof value === "string") {
|
|
@@ -2556,6 +2595,97 @@ function normalizeToolCall(call) {
|
|
|
2556
2595
|
args: call.args ?? call.arguments ?? call.input ?? call.function?.arguments ?? call.function_call?.arguments
|
|
2557
2596
|
};
|
|
2558
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
|
+
}
|
|
2559
2689
|
function createToolsNode(initialTools, opts) {
|
|
2560
2690
|
return async (state) => {
|
|
2561
2691
|
const runtime = state.agent || {
|
|
@@ -2584,13 +2714,16 @@ function createToolsNode(initialTools, opts) {
|
|
|
2584
2714
|
const traceSession = state.ctx?.__traceSession;
|
|
2585
2715
|
const pendingApprovals = Array.isArray(state.pendingApprovals) ? state.pendingApprovals.map((entry) => ({ ...entry })) : [];
|
|
2586
2716
|
const pendingByCallId = new Map(pendingApprovals.map((entry) => [entry.toolCallId, entry]));
|
|
2717
|
+
const pendingUserQuestions = Array.isArray(state.pendingUserQuestions) ? state.pendingUserQuestions.map((entry) => ({ ...entry })) : [];
|
|
2587
2718
|
let awaitingApproval = false;
|
|
2719
|
+
let awaitingUserQuestion = false;
|
|
2588
2720
|
for (const tool of toolByName.values()) {
|
|
2589
2721
|
const anyTool = tool;
|
|
2590
2722
|
if (anyTool._stateRef && typeof anyTool._stateRef === "object") {
|
|
2591
2723
|
anyTool._stateRef.toolHistory = state.toolHistory;
|
|
2592
2724
|
anyTool._stateRef.toolHistoryArchived = state.toolHistoryArchived;
|
|
2593
2725
|
anyTool._stateRef.pendingApprovals = pendingApprovals;
|
|
2726
|
+
anyTool._stateRef.pendingUserQuestions = pendingUserQuestions;
|
|
2594
2727
|
anyTool._stateRef.messages = state.messages;
|
|
2595
2728
|
anyTool._stateRef.ctx = state.ctx || (state.ctx = {});
|
|
2596
2729
|
anyTool._stateRef.__onEvent = onEvent;
|
|
@@ -2661,9 +2794,11 @@ function createToolsNode(initialTools, opts) {
|
|
|
2661
2794
|
args = validatedArgs.value;
|
|
2662
2795
|
}
|
|
2663
2796
|
const toolName = tool.name || tc.name;
|
|
2797
|
+
const toolDetails = buildToolDetails(tool, toolName);
|
|
2664
2798
|
const toolStateRef = tool._stateRef && typeof tool._stateRef === "object" ? tool._stateRef : null;
|
|
2665
2799
|
if (toolStateRef) {
|
|
2666
2800
|
toolStateRef.pendingApprovals = pendingApprovals;
|
|
2801
|
+
toolStateRef.pendingUserQuestions = pendingUserQuestions;
|
|
2667
2802
|
toolStateRef.ctx = state.ctx || (state.ctx = {});
|
|
2668
2803
|
toolStateRef.__currentToolCallId = toolCallId;
|
|
2669
2804
|
delete toolStateRef.__awaitingApproval;
|
|
@@ -2680,21 +2815,17 @@ function createToolsNode(initialTools, opts) {
|
|
|
2680
2815
|
label: `Tool Skipped - ${toolName}`,
|
|
2681
2816
|
actor: { scope: "tool", name: toolName, role: "tool" },
|
|
2682
2817
|
status: "skipped",
|
|
2818
|
+
toolDetails,
|
|
2683
2819
|
toolExecutionId: tc.id,
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
function: { name: toolName, arguments: sanitizeTracePayload(args) }
|
|
2694
|
-
}
|
|
2695
|
-
]
|
|
2696
|
-
}
|
|
2697
|
-
]
|
|
2820
|
+
sections: buildToolTraceSections({
|
|
2821
|
+
args,
|
|
2822
|
+
executionId: tc.id,
|
|
2823
|
+
output: limitMessage,
|
|
2824
|
+
status: "skipped",
|
|
2825
|
+
summary: limitMessage,
|
|
2826
|
+
toolDetails,
|
|
2827
|
+
toolName
|
|
2828
|
+
})
|
|
2698
2829
|
});
|
|
2699
2830
|
toolCount += 1;
|
|
2700
2831
|
return { status: "error" };
|
|
@@ -2781,6 +2912,25 @@ function createToolsNode(initialTools, opts) {
|
|
|
2781
2912
|
push({ role: "tool", content: breakerMsg, tool_call_id: toolCallId, name: tc.name });
|
|
2782
2913
|
markToolFailure(breakerMsg, toolName, toolCallId);
|
|
2783
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
|
+
});
|
|
2784
2934
|
toolCount += 1;
|
|
2785
2935
|
return { status: "error" };
|
|
2786
2936
|
}
|
|
@@ -2805,6 +2955,38 @@ function createToolsNode(initialTools, opts) {
|
|
|
2805
2955
|
});
|
|
2806
2956
|
push({ role: "tool", content: responsePolicy2.content, tool_call_id: tc.id || `${tc.name}_${toolCount}`, name: tc.name });
|
|
2807
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
|
+
});
|
|
2808
2990
|
toolCount += 1;
|
|
2809
2991
|
return { status: "success" };
|
|
2810
2992
|
}
|
|
@@ -2875,6 +3057,22 @@ function createToolsNode(initialTools, opts) {
|
|
|
2875
3057
|
approval: pendingApproval
|
|
2876
3058
|
};
|
|
2877
3059
|
}
|
|
3060
|
+
if (output && typeof output === "object" && output.__awaitingUserQuestion) {
|
|
3061
|
+
if (toolStateRef?.ctx && typeof toolStateRef.ctx === "object") {
|
|
3062
|
+
state.ctx = toolStateRef.ctx;
|
|
3063
|
+
}
|
|
3064
|
+
const pendingQuestion = pendingUserQuestions.find(
|
|
3065
|
+
(entry) => entry.toolCallId === output.toolCallId || entry.id === output.id
|
|
3066
|
+
);
|
|
3067
|
+
if (!pendingQuestion) {
|
|
3068
|
+
throw new Error(`Tool ${toolName} requested a user question but no pending question entry was recorded.`);
|
|
3069
|
+
}
|
|
3070
|
+
awaitingUserQuestion = true;
|
|
3071
|
+
return {
|
|
3072
|
+
status: "awaiting_user_question",
|
|
3073
|
+
userQuestion: pendingQuestion
|
|
3074
|
+
};
|
|
3075
|
+
}
|
|
2878
3076
|
if (output && typeof output === "object" && output.__finalStructuredOutput) {
|
|
2879
3077
|
if (!state.ctx) state.ctx = {};
|
|
2880
3078
|
state.ctx.__structuredOutputParsed = output.data;
|
|
@@ -2909,28 +3107,6 @@ function createToolsNode(initialTools, opts) {
|
|
|
2909
3107
|
}
|
|
2910
3108
|
const sanitizedOutput = sanitizeTracePayload(output);
|
|
2911
3109
|
const outputBytes = traceSession?.resolvedConfig.logData ? estimatePayloadBytes(sanitizedOutput) : void 0;
|
|
2912
|
-
const messageList = [
|
|
2913
|
-
{
|
|
2914
|
-
role: "assistant",
|
|
2915
|
-
name: toolName,
|
|
2916
|
-
content: "",
|
|
2917
|
-
tool_calls: [
|
|
2918
|
-
{
|
|
2919
|
-
id: tc.id || executionId,
|
|
2920
|
-
type: "function",
|
|
2921
|
-
function: {
|
|
2922
|
-
name: toolName,
|
|
2923
|
-
arguments: sanitizedArgs
|
|
2924
|
-
}
|
|
2925
|
-
}
|
|
2926
|
-
]
|
|
2927
|
-
},
|
|
2928
|
-
{
|
|
2929
|
-
role: "tool",
|
|
2930
|
-
name: toolName,
|
|
2931
|
-
content: responsePolicy.content
|
|
2932
|
-
}
|
|
2933
|
-
];
|
|
2934
3110
|
recordTraceEvent(traceSession, {
|
|
2935
3111
|
type: "tool_call",
|
|
2936
3112
|
label: `Tool Execution - ${toolName}`,
|
|
@@ -2938,8 +3114,20 @@ function createToolsNode(initialTools, opts) {
|
|
|
2938
3114
|
durationMs,
|
|
2939
3115
|
requestBytes: inputBytes,
|
|
2940
3116
|
responseBytes: outputBytes,
|
|
3117
|
+
toolDetails,
|
|
2941
3118
|
toolExecutionId: executionId,
|
|
2942
|
-
|
|
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
|
+
}),
|
|
2943
3131
|
debug: {
|
|
2944
3132
|
classification: responsePolicy.classification,
|
|
2945
3133
|
retentionPolicy: "keep_full",
|
|
@@ -2958,6 +3146,7 @@ function createToolsNode(initialTools, opts) {
|
|
|
2958
3146
|
markToolFailure(message, toolName, toolCallId);
|
|
2959
3147
|
onEvent?.({ type: "tool_call", phase: "error", name: toolName, id: tc.id, args, error: { message } });
|
|
2960
3148
|
onProgress?.({ stage: "tools", message: `Tool ${tc.name} failed`, detail: { error: message } });
|
|
3149
|
+
const errorOutput = { message, stack: error?.stack };
|
|
2961
3150
|
recordTraceEvent(traceSession, {
|
|
2962
3151
|
type: "tool_call",
|
|
2963
3152
|
label: `Tool Error - ${toolName}`,
|
|
@@ -2965,27 +3154,20 @@ function createToolsNode(initialTools, opts) {
|
|
|
2965
3154
|
status: "error",
|
|
2966
3155
|
durationMs,
|
|
2967
3156
|
requestBytes: inputBytes,
|
|
3157
|
+
responseBytes: traceSession?.resolvedConfig.logData ? estimatePayloadBytes(errorOutput) : void 0,
|
|
3158
|
+
toolDetails,
|
|
2968
3159
|
toolExecutionId: executionId,
|
|
2969
3160
|
error: { message, stack: error?.stack },
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
}
|
|
2981
|
-
]
|
|
2982
|
-
},
|
|
2983
|
-
{
|
|
2984
|
-
role: "tool",
|
|
2985
|
-
name: toolName,
|
|
2986
|
-
content: `Error executing tool: ${message}`
|
|
2987
|
-
}
|
|
2988
|
-
]
|
|
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
|
+
})
|
|
2989
3171
|
});
|
|
2990
3172
|
toolCount += 1;
|
|
2991
3173
|
return { status: "error", approval: approvalEntry };
|
|
@@ -3012,15 +3194,19 @@ function createToolsNode(initialTools, opts) {
|
|
|
3012
3194
|
return false;
|
|
3013
3195
|
};
|
|
3014
3196
|
for (const idx of approvalIndices) {
|
|
3015
|
-
if (awaitingApproval || shouldStop) break;
|
|
3197
|
+
if (awaitingApproval || awaitingUserQuestion || shouldStop) break;
|
|
3016
3198
|
if (checkCancellationStop()) break;
|
|
3017
3199
|
const result = await runOne(planned[idx], orderedSlots[idx]);
|
|
3018
3200
|
if (result.status === "awaiting_approval") {
|
|
3019
3201
|
awaitingApproval = true;
|
|
3020
3202
|
break;
|
|
3021
3203
|
}
|
|
3204
|
+
if (result.status === "awaiting_user_question") {
|
|
3205
|
+
awaitingUserQuestion = true;
|
|
3206
|
+
break;
|
|
3207
|
+
}
|
|
3022
3208
|
}
|
|
3023
|
-
if (!awaitingApproval && !shouldStop && parallelIndices.length > 0) {
|
|
3209
|
+
if (!awaitingApproval && !awaitingUserQuestion && !shouldStop && parallelIndices.length > 0) {
|
|
3024
3210
|
const concurrency = Math.max(1, Math.min(limits.maxParallelTools, parallelIndices.length));
|
|
3025
3211
|
let cursor = 0;
|
|
3026
3212
|
const workerError = {};
|
|
@@ -3028,7 +3214,7 @@ function createToolsNode(initialTools, opts) {
|
|
|
3028
3214
|
for (let w = 0; w < concurrency; w++) {
|
|
3029
3215
|
workers.push((async () => {
|
|
3030
3216
|
while (true) {
|
|
3031
|
-
if (workerError.err || shouldStop || awaitingApproval) return;
|
|
3217
|
+
if (workerError.err || shouldStop || awaitingApproval || awaitingUserQuestion) return;
|
|
3032
3218
|
const i = cursor++;
|
|
3033
3219
|
if (i >= parallelIndices.length) return;
|
|
3034
3220
|
if (checkCancellationStop()) return;
|
|
@@ -3039,6 +3225,10 @@ function createToolsNode(initialTools, opts) {
|
|
|
3039
3225
|
awaitingApproval = true;
|
|
3040
3226
|
return;
|
|
3041
3227
|
}
|
|
3228
|
+
if (result.status === "awaiting_user_question") {
|
|
3229
|
+
awaitingUserQuestion = true;
|
|
3230
|
+
return;
|
|
3231
|
+
}
|
|
3042
3232
|
} catch (err) {
|
|
3043
3233
|
workerError.err = err;
|
|
3044
3234
|
return;
|
|
@@ -3054,29 +3244,26 @@ function createToolsNode(initialTools, opts) {
|
|
|
3054
3244
|
}
|
|
3055
3245
|
for (const tc of skipped) {
|
|
3056
3246
|
onEvent?.({ type: "tool_call", phase: "skipped", name: tc.name, id: tc.id, args: tc.args });
|
|
3057
|
-
const
|
|
3247
|
+
const toolDetails = buildToolDetails(toolByName.get(tc.name), tc.name);
|
|
3248
|
+
const skipMessage = `Skipped tool due to tool-call limit: ${tc.name}`;
|
|
3058
3249
|
recordTraceEvent(traceSession, {
|
|
3059
3250
|
type: "tool_call",
|
|
3060
3251
|
label: `Tool Skipped - ${tc.name}`,
|
|
3061
3252
|
actor: { scope: "tool", name: tc.name, role: "tool" },
|
|
3062
3253
|
status: "skipped",
|
|
3254
|
+
toolDetails,
|
|
3063
3255
|
toolExecutionId: tc.id,
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
function: { name: tc.name, arguments: sanitizedArgs }
|
|
3074
|
-
}
|
|
3075
|
-
]
|
|
3076
|
-
}
|
|
3077
|
-
]
|
|
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
|
+
})
|
|
3078
3265
|
});
|
|
3079
|
-
appended.push({ role: "tool", content:
|
|
3266
|
+
appended.push({ role: "tool", content: skipMessage, tool_call_id: tc.id || `${tc.name}_${appended.length}`, name: tc.name });
|
|
3080
3267
|
toolCount += 1;
|
|
3081
3268
|
}
|
|
3082
3269
|
if (!awaitingApproval && state.ctx?.__awaitingApproval) {
|
|
@@ -3101,11 +3288,12 @@ function createToolsNode(initialTools, opts) {
|
|
|
3101
3288
|
toolCache: state.toolCache,
|
|
3102
3289
|
// Explicitly propagate ctx so callers using `{ ...state, ...delta }`
|
|
3103
3290
|
// do not silently capture a stale ctx reference. Mutations to
|
|
3104
|
-
// __summarizationExhausted / __awaitingApproval /
|
|
3105
|
-
// are made on this object during execution.
|
|
3291
|
+
// __summarizationExhausted / __awaitingApproval / __awaitingUserQuestion /
|
|
3292
|
+
// __structuredOutputParsed are made on this object during execution.
|
|
3106
3293
|
ctx: state.ctx,
|
|
3107
3294
|
agent: state.agent,
|
|
3108
|
-
pendingApprovals
|
|
3295
|
+
pendingApprovals,
|
|
3296
|
+
pendingUserQuestions
|
|
3109
3297
|
};
|
|
3110
3298
|
};
|
|
3111
3299
|
}
|
|
@@ -3571,6 +3759,226 @@ function resolveToolApprovalState(state, resolution) {
|
|
|
3571
3759
|
};
|
|
3572
3760
|
}
|
|
3573
3761
|
|
|
3762
|
+
// src/utils/userQuestions.ts
|
|
3763
|
+
var cloneQuestions = (questions) => Array.isArray(questions) ? questions.map((entry) => ({ ...entry })) : [];
|
|
3764
|
+
function validateAnswers(entry, answers, cancelled) {
|
|
3765
|
+
if (cancelled) {
|
|
3766
|
+
return answers || {};
|
|
3767
|
+
}
|
|
3768
|
+
const allowFreeText = entry.allowFreeText !== false;
|
|
3769
|
+
const out = {};
|
|
3770
|
+
const provided = answers || {};
|
|
3771
|
+
for (const question of entry.questions) {
|
|
3772
|
+
const required = question.required !== false;
|
|
3773
|
+
const key = question.question;
|
|
3774
|
+
const answer = provided[key] ?? provided[question.header || ""];
|
|
3775
|
+
if (!answer) {
|
|
3776
|
+
if (required) {
|
|
3777
|
+
throw new Error(`Missing answer for required question: "${key}".`);
|
|
3778
|
+
}
|
|
3779
|
+
continue;
|
|
3780
|
+
}
|
|
3781
|
+
const values = Array.isArray(answer.values) ? answer.values.filter((v) => typeof v === "string") : [];
|
|
3782
|
+
const freeText = typeof answer.freeText === "string" ? answer.freeText.trim() : "";
|
|
3783
|
+
const notes = typeof answer.notes === "string" ? answer.notes : void 0;
|
|
3784
|
+
if (freeText && !allowFreeText) {
|
|
3785
|
+
throw new Error(
|
|
3786
|
+
`Free-text answers are disabled for this agent (question: "${key}"). Pick one of the provided options.`
|
|
3787
|
+
);
|
|
3788
|
+
}
|
|
3789
|
+
if (values.length === 0 && !freeText) {
|
|
3790
|
+
if (required) {
|
|
3791
|
+
throw new Error(`Question "${key}" requires either a selected option or free-text answer.`);
|
|
3792
|
+
}
|
|
3793
|
+
continue;
|
|
3794
|
+
}
|
|
3795
|
+
if (values.length > 1 && !question.multiSelect) {
|
|
3796
|
+
throw new Error(`Question "${key}" is single-select but received multiple values.`);
|
|
3797
|
+
}
|
|
3798
|
+
if (Array.isArray(question.options) && question.options.length > 0 && values.length > 0) {
|
|
3799
|
+
const allowedValues = new Set(
|
|
3800
|
+
question.options.map((option) => option.value ?? option.label)
|
|
3801
|
+
);
|
|
3802
|
+
for (const value of values) {
|
|
3803
|
+
if (!allowedValues.has(value)) {
|
|
3804
|
+
if (!allowFreeText) {
|
|
3805
|
+
throw new Error(
|
|
3806
|
+
`Value "${value}" is not one of the allowed options for question "${key}".`
|
|
3807
|
+
);
|
|
3808
|
+
}
|
|
3809
|
+
}
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
3812
|
+
out[key] = { values, ...freeText ? { freeText } : {}, ...notes ? { notes } : {} };
|
|
3813
|
+
}
|
|
3814
|
+
return out;
|
|
3815
|
+
}
|
|
3816
|
+
function buildToolResponseContent(entry, answers, cancelled, notes) {
|
|
3817
|
+
if (cancelled) {
|
|
3818
|
+
return JSON.stringify({
|
|
3819
|
+
status: "cancelled",
|
|
3820
|
+
message: notes || "User dismissed the question without answering."
|
|
3821
|
+
});
|
|
3822
|
+
}
|
|
3823
|
+
const payload = {
|
|
3824
|
+
status: "answered",
|
|
3825
|
+
answers: entry.questions.map((question) => {
|
|
3826
|
+
const key = question.question;
|
|
3827
|
+
const ans = answers[key];
|
|
3828
|
+
return {
|
|
3829
|
+
question: key,
|
|
3830
|
+
header: question.header,
|
|
3831
|
+
values: ans?.values ?? [],
|
|
3832
|
+
freeText: ans?.freeText,
|
|
3833
|
+
notes: ans?.notes
|
|
3834
|
+
};
|
|
3835
|
+
}),
|
|
3836
|
+
...notes ? { reviewerNotes: notes } : {}
|
|
3837
|
+
};
|
|
3838
|
+
return JSON.stringify(payload);
|
|
3839
|
+
}
|
|
3840
|
+
function resolveUserQuestionState(state, resolution) {
|
|
3841
|
+
const pending = cloneQuestions(state.pendingUserQuestions);
|
|
3842
|
+
const matchIndex = pending.findIndex(
|
|
3843
|
+
(entry2) => entry2.id === resolution.id || entry2.toolCallId === resolution.id
|
|
3844
|
+
);
|
|
3845
|
+
if (matchIndex === -1) {
|
|
3846
|
+
throw new Error(`Pending user question not found for id: ${resolution.id}`);
|
|
3847
|
+
}
|
|
3848
|
+
const entry = { ...pending[matchIndex] };
|
|
3849
|
+
if (entry.status === "answered" || entry.status === "executed" || entry.status === "cancelled") {
|
|
3850
|
+
throw new Error(`User question ${entry.id} already resolved (status: ${entry.status}).`);
|
|
3851
|
+
}
|
|
3852
|
+
const cancelled = resolution.cancelled === true;
|
|
3853
|
+
const validated = validateAnswers(entry, resolution.answers, cancelled);
|
|
3854
|
+
entry.status = cancelled ? "cancelled" : "answered";
|
|
3855
|
+
entry.answers = validated;
|
|
3856
|
+
entry.cancelled = cancelled || void 0;
|
|
3857
|
+
entry.answeredBy = resolution.answeredBy;
|
|
3858
|
+
entry.notes = resolution.notes;
|
|
3859
|
+
entry.answeredAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3860
|
+
pending[matchIndex] = entry;
|
|
3861
|
+
const ctx = { ...state.ctx || {} };
|
|
3862
|
+
delete ctx.__awaitingUserQuestion;
|
|
3863
|
+
if (ctx.__resumeStage === "tools") {
|
|
3864
|
+
delete ctx.__resumeStage;
|
|
3865
|
+
}
|
|
3866
|
+
ctx.__userQuestionResolved = { id: entry.id, status: entry.status };
|
|
3867
|
+
const toolMessage = {
|
|
3868
|
+
role: "tool",
|
|
3869
|
+
name: "ask_user_question",
|
|
3870
|
+
tool_call_id: entry.toolCallId,
|
|
3871
|
+
content: buildToolResponseContent(entry, validated, cancelled, resolution.notes)
|
|
3872
|
+
};
|
|
3873
|
+
return {
|
|
3874
|
+
...state,
|
|
3875
|
+
pendingUserQuestions: pending,
|
|
3876
|
+
messages: [...state.messages || [], toolMessage],
|
|
3877
|
+
ctx
|
|
3878
|
+
};
|
|
3879
|
+
}
|
|
3880
|
+
var DEFAULT_DESCRIPTION_WITH_FREETEXT = "Pause the agent and surface a structured prompt to the human user when you genuinely cannot proceed without their input. Group up to 4 closely related questions into a single call. Prefer concrete options the user can pick over open-ended free-text \u2014 list `options` whenever you can anticipate the choices. The user may type a custom answer for any question. Do not use this tool for things you can deduce from the conversation, the system prompt, or another tool. After the user answers, their selections come back as the tool result.";
|
|
3881
|
+
var DEFAULT_DESCRIPTION_NO_FREETEXT = "Pause the agent and surface a structured multi-choice prompt to the human user when you genuinely cannot proceed without their input. Group up to 4 closely related questions into a single call. Every question MUST include at least two `options` \u2014 free-text answers are disabled for this agent. Do not use this tool for things you can deduce from the conversation, the system prompt, or another tool. After the user picks, their selections come back as the tool result.";
|
|
3882
|
+
function buildOptionSchema() {
|
|
3883
|
+
return z.object({
|
|
3884
|
+
label: z.string().min(1).describe("Display text the user sees"),
|
|
3885
|
+
value: z.string().min(1).optional().describe("Value returned in the answer; defaults to label"),
|
|
3886
|
+
description: z.string().optional(),
|
|
3887
|
+
preview: z.string().optional().describe("Optional code / ASCII preview rendered when this option is focused")
|
|
3888
|
+
}).strict();
|
|
3889
|
+
}
|
|
3890
|
+
function buildQuestionSchema(allowFreeText) {
|
|
3891
|
+
const optionSchema = buildOptionSchema();
|
|
3892
|
+
const baseShape = {
|
|
3893
|
+
question: z.string().min(1).describe("Full question shown to the user"),
|
|
3894
|
+
header: z.string().max(40).optional().describe("Short chip / tag rendered next to the question (max ~12 chars recommended)"),
|
|
3895
|
+
multiSelect: z.boolean().optional().describe("Allow multiple selections. Default: false"),
|
|
3896
|
+
placeholder: z.string().optional(),
|
|
3897
|
+
required: z.boolean().optional().describe("Default: true")
|
|
3898
|
+
};
|
|
3899
|
+
if (allowFreeText) {
|
|
3900
|
+
return z.object({
|
|
3901
|
+
...baseShape,
|
|
3902
|
+
options: z.array(optionSchema).min(2).max(12).optional()
|
|
3903
|
+
}).strict();
|
|
3904
|
+
}
|
|
3905
|
+
return z.object({
|
|
3906
|
+
...baseShape,
|
|
3907
|
+
options: z.array(optionSchema).min(2).max(12).describe("Required: free-text answers are disabled for this agent")
|
|
3908
|
+
}).strict();
|
|
3909
|
+
}
|
|
3910
|
+
function createAskUserQuestionTool(stateRef, config) {
|
|
3911
|
+
const allowFreeText = config.allowFreeText !== false;
|
|
3912
|
+
const description = config.promptOverride ?? (allowFreeText ? DEFAULT_DESCRIPTION_WITH_FREETEXT : DEFAULT_DESCRIPTION_NO_FREETEXT);
|
|
3913
|
+
const questionSchema = buildQuestionSchema(allowFreeText);
|
|
3914
|
+
const askUser = createTool({
|
|
3915
|
+
name: "ask_user_question",
|
|
3916
|
+
description,
|
|
3917
|
+
schema: z.object({
|
|
3918
|
+
questions: z.array(questionSchema).min(1).max(4).describe("1-4 related questions to ask in a single pause.")
|
|
3919
|
+
}).strict(),
|
|
3920
|
+
func: async ({ questions }) => {
|
|
3921
|
+
const ref = askUser._stateRef || (askUser._stateRef = {});
|
|
3922
|
+
const onEvent = ref.__onEvent;
|
|
3923
|
+
if (!ref.ctx) ref.ctx = {};
|
|
3924
|
+
const ctx = ref.ctx;
|
|
3925
|
+
const toolCallId = ref.__currentToolCallId || `ask_user_${nanoid(6)}`;
|
|
3926
|
+
if (!ref.pendingUserQuestions) ref.pendingUserQuestions = [];
|
|
3927
|
+
const pendingList = ref.pendingUserQuestions;
|
|
3928
|
+
const entry = {
|
|
3929
|
+
id: nanoid(),
|
|
3930
|
+
toolCallId,
|
|
3931
|
+
toolName: "ask_user_question",
|
|
3932
|
+
questions,
|
|
3933
|
+
status: "pending",
|
|
3934
|
+
requestedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3935
|
+
allowFreeText
|
|
3936
|
+
};
|
|
3937
|
+
pendingList.push(entry);
|
|
3938
|
+
ctx.__awaitingUserQuestion = {
|
|
3939
|
+
id: entry.id,
|
|
3940
|
+
toolCallId: entry.toolCallId,
|
|
3941
|
+
requestedAt: entry.requestedAt
|
|
3942
|
+
};
|
|
3943
|
+
ctx.__resumeStage = "tools";
|
|
3944
|
+
onEvent?.({
|
|
3945
|
+
type: "user_question",
|
|
3946
|
+
status: "pending",
|
|
3947
|
+
id: entry.id,
|
|
3948
|
+
toolCallId: entry.toolCallId,
|
|
3949
|
+
questions: entry.questions,
|
|
3950
|
+
allowFreeText
|
|
3951
|
+
});
|
|
3952
|
+
recordTraceEvent(ctx.__traceSession, {
|
|
3953
|
+
type: "user_question",
|
|
3954
|
+
label: "Ask User",
|
|
3955
|
+
actor: { scope: "agent", name: "ask_user_question", role: "user_interaction" },
|
|
3956
|
+
status: "success",
|
|
3957
|
+
sections: [
|
|
3958
|
+
{
|
|
3959
|
+
kind: "metadata",
|
|
3960
|
+
label: "Pending Question",
|
|
3961
|
+
data: {
|
|
3962
|
+
id: entry.id,
|
|
3963
|
+
toolCallId: entry.toolCallId,
|
|
3964
|
+
questions: entry.questions,
|
|
3965
|
+
allowFreeText
|
|
3966
|
+
}
|
|
3967
|
+
}
|
|
3968
|
+
]
|
|
3969
|
+
});
|
|
3970
|
+
return {
|
|
3971
|
+
__awaitingUserQuestion: true,
|
|
3972
|
+
id: entry.id,
|
|
3973
|
+
toolCallId: entry.toolCallId
|
|
3974
|
+
};
|
|
3975
|
+
}
|
|
3976
|
+
});
|
|
3977
|
+
askUser._stateRef = stateRef;
|
|
3978
|
+
askUser.__source = "human-in-the-loop";
|
|
3979
|
+
return askUser;
|
|
3980
|
+
}
|
|
3981
|
+
|
|
3574
3982
|
// src/agent.ts
|
|
3575
3983
|
init_utilTokens();
|
|
3576
3984
|
|
|
@@ -3782,6 +4190,21 @@ function createAgent(opts) {
|
|
|
3782
4190
|
const resolver = createResolverNode();
|
|
3783
4191
|
const agentCore = createAgentCoreNode(opts);
|
|
3784
4192
|
const toolsBase = [...opts.tools ?? []];
|
|
4193
|
+
const askUserConfig = (() => {
|
|
4194
|
+
const raw = opts.humanInTheLoop?.askUser;
|
|
4195
|
+
if (!raw) return void 0;
|
|
4196
|
+
if (raw === true) return { enabled: true, allowFreeText: true };
|
|
4197
|
+
return {
|
|
4198
|
+
enabled: true,
|
|
4199
|
+
allowFreeText: raw.allowFreeText !== false,
|
|
4200
|
+
promptOverride: raw.promptOverride
|
|
4201
|
+
};
|
|
4202
|
+
})();
|
|
4203
|
+
const askUserOnQuestion = typeof opts.humanInTheLoop?.askUser === "object" ? opts.humanInTheLoop?.askUser?.onQuestion : void 0;
|
|
4204
|
+
const askUserStateRef = askUserConfig ? { pendingUserQuestions: void 0, ctx: void 0, __onEvent: void 0, __currentToolCallId: void 0 } : void 0;
|
|
4205
|
+
if (askUserConfig && askUserStateRef) {
|
|
4206
|
+
toolsBase.push(createAskUserQuestionTool(askUserStateRef, askUserConfig));
|
|
4207
|
+
}
|
|
3785
4208
|
const soManager = opts.outputSchema ? new StructuredOutputManager(opts.outputSchema, resolveStrategy(opts.model)) : void 0;
|
|
3786
4209
|
if (soManager) {
|
|
3787
4210
|
const modelCapabilities = getModelCapabilities(opts.model);
|
|
@@ -3826,7 +4249,8 @@ function createAgent(opts) {
|
|
|
3826
4249
|
useTodoList: void 0,
|
|
3827
4250
|
outputSchema: opts.outputSchema,
|
|
3828
4251
|
responseFormat: soManager?.getResponseFormat(),
|
|
3829
|
-
tracing: opts.tracing
|
|
4252
|
+
tracing: opts.tracing,
|
|
4253
|
+
humanInTheLoop: askUserConfig ? { askUser: askUserConfig } : void 0
|
|
3830
4254
|
};
|
|
3831
4255
|
const summarizationThreshold = getActiveSummarizationThreshold(opts);
|
|
3832
4256
|
async function runLoop(initial, config, emit) {
|
|
@@ -4090,7 +4514,7 @@ function createAgent(opts) {
|
|
|
4090
4514
|
if (toolCalls.length === 0) {
|
|
4091
4515
|
if (soManager && !state.ctx?.__finalizedDueToStructuredOutput && !state.ctx?.__structuredOutputForceFinalize) {
|
|
4092
4516
|
if (soManager.strategy.kind === "native") {
|
|
4093
|
-
const assistantText =
|
|
4517
|
+
const assistantText = extractMessageText(lastMsg);
|
|
4094
4518
|
if (assistantText) {
|
|
4095
4519
|
const parsed = soManager.parseFromContent(assistantText);
|
|
4096
4520
|
if (parsed.success) {
|
|
@@ -4116,6 +4540,7 @@ function createAgent(opts) {
|
|
|
4116
4540
|
state = { ...state, ...await toolsNode(state) };
|
|
4117
4541
|
onProgress?.({ stage: "tools", message: "Tools finished" });
|
|
4118
4542
|
if (state.ctx?.__awaitingApproval) break;
|
|
4543
|
+
if (state.ctx?.__awaitingUserQuestion) break;
|
|
4119
4544
|
if (checkpointIfRequested("after_tools")) break;
|
|
4120
4545
|
if (state.ctx?.__finalizedDueToStructuredOutput) break;
|
|
4121
4546
|
if (reflectNode && resolvedReasoning?.reflection.enabled) {
|
|
@@ -4140,7 +4565,7 @@ function createAgent(opts) {
|
|
|
4140
4565
|
if (soManager && !state.ctx?.__finalizedDueToStructuredOutput) {
|
|
4141
4566
|
const lastForParse = state.messages[state.messages.length - 1];
|
|
4142
4567
|
if (lastForParse?.role === "assistant") {
|
|
4143
|
-
const assistantText =
|
|
4568
|
+
const assistantText = extractMessageText(lastForParse);
|
|
4144
4569
|
if (assistantText) {
|
|
4145
4570
|
const parsed = soManager.parseFromContent(assistantText);
|
|
4146
4571
|
if (parsed.success) {
|
|
@@ -4186,7 +4611,7 @@ function createAgent(opts) {
|
|
|
4186
4611
|
}
|
|
4187
4612
|
const lastAfterLoop = state.messages[state.messages.length - 1];
|
|
4188
4613
|
if (lastAfterLoop?.role === "tool" && !pausedStage) {
|
|
4189
|
-
const isExpectedExit = state.ctx?.__awaitingApproval || state.ctx?.__cancelled || state.ctx?.__finalizedDueToStructuredOutput || state.ctx?.__finalizedDueToToolLimit || state.ctx?.__needsSummarization || state.ctx?.__limitBreached;
|
|
4614
|
+
const isExpectedExit = state.ctx?.__awaitingApproval || state.ctx?.__awaitingUserQuestion || state.ctx?.__cancelled || state.ctx?.__finalizedDueToStructuredOutput || state.ctx?.__finalizedDueToToolLimit || state.ctx?.__needsSummarization || state.ctx?.__limitBreached;
|
|
4190
4615
|
if (!isExpectedExit) {
|
|
4191
4616
|
throw new Error(
|
|
4192
4617
|
"Agent loop terminated with a pending tool response but no subsequent model invocation. This usually indicates a model provider error or exhausted iteration budget."
|
|
@@ -4204,7 +4629,17 @@ function createAgent(opts) {
|
|
|
4204
4629
|
const { setTokenCounter: setTokenCounter2 } = await Promise.resolve().then(() => (init_utilTokens(), utilTokens_exports));
|
|
4205
4630
|
setTokenCounter2(userTokenCounter);
|
|
4206
4631
|
}
|
|
4207
|
-
const
|
|
4632
|
+
const callerOnEvent = config?.onEvent;
|
|
4633
|
+
const onEvent = askUserOnQuestion ? (event) => {
|
|
4634
|
+
if (event && event.type === "user_question") {
|
|
4635
|
+
try {
|
|
4636
|
+
askUserOnQuestion(event);
|
|
4637
|
+
} catch (err) {
|
|
4638
|
+
console.warn("[agent-sdk] humanInTheLoop.askUser.onQuestion error:", err);
|
|
4639
|
+
}
|
|
4640
|
+
}
|
|
4641
|
+
callerOnEvent?.(event);
|
|
4642
|
+
} : callerOnEvent;
|
|
4208
4643
|
const onProgress = config?.onProgress;
|
|
4209
4644
|
const onStream = config?.onStream;
|
|
4210
4645
|
const streamEnabled = config?.stream === true;
|
|
@@ -4248,6 +4683,7 @@ function createAgent(opts) {
|
|
|
4248
4683
|
metadata: input.metadata,
|
|
4249
4684
|
ctx,
|
|
4250
4685
|
pendingApprovals: input.pendingApprovals || [],
|
|
4686
|
+
pendingUserQuestions: input.pendingUserQuestions || [],
|
|
4251
4687
|
agent: input.agent || runtimeWithInvokeLimits,
|
|
4252
4688
|
usage: input.usage || { perRequest: [], totals: {} }
|
|
4253
4689
|
};
|
|
@@ -4282,7 +4718,7 @@ function createAgent(opts) {
|
|
|
4282
4718
|
const isTransientSummarizationExit = !!res.ctx?.__needsSummarization;
|
|
4283
4719
|
const finalAssistantMsg = isTransientSummarizationExit ? void 0 : getLastAssistantMessage(res.messages);
|
|
4284
4720
|
const finalIsSyntheticSummary = !isTransientSummarizationExit && finalAssistantMsg && isSyntheticSummaryMessage(finalAssistantMsg);
|
|
4285
|
-
const content = isTransientSummarizationExit || finalIsSyntheticSummary ? "" :
|
|
4721
|
+
const content = isTransientSummarizationExit || finalIsSyntheticSummary ? "" : extractMessageText(finalAssistantMsg);
|
|
4286
4722
|
let parsed = void 0;
|
|
4287
4723
|
let outputError = void 0;
|
|
4288
4724
|
if (soManager) {
|
|
@@ -4324,11 +4760,13 @@ function createAgent(opts) {
|
|
|
4324
4760
|
return invokeAgent(restoredState, config);
|
|
4325
4761
|
};
|
|
4326
4762
|
const resolveToolApproval = (state, resolution) => resolveToolApprovalState(state, resolution);
|
|
4763
|
+
const resolveUserQuestion = (state, resolution) => resolveUserQuestionState(state, resolution);
|
|
4327
4764
|
const instance = {
|
|
4328
4765
|
invoke: invokeAgent,
|
|
4329
4766
|
snapshot: snapshotState,
|
|
4330
4767
|
resume: resumeAgent,
|
|
4331
4768
|
resolveToolApproval,
|
|
4769
|
+
resolveUserQuestion,
|
|
4332
4770
|
asTool: ({ toolName, description, inputDescription }) => {
|
|
4333
4771
|
const schema = z.object({ input: z.string().describe(inputDescription || "Input for delegated agent") });
|
|
4334
4772
|
const delegatedTool = createTool({
|
|
@@ -4588,7 +5026,7 @@ function renderMemoryBlock(facts) {
|
|
|
4588
5026
|
function clampToBudget(messages, maxContextTokens) {
|
|
4589
5027
|
let working = [...messages];
|
|
4590
5028
|
while (working.length > 2) {
|
|
4591
|
-
const tokenCount = countApproxTokens(working.map(
|
|
5029
|
+
const tokenCount = countApproxTokens(working.map(extractMessageText).join("\n"));
|
|
4592
5030
|
if (tokenCount <= maxContextTokens) return working;
|
|
4593
5031
|
const firstNonSystem = working.findIndex((message, index) => !(index === 0 && message.role === "system"));
|
|
4594
5032
|
if (firstNonSystem < 0) break;
|
|
@@ -5645,7 +6083,20 @@ function createSmartAgent(opts) {
|
|
|
5645
6083
|
const userTools = opts.tools ?? [];
|
|
5646
6084
|
const factoryStateRef = { toolHistory: void 0, toolHistoryArchived: void 0, todoList: void 0, planVersion: 0, adherenceScore: 0 };
|
|
5647
6085
|
const factoryContextTools = createContextTools(factoryStateRef, { planningEnabled, includeGetToolResponse: false });
|
|
6086
|
+
const askUserConfig = (() => {
|
|
6087
|
+
const raw = opts.humanInTheLoop?.askUser;
|
|
6088
|
+
if (!raw) return void 0;
|
|
6089
|
+
if (raw === true) return { enabled: true, allowFreeText: true };
|
|
6090
|
+
return {
|
|
6091
|
+
enabled: true,
|
|
6092
|
+
allowFreeText: raw.allowFreeText !== false,
|
|
6093
|
+
promptOverride: raw.promptOverride
|
|
6094
|
+
};
|
|
6095
|
+
})();
|
|
5648
6096
|
const factoryToolsWithoutRecovery = [...userTools, ...factoryContextTools];
|
|
6097
|
+
if (askUserConfig) {
|
|
6098
|
+
factoryToolsWithoutRecovery.push(createAskUserQuestionTool(factoryStateRef, askUserConfig));
|
|
6099
|
+
}
|
|
5649
6100
|
const soManagerFactory = opts.outputSchema ? new StructuredOutputManager(opts.outputSchema, resolveStrategy(opts.model)) : void 0;
|
|
5650
6101
|
const modelCapabilities = opts.outputSchema ? getModelCapabilities(opts.model) : void 0;
|
|
5651
6102
|
const responseFinalizeTool = soManagerFactory && modelCapabilities?.structuredOutput !== "native" ? soManagerFactory.getResponseTool() : void 0;
|
|
@@ -5655,6 +6106,7 @@ function createSmartAgent(opts) {
|
|
|
5655
6106
|
const recoveryTool = createGetToolResponseTool(ref);
|
|
5656
6107
|
const base2 = [...userTools, ...ctxTools];
|
|
5657
6108
|
if (responseFinalizeTool) base2.push(responseFinalizeTool);
|
|
6109
|
+
if (askUserConfig) base2.push(createAskUserQuestionTool(ref, askUserConfig));
|
|
5658
6110
|
const without = base2;
|
|
5659
6111
|
const withRec = [...without, recoveryTool];
|
|
5660
6112
|
return { stateRef: ref, toolsWithoutRecovery: without, toolsWithRecovery: withRec };
|
|
@@ -5677,7 +6129,7 @@ function createSmartAgent(opts) {
|
|
|
5677
6129
|
].join("\n");
|
|
5678
6130
|
function latestUserPrompt(messages) {
|
|
5679
6131
|
const latest = [...messages].reverse().find((message) => message.role === "user");
|
|
5680
|
-
return latest ?
|
|
6132
|
+
return latest ? extractMessageText(latest) : "";
|
|
5681
6133
|
}
|
|
5682
6134
|
async function syncMemory(state) {
|
|
5683
6135
|
const query = latestUserPrompt(state.messages || []);
|
|
@@ -5839,6 +6291,7 @@ function createSmartAgent(opts) {
|
|
|
5839
6291
|
snapshot: base.snapshot,
|
|
5840
6292
|
resume: base.resume,
|
|
5841
6293
|
resolveToolApproval: base.resolveToolApproval,
|
|
6294
|
+
resolveUserQuestion: base.resolveUserQuestion,
|
|
5842
6295
|
asTool: base.asTool,
|
|
5843
6296
|
asHandoff: base.asHandoff,
|
|
5844
6297
|
__runtime: base.__runtime
|
|
@@ -8141,6 +8594,6 @@ function createProvider(config) {
|
|
|
8141
8594
|
}
|
|
8142
8595
|
}
|
|
8143
8596
|
|
|
8144
|
-
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, 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, restoreSnapshot, runSmartAgentEvalHarness, setTokenCounter, startStreamingSession, traceSessionToOtlp, withTools, writeSummaryFactsToMemory };
|
|
8597
|
+
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 };
|
|
8145
8598
|
//# sourceMappingURL=index.mjs.map
|
|
8146
8599
|
//# sourceMappingURL=index.mjs.map
|