neatlogs 1.0.3 → 1.0.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.cjs CHANGED
@@ -50,16 +50,24 @@ __export(index_exports, {
50
50
  getSessionConfig: () => getSessionConfig,
51
51
  init: () => init,
52
52
  isDebugEnabled: () => isDebugEnabled,
53
+ langchainHandler: () => langchainHandler,
53
54
  listPrompts: () => listPrompts,
54
55
  log: () => log,
56
+ openaiAgentsProcessor: () => openaiAgentsProcessor,
55
57
  registerCrewaiTask: () => registerCrewaiTask,
56
58
  removeTag: () => removeTag,
57
59
  saveAsVersion: () => saveAsVersion,
58
60
  shutdown: () => shutdown,
59
61
  span: () => span,
62
+ strandsHooks: () => strandsHooks,
60
63
  trace: () => trace2,
64
+ traceToolAnthropic: () => traceTool2,
65
+ traceToolOpenAI: () => traceTool,
61
66
  updatePrompt: () => updatePrompt,
62
- wrapAISDK: () => wrapAISDK
67
+ wrapAISDK: () => wrapAISDK,
68
+ wrapAnthropic: () => wrapAnthropic,
69
+ wrapMastra: () => wrapMastra,
70
+ wrapOpenAI: () => wrapOpenAI
63
71
  });
64
72
  module.exports = __toCommonJS(index_exports);
65
73
 
@@ -302,7 +310,6 @@ var VECTOR_DB_SYSTEMS = /* @__PURE__ */ new Set([
302
310
  "marqo",
303
311
  "weaviate",
304
312
  "lancedb",
305
- "astra",
306
313
  "pgvector",
307
314
  "elasticsearch"
308
315
  ]);
@@ -328,8 +335,7 @@ var VECTOR_DB_NAMES = [
328
335
  "qdrant",
329
336
  "milvus",
330
337
  "lancedb",
331
- "marqo",
332
- "astra"
338
+ "marqo"
333
339
  ];
334
340
 
335
341
  // src/span-kinds/mapping.ts
@@ -3149,7 +3155,8 @@ var attribute_mapping_default = {
3149
3155
  tool: {
3150
3156
  name: {
3151
3157
  sources: [
3152
- "tool.name"
3158
+ "tool.name",
3159
+ "gen_ai.tool.name"
3153
3160
  ],
3154
3161
  target: "neatlogs.tool.name"
3155
3162
  },
@@ -3898,16 +3905,25 @@ var AttributeMapper = class {
3898
3905
  }
3899
3906
  }
3900
3907
  }
3908
+ if (!spanKindValue && "neatlogs.span.kind" in attributes) {
3909
+ spanKindValue = attributes["neatlogs.span.kind"];
3910
+ }
3901
3911
  if (spanKindValue && spanKindValue in valuesMap) {
3902
3912
  return valuesMap[spanKindValue];
3903
3913
  }
3914
+ if (spanKindValue && Object.values(valuesMap).includes(spanKindValue)) {
3915
+ return spanKindValue;
3916
+ }
3904
3917
  const isLlmSpan = [
3905
3918
  "llm.model_name",
3906
3919
  "gen_ai.request.model",
3907
3920
  "llm.token_count.prompt",
3908
3921
  "llm.token_count.completion",
3909
3922
  "gen_ai.usage.prompt_tokens",
3910
- "gen_ai.usage.completion_tokens"
3923
+ "gen_ai.usage.completion_tokens",
3924
+ "neatlogs.llm.model_name",
3925
+ "neatlogs.llm.token_count.prompt",
3926
+ "neatlogs.llm.token_count.completion"
3911
3927
  ].some((key) => key in attributes);
3912
3928
  if (isLlmSpan) {
3913
3929
  return "llm";
@@ -5911,7 +5927,7 @@ async function init(options = {}) {
5911
5927
  logger13.debug(`Auto-generated session_id: ${sessionId}`);
5912
5928
  }
5913
5929
  }
5914
- const endpoint = options.endpoint ?? "https://staging-cloud.neatlogs.com/api/data/v4/batch";
5930
+ const endpoint = options.endpoint ?? "https://staging-cloud.neatlogs.com";
5915
5931
  const baseUrl = new URL(endpoint).origin;
