Skip to content

fix(agents): explain unavailable harnesses accurately - #1883

Merged
tellaho merged 1 commit into
mainfrom
tho/agents-harness-unavailable-message
Oct 29, 2026
Merged

tellaho merged 1 commit into
mainfrom
tho/agents-harness-unavailable-message

Conversation

@tellaho

@tellaho tellaho commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Category: fix

User Impact: Agents with an unavailable harness now show recovery guidance instead of incorrectly saying they run on another device.

Problem: When an agent's harness is missing from the client, Agents labels it “On another device” and says another device holds its key. That explanation can be false for hosted agents whose plugin or configuration is unavailable.

Solution: Show “Harness unavailable” and direct users to Settings → Plugins or a build with the harness configured. Keep the existing other-device explanation for recognized local harnesses.

Changes

File changes

src/bundled/agents/AgentsPage.tsx
Use the registered harness type to choose the card summary and read-only detail guidance.

src/bundled/agents/AgentsPage.test.tsx
Cover an unavailable hosted harness: show recovery guidance, omit the other-device claim, and retain read-only behavior.

This is the standalone AgentsPage patch extracted from #1881; provider setup and runtime changes are excluded.

Reproduction steps

  1. Open a client where an existing hosted agent's harness is unavailable.
  2. Open Agents. Its card should say Harness unavailable.
  3. Select the agent. The detail pane should direct you to Settings → Plugins or a build with its harness configured, without offering Delete agent.
  4. Check an agent using a recognized local harness on another device. It should retain the existing On another device explanation.

Validation

At aba84924710b4a5cad88e4e4a2d69c2bc75d4ae9, with a clean working tree:

  • Mandatory pre-commit checks passed: literal filenames, icons, Biome, and secret scanning.
  • Mandatory pre-push TypeScript and related unit-test gate passed, including the complete AgentsPage test file and app composition tests.
  • Design-system type and static checks passed. The Rust gate passed without selecting compilation for this TypeScript-only change.
  • git diff --check passed. The two-file patch has the same stable patch ID as its source in fix(builderlab): default unconfigured builds to production #1881 (6034b53b4d11a86794e3dcf2b65551d7bd4c8782).

Hosted CI passed all jobs except WebKit 9/12. That job failed before its activation assertions in unchanged solo-rename.spec.mjs:496: clock.pauseAt(new Date()) rejected moving the browser clock into the past. The same test passed at current main e210c8a47 (main CI); neither the test nor the Solo implementation differs in this PR. An isolated headless WebKit clock probe reproduced the exact error when its installed clock was ahead of the runner, while the same-file anchored-clock pattern passed.

The failed job and its dependents were rerun once without code changes: attempt 2. Completion is pending. Broad CI-equivalent suites were not duplicated locally.

Agent source review

Carl reviewed the final diff and traced registered-type lookup, service inventory classification, card summaries, and AgentPeek selection at aba849247. No source-level blockers found: missing harnesses receive recovery guidance, recognized local harnesses retain the existing explanation, and read-only actions are unchanged. The change reuses AgentCard/PeekIdentity and their existing typography, consistent with the design guide’s collection/detail and contextual-recovery rules. This was self-review by the implementer, not independent review.

Screenshots / remaining checks

Real-app capture was attempted again headlessly against the existing running build. That isolated browser session stops at Join a community with no configured community/browser identity. Agents also depends on native Tauri custody (nativeAgents() and the service's unavailable state), which this browser session does not provide. The changed production flow was not exercised; component/unit coverage does not establish native acceptance.

Remaining checks: the CI rerun, actual-app flow and screenshots (including theme/width/enlarged-text and keyboard checks), human testing, and independent review if required. Human testing and review approval remain with the maintainer; no completion attestation has been added.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@feedback.communities.buzz.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
@tellaho
tellaho marked this pull request as ready for review October 29, 2026 04:53
@tellaho
tellaho requested a review from a team as a code owner October 29, 2026 04:53
@tellaho

tellaho commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Independent agent review by Princess Donut, posted from Taylor's account on Taylor's behalf. Reviewed head aba849247. This is a comment, not an approval.

Blockers

None.

Verified

  • place: "elsewhere" covers two cases: a registered local type, and an unregistered type (service.ts:4075 gives elsewhere whenever types.get(row.runtime)?.remote is falsy). The new type && !type.remote split uses the same lookup, so a recognized local harness still gets the old copy. Only an unregistered type gets "Harness unavailable". The !type.remote arm can't be reached under the current mapping, but it's a harmless guard.
  • Both branches have tests: the new test at AgentsPage.test.tsx:2507 covers an unregistered type, and the existing test at :2528 still asserts "On another device" and "another of your devices" for a registered type.
  • The page stays read-only. Edit (editable, AgentsPage.tsx:993) and Delete (the card-only branch, :1099) are still gated on place, and the new test asserts that Delete is absent.
  • The guidance points to a real place. Settings → Plugins exists (used by builderlab/README.md and Activity.tsx:75). Builderlab registers its type only when oauthTarget() resolves (builderlab/index.tsx:33-40,76), so "use a build with this harness configured" is accurate for builds without that target.

Optional suggestions

  1. Two labels for one cause. summaryOf now returns "Harness unavailable" for an unregistered type elsewhere (AgentsPage.tsx:124), but "Type unavailable" for an unregistered type here (:126, and AgentSettingsHost.tsx:196). Consider using one term in a follow-up.
  2. "in this client". No other UI copy says "client", and Agents copy elsewhere says "here". Suggestion: "This agent's harness isn't available here. Check Settings → Plugins, or use a build that has it configured."
  3. Stale comment (pre-existing, outside this PR's two files). The AgentPlace doc (service.ts:174-176) and listedAgents doc (:4055-4056) say elsewhere means "on another of the owner's devices". It also covers unregistered types. Consider fixing that in a follow-up.

Not covered by this review

I didn't exercise the live app and didn't repeat local tests, since CI and the earlier push gates cover them. The human test of the real flow is still outstanding.

@kazemek21 kazemek21 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Kyle reviewed this PR and the Nexus review-tracker notes and approves.

Posted by Codex (gpt-6.1-sol) on behalf of kylez

@tellaho
tellaho merged commit a5a9a00 into main Oct 29, 2026
69 of 71 checks passed
@tellaho
tellaho deleted the tho/agents-harness-unavailable-message branch October 29, 2026 06:49
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.

2 participants