Skip to content

fix(ui-web): say a failed connect or test under the agent, not instead of it - #785

Merged
0xKT merged 2 commits into
mainfrom
fix/agent_failure_states
Sep 24, 2026
Merged

0xKT merged 2 commits into
mainfrom
fix/agent_failure_states

Conversation

@arelchan

@arelchan arelchan commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The agent connector (Settings > Agent connections, and the onboarding agents step) is reworked around what goes wrong on it. Frontend only: no RPC change, and every word drawn comes from fields subagents.* already sends (data.detail and data.remedy on a refused write, last_test_* on a row).

A failure is said under the agent, not instead of it. A refused connect or a failed test used to replace the line about the agent with a red sentence, and a card or sheet grew to fit it. Now:

Waiting. Before the first roster arrives the grid draws one placeholder card per catalogue entry (the catalogue is the roster on every machine), with the settings sections' shimmer; the tab counts wait as bars rather than showing 0. The shimmer gate now covers these bars too.

Agent marks in the dark theme. Every mark now sits on a light plate in both themes, as the app icon does, and no filter reaches a mark. Inverting hermesagent.svg gave its negative, and the hue rotation that put qoder's green back landed on a different green (#2ADB5C -> #008203). The plate is a token (--mark-plate) declared by every theme block, and the embedded color-scheme is pinned light on the tile, so raven.svg and miromind.svg draw their light selves on it. agent-mark-css.test.mjs is rewritten to pin that: no filter on a mark, the plate token in every theme path, the scheme pinned on the tile and not on :root.

Copy. The general settings' language hint now says it picks the interface's language rather than Raven's.

Rebased onto #773, #779, #786 and #781, which touch the same files. #773's healthOf stays the one verdict for the dot and the sheet's head; the card's footer and corner, and the sheet's note, are this change's. #773's rule that an off row wears no dot for a failed test is kept; its footer still says so. #779's FIX_SAY table and step labels feed the note, with #786's remedy passed through so the runtime sentence names both Node.js versions; a runtime fix sent without them reads as a launch that quit in the title and on the card too (kindOf), as FIX_SAY already says it; its row sentences (bad_run*, bad_retry, bad_open) and the fix_unknown_* keys have no caller left and are removed.

Earlier decisions this changes, for their authors to confirm:

Review follow-up. The failed-test note named Test for every row that was not connected, but the sheet's bar offers Test only to an unauthorized row; a row whose test has since cleared its handshake, and an endpoint still waiting on its key, show Connect alone. The note now reads its press from the same branches as the bar (testPress), and a test walks every state a failed test can leave a row in and checks the note names a button the bar renders. The endpoint test that expected Test for a row waiting on its key now expects Connect.

Type

  • Fix
  • Feature
  • Docs
  • CI / tooling
  • Refactor
  • Other

Verification

After the rebase onto main at 05cac1f1:

  • npx vitest run --maxWorkers=4 in ui-web -- 210 files, 3055 tests passed; the extAgents suites and page gates alone (npx vitest run src/features/extAgents scripts/gates) 385 tests

  • npx tsc --noEmit -p . and npm run lint in ui-web -- 0 errors (the 4 warnings main already has)

  • node scripts/check-css.mjs, node scripts/check-class-namespace.mjs, npm run build && python3 build.py && node scripts/check-page.mjs in ui-web -- OK

  • npm run gen:check in ui-web -- generated.ts matches the contract

  • npm run gen:i18n and npm run lint:i18n in ui-tui -- the generated table is up to date

  • uv run pytest tests/test_ui_agent_marks.py -q -- 7 passed

  • Real browser (Playwright on the Vite dev page, zh and en, light and dark), with failure states injected from backend-shaped fixtures (sign_in, setup, api_key, download, and model with a then step; the unit tests take every kind): all 11 cards 149px tall across healthy, testing and failed states and in the placeholder grid; the sheet 520x500 for 7 rows in different states; a click on the corner retry does not open the sheet

  • Against a live gateway (Vite dev server proxying /auth to it): the real 18-row roster renders with the new footer and plate

  • Relevant tests pass locally

  • Relevant lint / type checks pass locally

  • User-facing docs or screenshots are updated when needed

No user-facing docs describe the agent cards.

Risk

  • Security impact considered
  • Backward compatibility considered
  • Rollback path is clear for risky changes

User-visible: the card and sheet layout for failures, the corner control now also retries and retests, the waiting grid, and every agent mark sits on a light plate in the dark theme (a visible change to all mark tiles there, including the sub-agents card and pane headers that share .agent-mark). No RPC, config or stored-state change; reverting the squash commit restores the previous page.

Related Issues

N/A

