You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,8 @@ All notable changes to Sofos are documented in this file.
6
6
7
7
### Added
8
8
9
+
-**A new `/model` command opens an inline picker that lets you switch the active model.** Up and Down highlight an entry, Enter confirms, Esc cancels. Each row shows the model id, a short description, and a `(current)` tag on the model you are using right now. Models on the other provider are greyed out and tagged `(re-launch session to activate)`, because the underlying API client is built once at startup and cannot swap providers mid-session. The cursor skips greyed rows so you cannot land on a model the running session cannot reach. Typing `/model <name>` switches directly without opening the picker; same-provider switches happen in place, cross-provider attempts are refused with a clear "re-launch with `--model <name>`" message.
10
+
-**`--model` now lists the supported models when it rejects a value.** Passing `--model gpt-9.9` (or any slug outside the supported set) exits with `[supported models: claude-opus-4-7, claude-sonnet-4-6, claude-haiku-4-5, gpt-5.5, gpt-5.4, gpt-5.4-mini, gpt-5.3-codex]`, mirroring the existing `--reasoning-effort` rejection so the failure mode is consistent.
9
11
-**An inline suggestion list appears the moment you type `/`.** As soon as the input begins with a slash, a small panel below the input box lists every available slash command together with a short description, filtered by what you have typed so far. Up and Down highlight an entry, Enter runs it, Tab inserts it into the input so you can finish typing arguments, and Esc closes the panel. The Tab autocomplete that previously worked silently for a single match still does, but it now goes through the same suggestion list.
10
12
-**New `view_image` tool lets the model open an image on demand.** Given a local image file path or an `http(s)://` URL, the tool attaches the image to the conversation so the model can describe it. For a folder of images, the model is told to call `list_directory` first and then `view_image` once per file. Supports JPEG, PNG, GIF, and WebP up to 20 MB per local file; URLs are passed through to the model provider, which fetches them on its side. External paths reuse the same Read-permission prompt as `read_file`, so granting access to a directory once covers both tools. Local images larger than 2048 pixels on the long side are downscaled proportionally before they reach the model so a 4K screenshot does not burn through the per-image token budget; smaller images are sent unchanged.
11
13
@@ -17,7 +19,7 @@ All notable changes to Sofos are documented in this file.
17
19
18
20
-**Shell command and process substitution are now blocked in bash commands.** Constructs such as `echo $(rm bad)`, backtick substitution, and process substitution `<(cmd)` / `>(cmd)` previously slipped past the permission system because only the outer command name was checked. They are now refused before the command runs, with a clear message that names the marker. Single-quoted literals and arithmetic expansion `$((expr))` continue to work.
19
21
-**Workspace symlinks can no longer route bash reads outside the workspace.** When a bash command names a workspace-relative path that resolves through a symlink to a file outside the workspace, the path is now sent through the same external-path prompt that absolute and tilde paths already use.
20
-
-**MCP tools are filtered out in safe mode by default.** Previously safe mode only restricted Sofos's native tools, so any tool exposed by a configured MCP server still ran in safe-mode sessions. Each MCP server entry now has a `safe_mode` setting — `disabled` (default, filtered), `read_only`, or `allow` — and only servers whose setting opts them in have their tools listed to the model when safe mode is on. The startup banner and `/s` confirmation list which servers were filtered out and which were opted in so the user can see the actual scope of the session.
22
+
-**MCP tools are filtered out in safe mode by default.** Previously safe mode only restricted Sofos's native tools, so any tool exposed by a configured MCP server still ran in safe-mode sessions. Each MCP server entry now has a `safe_mode` setting — `disabled` (default, filtered), `read_only`, or `allow` — and only servers whose setting opts them in have their tools listed to the model when safe mode is on. The startup banner and `/safe` confirmation list which servers were filtered out and which were opted in so the user can see the actual scope of the session.
21
23
22
24
### Changed
23
25
@@ -244,7 +246,7 @@ All notable changes to Sofos are documented in this file.
244
246
245
247
-**Claude Opus 4.7 adaptive-thinking support.** Opus 4.7 rejects the older `{thinking: {type: "enabled", budget_tokens: N}}` shape; sofos now sends `{thinking: {type: "adaptive"}, output_config: {effort}}` instead. `/think on` maps to `effort: high`, `/think off` to `effort: low`. Status line and startup banner show `Adaptive thinking effort: high|low` instead of a fake token budget.
246
248
-**Confirmation modal now fits short terminals.** The 4-choice permission prompt grows the viewport when it can; when it can't, drops the separators / hint row and scrolls the choice list around the cursor with `▴` / `▾` cues.
247
-
-**Visible feedback on `/s` and `/n`** (safe-mode toggles). Now prints a one-line status (`Safe mode: enabled / read-only tools only; no writes or bash`, `Safe mode: disabled / all tools available`, or a dimmed `already enabled/disabled`).
249
+
-**Visible feedback on `/safe` and `/normal`** (safe-mode toggles). Now prints a one-line status (`Safe mode: enabled / read-only tools only; no writes or bash`, `Safe mode: disabled / all tools available`, or a dimmed `already enabled/disabled`).
|`/n`| Return to normal mode. Prompt changes to `>`. |
194
-
|`/exit`, `/quit`, `/q`, `Ctrl+D`| Save the session and exit with a cost summary. |
195
-
|`ESC` or `Ctrl+C` while busy | Interrupt the current AI turn. |
192
+
|`/model`| Open the model picker. Highlight an entry with **Up / Down**, **Enter** to switch, **Esc** to cancel. Models on the other provider are greyed out (the API client is fixed at startup) and the cursor skips them. |
193
+
|`/model <name>`| Switch directly to a named model without opening the picker. Same-provider only — cross-provider switches require relaunching with `--model <name>`. |
|`/normal`| Return to normal mode. Prompt changes to `>`. |
196
+
|`/exit`, `/quit`, `/q`, `Ctrl+D`| Save the session and exit with a cost summary. |
197
+
|`ESC` or `Ctrl+C` while busy | Interrupt the current AI turn. |
196
198
197
199
### Input behaviour
198
200
@@ -258,6 +260,20 @@ Supported formats: JPEG, PNG, GIF, and WebP. Local images are capped at 20 MB. I
258
260
259
261
## Models and reasoning effort
260
262
263
+
Sofos supports seven models, in `/model` picker order:
264
+
265
+
| Model | Provider |
266
+
|---|---|
267
+
|`claude-opus-4-7`| Anthropic |
268
+
|`claude-sonnet-4-6` (default) | Anthropic |
269
+
|`claude-haiku-4-5`| Anthropic |
270
+
|`gpt-5.5`| OpenAI |
271
+
|`gpt-5.4`| OpenAI |
272
+
|`gpt-5.4-mini`| OpenAI |
273
+
|`gpt-5.3-codex`| OpenAI |
274
+
275
+
`--model <name>` accepts only the values above; any other slug is refused at startup with the supported list. The same whitelist drives the inline `/model` picker, so the two surfaces never disagree about which models exist.
Copy file name to clipboardExpand all lines: STRUCTURE.md
+12-4Lines changed: 12 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -551,6 +551,8 @@ Rules:
551
551
552
552
It contains:
553
553
554
+
- the `SUPPORTED_MODELS` whitelist — every model id accepted by `--model` and shown in the `/model` picker, with its description and provider;
555
+
- helpers `canonical_model`, `model_support_error`, and `supported_models_label` that share one source of truth with the CLI rejection message and the picker rows;
554
556
- model registry entries;
555
557
- context-window sizes;
556
558
- auto-compaction thresholds;
@@ -562,7 +564,8 @@ It contains:
562
564
Rules:
563
565
564
566
- Model capability checks should use this registry instead of hard-coded scattered checks.
565
-
- Adding a supported model should be primarily a registry change plus any provider-specific wire support if needed.
567
+
- Adding a supported model is one struct literal in `SUPPORTED_MODELS` — the `Model` struct carries the user-facing description and provider alongside the context window, effort matrix, and pricing, so there is no separate `lookup` table to keep in sync.
568
+
- Removing a model is one deletion in `SUPPORTED_MODELS`. The CLI and the picker share that array as their source of truth, so nothing else has to be touched.
566
569
567
570
### 4.7 `api/truncate.rs`
568
571
@@ -608,7 +611,7 @@ It contains:
608
611
- available-tool refresh;
609
612
- one-shot prompt execution;
610
613
- status-line snapshots;
611
-
-`/think`, `/s`, `/n`, and `/clear` state handlers;
614
+
-`/think`, `/safe`, `/normal`, and `/clear` state handlers;
612
615
- shared interrupt and mid-turn steering buffers.
613
616
614
617
Rules:
@@ -759,6 +762,11 @@ It contains:
759
762
-`slash_popup.rs` — state for the inline slash-command suggestion list;
760
763
-`sgr.rs` — SGR escape helpers.
761
764
765
+
The TUI also carries two modal pickers as fields on `app::App` and corresponding job/event variants:
- the model picker (`ModelPicker` + `UiEvent::ShowModelPicker` + `Job::ModelSelected`) drives `/model`. Rows on the other provider are flagged unavailable on the `ModelPickerEntry`, the renderer greys them out, and the navigation helper in `app.rs` skips past them so the cursor only lands on a model the running session can switch to.
769
+
762
770
Rules:
763
771
764
772
- The TUI owns terminal interaction and event routing; it does not decide provider request structure.
0 commit comments