Files
task-69a474cdc46fd26feae69896/main.py
T
2026-05-27 13:11:25 +00:00

126 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Main entry point for the assignment.
This script demonstrates a deep agent that:
1. Uses `create_deep_agent` from the `deepagents` package.
2. Stores conversation history with `MemorySaver`.
3. Pauses before each tool call and asks the user for confirmation.
4. Can defend its decisions when a user contradicts the original task.
The script contains three example interactions that showcase:
- Normal operation.
- Tool usage with confirmation.
- Defending the agent's choice.
"""
import os
from typing import Dict, Any
# LLM configuration BroJS only
from langchain_openai import ChatOpenAI
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, FilesystemBackend
from langgraph.checkpoint.memory import MemorySaver
from rich.console import Console
from rich.markdown import Markdown
# ---------------------------------------------------------------------------
# Configuration
# ---------------------------------------------------------------------------
LLM = ChatOpenAI(
model="openai/gpt-oss-20b:free",
base_url="https://platform.brojs.ru/jrnl-bh/api/inference/v1",
api_key=os.getenv("JOURNAL_MCP_PAT"),
temperature=0.0,
)
# Backend virtual FS (real shell not needed for this demo).
backend = CompositeBackend(
default=FilesystemBackend(root_dir="./workspace", virtual_mode=True, inherit_env=True),
routes={},
)
# ---------------------------------------------------------------------------
# Helper tools
# ---------------------------------------------------------------------------
from langchain.tools import tool
@tool
def echo(text: str) -> str:
"""Return the same text useful for demonstration."""
return f"Echo: {text}"
@tool
def add(a: int, b: int) -> int:
"""Add two integers."""
return a + b
# ---------------------------------------------------------------------------
# Agent creation
# ---------------------------------------------------------------------------
memory = MemorySaver()
agent = create_deep_agent(
llm=LLM,
tools=[echo, add],
backend=backend,
system_prompt="You are an assistant that must follow the users instructions and can use tools. You should ask for confirmation before calling a tool.",
checkpointer=memory,
interrupt_before=["tools"], # pause before each tool call
)
console = Console()
# ---------------------------------------------------------------------------
# Interaction helpers
# ---------------------------------------------------------------------------
async def run_interaction(messages: list[Dict[str, str]], thread_id: str) -> None:
"""Run a single interaction with the agent."""
config = {"configurable": {"thread_id": thread_id}}
async for chunk in agent.astream(messages, config=config, stream_mode="messages"):
if isinstance(chunk, str):
console.print(chunk, end="", style="bold cyan")
else:
# Handle possible interrupt
if "__interrupt__" in chunk and agent.get_state(config).next == ("tools",):
console.print("\n[bold yellow]Agent wants to use a tool:[/]", style="yellow")
console.print(Markdown(str(chunk)))
confirm = input("Allow? (y/n) ").strip().lower()
if confirm == "y":
await agent.ainvoke(Command(resume=None), config)
else:
console.print("[red]Tool call rejected by user.[/]\n", style="red")
break
else:
console.print(chunk, style="green")
console.print("\n--- End of interaction ---\n", style="bold magenta")
# ---------------------------------------------------------------------------
# Main demo loop three examples
# ---------------------------------------------------------------------------
if __name__ == "__main__":
import asyncio
async def main():
# Example 1: Simple echo
await run_interaction(
[{"role": "human", "content": "Say hello."}],
thread_id="demo-echo",
)
# Example 2: Tool usage with confirmation
await run_interaction(
[{"role": "human", "content": "Add 7 and 5."}],
thread_id="demo-add",
)
# Example 3: Defending the agent when user contradicts task
await run_interaction(
[
{"role": "human", "content": "I think you should not use tools at all."},
{"role": "assistant", "content": "But I need to add numbers. Let me call the tool."},
],
thread_id="demo-contradiction",
)
asyncio.run(main())