""" Агент на базе smolagents + Ollama. Использует ToolCallingAgent — LLM вызывает инструменты через JSON tool calling. Продолжает работу пока задача не решена (до max_steps). """ import os import platform from loguru import logger from smolagents import ToolCallingAgent, LiteLLMModel from cosmo.memory import Memory # Выбираем инструменты под текущую платформу if platform.system() == "Darwin" or os.environ.get("COSMO_PLATFORM") == "mac": from cosmo.tools_mac import ALL_TOOLS, set_memory _PLATFORM_NOTE = "macOS. Используй bash, 'open -a AppName' для запуска приложений, mdfind для поиска файлов." else: from cosmo.tools import ALL_TOOLS, set_memory _PLATFORM_NOTE = "Windows. Используй Git Bash, 'start' для запуска приложений." SYSTEM_PROMPT = f"""Ты — Cosmo, умный голосовой ассистент. Платформа: {_PLATFORM_NOTE} Правила: 1. Используй инструменты для выполнения задач — не выдумывай результаты 2. Если первая попытка не сработала — пробуй другой подход, не сдавайся 3. Перед поиском программы — проверь память (memory_get), может путь уже известен 4. Если нашёл путь к программе — сохрани в память (memory_set) чтобы не искать повторно 5. Отвечай коротко на русском языке — пользователь слушает голосом, не читает Факты из памяти о пользователе и системе: {memory_facts} """ class Agent: def __init__(self, config: dict, memory: Memory): self.memory = memory self._cfg = config["ollama"] # Передаём память в инструменты set_memory(memory) model_id = f"ollama/{self._cfg['model']}" logger.info(f"Инициализирую smolagents с моделью {model_id}") self._model = LiteLLMModel( model_id=model_id, api_base=self._cfg["base_url"], temperature=self._cfg.get("temperature", 0.2), max_tokens=self._cfg.get("max_tokens", 1024), ) self._agent = ToolCallingAgent( tools=ALL_TOOLS, model=self._model, max_steps=self._cfg.get("max_agent_steps", 10), verbosity_level=1, ) logger.info("Агент готов") def run(self, user_input: str) -> str: """ Обработать команду пользователя. Возвращает финальный текст ответа для TTS. """ logger.info(f"Агент: '{user_input}'") # Сохраняем в историю self.memory.add_message("user", user_input) # Формируем промпт с текущей памятью system = SYSTEM_PROMPT.format(memory_facts=self.memory.facts_as_text()) # smolagents принимает задачу и опциональный системный промпт try: result = self._agent.run( user_input, additional_args={"system_prompt_override": system}, ) response = str(result).strip() if result else "Готово" except Exception as e: logger.error(f"Ошибка агента: {e}") response = "Произошла ошибка при выполнении команды" self.memory.add_message("assistant", response) logger.info(f"Агент ответил: '{response}'") return response