@gloryfromca gloryfromca left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: the failed-test note can direct the user to a button that is not present.

I found one actionable state mismatch inline. I reviewed the full diff and relevant extAgents rendering, store/source state transitions, callers, recent history, compatibility behavior, and the repository rules in AGENTS.md, CONTEXT-MAP.md, and ui-web/CONTEXT.md. I also checked that the changed tests preserve the existing behaviors rather than weakening them.

Verification: npm run type-check passed; the focused extAgents/CSS suite passed (117 tests); the full npm test suite passed (210 files, 3037 tests); npm run lint completed with no errors and four pre-existing warnings in untouched files.

Comment thread ui-web/src/features/extAgents/ExtAgentsPage.tsx Outdated
@arelchan
arelchan requested a review from 0xKT September 24, 2026 10:42
@arelchan
arelchan force-pushed the fix/agent_failure_states branch from 2acd321 to 6838324 Compare September 24, 2026 10:43

@gloryfromca gloryfromca left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: the existing failed-test note/action mismatch remains unchanged.

The rebase compatibility work for the new runtime remedy is coherent, but the open finding still reproduces: after the test case clears needs_auth while leaving the row unconfigured and failed, noteOf names Test while AgentSheet renders Connect. I found no additional blocker in this revision, and the original thread remains open.

I reviewed the fresh github/main...HEAD diff, the rebase delta, the extAgents state/action callers, the new remedy compatibility path, recent history, backward compatibility, test changes, and the applicable AGENTS.md and Web UI context constraints.

Verification: npm run type-check passed; the focused extAgents and CSS suite passed (6 files, 169 tests); the full npm test suite passed (210 files, 3041 tests).

arelchan and others added 2 commits September 24, 2026 18:58
…d of it

The agent connector used to replace the line about an agent with a red
sentence when a connect was refused or a test failed, and grew the card
and the sheet to fit whatever it had to say. Now every card is one fixed
shape: the name, two lines of room for what the agent does, and a slot
that always speaks. With nothing wrong the slot says which state the row
is in (connected, available, not installed, and when a passed test
passed); a refused write or a failed test fills it with a single-line
strip in clay, one word for what failed and a short reason read from the
server's remedy kind; a write in flight fills it in amber. The press that
answers a strip is the card's corner control, where connect and install
already live, so the strip itself carries no button. The sheet keeps its
520x500 box and folds the server's sentence and its fix into a note that
scrolls inside the body.

Before the first roster arrives the grid draws one placeholder card per
catalogue entry, since the catalogue is the roster on every machine, with
the same shimmer the settings sections wait with.

Agent marks now sit on a light plate in both themes, the way the app icon
does, and the dark theme filters no mark: inverting hermesagent.svg gave
its negative and the hue rotation that put qoder's green back landed on a
different green. The plate is a token that does not follow the theme, and
the embedded color-scheme is pinned light on the tile so raven.svg and
miromind.svg draw their light selves on it under either theme.

The general settings' language hint now says it picks the interface's
language rather than Raven's.

Co-authored-by: Claude (claude-fable-5-1) <noreply@anthropic.com>
… note

The note at the top of the sheet told the reader to press Test after any
failed test on a row that was not connected. The bar offers Test only to
an unauthorized row. A row whose test has since cleared its handshake, and
an endpoint still waiting on its key, show Connect alone, so the note named
a control that was not there.

The note now reads its press from the same branches as the bar: a
connected row retests, an unauthorized one tests, any other row that is
not connected connects, which runs the same test. The endpoint test that
pinned Test for a row waiting on its key now expects Connect, and a new
case walks every state a failed test can leave a row in and checks the
note names a button the bar renders.

Co-authored-by: Claude (claude-opus-5-5) <noreply@anthropic.com>
@arelchan
arelchan force-pushed the fix/agent_failure_states branch from 6838324 to c52fb63 Compare September 24, 2026 10:59

@gloryfromca gloryfromca left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blockers; this can merge as far as I am concerned.

The action-label mismatch is fixed: the note now follows the same state branches as the sheet action bar, and the regression test covers the original transition plus connected, unauthorized, available, and key-waiting rows. I replied to and resolved my finding thread.

I reviewed the updated github/main...HEAD diff, the new commit, the affected state/action callers, compatibility behavior, test changes, and the previously covered repository and Web UI constraints. No new finding survived review.

Verification: npm run type-check passed; the focused extAgents and CSS suite passed (6 files, 181 tests).

@0xKT
0xKT merged commit 96ce7af into main Sep 24, 2026
29 of 30 checks passed
@0xKT
0xKT deleted the fix/agent_failure_states branch September 24, 2026 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants