tracia 0.3.12 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -64,7 +64,13 @@ declare enum LLMProvider {
64
64
  OPENAI = "openai",
65
65
  ANTHROPIC = "anthropic",
66
66
  GOOGLE = "google",
67
- AMAZON_BEDROCK = "amazon_bedrock"
67
+ AMAZON_BEDROCK = "amazon_bedrock",
68
+ VOYAGE = "voyage"
69
+ }
70
+ declare enum SpanKind {
71
+ ROOT = "ROOT",
72
+ LLM = "LLM",
73
+ EMBEDDING = "EMBEDDING"
68
74
  }
69
75
  interface ApiSuccessResponse {
70
76
  text: string;
@@ -341,7 +347,8 @@ interface CreateSpanPayload {
341
347
  model: string;
342
348
  provider: LLMProvider;
343
349
  input: {
344
- messages: LocalPromptMessage[];
350
+ messages?: LocalPromptMessage[];
351
+ text?: string | string[];
345
352
  };
346
353
  variables: Record<string, string> | null;
347
354
  output: string | null;
@@ -363,6 +370,8 @@ interface CreateSpanPayload {
363
370
  traceId?: string;
364
371
  /** Parent span ID for chaining spans in a sequence */
365
372
  parentSpanId?: string;
373
+ /** Span kind override (for embedding spans) */
374
+ spanKind?: SpanKind;
366
375
  }
367
376
  interface CreateSpanResult {
368
377
  spanId: string;
@@ -561,6 +570,65 @@ interface ResponsesStream {
561
570
  /** Abort the stream */
562
571
  abort(): void;
563
572
  }
573
+ interface RunEmbeddingInput {
574
+ /** Text(s) to embed */
575
+ input: string | string[];
576
+ /** Embedding model (e.g., 'text-embedding-3-small') */
577
+ model: string;
578
+ /** Explicitly specify the provider */
579
+ provider?: LLMProvider;
580
+ /** Provider API key override */
581
+ providerApiKey?: string;
582
+ /** Optional dimension override */
583
+ dimensions?: number;
584
+ /** Whether to send span to Tracia (default: true) */
585
+ sendTrace?: boolean;
586
+ /** Custom span ID */
587
+ spanId?: string;
588
+ /** Tags for the span */
589
+ tags?: string[];
590
+ /** User ID for the span */
591
+ userId?: string;
592
+ /** Session ID for the span */
593
+ sessionId?: string;
594
+ /** Trace ID to group related spans together */
595
+ traceId?: string;
596
+ /** Parent span ID for chaining spans in a sequence */
597
+ parentSpanId?: string;
598
+ /** Timeout in milliseconds */
599
+ timeoutMs?: number;
600
+ }
601
+ interface EmbeddingVector {
602
+ /** The embedding values */
603
+ values: number[];
604
+ /** Index of this embedding in the input array */
605
+ index: number;
606
+ }
607
+ interface EmbeddingUsage {
608
+ /** Total tokens used for the embedding request */
609
+ totalTokens: number;
610
+ }
611
+ interface RunEmbeddingResult {
612
+ /** The generated embeddings */
613
+ embeddings: EmbeddingVector[];
614
+ /** Span ID for this request */
615
+ spanId: string;
616
+ /** Trace ID grouping related spans */
617
+ traceId: string;
618
+ /** Latency in milliseconds */
619
+ latencyMs: number;
620
+ /** Token usage */
621
+ usage: EmbeddingUsage;
622
+ /**
623
+ * Estimated cost in USD.
624
+ * Currently always `null` — cost is calculated server-side when the span is ingested.
625
+ */
626
+ cost: number | null;
627
+ /** The provider used */
628
+ provider: LLMProvider;
629
+ /** The model used */
630
+ model: string;
631
+ }
564
632
  /** @deprecated Use SpanStatus instead */
565
633
  type TraceStatus = SpanStatus;
566
634
  /** @deprecated Use SpanListItem instead */
@@ -612,6 +680,11 @@ type SessionRunLocalInput = Omit<RunLocalInput, 'traceId' | 'parentSpanId'>;
612
680
  * as those are managed by the session.
613
681
  */
614
682
  type SessionRunResponsesInput = Omit<RunResponsesInput, 'traceId' | 'parentSpanId'>;
683
+ /**
684
+ * Input for session.runEmbedding() - same as RunEmbeddingInput but without traceId/parentSpanId
685
+ * as those are managed by the session.
686
+ */
687
+ type SessionRunEmbeddingInput = Omit<RunEmbeddingInput, 'traceId' | 'parentSpanId'>;
615
688
  /**
616
689
  * A session for grouping related spans together under a single trace.
617
690
  *
@@ -691,6 +764,11 @@ declare class TraciaSession {
691
764
  }): Promise<RunResponsesResult>;
692
765
  private runResponsesNonStreaming;
693
766
  private runResponsesStreaming;
767
+ /**
768
+ * Generate embeddings, automatically linking the span to this session.
769
+ * See Tracia.runEmbedding() for full documentation.
770
+ */
771
+ runEmbedding(input: SessionRunEmbeddingInput): Promise<RunEmbeddingResult>;
694
772
  private updateSessionState;
695
773
  }
696
774
 
@@ -814,6 +892,29 @@ declare class Tracia {
814
892
  private createResponsesStream;
815
893
  private createLocalStream;
816
894
  private combineAbortSignals;
895
+ /**
896
+ * Generate embeddings for text input(s) using an embedding model.
897
+ *
898
+ * @example Single text
899
+ * ```typescript
900
+ * const result = await tracia.runEmbedding({
901
+ * model: 'text-embedding-3-small',
902
+ * input: 'Hello world',
903
+ * })
904
+ * console.log(result.embeddings[0].values.length) // 1536
905
+ * ```
906
+ *
907
+ * @example Batch
908
+ * ```typescript
909
+ * const result = await tracia.runEmbedding({
910
+ * model: 'text-embedding-3-small',
911
+ * input: ['Hello', 'World'],
912
+ * })
913
+ * console.log(result.embeddings.length) // 2
914
+ * ```
915
+ */
916
+ runEmbedding(input: RunEmbeddingInput): Promise<RunEmbeddingResult>;
917
+ private validateRunEmbeddingInput;
817
918
  flush(): Promise<void>;
818
919
  /**
819
920
  * Create a new session for grouping related spans together under a single trace.
@@ -859,4 +960,4 @@ declare class Tracia {
859
960
  private getProviderApiKey;
860
961
  }
861
962
 
862
- export { type ContentPart, type CreatePromptOptions, type CreateSpanPayload, type CreateSpanResult, type CreateTracePayload, type CreateTraceResult, Eval, type EvaluateOptions, type EvaluateResult, type FinishReason, type JsonSchemaProperty, LLMProvider, type ListSpansOptions, type ListSpansResult, type ListTracesOptions, type ListTracesResult, type LocalPromptMessage, type LocalStream, type MessageRole, type Prompt, type PromptListItem, type PromptMessage, type ResponsesEvent, type ResponsesInputItem, type ResponsesOutputItem, type ResponsesStream, type RunLocalInput, type RunLocalResult, type RunOptions, type RunResponsesInput, type RunResponsesResult, type RunResult, type RunVariables, type SessionRunLocalInput, type SessionRunResponsesInput, type Span, type SpanListItem, type SpanStatus, type StreamResult, type TextPart, type TokenUsage, type ToolCall, type ToolCallPart, type ToolChoice, type ToolDefinition, type ToolParameters, type Trace, type TraceListItem, type TraceStatus, Tracia, TraciaError, TraciaErrorCode, type TraciaOptions, TraciaSession, type UpdatePromptOptions };
963
+ export { type ContentPart, type CreatePromptOptions, type CreateSpanPayload, type CreateSpanResult, type CreateTracePayload, type CreateTraceResult, type EmbeddingUsage, type EmbeddingVector, Eval, type EvaluateOptions, type EvaluateResult, type FinishReason, type JsonSchemaProperty, LLMProvider, type ListSpansOptions, type ListSpansResult, type ListTracesOptions, type ListTracesResult, type LocalPromptMessage, type LocalStream, type MessageRole, type Prompt, type PromptListItem, type PromptMessage, type ResponsesEvent, type ResponsesInputItem, type ResponsesOutputItem, type ResponsesStream, type RunEmbeddingInput, type RunEmbeddingResult, type RunLocalInput, type RunLocalResult, type RunOptions, type RunResponsesInput, type RunResponsesResult, type RunResult, type RunVariables, type SessionRunEmbeddingInput, type SessionRunLocalInput, type SessionRunResponsesInput, type Span, SpanKind, type SpanListItem, type SpanStatus, type StreamResult, type TextPart, type TokenUsage, type ToolCall, type ToolCallPart, type ToolChoice, type ToolDefinition, type ToolParameters, type Trace, type TraceListItem, type TraceStatus, Tracia, TraciaError, TraciaErrorCode, type TraciaOptions, TraciaSession, type UpdatePromptOptions };
package/dist/index.d.ts CHANGED
@@ -64,7 +64,13 @@ declare enum LLMProvider {
64
64
  OPENAI = "openai",
65
65
  ANTHROPIC = "anthropic",
66
66
  GOOGLE = "google",
67
- AMAZON_BEDROCK = "amazon_bedrock"
67
+ AMAZON_BEDROCK = "amazon_bedrock",
68
+ VOYAGE = "voyage"
69
+ }
70
+ declare enum SpanKind {
71
+ ROOT = "ROOT",
72
+ LLM = "LLM",
73
+ EMBEDDING = "EMBEDDING"
68
74
  }
69
75
  interface ApiSuccessResponse {
70
76
  text: string;
@@ -341,7 +347,8 @@ interface CreateSpanPayload {
341
347
  model: string;
342
348
  provider: LLMProvider;
343
349
  input: {
344
- messages: LocalPromptMessage[];
350
+ messages?: LocalPromptMessage[];
351
+ text?: string | string[];
345
352
  };
346
353
  variables: Record<string, string> | null;
347
354
  output: string | null;
@@ -363,6 +370,8 @@ interface CreateSpanPayload {
363
370
  traceId?: string;
364
371
  /** Parent span ID for chaining spans in a sequence */
365
372
  parentSpanId?: string;
373
+ /** Span kind override (for embedding spans) */
374
+ spanKind?: SpanKind;
366
375
  }
367
376
  interface CreateSpanResult {
368
377
  spanId: string;
@@ -561,6 +570,65 @@ interface ResponsesStream {
561
570
  /** Abort the stream */
562
571
  abort(): void;
563
572
  }
573
+ interface RunEmbeddingInput {
574
+ /** Text(s) to embed */
575
+ input: string | string[];
576
+ /** Embedding model (e.g., 'text-embedding-3-small') */
577
+ model: string;
578
+ /** Explicitly specify the provider */
579
+ provider?: LLMProvider;
580
+ /** Provider API key override */
581
+ providerApiKey?: string;
582
+ /** Optional dimension override */
583
+ dimensions?: number;
584
+ /** Whether to send span to Tracia (default: true) */
585
+ sendTrace?: boolean;
586
+ /** Custom span ID */
587
+ spanId?: string;
588
+ /** Tags for the span */
589
+ tags?: string[];
590
+ /** User ID for the span */
591
+ userId?: string;
592
+ /** Session ID for the span */
593
+ sessionId?: string;
594
+ /** Trace ID to group related spans together */
595
+ traceId?: string;
596
+ /** Parent span ID for chaining spans in a sequence */
597
+ parentSpanId?: string;
598
+ /** Timeout in milliseconds */
599
+ timeoutMs?: number;
600
+ }
601
+ interface EmbeddingVector {
602
+ /** The embedding values */
603
+ values: number[];
604
+ /** Index of this embedding in the input array */
605
+ index: number;
606
+ }
607
+ interface EmbeddingUsage {
608
+ /** Total tokens used for the embedding request */
609
+ totalTokens: number;
610
+ }
611
+ interface RunEmbeddingResult {
612
+ /** The generated embeddings */
613
+ embeddings: EmbeddingVector[];
614
+ /** Span ID for this request */
615
+ spanId: string;
616
+ /** Trace ID grouping related spans */
617
+ traceId: string;
618
+ /** Latency in milliseconds */
619
+ latencyMs: number;
620
+ /** Token usage */
621
+ usage: EmbeddingUsage;
622
+ /**
623
+ * Estimated cost in USD.
624
+ * Currently always `null` — cost is calculated server-side when the span is ingested.
625
+ */
626
+ cost: number | null;
627
+ /** The provider used */
628
+ provider: LLMProvider;
629
+ /** The model used */
630
+ model: string;
631
+ }
564
632
  /** @deprecated Use SpanStatus instead */
565
633
  type TraceStatus = SpanStatus;
566
634
  /** @deprecated Use SpanListItem instead */
@@ -612,6 +680,11 @@ type SessionRunLocalInput = Omit<RunLocalInput, 'traceId' | 'parentSpanId'>;
612
680
  * as those are managed by the session.
613
681
  */
614
682
  type SessionRunResponsesInput = Omit<RunResponsesInput, 'traceId' | 'parentSpanId'>;
683
+ /**
684
+ * Input for session.runEmbedding() - same as RunEmbeddingInput but without traceId/parentSpanId
685
+ * as those are managed by the session.
686
+ */
687
+ type SessionRunEmbeddingInput = Omit<RunEmbeddingInput, 'traceId' | 'parentSpanId'>;
615
688
  /**
616
689
  * A session for grouping related spans together under a single trace.
617
690
  *
@@ -691,6 +764,11 @@ declare class TraciaSession {
691
764
  }): Promise<RunResponsesResult>;
692
765
  private runResponsesNonStreaming;
693
766
  private runResponsesStreaming;
767
+ /**
768
+ * Generate embeddings, automatically linking the span to this session.
769
+ * See Tracia.runEmbedding() for full documentation.
770
+ */
771
+ runEmbedding(input: SessionRunEmbeddingInput): Promise<RunEmbeddingResult>;
694
772
  private updateSessionState;
695
773
  }
696
774
 
@@ -814,6 +892,29 @@ declare class Tracia {
814
892
  private createResponsesStream;
815
893
  private createLocalStream;
816
894
  private combineAbortSignals;
895
+ /**
896
+ * Generate embeddings for text input(s) using an embedding model.
897
+ *
898
+ * @example Single text
899
+ * ```typescript
900
+ * const result = await tracia.runEmbedding({
901
+ * model: 'text-embedding-3-small',
902
+ * input: 'Hello world',
903
+ * })
904
+ * console.log(result.embeddings[0].values.length) // 1536
905
+ * ```
906
+ *
907
+ * @example Batch
908
+ * ```typescript
909
+ * const result = await tracia.runEmbedding({
910
+ * model: 'text-embedding-3-small',
911
+ * input: ['Hello', 'World'],
912
+ * })
913
+ * console.log(result.embeddings.length) // 2
914
+ * ```
915
+ */
916
+ runEmbedding(input: RunEmbeddingInput): Promise<RunEmbeddingResult>;
917
+ private validateRunEmbeddingInput;
817
918
  flush(): Promise<void>;
818
919
  /**
819
920
  * Create a new session for grouping related spans together under a single trace.
@@ -859,4 +960,4 @@ declare class Tracia {
859
960
  private getProviderApiKey;
860
961
  }
861
962
 
862
- export { type ContentPart, type CreatePromptOptions, type CreateSpanPayload, type CreateSpanResult, type CreateTracePayload, type CreateTraceResult, Eval, type EvaluateOptions, type EvaluateResult, type FinishReason, type JsonSchemaProperty, LLMProvider, type ListSpansOptions, type ListSpansResult, type ListTracesOptions, type ListTracesResult, type LocalPromptMessage, type LocalStream, type MessageRole, type Prompt, type PromptListItem, type PromptMessage, type ResponsesEvent, type ResponsesInputItem, type ResponsesOutputItem, type ResponsesStream, type RunLocalInput, type RunLocalResult, type RunOptions, type RunResponsesInput, type RunResponsesResult, type RunResult, type RunVariables, type SessionRunLocalInput, type SessionRunResponsesInput, type Span, type SpanListItem, type SpanStatus, type StreamResult, type TextPart, type TokenUsage, type ToolCall, type ToolCallPart, type ToolChoice, type ToolDefinition, type ToolParameters, type Trace, type TraceListItem, type TraceStatus, Tracia, TraciaError, TraciaErrorCode, type TraciaOptions, TraciaSession, type UpdatePromptOptions };
963
+ export { type ContentPart, type CreatePromptOptions, type CreateSpanPayload, type CreateSpanResult, type CreateTracePayload, type CreateTraceResult, type EmbeddingUsage, type EmbeddingVector, Eval, type EvaluateOptions, type EvaluateResult, type FinishReason, type JsonSchemaProperty, LLMProvider, type ListSpansOptions, type ListSpansResult, type ListTracesOptions, type ListTracesResult, type LocalPromptMessage, type LocalStream, type MessageRole, type Prompt, type PromptListItem, type PromptMessage, type ResponsesEvent, type ResponsesInputItem, type ResponsesOutputItem, type ResponsesStream, type RunEmbeddingInput, type RunEmbeddingResult, type RunLocalInput, type RunLocalResult, type RunOptions, type RunResponsesInput, type RunResponsesResult, type RunResult, type RunVariables, type SessionRunEmbeddingInput, type SessionRunLocalInput, type SessionRunResponsesInput, type Span, SpanKind, type SpanListItem, type SpanStatus, type StreamResult, type TextPart, type TokenUsage, type ToolCall, type ToolCallPart, type ToolChoice, type ToolDefinition, type ToolParameters, type Trace, type TraceListItem, type TraceStatus, Tracia, TraciaError, TraciaErrorCode, type TraciaOptions, TraciaSession, type UpdatePromptOptions };
package/dist/index.js CHANGED
@@ -32,6 +32,7 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  Eval: () => Eval,
34
34
  LLMProvider: () => LLMProvider,
35
+ SpanKind: () => SpanKind,
35
36
  Tracia: () => Tracia,
36
37
  TraciaError: () => TraciaError,
37
38
  TraciaErrorCode: () => TraciaErrorCode,
@@ -73,11 +74,18 @@ var LLMProvider = /* @__PURE__ */ ((LLMProvider2) => {
73
74
  LLMProvider2["ANTHROPIC"] = "anthropic";
74
75
  LLMProvider2["GOOGLE"] = "google";
75
76
  LLMProvider2["AMAZON_BEDROCK"] = "amazon_bedrock";
77
+ LLMProvider2["VOYAGE"] = "voyage";
76
78
  return LLMProvider2;
77
79
  })(LLMProvider || {});
80
+ var SpanKind = /* @__PURE__ */ ((SpanKind2) => {
81
+ SpanKind2["ROOT"] = "ROOT";
82
+ SpanKind2["LLM"] = "LLM";
83
+ SpanKind2["EMBEDDING"] = "EMBEDDING";
84
+ return SpanKind2;
85
+ })(SpanKind || {});
78
86
 
79
87
  // src/client.ts
80
- var SDK_VERSION = "0.3.12";
88
+ var SDK_VERSION = "0.4.1";
81
89
  var DEFAULT_TIMEOUT_MS = 12e4;
82
90
  function mapApiErrorCodeToTraciaErrorCode(apiCode) {
83
91
  const codeMap = {
@@ -342,7 +350,23 @@ var MODEL_TO_PROVIDER = {
342
350
  "amazon.nova-micro-v1:0": "amazon_bedrock" /* AMAZON_BEDROCK */,
343
351
  "amazon.nova-lite-v1:0": "amazon_bedrock" /* AMAZON_BEDROCK */,
344
352
  "amazon.nova-pro-v1:0": "amazon_bedrock" /* AMAZON_BEDROCK */,
345
- "mistral.pixtral-large-2502-v1:0": "amazon_bedrock" /* AMAZON_BEDROCK */
353
+ "mistral.pixtral-large-2502-v1:0": "amazon_bedrock" /* AMAZON_BEDROCK */,
354
+ // OpenAI - Embedding models
355
+ "text-embedding-3-small": "openai" /* OPENAI */,
356
+ "text-embedding-3-large": "openai" /* OPENAI */,
357
+ "text-embedding-ada-002": "openai" /* OPENAI */,
358
+ // Google - Embedding models
359
+ "text-embedding-004": "google" /* GOOGLE */,
360
+ // Amazon Bedrock - Embedding models
361
+ "amazon.titan-embed-text-v2:0": "amazon_bedrock" /* AMAZON_BEDROCK */,
362
+ "cohere.embed-english-v3": "amazon_bedrock" /* AMAZON_BEDROCK */,
363
+ // Voyage - Embedding models
364
+ "voyage-3": "voyage" /* VOYAGE */,
365
+ "voyage-3-large": "voyage" /* VOYAGE */,
366
+ "voyage-3-lite": "voyage" /* VOYAGE */,
367
+ "voyage-code-3": "voyage" /* VOYAGE */,
368
+ "voyage-finance-2": "voyage" /* VOYAGE */,
369
+ "voyage-law-2": "voyage" /* VOYAGE */
346
370
  };
347
371
  function getProviderForModel(modelId) {
348
372
  return MODEL_TO_PROVIDER[modelId];
@@ -477,6 +501,9 @@ function resolveProvider(model, explicitProvider) {
477
501
  if (model.startsWith("gemini-")) {
478
502
  return "google" /* GOOGLE */;
479
503
  }
504
+ if (model.startsWith("voyage-")) {
505
+ return "voyage" /* VOYAGE */;
506
+ }
480
507
  throw new TraciaError(
481
508
  "UNSUPPORTED_MODEL" /* UNSUPPORTED_MODEL */,
482
509
  `Cannot determine provider for model: ${model}. Specify provider explicitly.`
@@ -502,9 +529,14 @@ async function getLanguageModel(provider, model, apiKey) {
502
529
  case "amazon_bedrock" /* AMAZON_BEDROCK */: {
503
530
  const { createAmazonBedrock } = await loadBedrockProvider();
504
531
  const region = process.env.AWS_REGION ?? "eu-central-1";
505
- const bedrock = apiKey ? createAmazonBedrock({ apiKey, region }) : createAmazonBedrock({ region });
532
+ const bedrock = createAmazonBedrock({ region });
506
533
  return bedrock(applyBedrockRegionPrefix(model, region));
507
534
  }
535
+ case "voyage" /* VOYAGE */:
536
+ throw new TraciaError(
537
+ "UNSUPPORTED_MODEL" /* UNSUPPORTED_MODEL */,
538
+ "Voyage is an embedding-only provider. Use runEmbedding() instead of runLocal()."
539
+ );
508
540
  default:
509
541
  throw new TraciaError(
510
542
  "UNSUPPORTED_MODEL" /* UNSUPPORTED_MODEL */,
@@ -512,6 +544,108 @@ async function getLanguageModel(provider, model, apiKey) {
512
544
  );
513
545
  }
514
546
  }
547
+ async function getEmbeddingModel(provider, model, apiKey) {
548
+ switch (provider) {
549
+ case "openai" /* OPENAI */: {
550
+ const { createOpenAI } = await loadOpenAIProvider();
551
+ const openai = createOpenAI({ apiKey });
552
+ return openai.textEmbeddingModel(model);
553
+ }
554
+ case "google" /* GOOGLE */: {
555
+ const { createGoogleGenerativeAI } = await loadGoogleProvider();
556
+ const google = createGoogleGenerativeAI({ apiKey });
557
+ return google.textEmbeddingModel(model);
558
+ }
559
+ case "amazon_bedrock" /* AMAZON_BEDROCK */: {
560
+ const { createAmazonBedrock } = await loadBedrockProvider();
561
+ const region = process.env.AWS_REGION ?? "eu-central-1";
562
+ const bedrock = createAmazonBedrock({ region });
563
+ return bedrock.textEmbeddingModel(applyBedrockRegionPrefix(model, region));
564
+ }
565
+ case "anthropic" /* ANTHROPIC */:
566
+ throw new TraciaError(
567
+ "UNSUPPORTED_MODEL" /* UNSUPPORTED_MODEL */,
568
+ "Anthropic does not offer embedding models. Use OpenAI, Google, or Amazon Bedrock instead."
569
+ );
570
+ default:
571
+ throw new TraciaError(
572
+ "UNSUPPORTED_MODEL" /* UNSUPPORTED_MODEL */,
573
+ `Unsupported provider for embeddings: ${provider}`
574
+ );
575
+ }
576
+ }
577
+ async function callVoyageEmbedding(input, model, apiKey, timeoutMs) {
578
+ const response = await fetch("https://api.voyageai.com/v1/embeddings", {
579
+ method: "POST",
580
+ headers: {
581
+ "Content-Type": "application/json",
582
+ Authorization: `Bearer ${apiKey}`
583
+ },
584
+ body: JSON.stringify({ input, model }),
585
+ signal: timeoutMs ? AbortSignal.timeout(timeoutMs) : void 0
586
+ });
587
+ if (!response.ok) {
588
+ const body = await response.text();
589
+ throw new TraciaError(
590
+ "PROVIDER_ERROR" /* PROVIDER_ERROR */,
591
+ `Voyage AI API error ${response.status}: ${sanitizeErrorMessage(body)}`
592
+ );
593
+ }
594
+ const data = await response.json();
595
+ const embeddings = data.data.sort((a, b) => a.index - b.index).map((item) => ({ values: item.embedding, index: item.index }));
596
+ return {
597
+ embeddings,
598
+ totalTokens: data.usage?.total_tokens ?? 0,
599
+ provider: "voyage" /* VOYAGE */
600
+ };
601
+ }
602
+ async function embedText(options) {
603
+ const provider = resolveProvider(options.model, options.provider);
604
+ const inputs = Array.isArray(options.input) ? options.input : [options.input];
605
+ if (provider === "voyage" /* VOYAGE */) {
606
+ if (options.dimensions) {
607
+ throw new TraciaError(
608
+ "UNSUPPORTED_MODEL" /* UNSUPPORTED_MODEL */,
609
+ "Voyage AI does not support custom embedding dimensions"
610
+ );
611
+ }
612
+ return callVoyageEmbedding(inputs, options.model, options.apiKey, options.timeoutMs);
613
+ }
614
+ const embeddingModel = await getEmbeddingModel(provider, options.model, options.apiKey);
615
+ try {
616
+ const { embedMany } = await loadAISdk();
617
+ const providerOptions = {};
618
+ if (options.dimensions) {
619
+ if (provider === "openai" /* OPENAI */) {
620
+ providerOptions.openai = { dimensions: options.dimensions };
621
+ } else if (provider === "google" /* GOOGLE */) {
622
+ providerOptions.google = { outputDimensionality: options.dimensions };
623
+ }
624
+ }
625
+ const result = await embedMany({
626
+ model: embeddingModel,
627
+ values: inputs,
628
+ abortSignal: options.timeoutMs ? AbortSignal.timeout(options.timeoutMs) : void 0,
629
+ ...Object.keys(providerOptions).length > 0 && { providerOptions }
630
+ });
631
+ const embeddings = result.embeddings.map((values, index) => ({
632
+ values,
633
+ index
634
+ }));
635
+ return {
636
+ embeddings,
637
+ totalTokens: result.usage?.tokens ?? 0,
638
+ provider
639
+ };
640
+ } catch (error) {
641
+ if (error instanceof TraciaError) throw error;
642
+ const rawMessage = error instanceof Error ? error.message : String(error);
643
+ throw new TraciaError(
644
+ "PROVIDER_ERROR" /* PROVIDER_ERROR */,
645
+ `${provider} embedding error: ${sanitizeErrorMessage(rawMessage)}`
646
+ );
647
+ }
648
+ }
515
649
  function convertMessages(messages) {
516
650
  return messages.map((msg) => {
517
651
  if (msg.role === "tool") {
@@ -548,9 +682,12 @@ function convertMessages(messages) {
548
682
  };
549
683
  }
550
684
  const role = msg.role === "developer" ? "system" : msg.role;
685
+ if (typeof msg.content === "string") {
686
+ return { role, content: msg.content };
687
+ }
551
688
  return {
552
689
  role,
553
- content: typeof msg.content === "string" ? msg.content : msg.content.map((b) => b.type === "text" ? b.text : "").join("")
690
+ content: msg.content.map((b) => b.type === "text" ? b.text : "").join("")
554
691
  };
555
692
  });
556
693
  }
@@ -957,6 +1094,20 @@ var TraciaSession = class {
957
1094
  abort: () => responsesStream2.abort()
958
1095
  };
959
1096
  }
1097
+ /**
1098
+ * Generate embeddings, automatically linking the span to this session.
1099
+ * See Tracia.runEmbedding() for full documentation.
1100
+ */
1101
+ async runEmbedding(input) {
1102
+ const inputWithSession = {
1103
+ ...input,
1104
+ traceId: this.traceId ?? void 0,
1105
+ parentSpanId: this.lastSpanId ?? void 0
1106
+ };
1107
+ const result = await this.tracia.runEmbedding(inputWithSession);
1108
+ this.updateSessionState(result.spanId, result.traceId);
1109
+ return result;
1110
+ }
960
1111
  updateSessionState(spanId, traceId) {
961
1112
  if (!spanId) return;
962
1113
  if (!this.traceId && traceId) {
@@ -1074,7 +1225,8 @@ var ENV_VAR_MAP = {
1074
1225
  ["openai" /* OPENAI */]: "OPENAI_API_KEY",
1075
1226
  ["anthropic" /* ANTHROPIC */]: "ANTHROPIC_API_KEY",
1076
1227
  ["google" /* GOOGLE */]: "GOOGLE_API_KEY",
1077
- ["amazon_bedrock" /* AMAZON_BEDROCK */]: "BEDROCK_API_KEY"
1228
+ ["amazon_bedrock" /* AMAZON_BEDROCK */]: "BEDROCK_API_KEY",
1229
+ ["voyage" /* VOYAGE */]: "VOYAGE_API_KEY"
1078
1230
  };
1079
1231
  function convertResponsesItemToMessage(item) {
1080
1232
  if ("role" in item && (item.role === "developer" || item.role === "user")) {
@@ -1596,6 +1748,128 @@ var Tracia = class {
1596
1748
  signal2.addEventListener("abort", onAbort, { once: true });
1597
1749
  return controller.signal;
1598
1750
  }
1751
+ /**
1752
+ * Generate embeddings for text input(s) using an embedding model.
1753
+ *
1754
+ * @example Single text
1755
+ * ```typescript
1756
+ * const result = await tracia.runEmbedding({
1757
+ * model: 'text-embedding-3-small',
1758
+ * input: 'Hello world',
1759
+ * })
1760
+ * console.log(result.embeddings[0].values.length) // 1536
1761
+ * ```
1762
+ *
1763
+ * @example Batch
1764
+ * ```typescript
1765
+ * const result = await tracia.runEmbedding({
1766
+ * model: 'text-embedding-3-small',
1767
+ * input: ['Hello', 'World'],
1768
+ * })
1769
+ * console.log(result.embeddings.length) // 2
1770
+ * ```
1771
+ */
1772
+ async runEmbedding(input) {
1773
+ this.validateRunEmbeddingInput(input);
1774
+ let spanId = "";
1775
+ let traceId = "";
1776
+ if (input.sendTrace !== false) {
1777
+ if (input.spanId && !isValidSpanIdFormat(input.spanId)) {
1778
+ throw new TraciaError(
1779
+ "INVALID_REQUEST" /* INVALID_REQUEST */,
1780
+ `Invalid span ID format. Must match: sp_ + 16 hex characters (e.g., sp_1234567890abcdef)`
1781
+ );
1782
+ }
1783
+ spanId = input.spanId || generateSpanId();
1784
+ traceId = input.traceId || generateTraceId();
1785
+ }
1786
+ const provider = resolveProvider(input.model, input.provider);
1787
+ const apiKey = this.getProviderApiKey(provider, input.providerApiKey);
1788
+ const startTime = Date.now();
1789
+ let embeddingResult = null;
1790
+ let errorMessage = null;
1791
+ try {
1792
+ embeddingResult = await embedText({
1793
+ model: input.model,
1794
+ input: input.input,
1795
+ apiKey,
1796
+ provider: input.provider,
1797
+ dimensions: input.dimensions,
1798
+ timeoutMs: input.timeoutMs
1799
+ });
1800
+ } catch (error) {
1801
+ if (error instanceof TraciaError) {
1802
+ errorMessage = error.message;
1803
+ } else {
1804
+ errorMessage = error instanceof Error ? error.message : String(error);
1805
+ }
1806
+ }
1807
+ const latencyMs = Date.now() - startTime;
1808
+ const inputTexts = Array.isArray(input.input) ? input.input : [input.input];
1809
+ if (spanId) {
1810
+ const embeddingCount = embeddingResult?.embeddings.length ?? 0;
1811
+ const embeddingDimensions = embeddingResult?.embeddings[0]?.values.length ?? 0;
1812
+ this.scheduleSpanCreation(spanId, {
1813
+ spanId,
1814
+ model: input.model,
1815
+ provider: embeddingResult?.provider ?? provider,
1816
+ input: { text: inputTexts },
1817
+ variables: null,
1818
+ output: embeddingResult ? JSON.stringify({ dimensions: embeddingDimensions, count: embeddingCount }) : null,
1819
+ status: errorMessage ? SPAN_STATUS_ERROR : SPAN_STATUS_SUCCESS,
1820
+ error: errorMessage,
1821
+ latencyMs,
1822
+ inputTokens: embeddingResult?.totalTokens ?? 0,
1823
+ outputTokens: 0,
1824
+ totalTokens: embeddingResult?.totalTokens ?? 0,
1825
+ tags: input.tags,
1826
+ userId: input.userId,
1827
+ sessionId: input.sessionId,
1828
+ traceId,
1829
+ parentSpanId: input.parentSpanId,
1830
+ spanKind: "EMBEDDING" /* EMBEDDING */
1831
+ });
1832
+ }
1833
+ if (errorMessage || !embeddingResult) {
1834
+ throw new TraciaError("PROVIDER_ERROR" /* PROVIDER_ERROR */, errorMessage ?? "Embedding call returned no result");
1835
+ }
1836
+ return {
1837
+ embeddings: embeddingResult.embeddings,
1838
+ spanId,
1839
+ traceId,
1840
+ latencyMs,
1841
+ usage: { totalTokens: embeddingResult.totalTokens },
1842
+ cost: null,
1843
+ provider: embeddingResult.provider,
1844
+ model: input.model
1845
+ };
1846
+ }
1847
+ validateRunEmbeddingInput(input) {
1848
+ if (!input.model || input.model.trim() === "") {
1849
+ throw new TraciaError(
1850
+ "INVALID_REQUEST" /* INVALID_REQUEST */,
1851
+ "model is required and cannot be empty"
1852
+ );
1853
+ }
1854
+ if (!input.input || Array.isArray(input.input) && input.input.length === 0) {
1855
+ throw new TraciaError(
1856
+ "INVALID_REQUEST" /* INVALID_REQUEST */,
1857
+ "input is required and cannot be empty"
1858
+ );
1859
+ }
1860
+ if (typeof input.input === "string" && input.input.trim() === "") {
1861
+ throw new TraciaError(
1862
+ "INVALID_REQUEST" /* INVALID_REQUEST */,
1863
+ "input text cannot be empty"
1864
+ );
1865
+ }
1866
+ if (Array.isArray(input.input) && input.input.some((text) => text.trim() === "")) {
1867
+ throw new TraciaError(
1868
+ "INVALID_REQUEST" /* INVALID_REQUEST */,
1869
+ "input array cannot contain empty strings"
1870
+ );
1871
+ }
1872
+ }
1599
1873
  async flush() {
1600
1874
  await Promise.all(this.pendingSpans.values());
1601
1875
  }
@@ -1762,6 +2036,7 @@ var Tracia = class {
1762
2036
  0 && (module.exports = {
1763
2037
  Eval,
1764
2038
  LLMProvider,
2039
+ SpanKind,
1765
2040
  Tracia,
1766
2041
  TraciaError,
1767
2042
  TraciaErrorCode,