Skip to content

feat(dashboard): add Atomic Agent integration tab - #2274

Open
sosidudku1 wants to merge 1 commit into
exo-explore:mainfrom
sosidudku1:feat/atomic-agent-integration-tab
Open

feat(dashboard): add Atomic Agent integration tab#2274
sosidudku1 wants to merge 1 commit into
exo-explore:mainfrom
sosidudku1:feat/atomic-agent-integration-tab

Conversation

@sosidudku1

Copy link
Copy Markdown

Motivation

The integrations page covers coding agents (Claude Code, OpenCode, Codex, OpenClaw, Pi) but not Atomic Agent, a local-first agent runtime that reads OpenAI-compatible providers straight from its config file. Wiring it to an exo cluster needs no new code on either side, only the right config, so a tab is the whole integration.

Agents are also the workload that makes a cluster worth building: one task fans out into dozens of model calls with long context and real tool calling, which is a very different load profile from a chat window.

Changes

Single-file change to dashboard/src/routes/integrations/+page.svelte, following the same shape as the Pi tab (#1925):

  • adds "Atomic Agent" to the tabs tuple, after "Pi"
  • adds atomicAgentModel state, defaulted alongside codexModel / openClawModel / piModel
  • adds an atomicAgentConfigJson derivation that emits an llm.providers entry for ~/.atomic-agent/config.json
  • adds the tab block: a model selector (shown when several models are running) and one IntegrationCard

Generated config:

{
  "llm": {
    "activeTextProvider": "exo",
    "providers": [
      {
        "id": "exo",
        "kind": "openai-compatible",
        "baseUrl": "http://127.0.0.1:52415/v1",
        "apiKey": "exo",
        "defaultChatModel": "<selected running model>",
        "supportsTools": true,
        "supportsVision": false,
        "userModels": [
          { "id": "<model>", "kind": "chat", "contextWindow": 262144 }
        ]
      }
    ]
  }
}

Details that come from live cluster state, matching what the other tabs do:

  • baseUrl is the dashboard's own apiUrl plus /v1
  • defaultChatModel follows the model selector, falling back to your-model-id when nothing is running
  • supportsVision is derived from the model's exo capabilities
  • contextWindow comes from /v1/models, and userModels is omitted when the length is unknown rather than emitting a zero

Why It Works

Atomic Agent registers providers by kind. Its openai-compatible kind takes an arbitrary baseUrl and talks the plain OpenAI chat-completions surface with native tools, which is exactly what exo serves on /v1. So the tab is config generation only, no client changes and no backend changes.

apiKey is set to a placeholder because that provider kind always sends an Authorization header; exo ignores the value, same as the OpenClaw and Pi tabs already assume.

Test Plan

Manual Testing

Hardware: MacBook Air M4, 16 GB, single node, no cluster. macOS 26.1, exo from the released app.

  • npm run build in dashboard/ succeeds
  • svelte-check: no new errors in the touched file (the 15 pre-existing repo errors are unchanged)
  • prettier --check passes on the touched file
  • confirmed the tab renders and the compiled bundle carries the new config strings
  • pasted the generated config verbatim into ~/.atomic-agent/config.json, then:
    • chat completion through exo: OK, ~1 s round trip
    • tool calling through exo with mlx-community/Qwen3.5-2B-MLX-8bit: OK, structured tool_calls and finish_reason: "tool_calls"
    • agent loop against exo: connected and executed its own tools (os.fs.list, os.fs.glob) through the cluster

One observation worth recording, not a blocker for this tab: mlx-community/Llama-3.2-1B-Instruct-4bit returns tool calls as raw <|python_tag|> text in content with tool_calls: null, while Qwen models return them structured. Anything agentic wants a model with proper tool support.

Automated Testing

No automated tests. The change is config-string generation in a Svelte route, matching the existing tabs, which are likewise covered only by the build and type check.

Atomic Agent reads OpenAI-compatible providers from its config file,
so wiring it to an exo cluster needs no code on either side. Generate
the config the same way the Pi tab does: base URL from the dashboard,
model from the selector, vision flag and context window from live
cluster state.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant