156 lines
3.9 KiB
Python
156 lines
3.9 KiB
Python
"""
|
|
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()
|