cleveractors.langgraph provides no StateGraph bridge — host applications must walk CompiledActor nodes manually #8
Labels
No labels
auto/blocked-by-deps
auto/ci-timeout
auto/claimed-implementer
auto/claimed-merge
auto/claimed-reviewer
auto/driver-down
auto/invariant-violation
auto/last-attempt-tier-0
auto/last-attempt-tier-1
auto/last-attempt-tier-2
auto/last-attempt-tier-min
Automation Tracking
auto/needs-conflict-resolution
auto/needs-implementer
auto/postmortem
auto/ready-to-merge
auto/restart-throttled
auto/revert
auto/sentinel
auto/stale-inactivity
auto/unstable
Blocked
Bounty
$100
Bounty
$1000
Bounty
$10000
Bounty
$20
Bounty
$2000
Bounty
$250
Bounty
$50
Bounty
$500
Bounty
$5000
Bounty
$750
MoSCoW
Could have
MoSCoW
Must have
MoSCoW
Should have
Needs Feedback
Points
1
Points
13
Points
2
Points
21
Points
3
Points
34
Points
5
Points
55
Points
8
Points
88
Priority
Backlog
Priority
CI Blocker
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Signed-off: Owner
Signed-off: Scrum Master
Signed-off: Tech Lead
Spike
State
Completed
State
Duplicate
State
In Progress
State
In Review
State
Paused
State
Unverified
State
Verified
State
Wont Do
Type
Automation
Type
Bug
Type
Discussion
Type
Documentation
Type
Epic
Type
Feature
Type
Legendary
Type
Refactor
Type
Support
Type
Task
Type
Testing
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
cleveragents/cleveractors-core#8
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
cleveractors.langgraphexposesNodeConfig,Edge,GraphState, and a single-nodeNodeexecutor, but no function that assembles a compiled actor into a native LangGraphStateGraph. Every host application that wants to run aCompiledActormust re-implement the same node-walking loop by hand.langgraph>=0.2.0is already a declared runtime dependency of this library (seepyproject.toml) yet is never imported anywhere in the source tree. The dependency is deadweight until this bridge exists.Metadata
feat(langgraph): add build_state_graph() to assemble CompiledActor into a native StateGraphfeat/langgraph-state-graph-bridgeDetails
What the library currently provides
compile_actor()produces aCompiledActor— a typed, validated data bundle:Node.execute(state)runs a singleNodeConfigagainst aGraphStateand returns a partial-update dict. That is the full extent of the execution surface. There is no function that wires these pieces into a runningStateGraph.What hosts have to do instead
Every consumer must hand-roll the same loop:
This loop silently ignores conditional routing, does not compose with LangGraph's checkpointing, streaming, or interrupt APIs, and has to be duplicated in every host that uses the library.
Impact
langgraph>=0.2.0is a declared runtime dependency that is never exercised — it provides no value until this bridge is added.cleveractors.langgraphimplies LangGraph integration but stops at data types; the name becomes accurate only once the bridge exists.NodeType.CONDITIONALnodes cannot be wired toadd_conditional_edges()in the manual loop, so conditional branches are silently dropped.Proposed API
A single new public function in
src/cleveractors/langgraph/builder.py:A new public
ActorStateTypedDict is exported fromcleveractors.langgraphso hosts can type-annotate their own code against the state schema:Usage after the bridge exists:
Implementation notes
Four mapping problems must be solved:
1. State schema — LangGraph requires a TypedDict with reducer annotations.
GraphStateis a Pydantic model. A publicActorStateTypedDict adapter is defined inbuilder.pyand exported:2. Node wrapper — Each LangGraph node function receives
ActorStateand must return a partial-update dict.Node.execute()expects aGraphState, so each wrapper converts between the two:3. Conditional edges —
NodeType.CONDITIONALnodes produce acondition_result: boolupdate. They are wired viaadd_conditional_edges()using a routing function that readscondition_resultfrom state:Full expression-based routing (multi-branch conditions, field comparisons) is out of scope for this ticket and will be addressed in a follow-up if required.
4. Exit nodes →
END—actor.metadata.exit_nodesmust each receive an explicitadd_edge(exit_id, END)call; LangGraph has no implicit termination.New files
src/cleveractors/langgraph/builder.py—ActorStateandbuild_state_graph()docs/adr/ADR-006-langgraph-stategraph-execution-bridge.md— records the decision to expose a first-class LangGraph execution bridge, theActorStateTypedDict contract, thebuild_state_graphpublic API shape, and the rationale for scoping conditional routing to booleancondition_resultonlyDefinition of Done
ActorStateTypedDict defined insrc/cleveractors/langgraph/builder.pywithAnnotated[list[dict], operator.add]reducer onmessagesbuild_state_graph(actor, registry) -> CompiledStateGraphimplemented insrc/cleveractors/langgraph/builder.pyCompiledActor.nodesentry wrapped as an async LangGraph node function that convertsActorState ↔ GraphStategraph.add_edge()NodeType.CONDITIONALnodes wired viagraph.add_conditional_edges()using booleancondition_resultrouting; complex expression routing explicitly deferred to a follow-up ticketENDActorStateandbuild_state_graphadded tocleveractors/langgraph/__init__.pyand its__all__build_state_graphcondition_resultdocs/adr/ADR-006-langgraph-stategraph-execution-bridge.mdwritten, covering API contract,ActorStateschema, conditional routing scope decision, and rationaledocs/reference/actor_compiler.mdupdated with a "Running a compiled actor" section documentingbuild_state_graphandActorStatedocs/specification.mdupdated to listActorStateandbuild_state_graphin the public surface table