Skip to main content

Convert ATIF agent trajectories to OpenTelemetry protobuf spans with pluggable uploaders.

Project description

harbor-atif2otel

Convert ATIF agent trajectories to OpenTelemetry spans for visualization in any OTel-compatible backend.

Install

pip install harbor-atif2otel

Quick Start

import json
from harbor_atif2otel import convert_trajectory
from harbor_atif2otel.uploaders.mlflow_protobuf import MlflowProtobufUploader

# Load an ATIF trajectory
with open("trajectory.json") as f:
    trajectory = json.load(f)

# Convert to OTel ResourceSpans
resource_spans = convert_trajectory(trajectory)

# Upload to MLflow
uploader = MlflowProtobufUploader(
    endpoint="https://mlflow.example.com",
    experiment_name="my-eval",
    token="my-auth-token",
    workspace="default",
)
uploader.upload(resource_spans)

API

convert_trajectory(trajectory, trace_seed=None, service_name="harbor", max_attribute_bytes=10240)

Convert a single ATIF trajectory dict to an OTel ResourceSpans protobuf.

  • trajectory: Parsed ATIF JSON (dict)
  • trace_seed: Optional seed for deterministic trace/span IDs. Defaults to session_id or trajectory_id.
  • service_name: OTel resource service.name attribute
  • max_attribute_bytes: Truncation limit for large string attributes

Returns an opentelemetry.proto.trace.v1.trace_pb2.ResourceSpans.

convert_trajectories(trajectories, **kwargs)

Batch convert. Returns list[ResourceSpans].

validate_trajectory(trajectory)

Validate an ATIF trajectory dict. Returns list[str] of issues (empty = valid).

ATIF → OTel Mapping

ATIF Concept OTel Span
Trajectory Root AGENT span
Conversational turn Nested AGENT span (multi-turn only)
Agent step (source: "agent") LLM span
Tool call (tool_calls[]) TOOL span (sibling of LLM)
Subagent delegation Nested AGENT span tree

Span Hierarchy

Single-turn:

AGENT (root)
├── LLM (agent step 1)
├── TOOL (Read)
├── TOOL (Edit)
├── LLM (agent step 2)
└── TOOL (Bash)

Multi-turn:

AGENT (root)
├── AGENT (turn 1)
│   ├── LLM
│   └── TOOL
└── AGENT (turn 2)
    ├── LLM
    └── TOOL

Span Attributes

Spans carry OpenInference semantic attributes for LLM observability:

Attribute Set On Source
openinference.span.kind All AGENT / LLM / TOOL
session.id All trajectory.session_id
llm.model_name AGENT, LLM agent.model_name or step.model_name
llm.token_count.prompt AGENT, LLM final_metrics or step.metrics
llm.token_count.completion AGENT, LLM final_metrics or step.metrics
llm.token_count.prompt_details.cache_read LLM step.metrics.cached_tokens
llm.cost.total AGENT, LLM final_metrics.total_cost_usd or step.metrics.cost_usd
tool.name TOOL tool_call.function_name
input.value All Message or arguments
output.value All Response or observation result

ATIF v1.7 Feature Support

Feature Status
Core steps (user/agent/system) Supported
Tool calls + observation matching Supported
Multi-turn splitting Supported
final_metrics / metrics token counts Supported
reasoning_content Supported
tool_definitions Supported
llm_call_count: 0 (deterministic dispatch) Supported
llm_call_count > 1 (aggregated) Supported
is_copied_context filtering Supported
subagent_trajectories embedding Supported
Multimodal ContentPart (v1.6+) Supported (text extracted, images as metadata)
context_management system steps Supported

Harbor Job Plugin

The package includes a Harbor job plugin (OtelPlugin) that automatically exports OTel traces during harbor run. It supports two modes:

Streaming — upload each trial as it completes

harbor run --dataset terminal-bench@2.0 --agent claude-code \
  --plugin atif2otel \
  --plugin-kwarg endpoint=https://mlflow.example.com \
  --plugin-kwarg experiment_name=my-eval

Batch — write flat files after the job ends

harbor run --dataset terminal-bench@2.0 --agent claude-code \
  --plugin atif2otel \
  --plugin-kwarg output_dir=./otel-traces \
  --plugin-kwarg encoding=json

Both modes can be combined (stream to endpoint + write files). Mode is auto-detected from which outputs are configured, or set explicitly with --plugin-kwarg mode=stream|batch.

Plugin kwargs

Kwarg Env var fallback Description
endpoint OTEL_EXPORTER_OTLP_ENDPOINT OTLP endpoint URL
output_dir HARBOR_OTEL_OUTPUT_DIR Directory for flat file output
experiment_name MLFLOW_EXPERIMENT_NAME MLflow experiment name (defaults to job name)
token MLFLOW_TRACKING_TOKEN Auth token for the endpoint
workspace MLflow workspace (default: "default")
encoding "json" (JSONL) or "pb" (protobuf)
mode "auto", "stream", or "batch"

Shared Export API

The export functions are available for programmatic use:

from harbor_atif2otel.export import export_trial, export_trials

# Single trial
rs = export_trial(Path("jobs/my-job/trial-001"))

# Batch with file output
result = export_trials(trial_dirs, output=Path("out.jsonl"), encoding="json")
print(f"{result.converted} converted, {result.errors} errors")

Writing a Custom Uploader

Implement harbor_atif2otel.uploaders.base.Uploader:

from harbor_atif2otel.uploaders.base import Uploader
from opentelemetry.proto.trace.v1.trace_pb2 import ResourceSpans

class MyUploader(Uploader):
    def upload(self, resource_spans: ResourceSpans) -> None:
        # Serialize and send to your backend
        ...

The upload_batch() method is provided by the base class and calls upload() in a loop with error counting.

License

Apache 2.0 — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

harbor_atif2otel-0.1.0.tar.gz (37.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

harbor_atif2otel-0.1.0-py3-none-any.whl (18.4 kB view details)

Uploaded Python 3

File details

Details for the file harbor_atif2otel-0.1.0.tar.gz.

File metadata

  • Download URL: harbor_atif2otel-0.1.0.tar.gz
  • Upload date:
  • Size: 37.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for harbor_atif2otel-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7d359676ce328f01354beb0a9817fff8d52cc0a29d569d19582146e292d61065
MD5 d3b45966657cd2f9b188471de8b4d3d6
BLAKE2b-256 012e3e23f912e6f939e48488e4bf6065ff7af9dc48ae5b56cf1bf6de4f28d79a

See more details on using hashes here.

File details

Details for the file harbor_atif2otel-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: harbor_atif2otel-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 18.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for harbor_atif2otel-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0f3afd8e8da4650ab7dcb3ee86a1462575878fd3533dc392e37492698289e693
MD5 537af626fa2b7d28c72963601447b584
BLAKE2b-256 95d2d527047943e9c5a64d8b98f84be5827da16678e63b252cbf0e730714201a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page