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