Skip to content

Architecture

Overview

frontend/               React 19 + Vite + react-router-dom
  src/
    components/         LandingPage, LoginPage, AuthGuard, Sidebar,
                        MessageList, InputArea, ModelModal, ApprovalModal,
                        SettingsPanel, QuestionDrawer, RightPanel, ReportDrawer
    hooks/useSSE.ts     Server-Sent Events with reconnect + token auth
    api.ts              Fetch wrapper with JWT headers

backend/                Python 3.12 + FastAPI
  openmlr/
    app.py              FastAPI entry, lifespan, SPA serving
    config.py           Layered config (YAML → env → auto-detect)
    dependencies.py     Auth + DB dependency injection

    agent/
      llm.py            Multi-provider (OpenAI, Anthropic, OpenRouter)
      loop.py           Agentic loop (300 iter, streaming, tool execution)
      context.py        Token tracking, auto-compaction, undo
      session.py        Per-conversation state
      doom_loop.py      Repetitive pattern detection
      prompts.py        Jinja2 system prompt builder

    tools/
      local.py          Docker-isolated bash, read, write, edit
      papers.py         OpenAlex + CrossRef + ArXiv + Papers With Code
      research.py       Independent research sub-agent
      ask_user.py       Structured questions with options
      plan.py           Task tracking + completion reports
      writing.py        Paper drafting + bibliography
      github.py         Code search + file reading
      search.py         Brave web search
      sandbox_tools.py  Sandbox wrappers
      mcp.py            MCP server integration
      registry.py       ToolRouter

    sandbox/
      interface.py      Abstract SandboxInterface
      local.py          Docker-based local execution
      ssh.py            Remote via SSH/SFTP
      modal_sandbox.py  Modal cloud containers

    auth/               JWT (bcrypt + JOSE)
    db/                 SQLAlchemy async + Alembic
    routes/             agent.py, settings.py
    services/           EventBus (SSE), SessionManager

Data flow

  1. User sends message with mode (Plan/Research/Write) via POST /api/message
  2. Route persists to DB, creates/loads session, fires asyncio.create_task
  3. Agent loop: builds system prompt → calls LLM → parses tool calls → executes
  4. Events stream via SSE: assistant_chunk, tool_call, tool_output, etc.
  5. Frontend updates UI in real-time via the useSSE hook

SSE events

EventWhen
processingAgent starts thinking
assistant_chunkStreaming text token
assistant_stream_endStream finished
assistant_messageFull response (non-streaming fallback)
tool_callTool invocation started
tool_outputTool result
questionsAgent asks structured questions
plan_updateTask list changed
resources_updateResource list changed
context_usageToken gauge update
search_budgetPaper search budget update
turn_completeAgent finished processing
errorError occurred
interruptedUser cancelled

Database tables

TablePurpose
usersAccounts (username, bcrypt hash)
user_settingsPer-user key-value config (category/key/value)
conversationsChat sessions (uuid, title, model, mode)
messagesMessage history (role, content, metadata)
sandbox_configsSaved sandbox configurations
research_corpusPapers in the research corpus
writing_projectsPaper drafts (outline, sections, bibliography)

Released under the MIT License.