Skip to main content

Session Management

tj.init()

Configure provider imports and legacy SDK helpers. The generated API client and the trajectory.lib upload workflows do not require tj.init().

Harness telemetry

During a live rollout, the harness writes events, rewards, and completion through the generated client. These calls require an API key and an in-progress trajectory_id.
event_id and reward_id dedupe retries. New events or rewards after the trajectory is terminal are rejected. complete() is idempotent for an already-completed trajectory.

Benchmarks

Runtime-backed benchmark authoring

Author a generated BenchmarkSpec, then use trajectory.lib.benchmarks.submit() to upload artifacts and bounded task parts. It returns a BenchmarkOperation after the upload is accepted; registration and optional runtime image builds continue on the server. This workflow requires the asynchronous ingestion backend to be deployed and enabled.
ImageRef() accepts an immutable registry/image@sha256:... reference, a bpt_ blueprint ID, or an im- Modal image ID. RuntimeRef() refers to an existing organization runtime. DockerfileBuild() resolves the Dockerfile relative to root; its parent directory is the build context, and root-level .dockerignore rules determine which files are uploaded. Unresolved runtimes, mutable image references, and empty run commands are rejected before session creation. The runtime owns environment interaction and reports rewards through log_reward.

trajectory.lib.benchmarks.submit()

To add or update tasks, submit another manifest with bench_id set to the existing benchmark ID. Each task name is its stable key. Async append uploads the supplied artifacts and skips unchanged task writes on the server. Each submission has its own operation and idempotency key.

Operation status and results

get_operation(client, operation_id) returns a handle without making a request. operation.refresh() retrieves a BenchmarkIngestionOperationStatus. operation.result(timeout=1800, poll_interval=2) waits for a terminal status and returns a BenchmarkOperationResult. A TimeoutError stops local waiting; server processing continues. Use timeout=None to wait without a deadline. result.status.ready is true only when builds were explicitly requested, the operation succeeded, all submitted tasks registered, and every required runtime is ready. Registration-only success leaves ready false. result.tasks(), runtimes(), failures(), and affected_tasks(runtime_id) iterate paginated results. Failures are typed BenchmarkIngestionFailure objects. Pass cursor=failure.affected_tasks_cursor to affected_tasks() to start at a supplied failure cursor. Partial failure raises BenchmarkPartialFailureError; a failed operation raises BenchmarkOperationError. Both are available from trajectory.lib.benchmark_operations and expose partial_result and failures. Successful registrations and runtimes remain available. See benchmark submission operations for failure handling and limits.

Blocking and prepared-upload helpers

benchmarks.push(client, manifest, root=Path(".")) and benchmarks.append(client, bench_id, manifest, root=Path(".")) submit an operation and wait for registration. They preserve their successful IngestBenchmarkResponse and BenchmarkTaskAppendSummary return types, respectively, and raise on failed or partially failed operations. Use submit() for image builds, custom waiting, and reconnection. trajectory.lib.upload_benchmark() and trajectory.lib.append_benchmark_tasks() accept a prepared BenchmarkSpec or mapping and UploadFile objects. Small requests retain the legacy registration and append flow; large manifests or artifact maps automatically use ingestion operations and wait for completion. The small append path diffs tasks before uploading and commits changed tasks in batches. Its batch limits do not control task parts on the ingestion path.
Successful task writes remain if a later batch or ingestion step fails. Re-running the same input skips unchanged tasks. Async ingestion does not perform the legacy unchanged-artifact upload optimization.

Trace Import

tj.list_conversations()

List available conversations from the configured provider.

tj.import_conversations()

Import conversations and return one Trajectory per conversation.

tj.transform()

Transform raw provider data into a Trajectory without fetching. Useful for custom pipelines that already have the source payload.

Building Trajectories

See Bring Your Own Data for the full walkthrough.

tj.build_trajectory_from_messages()

Build a Trajectory from a flat list of Message objects. Cumulative steps, tool-call metrics, and telemetry fields (content hash, idempotency key) are computed automatically.
task_metadata recognizes num_turns, total_tokens, total_cost, and completion_tokens; other keys are ignored.

tj.build_trajectory_from_parsed()

Build a Trajectory from a ParsedConversation. Provider subclasses delegate to this so the ParsedConversation → Trajectory logic has a single implementation.

tj.build_reward_from_scalar()

Build a single-component Reward from a numeric score. scaled_value is normalized to [0, 1] using score_range.

Message Recipes

Adapters from common third-party message formats into Message objects. All recipes fail loud on unexpected input — see Bring Your Own Data for examples.

Helpers


Trace Workflow

See Linking Events to Trajectories for the workflow.

tj.start_trace()

Create a TraceContext for buffering correlated telemetry and trajectory data.
If trace_id is omitted, the SDK generates a UUID4 hex string.

TraceContext

trace.event(event_type, properties=None, *, user_id=None, trajectory_id=None, source="sdk", metadata=None) -> TelemetryEvent Append a TelemetryEvent to trace.events with trace_id and session_id set to trace.trace_id. trace.build_trajectory(messages, *, data_source, conversation_id=None, ...) -> Trajectory Convenience wrapper around build_trajectory_from_messages that injects trace_id and defaults conversation_id to trace_id. Accepts the same kwargs as build_trajectory_from_messages (minus trace_id).

upload_trace()

Upload trajectories, stamp matching events with returned trajectory_id values, then ingest the events. Import this workflow from trajectory.lib.
Each input trajectory must carry a unique string trace_id. The result contains typed upload and telemetry summaries plus the event mappings as sent. A trajectory failure raises PartialUploadError; a missing correlation ID raises TraceCorrelationError. In either case, no telemetry is ingested. TraceCorrelationError is also raised when the upload response omits an item for any submitted trajectory, even if the call contained no events. Events are serialized before trajectory upload so their trace_id values can be inspected. An unsupported JSON value raises TypeError before any request is made. Events that serialize but fail telemetry field validation are returned in result.telemetry.failures; valid events in the same call are still ingested and the uploaded trajectories remain stored.

Upload & Ingest

upload_trajectories()

Filter empty trajectories, batch valid trajectories, and upload through the generated client. The workflow uses up to eight workers, batches at 1,000 items or 128 MiB, and gives each upload request a 120-second timeout.
Returns a typed summary:

ingest_events()

Validate telemetry locally, split valid events into bounded chunks, and ingest them through the generated client.
The result contains ingested, total skipped, and structured failures. Local validation requires a non-empty event_type, a non-empty session_id, mapping properties, and an ISO 8601 timestamp. Events that are not mappings or contain unsupported JSON values are also returned as structured failures. Failure indices are mapped back to the original input list. chunk_size must be an integer greater than zero; other types raise TypeError, while zero and negative values raise ValueError.

tj.save()

Save trajectories to JSON files on disk. Each file is named {output_dir}/{conversation_id}.json.

Model ID Helpers

For chaining a Trajectory-served chat completion back to its trajectory id, the backend returns the model id on the response headers.

Primitives

All primitives are frozen dataclasses unless noted.

Trajectory

Task

Step

Message

ToolCall

ToolResponse

ToolDefinition

Reward & RewardComponent

TelemetryEvent

See Telemetry Events for the full guide.

TelemetryIngestSummary

Telemetry

TrajectoryMetrics & ExecutionMetrics

ConversationSummary


Type Aliases