5916
5932
  _setSessionConfig({
5917
5933
  sessionId,
@@ -6478,6 +6494,1639 @@ function recordSpanError(span2, err) {
6478
6494
  }
6479
6495
  }
6480
6496
 
6497
+ // src/openai.ts
6498
+ var import_api9 = require("@opentelemetry/api");
6499
+ var TRACER_NAME3 = "neatlogs.openai";
6500
+ function wrapOpenAI(client) {
6501
+ return wrapNamespace(client, []);
6502
+ }
6503
+ function traceTool(name, fn) {
6504
+ return async function tracedTool(args) {
6505
+ const tracer = import_api9.trace.getTracer(TRACER_NAME3);
6506
+ return tracer.startActiveSpan(
6507
+ `tool.${name}`,
6508
+ {
6509
+ attributes: {
6510
+ "neatlogs.span.kind": "TOOL",
6511
+ "neatlogs.tool.name": name,
6512
+ "input.value": safeStringify3(args)
6513
+ }
6514
+ },
6515
+ import_api9.context.active(),
6516
+ async (span2) => {
6517
+ try {
6518
+ const result = await fn(args);
6519
+ span2.setAttribute("output.value", safeStringify3(result));
6520
+ span2.setStatus({ code: import_api9.SpanStatusCode.OK });
6521
+ return result;
6522
+ } catch (err) {
6523
+ recordError(span2, err);
6524
+ throw err;
6525
+ } finally {
6526
+ span2.end();
6527
+ }
6528
+ }
6529
+ );
6530
+ };
6531
+ }
6532
+ function wrapNamespace(target, path4) {
6533
+ return new Proxy(target, {
6534
+ get(obj, prop, receiver) {
6535
+ const value = Reflect.get(obj, prop, receiver);
6536
+ if (typeof prop === "symbol" || String(prop).startsWith("_")) return value;
6537
+ const currentPath = [...path4, String(prop)];
6538
+ const pathStr = currentPath.join(".");
6539
+ if (pathStr === "chat.completions.create" && typeof value === "function") {
6540
+ return tracedChatCompletionsCreate(value.bind(obj));
6541
+ }
6542
+ if (pathStr === "responses.create" && typeof value === "function") {
6543
+ return tracedResponsesCreate(value.bind(obj));
6544
+ }
6545
+ if (value && typeof value === "object" && !Array.isArray(value) && isNamespace(currentPath)) {
6546
+ return wrapNamespace(value, currentPath);
6547
+ }
6548
+ return value;
6549
+ }
6550
+ });
6551
+ }
6552
+ function isNamespace(path4) {
6553
+ if (path4.length > 3) return false;
6554
+ const key = path4[path4.length - 1];
6555
+ return ["chat", "completions", "responses", "beta"].includes(key);
6556
+ }
6557
+ function tracedChatCompletionsCreate(original) {
6558
+ return function(opts, ...rest) {
6559
+ const tracer = import_api9.trace.getTracer(TRACER_NAME3);
6560
+ const model = opts?.model ?? "";
6561
+ const messages = opts?.messages ?? [];
6562
+ const isStream = opts?.stream === true;
6563
+ const span2 = tracer.startSpan("openai.chat.completions.create", {
6564
+ attributes: {
6565
+ "neatlogs.span.kind": "LLM",
6566
+ "neatlogs.llm.provider": "openai",
6567
+ "neatlogs.llm.system": "openai",
6568
+ "neatlogs.llm.model_name": model,
6569
+ "neatlogs.llm.is_streaming": isStream
6570
+ }
6571
+ }, import_api9.context.active());
6572
+ for (let i = 0; i < messages.length; i++) {
6573
+ const msg = messages[i];
6574
+ span2.setAttribute(`neatlogs.llm.input_messages.${i}.role`, msg.role ?? "");
6575
+ if (typeof msg.content === "string") {
6576
+ span2.setAttribute(`neatlogs.llm.input_messages.${i}.content`, msg.content);
6577
+ } else if (msg.content) {
6578
+ span2.setAttribute(`neatlogs.llm.input_messages.${i}.content`, safeStringify3(msg.content));
6579
+ }
6580
+ if (msg.tool_call_id) {
6581
+ span2.setAttribute(`neatlogs.llm.input_messages.${i}.tool_call_id`, msg.tool_call_id);
6582
+ }
6583
+ }
6584
+ if (opts?.tools) {
6585
+ for (let i = 0; i < opts.tools.length; i++) {
6586
+ const fn = opts.tools[i]?.function ?? {};
6587
+ span2.setAttribute(`neatlogs.llm.tools.${i}.name`, fn.name ?? "");
6588
+ if (fn.description) span2.setAttribute(`neatlogs.llm.tools.${i}.description`, fn.description);
6589
+ if (fn.parameters) span2.setAttribute(`neatlogs.llm.tools.${i}.input_schema`, safeStringify3(fn.parameters));
6590
+ }
6591
+ }
6592
+ setInvocationParams(span2, opts);
6593
+ if (isStream) {
6594
+ opts = { ...opts };
6595
+ const streamOpts = opts.stream_options ?? {};
6596
+ if (!streamOpts.include_usage) {
6597
+ opts.stream_options = { ...streamOpts, include_usage: true };
6598
+ }
6599
+ }
6600
+ const ctx = import_api9.trace.setSpan(import_api9.context.active(), span2);
6601
+ const promise = import_api9.context.with(ctx, () => original(opts, ...rest));
6602
+ return promise.then(
6603
+ (response) => {
6604
+ if (isStream) {
6605
+ return wrapAsyncIterableStream(response, span2);
6606
+ }
6607
+ finalizeChatResponse(span2, response);
6608
+ return response;
6609
+ },
6610
+ (err) => {
6611
+ recordError(span2, err);
6612
+ throw err;
6613
+ }
6614
+ );
6615
+ };
6616
+ }
6617
+ function tracedResponsesCreate(original) {
6618
+ return function(opts, ...rest) {
6619
+ const tracer = import_api9.trace.getTracer(TRACER_NAME3);
6620
+ const model = opts?.model ?? "";
6621
+ const span2 = tracer.startSpan("openai.responses.create", {
6622
+ attributes: {
6623
+ "neatlogs.span.kind": "LLM",
6624
+ "neatlogs.llm.provider": "openai",
6625
+ "neatlogs.llm.system": "openai",
6626
+ "neatlogs.llm.model_name": model,
6627
+ "input.value": safeStringify3(opts?.input ?? "")
6628
+ }
6629
+ }, import_api9.context.active());
6630
+ const ctx = import_api9.trace.setSpan(import_api9.context.active(), span2);
6631
+ const promise = import_api9.context.with(ctx, () => original(opts, ...rest));
6632
+ return promise.then(
6633
+ (response) => {
6634
+ if (response?.output_text) {
6635
+ span2.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
6636
+ span2.setAttribute("neatlogs.llm.output_messages.0.content", response.output_text);
6637
+ }
6638
+ if (response?.model) span2.setAttribute("neatlogs.llm.model_name", response.model);
6639
+ if (response?.usage) {
6640
+ if (response.usage.input_tokens != null) span2.setAttribute("neatlogs.llm.token_count.prompt", response.usage.input_tokens);
6641
+ if (response.usage.output_tokens != null) span2.setAttribute("neatlogs.llm.token_count.completion", response.usage.output_tokens);
6642
+ }
6643
+ span2.setStatus({ code: import_api9.SpanStatusCode.OK });
6644
+ span2.end();
6645
+ return response;
6646
+ },
6647
+ (err) => {
6648
+ recordError(span2, err);
6649
+ throw err;
6650
+ }
6651
+ );
6652
+ };
6653
+ }
6654
+ function wrapAsyncIterableStream(stream, span2) {
6655
+ const chunks = [];
6656
+ const originalAsyncIterator = stream[Symbol.asyncIterator]?.bind(stream);
6657
+ if (!originalAsyncIterator) {
6658
+ span2.setStatus({ code: import_api9.SpanStatusCode.OK });
6659
+ span2.end();
6660
+ return stream;
6661
+ }
6662
+ const wrapped = Object.create(Object.getPrototypeOf(stream));
6663
+ Object.assign(wrapped, stream);
6664
+ wrapped[Symbol.asyncIterator] = function() {
6665
+ const iterator = originalAsyncIterator();
6666
+ return {
6667
+ async next() {
6668
+ try {
6669
+ const result = await iterator.next();
6670
+ if (result.done) {
6671
+ finalizeStreamChunks(span2, chunks);
6672
+ return result;
6673
+ }
6674
+ chunks.push(result.value);
6675
+ return result;
6676
+ } catch (err) {
6677
+ recordError(span2, err);
6678
+ throw err;
6679
+ }
6680
+ },
6681
+ async return(value) {
6682
+ finalizeStreamChunks(span2, chunks);
6683
+ return iterator.return?.(value) ?? { done: true, value: void 0 };
6684
+ },
6685
+ async throw(err) {
6686
+ recordError(span2, err);
6687
+ return iterator.throw?.(err) ?? { done: true, value: void 0 };
6688
+ }
6689
+ };
6690
+ };
6691
+ return wrapped;
6692
+ }
6693
+ function finalizeStreamChunks(span2, chunks) {
6694
+ const textParts = [];
6695
+ const toolCallsAcc = {};
6696
+ let finishReason = "";
6697
+ let model = "";
6698
+ let usage = null;
6699
+ for (const chunk of chunks) {
6700
+ if (!chunk?.choices?.length) {
6701
+ if (chunk?.usage) usage = chunk.usage;
6702
+ continue;
6703
+ }
6704
+ const choice = chunk.choices[0];
6705
+ const delta = choice?.delta;
6706
+ if (delta?.content) textParts.push(delta.content);
6707
+ if (delta?.tool_calls) {
6708
+ for (const tc of delta.tool_calls) {
6709
+ const idx = tc.index ?? 0;
6710
+ if (!toolCallsAcc[idx]) toolCallsAcc[idx] = { id: "", name: "", arguments: "" };
6711
+ if (tc.id) toolCallsAcc[idx].id = tc.id;
6712
+ if (tc.function?.name) toolCallsAcc[idx].name = tc.function.name;
6713
+ if (tc.function?.arguments) toolCallsAcc[idx].arguments += tc.function.arguments;
6714
+ }
6715
+ }
6716
+ if (choice?.finish_reason) finishReason = choice.finish_reason;
6717
+ if (chunk?.model) model = chunk.model;
6718
+ }
6719
+ const fullText = textParts.join("");
6720
+ if (fullText) {
6721
+ span2.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
6722
+ span2.setAttribute("neatlogs.llm.output_messages.0.content", fullText);
6723
+ }
6724
+ let j = 0;
6725
+ for (const tc of Object.values(toolCallsAcc)) {
6726
+ span2.setAttribute(`neatlogs.llm.tool_calls.${j}.id`, tc.id);
6727
+ span2.setAttribute(`neatlogs.llm.tool_calls.${j}.name`, tc.name);
6728
+ span2.setAttribute(`neatlogs.llm.tool_calls.${j}.arguments`, tc.arguments);
6729
+ j++;
6730
+ }
6731
+ if (model) span2.setAttribute("neatlogs.llm.model_name", model);
6732
+ if (finishReason) span2.setAttribute("neatlogs.llm.finish_reason", finishReason);
6733
+ if (usage) {
6734
+ if (usage.prompt_tokens != null) span2.setAttribute("neatlogs.llm.token_count.prompt", usage.prompt_tokens);
6735
+ if (usage.completion_tokens != null) span2.setAttribute("neatlogs.llm.token_count.completion", usage.completion_tokens);
6736
+ if (usage.total_tokens != null) span2.setAttribute("neatlogs.llm.token_count.total", usage.total_tokens);
6737
+ if (usage.prompt_tokens_details?.cached_tokens != null) {
6738
+ span2.setAttribute("neatlogs.llm.token_count.cache_read", usage.prompt_tokens_details.cached_tokens);
6739
+ }
6740
+ if (usage.completion_tokens_details?.reasoning_tokens != null) {
6741
+ span2.setAttribute("neatlogs.llm.token_count.reasoning", usage.completion_tokens_details.reasoning_tokens);
6742
+ }
6743
+ }
6744
+ span2.setStatus({ code: import_api9.SpanStatusCode.OK });
6745
+ span2.end();
6746
+ }
6747
+ function finalizeChatResponse(span2, response) {
6748
+ const choices = response?.choices ?? [];
6749
+ for (let i = 0; i < choices.length; i++) {
6750
+ const message = choices[i]?.message;
6751
+ if (!message) continue;
6752
+ span2.setAttribute(`neatlogs.llm.output_messages.${i}.role`, "assistant");
6753
+ if (message.content) {
6754
+ span2.setAttribute(`neatlogs.llm.output_messages.${i}.content`, message.content);
6755
+ }
6756
+ if (message.tool_calls) {
6757
+ for (let j = 0; j < message.tool_calls.length; j++) {
6758
+ const tc = message.tool_calls[j];
6759
+ span2.setAttribute(`neatlogs.llm.tool_calls.${j}.id`, tc.id ?? "");
6760
+ span2.setAttribute(`neatlogs.llm.tool_calls.${j}.name`, tc.function?.name ?? "");
6761
+ span2.setAttribute(`neatlogs.llm.tool_calls.${j}.arguments`, tc.function?.arguments ?? "");
6762
+ }
6763
+ }
6764
+ if (choices[i].finish_reason) {
6765
+ span2.setAttribute("neatlogs.llm.finish_reason", choices[i].finish_reason);
6766
+ }
6767
+ }
6768
+ const usage = response?.usage;
6769
+ if (usage) {
6770
+ if (usage.prompt_tokens != null) span2.setAttribute("neatlogs.llm.token_count.prompt", usage.prompt_tokens);
6771
+ if (usage.completion_tokens != null) span2.setAttribute("neatlogs.llm.token_count.completion", usage.completion_tokens);
6772
+ if (usage.total_tokens != null) span2.setAttribute("neatlogs.llm.token_count.total", usage.total_tokens);
6773
+ if (usage.prompt_tokens_details?.cached_tokens != null) {
6774
+ span2.setAttribute("neatlogs.llm.token_count.cache_read", usage.prompt_tokens_details.cached_tokens);
6775
+ }
6776
+ if (usage.completion_tokens_details?.reasoning_tokens != null) {
6777
+ span2.setAttribute("neatlogs.llm.token_count.reasoning", usage.completion_tokens_details.reasoning_tokens);
6778
+ }
6779
+ }
6780
+ if (response?.model) span2.setAttribute("neatlogs.llm.model_name", response.model);
6781
+ span2.setStatus({ code: import_api9.SpanStatusCode.OK });
6782
+ span2.end();
6783
+ }
6784
+ function setInvocationParams(span2, opts) {
6785
+ if (opts?.temperature != null) span2.setAttribute("neatlogs.llm.temperature", opts.temperature);
6786
+ if (opts?.top_p != null) span2.setAttribute("neatlogs.llm.top_p", opts.top_p);
6787
+ if (opts?.max_tokens != null) span2.setAttribute("neatlogs.llm.max_tokens", opts.max_tokens);
6788
+ if (opts?.frequency_penalty != null) span2.setAttribute("neatlogs.llm.frequency_penalty", opts.frequency_penalty);
6789
+ if (opts?.presence_penalty != null) span2.setAttribute("neatlogs.llm.presence_penalty", opts.presence_penalty);
6790
+ if (opts?.stop) span2.setAttribute("neatlogs.llm.stop_sequences", safeStringify3(opts.stop));
6791
+ }
6792
+ function safeStringify3(value) {
6793
+ try {
6794
+ return typeof value === "string" ? value : JSON.stringify(value);
6795
+ } catch {
6796
+ return "";
6797
+ }
6798
+ }
6799
+ function recordError(span2, err) {
6800
+ if (err instanceof Error) {
6801
+ span2.setStatus({ code: import_api9.SpanStatusCode.ERROR, message: err.message });
6802
+ span2.recordException(err);
6803
+ } else {
6804
+ span2.setStatus({ code: import_api9.SpanStatusCode.ERROR, message: String(err) });
6805
+ }
6806
+ span2.end();
6807
+ }
6808
+
6809
+ // src/anthropic.ts
6810
+ var import_api10 = require("@opentelemetry/api");
6811
+ var TRACER_NAME4 = "neatlogs.anthropic";
6812
+ function wrapAnthropic(client) {
6813
+ return wrapNamespace2(client, []);
6814
+ }
6815
+ function traceTool2(name, fn) {
6816
+ return async function tracedTool(input) {
6817
+ const tracer = import_api10.trace.getTracer(TRACER_NAME4);
6818
+ return tracer.startActiveSpan(
6819
+ `tool.${name}`,
6820
+ {
6821
+ attributes: {
6822
+ "neatlogs.span.kind": "TOOL",
6823
+ "neatlogs.tool.name": name,
6824
+ "input.value": safeStringify4(input)
6825
+ }
6826
+ },
6827
+ import_api10.context.active(),
6828
+ async (span2) => {
6829
+ try {
6830
+ const result = await fn(input);
6831
+ span2.setAttribute("output.value", safeStringify4(result));
6832
+ span2.setStatus({ code: import_api10.SpanStatusCode.OK });
6833
+ return result;
6834
+ } catch (err) {
6835
+ recordError2(span2, err);
6836
+ throw err;
6837
+ } finally {
6838
+ span2.end();
6839
+ }
6840
+ }
6841
+ );
6842
+ };
6843
+ }
6844
+ function wrapNamespace2(target, path4) {
6845
+ return new Proxy(target, {
6846
+ get(obj, prop, receiver) {
6847
+ const value = Reflect.get(obj, prop, receiver);
6848
+ if (typeof prop === "symbol" || String(prop).startsWith("_")) return value;
6849
+ const currentPath = [...path4, String(prop)];
6850
+ const pathStr = currentPath.join(".");
6851
+ if (pathStr === "messages.create" && typeof value === "function") {
6852
+ return tracedMessagesCreate(value.bind(obj));
6853
+ }
6854
+ if (pathStr === "messages.stream" && typeof value === "function") {
6855
+ return tracedMessagesStream(value.bind(obj));
6856
+ }
6857
+ if (value && typeof value === "object" && !Array.isArray(value) && isNamespace2(currentPath)) {
6858
+ return wrapNamespace2(value, currentPath);
6859
+ }
6860
+ return value;
6861
+ }
6862
+ });
6863
+ }
6864
+ function isNamespace2(path4) {
6865
+ if (path4.length > 3) return false;
6866
+ const key = path4[path4.length - 1];
6867
+ return ["messages", "beta"].includes(key);
6868
+ }
6869
+ function tracedMessagesCreate(original) {
6870
+ return function(opts, ...rest) {
6871
+ const tracer = import_api10.trace.getTracer(TRACER_NAME4);
6872
+ const model = opts?.model ?? "";
6873
+ const messages = opts?.messages ?? [];
6874
+ const isStream = opts?.stream === true;
6875
+ const span2 = tracer.startSpan("anthropic.messages.create", {
6876
+ attributes: {
6877
+ "neatlogs.span.kind": "LLM",
6878
+ "neatlogs.llm.provider": "anthropic",
6879
+ "neatlogs.llm.system": "anthropic",
6880
+ "neatlogs.llm.model_name": model,
6881
+ "neatlogs.llm.is_streaming": isStream
6882
+ }
6883
+ }, import_api10.context.active());
6884
+ setInputMessages(span2, opts?.system, messages);
6885
+ setTools(span2, opts?.tools);
6886
+ setInvocationParams2(span2, opts);
6887
+ const ctx = import_api10.trace.setSpan(import_api10.context.active(), span2);
6888
+ const promise = import_api10.context.with(ctx, () => original(opts, ...rest));
6889
+ return promise.then(
6890
+ (response) => {
6891
+ if (isStream) {
6892
+ return wrapStreamIterable(response, span2);
6893
+ }
6894
+ finalizeMessageResponse(span2, response);
6895
+ return response;
6896
+ },
6897
+ (err) => {
6898
+ recordError2(span2, err);
6899
+ throw err;
6900
+ }
6901
+ );
6902
+ };
6903
+ }
6904
+ function tracedMessagesStream(original) {
6905
+ return function(opts, ...rest) {
6906
+ const tracer = import_api10.trace.getTracer(TRACER_NAME4);
6907
+ const model = opts?.model ?? "";
6908
+ const messages = opts?.messages ?? [];
6909
+ const span2 = tracer.startSpan("anthropic.messages.stream", {
6910
+ attributes: {
6911
+ "neatlogs.span.kind": "LLM",
6912
+ "neatlogs.llm.provider": "anthropic",
6913
+ "neatlogs.llm.system": "anthropic",
6914
+ "neatlogs.llm.model_name": model,
6915
+ "neatlogs.llm.is_streaming": true
6916
+ }
6917
+ }, import_api10.context.active());
6918
+ setInputMessages(span2, opts?.system, messages);
6919
+ setTools(span2, opts?.tools);
6920
+ setInvocationParams2(span2, opts);
6921
+ const ctx = import_api10.trace.setSpan(import_api10.context.active(), span2);
6922
+ const messageStream = import_api10.context.with(ctx, () => original(opts, ...rest));
6923
+ return wrapMessageStream(messageStream, span2);
6924
+ };
6925
+ }
6926
+ function wrapStreamIterable(stream, span2) {
6927
+ const events = [];
6928
+ const originalAsyncIterator = stream[Symbol.asyncIterator]?.bind(stream);
6929
+ if (!originalAsyncIterator) {
6930
+ span2.setStatus({ code: import_api10.SpanStatusCode.OK });
6931
+ span2.end();
6932
+ return stream;
6933
+ }
6934
+ const wrapped = Object.create(Object.getPrototypeOf(stream));
6935
+ Object.assign(wrapped, stream);
6936
+ wrapped[Symbol.asyncIterator] = function() {
6937
+ const iterator = originalAsyncIterator();
6938
+ return {
6939
+ async next() {
6940
+ try {
6941
+ const result = await iterator.next();
6942
+ if (result.done) {
6943
+ finalizeStreamEvents(span2, events);
6944
+ return result;
6945
+ }
6946
+ events.push(result.value);
6947
+ return result;
6948
+ } catch (err) {
6949
+ recordError2(span2, err);
6950
+ throw err;
6951
+ }
6952
+ },
6953
+ async return(value) {
6954
+ finalizeStreamEvents(span2, events);
6955
+ return iterator.return?.(value) ?? { done: true, value: void 0 };
6956
+ },
6957
+ async throw(err) {
6958
+ recordError2(span2, err);
6959
+ return iterator.throw?.(err) ?? { done: true, value: void 0 };
6960
+ }
6961
+ };
6962
+ };
6963
+ if (typeof stream.finalMessage === "function") {
6964
+ const origFinal = stream.finalMessage.bind(stream);
6965
+ wrapped.finalMessage = async function() {
6966
+ return origFinal();
6967
+ };
6968
+ }
6969
+ return wrapped;
6970
+ }
6971
+ function wrapMessageStream(messageStream, span2) {
6972
+ const origOn = messageStream.on?.bind(messageStream);
6973
+ if (origOn) {
6974
+ origOn("end", () => {
6975
+ const finalMsg = messageStream._finalMessage ?? messageStream.currentMessage;
6976
+ if (finalMsg) {
6977
+ finalizeMessageResponse(span2, finalMsg);
6978
+ } else {
6979
+ span2.setStatus({ code: import_api10.SpanStatusCode.OK });
6980
+ span2.end();
6981
+ }
6982
+ });
6983
+ origOn("error", (err) => {
6984
+ if (span2.isRecording()) recordError2(span2, err);
6985
+ });
6986
+ }
6987
+ if (typeof messageStream.finalMessage === "function") {
6988
+ const origFinal = messageStream.finalMessage.bind(messageStream);
6989
+ messageStream.finalMessage = async function() {
6990
+ const result = await origFinal();
6991
+ if (span2.isRecording()) {
6992
+ finalizeMessageResponse(span2, result);
6993
+ }
6994
+ return result;
6995
+ };
6996
+ }
6997
+ return messageStream;
6998
+ }
6999
+ function finalizeStreamEvents(span2, events) {
7000
+ const textParts = [];
7001
+ const thinkingParts = [];
7002
+ const toolCalls = [];
7003
+ let currentToolInput = "";
7004
+ let currentToolId = "";
7005
+ let currentToolName = "";
7006
+ let usage = null;
7007
+ let model = "";
7008
+ let stopReason = "";
7009
+ for (const event of events) {
7010
+ const type = event?.type ?? "";
7011
+ if (type === "content_block_delta") {
7012
+ const delta = event?.delta;
7013
+ if (delta?.type === "text_delta" && delta.text) textParts.push(delta.text);
7014
+ else if (delta?.type === "thinking_delta" && delta.thinking) thinkingParts.push(delta.thinking);
7015
+ else if (delta?.type === "input_json_delta" && delta.partial_json) currentToolInput += delta.partial_json;
7016
+ } else if (type === "content_block_start") {
7017
+ const block = event?.content_block;
7018
+ if (block?.type === "tool_use") {
7019
+ currentToolId = block.id ?? "";
7020
+ currentToolName = block.name ?? "";
7021
+ currentToolInput = "";
7022
+ }
7023
+ } else if (type === "content_block_stop") {
7024
+ if (currentToolName) {
7025
+ toolCalls.push({ id: currentToolId, name: currentToolName, input: currentToolInput });
7026
+ currentToolId = "";
7027
+ currentToolName = "";
7028
+ currentToolInput = "";
7029
+ }
7030
+ } else if (type === "message_start") {
7031
+ const msg = event?.message;
7032
+ if (msg?.model) model = msg.model;
7033
+ if (msg?.usage) usage = msg.usage;
7034
+ } else if (type === "message_delta") {
7035
+ const delta = event?.delta;
7036
+ if (delta?.stop_reason) stopReason = delta.stop_reason;
7037
+ if (event?.usage) usage = { ...usage ?? {}, ...event.usage };
7038
+ }
7039
+ }
7040
+ const fullText = textParts.join("");
7041
+ if (fullText) {
7042
+ span2.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
7043
+ span2.setAttribute("neatlogs.llm.output_messages.0.content", fullText);
7044
+ }
7045
+ const thinking = thinkingParts.join("");
7046
+ if (thinking) {
7047
+ span2.setAttribute("neatlogs.llm.output_messages.0.thinking", thinking);
7048
+ }
7049
+ for (let j = 0; j < toolCalls.length; j++) {
7050
+ span2.setAttribute(`neatlogs.llm.tool_calls.${j}.id`, toolCalls[j].id);
7051
+ span2.setAttribute(`neatlogs.llm.tool_calls.${j}.name`, toolCalls[j].name);
7052
+ span2.setAttribute(`neatlogs.llm.tool_calls.${j}.arguments`, toolCalls[j].input);
7053
+ }
7054
+ if (model) span2.setAttribute("neatlogs.llm.model_name", model);
7055
+ if (stopReason) span2.setAttribute("neatlogs.llm.stop_reason", stopReason);
7056
+ setUsageAttrs(span2, usage);
7057
+ span2.setStatus({ code: import_api10.SpanStatusCode.OK });
7058
+ span2.end();
7059
+ }
7060
+ function finalizeMessageResponse(span2, response) {
7061
+ const content = response?.content ?? [];
7062
+ const textParts = [];
7063
+ const thinkingParts = [];
7064
+ const toolCalls = [];
7065
+ for (const block of content) {
7066
+ if (block.type === "text" && block.text) textParts.push(block.text);
7067
+ else if (block.type === "thinking" && block.thinking) thinkingParts.push(block.thinking);
7068
+ else if (block.type === "tool_use") {
7069
+ toolCalls.push({
7070
+ id: block.id ?? "",
7071
+ name: block.name ?? "",
7072
+ input: safeStringify4(block.input ?? {})
7073
+ });
7074
+ }
7075
+ }
7076
+ if (textParts.length) {
7077
+ span2.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
7078
+ span2.setAttribute("neatlogs.llm.output_messages.0.content", textParts.join(""));
7079
+ }
7080
+ if (thinkingParts.length) {
7081
+ span2.setAttribute("neatlogs.llm.output_messages.0.thinking", thinkingParts.join(""));
7082
+ }
7083
+ for (let j = 0; j < toolCalls.length; j++) {
7084
+ span2.setAttribute(`neatlogs.llm.tool_calls.${j}.id`, toolCalls[j].id);
7085
+ span2.setAttribute(`neatlogs.llm.tool_calls.${j}.name`, toolCalls[j].name);
7086
+ span2.setAttribute(`neatlogs.llm.tool_calls.${j}.arguments`, toolCalls[j].input);
7087
+ }
7088
+ setUsageAttrs(span2, response?.usage);
7089
+ if (response?.model) span2.setAttribute("neatlogs.llm.model_name", response.model);
7090
+ if (response?.stop_reason) span2.setAttribute("neatlogs.llm.stop_reason", response.stop_reason);
7091
+ span2.setStatus({ code: import_api10.SpanStatusCode.OK });
7092
+ span2.end();
7093
+ }
7094
+ function setInputMessages(span2, system, messages) {
7095
+ let idx = 0;
7096
+ if (system) {
7097
+ const content = typeof system === "string" ? system : safeStringify4(system);
7098
+ span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, "system");
7099
+ span2.setAttribute(`neatlogs.llm.input_messages.${idx}.content`, content);
7100
+ idx++;
7101
+ }
7102
+ for (const msg of messages) {
7103
+ span2.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, msg.role ?? "");
7104
+ if (typeof msg.content === "string") {
7105
+ span2.setAttribute(`neatlogs.llm.input_messages.${idx}.content`, msg.content);
7106
+ } else if (msg.content) {
7107
+ span2.setAttribute(`neatlogs.llm.input_messages.${idx}.content`, safeStringify4(msg.content));
7108
+ }
7109
+ idx++;
7110
+ }
7111
+ }
7112
+ function setTools(span2, tools) {
7113
+ if (!tools) return;
7114
+ for (let i = 0; i < tools.length; i++) {
7115
+ const tool = tools[i];
7116
+ span2.setAttribute(`neatlogs.llm.tools.${i}.name`, tool.name ?? "");
7117
+ if (tool.description) span2.setAttribute(`neatlogs.llm.tools.${i}.description`, tool.description);
7118
+ if (tool.input_schema) span2.setAttribute(`neatlogs.llm.tools.${i}.input_schema`, safeStringify4(tool.input_schema));
7119
+ }
7120
+ }
7121
+ function setInvocationParams2(span2, opts) {
7122
+ if (opts?.temperature != null) span2.setAttribute("neatlogs.llm.temperature", opts.temperature);
7123
+ if (opts?.top_p != null) span2.setAttribute("neatlogs.llm.top_p", opts.top_p);
7124
+ if (opts?.top_k != null) span2.setAttribute("neatlogs.llm.top_k", opts.top_k);
7125
+ if (opts?.max_tokens != null) span2.setAttribute("neatlogs.llm.max_tokens", opts.max_tokens);
7126
+ if (opts?.stop_sequences) span2.setAttribute("neatlogs.llm.stop_sequences", safeStringify4(opts.stop_sequences));
7127
+ }
7128
+ function setUsageAttrs(span2, usage) {
7129
+ if (!usage) return;
7130
+ if (usage.input_tokens != null) span2.setAttribute("neatlogs.llm.token_count.prompt", usage.input_tokens);
7131
+ if (usage.output_tokens != null) span2.setAttribute("neatlogs.llm.token_count.completion", usage.output_tokens);
7132
+ if (usage.cache_read_input_tokens != null) span2.setAttribute("neatlogs.llm.token_count.cache_read", usage.cache_read_input_tokens);
7133
+ if (usage.cache_creation_input_tokens != null) span2.setAttribute("neatlogs.llm.token_count.cache_write", usage.cache_creation_input_tokens);
7134
+ }
7135
+ function safeStringify4(value) {
7136
+ try {
7137
+ return typeof value === "string" ? value : JSON.stringify(value);
7138
+ } catch {
7139
+ return "";
7140
+ }
7141
+ }
7142
+ function recordError2(span2, err) {
7143
+ if (err instanceof Error) {
7144
+ span2.setStatus({ code: import_api10.SpanStatusCode.ERROR, message: err.message });
7145
+ span2.recordException(err);
7146
+ } else {
7147
+ span2.setStatus({ code: import_api10.SpanStatusCode.ERROR, message: String(err) });
7148
+ }
7149
+ span2.end();
7150
+ }
7151
+
7152
+ // src/langchain.ts
7153
+ var import_api11 = require("@opentelemetry/api");
7154
+ var TRACER_NAME5 = "neatlogs.langchain";
7155
+ function langchainHandler(opts) {
7156
+ return new NeatlogsCallbackHandler(opts);
7157
+ }
7158
+ var NeatlogsCallbackHandler = class {
7159
+ name = "neatlogs";
7160
+ _spans = /* @__PURE__ */ new Map();
7161
+ _workflowName;
7162
+ constructor(opts) {
7163
+ this._workflowName = opts?.workflowName;
7164
+ }
7165
+ // --- Chain/Graph callbacks ---
7166
+ async handleChainStart(serialized, inputs, runId, parentRunId, tags, metadata) {
7167
+ const tracer = import_api11.trace.getTracer(TRACER_NAME5);
7168
+ const name = serialized?.name ?? serialized?.id?.at(-1) ?? "chain";
7169
+ const parentSpan = parentRunId ? this._spans.get(parentRunId) : void 0;
7170
+ const parentCtx = parentSpan ? import_api11.trace.setSpan(import_api11.context.active(), parentSpan) : import_api11.context.active();
7171
+ const attrs = {
7172
+ "neatlogs.span.kind": "CHAIN",
7173
+ "neatlogs.chain.name": name
7174
+ };
7175
+ if (this._workflowName) attrs["neatlogs.workflow.name"] = this._workflowName;
7176
+ if (inputs) attrs["input.value"] = safeStringify5(inputs).slice(0, 1e4);
7177
+ if (tags?.length) attrs["neatlogs.tags"] = tags.join(",");
7178
+ const span2 = tracer.startSpan(`langchain.chain.${name}`, { attributes: attrs }, parentCtx);
7179
+ this._spans.set(runId, span2);
7180
+ }
7181
+ async handleChainEnd(outputs, runId) {
7182
+ const span2 = this._spans.get(runId);
7183
+ if (!span2) return;
7184
+ if (outputs) span2.setAttribute("output.value", safeStringify5(outputs).slice(0, 1e4));
7185
+ span2.setStatus({ code: import_api11.SpanStatusCode.OK });
7186
+ span2.end();
7187
+ this._spans.delete(runId);
7188
+ }
7189
+ async handleChainError(error, runId) {
7190
+ const span2 = this._spans.get(runId);
7191
+ if (!span2) return;
7192
+ span2.setStatus({ code: import_api11.SpanStatusCode.ERROR, message: error.message });
7193
+ span2.recordException(error);
7194
+ span2.end();
7195
+ this._spans.delete(runId);
7196
+ }
7197
+ // --- LLM callbacks ---
7198
+ async handleLLMStart(serialized, prompts, runId, parentRunId, extraParams) {
7199
+ const tracer = import_api11.trace.getTracer(TRACER_NAME5);
7200
+ const model = serialized?.kwargs?.model_name ?? serialized?.kwargs?.model ?? serialized?.name ?? "";
7201
+ const parentSpan = parentRunId ? this._spans.get(parentRunId) : void 0;
7202
+ const parentCtx = parentSpan ? import_api11.trace.setSpan(import_api11.context.active(), parentSpan) : import_api11.context.active();
7203
+ const attrs = {
7204
+ "neatlogs.span.kind": "LLM",
7205
+ "neatlogs.llm.provider": detectProvider(model),
7206
+ "neatlogs.llm.model_name": model
7207
+ };
7208
+ for (let i = 0; i < prompts.length; i++) {
7209
+ attrs[`neatlogs.llm.input_messages.${i}.role`] = "user";
7210
+ attrs[`neatlogs.llm.input_messages.${i}.content`] = prompts[i].slice(0, 1e4);
7211
+ }
7212
+ if (extraParams?.invocation_params) {
7213
+ const p = extraParams.invocation_params;
7214
+ if (p.temperature != null) attrs["neatlogs.llm.temperature"] = p.temperature;
7215
+ if (p.max_tokens != null) attrs["neatlogs.llm.max_tokens"] = p.max_tokens;
7216
+ if (p.model_name) attrs["neatlogs.llm.model_name"] = p.model_name;
7217
+ }
7218
+ const span2 = tracer.startSpan("langchain.llm", { attributes: attrs }, parentCtx);
7219
+ this._spans.set(runId, span2);
7220
+ }
7221
+ async handleChatModelStart(serialized, messages, runId, parentRunId, extraParams) {
7222
+ const tracer = import_api11.trace.getTracer(TRACER_NAME5);
7223
+ const model = serialized?.kwargs?.model_name ?? serialized?.kwargs?.model ?? serialized?.name ?? "";
7224
+ const parentSpan = parentRunId ? this._spans.get(parentRunId) : void 0;
7225
+ const parentCtx = parentSpan ? import_api11.trace.setSpan(import_api11.context.active(), parentSpan) : import_api11.context.active();
7226
+ const attrs = {
7227
+ "neatlogs.span.kind": "LLM",
7228
+ "neatlogs.llm.provider": detectProvider(model),
7229
+ "neatlogs.llm.model_name": model
7230
+ };
7231
+ const flatMessages = messages.flat();
7232
+ for (let i = 0; i < flatMessages.length; i++) {
7233
+ const msg = flatMessages[i];
7234
+ const role = msg?.role ?? msg?._getType?.() ?? msg?.constructor?.name ?? "unknown";
7235
+ const content = typeof msg?.content === "string" ? msg.content : safeStringify5(msg?.content);
7236
+ attrs[`neatlogs.llm.input_messages.${i}.role`] = mapRole(role);
7237
+ attrs[`neatlogs.llm.input_messages.${i}.content`] = content.slice(0, 1e4);
7238
+ }
7239
+ if (extraParams?.invocation_params) {
7240
+ const p = extraParams.invocation_params;
7241
+ if (p.temperature != null) attrs["neatlogs.llm.temperature"] = p.temperature;
7242
+ if (p.max_tokens != null) attrs["neatlogs.llm.max_tokens"] = p.max_tokens;
7243
+ if (p.model_name) attrs["neatlogs.llm.model_name"] = p.model_name;
7244
+ }
7245
+ const span2 = tracer.startSpan("langchain.chat_model", { attributes: attrs }, parentCtx);
7246
+ this._spans.set(runId, span2);
7247
+ }
7248
+ async handleLLMEnd(output, runId) {
7249
+ const span2 = this._spans.get(runId);
7250
+ if (!span2) return;
7251
+ const generations = output?.generations ?? [];
7252
+ for (let i = 0; i < generations.length; i++) {
7253
+ const gen = generations[i];
7254
+ if (!Array.isArray(gen)) continue;
7255
+ for (let j = 0; j < gen.length; j++) {
7256
+ const msg = gen[j]?.message ?? gen[j];
7257
+ const content = msg?.content ?? msg?.text ?? "";
7258
+ span2.setAttribute(`neatlogs.llm.output_messages.${i}.role`, "assistant");
7259
+ span2.setAttribute(`neatlogs.llm.output_messages.${i}.content`, String(content).slice(0, 1e4));
7260
+ const toolCalls = msg?.tool_calls ?? msg?.additional_kwargs?.tool_calls;
7261
+ if (toolCalls && Array.isArray(toolCalls)) {
7262
+ for (let k = 0; k < toolCalls.length; k++) {
7263
+ const tc = toolCalls[k];
7264
+ span2.setAttribute(`neatlogs.llm.tool_calls.${k}.id`, tc.id ?? "");
7265
+ span2.setAttribute(`neatlogs.llm.tool_calls.${k}.name`, tc.name ?? tc.function?.name ?? "");
7266
+ span2.setAttribute(`neatlogs.llm.tool_calls.${k}.arguments`, tc.args ? safeStringify5(tc.args) : tc.function?.arguments ?? "");
7267
+ }
7268
+ }
7269
+ }
7270
+ }
7271
+ const usage = output?.llmOutput?.tokenUsage ?? output?.llmOutput?.usage;
7272
+ if (usage) {
7273
+ if (usage.promptTokens != null || usage.prompt_tokens != null) {
7274
+ span2.setAttribute("neatlogs.llm.token_count.prompt", usage.promptTokens ?? usage.prompt_tokens);
7275
+ }
7276
+ if (usage.completionTokens != null || usage.completion_tokens != null) {
7277
+ span2.setAttribute("neatlogs.llm.token_count.completion", usage.completionTokens ?? usage.completion_tokens);
7278
+ }
7279
+ if (usage.totalTokens != null || usage.total_tokens != null) {
7280
+ span2.setAttribute("neatlogs.llm.token_count.total", usage.totalTokens ?? usage.total_tokens);
7281
+ }
7282
+ }
7283
+ span2.setStatus({ code: import_api11.SpanStatusCode.OK });
7284
+ span2.end();
7285
+ this._spans.delete(runId);
7286
+ }
7287
+ async handleLLMNewToken(_token, _idx, _runId) {
7288
+ }
7289
+ async handleLLMError(error, runId) {
7290
+ const span2 = this._spans.get(runId);
7291
+ if (!span2) return;
7292
+ span2.setStatus({ code: import_api11.SpanStatusCode.ERROR, message: error.message });
7293
+ span2.recordException(error);
7294
+ span2.end();
7295
+ this._spans.delete(runId);
7296
+ }
7297
+ // --- Tool callbacks ---
7298
+ async handleToolStart(serialized, input, runId, parentRunId, _tags, _metadata, runName, toolCallId) {
7299
+ const tracer = import_api11.trace.getTracer(TRACER_NAME5);
7300
+ const name = serialized?.name || runName || (Array.isArray(serialized?.id) ? serialized.id[serialized.id.length - 1] : void 0) || "tool";
7301
+ const parentSpan = parentRunId ? this._spans.get(parentRunId) : void 0;
7302
+ const parentCtx = parentSpan ? import_api11.trace.setSpan(import_api11.context.active(), parentSpan) : import_api11.context.active();
7303
+ const attrs = {
7304
+ "neatlogs.span.kind": "TOOL",
7305
+ "neatlogs.tool.name": name,
7306
+ "input.value": String(input).slice(0, 1e4)
7307
+ };
7308
+ if (toolCallId) attrs["neatlogs.tool_call.id"] = toolCallId;
7309
+ const span2 = tracer.startSpan(`langchain.tool.${name}`, { attributes: attrs }, parentCtx);
7310
+ this._spans.set(runId, span2);
7311
+ }
7312
+ async handleToolEnd(output, runId) {
7313
+ const span2 = this._spans.get(runId);
7314
+ if (!span2) return;
7315
+ span2.setAttribute("output.value", String(output).slice(0, 1e4));
7316
+ span2.setStatus({ code: import_api11.SpanStatusCode.OK });
7317
+ span2.end();
7318
+ this._spans.delete(runId);
7319
+ }
7320
+ async handleToolError(error, runId) {
7321
+ const span2 = this._spans.get(runId);
7322
+ if (!span2) return;
7323
+ span2.setStatus({ code: import_api11.SpanStatusCode.ERROR, message: error.message });
7324
+ span2.recordException(error);
7325
+ span2.end();
7326
+ this._spans.delete(runId);
7327
+ }
7328
+ // --- Retriever callbacks ---
7329
+ async handleRetrieverStart(serialized, query, runId, parentRunId) {
7330
+ const tracer = import_api11.trace.getTracer(TRACER_NAME5);
7331
+ const name = serialized?.name ?? "retriever";
7332
+ const parentSpan = parentRunId ? this._spans.get(parentRunId) : void 0;
7333
+ const parentCtx = parentSpan ? import_api11.trace.setSpan(import_api11.context.active(), parentSpan) : import_api11.context.active();
7334
+ const attrs = {
7335
+ "neatlogs.span.kind": "RETRIEVER",
7336
+ "neatlogs.retriever.name": name,
7337
+ "input.value": query.slice(0, 1e4)
7338
+ };
7339
+ const span2 = tracer.startSpan(`langchain.retriever.${name}`, { attributes: attrs }, parentCtx);
7340
+ this._spans.set(runId, span2);
7341
+ }
7342
+ async handleRetrieverEnd(documents, runId) {
7343
+ const span2 = this._spans.get(runId);
7344
+ if (!span2) return;
7345
+ if (documents?.length) {
7346
+ span2.setAttribute("neatlogs.retriever.document_count", documents.length);
7347
+ for (let i = 0; i < Math.min(documents.length, 10); i++) {
7348
+ const doc = documents[i];
7349
+ if (doc?.pageContent) {
7350
+ span2.setAttribute(`neatlogs.retriever.documents.${i}.content`, doc.pageContent.slice(0, 2e3));
7351
+ }
7352
+ }
7353
+ }
7354
+ span2.setStatus({ code: import_api11.SpanStatusCode.OK });
7355
+ span2.end();
7356
+ this._spans.delete(runId);
7357
+ }
7358
+ async handleRetrieverError(error, runId) {
7359
+ const span2 = this._spans.get(runId);
7360
+ if (!span2) return;
7361
+ span2.setStatus({ code: import_api11.SpanStatusCode.ERROR, message: error.message });
7362
+ span2.recordException(error);
7363
+ span2.end();
7364
+ this._spans.delete(runId);
7365
+ }
7366
+ };
7367
+ function detectProvider(model) {
7368
+ const m = model.toLowerCase();
7369
+ if (m.includes("gpt") || m.includes("o1") || m.includes("o3") || m.includes("o4")) return "openai";
7370
+ if (m.includes("claude")) return "anthropic";
7371
+ if (m.includes("gemini")) return "google";
7372
+ if (m.includes("command")) return "cohere";
7373
+ if (m.includes("llama") || m.includes("mixtral")) return "meta";
7374
+ return "unknown";
7375
+ }
7376
+ function mapRole(role) {
7377
+ const r = role.toLowerCase();
7378
+ if (r === "human" || r === "humanmessage") return "user";
7379
+ if (r === "ai" || r === "aimessage") return "assistant";
7380
+ if (r === "system" || r === "systemmessage") return "system";
7381
+ if (r === "function" || r === "functionmessage") return "function";
7382
+ if (r === "tool" || r === "toolmessage") return "tool";
7383
+ return role;
7384
+ }
7385
+ function safeStringify5(value) {
7386
+ try {
7387
+ return typeof value === "string" ? value : JSON.stringify(value);
7388
+ } catch {
7389
+ return "";
7390
+ }
7391
+ }
7392
+
7393
+ // src/strands.ts
7394
+ function strandsHooks(agent) {
7395
+ if (agent && typeof agent === "object") {
7396
+ try {
7397
+ Object.defineProperty(agent, "_neatlogs_patched", {
7398
+ value: true,
7399
+ enumerable: false,
7400
+ configurable: true
7401
+ });
7402
+ } catch {
7403
+ agent._neatlogs_patched = true;
7404
+ }
7405
+ }
7406
+ return agent;
7407
+ }
7408
+
7409
+ // src/openai-agents.ts
7410
+ var import_api12 = require("@opentelemetry/api");
7411
+ var TRACER_NAME6 = "neatlogs.openai_agents";
7412
+ function openaiAgentsProcessor() {
7413
+ return new NeatlogsTraceProcessor();
7414
+ }
7415
+ var NeatlogsTraceProcessor = class {
7416
+ _spans = /* @__PURE__ */ new Map();
7417
+ _startTimes = /* @__PURE__ */ new Map();
7418
+ // The @openai/agents SDK passes a Trace object: { traceId, name, groupId, metadata }.
7419
+ onTraceStart(traceData) {
7420
+ const tracer = import_api12.trace.getTracer(TRACER_NAME6);
7421
+ const attrs = { "neatlogs.span.kind": "WORKFLOW" };
7422
+ const workflowName = traceData?.name ?? traceData?.workflow_name;
7423
+ if (workflowName) attrs["neatlogs.workflow.name"] = workflowName;
7424
+ const traceId = traceData?.traceId ?? traceData?.trace_id;
7425
+ if (traceId) attrs["neatlogs.agent.trace_id"] = String(traceId);
7426
+ const span2 = tracer.startSpan("openai_agents.trace", { attributes: attrs }, import_api12.context.active());
7427
+ const key = String(traceId ?? `trace_${Date.now()}`);
7428
+ this._spans.set(key, span2);
7429
+ this._startTimes.set(key, Date.now());
7430
+ }
7431
+ onTraceEnd(traceData) {
7432
+ const key = String(traceData?.traceId ?? traceData?.trace_id ?? "");
7433
+ const span2 = this._spans.get(key);
7434
+ if (!span2) return;
7435
+ const startTime = this._startTimes.get(key);
7436
+ if (startTime) {
7437
+ span2.setAttribute("neatlogs.metrics.duration_ms", Date.now() - startTime);
7438
+ }
7439
+ span2.setStatus({ code: import_api12.SpanStatusCode.OK });
7440
+ span2.end();
7441
+ this._spans.delete(key);
7442
+ this._startTimes.delete(key);
7443
+ }
7444
+ // The SDK passes a Span object: { type, spanId, traceId, parentId?, spanData: {...} }.
7445
+ // The meaningful payload (type, name, input, output, usage, ...) lives in `spanData`.
7446
+ onSpanStart(span2) {
7447
+ const tracer = import_api12.trace.getTracer(TRACER_NAME6);
7448
+ const data = span2?.spanData ?? span2 ?? {};
7449
+ const spanType = data?.type ?? data?.span_type ?? span2?.type ?? "";
7450
+ const spanId = String(span2?.spanId ?? span2?.span_id ?? data?.span_id ?? `span_${Date.now()}`);
7451
+ const parentKey = String(span2?.parentId ?? span2?.traceId ?? span2?.trace_id ?? "");
7452
+ const parentSpan = this._spans.get(parentKey);
7453
+ const parentCtx = parentSpan ? import_api12.trace.setSpan(import_api12.context.active(), parentSpan) : import_api12.context.active();
7454
+ let otelSpan;
7455
+ if (spanType === "agent" || spanType === "agent_run") {
7456
+ const agentName = data?.name ?? data?.agent_name ?? "agent";
7457
+ const attrs = {
7458
+ "neatlogs.span.kind": "AGENT",
7459
+ "neatlogs.agent.name": agentName
7460
+ };
7461
+ if (Array.isArray(data?.tools) && data.tools.length) {
7462
+ attrs["neatlogs.agent.available_tools"] = data.tools.join(",");
7463
+ }
7464
+ otelSpan = tracer.startSpan(`openai_agents.agent.${agentName}`, { attributes: attrs }, parentCtx);
7465
+ } else if (spanType === "response" || spanType === "generation" || spanType === "llm") {
7466
+ const attrs = {
7467
+ "neatlogs.span.kind": "LLM",
7468
+ "neatlogs.llm.provider": "openai"
7469
+ };
7470
+ const model = data?.model;
7471
+ if (model) attrs["neatlogs.llm.model_name"] = model;
7472
+ const inputMsgs = data?.input ?? data?.messages;
7473
+ if (inputMsgs && Array.isArray(inputMsgs)) {
7474
+ for (let i = 0; i < inputMsgs.length; i++) {
7475
+ const msg = inputMsgs[i];
7476
+ const role = typeof msg === "object" ? msg.role ?? "" : "";
7477
+ const content = typeof msg === "object" ? msg.content ?? "" : String(msg);
7478
+ if (role) attrs[`neatlogs.llm.input_messages.${i}.role`] = role;
7479
+ if (content) attrs[`neatlogs.llm.input_messages.${i}.content`] = (typeof content === "string" ? content : safeStringify6(content)).slice(0, 1e4);
7480
+ }
7481
+ }
7482
+ otelSpan = tracer.startSpan("openai_agents.generation", { attributes: attrs }, parentCtx);
7483
+ } else if (spanType === "function" || spanType === "tool" || spanType === "tool_call") {
7484
+ const toolName = data?.name ?? data?.function_name ?? "tool";
7485
+ const attrs = {
7486
+ "neatlogs.span.kind": "TOOL",
7487
+ "neatlogs.tool.name": toolName
7488
+ };
7489
+ const toolInput = data?.input ?? data?.arguments;
7490
+ if (toolInput !== void 0) {
7491
+ attrs["input.value"] = (typeof toolInput === "string" ? toolInput : safeStringify6(toolInput)).slice(0, 1e4);
7492
+ }
7493
+ otelSpan = tracer.startSpan(`openai_agents.tool.${toolName}`, { attributes: attrs }, parentCtx);
7494
+ } else if (spanType === "handoff") {
7495
+ const attrs = { "neatlogs.span.kind": "AGENT" };
7496
+ if (data?.from_agent) attrs["neatlogs.agent.handoff_from"] = String(data.from_agent);
7497
+ if (data?.to_agent) attrs["neatlogs.agent.name"] = String(data.to_agent);
7498
+ otelSpan = tracer.startSpan("openai_agents.handoff", { attributes: attrs }, parentCtx);
7499
+ } else {
7500
+ const attrs = { "neatlogs.span.kind": "CHAIN" };
7501
+ otelSpan = tracer.startSpan(`openai_agents.${spanType || "span"}`, { attributes: attrs }, parentCtx);
7502
+ }
7503
+ this._spans.set(spanId, otelSpan);
7504
+ this._startTimes.set(spanId, Date.now());
7505
+ }
7506
+ onSpanEnd(span2) {
7507
+ const data = span2?.spanData ?? span2 ?? {};
7508
+ const spanId = String(span2?.spanId ?? span2?.span_id ?? data?.span_id ?? "");
7509
+ const otelSpan = this._spans.get(spanId);
7510
+ if (!otelSpan) return;
7511
+ const spanType = data?.type ?? data?.span_type ?? span2?.type ?? "";
7512
+ const startTime = this._startTimes.get(spanId);
7513
+ if (spanType === "response" || spanType === "generation" || spanType === "llm") {
7514
+ const resp = data?._response ?? data?.response ?? {};
7515
+ const model = data?.model ?? resp?.model;
7516
+ if (model) otelSpan.setAttribute("neatlogs.llm.model_name", model);
7517
+ const outputItems = data?.output ?? resp?.output;
7518
+ if (Array.isArray(outputItems)) {
7519
+ const text = outputItems.filter((o) => o?.type === "message" || o?.role === "assistant").flatMap((o) => Array.isArray(o.content) ? o.content : [o.content]).map((c) => typeof c === "string" ? c : c?.text ?? "").join("");
7520
+ if (text) {
7521
+ otelSpan.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
7522
+ otelSpan.setAttribute("neatlogs.llm.output_messages.0.content", text.slice(0, 1e4));
7523
+ }
7524
+ const toolCalls = outputItems.filter((o) => o?.type === "function_call");
7525
+ for (let i = 0; i < toolCalls.length; i++) {
7526
+ const tc = toolCalls[i];
7527
+ otelSpan.setAttribute(`neatlogs.llm.tool_calls.${i}.name`, tc.name ?? "");
7528
+ otelSpan.setAttribute(`neatlogs.llm.tool_calls.${i}.arguments`, typeof tc.arguments === "string" ? tc.arguments : safeStringify6(tc.arguments ?? {}));
7529
+ if (tc.callId ?? tc.id) otelSpan.setAttribute(`neatlogs.llm.tool_calls.${i}.id`, tc.callId ?? tc.id);
7530
+ }
7531
+ } else if (outputItems?.content) {
7532
+ otelSpan.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
7533
+ const c = outputItems.content;
7534
+ otelSpan.setAttribute("neatlogs.llm.output_messages.0.content", (typeof c === "string" ? c : safeStringify6(c)).slice(0, 1e4));
7535
+ }
7536
+ const usage = data?.usage ?? resp?.usage;
7537
+ if (usage) {
7538
+ const inputTokens = usage.input_tokens ?? usage.prompt_tokens ?? usage.inputTokens;
7539
+ const outputTokens = usage.output_tokens ?? usage.completion_tokens ?? usage.outputTokens;
7540
+ const totalTokens = usage.total_tokens ?? usage.totalTokens;
7541
+ if (inputTokens != null) otelSpan.setAttribute("neatlogs.llm.token_count.prompt", inputTokens);
7542
+ if (outputTokens != null) otelSpan.setAttribute("neatlogs.llm.token_count.completion", outputTokens);
7543
+ if (totalTokens != null) otelSpan.setAttribute("neatlogs.llm.token_count.total", totalTokens);
7544
+ else if (inputTokens != null && outputTokens != null) {
7545
+ otelSpan.setAttribute("neatlogs.llm.token_count.total", inputTokens + outputTokens);
7546
+ }
7547
+ }
7548
+ } else if (spanType === "function" || spanType === "tool" || spanType === "tool_call") {
7549
+ const output = data?.output ?? data?.result;
7550
+ if (output != null) {
7551
+ otelSpan.setAttribute("output.value", (typeof output === "string" ? output : safeStringify6(output)).slice(0, 1e4));
7552
+ }
7553
+ } else if (spanType === "agent" || spanType === "agent_run") {
7554
+ const output = data?.output;
7555
+ if (output != null) {
7556
+ otelSpan.setAttribute("output.value", (typeof output === "string" ? output : safeStringify6(output)).slice(0, 1e4));
7557
+ }
7558
+ }
7559
+ const error = data?.error ?? span2?.error;
7560
+ if (error) {
7561
+ if (error instanceof Error) {
7562
+ otelSpan.setStatus({ code: import_api12.SpanStatusCode.ERROR, message: error.message });
7563
+ otelSpan.recordException(error);
7564
+ } else {
7565
+ otelSpan.setStatus({ code: import_api12.SpanStatusCode.ERROR, message: String(error) });
7566
+ }
7567
+ } else {
7568
+ otelSpan.setStatus({ code: import_api12.SpanStatusCode.OK });
7569
+ }
7570
+ if (startTime) {
7571
+ otelSpan.setAttribute("neatlogs.llm.metrics.duration_ms", Date.now() - startTime);
7572
+ }
7573
+ otelSpan.end();
7574
+ this._spans.delete(spanId);
7575
+ this._startTimes.delete(spanId);
7576
+ }
7577
+ shutdown() {
7578
+ for (const [, span2] of this._spans) {
7579
+ span2.setStatus({ code: import_api12.SpanStatusCode.ERROR, message: "Processor shutdown before span completed" });
7580
+ span2.end();
7581
+ }
7582
+ this._spans.clear();
7583
+ this._startTimes.clear();
7584
+ }
7585
+ forceFlush() {
7586
+ }
7587
+ };
7588
+ function safeStringify6(value) {
7589
+ try {
7590
+ return typeof value === "string" ? value : JSON.stringify(value);
7591
+ } catch {
7592
+ return "";
7593
+ }
7594
+ }
7595
+
7596
+ // src/mastra-wrap.ts
7597
+ var import_api13 = require("@opentelemetry/api");
7598
+ var TRACER_NAME7 = "neatlogs.mastra";
7599
+ var PATCH_FLAG = "_neatlogs_patched";
7600
+ function wrapMastra(entity) {
7601
+ if (!entity || entity[PATCH_FLAG]) return entity;
7602
+ const e = entity;
7603
+ const className = entity.constructor?.name ?? "";
7604
+ if (isRootMastra(e)) {
7605
+ const proxied = wrapRootMastra(e);
7606
+ markPatched(proxied);
7607
+ return proxied;
7608
+ }
7609
+ if (isAgent(e, className)) {
7610
+ patchAgent(e);
7611
+ } else if (isWorkflow(e, className)) {
7612
+ patchWorkflow(e);
7613
+ } else if (isVector(e, className)) {
7614
+ patchVector(e);
7615
+ } else if (isMemory(e, className)) {
7616
+ patchMemory(e);
7617
+ } else if (isDocument(e, className)) {
7618
+ patchDocument(e);
7619
+ }
7620
+ markPatched(e);
7621
+ return entity;
7622
+ }
7623
+ function isRootMastra(e) {
7624
+ return typeof e.getAgent === "function" && typeof e.getWorkflow === "function";
7625
+ }
7626
+ function isAgent(e, className) {
7627
+ return className === "Agent" || typeof e.generate === "function" || typeof e.stream === "function";
7628
+ }
7629
+ function isWorkflow(e, className) {
7630
+ return className === "Workflow" || typeof e.createRun === "function";
7631
+ }
7632
+ function isVector(e, className) {
7633
+ return /Vector/.test(className) || typeof e.query === "function" && typeof e.upsert === "function";
7634
+ }
7635
+ function isMemory(e, className) {
7636
+ return /Memory/.test(className) || typeof e.recall === "function" && typeof e.saveMessages === "function";
7637
+ }
7638
+ function isDocument(e, className) {
7639
+ return className === "MDocument" || typeof e.chunk === "function" && typeof e.getDocs === "function";
7640
+ }
7641
+ function patchAgent(agent) {
7642
+ patchAgentMethod(agent, "generate", false);
7643
+ patchAgentMethod(agent, "stream", true);
7644
+ }
7645
+ function patchAgentMethod(agent, method, streaming) {
7646
+ if (typeof agent[method] !== "function") return;
7647
+ const orig = agent[method].bind(agent);
7648
+ agent[method] = async function tracedAgentMethod(input, opts) {
7649
+ const agentName = agent.name ?? agent.id ?? "mastra_agent";
7650
+ const model = extractModelId(agent.model);
7651
+ installAgentLlmHook(agent);
7652
+ installAgentToolHooks(agent);
7653
+ const attrs = {
7654
+ "neatlogs.span.kind": "AGENT",
7655
+ "neatlogs.agent.name": agentName,
7656
+ "input.value": toInputValue(input)
7657
+ };
7658
+ if (model) attrs["neatlogs.llm.model_name"] = model;
7659
+ if (agent.instructions && typeof agent.instructions === "string") {
7660
+ attrs["neatlogs.llm.system_prompt"] = agent.instructions.slice(0, 5e3);
7661
+ }
7662
+ if (streaming) attrs["neatlogs.llm.is_streaming"] = true;
7663
+ if (streaming) {
7664
+ const tracer = import_api13.trace.getTracer(TRACER_NAME7);
7665
+ const span2 = tracer.startSpan(`mastra.agent.${agentName}`, { attributes: attrs }, import_api13.context.active());
7666
+ const ctx = import_api13.trace.setSpan(import_api13.context.active(), span2);
7667
+ try {
7668
+ const result = await import_api13.context.with(ctx, () => orig(input, opts));
7669
+ return wrapStreamingOutput(result, span2, ctx);
7670
+ } catch (err) {
7671
+ recordError3(span2, err);
7672
+ span2.end();
7673
+ throw err;
7674
+ }
7675
+ }
7676
+ return withActiveSpan(`mastra.agent.${agentName}`, attrs, async (span2) => {
7677
+ const result = await orig(input, opts);
7678
+ finalizeAgentResult(span2, result);
7679
+ return result;
7680
+ });
7681
+ };
7682
+ }
7683
+ function installAgentLlmHook(agent) {
7684
+ if (agent.__neatlogs_llm_hook || typeof agent.getLLM !== "function") return;
7685
+ agent.__neatlogs_llm_hook = true;
7686
+ const origGetLLM = agent.getLLM.bind(agent);
7687
+ agent.getLLM = function patchedGetLLM(...args) {
7688
+ const out = origGetLLM(...args);
7689
+ return Promise.resolve(out).then((llm) => {
7690
+ try {
7691
+ const model = typeof llm?.getModel === "function" ? llm.getModel() : llm;
7692
+ patchModelInPlace(model);
7693
+ } catch {
7694
+ }
7695
+ return llm;
7696
+ });
7697
+ };
7698
+ }
7699
+ function patchModelInPlace(model) {
7700
+ if (!model || model.__neatlogs_model_patched) return;
7701
+ model.__neatlogs_model_patched = true;
7702
+ const modelId = model.modelId ?? model.modelName ?? "";
7703
+ const provider = model.provider ?? "";
7704
+ for (const fn of ["doGenerate", "doStream"]) {
7705
+ if (typeof model[fn] !== "function") continue;
7706
+ const orig = model[fn].bind(model);
7707
+ const isStream = fn === "doStream";
7708
+ model[fn] = function tracedModelCall(callOpts) {
7709
+ const attrs = { "neatlogs.span.kind": "LLM" };
7710
+ if (modelId) attrs["neatlogs.llm.model_name"] = modelId;
7711
+ if (provider) attrs["neatlogs.llm.provider"] = provider;
7712
+ if (isStream) attrs["neatlogs.llm.is_streaming"] = true;
7713
+ const promptInput = callOpts?.prompt ?? callOpts?.messages;
7714
+ if (promptInput !== void 0) attrs["input.value"] = safeStringify7(promptInput).slice(0, 1e4);
7715
+ captureInvocationParams(attrs, callOpts);
7716
+ return withActiveSpan(`mastra.llm.${modelId || "model"}.${fn}`, attrs, async (span2) => {
7717
+ const result = await orig(callOpts);
7718
+ if (!isStream) finalizeModelResult(span2, result);
7719
+ else if (result?.usage) recordUsage(span2, result.usage);
7720
+ return result;
7721
+ });
7722
+ };
7723
+ }
7724
+ }
7725
+ function installAgentToolHooks(agent) {
7726
+ if (agent.__neatlogs_tool_hook) return;
7727
+ let tools;
7728
+ try {
7729
+ tools = typeof agent.listTools === "function" ? agent.listTools() : void 0;
7730
+ } catch {
7731
+ tools = void 0;
7732
+ }
7733
+ if (!tools || typeof tools !== "object") return;
7734
+ agent.__neatlogs_tool_hook = true;
7735
+ for (const [key, tool] of Object.entries(tools)) {
7736
+ patchToolExecute(tool, key);
7737
+ }
7738
+ }
7739
+ function patchToolExecute(tool, key) {
7740
+ if (!tool || typeof tool.execute !== "function" || tool.__neatlogs_tool_patched) return;
7741
+ tool.__neatlogs_tool_patched = true;
7742
+ const toolName = tool.id ?? key;
7743
+ const orig = tool.execute.bind(tool);
7744
+ tool.execute = function tracedToolExecute(params, options) {
7745
+ const attrs = {
7746
+ "neatlogs.span.kind": "TOOL",
7747
+ "neatlogs.tool.name": toolName,
7748
+ "input.value": safeStringify7(params).slice(0, 1e4)
7749
+ };
7750
+ if (tool.description) attrs["neatlogs.tool.description"] = String(tool.description).slice(0, 2e3);
7751
+ return withActiveSpan(`mastra.tool.${toolName}`, attrs, async (span2) => {
7752
+ const result = await orig(params, options);
7753
+ span2.setAttribute("output.value", safeStringify7(result).slice(0, 1e4));
7754
+ return result;
7755
+ });
7756
+ };
7757
+ }
7758
+ function patchWorkflow(workflow) {
7759
+ if (typeof workflow.createRun !== "function") return;
7760
+ const origCreateRun = workflow.createRun.bind(workflow);
7761
+ const workflowName = workflow.name ?? workflow.id ?? "mastra_workflow";
7762
+ workflow.createRun = async function tracedCreateRun(...args) {
7763
+ const run = await origCreateRun(...args);
7764
+ if (!run) return run;
7765
+ patchRunMethod(run, "start", workflowName);
7766
+ patchRunMethod(run, "resume", workflowName);
7767
+ return run;
7768
+ };
7769
+ }
7770
+ function patchRunMethod(run, method, workflowName) {
7771
+ if (typeof run[method] !== "function") return;
7772
+ const orig = run[method].bind(run);
7773
+ run[method] = async function tracedRunMethod(startOpts) {
7774
+ const attrs = {
7775
+ "neatlogs.span.kind": "WORKFLOW",
7776
+ "neatlogs.workflow.name": workflowName
7777
+ };
7778
+ if (startOpts?.inputData !== void 0) {
7779
+ attrs["input.value"] = safeStringify7(startOpts.inputData).slice(0, 1e4);
7780
+ }
7781
+ return withActiveSpan(`mastra.workflow.${workflowName}`, attrs, async (span2) => {
7782
+ const result = await orig(startOpts);
7783
+ if (result?.status) span2.setAttribute("neatlogs.metadata", safeStringify7({ status: result.status }));
7784
+ if (result?.result !== void 0) {
7785
+ span2.setAttribute("output.value", safeStringify7(result.result).slice(0, 1e4));
7786
+ }
7787
+ return result;
7788
+ });
7789
+ };
7790
+ }
7791
+ var VECTOR_READ_OPS = ["query"];
7792
+ var VECTOR_WRITE_OPS = ["upsert", "updateVector", "deleteVector", "createIndex", "deleteIndex"];
7793
+ function patchVector(vector) {
7794
+ for (const op of VECTOR_READ_OPS) patchVectorOp(vector, op, "RETRIEVER");
7795
+ for (const op of VECTOR_WRITE_OPS) patchVectorOp(vector, op, "VECTOR_STORE");
7796
+ }
7797
+ function patchVectorOp(vector, op, kind) {
7798
+ if (typeof vector[op] !== "function") return;
7799
+ const orig = vector[op].bind(vector);
7800
+ const dbName = vector.constructor?.name ?? "vector";
7801
+ vector[op] = async function tracedVectorOp(params) {
7802
+ const attrs = {
7803
+ "neatlogs.span.kind": kind,
7804
+ "neatlogs.db.system": dbName,
7805
+ "neatlogs.db.operation": op,
7806
+ "input.value": safeStringify7(params).slice(0, 1e4)
7807
+ };
7808
+ const indexName = params?.indexName;
7809
+ if (indexName) attrs["neatlogs.vectordb.index_name"] = String(indexName);
7810
+ if (kind === "RETRIEVER" && params?.topK != null) attrs["neatlogs.retriever.top_k"] = params.topK;
7811
+ return withActiveSpan(`mastra.vector.${op}`, attrs, async (span2) => {
7812
+ const result = await orig(params);
7813
+ span2.setAttribute("output.value", safeStringify7(result).slice(0, 1e4));
7814
+ return result;
7815
+ });
7816
+ };
7817
+ }
7818
+ var MEMORY_OPS = ["recall", "saveMessages", "updateWorkingMemory", "deleteMessages"];
7819
+ function patchMemory(memory) {
7820
+ for (const op of MEMORY_OPS) {
7821
+ if (typeof memory[op] !== "function") continue;
7822
+ const orig = memory[op].bind(memory);
7823
+ memory[op] = async function tracedMemoryOp(...args) {
7824
+ const attrs = {
7825
+ "neatlogs.span.kind": "CHAIN",
7826
+ "neatlogs.db.operation": op,
7827
+ "input.value": safeStringify7(args?.[0]).slice(0, 1e4)
7828
+ };
7829
+ return withActiveSpan(`mastra.memory.${op}`, attrs, async (span2) => {
7830
+ const result = await orig(...args);
7831
+ span2.setAttribute("output.value", safeStringify7(result).slice(0, 8e3));
7832
+ return result;
7833
+ });
7834
+ };
7835
+ }
7836
+ }
7837
+ function patchDocument(doc) {
7838
+ if (typeof doc.chunk !== "function") return;
7839
+ const orig = doc.chunk.bind(doc);
7840
+ doc.chunk = async function tracedChunk(...args) {
7841
+ const attrs = {
7842
+ "neatlogs.span.kind": "CHAIN",
7843
+ "neatlogs.db.operation": "chunk"
7844
+ };
7845
+ return withActiveSpan("mastra.document.chunk", attrs, async (span2) => {
7846
+ const result = await orig(...args);
7847
+ if (Array.isArray(result)) span2.setAttribute("neatlogs.db.documents_count", result.length);
7848
+ return result;
7849
+ });
7850
+ };
7851
+ }
7852
+ function wrapRootMastra(mastra) {
7853
+ const AGENT_GETTERS = /* @__PURE__ */ new Set(["getAgent", "getAgentById"]);
7854
+ const WORKFLOW_GETTERS = /* @__PURE__ */ new Set(["getWorkflow", "getWorkflowById"]);
7855
+ return new Proxy(mastra, {
7856
+ get(target, prop, receiver) {
7857
+ const value = Reflect.get(target, prop, receiver);
7858
+ if (typeof value !== "function") return value;
7859
+ const name = String(prop);
7860
+ if (AGENT_GETTERS.has(name) || WORKFLOW_GETTERS.has(name)) {
7861
+ return (...args) => {
7862
+ const entity = value.apply(target, args);
7863
+ return entity && typeof entity === "object" ? wrapMastra(entity) : entity;
7864
+ };
7865
+ }
7866
+ return value.bind(target);
7867
+ }
7868
+ });
7869
+ }
7870
+ function wrapStreamingOutput(output, span2, ctx) {
7871
+ if (!output) {
7872
+ span2.setStatus({ code: import_api13.SpanStatusCode.OK });
7873
+ span2.end();
7874
+ return output;
7875
+ }
7876
+ let ended = false;
7877
+ const endOnce = (err) => {
7878
+ if (ended) return;
7879
+ ended = true;
7880
+ if (err) recordError3(span2, err);
7881
+ else span2.setStatus({ code: import_api13.SpanStatusCode.OK });
7882
+ span2.end();
7883
+ };
7884
+ if (output.text && typeof output.text.then === "function") {
7885
+ const finalize = async () => {
7886
+ try {
7887
+ const [text, usage, finishReason] = await Promise.all([
7888
+ Promise.resolve(output.text).catch(() => void 0),
7889
+ Promise.resolve(output.usage).catch(() => void 0),
7890
+ Promise.resolve(output.finishReason).catch(() => void 0)
7891
+ ]);
7892
+ if (typeof text === "string" && text) {
7893
+ span2.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
7894
+ span2.setAttribute("neatlogs.llm.output_messages.0.content", text.slice(0, 1e4));
7895
+ }
7896
+ if (usage) recordUsage(span2, usage);
7897
+ if (finishReason) span2.setAttribute("neatlogs.llm.stop_reason", normalizeFinishReason(finishReason));
7898
+ endOnce();
7899
+ } catch (err) {
7900
+ endOnce(err);
7901
+ }
7902
+ };
7903
+ void finalize();
7904
+ return rebindStreamContext(output, ctx);
7905
+ }
7906
+ if (output[Symbol.asyncIterator]) {
7907
+ const origIterator = output[Symbol.asyncIterator].bind(output);
7908
+ const textParts = [];
7909
+ const wrapped = Object.create(Object.getPrototypeOf(output));
7910
+ Object.assign(wrapped, output);
7911
+ wrapped[Symbol.asyncIterator] = function() {
7912
+ const iterator = origIterator();
7913
+ const finish = () => {
7914
+ if (textParts.length) {
7915
+ span2.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
7916
+ span2.setAttribute("neatlogs.llm.output_messages.0.content", textParts.join("").slice(0, 1e4));
7917
+ }
7918
+ endOnce();
7919
+ };
7920
+ return {
7921
+ async next() {
7922
+ try {
7923
+ const r = await iterator.next();
7924
+ if (r.done) {
7925
+ finish();
7926
+ return r;
7927
+ }
7928
+ const chunk = r.value;
7929
+ if (typeof chunk === "string") textParts.push(chunk);
7930
+ else if (chunk?.text) textParts.push(chunk.text);
7931
+ else if (chunk?.delta) textParts.push(chunk.delta);
7932
+ return r;
7933
+ } catch (err) {
7934
+ endOnce(err);
7935
+ throw err;
7936
+ }
7937
+ },
7938
+ async return(value) {
7939
+ finish();
7940
+ return iterator.return?.(value) ?? { done: true, value: void 0 };
7941
+ },
7942
+ async throw(err) {
7943
+ endOnce(err);
7944
+ return iterator.throw?.(err) ?? { done: true, value: void 0 };
7945
+ }
7946
+ };
7947
+ };
7948
+ return wrapped;
7949
+ }
7950
+ if (typeof output.then === "function") {
7951
+ return output.then((resolved) => {
7952
+ finalizeAgentResult(span2, resolved);
7953
+ endOnce();
7954
+ return resolved;
7955
+ }).catch((err) => {
7956
+ endOnce(err);
7957
+ throw err;
7958
+ });
7959
+ }
7960
+ endOnce();
7961
+ return output;
7962
+ }
7963
+ function rebindStreamContext(output, ctx) {
7964
+ const STREAM_PROPS = /* @__PURE__ */ new Set(["textStream", "fullStream", "objectStream", "elementStream"]);
7965
+ return new Proxy(output, {
7966
+ get(target, prop, receiver) {
7967
+ const value = Reflect.get(target, prop, receiver);
7968
+ if (typeof prop === "string" && STREAM_PROPS.has(prop) && value && value[Symbol.asyncIterator]) {
7969
+ const origIterator = value[Symbol.asyncIterator].bind(value);
7970
+ return {
7971
+ [Symbol.asyncIterator]() {
7972
+ return import_api13.context.with(ctx, () => origIterator());
7973
+ }
7974
+ };
7975
+ }
7976
+ if (typeof value === "function") return value.bind(target);
7977
+ return value;
7978
+ }
7979
+ });
7980
+ }
7981
+ function finalizeAgentResult(span2, result) {
7982
+ if (!result) return;
7983
+ if (result.text) {
7984
+ span2.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
7985
+ span2.setAttribute("neatlogs.llm.output_messages.0.content", String(result.text).slice(0, 1e4));
7986
+ }
7987
+ if (Array.isArray(result.toolCalls)) {
7988
+ for (let i = 0; i < result.toolCalls.length; i++) {
7989
+ const tc = result.toolCalls[i];
7990
+ const p = tc.payload ?? tc;
7991
+ setToolCall(span2, i, p.toolName ?? p.name, p.args ?? p.arguments, p.toolCallId ?? p.id);
7992
+ }
7993
+ }
7994
+ if (result.usage) recordUsage(span2, result.usage);
7995
+ if (result.finishReason) span2.setAttribute("neatlogs.llm.stop_reason", normalizeFinishReason(result.finishReason));
7996
+ if (result.model) span2.setAttribute("neatlogs.llm.model_name", result.model);
7997
+ }
7998
+ function finalizeModelResult(span2, result) {
7999
+ if (!result) return;
8000
+ if (typeof result.text === "string" && result.text) {
8001
+ span2.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
8002
+ span2.setAttribute("neatlogs.llm.output_messages.0.content", result.text.slice(0, 1e4));
8003
+ } else if (Array.isArray(result.content)) {
8004
+ const text = result.content.filter((p) => p?.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
8005
+ if (text) {
8006
+ span2.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
8007
+ span2.setAttribute("neatlogs.llm.output_messages.0.content", text.slice(0, 1e4));
8008
+ }
8009
+ const toolCalls = result.content.filter((p) => p?.type === "tool-call");
8010
+ for (let i = 0; i < toolCalls.length; i++) {
8011
+ const tc = toolCalls[i];
8012
+ setToolCall(span2, i, tc.toolName, tc.input ?? tc.args, tc.toolCallId);
8013
+ }
8014
+ span2.setAttribute("output.value", safeStringify7(result.content).slice(0, 1e4));
8015
+ }
8016
+ if (result.usage) recordUsage(span2, result.usage);
8017
+ span2.setAttribute("neatlogs.llm.stop_reason", normalizeFinishReason(result.finishReason));
8018
+ }
8019
+ function normalizeFinishReason(fr) {
8020
+ if (fr == null) return "";
8021
+ if (typeof fr === "string") return fr;
8022
+ return String(fr.unified ?? fr.reason ?? fr.type ?? safeStringify7(fr));
8023
+ }
8024
+ function tokenValue(v) {
8025
+ if (v == null) return void 0;
8026
+ if (typeof v === "number") return v;
8027
+ if (typeof v === "object" && typeof v.total === "number") return v.total;
8028
+ const n = Number(v);
8029
+ return Number.isFinite(n) ? n : void 0;
8030
+ }
8031
+ function captureInvocationParams(attrs, callOpts) {
8032
+ if (!callOpts) return;
8033
+ const map = [
8034
+ ["temperature", "neatlogs.llm.temperature"],
8035
+ ["maxOutputTokens", "neatlogs.llm.max_tokens"],
8036
+ ["maxTokens", "neatlogs.llm.max_tokens"],
8037
+ ["topP", "neatlogs.llm.top_p"],
8038
+ ["topK", "neatlogs.llm.top_k"],
8039
+ ["frequencyPenalty", "neatlogs.llm.frequency_penalty"],
8040
+ ["presencePenalty", "neatlogs.llm.presence_penalty"]
8041
+ ];
8042
+ const invocation = {};
8043
+ for (const [src, target] of map) {
8044
+ const v = callOpts[src];
8045
+ if (v != null) {
8046
+ attrs[target] = v;
8047
+ invocation[src] = v;
8048
+ }
8049
+ }
8050
+ if (Array.isArray(callOpts.stopSequences) && callOpts.stopSequences.length) {
8051
+ attrs["neatlogs.llm.stop_sequences"] = safeStringify7(callOpts.stopSequences);
8052
+ invocation.stopSequences = callOpts.stopSequences;
8053
+ }
8054
+ if (Array.isArray(callOpts.tools)) {
8055
+ for (let i = 0; i < callOpts.tools.length; i++) {
8056
+ attrs[`neatlogs.llm.tools.${i}`] = safeStringify7(callOpts.tools[i]).slice(0, 4e3);
8057
+ }
8058
+ invocation.toolChoice = callOpts.toolChoice;
8059
+ }
8060
+ if (Object.keys(invocation).length) {
8061
+ attrs["neatlogs.llm.invocation_parameters"] = safeStringify7(invocation).slice(0, 4e3);
8062
+ }
8063
+ }
8064
+ function setToolCall(span2, i, name, args, id) {
8065
+ span2.setAttribute(`neatlogs.llm.tool_calls.${i}.name`, name ?? "");
8066
+ span2.setAttribute(`neatlogs.llm.tool_calls.${i}.arguments`, safeStringify7(args ?? {}));
8067
+ if (id) span2.setAttribute(`neatlogs.llm.tool_calls.${i}.id`, id);
8068
+ }
8069
+ function recordUsage(span2, usage) {
8070
+ if (!usage) return;
8071
+ const prompt = tokenValue(usage.promptTokens ?? usage.inputTokens ?? usage.input_tokens);
8072
+ const completion = tokenValue(usage.completionTokens ?? usage.outputTokens ?? usage.output_tokens);
8073
+ const total = tokenValue(usage.totalTokens);
8074
+ if (prompt != null) span2.setAttribute("neatlogs.llm.token_count.prompt", prompt);
8075
+ if (completion != null) span2.setAttribute("neatlogs.llm.token_count.completion", completion);
8076
+ if (total != null) span2.setAttribute("neatlogs.llm.token_count.total", total);
8077
+ else if (prompt != null && completion != null) {
8078
+ span2.setAttribute("neatlogs.llm.token_count.total", prompt + completion);
8079
+ }
8080
+ }
8081
+ function withActiveSpan(name, attrs, fn) {
8082
+ const tracer = import_api13.trace.getTracer(TRACER_NAME7);
8083
+ const span2 = tracer.startSpan(name, { attributes: attrs }, import_api13.context.active());
8084
+ const ctx = import_api13.trace.setSpan(import_api13.context.active(), span2);
8085
+ return import_api13.context.with(ctx, async () => {
8086
+ try {
8087
+ const result = await fn(span2);
8088
+ span2.setStatus({ code: import_api13.SpanStatusCode.OK });
8089
+ return result;
8090
+ } catch (err) {
8091
+ recordError3(span2, err);
8092
+ throw err;
8093
+ } finally {
8094
+ span2.end();
8095
+ }
8096
+ });
8097
+ }
8098
+ function markPatched(e) {
8099
+ try {
8100
+ Object.defineProperty(e, PATCH_FLAG, { value: true, enumerable: false, configurable: true });
8101
+ } catch {
8102
+ e[PATCH_FLAG] = true;
8103
+ }
8104
+ }
8105
+ function extractModelId(model) {
8106
+ if (!model) return "";
8107
+ if (typeof model === "string") return model;
8108
+ return model.modelId ?? model.name ?? "";
8109
+ }
8110
+ function toInputValue(input) {
8111
+ return (typeof input === "string" ? input : safeStringify7(input)).slice(0, 1e4);
8112
+ }
8113
+ function safeStringify7(value) {
8114
+ if (typeof value === "string") return value;
8115
+ try {
8116
+ return JSON.stringify(value) ?? "";
8117
+ } catch {
8118
+ return "";
8119
+ }
8120
+ }
8121
+ function recordError3(span2, err) {
8122
+ if (err instanceof Error) {
8123
+ span2.setStatus({ code: import_api13.SpanStatusCode.ERROR, message: err.message });
8124
+ span2.recordException(err);
8125
+ } else {
8126
+ span2.setStatus({ code: import_api13.SpanStatusCode.ERROR, message: String(err) });
8127
+ }
8128
+ }
8129
+
6481
8130
  // src/core/llm-binder.ts
6482
8131
  var logger15 = getLogger();
6483
8132
  function bindTemplates(llm, systemTpl, userTpl, compiledVars) {
@@ -6549,15 +8198,23 @@ function bindTemplates(llm, systemTpl, userTpl, compiledVars) {
6549
8198
  getSessionConfig,
6550
8199
  init,
6551
8200
  isDebugEnabled,
8201
+ langchainHandler,
6552
8202
  listPrompts,
6553
8203
  log,
8204
+ openaiAgentsProcessor,
6554
8205
  registerCrewaiTask,
6555
8206
  removeTag,
6556
8207
  saveAsVersion,
6557
8208
  shutdown,
6558
8209
  span,
8210
+ strandsHooks,
6559
8211
  trace,
8212
+ traceToolAnthropic,
8213
+ traceToolOpenAI,
6560
8214
  updatePrompt,
6561
- wrapAISDK
8215
+ wrapAISDK,
8216
+ wrapAnthropic,
8217
+ wrapMastra,
8218
+ wrapOpenAI
6562
8219
  });
6563
8220
  //# sourceMappingURL=index.cjs.map