coalex_context()¶
Context manager that creates a coalex.invocation parent span. All spans created inside this block are tagged with the agent metadata, making them queryable by agent_id, request_id, and version in the Coalex dashboard.
Signature¶
interface CoalexContextOptions {
agentId: string;
requestId?: string;
version?: string;
}
async function coalexContext<T>(
options: CoalexContextOptions,
fn: () => Promise<T> | T,
): Promise<T>
Callback pattern
The TypeScript SDK uses a callback pattern instead of Python's with statement. Pass your logic as an async function to coalexContext(). A synchronous variant coalexContextSync() is also available.
Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
agent_id |
str |
required | Identifier for the AI agent. Used to group all traces from the same agent in the dashboard. |
request_id |
str \| None |
None |
Unique request or invocation ID. Use this to correlate a single user request across multiple spans. |
version |
str \| None |
None |
Agent version string (e.g., "1.2.0", "canary"). Useful for A/B testing and rollback tracking. |
All parameters are keyword-only (enforced by *).
Returns¶
A context manager that yields None. Use it with with statements.
Span Attributes¶
The coalex.invocation parent span carries these attributes:
| Attribute | Set When | Value |
|---|---|---|
coalex.agent_id |
Always | Value of agent_id parameter |
coalex.request_id |
request_id is not None |
Value of request_id parameter |
coalex.agent_version |
version is not None |
Value of version parameter |
Attribute propagation
The CoalexAttributePropagator (configured by register()) automatically copies coalex.* attributes from the parent span to all child spans. This means every LLM call, retrieval, and tool invocation inside the context block inherits the agent metadata without manual tagging.
How It Works¶
- Obtains a tracer named
"coalex"from the globalTracerProvider. - Starts a new span named
"coalex.invocation"as the current span. - Sets the
coalex.*attributes on that span. - All spans created inside the
withblock become children of thecoalex.invocationspan. - When the block exits, the span ends automatically.
graph TD
A["coalex.invocation<br/>(coalex.agent_id=support-bot)"] --> B["openai.chat.completions<br/>(auto-instrumented)"]
A --> C["knowledge_base<br/>(@retrieval_span)"]
C --> D["embed<br/>(@embedding_span)"]
Examples¶
Basic usage¶
import coalex
from openai import OpenAI
coalex.register(api_key="your-key")
coalex.auto_instrument()
client = OpenAI()
with coalex.coalex_context(agent_id="support-bot", request_id="req-001"):
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "What is the refund policy?"}],
)
print(response.choices[0].message.content)
import { register, coalexContext, autoInstrument } from "@coalex-ai/sdk";
import OpenAI from "openai";
register({ apiKey: "your-key" });
autoInstrument();
const client = new OpenAI();
await coalexContext({ agentId: "support-bot", requestId: "req-001" }, async () => {
const response = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "What is the refund policy?" }],
});
console.log(response.choices[0].message.content);
});
With version tracking¶
await coalexContext({
agentId: "claims-processor",
requestId: "claim-2024-0042",
version: "2.1.0",
}, async () => {
// All spans inside here carry:
// - coalex.agent_id = "claims-processor"
// - coalex.request_id = "claim-2024-0042"
// - coalex.agent_version = "2.1.0"
const result = await processClaim(claimData);
});
Nested contexts¶
You can nest coalex_context blocks. The inner context creates a new parent span as a child of the outer one:
with coalex.coalex_context(agent_id="orchestrator", request_id="req-100"):
# Outer span: coalex.invocation (agent_id=orchestrator)
with coalex.coalex_context(agent_id="sub-agent-a", request_id="req-100-a"):
# Inner span: coalex.invocation (agent_id=sub-agent-a)
# This is a child of the outer coalex.invocation span
run_sub_agent_a()
with coalex.coalex_context(agent_id="sub-agent-b", request_id="req-100-b"):
run_sub_agent_b()
await coalexContext({ agentId: "orchestrator", requestId: "req-100" }, async () => {
// Outer span: coalex.invocation (agentId=orchestrator)
await coalexContext({ agentId: "sub-agent-a", requestId: "req-100-a" }, async () => {
// Inner span: coalex.invocation (agentId=sub-agent-a)
// This is a child of the outer coalex.invocation span
await runSubAgentA();
});
await coalexContext({ agentId: "sub-agent-b", requestId: "req-100-b" }, async () => {
await runSubAgentB();
});
});
Generating request IDs¶
Use uuid4 to generate unique request IDs:
Notes¶
coalex_context()requiresregister()to have been called first (so a globalTracerProviderexists). Ifregister()has not been called, spans are created on a no-op tracer and silently discarded.- The context manager is not reentrant -- do not reuse a single
coalex_contextinstance. Create a new one for each invocation. - The
request_iddoes not need to be globally unique, but it should be unique within a reasonable time window (e.g., per user session or per API request).
API Reference¶
coalex.context.coalex_context ¶
coalex_context(
*,
agent_id: str,
request_id: str | None = None,
version: str | None = None,
) -> Generator[None, None, None]
Create a parent span with Coalex attributes for all child spans.
All spans created inside this context are descendants of a
coalex.invocation span that carries the agent metadata.
This makes every child span queryable by agent_id, request_id,
and version in the Bronze layer.
Context vars are set before the span is created so that
CoalexAttributePropagator can propagate attributes even
across trace boundaries (e.g. when LangChain auto-instrumentors
create new root spans with separate trace IDs).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent_id
|
str
|
Identifier for the AI agent. |
required |
request_id
|
str | None
|
Unique request/invocation ID. |
None
|
version
|
str | None
|
Agent version string. |
None
|