Skip to content

Commit e941d1a

Browse files
committed
Merge branch 'dev/docs' into docs-build
2 parents 709ed49 + d695f2f commit e941d1a

4 files changed

Lines changed: 95 additions & 6 deletions

File tree

docs/public/building-from-scratch.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,32 @@ CodonWorkload is the foundation for building observable AI agents. Whether you b
1616

1717
For complete method signatures and parameters, see the [API Reference](api-reference.md).
1818

19+
### Execution and Results
20+
21+
**`execute(payload, *, deployment_id, entry_nodes=None, max_steps=1000)`**
22+
23+
Executes the workload synchronously and returns an `ExecutionReport`. This is the primary method for running workloads in synchronous contexts.
24+
25+
- **Async alternative**: Use `execute_async()` for async/await environments
26+
- **Parameters**: See [execute() API reference](api-reference.md#codon_sdk.agents.CodonWorkload.execute) for details
27+
28+
**`report.node_results(node_name)`**
29+
30+
Retrieves all outputs from a specific node during workload execution. Returns a list of results in execution order.
31+
32+
- **Usage**: `final_output = report.node_results("output_node")[-1]` gets the most recent result
33+
- **Multiple executions**: If a node runs multiple times, you get all results as a list
34+
- **Parameters**: See [node_results() API reference](api-reference.md#codon_sdk.agents.ExecutionReport.node_results) for details
35+
36+
**`report.ledger`**
37+
38+
Complete audit trail of execution events for compliance monitoring and debugging.
39+
40+
**Key Properties**
41+
42+
- **`logic_id`**: Unique identifier for this specific workload configuration. Changes when nodes/edges are modified. See [logic_id API reference](api-reference.md#codon_sdk.agents.CodonWorkload.logic_id).
43+
- **`agent_class_id`**: Stable identifier for this workload type (format: 'name:version'). Consistent across deployments. See [agent_class_id API reference](api-reference.md#codon_sdk.agents.CodonWorkload.agent_class_id).
44+
1945
## Key Concepts
2046

2147
**Nodes**: Individual Python functions that perform specific tasks (e.g., "summarize", "validate", "format"). Each node receives input, processes it, and can emit output to other nodes.
@@ -106,7 +132,7 @@ workload.add_node(prompt_builder, name="prompt_builder", role="format_prompt")
106132
workload.add_edge("prompt_builder", "call_model")
107133
workload.add_edge("call_model", "finalize")
108134

109-
# Execute the workload
135+
# Execute the workload (also available: execute_async() for async contexts)
110136
report = workload.execute({"question": "What is the meaning of life, the universe, and everything?"}, deployment_id="local")
111137

112138
# Check results
@@ -183,6 +209,7 @@ def build_multi_agent_workload() -> CodonWorkload:
183209
# Use the multi-agent workload
184210
multi_agent = build_multi_agent_workload()
185211
project = {"topic": "The impact of community gardens on urban wellbeing"}
212+
# Execute workload (also available: execute_async() for async contexts)
186213
multi_report = multi_agent.execute(project, deployment_id="demo", max_steps=20)
187214
final_document = multi_report.node_results("writer")[-1]
188215
```
@@ -218,13 +245,15 @@ When you execute workloads after initializing telemetry, each node function call
218245

219246
### Runtime Operations
220247
The `runtime` parameter provides access to workflow operations:
248+
221249
- `runtime.emit(node_name, payload)` - Send tokens to other nodes
222250
- `runtime.record_event(event_type, metadata={})` - Add custom audit entries
223251
- `runtime.state` - Shared dictionary for coordination between nodes
224252
- `runtime.stop()` - Halt execution early
225253

226254
### Audit Ledger
227255
Every workflow execution generates a comprehensive audit trail:
256+
228257
- Token enqueue/dequeue events
229258
- Node completion events
230259
- Custom events via `runtime.record_event()`

docs/public/instrumentation/index.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,6 @@ pip install codon-sdk
2828
pip install codon-instrumentation-langgraph
2929
```
3030

31-
Each integration provides telemetry and observability for its respective framework while working alongside the core Codon SDK.
31+
Each integration provides telemetry and observability for its respective framework while working alongside the core Codon SDK.
32+
33+
**Universal Interface:** All instrumentation packages convert framework-specific workflows into standard CodonWorkloads. This means you get the same `execute()`, `execute_async()`, `node_results()`, and other methods regardless of whether you built from scratch or wrapped an existing framework. See [Execution and Results](../building-from-scratch.md#execution-and-results) for the complete interface.

docs/public/instrumentation/langgraph.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,18 @@ workload = LangGraphWorkloadAdapter.from_langgraph(
7474
)
7575

7676
initial_state = {"topic": "Sustainable cities"}
77+
# Execute workload (also available: execute_async() for async contexts)
7778
report = workload.execute({"state": initial_state}, deployment_id="dev")
7879
print(report.node_results("writer")[-1])
7980
print(f"Ledger entries: {len(report.ledger)}")
8081
```
8182

8283
### What Happened?
83-
1. Every LangGraph node was registered as a Codon node via `add_node`, producing a `NodeSpec`.
84-
2. Edges in the LangGraph became workload edges, so `runtime.emit` drives execution.
85-
3. `execute` seeded tokens with the provided state, ran the graph in token order, and captured telemetry & audit logs.
86-
4. You can inspect `report.ledger` for compliance, or `report.node_results(...)` for business outputs.
84+
1. **LangGraph → CodonWorkload**: Your LangGraph was converted into a standard CodonWorkload with the same execution interface as [building from scratch](../building-from-scratch.md#execution-and-results)
85+
2. **Node Registration**: Every LangGraph node was registered as a Codon node via `add_node`, producing a `NodeSpec`
86+
3. **Edge Conversion**: Edges in the LangGraph became workload edges, so `runtime.emit` drives execution
87+
4. **Token Execution**: `execute` seeded tokens with the provided state, ran the graph in token order, and captured telemetry & audit logs
88+
5. **Universal Interface**: You can use all the same methods - `execute()`, `report.node_results()`, `logic_id`, etc. - documented in [Execution and Results](../building-from-scratch.md#execution-and-results)
8789

8890
## Platform Integration
8991

@@ -193,6 +195,7 @@ workload = LangGraphWorkloadAdapter.from_langgraph(
193195
name="ReflectiveAgent",
194196
version="0.1.0",
195197
)
198+
# Execute workload (also available: execute_async() for async contexts)
196199
result = workload.execute({"state": {"topic": "urban gardens"}}, deployment_id="demo")
197200
print(result.node_results("finalize")[-1])
198201
```

sdk/src/codon_sdk/agents/codon_workload.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,15 @@ class ExecutionReport:
218218
context: Dict[str, Any]
219219

220220
def node_results(self, node: str) -> List[Any]:
221+
"""Get all results from a specific node during execution.
222+
223+
Args:
224+
node: Name of the node to retrieve results from.
225+
226+
Returns:
227+
List of results in execution order. Empty list if node never executed.
228+
Use [-1] to get the most recent result if node executed multiple times.
229+
"""
221230
return [record.result for record in self.results.get(node, [])]
222231

223232

@@ -410,12 +419,23 @@ def __init__(
410419

411420
@property
412421
def agent_class_id(self) -> str:
422+
"""Stable identifier for this workload type.
423+
424+
Format is 'name:version' (e.g., 'my-agent:1.0.0'). Remains consistent
425+
across deployments as long as name and version don't change.
426+
"""
413427
if self._agent_class_id is None:
414428
raise WorkloadRegistrationError("Agent class ID has not been computed")
415429
return self._agent_class_id
416430

417431
@property
418432
def logic_id(self) -> str:
433+
"""Unique identifier for this specific workload configuration.
434+
435+
Generated from the complete workload structure (nodes, edges, topology).
436+
Changes whenever nodes or edges are added/modified, useful for detecting
437+
workload configuration changes.
438+
"""
419439
if self._logic_id is None:
420440
raise WorkloadRegistrationError("Logic ID has not been computed")
421441
return self._logic_id
@@ -521,6 +541,24 @@ async def execute_async(
521541
event_handler: Optional[Callable[[StreamEvent], Awaitable[None]]] = None,
522542
**kwargs: Any,
523543
) -> ExecutionReport:
544+
"""Execute the workload asynchronously.
545+
546+
Args:
547+
payload: Initial data passed to entry nodes as token payload.
548+
deployment_id: Identifier for this deployment (required, used in telemetry context).
549+
entry_nodes: List of node names to start execution from. If None, uses nodes with
550+
no predecessors, or all nodes if no entry nodes are found.
551+
max_steps: Maximum execution steps before raising WorkloadRuntimeError (default: 1000).
552+
event_handler: Optional callback for streaming execution events.
553+
**kwargs: Additional arguments for execution context.
554+
555+
Returns:
556+
ExecutionReport: Execution results with node outputs and audit logs.
557+
558+
Raises:
559+
ValueError: If deployment_id is empty.
560+
WorkloadRuntimeError: If no nodes registered, entry nodes invalid, or max_steps exceeded.
561+
"""
524562
if not deployment_id:
525563
raise ValueError("deployment_id is required when executing a workload")
526564
if not self._node_specs:
@@ -796,6 +834,23 @@ def execute(
796834
max_steps: int = 1000,
797835
**kwargs: Any,
798836
) -> ExecutionReport:
837+
"""Execute the workload synchronously.
838+
839+
Args:
840+
payload: Initial data passed to entry nodes as token payload.
841+
deployment_id: Identifier for this deployment (required, used in telemetry context).
842+
entry_nodes: List of node names to start execution from. If None, uses nodes with
843+
no predecessors, or all nodes if no entry nodes are found.
844+
max_steps: Maximum execution steps before raising WorkloadRuntimeError (default: 1000).
845+
**kwargs: Additional arguments passed to execute_async.
846+
847+
Returns:
848+
ExecutionReport: Execution results with node outputs and audit logs.
849+
850+
Raises:
851+
ValueError: If deployment_id is empty.
852+
WorkloadRuntimeError: If no nodes registered, entry nodes invalid, or max_steps exceeded.
853+
"""
799854
return _run_coroutine_sync(
800855
lambda: self.execute_async(
801856
payload,

0 commit comments

Comments
 (0)