neatlogs 1.1.19 → 1.1.21

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.
Files changed (69) hide show
  1. package/README.md +34 -2
  2. package/dist/ai-sdk.cjs +186 -11
  3. package/dist/ai-sdk.cjs.map +1 -1
  4. package/dist/ai-sdk.d.ts +17 -7
  5. package/dist/ai-sdk.mjs +189 -12
  6. package/dist/ai-sdk.mjs.map +1 -1
  7. package/dist/anthropic.cjs +31 -14
  8. package/dist/anthropic.cjs.map +1 -1
  9. package/dist/anthropic.mjs +31 -14
  10. package/dist/anthropic.mjs.map +1 -1
  11. package/dist/azure-openai.cjs +31 -14
  12. package/dist/azure-openai.cjs.map +1 -1
  13. package/dist/azure-openai.mjs +31 -14
  14. package/dist/azure-openai.mjs.map +1 -1
  15. package/dist/bedrock.cjs +31 -14
  16. package/dist/bedrock.cjs.map +1 -1
  17. package/dist/bedrock.mjs +31 -14
  18. package/dist/bedrock.mjs.map +1 -1
  19. package/dist/browser.cjs +26 -1
  20. package/dist/browser.cjs.map +1 -1
  21. package/dist/browser.d.ts +1 -1
  22. package/dist/browser.mjs +26 -1
  23. package/dist/browser.mjs.map +1 -1
  24. package/dist/claude-agent-sdk.cjs +2 -2
  25. package/dist/claude-agent-sdk.cjs.map +1 -1
  26. package/dist/claude-agent-sdk.mjs +2 -2
  27. package/dist/claude-agent-sdk.mjs.map +1 -1
  28. package/dist/cli.cjs +452 -200
  29. package/dist/cli.cjs.map +1 -1
  30. package/dist/cli.mjs +427 -173
  31. package/dist/cli.mjs.map +1 -1
  32. package/dist/google-genai.cjs +31 -14
  33. package/dist/google-genai.cjs.map +1 -1
  34. package/dist/google-genai.mjs +31 -14
  35. package/dist/google-genai.mjs.map +1 -1
  36. package/dist/index.cjs +652 -333
  37. package/dist/index.cjs.map +1 -1
  38. package/dist/index.d.ts +15 -6
  39. package/dist/index.mjs +505 -184
  40. package/dist/index.mjs.map +1 -1
  41. package/dist/langchain.cjs +3 -3
  42. package/dist/langchain.cjs.map +1 -1
  43. package/dist/langchain.mjs +3 -3
  44. package/dist/langchain.mjs.map +1 -1
  45. package/dist/mastra-wrap.cjs +2 -2
  46. package/dist/mastra-wrap.cjs.map +1 -1
  47. package/dist/mastra-wrap.mjs +2 -2
  48. package/dist/mastra-wrap.mjs.map +1 -1
  49. package/dist/openai-agents.cjs.map +1 -1
  50. package/dist/openai-agents.mjs.map +1 -1
  51. package/dist/openai.cjs +31 -14
  52. package/dist/openai.cjs.map +1 -1
  53. package/dist/openai.mjs +31 -14
  54. package/dist/openai.mjs.map +1 -1
  55. package/dist/opencode-plugin.cjs +1 -1
  56. package/dist/opencode-plugin.cjs.map +1 -1
  57. package/dist/opencode-plugin.mjs +1 -1
  58. package/dist/opencode-plugin.mjs.map +1 -1
  59. package/dist/openrouter-agent.cjs +31 -14
  60. package/dist/openrouter-agent.cjs.map +1 -1
  61. package/dist/openrouter-agent.mjs +31 -14
  62. package/dist/openrouter-agent.mjs.map +1 -1
  63. package/dist/pi-agent.cjs.map +1 -1
  64. package/dist/pi-agent.mjs.map +1 -1
  65. package/dist/vertex-ai.cjs +31 -14
  66. package/dist/vertex-ai.cjs.map +1 -1
  67. package/dist/vertex-ai.mjs +31 -14
  68. package/dist/vertex-ai.mjs.map +1 -1
  69. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -18,7 +18,7 @@ import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-proto";
18
18
  import * as fs from "fs";
19
19
  import * as path from "path";
20
20
  import { performance } from "perf_hooks";
21
- import { ROOT_CONTEXT as ROOT_CONTEXT4, trace as otelTrace3, TraceFlags, SpanStatusCode as SpanStatusCode3 } from "@opentelemetry/api";
21
+ import { ROOT_CONTEXT as ROOT_CONTEXT4, trace as otelTrace4, TraceFlags, SpanStatusCode as SpanStatusCode3 } from "@opentelemetry/api";
22
22
 
23
23
  // src/core/logger.ts
