"""Самописный поисковый deep agent (deepagents + виртуальная ФС + экспорт).""" from __future__ import annotations import asyncio import os import sys from pathlib import Path ROOT = Path(__file__).resolve().parent if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) from dotenv import load_dotenv from langchain_core.messages import HumanMessage from langchain_openai import ChatOpenAI from deepagents import create_deep_agent from deepagents.backends import LocalShellBackend from export_utils import export_virtual_files from research_tools import get_page_content, web_search load_dotenv() WORKSPACE_DIR = ROOT / "workspace" OUTPUT_DIR = ROOT / "output" OPENROUTER_BASE_URL = os.getenv("OPENROUTER_BASE_URL", "https://openrouter.ai/api/v1") OPENROUTER_MODEL = os.getenv( "OPENROUTER_MODEL", "poolside/laguna-m.1:free", ) SYSTEM_PROMPT = """\ Ты исследовательский deep agent (курс deep agents from scratch). Возможности: - web_search и get_page_content — поиск и чтение материалов в интернете - ls, read_file, write_file, edit_file — виртуальная файловая система Правила: 1. Получив задачу, найди информацию в интернете. 2. Сохраняй заметки и выжимки в виртуальные файлы (например /notes/topic.md). 3. Структурируй файлы по смыслу (папки notes/, research/). 4. В конце кратко сообщи, какие файлы созданы. Пиши на русском, если пользователь не просит иначе. """ def build_llm() -> ChatOpenAI: return ChatOpenAI( model=OPENROUTER_MODEL, base_url=OPENROUTER_BASE_URL, api_key=os.getenv("OPENAI_API_KEY"), temperature=0.2, ) def build_agent(): WORKSPACE_DIR.mkdir(parents=True, exist_ok=True) backend = LocalShellBackend( root_dir=str(WORKSPACE_DIR), virtual_mode=True, inherit_env=True, ) return create_deep_agent( model=build_llm(), tools=[web_search, get_page_content], system_prompt=SYSTEM_PROMPT, backend=backend, ) async def run_research(query: str) -> list[str]: agent = build_agent() print(f"Модель: {OPENROUTER_MODEL}") print(f"Запрос: {query}\n") result = await agent.ainvoke( {"messages": [HumanMessage(content=query)]} ) last = result["messages"][-1] print("\n--- Ответ агента ---") print(getattr(last, "content", last)) exported = export_virtual_files(WORKSPACE_DIR, OUTPUT_DIR) print("\n--- Экспорт в output/ ---") if exported: for path in exported: print(f" {path}") else: print(" (файлов для экспорта не найдено)") return exported def main() -> None: query = ( " ".join(sys.argv[1:]) if len(sys.argv) > 1 else "Краткий обзор Model Context Protocol (MCP): что это и зачем нужен." ) asyncio.run(run_research(query)) if __name__ == "__main__": main()