galaxyproject / galaxyproject/loom

Orbit: configure local/custom models from Preferences UI

Open
#30 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
14
Forks
12
Avg merge
6d 5h
Merged PRs (30d)
17

Description

## Problem

Today, configuring a local model (Ollama, LiteLLM proxy, any OpenAI-compatible endpoint) requires hand-editing `~/.pi/agent/models.json`. Orbit's Preferences UI only exposes:

- Provider dropdown (hardcoded list of 7 in `app/src/renderer/index.html:175-183`)
- Model dropdown (hardcoded preset list per provider; \"(custom)\" free-form fallback for unknown IDs)
- API key

Missing:
- **Base URL** — can't point at a custom Ollama port, a LiteLLM proxy on `localhost:4000`, or any other server
- **Context window / max tokens** — pi-coding-agent needs these to size requests; without them a custom model fails silently
- **`litellm` provider** — not in the dropdown at all, even though README documents it as supported
- **Custom model registration with metadata** — the \"(custom)\" fallback accepts any ID but writes no model definition, so pi-coding-agent rejects unknown models

Result: every local-model user has to read pi-coding-agent's source to discover the `models.json` schema, then hand-edit JSON. UI is a viewing surface, not a configuration surface.

## Proposed shape

Extend Preferences with an \"Add custom model\" section that maps 1:1 to pi-coding-agent's `ModelDefinitionSchema` (see `node_modules/@mariozechner/pi-coding-agent/dist/core/model-registry.js`). Fields:

- Provider name (free-form; defaults to \"ollama\" / \"litellm\" / \"custom\")
- Base URL (e.g. `http://localhost:11434/v1`)
- API kind dropdown (`openai-completions` is the practical lingua franca)
- Model ID
- Display name
- Context window
- Max output tokens
- Cost per 1M tokens (in/out — optional, defaults to 0 for local)

Save writes to `~/.pi/agent/models.json` via the documented schema; provider dropdown re-reads it on next open.

## Two bonus wins this unlocks

1. **Discovery for Ollama** — once base URL is settable, Orbit can call `GET {baseUrl}/api/tags` and prepopulate the model list. Same idea for LiteLLM via `/v1/models`. (See #13 for the broader dynamic-list discussion.)
2. **Capability probing** — Ollama's `/api/show` returns context window per model; we can fill in the metadata without the user typing it.

## Tradeoff

Adds ~100 lines of HTML + form-handler JS + a small IPC bridge to write `~/.pi/agent/models.json`. Validation against `ModelsConfigSchema` already exists in pi-coding-agent — Orbit just needs to surface load errors.

Alternative — punt to documentation only: cheaper but the README walkthrough already exists and clearly hasn't been enough; the UI gap is real friction for anyone running local models.

## Related

- #13 (dynamic model list — provider-side discovery; complementary)
- README.md:271-287 documents the JSON-only path that this issue would replace

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the Preferences provider and model controls in app/src/renderer/index.html:175-183, then inspect pi-coding-agent's ModelDefinitionSchema in node_modules/@mariozechner/pi-coding-agent/dist/core/model-registry.js and the existing IPC bridge. Done means custom fields can be saved to ~/.pi/agent/models.json, validation errors are surfaced, and the provider list reloads the saved configuration.

Written by the indexing model from the issue text.

Assessment

Tech stack
html, typescript
Domain
desktop, frontend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.