neatlogs 1.0.5 → 1.0.6

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.d.ts CHANGED
@@ -6,6 +6,7 @@ export { langchainHandler } from './langchain.js';
6
6
  export { strandsHooks } from './strands.js';
7
7
  export { openaiAgentsProcessor } from './openai-agents.js';
8
8
  export { wrapMastra } from './mastra-wrap.js';
9
+ export { piAgentHooks } from './pi-agent.js';
9
10
 
10
11
  /**
11
12
  * Span kind for categorizing instrumented operations.
@@ -531,8 +532,9 @@ declare function registerCrewaiTask(task: {
531
532
  }, vars?: Record<string, any>): void;
532
533
 
533
534
  /**
534
- * SDK version. Updated during release process.
535
+ * SDK version. Kept in sync with package.json by the `version:sync` script
536
+ * (runs automatically on `prebuild`). Do not edit by hand — bump package.json.
535
537
  */
536
- declare const __version__ = "1.0.0";
538
+ declare const __version__ = "1.0.6";
537
539
 
538
540
  export { type CachedPrompt, type InitOptions, type MaskFunction, PromptApiError, PromptClient, PromptClientError, PromptHandle, type PromptMessage, PromptNotFoundError, PromptTemplate, Span, type SpanKind, type SpanOptions, type TraceOptions, UserPromptTemplate, __version__, bindTemplates, createPrompt, deletePrompt, fetchPrompt, flush, getMastraObservability, getPrompt, getSessionConfig, init, isDebugEnabled, listPrompts, log, registerCrewaiTask, removeTag, saveAsVersion, shutdown, span, trace, updatePrompt };
package/dist/index.mjs CHANGED
@@ -5800,7 +5800,7 @@ async function removeTag(name, tag) {
5800
5800
  }
5801
5801
 
5802
5802
  // src/version.ts
5803
- var __version__ = "1.0.0";
5803
+ var __version__ = "1.0.6";
5804
5804
 
5805
5805
  // src/init.ts
5806
5806
  var logger13 = getLogger();
@@ -7329,20 +7329,143 @@ function safeStringify5(value) {
7329
7329
  }
7330
7330
 
7331
7331
  // src/strands.ts
