Skip to content

Architecture

Yash Aryan edited this page Aug 8, 2026 · 1 revision

Architecture

Big picture

flowchart TB
  subgraph Desktop["Electron desktop (app/)"]
    R[Renderer ESM<br/>index.html + js/*]
    P[Preload<br/>contextBridge → window.api]
    M[Main CJS<br/>ipc.ts + modules]
    R --> P --> M
    M --> Ollama[Ollama HTTP]
    M --> Chroma[Bundled Chroma]
    M --> Graph[Local knowledge graph]
    M --> Disk[userData JSON + OS keystore]
    M --> Proxy[OpenAI proxy :3227]
    M --> API[In-process REST dispatch<br/>src/main/api]
  end

  API --> FS[(Firestore)]
  AuthUI[System browser<br/>Firebase Hosting sign-in] --> M
  FS -. rules .-> Rules[firestore.rules]
  Web[web/ Next.js site] --> GH[GitHub Releases API]
Loading

Design invariants

  1. Local-first compute — generation, embeddings, tools, and most project data stay on the machine.
  2. No paid Firebase backend — no Cloud Functions; governance runs in-process.
  3. Rules are authzfirebase/firestore.rules authorize every org/policy/usage write.
  4. IPC is the UI contractapp/src/types/api.d.ts + preload.ts + ipc.ts must move together.
  5. Secrets never bake into the appapp/.env is public allowlisted config only.

Process model

Process Module system Entry Responsibility
Main CommonJS (tsconfig.main.json) app/main.ts Window, lifecycle, Ollama/Chroma/proxy, all IPC, governance API
Preload CJS (compiled with main) app/preload.ts contextBridge.exposeInMainWorld("api", …)
Renderer ESM (tsconfig.renderer.json) app/src/renderer/js/app.ts UI only; no Node; talks via window.api

Security flags: contextIsolation: true, nodeIntegration: false.

Chat turn (high level)

sequenceDiagram
  participant UI as Renderer chat.ts
  participant IPC as ipc.ts
  participant Gov as governance
  participant Ctx as context/memory/RAG
  participant Agents as agents/*
  participant Oll as ollama.chatStream
  participant Tools as tools/skills exec

  UI->>IPC: chat:start (messages, model, useTools, skillOverrides)
  IPC->>Gov: preflight / evaluatePrompt
  IPC->>Ctx: assemble system prompt (RAG, memory, skills, workspace)
  alt multi-agent eligible
    IPC->>Agents: plan → workers → synthesize
  else single-agent
    loop up to 15 tool rounds
      IPC->>Oll: stream (+ tool defs)
      Oll-->>IPC: chunks / tool_calls
      IPC->>Tools: execute (confirm if risky)
    end
  end
  IPC-->>UI: chat:chunk / activity / confirm / done
  IPC->>Ctx: remember + graph extract
Loading

Nuances:

  • Streaming uses events (chat:chunk, chat:activity, …), not a single invoke promise.
  • Project-coding turns force single-agent.
  • Multi-agent workers use a lower tool-round cap (MAX_TOOL_ROUNDS = 3 in agents/workers.ts).
  • Single-agent loop allows 15 rounds (ipc.ts) for coding/folder tasks.
  • Pasted JSON tool-call recovery exists for small models that don’t emit native tool calls cleanly.

Auth & governance

flowchart LR
  Email[Email/password] --> IT[Identity Toolkit]
  OAuth[Google/GitHub] --> Browser[Hosting page]
  Browser --> Loopback[127.0.0.1 callback + refreshToken]
  IT --> Store[token-store OS keystore]
  Loopback --> Store
  Store --> Req[auth.request]
  Req --> Dispatch[api/index.ts]
  Dispatch --> REST[Firestore REST]
  REST --> Rules[firestore.rules]
Loading

OAuth deliberately uses loopback + refresh token, not anylm:// for the credential handoff (RFC 8252). Connector OAuth is separate and used by skills.

Knowledge layers

Layer Code Storage
Project reference RAG rag.ts, context.ts Chroma anylm_project_context
Cross-thread memory memory.ts Chroma anylm_project_memory
General / org KB vectorstore.ts Chroma collections
Structured facts graph/ Local graph store
Embeddings embed.ts Ollama (nomic-embed-text default)

Chroma failures soft-fail: empty retrieval / dropped writes; summaries still work.

Persistence (userData)

Brand-pinned path under Electron userData (display name must keep AnyLM so Dev builds don’t fork data):

  • llmeter-projects.json — projects / threads / references metadata
  • llmeter-settings.json — theme, proxy, agents, load protection, …
  • anylm-tools.json / anylm-skills.json — registries
  • Encrypted tokens via token-store.ts
  • Generated docs / workspace folders / Chroma data

Related pages

Clone this wiki locally