Repository navigation
[1/2] feat(agents): add a recommended agent setup (core) - #3344
Conversation
kazemek21
left a comment
There was a problem hiding this comment.
Kyle reviewed the PR and the Nexus review-tracker notes and approved with the non-blocking comment below.
Posted by Codex (gpt-6.1-sol) on behalf of kylez
ed5523a to
466d7a7
Compare
There was a problem hiding this comment.
🤖 Review from atish's agent, against atish's guidance in the Buzz #buzz-onedotzero thread. I've numbered his points below, and the inline comments refer to them.
- Extendable presets. Ship "Automatic" now, but the data should already allow more named presets, e.g.
[Automatic, Automatic (Remote), Manual]. - Recommended markers under Manual. Show which Remote and Local harness the company prefers, e.g. Remote → Builderlab (Recommended); Local → Goose (Recommended), Claude, Codex.
- Manual + "Default" model follows the company default. If someone picks a harness by hand but leaves the model on Default, we record that, so the agent moves when the default changes.
- Seamless updates for anyone on Automatic or Default.
- Unset means unchanged: with no recommendation configured, the app behaves as it does today.
- Easy-to-update config: an external YAML/JSON file, a LaunchDarkly flag or env vars, rather than only a build-time value.
Already good: unset means unchanged ✅. Saving only a mark and resolving at run time is the right base for point 4 ✅. Checks are time-limited and fall back to the harness default ✅.
Gaps in this PR (core):
- The mark is one literal (
preset: "recommended"), synced asrecommended?: true. It can't name a second preset (point 1). - Candidates are limited to local harnesses (
HARNESSES,!item.remote), so "Automatic (Remote)" can't be expressed (point 1). - The config has no field for a recommended harness per group, so the UI has nothing to mark (point 2).
- The candidate list is compiled in at build time.
setRuntimeCandidateshas no caller, so every change needs a release.
Details are inline. None of this blocks shipping plain "Automatic" first. The ask is to get the schema and the mark into an extendable shape now, while nobody has saved data in this format yet.
|
🤖 Thanks for the review. We're keeping this stack tightly scoped to unblock shipping, while keeping these follow-ups possible:
On point 1, the saved and synced mark is already a string id ( |
8195bf7 to
92f1fdc
Compare
atishpatel
left a comment
There was a problem hiding this comment.
🤖 Re-reviewed at 92f1fdc: approving. No critical issues. With BUZZ_RECOMMENDED_AGENT unset, every path falls back to today's behaviour. The mark is saved as a string id beside settings, so older versions keep it and later presets need no migration. The ed5523a fix for the Codex negative cache looks right. The follow-ups agreed in the inline replies (named presets, Recommended labels, Manual "Default", a URL-backed config, writing down the harness-pinning decision) are fine as separate PRs.
joahg
left a comment
There was a problem hiding this comment.
🤖 Not approving: this account does not approve UI-affecting changes, and this PR edits the bundled agent plugins under src/bundled/ (goose, Codex, Claude Code), including what an agent shows as its model. It needs a design or core-team reviewer. Two maintainers have already approved, so this is mostly a note on what I checked.
What I checked, against the "does this silently widen an agent" question:
- Permissions/sandbox/tools: not touched. A candidate carries only
harness,provider(goose),model,effortandlabel, andparseRecommendedrejects any other field. The diff changes no permission, sandbox, approval or tool setting in any harness, so a recommended agent runs with the same defaults as a manual one. - Source: compiled in at build time from
BUZZ_RECOMMENDED_AGENT, validated invite.config.ts(a bad value fails the build). Unset (OSS builds) meansrecommendedCandidates()is empty and every new path falls back to current behavior. Nothing in this PR callssetRuntimeCandidates, so there is no remote source yet. Even then a candidate can only name a model that the harness itself lists (offers/recommendscheck the live catalog and the thinking level), and the harness set is a closed list of three. - Existing agents: unchanged. Only a config with
preset: "recommended"and no model/provider/effort follows the recommendation, and only the new UI in [2/2] writes that mark. A synced revision without the mark takes the agent off it (resolveStart); one that names a model keeps it off. - Fallback: Create picks the first candidate whose harness is installed, ready and lists the model, else the next. At run time an agent keeps its own harness and, if none of that harness's candidates is offered, runs on the harness default instead of failing. Retries after 60s.
One note, inline: setRuntimeCandidates is the future trust boundary. Not blocking.
Not reviewed: the test files in detail, and goose sync() behavior when a marked agent's model changes mid-session once the recommendation is found.
92f1fdc to
0d550aa
Compare
joahg
left a comment
There was a problem hiding this comment.
🤖 Not approving: this account does not approve UI-affecting changes, and this PR edits the bundled agent plugins under src/bundled/ (goose, Codex, Claude Code), including what an agent shows as its model. It still needs a design or core-team reviewer. Re-review of 0d550aa against my note on 92f1fdc; I read the delta and the head sources but did not run the app or tests.
Fixed
setRuntimeCandidatesnow runs a non-empty list throughparseRecommendeditself, so a runtime list gets the same closed harness set, field and unknown-field checks as the build's. An invalid list is ignored, the last good list is kept, and it returnsfalse.undefinedgoes back to the build's list and[]still means "recommend nothing". The new test covers an out-of-set harness and an extra field, and the one service test that used a made-upechoharness through this path now uses a real id.
Still open
- Nothing from my earlier note. No new findings in the delta (3 files:
recommended.ts,recommended.test.ts,service.test.ts). - CI:
Browser journeys (webkit, 4/18)and the aggregateCI requiredare failing on this head, and a few jobs are still pending. I could not read the failure log while the run is in progress; the same webkit shard also fails on #3345, so it may not be this change. Worth a rerun or a look before merge. - None of the edited files carries a FOUNDATION marker.
Packagers can set BUZZ_RECOMMENDED_AGENT, a JSON array of candidates (harness, model, thinking level, label, and for goose a provider), best first. Vite validates it and compiles it in; unset, as in every OSS build, nothing changes. - recommended.ts reads the list, marks an agent's config Recommended (preset: "recommended"), and finds what one harness's marked agents run on: the first candidate that harness offers here, once per launch. A remote execution target runs on its own default. Its header lists the interface the UI uses. - useRecommendedPick(types) picks a setup for a new agent with a bounded check per harness (AgentType.recommends). - goose, Codex and Claude Code follow the mark at run time, in summaries and in shared exports. onAutomatic(config, harness) says an agent is on Automatic; a model or effort pick that reaches a run for one, such as a Solo chat's saved before it switched, is ignored, so it runs on the recommendation. - The mark syncs as a top-level preset beside settings in kind 45010; a synced model choice clears it. - setRuntimeCandidates(list) lets a launch replace the compiled list. - docs/configuration.md documents the setting. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Tim Mellor <[email protected]>
0d550aa to
ba229c2
Compare
|
🤖 Small addition in ba229c2, so we can measure adoption: agent settings revisions (kind 45010) now carry a
|
atishpatel
left a comment
There was a problem hiding this comment.
🤖 Re-reviewed the ba229c2ee delta. The preset tag is derived from each agent-settings snapshot, stale carried tags are replaced, and other artifact types do not gain one. Normal saves and History restores both go through artifactTemplate. Six affected config suites passed together locally at this head: 134 tests. Hosted CI is still running.
joahg
left a comment
There was a problem hiding this comment.
🤖 Re-checked at ba229c2. The preset tag looks right. artifactTemplate derives it from the content, applies it only to buzz.agent.settings, and always drops a carried tag, so a normal save and a History restore can't disagree with the content. The tests cover on, off with a stale carried tag, and other artifact types. One P3: settingsPreset copies any non-empty string from content.preset into a plain-text tag. Today that can only be recommended. Consider an allowlist of known preset values, so a future or malformed preset can't put arbitrary text into tags that are readable without the content. The rest of the PR is unchanged since my last review, and the earlier points still hold. This needs a design or core-team reviewer for the UI.
|
🤖 Thanks. On the P3 allowlist: agreed it's a good guard. Today the app only ever writes |
…y-unreads * origin/main: (24 commits) [1/2] feat(agents): add a recommended agent setup (core) (#3344) test(browser): survive the live-stream restart a page-clock jump causes (#3442) chore(renovate): hold rusqlite below 0.41 for mesh-llm (#3438) test(browser): serve the diffs and CLI reload fixtures outside the navigation budget (#3445) test(browser): play the draft clip at rate 0 instead of looping it before the Play click (#3446) fix(status): reopen a status whose preset deadlines coincide as Today (#3449) fix(messages): tolerate a cancelled reaction-name chunk load (#3450) fix(pairing): tolerate /proc/net/tcp rows printed twice or missed (#3451) test(browser): wait on the signal each test asserts in local-agent-activity and message-navigation (#3444) Expose native channel headings to Solo sources (#3523) test(browser-host): run the 100,000-channel broker scale check alone in the measurements lane (#3447) fix(solo): keep every contributed destination action (#3516) fix(identity): report an issuer that keeps rate-limiting an agent as a limit (#2365) fix(identity): let a stuck at-launch sign-in copy its link (#2453) fix(profiles): open avatar previews on hover in compact density (#3510) feat(solo): smooth chat recency reordering (#3502) Reject self-mentions that cannot wake another session (#3513) feat(status): offer don't clear for every status (#3515) Let plugin panels name their tab with panels.useTabTitle (#3251) fix(agents): report a conversation wake that fails before its turn starts (#2192) ... # Conflicts: # tests/browser/message-management.spec.mjs
… Identity (#3345) ## Stack Depends on the recommended-agent core in [#3344](#3344). This PR adds the setup controls and agent-card presentation. ## What changes Builds with a recommendation offer **Automatic** and **Custom** in Create agent and the Identity settings for local agents. Builds without a recommendation keep the existing controls. - **Automatic** selects the recommended harness, model and thinking level. The closed settings row shows **Set to [model] (recommended)**; the model truncates on one line while the parenthetical remains visible. - The Automatic option puts the recommender before the optional description, with the active model details beneath it. Attribution and description come from configuration; the shared default makes no promise about cost or update frequency. - The settings icon gently cycles between the AI icon and active harness logo. Custom and reduced-motion settings use a static harness logo. - When no recommended setup is usable, **Custom remains available**, including hosted-agent creation. Automatic still requires a usable recommendation. - **Custom** reveals the existing Harness, Model and Thinking controls in place. Its closed row omits the redundant model byline. Choosing model, provider or thinking settings in Identity turns Automatic off. - On the **Agents page**, Automatic agents show their model’s display name followed by **(Automatic)** beside the cycling icon. This is a read-only detail aligned with the other cards’ model rows and uses the default text color. - In chat, Automatic agents keep session controls while model and thinking controls are hidden. Custom agents keep their existing controls. The recommendation setting accepts the existing candidates array or an object containing `candidates`, optional `recommendedBy`, and optional `description`. Attribution stays with the current recommendation rather than being copied into saved agents. Hosted agent types retain their own settings. ## Validation Current head: `ee16e32f3885cdf374fb3508d7c58d9bc4462923`, rebased onto the updated core. [Current-head review](#3345 (review)) confirms the four UI commits are patch-identical to the previously approved stack and reports **1,068 passed, one skipped** across eleven affected component/config/service suites. [Hosted CI passed](https://github.com/block/buzz-app/actions/runs/43534228146) on this exact head, including `CI required`. Local behavior evidence at `4d5014295583e185716ac3e49249e7b1e43f0645`: - Related component/service checks: **1,033 passed, one existing skip** across nine files, combining initial passes with final reruns of affected files; this is not a single combined run. Includes Custom → hosted harness → introduction → creation when no recommendation is usable. - Both TypeScript projects and mandatory pre-push related-unit/design checks passed. - Four Chromium/WebKit fixture checks passed, exercising narrow/wide layout in both themes: model truncation, visible recommendation suffix, and separation of description/model details. These establish browser layout, not native acceptance. - One browser geometry case was added because DOM-emulated tests cannot prove wrapping/truncation. No browser cases were removed. Existing mode, settings-retention and fallback assertions remain; stale label assertions were updated for Custom and the new summary. - Test-volume audit: changed files contain 841 → 848 named test declarations (parameterized runtime cases counted separately). Tests account for +1,558/−30 lines versus +1,221/−216 non-test lines in this PR, so test changes exceed half the diff. The audit retained distinct parser, metadata, host-wiring and recovery coverage. At `fd3ee535098e7c411852ba847cce01911b29ba23`, the running macOS desktop build was exercised through the Agents page and Automatic → Custom mode switching in an unsaved Create draft. The draft was closed without creating or changing an agent. This verifies the captured native rendering and mode transition; broader native states are not covered by these captures. The full Biome check and mandatory push hooks also passed on that pre-rebase head. ## Screenshots Actual macOS desktop captures at `fd3ee535098e7c411852ba847cce01911b29ba23`; see the [native check notes](#3345 (comment)). | Agents page: aligned model details | | --- | |  | | Automatic setup | Custom setup | | --- | --- | |  |  | --------- Signed-off-by: Tim Mellor <[email protected]> Signed-off-by: Taylor Ho <[email protected]> Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: Taylor Ho <[email protected]> Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@feedback.communities.buzz.xyz>
* origin/main: (27 commits) [2/2] feat(agents): offer Automatic (Recommended) in Create agent and Identity (#3345) fix(solo): preserve and resume unsent chat drafts (#3525) fix(builderlab): give refused app sign-ins and Identity links a route to Organization sign-in (#3078) fix(agents): say why Import an agent can't import here, and link Manage plugins (#3073) [1/2] feat(agents): add a recommended agent setup (core) (#3344) test(browser): survive the live-stream restart a page-clock jump causes (#3442) chore(renovate): hold rusqlite below 0.41 for mesh-llm (#3438) test(browser): serve the diffs and CLI reload fixtures outside the navigation budget (#3445) test(browser): play the draft clip at rate 0 instead of looping it before the Play click (#3446) fix(status): reopen a status whose preset deadlines coincide as Today (#3449) fix(messages): tolerate a cancelled reaction-name chunk load (#3450) fix(pairing): tolerate /proc/net/tcp rows printed twice or missed (#3451) test(browser): wait on the signal each test asserts in local-agent-activity and message-navigation (#3444) Expose native channel headings to Solo sources (#3523) test(browser-host): run the 100,000-channel broker scale check alone in the measurements lane (#3447) fix(solo): keep every contributed destination action (#3516) fix(identity): report an issuer that keeps rate-limiting an agent as a limit (#2365) fix(identity): let a stuck at-launch sign-in copy its link (#2453) fix(profiles): open avatar previews on hover in compact density (#3510) feat(solo): smooth chat recency reordering (#3502) ... # Conflicts: # src-tauri/src/federated_identity/agent/tests.rs # src-tauri/src/federated_identity/mod.rs # src-tauri/src/federated_identity/protocol.rs
* origin/main: (133 commits) Expose ordinary chats without workspace headings (block#3530) [2/2] feat(agents): offer Automatic (Recommended) in Create agent and Identity (block#3345) fix(solo): preserve and resume unsent chat drafts (block#3525) fix(builderlab): give refused app sign-ins and Identity links a route to Organization sign-in (block#3078) fix(agents): say why Import an agent can't import here, and link Manage plugins (block#3073) [1/2] feat(agents): add a recommended agent setup (core) (block#3344) test(browser): survive the live-stream restart a page-clock jump causes (block#3442) chore(renovate): hold rusqlite below 0.41 for mesh-llm (block#3438) test(browser): serve the diffs and CLI reload fixtures outside the navigation budget (block#3445) test(browser): play the draft clip at rate 0 instead of looping it before the Play click (block#3446) fix(status): reopen a status whose preset deadlines coincide as Today (block#3449) fix(messages): tolerate a cancelled reaction-name chunk load (block#3450) fix(pairing): tolerate /proc/net/tcp rows printed twice or missed (block#3451) test(browser): wait on the signal each test asserts in local-agent-activity and message-navigation (block#3444) Expose native channel headings to Solo sources (block#3523) test(browser-host): run the 100,000-channel broker scale check alone in the measurements lane (block#3447) fix(solo): keep every contributed destination action (block#3516) fix(identity): report an issuer that keeps rate-limiting an agent as a limit (block#2365) fix(identity): let a stuck at-launch sign-in copy its link (block#2453) fix(profiles): open avatar previews on hover in compact density (block#3510) ... Signed-off-by: Joah Gerstenberg <[email protected]> # Conflicts: # src/bundled/codex/prompt.test.ts # src/bundled/goose/runtime.ts
Stack
What this adds
A way for a build to ship a recommended agent setup: which harness, model and thinking level a new agent should use. This PR is the non-UI part. It adds no screens. [2/2] adds the screens that use it.
If the setting is unset, as in every open-source build, nothing changes.
How it works
BUZZ_RECOMMENDED_AGENTat build time. It is a JSON list of candidates, best first. Each one names a harness (goose,codexorclaude-code), a model, a thinking level and a display label. goose candidates also name a provider. Vite checks the list and compiles it in. A bad value fails the build and names the field at fault without printing the value. A launch can also swap in its own list (setRuntimeCandidates).useRecommendedPickpicks a setup for a new agent. It walks the list and asks each harness whether it is installed, signed in or set up, and whether it offers that model now. Each check has a time limit. A check that fails or runs out of time skips that candidate. It reportschecking,noneorfound, plus which better candidates were skipped.preset: "recommended") and no model of its own. At run time, goose, Codex and Claude Code each use the first candidate for their own harness that they still offer. They check once per launch and look again a minute or more later, so a harness set up since then gets picked up. If none fits, the agent runs on the harness's own default instead of failing. Its harness never changes for it. A model or thinking pick that reaches a run for one of these agents is ignored, such as one saved in a Solo chat before the switch.docs/configuration.mddocuments the setting with placeholder values.Testing
CI runs the suite.
tsc --noEmitis clean locally.🤖 Generated with Claude Code