@kortyx/hooks 0.14.0 → 0.16.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/CHANGELOG.md +22 -0
- package/dist/index.d.ts +25 -4
- package/dist/index.js +448 -57
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +8 -3
- package/dist/internal.js +24 -5
- package/dist/internal.js.map +1 -1
- package/dist/tracing-DK-T8zX5.d.ts +55 -0
- package/package.json +2 -2
- package/dist/tracing-BG-j1cer.d.ts +0 -25
package/dist/index.js
CHANGED
|
@@ -373,6 +373,7 @@ async function runReasonEngine(args) {
|
|
|
373
373
|
const reasoning = args.reasoning ?? args.model.options?.reasoning;
|
|
374
374
|
const responseFormat = args.responseFormat ?? args.model.options?.responseFormat;
|
|
375
375
|
const providerOptions = args.providerOptions ?? args.model.options?.providerOptions;
|
|
376
|
+
const tools = args.tools ?? args.model.options?.tools;
|
|
376
377
|
const model = args.model.provider.getModel(args.model.modelId, {
|
|
377
378
|
...temperature !== void 0 ? { temperature } : {},
|
|
378
379
|
streaming: stream,
|
|
@@ -381,13 +382,13 @@ async function runReasonEngine(args) {
|
|
|
381
382
|
...abortSignal !== void 0 ? { abortSignal } : {},
|
|
382
383
|
...reasoning !== void 0 ? { reasoning } : {},
|
|
383
384
|
...responseFormat !== void 0 ? { responseFormat } : {},
|
|
385
|
+
...tools !== void 0 ? { tools } : {},
|
|
384
386
|
...providerOptions !== void 0 ? { providerOptions } : {}
|
|
385
387
|
});
|
|
386
|
-
const messages = [
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
messages.push({ role: "user", content: String(args.input ?? "") });
|
|
388
|
+
const messages = args.messages !== void 0 ? args.messages : [
|
|
389
|
+
...typeof args.system === "string" && args.system.length > 0 ? [{ role: "system", content: args.system }] : [],
|
|
390
|
+
{ role: "user", content: String(args.input ?? "") }
|
|
391
|
+
];
|
|
391
392
|
const opId = typeof args.opId === "string" && args.opId.length > 0 ? args.opId : createRuntimeId();
|
|
392
393
|
const segmentId = typeof args.segmentId === "string" && args.segmentId.length > 0 ? args.segmentId : createRuntimeId();
|
|
393
394
|
const commonMeta = {
|
|
@@ -403,7 +404,15 @@ async function runReasonEngine(args) {
|
|
|
403
404
|
modelId: args.model.modelId,
|
|
404
405
|
stream,
|
|
405
406
|
emit,
|
|
407
|
+
...args.telemetry?.operation ? { operation: args.telemetry.operation } : {},
|
|
408
|
+
...args.telemetry?.prompt?.name ? { promptName: args.telemetry.prompt.name } : {},
|
|
409
|
+
...args.telemetry?.prompt?.version !== void 0 ? { promptVersion: args.telemetry.prompt.version } : {},
|
|
410
|
+
...args.telemetry?.prompt?.type ? { promptType: args.telemetry.prompt.type } : {},
|
|
406
411
|
...typeof args.nodeId === "string" && args.nodeId.length > 0 ? { nodeId: args.nodeId } : {}
|
|
412
|
+
},
|
|
413
|
+
telemetry: {
|
|
414
|
+
...args.telemetry ?? {},
|
|
415
|
+
input: args.telemetry?.input ?? messages
|
|
407
416
|
}
|
|
408
417
|
});
|
|
409
418
|
const endTrace = (span, result) => {
|
|
@@ -414,6 +423,10 @@ async function runReasonEngine(args) {
|
|
|
414
423
|
...result.warnings !== void 0 ? { warnings: result.warnings } : {},
|
|
415
424
|
attributes: {
|
|
416
425
|
textLength: result.text.length
|
|
426
|
+
},
|
|
427
|
+
telemetry: {
|
|
428
|
+
...args.telemetry ?? {},
|
|
429
|
+
output: args.telemetry?.output ?? result.text
|
|
417
430
|
}
|
|
418
431
|
});
|
|
419
432
|
};
|
|
@@ -431,6 +444,7 @@ async function runReasonEngine(args) {
|
|
|
431
444
|
let raw;
|
|
432
445
|
let usage;
|
|
433
446
|
let finishReason;
|
|
447
|
+
let toolCalls;
|
|
434
448
|
let providerMetadata;
|
|
435
449
|
let warnings;
|
|
436
450
|
if (emit) {
|
|
@@ -469,6 +483,9 @@ async function runReasonEngine(args) {
|
|
|
469
483
|
if (chunk.finishReason !== void 0) {
|
|
470
484
|
finishReason = chunk.finishReason;
|
|
471
485
|
}
|
|
486
|
+
if (chunk.toolCalls !== void 0) {
|
|
487
|
+
toolCalls = chunk.toolCalls;
|
|
488
|
+
}
|
|
472
489
|
if (chunk.providerMetadata !== void 0) {
|
|
473
490
|
providerMetadata = chunk.providerMetadata;
|
|
474
491
|
}
|
|
@@ -508,6 +525,7 @@ async function runReasonEngine(args) {
|
|
|
508
525
|
...raw !== void 0 ? { raw } : {},
|
|
509
526
|
...usage !== void 0 ? { usage } : {},
|
|
510
527
|
...finishReason !== void 0 ? { finishReason } : {},
|
|
528
|
+
...toolCalls !== void 0 ? { toolCalls } : {},
|
|
511
529
|
...providerMetadata !== void 0 ? { providerMetadata } : {},
|
|
512
530
|
...warnings !== void 0 ? { warnings } : {}
|
|
513
531
|
};
|
|
@@ -534,6 +552,7 @@ async function runReasonEngine(args) {
|
|
|
534
552
|
...response.raw !== void 0 ? { raw: response.raw } : {},
|
|
535
553
|
...response.usage !== void 0 ? { usage: response.usage } : {},
|
|
536
554
|
...response.finishReason !== void 0 ? { finishReason: response.finishReason } : {},
|
|
555
|
+
...response.toolCalls !== void 0 ? { toolCalls: response.toolCalls } : {},
|
|
537
556
|
...response.providerMetadata !== void 0 ? { providerMetadata: response.providerMetadata } : {},
|
|
538
557
|
...response.warnings !== void 0 ? { warnings: response.warnings } : {}
|
|
539
558
|
};
|
|
@@ -566,10 +585,13 @@ async function reasonEngine(args, meta, inputOverride) {
|
|
|
566
585
|
reasoning: args.reasoning,
|
|
567
586
|
responseFormat: args.responseFormat,
|
|
568
587
|
providerOptions: args.providerOptions,
|
|
588
|
+
tools: args.tools,
|
|
589
|
+
messages: args.messages,
|
|
569
590
|
defaultTemperature: ctx.node.config?.model?.temperature,
|
|
570
591
|
stream: args.stream,
|
|
571
592
|
emit: args.emit,
|
|
572
593
|
onTextChunk: args.onTextChunk,
|
|
594
|
+
telemetry: args.telemetry,
|
|
573
595
|
nodeId: ctx.node.graph.node,
|
|
574
596
|
emitEvent: ctx.node.emit,
|
|
575
597
|
reasonTrace: ctx.reasonTrace,
|
|
@@ -890,6 +912,65 @@ var withStructuredStreamHints = (input, args) => {
|
|
|
890
912
|
].join("\n\n");
|
|
891
913
|
};
|
|
892
914
|
|
|
915
|
+
// src/reason/result.ts
|
|
916
|
+
var mergeUsage = (left, right) => {
|
|
917
|
+
if (!left) return right;
|
|
918
|
+
if (!right) return left;
|
|
919
|
+
const sum = (a, b) => a === void 0 && b === void 0 ? void 0 : (a ?? 0) + (b ?? 0);
|
|
920
|
+
const raw = left.raw || right.raw ? {
|
|
921
|
+
...left.raw ?? {},
|
|
922
|
+
...right.raw ?? {}
|
|
923
|
+
} : void 0;
|
|
924
|
+
const input = sum(left.input, right.input);
|
|
925
|
+
const output = sum(left.output, right.output);
|
|
926
|
+
const total = sum(left.total, right.total);
|
|
927
|
+
const reasoning = sum(left.reasoning, right.reasoning);
|
|
928
|
+
const cacheRead = sum(left.cacheRead, right.cacheRead);
|
|
929
|
+
const cacheWrite = sum(left.cacheWrite, right.cacheWrite);
|
|
930
|
+
const merged = {};
|
|
931
|
+
if (input !== void 0) merged.input = input;
|
|
932
|
+
if (output !== void 0) merged.output = output;
|
|
933
|
+
if (total !== void 0) merged.total = total;
|
|
934
|
+
if (reasoning !== void 0) merged.reasoning = reasoning;
|
|
935
|
+
if (cacheRead !== void 0) merged.cacheRead = cacheRead;
|
|
936
|
+
if (cacheWrite !== void 0) merged.cacheWrite = cacheWrite;
|
|
937
|
+
if (raw) merged.raw = raw;
|
|
938
|
+
return merged;
|
|
939
|
+
};
|
|
940
|
+
var mergeWarnings = (left, right) => {
|
|
941
|
+
if (!left?.length) return right;
|
|
942
|
+
if (!right?.length) return left;
|
|
943
|
+
const seen = /* @__PURE__ */ new Set();
|
|
944
|
+
const merged = [];
|
|
945
|
+
for (const warning of [...left, ...right]) {
|
|
946
|
+
const key = JSON.stringify(warning);
|
|
947
|
+
if (seen.has(key)) continue;
|
|
948
|
+
seen.add(key);
|
|
949
|
+
merged.push(warning);
|
|
950
|
+
}
|
|
951
|
+
return merged;
|
|
952
|
+
};
|
|
953
|
+
var mergeProviderMetadata = (left, right) => {
|
|
954
|
+
if (!left) return right;
|
|
955
|
+
if (!right) return left;
|
|
956
|
+
return {
|
|
957
|
+
...left,
|
|
958
|
+
...right
|
|
959
|
+
};
|
|
960
|
+
};
|
|
961
|
+
var emitReasonStructuredOutput = (args) => {
|
|
962
|
+
if (!args.emit || !shouldEmitStructured(args.structured)) return;
|
|
963
|
+
emitStructuredData({
|
|
964
|
+
dataType: args.structured?.dataType ?? "reason-output",
|
|
965
|
+
data: args.output,
|
|
966
|
+
kind: "final",
|
|
967
|
+
...args.structured?.schemaId ? { schemaId: args.structured.schemaId } : {},
|
|
968
|
+
...args.structured?.schemaVersion ? { schemaVersion: args.structured.schemaVersion } : {},
|
|
969
|
+
...args.id ? { id: args.id } : {},
|
|
970
|
+
streamId: args.opId
|
|
971
|
+
});
|
|
972
|
+
};
|
|
973
|
+
|
|
893
974
|
// src/reason/structured-stream.ts
|
|
894
975
|
var resolveAppendFieldPaths = (cfg) => {
|
|
895
976
|
const fields = cfg?.fields;
|
|
@@ -1450,64 +1531,353 @@ var extractStreamingStringValues = (args) => {
|
|
|
1450
1531
|
});
|
|
1451
1532
|
};
|
|
1452
1533
|
|
|
1453
|
-
// src/reason/
|
|
1454
|
-
var
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
if (output !== void 0) merged.output = output;
|
|
1471
|
-
if (total !== void 0) merged.total = total;
|
|
1472
|
-
if (reasoning !== void 0) merged.reasoning = reasoning;
|
|
1473
|
-
if (cacheRead !== void 0) merged.cacheRead = cacheRead;
|
|
1474
|
-
if (cacheWrite !== void 0) merged.cacheWrite = cacheWrite;
|
|
1475
|
-
if (raw) merged.raw = raw;
|
|
1476
|
-
return merged;
|
|
1534
|
+
// src/reason/tools.ts
|
|
1535
|
+
var toErrorMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
1536
|
+
var toToolDefinitions = (tools) => tools.map((tool) => ({
|
|
1537
|
+
name: tool.name,
|
|
1538
|
+
...tool.title ? { title: tool.title } : {},
|
|
1539
|
+
...tool.description ? { description: tool.description } : {},
|
|
1540
|
+
inputSchema: tool.inputSchema,
|
|
1541
|
+
...tool.outputSchema !== void 0 ? { outputSchema: tool.outputSchema } : {},
|
|
1542
|
+
...tool.annotations !== void 0 ? { annotations: tool.annotations } : {},
|
|
1543
|
+
...tool.metadata !== void 0 ? { metadata: tool.metadata } : {}
|
|
1544
|
+
}));
|
|
1545
|
+
var resolveToolExecutionBoolean = (value, toolName, fallback) => {
|
|
1546
|
+
if (typeof value === "boolean") return value;
|
|
1547
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
1548
|
+
return value[toolName] ?? fallback;
|
|
1549
|
+
}
|
|
1550
|
+
return fallback;
|
|
1477
1551
|
};
|
|
1478
|
-
var
|
|
1479
|
-
if (!
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
merged.push(warning);
|
|
1552
|
+
var normalizeToolResult = (toolCall, value) => {
|
|
1553
|
+
if (value && typeof value === "object" && !Array.isArray(value) && "toolCallId" in value && "name" in value && "content" in value) {
|
|
1554
|
+
return value;
|
|
1555
|
+
}
|
|
1556
|
+
let content;
|
|
1557
|
+
try {
|
|
1558
|
+
content = typeof value === "string" ? value : JSON.stringify(value);
|
|
1559
|
+
} catch {
|
|
1560
|
+
content = String(value);
|
|
1488
1561
|
}
|
|
1489
|
-
return merged;
|
|
1490
|
-
};
|
|
1491
|
-
var mergeProviderMetadata = (left, right) => {
|
|
1492
|
-
if (!left) return right;
|
|
1493
|
-
if (!right) return left;
|
|
1494
1562
|
return {
|
|
1495
|
-
|
|
1496
|
-
|
|
1563
|
+
toolCallId: toolCall.id,
|
|
1564
|
+
name: toolCall.name,
|
|
1565
|
+
content,
|
|
1566
|
+
...value !== void 0 && value !== null && typeof value === "object" && !Array.isArray(value) ? { structuredContent: value } : {}
|
|
1497
1567
|
};
|
|
1498
1568
|
};
|
|
1499
|
-
var
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
...
|
|
1507
|
-
|
|
1508
|
-
|
|
1569
|
+
var closeOwnedTools = async (tools) => {
|
|
1570
|
+
const closeFns = /* @__PURE__ */ new Set();
|
|
1571
|
+
for (const tool of tools) {
|
|
1572
|
+
if (tool.closeAfterUse === false || !tool.close) continue;
|
|
1573
|
+
closeFns.add(tool.close);
|
|
1574
|
+
}
|
|
1575
|
+
await Promise.all(
|
|
1576
|
+
[...closeFns].map(async (close) => {
|
|
1577
|
+
await close();
|
|
1578
|
+
})
|
|
1579
|
+
);
|
|
1580
|
+
};
|
|
1581
|
+
var createInitialMessages = (args) => [
|
|
1582
|
+
...typeof args.system === "string" && args.system.length > 0 ? [{ role: "system", content: args.system }] : [],
|
|
1583
|
+
{ role: "user", content: String(args.input ?? "") }
|
|
1584
|
+
];
|
|
1585
|
+
var runReasonToolLoop = async (args) => {
|
|
1586
|
+
const { useReasonArgs, id, opId, traceSpan } = args;
|
|
1587
|
+
const ctx = getHookContext();
|
|
1588
|
+
const tools = useReasonArgs.tools ?? [];
|
|
1589
|
+
const toolByName = /* @__PURE__ */ new Map();
|
|
1590
|
+
let validationCompleted = false;
|
|
1591
|
+
try {
|
|
1592
|
+
for (const tool of tools) {
|
|
1593
|
+
if (toolByName.has(tool.name)) {
|
|
1594
|
+
throw new Error(
|
|
1595
|
+
`useReason received duplicate tool name "${tool.name}".`
|
|
1596
|
+
);
|
|
1597
|
+
}
|
|
1598
|
+
toolByName.set(tool.name, tool);
|
|
1599
|
+
}
|
|
1600
|
+
if (useReasonArgs.interrupt) {
|
|
1601
|
+
throw new Error(
|
|
1602
|
+
"useReason tools cannot be combined with useReason interrupt mode yet. Use toolExecution.approval for tool approval."
|
|
1603
|
+
);
|
|
1604
|
+
}
|
|
1605
|
+
validationCompleted = true;
|
|
1606
|
+
} finally {
|
|
1607
|
+
if (!validationCompleted) {
|
|
1608
|
+
await closeOwnedTools(tools);
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
const toolDefinitions = toToolDefinitions(tools);
|
|
1612
|
+
const maxSteps = Math.max(1, useReasonArgs.toolExecution?.maxSteps ?? 3);
|
|
1613
|
+
const messages = createInitialMessages({
|
|
1614
|
+
system: useReasonArgs.system,
|
|
1615
|
+
input: useReasonArgs.input
|
|
1509
1616
|
});
|
|
1617
|
+
const steps = [];
|
|
1618
|
+
const allToolCalls = [];
|
|
1619
|
+
const allToolResults = [];
|
|
1620
|
+
let finalText = "";
|
|
1621
|
+
let finalRaw;
|
|
1622
|
+
let finalOutput;
|
|
1623
|
+
let aggregatedUsage;
|
|
1624
|
+
let finalFinishReason;
|
|
1625
|
+
let aggregatedProviderMetadata;
|
|
1626
|
+
let aggregatedWarnings;
|
|
1627
|
+
const emitToolEvent = (event, payload) => {
|
|
1628
|
+
ctx.node.emit(event, {
|
|
1629
|
+
...payload,
|
|
1630
|
+
node: ctx.node.graph.node,
|
|
1631
|
+
...id ? { id } : {},
|
|
1632
|
+
opId
|
|
1633
|
+
});
|
|
1634
|
+
};
|
|
1635
|
+
try {
|
|
1636
|
+
for (let stepIndex = 0; stepIndex < maxSteps; stepIndex += 1) {
|
|
1637
|
+
traceSpan?.addEvent?.("useReason.tool-step.start", {
|
|
1638
|
+
stepIndex,
|
|
1639
|
+
toolCount: toolDefinitions.length
|
|
1640
|
+
});
|
|
1641
|
+
const step = await reasonEngine(
|
|
1642
|
+
{
|
|
1643
|
+
...useReasonArgs,
|
|
1644
|
+
tools: toolDefinitions,
|
|
1645
|
+
messages,
|
|
1646
|
+
emit: false,
|
|
1647
|
+
stream: false
|
|
1648
|
+
},
|
|
1649
|
+
{ ...id ? { id } : {}, opId }
|
|
1650
|
+
);
|
|
1651
|
+
finalText = step.text;
|
|
1652
|
+
finalRaw = step.raw;
|
|
1653
|
+
aggregatedUsage = mergeUsage(aggregatedUsage, step.usage);
|
|
1654
|
+
finalFinishReason = step.finishReason;
|
|
1655
|
+
aggregatedProviderMetadata = mergeProviderMetadata(
|
|
1656
|
+
aggregatedProviderMetadata,
|
|
1657
|
+
step.providerMetadata
|
|
1658
|
+
);
|
|
1659
|
+
aggregatedWarnings = mergeWarnings(aggregatedWarnings, step.warnings);
|
|
1660
|
+
const toolCalls = step.toolCalls ?? [];
|
|
1661
|
+
const toolResults = [];
|
|
1662
|
+
steps.push({
|
|
1663
|
+
stepIndex,
|
|
1664
|
+
text: step.text,
|
|
1665
|
+
toolCalls,
|
|
1666
|
+
toolResults,
|
|
1667
|
+
...step.usage ? { usage: step.usage } : {},
|
|
1668
|
+
...step.finishReason ? { finishReason: step.finishReason } : {},
|
|
1669
|
+
...step.providerMetadata ? { providerMetadata: step.providerMetadata } : {},
|
|
1670
|
+
...step.warnings ? { warnings: step.warnings } : {}
|
|
1671
|
+
});
|
|
1672
|
+
if (toolCalls.length === 0) {
|
|
1673
|
+
if ((useReasonArgs.emit ?? true) && step.text.length > 0) {
|
|
1674
|
+
emitToolEvent("text-start", {});
|
|
1675
|
+
emitToolEvent("text-delta", { delta: step.text });
|
|
1676
|
+
emitToolEvent("text-end", {});
|
|
1677
|
+
}
|
|
1678
|
+
break;
|
|
1679
|
+
}
|
|
1680
|
+
allToolCalls.push(...toolCalls);
|
|
1681
|
+
messages.push({
|
|
1682
|
+
role: "assistant",
|
|
1683
|
+
content: step.text,
|
|
1684
|
+
toolCalls
|
|
1685
|
+
});
|
|
1686
|
+
for (const toolCall of toolCalls) {
|
|
1687
|
+
const tool = toolByName.get(toolCall.name);
|
|
1688
|
+
if (!tool) {
|
|
1689
|
+
throw new Error(
|
|
1690
|
+
`Model requested unknown tool "${toolCall.name}" from useReason.`
|
|
1691
|
+
);
|
|
1692
|
+
}
|
|
1693
|
+
const shouldEmitTool = resolveToolExecutionBoolean(
|
|
1694
|
+
useReasonArgs.toolExecution?.emit,
|
|
1695
|
+
tool.name,
|
|
1696
|
+
false
|
|
1697
|
+
);
|
|
1698
|
+
const shouldApproveTool = resolveToolExecutionBoolean(
|
|
1699
|
+
useReasonArgs.toolExecution?.approval,
|
|
1700
|
+
tool.name,
|
|
1701
|
+
false
|
|
1702
|
+
);
|
|
1703
|
+
if (shouldEmitTool) {
|
|
1704
|
+
emitToolEvent("tool-call-start", {
|
|
1705
|
+
tool: tool.name,
|
|
1706
|
+
toolCallId: toolCall.id,
|
|
1707
|
+
input: toolCall.input
|
|
1708
|
+
});
|
|
1709
|
+
}
|
|
1710
|
+
if (shouldApproveTool) {
|
|
1711
|
+
const approval = await awaitInterruptInternal({
|
|
1712
|
+
id: `tool:${toolCall.id}`,
|
|
1713
|
+
request: {
|
|
1714
|
+
kind: "choice",
|
|
1715
|
+
question: `Approve ${tool.name}?`,
|
|
1716
|
+
options: [
|
|
1717
|
+
{ id: "approve", label: "Approve" },
|
|
1718
|
+
{ id: "deny", label: "Deny" }
|
|
1719
|
+
],
|
|
1720
|
+
meta: {
|
|
1721
|
+
tool: tool.name,
|
|
1722
|
+
toolCallId: toolCall.id,
|
|
1723
|
+
input: toolCall.input
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
});
|
|
1727
|
+
const approved = Array.isArray(approval) ? approval.includes("approve") : approval === "approve";
|
|
1728
|
+
if (!approved) {
|
|
1729
|
+
const denied = {
|
|
1730
|
+
toolCallId: toolCall.id,
|
|
1731
|
+
name: tool.name,
|
|
1732
|
+
content: "Tool call denied by user.",
|
|
1733
|
+
isError: true
|
|
1734
|
+
};
|
|
1735
|
+
toolResults.push(denied);
|
|
1736
|
+
allToolResults.push(denied);
|
|
1737
|
+
if (shouldEmitTool) {
|
|
1738
|
+
emitToolEvent("tool-call-result", {
|
|
1739
|
+
tool: tool.name,
|
|
1740
|
+
toolCallId: toolCall.id,
|
|
1741
|
+
content: denied.content,
|
|
1742
|
+
isError: true
|
|
1743
|
+
});
|
|
1744
|
+
}
|
|
1745
|
+
continue;
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
try {
|
|
1749
|
+
const rawResult = await tool.execute(toolCall.input, {
|
|
1750
|
+
toolCallId: toolCall.id,
|
|
1751
|
+
...useReasonArgs.abortSignal ? { abortSignal: useReasonArgs.abortSignal } : {}
|
|
1752
|
+
});
|
|
1753
|
+
const result2 = normalizeToolResult(toolCall, rawResult);
|
|
1754
|
+
toolResults.push(result2);
|
|
1755
|
+
allToolResults.push(result2);
|
|
1756
|
+
if (shouldEmitTool) {
|
|
1757
|
+
emitToolEvent("tool-call-result", {
|
|
1758
|
+
tool: result2.name,
|
|
1759
|
+
toolCallId: result2.toolCallId,
|
|
1760
|
+
content: result2.content,
|
|
1761
|
+
...result2.structuredContent !== void 0 ? { structuredContent: result2.structuredContent } : {},
|
|
1762
|
+
...result2.isError !== void 0 ? { isError: result2.isError } : {}
|
|
1763
|
+
});
|
|
1764
|
+
}
|
|
1765
|
+
traceSpan?.addEvent?.("useReason.tool-call.complete", {
|
|
1766
|
+
stepIndex,
|
|
1767
|
+
tool: result2.name,
|
|
1768
|
+
toolCallId: result2.toolCallId,
|
|
1769
|
+
isError: Boolean(result2.isError)
|
|
1770
|
+
});
|
|
1771
|
+
} catch (error) {
|
|
1772
|
+
const result2 = {
|
|
1773
|
+
toolCallId: toolCall.id,
|
|
1774
|
+
name: tool.name,
|
|
1775
|
+
content: toErrorMessage(error),
|
|
1776
|
+
isError: true
|
|
1777
|
+
};
|
|
1778
|
+
toolResults.push(result2);
|
|
1779
|
+
allToolResults.push(result2);
|
|
1780
|
+
if (shouldEmitTool) {
|
|
1781
|
+
emitToolEvent("tool-call-error", {
|
|
1782
|
+
tool: tool.name,
|
|
1783
|
+
toolCallId: toolCall.id,
|
|
1784
|
+
message: result2.content
|
|
1785
|
+
});
|
|
1786
|
+
}
|
|
1787
|
+
traceSpan?.addEvent?.("useReason.tool-call.error", {
|
|
1788
|
+
stepIndex,
|
|
1789
|
+
tool: tool.name,
|
|
1790
|
+
toolCallId: toolCall.id,
|
|
1791
|
+
message: result2.content
|
|
1792
|
+
});
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
const currentStep = steps[steps.length - 1];
|
|
1796
|
+
if (currentStep) {
|
|
1797
|
+
steps[steps.length - 1] = {
|
|
1798
|
+
...currentStep,
|
|
1799
|
+
toolResults
|
|
1800
|
+
};
|
|
1801
|
+
}
|
|
1802
|
+
for (const result2 of toolResults) {
|
|
1803
|
+
messages.push({
|
|
1804
|
+
role: "tool",
|
|
1805
|
+
content: result2.content,
|
|
1806
|
+
toolCallId: result2.toolCallId,
|
|
1807
|
+
name: result2.name,
|
|
1808
|
+
...result2.structuredContent !== void 0 ? { structuredContent: result2.structuredContent } : {},
|
|
1809
|
+
...result2.isError !== void 0 ? { isError: result2.isError } : {},
|
|
1810
|
+
...result2.raw !== void 0 ? { raw: result2.raw } : {}
|
|
1811
|
+
});
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
if (steps.length >= maxSteps && steps.at(-1)?.toolCalls.length) {
|
|
1815
|
+
throw new Error(
|
|
1816
|
+
`useReason tool loop reached maxSteps (${maxSteps}) before producing a final response.`
|
|
1817
|
+
);
|
|
1818
|
+
}
|
|
1819
|
+
if (useReasonArgs.outputSchema) {
|
|
1820
|
+
finalOutput = parseReasonOutputWithSchema({
|
|
1821
|
+
text: finalText,
|
|
1822
|
+
schema: useReasonArgs.outputSchema,
|
|
1823
|
+
...finalFinishReason ? { finishReason: finalFinishReason } : {},
|
|
1824
|
+
label: "useReason output"
|
|
1825
|
+
});
|
|
1826
|
+
}
|
|
1827
|
+
if (finalOutput !== void 0) {
|
|
1828
|
+
emitReasonStructuredOutput({
|
|
1829
|
+
...id ? { id } : {},
|
|
1830
|
+
opId,
|
|
1831
|
+
output: finalOutput,
|
|
1832
|
+
structured: useReasonArgs.structured,
|
|
1833
|
+
emit: useReasonArgs.emit ?? true
|
|
1834
|
+
});
|
|
1835
|
+
}
|
|
1836
|
+
const result = {
|
|
1837
|
+
...id ? { id } : {},
|
|
1838
|
+
opId,
|
|
1839
|
+
text: finalText,
|
|
1840
|
+
...finalRaw !== void 0 ? { raw: finalRaw } : {},
|
|
1841
|
+
...aggregatedUsage !== void 0 ? { usage: aggregatedUsage } : {},
|
|
1842
|
+
...finalFinishReason !== void 0 ? { finishReason: finalFinishReason } : {},
|
|
1843
|
+
...aggregatedProviderMetadata !== void 0 ? { providerMetadata: aggregatedProviderMetadata } : {},
|
|
1844
|
+
...aggregatedWarnings !== void 0 ? { warnings: aggregatedWarnings } : {},
|
|
1845
|
+
...finalOutput !== void 0 ? { output: finalOutput } : {},
|
|
1846
|
+
toolCalls: allToolCalls,
|
|
1847
|
+
toolResults: allToolResults,
|
|
1848
|
+
steps
|
|
1849
|
+
};
|
|
1850
|
+
traceSpan?.end?.({
|
|
1851
|
+
...aggregatedUsage !== void 0 ? { usage: aggregatedUsage } : {},
|
|
1852
|
+
...finalFinishReason !== void 0 ? { finishReason: finalFinishReason } : {},
|
|
1853
|
+
...aggregatedProviderMetadata !== void 0 ? { providerMetadata: aggregatedProviderMetadata } : {},
|
|
1854
|
+
...aggregatedWarnings !== void 0 ? { warnings: aggregatedWarnings } : {},
|
|
1855
|
+
attributes: {
|
|
1856
|
+
textLength: finalText.length,
|
|
1857
|
+
toolCallCount: allToolCalls.length,
|
|
1858
|
+
toolResultCount: allToolResults.length,
|
|
1859
|
+
toolStepCount: steps.length
|
|
1860
|
+
},
|
|
1861
|
+
telemetry: {
|
|
1862
|
+
...useReasonArgs.telemetry ?? {},
|
|
1863
|
+
output: useReasonArgs.telemetry?.output ?? finalOutput ?? finalText
|
|
1864
|
+
}
|
|
1865
|
+
});
|
|
1866
|
+
return result;
|
|
1867
|
+
} catch (error) {
|
|
1868
|
+
traceSpan?.fail?.(error, {
|
|
1869
|
+
attributes: {
|
|
1870
|
+
toolStepCount: steps.length,
|
|
1871
|
+
toolCallCount: allToolCalls.length
|
|
1872
|
+
}
|
|
1873
|
+
});
|
|
1874
|
+
throw error;
|
|
1875
|
+
} finally {
|
|
1876
|
+
await closeOwnedTools(tools);
|
|
1877
|
+
}
|
|
1510
1878
|
};
|
|
1879
|
+
|
|
1880
|
+
// src/reason/use-reason.ts
|
|
1511
1881
|
var shouldStreamReasonStructured = (args) => (args.emit ?? true) && shouldStreamStructured(args.structured);
|
|
1512
1882
|
var resolveEffectiveReasoningIncludeThoughts = (args) => args.reasoning?.includeThoughts ?? args.model.options?.reasoning?.includeThoughts ?? false;
|
|
1513
1883
|
var resolveEffectiveResponseFormatType = (args) => args.responseFormat?.type ?? args.model.options?.responseFormat?.type;
|
|
@@ -1548,11 +1918,28 @@ async function useReason(args) {
|
|
|
1548
1918
|
modelId: args.model.modelId,
|
|
1549
1919
|
stream: args.stream ?? args.model.options?.streaming ?? true,
|
|
1550
1920
|
emit: args.emit ?? true,
|
|
1921
|
+
...args.telemetry?.operation ? { operation: args.telemetry.operation } : {},
|
|
1922
|
+
...args.telemetry?.prompt?.name ? { promptName: args.telemetry.prompt.name } : {},
|
|
1923
|
+
...args.telemetry?.prompt?.version !== void 0 ? { promptVersion: args.telemetry.prompt.version } : {},
|
|
1924
|
+
...args.telemetry?.prompt?.type ? { promptType: args.telemetry.prompt.type } : {},
|
|
1551
1925
|
hasOutputSchema: Boolean(args.outputSchema),
|
|
1552
1926
|
hasInterrupt: Boolean(args.interrupt),
|
|
1553
|
-
hasStructured: Boolean(args.structured)
|
|
1927
|
+
hasStructured: Boolean(args.structured),
|
|
1928
|
+
hasTools: Boolean(args.tools?.length)
|
|
1929
|
+
},
|
|
1930
|
+
telemetry: {
|
|
1931
|
+
...args.telemetry ?? {},
|
|
1932
|
+
input: args.telemetry?.input ?? args.input
|
|
1554
1933
|
}
|
|
1555
1934
|
});
|
|
1935
|
+
if (args.tools?.length) {
|
|
1936
|
+
return runReasonToolLoop({
|
|
1937
|
+
useReasonArgs: args,
|
|
1938
|
+
...id ? { id } : {},
|
|
1939
|
+
opId,
|
|
1940
|
+
...traceSpan ? { traceSpan } : {}
|
|
1941
|
+
});
|
|
1942
|
+
}
|
|
1556
1943
|
const suppressTextStream = Boolean(args.outputSchema || args.interrupt);
|
|
1557
1944
|
const setFieldPaths = resolveSetFieldPaths(args.structured);
|
|
1558
1945
|
const appendFieldPaths = resolveAppendFieldPaths(args.structured);
|
|
@@ -1855,6 +2242,10 @@ async function useReason(args) {
|
|
|
1855
2242
|
textLength: finalText.length,
|
|
1856
2243
|
resumedFromCheckpoint: Boolean(existingCheckpoint),
|
|
1857
2244
|
interrupted: Boolean(interruptResponse !== void 0)
|
|
2245
|
+
},
|
|
2246
|
+
telemetry: {
|
|
2247
|
+
...args.telemetry ?? {},
|
|
2248
|
+
output: args.telemetry?.output ?? finalOutput ?? finalText
|
|
1858
2249
|
}
|
|
1859
2250
|
});
|
|
1860
2251
|
return result;
|