package ocaml-ai-sdk

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Module Ai_core.TelemetrySource

Telemetry configuration for AI SDK operations.

Mirrors the upstream AI SDK's TelemetrySettings. When enabled is false (the default), all instrumentation is skipped with zero overhead — Trace_core returns dummy spans and never serializes attribute data.

Quick start

  (* 1. Install a trace collector in your application entrypoint *)
  let () = Trace_core.setup_collector (my_otel_collector ())

  (* 2. Pass telemetry settings to generate_text / stream_text *)
  let telemetry =
    Telemetry.create ~enabled:true ~function_id:"chat-completion"
      ~metadata:[ "user_id", `String "u-123" ]
      ()

  let%lwt result = Generate_text.generate_text ~model ~messages ~telemetry ()

Span hierarchy

ai.generateText                     (root — full operation)
├── ai.generateText.doGenerate      (per-step LLM call)
└── ai.toolCall                     (per tool execution)

ai.streamText                       (root — full streaming operation)
├── ai.streamText.doStream          (per-step streaming call)
└── ai.toolCall                     (per tool execution)

Attribute selectivity

Attributes are classified as Input (prompts, tools), Output (responses, tool results), or Always (model info, usage). Input attributes are only recorded when record_inputs is true, Output when record_outputs is true. When enabled is false, no attributes are evaluated at all (zero serialization cost).

Upstream parity gaps

The following upstream attributes are not yet emitted:

  • ai.response.timestamp: our Generate_result.response_info does not carry timestamps.
  • ai.response.id on stream step spans. ai.response.model is emitted when the provider supplies Stream_result.raw_response.
  • ai.usage.inputTokenDetails.*, ai.usage.outputTokenDetails.*: our Usage.t only has input_tokens, output_tokens, total_tokens. When the provider-level type gains detail fields (Anthropic already returns them in provider metadata), the span attributes can be extended without API changes.
  • onStepStart integration callback: upstream added this; we only have on_step_finish.
  • gen_ai.response.finish_reasons: upstream emits a string array (["stop"]). Trace_core.user_data has no array variant, so we emit a plain string ("stop").
  • ai.prompt on root spans: upstream serializes full message content (gated by record_inputs). We emit placeholder strings ("<message>") to avoid serializing large payloads into span data. The full messages are available via integration callbacks.

W3C Trace Context

Parse the W3C Trace Context {traceparent} header to link backend spans to an incoming frontend trace. The header format (version 00) is a stable W3C Recommendation:

00-{32 hex trace_id}-{16 hex parent_id}-{2 hex flags}

When passed to create via ~traceparent, the parsed IDs are emitted as ai.trace_context.trace_id, ai.trace_context.parent_id, and ai.trace_context.sampled attributes on every root span, so any trace collector can reconstruct the parent link.

If the user also installs the opentelemetry-trace bridge with ambient context, the parenting happens automatically at the Trace_core level — the attributes are still present as a belt-and-suspenders fallback.

Sourcetype trace_context = {
  1. trace_id : string;
    (*

    32 lowercase hex chars

    *)
  2. parent_id : string;
    (*

    16 lowercase hex chars

    *)
  3. sampled : bool;
}

Parsed W3C traceparent fields.

Sourceval parse_traceparent : string -> trace_context option

Parse a raw W3C {traceparent} header value. Returns None if the value is malformed, the wrong version, or contains all-zero trace/parent IDs (invalid per spec).

Types

Sourcetype model_info = {
  1. provider : string;
  2. model_id : string;
}

Model info for callback events.

Sourceand integration = {
  1. on_start : (on_start_event -> unit Lwt.t) option;
  2. on_step_finish : (on_step_finish_event -> unit Lwt.t) option;
  3. on_tool_call_start : (on_tool_call_start_event -> unit Lwt.t) option;
  4. on_tool_call_finish : (on_tool_call_finish_event -> unit Lwt.t) option;
  5. on_finish : (on_finish_event -> unit Lwt.t) option;
}

Lifecycle callbacks for telemetry events.

All callbacks are optional — implement only the ones you need. Errors in callbacks are caught and ignored (they must not break the generation pipeline). Callbacks are called in order: global integrations first, then per-call integrations (matching upstream).

Sourceand on_start_event = {
  1. model : model_info;
  2. messages : Ai_provider.Prompt.message list;
  3. tools : (string * Core_tool.t) list;
  4. function_id : string option;
  5. metadata : (string * Trace_core.user_data) list;
}
Sourceand on_step_finish_event = {
  1. step_number : int;
  2. step : Generate_text_result.step;
  3. function_id : string option;
  4. metadata : (string * Trace_core.user_data) list;
}
Sourceand on_tool_call_start_event = {
  1. step_number : int;
  2. model : model_info;
  3. tool_name : string;
  4. tool_call_id : string;
  5. args : Yojson.Basic.t;
  6. function_id : string option;
  7. metadata : (string * Trace_core.user_data) list;
}
Sourceand on_tool_call_finish_event = {
  1. step_number : int;
  2. model : model_info;
  3. tool_name : string;
  4. tool_call_id : string;
  5. args : Yojson.Basic.t;
  6. result : tool_call_outcome;
  7. duration_ms : float;
  8. function_id : string option;
  9. metadata : (string * Trace_core.user_data) list;
}
Sourceand tool_call_outcome =
  1. | Success of Yojson.Basic.t
  2. | Error of string
Sourceand on_finish_event = {
  1. steps : Generate_text_result.step list;
  2. total_usage : Ai_provider.Usage.t;
  3. finish_reason : Ai_provider.Finish_reason.t;
  4. function_id : string option;
  5. metadata : (string * Trace_core.user_data) list;
}

Settings

Sourcetype t

Telemetry settings, enabling or disabling the logging of various pieces of information such as inputs or outputs or metadata

Sourceval create : ?enabled:bool -> ?record_inputs:bool -> ?record_outputs:bool -> ?function_id:string -> ?metadata:(string * Trace_core.user_data) list -> ?integrations:integration list -> ?traceparent:string -> unit -> t
Sourceval enabled : t -> bool
Sourceval record_inputs : t -> bool
Sourceval record_outputs : t -> bool
Sourceval function_id : t -> string option
Sourceval metadata : t -> (string * Trace_core.user_data) list
Sourceval integrations : t -> integration list
Sourceval trace_context : t -> trace_context option

Attribute Selection

Sourcetype attr =
  1. | Always of Trace_core.user_data
  2. | Input of unit -> Trace_core.user_data
  3. | Output of unit -> Trace_core.user_data

Attribute that may be conditionally recorded.

  • Always v: recorded whenever telemetry is enabled
  • Input f: recorded only when record_inputs is true; f evaluated lazily
  • Output f: recorded only when record_outputs is true; f evaluated lazily
Sourceval select_attributes : t -> (string * attr) list -> (string * Trace_core.user_data) list

Select attributes respecting telemetry settings. Returns [] immediately when enabled is false.

Sourceval assemble_operation_name : operation_id:string -> t -> (string * Trace_core.user_data) list

Operation Name Assembly

Builds the standard operation name attributes matching upstream: operation.name, resource.name, ai.operationId, ai.telemetry.functionId.

Sourceval base_attributes : provider:string -> model_id:string -> settings_attrs:(string * Trace_core.user_data) list -> headers:(string * string) list -> t -> (string * Trace_core.user_data) list

Base Telemetry Attributes

Model info, call settings, user metadata, and request headers. Used on every span.

Sourceval settings_attributes : ?max_output_tokens:int -> ?temperature:float -> ?top_p:float -> ?top_k:int -> ?stop_sequences:string list -> ?seed:int -> ?frequency_penalty:float -> ?presence_penalty:float -> ?max_retries:int -> unit -> (string * Trace_core.user_data) list

Build settings attributes from call options. Only includes non-None values.

Optional Attribute Helpers

Build a single-element attribute list from an option value, or [] when None. Useful for building span data from optional call settings and response fields.

Sourceval opt_attr : string -> ('a -> Trace_core.user_data) -> 'a option -> (string * Trace_core.user_data) list
Sourceval opt_string_attr : string -> string option -> (string * Trace_core.user_data) list
Sourceval opt_int_attr : string -> int option -> (string * Trace_core.user_data) list
Sourceval opt_float_attr : string -> float option -> (string * Trace_core.user_data) list

Lwt Span Helpers

An Lwt-aware ambient span provider (backed by Lwt.key) is installed at module load time. This makes Trace_core.current_span work across Lwt fibers, so nested with_span calls automatically form a parent-child hierarchy without explicit ~parent passing.

Sourceval with_span : ?parent:Trace_core.span -> __FILE__:string -> __LINE__:int -> data:(unit -> (string * Trace_core.user_data) list) -> string -> (Trace_core.span -> 'a Lwt.t) -> 'a Lwt.t

with_span ~__FILE__ ~__LINE__ ~data name f opens a span, sets it as the ambient current span (via Lwt.with_value), runs f span, and closes the span when the Lwt promise settles (via Lwt.on_termination).

When no Trace_core collector is installed, f receives a dummy span and no overhead is incurred.

Conditional Helpers

Convenience wrappers for use in generate_text and stream_text. When telemetry is None or enabled = false, these are zero-cost.

Sourceval maybe_span : t option -> string -> __FILE__:string -> __LINE__:int -> data:(unit -> (string * Trace_core.user_data) list) -> (Trace_core.span -> 'a Lwt.t) -> 'a Lwt.t

Conditionally wrap in a telemetry span. When telemetry is None or disabled, f is called with Trace_core.Collector.dummy_span.

Sourceval maybe_notify : t option -> (t -> unit Lwt.t) -> unit Lwt.t

Fire a telemetry notification when enabled; otherwise Lwt.return_unit.

Sourceval make_model_info : provider:string -> model_id:string -> model_info

Build a model_info from provider and model ID strings.

Sourceval tool_calls_to_json_string : Generate_text_result.tool_call list -> string

Serialize tool calls to a JSON string for telemetry attributes.

Precompute Helpers

One-shot telemetry setup shared by generate_text and stream_text. Extracts model info, settings, and base attributes. When telemetry is None or disabled, returns zero-cost defaults.

Sourcetype precomputed = {
  1. model_info : model_info;
  2. function_id_ : string option;
  3. metadata_ : (string * Trace_core.user_data) list;
  4. base_data : (string * Trace_core.user_data) list;
}

Precomputed telemetry values, extracted once per operation.

Sourceval precompute : operation_id:string -> model:(module Ai_provider.Language_model.S) -> ?max_output_tokens:int -> ?temperature:float -> ?top_p:float -> ?top_k:int -> ?stop_sequences:string list -> ?seed:int -> ?max_retries:int -> ?headers:(string * string) list -> t option -> precomputed

Step Span Attribute Builders

Shared helpers that build span attributes for step spans (doGenerate / doStream) and tool call spans. These prevent attribute key drift between generate_text and stream_text.

Sourceval step_request_attrs : operation_id:string -> model_info:model_info -> current_messages:Ai_provider.Prompt.message list -> tools:(string * Core_tool.t) list -> tool_choice:Ai_provider.Tool_choice.t option -> ?max_output_tokens:int -> ?temperature:float -> ?top_p:float -> ?top_k:int -> ?stop_sequences:string list -> t -> (string * Trace_core.user_data) list

Build request-side attributes for a step span.

Sourceval step_response_attrs : text:string -> reasoning:string -> tool_calls:Generate_text_result.tool_call list -> finish_reason:Ai_provider.Finish_reason.t -> usage:Ai_provider.Usage.t -> ?response_id:string -> ?response_model:string -> t -> (string * Trace_core.user_data) list

Build response-side attributes for a step span.

Sourceval final_response_attrs : text:string -> reasoning:string -> finish_reason:Ai_provider.Finish_reason.t -> usage:Ai_provider.Usage.t -> t -> (string * Trace_core.user_data) list

Build final response attributes for the root span.

Sourceval tool_call_span_data : model_info:model_info -> tool_name:string -> tool_call_id:string -> args:Yojson.Basic.t -> t -> (string * Trace_core.user_data) list

Build initial span data for a tool call span.

Sourceval tool_call_result_attrs : result:Yojson.Basic.t -> t -> (string * Trace_core.user_data) list

Build result attributes to add to a tool call span after execution.

Integration Values

Sourceval no_integration : integration

An empty integration with no callbacks. Useful as a starting point for building partial integrations:

  { Telemetry.no_integration with
    on_finish = Some (fun event -> ...);
  }

Integration Notification

Notify all integrations (per-call + global) of an event. Errors are caught and logged to stderr.

Sourceval notify_on_start : t -> on_start_event -> unit Lwt.t
Sourceval notify_on_step_finish : t -> on_step_finish_event -> unit Lwt.t
Sourceval notify_on_tool_call_start : t -> on_tool_call_start_event -> unit Lwt.t
Sourceval notify_on_tool_call_finish : t -> on_tool_call_finish_event -> unit Lwt.t
Sourceval notify_on_finish : t -> on_finish_event -> unit Lwt.t

Global Integration Registry

Sourceval register_global_integration : integration -> unit

Register an integration that receives events from all AI SDK operations. Useful for application-wide logging or metrics.

Sourceval clear_global_integrations : unit -> unit

Remove all global integrations. Primarily for testing.