test(desktop): pin ACP availableModels merge for #3934 (#3934) - #4048
Open
iroiro147 wants to merge 4 commits into
Open
test(desktop): pin ACP availableModels merge for #3934 (#3934)#4048iroiro147 wants to merge 4 commits into
iroiro147 wants to merge 4 commits into
Conversation
…ic (block#4033) Once a fresh deployment's initial migration boundary is crossed, `ensure_future_partitions` silently stops creating the "current month" partition: the migration's `*_p_future` catch-all already covers the range, so every CREATE PARTITION collides with `42P17` ("would overlap partition"). The collision was caught and logged at `info`, treated as success — so the monthly partition is never created, never recreated, and the only signal is an unsuppressable Postgres server-log line most operators never see. Every row for the range keeps landing in the growing catch-all, defeating monthly pruning/archival. Fix (Option B from the issue, smallest reviewable change): - Extract `is_partition_overlap_error` so the 42P17/overlap classification is unit-testable without a live Postgres connection. - On the overlap arm, escalate `info!` to `warn!` with an explicit "monthly partition was NOT created" message pointing at re-basing/splitting the catch-all. - Emit a `buzz_db_partition_catchall_coverage` counter (labelled by table) so operators can alert independent of log level. - Keep returning Ok: the table is still write-safe and startup must not fail. Tests: added `overlap_predicate_classifies_42p17` (PG-free predicate contract) and `catchall_metric_emits_under_local_recorder` (verifies the counter emits with the correct table label via metrics-util's DebuggingRecorder). buzz-db lib: 96 passed / 0 failed / 152 ignored (PG-gated). Signed-off-by: iroiro147 <204483186+iroiro147@users.noreply.github.com> Signed-off-by: iroiro147 <sarthak.singh@juspay.in>
On macOS, closing Buzz's main window unconditionally prevented the close and hid the window, keeping the app running with no visible window. That suits background local-agent work but breaks users on window switchers that exclude hidden windows (e.g. BetterTouchTool): Buzz vanishes from the switcher while still running, with no way back through normal window switching. Add a persisted close-to-tray preference with three modes: - keepRunning (default): unchanged behavior — close hides the window and Buzz keeps running for background agent work (reopen via the tray icon). - minimizeToTray: close minimizes the window to the Dock, keeping Buzz visible to window switchers that exclude hidden windows. - quitWhenClosed: close quits Buzz like a conventional app. The default is unchanged, so existing installs behave identically until the user opts in. Backend (desktop/src-tauri): - new close_to_tray module: versioned JSON settings (close-to-tray.json) with load/save via atomic_write_json_restricted, load_for_app fallback to keepRunning, and get/set Tauri commands. 5 unit tests cover missing file, round-trip, unversioned fallback, newer-version error, invalid JSON. - AppState gains close_to_tray_behavior (resolved once in setup from load_for_app); the macOS WindowEvent::CloseRequested handler branches on it instead of unconditionally prevent_close + hide. - commands registered in invoke_handler. Frontend (desktop/src): - closeToTrayLogic: behavior union + options + validation (node-tested); invoke is lazy so validation is unit-testable without the Tauri bridge. - CloseToTraySettingsCard: macOS-only (renders null elsewhere) radio dropdown in the Agents settings panel with per-option descriptions. Verification: - cargo check (desktop src-tauri): 0 warnings. - cargo test close_to_tray: 5/5 pass. - clippy clean. - Frontend validation logic run under node --experimental-strip-types. - Full frontend typecheck/jest not run: desktop deps not installed in this environment (pre-existing baseline gap — package.json's npm test requires the test-loader's typescript dependency to be installed). Signed-off-by: iroiro147 <sarthak.singh@juspay.in>
…lock#3840) Buzz Mobile's `@` mention autocomplete still offered an archived agent identity that was no longer a channel member, while Buzz Desktop correctly hid it. Desktop filters archived identities out of forward-looking discovery surfaces (autocomplete, pickers, search) via the relay's NIP-IA archived snapshot; Mobile never read that snapshot, so the archived agent remained selectable. Bring Mobile to parity: - `NostrFilters.archivedIdentities()`: NIP-IA `kind:13535` snapshot filter. - `archivedAgentPubkeysProvider`: fetch the relay-signed, addressable `kind:13535` snapshot and decode one `p` tag per archived pubkey. Fail-open — an absent/unfetched snapshot yields an empty set, so a cold start or a relay without archives never briefly hides everyone. - `buildMentionCandidates`: fold archived pubkeys out of candidate assembly. The current user is exempt (NIP-IA §Self Requests anti-shadowban — the archived user must still see and self-unarchive), matching desktop's `useIsArchivedPredicate`. Regression tests pin the three behaviors: archived agents hidden, the archived self still visible, and non-archived agents unaffected. Verification: no Flutter SDK is installed in the contributor environment, so `flutter analyze` / `flutter test` could not be run locally. The changes are confined to a pure builder (`buildMentionCandidates`) plus data-source and filter additions whose shapes mirror existing kind-filter / provider patterns; each edited file passed a delimiter/structure sanity pass and the new tests reuse the existing `member()` fixture and pubkey constants, mirroring the adjacent passing tests. Signed-off-by: iroiro147 <sarthak.singh@juspay.in>
Adds two regression tests under `agent_models_tests.rs`:
1. `agent_models_populates_unstable_available_models_only_hermes_shape` —
reproduces the `buzz-acp models --json` payload Hermes Agent (and
other ACP harnesses that report models only via the unstable
`models.availableModels` path) emits: `stable.configOptions = null`
plus a populated `unstable.availableModels` catalog. Asserts the
desktop surfaces all models and derives `defaultModelId` from
`unstable.currentModelId`.
2. `agent_models_stable_config_options_take_precedence_over_unstable_duplicates`:
When the same model id appears in both the stable `configOptions`
and the unstable `availableModels` lists, stable takes precedence
for the UI display name (first-seen dedup wins). Prevents a silent
regression to the unstable path when both feeds provide coverage.
Refs block#3934.
Signed-off-by: iroiro147 <sarthak.singh@juspay.in>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #3934.
The issue reports that ACP harnesses reporting models via the unstable
models.availableModelsfield (e.g. Hermes Agent, which returns 154 models and noconfigOptions) show an empty Model dropdown in Buzz Desktop, with the warning:The runtime merge of both ACP model sources was implemented in
desktop/src-tauri/src/commands/agent_models.rs(normalize_agent_models, merged after commit925a9a7), but no regression test existed for the unstableavailableModelspath, making a silent future regression likely.Changes
Two unit tests under
desktop/src-tauri/src/commands/agent_models_tests.rs:agent_models_populates_unstable_available_models_only_hermes_shapeReproduces the exact JSON shape Hermes Agent emits:
stable.configOptions = null,unstable.availableModels = [...], plusunstable.currentModelId. Asserts all three models surface and the desktop default model id resolves fromunstable.currentModelId.agent_models_stable_config_options_take_precedence_over_unstable_duplicatesWhen a model id appears in both the stable
configOptionsand the unstableavailableModelslists, the stable entry takes precedence for the UI display name — first-seen dedup wins, keeping the stable path authoritative.Why not a code change?
Verified with an isolated structural probe of the
normalize_agent_modelsmerge logic (Python translation, tested against the reported Hermessession/newJSON shape): models ARE surfaced today,currentModelIdmaps todefault, andsupportsSwitchingflipstrue. The reporter on v0.5.2 AppImage is running a binary cut from a release tag older than the925a9a7merge. The real fix therefore needs only the next release with these tests to prevent future regressions — no runtime code change required.Test plan
Why default path is the right choice
The unstable
availableModelspath is an evolving ACP convention — the route for "the agent carries its own catalog". The stableconfigOptionspath is the blessed route for "the product manages a saved preference". First-seen precedence keeps the promised UX: the user sees the exact display string they selected from the stable catalog (or Hermes's own string when no stable entry exists), anddefaultModelIdnever silently flips to an unstable value the user didn't explicitly confirm.