Sisyphus agent recreated in LangChain to figure out how it works and how to use it
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
"""
|
||||
CLI entry point for the Sisyphus LangChain agent.
|
||||
|
||||
This mirrors Loki's `loki --agent sisyphus` entry point.
|
||||
|
||||
In Loki:
|
||||
loki --agent sisyphus
|
||||
# Starts a REPL with the sisyphus agent loaded
|
||||
|
||||
In this LangChain version:
|
||||
python -m sisyphus_langchain.cli
|
||||
# or: sisyphus (if installed via pip)
|
||||
|
||||
Usage:
|
||||
# Interactive REPL mode
|
||||
sisyphus
|
||||
|
||||
# One-shot query
|
||||
sisyphus "Add a health check endpoint to the API"
|
||||
|
||||
# With custom models
|
||||
sisyphus --supervisor-model gpt-4o --explore-model gpt-4o-mini "Find auth patterns"
|
||||
|
||||
Environment variables:
|
||||
OPENAI_API_KEY — Required for OpenAI models
|
||||
ANTHROPIC_API_KEY — Required if using Anthropic models
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
from langchain_core.messages import HumanMessage
|
||||
|
||||
from sisyphus_langchain.graph import build_graph
|
||||
|
||||
|
||||
def run_query(graph, query: str, thread_id: str) -> str:
|
||||
"""
|
||||
Run a single query through the Sisyphus graph.
|
||||
|
||||
Args:
|
||||
graph: Compiled LangGraph.
|
||||
query: User's natural language request.
|
||||
thread_id: Session identifier for checkpointing.
|
||||
|
||||
Returns:
|
||||
The final output string.
|
||||
"""
|
||||
result = graph.invoke(
|
||||
{
|
||||
"messages": [HumanMessage(content=query)],
|
||||
"intent": "ambiguous",
|
||||
"next_agent": "",
|
||||
"iteration_count": 0,
|
||||
"todos": [],
|
||||
"agent_outputs": {},
|
||||
"final_output": "",
|
||||
"project_dir": ".",
|
||||
},
|
||||
config={
|
||||
"configurable": {"thread_id": thread_id},
|
||||
"recursion_limit": 50,
|
||||
},
|
||||
)
|
||||
return result.get("final_output", "(no output)")
|
||||
|
||||
|
||||
def repl(graph, thread_id: str) -> None:
|
||||
"""
|
||||
Interactive REPL loop — mirrors Loki's REPL mode.
|
||||
|
||||
Maintains conversation across turns via the thread_id (checkpointer).
|
||||
"""
|
||||
print("Sisyphus (LangChain) — type 'quit' to exit")
|
||||
print("=" * 50)
|
||||
|
||||
while True:
|
||||
try:
|
||||
query = input("\n> ").strip()
|
||||
except (EOFError, KeyboardInterrupt):
|
||||
print("\nBye.")
|
||||
break
|
||||
|
||||
if not query:
|
||||
continue
|
||||
if query.lower() in ("quit", "exit", "q"):
|
||||
print("Bye.")
|
||||
break
|
||||
|
||||
try:
|
||||
output = run_query(graph, query, thread_id)
|
||||
print(f"\n{output}")
|
||||
except Exception as e:
|
||||
print(f"\nError: {e}")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""CLI entry point."""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Sisyphus — multi-agent coding orchestrator (LangChain edition)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"query",
|
||||
nargs="?",
|
||||
help="One-shot query (omit for REPL mode)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--supervisor-model",
|
||||
default="gpt-4o",
|
||||
help="Model for the supervisor (default: gpt-4o)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--explore-model",
|
||||
default="gpt-4o-mini",
|
||||
help="Model for the explore agent (default: gpt-4o-mini)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--oracle-model",
|
||||
default="gpt-4o",
|
||||
help="Model for the oracle agent (default: gpt-4o)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--coder-model",
|
||||
default="gpt-4o",
|
||||
help="Model for the coder agent (default: gpt-4o)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--thread-id",
|
||||
default=None,
|
||||
help="Session thread ID for persistence (auto-generated if omitted)",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
graph = build_graph(
|
||||
supervisor_model=args.supervisor_model,
|
||||
explore_model=args.explore_model,
|
||||
oracle_model=args.oracle_model,
|
||||
coder_model=args.coder_model,
|
||||
)
|
||||
|
||||
thread_id = args.thread_id or f"sisyphus-{uuid.uuid4().hex[:8]}"
|
||||
|
||||
if args.query:
|
||||
output = run_query(graph, args.query, thread_id)
|
||||
print(output)
|
||||
else:
|
||||
repl(graph, thread_id)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user