New settings page #12

Closed
opened 2026-09-13 17:58:46 -04:00 by cmoriarty · 1 comment
Owner

I'd like a settings page, accessible through a little gear icon in the upper right.

Initial settings:

  1. Backend - This is where you should be able to point it at any backend, not just vLLM.
  2. Number of subagents - The number of subagents accessible to Braid should be configurable.
  3. KV per agent - I'm not sure how to express this, and I still get it confused with "context" values, but it should be configurable.
  4. Thinking blocks - by default they should be hidden by default, but this could change it to be shown by default.

Any other settings I'm not thinking of.

I'd like a settings page, accessible through a little gear icon in the upper right. Initial settings: 1. Backend - This is where you should be able to point it at any backend, not just vLLM. 2. Number of subagents - The number of subagents accessible to Braid should be configurable. 3. KV per agent - I'm not sure how to express this, and I still get it confused with "context" values, but it should be configurable. 4. Thinking blocks - by default they should be hidden by default, but this could change it to be shown by default. Any other settings I'm not thinking of.
Author
Owner

Shipped as the OpenSpec change settings-page (archived as openspec/changes/archive/2026-09-14-settings-page/). It adds a new main spec, settings, and updates agent-delegation. Commit 0a7e6a9.

A ⚙ at the upper right of the header opens #/settings on every screen and at every width.

settings

What you can set

  1. Backend. Any OpenAI-compatible server:
    • kind (vLLM, SGLang, llama.cpp, Ollama, LM Studio, OpenAI-compatible);
    • base URL, model and the model's context window;
    • an API key file: a path, never the key itself. A run's opencode.json gets "apiKey": "{file:<path>}", which opencode resolves (checked with opencode debug config).
    • Test connection asks /models and turns the ids it lists into one-click model choices.
    • The status light and the Inference screen name the configured backend. vLLM's /metrics is only scraped when the kind is vLLM.
  2. Subagents. Which of reader / explore / test implementation steps may use, and how many at once. 0 turns delegation off: nothing in the task permission, and no delegation policy in the prompt.
  3. KV per agent, called Context per agent on the page. It's each agent's share of the server's KV cache, i.e. the most context one session may hold. The handoff alarm and the step allowance scale with it at today's ratios (150k → 112k / 144k; 100k → 74,666 / 96,000), and the page shows both as you type.
  4. Thinking shown by default. It applies in every browser that hasn't ticked "show thinking" itself. Saving it resets your own browser's choice.
  5. Also: Concurrent runs, replacing OSF_RUN_CAP.

When a change applies

  • A run keeps the backend and subagents it started with (runs/<id>/settings.json), including across an osfd restart.
  • The context limit applies from the next attempt, including the pre-flight estimate.
  • The run limit applies at the next admission.
  • Every field shows its default when it differs, and says when it takes effect.

How it's stored: each save is one human.settings event on the log with the complete saved map, so every change is audited. Anything never saved falls back to the old env var or constant, so an install that never opens the page behaves exactly as before. Saves are all-or-nothing, with a message per invalid field.

phone

Tested

  • pytest (1556 passed): defaults, validation, the log read, the run snapshot, provisioning with a narrower roster or none, the delegation prompt, the model in prompts, the budget alarm moving with a saved context, the estimate subprocess, run admission, the probe with a key header, and the API (all-or-nothing, idempotency, null forgets, the key never echoed, Test connection against a live /models).
  • vitest 338.
  • e2e/settings.spec.ts against the fake osfd, 7 tests: gear from the runs list, a run and a phone; Save disabled until a change; a change surviving a reload; an out-of-range context saving nothing; the ladder hint; Test connection; the thinking default ticking the checkbox. Full Playwright suite: 33 passed, 3 skipped for live osfd.
  • A real osfd on a scratch state dir. I saved settings through the page, restarted osfd, and they were still there. A new run's opencode.json had the saved model, URL and only test as a subagent. After I saved a different model and restarted again, that run kept its original model and roster.

Not included: settings for a separate inference gate process (when OSF_GATE_URL is set the page says so), approval levels, and notifications. Those stay in the environment.

Shipped as the OpenSpec change `settings-page` (archived as `openspec/changes/archive/2026-09-14-settings-page/`). It adds a new main spec, `settings`, and updates `agent-delegation`. Commit 0a7e6a9. A **⚙** at the upper right of the header opens `#/settings` on every screen and at every width. ![settings](https://forgejo.underthere.xyz/attachments/e7f77714-4ebc-4055-b485-d994f873b9ff) **What you can set** 1. **Backend.** Any OpenAI-compatible server: - kind (vLLM, SGLang, llama.cpp, Ollama, LM Studio, OpenAI-compatible); - base URL, model and the model's context window; - an **API key file**: a path, never the key itself. A run's `opencode.json` gets `"apiKey": "{file:<path>}"`, which opencode resolves (checked with `opencode debug config`). - **Test connection** asks `/models` and turns the ids it lists into one-click model choices. - The status light and the Inference screen name the configured backend. vLLM's `/metrics` is only scraped when the kind is vLLM. 2. **Subagents.** Which of `reader` / `explore` / `test` implementation steps may use, and how many at once. 0 turns delegation off: nothing in the task permission, and no delegation policy in the prompt. 3. **KV per agent**, called **Context per agent** on the page. It's each agent's share of the server's KV cache, i.e. the most context one session may hold. The handoff alarm and the step allowance scale with it at today's ratios (150k → 112k / 144k; 100k → 74,666 / 96,000), and the page shows both as you type. 4. **Thinking shown by default.** It applies in every browser that hasn't ticked "show thinking" itself. Saving it resets your own browser's choice. 5. Also: **Concurrent runs**, replacing `OSF_RUN_CAP`. **When a change applies** - A run keeps the backend and subagents it started with (`runs/<id>/settings.json`), including across an osfd restart. - The context limit applies from the next attempt, including the pre-flight estimate. - The run limit applies at the next admission. - Every field shows its default when it differs, and says when it takes effect. **How it's stored:** each save is one `human.settings` event on the log with the complete saved map, so every change is audited. Anything never saved falls back to the old env var or constant, so an install that never opens the page behaves exactly as before. Saves are all-or-nothing, with a message per invalid field. ![phone](https://forgejo.underthere.xyz/attachments/91d49d98-97f0-4d3c-a5e0-afa9f4d5ae0c) **Tested** - **pytest** (1556 passed): defaults, validation, the log read, the run snapshot, provisioning with a narrower roster or none, the delegation prompt, the model in prompts, the budget alarm moving with a saved context, the estimate subprocess, run admission, the probe with a key header, and the API (all-or-nothing, idempotency, `null` forgets, the key never echoed, Test connection against a live `/models`). - **vitest** 338. - **`e2e/settings.spec.ts`** against the fake osfd, 7 tests: gear from the runs list, a run and a phone; Save disabled until a change; a change surviving a reload; an out-of-range context saving nothing; the ladder hint; Test connection; the thinking default ticking the checkbox. Full Playwright suite: 33 passed, 3 skipped for live osfd. - **A real osfd on a scratch state dir.** I saved settings through the page, restarted osfd, and they were still there. A new run's `opencode.json` had the saved model, URL and only `test` as a subagent. After I saved a different model and restarted again, that run kept its original model and roster. **Not included:** settings for a separate inference gate process (when `OSF_GATE_URL` is set the page says so), approval levels, and notifications. Those stay in the environment.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cmoriarty/braid#12
No description provided.