7332
+ var PATCH_FLAG = "_neatlogs_patched";
7332
7333
  function strandsHooks(agent) {
7334
+ installEventHookFromAgent(agent);
7333
7335
  if (agent && typeof agent === "object") {
7334
7336
  try {
7335
- Object.defineProperty(agent, "_neatlogs_patched", {
7337
+ Object.defineProperty(agent, PATCH_FLAG, {
7336
7338
  value: true,
7337
7339
  enumerable: false,
7338
7340
  configurable: true
7339
7341
  });
7340
7342
  } catch {
7341
- agent._neatlogs_patched = true;
7343
+ agent[PATCH_FLAG] = true;
7342
7344
  }
7343
7345
  }
7344
7346
  return agent;
7345
7347
  }
7348
+ function installEventHookFromAgent(agent) {
7349
+ const tracer = agent?._tracer;
7350
+ const proto = tracer ? Object.getPrototypeOf(tracer) : void 0;
7351
+ if (!proto || typeof proto._addEvent !== "function") return;
7352
+ if (proto._addEvent[PATCH_FLAG]) return;
7353
+ const orig = proto._addEvent;
7354
+ function patchedAddEvent(span2, eventName, eventAttributes) {
7355
+ const result = orig.call(this, span2, eventName, eventAttributes);
7356
+ try {
7357
+ enrichSpanFromEvent(span2, eventName, eventAttributes || {});
7358
+ } catch {
7359
+ }
7360
+ return result;
7361
+ }
7362
+ patchedAddEvent[PATCH_FLAG] = true;
7363
+ proto._addEvent = patchedAddEvent;
7364
+ }
7365
+ function enrichSpanFromEvent(span2, eventName, attrs) {
7366
+ if (!span2 || typeof span2.setAttribute !== "function") return;
7367
+ if (typeof span2.isRecording === "function" && !span2.isRecording()) return;
7368
+ const isTool = readSpanOp(span2) === "execute_tool";
7369
+ if (eventName.startsWith("gen_ai.") && eventName.endsWith(".message")) {
7370
+ const role = eventName.slice("gen_ai.".length, -".message".length);
7371
+ const content = flattenStrandsContent(attrs.content);
7372
+ if (content) {
7373
+ if (isTool) {
7374
+ span2.setAttribute("input.value", content);
7375
+ span2.setAttribute("neatlogs.tool.input", content);
7376
+ } else {
7377
+ appendInputMessage(span2, role, content);
7378
+ }
7379
+ }
7380
+ return;
7381
+ }
7382
+ if (eventName === "gen_ai.choice") {
7383
+ const out = flattenStrandsContent(attrs.message);
7384
+ if (out) setOutput(span2, isTool, out);
7385
+ return;
7386
+ }
7387
+ if (eventName === "gen_ai.client.inference.operation.details") {
7388
+ const out = flattenStrandsContent(attrs["gen_ai.output.messages"]);
7389
+ if (out) setOutput(span2, isTool, out);
7390
+ }
7391
+ }
7392
+ function setOutput(span2, isTool, out) {
7393
+ span2.setAttribute("output.value", out);
7394
+ if (isTool) {
7395
+ span2.setAttribute("neatlogs.tool.output", out);
7396
+ } else {
7397
+ span2.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
7398
+ span2.setAttribute("neatlogs.llm.output_messages.0.content", out);
7399
+ span2.setAttribute("neatlogs.llm.output", safeStringify6({ role: "assistant", content: out }));
7400
+ }
7401
+ }
7402
+ function appendInputMessage(span2, role, content) {
7403
+ const idx = span2.__neatlogs_in_idx ?? 0;
7404
+ span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, role);
7405
+ span2.setAttribute(`neatlogs.llm.input_messages.${idx}.content`, content);
7406
+ span2.__neatlogs_in_idx = idx + 1;
7407
+ const existing = span2.__neatlogs_in_msgs ?? [];
7408
+ existing.push({ role, content });
7409
+ span2.__neatlogs_in_msgs = existing;
7410
+ const blob = safeStringify6({ messages: existing });
7411
+ span2.setAttribute("input.value", blob);
7412
+ span2.setAttribute("neatlogs.llm.input", blob);
7413
+ }
7414
+ function readSpanOp(span2) {
7415
+ try {
7416
+ const a = span2.attributes;
7417
+ if (!a) return "";
7418
+ const v = typeof a.get === "function" ? a.get("gen_ai.operation.name") : a["gen_ai.operation.name"];
7419
+ return typeof v === "string" ? v.toLowerCase() : "";
7420
+ } catch {
7421
+ return "";
7422
+ }
7423
+ }
7424
+ function flattenStrandsContent(content) {
7425
+ if (content == null) return "";
7426
+ let val = content;
7427
+ if (typeof val === "string") {
7428
+ const s = val.trim();
7429
+ if (!(s.startsWith("[") || s.startsWith("{"))) return val;
7430
+ try {
7431
+ val = JSON.parse(s);
7432
+ } catch {
7433
+ return val;
7434
+ }
7435
+ }
7436
+ return flattenBlocks(val);
7437
+ }
7438
+ function flattenBlocks(val) {
7439
+ const items = Array.isArray(val) ? val : [val];
7440
+ const out = [];
7441
+ for (const item of items) {
7442
+ if (typeof item === "string") {
7443
+ out.push(item);
7444
+ continue;
7445
+ }
7446
+ if (!item || typeof item !== "object") {
7447
+ if (item != null) out.push(String(item));
7448
+ continue;
7449
+ }
7450
+ const o = item;
7451
+ if (typeof o.text === "string") out.push(o.text);
7452
+ else if (typeof o.content === "string") out.push(o.content);
7453
+ else if (o.toolUse) out.push(`${o.toolUse.name ?? "tool"}(${safeStringify6(o.toolUse.input ?? {})})`);
7454
+ else if (o.toolResult) out.push(flattenBlocks(o.toolResult.content ?? o.toolResult));
7455
+ else if (Array.isArray(o.parts)) out.push(flattenBlocks(o.parts));
7456
+ else if (Array.isArray(o.content)) out.push(flattenBlocks(o.content));
7457
+ else out.push(safeStringify6(o));
7458
+ }
7459
+ return out.filter(Boolean).join("\n");
7460
+ }
7461
+ function safeStringify6(value) {
7462
+ if (typeof value === "string") return value;
7463
+ try {
7464
+ return JSON.stringify(value) ?? "";
7465
+ } catch {
7466
+ return "";
7467
+ }
7468
+ }
7346
7469
 
7347
7470
  // src/openai-agents.ts
7348
7471
  import { trace as trace9, context as otelContext7, SpanStatusCode as SpanStatusCode8 } from "@opentelemetry/api";
@@ -7414,7 +7537,7 @@ var NeatlogsTraceProcessor = class {
7414
7537
  const role = typeof msg === "object" ? msg.role ?? "" : "";
7415
7538
  const content = typeof msg === "object" ? msg.content ?? "" : String(msg);
7416
7539
  if (role) attrs[`neatlogs.llm.input_messages.${i}.role`] = role;
7417
- if (content) attrs[`neatlogs.llm.input_messages.${i}.content`] = (typeof content === "string" ? content : safeStringify6(content)).slice(0, 1e4);
7540
+ if (content) attrs[`neatlogs.llm.input_messages.${i}.content`] = (typeof content === "string" ? content : safeStringify7(content)).slice(0, 1e4);
7418
7541
  }
7419
7542
  }
