Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Release to PyPI

on:
push:
tags:
- 'sdk/v*' # Triggers for the Core SDK
- 'langgraph-adapter/v*' # Triggers for the LangGraph Adapter

jobs:
pypi-publish:
name: Upload release to PyPI
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.9'

- name: Install Build Tools
run: pip install build

# --- LOGIC FOR CORE SDK ---
# Matches tags like: sdk/v0.1.0
- name: Build Codon SDK
if: startsWith(github.ref, 'refs/tags/sdk/')
run: |
cd sdk
python -m build
echo "PACKAGE_PATH=sdk/dist/*" >> $GITHUB_ENV

# --- LOGIC FOR LANGGRAPH ADAPTER ---
# Matches tags like: langgraph-adapter/v0.1.0
- name: Build LangGraph Adapter
if: startsWith(github.ref, 'refs/tags/langgraph-adapter/')
run: |
cd instrumentation-packages/codon-instrumentation-langgraph
python -m build
echo "PACKAGE_PATH=instrumentation-packages/codon-instrumentation-langgraph/dist/*" >> $GITHUB_ENV

# --- COMMON UPLOAD STEP ---
- name: Publish to PyPI
if: env.PACKAGE_PATH != ''
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages_dir: ${{ env.PACKAGE_PATH }}
password: ${{ secrets.PYPI_API_TOKEN }}
70 changes: 43 additions & 27 deletions instrumentation-packages/codon-instrumentation-langgraph/README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,56 @@
# Codon LangGraph Adapter

This adapter lets you wrap an existing LangGraph `StateGraph` inside Codon’s `CodonWorkload`. By doing so you inherit:
If you're already using LangGraph, the Codon SDK provides seamless integration through the `LangGraphWorkloadAdapter`. This allows you to wrap your existing StateGraphs with minimal code changes while gaining comprehensive telemetry and observability.

- automatic `NodeSpec` creation and logic ID generation
- OpenTelemetry spans through `track_node`
- the token-based runtime with audit ledger
## Understanding State Graph vs Compiled Graph

LangGraph has two distinct graph representations:
- **State Graph**: The graph you define and add nodes to during development
- **Compiled Graph**: The executable version created when you want to run the graph

The `LangGraphWorkloadAdapter` works by wrapping your StateGraph and compiling it for you, allowing you to pass compile keyword arguments for features like checkpointers and long-term memory.

## Using LangGraphWorkloadAdapter

The primary way to integrate LangGraph with Codon is through the `LangGraphWorkloadAdapter.from_langgraph()` method:

## Quick Start
```python
from langgraph.graph import StateGraph
from langgraph.checkpoint.memory import MemorySaver
from codon.instrumentation.langgraph import LangGraphWorkloadAdapter
from myproject.langgraph import graph

workload = LangGraphWorkloadAdapter.from_langgraph(
graph,
name="LangGraphAgent",
version="1.0.0",
# Your existing StateGraph
db_agent_graph = StateGraph(SQLAnalysisState)
db_agent_graph.add_node("query_resolver_node", self.query_resolver_node)
db_agent_graph.add_node("query_executor_node", self.query_executor_node)
# ... add more nodes and edges

# Wrap with Codon adapter
self._graph = LangGraphWorkloadAdapter.from_langgraph(
db_agent_graph,
name="LangGraphSQLAgentDemo",
version="0.1.0",
description="A SQL agent created using the LangGraph framework",
tags=["langgraph", "demo", "sql"],
compile_kwargs={"checkpointer": MemorySaver()}
)
```

result = workload.execute({"state": initial_state}, deployment_id="dev")
### Automatic Node Inference

# Adding compile-time extras (e.g., checkpointer)
from langgraph.checkpoint.memory import InMemorySaver
The adapter automatically infers nodes from your StateGraph, eliminating the need to manually instrument each node with decorators. This provides comprehensive telemetry out of the box.

workload_with_ckpt = LangGraphWorkloadAdapter.from_langgraph(
graph,
name="LangGraphAgent",
version="1.0.0",
compile_kwargs={"checkpointer": InMemorySaver()},
)
**Note:** Only fired nodes are represented in a workload run, so the complete workload definition may not be present in the workload run summary. This is particularly relevant for LangGraph workflows with conditional edges and branching logic—your execution reports will show actual paths taken, not all possible paths.

# Override or extend at invocation time if needed
run = workload_with_ckpt.execute(
{"state": initial_state},
deployment_id="dev",
langgraph_config={"metadata": "run-123"},
)
```
### Compile Keyword Arguments

You can pass any LangGraph compile arguments through `compile_kwargs`:
- Checkpointers for persistence
- Memory configurations
- Custom compilation options

## Best Practices

See `AGENTS.md` for more detailed instructions and advanced usage.
1. **Use the adapter**: `LangGraphWorkloadAdapter.from_langgraph()` provides comprehensive instrumentation with just a few lines of code
2. **Initialize telemetry early**: Call `initialize_telemetry()` before creating your workloads
3. **Leverage compile_kwargs**: Pass checkpointers and memory configurations through the adapter
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ build-backend = "setuptools.build_meta"
[project]
name = "codon-instrumentation-langgraph"
version = "0.1.0a1"
license = "Apache-2.0"
license = {text = "Apache-2.0"}
authors = [
{ name="Codon, Inc.", email="martin@codonops.ai" },
{ name="Sheldon Gilbert", email="sheldon@codonops.ai"},
{ name="Martin Arroyo", email="martin@codonops.ai" },
]
maintainers = [
{ name="Martin Arroyo", email="martin@codonops.ai" },
{ name="Carl Gordon", email="carl@codonops.ai"},
{ name="Luis Moreno", email="luis@codonops.ai"},
]
description = "Instrumentation package for LangGraph in the Codon ecosystem."
readme = "README.md"
requires-python = ">=3.9"
Expand All @@ -19,12 +25,13 @@ classifiers = [
"Operating System :: OS Independent",
]
dependencies = [
"codon_sdk",
"codon-sdk",
"opentelemetry-api",
"opentelemetry-sdk",
"opentelemetry-exporter-otlp-proto-grpc",
]

[project.urls]
"Homepage" = "https://github.com/your-username/codon-sdk"
"Bug Tracker" = "https://github.com/your-username/codon-sdk/issues"
"Homepage" = "https://codon-ops.github.io/codon-sdk/instrumentation/langgraph/"
"Bug Tracker" = "https://github.com/Codon-Ops/codon-sdk/issues"
"Documentation" = "https://codon-ops.github.io/codon-sdk/instrumentation/langgraph/"
2 changes: 1 addition & 1 deletion sdk/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
[project]
# This is the main SDK package name
name = "codon_sdk"
version = "0.1.0a4"
version = "0.1.0a1"
license = {text = "Apache-2.0"}
authors = [
{ name="Codon, Inc.", email="martin@codonops.ai" },
Expand Down