Mirascope (tracing)

Mirascope is a Python toolkit for building LLM applications with a unified model API, structured outputs, streaming, and typed tools. respan-instrumentation-mirascope traces Mirascope 2.x model operations as canonical Respan chat spans and toolkit execution as tool spans.

Synchronous and asynchronous calls are supported. Streaming spans stay open until the underlying stream is consumed, so their timing, output, usage, and iterator errors describe the complete stream.

Create an account at platform.respan.ai and grab an API key.

Run npx @respan/cli setup to set up with your coding agent.

Setup

1

Install packages

$pip install respan-ai respan-instrumentation-mirascope "mirascope[openai]"
2

Set environment variables

$export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"
$export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"

Use the credential required by your selected Mirascope provider when it is not OpenAI.

3

Initialize and call a model

1from mirascope import llm
2from respan import Respan
3from respan_instrumentation_mirascope import MirascopeInstrumentor
4
5respan = Respan(
6 app_name="mirascope-support-agent",
7 instrumentations=[MirascopeInstrumentor()],
8)
9model = llm.Model("openai/gpt-4o-mini")
10
11try:
12 response = model.call("Explain distributed tracing in one sentence.")
13 print(response.text())
14finally:
15 respan.shutdown()
4

View your trace

Open the Traces page to inspect the Mirascope chat span, provider, model, messages, usage, and status.

Supported operations

Mirascope surfaceRespan log typeLifecycle
Model.call and Model.call_asyncchatEnds when the call returns or raises.
Context-aware model callschatPreserves the active Respan parent context.
Model.stream and Model.stream_asyncchatEnds when the stream is consumed, fails, or is abandoned.
Toolkit executiontoolCaptures the tool name, arguments, result, and error status.

Model calls include prompts, completions, tool definitions and calls, model and provider identifiers, and token usage when the provider response supplies them. Errors are re-raised unchanged after the span records OpenTelemetry error status, status_code, and error.message.

Stream model output

The stream span finishes when text_stream() is exhausted:

1from mirascope import llm
2
3model = llm.Model("openai/gpt-4o-mini")
4response = model.stream("Count from one to three.")
5
6for text in response.text_stream():
7 print(text, end="")

For an asynchronous stream, await stream_async() and consume its text stream with async for:

1from mirascope import llm
2
3
4async def stream_answer() -> str:
5 model = llm.Model("openai/gpt-4o-mini")
6 response = await model.stream_async("Count from four to six.")
7 parts = []
8 async for text in response.text_stream():
9 parts.append(text)
10 return "".join(parts)

Trace tool execution

Tools passed to a model call are captured on the chat span. When Mirascope executes a returned tool call, the execution becomes a child tool span.

1import math
2
3from mirascope import llm
4
5
6@llm.tool
7def square_root(number: float) -> float:
8 """Calculate the square root of a number."""
9 return math.sqrt(number)
10
11
12model = llm.Model("openai/gpt-4o-mini")
13response = model.call(
14 "Use the tool to calculate the square root of 144.",
15 tools=[square_root],
16)
17results = response.execute_tools() if response.tool_calls else []
18print(results)

Configuration

ParameterTypeDefaultDescription
capture_contentboolTrueCapture model messages, tool definitions, arguments, and outputs.
instrumentationslist[]Pass [MirascopeInstrumentor()] to activate Mirascope tracing.
api_keystr | NoneNoneFalls back to RESPAN_API_KEY.
base_urlstr | NoneNoneFalls back to RESPAN_BASE_URL.
customer_identifierstr | NoneNoneDefault customer identifier for all emitted spans.
metadatadict | NoneNoneDefault metadata attached to all emitted spans.

Disable content capture

1from respan import Respan
2from respan_instrumentation_mirascope import MirascopeInstrumentor
3
4respan = Respan(
5 instrumentations=[MirascopeInstrumentor(capture_content=False)],
6)

With capture disabled, messages, tool definitions, arguments, and model outputs are omitted. Provider, model, usage, timing, status, and exception type remain available.

Add trace context

1from respan import Respan
2
3with Respan.propagate_attributes(
4 customer_identifier="user_123",
5 thread_identifier="conversation_abc",
6 trace_group_identifier="mirascope_support_workflow",
7 metadata={"plan": "pro"},
8):
9 response = model.call("Draft a concise answer to this support request.")

Do not combine this adapter with mirascope.ops.instrument_llm() unless you intentionally want two independent telemetry pipelines for each operation.