mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-05 21:39:54 +02:00
Adds a first-class `model` field to agents so users can pick the LLM model
from the create / settings UI instead of editing custom_env / custom_args.
The previous "set MULTICA_<PROVIDER>_MODEL env var on the daemon" approach
forced one model per provider per machine and was easy to misconfigure
(e.g. -m as a custom_arg breaks codex app-server initialization).
Backend (server/pkg/agent):
- New `agent.ListModels(provider, path)` returns the models supported by a
provider. Static catalogs for claude, codex, gemini, cursor, copilot;
dynamic discovery for opencode (`opencode models`), pi (`pi --list-models`),
openclaw (`openclaw agents list`); 60s TTL cache + empty-list fallback on
failure. Hermes returns an empty list and `ModelSelectionSupported=false`
because its model is configured out-of-band.
- `agent.DefaultModel(provider)` returns the recommended default per
provider (Sonnet 4.6 for claude, GPT-5.4 for codex, Gemini 2.5 Pro for
gemini, composer-1.5 for cursor); copilot/openclaw/hermes deliberately
have no default. The static catalog tags one entry per provider with
`Default: true` so the UI can render a badge.
- For openclaw, opts.Model is mapped to `--agent <name>` since the CLI
rejects `--model` outright; custom_args `--agent` still wins for
back-compat.
Daemon protocol (server/internal/daemon):
- Heartbeat response carries an optional `pending_model_list` request
(same pattern as PingStore / UpdateStore). The daemon resolves models
via `agent.ListModels`, including the `supported` flag, and reports
back via /api/daemon/runtimes/{id}/models/{requestId}/result.
- Task dispatch uses a three-tier fallback for the runtime model:
agent.model → MULTICA_<PROVIDER>_MODEL env → agent.DefaultModel(provider).
Server API (server/internal/handler):
- `agent.model` is a new column (migration 050) and surfaces in
Agent / CreateAgent / UpdateAgent payloads.
- New endpoints under /api/runtimes/{id}/models: POST to initiate
discovery, GET to poll the request, plus the daemon-side report
endpoint above.
CLI (server/cmd/multica):
- `multica agent create / update --model <id>`. Help copy steers users
away from passing --model via --custom-args, which fails on codex
(app-server mode) and openclaw.
Frontend (packages/core, packages/views):
- `Agent.model`, `RuntimeModel`, `RuntimeModelListRequest`,
`RuntimeModelsResult` types.
- `runtimes/models.ts` exports `runtimeModelsOptions(runtimeId)` which
initiates discovery and polls the request to completion (500ms
cadence, 30s ceiling).
- New `ModelDropdown` (packages/views/agents) — searchable popover,
provider grouping, creatable manual entry, "default" badge on the
shipped recommendation, disabled state when the provider reports
`supported=false` (Hermes), and clears any stale model value in that
case to avoid persisting a ghost configuration.
- Wired into create-agent-dialog and the agent settings tab.
Verification:
- gofmt clean on touched files
- `go build ./... && go test ./...` (server) green; new openclaw and
models_test cases included
- `pnpm typecheck` green across all 6 packages
Closes the immediate UX gap behind MUL-1151. DeepSeek V4 (or any new
model) becomes a zero-code addition: add it to the relevant static
catalog, or rely on the creatable input for one-off use.