Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,26 +78,22 @@ Pinned image tags, binary tarballs (linux/darwin × amd64/arm64), checksums, com

### Add a provider

On first boot, Chats is already available, but model chat needs at least one configured provider. Open **Providers**, click **Add provider**, pick a preset, and save the minimal setup:
On first boot, Chats is already available. If Hecate detects a local runtime such as Ollama or LM Studio, the model chat setup can be one click: choose **Add detected providers** and Hecate adds the detected local endpoints with the preset defaults.

![Chats first-run state — detected local providers and one-click Add detected providers setup](docs/screenshots/chat-empty.png)

You can still configure providers manually from **Providers → Add provider**:

- Cloud providers need an API key.
- Local providers need a running local server URL, usually the preset default.
- Custom OpenAI-compatible endpoints can be added from the same modal when the preset catalog is not enough.

![Empty Providers tab on first boot — Add provider CTA](docs/screenshots/providers-empty.png)

![Add provider modal on the Cloud tab — preset catalog](docs/screenshots/providers-presets.png)

![Providers table populated with three providers — Health, Endpoint, Credentials, Models](docs/screenshots/providers.png)

After a provider is saved, Hecate discovers models and the Chats model picker becomes routable. The full preset catalog, env bootstrapping, custom-endpoint walk-through, and credential rotation live in [`docs/providers.md`](docs/providers.md).

### Talk to it

Chats is the primary day-to-day surface. It explains missing setup before you send a request, then lets you choose between model traffic and local coding-agent sessions.

![Chats first-run state — no configured providers or available external agents yet](docs/screenshots/chat-empty.png)

![Chats workspace talking to a local Ollama llama3.1:8b model with sessions sidebar and inline runtime metadata](docs/screenshots/chat.png)

![Chats workspace with an external-agent file-write approval waiting for operator review](docs/screenshots/chat-agent-approval.png)
Expand Down Expand Up @@ -158,6 +154,12 @@ The embedded UI is a runtime console for the operator.

![Observability view — request ledger and route-report drilldown](docs/screenshots/observe.png)

![Empty Providers tab — Add provider CTA](docs/screenshots/providers-empty.png)

![Add provider modal — local preset catalog with detected runtime status](docs/screenshots/providers-presets.png)

![Providers workspace — configured cloud and local providers with health, endpoint, credentials, and models](docs/screenshots/providers.png)

![Tasks workspace — task list with run state and approval queue](docs/screenshots/tasks.png)

![Costs workspace — balance card and usage table](docs/screenshots/costs.png)
Expand Down
23 changes: 23 additions & 0 deletions docs-ai/skills/ui/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,29 @@ Every screen should answer the following quickly:

When choosing between "pretty" and "operationally clear," choose clarity.

## Accessibility baseline

Accessibility is part of the design pass, not a cleanup pass. Every UI change
should preserve keyboard, screen-reader, focus, contrast, and motion ergonomics
unless there is an explicit product reason and a documented follow-up.

- Use semantic HTML first: buttons for actions, anchors for navigation, labels
for form controls, tables for real tables, headings that reflect structure.
- Every interactive control needs a visible focus state and a keyboard path.
Dropdowns, dialogs, popovers, and slideovers must support Escape / outside
dismissal where appropriate and return focus to the trigger.
- Icon-only controls need accessible names. Status chips and color-coded states
need text, not color alone.
- Modal and dialog work must include focus management, `aria-modal`, labelled
titles, and non-trapping escape paths.
- Keep contrast readable in the dark operator theme. Muted text can be quiet,
but it still needs to be legible against panels and borders.
- Respect reduced-motion expectations. Motion should orient; avoid relying on
animation to convey state.
- Add or update tests for accessibility-sensitive behavior when changing UI
primitives: role/name queries, focus movement, disabled states, and keyboard
interactions are preferred over brittle DOM selectors.

## Information architecture

Organize the UI around operator jobs, not components:
Expand Down
22 changes: 21 additions & 1 deletion docs/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The Providers tab starts empty:

Click **Add provider** to open the modal:

