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/index.mjs CHANGED
@@ -2136,9 +2136,84 @@ function applyMask(spanData, globalMask) {
2136
2136
  }
2137
2137
  }
2138
2138
 
2139
- // src/prompt/template.ts
2139
+ // src/core/identity.ts
2140
2140
  import { AsyncLocalStorage } from "async_hooks";
2141
- var _promptStorage = new AsyncLocalStorage();
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 AsyncLocalStorage();
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.2";
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/bedrock.ts
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.bedrock";
7813
- var PROVIDER3 = "bedrock";
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 wrapBedrock(client) {
7844
- const c = client;
7845
- if (c._neatlogsBedrockPatched) return client;
7846
- if (typeof c.send !== "function") return client;
7847
- const originalSend = c.send.bind(c);
7848
- c.send = function(command, ...rest) {
7849
- const name = command?.constructor?.name ?? "";
7850
- const input = command?.input ?? {};
7851
- if (name === "ConverseCommand") {
7852
- return tracedConverse(originalSend, command, input, rest, false);
7853
- }
7854
- if (name === "ConverseStreamCommand") {
7855
- return tracedConverse(originalSend, command, input, rest, true);
7856
- }
7857
- if (name === "InvokeModelCommand") {
7858
- return tracedInvokeModel(originalSend, command, input, rest, false);
7859
- }
7860
- if (name === "InvokeModelWithResponseStreamCommand") {
7861
- return tracedInvokeModel(originalSend, command, input, rest, true);
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
- return originalSend(command, ...rest);
7864
- };
7865
- c._neatlogsBedrockPatched = true;
7866
- return client;
7873
+ });
7867
7874
  }
7868
- function vendorFromModel(modelId) {
7869
- let tail = String(modelId ?? "").split("/").pop() ?? "";
7870
- for (const prefix of ["us.", "eu.", "apac.", "us-gov."]) {
7871
- if (tail.startsWith(prefix)) tail = tail.slice(prefix.length);
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
- const vendor = tail.includes(".") ? tail.split(".")[0] : "";
7874
- return vendor || "bedrock";
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 startSpan(name, modelId, isStream) {
7877
- return getProviderTracer(TRACER_NAME7).startSpan(name, {
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": vendorFromModel(modelId),
7882
- "neatlogs.llm.model_name": String(modelId ?? ""),
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
- function tracedConverse(originalSend, command, input, rest, isStream) {
7888
- const span2 = startSpan(
7889
- isStream ? "bedrock.converse_stream" : "bedrock.converse",
7890
- input?.modelId,
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 promise = otelContext10.with(ctx, () => originalSend(command, ...rest));
7896
- return promise.then(
7916
+ const result = otelContext10.with(ctx, () => original(params, ...rest));
7917
+ return Promise.resolve(result).then(
7897
7918
  (response) => {
7898
- if (isStream) {
7899
- return wrapConverseStream(response, span2);
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 setConverseInput(span2, input) {
7911
- let idx = 0;
7912
- if (Array.isArray(input?.system)) {
7913
- const text = input.system.map((b) => b?.text ?? "").join(" ").trim();
7914
- if (text) {
7915
- span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, "system");
7916
- span2.setAttribute(`neatlogs.llm.input_messages.${idx}.content`, text);
7917
- idx++;
7918
- }
7919
- }
7920
- for (const msg of input?.messages ?? []) {
7921
- span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, msg?.role ?? "user");
7922
- span2.setAttribute(`neatlogs.llm.input_messages.${idx}.content`, converseBlocksToText(msg?.content));
7923
- idx++;
7924
- }
7925
- const cfg = input?.inferenceConfig ?? {};
7926
- if (cfg.temperature != null) span2.setAttribute("neatlogs.llm.temperature", cfg.temperature);
7927
- if (cfg.topP != null) span2.setAttribute("neatlogs.llm.top_p", cfg.topP);
7928
- if (cfg.maxTokens != null) span2.setAttribute("neatlogs.llm.max_tokens", cfg.maxTokens);
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`, safeStringify7(spec.inputSchema));
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 safeStringify7(content);
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(safeStringify7(block.toolResult));
7945
- else if ("toolUse" in block) parts.push(safeStringify7(block.toolUse));
7946
- else parts.push(safeStringify7(block));
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`, safeStringify7(tu?.input ?? {}));
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: SpanStatusCode9.OK });
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: SpanStatusCode9.OK });
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
- recordError5(span2, err);
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: SpanStatusCode9.OK });
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(TRACER_NAME7).startSpan("bedrock.invoke_model", {
8463
+ span2 = getProviderTracer(TRACER_NAME8).startSpan("bedrock.invoke_model", {
8070
8464
  attributes: {
8071
8465
  "neatlogs.span.kind": "EMBEDDING",
8072
- "neatlogs.llm.provider": PROVIDER3,
8466
+ "neatlogs.llm.provider": PROVIDER4,
8073
8467
  "neatlogs.embedding.model_name": String(input?.modelId ?? "")
8074
8468
  }
8075
- }, otelContext10.active());
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 : safeStringify7(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 = trace10.setSpan(otelContext10.active(), span2);
8089
- const promise = otelContext10.with(ctx, () => originalSend(command, ...rest));
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: SpanStatusCode9.OK });
8496
+ span2.setStatus({ code: SpanStatusCode10.OK });
8103
8497
  span2.end();
8104
8498
  }
8105
8499
  return response;
8106
8500
  },
8107
8501
  (err) => {
8108
- recordError5(span2, err);
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: SpanStatusCode9.OK });
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 : safeStringify7(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 : safeStringify7(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`, safeStringify7(b.input ?? {}));
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: SpanStatusCode9.OK });
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: SpanStatusCode9.OK });
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: SpanStatusCode9.OK });
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
- recordError5(span2, err);
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 safeStringify7(value) {
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 recordError5(span2, err) {
8704
+ function recordError6(span2, err) {
8311
8705
  if (err instanceof Error) {
8312
- span2.setStatus({ code: SpanStatusCode9.ERROR, message: err.message });
8706
+ span2.setStatus({ code: SpanStatusCode10.ERROR, message: err.message });
8313
8707
  span2.recordException(err);
8314
8708
  } else {
8315
- span2.setStatus({ code: SpanStatusCode9.ERROR, message: String(err) });
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 trace11, context as otelContext11, SpanStatusCode as SpanStatusCode10 } from "@opentelemetry/api";
8322
- var TRACER_NAME8 = "neatlogs.langchain";
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 trace11.setSpan(otelContext11.active(), parentSpan);
8740
+ return trace12.setSpan(otelContext12.active(), parentSpan);
8347
8741
  }
8348
- const tracer = trace11.getTracer(TRACER_NAME8);
8349
- const { root, ctx } = maybeOpenAutoRoot(tracer, kind, otelContext11.active());
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 = trace11.getTracer(TRACER_NAME8);
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"] = safeStringify8(inputs);
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", safeStringify8(outputs));
8379
- span2.setStatus({ code: SpanStatusCode10.OK });
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: SpanStatusCode10.ERROR, message: error.message });
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 = trace11.getTracer(TRACER_NAME8);
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 = trace11.getTracer(TRACER_NAME8);
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 : safeStringify8(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 ? safeStringify8(tc.args) : tc.function?.arguments ?? "");
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: SpanStatusCode10.OK });
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: SpanStatusCode10.ERROR, message: error.message });
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 = trace11.getTracer(TRACER_NAME8);
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: SpanStatusCode10.OK });
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: SpanStatusCode10.ERROR, message: error.message });
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 = trace11.getTracer(TRACER_NAME8);
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: SpanStatusCode10.OK });
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: SpanStatusCode10.ERROR, message: error.message });
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 safeStringify8(value) {
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", safeStringify9({ role: "assistant", content: out }));
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 = safeStringify9({ messages: existing });
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"}(${safeStringify9(o.toolUse.input ?? {})})`);
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(safeStringify9(o));
9111
+ else out.push(safeStringify10(o));
8718
9112
  }
8719
9113
  return out.filter(Boolean).join("\n");
8720
9114
  }
8721
- function safeStringify9(value) {
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 trace12, context as otelContext12, SpanStatusCode as SpanStatusCode11 } from "@opentelemetry/api";
8732
- var TRACER_NAME9 = "neatlogs.openai_agents";
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 = trace12.getTracer(TRACER_NAME9);
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 }, otelContext12.active());
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: SpanStatusCode11.OK });
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 = trace12.getTracer(TRACER_NAME9);
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 ? trace12.setSpan(otelContext12.active(), parentSpan) : otelContext12.active();
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 : safeStringify10(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 : safeStringify10(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 : safeStringify10(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 : safeStringify10(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 : safeStringify10(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 : safeStringify10(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: SpanStatusCode11.ERROR, message: error.message });
9277
+ otelSpan.setStatus({ code: SpanStatusCode12.ERROR, message: error.message });
8884
9278
  otelSpan.recordException(error);
8885
9279
  } else {
8886
- otelSpan.setStatus({ code: SpanStatusCode11.ERROR, message: String(error) });
9280
+ otelSpan.setStatus({ code: SpanStatusCode12.ERROR, message: String(error) });
8887
9281
  }
8888
9282
  } else {
8889
- otelSpan.setStatus({ code: SpanStatusCode11.OK });
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: SpanStatusCode11.ERROR, message: "Processor shutdown before span completed" });
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 safeStringify10(value) {
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 trace13, context as otelContext13, SpanStatusCode as SpanStatusCode12 } from "@opentelemetry/api";
8919
- var TRACER_NAME10 = "neatlogs.mastra";
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 = trace13.getTracer(TRACER_NAME10);
8986
- const span2 = tracer.startSpan(`mastra.agent.${agentName}`, { attributes: attrs }, otelContext13.active());
8987
- const ctx = trace13.setSpan(otelContext13.active(), span2);
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 otelContext13.with(ctx, () => orig(input, opts));
9383
+ const result = await otelContext14.with(ctx, () => orig(input, opts));
8990
9384
  return wrapStreamingOutput(result, span2, ctx);
8991
9385
  } catch (err) {
8992
- recordError6(span2, err);
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"] = safeStringify11(promptInput);
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": safeStringify11(params)
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", safeStringify11(result));
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"] = safeStringify11(startOpts.inputData);
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", safeStringify11({ status: result.status }));
9498
+ if (result?.status) span2.setAttribute("neatlogs.metadata", safeStringify12({ status: result.status }));
9105
9499
  if (result?.result !== void 0) {
9106
- span2.setAttribute("output.value", safeStringify11(result.result));
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": safeStringify11(params)
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", safeStringify11(result));
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": safeStringify11(args?.[0])
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", safeStringify11(result));
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: SpanStatusCode12.OK });
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) recordError6(span2, err);
9202
- else span2.setStatus({ code: SpanStatusCode12.OK });
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 otelContext13.with(ctx, () => origIterator());
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", safeStringify11(result.content));
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 ?? safeStringify11(fr));
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"] = safeStringify11(callOpts.stopSequences);
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}`] = safeStringify11(callOpts.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"] = safeStringify11(invocation);
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`, safeStringify11(args ?? {}));
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 = trace13.getTracer(TRACER_NAME10);
9404
- const span2 = tracer.startSpan(name, { attributes: attrs }, otelContext13.active());
9405
- const ctx = trace13.setSpan(otelContext13.active(), span2);
9406
- return otelContext13.with(ctx, async () => {
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: SpanStatusCode12.OK });
9803
+ span2.setStatus({ code: SpanStatusCode13.OK });
9410
9804
  return result;
9411
9805
  } catch (err) {
9412
- recordError6(span2, err);
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 : safeStringify11(input);
9826
+ return typeof input === "string" ? input : safeStringify12(input);
9433
9827
  }
9434
- function safeStringify11(value) {
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 recordError6(span2, err) {
9836
+ function recordError7(span2, err) {
9443
9837
  if (err instanceof Error) {
9444
- span2.setStatus({ code: SpanStatusCode12.ERROR, message: err.message });
9838
+ span2.setStatus({ code: SpanStatusCode13.ERROR, message: err.message });
9445
9839
  span2.recordException(err);
9446
9840
  } else {
9447
- span2.setStatus({ code: SpanStatusCode12.ERROR, message: String(err) });
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 trace14,
9454
- context as otelContext14,
9455
- SpanStatusCode as SpanStatusCode13
9847
+ trace as trace15,
9848
+ context as otelContext15,
9849
+ SpanStatusCode as SpanStatusCode14
9456
9850
  } from "@opentelemetry/api";
9457
- var TRACER_NAME11 = "neatlogs.pi-agent";
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 = trace14.getTracer(TRACER_NAME11);
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
- otelContext14.active()
9874
+ otelContext15.active()
9481
9875
  );
9482
9876
  state.agentSpan = span2;
9483
- state.agentCtx = trace14.setSpan(otelContext14.active(), span2);
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 ?? otelContext14.active();
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": safeStringify12(event.args) } : {}
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", safeStringify12(event.result));
9915
+ span2.setAttribute("output.value", safeStringify13(event.result));
9522
9916
  }
9523
9917
  if (event.isError) {
9524
- span2.setStatus({ code: SpanStatusCode13.ERROR });
9918
+ span2.setStatus({ code: SpanStatusCode14.ERROR });
9525
9919
  span2.setAttribute("neatlogs.tool.is_error", true);
9526
9920
  } else {
9527
- span2.setStatus({ code: SpanStatusCode13.OK });
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: SpanStatusCode13.OK });
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"] = safeStringify12({ messages: inMsgs });
9569
- attrs["input.value"] = safeStringify12({ messages: inMsgs });
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}(${safeStringify12(tc.arguments)})`).join("\n");
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`] = safeStringify12(tc.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"] = safeStringify12(outBlob);
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 ?? otelContext14.active();
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: SpanStatusCode13.OK });
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"}(${safeStringify12(block.arguments)})`);
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 safeStringify12(value) {
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 trace15, context as otelContext15, SpanStatusCode as SpanStatusCode14 } from "@opentelemetry/api";
9666
- var TRACER_NAME12 = "neatlogs.claude_agent_sdk";
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 = trace15.getTracer(TRACER_NAME12);
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
- otelContext15.active()
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 = trace15.setSpan(otelContext15.active(), agentSpan);
9702
- const queryObj = otelContext15.with(agentCtx, () => original(params, ...rest));
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: SpanStatusCode14.OK });
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
- recordError7(agentSpan, err);
10150
+ recordError8(agentSpan, err);
9757
10151
  } else {
9758
- agentSpan.setStatus({ code: SpanStatusCode14.OK });
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 otelContext15.with(agentCtx, () => iterator.next());
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" ? SpanStatusCode14.OK : SpanStatusCode14.ERROR });
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 ? trace15.setSpan(otelContext15.active(), parentToolSpan) : state.scopes.get(ROOT_SCOPE).ctx;
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: trace15.setSpan(otelContext15.active(), span2),
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) setUsage2(rootScope.span, 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"] = safeStringify13({ messages: scope.inputMessages });
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}(${safeStringify13(tc.input ?? {})})`).join("\n");
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`] = safeStringify13(tc.input ?? {});
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) setUsage2(span2, buf.usage);
9949
- span2.setStatus({ code: SpanStatusCode14.OK });
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} ${safeStringify13(tc.input ?? {})}]`);
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": safeStringify13(tc.input ?? {})
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 : safeStringify13(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: SpanStatusCode14.ERROR });
10378
+ span2.setStatus({ code: SpanStatusCode15.ERROR });
9985
10379
  span2.setAttribute("neatlogs.tool.is_error", true);
9986
10380
  } else {
9987
- span2.setStatus({ code: SpanStatusCode14.OK });
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 setUsage2(span2, usage) {
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 safeStringify13(value) {
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 recordError7(span2, err) {
10426
+ function recordError8(span2, err) {
10033
10427
  if (err instanceof Error) {
10034
- span2.setStatus({ code: SpanStatusCode14.ERROR, message: err.message });
10428
+ span2.setStatus({ code: SpanStatusCode15.ERROR, message: err.message });
10035
10429
  span2.recordException(err);
10036
10430
  } else {
10037
- span2.setStatus({ code: SpanStatusCode14.ERROR, message: String(err) });
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 trace16, context as otelContext16, SpanStatusCode as SpanStatusCode15 } from "@opentelemetry/api";
10044
- var TRACER_NAME13 = "neatlogs.openrouter_agent";
10045
- var PROVIDER4 = "openrouter";
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 = trace16.setSpan(otelContext16.active(), span2);
10063
- const result = otelContext16.with(ctx, () => callModel.call(this, clientArg, opts, ...rest));
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 = trace16.setSpan(otelContext16.active(), span2);
10071
- const result = otelContext16.with(ctx, () => original(opts, ...rest));
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(TRACER_NAME13);
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": PROVIDER4,
10082
- "neatlogs.llm.system": PROVIDER4,
10475
+ "neatlogs.llm.provider": PROVIDER5,
10476
+ "neatlogs.llm.system": PROVIDER5,
10083
10477
  "neatlogs.llm.model_name": model
10084
10478
  }
10085
- }, otelContext16.active());
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 : safeStringify14(content)
10487
+ typeof content === "string" ? content : safeStringify15(content)
10094
10488
  );
10095
10489
  });
10096
- span2.setAttribute("input.value", safeStringify14({ messages }));
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: SpanStatusCode15.OK });
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: SpanStatusCode15.OK });
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
- recordError8(span2, err);
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 : safeStringify14(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: SpanStatusCode15.OK });
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 safeStringify14(value) {
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 recordError8(span2, err) {
10669
+ function recordError9(span2, err) {
10276
10670
  if (err instanceof Error) {
10277
- span2.setStatus({ code: SpanStatusCode15.ERROR, message: err.message });
10671
+ span2.setStatus({ code: SpanStatusCode16.ERROR, message: err.message });
10278
10672
  span2.recordException(err);
10279
10673
  } else {
10280
- span2.setStatus({ code: SpanStatusCode15.ERROR, message: String(err) });
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 SpanStatusCode16 = { UNSET: 0, OK: 1, ERROR: 2 };
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: SpanStatusCode16.OK }
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", safeStringify15(start.args), void 0);
10732
- push(attrs, attrStr("neatlogs.tool.input", safeStringify15(start.args)));
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 : safeStringify15(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", safeStringify15(result.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: SpanStatusCode16.OK }
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`, safeStringify15(tc.input ?? {})));
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}(${safeStringify15(tc.input ?? {})})`).join("\n");
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: SpanStatusCode16.OK }
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 safeStringify15(value) {
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
- traceTool5 as traceToolBedrock,
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,