@cuylabs/agent-core 0.8.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-CAA7FHIH.js → chunk-6HZBHFOL.js} +3 -103
- package/dist/chunk-CJI7PVS2.js +58 -0
- package/dist/{chunk-N6HWIEEA.js → chunk-CMYN2RCB.js} +278 -61
- package/dist/chunk-FII65CN7.js +117 -0
- package/dist/{chunk-IVUJDISU.js → chunk-GFTW23FV.js} +5 -14
- package/dist/chunk-I6PKJ7XQ.js +292 -0
- package/dist/{chunk-BDBZ3SLK.js → chunk-ICZ66572.js} +48 -4
- package/dist/chunk-KYLPMBHD.js +316 -0
- package/dist/chunk-MXAP4UG6.js +2956 -0
- package/dist/{chunk-RZITT45F.js → chunk-N3VX7FEE.js} +39 -6
- package/dist/{chunk-YSLSEQ6B.js → chunk-NDZWXCBZ.js} +218 -95
- package/dist/{chunk-P6YF7USR.js → chunk-Q742PSH3.js} +23 -38
- package/dist/chunk-QAL3OMI3.js +943 -0
- package/dist/{chunk-RFEKJKTO.js → chunk-RN6WZEUF.js} +330 -280
- package/dist/{chunk-ZXAKHMWH.js → chunk-ROTGCYDW.js} +22 -84
- package/dist/chunk-SPBFQXOT.js +0 -0
- package/dist/{chunk-LRHOS4ZN.js → chunk-SPILYYDF.js} +3 -2
- package/dist/chunk-SSFBF3US.js +602 -0
- package/dist/chunk-SZ2XBPTW.js +8 -0
- package/dist/chunk-T4UIX5D7.js +115 -0
- package/dist/chunk-TIHPYVAJ.js +102 -0
- package/dist/{chunk-YUUJK53A.js → chunk-TOTDGK3P.js} +1 -1
- package/dist/chunk-V4RFNEET.js +563 -0
- package/dist/chunk-VOUEJSW6.js +0 -0
- package/dist/{chunk-4BDA7DQY.js → chunk-WBPOZ7CL.js} +673 -273
- 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 -34
- package/dist/{runtime → execution}/index.js +18 -13
- package/dist/index-BCqEGzBj.d.ts +251 -0
- package/dist/index.d.ts +490 -122
- package/dist/index.js +2104 -615
- package/dist/{errors → inference/errors}/index.d.ts +2 -2
- package/dist/{errors → inference/errors}/index.js +1 -1
- package/dist/inference/index.d.ts +16 -23
- package/dist/inference/index.js +45 -16
- 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 -149
- package/dist/middleware/index.js +11 -3
- package/dist/model-messages-B4nK9D1-.d.ts +13 -0
- package/dist/models/index.d.ts +23 -18
- package/dist/models/index.js +48 -11
- package/dist/models/reasoning/index.d.ts +4 -0
- package/dist/{reasoning → models/reasoning}/index.js +3 -3
- package/dist/plugin/index.d.ts +458 -0
- package/dist/plugin/index.js +32 -0
- package/dist/profiles/index.d.ts +55 -0
- package/dist/profiles/index.js +30 -0
- package/dist/prompt/index.d.ts +8 -12
- package/dist/prompt/index.js +3 -2
- 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 +3 -3
- 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 +125 -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 +58 -53
- package/dist/builder-UpOWQMW3.d.ts +0 -34
- package/dist/chunk-7MUFEN4K.js +0 -559
- package/dist/chunk-7VKQ4WPB.js +0 -73
- package/dist/chunk-BFM2YHNM.js +0 -222
- package/dist/chunk-DWYX7ASF.js +0 -26
- package/dist/chunk-KUVSERLJ.js +0 -50
- package/dist/chunk-N7P4PN3O.js +0 -84
- package/dist/chunk-SDSBEQXG.js +0 -157
- package/dist/chunk-SQU2AJHO.js +0 -305
- package/dist/chunk-VBWWUHWI.js +0 -724
- 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-CWSchSql.d.ts +0 -1058
- package/dist/messages-BYWGn8TY.d.ts +0 -110
- package/dist/presets/index.d.ts +0 -53
- package/dist/presets/index.js +0 -28
- package/dist/reasoning/index.d.ts +0 -116
- package/dist/registry-DwYqsQkX.d.ts +0 -164
- package/dist/runner-e2YRcUoX.d.ts +0 -786
- package/dist/scope/index.d.ts +0 -10
- package/dist/scope/index.js +0 -14
- package/dist/session-manager-B_CWGTsl.d.ts +0 -274
- package/dist/signal/index.d.ts +0 -28
- package/dist/signal/index.js +0 -6
- package/dist/sub-agent/index.d.ts +0 -23
- package/dist/sub-agent/index.js +0 -15
- package/dist/tool-BHbyUAy3.d.ts +0 -150
- package/dist/tool-DLXAR9Ce.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-BnpEOYV-.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-KKDrdU9Y.d.ts +0 -325
- package/dist/types-QA4WhEfz.d.ts +0 -138
- package/dist/types-QKHHQLLq.d.ts +0 -336
- package/dist/types-YuWV4ag7.d.ts +0 -72
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/errors/classify.ts
|
|
1
|
+
// src/inference/errors/classify.ts
|
|
2
2
|
function isRetryableCategory(category) {
|
|
3
3
|
switch (category) {
|
|
4
4
|
case "rate_limit":
|
|
@@ -80,7 +80,7 @@ function parseRetryDelay(headers) {
|
|
|
80
80
|
return void 0;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
// src/errors/extract.ts
|
|
83
|
+
// src/inference/errors/extract.ts
|
|
84
84
|
function extractFromAISDKError(error) {
|
|
85
85
|
const result = {};
|
|
86
86
|
const anyError = error;
|
|
@@ -111,7 +111,31 @@ function extractFromAISDKError(error) {
|
|
|
111
111
|
return result;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
// src/errors/llm-error.ts
|
|
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
|
});
|
|
@@ -171,7 +204,7 @@ var LLMError = class _LLMError extends Error {
|
|
|
171
204
|
}
|
|
172
205
|
};
|
|
173
206
|
|
|
174
|
-
// src/errors/utils.ts
|
|
207
|
+
// src/inference/errors/utils.ts
|
|
175
208
|
function isRetryable(error) {
|
|
176
209
|
if (error instanceof LLMError) {
|
|
177
210
|
return error.isRetryable;
|
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
DEFAULT_AGENT_NAME,
|
|
3
|
+
isBlockedModelCall
|
|
4
|
+
} from "./chunk-CJI7PVS2.js";
|
|
4
5
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "./chunk-
|
|
6
|
+
extractModelId,
|
|
7
|
+
extractProvider
|
|
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
20
|
var MiddlewareRunner = class {
|
|
14
21
|
stack;
|
|
15
|
-
|
|
22
|
+
log;
|
|
23
|
+
constructor(middleware = [], logger) {
|
|
16
24
|
this.stack = Object.freeze([...middleware]);
|
|
25
|
+
this.log = logger?.child("middleware") ?? silentLogger;
|
|
17
26
|
}
|
|
18
27
|
/** Number of registered middleware */
|
|
19
28
|
get count() {
|
|
@@ -67,10 +76,7 @@ var MiddlewareRunner = class {
|
|
|
67
76
|
current = next;
|
|
68
77
|
}
|
|
69
78
|
} catch (err) {
|
|
70
|
-
|
|
71
|
-
`[middleware] "${mw.name}" model.chunk error:`,
|
|
72
|
-
err instanceof Error ? err.message : String(err)
|
|
73
|
-
);
|
|
79
|
+
this.log.warn(`"${mw.name}" model.chunk error: ${err instanceof Error ? err.message : String(err)}`);
|
|
74
80
|
}
|
|
75
81
|
}
|
|
76
82
|
return current ?? void 0;
|
|
@@ -89,10 +95,7 @@ var MiddlewareRunner = class {
|
|
|
89
95
|
current = next;
|
|
90
96
|
}
|
|
91
97
|
} catch (err) {
|
|
92
|
-
|
|
93
|
-
`[middleware] "${mw.name}" model.output error:`,
|
|
94
|
-
err instanceof Error ? err.message : String(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,10 +158,7 @@ var MiddlewareRunner = class {
|
|
|
142
158
|
try {
|
|
143
159
|
current = await mw.afterToolCall(tool, args, current, ctx);
|
|
144
160
|
} catch (err) {
|
|
145
|
-
|
|
146
|
-
`[middleware] "${mw.name}" afterToolCall error:`,
|
|
147
|
-
err instanceof Error ? err.message : String(err)
|
|
148
|
-
);
|
|
161
|
+
this.log.warn(`"${mw.name}" afterToolCall error: ${err instanceof Error ? err.message : String(err)}`);
|
|
149
162
|
}
|
|
150
163
|
}
|
|
151
164
|
return current;
|
|
@@ -172,10 +185,7 @@ var MiddlewareRunner = class {
|
|
|
172
185
|
sections.push(result);
|
|
173
186
|
}
|
|
174
187
|
} catch (err) {
|
|
175
|
-
|
|
176
|
-
`[middleware] "${mw.name}" promptSections error:`,
|
|
177
|
-
err instanceof Error ? err.message : String(err)
|
|
178
|
-
);
|
|
188
|
+
this.log.warn(`"${mw.name}" promptSections error: ${err instanceof Error ? err.message : String(err)}`);
|
|
179
189
|
}
|
|
180
190
|
}
|
|
181
191
|
return sections;
|
|
@@ -202,11 +212,11 @@ var MiddlewareRunner = class {
|
|
|
202
212
|
* Get the OTel context for a session from the telemetry middleware.
|
|
203
213
|
* Returns undefined if no telemetry middleware is registered.
|
|
204
214
|
*/
|
|
205
|
-
getOtelContext(sessionId) {
|
|
215
|
+
getOtelContext(sessionId, ctx) {
|
|
206
216
|
for (const mw of this.stack) {
|
|
207
217
|
if (mw.getOtelContext) {
|
|
208
|
-
const
|
|
209
|
-
if (
|
|
218
|
+
const otelCtx = mw.getOtelContext(sessionId, ctx);
|
|
219
|
+
if (otelCtx) return otelCtx;
|
|
210
220
|
}
|
|
211
221
|
}
|
|
212
222
|
return void 0;
|
|
@@ -220,16 +230,13 @@ var MiddlewareRunner = class {
|
|
|
220
230
|
* Errors are caught and logged — a broken logger should not
|
|
221
231
|
* prevent the chat from starting.
|
|
222
232
|
*/
|
|
223
|
-
async runChatStart(sessionId, message) {
|
|
233
|
+
async runChatStart(sessionId, message, ctx) {
|
|
224
234
|
for (const mw of this.stack) {
|
|
225
235
|
if (!mw.onChatStart) continue;
|
|
226
236
|
try {
|
|
227
|
-
await mw.onChatStart(sessionId, message);
|
|
237
|
+
await mw.onChatStart(sessionId, message, ctx);
|
|
228
238
|
} catch (err) {
|
|
229
|
-
|
|
230
|
-
`[middleware] "${mw.name}" onChatStart error:`,
|
|
231
|
-
err instanceof Error ? err.message : String(err)
|
|
232
|
-
);
|
|
239
|
+
this.log.warn(`"${mw.name}" onChatStart error: ${err instanceof Error ? err.message : String(err)}`);
|
|
233
240
|
}
|
|
234
241
|
}
|
|
235
242
|
}
|
|
@@ -242,33 +249,49 @@ var MiddlewareRunner = class {
|
|
|
242
249
|
* Always called, even when the stream errored. Errors in handlers
|
|
243
250
|
* are caught and logged.
|
|
244
251
|
*/
|
|
245
|
-
async runChatEnd(sessionId, result) {
|
|
252
|
+
async runChatEnd(sessionId, result, ctx) {
|
|
246
253
|
for (const mw of this.stack) {
|
|
247
254
|
if (!mw.onChatEnd) continue;
|
|
248
255
|
try {
|
|
249
|
-
await mw.onChatEnd(sessionId, result);
|
|
256
|
+
await mw.onChatEnd(sessionId, result, ctx);
|
|
250
257
|
} catch (err) {
|
|
251
|
-
|
|
252
|
-
`[middleware] "${mw.name}" onChatEnd error:`,
|
|
253
|
-
err instanceof Error ? err.message : String(err)
|
|
254
|
-
);
|
|
258
|
+
this.log.warn(`"${mw.name}" onChatEnd error: ${err instanceof Error ? err.message : String(err)}`);
|
|
255
259
|
}
|
|
256
260
|
}
|
|
257
261
|
}
|
|
258
262
|
};
|
|
259
263
|
|
|
260
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
|
+
}
|
|
261
268
|
function approvalMiddleware(config = {}) {
|
|
262
269
|
const handler = createApprovalHandler(config);
|
|
263
270
|
return {
|
|
264
271
|
name: "approval",
|
|
272
|
+
approvalHandler: handler,
|
|
273
|
+
...config.customRisks ? { approvalCustomRisks: config.customRisks } : {},
|
|
265
274
|
async beforeToolCall(tool, args, ctx) {
|
|
266
275
|
try {
|
|
267
|
-
await handler.request(
|
|
276
|
+
await handler.request(
|
|
277
|
+
ctx.sessionID,
|
|
278
|
+
tool,
|
|
279
|
+
args,
|
|
280
|
+
config.customRisks,
|
|
281
|
+
ctx.toolCapabilities,
|
|
282
|
+
ctx.permissionPatterns
|
|
283
|
+
);
|
|
268
284
|
return { action: "allow" };
|
|
269
285
|
} catch (err) {
|
|
270
|
-
const reason = err instanceof Error ? err.message :
|
|
271
|
-
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
|
+
};
|
|
272
295
|
}
|
|
273
296
|
}
|
|
274
297
|
};
|
|
@@ -276,6 +299,56 @@ function approvalMiddleware(config = {}) {
|
|
|
276
299
|
|
|
277
300
|
// src/middleware/telemetry/otel.ts
|
|
278
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
|
+
}
|
|
279
352
|
function getInputMimeType(value) {
|
|
280
353
|
const trimmed = value.trimStart();
|
|
281
354
|
return trimmed.startsWith("{") || trimmed.startsWith("[") ? "application/json" : "text/plain";
|
|
@@ -304,7 +377,7 @@ function scheduleSpanTimeout(options) {
|
|
|
304
377
|
function otelMiddleware(config = {}) {
|
|
305
378
|
const recordInputs = config.recordInputs ?? true;
|
|
306
379
|
const recordOutputs = config.recordOutputs ?? true;
|
|
307
|
-
const agentName = config.agentName ??
|
|
380
|
+
const agentName = config.agentName ?? DEFAULT_AGENT_NAME;
|
|
308
381
|
const emitToolSpans = config.emitToolSpans ?? true;
|
|
309
382
|
const spanTimeoutMs = config.spanTimeoutMs ?? 5 * 60 * 1e3;
|
|
310
383
|
const chatSpans = /* @__PURE__ */ new Map();
|
|
@@ -315,6 +388,9 @@ function otelMiddleware(config = {}) {
|
|
|
315
388
|
if (tracer) {
|
|
316
389
|
return tracer;
|
|
317
390
|
}
|
|
391
|
+
if (config.providerReady) {
|
|
392
|
+
await config.providerReady;
|
|
393
|
+
}
|
|
318
394
|
otel = await getOtelModule();
|
|
319
395
|
if (!otel) {
|
|
320
396
|
return null;
|
|
@@ -324,20 +400,25 @@ function otelMiddleware(config = {}) {
|
|
|
324
400
|
}
|
|
325
401
|
return {
|
|
326
402
|
name: "opentelemetry",
|
|
327
|
-
getOtelContext(sessionId) {
|
|
328
|
-
|
|
403
|
+
getOtelContext(sessionId, ctx) {
|
|
404
|
+
const key = findChatSpanKey(chatSpans, sessionId, ctx);
|
|
405
|
+
return key ? chatSpans.get(key)?.ctx : void 0;
|
|
329
406
|
},
|
|
330
|
-
async onChatStart(sessionId, message) {
|
|
407
|
+
async onChatStart(sessionId, message, chatCtx) {
|
|
331
408
|
const activeTracer = await ensureTracer();
|
|
332
409
|
if (!activeTracer || !otel) {
|
|
333
410
|
return;
|
|
334
411
|
}
|
|
412
|
+
const key = makeChatSpanKey(sessionId, chatCtx?.turnId);
|
|
335
413
|
const attributes = {
|
|
336
414
|
"openinference.span.kind": "AGENT",
|
|
337
415
|
"gen_ai.operation.name": "invoke_agent",
|
|
338
416
|
"gen_ai.agent.name": agentName,
|
|
339
417
|
"gen_ai.agent.session_id": sessionId
|
|
340
418
|
};
|
|
419
|
+
if (chatCtx?.turnId) {
|
|
420
|
+
attributes["gen_ai.agent.turn_id"] = chatCtx.turnId;
|
|
421
|
+
}
|
|
341
422
|
if (config.agentDescription) {
|
|
342
423
|
attributes["gen_ai.agent.description"] = config.agentDescription;
|
|
343
424
|
}
|
|
@@ -349,13 +430,13 @@ function otelMiddleware(config = {}) {
|
|
|
349
430
|
const span = activeTracer.startSpan(`invoke_agent ${agentName}`, {
|
|
350
431
|
attributes
|
|
351
432
|
});
|
|
352
|
-
const
|
|
353
|
-
chatSpans.set(
|
|
433
|
+
const spanCtx = otel.trace.setSpan(otel.context.active(), span);
|
|
434
|
+
chatSpans.set(key, {
|
|
354
435
|
span,
|
|
355
|
-
ctx,
|
|
436
|
+
ctx: spanCtx,
|
|
356
437
|
timer: scheduleSpanTimeout({
|
|
357
438
|
spans: chatSpans,
|
|
358
|
-
key
|
|
439
|
+
key,
|
|
359
440
|
otel,
|
|
360
441
|
timeoutMs: spanTimeoutMs
|
|
361
442
|
})
|
|
@@ -370,7 +451,10 @@ function otelMiddleware(config = {}) {
|
|
|
370
451
|
return { action: "allow" };
|
|
371
452
|
}
|
|
372
453
|
const sessionId = ctx?.sessionID;
|
|
373
|
-
const
|
|
454
|
+
const parentKey = sessionId ? findChatSpanKey(chatSpans, sessionId, {
|
|
455
|
+
turnId: ctx?.turnID
|
|
456
|
+
}) : void 0;
|
|
457
|
+
const parent = parentKey ? chatSpans.get(parentKey) : void 0;
|
|
374
458
|
const parentCtx = parent?.ctx ?? otel.context.active();
|
|
375
459
|
const span = activeTracer.startSpan(
|
|
376
460
|
`execute_tool ${tool}`,
|
|
@@ -392,8 +476,8 @@ function otelMiddleware(config = {}) {
|
|
|
392
476
|
},
|
|
393
477
|
parentCtx
|
|
394
478
|
);
|
|
395
|
-
const callId =
|
|
396
|
-
const key =
|
|
479
|
+
const callId = resolveToolCallId(args, ctx);
|
|
480
|
+
const key = makeToolSpanKey(tool, callId);
|
|
397
481
|
const toolCtx = otel.trace.setSpan(parentCtx, span);
|
|
398
482
|
toolSpans.set(key, {
|
|
399
483
|
span,
|
|
@@ -408,12 +492,13 @@ function otelMiddleware(config = {}) {
|
|
|
408
492
|
return { action: "allow" };
|
|
409
493
|
},
|
|
410
494
|
async afterToolCall(tool, args, result, ctx) {
|
|
411
|
-
const callId =
|
|
412
|
-
const
|
|
413
|
-
const
|
|
414
|
-
const entry = toolSpans
|
|
415
|
-
([
|
|
416
|
-
|
|
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);
|
|
417
502
|
if (entry) {
|
|
418
503
|
if (entry.timer) {
|
|
419
504
|
clearTimeout(entry.timer);
|
|
@@ -426,12 +511,6 @@ function otelMiddleware(config = {}) {
|
|
|
426
511
|
}
|
|
427
512
|
entry.span.setStatus({ code: otel?.SpanStatusCode.OK ?? 1 });
|
|
428
513
|
entry.span.end();
|
|
429
|
-
for (const [candidateKey, candidateEntry] of toolSpans) {
|
|
430
|
-
if (candidateEntry === entry) {
|
|
431
|
-
toolSpans.delete(candidateKey);
|
|
432
|
-
break;
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
514
|
}
|
|
436
515
|
return result;
|
|
437
516
|
},
|
|
@@ -439,10 +518,13 @@ function otelMiddleware(config = {}) {
|
|
|
439
518
|
if (event.type !== "tool-error") {
|
|
440
519
|
return;
|
|
441
520
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
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) {
|
|
446
528
|
if (entry.timer) {
|
|
447
529
|
clearTimeout(entry.timer);
|
|
448
530
|
}
|
|
@@ -455,12 +537,14 @@ function otelMiddleware(config = {}) {
|
|
|
455
537
|
message: event.error
|
|
456
538
|
});
|
|
457
539
|
entry.span.end();
|
|
458
|
-
toolSpans.delete(key);
|
|
459
|
-
break;
|
|
460
540
|
}
|
|
461
541
|
},
|
|
462
|
-
async onChatEnd(sessionId, result) {
|
|
463
|
-
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);
|
|
464
548
|
if (!entry) {
|
|
465
549
|
return;
|
|
466
550
|
}
|
|
@@ -489,34 +573,38 @@ function otelMiddleware(config = {}) {
|
|
|
489
573
|
entry.span.setStatus({ code: otel?.SpanStatusCode.OK ?? 1 });
|
|
490
574
|
}
|
|
491
575
|
entry.span.end();
|
|
492
|
-
chatSpans.delete(
|
|
576
|
+
chatSpans.delete(key);
|
|
493
577
|
}
|
|
494
578
|
};
|
|
495
579
|
}
|
|
496
580
|
|
|
497
581
|
// src/middleware/telemetry/provider.ts
|
|
582
|
+
var sharedProviderState;
|
|
498
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
|
+
}
|
|
499
593
|
const middleware = otelMiddleware({
|
|
500
594
|
agentName: config.agentName,
|
|
501
595
|
agentDescription: config.agentDescription,
|
|
502
|
-
recordInputs
|
|
503
|
-
recordOutputs
|
|
596
|
+
recordInputs,
|
|
597
|
+
recordOutputs,
|
|
504
598
|
emitToolSpans: config.emitToolSpans,
|
|
505
|
-
spanTimeoutMs: config.spanTimeoutMs
|
|
599
|
+
spanTimeoutMs: config.spanTimeoutMs,
|
|
600
|
+
providerReady: providerPromise
|
|
506
601
|
});
|
|
507
602
|
const telemetry = {
|
|
508
603
|
isEnabled: true,
|
|
509
604
|
functionId: config.agentName,
|
|
510
|
-
recordInputs
|
|
511
|
-
recordOutputs
|
|
605
|
+
recordInputs,
|
|
606
|
+
recordOutputs
|
|
512
607
|
};
|
|
513
|
-
let providerPromise;
|
|
514
|
-
if (config.spanProcessor) {
|
|
515
|
-
providerPromise = createAndRegisterProvider(
|
|
516
|
-
config.spanProcessor,
|
|
517
|
-
config.serviceName ?? config.agentName
|
|
518
|
-
);
|
|
519
|
-
}
|
|
520
608
|
return {
|
|
521
609
|
middleware,
|
|
522
610
|
telemetry,
|
|
@@ -524,12 +612,46 @@ function createTelemetryConfig(config) {
|
|
|
524
612
|
if (!providerPromise) {
|
|
525
613
|
return;
|
|
526
614
|
}
|
|
527
|
-
|
|
528
|
-
await provider.forceFlush();
|
|
529
|
-
await provider.shutdown();
|
|
615
|
+
await releaseSharedProvider(providerPromise);
|
|
530
616
|
}
|
|
531
617
|
};
|
|
532
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
|
+
}
|
|
533
655
|
async function createAndRegisterProvider(spanProcessor, serviceName) {
|
|
534
656
|
const [{ NodeTracerProvider }, { resourceFromAttributes }, { ATTR_SERVICE_NAME }] = await Promise.all([
|
|
535
657
|
import("@opentelemetry/sdk-trace-node"),
|
|
@@ -547,14 +669,14 @@ async function createAndRegisterProvider(spanProcessor, serviceName) {
|
|
|
547
669
|
|
|
548
670
|
// src/middleware/prompt-cache/cache.ts
|
|
549
671
|
function detectCacheProvider(input) {
|
|
550
|
-
const provider =
|
|
672
|
+
const provider = extractProvider(input.model);
|
|
551
673
|
if (provider) {
|
|
552
674
|
const p = provider.toLowerCase();
|
|
553
675
|
if (p === "anthropic") return "anthropic";
|
|
554
676
|
if (p === "openai") return "openai";
|
|
555
677
|
if (p === "google") return "google";
|
|
556
678
|
}
|
|
557
|
-
const modelId =
|
|
679
|
+
const modelId = extractModelId(input.model);
|
|
558
680
|
if (/claude/i.test(modelId)) return "anthropic";
|
|
559
681
|
return "unknown";
|
|
560
682
|
}
|
|
@@ -642,8 +764,9 @@ function promptCacheMiddleware(config) {
|
|
|
642
764
|
|
|
643
765
|
export {
|
|
644
766
|
MiddlewareRunner,
|
|
767
|
+
isApprovalMiddleware,
|
|
768
|
+
approvalMiddleware,
|
|
645
769
|
otelMiddleware,
|
|
646
770
|
createTelemetryConfig,
|
|
647
|
-
approvalMiddleware,
|
|
648
771
|
promptCacheMiddleware
|
|
649
772
|
};
|