This scaffold explains the agent-facing contracts provided by codon_sdk. Flesh it out as APIs mature and new helper modules appear.
- Module:
codon_sdk.agents.workload - Class:
Workload - Purpose: Defines the portable workload contract that framework adapters must implement. Captures metadata (name, version, description, tags), registers Agent Class / Logic IDs, and exposes graph-building plus execution hooks.
- Expectations: Subclasses auto-register logic in
_register_logic_group, wrap callables inadd_node, manage topology viaadd_edge, and bind a run todeployment_idinsideexecutewhile emitting telemetry. - Instrumentation mixins: Framework packages ship their own mixins (see
docs/guides/workload-mixin-guidelines.md) to exposefrom_*constructors while keeping the core SDK agnostic. - Reference implementation: Each instrumentation package should define mixins inside its own namespace (e.g.,
codon.instrumentation.langgraph.LangGraphWorkloadMixin). - Adapters:
LangGraphWorkloadAdapter.from_langgraph(...)wraps existing LangGraph graphs and returns an instrumented graph that preserves native invocation semantics while emitting Codon telemetry; use it as a model for future adapters. - LangGraph compatibility:
codon-instrumentation-langgraph0.1.0a5is the final release that supports LangGraph 0.3.x. Starting in0.2.0a0, the adapter targets LangChain/LangGraph v1.x only and will emit aDeprecationWarningon older versions.
- Module:
codon_sdk.agents.codon_workload - Class:
CodonWorkload - Purpose: Provide a token-based runtime for bespoke agents, including audit-ready provenance capture.
- Execution model: Nodes receive a token
message, interact with a runtime handle to emit downstream tokens, record custom events, share per-run state, and optionally halt execution. - Execution context: Every node also receives a
contextmapping containingworkload_id,logic_id,workload_run_id,deployment_id, and organisation metadata so instrumentation layers can stamp spans and logs with the identifiers required by the Codon telemetry schema. - Telemetry payload:
runtime.telemetryexposes a sharedNodeTelemetryPayload(codon_sdk.instrumentation.telemetry) that instrumentation mixins use to enrich spans/logs/metrics with token usage, model metadata, network calls, and rollout identifiers. - Streaming:
execute_streaming_async(...)exposes an async generator ofStreamEvents (token_enqueued,node_completed,workflow_finished, etc.).execute_streaming(...)wraps it for synchronous code, making it a drop-in replacement for frameworks that already usestream/astreampatterns. - Audit trail:
execute(...)returns anExecutionReportwith node results plus an immutable ledger of all enqueue/dequeue and completion events. - Error handling: Raises
WorkloadRegistrationErrorfor registration issues andWorkloadRuntimeErrorfor runtime violations (unknown routes, step limits, etc.). - Async support: Run
await workload.execute_async(...)inside event loops; the synchronousexecute(...)delegates to the async implementation for convenience.
from codon_sdk.agents import CodonWorkload
def ingest(message, *, runtime, context):
lines = message["document"].splitlines()
runtime.emit("summarize", {"lines": lines})
return {"line_count": len(lines)}
def summarize(message, *, runtime, context):
runtime.record_event("summary_started", {"lines": len(message["lines"])})
return {
"title": message["lines"][0] if message["lines"] else "",
"line_count": len(message["lines"]),
"deployment": context["deployment_id"],
}
workload = CodonWorkload(name="ReportAgent", version="0.2.0")
workload.add_node(ingest, name="ingest", role="parser")
workload.add_node(summarize, name="summarize", role="responder")
workload.add_edge("ingest", "summarize")
report = workload.execute(
{"document": "Status Update\nWeek 42"},
deployment_id="dev-cluster-1",
invoked_by="cli",
)
# In async contexts (e.g., notebooks) prefer:
# report = await workload.execute_async(...)
print(report.node_results("summarize")[-1]["line_count"]) # -> 2
print(len(report.ledger)) # -> auditable event streamFor a full walkthrough, see docs/guides/codon-workload-quickstart.md.
- Purpose: Provide immutable, hashed descriptors for agent nodes so telemetry, caching, and orchestration can agree on identity.
- Current usage:
NodeSpecintrospects Python callables, requiresORG_NAMESPACE, and produces span attributes defined inNodeSpecSpanAttributes. - To document: Validation rules, strategies for functions without type hints, and migration guidance when schema versions bump.
- Ensure
ORG_NAMESPACEis set in the environment (or passorg_namespaceexplicitly). - Annotate callable inputs/outputs—schemas are derived from type hints.
- Initialize
NodeSpecduring module import so IDs stay stable. - Surface
nodespec.idand related metadata in your agent’s telemetry or persistence layer.
- Purpose: Detect duplicate workloads and support idempotent scheduling.
- Key classes:
AgentClass,Topology,LogicRequest, and helpers inlogic_id. - To expand: Examples involving multiple nodes, topology edges, and how logic IDs interact with retries or cache stores.
codon_sdk.instrumentation.schemas.telemetry.spansdefines span names and base attributes shared across frameworks.- Document additions here before using them in instrumentation packages to keep alignment.
- Telemetry initialization is centralized in
codon_sdk.instrumentation.initialize_telemetry, with default endpointhttps://ingest.codonops.ai:4317andx-codon-api-keyheader support (args override env; env varsOTEL_EXPORTER_OTLP_ENDPOINT,CODON_API_KEY,OTEL_SERVICE_NAMEremain valid). Optional attach mode (attach_to_existingarg orCODON_ATTACH_TO_EXISTING_OTEL_PROVIDERenv) lets you add Codon’s exporter to an existing tracer provider instead of replacing it—useful when OTEL auto-instrumentation is already active. - CodonWorkload can emit spans natively when
enable_tracing=True(default: False). It uses the global tracer provider configured viainitialize_telemetryto create one span per node execution with workload/org/deployment IDs, logic/run IDs, and NodeSpec attributes. Leave it disabled if another instrumentation layer (e.g., LangGraph adapter) is already wrapping nodes to avoid duplicate spans. - Organization metadata: when an API key is present and an org lookup URL is configured,
initialize_telemetrywill resolve the organization and namespace and apply them to telemetry resources and as the defaultorg_namespacefor NodeSpecs (overridingORG_NAMESPACE). If no org is resolved, NodeSpecs fall back toORG_NAMESPACEor a placeholder with a warning to avoid crashes. - Auto-instrumentation: a configurator hook exists (
OTEL_PYTHON_CONFIGURATOR=codon_sdk.instrumentation.config:otel_configure) to run Codon telemetry init duringopentelemetry-instrument, but this path is not yet stable end-to-end. For reliable results, callinitialize_telemetry()explicitly; revisit the configurator once validated. - Span org attributes:
codon.organization.idnow prefers the ID resolved via API-key lookup or the execution context, whileorg.namespaceuses the namespace; they are no longer forced to the same value when both are available.
- Capture requirements for new schema fields inside each class docstring and mirror them here.
- Outline testing expectations (e.g.,
pytesttargets) as they are established. - Note backward-compatibility policies once releases begin.
- How will version negotiation work between agents and orchestration layers?
- Do we standardize error reporting alongside spans?
- Should helper utilities exist for agents that are not framework-backed?
Update this file every time you introduce a new agent contract or refine the public API. Treat it as the canonical reference for downstream instrumentation packages.