@kortyx/agent 0.24.0 → 0.25.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/CHANGELOG.md +29 -0
- package/dist/index.js +1472 -471
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -29,6 +29,476 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
29
|
));
|
|
30
30
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
31
|
|
|
32
|
+
// ../hooks/dist/internal.js
|
|
33
|
+
var require_internal = __commonJS({
|
|
34
|
+
"../hooks/dist/internal.js"(exports2, module2) {
|
|
35
|
+
var __defProp2 = Object.defineProperty;
|
|
36
|
+
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
37
|
+
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
38
|
+
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
39
|
+
var __export2 = (target, all) => {
|
|
40
|
+
for (var name in all)
|
|
41
|
+
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
42
|
+
};
|
|
43
|
+
var __copyProps2 = (to, from, except, desc) => {
|
|
44
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
45
|
+
for (let key of __getOwnPropNames2(from))
|
|
46
|
+
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
47
|
+
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
48
|
+
}
|
|
49
|
+
return to;
|
|
50
|
+
};
|
|
51
|
+
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
52
|
+
var internal_exports = {};
|
|
53
|
+
__export2(internal_exports, {
|
|
54
|
+
errorDiagnostics: () => errorDiagnostics,
|
|
55
|
+
exceptionDiagnostics: () => exceptionDiagnostics,
|
|
56
|
+
isModelTraceSpan: () => isModelTraceSpan,
|
|
57
|
+
runReasonEngine: () => runReasonEngine,
|
|
58
|
+
safeSpan: () => safeSpan,
|
|
59
|
+
safeStartSpan: () => safeStartSpan2,
|
|
60
|
+
safeTelemetryMetadata: () => safeTelemetryMetadata2,
|
|
61
|
+
withSafeTraceSpan: () => withSafeTraceSpan2
|
|
62
|
+
});
|
|
63
|
+
module2.exports = __toCommonJS2(internal_exports);
|
|
64
|
+
var import_errors6 = require("@kortyx/core/errors");
|
|
65
|
+
var MAX_STACK_LENGTH = 32768;
|
|
66
|
+
var MAX_CAUSE_DEPTH = 4;
|
|
67
|
+
var projectDetails = (value, depth, seen) => {
|
|
68
|
+
const objectValue = value && typeof value === "object" ? value : void 0;
|
|
69
|
+
if (objectValue) {
|
|
70
|
+
if (seen.has(objectValue))
|
|
71
|
+
return { type: "Error", message: "Circular error cause." };
|
|
72
|
+
seen.add(objectValue);
|
|
73
|
+
}
|
|
74
|
+
const name = (0, import_errors6.errorProperty)(value, "name") ?? (value instanceof Error ? value.name : void 0);
|
|
75
|
+
const message = (0, import_errors6.errorProperty)(value, "message");
|
|
76
|
+
const stack = (0, import_errors6.errorProperty)(value, "stack") ?? (value instanceof Error ? (() => {
|
|
77
|
+
try {
|
|
78
|
+
return value.stack;
|
|
79
|
+
} catch {
|
|
80
|
+
return void 0;
|
|
81
|
+
}
|
|
82
|
+
})() : void 0);
|
|
83
|
+
const cause = depth < MAX_CAUSE_DEPTH ? (0, import_errors6.errorProperty)(value, "cause") : null;
|
|
84
|
+
return {
|
|
85
|
+
type: typeof name === "string" ? name.slice(0, 256) : "Error",
|
|
86
|
+
message: (typeof value === "string" ? value : typeof message === "string" ? message : "Execution reported a fault.").slice(0, 8192),
|
|
87
|
+
...typeof stack === "string" ? { stack: stack.slice(0, MAX_STACK_LENGTH) } : {},
|
|
88
|
+
...cause !== null && cause !== void 0 ? { cause: projectDetails(cause, depth + 1, seen) } : {}
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
var sanitizeProjectedDetails = (details, depth = 0) => ({
|
|
92
|
+
...typeof details.type === "string" ? { type: details.type.slice(0, 256) } : {},
|
|
93
|
+
message: typeof details.message === "string" ? details.message.slice(0, 8192) : "Execution reported a fault.",
|
|
94
|
+
...typeof details.stack === "string" ? { stack: details.stack.slice(0, MAX_STACK_LENGTH) } : {},
|
|
95
|
+
...depth < MAX_CAUSE_DEPTH && details.cause ? { cause: sanitizeProjectedDetails(details.cause, depth + 1) } : {}
|
|
96
|
+
});
|
|
97
|
+
function exceptionDiagnostics(error, project) {
|
|
98
|
+
try {
|
|
99
|
+
const details = project ? project(error) : projectDetails(error, 0, /* @__PURE__ */ new WeakSet());
|
|
100
|
+
return details ? sanitizeProjectedDetails(details) : null;
|
|
101
|
+
} catch {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function errorDiagnostics(error, project) {
|
|
106
|
+
const details = exceptionDiagnostics(error, project);
|
|
107
|
+
return details ? {
|
|
108
|
+
errorMessage: details.message,
|
|
109
|
+
...details.type ? { errorType: details.type } : {}
|
|
110
|
+
} : {};
|
|
111
|
+
}
|
|
112
|
+
function isModelTraceSpan(name) {
|
|
113
|
+
return name === "runReasonEngine" || name === "useReason";
|
|
114
|
+
}
|
|
115
|
+
var import_node_crypto4 = require("crypto");
|
|
116
|
+
var import_core6 = require("@kortyx/core");
|
|
117
|
+
var import_errors22 = require("@kortyx/core/errors");
|
|
118
|
+
function safeSpan(span) {
|
|
119
|
+
const guard = (fn) => (...args) => {
|
|
120
|
+
try {
|
|
121
|
+
fn?.(...args);
|
|
122
|
+
} catch {
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
let ended = false;
|
|
126
|
+
const finish = (fn) => (...args) => {
|
|
127
|
+
if (ended) return;
|
|
128
|
+
ended = true;
|
|
129
|
+
guard(fn)(...args);
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
addEvent: guard(
|
|
133
|
+
(name, attributes) => span?.addEvent?.(name, attributes)
|
|
134
|
+
),
|
|
135
|
+
setAttributes: guard(
|
|
136
|
+
(attributes) => span?.setAttributes?.(attributes)
|
|
137
|
+
),
|
|
138
|
+
end: finish((args) => span?.end?.(args)),
|
|
139
|
+
fail: finish((error, args) => {
|
|
140
|
+
if (span?.fail) span.fail(error, args);
|
|
141
|
+
else span?.end?.(args);
|
|
142
|
+
})
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function safeStartSpan2(adapter, args) {
|
|
146
|
+
try {
|
|
147
|
+
return safeSpan(adapter?.startSpan?.(args));
|
|
148
|
+
} catch {
|
|
149
|
+
return safeSpan(void 0);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async function withSafeTraceSpan2(adapter, args, fn) {
|
|
153
|
+
let execution;
|
|
154
|
+
const invoke = (span) => {
|
|
155
|
+
execution ??= Promise.resolve().then(async () => {
|
|
156
|
+
const observed = safeSpan(span);
|
|
157
|
+
try {
|
|
158
|
+
const result = await fn(observed);
|
|
159
|
+
observed.end?.();
|
|
160
|
+
return result;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
observed.fail?.(error);
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
return execution;
|
|
167
|
+
};
|
|
168
|
+
let activeScope;
|
|
169
|
+
try {
|
|
170
|
+
activeScope = adapter?.withSpan?.bind(adapter);
|
|
171
|
+
} catch {
|
|
172
|
+
}
|
|
173
|
+
if (activeScope) {
|
|
174
|
+
let started;
|
|
175
|
+
const invoked = new Promise((resolve2) => {
|
|
176
|
+
started = resolve2;
|
|
177
|
+
});
|
|
178
|
+
const observe = async () => {
|
|
179
|
+
try {
|
|
180
|
+
await activeScope(args, (span) => {
|
|
181
|
+
const result = invoke(span);
|
|
182
|
+
started?.();
|
|
183
|
+
return result;
|
|
184
|
+
});
|
|
185
|
+
} catch {
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
const observation = observe();
|
|
189
|
+
if (!execution) await Promise.race([invoked, observation]);
|
|
190
|
+
} else {
|
|
191
|
+
await invoke(safeStartSpan2(adapter, args)).catch(() => {
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
return execution ?? invoke(safeSpan(void 0));
|
|
195
|
+
}
|
|
196
|
+
function assertModelFinish(result) {
|
|
197
|
+
if (result.finishReason?.unified !== "content-filter") return;
|
|
198
|
+
throw Object.assign(
|
|
199
|
+
new import_errors22.KortyxError("PROVIDER_REFUSAL", "The provider refused the request.", {
|
|
200
|
+
category: "provider",
|
|
201
|
+
retryable: false,
|
|
202
|
+
safeMessage: "The provider refused the request."
|
|
203
|
+
}),
|
|
204
|
+
{
|
|
205
|
+
...result.usage ? { usage: result.usage } : {},
|
|
206
|
+
finishReason: result.finishReason
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
var toError = (value) => value instanceof Error ? value : new Error(String(value));
|
|
211
|
+
var createRuntimeId = () => {
|
|
212
|
+
try {
|
|
213
|
+
return (0, import_node_crypto4.randomUUID)();
|
|
214
|
+
} catch {
|
|
215
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
var emitNodeEvent = (emitEvent, nodeId, event, payload) => {
|
|
219
|
+
if (!emitEvent) return;
|
|
220
|
+
emitEvent(event, {
|
|
221
|
+
...payload,
|
|
222
|
+
...typeof nodeId === "string" && nodeId.length > 0 ? { node: nodeId } : {}
|
|
223
|
+
});
|
|
224
|
+
};
|
|
225
|
+
var resolveProviderOptions = (defaults, overrides) => {
|
|
226
|
+
const providerOptions = defaults || overrides ? { ...defaults, ...overrides } : void 0;
|
|
227
|
+
for (const [key, value] of Object.entries(overrides ?? {})) {
|
|
228
|
+
const previous = defaults?.[key];
|
|
229
|
+
if (previous && value && typeof previous === "object" && typeof value === "object" && !Array.isArray(previous) && !Array.isArray(value)) {
|
|
230
|
+
if (providerOptions) providerOptions[key] = { ...previous, ...value };
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return providerOptions;
|
|
234
|
+
};
|
|
235
|
+
async function runReasonEngine(args) {
|
|
236
|
+
let stream = args.stream ?? args.model.options?.streaming ?? true;
|
|
237
|
+
const emit = args.emit ?? true;
|
|
238
|
+
const temperature = args.temperature ?? args.model.options?.temperature ?? args.defaultTemperature;
|
|
239
|
+
const maxOutputTokens = args.maxOutputTokens ?? args.model.options?.maxOutputTokens;
|
|
240
|
+
const stopSequences = args.stopSequences ?? args.model.options?.stopSequences;
|
|
241
|
+
const abortSignal = args.abortSignal ?? args.model.options?.abortSignal;
|
|
242
|
+
const reasoning = args.reasoning ?? args.model.options?.reasoning;
|
|
243
|
+
const responseFormat = args.responseFormat ?? args.model.options?.responseFormat;
|
|
244
|
+
const providerOptions = resolveProviderOptions(
|
|
245
|
+
args.model.options?.providerOptions,
|
|
246
|
+
args.providerOptions
|
|
247
|
+
);
|
|
248
|
+
const tools = args.tools ?? args.model.options?.tools;
|
|
249
|
+
(0, import_core6.throwIfExecutionAborted)(abortSignal);
|
|
250
|
+
const model = args.model.provider.getModel(args.model.modelId, {
|
|
251
|
+
...temperature !== void 0 ? { temperature } : {},
|
|
252
|
+
streaming: stream,
|
|
253
|
+
...maxOutputTokens !== void 0 ? { maxOutputTokens } : {},
|
|
254
|
+
...stopSequences !== void 0 ? { stopSequences } : {},
|
|
255
|
+
...abortSignal !== void 0 ? { abortSignal } : {},
|
|
256
|
+
...reasoning !== void 0 ? { reasoning } : {},
|
|
257
|
+
...responseFormat !== void 0 ? { responseFormat } : {},
|
|
258
|
+
...tools !== void 0 ? { tools } : {},
|
|
259
|
+
...providerOptions !== void 0 ? { providerOptions } : {}
|
|
260
|
+
});
|
|
261
|
+
if (tools?.length && !model.supportsToolStreaming) stream = false;
|
|
262
|
+
const messages = args.messages !== void 0 ? args.messages : [
|
|
263
|
+
...typeof args.system === "string" && args.system.length > 0 ? [{ role: "system", content: args.system }] : [],
|
|
264
|
+
{ role: "user", content: String(args.input ?? "") }
|
|
265
|
+
];
|
|
266
|
+
const opId = typeof args.opId === "string" && args.opId.length > 0 ? args.opId : createRuntimeId();
|
|
267
|
+
const segmentId = typeof args.segmentId === "string" && args.segmentId.length > 0 ? args.segmentId : createRuntimeId();
|
|
268
|
+
const commonMeta = {
|
|
269
|
+
...typeof args.id === "string" && args.id.length > 0 ? { id: args.id } : {},
|
|
270
|
+
opId,
|
|
271
|
+
segmentId
|
|
272
|
+
};
|
|
273
|
+
const traceSpan = safeStartSpan2(args.reasonTrace, {
|
|
274
|
+
name: "runReasonEngine",
|
|
275
|
+
attributes: {
|
|
276
|
+
...commonMeta,
|
|
277
|
+
providerId: args.model.provider.id,
|
|
278
|
+
modelId: args.model.modelId,
|
|
279
|
+
stream,
|
|
280
|
+
emit,
|
|
281
|
+
...args.telemetry?.operation ? { operation: args.telemetry.operation } : {},
|
|
282
|
+
...args.telemetry?.prompt?.name ? { promptName: args.telemetry.prompt.name } : {},
|
|
283
|
+
...args.telemetry?.prompt?.version !== void 0 ? { promptVersion: args.telemetry.prompt.version } : {},
|
|
284
|
+
...args.telemetry?.prompt?.type ? { promptType: args.telemetry.prompt.type } : {},
|
|
285
|
+
...typeof args.nodeId === "string" && args.nodeId.length > 0 ? { nodeId: args.nodeId } : {}
|
|
286
|
+
},
|
|
287
|
+
telemetry: {
|
|
288
|
+
...args.telemetry ?? {},
|
|
289
|
+
input: args.telemetry?.input ?? messages.map(
|
|
290
|
+
({ continuation: _continuation, raw: _raw, ...message }) => message
|
|
291
|
+
)
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
const modelRequestStartedAt = Date.now();
|
|
295
|
+
let firstTextTokenAt;
|
|
296
|
+
let lastTextTokenAt;
|
|
297
|
+
const generationTimingAttributes = () => firstTextTokenAt === void 0 || lastTextTokenAt === void 0 ? {} : {
|
|
298
|
+
ttftMs: Math.max(0, firstTextTokenAt - modelRequestStartedAt),
|
|
299
|
+
streamDurationMs: Math.max(0, lastTextTokenAt - firstTextTokenAt),
|
|
300
|
+
timeToLastTokenMs: Math.max(
|
|
301
|
+
0,
|
|
302
|
+
lastTextTokenAt - modelRequestStartedAt
|
|
303
|
+
)
|
|
304
|
+
};
|
|
305
|
+
const endTrace = (span, result) => {
|
|
306
|
+
span?.end?.({
|
|
307
|
+
...result.usage !== void 0 ? { usage: result.usage } : {},
|
|
308
|
+
...result.finishReason !== void 0 ? { finishReason: result.finishReason } : {},
|
|
309
|
+
...result.providerMetadata !== void 0 ? { providerMetadata: result.providerMetadata } : {},
|
|
310
|
+
...result.warnings !== void 0 ? { warnings: result.warnings } : {},
|
|
311
|
+
attributes: {
|
|
312
|
+
textLength: result.text.length,
|
|
313
|
+
...generationTimingAttributes()
|
|
314
|
+
},
|
|
315
|
+
telemetry: {
|
|
316
|
+
...args.telemetry ?? {},
|
|
317
|
+
output: args.telemetry?.output ?? result.text
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
};
|
|
321
|
+
const failTrace = (span, error) => {
|
|
322
|
+
const detail = error;
|
|
323
|
+
try {
|
|
324
|
+
span?.fail?.(error, {
|
|
325
|
+
...detail?.usage ? { usage: detail.usage } : {},
|
|
326
|
+
...detail?.finishReason ? { finishReason: detail.finishReason } : {},
|
|
327
|
+
...detail?.providerMetadata ? { providerMetadata: detail.providerMetadata } : {},
|
|
328
|
+
attributes: {
|
|
329
|
+
providerId: args.model.provider.id,
|
|
330
|
+
modelId: args.model.modelId
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
} catch {
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
try {
|
|
337
|
+
if (stream) {
|
|
338
|
+
let continuation;
|
|
339
|
+
let final = "";
|
|
340
|
+
let raw;
|
|
341
|
+
let usage;
|
|
342
|
+
let finishReason;
|
|
343
|
+
let toolCalls;
|
|
344
|
+
let providerMetadata;
|
|
345
|
+
let warnings;
|
|
346
|
+
if (emit) {
|
|
347
|
+
emitNodeEvent(args.emitEvent, args.nodeId, "text-start", {
|
|
348
|
+
...commonMeta
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
const response2 = await model.stream(messages);
|
|
352
|
+
for await (const chunk of response2) {
|
|
353
|
+
(0, import_core6.throwIfExecutionAborted)(abortSignal);
|
|
354
|
+
switch (chunk.type) {
|
|
355
|
+
case "text-delta": {
|
|
356
|
+
if (chunk.delta.length === 0) break;
|
|
357
|
+
const tokenAt = Date.now();
|
|
358
|
+
firstTextTokenAt ??= tokenAt;
|
|
359
|
+
lastTextTokenAt = tokenAt;
|
|
360
|
+
final += chunk.delta;
|
|
361
|
+
args.onTextChunk?.(chunk.delta);
|
|
362
|
+
if (chunk.raw !== void 0) {
|
|
363
|
+
raw = chunk.raw;
|
|
364
|
+
}
|
|
365
|
+
if (chunk.providerMetadata !== void 0) {
|
|
366
|
+
providerMetadata = chunk.providerMetadata;
|
|
367
|
+
}
|
|
368
|
+
if (emit) {
|
|
369
|
+
emitNodeEvent(args.emitEvent, args.nodeId, "text-delta", {
|
|
370
|
+
...commonMeta,
|
|
371
|
+
delta: chunk.delta
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
case "finish": {
|
|
377
|
+
continuation = chunk.continuation;
|
|
378
|
+
if (chunk.raw !== void 0) {
|
|
379
|
+
raw = chunk.raw;
|
|
380
|
+
}
|
|
381
|
+
if (chunk.usage !== void 0) {
|
|
382
|
+
usage = chunk.usage;
|
|
383
|
+
}
|
|
384
|
+
if (chunk.finishReason !== void 0) {
|
|
385
|
+
finishReason = chunk.finishReason;
|
|
386
|
+
}
|
|
387
|
+
if (chunk.toolCalls !== void 0) {
|
|
388
|
+
toolCalls = chunk.toolCalls;
|
|
389
|
+
}
|
|
390
|
+
if (chunk.providerMetadata !== void 0) {
|
|
391
|
+
providerMetadata = chunk.providerMetadata;
|
|
392
|
+
}
|
|
393
|
+
if (chunk.warnings !== void 0) {
|
|
394
|
+
warnings = chunk.warnings;
|
|
395
|
+
}
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
case "raw": {
|
|
399
|
+
raw = chunk.raw;
|
|
400
|
+
if (chunk.providerMetadata !== void 0) {
|
|
401
|
+
providerMetadata = chunk.providerMetadata;
|
|
402
|
+
}
|
|
403
|
+
break;
|
|
404
|
+
}
|
|
405
|
+
case "error": {
|
|
406
|
+
if (chunk.raw !== void 0) {
|
|
407
|
+
raw = chunk.raw;
|
|
408
|
+
}
|
|
409
|
+
if (chunk.providerMetadata !== void 0) {
|
|
410
|
+
providerMetadata = chunk.providerMetadata;
|
|
411
|
+
}
|
|
412
|
+
if (chunk.warnings !== void 0) {
|
|
413
|
+
warnings = chunk.warnings;
|
|
414
|
+
}
|
|
415
|
+
throw toError(chunk.error);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
(0, import_core6.throwIfExecutionAborted)(abortSignal);
|
|
420
|
+
assertModelFinish({ finishReason, usage });
|
|
421
|
+
if (emit) {
|
|
422
|
+
emitNodeEvent(args.emitEvent, args.nodeId, "text-end", {
|
|
423
|
+
...commonMeta
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
const result2 = {
|
|
427
|
+
text: final,
|
|
428
|
+
...continuation ? { continuation } : {},
|
|
429
|
+
...raw !== void 0 ? { raw } : {},
|
|
430
|
+
...usage !== void 0 ? { usage } : {},
|
|
431
|
+
...finishReason !== void 0 ? { finishReason } : {},
|
|
432
|
+
...toolCalls !== void 0 ? { toolCalls } : {},
|
|
433
|
+
...providerMetadata !== void 0 ? { providerMetadata } : {},
|
|
434
|
+
...warnings !== void 0 ? { warnings } : {}
|
|
435
|
+
};
|
|
436
|
+
(0, import_core6.throwIfExecutionAborted)(abortSignal);
|
|
437
|
+
endTrace(traceSpan, result2);
|
|
438
|
+
return result2;
|
|
439
|
+
}
|
|
440
|
+
const response = await model.invoke(messages);
|
|
441
|
+
(0, import_core6.throwIfExecutionAborted)(abortSignal);
|
|
442
|
+
assertModelFinish(response);
|
|
443
|
+
if (response.content) args.onTextChunk?.(response.content);
|
|
444
|
+
if (emit) {
|
|
445
|
+
emitNodeEvent(args.emitEvent, args.nodeId, "text-start", {
|
|
446
|
+
...commonMeta
|
|
447
|
+
});
|
|
448
|
+
if (response.content) {
|
|
449
|
+
emitNodeEvent(args.emitEvent, args.nodeId, "text-delta", {
|
|
450
|
+
...commonMeta,
|
|
451
|
+
delta: response.content
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
emitNodeEvent(args.emitEvent, args.nodeId, "text-end", {
|
|
455
|
+
...commonMeta
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
const result = {
|
|
459
|
+
text: response.content,
|
|
460
|
+
...response.continuation ? { continuation: response.continuation } : {},
|
|
461
|
+
...response.raw !== void 0 ? { raw: response.raw } : {},
|
|
462
|
+
...response.usage !== void 0 ? { usage: response.usage } : {},
|
|
463
|
+
...response.finishReason !== void 0 ? { finishReason: response.finishReason } : {},
|
|
464
|
+
...response.toolCalls !== void 0 ? { toolCalls: response.toolCalls } : {},
|
|
465
|
+
...response.providerMetadata !== void 0 ? { providerMetadata: response.providerMetadata } : {},
|
|
466
|
+
...response.warnings !== void 0 ? { warnings: response.warnings } : {}
|
|
467
|
+
};
|
|
468
|
+
endTrace(traceSpan, result);
|
|
469
|
+
return result;
|
|
470
|
+
} catch (error) {
|
|
471
|
+
const failure = abortSignal?.aborted ? (0, import_core6.createExecutionCancelledError)() : error;
|
|
472
|
+
failTrace(traceSpan, failure);
|
|
473
|
+
throw failure;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
var privateField = /^(?:password|passwd|secret|clientsecret|privatekey|credential|credentials|authorization|bearer|bearertoken|jwt|token|accesstoken|refreshtoken|authtoken|apikey|apisecret|cookie|setcookie|resumehandle|resumetoken)$/;
|
|
477
|
+
function safeTelemetryMetadata2(value) {
|
|
478
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
479
|
+
const visit = (input, depth) => {
|
|
480
|
+
if (depth > 8 || typeof input === "function" || typeof input === "symbol")
|
|
481
|
+
return void 0;
|
|
482
|
+
if (!input || typeof input !== "object") return input;
|
|
483
|
+
if (seen.has(input)) return void 0;
|
|
484
|
+
seen.add(input);
|
|
485
|
+
if (Array.isArray(input))
|
|
486
|
+
return input.map((item) => visit(item, depth + 1));
|
|
487
|
+
return Object.fromEntries(
|
|
488
|
+
Object.entries(input).flatMap(
|
|
489
|
+
([key, nested]) => privateField.test(key.toLowerCase().replace(/[^a-z0-9]/g, "")) ? [] : [[key, visit(nested, depth + 1)]]
|
|
490
|
+
)
|
|
491
|
+
);
|
|
492
|
+
};
|
|
493
|
+
try {
|
|
494
|
+
return visit(value, 0);
|
|
495
|
+
} catch {
|
|
496
|
+
return {};
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
|
|
32
502
|
// ../hooks/dist/index.js
|
|
33
503
|
var require_dist = __commonJS({
|
|
34
504
|
"../hooks/dist/index.js"(exports2, module2) {
|
|
@@ -57,6 +527,7 @@ var require_dist = __commonJS({
|
|
|
57
527
|
createWorkflowHooks: () => createWorkflowHooks,
|
|
58
528
|
emitWorkflowCall: () => emitWorkflowCall2,
|
|
59
529
|
parallel: () => parallel,
|
|
530
|
+
reportError: () => reportError,
|
|
60
531
|
runWithHookContext: () => runWithHookContext,
|
|
61
532
|
useAbortSignal: () => useAbortSignal,
|
|
62
533
|
useInterrupt: () => useInterrupt,
|
|
@@ -64,6 +535,7 @@ var require_dist = __commonJS({
|
|
|
64
535
|
useReason: () => useReason2,
|
|
65
536
|
useRuntimeContext: () => useRuntimeContext,
|
|
66
537
|
useStructuredData: () => useStructuredData,
|
|
538
|
+
useTool: () => useTool,
|
|
67
539
|
useWorkflow: () => useWorkflow,
|
|
68
540
|
useWorkflowState: () => useWorkflowState,
|
|
69
541
|
workflowCallFingerprint: () => workflowCallFingerprint
|
|
@@ -127,6 +599,7 @@ var require_dist = __commonJS({
|
|
|
127
599
|
workflowContextClosed: false,
|
|
128
600
|
nodeStateIndex: 0,
|
|
129
601
|
reasonCallIndex: 0,
|
|
602
|
+
toolCallIndex: 0,
|
|
130
603
|
currentNodeState,
|
|
131
604
|
workflowState: cloneWorkflowState(hookRuntimeState.workflowState),
|
|
132
605
|
tokenUsage: cloneTokenUsage(ctx.state.runtime?.tokenUsage),
|
|
@@ -217,6 +690,12 @@ var require_dist = __commonJS({
|
|
|
217
690
|
}
|
|
218
691
|
});
|
|
219
692
|
cleanupCompletedReasonCheckpoints(internal);
|
|
693
|
+
for (const key of Object.keys(internal.currentNodeState.byKey)) {
|
|
694
|
+
if (key.startsWith("__useTool:")) {
|
|
695
|
+
delete internal.currentNodeState.byKey[key];
|
|
696
|
+
internal.stateDirty = true;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
220
699
|
for (const key of Object.keys(internal.currentNodeState.byKey)) {
|
|
221
700
|
if (key.startsWith("__useWorkflow:") || key.startsWith("__parallel:") || key === "__useWorkflowActivation") {
|
|
222
701
|
internal.currentNodeState.byKey[key] = null;
|
|
@@ -357,7 +836,85 @@ var require_dist = __commonJS({
|
|
|
357
836
|
);
|
|
358
837
|
return Promise.resolve(response);
|
|
359
838
|
};
|
|
360
|
-
var
|
|
839
|
+
var import_core62 = require("@kortyx/core");
|
|
840
|
+
function safeSpan(span) {
|
|
841
|
+
const guard = (fn) => (...args) => {
|
|
842
|
+
try {
|
|
843
|
+
fn?.(...args);
|
|
844
|
+
} catch {
|
|
845
|
+
}
|
|
846
|
+
};
|
|
847
|
+
let ended = false;
|
|
848
|
+
const finish = (fn) => (...args) => {
|
|
849
|
+
if (ended) return;
|
|
850
|
+
ended = true;
|
|
851
|
+
guard(fn)(...args);
|
|
852
|
+
};
|
|
853
|
+
return {
|
|
854
|
+
addEvent: guard(
|
|
855
|
+
(name, attributes) => span?.addEvent?.(name, attributes)
|
|
856
|
+
),
|
|
857
|
+
setAttributes: guard(
|
|
858
|
+
(attributes) => span?.setAttributes?.(attributes)
|
|
859
|
+
),
|
|
860
|
+
end: finish((args) => span?.end?.(args)),
|
|
861
|
+
fail: finish((error, args) => {
|
|
862
|
+
if (span?.fail) span.fail(error, args);
|
|
863
|
+
else span?.end?.(args);
|
|
864
|
+
})
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
function safeStartSpan2(adapter, args) {
|
|
868
|
+
try {
|
|
869
|
+
return safeSpan(adapter?.startSpan?.(args));
|
|
870
|
+
} catch {
|
|
871
|
+
return safeSpan(void 0);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
async function withSafeTraceSpan2(adapter, args, fn) {
|
|
875
|
+
let execution;
|
|
876
|
+
const invoke = (span) => {
|
|
877
|
+
execution ??= Promise.resolve().then(async () => {
|
|
878
|
+
const observed = safeSpan(span);
|
|
879
|
+
try {
|
|
880
|
+
const result = await fn(observed);
|
|
881
|
+
observed.end?.();
|
|
882
|
+
return result;
|
|
883
|
+
} catch (error) {
|
|
884
|
+
observed.fail?.(error);
|
|
885
|
+
throw error;
|
|
886
|
+
}
|
|
887
|
+
});
|
|
888
|
+
return execution;
|
|
889
|
+
};
|
|
890
|
+
let activeScope;
|
|
891
|
+
try {
|
|
892
|
+
activeScope = adapter?.withSpan?.bind(adapter);
|
|
893
|
+
} catch {
|
|
894
|
+
}
|
|
895
|
+
if (activeScope) {
|
|
896
|
+
let started;
|
|
897
|
+
const invoked = new Promise((resolve2) => {
|
|
898
|
+
started = resolve2;
|
|
899
|
+
});
|
|
900
|
+
const observe = async () => {
|
|
901
|
+
try {
|
|
902
|
+
await activeScope(args, (span) => {
|
|
903
|
+
const result = invoke(span);
|
|
904
|
+
started?.();
|
|
905
|
+
return result;
|
|
906
|
+
});
|
|
907
|
+
} catch {
|
|
908
|
+
}
|
|
909
|
+
};
|
|
910
|
+
const observation = observe();
|
|
911
|
+
if (!execution) await Promise.race([invoked, observation]);
|
|
912
|
+
} else {
|
|
913
|
+
await invoke(safeStartSpan2(adapter, args)).catch(() => {
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
return execution ?? invoke(safeSpan(void 0));
|
|
917
|
+
}
|
|
361
918
|
var import_node_crypto4 = require("crypto");
|
|
362
919
|
var parseStructuredPath = (path, source) => {
|
|
363
920
|
if (path.length === 0) {
|
|
@@ -444,15 +1001,408 @@ var require_dist = __commonJS({
|
|
|
444
1001
|
};
|
|
445
1002
|
var shouldEmitStructured = (cfg) => Boolean(cfg);
|
|
446
1003
|
var shouldStreamStructured = (cfg) => Boolean(cfg) && (cfg?.stream ?? true);
|
|
1004
|
+
var import_node_async_hooks2 = require("async_hooks");
|
|
447
1005
|
var import_node_crypto32 = require("crypto");
|
|
1006
|
+
var import_core22 = require("@kortyx/core");
|
|
1007
|
+
var import_errors32 = require("@kortyx/core/errors");
|
|
1008
|
+
var import_errors22 = require("@kortyx/core/errors");
|
|
1009
|
+
var MAX_STACK_LENGTH = 32768;
|
|
1010
|
+
var MAX_CAUSE_DEPTH = 4;
|
|
1011
|
+
var projectDetails = (value, depth, seen) => {
|
|
1012
|
+
const objectValue = value && typeof value === "object" ? value : void 0;
|
|
1013
|
+
if (objectValue) {
|
|
1014
|
+
if (seen.has(objectValue))
|
|
1015
|
+
return { type: "Error", message: "Circular error cause." };
|
|
1016
|
+
seen.add(objectValue);
|
|
1017
|
+
}
|
|
1018
|
+
const name = (0, import_errors22.errorProperty)(value, "name") ?? (value instanceof Error ? value.name : void 0);
|
|
1019
|
+
const message = (0, import_errors22.errorProperty)(value, "message");
|
|
1020
|
+
const stack = (0, import_errors22.errorProperty)(value, "stack") ?? (value instanceof Error ? (() => {
|
|
1021
|
+
try {
|
|
1022
|
+
return value.stack;
|
|
1023
|
+
} catch {
|
|
1024
|
+
return void 0;
|
|
1025
|
+
}
|
|
1026
|
+
})() : void 0);
|
|
1027
|
+
const cause = depth < MAX_CAUSE_DEPTH ? (0, import_errors22.errorProperty)(value, "cause") : null;
|
|
1028
|
+
return {
|
|
1029
|
+
type: typeof name === "string" ? name.slice(0, 256) : "Error",
|
|
1030
|
+
message: (typeof value === "string" ? value : typeof message === "string" ? message : "Execution reported a fault.").slice(0, 8192),
|
|
1031
|
+
...typeof stack === "string" ? { stack: stack.slice(0, MAX_STACK_LENGTH) } : {},
|
|
1032
|
+
...cause !== null && cause !== void 0 ? { cause: projectDetails(cause, depth + 1, seen) } : {}
|
|
1033
|
+
};
|
|
1034
|
+
};
|
|
1035
|
+
var sanitizeProjectedDetails = (details, depth = 0) => ({
|
|
1036
|
+
...typeof details.type === "string" ? { type: details.type.slice(0, 256) } : {},
|
|
1037
|
+
message: typeof details.message === "string" ? details.message.slice(0, 8192) : "Execution reported a fault.",
|
|
1038
|
+
...typeof details.stack === "string" ? { stack: details.stack.slice(0, MAX_STACK_LENGTH) } : {},
|
|
1039
|
+
...depth < MAX_CAUSE_DEPTH && details.cause ? { cause: sanitizeProjectedDetails(details.cause, depth + 1) } : {}
|
|
1040
|
+
});
|
|
1041
|
+
function exceptionDiagnostics(error, project) {
|
|
1042
|
+
try {
|
|
1043
|
+
const details = project ? project(error) : projectDetails(error, 0, /* @__PURE__ */ new WeakSet());
|
|
1044
|
+
return details ? sanitizeProjectedDetails(details) : null;
|
|
1045
|
+
} catch {
|
|
1046
|
+
return null;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
function errorDiagnostics(error, project) {
|
|
1050
|
+
const details = exceptionDiagnostics(error, project);
|
|
1051
|
+
return details ? {
|
|
1052
|
+
errorMessage: details.message,
|
|
1053
|
+
...details.type ? { errorType: details.type } : {}
|
|
1054
|
+
} : {};
|
|
1055
|
+
}
|
|
1056
|
+
var import_node_crypto22 = require("crypto");
|
|
1057
|
+
function emitWorkflowCall2(telemetry, type, payload) {
|
|
1058
|
+
const base = telemetry?.correlation;
|
|
1059
|
+
if (!telemetry?.reporter || !telemetry.environment || !telemetry.service || !base?.runId || !base.workflowId)
|
|
1060
|
+
return;
|
|
1061
|
+
try {
|
|
1062
|
+
const active = telemetry.trace?.getActiveContext?.();
|
|
1063
|
+
void Promise.resolve(
|
|
1064
|
+
telemetry.reporter.emit([
|
|
1065
|
+
{
|
|
1066
|
+
schemaVersion: 1,
|
|
1067
|
+
eventId: (0, import_node_crypto22.randomUUID)(),
|
|
1068
|
+
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1069
|
+
environment: telemetry.environment,
|
|
1070
|
+
service: telemetry.service,
|
|
1071
|
+
correlation: {
|
|
1072
|
+
...base,
|
|
1073
|
+
runId: base.runId,
|
|
1074
|
+
workflowId: base.workflowId,
|
|
1075
|
+
...active
|
|
1076
|
+
},
|
|
1077
|
+
type,
|
|
1078
|
+
payload
|
|
1079
|
+
}
|
|
1080
|
+
])
|
|
1081
|
+
).catch(() => {
|
|
1082
|
+
});
|
|
1083
|
+
} catch {
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
function workflowCallContent(telemetry, side, value) {
|
|
1087
|
+
const policy = telemetry?.captureContent;
|
|
1088
|
+
if (!(policy === true || policy && typeof policy === "object" && policy[side]))
|
|
1089
|
+
return {};
|
|
1090
|
+
const serialized = JSON.stringify(value);
|
|
1091
|
+
return serialized && Buffer.byteLength(serialized, "utf8") <= 16384 ? { [side]: JSON.parse(serialized) } : { [`${side}Omitted`]: "Content exceeds 16 KiB" };
|
|
1092
|
+
}
|
|
1093
|
+
var tools = new import_node_async_hooks2.AsyncLocalStorage();
|
|
1094
|
+
function classification(tool, value, thrown, policy = tool.outcomes) {
|
|
1095
|
+
const fallback = {
|
|
1096
|
+
outcome: thrown ? "fault" : "success"
|
|
1097
|
+
};
|
|
1098
|
+
try {
|
|
1099
|
+
if (value && typeof value === "object" && "isError" in value && value.isError === true)
|
|
1100
|
+
fallback.outcome = "fault";
|
|
1101
|
+
const result = thrown ? policy?.classifyError?.(value) : policy?.classifyResult?.(value);
|
|
1102
|
+
if (!result || !["success", "denied", "fault"].includes(result.outcome))
|
|
1103
|
+
return fallback;
|
|
1104
|
+
if (result.outcome !== "denied")
|
|
1105
|
+
return thrown || fallback.outcome === "fault" ? fallback : { outcome: result.outcome };
|
|
1106
|
+
const code = result.code;
|
|
1107
|
+
return {
|
|
1108
|
+
outcome: "denied",
|
|
1109
|
+
code: typeof code === "string" && /^[A-Z][A-Z0-9_]{0,63}$/.test(code) && policy?.denialCodes?.includes(code) ? code : "DENIED"
|
|
1110
|
+
};
|
|
1111
|
+
} catch {
|
|
1112
|
+
return fallback;
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
async function closeOwnedTools(owned) {
|
|
1116
|
+
const closers = /* @__PURE__ */ new Map();
|
|
1117
|
+
for (const tool of owned) {
|
|
1118
|
+
if (tool.closeAfterUse !== false && tool.close && !closers.has(tool.close))
|
|
1119
|
+
closers.set(tool.close, tool);
|
|
1120
|
+
}
|
|
1121
|
+
await Promise.all(
|
|
1122
|
+
[...closers].map(async ([close, tool]) => {
|
|
1123
|
+
try {
|
|
1124
|
+
await close.call(tool);
|
|
1125
|
+
} catch {
|
|
1126
|
+
const ctx = getHookContext();
|
|
1127
|
+
try {
|
|
1128
|
+
ctx.reasonTrace?.startSpan({
|
|
1129
|
+
name: "kortyx.tool.cleanup",
|
|
1130
|
+
attributes: { cleanupFailed: true }
|
|
1131
|
+
})?.end?.();
|
|
1132
|
+
} catch {
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
})
|
|
1136
|
+
);
|
|
1137
|
+
}
|
|
1138
|
+
function captureToolError(observation, error, policy, returned = false) {
|
|
1139
|
+
try {
|
|
1140
|
+
const reported = returned && error && typeof error === "object" && "isError" in error && error.isError === true && "content" in error && typeof error.content === "string" ? { name: "ToolError", message: error.content } : error;
|
|
1141
|
+
Object.assign(
|
|
1142
|
+
observation,
|
|
1143
|
+
errorDiagnostics(policy?.error ? error : reported, policy?.error)
|
|
1144
|
+
);
|
|
1145
|
+
} catch {
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
function ownership() {
|
|
1149
|
+
const ctx = getHookContext();
|
|
1150
|
+
const correlation = ctx.node.workflowCallTelemetry?.correlation;
|
|
1151
|
+
return {
|
|
1152
|
+
workflowId: ctx.node.graph.name,
|
|
1153
|
+
nodeId: ctx.node.graph.node,
|
|
1154
|
+
...correlation?.workflowRevisionId ? { workflowRevisionId: correlation.workflowRevisionId } : {},
|
|
1155
|
+
...correlation?.parentInvocationId ? { parentInvocationId: correlation.parentInvocationId } : {},
|
|
1156
|
+
...correlation?.runId ? { runId: correlation.runId } : {},
|
|
1157
|
+
...correlation?.invocationId ? { invocationId: correlation.invocationId } : {},
|
|
1158
|
+
...correlation?.branchId ? { branchId: correlation.branchId } : {}
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1161
|
+
function rememberToolObservation(observation) {
|
|
1162
|
+
const ctx = getHookContext();
|
|
1163
|
+
const existing = ctx.workflowState.__kortyxToolObservations;
|
|
1164
|
+
const observations = Array.isArray(existing) ? existing : [];
|
|
1165
|
+
if (!observations.some((item) => item.attemptId === observation.attemptId))
|
|
1166
|
+
observations.push({ ...observation });
|
|
1167
|
+
ctx.workflowState.__kortyxToolObservations = observations;
|
|
1168
|
+
ctx.stateDirty = true;
|
|
1169
|
+
}
|
|
1170
|
+
function toolTrace(observation) {
|
|
1171
|
+
const ctx = getHookContext();
|
|
1172
|
+
const adapter = ctx.reasonTrace ?? ctx.node.workflowCallTelemetry?.trace;
|
|
1173
|
+
if (adapter) return adapter;
|
|
1174
|
+
const telemetry = ctx.node.workflowCallTelemetry;
|
|
1175
|
+
if (!telemetry?.reporter) return void 0;
|
|
1176
|
+
const correlation = { ...telemetry.correlation, ...observation };
|
|
1177
|
+
const spanId = (0, import_node_crypto32.randomUUID)();
|
|
1178
|
+
const emit = (type, payload) => emitWorkflowCall2(
|
|
1179
|
+
{
|
|
1180
|
+
...telemetry,
|
|
1181
|
+
correlation,
|
|
1182
|
+
trace: {
|
|
1183
|
+
startSpan: () => void 0,
|
|
1184
|
+
getActiveContext: () => ({
|
|
1185
|
+
traceId: correlation.runId ?? spanId,
|
|
1186
|
+
spanId
|
|
1187
|
+
})
|
|
1188
|
+
}
|
|
1189
|
+
},
|
|
1190
|
+
type,
|
|
1191
|
+
payload
|
|
1192
|
+
);
|
|
1193
|
+
return {
|
|
1194
|
+
startSpan: ({ attributes = {} }) => {
|
|
1195
|
+
if (attributes.executed === true) emit("tool.started", attributes);
|
|
1196
|
+
let ended = false;
|
|
1197
|
+
return {
|
|
1198
|
+
end: (args) => {
|
|
1199
|
+
if (ended) return;
|
|
1200
|
+
ended = true;
|
|
1201
|
+
const payload = { ...attributes, ...args?.attributes };
|
|
1202
|
+
const type = payload.observationKind === "reused" ? "tool.reused" : payload.observationKind === "waiting" ? "tool.waiting" : payload.suspended ? "tool.suspended" : payload.outcome === "denied" ? "tool.denied" : payload.outcome === "fault" ? "tool.failed" : payload.outcome === "cancelled" ? "tool.cancelled" : "tool.completed";
|
|
1203
|
+
emit(type, payload);
|
|
1204
|
+
}
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
async function executeObservedTool(args) {
|
|
1210
|
+
const ctx = getHookContext();
|
|
1211
|
+
const observation = {
|
|
1212
|
+
version: 1,
|
|
1213
|
+
name: args.tool.name,
|
|
1214
|
+
toolCallId: args.toolCallId,
|
|
1215
|
+
attemptId: (0, import_node_crypto32.randomUUID)(),
|
|
1216
|
+
callingMode: args.callingMode,
|
|
1217
|
+
executed: false,
|
|
1218
|
+
...ownership()
|
|
1219
|
+
};
|
|
1220
|
+
const scope = {
|
|
1221
|
+
tool: args.tool,
|
|
1222
|
+
input: args.input,
|
|
1223
|
+
signal: args.abortSignal,
|
|
1224
|
+
mode: args.callingMode,
|
|
1225
|
+
providerToolCallId: args.providerToolCallId ?? args.toolCallId,
|
|
1226
|
+
adopted: false
|
|
1227
|
+
};
|
|
1228
|
+
try {
|
|
1229
|
+
(0, import_core22.throwIfExecutionAborted)(args.abortSignal);
|
|
1230
|
+
} catch (error) {
|
|
1231
|
+
observation.outcome = "cancelled";
|
|
1232
|
+
await observeToolFact(observation);
|
|
1233
|
+
args.onObservation?.(observation);
|
|
1234
|
+
throw error;
|
|
1235
|
+
}
|
|
1236
|
+
ctx.node.consumeExecution?.("maxToolCalls");
|
|
1237
|
+
observation.executed = true;
|
|
1238
|
+
const started = performance.now();
|
|
1239
|
+
return withSafeTraceSpan2(
|
|
1240
|
+
toolTrace(observation),
|
|
1241
|
+
{
|
|
1242
|
+
name: "kortyx.tool",
|
|
1243
|
+
attributes: { ...observation, nodeId: ctx.node.graph.node }
|
|
1244
|
+
},
|
|
1245
|
+
async (span) => tools.run(scope, async () => {
|
|
1246
|
+
try {
|
|
1247
|
+
const result = await args.tool.execute(args.input, {
|
|
1248
|
+
toolCallId: args.providerToolCallId ?? args.toolCallId,
|
|
1249
|
+
...args.abortSignal ? { abortSignal: args.abortSignal } : {}
|
|
1250
|
+
});
|
|
1251
|
+
(0, import_core22.throwIfExecutionAborted)(args.abortSignal);
|
|
1252
|
+
const outcome = classification(
|
|
1253
|
+
args.tool,
|
|
1254
|
+
result,
|
|
1255
|
+
false,
|
|
1256
|
+
scope.classify ?? args.tool.outcomes
|
|
1257
|
+
);
|
|
1258
|
+
observation.outcome = outcome.outcome;
|
|
1259
|
+
if (outcome.code) observation.denialCode = outcome.code;
|
|
1260
|
+
if (observation.outcome === "fault") {
|
|
1261
|
+
captureToolError(
|
|
1262
|
+
observation,
|
|
1263
|
+
result,
|
|
1264
|
+
scope.telemetry ?? args.tool.telemetry,
|
|
1265
|
+
true
|
|
1266
|
+
);
|
|
1267
|
+
}
|
|
1268
|
+
return result;
|
|
1269
|
+
} catch (error) {
|
|
1270
|
+
if (args.abortSignal?.aborted) observation.outcome = "cancelled";
|
|
1271
|
+
else if (!(0, import_errors32.isControlFlowError)(error)) {
|
|
1272
|
+
const outcome = classification(
|
|
1273
|
+
args.tool,
|
|
1274
|
+
error,
|
|
1275
|
+
true,
|
|
1276
|
+
scope.classify ?? args.tool.outcomes
|
|
1277
|
+
);
|
|
1278
|
+
observation.outcome = outcome.outcome;
|
|
1279
|
+
if (outcome.code) observation.denialCode = outcome.code;
|
|
1280
|
+
if (observation.outcome === "fault")
|
|
1281
|
+
captureToolError(
|
|
1282
|
+
observation,
|
|
1283
|
+
error,
|
|
1284
|
+
scope.telemetry ?? args.tool.telemetry
|
|
1285
|
+
);
|
|
1286
|
+
}
|
|
1287
|
+
throw error;
|
|
1288
|
+
} finally {
|
|
1289
|
+
observation.durationMs = Math.max(0, performance.now() - started);
|
|
1290
|
+
span.end?.({
|
|
1291
|
+
attributes: {
|
|
1292
|
+
...observation,
|
|
1293
|
+
...observation.outcome ? {} : { suspended: true }
|
|
1294
|
+
}
|
|
1295
|
+
});
|
|
1296
|
+
rememberToolObservation(observation);
|
|
1297
|
+
args.onObservation?.({ ...observation });
|
|
1298
|
+
}
|
|
1299
|
+
})
|
|
1300
|
+
);
|
|
1301
|
+
}
|
|
1302
|
+
async function observeToolFact(observation, kind, preserveOwner = false) {
|
|
1303
|
+
const ctx = getHookContext();
|
|
1304
|
+
if (!preserveOwner) Object.assign(observation, ownership());
|
|
1305
|
+
if (observation.outcome && kind !== "reused")
|
|
1306
|
+
rememberToolObservation(observation);
|
|
1307
|
+
await withSafeTraceSpan2(
|
|
1308
|
+
toolTrace(observation),
|
|
1309
|
+
{
|
|
1310
|
+
name: "kortyx.tool",
|
|
1311
|
+
attributes: {
|
|
1312
|
+
...observation,
|
|
1313
|
+
executed: false,
|
|
1314
|
+
...kind ? { observationKind: kind } : {},
|
|
1315
|
+
nodeId: observation.nodeId ?? ctx.node.graph.node
|
|
1316
|
+
}
|
|
1317
|
+
},
|
|
1318
|
+
async (span) => {
|
|
1319
|
+
span.end?.({
|
|
1320
|
+
attributes: {
|
|
1321
|
+
...observation,
|
|
1322
|
+
executed: false,
|
|
1323
|
+
...kind ? { observationKind: kind } : {}
|
|
1324
|
+
}
|
|
1325
|
+
});
|
|
1326
|
+
}
|
|
1327
|
+
);
|
|
1328
|
+
}
|
|
1329
|
+
async function useTool(args) {
|
|
1330
|
+
const ctx = getHookContext();
|
|
1331
|
+
const scope = tools.getStore();
|
|
1332
|
+
if (scope?.mode === "model" && !scope.adopted && scope.tool.name === args.tool.name && scope.input === args.input) {
|
|
1333
|
+
scope.adopted = true;
|
|
1334
|
+
scope.classify = args.tool.outcomes ?? scope.classify;
|
|
1335
|
+
scope.telemetry = args.tool.telemetry ?? scope.telemetry;
|
|
1336
|
+
return tools.run(
|
|
1337
|
+
{ ...scope, mode: "direct" },
|
|
1338
|
+
() => args.tool.execute(args.input, {
|
|
1339
|
+
toolCallId: scope.providerToolCallId,
|
|
1340
|
+
...scope.signal ? { abortSignal: scope.signal } : {}
|
|
1341
|
+
})
|
|
1342
|
+
);
|
|
1343
|
+
}
|
|
1344
|
+
const index = ctx.toolCallIndex++;
|
|
1345
|
+
const key = `__useTool:${args.id ?? `auto:${index}`}`;
|
|
1346
|
+
let id = ctx.currentNodeState.byKey[key];
|
|
1347
|
+
if (typeof id !== "string") {
|
|
1348
|
+
id = (0, import_node_crypto32.randomUUID)();
|
|
1349
|
+
ctx.currentNodeState.byKey[key] = id;
|
|
1350
|
+
ctx.stateDirty = true;
|
|
1351
|
+
}
|
|
1352
|
+
try {
|
|
1353
|
+
return await executeObservedTool({
|
|
1354
|
+
tool: args.tool,
|
|
1355
|
+
input: args.input,
|
|
1356
|
+
toolCallId: String(id),
|
|
1357
|
+
callingMode: "direct",
|
|
1358
|
+
abortSignal: (0, import_core22.combineAbortSignals)(ctx.node.abortSignal, args.abortSignal)
|
|
1359
|
+
});
|
|
1360
|
+
} finally {
|
|
1361
|
+
await closeOwnedTools([args.tool]);
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
async function replayToolObservations(observations, child = false) {
|
|
1365
|
+
for (const original of observations) {
|
|
1366
|
+
const source = original.source ?? {
|
|
1367
|
+
...ownershipFrom(original),
|
|
1368
|
+
toolCallId: original.toolCallId,
|
|
1369
|
+
attemptId: original.attemptId
|
|
1370
|
+
};
|
|
1371
|
+
await observeToolFact(
|
|
1372
|
+
{
|
|
1373
|
+
...original,
|
|
1374
|
+
...ownership(),
|
|
1375
|
+
...child ? {
|
|
1376
|
+
workflowId: original.workflowId,
|
|
1377
|
+
nodeId: original.nodeId,
|
|
1378
|
+
workflowRevisionId: original.workflowRevisionId,
|
|
1379
|
+
invocationId: original.invocationId,
|
|
1380
|
+
parentInvocationId: original.parentInvocationId
|
|
1381
|
+
} : {},
|
|
1382
|
+
attemptId: (0, import_node_crypto32.randomUUID)(),
|
|
1383
|
+
executed: false,
|
|
1384
|
+
source,
|
|
1385
|
+
durationMs: void 0
|
|
1386
|
+
},
|
|
1387
|
+
"reused",
|
|
1388
|
+
child
|
|
1389
|
+
);
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
var ownershipFrom = (observation) => ({
|
|
1393
|
+
runId: observation.runId,
|
|
1394
|
+
invocationId: observation.invocationId,
|
|
1395
|
+
branchId: observation.branchId
|
|
1396
|
+
});
|
|
1397
|
+
var import_node_crypto5 = require("crypto");
|
|
1398
|
+
var import_core42 = require("@kortyx/core");
|
|
1399
|
+
var import_node_crypto42 = require("crypto");
|
|
448
1400
|
var import_core32 = require("@kortyx/core");
|
|
449
|
-
var
|
|
450
|
-
var import_core22 = require("@kortyx/core");
|
|
451
|
-
var import_errors22 = require("@kortyx/core/errors");
|
|
1401
|
+
var import_errors42 = require("@kortyx/core/errors");
|
|
452
1402
|
function assertModelFinish(result) {
|
|
453
1403
|
if (result.finishReason?.unified !== "content-filter") return;
|
|
454
1404
|
throw Object.assign(
|
|
455
|
-
new
|
|
1405
|
+
new import_errors42.KortyxError("PROVIDER_REFUSAL", "The provider refused the request.", {
|
|
456
1406
|
category: "provider",
|
|
457
1407
|
retryable: false,
|
|
458
1408
|
safeMessage: "The provider refused the request."
|
|
@@ -466,7 +1416,7 @@ var require_dist = __commonJS({
|
|
|
466
1416
|
var toError = (value) => value instanceof Error ? value : new Error(String(value));
|
|
467
1417
|
var createRuntimeId = () => {
|
|
468
1418
|
try {
|
|
469
|
-
return (0,
|
|
1419
|
+
return (0, import_node_crypto42.randomUUID)();
|
|
470
1420
|
} catch {
|
|
471
1421
|
return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
472
1422
|
}
|
|
@@ -501,8 +1451,8 @@ var require_dist = __commonJS({
|
|
|
501
1451
|
args.model.options?.providerOptions,
|
|
502
1452
|
args.providerOptions
|
|
503
1453
|
);
|
|
504
|
-
const
|
|
505
|
-
(0,
|
|
1454
|
+
const tools2 = args.tools ?? args.model.options?.tools;
|
|
1455
|
+
(0, import_core32.throwIfExecutionAborted)(abortSignal);
|
|
506
1456
|
const model = args.model.provider.getModel(args.model.modelId, {
|
|
507
1457
|
...temperature !== void 0 ? { temperature } : {},
|
|
508
1458
|
streaming: stream,
|
|
@@ -511,10 +1461,10 @@ var require_dist = __commonJS({
|
|
|
511
1461
|
...abortSignal !== void 0 ? { abortSignal } : {},
|
|
512
1462
|
...reasoning !== void 0 ? { reasoning } : {},
|
|
513
1463
|
...responseFormat !== void 0 ? { responseFormat } : {},
|
|
514
|
-
...
|
|
1464
|
+
...tools2 !== void 0 ? { tools: tools2 } : {},
|
|
515
1465
|
...providerOptions !== void 0 ? { providerOptions } : {}
|
|
516
1466
|
});
|
|
517
|
-
if (
|
|
1467
|
+
if (tools2?.length && !model.supportsToolStreaming) stream = false;
|
|
518
1468
|
const messages = args.messages !== void 0 ? args.messages : [
|
|
519
1469
|
...typeof args.system === "string" && args.system.length > 0 ? [{ role: "system", content: args.system }] : [],
|
|
520
1470
|
{ role: "user", content: String(args.input ?? "") }
|
|
@@ -526,7 +1476,7 @@ var require_dist = __commonJS({
|
|
|
526
1476
|
opId,
|
|
527
1477
|
segmentId
|
|
528
1478
|
};
|
|
529
|
-
const traceSpan = args.reasonTrace
|
|
1479
|
+
const traceSpan = safeStartSpan2(args.reasonTrace, {
|
|
530
1480
|
name: "runReasonEngine",
|
|
531
1481
|
attributes: {
|
|
532
1482
|
...commonMeta,
|
|
@@ -606,7 +1556,7 @@ var require_dist = __commonJS({
|
|
|
606
1556
|
}
|
|
607
1557
|
const response2 = await model.stream(messages);
|
|
608
1558
|
for await (const chunk of response2) {
|
|
609
|
-
(0,
|
|
1559
|
+
(0, import_core32.throwIfExecutionAborted)(abortSignal);
|
|
610
1560
|
switch (chunk.type) {
|
|
611
1561
|
case "text-delta": {
|
|
612
1562
|
if (chunk.delta.length === 0) break;
|
|
@@ -672,7 +1622,7 @@ var require_dist = __commonJS({
|
|
|
672
1622
|
}
|
|
673
1623
|
}
|
|
674
1624
|
}
|
|
675
|
-
(0,
|
|
1625
|
+
(0, import_core32.throwIfExecutionAborted)(abortSignal);
|
|
676
1626
|
assertModelFinish({ finishReason, usage });
|
|
677
1627
|
if (emit) {
|
|
678
1628
|
emitNodeEvent(args.emitEvent, args.nodeId, "text-end", {
|
|
@@ -689,12 +1639,12 @@ var require_dist = __commonJS({
|
|
|
689
1639
|
...providerMetadata !== void 0 ? { providerMetadata } : {},
|
|
690
1640
|
...warnings !== void 0 ? { warnings } : {}
|
|
691
1641
|
};
|
|
692
|
-
(0,
|
|
1642
|
+
(0, import_core32.throwIfExecutionAborted)(abortSignal);
|
|
693
1643
|
endTrace(traceSpan, result2);
|
|
694
1644
|
return result2;
|
|
695
1645
|
}
|
|
696
1646
|
const response = await model.invoke(messages);
|
|
697
|
-
(0,
|
|
1647
|
+
(0, import_core32.throwIfExecutionAborted)(abortSignal);
|
|
698
1648
|
assertModelFinish(response);
|
|
699
1649
|
if (response.content) args.onTextChunk?.(response.content);
|
|
700
1650
|
if (emit) {
|
|
@@ -724,26 +1674,26 @@ var require_dist = __commonJS({
|
|
|
724
1674
|
endTrace(traceSpan, result);
|
|
725
1675
|
return result;
|
|
726
1676
|
} catch (error) {
|
|
727
|
-
const failure = abortSignal?.aborted ? (0,
|
|
1677
|
+
const failure = abortSignal?.aborted ? (0, import_core32.createExecutionCancelledError)() : error;
|
|
728
1678
|
failTrace(traceSpan, failure);
|
|
729
1679
|
throw failure;
|
|
730
1680
|
}
|
|
731
1681
|
}
|
|
732
1682
|
var createRuntimeId2 = () => {
|
|
733
1683
|
try {
|
|
734
|
-
return (0,
|
|
1684
|
+
return (0, import_node_crypto5.randomUUID)();
|
|
735
1685
|
} catch {
|
|
736
1686
|
return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
737
1687
|
}
|
|
738
1688
|
};
|
|
739
1689
|
async function reasonEngine(args, meta, inputOverride) {
|
|
740
1690
|
const ctx = getHookContext();
|
|
741
|
-
const abortSignal = (0,
|
|
1691
|
+
const abortSignal = (0, import_core42.combineAbortSignals)(
|
|
742
1692
|
ctx.node.abortSignal,
|
|
743
1693
|
args.abortSignal,
|
|
744
1694
|
args.model.options?.abortSignal
|
|
745
1695
|
);
|
|
746
|
-
(0,
|
|
1696
|
+
(0, import_core42.throwIfExecutionAborted)(abortSignal);
|
|
747
1697
|
ctx.node.consumeExecution?.("maxModelPasses");
|
|
748
1698
|
try {
|
|
749
1699
|
return await runReasonEngine({
|
|
@@ -1485,7 +2435,7 @@ var require_dist = __commonJS({
|
|
|
1485
2435
|
}
|
|
1486
2436
|
};
|
|
1487
2437
|
}
|
|
1488
|
-
var
|
|
2438
|
+
var import_errors52 = require("@kortyx/core/errors");
|
|
1489
2439
|
var tryJsonParse = (value) => {
|
|
1490
2440
|
try {
|
|
1491
2441
|
return { ok: true, value: JSON.parse(value) };
|
|
@@ -1523,12 +2473,12 @@ var require_dist = __commonJS({
|
|
|
1523
2473
|
}
|
|
1524
2474
|
return text;
|
|
1525
2475
|
};
|
|
1526
|
-
var createTruncatedStructuredOutputError = (label, cause) => new
|
|
2476
|
+
var createTruncatedStructuredOutputError = (label, cause) => new import_errors52.ValidationError(
|
|
1527
2477
|
"OUTPUT_TRUNCATED",
|
|
1528
2478
|
`${label} was truncated before producing valid structured output. The model stopped due to output length. Increase maxOutputTokens or simplify the requested output.`,
|
|
1529
2479
|
cause
|
|
1530
2480
|
);
|
|
1531
|
-
var createInvalidStructuredOutputError = (label, cause) => new
|
|
2481
|
+
var createInvalidStructuredOutputError = (label, cause) => new import_errors52.ValidationError(
|
|
1532
2482
|
"INVALID_MODEL_JSON",
|
|
1533
2483
|
`${label} did not produce valid structured output. The model returned text instead of the expected JSON payload. Check outputSchema and provider structured-output settings.`,
|
|
1534
2484
|
cause
|
|
@@ -1540,7 +2490,7 @@ var require_dist = __commonJS({
|
|
|
1540
2490
|
try {
|
|
1541
2491
|
return parseWithSchema(args.schema, candidate, args.label);
|
|
1542
2492
|
} catch (error) {
|
|
1543
|
-
if (!(error instanceof
|
|
2493
|
+
if (!(error instanceof import_errors52.ValidationError)) throw error;
|
|
1544
2494
|
const failure = args.finishReason?.unified === "length" ? createTruncatedStructuredOutputError(args.label, error) : typeof candidate === "string" && !validJson ? createInvalidStructuredOutputError(args.label, error) : error;
|
|
1545
2495
|
if (failure && typeof failure === "object")
|
|
1546
2496
|
Object.assign(failure, {
|
|
@@ -1560,7 +2510,7 @@ var require_dist = __commonJS({
|
|
|
1560
2510
|
if (typeof candidate === "string" && candidate.trim().length > 0) {
|
|
1561
2511
|
throw createInvalidStructuredOutputError("useReason output");
|
|
1562
2512
|
}
|
|
1563
|
-
throw new
|
|
2513
|
+
throw new import_errors52.ValidationError(
|
|
1564
2514
|
"MODEL_OUTPUT_SCHEMA",
|
|
1565
2515
|
"useReason first pass with interrupt must return a JSON object."
|
|
1566
2516
|
);
|
|
@@ -1569,7 +2519,7 @@ var require_dist = __commonJS({
|
|
|
1569
2519
|
let interruptRequired = true;
|
|
1570
2520
|
if (mode === "optional") {
|
|
1571
2521
|
if (candidate.decision !== "continue" && candidate.decision !== "interrupt") {
|
|
1572
|
-
throw new
|
|
2522
|
+
throw new import_errors52.ValidationError(
|
|
1573
2523
|
"MODEL_OUTPUT_SCHEMA",
|
|
1574
2524
|
'useReason optional interrupt first pass must include decision "continue" or "interrupt".'
|
|
1575
2525
|
);
|
|
@@ -1582,7 +2532,7 @@ var require_dist = __commonJS({
|
|
|
1582
2532
|
candidate.interrupt
|
|
1583
2533
|
].some((value) => value !== null && value !== void 0);
|
|
1584
2534
|
if (hasUnexpectedRequest) {
|
|
1585
|
-
throw new
|
|
2535
|
+
throw new import_errors52.ValidationError(
|
|
1586
2536
|
"MODEL_OUTPUT_SCHEMA",
|
|
1587
2537
|
'useReason optional interrupt first pass with decision "continue" must not include an interrupt request.'
|
|
1588
2538
|
);
|
|
@@ -1616,7 +2566,7 @@ var require_dist = __commonJS({
|
|
|
1616
2566
|
"useReason output"
|
|
1617
2567
|
);
|
|
1618
2568
|
} catch (error) {
|
|
1619
|
-
if (!(error instanceof
|
|
2569
|
+
if (!(error instanceof import_errors52.ValidationError)) throw error;
|
|
1620
2570
|
if (args.finishReason?.unified === "length") {
|
|
1621
2571
|
throw createTruncatedStructuredOutputError("useReason output", error);
|
|
1622
2572
|
}
|
|
@@ -1625,7 +2575,7 @@ var require_dist = __commonJS({
|
|
|
1625
2575
|
}
|
|
1626
2576
|
const explicitDraft = typeof candidate.draftText === "string" && candidate.draftText.length > 0 ? candidate.draftText : typeof candidate.text === "string" && candidate.text.length > 0 ? candidate.text : void 0;
|
|
1627
2577
|
if (!args.outputSchema && !explicitDraft) {
|
|
1628
|
-
throw new
|
|
2578
|
+
throw new import_errors52.ValidationError(
|
|
1629
2579
|
"MODEL_OUTPUT_SCHEMA",
|
|
1630
2580
|
"useReason first pass with interrupt requires `draftText` when outputSchema is not provided."
|
|
1631
2581
|
);
|
|
@@ -1811,6 +2761,7 @@ ${tryStringify2(args.response)}`
|
|
|
1811
2761
|
const reasoning = sum(left.reasoning, right.reasoning);
|
|
1812
2762
|
const cacheRead = sum(left.cacheRead, right.cacheRead);
|
|
1813
2763
|
const cacheWrite = sum(left.cacheWrite, right.cacheWrite);
|
|
2764
|
+
const cacheWrite1h = sum(left.cacheWrite1h, right.cacheWrite1h);
|
|
1814
2765
|
const merged = {
|
|
1815
2766
|
...right.outputIncludesReasoning !== void 0 ? { outputIncludesReasoning: right.outputIncludesReasoning } : {},
|
|
1816
2767
|
...right.inputIncludesCacheWrite !== void 0 ? { inputIncludesCacheWrite: right.inputIncludesCacheWrite } : {},
|
|
@@ -1822,6 +2773,7 @@ ${tryStringify2(args.response)}`
|
|
|
1822
2773
|
if (reasoning !== void 0) merged.reasoning = reasoning;
|
|
1823
2774
|
if (cacheRead !== void 0) merged.cacheRead = cacheRead;
|
|
1824
2775
|
if (cacheWrite !== void 0) merged.cacheWrite = cacheWrite;
|
|
2776
|
+
if (cacheWrite1h !== void 0) merged.cacheWrite1h = cacheWrite1h;
|
|
1825
2777
|
if (raw) merged.raw = raw;
|
|
1826
2778
|
return merged;
|
|
1827
2779
|
};
|
|
@@ -1858,9 +2810,9 @@ ${tryStringify2(args.response)}`
|
|
|
1858
2810
|
streamId: args.opId
|
|
1859
2811
|
});
|
|
1860
2812
|
};
|
|
1861
|
-
var
|
|
1862
|
-
var
|
|
1863
|
-
var toToolDefinitions = (
|
|
2813
|
+
var import_core52 = require("@kortyx/core");
|
|
2814
|
+
var import_errors62 = require("@kortyx/core/errors");
|
|
2815
|
+
var toToolDefinitions = (tools2) => tools2.map((tool) => ({
|
|
1864
2816
|
name: tool.name,
|
|
1865
2817
|
...tool.title ? { title: tool.title } : {},
|
|
1866
2818
|
...tool.description ? { description: tool.description } : {},
|
|
@@ -1877,12 +2829,13 @@ ${tryStringify2(args.response)}`
|
|
|
1877
2829
|
return fallback;
|
|
1878
2830
|
};
|
|
1879
2831
|
var normalizeToolResult = (toolCall, value) => {
|
|
1880
|
-
if (value && typeof value === "object" && !Array.isArray(value) && "toolCallId" in value && "name" in value && "content" in value) {
|
|
1881
|
-
|
|
2832
|
+
if (value && typeof value === "object" && !Array.isArray(value) && "toolCallId" in value && "name" in value && "content" in value && typeof value.content === "string") {
|
|
2833
|
+
const result = value;
|
|
2834
|
+
return { ...result, toolCallId: toolCall.id, name: toolCall.name };
|
|
1882
2835
|
}
|
|
1883
2836
|
let content;
|
|
1884
2837
|
try {
|
|
1885
|
-
content = typeof value === "string" ? value : JSON.stringify(value);
|
|
2838
|
+
content = typeof value === "string" ? value : JSON.stringify(value) ?? String(value);
|
|
1886
2839
|
} catch {
|
|
1887
2840
|
content = String(value);
|
|
1888
2841
|
}
|
|
@@ -1893,28 +2846,6 @@ ${tryStringify2(args.response)}`
|
|
|
1893
2846
|
...value !== void 0 && value !== null && typeof value === "object" && !Array.isArray(value) ? { structuredContent: value } : {}
|
|
1894
2847
|
};
|
|
1895
2848
|
};
|
|
1896
|
-
var closeOwnedTools = async (tools, preserveFailure = false, traceSpan) => {
|
|
1897
|
-
const closeFns = /* @__PURE__ */ new Set();
|
|
1898
|
-
for (const tool of tools) {
|
|
1899
|
-
if (tool.closeAfterUse === false || !tool.close) continue;
|
|
1900
|
-
closeFns.add(tool.close);
|
|
1901
|
-
}
|
|
1902
|
-
try {
|
|
1903
|
-
await Promise.all(
|
|
1904
|
-
[...closeFns].map(async (close) => {
|
|
1905
|
-
await close();
|
|
1906
|
-
})
|
|
1907
|
-
);
|
|
1908
|
-
} catch (error) {
|
|
1909
|
-
if (!preserveFailure) throw error;
|
|
1910
|
-
try {
|
|
1911
|
-
traceSpan?.addEvent?.("useReason.cleanup.failed", {
|
|
1912
|
-
failure: (0, import_errors42.serializeFailure)(error)
|
|
1913
|
-
});
|
|
1914
|
-
} catch {
|
|
1915
|
-
}
|
|
1916
|
-
}
|
|
1917
|
-
};
|
|
1918
2849
|
var createInitialMessages = (args) => [
|
|
1919
2850
|
...typeof args.system === "string" && args.system.length > 0 ? [{ role: "system", content: args.system }] : [],
|
|
1920
2851
|
{ role: "user", content: String(args.input ?? "") }
|
|
@@ -1922,7 +2853,7 @@ ${tryStringify2(args.response)}`
|
|
|
1922
2853
|
var runReasonToolLoop = async (args) => {
|
|
1923
2854
|
const { useReasonArgs, id, traceSpan, checkpointKey } = args;
|
|
1924
2855
|
const ctx = getHookContext();
|
|
1925
|
-
const abortSignal = (0,
|
|
2856
|
+
const abortSignal = (0, import_core52.combineAbortSignals)(
|
|
1926
2857
|
ctx.node.abortSignal,
|
|
1927
2858
|
useReasonArgs.abortSignal,
|
|
1928
2859
|
useReasonArgs.model.options?.abortSignal
|
|
@@ -1930,43 +2861,32 @@ ${tryStringify2(args.response)}`
|
|
|
1930
2861
|
const saved = ctx.currentNodeState.byKey[checkpointKey];
|
|
1931
2862
|
const checkpoint = saved?.status === "tool_loop" ? saved : void 0;
|
|
1932
2863
|
const opId = checkpoint?.opId ?? args.opId;
|
|
1933
|
-
|
|
1934
|
-
const tools = useReasonArgs.tools ?? [];
|
|
2864
|
+
const tools2 = useReasonArgs.tools ?? [];
|
|
1935
2865
|
const toolByName = /* @__PURE__ */ new Map();
|
|
1936
|
-
let validationCompleted = false;
|
|
1937
2866
|
let separateOutput = false;
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
throw new Error(
|
|
1942
|
-
`useReason received duplicate tool name "${tool.name}".`
|
|
1943
|
-
);
|
|
1944
|
-
}
|
|
1945
|
-
toolByName.set(tool.name, tool);
|
|
2867
|
+
for (const tool of tools2) {
|
|
2868
|
+
if (toolByName.has(tool.name)) {
|
|
2869
|
+
throw new Error(`useReason received duplicate tool name "${tool.name}".`);
|
|
1946
2870
|
}
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
separateOutput = Boolean(
|
|
1953
|
-
useReasonArgs.model.provider.getModel(useReasonArgs.model.modelId, {
|
|
1954
|
-
...useReasonArgs.model.options,
|
|
1955
|
-
...useReasonArgs.reasoning !== void 0 ? { reasoning: useReasonArgs.reasoning } : {},
|
|
1956
|
-
...useReasonArgs.responseFormat ? { responseFormat: useReasonArgs.responseFormat } : {},
|
|
1957
|
-
providerOptions: resolveProviderOptions(
|
|
1958
|
-
useReasonArgs.model.options?.providerOptions,
|
|
1959
|
-
useReasonArgs.providerOptions
|
|
1960
|
-
) ?? {}
|
|
1961
|
-
}).requiresSeparateStructuredOutput
|
|
2871
|
+
toolByName.set(tool.name, tool);
|
|
2872
|
+
}
|
|
2873
|
+
if (useReasonArgs.interrupt) {
|
|
2874
|
+
throw new Error(
|
|
2875
|
+
"useReason tools cannot be combined with useReason interrupt mode yet. Use toolExecution.approval for tool approval."
|
|
1962
2876
|
);
|
|
1963
|
-
validationCompleted = true;
|
|
1964
|
-
} finally {
|
|
1965
|
-
if (!validationCompleted) {
|
|
1966
|
-
await closeOwnedTools(tools, true, traceSpan);
|
|
1967
|
-
}
|
|
1968
2877
|
}
|
|
1969
|
-
|
|
2878
|
+
separateOutput = Boolean(
|
|
2879
|
+
useReasonArgs.model.provider.getModel(useReasonArgs.model.modelId, {
|
|
2880
|
+
...useReasonArgs.model.options,
|
|
2881
|
+
...useReasonArgs.reasoning !== void 0 ? { reasoning: useReasonArgs.reasoning } : {},
|
|
2882
|
+
...useReasonArgs.responseFormat ? { responseFormat: useReasonArgs.responseFormat } : {},
|
|
2883
|
+
providerOptions: resolveProviderOptions(
|
|
2884
|
+
useReasonArgs.model.options?.providerOptions,
|
|
2885
|
+
useReasonArgs.providerOptions
|
|
2886
|
+
) ?? {}
|
|
2887
|
+
}).requiresSeparateStructuredOutput
|
|
2888
|
+
);
|
|
2889
|
+
const toolDefinitions = toToolDefinitions(tools2);
|
|
1970
2890
|
let finalizing = checkpoint?.finalizing ?? false;
|
|
1971
2891
|
let completed = false;
|
|
1972
2892
|
const maxSteps = Math.max(1, useReasonArgs.toolExecution?.maxSteps ?? 3);
|
|
@@ -2018,7 +2938,7 @@ ${tryStringify2(args.response)}`
|
|
|
2018
2938
|
};
|
|
2019
2939
|
try {
|
|
2020
2940
|
for (let stepIndex = pending ? steps.length - 1 : steps.length; stepIndex < maxSteps; stepIndex += 1) {
|
|
2021
|
-
(0,
|
|
2941
|
+
(0, import_core52.throwIfExecutionAborted)(abortSignal);
|
|
2022
2942
|
traceSpan?.addEvent?.("useReason.tool-step.start", {
|
|
2023
2943
|
stepIndex,
|
|
2024
2944
|
toolCount: toolDefinitions.length
|
|
@@ -2062,6 +2982,12 @@ ${tryStringify2(args.response)}`
|
|
|
2062
2982
|
);
|
|
2063
2983
|
aggregatedWarnings = mergeWarnings(aggregatedWarnings, step.warnings);
|
|
2064
2984
|
const toolCalls = step.toolCalls ?? [];
|
|
2985
|
+
const ids = /* @__PURE__ */ new Set();
|
|
2986
|
+
for (const call of toolCalls) {
|
|
2987
|
+
if (!call.id || ids.has(call.id) || !reused && allToolCalls.some((prior) => prior.id === call.id))
|
|
2988
|
+
throw new Error("Model returned duplicate or empty tool call IDs.");
|
|
2989
|
+
ids.add(call.id);
|
|
2990
|
+
}
|
|
2065
2991
|
const toolResults = reused ? steps[stepIndex]?.toolResults ?? [] : [];
|
|
2066
2992
|
if (!reused)
|
|
2067
2993
|
steps.push({
|
|
@@ -2130,9 +3056,15 @@ ${tryStringify2(args.response)}`
|
|
|
2130
3056
|
pending = step;
|
|
2131
3057
|
save();
|
|
2132
3058
|
for (const toolCall of toolCalls) {
|
|
2133
|
-
if (toolResults.some((result2) => result2.toolCallId === toolCall.id))
|
|
3059
|
+
if (toolResults.some((result2) => result2.toolCallId === toolCall.id)) {
|
|
3060
|
+
await replayToolObservations(
|
|
3061
|
+
steps[stepIndex]?.toolObservations?.filter(
|
|
3062
|
+
(observation) => observation.toolCallId === `${opId}:${toolCall.id}`
|
|
3063
|
+
) ?? []
|
|
3064
|
+
);
|
|
2134
3065
|
continue;
|
|
2135
|
-
|
|
3066
|
+
}
|
|
3067
|
+
(0, import_core52.throwIfExecutionAborted)(abortSignal);
|
|
2136
3068
|
const tool = toolByName.get(toolCall.name);
|
|
2137
3069
|
if (!tool) {
|
|
2138
3070
|
throw new Error(
|
|
@@ -2149,11 +3081,6 @@ ${tryStringify2(args.response)}`
|
|
|
2149
3081
|
tool.name,
|
|
2150
3082
|
false
|
|
2151
3083
|
);
|
|
2152
|
-
traceSpan?.addEvent?.("useReason.tool-call.start", {
|
|
2153
|
-
stepIndex,
|
|
2154
|
-
tool: tool.name,
|
|
2155
|
-
toolCallId: toolCall.id
|
|
2156
|
-
});
|
|
2157
3084
|
if (shouldEmitTool) {
|
|
2158
3085
|
emitToolEvent("tool-call-start", {
|
|
2159
3086
|
tool: tool.name,
|
|
@@ -2162,6 +3089,17 @@ ${tryStringify2(args.response)}`
|
|
|
2162
3089
|
});
|
|
2163
3090
|
}
|
|
2164
3091
|
if (shouldApproveTool && !approvedCalls.includes(toolCall.id)) {
|
|
3092
|
+
await observeToolFact(
|
|
3093
|
+
{
|
|
3094
|
+
version: 1,
|
|
3095
|
+
name: tool.name,
|
|
3096
|
+
toolCallId: `${opId}:${toolCall.id}`,
|
|
3097
|
+
attemptId: `${opId}:${toolCall.id}:approval`,
|
|
3098
|
+
callingMode: "model",
|
|
3099
|
+
executed: false
|
|
3100
|
+
},
|
|
3101
|
+
"waiting"
|
|
3102
|
+
);
|
|
2165
3103
|
const approval = await awaitInterruptInternal({
|
|
2166
3104
|
id: `tool:${toolCall.id}`,
|
|
2167
3105
|
request: {
|
|
@@ -2180,6 +3118,22 @@ ${tryStringify2(args.response)}`
|
|
|
2180
3118
|
});
|
|
2181
3119
|
const approved = Array.isArray(approval) ? approval.includes("approve") : approval === "approve";
|
|
2182
3120
|
if (!approved) {
|
|
3121
|
+
const deniedObservation = {
|
|
3122
|
+
version: 1,
|
|
3123
|
+
name: tool.name,
|
|
3124
|
+
toolCallId: `${opId}:${toolCall.id}`,
|
|
3125
|
+
attemptId: `${opId}:${toolCall.id}:approval`,
|
|
3126
|
+
callingMode: "model",
|
|
3127
|
+
executed: false,
|
|
3128
|
+
outcome: "denied",
|
|
3129
|
+
denialCode: "APPROVAL_DENIED"
|
|
3130
|
+
};
|
|
3131
|
+
await observeToolFact(deniedObservation);
|
|
3132
|
+
const entry = steps[stepIndex];
|
|
3133
|
+
if (entry) {
|
|
3134
|
+
entry.toolObservations ??= [];
|
|
3135
|
+
entry.toolObservations.push(deniedObservation);
|
|
3136
|
+
}
|
|
2183
3137
|
const denied = {
|
|
2184
3138
|
toolCallId: toolCall.id,
|
|
2185
3139
|
name: tool.name,
|
|
@@ -2210,13 +3164,24 @@ ${tryStringify2(args.response)}`
|
|
|
2210
3164
|
save();
|
|
2211
3165
|
}
|
|
2212
3166
|
try {
|
|
2213
|
-
(0,
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
3167
|
+
(0, import_core52.throwIfExecutionAborted)(abortSignal);
|
|
3168
|
+
const rawResult = await executeObservedTool({
|
|
3169
|
+
tool,
|
|
3170
|
+
input: toolCall.input,
|
|
3171
|
+
toolCallId: `${opId}:${toolCall.id}`,
|
|
3172
|
+
providerToolCallId: toolCall.id,
|
|
3173
|
+
callingMode: "model",
|
|
3174
|
+
abortSignal,
|
|
3175
|
+
onObservation: (observation) => {
|
|
3176
|
+
const entry = steps[stepIndex];
|
|
3177
|
+
if (entry) {
|
|
3178
|
+
entry.toolObservations ??= [];
|
|
3179
|
+
entry.toolObservations.push(observation);
|
|
3180
|
+
save();
|
|
3181
|
+
}
|
|
3182
|
+
}
|
|
2218
3183
|
});
|
|
2219
|
-
(0,
|
|
3184
|
+
(0, import_core52.throwIfExecutionAborted)(abortSignal);
|
|
2220
3185
|
const result2 = normalizeToolResult(toolCall, rawResult);
|
|
2221
3186
|
toolResults.push(result2);
|
|
2222
3187
|
allToolResults.push(result2);
|
|
@@ -2229,20 +3194,14 @@ ${tryStringify2(args.response)}`
|
|
|
2229
3194
|
...result2.isError !== void 0 ? { isError: result2.isError } : {}
|
|
2230
3195
|
});
|
|
2231
3196
|
}
|
|
2232
|
-
traceSpan?.addEvent?.("useReason.tool-call.complete", {
|
|
2233
|
-
stepIndex,
|
|
2234
|
-
tool: result2.name,
|
|
2235
|
-
toolCallId: result2.toolCallId,
|
|
2236
|
-
isError: Boolean(result2.isError)
|
|
2237
|
-
});
|
|
2238
3197
|
} catch (error) {
|
|
2239
|
-
(0,
|
|
2240
|
-
if ((0,
|
|
3198
|
+
(0, import_core52.throwIfExecutionAborted)(abortSignal);
|
|
3199
|
+
if ((0, import_errors62.isControlFlowError)(error)) throw error;
|
|
2241
3200
|
const result2 = {
|
|
2242
3201
|
toolCallId: toolCall.id,
|
|
2243
3202
|
name: tool.name,
|
|
2244
|
-
content: (0,
|
|
2245
|
-
failure: (0,
|
|
3203
|
+
content: (0, import_errors62.serializeFailure)(error).message,
|
|
3204
|
+
failure: (0, import_errors62.serializeFailure)(error),
|
|
2246
3205
|
isError: true
|
|
2247
3206
|
};
|
|
2248
3207
|
toolResults.push(result2);
|
|
@@ -2255,13 +3214,6 @@ ${tryStringify2(args.response)}`
|
|
|
2255
3214
|
failure: result2.failure
|
|
2256
3215
|
});
|
|
2257
3216
|
}
|
|
2258
|
-
traceSpan?.addEvent?.("useReason.tool-call.error", {
|
|
2259
|
-
stepIndex,
|
|
2260
|
-
tool: tool.name,
|
|
2261
|
-
toolCallId: toolCall.id,
|
|
2262
|
-
message: result2.content,
|
|
2263
|
-
failure: result2.failure
|
|
2264
|
-
});
|
|
2265
3217
|
}
|
|
2266
3218
|
const completed2 = toolResults.at(-1);
|
|
2267
3219
|
if (completed2)
|
|
@@ -2334,7 +3286,6 @@ ${tryStringify2(args.response)}`
|
|
|
2334
3286
|
ctx.stateDirty = true;
|
|
2335
3287
|
return result;
|
|
2336
3288
|
} catch (error) {
|
|
2337
|
-
primaryFailure = true;
|
|
2338
3289
|
try {
|
|
2339
3290
|
traceSpan?.fail?.(error, {
|
|
2340
3291
|
attributes: {
|
|
@@ -2345,8 +3296,6 @@ ${tryStringify2(args.response)}`
|
|
|
2345
3296
|
} catch {
|
|
2346
3297
|
}
|
|
2347
3298
|
throw error;
|
|
2348
|
-
} finally {
|
|
2349
|
-
await closeOwnedTools(tools, primaryFailure, traceSpan);
|
|
2350
3299
|
}
|
|
2351
3300
|
};
|
|
2352
3301
|
var shouldStreamReasonStructured = (args) => (args.emit ?? true) && shouldStreamStructured(args.structured);
|
|
@@ -2360,15 +3309,15 @@ ${tryStringify2(args.response)}`
|
|
|
2360
3309
|
"useReason does not support reasoning.includeThoughts with structured output, interrupt mode, or JSON responseFormat. Disable includeThoughts for this call."
|
|
2361
3310
|
);
|
|
2362
3311
|
};
|
|
2363
|
-
async function
|
|
3312
|
+
async function runReason(args) {
|
|
2364
3313
|
assertReasoningThoughtsCompatibility(args);
|
|
2365
3314
|
const ctx = getHookContext();
|
|
2366
|
-
const abortSignal = (0,
|
|
3315
|
+
const abortSignal = (0, import_core62.combineAbortSignals)(
|
|
2367
3316
|
ctx.node.abortSignal,
|
|
2368
3317
|
args.abortSignal,
|
|
2369
3318
|
args.model.options?.abortSignal
|
|
2370
3319
|
);
|
|
2371
|
-
(0,
|
|
3320
|
+
(0, import_core62.throwIfExecutionAborted)(abortSignal);
|
|
2372
3321
|
const allowValidatedToolOutput = Boolean(
|
|
2373
3322
|
args.outputSchema && !(args.responseFormat ?? args.model.options?.responseFormat)
|
|
2374
3323
|
);
|
|
@@ -2391,286 +3340,303 @@ ${tryStringify2(args.response)}`
|
|
|
2391
3340
|
ctx.currentNodeState.byKey[checkpointKey]
|
|
2392
3341
|
);
|
|
2393
3342
|
if (existingCompleted) {
|
|
3343
|
+
await replayToolObservations(
|
|
3344
|
+
existingCompleted.result.steps?.flatMap(
|
|
3345
|
+
(step) => step.toolObservations ?? []
|
|
3346
|
+
) ?? []
|
|
3347
|
+
);
|
|
2394
3348
|
return existingCompleted.result;
|
|
2395
3349
|
}
|
|
2396
3350
|
const existingCheckpoint = readReasonCheckpoint(
|
|
2397
3351
|
ctx.currentNodeState.byKey[checkpointKey]
|
|
2398
3352
|
);
|
|
2399
3353
|
const reasonMeta = typeof id === "string" ? { id, opId } : { opId };
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
...args.telemetry ?? {},
|
|
2421
|
-
input: args.telemetry?.input ?? args.input
|
|
2422
|
-
}
|
|
2423
|
-
});
|
|
2424
|
-
if (args.tools?.length) {
|
|
2425
|
-
return runReasonToolLoop({
|
|
2426
|
-
useReasonArgs: args,
|
|
2427
|
-
allowValidatedToolOutput,
|
|
2428
|
-
checkpointKey,
|
|
2429
|
-
initialWarnings: inferred.warnings,
|
|
2430
|
-
...id ? { id } : {},
|
|
2431
|
-
opId,
|
|
2432
|
-
...traceSpan ? { traceSpan } : {}
|
|
2433
|
-
});
|
|
2434
|
-
}
|
|
2435
|
-
const suppressTextStream = Boolean(args.outputSchema || args.interrupt);
|
|
2436
|
-
const setFieldPaths = resolveSetFieldPaths(args.structured);
|
|
2437
|
-
const appendFieldPaths = resolveAppendFieldPaths(args.structured);
|
|
2438
|
-
const textDeltaFieldPaths = resolveTextDeltaFieldPaths(args.structured);
|
|
2439
|
-
const useStructuredIncrementalStreaming = Boolean(
|
|
2440
|
-
args.outputSchema && !args.interrupt && (setFieldPaths.length > 0 || appendFieldPaths.length > 0 || textDeltaFieldPaths.length > 0) && args.stream !== false && shouldStreamReasonStructured(args)
|
|
2441
|
-
);
|
|
2442
|
-
let firstText = "";
|
|
2443
|
-
let firstRaw;
|
|
2444
|
-
let firstOutput;
|
|
2445
|
-
let firstInterruptRequest;
|
|
2446
|
-
let firstInterruptRequired = false;
|
|
2447
|
-
let finalText = "";
|
|
2448
|
-
let finalRaw;
|
|
2449
|
-
let finalOutput;
|
|
2450
|
-
let aggregatedUsage;
|
|
2451
|
-
let finalFinishReason;
|
|
2452
|
-
let aggregatedProviderMetadata;
|
|
2453
|
-
let aggregatedWarnings = inferred.warnings;
|
|
2454
|
-
if (existingCheckpoint) {
|
|
2455
|
-
firstText = existingCheckpoint.firstText;
|
|
2456
|
-
firstRaw = existingCheckpoint.firstRaw;
|
|
2457
|
-
firstOutput = existingCheckpoint.firstOutput;
|
|
2458
|
-
finalText = firstText;
|
|
2459
|
-
finalRaw = firstRaw;
|
|
2460
|
-
finalOutput = firstOutput;
|
|
2461
|
-
aggregatedUsage = existingCheckpoint.firstUsage;
|
|
2462
|
-
finalFinishReason = existingCheckpoint.firstFinishReason;
|
|
2463
|
-
aggregatedProviderMetadata = existingCheckpoint.firstProviderMetadata;
|
|
2464
|
-
aggregatedWarnings = existingCheckpoint.firstWarnings;
|
|
2465
|
-
traceSpan?.addEvent?.("useReason.resume", {
|
|
2466
|
-
checkpointKey
|
|
2467
|
-
});
|
|
2468
|
-
} else {
|
|
2469
|
-
const first = await reasonEngine(
|
|
2470
|
-
{
|
|
2471
|
-
...args,
|
|
2472
|
-
emit: suppressTextStream ? false : args.emit,
|
|
2473
|
-
stream: useStructuredIncrementalStreaming ? true : suppressTextStream ? false : args.stream,
|
|
2474
|
-
...useStructuredIncrementalStreaming ? {
|
|
2475
|
-
onTextChunk: createStructuredOutputStreamer(args, id, opId)
|
|
2476
|
-
} : {}
|
|
3354
|
+
return withSafeTraceSpan2(
|
|
3355
|
+
getReasonTraceAdapter(),
|
|
3356
|
+
{
|
|
3357
|
+
name: "useReason",
|
|
3358
|
+
attributes: {
|
|
3359
|
+
...id ? { id } : {},
|
|
3360
|
+
opId,
|
|
3361
|
+
nodeId: ctx.node.graph.node,
|
|
3362
|
+
providerId: args.model.provider.id,
|
|
3363
|
+
modelId: args.model.modelId,
|
|
3364
|
+
stream: args.stream ?? args.model.options?.streaming ?? true,
|
|
3365
|
+
emit: args.emit ?? true,
|
|
3366
|
+
...args.telemetry?.operation ? { operation: args.telemetry.operation } : {},
|
|
3367
|
+
...args.telemetry?.prompt?.name ? { promptName: args.telemetry.prompt.name } : {},
|
|
3368
|
+
...args.telemetry?.prompt?.version !== void 0 ? { promptVersion: args.telemetry.prompt.version } : {},
|
|
3369
|
+
...args.telemetry?.prompt?.type ? { promptType: args.telemetry.prompt.type } : {},
|
|
3370
|
+
hasOutputSchema: Boolean(args.outputSchema),
|
|
3371
|
+
hasInterrupt: Boolean(args.interrupt),
|
|
3372
|
+
hasStructured: Boolean(args.structured),
|
|
3373
|
+
hasTools: Boolean(args.tools?.length)
|
|
2477
3374
|
},
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
input: args.input
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
firstRaw = first.raw;
|
|
2494
|
-
finalRaw = first.raw;
|
|
2495
|
-
accumulateTokenUsage(first.usage);
|
|
2496
|
-
aggregatedUsage = mergeUsage(aggregatedUsage, first.usage);
|
|
2497
|
-
finalFinishReason = first.finishReason;
|
|
2498
|
-
aggregatedProviderMetadata = mergeProviderMetadata(
|
|
2499
|
-
aggregatedProviderMetadata,
|
|
2500
|
-
first.providerMetadata
|
|
2501
|
-
);
|
|
2502
|
-
aggregatedWarnings = mergeWarnings(aggregatedWarnings, first.warnings);
|
|
2503
|
-
traceSpan?.addEvent?.("useReason.first-pass.complete", {
|
|
2504
|
-
textLength: first.text.length,
|
|
2505
|
-
hasInterrupt: Boolean(args.interrupt)
|
|
2506
|
-
});
|
|
2507
|
-
if (args.interrupt) {
|
|
2508
|
-
const firstPass = parseInterruptFirstPassResult({
|
|
2509
|
-
text: first.text,
|
|
2510
|
-
requestSchema: args.interrupt.requestSchema,
|
|
2511
|
-
...first.finishReason ? { finishReason: first.finishReason } : {},
|
|
2512
|
-
...first.usage ? { usage: first.usage } : {},
|
|
2513
|
-
...args.outputSchema ? { outputSchema: args.outputSchema } : {},
|
|
2514
|
-
mode: args.interrupt.mode ?? "required"
|
|
2515
|
-
});
|
|
2516
|
-
firstText = firstPass.draftText;
|
|
2517
|
-
finalText = firstPass.draftText;
|
|
2518
|
-
firstInterruptRequired = firstPass.interruptRequired;
|
|
2519
|
-
firstInterruptRequest = firstPass.request;
|
|
2520
|
-
firstOutput = firstPass.output;
|
|
2521
|
-
finalOutput = firstPass.output;
|
|
2522
|
-
} else {
|
|
2523
|
-
firstText = first.text;
|
|
2524
|
-
finalText = first.text;
|
|
2525
|
-
if (args.outputSchema) {
|
|
2526
|
-
firstOutput = parseReasonOutputWithSchema({
|
|
2527
|
-
text: first.text,
|
|
2528
|
-
schema: args.outputSchema,
|
|
2529
|
-
...first.finishReason ? { finishReason: first.finishReason } : {},
|
|
2530
|
-
...first.usage ? { usage: first.usage } : {},
|
|
2531
|
-
label: "useReason output"
|
|
3375
|
+
telemetry: {
|
|
3376
|
+
...args.telemetry ?? {},
|
|
3377
|
+
input: args.telemetry?.input ?? args.input
|
|
3378
|
+
}
|
|
3379
|
+
},
|
|
3380
|
+
async (traceSpan) => {
|
|
3381
|
+
if (args.tools?.length) {
|
|
3382
|
+
return runReasonToolLoop({
|
|
3383
|
+
useReasonArgs: args,
|
|
3384
|
+
allowValidatedToolOutput,
|
|
3385
|
+
checkpointKey,
|
|
3386
|
+
initialWarnings: inferred.warnings,
|
|
3387
|
+
...id ? { id } : {},
|
|
3388
|
+
opId,
|
|
3389
|
+
...traceSpan ? { traceSpan } : {}
|
|
2532
3390
|
});
|
|
2533
3391
|
}
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
const interruptRequest = existingCheckpoint ? parseWithSchema(
|
|
2541
|
-
requestSchema,
|
|
2542
|
-
existingCheckpoint.request,
|
|
2543
|
-
"useReason interrupt.request"
|
|
2544
|
-
) : firstInterruptRequest;
|
|
2545
|
-
if (!interruptRequest) {
|
|
2546
|
-
throw new Error(
|
|
2547
|
-
"useReason interrupt request is missing; first pass did not produce a valid interrupt payload."
|
|
3392
|
+
const suppressTextStream = Boolean(args.outputSchema || args.interrupt);
|
|
3393
|
+
const setFieldPaths = resolveSetFieldPaths(args.structured);
|
|
3394
|
+
const appendFieldPaths = resolveAppendFieldPaths(args.structured);
|
|
3395
|
+
const textDeltaFieldPaths = resolveTextDeltaFieldPaths(args.structured);
|
|
3396
|
+
const useStructuredIncrementalStreaming = Boolean(
|
|
3397
|
+
args.outputSchema && !args.interrupt && (setFieldPaths.length > 0 || appendFieldPaths.length > 0 || textDeltaFieldPaths.length > 0) && args.stream !== false && shouldStreamReasonStructured(args)
|
|
2548
3398
|
);
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
3399
|
+
let firstText = "";
|
|
3400
|
+
let firstRaw;
|
|
3401
|
+
let firstOutput;
|
|
3402
|
+
let firstInterruptRequest;
|
|
3403
|
+
let firstInterruptRequired = false;
|
|
3404
|
+
let finalText = "";
|
|
3405
|
+
let finalRaw;
|
|
3406
|
+
let finalOutput;
|
|
3407
|
+
let aggregatedUsage;
|
|
3408
|
+
let finalFinishReason;
|
|
3409
|
+
let aggregatedProviderMetadata;
|
|
3410
|
+
let aggregatedWarnings = inferred.warnings;
|
|
3411
|
+
if (existingCheckpoint) {
|
|
3412
|
+
firstText = existingCheckpoint.firstText;
|
|
3413
|
+
firstRaw = existingCheckpoint.firstRaw;
|
|
3414
|
+
firstOutput = existingCheckpoint.firstOutput;
|
|
3415
|
+
finalText = firstText;
|
|
3416
|
+
finalRaw = firstRaw;
|
|
3417
|
+
finalOutput = firstOutput;
|
|
3418
|
+
aggregatedUsage = existingCheckpoint.firstUsage;
|
|
3419
|
+
finalFinishReason = existingCheckpoint.firstFinishReason;
|
|
3420
|
+
aggregatedProviderMetadata = existingCheckpoint.firstProviderMetadata;
|
|
3421
|
+
aggregatedWarnings = existingCheckpoint.firstWarnings;
|
|
3422
|
+
traceSpan?.addEvent?.("useReason.resume", {
|
|
3423
|
+
checkpointKey
|
|
3424
|
+
});
|
|
3425
|
+
} else {
|
|
3426
|
+
const first = await reasonEngine(
|
|
3427
|
+
{
|
|
3428
|
+
...args,
|
|
3429
|
+
emit: suppressTextStream ? false : args.emit,
|
|
3430
|
+
stream: useStructuredIncrementalStreaming ? true : suppressTextStream ? false : args.stream,
|
|
3431
|
+
...useStructuredIncrementalStreaming ? {
|
|
3432
|
+
onTextChunk: createStructuredOutputStreamer(args, id, opId)
|
|
3433
|
+
} : {}
|
|
3434
|
+
},
|
|
3435
|
+
reasonMeta,
|
|
3436
|
+
args.interrupt ? defaultInterruptFirstPassInput({
|
|
3437
|
+
input: args.input,
|
|
3438
|
+
requestSchema: args.interrupt.requestSchema,
|
|
3439
|
+
mode: args.interrupt.mode ?? "required",
|
|
3440
|
+
...args.outputSchema ? { outputSchema: args.outputSchema } : {}
|
|
3441
|
+
}) : args.outputSchema ? withOutputGuardrails(
|
|
3442
|
+
withStructuredStreamHints(args.input, {
|
|
3443
|
+
...setFieldPaths.length > 0 ? { setFieldPaths } : {},
|
|
3444
|
+
...appendFieldPaths.length > 0 ? { appendFieldPaths } : {},
|
|
3445
|
+
...textDeltaFieldPaths.length > 0 ? { textDeltaFieldPaths } : {}
|
|
3446
|
+
}),
|
|
3447
|
+
args.outputSchema
|
|
3448
|
+
) : void 0
|
|
3449
|
+
);
|
|
3450
|
+
firstRaw = first.raw;
|
|
3451
|
+
finalRaw = first.raw;
|
|
3452
|
+
accumulateTokenUsage(first.usage);
|
|
3453
|
+
aggregatedUsage = mergeUsage(aggregatedUsage, first.usage);
|
|
3454
|
+
finalFinishReason = first.finishReason;
|
|
3455
|
+
aggregatedProviderMetadata = mergeProviderMetadata(
|
|
3456
|
+
aggregatedProviderMetadata,
|
|
3457
|
+
first.providerMetadata
|
|
3458
|
+
);
|
|
3459
|
+
aggregatedWarnings = mergeWarnings(aggregatedWarnings, first.warnings);
|
|
3460
|
+
traceSpan?.addEvent?.("useReason.first-pass.complete", {
|
|
3461
|
+
textLength: first.text.length,
|
|
3462
|
+
hasInterrupt: Boolean(args.interrupt)
|
|
3463
|
+
});
|
|
3464
|
+
if (args.interrupt) {
|
|
3465
|
+
const firstPass = parseInterruptFirstPassResult({
|
|
3466
|
+
text: first.text,
|
|
3467
|
+
requestSchema: args.interrupt.requestSchema,
|
|
3468
|
+
...first.finishReason ? { finishReason: first.finishReason } : {},
|
|
3469
|
+
...first.usage ? { usage: first.usage } : {},
|
|
3470
|
+
...args.outputSchema ? { outputSchema: args.outputSchema } : {},
|
|
3471
|
+
mode: args.interrupt.mode ?? "required"
|
|
3472
|
+
});
|
|
3473
|
+
firstText = firstPass.draftText;
|
|
3474
|
+
finalText = firstPass.draftText;
|
|
3475
|
+
firstInterruptRequired = firstPass.interruptRequired;
|
|
3476
|
+
firstInterruptRequest = firstPass.request;
|
|
3477
|
+
firstOutput = firstPass.output;
|
|
3478
|
+
finalOutput = firstPass.output;
|
|
3479
|
+
} else {
|
|
3480
|
+
firstText = first.text;
|
|
3481
|
+
finalText = first.text;
|
|
3482
|
+
if (args.outputSchema) {
|
|
3483
|
+
firstOutput = parseReasonOutputWithSchema({
|
|
3484
|
+
text: first.text,
|
|
3485
|
+
schema: args.outputSchema,
|
|
3486
|
+
...first.finishReason ? { finishReason: first.finishReason } : {},
|
|
3487
|
+
...first.usage ? { usage: first.usage } : {},
|
|
3488
|
+
label: "useReason output"
|
|
3489
|
+
});
|
|
3490
|
+
}
|
|
3491
|
+
finalOutput = firstOutput;
|
|
3492
|
+
}
|
|
2578
3493
|
}
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
3494
|
+
let interruptResponse;
|
|
3495
|
+
if (args.interrupt && (existingCheckpoint || firstInterruptRequired)) {
|
|
3496
|
+
const requestSchema = args.interrupt.requestSchema;
|
|
3497
|
+
const interruptRequest = existingCheckpoint ? parseWithSchema(
|
|
3498
|
+
requestSchema,
|
|
3499
|
+
existingCheckpoint.request,
|
|
3500
|
+
"useReason interrupt.request"
|
|
3501
|
+
) : firstInterruptRequest;
|
|
3502
|
+
if (!interruptRequest) {
|
|
3503
|
+
throw new Error(
|
|
3504
|
+
"useReason interrupt request is missing; first pass did not produce a valid interrupt payload."
|
|
3505
|
+
);
|
|
3506
|
+
}
|
|
3507
|
+
if (!existingCheckpoint) {
|
|
3508
|
+
ctx.currentNodeState.byKey[checkpointKey] = {
|
|
3509
|
+
status: "awaiting_interrupt",
|
|
3510
|
+
request: interruptRequest,
|
|
3511
|
+
firstText,
|
|
3512
|
+
...firstRaw !== void 0 ? { firstRaw } : {},
|
|
3513
|
+
...aggregatedUsage !== void 0 ? { firstUsage: aggregatedUsage } : {},
|
|
3514
|
+
...finalFinishReason !== void 0 ? { firstFinishReason: finalFinishReason } : {},
|
|
3515
|
+
...aggregatedProviderMetadata !== void 0 ? { firstProviderMetadata: aggregatedProviderMetadata } : {},
|
|
3516
|
+
...aggregatedWarnings !== void 0 ? { firstWarnings: aggregatedWarnings } : {},
|
|
3517
|
+
...firstOutput !== void 0 ? { firstOutput } : {}
|
|
3518
|
+
};
|
|
3519
|
+
ctx.stateDirty = true;
|
|
3520
|
+
}
|
|
3521
|
+
const resumeStatePatch = resolveHookStatePatch({
|
|
3522
|
+
nodeId: ctx.node.graph.node,
|
|
3523
|
+
currentNodeState: ctx.currentNodeState,
|
|
3524
|
+
workflowState: ctx.workflowState
|
|
3525
|
+
});
|
|
3526
|
+
interruptResponse = await awaitInterruptInternal({
|
|
3527
|
+
request: interruptRequest,
|
|
3528
|
+
requestSchema,
|
|
3529
|
+
responseSchema: args.interrupt.responseSchema,
|
|
3530
|
+
...args.interrupt.schemaId ? { schemaId: args.interrupt.schemaId } : {},
|
|
3531
|
+
...args.interrupt.schemaVersion ? { schemaVersion: args.interrupt.schemaVersion } : {},
|
|
3532
|
+
...id ? { id } : {},
|
|
3533
|
+
meta: {
|
|
3534
|
+
__kortyxResumeStatePatch: resumeStatePatch
|
|
3535
|
+
}
|
|
3536
|
+
});
|
|
3537
|
+
traceSpan?.addEvent?.("useReason.interrupt.resolved", {
|
|
3538
|
+
checkpointKey
|
|
3539
|
+
});
|
|
3540
|
+
if (Object.hasOwn(ctx.currentNodeState.byKey, checkpointKey)) {
|
|
3541
|
+
delete ctx.currentNodeState.byKey[checkpointKey];
|
|
3542
|
+
ctx.stateDirty = true;
|
|
3543
|
+
}
|
|
3544
|
+
const continuationInput = defaultContinuationInput({
|
|
3545
|
+
input: args.input,
|
|
3546
|
+
draftText: firstText,
|
|
3547
|
+
...firstOutput !== void 0 ? { draftOutput: firstOutput } : {},
|
|
3548
|
+
request: interruptRequest,
|
|
3549
|
+
response: interruptResponse
|
|
3550
|
+
});
|
|
3551
|
+
const second = await reasonEngine(
|
|
3552
|
+
{
|
|
3553
|
+
...args,
|
|
3554
|
+
...inferred.responseFormat ? { responseFormat: inferred.responseFormat } : {},
|
|
3555
|
+
emit: suppressTextStream ? false : args.emit,
|
|
3556
|
+
stream: suppressTextStream ? false : args.stream
|
|
3557
|
+
},
|
|
3558
|
+
reasonMeta,
|
|
3559
|
+
args.outputSchema ? withOutputGuardrails(
|
|
3560
|
+
continuationInput,
|
|
3561
|
+
args.outputSchema
|
|
3562
|
+
) : continuationInput
|
|
3563
|
+
);
|
|
3564
|
+
finalText = second.text;
|
|
3565
|
+
finalRaw = second.raw;
|
|
3566
|
+
accumulateTokenUsage(second.usage);
|
|
3567
|
+
aggregatedUsage = mergeUsage(aggregatedUsage, second.usage);
|
|
3568
|
+
finalFinishReason = second.finishReason;
|
|
3569
|
+
aggregatedProviderMetadata = mergeProviderMetadata(
|
|
3570
|
+
aggregatedProviderMetadata,
|
|
3571
|
+
second.providerMetadata
|
|
3572
|
+
);
|
|
3573
|
+
aggregatedWarnings = mergeWarnings(aggregatedWarnings, second.warnings);
|
|
3574
|
+
traceSpan?.addEvent?.("useReason.continuation.complete", {
|
|
3575
|
+
textLength: second.text.length
|
|
3576
|
+
});
|
|
3577
|
+
if (args.outputSchema) {
|
|
3578
|
+
finalOutput = parseReasonOutputWithSchema({
|
|
3579
|
+
text: finalText,
|
|
3580
|
+
schema: args.outputSchema,
|
|
3581
|
+
...second.finishReason ? { finishReason: second.finishReason } : {},
|
|
3582
|
+
...aggregatedUsage ? { usage: aggregatedUsage } : {},
|
|
3583
|
+
label: "useReason output"
|
|
3584
|
+
});
|
|
3585
|
+
}
|
|
3586
|
+
}
|
|
3587
|
+
if (finalOutput !== void 0) {
|
|
3588
|
+
emitReasonStructuredOutput({
|
|
3589
|
+
...id ? { id } : {},
|
|
3590
|
+
opId,
|
|
3591
|
+
output: finalOutput,
|
|
3592
|
+
structured: args.structured,
|
|
3593
|
+
emit: args.emit ?? true
|
|
3594
|
+
});
|
|
3595
|
+
}
|
|
3596
|
+
const result = {
|
|
3597
|
+
...id ? { id } : {},
|
|
3598
|
+
opId,
|
|
2622
3599
|
text: finalText,
|
|
2623
|
-
|
|
2624
|
-
...
|
|
2625
|
-
...
|
|
2626
|
-
|
|
3600
|
+
...finalRaw !== void 0 ? { raw: finalRaw } : {},
|
|
3601
|
+
...aggregatedUsage !== void 0 ? { usage: aggregatedUsage } : {},
|
|
3602
|
+
...finalFinishReason !== void 0 ? { finishReason: finalFinishReason } : {},
|
|
3603
|
+
...aggregatedProviderMetadata !== void 0 ? { providerMetadata: aggregatedProviderMetadata } : {},
|
|
3604
|
+
...aggregatedWarnings !== void 0 ? { warnings: aggregatedWarnings } : {},
|
|
3605
|
+
...finalOutput !== void 0 ? { output: finalOutput } : {},
|
|
3606
|
+
...interruptResponse !== void 0 ? { interruptResponse } : {}
|
|
3607
|
+
};
|
|
3608
|
+
if (args.interrupt) {
|
|
3609
|
+
ctx.currentNodeState.byKey[checkpointKey] = {
|
|
3610
|
+
status: "completed",
|
|
3611
|
+
result
|
|
3612
|
+
};
|
|
3613
|
+
ctx.stateDirty = true;
|
|
3614
|
+
}
|
|
3615
|
+
traceSpan?.end?.({
|
|
3616
|
+
...aggregatedUsage !== void 0 ? { usage: aggregatedUsage } : {},
|
|
3617
|
+
...finalFinishReason !== void 0 ? { finishReason: finalFinishReason } : {},
|
|
3618
|
+
...aggregatedProviderMetadata !== void 0 ? { providerMetadata: aggregatedProviderMetadata } : {},
|
|
3619
|
+
...aggregatedWarnings !== void 0 ? { warnings: aggregatedWarnings } : {},
|
|
3620
|
+
attributes: {
|
|
3621
|
+
textLength: finalText.length,
|
|
3622
|
+
resumedFromCheckpoint: Boolean(existingCheckpoint),
|
|
3623
|
+
interrupted: Boolean(interruptResponse !== void 0)
|
|
3624
|
+
},
|
|
3625
|
+
telemetry: {
|
|
3626
|
+
...args.telemetry ?? {},
|
|
3627
|
+
output: args.telemetry?.output ?? finalOutput ?? finalText
|
|
3628
|
+
}
|
|
2627
3629
|
});
|
|
3630
|
+
return result;
|
|
2628
3631
|
}
|
|
3632
|
+
);
|
|
3633
|
+
}
|
|
3634
|
+
async function useReason(args) {
|
|
3635
|
+
try {
|
|
3636
|
+
return await runReason(args);
|
|
3637
|
+
} finally {
|
|
3638
|
+
await closeOwnedTools(args.tools ?? []);
|
|
2629
3639
|
}
|
|
2630
|
-
if (finalOutput !== void 0) {
|
|
2631
|
-
emitReasonStructuredOutput({
|
|
2632
|
-
...id ? { id } : {},
|
|
2633
|
-
opId,
|
|
2634
|
-
output: finalOutput,
|
|
2635
|
-
structured: args.structured,
|
|
2636
|
-
emit: args.emit ?? true
|
|
2637
|
-
});
|
|
2638
|
-
}
|
|
2639
|
-
const result = {
|
|
2640
|
-
...id ? { id } : {},
|
|
2641
|
-
opId,
|
|
2642
|
-
text: finalText,
|
|
2643
|
-
...finalRaw !== void 0 ? { raw: finalRaw } : {},
|
|
2644
|
-
...aggregatedUsage !== void 0 ? { usage: aggregatedUsage } : {},
|
|
2645
|
-
...finalFinishReason !== void 0 ? { finishReason: finalFinishReason } : {},
|
|
2646
|
-
...aggregatedProviderMetadata !== void 0 ? { providerMetadata: aggregatedProviderMetadata } : {},
|
|
2647
|
-
...aggregatedWarnings !== void 0 ? { warnings: aggregatedWarnings } : {},
|
|
2648
|
-
...finalOutput !== void 0 ? { output: finalOutput } : {},
|
|
2649
|
-
...interruptResponse !== void 0 ? { interruptResponse } : {}
|
|
2650
|
-
};
|
|
2651
|
-
if (args.interrupt) {
|
|
2652
|
-
ctx.currentNodeState.byKey[checkpointKey] = {
|
|
2653
|
-
status: "completed",
|
|
2654
|
-
result
|
|
2655
|
-
};
|
|
2656
|
-
ctx.stateDirty = true;
|
|
2657
|
-
}
|
|
2658
|
-
traceSpan?.end?.({
|
|
2659
|
-
...aggregatedUsage !== void 0 ? { usage: aggregatedUsage } : {},
|
|
2660
|
-
...finalFinishReason !== void 0 ? { finishReason: finalFinishReason } : {},
|
|
2661
|
-
...aggregatedProviderMetadata !== void 0 ? { providerMetadata: aggregatedProviderMetadata } : {},
|
|
2662
|
-
...aggregatedWarnings !== void 0 ? { warnings: aggregatedWarnings } : {},
|
|
2663
|
-
attributes: {
|
|
2664
|
-
textLength: finalText.length,
|
|
2665
|
-
resumedFromCheckpoint: Boolean(existingCheckpoint),
|
|
2666
|
-
interrupted: Boolean(interruptResponse !== void 0)
|
|
2667
|
-
},
|
|
2668
|
-
telemetry: {
|
|
2669
|
-
...args.telemetry ?? {},
|
|
2670
|
-
output: args.telemetry?.output ?? finalOutput ?? finalText
|
|
2671
|
-
}
|
|
2672
|
-
});
|
|
2673
|
-
return result;
|
|
2674
3640
|
}
|
|
2675
3641
|
function useStructuredData(args) {
|
|
2676
3642
|
emitStructuredData(args);
|
|
@@ -2725,8 +3691,8 @@ ${tryStringify2(args.response)}`
|
|
|
2725
3691
|
};
|
|
2726
3692
|
return [getValue(), setValue];
|
|
2727
3693
|
}
|
|
2728
|
-
var
|
|
2729
|
-
var
|
|
3694
|
+
var import_core7 = require("@kortyx/core");
|
|
3695
|
+
var import_errors7 = require("@kortyx/core/errors");
|
|
2730
3696
|
var ParallelChildWaiting = class extends Error {
|
|
2731
3697
|
name = "ParallelChildWaiting";
|
|
2732
3698
|
};
|
|
@@ -2740,14 +3706,14 @@ ${tryStringify2(args.response)}`
|
|
|
2740
3706
|
);
|
|
2741
3707
|
this.results = results;
|
|
2742
3708
|
this.name = "ParallelError";
|
|
2743
|
-
this.failure = (0,
|
|
3709
|
+
this.failure = (0, import_errors7.serializeFailure)({
|
|
2744
3710
|
version: 1,
|
|
2745
3711
|
code: this.code,
|
|
2746
3712
|
category: "workflow",
|
|
2747
3713
|
message: this.message,
|
|
2748
3714
|
retryable: null,
|
|
2749
3715
|
results: results.map(
|
|
2750
|
-
(result) => result.status === "fulfilled" ? { status: "fulfilled" } : { status: "rejected", failure: (0,
|
|
3716
|
+
(result) => result.status === "fulfilled" ? { status: "fulfilled" } : { status: "rejected", failure: (0, import_errors7.serializeFailure)(result.reason) }
|
|
2751
3717
|
)
|
|
2752
3718
|
});
|
|
2753
3719
|
}
|
|
@@ -2755,7 +3721,7 @@ ${tryStringify2(args.response)}`
|
|
|
2755
3721
|
code = "PARALLEL_FAILED";
|
|
2756
3722
|
failure;
|
|
2757
3723
|
toJSON() {
|
|
2758
|
-
return (0,
|
|
3724
|
+
return (0, import_errors7.serializeFailure)(this);
|
|
2759
3725
|
}
|
|
2760
3726
|
};
|
|
2761
3727
|
function registerWorkflowTask(id) {
|
|
@@ -2851,13 +3817,13 @@ ${tryStringify2(args.response)}`
|
|
|
2851
3817
|
);
|
|
2852
3818
|
}
|
|
2853
3819
|
if (ready[0]?.status === "rejected") throw ready[0].reason;
|
|
2854
|
-
(0,
|
|
3820
|
+
(0, import_core7.throwIfExecutionAborted)(ctx.node.abortSignal);
|
|
2855
3821
|
if (ctx.workflowControlError) throw ctx.workflowControlError;
|
|
2856
3822
|
const rejected = outcomes.filter(
|
|
2857
3823
|
(outcome) => outcome.status === "rejected"
|
|
2858
3824
|
);
|
|
2859
3825
|
const control = rejected.find(
|
|
2860
|
-
(outcome) => (0,
|
|
3826
|
+
(outcome) => (0, import_core7.isExecutionCancelled)(outcome.reason) || (0, import_core7.isExecutionLimitReached)(outcome.reason)
|
|
2861
3827
|
);
|
|
2862
3828
|
if (control) {
|
|
2863
3829
|
ctx.workflowControlError = control.reason;
|
|
@@ -2892,50 +3858,19 @@ ${tryStringify2(args.response)}`
|
|
|
2892
3858
|
});
|
|
2893
3859
|
return promise;
|
|
2894
3860
|
}
|
|
2895
|
-
|
|
2896
|
-
var import_core7 = require("@kortyx/core");
|
|
2897
|
-
var import_errors62 = require("@kortyx/core/errors");
|
|
2898
|
-
var import_node_crypto42 = require("crypto");
|
|
2899
|
-
function emitWorkflowCall2(telemetry, type, payload) {
|
|
2900
|
-
const base = telemetry?.correlation;
|
|
2901
|
-
if (!telemetry?.reporter || !telemetry.environment || !telemetry.service || !base?.runId || !base.workflowId)
|
|
2902
|
-
return;
|
|
3861
|
+
function reportError(error, options = {}) {
|
|
2903
3862
|
try {
|
|
2904
|
-
|
|
2905
|
-
void Promise.resolve(
|
|
2906
|
-
telemetry.reporter.emit([
|
|
2907
|
-
{
|
|
2908
|
-
schemaVersion: 1,
|
|
2909
|
-
eventId: (0, import_node_crypto42.randomUUID)(),
|
|
2910
|
-
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2911
|
-
environment: telemetry.environment,
|
|
2912
|
-
service: telemetry.service,
|
|
2913
|
-
correlation: {
|
|
2914
|
-
...base,
|
|
2915
|
-
runId: base.runId,
|
|
2916
|
-
workflowId: base.workflowId,
|
|
2917
|
-
...active
|
|
2918
|
-
},
|
|
2919
|
-
type,
|
|
2920
|
-
payload
|
|
2921
|
-
}
|
|
2922
|
-
])
|
|
2923
|
-
).catch(() => {
|
|
2924
|
-
});
|
|
3863
|
+
getReasonTraceAdapter()?.reportError?.(error, options);
|
|
2925
3864
|
} catch {
|
|
2926
3865
|
}
|
|
2927
3866
|
}
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
const serialized = JSON.stringify(value);
|
|
2933
|
-
return serialized && Buffer.byteLength(serialized, "utf8") <= 16384 ? { [side]: JSON.parse(serialized) } : { [`${side}Omitted`]: "Content exceeds 16 KiB" };
|
|
2934
|
-
}
|
|
2935
|
-
var WorkflowCallError = class extends import_errors62.KortyxError {
|
|
3867
|
+
var import_node_crypto6 = require("crypto");
|
|
3868
|
+
var import_core8 = require("@kortyx/core");
|
|
3869
|
+
var import_errors8 = require("@kortyx/core/errors");
|
|
3870
|
+
var WorkflowCallError = class extends import_errors8.KortyxError {
|
|
2936
3871
|
constructor(workflow, message, cause, failure) {
|
|
2937
|
-
const detail = (0,
|
|
2938
|
-
failure ?? cause ?? new
|
|
3872
|
+
const detail = (0, import_errors8.serializeFailure)(
|
|
3873
|
+
failure ?? cause ?? new import_errors8.WorkflowContractError(message)
|
|
2939
3874
|
);
|
|
2940
3875
|
super(detail.code, `Workflow '${workflow}': ${message}`, {
|
|
2941
3876
|
...detail,
|
|
@@ -2956,12 +3891,12 @@ ${tryStringify2(args.response)}`
|
|
|
2956
3891
|
if (v === null || typeof v === "string" || typeof v === "boolean") return v;
|
|
2957
3892
|
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
2958
3893
|
if (typeof v !== "object" || !v || seen.has(v)) {
|
|
2959
|
-
throw new
|
|
3894
|
+
throw new import_errors8.WorkflowContractError(
|
|
2960
3895
|
"Workflow input and output must be JSON serializable."
|
|
2961
3896
|
);
|
|
2962
3897
|
}
|
|
2963
3898
|
if (!Array.isArray(v) && Object.getPrototypeOf(v) !== Object.prototype) {
|
|
2964
|
-
throw new
|
|
3899
|
+
throw new import_errors8.WorkflowContractError(
|
|
2965
3900
|
"Workflow input and output must contain plain JSON objects."
|
|
2966
3901
|
);
|
|
2967
3902
|
}
|
|
@@ -2982,7 +3917,7 @@ ${tryStringify2(args.response)}`
|
|
|
2982
3917
|
useWorkflow: (args) => {
|
|
2983
3918
|
const workflow = workflows[args.workflow];
|
|
2984
3919
|
if (!workflow || workflow.id !== args.workflow)
|
|
2985
|
-
throw new
|
|
3920
|
+
throw new import_errors8.WorkflowContractError(
|
|
2986
3921
|
"Workflow registry keys must match definition ids."
|
|
2987
3922
|
);
|
|
2988
3923
|
return useWorkflow({ ...args, workflow });
|
|
@@ -2996,7 +3931,7 @@ ${tryStringify2(args.response)}`
|
|
|
2996
3931
|
if (task.group) await task.group.ready;
|
|
2997
3932
|
return await runWorkflowCall(args, task);
|
|
2998
3933
|
} catch (error) {
|
|
2999
|
-
if ((0,
|
|
3934
|
+
if ((0, import_core8.isExecutionCancelled)(error) || (0, import_core8.isExecutionLimitReached)(error))
|
|
3000
3935
|
getHookContext().workflowControlError = error;
|
|
3001
3936
|
throw error;
|
|
3002
3937
|
} finally {
|
|
@@ -3005,26 +3940,26 @@ ${tryStringify2(args.response)}`
|
|
|
3005
3940
|
}
|
|
3006
3941
|
async function runWorkflowCall(args, task) {
|
|
3007
3942
|
const ctx = getHookContext();
|
|
3008
|
-
(0,
|
|
3943
|
+
(0, import_core8.throwIfExecutionAborted)(ctx.node.abortSignal);
|
|
3009
3944
|
const service = ctx.node.callWorkflow;
|
|
3010
3945
|
if (!service)
|
|
3011
|
-
throw new
|
|
3946
|
+
throw new import_errors8.WorkflowContractError(
|
|
3012
3947
|
"useWorkflow requires an agent workflow registry."
|
|
3013
3948
|
);
|
|
3014
3949
|
if (!args.id.trim())
|
|
3015
|
-
throw new
|
|
3950
|
+
throw new import_errors8.WorkflowContractError(
|
|
3016
3951
|
"useWorkflow requires a stable, nonempty id."
|
|
3017
3952
|
);
|
|
3018
3953
|
if (ctx.workflowCallActive && !task.group)
|
|
3019
|
-
throw new
|
|
3954
|
+
throw new import_errors8.WorkflowContractError(
|
|
3020
3955
|
"Concurrent workflow calls require parallel([...]); otherwise await each call."
|
|
3021
3956
|
);
|
|
3022
3957
|
if (ctx.workflowCallIds.has(args.id))
|
|
3023
|
-
throw new
|
|
3958
|
+
throw new import_errors8.WorkflowContractError(
|
|
3024
3959
|
`Duplicate workflow call id '${args.id}' in one node activation.`
|
|
3025
3960
|
);
|
|
3026
3961
|
if (ctx.workflowCallIds.size >= 64)
|
|
3027
|
-
throw new
|
|
3962
|
+
throw new import_errors8.WorkflowContractError(
|
|
3028
3963
|
"A node may call at most 64 child workflows per activation."
|
|
3029
3964
|
);
|
|
3030
3965
|
ctx.workflowCallIds.add(args.id);
|
|
@@ -3051,7 +3986,7 @@ ${tryStringify2(args.response)}`
|
|
|
3051
3986
|
if (!record) ctx.node.consumeExecution?.("maxChildInvocations");
|
|
3052
3987
|
record ??= {
|
|
3053
3988
|
fingerprint,
|
|
3054
|
-
invocationId: (0,
|
|
3989
|
+
invocationId: (0, import_node_crypto6.randomUUID)(),
|
|
3055
3990
|
status: "running",
|
|
3056
3991
|
interrupts: [],
|
|
3057
3992
|
...task.group ? { parallelKey: task.group.key } : {}
|
|
@@ -3061,7 +3996,7 @@ ${tryStringify2(args.response)}`
|
|
|
3061
3996
|
if (!task.group) ctx.workflowCallActive = true;
|
|
3062
3997
|
const telemetry = ctx.node.workflowCallTelemetry;
|
|
3063
3998
|
const activationKey = "__useWorkflowActivation";
|
|
3064
|
-
ctx.currentNodeState.byKey[activationKey] ??= (0,
|
|
3999
|
+
ctx.currentNodeState.byKey[activationKey] ??= (0, import_node_crypto6.randomUUID)();
|
|
3065
4000
|
const callerNodeExecutionId = ctx.currentNodeState.byKey[activationKey];
|
|
3066
4001
|
const metadata2 = {
|
|
3067
4002
|
invocationId: record.invocationId,
|
|
@@ -3105,7 +4040,7 @@ ${tryStringify2(args.response)}`
|
|
|
3105
4040
|
workflow,
|
|
3106
4041
|
record.error ?? "child failed",
|
|
3107
4042
|
void 0,
|
|
3108
|
-
record.failure ?? (0,
|
|
4043
|
+
record.failure ?? (0, import_errors8.serializeFailure)(void 0)
|
|
3109
4044
|
);
|
|
3110
4045
|
if (task.group && record.status === "interrupted" && record.interrupts.at(-1)?.response === void 0)
|
|
3111
4046
|
throw new ParallelChildWaiting();
|
|
@@ -3129,9 +4064,9 @@ ${tryStringify2(args.response)}`
|
|
|
3129
4064
|
} catch (error) {
|
|
3130
4065
|
const child = error;
|
|
3131
4066
|
recordUsage(child?.__kortyxChildUsage);
|
|
3132
|
-
(0,
|
|
3133
|
-
if ((0,
|
|
3134
|
-
if ((0,
|
|
4067
|
+
(0, import_core8.throwIfExecutionAborted)(ctx.node.abortSignal);
|
|
4068
|
+
if ((0, import_core8.isExecutionCancelled)(error)) throw error;
|
|
4069
|
+
if ((0, import_core8.isExecutionLimitReached)(error)) {
|
|
3135
4070
|
if (child?.__kortyxChildSnapshot)
|
|
3136
4071
|
record.snapshot = child.__kortyxChildSnapshot;
|
|
3137
4072
|
report("suspended", {
|
|
@@ -3141,7 +4076,7 @@ ${tryStringify2(args.response)}`
|
|
|
3141
4076
|
throw error;
|
|
3142
4077
|
}
|
|
3143
4078
|
record.status = "failed";
|
|
3144
|
-
record.failure = (0,
|
|
4079
|
+
record.failure = (0, import_errors8.serializeFailure)(error);
|
|
3145
4080
|
record.error = record.failure.message;
|
|
3146
4081
|
report("failed", { error: "Child workflow failed" });
|
|
3147
4082
|
throw new WorkflowCallError(
|
|
@@ -3151,12 +4086,15 @@ ${tryStringify2(args.response)}`
|
|
|
3151
4086
|
record.failure
|
|
3152
4087
|
);
|
|
3153
4088
|
}
|
|
3154
|
-
(0,
|
|
4089
|
+
(0, import_core8.throwIfExecutionAborted)(ctx.node.abortSignal);
|
|
3155
4090
|
recordUsage(outcome.usage);
|
|
3156
4091
|
if (outcome.status === "completed") {
|
|
3157
4092
|
record.data = outcome.data;
|
|
3158
4093
|
workflowCallFingerprint(record.data);
|
|
3159
4094
|
record.status = "completed";
|
|
4095
|
+
record.toolObservations = outcome.toolObservations ?? [];
|
|
4096
|
+
for (const observation of record.toolObservations)
|
|
4097
|
+
rememberToolObservation(observation);
|
|
3160
4098
|
delete record.snapshot;
|
|
3161
4099
|
report(
|
|
3162
4100
|
"completed",
|
|
@@ -3179,8 +4117,12 @@ ${tryStringify2(args.response)}`
|
|
|
3179
4117
|
});
|
|
3180
4118
|
}
|
|
3181
4119
|
}
|
|
3182
|
-
if (cached)
|
|
4120
|
+
if (cached) {
|
|
3183
4121
|
report("reused", workflowCallContent(telemetry, "output", record.data));
|
|
4122
|
+
if (record.restoredToolBranch !== telemetry?.correlation?.branchId)
|
|
4123
|
+
await replayToolObservations(record.toolObservations ?? [], true);
|
|
4124
|
+
delete record.restoredToolBranch;
|
|
4125
|
+
}
|
|
3184
4126
|
const data = record.data ?? {};
|
|
3185
4127
|
return {
|
|
3186
4128
|
data: JSON.parse(JSON.stringify(data))
|
|
@@ -3417,6 +4359,7 @@ var ExecutionRequestError = class extends import_errors2.KortyxError {
|
|
|
3417
4359
|
var import_node_stream = require("stream");
|
|
3418
4360
|
var import_core2 = require("@kortyx/core");
|
|
3419
4361
|
var import_errors4 = require("@kortyx/core/errors");
|
|
4362
|
+
var import_internal = __toESM(require_internal());
|
|
3420
4363
|
var import_runtime = require("@kortyx/runtime");
|
|
3421
4364
|
var import_langgraph = require("@langchain/langgraph");
|
|
3422
4365
|
|
|
@@ -3991,7 +4934,9 @@ async function orchestrateGraphStream({
|
|
|
3991
4934
|
let structuredSeq = 0;
|
|
3992
4935
|
const debugEnabled = Boolean(config?.features?.tracing);
|
|
3993
4936
|
const traceAdapter = getTraceAdapter(config);
|
|
3994
|
-
const contextMeta =
|
|
4937
|
+
const contextMeta = (0, import_internal.safeTelemetryMetadata)(
|
|
4938
|
+
isRecord3(config.context) ? { userId: config.context.userId, tenantId: config.context.tenantId } : {}
|
|
4939
|
+
);
|
|
3995
4940
|
const telemetryConfig = isRecord3(config.telemetry) ? config.telemetry : {};
|
|
3996
4941
|
const emitResumeFailure = (resumeError) => {
|
|
3997
4942
|
const interruptId = typeof config.telemetryInterruptId === "string" ? config.telemetryInterruptId : void 0;
|
|
@@ -4027,8 +4972,13 @@ async function orchestrateGraphStream({
|
|
|
4027
4972
|
...isRecord3(telemetryConfig.metadata) ? telemetryConfig.metadata : {},
|
|
4028
4973
|
...contextMeta
|
|
4029
4974
|
},
|
|
4030
|
-
tags: Array.isArray(telemetryConfig.tags) ? telemetryConfig.tags
|
|
4031
|
-
|
|
4975
|
+
tags: Array.isArray(telemetryConfig.tags) ? telemetryConfig.tags.filter(
|
|
4976
|
+
(tag) => typeof tag === "string"
|
|
4977
|
+
) : void 0,
|
|
4978
|
+
captureContent: typeof telemetryConfig.captureContent === "boolean" ? telemetryConfig.captureContent : isRecord3(telemetryConfig.captureContent) ? {
|
|
4979
|
+
...typeof telemetryConfig.captureContent.input === "boolean" ? { input: telemetryConfig.captureContent.input } : {},
|
|
4980
|
+
...typeof telemetryConfig.captureContent.output === "boolean" ? { output: telemetryConfig.captureContent.output } : {}
|
|
4981
|
+
} : void 0,
|
|
4032
4982
|
input: typeof state.input === "string" ? state.input : JSON.stringify(state.input)
|
|
4033
4983
|
}
|
|
4034
4984
|
};
|
|
@@ -4784,24 +5734,28 @@ async function orchestrateGraphStream({
|
|
|
4784
5734
|
}
|
|
4785
5735
|
};
|
|
4786
5736
|
const emitTraceChunk = () => {
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
5737
|
+
try {
|
|
5738
|
+
const traceContext = traceAdapter?.getActiveContext?.();
|
|
5739
|
+
if (!traceContext) return;
|
|
5740
|
+
write({
|
|
5741
|
+
type: "trace",
|
|
5742
|
+
traceId: traceContext.traceId,
|
|
5743
|
+
spanId: traceContext.spanId,
|
|
5744
|
+
runId,
|
|
5745
|
+
rootSpanName: "kortyx.run"
|
|
5746
|
+
});
|
|
5747
|
+
} catch {
|
|
5748
|
+
}
|
|
4796
5749
|
};
|
|
4797
|
-
|
|
5750
|
+
let fallbackRunSpan;
|
|
4798
5751
|
if (!traceAdapter?.withSpan) {
|
|
5752
|
+
fallbackRunSpan = (0, import_internal.safeStartSpan)(traceAdapter, runSpanArgs);
|
|
4799
5753
|
emitTraceChunk();
|
|
4800
5754
|
}
|
|
4801
|
-
const startRun = () => traceAdapter?.withSpan ?
|
|
5755
|
+
const startRun = () => traceAdapter?.withSpan ? (0, import_internal.withSafeTraceSpan)(traceAdapter, runSpanArgs, async (runTraceSpan) => {
|
|
4802
5756
|
emitTraceChunk();
|
|
4803
5757
|
return runLoop(runTraceSpan);
|
|
4804
|
-
}) : runLoop(fallbackRunSpan
|
|
5758
|
+
}) : runLoop(fallbackRunSpan);
|
|
4805
5759
|
const runPromise = frameworkAdapter?.acquireRunLease && !releaseLease ? frameworkAdapter.acquireRunLease({
|
|
4806
5760
|
runId,
|
|
4807
5761
|
...sessionId ? { sessionId } : {},
|
|
@@ -5564,6 +6518,7 @@ var import_hooks = __toESM(require_dist());
|
|
|
5564
6518
|
function restoreWorkflowCallBranch(requests, telemetry, sourceRunId) {
|
|
5565
6519
|
const branchId = (0, import_node_crypto3.randomUUID)();
|
|
5566
6520
|
const emitted = /* @__PURE__ */ new Set();
|
|
6521
|
+
const toolEvidence = /* @__PURE__ */ new Set();
|
|
5567
6522
|
for (const request of requests) {
|
|
5568
6523
|
if (request.state)
|
|
5569
6524
|
request.state.config = {
|
|
@@ -5601,6 +6556,52 @@ function restoreWorkflowCallBranch(requests, telemetry, sourceRunId) {
|
|
|
5601
6556
|
status: record.status
|
|
5602
6557
|
}
|
|
5603
6558
|
);
|
|
6559
|
+
if (record.status === "completed" && Array.isArray(record.toolObservations)) {
|
|
6560
|
+
if (telemetry?.reporter && telemetry.environment && telemetry.service)
|
|
6561
|
+
record.restoredToolBranch = branchId;
|
|
6562
|
+
for (const original of record.toolObservations) {
|
|
6563
|
+
const key = JSON.stringify([
|
|
6564
|
+
original.invocationId,
|
|
6565
|
+
original.toolCallId,
|
|
6566
|
+
original.attemptId
|
|
6567
|
+
]);
|
|
6568
|
+
if (toolEvidence.has(key)) continue;
|
|
6569
|
+
toolEvidence.add(key);
|
|
6570
|
+
const payload = {
|
|
6571
|
+
...original,
|
|
6572
|
+
runId: request.runId,
|
|
6573
|
+
branchId,
|
|
6574
|
+
attemptId: (0, import_node_crypto3.randomUUID)(),
|
|
6575
|
+
executed: false,
|
|
6576
|
+
durationMs: void 0,
|
|
6577
|
+
observationKind: "reused",
|
|
6578
|
+
source: original.source ?? {
|
|
6579
|
+
runId: original.runId ?? sourceRunId,
|
|
6580
|
+
invocationId: original.invocationId,
|
|
6581
|
+
branchId: original.branchId,
|
|
6582
|
+
toolCallId: original.toolCallId,
|
|
6583
|
+
attemptId: original.attemptId
|
|
6584
|
+
}
|
|
6585
|
+
};
|
|
6586
|
+
(0, import_hooks.emitWorkflowCall)(
|
|
6587
|
+
telemetry ? {
|
|
6588
|
+
...telemetry,
|
|
6589
|
+
correlation: {
|
|
6590
|
+
runId: request.runId,
|
|
6591
|
+
sessionId: request.sessionId,
|
|
6592
|
+
workflowId: original.workflowId ?? request.workflow,
|
|
6593
|
+
nodeId: original.nodeId,
|
|
6594
|
+
workflowRevisionId: original.workflowRevisionId,
|
|
6595
|
+
invocationId: original.invocationId,
|
|
6596
|
+
parentInvocationId: original.parentInvocationId,
|
|
6597
|
+
branchId
|
|
6598
|
+
}
|
|
6599
|
+
} : void 0,
|
|
6600
|
+
"tool.reused",
|
|
6601
|
+
payload
|
|
6602
|
+
);
|
|
6603
|
+
}
|
|
6604
|
+
}
|
|
5604
6605
|
}
|
|
5605
6606
|
}
|
|
5606
6607
|
}
|