autotel 2.26.0 → 2.26.2
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/attribute-redacting-processor.cjs +14 -6
- package/dist/attribute-redacting-processor.d.cts +63 -1
- package/dist/attribute-redacting-processor.d.ts +63 -1
- package/dist/attribute-redacting-processor.js +1 -1
- package/dist/attributes.cjs +21 -21
- package/dist/attributes.js +2 -2
- package/dist/auto.cjs +8 -8
- package/dist/auto.js +6 -6
- package/dist/{chunk-RUD7KS4R.js → chunk-3SDILILG.js} +3 -3
- package/dist/{chunk-RUD7KS4R.js.map → chunk-3SDILILG.js.map} +1 -1
- package/dist/{chunk-B33XPEKY.js → chunk-55ER2KD5.js} +4 -4
- package/dist/chunk-55ER2KD5.js.map +1 -0
- package/dist/{chunk-UJJPTSEI.cjs → chunk-563EL6O6.cjs} +81 -14
- package/dist/chunk-563EL6O6.cjs.map +1 -0
- package/dist/{chunk-TS7IHIRW.cjs → chunk-6YGUN7IY.cjs} +5 -5
- package/dist/{chunk-TS7IHIRW.cjs.map → chunk-6YGUN7IY.cjs.map} +1 -1
- package/dist/{chunk-XDKK53OL.js → chunk-A4E5AQFK.js} +3 -3
- package/dist/{chunk-XDKK53OL.js.map → chunk-A4E5AQFK.js.map} +1 -1
- package/dist/{chunk-WAB4CHBU.js → chunk-BJ2XPN77.js} +3 -3
- package/dist/{chunk-WAB4CHBU.js.map → chunk-BJ2XPN77.js.map} +1 -1
- package/dist/{chunk-KZEC4CHV.cjs → chunk-CEAQK2QY.cjs} +5 -5
- package/dist/{chunk-KZEC4CHV.cjs.map → chunk-CEAQK2QY.cjs.map} +1 -1
- package/dist/chunk-CMNGGTQL.cjs +349 -0
- package/dist/chunk-CMNGGTQL.cjs.map +1 -0
- package/dist/{chunk-VYA6QDNA.js → chunk-DPSA4QLA.js} +4 -2
- package/dist/chunk-DPSA4QLA.js.map +1 -0
- package/dist/{chunk-M4US3P4K.js → chunk-ER43K7ES.js} +3 -3
- package/dist/{chunk-M4US3P4K.js.map → chunk-ER43K7ES.js.map} +1 -1
- package/dist/{chunk-AZ24DJAG.cjs → chunk-FU6R566Y.cjs} +4 -4
- package/dist/chunk-FU6R566Y.cjs.map +1 -0
- package/dist/{chunk-4PTCDOZY.js → chunk-HPUGKUMZ.js} +4 -4
- package/dist/{chunk-4PTCDOZY.js.map → chunk-HPUGKUMZ.js.map} +1 -1
- package/dist/{chunk-XRBP4RYL.cjs → chunk-JKIMEPI2.cjs} +4 -4
- package/dist/{chunk-XRBP4RYL.cjs.map → chunk-JKIMEPI2.cjs.map} +1 -1
- package/dist/{chunk-N344PVE5.cjs → chunk-OBWXM4NN.cjs} +9 -9
- package/dist/{chunk-N344PVE5.cjs.map → chunk-OBWXM4NN.cjs.map} +1 -1
- package/dist/{chunk-OFPZULMQ.cjs → chunk-OC6X2VIN.cjs} +8 -8
- package/dist/{chunk-OFPZULMQ.cjs.map → chunk-OC6X2VIN.cjs.map} +1 -1
- package/dist/{chunk-GTD3NXOS.js → chunk-QC5MNKVF.js} +4 -4
- package/dist/{chunk-GTD3NXOS.js.map → chunk-QC5MNKVF.js.map} +1 -1
- package/dist/chunk-TDNKIHKT.js +341 -0
- package/dist/chunk-TDNKIHKT.js.map +1 -0
- package/dist/{chunk-DGPUZ6TE.js → chunk-U54FTVFH.js} +3 -3
- package/dist/{chunk-DGPUZ6TE.js.map → chunk-U54FTVFH.js.map} +1 -1
- package/dist/{chunk-ZJ5GXCOT.cjs → chunk-UTZR7P7E.cjs} +36 -36
- package/dist/{chunk-ZJ5GXCOT.cjs.map → chunk-UTZR7P7E.cjs.map} +1 -1
- package/dist/{chunk-7FIGORWI.cjs → chunk-VH77IPJN.cjs} +4 -2
- package/dist/chunk-VH77IPJN.cjs.map +1 -0
- package/dist/{chunk-EXOXDI5A.js → chunk-W35FVJBC.js} +73 -8
- package/dist/chunk-W35FVJBC.js.map +1 -0
- package/dist/{chunk-II7GFVAF.cjs → chunk-WZOKY3PW.cjs} +13 -13
- package/dist/{chunk-II7GFVAF.cjs.map → chunk-WZOKY3PW.cjs.map} +1 -1
- package/dist/{chunk-CMADDTHY.cjs → chunk-YEVCD6DR.cjs} +7 -7
- package/dist/{chunk-CMADDTHY.cjs.map → chunk-YEVCD6DR.cjs.map} +1 -1
- package/dist/{chunk-RXFZKLRQ.js → chunk-YN7USLHW.js} +3 -3
- package/dist/{chunk-RXFZKLRQ.js.map → chunk-YN7USLHW.js.map} +1 -1
- package/dist/decorators.cjs +7 -7
- package/dist/decorators.js +7 -7
- package/dist/event.cjs +10 -10
- package/dist/event.js +7 -7
- package/dist/functional.cjs +14 -14
- package/dist/functional.js +7 -7
- package/dist/index.cjs +340 -97
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +205 -3
- package/dist/index.d.ts +205 -3
- package/dist/index.js +257 -33
- package/dist/index.js.map +1 -1
- package/dist/{init-QSj7X6zU.d.cts → init-CMuTaFAV.d.cts} +26 -1
- package/dist/{init-FiR_glVc.d.ts → init-D6JfWEjL.d.ts} +26 -1
- package/dist/instrumentation.cjs +14 -14
- package/dist/instrumentation.js +6 -6
- package/dist/logger.cjs +8 -8
- package/dist/logger.js +1 -1
- package/dist/messaging.cjs +11 -11
- package/dist/messaging.js +8 -8
- package/dist/metric.cjs +1 -1
- package/dist/metric.js +1 -1
- package/dist/sampling.cjs +15 -15
- package/dist/sampling.js +2 -2
- package/dist/semantic-helpers.cjs +12 -12
- package/dist/semantic-helpers.js +8 -8
- package/dist/tail-sampling-processor.cjs +4 -4
- package/dist/tail-sampling-processor.js +3 -3
- package/dist/testing.cjs +1 -1
- package/dist/testing.js +1 -1
- package/dist/webhook.cjs +9 -8
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.js +8 -7
- package/dist/webhook.js.map +1 -1
- package/dist/workflow-distributed.cjs +9 -9
- package/dist/workflow-distributed.js +7 -7
- package/dist/workflow.cjs +12 -12
- package/dist/workflow.js +8 -8
- package/dist/yaml-config.cjs +6 -6
- package/dist/yaml-config.d.cts +1 -1
- package/dist/yaml-config.d.ts +1 -1
- package/dist/yaml-config.js +3 -3
- package/package.json +1 -1
- package/src/attribute-redacting-processor.test.ts +81 -16
- package/src/attribute-redacting-processor.ts +278 -24
- package/src/autotel-logger.ts +2 -2
- package/src/gen-ai-events.test.ts +135 -0
- package/src/gen-ai-events.ts +199 -0
- package/src/gen-ai-metrics.test.ts +96 -0
- package/src/gen-ai-metrics.ts +128 -0
- package/src/index.ts +28 -1
- package/src/init.ts +117 -2
- package/src/request-logger.test.ts +266 -1
- package/src/request-logger.ts +115 -16
- package/src/structured-error.ts +54 -1
- package/dist/chunk-7FIGORWI.cjs.map +0 -1
- package/dist/chunk-AZ24DJAG.cjs.map +0 -1
- package/dist/chunk-B33XPEKY.js.map +0 -1
- package/dist/chunk-ELW34S4C.cjs +0 -173
- package/dist/chunk-ELW34S4C.cjs.map +0 -1
- package/dist/chunk-EXOXDI5A.js.map +0 -1
- package/dist/chunk-SNINLBEE.js +0 -167
- package/dist/chunk-SNINLBEE.js.map +0 -1
- package/dist/chunk-UJJPTSEI.cjs.map +0 -1
- package/dist/chunk-VYA6QDNA.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AutotelConfig, i as init } from './init-
|
|
1
|
+
export { A as AutotelConfig, i as init, a as isLoggerLocked, l as lockLogger } from './init-D6JfWEjL.js';
|
|
2
2
|
import { Span, Context } from '@opentelemetry/api';
|
|
3
3
|
export { Context, ROOT_CONTEXT, Span, SpanContext, SpanKind, Link as SpanLink, SpanStatusCode, TextMapGetter, TextMapSetter, Tracer, context, trace as otelTrace, propagation } from '@opentelemetry/api';
|
|
4
4
|
import { SpanProcessor, ReadableSpan } from '@opentelemetry/sdk-trace-base';
|
|
@@ -18,6 +18,7 @@ export { AUTOTEL_SAMPLING_TAIL_EVALUATED, AUTOTEL_SAMPLING_TAIL_KEEP, AdaptiveSa
|
|
|
18
18
|
export { Event, EventsOptions, getEvents, resetEvents } from './event.js';
|
|
19
19
|
export { Metric, MetricsOptions, getMetrics, resetMetrics } from './metric.js';
|
|
20
20
|
export { createCounter, createHistogram, createObservableGauge, createUpDownCounter, getMeter } from './metric-helpers.js';
|
|
21
|
+
import { ViewOptions } from '@opentelemetry/sdk-metrics';
|
|
21
22
|
export { TraceContext as OtelTraceContext, createDeterministicTraceId, enrichWithTraceContext, finalizeSpan, flattenMetadata, getActiveContext, getActiveSpan, getTraceContext, getTracer, isTracing, resolveTraceUrl, runWithSpan } from './trace-helpers.js';
|
|
22
23
|
export { getAutotelTracer, getAutotelTracerProvider, setAutotelTracerProvider } from './tracer-provider.js';
|
|
23
24
|
export { DBConfig, HTTPConfig, LLMConfig, MessagingConfig, traceDB, traceHTTP, traceLLM, traceMessaging } from './semantic-helpers.js';
|
|
@@ -30,7 +31,6 @@ import '@opentelemetry/sdk-node';
|
|
|
30
31
|
import '@opentelemetry/resources';
|
|
31
32
|
import './logger.js';
|
|
32
33
|
import 'pino';
|
|
33
|
-
import '@opentelemetry/sdk-metrics';
|
|
34
34
|
import '@opentelemetry/sdk-logs';
|
|
35
35
|
import './processors.js';
|
|
36
36
|
import 'node:async_hooks';
|
|
@@ -428,6 +428,7 @@ interface RequestLogger {
|
|
|
428
428
|
error(error: Error | string, fields?: Record<string, unknown>): void;
|
|
429
429
|
getContext(): Record<string, unknown>;
|
|
430
430
|
emitNow(overrides?: Record<string, unknown>): RequestLogSnapshot;
|
|
431
|
+
fork(label: string, fn: () => void | Promise<void>): void;
|
|
431
432
|
}
|
|
432
433
|
interface RequestLogSnapshot {
|
|
433
434
|
timestamp: string;
|
|
@@ -452,6 +453,8 @@ interface StructuredErrorInput {
|
|
|
452
453
|
cause?: unknown;
|
|
453
454
|
details?: Record<string, unknown>;
|
|
454
455
|
name?: string;
|
|
456
|
+
/** Backend-only context. Omitted from toJSON() and never serialized to clients. */
|
|
457
|
+
internal?: Record<string, unknown>;
|
|
455
458
|
}
|
|
456
459
|
interface StructuredError extends Error {
|
|
457
460
|
why?: string;
|
|
@@ -460,8 +463,11 @@ interface StructuredError extends Error {
|
|
|
460
463
|
code?: string | number;
|
|
461
464
|
status?: number;
|
|
462
465
|
details?: Record<string, unknown>;
|
|
466
|
+
/** Backend-only context. Omitted from toJSON() and never serialized to clients. */
|
|
467
|
+
readonly internal?: Record<string, unknown>;
|
|
463
468
|
}
|
|
464
469
|
declare function createStructuredError(input: StructuredErrorInput): StructuredError;
|
|
470
|
+
declare function structuredErrorToJSON(error: StructuredError): Record<string, unknown>;
|
|
465
471
|
declare function getStructuredErrorAttributes(error: Error): Record<string, AttributeValue>;
|
|
466
472
|
declare function recordStructuredError(ctx: Pick<TraceContext, 'recordException' | 'setAttributes' | 'setStatus'>, error: Error): void;
|
|
467
473
|
|
|
@@ -486,4 +492,200 @@ declare function flattenToAttributes(fields: Record<string, unknown>, prefix?: s
|
|
|
486
492
|
*/
|
|
487
493
|
declare function formatDuration(ms: number): string;
|
|
488
494
|
|
|
489
|
-
|
|
495
|
+
/**
|
|
496
|
+
* LLM-tuned histogram buckets.
|
|
497
|
+
*
|
|
498
|
+
* Default OpenTelemetry histogram buckets target HTTP latency (0ms–10s)
|
|
499
|
+
* and small counter values. LLM workloads have very different shapes:
|
|
500
|
+
*
|
|
501
|
+
* - **Duration**: single-token prompts can be fast (50ms), long
|
|
502
|
+
* generations and reasoning models can run for minutes. Default buckets
|
|
503
|
+
* crush everything above 10s into one bucket.
|
|
504
|
+
* - **Token usage**: heavily right-skewed. A single request can range
|
|
505
|
+
* from tens of tokens to the million-token context windows.
|
|
506
|
+
* - **Cost (USD)**: per-request values are tiny (fractions of a cent),
|
|
507
|
+
* so linear buckets waste resolution at the low end.
|
|
508
|
+
*
|
|
509
|
+
* This module exposes empirically-chosen bucket arrays and a View helper
|
|
510
|
+
* so users can apply them to their `MeterProvider` without knowing the
|
|
511
|
+
* exact instrument names emitted by OpenAI/Anthropic/Traceloop plugins.
|
|
512
|
+
*
|
|
513
|
+
* @example
|
|
514
|
+
* ```typescript
|
|
515
|
+
* import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
516
|
+
* import { genAiMetricViews } from 'autotel';
|
|
517
|
+
*
|
|
518
|
+
* const sdk = new NodeSDK({
|
|
519
|
+
* serviceName: 'my-agent',
|
|
520
|
+
* views: [...genAiMetricViews()],
|
|
521
|
+
* });
|
|
522
|
+
* sdk.start();
|
|
523
|
+
* ```
|
|
524
|
+
*/
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Duration buckets for LLM operations, in **seconds**. Covers fast
|
|
528
|
+
* completions (50ms) through long-running reasoning jobs (5 min).
|
|
529
|
+
*
|
|
530
|
+
* Aligns with the OTel GenAI semantic conventions' published advice for
|
|
531
|
+
* `gen_ai.client.operation.duration`.
|
|
532
|
+
*/
|
|
533
|
+
declare const GEN_AI_DURATION_BUCKETS_SECONDS: readonly number[];
|
|
534
|
+
/**
|
|
535
|
+
* Token-count buckets for prompt, completion, and total token histograms.
|
|
536
|
+
* Ranges from tiny prompts to million-token context windows.
|
|
537
|
+
*
|
|
538
|
+
* Aligns with the OTel GenAI semantic conventions' published advice for
|
|
539
|
+
* `gen_ai.client.token.usage`.
|
|
540
|
+
*/
|
|
541
|
+
declare const GEN_AI_TOKEN_USAGE_BUCKETS: readonly number[];
|
|
542
|
+
/**
|
|
543
|
+
* USD cost buckets. Sub-cent resolution at the low end (fractions of a
|
|
544
|
+
* cent per small call) up to tens of dollars (batch jobs, Opus/o1 runs).
|
|
545
|
+
*/
|
|
546
|
+
declare const GEN_AI_COST_USD_BUCKETS: readonly number[];
|
|
547
|
+
/**
|
|
548
|
+
* Instrument-level advice object for `createHistogram(name, advice)`.
|
|
549
|
+
* Use when you control the instrument creation (e.g. custom business
|
|
550
|
+
* LLM metrics); `genAiMetricViews()` is better when the metric comes
|
|
551
|
+
* from a third-party plugin.
|
|
552
|
+
*/
|
|
553
|
+
declare function llmHistogramAdvice(kind: 'duration' | 'tokens' | 'cost'): {
|
|
554
|
+
advice: {
|
|
555
|
+
explicitBucketBoundaries: number[];
|
|
556
|
+
};
|
|
557
|
+
};
|
|
558
|
+
/**
|
|
559
|
+
* Returns `View`s that re-bucket the standard OTel GenAI histograms. Pass
|
|
560
|
+
* the result to your `MeterProvider`'s `views` option.
|
|
561
|
+
*
|
|
562
|
+
* Matches instrument names emitted by:
|
|
563
|
+
* - OpenTelemetry GenAI autoinstrumentation
|
|
564
|
+
* - OpenInference / OpenLLMetry (traceloop)
|
|
565
|
+
* - Arize Phoenix, LangSmith, etc. that follow the OTel spec
|
|
566
|
+
*
|
|
567
|
+
* Add more instrument patterns via the `extra` argument if you emit
|
|
568
|
+
* custom LLM metrics.
|
|
569
|
+
*/
|
|
570
|
+
declare function genAiMetricViews(extra?: {
|
|
571
|
+
instrumentName: string;
|
|
572
|
+
kind: 'duration' | 'tokens' | 'cost';
|
|
573
|
+
}[]): ViewOptions[];
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Span event helpers for LLM lifecycle, aligned with the OpenTelemetry
|
|
577
|
+
* GenAI semantic conventions.
|
|
578
|
+
*
|
|
579
|
+
* Span events are timestamped points within a span — they render as dots
|
|
580
|
+
* on the trace timeline in Jaeger / Tempo / Langfuse / Arize. Use them
|
|
581
|
+
* to mark lifecycle moments the span attributes alone can't express:
|
|
582
|
+
*
|
|
583
|
+
* - When the prompt was sent (vs. when the first token arrived)
|
|
584
|
+
* - When each retry attempt started, and why
|
|
585
|
+
* - When a streaming response produced its first token (TTFT)
|
|
586
|
+
* - When a tool was invoked
|
|
587
|
+
*
|
|
588
|
+
* Every helper pins the event name + attribute keys to the published
|
|
589
|
+
* spec so downstream tooling (autotel-mcp, Langfuse, vendor UIs) can
|
|
590
|
+
* render them consistently.
|
|
591
|
+
*
|
|
592
|
+
* @example
|
|
593
|
+
* ```typescript
|
|
594
|
+
* import { trace, recordPromptSent, recordResponseReceived, recordRetry } from 'autotel';
|
|
595
|
+
*
|
|
596
|
+
* export const chat = trace('chat', ctx => async (prompt: string) => {
|
|
597
|
+
* recordPromptSent(ctx, { model: 'gpt-4o', messageCount: 1 });
|
|
598
|
+
*
|
|
599
|
+
* for (let attempt = 1; attempt <= 3; attempt++) {
|
|
600
|
+
* try {
|
|
601
|
+
* const res = await openai.chat.completions.create({...});
|
|
602
|
+
* recordResponseReceived(ctx, {
|
|
603
|
+
* model: res.model,
|
|
604
|
+
* promptTokens: res.usage?.prompt_tokens,
|
|
605
|
+
* completionTokens: res.usage?.completion_tokens,
|
|
606
|
+
* finishReasons: res.choices.map(c => c.finish_reason),
|
|
607
|
+
* });
|
|
608
|
+
* return res;
|
|
609
|
+
* } catch (err) {
|
|
610
|
+
* recordRetry(ctx, { attempt, reason: 'rate_limit', delayMs: 500 });
|
|
611
|
+
* await sleep(500 * attempt);
|
|
612
|
+
* }
|
|
613
|
+
* }
|
|
614
|
+
* });
|
|
615
|
+
* ```
|
|
616
|
+
*/
|
|
617
|
+
|
|
618
|
+
/** Attributes expected on a `gen_ai.prompt.sent` event. */
|
|
619
|
+
interface PromptSentEvent {
|
|
620
|
+
/** Model the caller intends to invoke (may differ from response model). */
|
|
621
|
+
model?: string;
|
|
622
|
+
/** Estimated input token count, when known before the call. */
|
|
623
|
+
promptTokens?: number;
|
|
624
|
+
/** Number of messages in a chat request (system + user + assistant). */
|
|
625
|
+
messageCount?: number;
|
|
626
|
+
/** Free-form operation kind — `chat` / `completion` / `embedding`. */
|
|
627
|
+
operation?: string;
|
|
628
|
+
}
|
|
629
|
+
/** Attributes expected on a `gen_ai.response.received` event. */
|
|
630
|
+
interface ResponseReceivedEvent {
|
|
631
|
+
/** Model the provider actually served (may be more specific than requested). */
|
|
632
|
+
model?: string;
|
|
633
|
+
promptTokens?: number;
|
|
634
|
+
completionTokens?: number;
|
|
635
|
+
totalTokens?: number;
|
|
636
|
+
/** `stop`, `length`, `content_filter`, `tool_calls`, etc. */
|
|
637
|
+
finishReasons?: string[];
|
|
638
|
+
}
|
|
639
|
+
/** Attributes expected on a `gen_ai.retry` event. */
|
|
640
|
+
interface RetryEvent {
|
|
641
|
+
attempt: number;
|
|
642
|
+
/** `rate_limit` | `timeout` | `provider_error` | custom label. */
|
|
643
|
+
reason?: string;
|
|
644
|
+
/** How long we'll wait before the next attempt. */
|
|
645
|
+
delayMs?: number;
|
|
646
|
+
/** HTTP status that triggered the retry, when applicable. */
|
|
647
|
+
statusCode?: number;
|
|
648
|
+
}
|
|
649
|
+
/** Attributes expected on a `gen_ai.tool.call` event. */
|
|
650
|
+
interface ToolCallEvent {
|
|
651
|
+
toolName: string;
|
|
652
|
+
/** Call identifier so responses can be correlated back to calls. */
|
|
653
|
+
toolCallId?: string;
|
|
654
|
+
/** Pre-serialised tool arguments; omit if sensitive. */
|
|
655
|
+
arguments?: string;
|
|
656
|
+
}
|
|
657
|
+
/** Attributes expected on a `gen_ai.stream.first_token` event. */
|
|
658
|
+
interface StreamFirstTokenEvent {
|
|
659
|
+
/** Tokens streamed so far, if the caller tracks that. */
|
|
660
|
+
tokensSoFar?: number;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Record that a prompt was dispatched to the provider. Typically called
|
|
664
|
+
* before `await provider.chat.completions.create(...)`.
|
|
665
|
+
*/
|
|
666
|
+
declare function recordPromptSent(ctx: TraceContext, event?: PromptSentEvent): void;
|
|
667
|
+
/**
|
|
668
|
+
* Record a successful provider response. Call after the response arrives
|
|
669
|
+
* (for non-streaming) or after the stream completes.
|
|
670
|
+
*/
|
|
671
|
+
declare function recordResponseReceived(ctx: TraceContext, event?: ResponseReceivedEvent): void;
|
|
672
|
+
/**
|
|
673
|
+
* Record a retry attempt on an LLM call. Call *before* sleeping for
|
|
674
|
+
* `delayMs` so the event timestamp accurately marks when the retry
|
|
675
|
+
* decision was made.
|
|
676
|
+
*/
|
|
677
|
+
declare function recordRetry(ctx: TraceContext, event: RetryEvent): void;
|
|
678
|
+
/**
|
|
679
|
+
* Record a tool / function call made in the course of an agent step.
|
|
680
|
+
* Emits an event rather than a child span because many frameworks fire
|
|
681
|
+
* several tool calls within a single provider response.
|
|
682
|
+
*/
|
|
683
|
+
declare function recordToolCall(ctx: TraceContext, event: ToolCallEvent): void;
|
|
684
|
+
/**
|
|
685
|
+
* Record the time-to-first-token for a streaming response. Pair with
|
|
686
|
+
* `recordResponseReceived` at the end so the span carries both the TTFT
|
|
687
|
+
* marker and the final usage numbers.
|
|
688
|
+
*/
|
|
689
|
+
declare function recordStreamFirstToken(ctx: TraceContext, event?: StreamFirstTokenEvent): void;
|
|
690
|
+
|
|
691
|
+
export { AttributeRedactorConfig, AttributeRedactorPreset, BaggageSpanProcessor, type BaggageSpanProcessorOptions, EventAttributes, EventSubscriber, GEN_AI_COST_USD_BUCKETS, GEN_AI_DURATION_BUCKETS_SECONDS, GEN_AI_TOKEN_USAGE_BUCKETS, type OperationContext, type PromptSentEvent, type RequestLogSnapshot, type RequestLogger, type RequestLoggerOptions, type ResponseReceivedEvent, type RetryEvent, type StreamFirstTokenEvent, type StringRedactor, type StructuredError, type StructuredErrorInput, type ToolCallEvent, TraceContext, createStringRedactor, createStructuredError, flattenToAttributes, flush, formatDuration, genAiMetricViews, getEventQueue, getOperationContext, getRequestLogger, getStructuredErrorAttributes, llmHistogramAdvice, recordPromptSent, recordResponseReceived, recordRetry, recordStreamFirstToken, recordStructuredError, recordToolCall, runInOperationContext, runWithRequestContext, shutdown, structuredErrorToJSON, toAttributeValue, track };
|
package/dist/index.js
CHANGED
|
@@ -1,45 +1,46 @@
|
|
|
1
1
|
export { createDrainPipeline } from './chunk-KFOHQK7X.js';
|
|
2
|
-
export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-
|
|
3
|
-
export { attrs, autoRedactPII, dbClient, httpClient, httpServer, identify, mergeAttrs, mergeServiceResource, request, safeSetAttributes, setDevice, setError, setException, setSession, setUser, validateAttribute } from './chunk-
|
|
2
|
+
export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-YN7USLHW.js';
|
|
3
|
+
export { attrs, autoRedactPII, dbClient, httpClient, httpServer, identify, mergeAttrs, mergeServiceResource, request, safeSetAttributes, setDevice, setError, setException, setSession, setUser, validateAttribute } from './chunk-ER43K7ES.js';
|
|
4
4
|
export { httpRequestHeaderAttribute, httpResponseHeaderAttribute } from './chunk-7552UTQW.js';
|
|
5
5
|
export { HTTPAttributes, ServiceAttributes, URLAttributes } from './chunk-4A53YIAX.js';
|
|
6
6
|
export { parseError } from './chunk-J7VGRIAJ.js';
|
|
7
|
-
export { traceConsumer, traceProducer } from './chunk-
|
|
7
|
+
export { traceConsumer, traceProducer } from './chunk-QC5MNKVF.js';
|
|
8
8
|
export { BusinessBaggage, createSafeBaggageSchema } from './chunk-4IFSYQVX.js';
|
|
9
9
|
import { resetMetrics } from './chunk-7SAWIN74.js';
|
|
10
10
|
export { Metric, getMetrics, resetMetrics } from './chunk-7SAWIN74.js';
|
|
11
11
|
import './chunk-5ZN622AO.js';
|
|
12
12
|
export { createCounter, createHistogram, createObservableGauge, createUpDownCounter, getMeter } from './chunk-TQ5UWA7S.js';
|
|
13
|
-
export { traceDB, traceHTTP, traceLLM, traceMessaging } from './chunk-
|
|
14
|
-
import { getEventQueue, resetEventQueue } from './chunk-
|
|
15
|
-
export { ctx, getEventQueue, instrument, span, trace, track, withBaggage, withNewContext, withTracing } from './chunk-
|
|
13
|
+
export { traceDB, traceHTTP, traceLLM, traceMessaging } from './chunk-U54FTVFH.js';
|
|
14
|
+
import { getEventQueue, resetEventQueue } from './chunk-HPUGKUMZ.js';
|
|
15
|
+
export { ctx, getEventQueue, instrument, span, trace, track, withBaggage, withNewContext, withTracing } from './chunk-HPUGKUMZ.js';
|
|
16
16
|
export { createDeterministicTraceId, enrichWithTraceContext, finalizeSpan, flattenMetadata, getActiveContext, getActiveSpan, getTraceContext, getTracer, isTracing, resolveTraceUrl, runWithSpan } from './chunk-B3ZHLLMP.js';
|
|
17
|
-
import { resetEvents } from './chunk-
|
|
18
|
-
export { Event, getEvents, resetEvents } from './chunk-
|
|
17
|
+
import { resetEvents } from './chunk-BJ2XPN77.js';
|
|
18
|
+
export { Event, getEvents, resetEvents } from './chunk-BJ2XPN77.js';
|
|
19
19
|
import './chunk-LITNXTTT.js';
|
|
20
20
|
import './chunk-BZHG5IZ4.js';
|
|
21
21
|
export { getOperationContext, runInOperationContext } from './chunk-WD4RP6IV.js';
|
|
22
22
|
export { CORRELATION_ID_BAGGAGE_KEY, generateCorrelationId, getCorrelationId, getOrCreateCorrelationId, runWithCorrelationId, setCorrelationId, setCorrelationIdInBaggage } from './chunk-S4OFEXLA.js';
|
|
23
23
|
import { createTraceContext } from './chunk-BBBWDIYQ.js';
|
|
24
24
|
export { defineBaggageSchema } from './chunk-BBBWDIYQ.js';
|
|
25
|
-
import { getLogger, getSdk, _closeEmbeddedDevtools } from './chunk-
|
|
26
|
-
export { BaggageSpanProcessor, createStringRedactor, init } from './chunk-
|
|
27
|
-
import './chunk-
|
|
28
|
-
import './chunk-
|
|
25
|
+
import { getLogger, getSdk, _closeEmbeddedDevtools } from './chunk-W35FVJBC.js';
|
|
26
|
+
export { BaggageSpanProcessor, createStringRedactor, init, isLoggerLocked, lockLogger } from './chunk-W35FVJBC.js';
|
|
27
|
+
import './chunk-3SDILILG.js';
|
|
28
|
+
import './chunk-A4E5AQFK.js';
|
|
29
29
|
export { FilteringSpanProcessor } from './chunk-WGWSHJ2N.js';
|
|
30
30
|
export { NORMALIZER_PATTERNS, NORMALIZER_PRESETS, SpanNameNormalizingProcessor } from './chunk-GYR5K654.js';
|
|
31
|
-
export { AttributeRedactingProcessor, REDACTOR_PATTERNS, REDACTOR_PRESETS, createAttributeRedactor, createRedactedSpan } from './chunk-
|
|
31
|
+
export { AttributeRedactingProcessor, REDACTOR_PATTERNS, REDACTOR_PRESETS, createAttributeRedactor, createRedactedSpan } from './chunk-TDNKIHKT.js';
|
|
32
32
|
import './chunk-6UQRVUN3.js';
|
|
33
33
|
export { formatDuration } from './chunk-3QXBFGKP.js';
|
|
34
34
|
import './chunk-33WTKH7X.js';
|
|
35
|
-
export { AUTOTEL_SAMPLING_TAIL_EVALUATED, AUTOTEL_SAMPLING_TAIL_KEEP, AdaptiveSampler, AlwaysSampler, NeverSampler, RandomSampler, UserIdSampler, createLinkFromHeaders, extractLinksFromBatch, resolveSamplingPreset, samplingPresets } from './chunk-
|
|
36
|
-
import './chunk-
|
|
35
|
+
export { AUTOTEL_SAMPLING_TAIL_EVALUATED, AUTOTEL_SAMPLING_TAIL_KEEP, AdaptiveSampler, AlwaysSampler, NeverSampler, RandomSampler, UserIdSampler, createLinkFromHeaders, extractLinksFromBatch, resolveSamplingPreset, samplingPresets } from './chunk-DPSA4QLA.js';
|
|
36
|
+
import './chunk-55ER2KD5.js';
|
|
37
37
|
import './chunk-J5QENANM.js';
|
|
38
38
|
export { getAutotelTracer, getAutotelTracerProvider, setAutotelTracerProvider } from './chunk-HA2WBOGQ.js';
|
|
39
39
|
import './chunk-DGUM43GV.js';
|
|
40
40
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
41
41
|
import { SpanStatusCode, trace } from '@opentelemetry/api';
|
|
42
42
|
export { ROOT_CONTEXT, SpanKind, SpanStatusCode, context, trace as otelTrace, propagation } from '@opentelemetry/api';
|
|
43
|
+
import { AggregationType } from '@opentelemetry/sdk-metrics';
|
|
43
44
|
|
|
44
45
|
// src/shutdown.ts
|
|
45
46
|
async function flush(options) {
|
|
@@ -228,6 +229,7 @@ function flattenToAttributes(fields, prefix = "") {
|
|
|
228
229
|
}
|
|
229
230
|
|
|
230
231
|
// src/structured-error.ts
|
|
232
|
+
var internalKey = /* @__PURE__ */ Symbol.for("autotel.error.internal");
|
|
231
233
|
function createStructuredError(input) {
|
|
232
234
|
const error = new Error(input.message, {
|
|
233
235
|
cause: input.cause
|
|
@@ -239,6 +241,21 @@ function createStructuredError(input) {
|
|
|
239
241
|
if (input.code !== void 0) error.code = input.code;
|
|
240
242
|
if (input.status !== void 0) error.status = input.status;
|
|
241
243
|
if (input.details !== void 0) error.details = input.details;
|
|
244
|
+
if (input.internal !== void 0) {
|
|
245
|
+
Object.defineProperty(error, internalKey, {
|
|
246
|
+
value: input.internal,
|
|
247
|
+
enumerable: false,
|
|
248
|
+
writable: false,
|
|
249
|
+
configurable: true
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
Object.defineProperty(error, "internal", {
|
|
253
|
+
get() {
|
|
254
|
+
return this[internalKey];
|
|
255
|
+
},
|
|
256
|
+
enumerable: false,
|
|
257
|
+
configurable: true
|
|
258
|
+
});
|
|
242
259
|
error.toString = () => {
|
|
243
260
|
const lines = [`${error.name}: ${error.message}`];
|
|
244
261
|
if (error.why) lines.push(` Why: ${error.why}`);
|
|
@@ -246,11 +263,34 @@ function createStructuredError(input) {
|
|
|
246
263
|
if (error.link) lines.push(` Link: ${error.link}`);
|
|
247
264
|
if (error.code !== void 0) lines.push(` Code: ${error.code}`);
|
|
248
265
|
if (error.status !== void 0) lines.push(` Status: ${error.status}`);
|
|
249
|
-
if (error.cause)
|
|
266
|
+
if (error.cause) {
|
|
267
|
+
const cause = error.cause;
|
|
268
|
+
lines.push(` Caused by: ${cause.name}: ${cause.message}`);
|
|
269
|
+
}
|
|
250
270
|
return lines.join("\n");
|
|
251
271
|
};
|
|
252
272
|
return error;
|
|
253
273
|
}
|
|
274
|
+
function structuredErrorToJSON(error) {
|
|
275
|
+
const result = {
|
|
276
|
+
name: error.name,
|
|
277
|
+
message: error.message
|
|
278
|
+
};
|
|
279
|
+
if (error.status !== void 0) result.status = error.status;
|
|
280
|
+
if (error.why || error.fix || error.link) {
|
|
281
|
+
result.data = {
|
|
282
|
+
...error.why && { why: error.why },
|
|
283
|
+
...error.fix && { fix: error.fix },
|
|
284
|
+
...error.link && { link: error.link }
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
if (error.code !== void 0) result.code = error.code;
|
|
288
|
+
if (error.details) result.details = error.details;
|
|
289
|
+
if (error.cause instanceof Error) {
|
|
290
|
+
result.cause = { name: error.cause.name, message: error.cause.message };
|
|
291
|
+
}
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
254
294
|
function getStructuredErrorAttributes(error) {
|
|
255
295
|
const structured = error;
|
|
256
296
|
const attributes = {
|
|
@@ -285,6 +325,29 @@ function recordStructuredError(ctx2, error) {
|
|
|
285
325
|
}
|
|
286
326
|
|
|
287
327
|
// src/request-logger.ts
|
|
328
|
+
var POST_EMIT_FORK_HINT = "For intentional background work tied to this request, use log.fork('label', fn) when available.";
|
|
329
|
+
function warnPostEmit(method, detail) {
|
|
330
|
+
console.warn(
|
|
331
|
+
`[autotel] ${method} called after the wide event was emitted \u2014 ${detail} This data will not appear in observability. ${POST_EMIT_FORK_HINT}`
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
function mergeInto(target, source) {
|
|
335
|
+
for (const key in source) {
|
|
336
|
+
const sourceVal = source[key];
|
|
337
|
+
if (sourceVal === void 0) continue;
|
|
338
|
+
const targetVal = target[key];
|
|
339
|
+
if (sourceVal !== null && typeof sourceVal === "object" && !Array.isArray(sourceVal) && targetVal !== null && typeof targetVal === "object" && !Array.isArray(targetVal)) {
|
|
340
|
+
mergeInto(
|
|
341
|
+
targetVal,
|
|
342
|
+
sourceVal
|
|
343
|
+
);
|
|
344
|
+
} else if (Array.isArray(targetVal) && Array.isArray(sourceVal)) {
|
|
345
|
+
target[key] = [...targetVal, ...sourceVal];
|
|
346
|
+
} else {
|
|
347
|
+
target[key] = sourceVal;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
288
351
|
var requestContextStore = new AsyncLocalStorage();
|
|
289
352
|
function runWithRequestContext(ctx2, fn) {
|
|
290
353
|
return requestContextStore.run(ctx2, fn);
|
|
@@ -304,6 +367,8 @@ function resolveContext(ctx2) {
|
|
|
304
367
|
function getRequestLogger(ctx2, options) {
|
|
305
368
|
const activeContext = resolveContext(ctx2);
|
|
306
369
|
let contextState = {};
|
|
370
|
+
let emitted = false;
|
|
371
|
+
let lastSnapshot = null;
|
|
307
372
|
const addLogEvent = (level, message, fields) => {
|
|
308
373
|
const attrs2 = fields ? flattenToAttributes(fields) : void 0;
|
|
309
374
|
activeContext.addEvent(`log.${level}`, {
|
|
@@ -311,44 +376,51 @@ function getRequestLogger(ctx2, options) {
|
|
|
311
376
|
...attrs2
|
|
312
377
|
});
|
|
313
378
|
};
|
|
379
|
+
const sealCheck = (method, keys) => {
|
|
380
|
+
if (emitted) {
|
|
381
|
+
warnPostEmit(
|
|
382
|
+
method,
|
|
383
|
+
`Keys dropped: ${keys.length ? keys.join(", ") : "(empty)"}.`
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
};
|
|
314
387
|
return {
|
|
315
388
|
set(fields) {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
};
|
|
389
|
+
sealCheck("log.set()", Object.keys(fields));
|
|
390
|
+
if (emitted) return;
|
|
391
|
+
mergeInto(contextState, fields);
|
|
320
392
|
activeContext.setAttributes(flattenToAttributes(fields));
|
|
321
393
|
},
|
|
322
394
|
info(message, fields) {
|
|
395
|
+
const keys = fields ? ["message", ...Object.keys(fields).filter((k) => k !== "requestLogs")] : ["message"];
|
|
396
|
+
sealCheck("log.info()", keys);
|
|
397
|
+
if (emitted) return;
|
|
323
398
|
addLogEvent("info", message, fields);
|
|
324
399
|
if (fields) {
|
|
325
|
-
contextState
|
|
326
|
-
...contextState,
|
|
327
|
-
...fields
|
|
328
|
-
};
|
|
400
|
+
mergeInto(contextState, fields);
|
|
329
401
|
activeContext.setAttributes(flattenToAttributes(fields));
|
|
330
402
|
}
|
|
331
403
|
},
|
|
332
404
|
warn(message, fields) {
|
|
405
|
+
const keys = fields ? ["message", ...Object.keys(fields).filter((k) => k !== "requestLogs")] : ["message"];
|
|
406
|
+
sealCheck("log.warn()", keys);
|
|
407
|
+
if (emitted) return;
|
|
333
408
|
addLogEvent("warn", message, fields);
|
|
334
409
|
activeContext.setAttribute("autotel.log.level", "warn");
|
|
335
410
|
if (fields) {
|
|
336
|
-
contextState
|
|
337
|
-
...contextState,
|
|
338
|
-
...fields
|
|
339
|
-
};
|
|
411
|
+
mergeInto(contextState, fields);
|
|
340
412
|
activeContext.setAttributes(flattenToAttributes(fields));
|
|
341
413
|
}
|
|
342
414
|
},
|
|
343
415
|
error(error, fields) {
|
|
416
|
+
const keys = fields ? [...Object.keys(fields), "error"] : ["error"];
|
|
417
|
+
sealCheck("log.error()", keys);
|
|
418
|
+
if (emitted) return;
|
|
344
419
|
const err = typeof error === "string" ? new Error(error) : error;
|
|
345
420
|
recordStructuredError(activeContext, err);
|
|
346
421
|
addLogEvent("error", err.message, fields);
|
|
347
422
|
if (fields) {
|
|
348
|
-
contextState
|
|
349
|
-
...contextState,
|
|
350
|
-
...fields
|
|
351
|
-
};
|
|
423
|
+
mergeInto(contextState, fields);
|
|
352
424
|
activeContext.setAttributes(flattenToAttributes(fields));
|
|
353
425
|
}
|
|
354
426
|
activeContext.setAttribute("autotel.log.level", "error");
|
|
@@ -357,6 +429,10 @@ function getRequestLogger(ctx2, options) {
|
|
|
357
429
|
return { ...contextState };
|
|
358
430
|
},
|
|
359
431
|
emitNow(overrides) {
|
|
432
|
+
if (emitted) {
|
|
433
|
+
warnPostEmit("log.emitNow()", "Ignoring duplicate emit.");
|
|
434
|
+
return lastSnapshot;
|
|
435
|
+
}
|
|
360
436
|
const mergedContext = {
|
|
361
437
|
...contextState,
|
|
362
438
|
...overrides ?? {}
|
|
@@ -378,11 +454,159 @@ function getRequestLogger(ctx2, options) {
|
|
|
378
454
|
console.warn("[autotel] request logger onEmit failed:", error);
|
|
379
455
|
});
|
|
380
456
|
}
|
|
457
|
+
emitted = true;
|
|
458
|
+
lastSnapshot = snapshot;
|
|
381
459
|
return snapshot;
|
|
460
|
+
},
|
|
461
|
+
fork(label, fn) {
|
|
462
|
+
const parentRequestId = activeContext.correlationId;
|
|
463
|
+
if (typeof parentRequestId !== "string" || parentRequestId.length === 0) {
|
|
464
|
+
throw new Error(
|
|
465
|
+
"[autotel] log.fork() requires the parent logger to have a correlationId. Ensure the request was created by autotel middleware."
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
const tracer = trace.getTracer("autotel.request-logger");
|
|
469
|
+
void tracer.startActiveSpan(`request.fork:${label}`, (childSpan) => {
|
|
470
|
+
const childContext = {
|
|
471
|
+
...createTraceContext(childSpan),
|
|
472
|
+
correlationId: crypto.randomUUID()
|
|
473
|
+
};
|
|
474
|
+
requestContextStore.run(childContext, () => {
|
|
475
|
+
const childLog = getRequestLogger(childContext);
|
|
476
|
+
childLog.set({
|
|
477
|
+
operation: label,
|
|
478
|
+
_parentCorrelationId: parentRequestId
|
|
479
|
+
});
|
|
480
|
+
void Promise.resolve().then(() => fn()).then(() => {
|
|
481
|
+
childLog.emitNow();
|
|
482
|
+
}).catch((err) => {
|
|
483
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
484
|
+
childLog.error(error);
|
|
485
|
+
childLog.emitNow();
|
|
486
|
+
}).finally(() => {
|
|
487
|
+
childSpan.end();
|
|
488
|
+
});
|
|
489
|
+
});
|
|
490
|
+
});
|
|
382
491
|
}
|
|
383
492
|
};
|
|
384
493
|
}
|
|
494
|
+
var GEN_AI_DURATION_BUCKETS_SECONDS = Object.freeze(
|
|
495
|
+
[0.01, 0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 20, 30, 60, 120, 300]
|
|
496
|
+
);
|
|
497
|
+
var GEN_AI_TOKEN_USAGE_BUCKETS = Object.freeze([
|
|
498
|
+
1,
|
|
499
|
+
4,
|
|
500
|
+
16,
|
|
501
|
+
64,
|
|
502
|
+
256,
|
|
503
|
+
1024,
|
|
504
|
+
4096,
|
|
505
|
+
16384,
|
|
506
|
+
65536,
|
|
507
|
+
262144,
|
|
508
|
+
1048576,
|
|
509
|
+
4194304
|
|
510
|
+
]);
|
|
511
|
+
var GEN_AI_COST_USD_BUCKETS = Object.freeze([
|
|
512
|
+
1e-5,
|
|
513
|
+
1e-4,
|
|
514
|
+
1e-3,
|
|
515
|
+
5e-3,
|
|
516
|
+
0.01,
|
|
517
|
+
0.05,
|
|
518
|
+
0.1,
|
|
519
|
+
0.5,
|
|
520
|
+
1,
|
|
521
|
+
5,
|
|
522
|
+
10,
|
|
523
|
+
50
|
|
524
|
+
]);
|
|
525
|
+
function llmHistogramAdvice(kind) {
|
|
526
|
+
const boundaries = kind === "duration" ? GEN_AI_DURATION_BUCKETS_SECONDS : kind === "tokens" ? GEN_AI_TOKEN_USAGE_BUCKETS : GEN_AI_COST_USD_BUCKETS;
|
|
527
|
+
return { advice: { explicitBucketBoundaries: [...boundaries] } };
|
|
528
|
+
}
|
|
529
|
+
function genAiMetricViews(extra = []) {
|
|
530
|
+
const defaults = [
|
|
531
|
+
{ instrumentName: "gen_ai.client.operation.duration", kind: "duration" },
|
|
532
|
+
{ instrumentName: "gen_ai.client.token.usage", kind: "tokens" },
|
|
533
|
+
// Autotel-emitted cost metric. No-op if you don't emit it.
|
|
534
|
+
{ instrumentName: "gen_ai.client.cost.usd", kind: "cost" }
|
|
535
|
+
];
|
|
536
|
+
return [...defaults, ...extra].map(
|
|
537
|
+
({ instrumentName, kind }) => ({
|
|
538
|
+
instrumentName,
|
|
539
|
+
aggregation: {
|
|
540
|
+
type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM,
|
|
541
|
+
options: {
|
|
542
|
+
boundaries: kind === "duration" ? [...GEN_AI_DURATION_BUCKETS_SECONDS] : kind === "tokens" ? [...GEN_AI_TOKEN_USAGE_BUCKETS] : [...GEN_AI_COST_USD_BUCKETS]
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
})
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// src/gen-ai-events.ts
|
|
550
|
+
function recordPromptSent(ctx2, event = {}) {
|
|
551
|
+
ctx2.addEvent("gen_ai.prompt.sent", buildPromptSentAttrs(event));
|
|
552
|
+
}
|
|
553
|
+
function recordResponseReceived(ctx2, event = {}) {
|
|
554
|
+
ctx2.addEvent("gen_ai.response.received", buildResponseAttrs(event));
|
|
555
|
+
}
|
|
556
|
+
function recordRetry(ctx2, event) {
|
|
557
|
+
ctx2.addEvent("gen_ai.retry", buildRetryAttrs(event));
|
|
558
|
+
}
|
|
559
|
+
function recordToolCall(ctx2, event) {
|
|
560
|
+
ctx2.addEvent("gen_ai.tool.call", buildToolCallAttrs(event));
|
|
561
|
+
}
|
|
562
|
+
function recordStreamFirstToken(ctx2, event = {}) {
|
|
563
|
+
ctx2.addEvent("gen_ai.stream.first_token", buildStreamFirstTokenAttrs(event));
|
|
564
|
+
}
|
|
565
|
+
function buildPromptSentAttrs(event) {
|
|
566
|
+
const attrs2 = {};
|
|
567
|
+
if (event.model) attrs2["gen_ai.request.model"] = event.model;
|
|
568
|
+
if (event.promptTokens !== void 0)
|
|
569
|
+
attrs2["gen_ai.usage.input_tokens"] = event.promptTokens;
|
|
570
|
+
if (event.messageCount !== void 0)
|
|
571
|
+
attrs2["gen_ai.request.message_count"] = event.messageCount;
|
|
572
|
+
if (event.operation) attrs2["gen_ai.operation.name"] = event.operation;
|
|
573
|
+
return attrs2;
|
|
574
|
+
}
|
|
575
|
+
function buildResponseAttrs(event) {
|
|
576
|
+
const attrs2 = {};
|
|
577
|
+
if (event.model) attrs2["gen_ai.response.model"] = event.model;
|
|
578
|
+
if (event.promptTokens !== void 0)
|
|
579
|
+
attrs2["gen_ai.usage.input_tokens"] = event.promptTokens;
|
|
580
|
+
if (event.completionTokens !== void 0)
|
|
581
|
+
attrs2["gen_ai.usage.output_tokens"] = event.completionTokens;
|
|
582
|
+
if (event.totalTokens !== void 0)
|
|
583
|
+
attrs2["gen_ai.usage.total_tokens"] = event.totalTokens;
|
|
584
|
+
if (event.finishReasons && event.finishReasons.length > 0) {
|
|
585
|
+
attrs2["gen_ai.response.finish_reasons"] = event.finishReasons.join(",");
|
|
586
|
+
}
|
|
587
|
+
return attrs2;
|
|
588
|
+
}
|
|
589
|
+
function buildRetryAttrs(event) {
|
|
590
|
+
const attrs2 = { "retry.attempt": event.attempt };
|
|
591
|
+
if (event.reason) attrs2["retry.reason"] = event.reason;
|
|
592
|
+
if (event.delayMs !== void 0) attrs2["retry.delay_ms"] = event.delayMs;
|
|
593
|
+
if (event.statusCode !== void 0)
|
|
594
|
+
attrs2["http.response.status_code"] = event.statusCode;
|
|
595
|
+
return attrs2;
|
|
596
|
+
}
|
|
597
|
+
function buildToolCallAttrs(event) {
|
|
598
|
+
const attrs2 = { "gen_ai.tool.name": event.toolName };
|
|
599
|
+
if (event.toolCallId) attrs2["gen_ai.tool.call.id"] = event.toolCallId;
|
|
600
|
+
if (event.arguments) attrs2["gen_ai.tool.arguments"] = event.arguments;
|
|
601
|
+
return attrs2;
|
|
602
|
+
}
|
|
603
|
+
function buildStreamFirstTokenAttrs(event) {
|
|
604
|
+
const attrs2 = {};
|
|
605
|
+
if (event.tokensSoFar !== void 0)
|
|
606
|
+
attrs2["gen_ai.stream.tokens_so_far"] = event.tokensSoFar;
|
|
607
|
+
return attrs2;
|
|
608
|
+
}
|
|
385
609
|
|
|
386
|
-
export { createStructuredError, flattenToAttributes, flush, getRequestLogger, getStructuredErrorAttributes, recordStructuredError, runWithRequestContext, shutdown, toAttributeValue };
|
|
610
|
+
export { GEN_AI_COST_USD_BUCKETS, GEN_AI_DURATION_BUCKETS_SECONDS, GEN_AI_TOKEN_USAGE_BUCKETS, createStructuredError, flattenToAttributes, flush, genAiMetricViews, getRequestLogger, getStructuredErrorAttributes, llmHistogramAdvice, recordPromptSent, recordResponseReceived, recordRetry, recordStreamFirstToken, recordStructuredError, recordToolCall, runWithRequestContext, shutdown, structuredErrorToJSON, toAttributeValue };
|
|
387
611
|
//# sourceMappingURL=index.js.map
|
|
388
612
|
//# sourceMappingURL=index.js.map
|