24
24
  var LOG_LEVELS = {
@@ -71,9 +71,9 @@ var SCOPE_PATTERNS = {
71
71
  // Neatlogs custom instrumentations
72
72
  "@neatlogs/instrumentation-google-genai": { provider: "google", framework: "google_genai" },
73
73
  "@neatlogs/instrumentation-mastra": { framework: "mastra" },
74
- "@neatlogs/instrumentation-ai-sdk": { framework: "ai_sdk" },
74
+ "@neatlogs/instrumentation-ai-sdk": { framework: "vercel_ai_sdk" },
75
75
  // Vercel AI SDK native scope (the `ai` package emits this directly)
76
- ai: { framework: "ai_sdk" },
76
+ ai: { framework: "vercel_ai_sdk" },
77
77
  // OpenInference instrumentations (npm @arizeai scope names)
78
78
  "@arizeai/openinference-instrumentation-openai": { provider: "openai", framework: "openai" },
79
79
  "@arizeai/openinference-instrumentation-anthropic": { provider: "anthropic", framework: "anthropic" },
@@ -162,7 +162,7 @@ function parseInstrumentationScope(scopeName) {
162
162
  } else if (scopeLower.includes("dspy")) {
163
163
  result.framework = "dspy";
164
164
  } else if (scopeLower.includes("vercel-ai") || scopeLower.includes("ai-sdk")) {
165
- result.framework = "ai_sdk";
165
+ result.framework = "vercel_ai_sdk";
166
166
  }
167
167
  if (scopeLower.includes("openai")) {
168
168
  result.provider = "openai";
@@ -276,15 +276,26 @@ var VALID_SPAN_KINDS = /* @__PURE__ */ new Set([
276
276
  "RETRIEVER",
277
277
  "EMBEDDING",
278
278
  "MCP_TOOL",
279
- "GUARDRAIL"
279
+ "GUARDRAIL",
280
+ "EVALUATOR"
280
281
  ]);
281
282
  var ALL_SPAN_KINDS = /* @__PURE__ */ new Set([
282
283
  ...VALID_SPAN_KINDS,
283
284
  "LLM",
284
285
  "RERANKER",
285
- "EVALUATOR",
286
286
  "VECTOR_STORE"
287
287
  ]);
288
+ function resolveExplicitSpanKind(attributes) {
289
+ for (const key of [
290
+ "neatlogs.span.kind",
291
+ "openinference.span.kind",
292
+ "traceloop.span.kind"
293
+ ]) {
294
+ const value = String(attributes[key] ?? "").trim();
295
+ if (value) return value;
296
+ }
297
+ return "";
298
+ }
288
299
  function inferSpanKindFromName(spanName) {
289
300
  const nameLower = spanName.toLowerCase();
290
301
  if (["openai", "anthropic", "cohere", "bedrock", "chat", "completion", "llm", "gemini", "google_genai"].some(
@@ -2372,11 +2383,11 @@ function getNeatlogsParentContext(baseContext) {
2372
2383
  function getNeatlogsBaseContext(baseContext) {
2373
2384
  return baseContext ?? getNeatlogsActiveContext();
2374
2385
  }
2375
- function withNeatlogsSpan(span2, fn, baseContext) {
2386
+ function withNeatlogsSpan(span2, fn, baseContext, rootSpan) {
2376
2387
  const base = baseContext ?? getNeatlogsActiveContext();
2377
2388
  let ctx = otelTrace.setSpan(base, span2);
2378
2389
  if (base.getValue(NEATLOGS_ROOT_SPAN_KEY) === void 0) {
2379
- ctx = ctx.setValue(NEATLOGS_ROOT_SPAN_KEY, span2);
2390
+ ctx = ctx.setValue(NEATLOGS_ROOT_SPAN_KEY, rootSpan ?? span2);
2380
2391
  }
2381
2392
  return privateContextStorage.run(ctx, fn);
2382
2393
  }
@@ -2574,7 +2585,7 @@ var UserPromptTemplate = class extends BasePromptTemplate {
2574
2585
 
2575
2586
  // src/core/context.ts
2576
2587
  import {
2577
- trace as otelTrace2,
2588
+ trace as otelTrace3,
2578
2589
  createContextKey as createContextKey2,
2579
2590
  ROOT_CONTEXT as ROOT_CONTEXT3,
2580
2591
  SpanStatusCode as SpanStatusCode2
@@ -4215,6 +4226,139 @@ function discardPendingMediaOwner(owner) {
4215
4226
  pendingMediaOwners.delete(owner ?? defaultPendingMediaOwner);
4216
4227
  }
4217
4228
 
4229
+ // src/core/auto-root.ts
4230
+ import {
4231
+ trace as otelTrace2
4232
+ } from "@opentelemetry/api";
4233
+ var boundAutoRoots = /* @__PURE__ */ new WeakMap();
4234
+ var ROOT_KINDS = /* @__PURE__ */ new Set(["workflow", "chain", "agent", "mcp_tool", "llm"]);
4235
+ function autoRootEnabled() {
4236
+ const val = (process.env.NEATLOGS_AUTO_ROOT ?? "").trim().toLowerCase();
4237
+ return !["false", "0", "no", "off"].includes(val);
4238
+ }
4239
+ function resolveRootWorkflowName() {
4240
+ const clientName = getActiveClient()?.workflowName;
4241
+ if (typeof clientName === "string" && clientName.trim()) return clientName;
4242
+ try {
4243
+ const name = getSessionConfig()?.workflowName;
4244
+ if (typeof name === "string" && name.trim()) return name;
4245
+ } catch {
4246
+ }
4247
+ return "workflow";
4248
+ }
4249
+ function stampRootIdentity(root) {
4250
+ applySessionAttributes(root, void 0, true);
4251
+ applyEndUserAttributes(root, void 0, void 0, true);
4252
+ }
4253
+ function bindSpanToAutoRoot(child, root) {
4254
+ if (!root) return child;
4255
+ let ended = false;
4256
+ const proxy = new Proxy(child, {
4257
+ get(target, prop, _receiver) {
4258
+ if (prop === "end") {
4259
+ return (...args) => {
4260
+ if (ended) return;
4261
+ ended = true;
4262
+ try {
4263
+ target.end(...args);
4264
+ } finally {
4265
+ try {
4266
+ root.end();
4267
+ } catch {
4268
+ }
4269
+ }
4270
+ };
4271
+ }
4272
+ const value = Reflect.get(target, prop, target);
4273
+ return typeof value === "function" ? value.bind(target) : value;
4274
+ }
4275
+ });
4276
+ boundAutoRoots.set(proxy, root);
4277
+ aliasMediaCaptureSpan(proxy, child);
4278
+ return proxy;
4279
+ }
4280
+ function maybeOpenAutoRoot(tracer, kind, baseCtx) {
4281
+ const k = String(kind ?? "").toLowerCase();
4282
+ const existing = getActiveNeatlogsSpan();
4283
+ if (!autoRootEnabled() || ROOT_KINDS.has(k) || existing !== void 0 && existing.isRecording()) {
4284
+ return { root: void 0, ctx: baseCtx };
4285
+ }
4286
+ const root = tracer.startSpan(
4287
+ resolveRootWorkflowName(),
4288
+ { attributes: { "neatlogs.span.kind": "workflow", "neatlogs.auto_root": true } },
4289
+ baseCtx
4290
+ );
4291
+ stampRootIdentity(root);
4292
+ return { root, ctx: otelTrace2.setSpan(baseCtx, root) };
4293
+ }
4294
+ function endAutoRoot(root) {
4295
+ if (!root) return;
4296
+ try {
4297
+ root.end();
4298
+ } catch {
4299
+ }
4300
+ }
4301
+ var AutoRootTracer = class {
4302
+ constructor(_tracer) {
4303
+ this._tracer = _tracer;
4304
+ }
4305
+ _tracer;
4306
+ startSpan(name, options, context2) {
4307
+ const kind = String(
4308
+ options?.attributes?.["neatlogs.span.kind"] ?? ""
4309
+ ).toLowerCase();
4310
+ const hasExplicitContext = context2 !== void 0;
4311
+ const ctx = context2 ?? getNeatlogsParentContext();
4312
+ const parent = getActiveNeatlogsSpan();
4313
+ const isParentless = !hasExplicitContext && !(parent !== void 0 && parent.isRecording());
4314
+ const needsRoot = autoRootEnabled() && !ROOT_KINDS.has(kind) && isParentless;
4315
+ if (!needsRoot) {
4316
+ const span2 = this._tracer.startSpan(name, options, ctx);
4317
+ if (isParentless && ROOT_KINDS.has(kind)) stampRootIdentity(span2);
4318
+ return span2;
4319
+ }
4320
+ const root = this._tracer.startSpan(
4321
+ resolveRootWorkflowName(),
4322
+ { attributes: { "neatlogs.span.kind": "workflow", "neatlogs.auto_root": true } },
4323
+ ctx
4324
+ );
4325
+ stampRootIdentity(root);
4326
+ const childCtx = otelTrace2.setSpan(ctx, root);
4327
+ const child = this._tracer.startSpan(name, options, childCtx);
4328
+ return bindSpanToAutoRoot(child, root);
4329
+ }
4330
+ startActiveSpan = ((name, ...args) => {
4331
+ const callback = args.at(-1);
4332
+ if (typeof callback !== "function") {
4333
+ throw new TypeError("startActiveSpan requires a callback");
4334
+ }
4335
+ const options = args.length >= 2 ? args[0] : void 0;
4336
+ const parentContext = args.length >= 3 ? args[1] : getNeatlogsParentContext();
4337
+ const span2 = args.length >= 3 ? this.startSpan(name, options, parentContext) : this.startSpan(name, options);
4338
+ return withNeatlogsSpan(
4339
+ span2,
4340
+ () => callback(span2),
4341
+ parentContext,
4342
+ boundAutoRoots.get(span2)
4343
+ );
4344
+ });
4345
+ };
4346
+ function getProviderTracer(name) {
4347
+ return new AutoRootTracer(getNeatlogsTracer(name));
4348
+ }
4349
+
4350
+ // src/errors.ts
4351
+ var NeatlogsConfigurationError = class extends TypeError {
4352
+ code;
4353
+ option;
4354
+ constructor(code, option, message) {
4355
+ super(message);
4356
+ this.name = "NeatlogsConfigurationError";
4357
+ this.code = code;
4358
+ this.option = option;
4359
+ }
4360
+ };
4361
+
4218
4362
  // src/decorators/base.ts
4219
4363
  import {
4220
4364
  ROOT_CONTEXT as ROOT_CONTEXT2,
@@ -4321,7 +4465,28 @@ function decorateSpan(opts, fn) {
4321
4465
  const tracer = getNeatlogsTracer(TRACER_NAME);
4322
4466
  const isRoot = isRootSpan();
4323
4467
  const parentContext = isRoot ? ROOT_CONTEXT2 : getNeatlogsParentContext();
4324
- const span2 = tracer.startSpan(spanName, {}, parentContext);
4468
+ const autoRoot = maybeOpenAutoRoot(
4469
+ tracer,
4470
+ String(opts.kind ?? ""),
4471
+ parentContext
4472
+ );
4473
+ if (autoRoot.root) {
4474
+ applySessionAttributes(autoRoot.root, opts.sessionId, true, {
4475
+ parentSessionId: opts.parentSessionId,
4476
+ sessionFeatureName: opts.sessionFeatureName,
4477
+ sessionEntryPoint: opts.sessionEntryPoint
4478
+ });
4479
+ applyEndUserAttributes(
4480
+ autoRoot.root,
4481
+ opts.endUserId,
4482
+ opts.endUserMetadata,
4483
+ true
4484
+ );
4485
+ }
4486
+ const span2 = bindSpanToAutoRoot(
4487
+ tracer.startSpan(spanName, {}, autoRoot.ctx),
4488
+ autoRoot.root
4489
+ );
4325
4490
  return withNeatlogsSpan(span2, () => {
4326
4491
  let finished = false;
4327
4492
  let streamInterrupted = false;
@@ -4690,7 +4855,8 @@ function decorateSpan(opts, fn) {
4690
4855
  });
4691
4856
  try {
4692
4857
  setCommonSpanAttrs(span2, opts);
4693
- applySessionAttributes(span2, opts.sessionId, isRoot, {
4858
+ const spanIsRoot = isRoot && !autoRoot.root;
4859
+ applySessionAttributes(span2, opts.sessionId, spanIsRoot, {
4694
4860
  parentSessionId: opts.parentSessionId,
4695
4861
  sessionFeatureName: opts.sessionFeatureName,
4696
4862
  sessionEntryPoint: opts.sessionEntryPoint
@@ -4699,7 +4865,7 @@ function decorateSpan(opts, fn) {
4699
4865
  span2,
4700
4866
  opts.endUserId,
4701
4867
  opts.endUserMetadata,
4702
- isRoot
4868
+ spanIsRoot
4703
4869
  );
4704
4870
  if (captureInput && args.length > 0) {
4705
4871
  try {
@@ -4739,7 +4905,7 @@ function decorateSpan(opts, fn) {
4739
4905
  finishError(error);
4740
4906
  throw error;
4741
4907
  }
4742
- });
4908
+ }, autoRoot.ctx, autoRoot.root);
4743
4909
  };
4744
4910
  Object.defineProperty(wrapped, "name", {
4745
4911
  value: spanName,
@@ -4794,6 +4960,20 @@ var KNOWN_OPTION_KEYS = /* @__PURE__ */ new Set([
4794
4960
  "endUserId",
4795
4961
  "endUserMetadata"
4796
4962
  ]);
4963
+ function assertNoHttpSpanKind(kind, attributes) {
4964
+ const candidates = [
4965
+ kind,
4966
+ attributes?.["neatlogs.span.kind"],
4967
+ attributes?.["openinference.span.kind"]
4968
+ ];
4969
+ if (candidates.some((value) => String(value ?? "").trim().toUpperCase() === "HTTP")) {
4970
+ throw new NeatlogsConfigurationError(
4971
+ "UNSUPPORTED_SPAN_KIND",
4972
+ "kind",
4973
+ "HTTP spans are not supported. Trace the semantic LLM, TOOL, RETRIEVER, or other AI operation instead."
4974
+ );
4975
+ }
4976
+ }
4797
4977
  function _setSpanAttributes(span2, kind, attributes) {
4798
4978
  if (kind?.toUpperCase() === "LLM") {
4799
4979
  span2.setAttribute("neatlogs.internal", true);
@@ -4864,6 +5044,7 @@ async function trace(options, fn) {
4864
5044
  attributes: explicitAttributes,
4865
5045
  ...extraOptions
4866
5046
  } = options;
5047
+ assertNoHttpSpanKind(kind, explicitAttributes);
4867
5048
  const sessionId = sessionIdOption ?? currentSessionId();
4868
5049
  const currentSpan = getActiveNeatlogsSpan();
4869
5050
  const rootSpan = getNeatlogsRootSpan();
@@ -4908,7 +5089,7 @@ async function trace(options, fn) {
4908
5089
  }
4909
5090
  let ctx = getNeatlogsActiveContext();
4910
5091
  if (shouldFallbackToRoot) {
4911
- ctx = otelTrace2.setSpan(ctx, rootSpan);
5092
+ ctx = otelTrace3.setSpan(ctx, rootSpan);
4912
5093
  }
4913
5094
  const variablesJson = promptVariables ? JSON.stringify(promptVariables) : void 0;
4914
5095
  const userVariablesJson = userPromptVariables ? JSON.stringify(userPromptVariables) : void 0;
@@ -4942,12 +5123,13 @@ async function trace(options, fn) {
4942
5123
  const tracer = getNeatlogsTracer("neatlogs.trace");
4943
5124
  const spanCallback = async (span3) => {
4944
5125
  _setSpanAttributes(span3, kind, extraAttributes);
4945
- applySessionAttributes(span3, sessionId, isRootTrace, {
5126
+ const spanIsRoot = isRootTrace && !autoRoot.root;
5127
+ applySessionAttributes(span3, sessionId, spanIsRoot, {
4946
5128
  parentSessionId,
4947
5129
  sessionFeatureName,
4948
5130
  sessionEntryPoint
4949
5131
  });
4950
- applyEndUserAttributes(span3, endUserId, endUserMetadata, isRootTrace);
5132
+ applyEndUserAttributes(span3, endUserId, endUserMetadata, spanIsRoot);
4951
5133
  if (input !== void 0 && input !== null) {
4952
5134
  const capturedInput = captureMedia(
4953
5135
  span3,
@@ -4999,13 +5181,34 @@ async function trace(options, fn) {
4999
5181
  };
5000
5182
  const parentContext = shouldCreateRootTrace ? ROOT_CONTEXT3 : getNeatlogsParentContext(ctx);
5001
5183
  const startAttributes = kind ? { "openinference.span.kind": kind } : void 0;
5002
- const span2 = tracer.startSpan(name, startAttributes ? { attributes: startAttributes } : {}, parentContext);
5184
+ const autoRoot = isRootTrace ? maybeOpenAutoRoot(tracer, String(kind ?? "CHAIN"), parentContext) : { root: void 0, ctx: parentContext };
5185
+ if (autoRoot.root) {
5186
+ applySessionAttributes(autoRoot.root, sessionId, true, {
5187
+ parentSessionId,
5188
+ sessionFeatureName,
5189
+ sessionEntryPoint
5190
+ });
5191
+ applyEndUserAttributes(autoRoot.root, endUserId, endUserMetadata, true);
5192
+ }
5193
+ const span2 = bindSpanToAutoRoot(
5194
+ tracer.startSpan(
5195
+ name,
5196
+ startAttributes ? { attributes: startAttributes } : {},
5197
+ autoRoot.ctx
5198
+ ),
5199
+ autoRoot.root
5200
+ );
5003
5201
  if (shouldCreateRootTrace) {
5004
5202
  logger7.debug(`[trace] Creating NEW root trace '${name}' (sessionId=${sessionId})`);
5005
5203
  } else {
5006
5204
  logger7.debug(`[trace] Creating child span '${name}'`);
5007
5205
  }
5008
- return withNeatlogsSpan(span2, () => spanCallback(span2), ctx);
5206
+ return withNeatlogsSpan(
5207
+ span2,
5208
+ () => spanCallback(span2),
5209
+ autoRoot.ctx,
5210
+ autoRoot.root
5211
+ );
5009
5212
  }
5010
5213
 
5011
5214
  // src/core/crewai-task-registry.ts
@@ -6203,27 +6406,11 @@ var AttributeMapper = class {
6203
6406
  /** Extract and normalize span kind from multiple possible sources. */
6204
6407
  mapSpanKind(attributes) {
6205
6408
  const spanKindConfig = this.mappings.span_kind ?? {};
6206
- const sources = spanKindConfig.sources ?? [];
6207
6409
  const valuesMap = spanKindConfig.values ?? {};
6208
- const priority = spanKindConfig.priority ?? "openinference";
6209
- let spanKindValue;
6210
- if (priority === "openinference") {
6211
- if ("openinference.span.kind" in attributes) {
6212
- spanKindValue = attributes["openinference.span.kind"];
6213
- }
6214
- } else {
6215
- for (const source of sources) {
6216
- if (source in attributes) {
6217
- spanKindValue = attributes[source];
6218
- break;
6219
- }
6220
- }
6221
- }
6222
- if (!spanKindValue && "neatlogs.span.kind" in attributes) {
6223
- spanKindValue = attributes["neatlogs.span.kind"];
6224
- }
6225
- if (spanKindValue && spanKindValue in valuesMap) {
6226
- return valuesMap[spanKindValue];
6410
+ const spanKindValue = resolveExplicitSpanKind(attributes);
6411
+ if (spanKindValue) {
6412
+ const mapped = valuesMap[spanKindValue] ?? valuesMap[spanKindValue.toUpperCase()];
6413
+ if (mapped) return mapped;
6227
6414
  }
6228
6415
  if (spanKindValue && Object.values(valuesMap).includes(spanKindValue)) {
6229
6416
  return spanKindValue;
@@ -6505,6 +6692,46 @@ function addVerificationMarkerResourceAttribute(attributes) {
6505
6692
  if (marker) attributes[VERIFICATION_MARKER_KEY] = marker;
6506
6693
  }
6507
6694
 
6695
+ // src/core/http-span.ts
6696
+ import { SpanKind } from "@opentelemetry/api";
6697
+ var HTTP_SCOPE_PREFIXES = [
6698
+ "@opentelemetry/instrumentation-http",
6699
+ "@opentelemetry/instrumentation-fetch",
6700
+ "@opentelemetry/instrumentation-undici"
6701
+ ];
6702
+ var HTTP_ATTRIBUTE_KEYS = [
6703
+ "http.method",
6704
+ "http.request.method",
6705
+ "http.url",
6706
+ "http.route",
6707
+ "url.full"
6708
+ ];
6709
+ var SEMANTIC_AI_KINDS = /* @__PURE__ */ new Set([
6710
+ "WORKFLOW",
6711
+ "AGENT",
6712
+ "CHAIN",
6713
+ "TOOL",
6714
+ "RETRIEVER",
6715
+ "EMBEDDING",
6716
+ "GUARDRAIL",
6717
+ "LLM",
6718
+ "RERANKER",
6719
+ "VECTOR_STORE",
6720
+ "TASK",
6721
+ "EVALUATOR",
6722
+ "LOG",
6723
+ "MEMORY",
6724
+ "MCP_TOOL"
6725
+ ]);
6726
+ function isHttpSpan(span2, attributes = span2.attributes ?? {}) {
6727
+ const resolvedKind = resolveExplicitSpanKind(attributes).toUpperCase();
6728
+ if (resolvedKind === "HTTP") return true;
6729
+ if (SEMANTIC_AI_KINDS.has(resolvedKind)) return false;
6730
+ const scopeName = span2.instrumentationLibrary.name ?? "";
6731
+ if (HTTP_SCOPE_PREFIXES.some((prefix) => scopeName.startsWith(prefix))) return true;
6732
+ return span2.kind === SpanKind.CLIENT && HTTP_ATTRIBUTE_KEYS.some((key) => key in attributes);
6733
+ }
6734
+
6508
6735
  // src/core/span-processor.ts
6509
6736
  var logger10 = getLogger();
6510
6737
  function resolveLogFilePath(configuredPath) {
@@ -6776,6 +7003,7 @@ var NeatlogsSpanProcessor = class {
6776
7003
  onEnd(span2) {
6777
7004
  this._activeSpans.delete(span2.spanContext().spanId);
6778
7005
  if (this._closed) return;
7006
+ if (isHttpSpan(span2)) return;
6779
7007
  if (span2.name === "neatlogs.trace.complete") {
6780
7008
  const markerData = spanToDict(span2, { includeScope: true });
6781
7009
  markerData.resource = { attributes: markerData.resource };
@@ -6935,6 +7163,7 @@ var NeatlogsSpanProcessor = class {
6935
7163
  const maskResult = scheduleMask(span2, spanData, this.mask ?? null);
6936
7164
  const pending = maskResult.then((maskedSpanData) => {
6937
7165
  if (maskedSpanData === null) return;
7166
+ if (isHttpSpan(span2, maskedSpanData.attributes ?? {})) return;
6938
7167
  if (this._processedLogStream && !this._processedLogStream.destroyed) {
6939
7168
  try {
6940
7169
  this._processedLogStream.write(JSON.stringify(maskedSpanData) + "\n");
@@ -7033,8 +7262,8 @@ var NeatlogsSpanProcessor = class {
7033
7262
  isRemote: false,
7034
7263
  traceFlags: TraceFlags.SAMPLED
7035
7264
  };
7036
- const wrappedSpan = otelTrace3.wrapSpanContext(spanCtx);
7037
- const ctx = otelTrace3.setSpan(ROOT_CONTEXT4, wrappedSpan);
7265
+ const wrappedSpan = otelTrace4.wrapSpanContext(spanCtx);
7266
+ const ctx = otelTrace4.setSpan(ROOT_CONTEXT4, wrappedSpan);
7038
7267
  const marker = markerTracer.startSpan("neatlogs.trace.complete", void 0, ctx);
7039
7268
  marker.setAttribute("neatlogs.trace.complete", true);
7040
7269
  marker.setAttribute("neatlogs.internal", true);
@@ -7203,7 +7432,8 @@ var CompletionMarkerSpanProcessor = class {
7203
7432
  onStart(_span, _parentContext) {
7204
7433
  }
7205
7434
  onEnd(span2) {
7206
- if (this.closed || span2.name === "neatlogs.trace.complete" || span2.parentSpanId) return;
7435
+ if (this.closed || span2.name === "neatlogs.trace.complete" || span2.parentSpanId || isHttpSpan(span2))
7436
+ return;
7207
7437
  if (!this.source.ownsSpan(span2)) return;
7208
7438
  const task = this.source.whenMaskComplete(span2).then((eligible) => {
7209
7439
  if (!eligible || this.closed) return;
@@ -7355,6 +7585,10 @@ var FilteringExporter = class {
7355
7585
  _onPrepared;
7356
7586
  export(spans, resultCallback) {
7357
7587
  void mapWithConcurrency(spans, MEDIA_RESOLUTION_CONCURRENCY, async (span2) => {
7588
+ if (isHttpSpan(span2)) {
7589
+ discardPendingMedia(span2);
7590
+ return { span: null, mediaReady: true };
7591
+ }
7358
7592
  if (span2.instrumentationLibrary.name === "next.js") {
7359
7593
  discardPendingMedia(span2);
7360
7594
  this.diagnostics?.recordFrameworkSpanDrop();
@@ -7375,6 +7609,11 @@ var FilteringExporter = class {
7375
7609
  ...masked.attributes && typeof masked.attributes === "object" ? masked.attributes : {}
7376
7610
  };
7377
7611
  const maskedData = { ...masked, attributes };
7612
+ const maskedSpan = maskedReadableSpan(span2, maskedData);
7613
+ if (isHttpSpan(maskedSpan)) {
7614
+ discardPendingMedia(span2);
7615
+ return { span: null, mediaReady: true };
7616
+ }
7378
7617
  captureMediaInSnapshot(
7379
7618
  span2,
7380
7619
  maskedData,
@@ -9044,19 +9283,7 @@ function _resetMastraCache() {
9044
9283
  }
9045
9284
 
9046
9285
  // src/version.ts
9047
- var __version__ = "1.1.19";
9048
-
9049
- // src/errors.ts
9050
- var NeatlogsConfigurationError = class extends TypeError {
9051
- code;
9052
- option;
9053
- constructor(code, option, message) {
9054
- super(message);
9055
- this.name = "NeatlogsConfigurationError";
9056
- this.code = code;
9057
- this.option = option;
9058
- }
9059
- };
9286
+ var __version__ = "1.1.21";
9060
9287
 
9061
9288
  // src/core/deadline.ts
9062
9289
  async function runByDeadline(operation, deadlineMs) {
@@ -9158,6 +9385,24 @@ var INIT_OPTION_KEYS = /* @__PURE__ */ new Set([
9158
9385
  "piiSpanTypes",
9159
9386
  "uploadAuthority"
9160
9387
  ]);
9388
+ function resolveInitEndpoint(endpoint) {
9389
+ const explicit = (endpoint ?? "").trim();
9390
+ if (explicit) return explicit;
9391
+ const fromEnv = (process.env.NEATLOGS_ENDPOINT ?? "").trim();
9392
+ return fromEnv || DEFAULT_INGEST_ENDPOINT;
9393
+ }
9394
+ function resolveIngestBaseUrl(endpoint) {
9395
+ const parsed = new URL(endpoint.trim());
9396
+ const path3 = parsed.pathname.replace(/\/+$/, "");
9397
+ if (path3 !== "" && path3 !== "/v1/traces") {
9398
+ throw new NeatlogsConfigurationError(
9399
+ "INVALID_ENDPOINT",
9400
+ "endpoint",
9401
+ "endpoint must be a base URL or an OTLP traces URL ending in /v1/traces."
9402
+ );
9403
+ }
9404
+ return parsed.origin;
9405
+ }
9161
9406
  function validateInitOptions(options) {
9162
9407
  const raw = options;
9163
9408
  if (Object.prototype.hasOwnProperty.call(raw, "instrumentations")) {
@@ -9241,8 +9486,13 @@ function stableValue(value, ancestors = /* @__PURE__ */ new WeakSet(), location
9241
9486
  ancestors.delete(value);
9242
9487
  }
9243
9488
  }
9489
+ function resolveApiKey(apiKey) {
9490
+ const explicit = (apiKey ?? "").trim();
9491
+ if (explicit) return explicit;
9492
+ return (process.env.NEATLOGS_API_KEY ?? "").trim();
9493
+ }
9244
9494
  function initIdentity(options) {
9245
- const apiKey = (options.apiKey ?? process.env.NEATLOGS_API_KEY ?? "").trim();
9495
+ const apiKey = resolveApiKey(options.apiKey);
9246
9496
  const apiKeyDigest = createHash4("sha256").update(apiKey).digest("hex");
9247
9497
  const serialized = stableValue({
9248
9498
  apiKeyDigest,
@@ -9262,7 +9512,7 @@ function initIdentity(options) {
9262
9512
  captureLogs: options.captureLogs ?? false,
9263
9513
  pii: options.pii ?? null,
9264
9514
  version: options.version ?? null,
9265
- endpoint: options.endpoint ?? DEFAULT_INGEST_ENDPOINT,
9515
+ endpoint: resolveInitEndpoint(options.endpoint),
9266
9516
  batchSize: options.batchSize ?? 100,
9267
9517
  flushInterval: options.flushInterval ?? 5,
9268
9518
  piiEnabled: options.piiEnabled ?? null,
@@ -9342,12 +9592,7 @@ async function _performInit(options) {
9342
9592
  );
9343
9593
  }
9344
9594
  _deliveryDiagnostics = new DeliveryDiagnostics();
9345
- let resolvedKey;
9346
- if (options.apiKey && options.apiKey.trim()) {
9347
- resolvedKey = options.apiKey.trim();
9348
- } else {
9349
- resolvedKey = (process.env.NEATLOGS_API_KEY ?? "").trim();
9350
- }
9595
+ let resolvedKey = resolveApiKey(options.apiKey);
9351
9596
  let disableExportResolved = !!options.disableExport || ["true", "1", "yes"].includes(
9352
9597
  (process.env.NEATLOGS_DISABLE_EXPORT ?? "").toLowerCase()
9353
9598
  );
@@ -9368,8 +9613,8 @@ async function _performInit(options) {
9368
9613
  }
9369
9614
  _debugMode2 = options.debug ?? false;
9370
9615
  const resolvedWorkflowName = _resolveWorkflowName(options.workflowName);
9371
- const endpoint = options.endpoint ?? DEFAULT_INGEST_ENDPOINT;
9372
- const baseUrl = new URL(endpoint).origin;
9616
+ const endpoint = resolveInitEndpoint(options.endpoint);
9617
+ const baseUrl = resolveIngestBaseUrl(endpoint);
9373
9618
  const uploadAuthority = disableExportResolved ? new DisabledUploadAuthority("export_disabled") : resolveUploadAuthority(
9374
9619
  options.uploadAuthority,
9375
9620
  process.env.NEATLOGS_UPLOADS_ENABLED,
@@ -9784,7 +10029,7 @@ function _doctorRuntimeSnapshot() {
9784
10029
  // src/core/client.ts
9785
10030
  import {
9786
10031
  INVALID_SPAN_CONTEXT as INVALID_SPAN_CONTEXT2,
9787
- trace as otelTrace4
10032
+ trace as otelTrace5
9788
10033
  } from "@opentelemetry/api";
9789
10034
  import { Resource as Resource4 } from "@opentelemetry/resources";
9790
10035
  import { ATTR_SERVICE_NAME as ATTR_SERVICE_NAME2 } from "@opentelemetry/semantic-conventions";
@@ -9800,12 +10045,12 @@ import { OTLPLogExporter as OTLPLogExporter2 } from "@opentelemetry/exporter-log
9800
10045
  var logger14 = getLogger();
9801
10046
  var closedTracer = {
9802
10047
  startSpan() {
9803
- return otelTrace4.wrapSpanContext(INVALID_SPAN_CONTEXT2);
10048
+ return otelTrace5.wrapSpanContext(INVALID_SPAN_CONTEXT2);
9804
10049
  },
9805
10050
  startActiveSpan(_name, arg2, arg3, arg4) {
9806
10051
  const fn = typeof arg2 === "function" ? arg2 : typeof arg3 === "function" ? arg3 : arg4;
9807
10052
  return fn(
9808
- otelTrace4.wrapSpanContext(INVALID_SPAN_CONTEXT2)
10053
+ otelTrace5.wrapSpanContext(INVALID_SPAN_CONTEXT2)
9809
10054
  );
9810
10055
  }
9811
10056
  };
@@ -10286,7 +10531,7 @@ function Span(options) {
10286
10531
  import {
10287
10532
  TraceFlags as TraceFlags3,
10288
10533
  createTraceState,
10289
- trace as otelTrace5
10534
+ trace as otelTrace6
10290
10535
  } from "@opentelemetry/api";
10291
10536
  function injectTraceContext(carrier) {
10292
10537
  const spanContext = getActiveNeatlogsSpan()?.spanContext();
@@ -10316,7 +10561,7 @@ function extractTraceContext(carrier, fn) {
10316
10561
  if (!spanContext) {
10317
10562
  return fn();
10318
10563
  }
10319
- return withNeatlogsRemoteParent(otelTrace5.wrapSpanContext(spanContext), fn);
10564
+ return withNeatlogsRemoteParent(otelTrace6.wrapSpanContext(spanContext), fn);
10320
10565
  }
10321
10566
  function parseTraceParent(traceparent, tracestate) {
10322
10567
  const match = traceparent?.trim().match(
@@ -10352,10 +10597,14 @@ function setHeader(carrier, name, value) {
10352
10597
  }
10353
10598
 
10354
10599
  // src/ai-sdk.ts
10355
- import { SpanStatusCode as SpanStatusCode6 } from "@opentelemetry/api";
10600
+ import {
10601
+ SpanStatusCode as SpanStatusCode6
10602
+ } from "@opentelemetry/api";
10356
10603
  var TRACER_NAME2 = "neatlogs.ai-sdk";
10357
10604
  function createAITelemetry(opts = {}) {
10358
10605
  const userMeta = opts.metadata ?? {};
10606
+ const neatlogsTracer = getRoutingNeatlogsTracer(TRACER_NAME2);
10607
+ const callerTracer = opts.tracer;
10359
10608
  return {
10360
10609
  isEnabled: true,
10361
10610
  recordInputs: true,
@@ -10364,8 +10613,11 @@ function createAITelemetry(opts = {}) {
10364
10613
  // internally, which would otherwise parent its native spans from the foreign
10365
10614
  // global context AND push them onto it (so a co-tenant's next span inherits
10366
10615
  // ours). The facade routes both through the private Neatlogs context.
10367
- tracer: getRoutingNeatlogsTracer(TRACER_NAME2),
10368
- metadata: { ...userMeta, neatlogsWrapped: true }
10616
+ tracer: callerTracer ? createMirroredTracer(callerTracer, neatlogsTracer) : neatlogsTracer,
10617
+ ...opts.functionId !== void 0 ? { functionId: opts.functionId } : {},
10618
+ // The marker is an implementation detail used only when Neatlogs owns the
10619
+ // telemetry stream. Do not leak it into caller-owned providers.
10620
+ metadata: callerTracer ? { ...userMeta } : { ...userMeta, neatlogsWrapped: true }
10369
10621
  };
10370
10622
  }
10371
10623
  function safeStringify2(value) {
@@ -10439,21 +10691,80 @@ var WRAPPED_FUNCTIONS = [
10439
10691
  "embedMany",
10440
10692
  "rerank"
10441
10693
  ];
10694
+ var WRAPPED_AGENT_CONSTRUCTORS = [
10695
+ "ToolLoopAgent",
10696
+ "Experimental_Agent"
10697
+ ];
10698
+ var wrappedExports = /* @__PURE__ */ new WeakSet();
10699
+ var wrapperByOriginal = /* @__PURE__ */ new WeakMap();
10442
10700
  function wrapAISDK(aiModule) {
10443
10701
  const wrapped = { ...aiModule };
10444
10702
  for (const name of WRAPPED_FUNCTIONS) {
10445
10703
  const original = aiModule[name];
10446
10704
  if (typeof original !== "function") continue;
10705
+ const existing = getExistingWrapper(original);
10706
+ if (existing) {
10707
+ wrapped[name] = existing;
10708
+ continue;
10709
+ }
10447
10710
  if (name === "streamText" || name === "streamObject") {
10448
- wrapped[name] = createStreamWrapper(name, original);
10711
+ wrapped[name] = cacheWrapper(
10712
+ original,
10713
+ createStreamWrapper(name, original)
10714
+ );
10449
10715
  } else {
10450
- wrapped[name] = createAsyncWrapper(name, original);
10716
+ wrapped[name] = cacheWrapper(
10717
+ original,
10718
+ createAsyncWrapper(name, original)
10719
+ );
10451
10720
  }
10452
10721
  }
10722
+ for (const name of WRAPPED_AGENT_CONSTRUCTORS) {
10723
+ const original = aiModule[name];
10724
+ if (typeof original !== "function") continue;
10725
+ const existing = getExistingWrapper(original);
10726
+ wrapped[name] = existing ?? cacheWrapper(
10727
+ original,
10728
+ createAgentConstructorWrapper(original)
10729
+ );
10730
+ }
10731
+ return wrapped;
10732
+ }
10733
+ function getExistingWrapper(original) {
10734
+ if (wrappedExports.has(original)) return original;
10735
+ return wrapperByOriginal.get(original);
10736
+ }
10737
+ function cacheWrapper(original, wrapped) {
10738
+ wrapperByOriginal.set(original, wrapped);
10739
+ wrappedExports.add(wrapped);
10453
10740
  return wrapped;
10454
10741
  }
10742
+ function createAgentConstructorWrapper(original) {
10743
+ return new Proxy(original, {
10744
+ construct(target, args, newTarget) {
10745
+ if (args.length === 0 || typeof args[0] !== "object" || args[0] === null) {
10746
+ return Reflect.construct(target, args, newTarget);
10747
+ }
10748
+ const settings = mergeAgentSettings(args[0]);
10749
+ return Reflect.construct(target, [settings, ...args.slice(1)], newTarget);
10750
+ }
10751
+ });
10752
+ }
10753
+ function mergeAgentSettings(settings) {
10754
+ const merged = mergeTelemetry(settings);
10755
+ const userPrepareCall = settings.prepareCall;
10756
+ if (typeof userPrepareCall !== "function") return merged;
10757
+ return {
10758
+ ...merged,
10759
+ prepareCall: async function wrappedPrepareCall(...args) {
10760
+ const prepared = await Reflect.apply(userPrepareCall, this, args);
10761
+ return prepared == null ? prepared : mergeTelemetry(prepared, settings.experimental_telemetry);
10762
+ }
10763
+ };
10764
+ }
10455
10765
  function rootSpanKind(name) {
10456
- if (name === "embed" || name === "embedMany" || name === "rerank") return "CHAIN";
10766
+ if (name === "embed" || name === "embedMany" || name === "rerank")
10767
+ return "CHAIN";
10457
10768
  return "WORKFLOW";
10458
10769
  }
10459
10770
  function getParentContext() {
@@ -10550,15 +10861,126 @@ function createStreamWrapper(name, original) {
10550
10861
  );
10551
10862
  };
10552
10863
  }
10553
- function mergeTelemetry(opts) {
10864
+ function createMirroredSpan(primary, secondary) {
10865
+ const mirrored = {
10866
+ spanContext() {
10867
+ return primary.spanContext();
10868
+ },
10869
+ setAttribute(key, value) {
10870
+ primary.setAttribute(key, value);
10871
+ secondary.setAttribute(key, value);
10872
+ return mirrored;
10873
+ },
10874
+ setAttributes(attributes) {
10875
+ primary.setAttributes(attributes);
10876
+ secondary.setAttributes(attributes);
10877
+ return mirrored;
10878
+ },
10879
+ addEvent(name, attributesOrStartTime, startTime) {
10880
+ primary.addEvent(name, attributesOrStartTime, startTime);
10881
+ secondary.addEvent(name, attributesOrStartTime, startTime);
10882
+ return mirrored;
10883
+ },
10884
+ addLink(link) {
10885
+ primary.addLink(link);
10886
+ secondary.addLink(link);
10887
+ return mirrored;
10888
+ },
10889
+ addLinks(links) {
10890
+ primary.addLinks(links);
10891
+ secondary.addLinks(links);
10892
+ return mirrored;
10893
+ },
10894
+ setStatus(status) {
10895
+ primary.setStatus(status);
10896
+ secondary.setStatus(status);
10897
+ return mirrored;
10898
+ },
10899
+ updateName(name) {
10900
+ primary.updateName(name);
10901
+ secondary.updateName(name);
10902
+ return mirrored;
10903
+ },
10904
+ end(endTime) {
10905
+ primary.end(endTime);
10906
+ secondary.end(endTime);
10907
+ },
10908
+ isRecording() {
10909
+ return primary.isRecording() || secondary.isRecording();
10910
+ },
10911
+ recordException(exception, time) {
10912
+ primary.recordException(exception, time);
10913
+ secondary.recordException(exception, time);
10914
+ }
10915
+ };
10916
+ return mirrored;
10917
+ }
10918
+ function createMirroredTracer(primary, secondary) {
10919
+ return {
10920
+ startSpan(name, options, context2) {
10921
+ const primarySpan = primary.startSpan(name, options, context2);
10922
+ const secondarySpan = secondary.startSpan(name, options);
10923
+ return createMirroredSpan(primarySpan, secondarySpan);
10924
+ },
10925
+ startActiveSpan: ((name, arg2, arg3, arg4) => {
10926
+ let options;
10927
+ let context2;
10928
+ let fn;
10929
+ if (typeof arg2 === "function") {
10930
+ fn = arg2;
10931
+ } else if (typeof arg3 === "function") {
10932
+ options = arg2;
10933
+ fn = arg3;
10934
+ } else {
10935
+ options = arg2;
10936
+ context2 = arg3;
10937
+ fn = arg4;
10938
+ }
10939
+ const runSecondary = (primarySpan) => {
10940
+ const onSecondarySpan = (secondarySpan) => fn(createMirroredSpan(primarySpan, secondarySpan));
10941
+ return options === void 0 ? secondary.startActiveSpan(name, onSecondarySpan) : secondary.startActiveSpan(name, options, onSecondarySpan);
10942
+ };
10943
+ if (context2 !== void 0) {
10944
+ return primary.startActiveSpan(
10945
+ name,
10946
+ options ?? {},
10947
+ context2,
10948
+ runSecondary
10949
+ );
10950
+ }
10951
+ return options === void 0 ? primary.startActiveSpan(name, runSecondary) : primary.startActiveSpan(name, options, runSecondary);
10952
+ })
10953
+ };
10954
+ }
10955
+ function mergeTelemetry(opts, fallbackTelemetry) {
10956
+ const requestedTelemetry = {
10957
+ ...fallbackTelemetry,
10958
+ ...opts?.experimental_telemetry,
10959
+ metadata: {
10960
+ ...fallbackTelemetry?.metadata,
10961
+ ...opts?.experimental_telemetry?.metadata
10962
+ }
10963
+ };
10554
10964
  const baseTelemetry = createAITelemetry({
10555
- metadata: opts?.experimental_telemetry?.metadata
10965
+ functionId: requestedTelemetry.functionId,
10966
+ metadata: requestedTelemetry.metadata,
10967
+ tracer: requestedTelemetry.tracer
10556
10968
  });
10969
+ const callerTracer = requestedTelemetry.tracer;
10970
+ const hasCallerTracer = callerTracer !== void 0;
10557
10971
  return {
10558
10972
  ...opts,
10559
10973
  experimental_telemetry: {
10560
- ...opts?.experimental_telemetry,
10561
- ...baseTelemetry
10974
+ ...baseTelemetry,
10975
+ ...requestedTelemetry,
10976
+ isEnabled: true,
10977
+ recordInputs: requestedTelemetry.recordInputs ?? true,
10978
+ recordOutputs: requestedTelemetry.recordOutputs ?? true,
10979
+ tracer: baseTelemetry.tracer,
10980
+ // Do not add Neatlogs-only marker metadata to a caller-owned telemetry
10981
+ // pipeline such as Laminar. Both providers receive the same AI SDK span
10982
+ // data, while their providers, parent contexts, and exporters stay separate.
10983
+ metadata: hasCallerTracer ? requestedTelemetry.metadata : baseTelemetry.metadata
10562
10984
  }
10563
10985
  };
10564
10986
  }
@@ -10574,110 +10996,6 @@ function recordSpanError(span2, err) {
10574
10996
  // src/openai.ts
10575
10997
  import { SpanStatusCode as SpanStatusCode8 } from "@opentelemetry/api";
10576
10998
 
10577
- // src/core/auto-root.ts
10578
- import {
10579
- trace as otelTrace6
10580
- } from "@opentelemetry/api";
10581
- var ROOT_KINDS = /* @__PURE__ */ new Set(["workflow", "chain", "agent", "mcp_tool"]);
10582
- function autoRootEnabled() {
10583
- const val = (process.env.NEATLOGS_AUTO_ROOT ?? "").trim().toLowerCase();
10584
- return !["false", "0", "no", "off"].includes(val);
10585
- }
10586
- function resolveRootWorkflowName() {
10587
- const clientName = getActiveClient()?.workflowName;
10588
- if (typeof clientName === "string" && clientName.trim()) return clientName;
10589
- try {
10590
- const name = getSessionConfig()?.workflowName;
10591
- if (typeof name === "string" && name.trim()) return name;
10592
- } catch {
10593
- }
10594
- return "workflow";
10595
- }
10596
- function stampAutoRootIdentity(root) {
10597
- applySessionAttributes(root, void 0, true);
10598
- applyEndUserAttributes(root, void 0, void 0, true);
10599
- }
10600
- function wrapSpanWithRoot(child, root) {
10601
- let ended = false;
10602
- const proxy = new Proxy(child, {
10603
- get(target, prop, _receiver) {
10604
- if (prop === "end") {
10605
- return (...args) => {
10606
- if (ended) return;
10607
- ended = true;
10608
- try {
10609
- target.end(...args);
10610
- } finally {
10611
- try {
10612
- root.end();
10613
- } catch {
10614
- }
10615
- }
10616
- };
10617
- }
10618
- const value = Reflect.get(target, prop, target);
10619
- return typeof value === "function" ? value.bind(target) : value;
10620
- }
10621
- });
10622
- aliasMediaCaptureSpan(proxy, child);
10623
- return proxy;
10624
- }
10625
- function maybeOpenAutoRoot(tracer, kind, baseCtx) {
10626
- const k = String(kind ?? "").toLowerCase();
10627
- const existing = getActiveNeatlogsSpan();
10628
- if (!autoRootEnabled() || ROOT_KINDS.has(k) || existing !== void 0 && existing.isRecording()) {
10629
- return { root: void 0, ctx: baseCtx };
10630
- }
10631
- const root = tracer.startSpan(
10632
- resolveRootWorkflowName(),
10633
- { attributes: { "neatlogs.span.kind": "workflow", "neatlogs.auto_root": true } },
10634
- baseCtx
10635
- );
10636
- stampAutoRootIdentity(root);
10637
- return { root, ctx: otelTrace6.setSpan(baseCtx, root) };
10638
- }
10639
- function endAutoRoot(root) {
10640
- if (!root) return;
10641
- try {
10642
- root.end();
10643
- } catch {
10644
- }
10645
- }
10646
- var AutoRootTracer = class {
10647
- constructor(_tracer) {
10648
- this._tracer = _tracer;
10649
- }
10650
- _tracer;
10651
- startSpan(name, options, context2) {
10652
- const kind = String(
10653
- options?.attributes?.["neatlogs.span.kind"] ?? ""
10654
- ).toLowerCase();
10655
- const ctx = context2 ?? getNeatlogsParentContext();
10656
- const parent = getActiveNeatlogsSpan();
10657
- const needsRoot = autoRootEnabled() && !ROOT_KINDS.has(kind) && !(parent !== void 0 && parent.isRecording());
10658
- if (!needsRoot) {
10659
- return this._tracer.startSpan(name, options, ctx);
10660
- }
10661
- const root = this._tracer.startSpan(
10662
- resolveRootWorkflowName(),
10663
- { attributes: { "neatlogs.span.kind": "workflow", "neatlogs.auto_root": true } },
10664
- ctx
10665
- );
10666
- stampAutoRootIdentity(root);
10667
- const childCtx = otelTrace6.setSpan(ctx, root);
10668
- const child = this._tracer.startSpan(name, options, childCtx);
10669
- return wrapSpanWithRoot(child, root);
10670
- }
10671
- // startActiveSpan is used by traceTool (callback-scoped, always under an
10672
- // active span in practice) — pass straight through, no auto-root.
10673
- startActiveSpan = ((...args) => this._tracer.startActiveSpan(
10674
- ...args
10675
- ));
10676
- };
10677
- function getProviderTracer(name) {
10678
- return new AutoRootTracer(getNeatlogsTracer(name));
10679
- }
10680
-
10681
10999
  // src/core/choice-accumulator.ts
10682
11000
  import { SpanStatusCode as SpanStatusCode7 } from "@opentelemetry/api";
10683
11001
  import { createHash as createHash5 } from "crypto";
@@ -17834,6 +18152,7 @@ var neatlogs_telemetry_schema_default = {
17834
18152
  "VECTOR_STORE",
17835
18153
  "MEMORY",
17836
18154
  "GUARDRAIL",
18155
+ "EVALUATOR",
17837
18156
  "LOG",
17838
18157
  "HTTP",
17839
18158
  "UNKNOWN"
@@ -19262,6 +19581,7 @@ var neatlogs_telemetry_schema_default = {
19262
19581
  "AGENT",
19263
19582
  "CHAIN",
19264
19583
  "TASK",
19584
+ "EVALUATOR",
19265
19585
  "HTTP",
19266
19586
  "UNKNOWN"
19267
19587
  ]
@@ -19425,6 +19745,7 @@ var neatlogs_telemetry_schema_default = {
19425
19745
  "neatlogs.vector_store.*",
19426
19746
  "neatlogs.memory.*",
19427
19747
  "neatlogs.guardrail.*",
19748
+ "neatlogs.evaluator.*",
19428
19749
  "neatlogs.mcp.*",
19429
19750
  "neatlogs.code.*"
19430
19751
  ],
@@ -19503,7 +19824,7 @@ var neatlogs_telemetry_schema_default = {
19503
19824
  // src/schema-v2.ts
19504
19825
  var TELEMETRY_CONTRACT_VERSION = "2.0.0";
19505
19826
  var TELEMETRY_SCHEMA_VERSION = 2;
19506
- var TELEMETRY_SCHEMA_SHA256 = "50bbd9f1e6eaa6c83f08dcb84da3a98867c962fc8c4e1edd629da561fe5fe5a8";
19827
+ var TELEMETRY_SCHEMA_SHA256 = "ae79717d127e2faa761ad83c8a51a08cae6fce00a04446d46dcc6d1a371818ce";
19507
19828
  var TELEMETRY_SCHEMA_V2 = Object.freeze(neatlogs_telemetry_schema_default);
19508
19829
  var TELEMETRY_CONFLICT_PRECEDENCE = Object.freeze(
19509
19830
  [...neatlogs_telemetry_schema_default["x-neatlogs-policy"].conflict_precedence]