from aiohttp import web import asyncio from .auto_approver import AutoApprover from .chat_io_buffer import ChatIOBuffer from .config import Config from .iteration_logger import IterationLogger from .llm_engine import LlmEngine from .response_parser import ResponseParser from .system_metrics import SystemMetrics from .web.api import Api from .web.static import Static from .web.websockets import Websockets from .web_agent import WebAgent from .working_memory import WorkingMemory class Main: @classmethod async def create(cls, config: Config): self = cls() self._config = config self._system_prompt = self._config.system_prompt.read_text() self._action_schema = self._config.action_schema.read_text() # Initialize LLM engines based on config self._llms = {} # Use the config.llms property which returns only enabled LLMs for llm_name, executable_path in config.llms.items(): self._llms[llm_name] = LlmEngine( executable_path=executable_path, action_schema_path=str(config.action_schema) ) if not self._llms: raise ValueError("No LLM engines enabled in configuration") self._io_buffer = ChatIOBuffer() self._working_memory = WorkingMemory() self._agent = WebAgent( system_prompt=self._system_prompt, action_schema=self._action_schema, working_memory=self._working_memory, metrics=SystemMetrics(), llms=self._llms, parser=ResponseParser(config.work_dir, self._io_buffer), iteration_logger=IterationLogger(self._config.iterations_dir, self._system_prompt, self._action_schema), ) self._auto_approver = AutoApprover(self._agent) self._app = web.Application() self._api = Api(config.work_dir, self._app, self._agent, self._io_buffer, self._working_memory, self._auto_approver) self._websockets = Websockets(self._app, self._agent, self._io_buffer, self._auto_approver, self._working_memory) self._static = Static(self._app, self._config) return self @property def app(self): return self._app async def _serve_index(self, request: web.Request) -> web.Response: """Serve the React application HTML for any unmatched routes.""" index_path = self._config.static_files / "index.html" if not index_path.exists(): raise web.HTTPNotFound() with open(index_path, "r") as f: html_content = f.read() return web.Response( text=html_content, content_type="text/html" ) def main(): loop = asyncio.new_event_loop() config = Config() main_instance = loop.run_until_complete(Main.create(config)) print(f"Web server started at http://localhost:{config.port}") web.run_app(main_instance.app, loop=loop, host=config.host, port=config.port) return 0