-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlanggraph_self_correcting_graph.py
More file actions
80 lines (60 loc) · 2.05 KB
/
langgraph_self_correcting_graph.py
File metadata and controls
80 lines (60 loc) · 2.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
"""
LangGraph reference example: Sentience observe → act → verify → branch (self-correcting).
Install:
pip install predicate-runtime[langchain]
Run:
python examples/lang-chain/langgraph_self_correcting_graph.py
"""
from __future__ import annotations
import asyncio
from dataclasses import dataclass
from predicate import AsyncSentienceBrowser
from predicate.integrations.langchain import SentienceLangChainContext, SentienceLangChainCore
@dataclass
class State:
url: str | None = None
last_action: str | None = None
attempts: int = 0
done: bool = False
async def main() -> None:
from langgraph.graph import END, StateGraph
browser = AsyncSentienceBrowser(headless=False)
await browser.start()
core = SentienceLangChainCore(SentienceLangChainContext(browser=browser))
async def observe(state: State) -> State:
s = await core.snapshot_state()
state.url = s.url
return state
async def act(state: State) -> State:
# Replace with an LLM decision node. For demo we just navigate once.
if state.attempts == 0:
await core.navigate("https://example.com")
state.last_action = "navigate"
else:
state.last_action = "noop"
state.attempts += 1
return state
async def verify(state: State) -> State:
out = await core.verify_url_matches(r"example\.com")
state.done = bool(out.passed)
return state
def branch(state: State) -> str:
if state.done:
return "done"
if state.attempts >= 3:
return "done"
return "retry"
g = StateGraph(State)
g.add_node("observe", observe)
g.add_node("act", act)
g.add_node("verify", verify)
g.set_entry_point("observe")
g.add_edge("observe", "act")
g.add_edge("act", "verify")
g.add_conditional_edges("verify", branch, {"retry": "observe", "done": END})
app = g.compile()
final = await app.ainvoke(State())
print(final)
await browser.close()
if __name__ == "__main__":
asyncio.run(main())