@cuylabs/agent-core 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -17
- package/dist/chunk-2O4MCSQS.js +780 -0
- package/dist/chunk-2TTOLHBT.js +198 -0
- package/dist/chunk-5FMSGQVX.js +281 -0
- package/dist/chunk-5NVVNXPQ.js +288 -0
- package/dist/{chunk-EKR6PKXU.js → chunk-6HZBHFOL.js} +3 -3
- package/dist/chunk-CJI7PVS2.js +58 -0
- package/dist/{chunk-WKHDSSXG.js → chunk-CMYN2RCB.js} +146 -46
- package/dist/chunk-FII65CN7.js +117 -0
- package/dist/{chunk-UHCJEM2E.js → chunk-ICZ66572.js} +13 -6
- package/dist/chunk-KYLPMBHD.js +316 -0
- package/dist/chunk-MXAP4UG6.js +2956 -0
- package/dist/{chunk-4QFNWPIF.js → chunk-N3VX7FEE.js} +35 -2
- package/dist/{chunk-MAZ5DY5B.js → chunk-NDZWXCBZ.js} +213 -78
- package/dist/{chunk-MHKK374K.js → chunk-Q742PSH3.js} +11 -27
- package/dist/{chunk-WGZAPU6N.js → chunk-QAL3OMI3.js} +15 -1
- package/dist/{chunk-UDCZ673N.js → chunk-RN6WZEUF.js} +27 -23
- package/dist/{chunk-ZXAKHMWH.js → chunk-ROTGCYDW.js} +22 -84
- package/dist/chunk-SPBFQXOT.js +0 -0
- package/dist/chunk-SSFBF3US.js +602 -0
- package/dist/chunk-SZ2XBPTW.js +8 -0
- package/dist/chunk-T4UIX5D7.js +115 -0
- package/dist/{chunk-IYWQOJMQ.js → chunk-TIHPYVAJ.js} +34 -34
- package/dist/{chunk-RKEW5WXI.js → chunk-TOTDGK3P.js} +1 -1
- package/dist/chunk-V4RFNEET.js +563 -0
- package/dist/chunk-VOUEJSW6.js +0 -0
- package/dist/{chunk-J4QDGZIA.js → chunk-WBPOZ7CL.js} +659 -275
- package/dist/chunk-X4VN4GIJ.js +185 -0
- package/dist/dispatch/index.d.ts +93 -0
- package/dist/dispatch/index.js +37 -0
- package/dist/events/index.d.ts +93 -0
- package/dist/events/index.js +6 -0
- package/dist/{runtime → execution}/index.d.ts +120 -35
- package/dist/{runtime → execution}/index.js +17 -11
- package/dist/index.d.ts +489 -115
- package/dist/index.js +1665 -462
- package/dist/inference/errors/index.js +1 -1
- package/dist/inference/index.d.ts +13 -21
- package/dist/inference/index.js +15 -12
- package/dist/instance-BqV2D5pc.d.ts +5723 -0
- package/dist/logger/index.d.ts +50 -0
- package/dist/logger/index.js +11 -0
- package/dist/mcp/index.d.ts +5 -9
- package/dist/mcp/index.js +2 -3
- package/dist/middleware/index.d.ts +10 -150
- package/dist/middleware/index.js +10 -2
- package/dist/model-messages-B4nK9D1-.d.ts +13 -0
- package/dist/models/index.d.ts +5 -2
- package/dist/models/index.js +2 -1
- package/dist/models/reasoning/index.js +2 -1
- package/dist/plugin/index.d.ts +55 -11
- package/dist/plugin/index.js +1 -1
- package/dist/profiles/index.d.ts +55 -0
- package/dist/{presets → profiles}/index.js +10 -10
- package/dist/prompt/index.d.ts +8 -13
- package/dist/safety/index.d.ts +109 -14
- package/dist/safety/index.js +59 -3
- package/dist/sandbox/index.d.ts +81 -0
- package/dist/sandbox/index.js +1 -0
- package/dist/skill/index.d.ts +10 -8
- package/dist/skill/index.js +2 -2
- package/dist/storage/index.d.ts +12 -4
- package/dist/storage/index.js +1 -1
- package/dist/subagents/index.d.ts +177 -0
- package/dist/subagents/index.js +78 -0
- package/dist/team/index.d.ts +544 -0
- package/dist/team/index.js +41 -0
- package/dist/tool/host/index.d.ts +41 -0
- package/dist/tool/host/index.js +10 -0
- package/dist/tool/index.d.ts +111 -21
- package/dist/tool/index.js +20 -13
- package/dist/{types-VQgymC1N.d.ts → types-Bj_J8u_W.d.ts} +44 -64
- package/dist/{types-CHiPh8U2.d.ts → types-C_LCeYNg.d.ts} +7 -7
- package/dist/types-RSCv7nQ4.d.ts +59 -0
- package/package.json +46 -47
- package/dist/builder-BgZ_j4Vs.d.ts +0 -35
- package/dist/chunk-5ARZJWD2.js +0 -259
- package/dist/chunk-DXFBQMXP.js +0 -53
- package/dist/chunk-H3FUYU52.js +0 -81
- package/dist/chunk-JLXG2SH7.js +0 -905
- package/dist/chunk-N7P4PN3O.js +0 -84
- package/dist/chunk-OFDKHNCX.js +0 -727
- package/dist/chunk-SDSBEQXG.js +0 -157
- package/dist/chunk-VEKUXUVF.js +0 -41
- package/dist/chunk-VNQBHPCT.js +0 -398
- package/dist/chunk-WWYYNWEW.js +0 -259
- package/dist/context/index.d.ts +0 -259
- package/dist/context/index.js +0 -26
- package/dist/events-CE72w8W4.d.ts +0 -149
- package/dist/host/index.d.ts +0 -45
- package/dist/host/index.js +0 -8
- package/dist/index-DQuTZ8xL.d.ts +0 -1335
- package/dist/messages-BYWGn8TY.d.ts +0 -110
- package/dist/presets/index.d.ts +0 -53
- package/dist/registry-DwYqsQkX.d.ts +0 -164
- package/dist/runner-CI-XeR16.d.ts +0 -91
- package/dist/scope/index.d.ts +0 -10
- package/dist/scope/index.js +0 -14
- package/dist/session-manager-KbYt2WUh.d.ts +0 -282
- package/dist/signal/index.d.ts +0 -28
- package/dist/signal/index.js +0 -6
- package/dist/sub-agent/index.d.ts +0 -24
- package/dist/sub-agent/index.js +0 -32
- package/dist/tool-CZWN3KbO.d.ts +0 -141
- package/dist/tool-DkhSCV2Y.d.ts +0 -145
- package/dist/tracker-DClqYqTj.d.ts +0 -96
- package/dist/tracking/index.d.ts +0 -111
- package/dist/tracking/index.js +0 -20
- package/dist/types-BfNpU8NS.d.ts +0 -270
- package/dist/types-BlOKk-Bb.d.ts +0 -330
- package/dist/types-BlZwmnuW.d.ts +0 -50
- package/dist/types-CQL-SvTn.d.ts +0 -29
- package/dist/types-CWm-7rvB.d.ts +0 -55
- package/dist/types-DTSkxakL.d.ts +0 -651
- package/dist/types-DmDwi2zI.d.ts +0 -339
- package/dist/types-YuWV4ag7.d.ts +0 -72
|
@@ -112,6 +112,30 @@ function extractFromAISDKError(error) {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
// src/inference/errors/llm-error.ts
|
|
115
|
+
function extractMessage(error) {
|
|
116
|
+
if (typeof error === "string") return error;
|
|
117
|
+
if (error && typeof error === "object") {
|
|
118
|
+
if ("message" in error && typeof error.message === "string") {
|
|
119
|
+
return error.message;
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
return JSON.stringify(error);
|
|
123
|
+
} catch {
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return String(error);
|
|
127
|
+
}
|
|
128
|
+
function sanitizeErrorMessage(message) {
|
|
129
|
+
const trimmed = message.trim();
|
|
130
|
+
const stackIndex = trimmed.indexOf("\n at ");
|
|
131
|
+
if (stackIndex >= 0) {
|
|
132
|
+
return trimmed.slice(0, stackIndex).trim();
|
|
133
|
+
}
|
|
134
|
+
return trimmed.split("\n").map((line) => line.trim()).find(Boolean) ?? trimmed;
|
|
135
|
+
}
|
|
136
|
+
function isNoOutputGeneratedError(error) {
|
|
137
|
+
return error.name === "AI_NoOutputGeneratedError" || error.name === "NoOutputGeneratedError" || error.message.includes("No output generated. Check the stream for errors.");
|
|
138
|
+
}
|
|
115
139
|
var LLMError = class _LLMError extends Error {
|
|
116
140
|
category;
|
|
117
141
|
status;
|
|
@@ -147,15 +171,24 @@ var LLMError = class _LLMError extends Error {
|
|
|
147
171
|
...context
|
|
148
172
|
});
|
|
149
173
|
}
|
|
174
|
+
if (isNoOutputGeneratedError(error)) {
|
|
175
|
+
return new _LLMError({
|
|
176
|
+
message: "No output generated. Check the underlying provider error.",
|
|
177
|
+
cause: error,
|
|
178
|
+
category: "unknown",
|
|
179
|
+
...extractFromAISDKError(error),
|
|
180
|
+
...context
|
|
181
|
+
});
|
|
182
|
+
}
|
|
150
183
|
return new _LLMError({
|
|
151
|
-
message: error.message,
|
|
184
|
+
message: sanitizeErrorMessage(error.message),
|
|
152
185
|
cause: error,
|
|
153
186
|
...extractFromAISDKError(error),
|
|
154
187
|
...context
|
|
155
188
|
});
|
|
156
189
|
}
|
|
157
190
|
return new _LLMError({
|
|
158
|
-
message:
|
|
191
|
+
message: extractMessage(error),
|
|
159
192
|
category: "unknown",
|
|
160
193
|
...context
|
|
161
194
|
});
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
DEFAULT_AGENT_NAME,
|
|
3
|
+
isBlockedModelCall
|
|
4
|
+
} from "./chunk-CJI7PVS2.js";
|
|
4
5
|
import {
|
|
5
6
|
extractModelId,
|
|
6
7
|
extractProvider
|
|
7
8
|
} from "./chunk-I6PKJ7XQ.js";
|
|
9
|
+
import {
|
|
10
|
+
ApprovalDeniedError,
|
|
11
|
+
createApprovalCorrection,
|
|
12
|
+
createApprovalHandler,
|
|
13
|
+
formatApprovalDeniedReason
|
|
14
|
+
} from "./chunk-V4RFNEET.js";
|
|
15
|
+
import {
|
|
16
|
+
silentLogger
|
|
17
|
+
} from "./chunk-T4UIX5D7.js";
|
|
8
18
|
|
|
9
19
|
// src/middleware/runner.ts
|
|
10
|
-
function isBlockedModelCall(value) {
|
|
11
|
-
return "block" in value && value.block === true;
|
|
12
|
-
}
|
|
13
|
-
function logMiddlewareWarning(middlewareName, hook, error) {
|
|
14
|
-
console.warn(
|
|
15
|
-
`[middleware] "${middlewareName}" ${hook} error:`,
|
|
16
|
-
error instanceof Error ? error.message : String(error)
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
20
|
var MiddlewareRunner = class {
|
|
20
21
|
stack;
|
|
21
|
-
|
|
22
|
+
log;
|
|
23
|
+
constructor(middleware = [], logger) {
|
|
22
24
|
this.stack = Object.freeze([...middleware]);
|
|
25
|
+
this.log = logger?.child("middleware") ?? silentLogger;
|
|
23
26
|
}
|
|
24
27
|
/** Number of registered middleware */
|
|
25
28
|
get count() {
|
|
@@ -73,7 +76,7 @@ var MiddlewareRunner = class {
|
|
|
73
76
|
current = next;
|
|
74
77
|
}
|
|
75
78
|
} catch (err) {
|
|
76
|
-
|
|
79
|
+
this.log.warn(`"${mw.name}" model.chunk error: ${err instanceof Error ? err.message : String(err)}`);
|
|
77
80
|
}
|
|
78
81
|
}
|
|
79
82
|
return current ?? void 0;
|
|
@@ -92,7 +95,7 @@ var MiddlewareRunner = class {
|
|
|
92
95
|
current = next;
|
|
93
96
|
}
|
|
94
97
|
} catch (err) {
|
|
95
|
-
|
|
98
|
+
this.log.warn(`"${mw.name}" model.output error: ${err instanceof Error ? err.message : String(err)}`);
|
|
96
99
|
}
|
|
97
100
|
}
|
|
98
101
|
return current;
|
|
@@ -106,15 +109,24 @@ var MiddlewareRunner = class {
|
|
|
106
109
|
* Returns `{ action: "allow" }` if all middleware allow (or have no hook).
|
|
107
110
|
* Returns `{ action: "deny", reason }` on first denial — remaining
|
|
108
111
|
* middleware are skipped.
|
|
112
|
+
*
|
|
113
|
+
* When a middleware rewrites args via `decision.args`, subsequent
|
|
114
|
+
* middleware in the chain receive the rewritten args.
|
|
109
115
|
*/
|
|
110
116
|
async runBeforeToolCall(tool, args, ctx) {
|
|
117
|
+
let currentArgs = args;
|
|
118
|
+
let rewritten = false;
|
|
111
119
|
for (const mw of this.stack) {
|
|
112
120
|
if (!mw.beforeToolCall) continue;
|
|
113
121
|
try {
|
|
114
|
-
const decision = await mw.beforeToolCall(tool,
|
|
122
|
+
const decision = await mw.beforeToolCall(tool, currentArgs, ctx);
|
|
115
123
|
if (decision.action === "deny") {
|
|
116
124
|
return decision;
|
|
117
125
|
}
|
|
126
|
+
if (decision.args !== void 0) {
|
|
127
|
+
currentArgs = decision.args;
|
|
128
|
+
rewritten = true;
|
|
129
|
+
}
|
|
118
130
|
} catch (err) {
|
|
119
131
|
return {
|
|
120
132
|
action: "deny",
|
|
@@ -122,7 +134,7 @@ var MiddlewareRunner = class {
|
|
|
122
134
|
};
|
|
123
135
|
}
|
|
124
136
|
}
|
|
125
|
-
return { action: "allow" };
|
|
137
|
+
return rewritten ? { action: "allow", args: currentArgs } : { action: "allow" };
|
|
126
138
|
}
|
|
127
139
|
// --------------------------------------------------------------------------
|
|
128
140
|
// afterToolCall — reverse order (innermost first)
|
|
@@ -133,6 +145,10 @@ var MiddlewareRunner = class {
|
|
|
133
145
|
* Each hook receives the result from the previous hook (or the
|
|
134
146
|
* original tool result for the first hook). Errors are caught
|
|
135
147
|
* and logged — the original result passes through.
|
|
148
|
+
*
|
|
149
|
+
* Middleware can add a `supplement` to inject extra text the model
|
|
150
|
+
* sees alongside the tool output. Supplements chain naturally —
|
|
151
|
+
* each middleware receives any supplement added by earlier hooks.
|
|
136
152
|
*/
|
|
137
153
|
async runAfterToolCall(tool, args, result, ctx) {
|
|
138
154
|
let current = result;
|
|
@@ -142,7 +158,7 @@ var MiddlewareRunner = class {
|
|
|
142
158
|
try {
|
|
143
159
|
current = await mw.afterToolCall(tool, args, current, ctx);
|
|
144
160
|
} catch (err) {
|
|
145
|
-
|
|
161
|
+
this.log.warn(`"${mw.name}" afterToolCall error: ${err instanceof Error ? err.message : String(err)}`);
|
|
146
162
|
}
|
|
147
163
|
}
|
|
148
164
|
return current;
|
|
@@ -169,7 +185,7 @@ var MiddlewareRunner = class {
|
|
|
169
185
|
sections.push(result);
|
|
170
186
|
}
|
|
171
187
|
} catch (err) {
|
|
172
|
-
|
|
188
|
+
this.log.warn(`"${mw.name}" promptSections error: ${err instanceof Error ? err.message : String(err)}`);
|
|
173
189
|
}
|
|
174
190
|
}
|
|
175
191
|
return sections;
|
|
@@ -196,11 +212,11 @@ var MiddlewareRunner = class {
|
|
|
196
212
|
* Get the OTel context for a session from the telemetry middleware.
|
|
197
213
|
* Returns undefined if no telemetry middleware is registered.
|
|
198
214
|
*/
|
|
199
|
-
getOtelContext(sessionId) {
|
|
215
|
+
getOtelContext(sessionId, ctx) {
|
|
200
216
|
for (const mw of this.stack) {
|
|
201
217
|
if (mw.getOtelContext) {
|
|
202
|
-
const
|
|
203
|
-
if (
|
|
218
|
+
const otelCtx = mw.getOtelContext(sessionId, ctx);
|
|
219
|
+
if (otelCtx) return otelCtx;
|
|
204
220
|
}
|
|
205
221
|
}
|
|
206
222
|
return void 0;
|
|
@@ -214,13 +230,13 @@ var MiddlewareRunner = class {
|
|
|
214
230
|
* Errors are caught and logged — a broken logger should not
|
|
215
231
|
* prevent the chat from starting.
|
|
216
232
|
*/
|
|
217
|
-
async runChatStart(sessionId, message) {
|
|
233
|
+
async runChatStart(sessionId, message, ctx) {
|
|
218
234
|
for (const mw of this.stack) {
|
|
219
235
|
if (!mw.onChatStart) continue;
|
|
220
236
|
try {
|
|
221
|
-
await mw.onChatStart(sessionId, message);
|
|
237
|
+
await mw.onChatStart(sessionId, message, ctx);
|
|
222
238
|
} catch (err) {
|
|
223
|
-
|
|
239
|
+
this.log.warn(`"${mw.name}" onChatStart error: ${err instanceof Error ? err.message : String(err)}`);
|
|
224
240
|
}
|
|
225
241
|
}
|
|
226
242
|
}
|
|
@@ -233,30 +249,49 @@ var MiddlewareRunner = class {
|
|
|
233
249
|
* Always called, even when the stream errored. Errors in handlers
|
|
234
250
|
* are caught and logged.
|
|
235
251
|
*/
|
|
236
|
-
async runChatEnd(sessionId, result) {
|
|
252
|
+
async runChatEnd(sessionId, result, ctx) {
|
|
237
253
|
for (const mw of this.stack) {
|
|
238
254
|
if (!mw.onChatEnd) continue;
|
|
239
255
|
try {
|
|
240
|
-
await mw.onChatEnd(sessionId, result);
|
|
256
|
+
await mw.onChatEnd(sessionId, result, ctx);
|
|
241
257
|
} catch (err) {
|
|
242
|
-
|
|
258
|
+
this.log.warn(`"${mw.name}" onChatEnd error: ${err instanceof Error ? err.message : String(err)}`);
|
|
243
259
|
}
|
|
244
260
|
}
|
|
245
261
|
}
|
|
246
262
|
};
|
|
247
263
|
|
|
248
264
|
// src/middleware/approval.ts
|
|
265
|
+
function isApprovalMiddleware(value) {
|
|
266
|
+
return value.name === "approval" && "approvalHandler" in value && typeof value.approvalHandler === "object" && value.approvalHandler !== null;
|
|
267
|
+
}
|
|
249
268
|
function approvalMiddleware(config = {}) {
|
|
250
269
|
const handler = createApprovalHandler(config);
|
|
251
270
|
return {
|
|
252
271
|
name: "approval",
|
|
272
|
+
approvalHandler: handler,
|
|
273
|
+
...config.customRisks ? { approvalCustomRisks: config.customRisks } : {},
|
|
253
274
|
async beforeToolCall(tool, args, ctx) {
|
|
254
275
|
try {
|
|
255
|
-
await handler.request(
|
|
276
|
+
await handler.request(
|
|
277
|
+
ctx.sessionID,
|
|
278
|
+
tool,
|
|
279
|
+
args,
|
|
280
|
+
config.customRisks,
|
|
281
|
+
ctx.toolCapabilities,
|
|
282
|
+
ctx.permissionPatterns
|
|
283
|
+
);
|
|
256
284
|
return { action: "allow" };
|
|
257
285
|
} catch (err) {
|
|
258
|
-
const reason = err instanceof Error ? err.message :
|
|
259
|
-
return {
|
|
286
|
+
const reason = err instanceof Error ? err.message : formatApprovalDeniedReason(tool);
|
|
287
|
+
return {
|
|
288
|
+
action: "deny",
|
|
289
|
+
reason,
|
|
290
|
+
correction: createApprovalCorrection(
|
|
291
|
+
tool,
|
|
292
|
+
err instanceof ApprovalDeniedError ? err.feedback : void 0
|
|
293
|
+
)
|
|
294
|
+
};
|
|
260
295
|
}
|
|
261
296
|
}
|
|
262
297
|
};
|
|
@@ -264,6 +299,56 @@ function approvalMiddleware(config = {}) {
|
|
|
264
299
|
|
|
265
300
|
// src/middleware/telemetry/otel.ts
|
|
266
301
|
var otelModulePromise;
|
|
302
|
+
function resolveToolCallId(args, ctx) {
|
|
303
|
+
const extraToolCallId = ctx?.extra?.toolCallId;
|
|
304
|
+
if (typeof extraToolCallId === "string" && extraToolCallId.length > 0) {
|
|
305
|
+
return extraToolCallId;
|
|
306
|
+
}
|
|
307
|
+
if (ctx?.messageID) {
|
|
308
|
+
return ctx.messageID;
|
|
309
|
+
}
|
|
310
|
+
try {
|
|
311
|
+
return JSON.stringify(args);
|
|
312
|
+
} catch {
|
|
313
|
+
return String(args);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
function makeToolSpanKey(toolName, toolCallId) {
|
|
317
|
+
return `${toolName}:${toolCallId}`;
|
|
318
|
+
}
|
|
319
|
+
function makeChatSpanKey(sessionId, turnId) {
|
|
320
|
+
return turnId ? `${sessionId}:${turnId}` : sessionId;
|
|
321
|
+
}
|
|
322
|
+
function findChatSpanKey(spans, sessionId, ctx) {
|
|
323
|
+
const exactKey = makeChatSpanKey(sessionId, ctx?.turnId);
|
|
324
|
+
if (spans.has(exactKey)) {
|
|
325
|
+
return exactKey;
|
|
326
|
+
}
|
|
327
|
+
if (!ctx?.turnId && spans.has(sessionId)) {
|
|
328
|
+
return sessionId;
|
|
329
|
+
}
|
|
330
|
+
for (const key of spans.keys()) {
|
|
331
|
+
if (key === sessionId || key.startsWith(`${sessionId}:`)) {
|
|
332
|
+
return key;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return void 0;
|
|
336
|
+
}
|
|
337
|
+
function removeSpanEntry(spans, key) {
|
|
338
|
+
const entry = spans.get(key);
|
|
339
|
+
if (entry) {
|
|
340
|
+
spans.delete(key);
|
|
341
|
+
}
|
|
342
|
+
return entry;
|
|
343
|
+
}
|
|
344
|
+
function findSpanEntryByTool(spans, toolName) {
|
|
345
|
+
for (const [key, entry] of spans) {
|
|
346
|
+
if (key.startsWith(`${toolName}:`)) {
|
|
347
|
+
return [key, entry];
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return void 0;
|
|
351
|
+
}
|
|
267
352
|
function getInputMimeType(value) {
|
|
268
353
|
const trimmed = value.trimStart();
|
|
269
354
|
return trimmed.startsWith("{") || trimmed.startsWith("[") ? "application/json" : "text/plain";
|
|
@@ -292,7 +377,7 @@ function scheduleSpanTimeout(options) {
|
|
|
292
377
|
function otelMiddleware(config = {}) {
|
|
293
378
|
const recordInputs = config.recordInputs ?? true;
|
|
294
379
|
const recordOutputs = config.recordOutputs ?? true;
|
|
295
|
-
const agentName = config.agentName ??
|
|
380
|
+
const agentName = config.agentName ?? DEFAULT_AGENT_NAME;
|
|
296
381
|
const emitToolSpans = config.emitToolSpans ?? true;
|
|
297
382
|
const spanTimeoutMs = config.spanTimeoutMs ?? 5 * 60 * 1e3;
|
|
298
383
|
const chatSpans = /* @__PURE__ */ new Map();
|
|
@@ -303,6 +388,9 @@ function otelMiddleware(config = {}) {
|
|
|
303
388
|
if (tracer) {
|
|
304
389
|
return tracer;
|
|
305
390
|
}
|
|
391
|
+
if (config.providerReady) {
|
|
392
|
+
await config.providerReady;
|
|
393
|
+
}
|
|
306
394
|
otel = await getOtelModule();
|
|
307
395
|
if (!otel) {
|
|
308
396
|
return null;
|
|
@@ -312,20 +400,25 @@ function otelMiddleware(config = {}) {
|
|
|
312
400
|
}
|
|
313
401
|
return {
|
|
314
402
|
name: "opentelemetry",
|
|
315
|
-
getOtelContext(sessionId) {
|
|
316
|
-
|
|
403
|
+
getOtelContext(sessionId, ctx) {
|
|
404
|
+
const key = findChatSpanKey(chatSpans, sessionId, ctx);
|
|
405
|
+
return key ? chatSpans.get(key)?.ctx : void 0;
|
|
317
406
|
},
|
|
318
|
-
async onChatStart(sessionId, message) {
|
|
407
|
+
async onChatStart(sessionId, message, chatCtx) {
|
|
319
408
|
const activeTracer = await ensureTracer();
|
|
320
409
|
if (!activeTracer || !otel) {
|
|
321
410
|
return;
|
|
322
411
|
}
|
|
412
|
+
const key = makeChatSpanKey(sessionId, chatCtx?.turnId);
|
|
323
413
|
const attributes = {
|
|
324
414
|
"openinference.span.kind": "AGENT",
|
|
325
415
|
"gen_ai.operation.name": "invoke_agent",
|
|
326
416
|
"gen_ai.agent.name": agentName,
|
|
327
417
|
"gen_ai.agent.session_id": sessionId
|
|
328
418
|
};
|
|
419
|
+
if (chatCtx?.turnId) {
|
|
420
|
+
attributes["gen_ai.agent.turn_id"] = chatCtx.turnId;
|
|
421
|
+
}
|
|
329
422
|
if (config.agentDescription) {
|
|
330
423
|
attributes["gen_ai.agent.description"] = config.agentDescription;
|
|
331
424
|
}
|
|
@@ -337,13 +430,13 @@ function otelMiddleware(config = {}) {
|
|
|
337
430
|
const span = activeTracer.startSpan(`invoke_agent ${agentName}`, {
|
|
338
431
|
attributes
|
|
339
432
|
});
|
|
340
|
-
const
|
|
341
|
-
chatSpans.set(
|
|
433
|
+
const spanCtx = otel.trace.setSpan(otel.context.active(), span);
|
|
434
|
+
chatSpans.set(key, {
|
|
342
435
|
span,
|
|
343
|
-
ctx,
|
|
436
|
+
ctx: spanCtx,
|
|
344
437
|
timer: scheduleSpanTimeout({
|
|
345
438
|
spans: chatSpans,
|
|
346
|
-
key
|
|
439
|
+
key,
|
|
347
440
|
otel,
|
|
348
441
|
timeoutMs: spanTimeoutMs
|
|
349
442
|
})
|
|
@@ -358,7 +451,10 @@ function otelMiddleware(config = {}) {
|
|
|
358
451
|
return { action: "allow" };
|
|
359
452
|
}
|
|
360
453
|
const sessionId = ctx?.sessionID;
|
|
361
|
-
const
|
|
454
|
+
const parentKey = sessionId ? findChatSpanKey(chatSpans, sessionId, {
|
|
455
|
+
turnId: ctx?.turnID
|
|
456
|
+
}) : void 0;
|
|
457
|
+
const parent = parentKey ? chatSpans.get(parentKey) : void 0;
|
|
362
458
|
const parentCtx = parent?.ctx ?? otel.context.active();
|
|
363
459
|
const span = activeTracer.startSpan(
|
|
364
460
|
`execute_tool ${tool}`,
|
|
@@ -380,8 +476,8 @@ function otelMiddleware(config = {}) {
|
|
|
380
476
|
},
|
|
381
477
|
parentCtx
|
|
382
478
|
);
|
|
383
|
-
const callId =
|
|
384
|
-
const key =
|
|
479
|
+
const callId = resolveToolCallId(args, ctx);
|
|
480
|
+
const key = makeToolSpanKey(tool, callId);
|
|
385
481
|
const toolCtx = otel.trace.setSpan(parentCtx, span);
|
|
386
482
|
toolSpans.set(key, {
|
|
387
483
|
span,
|
|
@@ -396,12 +492,13 @@ function otelMiddleware(config = {}) {
|
|
|
396
492
|
return { action: "allow" };
|
|
397
493
|
},
|
|
398
494
|
async afterToolCall(tool, args, result, ctx) {
|
|
399
|
-
const callId =
|
|
400
|
-
const
|
|
401
|
-
const
|
|
402
|
-
const entry = toolSpans
|
|
403
|
-
([
|
|
404
|
-
|
|
495
|
+
const callId = resolveToolCallId(args, ctx);
|
|
496
|
+
const key = makeToolSpanKey(tool, callId);
|
|
497
|
+
const fallback = findSpanEntryByTool(toolSpans, tool);
|
|
498
|
+
const entry = removeSpanEntry(toolSpans, key) ?? (fallback ? (() => {
|
|
499
|
+
toolSpans.delete(fallback[0]);
|
|
500
|
+
return fallback[1];
|
|
501
|
+
})() : void 0);
|
|
405
502
|
if (entry) {
|
|
406
503
|
if (entry.timer) {
|
|
407
504
|
clearTimeout(entry.timer);
|
|
@@ -414,12 +511,6 @@ function otelMiddleware(config = {}) {
|
|
|
414
511
|
}
|
|
415
512
|
entry.span.setStatus({ code: otel?.SpanStatusCode.OK ?? 1 });
|
|
416
513
|
entry.span.end();
|
|
417
|
-
for (const [candidateKey, candidateEntry] of toolSpans) {
|
|
418
|
-
if (candidateEntry === entry) {
|
|
419
|
-
toolSpans.delete(candidateKey);
|
|
420
|
-
break;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
514
|
}
|
|
424
515
|
return result;
|
|
425
516
|
},
|
|
@@ -427,10 +518,13 @@ function otelMiddleware(config = {}) {
|
|
|
427
518
|
if (event.type !== "tool-error") {
|
|
428
519
|
return;
|
|
429
520
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
521
|
+
const key = makeToolSpanKey(event.toolName, event.toolCallId);
|
|
522
|
+
const fallback = findSpanEntryByTool(toolSpans, event.toolName);
|
|
523
|
+
const entry = removeSpanEntry(toolSpans, key) ?? (fallback ? (() => {
|
|
524
|
+
toolSpans.delete(fallback[0]);
|
|
525
|
+
return fallback[1];
|
|
526
|
+
})() : void 0);
|
|
527
|
+
if (entry) {
|
|
434
528
|
if (entry.timer) {
|
|
435
529
|
clearTimeout(entry.timer);
|
|
436
530
|
}
|
|
@@ -443,12 +537,14 @@ function otelMiddleware(config = {}) {
|
|
|
443
537
|
message: event.error
|
|
444
538
|
});
|
|
445
539
|
entry.span.end();
|
|
446
|
-
toolSpans.delete(key);
|
|
447
|
-
break;
|
|
448
540
|
}
|
|
449
541
|
},
|
|
450
|
-
async onChatEnd(sessionId, result) {
|
|
451
|
-
const
|
|
542
|
+
async onChatEnd(sessionId, result, ctx) {
|
|
543
|
+
const key = findChatSpanKey(chatSpans, sessionId, ctx);
|
|
544
|
+
if (!key) {
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
const entry = chatSpans.get(key);
|
|
452
548
|
if (!entry) {
|
|
453
549
|
return;
|
|
454
550
|
}
|
|
@@ -477,34 +573,38 @@ function otelMiddleware(config = {}) {
|
|
|
477
573
|
entry.span.setStatus({ code: otel?.SpanStatusCode.OK ?? 1 });
|
|
478
574
|
}
|
|
479
575
|
entry.span.end();
|
|
480
|
-
chatSpans.delete(
|
|
576
|
+
chatSpans.delete(key);
|
|
481
577
|
}
|
|
482
578
|
};
|
|
483
579
|
}
|
|
484
580
|
|
|
485
581
|
// src/middleware/telemetry/provider.ts
|
|
582
|
+
var sharedProviderState;
|
|
486
583
|
function createTelemetryConfig(config) {
|
|
584
|
+
const recordInputs = config.recordInputs ?? true;
|
|
585
|
+
const recordOutputs = config.recordOutputs ?? true;
|
|
586
|
+
let providerPromise;
|
|
587
|
+
if (config.spanProcessor) {
|
|
588
|
+
providerPromise = acquireSharedProvider(
|
|
589
|
+
config.spanProcessor,
|
|
590
|
+
config.serviceName ?? config.agentName
|
|
591
|
+
);
|
|
592
|
+
}
|
|
487
593
|
const middleware = otelMiddleware({
|
|
488
594
|
agentName: config.agentName,
|
|
489
595
|
agentDescription: config.agentDescription,
|
|
490
|
-
recordInputs
|
|
491
|
-
recordOutputs
|
|
596
|
+
recordInputs,
|
|
597
|
+
recordOutputs,
|
|
492
598
|
emitToolSpans: config.emitToolSpans,
|
|
493
|
-
spanTimeoutMs: config.spanTimeoutMs
|
|
599
|
+
spanTimeoutMs: config.spanTimeoutMs,
|
|
600
|
+
providerReady: providerPromise
|
|
494
601
|
});
|
|
495
602
|
const telemetry = {
|
|
496
603
|
isEnabled: true,
|
|
497
604
|
functionId: config.agentName,
|
|
498
|
-
recordInputs
|
|
499
|
-
recordOutputs
|
|
605
|
+
recordInputs,
|
|
606
|
+
recordOutputs
|
|
500
607
|
};
|
|
501
|
-
let providerPromise;
|
|
502
|
-
if (config.spanProcessor) {
|
|
503
|
-
providerPromise = createAndRegisterProvider(
|
|
504
|
-
config.spanProcessor,
|
|
505
|
-
config.serviceName ?? config.agentName
|
|
506
|
-
);
|
|
507
|
-
}
|
|
508
608
|
return {
|
|
509
609
|
middleware,
|
|
510
610
|
telemetry,
|
|
@@ -512,12 +612,46 @@ function createTelemetryConfig(config) {
|
|
|
512
612
|
if (!providerPromise) {
|
|
513
613
|
return;
|
|
514
614
|
}
|
|
515
|
-
|
|
516
|
-
await provider.forceFlush();
|
|
517
|
-
await provider.shutdown();
|
|
615
|
+
await releaseSharedProvider(providerPromise);
|
|
518
616
|
}
|
|
519
617
|
};
|
|
520
618
|
}
|
|
619
|
+
function acquireSharedProvider(spanProcessor, serviceName) {
|
|
620
|
+
if (!sharedProviderState) {
|
|
621
|
+
const promise = createAndRegisterProvider(spanProcessor, serviceName).catch(
|
|
622
|
+
(error) => {
|
|
623
|
+
if (sharedProviderState?.promise === promise) {
|
|
624
|
+
sharedProviderState = void 0;
|
|
625
|
+
}
|
|
626
|
+
throw error;
|
|
627
|
+
}
|
|
628
|
+
);
|
|
629
|
+
sharedProviderState = {
|
|
630
|
+
promise,
|
|
631
|
+
refCount: 0
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
sharedProviderState.refCount += 1;
|
|
635
|
+
return sharedProviderState.promise;
|
|
636
|
+
}
|
|
637
|
+
async function releaseSharedProvider(providerPromise) {
|
|
638
|
+
if (!sharedProviderState || sharedProviderState.promise !== providerPromise) {
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
sharedProviderState.refCount -= 1;
|
|
642
|
+
if (sharedProviderState.refCount > 0) {
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
const provider = await providerPromise;
|
|
646
|
+
try {
|
|
647
|
+
await provider.forceFlush();
|
|
648
|
+
await provider.shutdown();
|
|
649
|
+
} finally {
|
|
650
|
+
if (sharedProviderState?.promise === providerPromise) {
|
|
651
|
+
sharedProviderState = void 0;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
}
|
|
521
655
|
async function createAndRegisterProvider(spanProcessor, serviceName) {
|
|
522
656
|
const [{ NodeTracerProvider }, { resourceFromAttributes }, { ATTR_SERVICE_NAME }] = await Promise.all([
|
|
523
657
|
import("@opentelemetry/sdk-trace-node"),
|
|
@@ -630,8 +764,9 @@ function promptCacheMiddleware(config) {
|
|
|
630
764
|
|
|
631
765
|
export {
|
|
632
766
|
MiddlewareRunner,
|
|
767
|
+
isApprovalMiddleware,
|
|
768
|
+
approvalMiddleware,
|
|
633
769
|
otelMiddleware,
|
|
634
770
|
createTelemetryConfig,
|
|
635
|
-
approvalMiddleware,
|
|
636
771
|
promptCacheMiddleware
|
|
637
772
|
};
|
|
@@ -89,11 +89,6 @@ ${end}`;
|
|
|
89
89
|
outputPath
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
|
-
function formatSize(bytes) {
|
|
93
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
94
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
95
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
96
|
-
}
|
|
97
92
|
|
|
98
93
|
// src/tool/tool.ts
|
|
99
94
|
import { z } from "zod";
|
|
@@ -106,13 +101,17 @@ var Tool;
|
|
|
106
101
|
);
|
|
107
102
|
return {
|
|
108
103
|
id,
|
|
104
|
+
capabilitiesHint: options.capabilitiesHint,
|
|
109
105
|
replayPolicy: staticReplayPolicy,
|
|
106
|
+
deferred: options.deferred,
|
|
107
|
+
searchKeywords: options.searchKeywords,
|
|
110
108
|
init: async (initCtx) => {
|
|
111
109
|
const toolInfo = typeof init === "function" ? await init(initCtx) : init;
|
|
112
110
|
const replayPolicy = normalizeToolReplayPolicy(
|
|
113
111
|
toolInfo.replayPolicy ?? staticReplayPolicy,
|
|
114
112
|
toolInfo.fileOps
|
|
115
113
|
);
|
|
114
|
+
const perToolMaxBytes = toolInfo.capabilities?.maxOutputChars;
|
|
116
115
|
const originalExecute = toolInfo.execute;
|
|
117
116
|
const execute = async (params, ctx) => {
|
|
118
117
|
let validated;
|
|
@@ -131,15 +130,18 @@ Please rewrite the input so it satisfies the expected schema.`,
|
|
|
131
130
|
);
|
|
132
131
|
}
|
|
133
132
|
const result = await originalExecute(validated, ctx);
|
|
134
|
-
|
|
133
|
+
const meta = result.metadata ?? {};
|
|
134
|
+
if (meta.truncated !== void 0) {
|
|
135
135
|
return result;
|
|
136
136
|
}
|
|
137
|
-
const truncated = truncateOutput(result.output
|
|
137
|
+
const truncated = truncateOutput(result.output, {
|
|
138
|
+
...perToolMaxBytes !== void 0 ? { maxBytes: perToolMaxBytes } : {}
|
|
139
|
+
});
|
|
138
140
|
return {
|
|
139
141
|
...result,
|
|
140
142
|
output: truncated.content,
|
|
141
143
|
metadata: {
|
|
142
|
-
...
|
|
144
|
+
...meta,
|
|
143
145
|
truncated: truncated.truncated,
|
|
144
146
|
...truncated.truncated && { outputPath: truncated.outputPath }
|
|
145
147
|
}
|
|
@@ -155,29 +157,11 @@ Please rewrite the input so it satisfies the expected schema.`,
|
|
|
155
157
|
}
|
|
156
158
|
Tool2.define = define;
|
|
157
159
|
})(Tool || (Tool = {}));
|
|
158
|
-
function defineTool(definition) {
|
|
159
|
-
return Tool.define(definition.id, {
|
|
160
|
-
description: definition.description,
|
|
161
|
-
parameters: definition.parameters,
|
|
162
|
-
execute: async (params, ctx) => {
|
|
163
|
-
const result = await definition.execute(params, ctx);
|
|
164
|
-
return {
|
|
165
|
-
title: result.title,
|
|
166
|
-
output: result.output,
|
|
167
|
-
metadata: result.metadata ?? {}
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
160
|
|
|
173
161
|
export {
|
|
174
162
|
normalizeToolReplayPolicy,
|
|
175
163
|
MAX_LINES,
|
|
176
164
|
MAX_BYTES,
|
|
177
|
-
TRUNCATE_DIR,
|
|
178
|
-
TRUNCATE_GLOB,
|
|
179
165
|
truncateOutput,
|
|
180
|
-
|
|
181
|
-
Tool,
|
|
182
|
-
defineTool
|
|
166
|
+
Tool
|
|
183
167
|
};
|