![Add provider modal — Cloud preset catalog](screenshots/providers-presets.png)
![Add provider modal — Local preset catalog with detected runtime status](screenshots/providers-presets.png)


1. Pick **Cloud** or **Local** at the top.
Expand All @@ -39,6 +39,23 @@ Click **Add provider** to open the modal:
- **API Key** is shown for cloud and custom-cloud providers; stored encrypted at rest with `GATEWAY_CONTROL_PLANE_SECRET_KEY`.
4. Click **Add provider**.

The Local tab also runs a lightweight discovery check before you choose a
preset. Hecate checks whether the expected command is on `PATH` (`ollama`,
`lms`, `llama-server`, `local-ai` / `localai`) and probes each unique local
HTTP endpoint once. The preset cards then show:

- **Running** — the local HTTP API responded; model count is shown when the
provider returned one.
- **Installed** — the command is available, but the HTTP server is not running
yet.
- **Not detected** — no command on `PATH` and no response from the default
endpoint.

`llamacpp` and `localai` share `127.0.0.1:8080` by default, so Hecate sends one
HTTP request and reuses that result for both cards. The signal is advisory:
adding the provider still uses the configured endpoint URL, and routing health
continues to come from the normal `/admin/providers` probes.

A provider you add is immediately routable. There is no separate enable/disable toggle — to take a provider out of rotation, delete it.

![Providers table populated with three providers — Health, Endpoint, Credentials, Models columns](screenshots/providers.png)
Expand Down Expand Up @@ -114,6 +131,9 @@ normalized assistant text, model, and token usage are.
Every UI action maps to a control-plane endpoint:

- `POST /admin/control-plane/providers` — add a provider. Body `{name, kind, protocol, base_url?, api_key?, custom_name?, preset_id?}`.
- `GET /admin/control-plane/providers/local-discovery` — probe local presets
for command presence and default endpoint availability. Used by the Add
provider modal before a provider is created.
- `DELETE /admin/control-plane/providers/{id}` — remove it.
- `PATCH /admin/control-plane/providers/{id}` — partial update; accepts `base_url`, `name`, and `custom_name`.
- `PUT /admin/control-plane/providers/{id}/api-key` — set the API key (empty `key` clears it).
Expand Down
42 changes: 42 additions & 0 deletions docs/runtime-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,48 @@ GET /v1/provider-presets

The list is built from `config.BuiltInProviders()` — see [`docs/providers.md`](providers.md) for the full catalog and OpenAI-compatible custom-endpoint flow.

### `GET /admin/control-plane/providers/local-discovery`

Advisory discovery for the Providers tab's **Add provider → Local** catalog.
The gateway checks whether the expected provider command is on `PATH` and
probes each unique default local endpoint once. Shared endpoints, such as the
`llama.cpp` / `LocalAI` default `127.0.0.1:8080/v1`, are only called once and
then reused for every matching preset card.

```json
GET /admin/control-plane/providers/local-discovery
→ 200
{
"object": "local_provider_discovery",
"data": [
{
"preset_id": "ollama",
"name": "Ollama",
"base_url": "http://127.0.0.1:11434/v1",
"probe_url": "http://127.0.0.1:11434/api/tags",
"status": "running",
"command": "ollama",
"command_available": true,
"command_path": "/opt/homebrew/bin/ollama",
"http_available": true,
"model_count": 2,
"models": ["llama3.1:8b", "qwen2.5:7b"]
}
]
}
```

`status` is one of:

- `running` — the HTTP probe returned 2xx.
- `installed` — the command is present on `PATH`, but the default HTTP
endpoint did not respond.
- `not_detected` — neither the command nor the default HTTP endpoint was found.

This endpoint does not create or mutate provider records. It is a UX helper for
the picker; routing readiness still comes from `GET /admin/providers` after the
operator adds a provider.

### `GET /v1/agent-adapters`

External coding-agent adapter catalog. This is the first discovery surface for
Expand Down
Binary file modified docs/screenshots/chat-agent-approval.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/chat-empty.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/chat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/observe.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/providers-presets.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/providers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/settings-external-agents.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/tasks.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading