neatlogs 1.1.2 → 1.1.5
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/dist/browser.cjs +11 -11
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +15 -15
- package/dist/browser.mjs +11 -11
- package/dist/browser.mjs.map +1 -1
- package/dist/google-genai.cjs +640 -0
- package/dist/google-genai.cjs.map +1 -0
- package/dist/google-genai.d.ts +42 -0
- package/dist/google-genai.mjs +622 -0
- package/dist/google-genai.mjs.map +1 -0
- package/dist/index.cjs +746 -346
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.mjs +745 -348
- package/dist/index.mjs.map +1 -1
- package/dist/opencode-plugin.cjs +1 -1
- package/dist/opencode-plugin.cjs.map +1 -1
- package/dist/opencode-plugin.mjs +1 -1
- package/dist/opencode-plugin.mjs.map +1 -1
- package/package.json +12 -1
package/dist/index.mjs
CHANGED
|
@@ -2136,9 +2136,84 @@ function applyMask(spanData, globalMask) {
|
|
|
2136
2136
|
}
|
|
2137
2137
|
}
|
|
2138
2138
|
|
|
2139
|
-
// src/
|
|
2139
|
+
// src/core/identity.ts
|
|
2140
2140
|
import { AsyncLocalStorage } from "async_hooks";
|
|
2141
|
-
var
|
|
2141
|
+
var _GLOBAL_KEY = /* @__PURE__ */ Symbol.for("neatlogs.identity.storage");
|
|
2142
|
+
var _g = globalThis;
|
|
2143
|
+
var _storage = _g[_GLOBAL_KEY] ?? (_g[_GLOBAL_KEY] = new AsyncLocalStorage());
|
|
2144
|
+
function currentSessionId() {
|
|
2145
|
+
return _storage.getStore()?.sessionId;
|
|
2146
|
+
}
|
|
2147
|
+
function currentEndUserId() {
|
|
2148
|
+
return _storage.getStore()?.endUserId;
|
|
2149
|
+
}
|
|
2150
|
+
function currentEndUserMetadata() {
|
|
2151
|
+
return _storage.getStore()?.endUserMetadata;
|
|
2152
|
+
}
|
|
2153
|
+
function identify(opts, fn) {
|
|
2154
|
+
const prev = _storage.getStore();
|
|
2155
|
+
const next = { ...prev ?? {} };
|
|
2156
|
+
if (opts.sessionId !== void 0) next.sessionId = opts.sessionId;
|
|
2157
|
+
if (opts.endUserId !== void 0) next.endUserId = opts.endUserId;
|
|
2158
|
+
if (opts.endUserMetadata !== void 0) next.endUserMetadata = opts.endUserMetadata;
|
|
2159
|
+
return _storage.run(next, fn);
|
|
2160
|
+
}
|
|
2161
|
+
|
|
2162
|
+
// src/core/session.ts
|
|
2163
|
+
var logger4 = getLogger();
|
|
2164
|
+
var SESSION_ID_KEY = "neatlogs.session.id";
|
|
2165
|
+
function applySessionAttributes(span2, sessionId, isRoot = true) {
|
|
2166
|
+
const resolved = isRoot ? sessionId ?? currentSessionId() : sessionId;
|
|
2167
|
+
if (!resolved) return;
|
|
2168
|
+
if (!isRoot) {
|
|
2169
|
+
logger4.debug(
|
|
2170
|
+
"[session] Ignoring sessionId on a non-root span \u2014 declare it on the trace root (top-level trace()/span()) or identify()."
|
|
2171
|
+
);
|
|
2172
|
+
return;
|
|
2173
|
+
}
|
|
2174
|
+
span2.setAttribute(SESSION_ID_KEY, String(resolved));
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
// src/core/end-user.ts
|
|
2178
|
+
import { trace as otelTrace, context as otelContext } from "@opentelemetry/api";
|
|
2179
|
+
var logger5 = getLogger();
|
|
2180
|
+
var END_USER_ID_KEY = "neatlogs.end_user.id";
|
|
2181
|
+
var END_USER_METADATA_KEY = "neatlogs.end_user.metadata";
|
|
2182
|
+
function normalizeEndUserMetadata(metadata) {
|
|
2183
|
+
if (metadata === void 0 || metadata === null) return void 0;
|
|
2184
|
+
if (typeof metadata === "string") return metadata || void 0;
|
|
2185
|
+
try {
|
|
2186
|
+
return JSON.stringify(metadata);
|
|
2187
|
+
} catch {
|
|
2188
|
+
return JSON.stringify(String(metadata));
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
function isRootSpan() {
|
|
2192
|
+
const current = otelTrace.getSpan(otelContext.active());
|
|
2193
|
+
return !(current && current.isRecording());
|
|
2194
|
+
}
|
|
2195
|
+
function applyEndUserAttributes(span2, endUserId, endUserMetadata, isRoot = true) {
|
|
2196
|
+
const resolvedId = isRoot ? endUserId ?? currentEndUserId() : endUserId;
|
|
2197
|
+
const resolvedMeta = isRoot ? endUserMetadata ?? currentEndUserMetadata() : endUserMetadata;
|
|
2198
|
+
if (!resolvedId && !resolvedMeta) return;
|
|
2199
|
+
if (!isRoot) {
|
|
2200
|
+
logger5.debug(
|
|
2201
|
+
"[end_user] Ignoring endUserId/endUserMetadata on a non-root span \u2014 declare it on the trace root (top-level trace()/span()) or identify()."
|
|
2202
|
+
);
|
|
2203
|
+
return;
|
|
2204
|
+
}
|
|
2205
|
+
if (resolvedId) {
|
|
2206
|
+
span2.setAttribute(END_USER_ID_KEY, String(resolvedId));
|
|
2207
|
+
}
|
|
2208
|
+
const metaJson = normalizeEndUserMetadata(resolvedMeta);
|
|
2209
|
+
if (metaJson) {
|
|
2210
|
+
span2.setAttribute(END_USER_METADATA_KEY, metaJson);
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
// src/prompt/template.ts
|
|
2215
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
2216
|
+
var _promptStorage = new AsyncLocalStorage2();
|
|
2142
2217
|
var PromptContext = class {
|
|
2143
2218
|
/**
|
|
2144
2219
|
* Store system prompt template and variables in context.
|
|
@@ -2165,7 +2240,7 @@ var PromptContext = class {
|
|
|
2165
2240
|
_promptStorage.enterWith(void 0);
|
|
2166
2241
|
}
|
|
2167
2242
|
};
|
|
2168
|
-
var _userPromptStorage = new
|
|
2243
|
+
var _userPromptStorage = new AsyncLocalStorage2();
|
|
2169
2244
|
var UserPromptContext = class {
|
|
2170
2245
|
/**
|
|
2171
2246
|
* Store user prompt template and variables in context.
|
|
@@ -2297,83 +2372,6 @@ import {
|
|
|
2297
2372
|
SpanStatusCode as SpanStatusCode2
|
|
2298
2373
|
} from "@opentelemetry/api";
|
|
2299
2374
|
|
|
2300
|
-
// src/core/end-user.ts
|
|
2301
|
-
import { trace as otelTrace, context as otelContext } from "@opentelemetry/api";
|
|
2302
|
-
|
|
2303
|
-
// src/core/identity.ts
|
|
2304
|
-
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
2305
|
-
var _GLOBAL_KEY = /* @__PURE__ */ Symbol.for("neatlogs.identity.storage");
|
|
2306
|
-
var _g = globalThis;
|
|
2307
|
-
var _storage = _g[_GLOBAL_KEY] ?? (_g[_GLOBAL_KEY] = new AsyncLocalStorage2());
|
|
2308
|
-
function currentSessionId() {
|
|
2309
|
-
return _storage.getStore()?.sessionId;
|
|
2310
|
-
}
|
|
2311
|
-
function currentEndUserId() {
|
|
2312
|
-
return _storage.getStore()?.endUserId;
|
|
2313
|
-
}
|
|
2314
|
-
function currentEndUserMetadata() {
|
|
2315
|
-
return _storage.getStore()?.endUserMetadata;
|
|
2316
|
-
}
|
|
2317
|
-
function identify(opts, fn) {
|
|
2318
|
-
const prev = _storage.getStore();
|
|
2319
|
-
const next = { ...prev ?? {} };
|
|
2320
|
-
if (opts.sessionId !== void 0) next.sessionId = opts.sessionId;
|
|
2321
|
-
if (opts.endUserId !== void 0) next.endUserId = opts.endUserId;
|
|
2322
|
-
if (opts.endUserMetadata !== void 0) next.endUserMetadata = opts.endUserMetadata;
|
|
2323
|
-
return _storage.run(next, fn);
|
|
2324
|
-
}
|
|
2325
|
-
|
|
2326
|
-
// src/core/end-user.ts
|
|
2327
|
-
var logger4 = getLogger();
|
|
2328
|
-
var END_USER_ID_KEY = "neatlogs.end_user.id";
|
|
2329
|
-
var END_USER_METADATA_KEY = "neatlogs.end_user.metadata";
|
|
2330
|
-
function normalizeEndUserMetadata(metadata) {
|
|
2331
|
-
if (metadata === void 0 || metadata === null) return void 0;
|
|
2332
|
-
if (typeof metadata === "string") return metadata || void 0;
|
|
2333
|
-
try {
|
|
2334
|
-
return JSON.stringify(metadata);
|
|
2335
|
-
} catch {
|
|
2336
|
-
return JSON.stringify(String(metadata));
|
|
2337
|
-
}
|
|
2338
|
-
}
|
|
2339
|
-
function isRootSpan() {
|
|
2340
|
-
const current = otelTrace.getSpan(otelContext.active());
|
|
2341
|
-
return !(current && current.isRecording());
|
|
2342
|
-
}
|
|
2343
|
-
function applyEndUserAttributes(span2, endUserId, endUserMetadata, isRoot = true) {
|
|
2344
|
-
const resolvedId = isRoot ? endUserId ?? currentEndUserId() : endUserId;
|
|
2345
|
-
const resolvedMeta = isRoot ? endUserMetadata ?? currentEndUserMetadata() : endUserMetadata;
|
|
2346
|
-
if (!resolvedId && !resolvedMeta) return;
|
|
2347
|
-
if (!isRoot) {
|
|
2348
|
-
logger4.debug(
|
|
2349
|
-
"[end_user] Ignoring endUserId/endUserMetadata on a non-root span \u2014 declare it on the trace root (top-level trace()/span()) or identify()."
|
|
2350
|
-
);
|
|
2351
|
-
return;
|
|
2352
|
-
}
|
|
2353
|
-
if (resolvedId) {
|
|
2354
|
-
span2.setAttribute(END_USER_ID_KEY, String(resolvedId));
|
|
2355
|
-
}
|
|
2356
|
-
const metaJson = normalizeEndUserMetadata(resolvedMeta);
|
|
2357
|
-
if (metaJson) {
|
|
2358
|
-
span2.setAttribute(END_USER_METADATA_KEY, metaJson);
|
|
2359
|
-
}
|
|
2360
|
-
}
|
|
2361
|
-
|
|
2362
|
-
// src/core/session.ts
|
|
2363
|
-
var logger5 = getLogger();
|
|
2364
|
-
var SESSION_ID_KEY = "neatlogs.session.id";
|
|
2365
|
-
function applySessionAttributes(span2, sessionId, isRoot = true) {
|
|
2366
|
-
const resolved = isRoot ? sessionId ?? currentSessionId() : sessionId;
|
|
2367
|
-
if (!resolved) return;
|
|
2368
|
-
if (!isRoot) {
|
|
2369
|
-
logger5.debug(
|
|
2370
|
-
"[session] Ignoring sessionId on a non-root span \u2014 declare it on the trace root (top-level trace()/span()) or identify()."
|
|
2371
|
-
);
|
|
2372
|
-
return;
|
|
2373
|
-
}
|
|
2374
|
-
span2.setAttribute(SESSION_ID_KEY, String(resolved));
|
|
2375
|
-
}
|
|
2376
|
-
|
|
2377
2375
|
// src/decorators/base.ts
|
|
2378
2376
|
import { trace, SpanStatusCode } from "@opentelemetry/api";
|
|
2379
2377
|
var logger6 = getLogger();
|
|
@@ -4351,6 +4349,10 @@ var NeatlogsSpanProcessor = class {
|
|
|
4351
4349
|
onStart(span2, parentContext) {
|
|
4352
4350
|
const startTime = performance.now();
|
|
4353
4351
|
try {
|
|
4352
|
+
if (!span2.parentSpanId) {
|
|
4353
|
+
applySessionAttributes(span2, void 0, true);
|
|
4354
|
+
applyEndUserAttributes(span2, void 0, void 0, true);
|
|
4355
|
+
}
|
|
4354
4356
|
const attrs = span2.attributes ?? {};
|
|
4355
4357
|
const spanKind = attrs["openinference.span.kind"];
|
|
4356
4358
|
const spanName = typeof span2.name === "string" ? span2.name : "";
|
|
@@ -5743,7 +5745,7 @@ async function removeTag(name, tag) {
|
|
|
5743
5745
|
}
|
|
5744
5746
|
|
|
5745
5747
|
// src/version.ts
|
|
5746
|
-
var __version__ = "1.1.
|
|
5748
|
+
var __version__ = "1.1.5";
|
|
5747
5749
|
|
|
5748
5750
|
// src/init.ts
|
|
5749
5751
|
var logger13 = getLogger();
|
|
@@ -7807,10 +7809,14 @@ function recordError4(span2, err) {
|
|
|
7807
7809
|
span2.end();
|
|
7808
7810
|
}
|
|
7809
7811
|
|
|
7810
|
-
// src/
|
|
7812
|
+
// src/google-genai.ts
|
|
7811
7813
|
import { trace as trace10, context as otelContext10, SpanStatusCode as SpanStatusCode9 } from "@opentelemetry/api";
|
|
7812
|
-
var TRACER_NAME7 = "neatlogs.
|
|
7813
|
-
var PROVIDER3 = "
|
|
7814
|
+
var TRACER_NAME7 = "neatlogs.google_genai";
|
|
7815
|
+
var PROVIDER3 = "google";
|
|
7816
|
+
var SYSTEM3 = "google_genai";
|
|
7817
|
+
function wrapGoogleGenAI(client) {
|
|
7818
|
+
return wrapNamespace5(client, []);
|
|
7819
|
+
}
|
|
7814
7820
|
function traceTool5(name, fn) {
|
|
7815
7821
|
return async function tracedTool(args) {
|
|
7816
7822
|
const tracer = getProviderTracer(TRACER_NAME7);
|
|
@@ -7840,65 +7846,78 @@ function traceTool5(name, fn) {
|
|
|
7840
7846
|
);
|
|
7841
7847
|
};
|
|
7842
7848
|
}
|
|
7843
|
-
function
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7849
|
+
function wrapNamespace5(target, path3) {
|
|
7850
|
+
return new Proxy(target, {
|
|
7851
|
+
get(obj, prop, receiver) {
|
|
7852
|
+
const value = Reflect.get(obj, prop, receiver);
|
|
7853
|
+
if (typeof prop === "symbol" || String(prop).startsWith("_")) return value;
|
|
7854
|
+
const currentPath = [...path3, String(prop)];
|
|
7855
|
+
const pathStr = currentPath.join(".");
|
|
7856
|
+
if (pathStr === "models.generateContent" && typeof value === "function") {
|
|
7857
|
+
return tracedGenerateContent2(value.bind(obj), false);
|
|
7858
|
+
}
|
|
7859
|
+
if (pathStr === "models.generateContentStream" && typeof value === "function") {
|
|
7860
|
+
return tracedGenerateContent2(value.bind(obj), true);
|
|
7861
|
+
}
|
|
7862
|
+
if (pathStr === "models.embedContent" && typeof value === "function") {
|
|
7863
|
+
return tracedEmbedContent2(value.bind(obj));
|
|
7864
|
+
}
|
|
7865
|
+
if (pathStr === "models.countTokens" && typeof value === "function") {
|
|
7866
|
+
return tracedCountTokens2(value.bind(obj));
|
|
7867
|
+
}
|
|
7868
|
+
if (value && typeof value === "object" && !Array.isArray(value) && isNamespace5(currentPath)) {
|
|
7869
|
+
return wrapNamespace5(value, currentPath);
|
|
7870
|
+
}
|
|
7871
|
+
return value;
|
|
7862
7872
|
}
|
|
7863
|
-
|
|
7864
|
-
};
|
|
7865
|
-
c._neatlogsBedrockPatched = true;
|
|
7866
|
-
return client;
|
|
7873
|
+
});
|
|
7867
7874
|
}
|
|
7868
|
-
function
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7875
|
+
function isNamespace5(path3) {
|
|
7876
|
+
if (path3.length > 2) return false;
|
|
7877
|
+
return ["models", "chats"].includes(path3[path3.length - 1]);
|
|
7878
|
+
}
|
|
7879
|
+
function wrapGoogleGenAIChat(chat) {
|
|
7880
|
+
const c = chat;
|
|
7881
|
+
if (!c || c._neatlogsGoogleGenAIPatched) return chat;
|
|
7882
|
+
if (typeof c.sendMessage === "function") {
|
|
7883
|
+
const orig = c.sendMessage.bind(c);
|
|
7884
|
+
c.sendMessage = (params, ...rest) => tracedChatSend2(orig, c, params, rest, false);
|
|
7872
7885
|
}
|
|
7873
|
-
|
|
7874
|
-
|
|
7886
|
+
if (typeof c.sendMessageStream === "function") {
|
|
7887
|
+
const orig = c.sendMessageStream.bind(c);
|
|
7888
|
+
c.sendMessageStream = (params, ...rest) => tracedChatSend2(orig, c, params, rest, true);
|
|
7889
|
+
}
|
|
7890
|
+
try {
|
|
7891
|
+
Object.defineProperty(c, "_neatlogsGoogleGenAIPatched", { value: true, enumerable: false, configurable: true });
|
|
7892
|
+
} catch {
|
|
7893
|
+
c._neatlogsGoogleGenAIPatched = true;
|
|
7894
|
+
}
|
|
7895
|
+
return chat;
|
|
7875
7896
|
}
|
|
7876
|
-
function
|
|
7877
|
-
|
|
7897
|
+
function tracedChatSend2(original, chat, params, rest, isStream) {
|
|
7898
|
+
const tracer = getProviderTracer(TRACER_NAME7);
|
|
7899
|
+
const model = chat?.model ?? chat?.modelVersion ?? "";
|
|
7900
|
+
const span2 = tracer.startSpan("google_genai.chat.send_message", {
|
|
7878
7901
|
attributes: {
|
|
7879
7902
|
"neatlogs.span.kind": "LLM",
|
|
7880
7903
|
"neatlogs.llm.provider": PROVIDER3,
|
|
7881
|
-
"neatlogs.llm.system":
|
|
7882
|
-
"neatlogs.llm.model_name":
|
|
7904
|
+
"neatlogs.llm.system": SYSTEM3,
|
|
7905
|
+
"neatlogs.llm.model_name": model,
|
|
7883
7906
|
"neatlogs.llm.is_streaming": isStream
|
|
7884
7907
|
}
|
|
7885
7908
|
}, otelContext10.active());
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
isStream
|
|
7909
|
+
const message = params?.message ?? params;
|
|
7910
|
+
span2.setAttribute("neatlogs.llm.input_messages.0.role", "user");
|
|
7911
|
+
span2.setAttribute(
|
|
7912
|
+
"neatlogs.llm.input_messages.0.content",
|
|
7913
|
+
typeof message === "string" ? message : safeStringify7(message)
|
|
7892
7914
|
);
|
|
7893
|
-
setConverseInput(span2, input);
|
|
7894
7915
|
const ctx = trace10.setSpan(otelContext10.active(), span2);
|
|
7895
|
-
const
|
|
7896
|
-
return
|
|
7916
|
+
const result = otelContext10.with(ctx, () => original(params, ...rest));
|
|
7917
|
+
return Promise.resolve(result).then(
|
|
7897
7918
|
(response) => {
|
|
7898
|
-
if (isStream)
|
|
7899
|
-
|
|
7900
|
-
}
|
|
7901
|
-
finalizeConverse(span2, response);
|
|
7919
|
+
if (isStream) return wrapStream2(response, span2);
|
|
7920
|
+
finalizeResponse2(span2, response);
|
|
7902
7921
|
return response;
|
|
7903
7922
|
},
|
|
7904
7923
|
(err) => {
|
|
@@ -7907,43 +7926,418 @@ function tracedConverse(originalSend, command, input, rest, isStream) {
|
|
|
7907
7926
|
}
|
|
7908
7927
|
);
|
|
7909
7928
|
}
|
|
7910
|
-
function
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
const
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
+
function tracedEmbedContent2(original) {
|
|
7930
|
+
return function(opts, ...rest) {
|
|
7931
|
+
const tracer = getProviderTracer(TRACER_NAME7);
|
|
7932
|
+
const span2 = tracer.startSpan("google_genai.models.embed_content", {
|
|
7933
|
+
attributes: {
|
|
7934
|
+
"neatlogs.span.kind": "EMBEDDING",
|
|
7935
|
+
"neatlogs.llm.provider": PROVIDER3,
|
|
7936
|
+
"neatlogs.embedding.model_name": opts?.model ?? "",
|
|
7937
|
+
"neatlogs.embedding.text": safeStringify7(opts?.contents ?? "")
|
|
7938
|
+
}
|
|
7939
|
+
}, otelContext10.active());
|
|
7940
|
+
const ctx = trace10.setSpan(otelContext10.active(), span2);
|
|
7941
|
+
const result = otelContext10.with(ctx, () => original(opts, ...rest));
|
|
7942
|
+
return Promise.resolve(result).then(
|
|
7943
|
+
(response) => {
|
|
7944
|
+
const embeddings = response?.embeddings;
|
|
7945
|
+
if (Array.isArray(embeddings)) {
|
|
7946
|
+
span2.setAttribute("neatlogs.embedding.count", embeddings.length);
|
|
7947
|
+
const vals = embeddings[0]?.values;
|
|
7948
|
+
if (Array.isArray(vals)) span2.setAttribute("neatlogs.embedding.dimensions", vals.length);
|
|
7949
|
+
}
|
|
7950
|
+
span2.setStatus({ code: SpanStatusCode9.OK });
|
|
7951
|
+
span2.end();
|
|
7952
|
+
return response;
|
|
7953
|
+
},
|
|
7954
|
+
(err) => {
|
|
7955
|
+
recordError5(span2, err);
|
|
7956
|
+
throw err;
|
|
7957
|
+
}
|
|
7958
|
+
);
|
|
7959
|
+
};
|
|
7960
|
+
}
|
|
7961
|
+
function tracedCountTokens2(original) {
|
|
7962
|
+
return function(opts, ...rest) {
|
|
7963
|
+
const tracer = getProviderTracer(TRACER_NAME7);
|
|
7964
|
+
const span2 = tracer.startSpan("google_genai.models.count_tokens", {
|
|
7965
|
+
attributes: {
|
|
7966
|
+
"neatlogs.span.kind": "LLM",
|
|
7967
|
+
"neatlogs.llm.provider": PROVIDER3,
|
|
7968
|
+
"neatlogs.llm.task": "count_tokens",
|
|
7969
|
+
"neatlogs.llm.model_name": opts?.model ?? ""
|
|
7970
|
+
}
|
|
7971
|
+
}, otelContext10.active());
|
|
7972
|
+
const ctx = trace10.setSpan(otelContext10.active(), span2);
|
|
7973
|
+
const result = otelContext10.with(ctx, () => original(opts, ...rest));
|
|
7974
|
+
return Promise.resolve(result).then(
|
|
7975
|
+
(response) => {
|
|
7976
|
+
if (response?.totalTokens != null) span2.setAttribute("neatlogs.llm.token_count.prompt", response.totalTokens);
|
|
7977
|
+
span2.setStatus({ code: SpanStatusCode9.OK });
|
|
7978
|
+
span2.end();
|
|
7979
|
+
return response;
|
|
7980
|
+
},
|
|
7981
|
+
(err) => {
|
|
7982
|
+
recordError5(span2, err);
|
|
7983
|
+
throw err;
|
|
7984
|
+
}
|
|
7985
|
+
);
|
|
7986
|
+
};
|
|
7987
|
+
}
|
|
7988
|
+
function tracedGenerateContent2(original, isStream) {
|
|
7989
|
+
return function(opts, ...rest) {
|
|
7990
|
+
const tracer = getProviderTracer(TRACER_NAME7);
|
|
7991
|
+
const model = opts?.model ?? "";
|
|
7992
|
+
const span2 = tracer.startSpan("google_genai.models.generate_content", {
|
|
7993
|
+
attributes: {
|
|
7994
|
+
"neatlogs.span.kind": "LLM",
|
|
7995
|
+
"neatlogs.llm.provider": PROVIDER3,
|
|
7996
|
+
"neatlogs.llm.system": SYSTEM3,
|
|
7997
|
+
"neatlogs.llm.model_name": model,
|
|
7998
|
+
"neatlogs.llm.is_streaming": isStream
|
|
7999
|
+
}
|
|
8000
|
+
}, otelContext10.active());
|
|
8001
|
+
setInputAttributes2(span2, opts);
|
|
8002
|
+
const ctx = trace10.setSpan(otelContext10.active(), span2);
|
|
8003
|
+
const result = otelContext10.with(ctx, () => original(opts, ...rest));
|
|
8004
|
+
return Promise.resolve(result).then(
|
|
8005
|
+
(response) => {
|
|
8006
|
+
if (isStream) {
|
|
8007
|
+
return wrapStream2(response, span2);
|
|
8008
|
+
}
|
|
8009
|
+
finalizeResponse2(span2, response);
|
|
8010
|
+
return response;
|
|
8011
|
+
},
|
|
8012
|
+
(err) => {
|
|
8013
|
+
recordError5(span2, err);
|
|
8014
|
+
throw err;
|
|
8015
|
+
}
|
|
8016
|
+
);
|
|
8017
|
+
};
|
|
8018
|
+
}
|
|
8019
|
+
function setInputAttributes2(span2, opts) {
|
|
8020
|
+
let idx = 0;
|
|
8021
|
+
const config = opts?.config;
|
|
8022
|
+
const systemInstruction = config?.systemInstruction ?? config?.system_instruction;
|
|
8023
|
+
if (systemInstruction) {
|
|
8024
|
+
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, "system");
|
|
8025
|
+
span2.setAttribute(
|
|
8026
|
+
`neatlogs.llm.input_messages.${idx}.content`,
|
|
8027
|
+
typeof systemInstruction === "string" ? systemInstruction : safeStringify7(systemInstruction)
|
|
8028
|
+
);
|
|
8029
|
+
idx++;
|
|
8030
|
+
}
|
|
8031
|
+
const contents = opts?.contents;
|
|
8032
|
+
if (typeof contents === "string") {
|
|
8033
|
+
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, "user");
|
|
8034
|
+
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.content`, contents);
|
|
8035
|
+
} else if (Array.isArray(contents)) {
|
|
8036
|
+
for (const item of contents) {
|
|
8037
|
+
if (typeof item === "string") {
|
|
8038
|
+
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, "user");
|
|
8039
|
+
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.content`, item);
|
|
8040
|
+
idx++;
|
|
8041
|
+
} else if (item && typeof item === "object") {
|
|
8042
|
+
const role = item.role ?? "user";
|
|
8043
|
+
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, role);
|
|
8044
|
+
const parts = item.parts ?? [];
|
|
8045
|
+
const textParts = [];
|
|
8046
|
+
for (const part of parts) {
|
|
8047
|
+
if (typeof part === "string") textParts.push(part);
|
|
8048
|
+
else if (part?.text) textParts.push(part.text);
|
|
8049
|
+
}
|
|
8050
|
+
span2.setAttribute(
|
|
8051
|
+
`neatlogs.llm.input_messages.${idx}.content`,
|
|
8052
|
+
textParts.length ? textParts.join("\n") : safeStringify7(parts)
|
|
8053
|
+
);
|
|
8054
|
+
idx++;
|
|
8055
|
+
}
|
|
8056
|
+
}
|
|
8057
|
+
} else if (contents) {
|
|
8058
|
+
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, "user");
|
|
8059
|
+
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.content`, safeStringify7(contents));
|
|
8060
|
+
}
|
|
8061
|
+
const tools = config?.tools;
|
|
8062
|
+
if (Array.isArray(tools)) {
|
|
8063
|
+
let t = 0;
|
|
8064
|
+
for (const tool of tools) {
|
|
8065
|
+
const decls = tool?.functionDeclarations ?? tool?.function_declarations ?? [];
|
|
8066
|
+
for (const fn of decls) {
|
|
8067
|
+
span2.setAttribute(`neatlogs.llm.tools.${t}.name`, fn?.name ?? "");
|
|
8068
|
+
if (fn?.description) span2.setAttribute(`neatlogs.llm.tools.${t}.description`, fn.description);
|
|
8069
|
+
if (fn?.parameters) span2.setAttribute(`neatlogs.llm.tools.${t}.input_schema`, safeStringify7(fn.parameters));
|
|
8070
|
+
t++;
|
|
8071
|
+
}
|
|
8072
|
+
}
|
|
8073
|
+
}
|
|
8074
|
+
if (config) {
|
|
8075
|
+
if (config.temperature != null) span2.setAttribute("neatlogs.llm.temperature", config.temperature);
|
|
8076
|
+
if (config.topP != null) span2.setAttribute("neatlogs.llm.top_p", config.topP);
|
|
8077
|
+
if (config.topK != null) span2.setAttribute("neatlogs.llm.top_k", config.topK);
|
|
8078
|
+
const maxTokens = config.maxOutputTokens ?? config.max_output_tokens;
|
|
8079
|
+
if (maxTokens != null) span2.setAttribute("neatlogs.llm.max_tokens", maxTokens);
|
|
8080
|
+
const params = {};
|
|
8081
|
+
if (config.temperature != null) params.temperature = config.temperature;
|
|
8082
|
+
if (config.topP != null) params.top_p = config.topP;
|
|
8083
|
+
if (config.topK != null) params.top_k = config.topK;
|
|
8084
|
+
if (maxTokens != null) params.max_tokens = maxTokens;
|
|
8085
|
+
if (config.frequencyPenalty != null) params.frequency_penalty = config.frequencyPenalty;
|
|
8086
|
+
if (config.presencePenalty != null) params.presence_penalty = config.presencePenalty;
|
|
8087
|
+
if (Object.keys(params).length > 0) {
|
|
8088
|
+
span2.setAttribute("neatlogs.llm.invocation_parameters", JSON.stringify(params));
|
|
8089
|
+
}
|
|
8090
|
+
}
|
|
8091
|
+
}
|
|
8092
|
+
function wrapStream2(stream, span2) {
|
|
8093
|
+
const chunks = [];
|
|
8094
|
+
const originalAsyncIterator = stream?.[Symbol.asyncIterator]?.bind(stream);
|
|
8095
|
+
if (!originalAsyncIterator) {
|
|
8096
|
+
finalizeStreamChunks4(span2, chunks);
|
|
8097
|
+
return stream;
|
|
8098
|
+
}
|
|
8099
|
+
const wrapped = Object.create(Object.getPrototypeOf(stream));
|
|
8100
|
+
Object.assign(wrapped, stream);
|
|
8101
|
+
wrapped[Symbol.asyncIterator] = function() {
|
|
8102
|
+
const iterator = originalAsyncIterator();
|
|
8103
|
+
return {
|
|
8104
|
+
async next() {
|
|
8105
|
+
try {
|
|
8106
|
+
const result = await iterator.next();
|
|
8107
|
+
if (result.done) {
|
|
8108
|
+
finalizeStreamChunks4(span2, chunks);
|
|
8109
|
+
return result;
|
|
8110
|
+
}
|
|
8111
|
+
chunks.push(result.value);
|
|
8112
|
+
return result;
|
|
8113
|
+
} catch (err) {
|
|
8114
|
+
recordError5(span2, err);
|
|
8115
|
+
throw err;
|
|
8116
|
+
}
|
|
8117
|
+
},
|
|
8118
|
+
async return(value) {
|
|
8119
|
+
finalizeStreamChunks4(span2, chunks);
|
|
8120
|
+
return iterator.return?.(value) ?? { done: true, value: void 0 };
|
|
8121
|
+
},
|
|
8122
|
+
async throw(err) {
|
|
8123
|
+
recordError5(span2, err);
|
|
8124
|
+
return iterator.throw?.(err) ?? { done: true, value: void 0 };
|
|
8125
|
+
}
|
|
8126
|
+
};
|
|
8127
|
+
};
|
|
8128
|
+
return wrapped;
|
|
8129
|
+
}
|
|
8130
|
+
function finalizeStreamChunks4(span2, chunks) {
|
|
8131
|
+
const textParts = [];
|
|
8132
|
+
let finishReason = "";
|
|
8133
|
+
let usage = null;
|
|
8134
|
+
for (const chunk of chunks) {
|
|
8135
|
+
for (const candidate of chunk?.candidates ?? []) {
|
|
8136
|
+
for (const part of candidate?.content?.parts ?? []) {
|
|
8137
|
+
if (part?.text && !part?.thought) textParts.push(part.text);
|
|
8138
|
+
}
|
|
8139
|
+
if (candidate?.finishReason) finishReason = candidate.finishReason;
|
|
8140
|
+
}
|
|
8141
|
+
if (chunk?.usageMetadata) usage = chunk.usageMetadata;
|
|
8142
|
+
}
|
|
8143
|
+
const fullText = textParts.join("");
|
|
8144
|
+
if (fullText) {
|
|
8145
|
+
span2.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
|
|
8146
|
+
span2.setAttribute("neatlogs.llm.output_messages.0.content", fullText);
|
|
8147
|
+
}
|
|
8148
|
+
if (finishReason) span2.setAttribute("neatlogs.llm.finish_reason", String(finishReason));
|
|
8149
|
+
setUsage2(span2, usage);
|
|
8150
|
+
span2.setStatus({ code: SpanStatusCode9.OK });
|
|
8151
|
+
span2.end();
|
|
8152
|
+
}
|
|
8153
|
+
function finalizeResponse2(span2, response) {
|
|
8154
|
+
const textParts = [];
|
|
8155
|
+
let toolIdx = 0;
|
|
8156
|
+
for (const candidate of response?.candidates ?? []) {
|
|
8157
|
+
for (const part of candidate?.content?.parts ?? []) {
|
|
8158
|
+
if (part?.text && !part?.thought) {
|
|
8159
|
+
textParts.push(part.text);
|
|
8160
|
+
} else if (part?.thought && part?.text) {
|
|
8161
|
+
span2.setAttribute("neatlogs.llm.output_messages.0.thinking", part.text);
|
|
8162
|
+
} else if (part?.functionCall) {
|
|
8163
|
+
const fc = part.functionCall;
|
|
8164
|
+
span2.setAttribute(`neatlogs.llm.tool_calls.${toolIdx}.name`, fc?.name ?? "");
|
|
8165
|
+
span2.setAttribute(`neatlogs.llm.tool_calls.${toolIdx}.arguments`, safeStringify7(fc?.args ?? {}));
|
|
8166
|
+
toolIdx++;
|
|
8167
|
+
}
|
|
8168
|
+
}
|
|
8169
|
+
if (candidate?.finishReason) span2.setAttribute("neatlogs.llm.finish_reason", String(candidate.finishReason));
|
|
8170
|
+
}
|
|
8171
|
+
if (textParts.length) {
|
|
8172
|
+
span2.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
|
|
8173
|
+
span2.setAttribute("neatlogs.llm.output_messages.0.content", textParts.join(""));
|
|
8174
|
+
}
|
|
8175
|
+
setUsage2(span2, response?.usageMetadata);
|
|
8176
|
+
span2.setStatus({ code: SpanStatusCode9.OK });
|
|
8177
|
+
span2.end();
|
|
8178
|
+
}
|
|
8179
|
+
function setUsage2(span2, usage) {
|
|
8180
|
+
if (!usage) return;
|
|
8181
|
+
if (usage.promptTokenCount != null) span2.setAttribute("neatlogs.llm.token_count.prompt", usage.promptTokenCount);
|
|
8182
|
+
if (usage.candidatesTokenCount != null) span2.setAttribute("neatlogs.llm.token_count.completion", usage.candidatesTokenCount);
|
|
8183
|
+
if (usage.totalTokenCount != null) span2.setAttribute("neatlogs.llm.token_count.total", usage.totalTokenCount);
|
|
8184
|
+
if (usage.cachedContentTokenCount != null) span2.setAttribute("neatlogs.llm.token_count.cache_read", usage.cachedContentTokenCount);
|
|
8185
|
+
if (usage.thoughtsTokenCount != null) span2.setAttribute("neatlogs.llm.token_count.reasoning", usage.thoughtsTokenCount);
|
|
8186
|
+
}
|
|
8187
|
+
function safeStringify7(value) {
|
|
8188
|
+
try {
|
|
8189
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
8190
|
+
} catch {
|
|
8191
|
+
return "";
|
|
8192
|
+
}
|
|
8193
|
+
}
|
|
8194
|
+
function recordError5(span2, err) {
|
|
8195
|
+
if (err instanceof Error) {
|
|
8196
|
+
span2.setStatus({ code: SpanStatusCode9.ERROR, message: err.message });
|
|
8197
|
+
span2.recordException(err);
|
|
8198
|
+
} else {
|
|
8199
|
+
span2.setStatus({ code: SpanStatusCode9.ERROR, message: String(err) });
|
|
8200
|
+
}
|
|
8201
|
+
span2.end();
|
|
8202
|
+
}
|
|
8203
|
+
|
|
8204
|
+
// src/bedrock.ts
|
|
8205
|
+
import { trace as trace11, context as otelContext11, SpanStatusCode as SpanStatusCode10 } from "@opentelemetry/api";
|
|
8206
|
+
var TRACER_NAME8 = "neatlogs.bedrock";
|
|
8207
|
+
var PROVIDER4 = "bedrock";
|
|
8208
|
+
function traceTool6(name, fn) {
|
|
8209
|
+
return async function tracedTool(args) {
|
|
8210
|
+
const tracer = getProviderTracer(TRACER_NAME8);
|
|
8211
|
+
return tracer.startActiveSpan(
|
|
8212
|
+
`tool.${name}`,
|
|
8213
|
+
{
|
|
8214
|
+
attributes: {
|
|
8215
|
+
"neatlogs.span.kind": "TOOL",
|
|
8216
|
+
"neatlogs.tool.name": name,
|
|
8217
|
+
"input.value": safeStringify8(args)
|
|
8218
|
+
}
|
|
8219
|
+
},
|
|
8220
|
+
otelContext11.active(),
|
|
8221
|
+
async (span2) => {
|
|
8222
|
+
try {
|
|
8223
|
+
const result = await fn(args);
|
|
8224
|
+
span2.setAttribute("output.value", safeStringify8(result));
|
|
8225
|
+
span2.setStatus({ code: SpanStatusCode10.OK });
|
|
8226
|
+
return result;
|
|
8227
|
+
} catch (err) {
|
|
8228
|
+
recordError6(span2, err);
|
|
8229
|
+
throw err;
|
|
8230
|
+
} finally {
|
|
8231
|
+
span2.end();
|
|
8232
|
+
}
|
|
8233
|
+
}
|
|
8234
|
+
);
|
|
8235
|
+
};
|
|
8236
|
+
}
|
|
8237
|
+
function wrapBedrock(client) {
|
|
8238
|
+
const c = client;
|
|
8239
|
+
if (c._neatlogsBedrockPatched) return client;
|
|
8240
|
+
if (typeof c.send !== "function") return client;
|
|
8241
|
+
const originalSend = c.send.bind(c);
|
|
8242
|
+
c.send = function(command, ...rest) {
|
|
8243
|
+
const name = command?.constructor?.name ?? "";
|
|
8244
|
+
const input = command?.input ?? {};
|
|
8245
|
+
if (name === "ConverseCommand") {
|
|
8246
|
+
return tracedConverse(originalSend, command, input, rest, false);
|
|
8247
|
+
}
|
|
8248
|
+
if (name === "ConverseStreamCommand") {
|
|
8249
|
+
return tracedConverse(originalSend, command, input, rest, true);
|
|
8250
|
+
}
|
|
8251
|
+
if (name === "InvokeModelCommand") {
|
|
8252
|
+
return tracedInvokeModel(originalSend, command, input, rest, false);
|
|
8253
|
+
}
|
|
8254
|
+
if (name === "InvokeModelWithResponseStreamCommand") {
|
|
8255
|
+
return tracedInvokeModel(originalSend, command, input, rest, true);
|
|
8256
|
+
}
|
|
8257
|
+
return originalSend(command, ...rest);
|
|
8258
|
+
};
|
|
8259
|
+
c._neatlogsBedrockPatched = true;
|
|
8260
|
+
return client;
|
|
8261
|
+
}
|
|
8262
|
+
function vendorFromModel(modelId) {
|
|
8263
|
+
let tail = String(modelId ?? "").split("/").pop() ?? "";
|
|
8264
|
+
for (const prefix of ["us.", "eu.", "apac.", "us-gov."]) {
|
|
8265
|
+
if (tail.startsWith(prefix)) tail = tail.slice(prefix.length);
|
|
8266
|
+
}
|
|
8267
|
+
const vendor = tail.includes(".") ? tail.split(".")[0] : "";
|
|
8268
|
+
return vendor || "bedrock";
|
|
8269
|
+
}
|
|
8270
|
+
function startSpan(name, modelId, isStream) {
|
|
8271
|
+
return getProviderTracer(TRACER_NAME8).startSpan(name, {
|
|
8272
|
+
attributes: {
|
|
8273
|
+
"neatlogs.span.kind": "LLM",
|
|
8274
|
+
"neatlogs.llm.provider": PROVIDER4,
|
|
8275
|
+
"neatlogs.llm.system": vendorFromModel(modelId),
|
|
8276
|
+
"neatlogs.llm.model_name": String(modelId ?? ""),
|
|
8277
|
+
"neatlogs.llm.is_streaming": isStream
|
|
8278
|
+
}
|
|
8279
|
+
}, otelContext11.active());
|
|
8280
|
+
}
|
|
8281
|
+
function tracedConverse(originalSend, command, input, rest, isStream) {
|
|
8282
|
+
const span2 = startSpan(
|
|
8283
|
+
isStream ? "bedrock.converse_stream" : "bedrock.converse",
|
|
8284
|
+
input?.modelId,
|
|
8285
|
+
isStream
|
|
8286
|
+
);
|
|
8287
|
+
setConverseInput(span2, input);
|
|
8288
|
+
const ctx = trace11.setSpan(otelContext11.active(), span2);
|
|
8289
|
+
const promise = otelContext11.with(ctx, () => originalSend(command, ...rest));
|
|
8290
|
+
return promise.then(
|
|
8291
|
+
(response) => {
|
|
8292
|
+
if (isStream) {
|
|
8293
|
+
return wrapConverseStream(response, span2);
|
|
8294
|
+
}
|
|
8295
|
+
finalizeConverse(span2, response);
|
|
8296
|
+
return response;
|
|
8297
|
+
},
|
|
8298
|
+
(err) => {
|
|
8299
|
+
recordError6(span2, err);
|
|
8300
|
+
throw err;
|
|
8301
|
+
}
|
|
8302
|
+
);
|
|
8303
|
+
}
|
|
8304
|
+
function setConverseInput(span2, input) {
|
|
8305
|
+
let idx = 0;
|
|
8306
|
+
if (Array.isArray(input?.system)) {
|
|
8307
|
+
const text = input.system.map((b) => b?.text ?? "").join(" ").trim();
|
|
8308
|
+
if (text) {
|
|
8309
|
+
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, "system");
|
|
8310
|
+
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.content`, text);
|
|
8311
|
+
idx++;
|
|
8312
|
+
}
|
|
8313
|
+
}
|
|
8314
|
+
for (const msg of input?.messages ?? []) {
|
|
8315
|
+
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, msg?.role ?? "user");
|
|
8316
|
+
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.content`, converseBlocksToText(msg?.content));
|
|
8317
|
+
idx++;
|
|
8318
|
+
}
|
|
8319
|
+
const cfg = input?.inferenceConfig ?? {};
|
|
8320
|
+
if (cfg.temperature != null) span2.setAttribute("neatlogs.llm.temperature", cfg.temperature);
|
|
8321
|
+
if (cfg.topP != null) span2.setAttribute("neatlogs.llm.top_p", cfg.topP);
|
|
8322
|
+
if (cfg.maxTokens != null) span2.setAttribute("neatlogs.llm.max_tokens", cfg.maxTokens);
|
|
7929
8323
|
const tools = input?.toolConfig?.tools ?? [];
|
|
7930
8324
|
for (let i = 0; i < tools.length; i++) {
|
|
7931
8325
|
const spec = tools[i]?.toolSpec ?? {};
|
|
7932
8326
|
if (spec.name) span2.setAttribute(`neatlogs.llm.tools.${i}.name`, spec.name);
|
|
7933
8327
|
if (spec.description) span2.setAttribute(`neatlogs.llm.tools.${i}.description`, spec.description);
|
|
7934
|
-
if (spec.inputSchema) span2.setAttribute(`neatlogs.llm.tools.${i}.input_schema`,
|
|
8328
|
+
if (spec.inputSchema) span2.setAttribute(`neatlogs.llm.tools.${i}.input_schema`, safeStringify8(spec.inputSchema));
|
|
7935
8329
|
}
|
|
7936
8330
|
}
|
|
7937
8331
|
function converseBlocksToText(content) {
|
|
7938
8332
|
if (typeof content === "string") return content;
|
|
7939
|
-
if (!Array.isArray(content)) return
|
|
8333
|
+
if (!Array.isArray(content)) return safeStringify8(content);
|
|
7940
8334
|
const parts = [];
|
|
7941
8335
|
for (const block of content) {
|
|
7942
8336
|
if (block && typeof block === "object") {
|
|
7943
8337
|
if ("text" in block) parts.push(String(block.text));
|
|
7944
|
-
else if ("toolResult" in block) parts.push(
|
|
7945
|
-
else if ("toolUse" in block) parts.push(
|
|
7946
|
-
else parts.push(
|
|
8338
|
+
else if ("toolResult" in block) parts.push(safeStringify8(block.toolResult));
|
|
8339
|
+
else if ("toolUse" in block) parts.push(safeStringify8(block.toolUse));
|
|
8340
|
+
else parts.push(safeStringify8(block));
|
|
7947
8341
|
} else {
|
|
7948
8342
|
parts.push(String(block));
|
|
7949
8343
|
}
|
|
@@ -7962,7 +8356,7 @@ function finalizeConverse(span2, response) {
|
|
|
7962
8356
|
const tu = block.toolUse;
|
|
7963
8357
|
span2.setAttribute(`neatlogs.llm.tool_calls.${toolIdx}.id`, String(tu?.toolUseId ?? ""));
|
|
7964
8358
|
span2.setAttribute(`neatlogs.llm.tool_calls.${toolIdx}.name`, String(tu?.name ?? ""));
|
|
7965
|
-
span2.setAttribute(`neatlogs.llm.tool_calls.${toolIdx}.arguments`,
|
|
8359
|
+
span2.setAttribute(`neatlogs.llm.tool_calls.${toolIdx}.arguments`, safeStringify8(tu?.input ?? {}));
|
|
7966
8360
|
toolIdx++;
|
|
7967
8361
|
}
|
|
7968
8362
|
}
|
|
@@ -7972,7 +8366,7 @@ function finalizeConverse(span2, response) {
|
|
|
7972
8366
|
}
|
|
7973
8367
|
if (response?.stopReason) span2.setAttribute("neatlogs.llm.finish_reason", String(response.stopReason));
|
|
7974
8368
|
setConverseUsage(span2, response?.usage);
|
|
7975
|
-
span2.setStatus({ code:
|
|
8369
|
+
span2.setStatus({ code: SpanStatusCode10.OK });
|
|
7976
8370
|
span2.end();
|
|
7977
8371
|
}
|
|
7978
8372
|
function setConverseUsage(span2, usage) {
|
|
@@ -7986,7 +8380,7 @@ function setConverseUsage(span2, usage) {
|
|
|
7986
8380
|
function wrapConverseStream(response, span2) {
|
|
7987
8381
|
const stream = response?.stream;
|
|
7988
8382
|
if (!stream || typeof stream[Symbol.asyncIterator] !== "function") {
|
|
7989
|
-
span2.setStatus({ code:
|
|
8383
|
+
span2.setStatus({ code: SpanStatusCode10.OK });
|
|
7990
8384
|
span2.end();
|
|
7991
8385
|
return response;
|
|
7992
8386
|
}
|
|
@@ -8025,7 +8419,7 @@ function wrapConverseStream(response, span2) {
|
|
|
8025
8419
|
if (ev?.metadata?.usage) usage = ev.metadata.usage;
|
|
8026
8420
|
return result;
|
|
8027
8421
|
} catch (err) {
|
|
8028
|
-
|
|
8422
|
+
recordError6(span2, err);
|
|
8029
8423
|
throw err;
|
|
8030
8424
|
}
|
|
8031
8425
|
},
|
|
@@ -8054,7 +8448,7 @@ function finalizeConverseStream(span2, textParts, toolCalls, finishReason, usage
|
|
|
8054
8448
|
}
|
|
8055
8449
|
if (finishReason) span2.setAttribute("neatlogs.llm.finish_reason", String(finishReason));
|
|
8056
8450
|
setConverseUsage(span2, usage);
|
|
8057
|
-
span2.setStatus({ code:
|
|
8451
|
+
span2.setStatus({ code: SpanStatusCode10.OK });
|
|
8058
8452
|
span2.end();
|
|
8059
8453
|
}
|
|
8060
8454
|
function isEmbeddingModel(modelId) {
|
|
@@ -8066,16 +8460,16 @@ function tracedInvokeModel(originalSend, command, input, rest, isStream) {
|
|
|
8066
8460
|
const bodyIn = decodeBody(input?.body);
|
|
8067
8461
|
let span2;
|
|
8068
8462
|
if (isEmbedding) {
|
|
8069
|
-
span2 = getProviderTracer(
|
|
8463
|
+
span2 = getProviderTracer(TRACER_NAME8).startSpan("bedrock.invoke_model", {
|
|
8070
8464
|
attributes: {
|
|
8071
8465
|
"neatlogs.span.kind": "EMBEDDING",
|
|
8072
|
-
"neatlogs.llm.provider":
|
|
8466
|
+
"neatlogs.llm.provider": PROVIDER4,
|
|
8073
8467
|
"neatlogs.embedding.model_name": String(input?.modelId ?? "")
|
|
8074
8468
|
}
|
|
8075
|
-
},
|
|
8469
|
+
}, otelContext11.active());
|
|
8076
8470
|
const text = bodyIn?.inputText ?? bodyIn?.texts ?? bodyIn?.input_text;
|
|
8077
8471
|
if (text) {
|
|
8078
|
-
span2.setAttribute("neatlogs.embedding.text", typeof text === "string" ? text :
|
|
8472
|
+
span2.setAttribute("neatlogs.embedding.text", typeof text === "string" ? text : safeStringify8(text));
|
|
8079
8473
|
}
|
|
8080
8474
|
} else {
|
|
8081
8475
|
span2 = startSpan(
|
|
@@ -8085,8 +8479,8 @@ function tracedInvokeModel(originalSend, command, input, rest, isStream) {
|
|
|
8085
8479
|
);
|
|
8086
8480
|
setInvokeInput(span2, vendor, bodyIn);
|
|
8087
8481
|
}
|
|
8088
|
-
const ctx =
|
|
8089
|
-
const promise =
|
|
8482
|
+
const ctx = trace11.setSpan(otelContext11.active(), span2);
|
|
8483
|
+
const promise = otelContext11.with(ctx, () => originalSend(command, ...rest));
|
|
8090
8484
|
return promise.then(
|
|
8091
8485
|
(response) => {
|
|
8092
8486
|
if (isStream) {
|
|
@@ -8099,13 +8493,13 @@ function tracedInvokeModel(originalSend, command, input, rest, isStream) {
|
|
|
8099
8493
|
finalizeInvoke(span2, vendor, decodeBody(response?.body));
|
|
8100
8494
|
}
|
|
8101
8495
|
} catch {
|
|
8102
|
-
span2.setStatus({ code:
|
|
8496
|
+
span2.setStatus({ code: SpanStatusCode10.OK });
|
|
8103
8497
|
span2.end();
|
|
8104
8498
|
}
|
|
8105
8499
|
return response;
|
|
8106
8500
|
},
|
|
8107
8501
|
(err) => {
|
|
8108
|
-
|
|
8502
|
+
recordError6(span2, err);
|
|
8109
8503
|
throw err;
|
|
8110
8504
|
}
|
|
8111
8505
|
);
|
|
@@ -8124,7 +8518,7 @@ function finalizeInvokeEmbedding(span2, body) {
|
|
|
8124
8518
|
span2.setAttribute("neatlogs.llm.token_count.prompt", body.inputTextTokenCount);
|
|
8125
8519
|
span2.setAttribute("neatlogs.embedding.token_count", body.inputTextTokenCount);
|
|
8126
8520
|
}
|
|
8127
|
-
span2.setStatus({ code:
|
|
8521
|
+
span2.setStatus({ code: SpanStatusCode10.OK });
|
|
8128
8522
|
span2.end();
|
|
8129
8523
|
}
|
|
8130
8524
|
function decodeBody(body) {
|
|
@@ -8146,7 +8540,7 @@ function setInvokeInput(span2, vendor, body) {
|
|
|
8146
8540
|
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, "system");
|
|
8147
8541
|
span2.setAttribute(
|
|
8148
8542
|
`neatlogs.llm.input_messages.${idx}.content`,
|
|
8149
|
-
typeof body.system === "string" ? body.system :
|
|
8543
|
+
typeof body.system === "string" ? body.system : safeStringify8(body.system)
|
|
8150
8544
|
);
|
|
8151
8545
|
idx++;
|
|
8152
8546
|
}
|
|
@@ -8155,7 +8549,7 @@ function setInvokeInput(span2, vendor, body) {
|
|
|
8155
8549
|
span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, msg?.role ?? "user");
|
|
8156
8550
|
span2.setAttribute(
|
|
8157
8551
|
`neatlogs.llm.input_messages.${idx}.content`,
|
|
8158
|
-
typeof msg?.content === "string" ? msg.content :
|
|
8552
|
+
typeof msg?.content === "string" ? msg.content : safeStringify8(msg?.content)
|
|
8159
8553
|
);
|
|
8160
8554
|
idx++;
|
|
8161
8555
|
}
|
|
@@ -8190,7 +8584,7 @@ function finalizeInvoke(span2, vendor, body) {
|
|
|
8190
8584
|
if (b?.type === "tool_use") {
|
|
8191
8585
|
span2.setAttribute(`neatlogs.llm.tool_calls.${toolIdx}.id`, String(b.id ?? ""));
|
|
8192
8586
|
span2.setAttribute(`neatlogs.llm.tool_calls.${toolIdx}.name`, String(b.name ?? ""));
|
|
8193
|
-
span2.setAttribute(`neatlogs.llm.tool_calls.${toolIdx}.arguments`,
|
|
8587
|
+
span2.setAttribute(`neatlogs.llm.tool_calls.${toolIdx}.arguments`, safeStringify8(b.input ?? {}));
|
|
8194
8588
|
toolIdx++;
|
|
8195
8589
|
}
|
|
8196
8590
|
}
|
|
@@ -8232,13 +8626,13 @@ function finalizeInvoke(span2, vendor, body) {
|
|
|
8232
8626
|
span2.setAttribute("neatlogs.llm.token_count.total", promptTokens + completionTokens);
|
|
8233
8627
|
}
|
|
8234
8628
|
if (finishReason) span2.setAttribute("neatlogs.llm.finish_reason", String(finishReason));
|
|
8235
|
-
span2.setStatus({ code:
|
|
8629
|
+
span2.setStatus({ code: SpanStatusCode10.OK });
|
|
8236
8630
|
span2.end();
|
|
8237
8631
|
}
|
|
8238
8632
|
function wrapInvokeStream(response, span2, vendor) {
|
|
8239
8633
|
const body = response?.body;
|
|
8240
8634
|
if (!body || typeof body[Symbol.asyncIterator] !== "function") {
|
|
8241
|
-
span2.setStatus({ code:
|
|
8635
|
+
span2.setStatus({ code: SpanStatusCode10.OK });
|
|
8242
8636
|
span2.end();
|
|
8243
8637
|
return response;
|
|
8244
8638
|
}
|
|
@@ -8256,7 +8650,7 @@ function wrapInvokeStream(response, span2, vendor) {
|
|
|
8256
8650
|
if (promptTokens != null) span2.setAttribute("neatlogs.llm.token_count.prompt", promptTokens);
|
|
8257
8651
|
if (completionTokens != null) span2.setAttribute("neatlogs.llm.token_count.completion", completionTokens);
|
|
8258
8652
|
if (finishReason) span2.setAttribute("neatlogs.llm.finish_reason", String(finishReason));
|
|
8259
|
-
span2.setStatus({ code:
|
|
8653
|
+
span2.setStatus({ code: SpanStatusCode10.OK });
|
|
8260
8654
|
span2.end();
|
|
8261
8655
|
};
|
|
8262
8656
|
const wrappedBody = {
|
|
@@ -8286,7 +8680,7 @@ function wrapInvokeStream(response, span2, vendor) {
|
|
|
8286
8680
|
}
|
|
8287
8681
|
return result;
|
|
8288
8682
|
} catch (err) {
|
|
8289
|
-
|
|
8683
|
+
recordError6(span2, err);
|
|
8290
8684
|
throw err;
|
|
8291
8685
|
}
|
|
8292
8686
|
},
|
|
@@ -8300,26 +8694,26 @@ function wrapInvokeStream(response, span2, vendor) {
|
|
|
8300
8694
|
response.body = wrappedBody;
|
|
8301
8695
|
return response;
|
|
8302
8696
|
}
|
|
8303
|
-
function
|
|
8697
|
+
function safeStringify8(value) {
|
|
8304
8698
|
try {
|
|
8305
8699
|
return typeof value === "string" ? value : JSON.stringify(value);
|
|
8306
8700
|
} catch {
|
|
8307
8701
|
return "";
|
|
8308
8702
|
}
|
|
8309
8703
|
}
|
|
8310
|
-
function
|
|
8704
|
+
function recordError6(span2, err) {
|
|
8311
8705
|
if (err instanceof Error) {
|
|
8312
|
-
span2.setStatus({ code:
|
|
8706
|
+
span2.setStatus({ code: SpanStatusCode10.ERROR, message: err.message });
|
|
8313
8707
|
span2.recordException(err);
|
|
8314
8708
|
} else {
|
|
8315
|
-
span2.setStatus({ code:
|
|
8709
|
+
span2.setStatus({ code: SpanStatusCode10.ERROR, message: String(err) });
|
|
8316
8710
|
}
|
|
8317
8711
|
span2.end();
|
|
8318
8712
|
}
|
|
8319
8713
|
|
|
8320
8714
|
// src/langchain.ts
|
|
8321
|
-
import { trace as
|
|
8322
|
-
var
|
|
8715
|
+
import { trace as trace12, context as otelContext12, SpanStatusCode as SpanStatusCode11 } from "@opentelemetry/api";
|
|
8716
|
+
var TRACER_NAME9 = "neatlogs.langchain";
|
|
8323
8717
|
function langchainHandler(opts) {
|
|
8324
8718
|
return new NeatlogsCallbackHandler(opts);
|
|
8325
8719
|
}
|
|
@@ -8343,10 +8737,10 @@ var NeatlogsCallbackHandler = class {
|
|
|
8343
8737
|
_startCtx(parentRunId, runId, kind) {
|
|
8344
8738
|
const parentSpan = parentRunId ? this._spans.get(parentRunId) : void 0;
|
|
8345
8739
|
if (parentSpan) {
|
|
8346
|
-
return
|
|
8740
|
+
return trace12.setSpan(otelContext12.active(), parentSpan);
|
|
8347
8741
|
}
|
|
8348
|
-
const tracer =
|
|
8349
|
-
const { root, ctx } = maybeOpenAutoRoot(tracer, kind,
|
|
8742
|
+
const tracer = trace12.getTracer(TRACER_NAME9);
|
|
8743
|
+
const { root, ctx } = maybeOpenAutoRoot(tracer, kind, otelContext12.active());
|
|
8350
8744
|
if (root) this._autoRoots.set(runId, root);
|
|
8351
8745
|
return ctx;
|
|
8352
8746
|
}
|
|
@@ -8359,7 +8753,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8359
8753
|
}
|
|
8360
8754
|
// --- Chain/Graph callbacks ---
|
|
8361
8755
|
async handleChainStart(serialized, inputs, runId, parentRunId, tags, metadata) {
|
|
8362
|
-
const tracer =
|
|
8756
|
+
const tracer = trace12.getTracer(TRACER_NAME9);
|
|
8363
8757
|
const name = serialized?.name ?? serialized?.id?.at(-1) ?? "chain";
|
|
8364
8758
|
const parentCtx = this._startCtx(parentRunId, runId, "chain");
|
|
8365
8759
|
const attrs = {
|
|
@@ -8367,7 +8761,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8367
8761
|
"neatlogs.chain.name": name
|
|
8368
8762
|
};
|
|
8369
8763
|
if (this._workflowName) attrs["neatlogs.workflow.name"] = this._workflowName;
|
|
8370
|
-
if (inputs) attrs["input.value"] =
|
|
8764
|
+
if (inputs) attrs["input.value"] = safeStringify9(inputs);
|
|
8371
8765
|
if (tags?.length) attrs["neatlogs.tags"] = tags.join(",");
|
|
8372
8766
|
const span2 = tracer.startSpan(`langchain.chain.${name}`, { attributes: attrs }, parentCtx);
|
|
8373
8767
|
this._spans.set(runId, span2);
|
|
@@ -8375,8 +8769,8 @@ var NeatlogsCallbackHandler = class {
|
|
|
8375
8769
|
async handleChainEnd(outputs, runId) {
|
|
8376
8770
|
const span2 = this._spans.get(runId);
|
|
8377
8771
|
if (!span2) return;
|
|
8378
|
-
if (outputs) span2.setAttribute("output.value",
|
|
8379
|
-
span2.setStatus({ code:
|
|
8772
|
+
if (outputs) span2.setAttribute("output.value", safeStringify9(outputs));
|
|
8773
|
+
span2.setStatus({ code: SpanStatusCode11.OK });
|
|
8380
8774
|
span2.end();
|
|
8381
8775
|
this._spans.delete(runId);
|
|
8382
8776
|
this._endAutoRoot(runId);
|
|
@@ -8384,7 +8778,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8384
8778
|
async handleChainError(error, runId) {
|
|
8385
8779
|
const span2 = this._spans.get(runId);
|
|
8386
8780
|
if (!span2) return;
|
|
8387
|
-
span2.setStatus({ code:
|
|
8781
|
+
span2.setStatus({ code: SpanStatusCode11.ERROR, message: error.message });
|
|
8388
8782
|
span2.recordException(error);
|
|
8389
8783
|
span2.end();
|
|
8390
8784
|
this._spans.delete(runId);
|
|
@@ -8392,7 +8786,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8392
8786
|
}
|
|
8393
8787
|
// --- LLM callbacks ---
|
|
8394
8788
|
async handleLLMStart(serialized, prompts, runId, parentRunId, extraParams) {
|
|
8395
|
-
const tracer =
|
|
8789
|
+
const tracer = trace12.getTracer(TRACER_NAME9);
|
|
8396
8790
|
const model = serialized?.kwargs?.model_name ?? serialized?.kwargs?.model ?? serialized?.name ?? "";
|
|
8397
8791
|
const parentCtx = this._startCtx(parentRunId, runId, "llm");
|
|
8398
8792
|
const attrs = {
|
|
@@ -8414,7 +8808,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8414
8808
|
this._spans.set(runId, span2);
|
|
8415
8809
|
}
|
|
8416
8810
|
async handleChatModelStart(serialized, messages, runId, parentRunId, extraParams) {
|
|
8417
|
-
const tracer =
|
|
8811
|
+
const tracer = trace12.getTracer(TRACER_NAME9);
|
|
8418
8812
|
const model = serialized?.kwargs?.model_name ?? serialized?.kwargs?.model ?? serialized?.name ?? "";
|
|
8419
8813
|
const parentCtx = this._startCtx(parentRunId, runId, "llm");
|
|
8420
8814
|
const attrs = {
|
|
@@ -8426,7 +8820,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8426
8820
|
for (let i = 0; i < flatMessages.length; i++) {
|
|
8427
8821
|
const msg = flatMessages[i];
|
|
8428
8822
|
const role = msg?.role ?? msg?._getType?.() ?? msg?.constructor?.name ?? "unknown";
|
|
8429
|
-
const content = typeof msg?.content === "string" ? msg.content :
|
|
8823
|
+
const content = typeof msg?.content === "string" ? msg.content : safeStringify9(msg?.content);
|
|
8430
8824
|
attrs[`neatlogs.llm.input_messages.${i}.role`] = mapRole(role);
|
|
8431
8825
|
attrs[`neatlogs.llm.input_messages.${i}.content`] = content;
|
|
8432
8826
|
}
|
|
@@ -8457,7 +8851,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8457
8851
|
const tc = toolCalls[k];
|
|
8458
8852
|
span2.setAttribute(`neatlogs.llm.tool_calls.${k}.id`, tc.id ?? "");
|
|
8459
8853
|
span2.setAttribute(`neatlogs.llm.tool_calls.${k}.name`, tc.name ?? tc.function?.name ?? "");
|
|
8460
|
-
span2.setAttribute(`neatlogs.llm.tool_calls.${k}.arguments`, tc.args ?
|
|
8854
|
+
span2.setAttribute(`neatlogs.llm.tool_calls.${k}.arguments`, tc.args ? safeStringify9(tc.args) : tc.function?.arguments ?? "");
|
|
8461
8855
|
}
|
|
8462
8856
|
}
|
|
8463
8857
|
}
|
|
@@ -8474,7 +8868,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8474
8868
|
span2.setAttribute("neatlogs.llm.token_count.total", usage.totalTokens ?? usage.total_tokens);
|
|
8475
8869
|
}
|
|
8476
8870
|
}
|
|
8477
|
-
span2.setStatus({ code:
|
|
8871
|
+
span2.setStatus({ code: SpanStatusCode11.OK });
|
|
8478
8872
|
span2.end();
|
|
8479
8873
|
this._spans.delete(runId);
|
|
8480
8874
|
this._endAutoRoot(runId);
|
|
@@ -8484,7 +8878,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8484
8878
|
async handleLLMError(error, runId) {
|
|
8485
8879
|
const span2 = this._spans.get(runId);
|
|
8486
8880
|
if (!span2) return;
|
|
8487
|
-
span2.setStatus({ code:
|
|
8881
|
+
span2.setStatus({ code: SpanStatusCode11.ERROR, message: error.message });
|
|
8488
8882
|
span2.recordException(error);
|
|
8489
8883
|
span2.end();
|
|
8490
8884
|
this._spans.delete(runId);
|
|
@@ -8492,7 +8886,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8492
8886
|
}
|
|
8493
8887
|
// --- Tool callbacks ---
|
|
8494
8888
|
async handleToolStart(serialized, input, runId, parentRunId, _tags, _metadata, runName, toolCallId) {
|
|
8495
|
-
const tracer =
|
|
8889
|
+
const tracer = trace12.getTracer(TRACER_NAME9);
|
|
8496
8890
|
const name = serialized?.name || runName || (Array.isArray(serialized?.id) ? serialized.id[serialized.id.length - 1] : void 0) || "tool";
|
|
8497
8891
|
const parentCtx = this._startCtx(parentRunId, runId, "tool");
|
|
8498
8892
|
const attrs = {
|
|
@@ -8508,7 +8902,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8508
8902
|
const span2 = this._spans.get(runId);
|
|
8509
8903
|
if (!span2) return;
|
|
8510
8904
|
span2.setAttribute("output.value", String(output));
|
|
8511
|
-
span2.setStatus({ code:
|
|
8905
|
+
span2.setStatus({ code: SpanStatusCode11.OK });
|
|
8512
8906
|
span2.end();
|
|
8513
8907
|
this._spans.delete(runId);
|
|
8514
8908
|
this._endAutoRoot(runId);
|
|
@@ -8516,7 +8910,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8516
8910
|
async handleToolError(error, runId) {
|
|
8517
8911
|
const span2 = this._spans.get(runId);
|
|
8518
8912
|
if (!span2) return;
|
|
8519
|
-
span2.setStatus({ code:
|
|
8913
|
+
span2.setStatus({ code: SpanStatusCode11.ERROR, message: error.message });
|
|
8520
8914
|
span2.recordException(error);
|
|
8521
8915
|
span2.end();
|
|
8522
8916
|
this._spans.delete(runId);
|
|
@@ -8524,7 +8918,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8524
8918
|
}
|
|
8525
8919
|
// --- Retriever callbacks ---
|
|
8526
8920
|
async handleRetrieverStart(serialized, query, runId, parentRunId) {
|
|
8527
|
-
const tracer =
|
|
8921
|
+
const tracer = trace12.getTracer(TRACER_NAME9);
|
|
8528
8922
|
const name = serialized?.name ?? "retriever";
|
|
8529
8923
|
const parentCtx = this._startCtx(parentRunId, runId, "retriever");
|
|
8530
8924
|
const attrs = {
|
|
@@ -8547,7 +8941,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8547
8941
|
}
|
|
8548
8942
|
}
|
|
8549
8943
|
}
|
|
8550
|
-
span2.setStatus({ code:
|
|
8944
|
+
span2.setStatus({ code: SpanStatusCode11.OK });
|
|
8551
8945
|
span2.end();
|
|
8552
8946
|
this._spans.delete(runId);
|
|
8553
8947
|
this._endAutoRoot(runId);
|
|
@@ -8555,7 +8949,7 @@ var NeatlogsCallbackHandler = class {
|
|
|
8555
8949
|
async handleRetrieverError(error, runId) {
|
|
8556
8950
|
const span2 = this._spans.get(runId);
|
|
8557
8951
|
if (!span2) return;
|
|
8558
|
-
span2.setStatus({ code:
|
|
8952
|
+
span2.setStatus({ code: SpanStatusCode11.ERROR, message: error.message });
|
|
8559
8953
|
span2.recordException(error);
|
|
8560
8954
|
span2.end();
|
|
8561
8955
|
this._spans.delete(runId);
|
|
@@ -8580,7 +8974,7 @@ function mapRole(role) {
|
|
|
8580
8974
|
if (r === "tool" || r === "toolmessage") return "tool";
|
|
8581
8975
|
return role;
|
|
8582
8976
|
}
|
|
8583
|
-
function
|
|
8977
|
+
function safeStringify9(value) {
|
|
8584
8978
|
try {
|
|
8585
8979
|
return typeof value === "string" ? value : JSON.stringify(value);
|
|
8586
8980
|
} catch {
|
|
@@ -8656,7 +9050,7 @@ function setOutput(span2, isTool, out) {
|
|
|
8656
9050
|
} else {
|
|
8657
9051
|
span2.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
|
|
8658
9052
|
span2.setAttribute("neatlogs.llm.output_messages.0.content", out);
|
|
8659
|
-
span2.setAttribute("neatlogs.llm.output",
|
|
9053
|
+
span2.setAttribute("neatlogs.llm.output", safeStringify10({ role: "assistant", content: out }));
|
|
8660
9054
|
}
|
|
8661
9055
|
}
|
|
8662
9056
|
function appendInputMessage(span2, role, content) {
|
|
@@ -8667,7 +9061,7 @@ function appendInputMessage(span2, role, content) {
|
|
|
8667
9061
|
const existing = span2.__neatlogs_in_msgs ?? [];
|
|
8668
9062
|
existing.push({ role, content });
|
|
8669
9063
|
span2.__neatlogs_in_msgs = existing;
|
|
8670
|
-
const blob =
|
|
9064
|
+
const blob = safeStringify10({ messages: existing });
|
|
8671
9065
|
span2.setAttribute("input.value", blob);
|
|
8672
9066
|
span2.setAttribute("neatlogs.llm.input", blob);
|
|
8673
9067
|
}
|
|
@@ -8710,15 +9104,15 @@ function flattenBlocks(val) {
|
|
|
8710
9104
|
const o = item;
|
|
8711
9105
|
if (typeof o.text === "string") out.push(o.text);
|
|
8712
9106
|
else if (typeof o.content === "string") out.push(o.content);
|
|
8713
|
-
else if (o.toolUse) out.push(`${o.toolUse.name ?? "tool"}(${
|
|
9107
|
+
else if (o.toolUse) out.push(`${o.toolUse.name ?? "tool"}(${safeStringify10(o.toolUse.input ?? {})})`);
|
|
8714
9108
|
else if (o.toolResult) out.push(flattenBlocks(o.toolResult.content ?? o.toolResult));
|
|
8715
9109
|
else if (Array.isArray(o.parts)) out.push(flattenBlocks(o.parts));
|
|
8716
9110
|
else if (Array.isArray(o.content)) out.push(flattenBlocks(o.content));
|
|
8717
|
-
else out.push(
|
|
9111
|
+
else out.push(safeStringify10(o));
|
|
8718
9112
|
}
|
|
8719
9113
|
return out.filter(Boolean).join("\n");
|
|
8720
9114
|
}
|
|
8721
|
-
function
|
|
9115
|
+
function safeStringify10(value) {
|
|
8722
9116
|
if (typeof value === "string") return value;
|
|
8723
9117
|
try {
|
|
8724
9118
|
return JSON.stringify(value) ?? "";
|
|
@@ -8728,8 +9122,8 @@ function safeStringify9(value) {
|
|
|
8728
9122
|
}
|
|
8729
9123
|
|
|
8730
9124
|
// src/openai-agents.ts
|
|
8731
|
-
import { trace as
|
|
8732
|
-
var
|
|
9125
|
+
import { trace as trace13, context as otelContext13, SpanStatusCode as SpanStatusCode12 } from "@opentelemetry/api";
|
|
9126
|
+
var TRACER_NAME10 = "neatlogs.openai_agents";
|
|
8733
9127
|
function openaiAgentsProcessor() {
|
|
8734
9128
|
return new NeatlogsTraceProcessor();
|
|
8735
9129
|
}
|
|
@@ -8738,13 +9132,13 @@ var NeatlogsTraceProcessor = class {
|
|
|
8738
9132
|
_startTimes = /* @__PURE__ */ new Map();
|
|
8739
9133
|
// The @openai/agents SDK passes a Trace object: { traceId, name, groupId, metadata }.
|
|
8740
9134
|
onTraceStart(traceData) {
|
|
8741
|
-
const tracer =
|
|
9135
|
+
const tracer = trace13.getTracer(TRACER_NAME10);
|
|
8742
9136
|
const attrs = { "neatlogs.span.kind": "WORKFLOW" };
|
|
8743
9137
|
const workflowName = traceData?.name ?? traceData?.workflow_name;
|
|
8744
9138
|
if (workflowName) attrs["neatlogs.workflow.name"] = workflowName;
|
|
8745
9139
|
const traceId = traceData?.traceId ?? traceData?.trace_id;
|
|
8746
9140
|
if (traceId) attrs["neatlogs.agent.trace_id"] = String(traceId);
|
|
8747
|
-
const span2 = tracer.startSpan("openai_agents.trace", { attributes: attrs },
|
|
9141
|
+
const span2 = tracer.startSpan("openai_agents.trace", { attributes: attrs }, otelContext13.active());
|
|
8748
9142
|
const key = String(traceId ?? `trace_${Date.now()}`);
|
|
8749
9143
|
this._spans.set(key, span2);
|
|
8750
9144
|
this._startTimes.set(key, Date.now());
|
|
@@ -8757,7 +9151,7 @@ var NeatlogsTraceProcessor = class {
|
|
|
8757
9151
|
if (startTime) {
|
|
8758
9152
|
span2.setAttribute("neatlogs.metrics.duration_ms", Date.now() - startTime);
|
|
8759
9153
|
}
|
|
8760
|
-
span2.setStatus({ code:
|
|
9154
|
+
span2.setStatus({ code: SpanStatusCode12.OK });
|
|
8761
9155
|
span2.end();
|
|
8762
9156
|
this._spans.delete(key);
|
|
8763
9157
|
this._startTimes.delete(key);
|
|
@@ -8765,13 +9159,13 @@ var NeatlogsTraceProcessor = class {
|
|
|
8765
9159
|
// The SDK passes a Span object: { type, spanId, traceId, parentId?, spanData: {...} }.
|
|
8766
9160
|
// The meaningful payload (type, name, input, output, usage, ...) lives in `spanData`.
|
|
8767
9161
|
onSpanStart(span2) {
|
|
8768
|
-
const tracer =
|
|
9162
|
+
const tracer = trace13.getTracer(TRACER_NAME10);
|
|
8769
9163
|
const data = span2?.spanData ?? span2 ?? {};
|
|
8770
9164
|
const spanType = data?.type ?? data?.span_type ?? span2?.type ?? "";
|
|
8771
9165
|
const spanId = String(span2?.spanId ?? span2?.span_id ?? data?.span_id ?? `span_${Date.now()}`);
|
|
8772
9166
|
const parentKey = String(span2?.parentId ?? span2?.traceId ?? span2?.trace_id ?? "");
|
|
8773
9167
|
const parentSpan = this._spans.get(parentKey);
|
|
8774
|
-
const parentCtx = parentSpan ?
|
|
9168
|
+
const parentCtx = parentSpan ? trace13.setSpan(otelContext13.active(), parentSpan) : otelContext13.active();
|
|
8775
9169
|
let otelSpan;
|
|
8776
9170
|
if (spanType === "agent" || spanType === "agent_run") {
|
|
8777
9171
|
const agentName = data?.name ?? data?.agent_name ?? "agent";
|
|
@@ -8797,7 +9191,7 @@ var NeatlogsTraceProcessor = class {
|
|
|
8797
9191
|
const role = typeof msg === "object" ? msg.role ?? "" : "";
|
|
8798
9192
|
const content = typeof msg === "object" ? msg.content ?? "" : String(msg);
|
|
8799
9193
|
if (role) attrs[`neatlogs.llm.input_messages.${i}.role`] = role;
|
|
8800
|
-
if (content) attrs[`neatlogs.llm.input_messages.${i}.content`] = typeof content === "string" ? content :
|
|
9194
|
+
if (content) attrs[`neatlogs.llm.input_messages.${i}.content`] = typeof content === "string" ? content : safeStringify11(content);
|
|
8801
9195
|
}
|
|
8802
9196
|
}
|
|
8803
9197
|
otelSpan = tracer.startSpan("openai_agents.generation", { attributes: attrs }, parentCtx);
|
|
@@ -8809,7 +9203,7 @@ var NeatlogsTraceProcessor = class {
|
|
|
8809
9203
|
};
|
|
8810
9204
|
const toolInput = data?.input ?? data?.arguments;
|
|
8811
9205
|
if (toolInput !== void 0) {
|
|
8812
|
-
attrs["input.value"] = typeof toolInput === "string" ? toolInput :
|
|
9206
|
+
attrs["input.value"] = typeof toolInput === "string" ? toolInput : safeStringify11(toolInput);
|
|
8813
9207
|
}
|
|
8814
9208
|
otelSpan = tracer.startSpan(`openai_agents.tool.${toolName}`, { attributes: attrs }, parentCtx);
|
|
8815
9209
|
} else if (spanType === "handoff") {
|
|
@@ -8846,13 +9240,13 @@ var NeatlogsTraceProcessor = class {
|
|
|
8846
9240
|
for (let i = 0; i < toolCalls.length; i++) {
|
|
8847
9241
|
const tc = toolCalls[i];
|
|
8848
9242
|
otelSpan.setAttribute(`neatlogs.llm.tool_calls.${i}.name`, tc.name ?? "");
|
|
8849
|
-
otelSpan.setAttribute(`neatlogs.llm.tool_calls.${i}.arguments`, typeof tc.arguments === "string" ? tc.arguments :
|
|
9243
|
+
otelSpan.setAttribute(`neatlogs.llm.tool_calls.${i}.arguments`, typeof tc.arguments === "string" ? tc.arguments : safeStringify11(tc.arguments ?? {}));
|
|
8850
9244
|
if (tc.callId ?? tc.id) otelSpan.setAttribute(`neatlogs.llm.tool_calls.${i}.id`, tc.callId ?? tc.id);
|
|
8851
9245
|
}
|
|
8852
9246
|
} else if (outputItems?.content) {
|
|
8853
9247
|
otelSpan.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
|
|
8854
9248
|
const c = outputItems.content;
|
|
8855
|
-
otelSpan.setAttribute("neatlogs.llm.output_messages.0.content", typeof c === "string" ? c :
|
|
9249
|
+
otelSpan.setAttribute("neatlogs.llm.output_messages.0.content", typeof c === "string" ? c : safeStringify11(c));
|
|
8856
9250
|
}
|
|
8857
9251
|
const usage = data?.usage ?? resp?.usage;
|
|
8858
9252
|
if (usage) {
|
|
@@ -8869,24 +9263,24 @@ var NeatlogsTraceProcessor = class {
|
|
|
8869
9263
|
} else if (spanType === "function" || spanType === "tool" || spanType === "tool_call") {
|
|
8870
9264
|
const output = data?.output ?? data?.result;
|
|
8871
9265
|
if (output != null) {
|
|
8872
|
-
otelSpan.setAttribute("output.value", typeof output === "string" ? output :
|
|
9266
|
+
otelSpan.setAttribute("output.value", typeof output === "string" ? output : safeStringify11(output));
|
|
8873
9267
|
}
|
|
8874
9268
|
} else if (spanType === "agent" || spanType === "agent_run") {
|
|
8875
9269
|
const output = data?.output;
|
|
8876
9270
|
if (output != null) {
|
|
8877
|
-
otelSpan.setAttribute("output.value", typeof output === "string" ? output :
|
|
9271
|
+
otelSpan.setAttribute("output.value", typeof output === "string" ? output : safeStringify11(output));
|
|
8878
9272
|
}
|
|
8879
9273
|
}
|
|
8880
9274
|
const error = data?.error ?? span2?.error;
|
|
8881
9275
|
if (error) {
|
|
8882
9276
|
if (error instanceof Error) {
|
|
8883
|
-
otelSpan.setStatus({ code:
|
|
9277
|
+
otelSpan.setStatus({ code: SpanStatusCode12.ERROR, message: error.message });
|
|
8884
9278
|
otelSpan.recordException(error);
|
|
8885
9279
|
} else {
|
|
8886
|
-
otelSpan.setStatus({ code:
|
|
9280
|
+
otelSpan.setStatus({ code: SpanStatusCode12.ERROR, message: String(error) });
|
|
8887
9281
|
}
|
|
8888
9282
|
} else {
|
|
8889
|
-
otelSpan.setStatus({ code:
|
|
9283
|
+
otelSpan.setStatus({ code: SpanStatusCode12.OK });
|
|
8890
9284
|
}
|
|
8891
9285
|
if (startTime) {
|
|
8892
9286
|
otelSpan.setAttribute("neatlogs.llm.metrics.duration_ms", Date.now() - startTime);
|
|
@@ -8897,7 +9291,7 @@ var NeatlogsTraceProcessor = class {
|
|
|
8897
9291
|
}
|
|
8898
9292
|
shutdown() {
|
|
8899
9293
|
for (const [, span2] of this._spans) {
|
|
8900
|
-
span2.setStatus({ code:
|
|
9294
|
+
span2.setStatus({ code: SpanStatusCode12.ERROR, message: "Processor shutdown before span completed" });
|
|
8901
9295
|
span2.end();
|
|
8902
9296
|
}
|
|
8903
9297
|
this._spans.clear();
|
|
@@ -8906,7 +9300,7 @@ var NeatlogsTraceProcessor = class {
|
|
|
8906
9300
|
forceFlush() {
|
|
8907
9301
|
}
|
|
8908
9302
|
};
|
|
8909
|
-
function
|
|
9303
|
+
function safeStringify11(value) {
|
|
8910
9304
|
try {
|
|
8911
9305
|
return typeof value === "string" ? value : JSON.stringify(value);
|
|
8912
9306
|
} catch {
|
|
@@ -8915,8 +9309,8 @@ function safeStringify10(value) {
|
|
|
8915
9309
|
}
|
|
8916
9310
|
|
|
8917
9311
|
// src/mastra-wrap.ts
|
|
8918
|
-
import { trace as
|
|
8919
|
-
var
|
|
9312
|
+
import { trace as trace14, context as otelContext14, SpanStatusCode as SpanStatusCode13 } from "@opentelemetry/api";
|
|
9313
|
+
var TRACER_NAME11 = "neatlogs.mastra";
|
|
8920
9314
|
var PATCH_FLAG2 = "_neatlogs_patched";
|
|
8921
9315
|
function wrapMastra(entity) {
|
|
8922
9316
|
if (!entity || entity[PATCH_FLAG2]) return entity;
|
|
@@ -8982,14 +9376,14 @@ function patchAgentMethod(agent, method, streaming) {
|
|
|
8982
9376
|
}
|
|
8983
9377
|
if (streaming) attrs["neatlogs.llm.is_streaming"] = true;
|
|
8984
9378
|
if (streaming) {
|
|
8985
|
-
const tracer =
|
|
8986
|
-
const span2 = tracer.startSpan(`mastra.agent.${agentName}`, { attributes: attrs },
|
|
8987
|
-
const ctx =
|
|
9379
|
+
const tracer = trace14.getTracer(TRACER_NAME11);
|
|
9380
|
+
const span2 = tracer.startSpan(`mastra.agent.${agentName}`, { attributes: attrs }, otelContext14.active());
|
|
9381
|
+
const ctx = trace14.setSpan(otelContext14.active(), span2);
|
|
8988
9382
|
try {
|
|
8989
|
-
const result = await
|
|
9383
|
+
const result = await otelContext14.with(ctx, () => orig(input, opts));
|
|
8990
9384
|
return wrapStreamingOutput(result, span2, ctx);
|
|
8991
9385
|
} catch (err) {
|
|
8992
|
-
|
|
9386
|
+
recordError7(span2, err);
|
|
8993
9387
|
span2.end();
|
|
8994
9388
|
throw err;
|
|
8995
9389
|
}
|
|
@@ -9032,7 +9426,7 @@ function patchModelInPlace(model) {
|
|
|
9032
9426
|
if (provider) attrs["neatlogs.llm.provider"] = provider;
|
|
9033
9427
|
if (isStream) attrs["neatlogs.llm.is_streaming"] = true;
|
|
9034
9428
|
const promptInput = callOpts?.prompt ?? callOpts?.messages;
|
|
9035
|
-
if (promptInput !== void 0) attrs["input.value"] =
|
|
9429
|
+
if (promptInput !== void 0) attrs["input.value"] = safeStringify12(promptInput);
|
|
9036
9430
|
captureInvocationParams(attrs, callOpts);
|
|
9037
9431
|
return withActiveSpan(`mastra.llm.${modelId || "model"}.${fn}`, attrs, async (span2) => {
|
|
9038
9432
|
const result = await orig(callOpts);
|
|
@@ -9066,12 +9460,12 @@ function patchToolExecute(tool, key) {
|
|
|
9066
9460
|
const attrs = {
|
|
9067
9461
|
"neatlogs.span.kind": "TOOL",
|
|
9068
9462
|
"neatlogs.tool.name": toolName,
|
|
9069
|
-
"input.value":
|
|
9463
|
+
"input.value": safeStringify12(params)
|
|
9070
9464
|
};
|
|
9071
9465
|
if (tool.description) attrs["neatlogs.tool.description"] = String(tool.description);
|
|
9072
9466
|
return withActiveSpan(`mastra.tool.${toolName}`, attrs, async (span2) => {
|
|
9073
9467
|
const result = await orig(params, options);
|
|
9074
|
-
span2.setAttribute("output.value",
|
|
9468
|
+
span2.setAttribute("output.value", safeStringify12(result));
|
|
9075
9469
|
return result;
|
|
9076
9470
|
});
|
|
9077
9471
|
};
|
|
@@ -9097,13 +9491,13 @@ function patchRunMethod(run, method, workflowName) {
|
|
|
9097
9491
|
"neatlogs.workflow.name": workflowName
|
|
9098
9492
|
};
|
|
9099
9493
|
if (startOpts?.inputData !== void 0) {
|
|
9100
|
-
attrs["input.value"] =
|
|
9494
|
+
attrs["input.value"] = safeStringify12(startOpts.inputData);
|
|
9101
9495
|
}
|
|
9102
9496
|
return withActiveSpan(`mastra.workflow.${workflowName}`, attrs, async (span2) => {
|
|
9103
9497
|
const result = await orig(startOpts);
|
|
9104
|
-
if (result?.status) span2.setAttribute("neatlogs.metadata",
|
|
9498
|
+
if (result?.status) span2.setAttribute("neatlogs.metadata", safeStringify12({ status: result.status }));
|
|
9105
9499
|
if (result?.result !== void 0) {
|
|
9106
|
-
span2.setAttribute("output.value",
|
|
9500
|
+
span2.setAttribute("output.value", safeStringify12(result.result));
|
|
9107
9501
|
}
|
|
9108
9502
|
return result;
|
|
9109
9503
|
});
|
|
@@ -9124,14 +9518,14 @@ function patchVectorOp(vector, op, kind) {
|
|
|
9124
9518
|
"neatlogs.span.kind": kind,
|
|
9125
9519
|
"neatlogs.db.system": dbName,
|
|
9126
9520
|
"neatlogs.db.operation": op,
|
|
9127
|
-
"input.value":
|
|
9521
|
+
"input.value": safeStringify12(params)
|
|
9128
9522
|
};
|
|
9129
9523
|
const indexName = params?.indexName;
|
|
9130
9524
|
if (indexName) attrs["neatlogs.vectordb.index_name"] = String(indexName);
|
|
9131
9525
|
if (kind === "RETRIEVER" && params?.topK != null) attrs["neatlogs.retriever.top_k"] = params.topK;
|
|
9132
9526
|
return withActiveSpan(`mastra.vector.${op}`, attrs, async (span2) => {
|
|
9133
9527
|
const result = await orig(params);
|
|
9134
|
-
span2.setAttribute("output.value",
|
|
9528
|
+
span2.setAttribute("output.value", safeStringify12(result));
|
|
9135
9529
|
return result;
|
|
9136
9530
|
});
|
|
9137
9531
|
};
|
|
@@ -9145,11 +9539,11 @@ function patchMemory(memory) {
|
|
|
9145
9539
|
const attrs = {
|
|
9146
9540
|
"neatlogs.span.kind": "CHAIN",
|
|
9147
9541
|
"neatlogs.db.operation": op,
|
|
9148
|
-
"input.value":
|
|
9542
|
+
"input.value": safeStringify12(args?.[0])
|
|
9149
9543
|
};
|
|
9150
9544
|
return withActiveSpan(`mastra.memory.${op}`, attrs, async (span2) => {
|
|
9151
9545
|
const result = await orig(...args);
|
|
9152
|
-
span2.setAttribute("output.value",
|
|
9546
|
+
span2.setAttribute("output.value", safeStringify12(result));
|
|
9153
9547
|
return result;
|
|
9154
9548
|
});
|
|
9155
9549
|
};
|
|
@@ -9190,7 +9584,7 @@ function wrapRootMastra(mastra) {
|
|
|
9190
9584
|
}
|
|
9191
9585
|
function wrapStreamingOutput(output, span2, ctx) {
|
|
9192
9586
|
if (!output) {
|
|
9193
|
-
span2.setStatus({ code:
|
|
9587
|
+
span2.setStatus({ code: SpanStatusCode13.OK });
|
|
9194
9588
|
span2.end();
|
|
9195
9589
|
return output;
|
|
9196
9590
|
}
|
|
@@ -9198,8 +9592,8 @@ function wrapStreamingOutput(output, span2, ctx) {
|
|
|
9198
9592
|
const endOnce = (err) => {
|
|
9199
9593
|
if (ended) return;
|
|
9200
9594
|
ended = true;
|
|
9201
|
-
if (err)
|
|
9202
|
-
else span2.setStatus({ code:
|
|
9595
|
+
if (err) recordError7(span2, err);
|
|
9596
|
+
else span2.setStatus({ code: SpanStatusCode13.OK });
|
|
9203
9597
|
span2.end();
|
|
9204
9598
|
};
|
|
9205
9599
|
if (output.text && typeof output.text.then === "function") {
|
|
@@ -9290,7 +9684,7 @@ function rebindStreamContext(output, ctx) {
|
|
|
9290
9684
|
const origIterator = value[Symbol.asyncIterator].bind(value);
|
|
9291
9685
|
return {
|
|
9292
9686
|
[Symbol.asyncIterator]() {
|
|
9293
|
-
return
|
|
9687
|
+
return otelContext14.with(ctx, () => origIterator());
|
|
9294
9688
|
}
|
|
9295
9689
|
};
|
|
9296
9690
|
}
|
|
@@ -9332,7 +9726,7 @@ function finalizeModelResult(span2, result) {
|
|
|
9332
9726
|
const tc = toolCalls[i];
|
|
9333
9727
|
setToolCall(span2, i, tc.toolName, tc.input ?? tc.args, tc.toolCallId);
|
|
9334
9728
|
}
|
|
9335
|
-
span2.setAttribute("output.value",
|
|
9729
|
+
span2.setAttribute("output.value", safeStringify12(result.content));
|
|
9336
9730
|
}
|
|
9337
9731
|
if (result.usage) recordUsage(span2, result.usage);
|
|
9338
9732
|
span2.setAttribute("neatlogs.llm.stop_reason", normalizeFinishReason(result.finishReason));
|
|
@@ -9340,7 +9734,7 @@ function finalizeModelResult(span2, result) {
|
|
|
9340
9734
|
function normalizeFinishReason(fr) {
|
|
9341
9735
|
if (fr == null) return "";
|
|
9342
9736
|
if (typeof fr === "string") return fr;
|
|
9343
|
-
return String(fr.unified ?? fr.reason ?? fr.type ??
|
|
9737
|
+
return String(fr.unified ?? fr.reason ?? fr.type ?? safeStringify12(fr));
|
|
9344
9738
|
}
|
|
9345
9739
|
function tokenValue(v) {
|
|
9346
9740
|
if (v == null) return void 0;
|
|
@@ -9369,22 +9763,22 @@ function captureInvocationParams(attrs, callOpts) {
|
|
|
9369
9763
|
}
|
|
9370
9764
|
}
|
|
9371
9765
|
if (Array.isArray(callOpts.stopSequences) && callOpts.stopSequences.length) {
|
|
9372
|
-
attrs["neatlogs.llm.stop_sequences"] =
|
|
9766
|
+
attrs["neatlogs.llm.stop_sequences"] = safeStringify12(callOpts.stopSequences);
|
|
9373
9767
|
invocation.stopSequences = callOpts.stopSequences;
|
|
9374
9768
|
}
|
|
9375
9769
|
if (Array.isArray(callOpts.tools)) {
|
|
9376
9770
|
for (let i = 0; i < callOpts.tools.length; i++) {
|
|
9377
|
-
attrs[`neatlogs.llm.tools.${i}`] =
|
|
9771
|
+
attrs[`neatlogs.llm.tools.${i}`] = safeStringify12(callOpts.tools[i]);
|
|
9378
9772
|
}
|
|
9379
9773
|
invocation.toolChoice = callOpts.toolChoice;
|
|
9380
9774
|
}
|
|
9381
9775
|
if (Object.keys(invocation).length) {
|
|
9382
|
-
attrs["neatlogs.llm.invocation_parameters"] =
|
|
9776
|
+
attrs["neatlogs.llm.invocation_parameters"] = safeStringify12(invocation);
|
|
9383
9777
|
}
|
|
9384
9778
|
}
|
|
9385
9779
|
function setToolCall(span2, i, name, args, id) {
|
|
9386
9780
|
span2.setAttribute(`neatlogs.llm.tool_calls.${i}.name`, name ?? "");
|
|
9387
|
-
span2.setAttribute(`neatlogs.llm.tool_calls.${i}.arguments`,
|
|
9781
|
+
span2.setAttribute(`neatlogs.llm.tool_calls.${i}.arguments`, safeStringify12(args ?? {}));
|
|
9388
9782
|
if (id) span2.setAttribute(`neatlogs.llm.tool_calls.${i}.id`, id);
|
|
9389
9783
|
}
|
|
9390
9784
|
function recordUsage(span2, usage) {
|
|
@@ -9400,16 +9794,16 @@ function recordUsage(span2, usage) {
|
|
|
9400
9794
|
}
|
|
9401
9795
|
}
|
|
9402
9796
|
function withActiveSpan(name, attrs, fn) {
|
|
9403
|
-
const tracer =
|
|
9404
|
-
const span2 = tracer.startSpan(name, { attributes: attrs },
|
|
9405
|
-
const ctx =
|
|
9406
|
-
return
|
|
9797
|
+
const tracer = trace14.getTracer(TRACER_NAME11);
|
|
9798
|
+
const span2 = tracer.startSpan(name, { attributes: attrs }, otelContext14.active());
|
|
9799
|
+
const ctx = trace14.setSpan(otelContext14.active(), span2);
|
|
9800
|
+
return otelContext14.with(ctx, async () => {
|
|
9407
9801
|
try {
|
|
9408
9802
|
const result = await fn(span2);
|
|
9409
|
-
span2.setStatus({ code:
|
|
9803
|
+
span2.setStatus({ code: SpanStatusCode13.OK });
|
|
9410
9804
|
return result;
|
|
9411
9805
|
} catch (err) {
|
|
9412
|
-
|
|
9806
|
+
recordError7(span2, err);
|
|
9413
9807
|
throw err;
|
|
9414
9808
|
} finally {
|
|
9415
9809
|
span2.end();
|
|
@@ -9429,9 +9823,9 @@ function extractModelId(model) {
|
|
|
9429
9823
|
return model.modelId ?? model.name ?? "";
|
|
9430
9824
|
}
|
|
9431
9825
|
function toInputValue(input) {
|
|
9432
|
-
return typeof input === "string" ? input :
|
|
9826
|
+
return typeof input === "string" ? input : safeStringify12(input);
|
|
9433
9827
|
}
|
|
9434
|
-
function
|
|
9828
|
+
function safeStringify12(value) {
|
|
9435
9829
|
if (typeof value === "string") return value;
|
|
9436
9830
|
try {
|
|
9437
9831
|
return JSON.stringify(value) ?? "";
|
|
@@ -9439,29 +9833,29 @@ function safeStringify11(value) {
|
|
|
9439
9833
|
return "";
|
|
9440
9834
|
}
|
|
9441
9835
|
}
|
|
9442
|
-
function
|
|
9836
|
+
function recordError7(span2, err) {
|
|
9443
9837
|
if (err instanceof Error) {
|
|
9444
|
-
span2.setStatus({ code:
|
|
9838
|
+
span2.setStatus({ code: SpanStatusCode13.ERROR, message: err.message });
|
|
9445
9839
|
span2.recordException(err);
|
|
9446
9840
|
} else {
|
|
9447
|
-
span2.setStatus({ code:
|
|
9841
|
+
span2.setStatus({ code: SpanStatusCode13.ERROR, message: String(err) });
|
|
9448
9842
|
}
|
|
9449
9843
|
}
|
|
9450
9844
|
|
|
9451
9845
|
// src/pi-agent.ts
|
|
9452
9846
|
import {
|
|
9453
|
-
trace as
|
|
9454
|
-
context as
|
|
9455
|
-
SpanStatusCode as
|
|
9847
|
+
trace as trace15,
|
|
9848
|
+
context as otelContext15,
|
|
9849
|
+
SpanStatusCode as SpanStatusCode14
|
|
9456
9850
|
} from "@opentelemetry/api";
|
|
9457
|
-
var
|
|
9851
|
+
var TRACER_NAME12 = "neatlogs.pi-agent";
|
|
9458
9852
|
var PATCH_FLAG3 = "_neatlogs_patched";
|
|
9459
9853
|
function piAgentHooks(agent) {
|
|
9460
9854
|
if (!agent || agent[PATCH_FLAG3]) return agent;
|
|
9461
9855
|
const a = agent;
|
|
9462
9856
|
if (typeof a.subscribe !== "function") return agent;
|
|
9463
9857
|
const state = { toolSpans: /* @__PURE__ */ new Map(), inputMessages: [] };
|
|
9464
|
-
const tracer =
|
|
9858
|
+
const tracer = trace15.getTracer(TRACER_NAME12);
|
|
9465
9859
|
a.subscribe((event) => {
|
|
9466
9860
|
try {
|
|
9467
9861
|
handleEvent(tracer, state, event);
|
|
@@ -9477,10 +9871,10 @@ function handleEvent(tracer, state, event) {
|
|
|
9477
9871
|
const span2 = tracer.startSpan(
|
|
9478
9872
|
"pi_agent.run",
|
|
9479
9873
|
{ attributes: { "neatlogs.span.kind": "AGENT" } },
|
|
9480
|
-
|
|
9874
|
+
otelContext15.active()
|
|
9481
9875
|
);
|
|
9482
9876
|
state.agentSpan = span2;
|
|
9483
|
-
state.agentCtx =
|
|
9877
|
+
state.agentCtx = trace15.setSpan(otelContext15.active(), span2);
|
|
9484
9878
|
state.inputMessages = [];
|
|
9485
9879
|
break;
|
|
9486
9880
|
}
|
|
@@ -9499,14 +9893,14 @@ function handleEvent(tracer, state, event) {
|
|
|
9499
9893
|
break;
|
|
9500
9894
|
}
|
|
9501
9895
|
case "tool_execution_start": {
|
|
9502
|
-
const parent = state.agentCtx ??
|
|
9896
|
+
const parent = state.agentCtx ?? otelContext15.active();
|
|
9503
9897
|
const span2 = tracer.startSpan(
|
|
9504
9898
|
`pi_agent.tool.${event.toolName ?? "tool"}`,
|
|
9505
9899
|
{
|
|
9506
9900
|
attributes: {
|
|
9507
9901
|
"neatlogs.span.kind": "TOOL",
|
|
9508
9902
|
...event.toolName ? { "neatlogs.tool.name": String(event.toolName) } : {},
|
|
9509
|
-
...event.args !== void 0 ? { "input.value":
|
|
9903
|
+
...event.args !== void 0 ? { "input.value": safeStringify13(event.args) } : {}
|
|
9510
9904
|
}
|
|
9511
9905
|
},
|
|
9512
9906
|
parent
|
|
@@ -9518,13 +9912,13 @@ function handleEvent(tracer, state, event) {
|
|
|
9518
9912
|
const span2 = event.toolCallId ? state.toolSpans.get(event.toolCallId) : void 0;
|
|
9519
9913
|
if (!span2) return;
|
|
9520
9914
|
if (event.result !== void 0) {
|
|
9521
|
-
span2.setAttribute("output.value",
|
|
9915
|
+
span2.setAttribute("output.value", safeStringify13(event.result));
|
|
9522
9916
|
}
|
|
9523
9917
|
if (event.isError) {
|
|
9524
|
-
span2.setStatus({ code:
|
|
9918
|
+
span2.setStatus({ code: SpanStatusCode14.ERROR });
|
|
9525
9919
|
span2.setAttribute("neatlogs.tool.is_error", true);
|
|
9526
9920
|
} else {
|
|
9527
|
-
span2.setStatus({ code:
|
|
9921
|
+
span2.setStatus({ code: SpanStatusCode14.OK });
|
|
9528
9922
|
}
|
|
9529
9923
|
span2.end();
|
|
9530
9924
|
if (event.toolCallId) state.toolSpans.delete(event.toolCallId);
|
|
@@ -9543,7 +9937,7 @@ function handleEvent(tracer, state, event) {
|
|
|
9543
9937
|
if (firstUser) state.agentSpan.setAttribute("input.value", firstUser.content);
|
|
9544
9938
|
const finalText = lastAssistantText(event.messages);
|
|
9545
9939
|
if (finalText) state.agentSpan.setAttribute("output.value", finalText);
|
|
9546
|
-
state.agentSpan.setStatus({ code:
|
|
9940
|
+
state.agentSpan.setStatus({ code: SpanStatusCode14.OK });
|
|
9547
9941
|
state.agentSpan.end();
|
|
9548
9942
|
state.agentSpan = void 0;
|
|
9549
9943
|
state.agentCtx = void 0;
|
|
@@ -9565,11 +9959,11 @@ function emitLlmSpan(tracer, state, msg) {
|
|
|
9565
9959
|
attrs[`neatlogs.llm.input_messages.${i}.role`] = m.role;
|
|
9566
9960
|
attrs[`neatlogs.llm.input_messages.${i}.content`] = m.content;
|
|
9567
9961
|
});
|
|
9568
|
-
attrs["neatlogs.llm.input"] =
|
|
9569
|
-
attrs["input.value"] =
|
|
9962
|
+
attrs["neatlogs.llm.input"] = safeStringify13({ messages: inMsgs });
|
|
9963
|
+
attrs["input.value"] = safeStringify13({ messages: inMsgs });
|
|
9570
9964
|
}
|
|
9571
9965
|
const { text, toolCalls } = splitAssistantContent(msg.content);
|
|
9572
|
-
const outText = text || toolCalls.map((tc) => `${tc.name}(${
|
|
9966
|
+
const outText = text || toolCalls.map((tc) => `${tc.name}(${safeStringify13(tc.arguments)})`).join("\n");
|
|
9573
9967
|
if (outText || toolCalls.length) {
|
|
9574
9968
|
attrs["neatlogs.llm.output_messages.0.role"] = "assistant";
|
|
9575
9969
|
attrs["neatlogs.llm.output_messages.0.content"] = outText || "";
|
|
@@ -9579,11 +9973,11 @@ function emitLlmSpan(tracer, state, msg) {
|
|
|
9579
9973
|
toolCalls.forEach((tc, j) => {
|
|
9580
9974
|
if (tc.name) attrs[`neatlogs.llm.tool_calls.${j}.name`] = tc.name;
|
|
9581
9975
|
if (tc.arguments !== void 0)
|
|
9582
|
-
attrs[`neatlogs.llm.tool_calls.${j}.arguments`] =
|
|
9976
|
+
attrs[`neatlogs.llm.tool_calls.${j}.arguments`] = safeStringify13(tc.arguments);
|
|
9583
9977
|
if (tc.id) attrs[`neatlogs.llm.tool_calls.${j}.id`] = String(tc.id);
|
|
9584
9978
|
});
|
|
9585
9979
|
}
|
|
9586
|
-
attrs["neatlogs.llm.output"] =
|
|
9980
|
+
attrs["neatlogs.llm.output"] = safeStringify13(outBlob);
|
|
9587
9981
|
attrs["output.value"] = outText || "";
|
|
9588
9982
|
}
|
|
9589
9983
|
const usage = msg.usage;
|
|
@@ -9595,13 +9989,13 @@ function emitLlmSpan(tracer, state, msg) {
|
|
|
9595
9989
|
if (usage.cacheRead) attrs["neatlogs.llm.token_count.cache_read"] = usage.cacheRead;
|
|
9596
9990
|
if (usage.cacheWrite) attrs["neatlogs.llm.token_count.cache_write"] = usage.cacheWrite;
|
|
9597
9991
|
}
|
|
9598
|
-
const parent = state.agentCtx ??
|
|
9992
|
+
const parent = state.agentCtx ?? otelContext15.active();
|
|
9599
9993
|
const span2 = tracer.startSpan(
|
|
9600
9994
|
`pi_agent.llm.${msg.model || "model"}`,
|
|
9601
9995
|
{ attributes: attrs },
|
|
9602
9996
|
parent
|
|
9603
9997
|
);
|
|
9604
|
-
span2.setStatus({ code:
|
|
9998
|
+
span2.setStatus({ code: SpanStatusCode14.OK });
|
|
9605
9999
|
span2.end();
|
|
9606
10000
|
}
|
|
9607
10001
|
function splitAssistantContent(content) {
|
|
@@ -9629,7 +10023,7 @@ function messageText(msg) {
|
|
|
9629
10023
|
if (typeof block === "string") parts.push(block);
|
|
9630
10024
|
else if (block && typeof block === "object") {
|
|
9631
10025
|
if (typeof block.text === "string") parts.push(block.text);
|
|
9632
|
-
else if (block.type === "toolCall") parts.push(`${block.name ?? "tool"}(${
|
|
10026
|
+
else if (block.type === "toolCall") parts.push(`${block.name ?? "tool"}(${safeStringify13(block.arguments)})`);
|
|
9633
10027
|
}
|
|
9634
10028
|
}
|
|
9635
10029
|
return parts.join("");
|
|
@@ -9652,7 +10046,7 @@ function markPatched2(e) {
|
|
|
9652
10046
|
e[PATCH_FLAG3] = true;
|
|
9653
10047
|
}
|
|
9654
10048
|
}
|
|
9655
|
-
function
|
|
10049
|
+
function safeStringify13(value) {
|
|
9656
10050
|
if (typeof value === "string") return value;
|
|
9657
10051
|
try {
|
|
9658
10052
|
return JSON.stringify(value) ?? "";
|
|
@@ -9662,8 +10056,8 @@ function safeStringify12(value) {
|
|
|
9662
10056
|
}
|
|
9663
10057
|
|
|
9664
10058
|
// src/claude-agent-sdk.ts
|
|
9665
|
-
import { trace as
|
|
9666
|
-
var
|
|
10059
|
+
import { trace as trace16, context as otelContext16, SpanStatusCode as SpanStatusCode15 } from "@opentelemetry/api";
|
|
10060
|
+
var TRACER_NAME13 = "neatlogs.claude_agent_sdk";
|
|
9667
10061
|
var ROOT_SCOPE = "__root__";
|
|
9668
10062
|
function wrapClaudeAgentSDK(sdk, options = {}) {
|
|
9669
10063
|
if (!sdk || typeof sdk.query !== "function") return sdk;
|
|
@@ -9683,13 +10077,13 @@ function wrapClaudeAgentSDK(sdk, options = {}) {
|
|
|
9683
10077
|
}
|
|
9684
10078
|
function wrapQuery(original, options) {
|
|
9685
10079
|
return function(params, ...rest) {
|
|
9686
|
-
const tracer =
|
|
10080
|
+
const tracer = trace16.getTracer(TRACER_NAME13);
|
|
9687
10081
|
const workflowName = options.workflowName ?? "claude_agent.query";
|
|
9688
10082
|
const promptRef = { text: "" };
|
|
9689
10083
|
const agentSpan = tracer.startSpan(
|
|
9690
10084
|
"claude_agent.query",
|
|
9691
10085
|
{ attributes: { "neatlogs.span.kind": "AGENT", "neatlogs.workflow.name": workflowName } },
|
|
9692
|
-
|
|
10086
|
+
otelContext16.active()
|
|
9693
10087
|
);
|
|
9694
10088
|
const promptText = extractPromptText(params?.prompt);
|
|
9695
10089
|
if (promptText) {
|
|
@@ -9698,8 +10092,8 @@ function wrapQuery(original, options) {
|
|
|
9698
10092
|
} else if (params && isAsyncIterable(params.prompt)) {
|
|
9699
10093
|
params = { ...params, prompt: tapPromptStream(params.prompt, promptRef) };
|
|
9700
10094
|
}
|
|
9701
|
-
const agentCtx =
|
|
9702
|
-
const queryObj =
|
|
10095
|
+
const agentCtx = trace16.setSpan(otelContext16.active(), agentSpan);
|
|
10096
|
+
const queryObj = otelContext16.with(agentCtx, () => original(params, ...rest));
|
|
9703
10097
|
return instrumentQueryIterable(queryObj, agentSpan, agentCtx, tracer, promptRef);
|
|
9704
10098
|
};
|
|
9705
10099
|
}
|
|
@@ -9718,7 +10112,7 @@ async function* tapPromptStream(prompt, ref) {
|
|
|
9718
10112
|
function instrumentQueryIterable(queryObj, agentSpan, agentCtx, tracer, promptRef) {
|
|
9719
10113
|
const originalAsyncIterator = queryObj?.[Symbol.asyncIterator]?.bind(queryObj);
|
|
9720
10114
|
if (!originalAsyncIterator) {
|
|
9721
|
-
agentSpan.setStatus({ code:
|
|
10115
|
+
agentSpan.setStatus({ code: SpanStatusCode15.OK });
|
|
9722
10116
|
agentSpan.end();
|
|
9723
10117
|
return queryObj;
|
|
9724
10118
|
}
|
|
@@ -9753,9 +10147,9 @@ function instrumentQueryIterable(queryObj, agentSpan, agentCtx, tracer, promptRe
|
|
|
9753
10147
|
}
|
|
9754
10148
|
if (rootScope.finalText) agentSpan.setAttribute("output.value", rootScope.finalText);
|
|
9755
10149
|
if (status === "error") {
|
|
9756
|
-
|
|
10150
|
+
recordError8(agentSpan, err);
|
|
9757
10151
|
} else {
|
|
9758
|
-
agentSpan.setStatus({ code:
|
|
10152
|
+
agentSpan.setStatus({ code: SpanStatusCode15.OK });
|
|
9759
10153
|
agentSpan.end();
|
|
9760
10154
|
}
|
|
9761
10155
|
};
|
|
@@ -9766,7 +10160,7 @@ function instrumentQueryIterable(queryObj, agentSpan, agentCtx, tracer, promptRe
|
|
|
9766
10160
|
return {
|
|
9767
10161
|
async next() {
|
|
9768
10162
|
try {
|
|
9769
|
-
const result = await
|
|
10163
|
+
const result = await otelContext16.with(agentCtx, () => iterator.next());
|
|
9770
10164
|
if (result.done) {
|
|
9771
10165
|
finalizeAgent("ok");
|
|
9772
10166
|
return result;
|
|
@@ -9797,7 +10191,7 @@ function instrumentQueryIterable(queryObj, agentSpan, agentCtx, tracer, promptRe
|
|
|
9797
10191
|
function closeScope(scope, status) {
|
|
9798
10192
|
try {
|
|
9799
10193
|
if (scope.finalText) scope.span.setAttribute("output.value", scope.finalText);
|
|
9800
|
-
scope.span.setStatus({ code: status === "ok" ?
|
|
10194
|
+
scope.span.setStatus({ code: status === "ok" ? SpanStatusCode15.OK : SpanStatusCode15.ERROR });
|
|
9801
10195
|
scope.span.end();
|
|
9802
10196
|
} catch {
|
|
9803
10197
|
}
|
|
@@ -9812,7 +10206,7 @@ function getScope(tracer, state, msg) {
|
|
|
9812
10206
|
flushAssistantTurn(tracer, root, state);
|
|
9813
10207
|
}
|
|
9814
10208
|
const parentToolSpan = state.toolSpans.get(parentId);
|
|
9815
|
-
const parentCtx = parentToolSpan ?
|
|
10209
|
+
const parentCtx = parentToolSpan ? trace16.setSpan(otelContext16.active(), parentToolSpan) : state.scopes.get(ROOT_SCOPE).ctx;
|
|
9816
10210
|
const subType = msg?.subagent_type ? String(msg.subagent_type) : "subagent";
|
|
9817
10211
|
const attrs = {
|
|
9818
10212
|
"neatlogs.span.kind": "AGENT",
|
|
@@ -9822,7 +10216,7 @@ function getScope(tracer, state, msg) {
|
|
|
9822
10216
|
const span2 = tracer.startSpan(`claude_agent.subagent.${subType}`, { attributes: attrs }, parentCtx);
|
|
9823
10217
|
const scope = {
|
|
9824
10218
|
span: span2,
|
|
9825
|
-
ctx:
|
|
10219
|
+
ctx: trace16.setSpan(otelContext16.active(), span2),
|
|
9826
10220
|
inputMessages: msg?.task_description ? [{ role: "user", content: String(msg.task_description) }] : [],
|
|
9827
10221
|
assistantBuffer: null,
|
|
9828
10222
|
finalText: "",
|
|
@@ -9877,7 +10271,7 @@ function handleMessage(tracer, state, msg, finalizeAgent) {
|
|
|
9877
10271
|
rootScope.span.setAttribute("neatlogs.conversation.id", String(msg.session_id));
|
|
9878
10272
|
}
|
|
9879
10273
|
const usage = msg.usage;
|
|
9880
|
-
if (usage)
|
|
10274
|
+
if (usage) setUsage3(rootScope.span, usage);
|
|
9881
10275
|
if (msg.total_cost_usd != null) rootScope.span.setAttribute("neatlogs.agent.cost_usd", msg.total_cost_usd);
|
|
9882
10276
|
if (msg.num_turns != null) rootScope.span.setAttribute("neatlogs.agent.num_turns", msg.num_turns);
|
|
9883
10277
|
if (msg.is_error) rootScope.span.setAttribute("neatlogs.agent.is_error", true);
|
|
@@ -9926,10 +10320,10 @@ function flushAssistantTurn(tracer, scope, state) {
|
|
|
9926
10320
|
attrs[`neatlogs.llm.input_messages.${i}.content`] = m.content;
|
|
9927
10321
|
});
|
|
9928
10322
|
if (scope.inputMessages.length) {
|
|
9929
|
-
attrs["input.value"] =
|
|
10323
|
+
attrs["input.value"] = safeStringify14({ messages: scope.inputMessages });
|
|
9930
10324
|
}
|
|
9931
10325
|
const outText = buf.textParts.join("");
|
|
9932
|
-
const outValue = outText || buf.toolCalls.map((tc) => `${tc.name}(${
|
|
10326
|
+
const outValue = outText || buf.toolCalls.map((tc) => `${tc.name}(${safeStringify14(tc.input ?? {})})`).join("\n");
|
|
9933
10327
|
if (outValue) {
|
|
9934
10328
|
attrs["neatlogs.llm.output_messages.0.role"] = "assistant";
|
|
9935
10329
|
attrs["neatlogs.llm.output_messages.0.content"] = outValue;
|
|
@@ -9941,17 +10335,17 @@ function flushAssistantTurn(tracer, scope, state) {
|
|
|
9941
10335
|
buf.toolCalls.forEach((tc, j) => {
|
|
9942
10336
|
attrs[`neatlogs.llm.tool_calls.${j}.id`] = tc.id;
|
|
9943
10337
|
attrs[`neatlogs.llm.tool_calls.${j}.name`] = tc.name;
|
|
9944
|
-
attrs[`neatlogs.llm.tool_calls.${j}.arguments`] =
|
|
10338
|
+
attrs[`neatlogs.llm.tool_calls.${j}.arguments`] = safeStringify14(tc.input ?? {});
|
|
9945
10339
|
});
|
|
9946
10340
|
if (buf.stopReason) attrs["neatlogs.llm.finish_reason"] = String(buf.stopReason);
|
|
9947
10341
|
const span2 = tracer.startSpan(`claude_agent.llm.${model || "model"}`, { attributes: attrs }, scope.ctx);
|
|
9948
|
-
if (buf.usage)
|
|
9949
|
-
span2.setStatus({ code:
|
|
10342
|
+
if (buf.usage) setUsage3(span2, buf.usage);
|
|
10343
|
+
span2.setStatus({ code: SpanStatusCode15.OK });
|
|
9950
10344
|
span2.end();
|
|
9951
10345
|
if (outText) scope.finalText = outText;
|
|
9952
10346
|
const turnParts = [];
|
|
9953
10347
|
if (outText) turnParts.push(outText);
|
|
9954
|
-
for (const tc of buf.toolCalls) turnParts.push(`[tool_call ${tc.name} ${
|
|
10348
|
+
for (const tc of buf.toolCalls) turnParts.push(`[tool_call ${tc.name} ${safeStringify14(tc.input ?? {})}]`);
|
|
9955
10349
|
if (turnParts.length) scope.inputMessages.push({ role: "assistant", content: turnParts.join("\n") });
|
|
9956
10350
|
for (const tc of buf.toolCalls) {
|
|
9957
10351
|
const toolSpan = tracer.startSpan(
|
|
@@ -9961,7 +10355,7 @@ function flushAssistantTurn(tracer, scope, state) {
|
|
|
9961
10355
|
"neatlogs.span.kind": "TOOL",
|
|
9962
10356
|
"neatlogs.tool.name": String(tc.name ?? ""),
|
|
9963
10357
|
...tc.id ? { "neatlogs.tool_call.id": String(tc.id) } : {},
|
|
9964
|
-
"input.value":
|
|
10358
|
+
"input.value": safeStringify14(tc.input ?? {})
|
|
9965
10359
|
}
|
|
9966
10360
|
},
|
|
9967
10361
|
scope.ctx
|
|
@@ -9975,16 +10369,16 @@ function closeToolSpansFromUser(state, scope, msg) {
|
|
|
9975
10369
|
if (block?.type !== "tool_result") continue;
|
|
9976
10370
|
const id = block.tool_use_id ?? "";
|
|
9977
10371
|
const out = block.content;
|
|
9978
|
-
const outText = typeof out === "string" ? out :
|
|
10372
|
+
const outText = typeof out === "string" ? out : safeStringify14(out);
|
|
9979
10373
|
if (outText) scope.inputMessages.push({ role: "tool", content: outText });
|
|
9980
10374
|
const span2 = state.toolSpans.get(id);
|
|
9981
10375
|
if (!span2) continue;
|
|
9982
10376
|
span2.setAttribute("output.value", outText);
|
|
9983
10377
|
if (block.is_error) {
|
|
9984
|
-
span2.setStatus({ code:
|
|
10378
|
+
span2.setStatus({ code: SpanStatusCode15.ERROR });
|
|
9985
10379
|
span2.setAttribute("neatlogs.tool.is_error", true);
|
|
9986
10380
|
} else {
|
|
9987
|
-
span2.setStatus({ code:
|
|
10381
|
+
span2.setStatus({ code: SpanStatusCode15.OK });
|
|
9988
10382
|
}
|
|
9989
10383
|
span2.end();
|
|
9990
10384
|
state.toolSpans.delete(id);
|
|
@@ -10003,7 +10397,7 @@ function userMessageText(msg) {
|
|
|
10003
10397
|
}
|
|
10004
10398
|
return parts.join("\n");
|
|
10005
10399
|
}
|
|
10006
|
-
function
|
|
10400
|
+
function setUsage3(span2, usage) {
|
|
10007
10401
|
if (!usage) return;
|
|
10008
10402
|
if (usage.input_tokens != null) span2.setAttribute("neatlogs.llm.token_count.prompt", usage.input_tokens);
|
|
10009
10403
|
if (usage.output_tokens != null) span2.setAttribute("neatlogs.llm.token_count.completion", usage.output_tokens);
|
|
@@ -10021,7 +10415,7 @@ function extractPromptText(prompt) {
|
|
|
10021
10415
|
if (typeof prompt === "string") return prompt;
|
|
10022
10416
|
return "";
|
|
10023
10417
|
}
|
|
10024
|
-
function
|
|
10418
|
+
function safeStringify14(value) {
|
|
10025
10419
|
if (typeof value === "string") return value;
|
|
10026
10420
|
try {
|
|
10027
10421
|
return JSON.stringify(value) ?? "";
|
|
@@ -10029,20 +10423,20 @@ function safeStringify13(value) {
|
|
|
10029
10423
|
return "";
|
|
10030
10424
|
}
|
|
10031
10425
|
}
|
|
10032
|
-
function
|
|
10426
|
+
function recordError8(span2, err) {
|
|
10033
10427
|
if (err instanceof Error) {
|
|
10034
|
-
span2.setStatus({ code:
|
|
10428
|
+
span2.setStatus({ code: SpanStatusCode15.ERROR, message: err.message });
|
|
10035
10429
|
span2.recordException(err);
|
|
10036
10430
|
} else {
|
|
10037
|
-
span2.setStatus({ code:
|
|
10431
|
+
span2.setStatus({ code: SpanStatusCode15.ERROR, message: String(err) });
|
|
10038
10432
|
}
|
|
10039
10433
|
span2.end();
|
|
10040
10434
|
}
|
|
10041
10435
|
|
|
10042
10436
|
// src/openrouter-agent.ts
|
|
10043
|
-
import { trace as
|
|
10044
|
-
var
|
|
10045
|
-
var
|
|
10437
|
+
import { trace as trace17, context as otelContext17, SpanStatusCode as SpanStatusCode16 } from "@opentelemetry/api";
|
|
10438
|
+
var TRACER_NAME14 = "neatlogs.openrouter_agent";
|
|
10439
|
+
var PROVIDER5 = "openrouter";
|
|
10046
10440
|
function wrapOpenRouterAgent(client) {
|
|
10047
10441
|
const c = client;
|
|
10048
10442
|
if (!c || c._neatlogsWrapped) return client;
|
|
@@ -10059,30 +10453,30 @@ function wrapOpenRouterAgent(client) {
|
|
|
10059
10453
|
function wrapCallModel(callModel) {
|
|
10060
10454
|
return function(clientArg, opts, ...rest) {
|
|
10061
10455
|
const span2 = startLlmSpan(opts);
|
|
10062
|
-
const ctx =
|
|
10063
|
-
const result =
|
|
10456
|
+
const ctx = trace17.setSpan(otelContext17.active(), span2);
|
|
10457
|
+
const result = otelContext17.with(ctx, () => callModel.call(this, clientArg, opts, ...rest));
|
|
10064
10458
|
return instrumentModelResult(result, span2);
|
|
10065
10459
|
};
|
|
10066
10460
|
}
|
|
10067
10461
|
function tracedCallModel(original) {
|
|
10068
10462
|
return function(opts, ...rest) {
|
|
10069
10463
|
const span2 = startLlmSpan(opts);
|
|
10070
|
-
const ctx =
|
|
10071
|
-
const result =
|
|
10464
|
+
const ctx = trace17.setSpan(otelContext17.active(), span2);
|
|
10465
|
+
const result = otelContext17.with(ctx, () => original(opts, ...rest));
|
|
10072
10466
|
return instrumentModelResult(result, span2);
|
|
10073
10467
|
};
|
|
10074
10468
|
}
|
|
10075
10469
|
function startLlmSpan(opts) {
|
|
10076
|
-
const tracer = getProviderTracer(
|
|
10470
|
+
const tracer = getProviderTracer(TRACER_NAME14);
|
|
10077
10471
|
const model = opts?.model ?? "";
|
|
10078
10472
|
const span2 = tracer.startSpan("openrouter.call_model", {
|
|
10079
10473
|
attributes: {
|
|
10080
10474
|
"neatlogs.span.kind": "LLM",
|
|
10081
|
-
"neatlogs.llm.provider":
|
|
10082
|
-
"neatlogs.llm.system":
|
|
10475
|
+
"neatlogs.llm.provider": PROVIDER5,
|
|
10476
|
+
"neatlogs.llm.system": PROVIDER5,
|
|
10083
10477
|
"neatlogs.llm.model_name": model
|
|
10084
10478
|
}
|
|
10085
|
-
},
|
|
10479
|
+
}, otelContext17.active());
|
|
10086
10480
|
const messages = Array.isArray(opts?.messages) ? opts.messages : Array.isArray(opts?.input) ? opts.input : [];
|
|
10087
10481
|
if (messages.length) {
|
|
10088
10482
|
messages.forEach((msg, i) => {
|
|
@@ -10090,10 +10484,10 @@ function startLlmSpan(opts) {
|
|
|
10090
10484
|
const content = msg?.content;
|
|
10091
10485
|
span2.setAttribute(
|
|
10092
10486
|
`neatlogs.llm.input_messages.${i}.content`,
|
|
10093
|
-
typeof content === "string" ? content :
|
|
10487
|
+
typeof content === "string" ? content : safeStringify15(content)
|
|
10094
10488
|
);
|
|
10095
10489
|
});
|
|
10096
|
-
span2.setAttribute("input.value",
|
|
10490
|
+
span2.setAttribute("input.value", safeStringify15({ messages }));
|
|
10097
10491
|
} else if (typeof opts?.input === "string") {
|
|
10098
10492
|
span2.setAttribute("neatlogs.llm.input_messages.0.role", "user");
|
|
10099
10493
|
span2.setAttribute("neatlogs.llm.input_messages.0.content", opts.input);
|
|
@@ -10134,7 +10528,7 @@ function startLlmSpan(opts) {
|
|
|
10134
10528
|
}
|
|
10135
10529
|
function instrumentModelResult(result, span2) {
|
|
10136
10530
|
if (!result || typeof result !== "object" && typeof result !== "function") {
|
|
10137
|
-
span2.setStatus({ code:
|
|
10531
|
+
span2.setStatus({ code: SpanStatusCode16.OK });
|
|
10138
10532
|
span2.end();
|
|
10139
10533
|
return result;
|
|
10140
10534
|
}
|
|
@@ -10145,14 +10539,14 @@ function instrumentModelResult(result, span2) {
|
|
|
10145
10539
|
try {
|
|
10146
10540
|
finalizeLlm(span2, resolved);
|
|
10147
10541
|
} catch {
|
|
10148
|
-
span2.setStatus({ code:
|
|
10542
|
+
span2.setStatus({ code: SpanStatusCode16.OK });
|
|
10149
10543
|
span2.end();
|
|
10150
10544
|
}
|
|
10151
10545
|
};
|
|
10152
10546
|
const finalizeError = (err) => {
|
|
10153
10547
|
if (finalized) return;
|
|
10154
10548
|
finalized = true;
|
|
10155
|
-
|
|
10549
|
+
recordError9(span2, err);
|
|
10156
10550
|
};
|
|
10157
10551
|
return new Proxy(result, {
|
|
10158
10552
|
get(obj, prop, receiver) {
|
|
@@ -10238,7 +10632,7 @@ function finalizeLlm(span2, result) {
|
|
|
10238
10632
|
span2.setAttribute(`neatlogs.llm.tool_calls.${j}.id`, tc?.id ?? "");
|
|
10239
10633
|
span2.setAttribute(`neatlogs.llm.tool_calls.${j}.name`, tc?.function?.name ?? tc?.name ?? "");
|
|
10240
10634
|
const args = tc?.function?.arguments ?? tc?.arguments;
|
|
10241
|
-
span2.setAttribute(`neatlogs.llm.tool_calls.${j}.arguments`, typeof args === "string" ? args :
|
|
10635
|
+
span2.setAttribute(`neatlogs.llm.tool_calls.${j}.arguments`, typeof args === "string" ? args : safeStringify15(args ?? {}));
|
|
10242
10636
|
});
|
|
10243
10637
|
}
|
|
10244
10638
|
const model = result?.model ?? result?.response?.model;
|
|
@@ -10248,7 +10642,7 @@ function finalizeLlm(span2, result) {
|
|
|
10248
10642
|
const finishReason = result?.finishReason ?? result?.finish_reason ?? result?.choices?.[0]?.finish_reason;
|
|
10249
10643
|
if (finishReason) span2.setAttribute("neatlogs.llm.finish_reason", String(finishReason));
|
|
10250
10644
|
setOpenResponsesUsage(span2, result);
|
|
10251
|
-
span2.setStatus({ code:
|
|
10645
|
+
span2.setStatus({ code: SpanStatusCode16.OK });
|
|
10252
10646
|
span2.end();
|
|
10253
10647
|
}
|
|
10254
10648
|
function extractOpenResponsesText(result) {
|
|
@@ -10264,7 +10658,7 @@ function extractOpenResponsesText(result) {
|
|
|
10264
10658
|
}
|
|
10265
10659
|
return parts.length ? parts.join("") : void 0;
|
|
10266
10660
|
}
|
|
10267
|
-
function
|
|
10661
|
+
function safeStringify15(value) {
|
|
10268
10662
|
if (typeof value === "string") return value;
|
|
10269
10663
|
try {
|
|
10270
10664
|
return JSON.stringify(value) ?? "";
|
|
@@ -10272,12 +10666,12 @@ function safeStringify14(value) {
|
|
|
10272
10666
|
return "";
|
|
10273
10667
|
}
|
|
10274
10668
|
}
|
|
10275
|
-
function
|
|
10669
|
+
function recordError9(span2, err) {
|
|
10276
10670
|
if (err instanceof Error) {
|
|
10277
|
-
span2.setStatus({ code:
|
|
10671
|
+
span2.setStatus({ code: SpanStatusCode16.ERROR, message: err.message });
|
|
10278
10672
|
span2.recordException(err);
|
|
10279
10673
|
} else {
|
|
10280
|
-
span2.setStatus({ code:
|
|
10674
|
+
span2.setStatus({ code: SpanStatusCode16.ERROR, message: String(err) });
|
|
10281
10675
|
}
|
|
10282
10676
|
span2.end();
|
|
10283
10677
|
}
|
|
@@ -10434,7 +10828,7 @@ var protoRoot = protobuf.Root.fromJSON(OTLP_PROTO_JSON);
|
|
|
10434
10828
|
var ExportTraceServiceRequest = protoRoot.lookupType(
|
|
10435
10829
|
"opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest"
|
|
10436
10830
|
);
|
|
10437
|
-
var
|
|
10831
|
+
var SpanStatusCode17 = { UNSET: 0, OK: 1, ERROR: 2 };
|
|
10438
10832
|
function randomBytes(length) {
|
|
10439
10833
|
const out = new Uint8Array(length);
|
|
10440
10834
|
const crypto = globalThis.crypto;
|
|
@@ -10641,7 +11035,7 @@ var NeatlogsOpencodePlugin = async (_ctx) => {
|
|
|
10641
11035
|
startTimeUnixNano: st.rootSpan.startNano,
|
|
10642
11036
|
endTimeUnixNano: nowNanoString(),
|
|
10643
11037
|
attributes: attrs,
|
|
10644
|
-
status: { code:
|
|
11038
|
+
status: { code: SpanStatusCode17.OK }
|
|
10645
11039
|
});
|
|
10646
11040
|
const m = nowNanoString();
|
|
10647
11041
|
shipper.enqueue({
|
|
@@ -10728,18 +11122,18 @@ var NeatlogsOpencodePlugin = async (_ctx) => {
|
|
|
10728
11122
|
{ key: "neatlogs.conversation.id", value: { stringValue: sessionID } }
|
|
10729
11123
|
];
|
|
10730
11124
|
if (start.args !== void 0) {
|
|
10731
|
-
setIO(attrs, "TOOL",
|
|
10732
|
-
push(attrs, attrStr("neatlogs.tool.input",
|
|
11125
|
+
setIO(attrs, "TOOL", safeStringify16(start.args), void 0);
|
|
11126
|
+
push(attrs, attrStr("neatlogs.tool.input", safeStringify16(start.args)));
|
|
10733
11127
|
}
|
|
10734
11128
|
if (result?.title) push(attrs, attrStr("neatlogs.tool.title", String(result.title)));
|
|
10735
11129
|
const out = result?.output ?? result?.result;
|
|
10736
11130
|
if (out !== void 0) {
|
|
10737
|
-
const o = typeof out === "string" ? out :
|
|
11131
|
+
const o = typeof out === "string" ? out : safeStringify16(out);
|
|
10738
11132
|
setIO(attrs, "TOOL", void 0, o);
|
|
10739
11133
|
push(attrs, attrStr("neatlogs.tool.output", o));
|
|
10740
11134
|
}
|
|
10741
11135
|
if (result?.metadata !== void 0) {
|
|
10742
|
-
push(attrs, attrStr("neatlogs.tool.metadata",
|
|
11136
|
+
push(attrs, attrStr("neatlogs.tool.metadata", safeStringify16(result.metadata)));
|
|
10743
11137
|
}
|
|
10744
11138
|
shipper.enqueue({
|
|
10745
11139
|
traceId: st.traceId,
|
|
@@ -10750,7 +11144,7 @@ var NeatlogsOpencodePlugin = async (_ctx) => {
|
|
|
10750
11144
|
startTimeUnixNano: start.startNano,
|
|
10751
11145
|
endTimeUnixNano: nowNanoString(),
|
|
10752
11146
|
attributes: attrs,
|
|
10753
|
-
status: { code:
|
|
11147
|
+
status: { code: SpanStatusCode17.OK }
|
|
10754
11148
|
});
|
|
10755
11149
|
} catch {
|
|
10756
11150
|
}
|
|
@@ -10837,10 +11231,10 @@ function emitLlmSpan2(shipper, st, info, sessionID) {
|
|
|
10837
11231
|
if (toolCalls.length) {
|
|
10838
11232
|
toolCalls.forEach((tc, j) => {
|
|
10839
11233
|
push(attrs, attrStr(`neatlogs.llm.tool_calls.${j}.name`, tc.name));
|
|
10840
|
-
push(attrs, attrStr(`neatlogs.llm.tool_calls.${j}.arguments`,
|
|
11234
|
+
push(attrs, attrStr(`neatlogs.llm.tool_calls.${j}.arguments`, safeStringify16(tc.input ?? {})));
|
|
10841
11235
|
});
|
|
10842
11236
|
if (!outText) {
|
|
10843
|
-
const rendered = toolCalls.map((tc) => `\u2192 ${tc.name}(${
|
|
11237
|
+
const rendered = toolCalls.map((tc) => `\u2192 ${tc.name}(${safeStringify16(tc.input ?? {})})`).join("\n");
|
|
10844
11238
|
push(attrs, attrStr("neatlogs.llm.output_messages.0.role", "assistant"));
|
|
10845
11239
|
push(attrs, attrStr("neatlogs.llm.output_messages.0.content", rendered));
|
|
10846
11240
|
setIO(attrs, "LLM", void 0, rendered);
|
|
@@ -10869,7 +11263,7 @@ function emitLlmSpan2(shipper, st, info, sessionID) {
|
|
|
10869
11263
|
startTimeUnixNano: startNano,
|
|
10870
11264
|
endTimeUnixNano: nowNanoString(),
|
|
10871
11265
|
attributes: attrs,
|
|
10872
|
-
status: { code:
|
|
11266
|
+
status: { code: SpanStatusCode17.OK }
|
|
10873
11267
|
});
|
|
10874
11268
|
if (info?.id) {
|
|
10875
11269
|
st.outputParts.delete(String(info.id));
|
|
@@ -10905,7 +11299,7 @@ function messageText2(info) {
|
|
|
10905
11299
|
}
|
|
10906
11300
|
return out.join("");
|
|
10907
11301
|
}
|
|
10908
|
-
function
|
|
11302
|
+
function safeStringify16(value) {
|
|
10909
11303
|
if (typeof value === "string") return value;
|
|
10910
11304
|
try {
|
|
10911
11305
|
return JSON.stringify(value) ?? "";
|
|
@@ -11000,7 +11394,8 @@ export {
|
|
|
11000
11394
|
trace2 as trace,
|
|
11001
11395
|
traceTool2 as traceToolAnthropic,
|
|
11002
11396
|
traceTool3 as traceToolAzureOpenAI,
|
|
11003
|
-
|
|
11397
|
+
traceTool6 as traceToolBedrock,
|
|
11398
|
+
traceTool5 as traceToolGoogleGenAI,
|
|
11004
11399
|
traceTool as traceToolOpenAI,
|
|
11005
11400
|
traceTool4 as traceToolVertexAI,
|
|
11006
11401
|
updatePrompt,
|
|
@@ -11010,6 +11405,8 @@ export {
|
|
|
11010
11405
|
wrapBedrock,
|
|
11011
11406
|
wrapCallModel,
|
|
11012
11407
|
wrapClaudeAgentSDK,
|
|
11408
|
+
wrapGoogleGenAI,
|
|
11409
|
+
wrapGoogleGenAIChat,
|
|
11013
11410
|
wrapMastra,
|
|
11014
11411
|
wrapOpenAI,
|
|
11015
11412
|
wrapOpenRouterAgent,
|