import os import asyncio from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage from langchain.tools import tool from deepagents import create_deep_agent from deepagents.backends import FilesystemBackend, LocalShellBackend, CompositeBackend import requests from bs4 import BeautifulSoup # LLM configuration – OpenRouter llm = ChatOpenAI( model="openai/gpt-oss-20b:free", base_url="https://openrouter.ai/api/v1", api_key=os.getenv("OPENAI_API_KEY"), temperature=0.0, ) # Backend: virtual workspace + ability to export to real FS backend = CompositeBackend([ LocalShellBackend(workspace_dir="./workspace"), FilesystemBackend(), ]) # ---------- Tools ---------- @tool def search_web(query: str) -> str: """Search the web using DuckDuckGo and return the first paragraph of the first result.""" try: resp = requests.get( "https://duckduckgo.com/html/", params={"q": query}, timeout=10, ) resp.raise_for_status() soup = BeautifulSoup(resp.text, "html.parser") results = soup.select("a.result__a") if not results: return "No results found." first_link = results[0].get("href") # fetch the linked page page_resp = requests.get(first_link, timeout=10) page_resp.raise_for_status() page_soup = BeautifulSoup(page_resp.text, "html.parser") # grab first paragraph para = page_soup.find("p") return para.get_text(strip=True) if para else "No paragraph found." except Exception as e: return f"Error during search: {e}" @tool def write_file(filename: str, content: str) -> str: """Write content to a virtual file in the workspace.""" try: backend.write_file(filename, content) return f"File '{filename}' written successfully." except Exception as e: return f"Failed to write file: {e}" # ---------- Agent ---------- agent = create_deep_agent( model=llm, tools=[search_web, write_file], backend=backend, system_prompt="You are a research assistant. Search the web, create virtual files, and finally export them to the real filesystem.", ) async def main(): # Example task: gather information about "Python asyncio" and store in a file user_prompt = "Collect a concise summary about Python asyncio and save it to summary.txt" result = await agent.ainvoke( {"messages": [HumanMessage(content=user_prompt)]}, {"configurable": {"thread_id": "session-1"}}, ) print("Agent finished.") # Export virtual workspace to real filesystem backend.export("./exported_workspace") print("Exported virtual files to ./exported_workspace") if __name__ == "__main__": asyncio.run(main())