Skip to content

Commit ecdde9d

Browse files
authored
feat(web): redesign the Providers settings panel (#280)
## Related Issue None — user-reported UX problem with the desktop Providers settings tab, plus engine/gateway hardening carried on the same branch. ## Problem The Providers tab listed all models above the config form, so editing a provider meant scrolling past dozens of rows. Worse, the form under the list showed a *different* provider's data (selecting `opencode-go` still showed `deepseek`'s name and key) and an empty `model-id` row. Delete lived in a button at the bottom of that scroll. Separately: quoted heredoc bodies forced extra Bash approval prompts, the Bash tool rejected a `cwd` outside the workspace roots, an uncaught exception killed the gateway process, and session details always reported `last_seq: 0` so clients replayed history on resume. ## What changed **Web (`apps/pythinker-web`)** - `ProvidersPanel.vue`: config form comes first; the read-only model list and the bottom delete button are gone. Each provider row has a red trash icon that opens the existing delete confirmation. The edit form is keyed by provider id so switching providers re-seeds it (root cause of the stale `deepseek` form). - `ProviderForm.vue`: the editable model table is collapsed behind a "Models (N)" toggle, open by default only in add mode; auto-opens on Add model or a model-row validation error. The form re-seeds when the config prop arrives after mount (root cause of the empty row). The grid fits the pane without horizontal scroll. - `providerForm.ts`: `modelsForProvider` falls back to catalog aliases when the config section has no rows; the panel merges `listModels()` in so fallback rows carry real context sizes. - `dist-web` restaged. **Engine / gateway** - `tree-sitter-bash` lexer: `scanBalancedStatements` is heredoc-aware (queues `<<`/`<<-` delimiters, skips bodies after the newline), and skips comments, `$[ ]`/`${ }`, `[[ ]]`, subscripts and `(( ))` so a `<<` inside them is not taken as a heredoc. Parse budget raised from 20ms to 500ms in the permission policy and AGENTS.md reminder. - `RuntimeWorkspaceView.resolve` no longer asserts the path is inside the workspace; `assertAllowed` returns the resolved path and the terminal service calls it explicitly. The Bash tool therefore accepts any `cwd` (a command could `cd` there anyway). - `start.ts`: `uncaughtException` is logged at error level and no longer exits the process. - Session detail (`GET /api/v1/sessions/:id`) reports the broadcaster's journaled watermark as `last_seq`; the cursor is fetched after the 404 check. - Telemetry `flattenEvent` drops null fields; `SessionIndexMirror` tracks the give-up event once per failure streak. - `createServerLogger` accepts a pino destination stream (used by `boot.test.ts`). ## Verification - `pnpm run lint`: 0 errors. Typecheck clean for agent-core-v2, agent-gateway, telemetry, tree-sitter-bash, pythinker-web. - Package suites: agent-gateway 1361, telemetry 72, tree-sitter-bash 867, pythinker-web 1186, agent-core-v2 6089 (7 temp-dir races under parallel load; pass in isolation). - Pre-push full run: 7347 passed. - Providers tab checked in the browser against the dev gateway. ## Checklist - [x] I have read the [CONTRIBUTING](https://github.com/PyModel/pythinker-code/blob/main/CONTRIBUTING.md) document. - [ ] I have linked a related issue (external PRs: the issue must have a maintainer's `/approve`). - [x] I have added tests that prove my feature works. - [x] Ran `gen-changesets` skill, or this PR needs no changeset. - [x] Ran `gen-docs` skill, or this PR needs no doc update. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Redesigned provider settings with per-provider model configuration, collapsible model lists, model counts, and inline deletion controls. * Session details now report event positions so clients can resume without replaying earlier events. * Bash commands support working directories outside workspace roots. * **Bug Fixes** * Quoted Bash heredocs no longer trigger unnecessary approval prompts. * The gateway server remains available after unexpected errors. * Provider model catalogs now populate missing configured model entries automatically. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 6c8f668 commit ecdde9d

126 files changed

Lines changed: 1033 additions & 460 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@pymodel/pythinker-code": patch
3+
---
4+
5+
Allow the Bash tool to run with a working directory outside the workspace roots.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@pymodel/pythinker-code": patch
3+
---
4+
5+
Handle heredocs when scanning Bash commands so quoted heredoc content no longer forces extra approval prompts.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@pymodel/pythinker-code": minor
3+
---
4+
5+
Redesign the Providers settings: each provider shows its own config first with models in a collapsible section, and a delete icon sits next to every provider.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@pymodel/pythinker-code": patch
3+
---
4+
5+
Keep the gateway server running after an unexpected error instead of exiting the process.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@pymodel/pythinker-code": patch
3+
---
4+
5+
Fetch the current event position with session details so clients resume without replaying past events.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"sourceHash": "b4e1d71e0d61f64d0e2e3912d98a78ef4aa51b98b2885e614081ae9e47c77e34",
2+
"sourceHash": "ec0a2f164d8ce7b1beae37abae45b2de37e96de5c4f7b54e460eb1fc77996537",
33
"sourceFileCount": 422
44
}

apps/pythinker-code/dist-web/assets/CodeBlockNode-DurPx7zc.js renamed to apps/pythinker-code/dist-web/assets/CodeBlockNode-BEWBjffx.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/pythinker-code/dist-web/assets/DesignSystemView-Cp27_JXa.js renamed to apps/pythinker-code/dist-web/assets/DesignSystemView-DpIR-8qH.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/pythinker-code/dist-web/assets/Tooltip-BPZnuv72.js renamed to apps/pythinker-code/dist-web/assets/Tooltip-BESdymXf.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/pythinker-code/dist-web/assets/abnfDiagram-VCTEODGH-BcDooclE.js renamed to apps/pythinker-code/dist-web/assets/abnfDiagram-VCTEODGH-pY3uSi_B.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)