7420
7543
  otelSpan = tracer.startSpan("openai_agents.generation", { attributes: attrs }, parentCtx);
@@ -7426,7 +7549,7 @@ var NeatlogsTraceProcessor = class {
7426
7549
  };
7427
7550
  const toolInput = data?.input ?? data?.arguments;
7428
7551
  if (toolInput !== void 0) {
7429
- attrs["input.value"] = (typeof toolInput === "string" ? toolInput : safeStringify6(toolInput)).slice(0, 1e4);
7552
+ attrs["input.value"] = (typeof toolInput === "string" ? toolInput : safeStringify7(toolInput)).slice(0, 1e4);
7430
7553
  }
7431
7554
  otelSpan = tracer.startSpan(`openai_agents.tool.${toolName}`, { attributes: attrs }, parentCtx);
7432
7555
  } else if (spanType === "handoff") {
@@ -7463,13 +7586,13 @@ var NeatlogsTraceProcessor = class {
7463
7586
  for (let i = 0; i < toolCalls.length; i++) {
7464
7587
  const tc = toolCalls[i];
7465
7588
  otelSpan.setAttribute(`neatlogs.llm.tool_calls.${i}.name`, tc.name ?? "");
7466
- otelSpan.setAttribute(`neatlogs.llm.tool_calls.${i}.arguments`, typeof tc.arguments === "string" ? tc.arguments : safeStringify6(tc.arguments ?? {}));
7589
+ otelSpan.setAttribute(`neatlogs.llm.tool_calls.${i}.arguments`, typeof tc.arguments === "string" ? tc.arguments : safeStringify7(tc.arguments ?? {}));
7467
7590
  if (tc.callId ?? tc.id) otelSpan.setAttribute(`neatlogs.llm.tool_calls.${i}.id`, tc.callId ?? tc.id);
7468
7591
  }
7469
7592
  } else if (outputItems?.content) {
7470
7593
  otelSpan.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
7471
7594
  const c = outputItems.content;
7472
- otelSpan.setAttribute("neatlogs.llm.output_messages.0.content", (typeof c === "string" ? c : safeStringify6(c)).slice(0, 1e4));
7595
+ otelSpan.setAttribute("neatlogs.llm.output_messages.0.content", (typeof c === "string" ? c : safeStringify7(c)).slice(0, 1e4));
7473
7596
  }
7474
7597
  const usage = data?.usage ?? resp?.usage;
7475
7598
  if (usage) {
@@ -7486,12 +7609,12 @@ var NeatlogsTraceProcessor = class {
7486
7609
  } else if (spanType === "function" || spanType === "tool" || spanType === "tool_call") {
7487
7610
  const output = data?.output ?? data?.result;
7488
7611
  if (output != null) {
7489
- otelSpan.setAttribute("output.value", (typeof output === "string" ? output : safeStringify6(output)).slice(0, 1e4));
7612
+ otelSpan.setAttribute("output.value", (typeof output === "string" ? output : safeStringify7(output)).slice(0, 1e4));
7490
7613
  }
7491
7614
  } else if (spanType === "agent" || spanType === "agent_run") {
7492
7615
  const output = data?.output;
7493
7616
  if (output != null) {
7494
- otelSpan.setAttribute("output.value", (typeof output === "string" ? output : safeStringify6(output)).slice(0, 1e4));
7617
+ otelSpan.setAttribute("output.value", (typeof output === "string" ? output : safeStringify7(output)).slice(0, 1e4));
7495
7618
  }
7496
7619
  }
7497
7620
  const error = data?.error ?? span2?.error;
@@ -7523,7 +7646,7 @@ var NeatlogsTraceProcessor = class {
7523
7646
  forceFlush() {
7524
7647
  }
7525
7648
  };
7526
- function safeStringify6(value) {
7649
+ function safeStringify7(value) {
7527
7650
  try {
7528
7651
  return typeof value === "string" ? value : JSON.stringify(value);
7529
7652
  } catch {
@@ -7534,9 +7657,9 @@ function safeStringify6(value) {
7534
7657
  // src/mastra-wrap.ts
7535
7658
  import { trace as trace10, context as otelContext8, SpanStatusCode as SpanStatusCode9 } from "@opentelemetry/api";
7536
7659
  var TRACER_NAME7 = "neatlogs.mastra";
7537
- var PATCH_FLAG = "_neatlogs_patched";
7660
+ var PATCH_FLAG2 = "_neatlogs_patched";
7538
7661
  function wrapMastra(entity) {
7539
- if (!entity || entity[PATCH_FLAG]) return entity;
7662
+ if (!entity || entity[PATCH_FLAG2]) return entity;
7540
7663
  const e = entity;
7541
7664
  const className = entity.constructor?.name ?? "";
7542
7665
  if (isRootMastra(e)) {
@@ -7649,7 +7772,7 @@ function patchModelInPlace(model) {
7649
7772
  if (provider) attrs["neatlogs.llm.provider"] = provider;
7650
7773
  if (isStream) attrs["neatlogs.llm.is_streaming"] = true;
7651
7774
  const promptInput = callOpts?.prompt ?? callOpts?.messages;
7652
- if (promptInput !== void 0) attrs["input.value"] = safeStringify7(promptInput).slice(0, 1e4);
7775
+ if (promptInput !== void 0) attrs["input.value"] = safeStringify8(promptInput).slice(0, 1e4);
7653
7776
  captureInvocationParams(attrs, callOpts);
7654
7777
  return withActiveSpan(`mastra.llm.${modelId || "model"}.${fn}`, attrs, async (span2) => {
7655
7778
  const result = await orig(callOpts);
@@ -7683,12 +7806,12 @@ function patchToolExecute(tool, key) {
7683
7806
  const attrs = {
7684
7807
  "neatlogs.span.kind": "TOOL",
7685
7808
  "neatlogs.tool.name": toolName,
7686
- "input.value": safeStringify7(params).slice(0, 1e4)
7809
+ "input.value": safeStringify8(params).slice(0, 1e4)
7687
7810
  };
7688
7811
  if (tool.description) attrs["neatlogs.tool.description"] = String(tool.description).slice(0, 2e3);
7689
7812
  return withActiveSpan(`mastra.tool.${toolName}`, attrs, async (span2) => {
7690
7813
  const result = await orig(params, options);
7691
- span2.setAttribute("output.value", safeStringify7(result).slice(0, 1e4));
7814
+ span2.setAttribute("output.value", safeStringify8(result).slice(0, 1e4));
7692
7815
  return result;
7693
7816
  });
7694
7817
  };
@@ -7714,13 +7837,13 @@ function patchRunMethod(run, method, workflowName) {
7714
7837
  "neatlogs.workflow.name": workflowName
7715
7838
  };
7716
7839
  if (startOpts?.inputData !== void 0) {
7717
- attrs["input.value"] = safeStringify7(startOpts.inputData).slice(0, 1e4);
7840
+ attrs["input.value"] = safeStringify8(startOpts.inputData).slice(0, 1e4);
7718
7841
  }
7719
7842
  return withActiveSpan(`mastra.workflow.${workflowName}`, attrs, async (span2) => {
7720
7843
  const result = await orig(startOpts);
7721
- if (result?.status) span2.setAttribute("neatlogs.metadata", safeStringify7({ status: result.status }));
7844
+ if (result?.status) span2.setAttribute("neatlogs.metadata", safeStringify8({ status: result.status }));
7722
7845
  if (result?.result !== void 0) {
7723
- span2.setAttribute("output.value", safeStringify7(result.result).slice(0, 1e4));
7846
+ span2.setAttribute("output.value", safeStringify8(result.result).slice(0, 1e4));
7724
7847
  }
7725
7848
  return result;
7726
7849
  });
@@ -7741,14 +7864,14 @@ function patchVectorOp(vector, op, kind) {
7741
7864
  "neatlogs.span.kind": kind,
7742
7865
  "neatlogs.db.system": dbName,
7743
7866
  "neatlogs.db.operation": op,
7744
- "input.value": safeStringify7(params).slice(0, 1e4)
7867
+ "input.value": safeStringify8(params).slice(0, 1e4)
7745
7868
  };
7746
7869
  const indexName = params?.indexName;
7747
7870
  if (indexName) attrs["neatlogs.vectordb.index_name"] = String(indexName);
7748
7871
  if (kind === "RETRIEVER" && params?.topK != null) attrs["neatlogs.retriever.top_k"] = params.topK;
7749
7872
  return withActiveSpan(`mastra.vector.${op}`, attrs, async (span2) => {
7750
7873
  const result = await orig(params);
7751
- span2.setAttribute("output.value", safeStringify7(result).slice(0, 1e4));
7874
+ span2.setAttribute("output.value", safeStringify8(result).slice(0, 1e4));
7752
7875
  return result;
7753
7876
  });
7754
7877
  };
@@ -7762,11 +7885,11 @@ function patchMemory(memory) {
7762
7885
  const attrs = {
7763
7886
  "neatlogs.span.kind": "CHAIN",
7764
7887
  "neatlogs.db.operation": op,
7765
- "input.value": safeStringify7(args?.[0]).slice(0, 1e4)
7888
+ "input.value": safeStringify8(args?.[0]).slice(0, 1e4)
7766
7889
  };
7767
7890
  return withActiveSpan(`mastra.memory.${op}`, attrs, async (span2) => {
7768
7891
  const result = await orig(...args);
7769
- span2.setAttribute("output.value", safeStringify7(result).slice(0, 8e3));
7892
+ span2.setAttribute("output.value", safeStringify8(result).slice(0, 8e3));
7770
7893
  return result;
7771
7894
  });
7772
7895
  };
@@ -7949,7 +8072,7 @@ function finalizeModelResult(span2, result) {
7949
8072
  const tc = toolCalls[i];
7950
8073
  setToolCall(span2, i, tc.toolName, tc.input ?? tc.args, tc.toolCallId);
7951
8074
  }
7952
- span2.setAttribute("output.value", safeStringify7(result.content).slice(0, 1e4));
8075
+ span2.setAttribute("output.value", safeStringify8(result.content).slice(0, 1e4));
7953
8076
  }
7954
8077
  if (result.usage) recordUsage(span2, result.usage);
7955
8078
  span2.setAttribute("neatlogs.llm.stop_reason", normalizeFinishReason(result.finishReason));
@@ -7957,7 +8080,7 @@ function finalizeModelResult(span2, result) {
7957
8080
  function normalizeFinishReason(fr) {
7958
8081
  if (fr == null) return "";
7959
8082
  if (typeof fr === "string") return fr;
7960
- return String(fr.unified ?? fr.reason ?? fr.type ?? safeStringify7(fr));
8083
+ return String(fr.unified ?? fr.reason ?? fr.type ?? safeStringify8(fr));
7961
8084
  }
7962
8085
  function tokenValue(v) {
7963
8086
  if (v == null) return void 0;
@@ -7986,22 +8109,22 @@ function captureInvocationParams(attrs, callOpts) {
7986
8109
  }
7987
8110
  }
7988
8111
  if (Array.isArray(callOpts.stopSequences) && callOpts.stopSequences.length) {
7989
- attrs["neatlogs.llm.stop_sequences"] = safeStringify7(callOpts.stopSequences);
8112
+ attrs["neatlogs.llm.stop_sequences"] = safeStringify8(callOpts.stopSequences);
7990
8113
  invocation.stopSequences = callOpts.stopSequences;
7991
8114
  }
7992
8115
  if (Array.isArray(callOpts.tools)) {
7993
8116
  for (let i = 0; i < callOpts.tools.length; i++) {
7994
- attrs[`neatlogs.llm.tools.${i}`] = safeStringify7(callOpts.tools[i]).slice(0, 4e3);
8117
+ attrs[`neatlogs.llm.tools.${i}`] = safeStringify8(callOpts.tools[i]).slice(0, 4e3);
7995
8118
  }
7996
8119
  invocation.toolChoice = callOpts.toolChoice;
7997
8120
  }
7998
8121
  if (Object.keys(invocation).length) {
7999
- attrs["neatlogs.llm.invocation_parameters"] = safeStringify7(invocation).slice(0, 4e3);
8122
+ attrs["neatlogs.llm.invocation_parameters"] = safeStringify8(invocation).slice(0, 4e3);
8000
8123
  }
8001
8124
  }
8002
8125
  function setToolCall(span2, i, name, args, id) {
8003
8126
  span2.setAttribute(`neatlogs.llm.tool_calls.${i}.name`, name ?? "");
8004
- span2.setAttribute(`neatlogs.llm.tool_calls.${i}.arguments`, safeStringify7(args ?? {}));
8127
+ span2.setAttribute(`neatlogs.llm.tool_calls.${i}.arguments`, safeStringify8(args ?? {}));
8005
8128
  if (id) span2.setAttribute(`neatlogs.llm.tool_calls.${i}.id`, id);
8006
8129
  }
8007
8130
  function recordUsage(span2, usage) {
@@ -8035,9 +8158,9 @@ function withActiveSpan(name, attrs, fn) {
8035
8158
  }
8036
8159
  function markPatched(e) {
8037
8160
  try {
8038
- Object.defineProperty(e, PATCH_FLAG, { value: true, enumerable: false, configurable: true });
8161
+ Object.defineProperty(e, PATCH_FLAG2, { value: true, enumerable: false, configurable: true });
8039
8162
  } catch {
8040
- e[PATCH_FLAG] = true;
8163
+ e[PATCH_FLAG2] = true;
8041
8164
  }
8042
8165
  }
8043
8166
  function extractModelId(model) {
@@ -8046,9 +8169,9 @@ function extractModelId(model) {
8046
8169
  return model.modelId ?? model.name ?? "";
8047
8170
  }
8048
8171
  function toInputValue(input) {
8049
- return (typeof input === "string" ? input : safeStringify7(input)).slice(0, 1e4);
8172
+ return (typeof input === "string" ? input : safeStringify8(input)).slice(0, 1e4);
8050
8173
  }
8051
- function safeStringify7(value) {
8174
+ function safeStringify8(value) {
8052
8175
  if (typeof value === "string") return value;
8053
8176
  try {
8054
8177
  return JSON.stringify(value) ?? "";
@@ -8065,6 +8188,219 @@ function recordError3(span2, err) {
8065
8188
  }
8066
8189
  }
8067
8190
 
8191
+ // src/pi-agent.ts
8192
+ import {
8193
+ trace as trace11,
8194
+ context as otelContext9,
8195
+ SpanStatusCode as SpanStatusCode10
8196
+ } from "@opentelemetry/api";
8197
+ var TRACER_NAME8 = "neatlogs.pi-agent";
8198
+ var PATCH_FLAG3 = "_neatlogs_patched";
8199
+ function piAgentHooks(agent) {
8200
+ if (!agent || agent[PATCH_FLAG3]) return agent;
8201
+ const a = agent;
8202
+ if (typeof a.subscribe !== "function") return agent;
8203
+ const state = { toolSpans: /* @__PURE__ */ new Map(), inputMessages: [] };
8204
+ const tracer = trace11.getTracer(TRACER_NAME8);
8205
+ a.subscribe((event) => {
8206
+ try {
8207
+ handleEvent(tracer, state, event);
8208
+ } catch {
8209
+ }
8210
+ });
8211
+ markPatched2(a);
8212
+ return agent;
8213
+ }
8214
+ function handleEvent(tracer, state, event) {
8215
+ switch (event.type) {
8216
+ case "agent_start": {
8217
+ const span2 = tracer.startSpan(
8218
+ "pi_agent.run",
8219
+ { attributes: { "neatlogs.span.kind": "AGENT" } },
8220
+ otelContext9.active()
8221
+ );
8222
+ state.agentSpan = span2;
8223
+ state.agentCtx = trace11.setSpan(otelContext9.active(), span2);
8224
+ state.inputMessages = [];
8225
+ break;
8226
+ }
8227
+ case "message_end": {
8228
+ const msg = event.message;
8229
+ if (!msg) return;
8230
+ if (msg.role === "assistant") {
8231
+ emitLlmSpan(tracer, state, msg);
8232
+ const { text } = splitAssistantContent(msg.content);
8233
+ if (text) state.inputMessages.push({ role: "assistant", content: text });
8234
+ } else {
8235
+ const role = msg.role === "toolResult" ? "tool" : String(msg.role || "user");
8236
+ const content = messageText(msg);
8237
+ if (content) state.inputMessages.push({ role, content });
8238
+ }
8239
+ break;
8240
+ }
8241
+ case "tool_execution_start": {
8242
+ const parent = state.agentCtx ?? otelContext9.active();
8243
+ const span2 = tracer.startSpan(
8244
+ `pi_agent.tool.${event.toolName ?? "tool"}`,
8245
+ {
8246
+ attributes: {
8247
+ "neatlogs.span.kind": "TOOL",
8248
+ ...event.toolName ? { "neatlogs.tool.name": String(event.toolName) } : {},
8249
+ ...event.args !== void 0 ? { "input.value": safeStringify9(event.args).slice(0, 1e4) } : {}
8250
+ }
8251
+ },
8252
+ parent
8253
+ );
8254
+ if (event.toolCallId) state.toolSpans.set(event.toolCallId, span2);
8255
+ break;
8256
+ }
8257
+ case "tool_execution_end": {
8258
+ const span2 = event.toolCallId ? state.toolSpans.get(event.toolCallId) : void 0;
8259
+ if (!span2) return;
8260
+ if (event.result !== void 0) {
8261
+ span2.setAttribute("output.value", safeStringify9(event.result).slice(0, 1e4));
8262
+ }
8263
+ if (event.isError) {
8264
+ span2.setStatus({ code: SpanStatusCode10.ERROR });
8265
+ span2.setAttribute("neatlogs.tool.is_error", true);
8266
+ } else {
8267
+ span2.setStatus({ code: SpanStatusCode10.OK });
8268
+ }
8269
+ span2.end();
8270
+ if (event.toolCallId) state.toolSpans.delete(event.toolCallId);
8271
+ break;
8272
+ }
8273
+ case "agent_end": {
8274
+ for (const ts of state.toolSpans.values()) {
8275
+ try {
8276
+ ts.end();
8277
+ } catch {
8278
+ }
8279
+ }
8280
+ state.toolSpans.clear();
8281
+ if (state.agentSpan) {
8282
+ const firstUser = state.inputMessages.find((m) => m.role === "user");
8283
+ if (firstUser) state.agentSpan.setAttribute("input.value", firstUser.content.slice(0, 1e4));
8284
+ const finalText = lastAssistantText(event.messages);
8285
+ if (finalText) state.agentSpan.setAttribute("output.value", finalText.slice(0, 1e4));
8286
+ state.agentSpan.setStatus({ code: SpanStatusCode10.OK });
8287
+ state.agentSpan.end();
8288
+ state.agentSpan = void 0;
8289
+ state.agentCtx = void 0;
8290
+ }
8291
+ break;
8292
+ }
8293
+ default:
8294
+ break;
8295
+ }
8296
+ }
8297
+ function emitLlmSpan(tracer, state, msg) {
8298
+ const attrs = { "neatlogs.span.kind": "LLM" };
8299
+ if (msg.model) attrs["neatlogs.llm.model_name"] = String(msg.model);
8300
+ if (msg.provider) attrs["neatlogs.llm.provider"] = String(msg.provider);
8301
+ if (msg.stopReason) attrs["neatlogs.llm.stop_reason"] = String(msg.stopReason);
8302
+ const inMsgs = state.inputMessages;
8303
+ if (inMsgs.length) {
8304
+ inMsgs.forEach((m, i) => {
8305
+ attrs[`neatlogs.llm.input_messages.${i}.role`] = m.role;
8306
+ attrs[`neatlogs.llm.input_messages.${i}.content`] = m.content.slice(0, 1e4);
8307
+ });
8308
+ attrs["neatlogs.llm.input"] = safeStringify9({ messages: inMsgs }).slice(0, 2e4);
8309
+ attrs["input.value"] = safeStringify9({ messages: inMsgs }).slice(0, 1e4);
8310
+ }
8311
+ const { text, toolCalls } = splitAssistantContent(msg.content);
8312
+ const outText = text || toolCalls.map((tc) => `${tc.name}(${safeStringify9(tc.arguments)})`).join("\n");
8313
+ if (outText || toolCalls.length) {
8314
+ attrs["neatlogs.llm.output_messages.0.role"] = "assistant";
8315
+ attrs["neatlogs.llm.output_messages.0.content"] = (outText || "").slice(0, 1e4);
8316
+ const outBlob = { role: "assistant", content: outText || "" };
8317
+ if (toolCalls.length) {
8318
+ outBlob.tool_calls = toolCalls.map((tc) => ({ name: tc.name, arguments: tc.arguments }));
8319
+ toolCalls.forEach((tc, j) => {
8320
+ if (tc.name) attrs[`neatlogs.llm.tool_calls.${j}.name`] = tc.name;
8321
+ if (tc.arguments !== void 0)
8322
+ attrs[`neatlogs.llm.tool_calls.${j}.arguments`] = safeStringify9(tc.arguments);
8323
+ if (tc.id) attrs[`neatlogs.llm.tool_calls.${j}.id`] = String(tc.id);
8324
+ });
8325
+ }
8326
+ attrs["neatlogs.llm.output"] = safeStringify9(outBlob).slice(0, 2e4);
8327
+ attrs["output.value"] = (outText || "").slice(0, 1e4);
8328
+ }
8329
+ const usage = msg.usage;
8330
+ if (usage) {
8331
+ if (usage.input != null) attrs["neatlogs.llm.token_count.prompt"] = usage.input;
8332
+ if (usage.output != null) attrs["neatlogs.llm.token_count.completion"] = usage.output;
8333
+ const total = usage.totalTokens ?? (usage.input ?? 0) + (usage.output ?? 0);
8334
+ if (total) attrs["neatlogs.llm.token_count.total"] = total;
8335
+ if (usage.cacheRead) attrs["neatlogs.llm.token_count.cache_read"] = usage.cacheRead;
8336
+ if (usage.cacheWrite) attrs["neatlogs.llm.token_count.cache_write"] = usage.cacheWrite;
8337
+ }
8338
+ const parent = state.agentCtx ?? otelContext9.active();
8339
+ const span2 = tracer.startSpan(
8340
+ `pi_agent.llm.${msg.model || "model"}`,
8341
+ { attributes: attrs },
8342
+ parent
8343
+ );
8344
+ span2.setStatus({ code: SpanStatusCode10.OK });
8345
+ span2.end();
8346
+ }
8347
+ function splitAssistantContent(content) {
8348
+ const texts = [];
8349
+ const toolCalls = [];
8350
+ if (Array.isArray(content)) {
8351
+ for (const block of content) {
8352
+ if (!block || typeof block !== "object") continue;
8353
+ if (block.type === "text" && typeof block.text === "string") texts.push(block.text);
8354
+ else if (block.type === "toolCall")
8355
+ toolCalls.push(block);
8356
+ }
8357
+ } else if (typeof content === "string") {
8358
+ texts.push(content);
8359
+ }
8360
+ return { text: texts.join(""), toolCalls };
8361
+ }
8362
+ function messageText(msg) {
8363
+ if (!msg) return "";
8364
+ const c = msg.content;
8365
+ if (typeof c === "string") return c;
8366
+ if (!Array.isArray(c)) return "";
8367
+ const parts = [];
8368
+ for (const block of c) {
8369
+ if (typeof block === "string") parts.push(block);
8370
+ else if (block && typeof block === "object") {
8371
+ if (typeof block.text === "string") parts.push(block.text);
8372
+ else if (block.type === "toolCall") parts.push(`${block.name ?? "tool"}(${safeStringify9(block.arguments)})`);
8373
+ }
8374
+ }
8375
+ return parts.join("");
8376
+ }
8377
+ function lastAssistantText(messages) {
8378
+ if (!Array.isArray(messages)) return "";
8379
+ for (let i = messages.length - 1; i >= 0; i--) {
8380
+ const m = messages[i];
8381
+ if (m && m.role === "assistant") {
8382
+ const { text } = splitAssistantContent(m.content);
8383
+ if (text) return text;
8384
+ }
8385
+ }
8386
+ return "";
8387
+ }
8388
+ function markPatched2(e) {
8389
+ try {
8390
+ Object.defineProperty(e, PATCH_FLAG3, { value: true, enumerable: false, configurable: true });
8391
+ } catch {
8392
+ e[PATCH_FLAG3] = true;
8393
+ }
8394
+ }
8395
+ function safeStringify9(value) {
8396
+ if (typeof value === "string") return value;
8397
+ try {
8398
+ return JSON.stringify(value) ?? "";
8399
+ } catch {
8400
+ return "";
8401
+ }
8402
+ }
8403
+
8068
8404
  // src/core/llm-binder.ts
8069
8405
  var logger15 = getLogger();
8070
8406
  function bindTemplates(llm, systemTpl, userTpl, compiledVars) {
@@ -8139,6 +8475,7 @@ export {
8139
8475
  listPrompts,
8140
8476
  log,
8141
8477
  openaiAgentsProcessor,
8478
+ piAgentHooks,
8142
8479
  registerCrewaiTask,
8143
8480
  removeTag,
8144
8481
  saveAsVersion,