Skip to content

prefactor_core.span_context module

Span context for automatic lifecycle management.

The SpanContext provides an interface for updating span data during execution and ensures proper cleanup when the span completes.

class prefactor_core.span_context.SpanContext(temp_id: str, span_manager: SpanManager, default_payload: dict[str, Any] | None = None)

Section titled “class prefactor_core.span_context.SpanContext(temp_id: str, span_manager: SpanManager, default_payload: dict[str, Any] | None = None)”

Bases: object

Context for an active span.

Returned by instance.span() / client.span() context managers.

Spans follow a three-phase lifecycle:

  1. Enter context — span is prepared locally (no HTTP call yet).
  2. “await span.start(payload)“ — POSTs the span to the API as active with the given params payload.
  3. “await span.complete(result)“ (or .fail() / .cancel()) — finishes the span with the appropriate terminal status.

cancelled before start is handled via pending → cancelled; once started, the span transitions from active to a terminal status.

If start() or a finish method is omitted, the context manager calls them automatically on exit (auto-start uses default_payload; the default finish status is complete), so explicit calls are opt-in.

Example:

async with instance.span("agent:llm_call") as span:
await span.start({"model": "claude-3-5-sonnet", "prompt": "Hi"})
try:
response = await call_llm(...)
await span.complete({"response": response, "tokens": 42})
except Exception as exc:
await span.fail({"error": str(exc)})
# Skip start entirely to cancel before any work begins:
async with instance.span("agent:retrieval") as span:
if not needed:
await span.cancel()
else:
await span.start({"query": "..."})
...

Finish the span with cancelled status.

Can be called before or after start(). If start() has not been called yet, the span is posted as pending then immediately cancelled — the API only accepts cancellation from the pending state, so this is always a valid sequence.

async complete(result: dict[str, Any] | None = None) → None

Section titled “async complete(result: dict[str, Any] | None = None) → None”

Finish the span with complete status.

  • Parameters: result – Optional result payload to attach to the span.

async fail(result: dict[str, Any] | None = None) → None

Section titled “async fail(result: dict[str, Any] | None = None) → None”

Finish the span with failed status.

  • Parameters: result – Optional result payload (e.g. error details).

Finish the span using whichever status was last set (default: complete).

Called automatically when exiting the context manager. Can also be called manually; subsequent calls are no-ops.

Get the span ID.

Before start() is called this returns the temporary local ID. After start() it returns the API-generated ID.

  • Returns: The span identifier.

Store result data to be sent when the span finishes.

The data is merged and sent as result_payload when the span finishes. Calling this does not finish the span.

  • Parameters: data – Dictionary of result data for the span.

async start(payload: dict[str, Any] | None = None) → None

Section titled “async start(payload: dict[str, Any] | None = None) → None”

Post the span to the API as active with the given params payload.

This triggers POST /api/v1/agent_spans. The span is created as pending so that any terminal status (complete, failed, cancelled) is a valid transition via the finish endpoint. Must be called at most once; subsequent calls are no-ops.

  • Parameters: payload – Optional params/inputs for the span (e.g. model name, prompt text, tool input). Stored as the span’s payload field in the API.