Skip to content

fix: gemma4 loader, fleet count, pap:// routing safety, address bar & chrome polish#282

Merged
toadkicker merged 14 commits intomainfrom
feat/a875-repeat-issue
Apr 12, 2026
Merged

fix: gemma4 loader, fleet count, pap:// routing safety, address bar & chrome polish#282
toadkicker merged 14 commits intomainfrom
feat/a875-repeat-issue

Conversation

@toadkicker
Copy link
Copy Markdown
Contributor

Summary

Seven commits resolving the repeat issues from this session:

  • Gemma 4 model loadingremap_gemma4_metadata() rewrites gemma4.* GGUF keys to gemma3.* before passing to quantized_gemma3::from_gguf(), which only probes the gemma3 prefix family
  • Fleet total countlist_local_agents now includes DB-only catalog agents (tagged live=false) so the fleet badge shows ~350 instead of 4; active_count fixed to count only compiled agents
  • pap:// routing safetyAgentInfo.live field gates catalog map inclusion; DB-only agents can no longer silently resolve pap://agent-name URIs to a handler-less DID (which would fall back to On-Device AI)
  • pap:// autocomplete — typing pap:// in the address bar surfaces live agent names from CatalogState with arrow-key navigation, Enter to confirm, Escape to dismiss
  • DB migration — additive ALTER TABLE agents ADD COLUMN for version and schema_version; fixes 300+ catalog agents failing to seed on existing databases
  • Browser-style chrome — topbar redesigned with 3 zones: 64px brand (aligns with sidebar), full-width pill address bar (InlinePrompt promoted from canvas), single status dot; removes hamburger, DID display, READY badge, and settings gear from the header
  • Logo clipping fix — brand zone is now icon-only (text hidden via display:none) to prevent clipping in the 64px constraint

Test plan

  • Settings → Models → select Gemma 4 E2B → confirm no "gemma3.attention.head_count" error
  • Fleet page → total badge shows 300+ agents
  • Address bar: type pap://wiki → dropdown shows wikipedia-knowledge, wikipedia-summary, etc.
  • Arrow keys navigate suggestions; Enter submits; Escape dismisses
  • pap://duckduckgo-search → submits and resolves (not silently routed to On-Device AI)
  • On a fresh DB (delete %APPDATA%\papillon\papillon.db): catalog agents seed without "no column named version" errors
  • Topbar: butterfly logo centered in 64px, no clipping; address bar fills center; status dot only on right
  • Sidebar settings gear still navigates to /settings; canvas dropdown opens from logo click

🤖 Generated with Claude Code

Todd Baur and others added 13 commits April 7, 2026 12:28
Adds @media print styles so Ctrl+P / Save as PDF renders all 13 slides
as full-bleed landscape pages rather than a single clipped view:

- @page { size: landscape; margin: 0 } for edge-to-edge layout
- print-color-adjust: exact to preserve dark bg and brand colors
- Resets the horizontal scroll shell (overflow, transform) so all
  slides are visible to the print engine
- page-break-after: always on each .s for one slide per page
- Hides nav buttons, dot indicators, and slide counter

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Overrides CSS variables inside @media print so all slides render with
a white background and dark text instead of the dark-mode palette:

- --bg / slide backgrounds: white (#fff)
- --surface: light lavender-grey for cards and rows
- --text: near-black, --muted / --faint darkened for contrast
- --purple / --violet: slightly deeper (#5b4bd4) for legibility on white
- Card elements (sys-node, biz-row, ba-items, flow-box) re-skinned
- Decorative radial glows hidden (they don't translate to paper)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds @media print CSS to docs/pitch-deck.html so Ctrl+P / Save as PDF
renders all 13 slides as full-bleed landscape pages with a clean
light-mode palette instead of the dark screen theme.

- @page { size: landscape; margin: 0 } for edge-to-edge layout
- CSS variable overrides: white backgrounds, dark text, readable purple
- page-break-after: always on each slide — one slide per page
- Cards, surfaces, and highlight boxes re-skinned for print
- Decorative radial glows hidden
- Nav chrome hidden in print

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…compatibility

candle-transformers 0.10.2's quantized_gemma3 loader probes only
["gemma3", "gemma2", "gemma", "gemma-embedding"] as metadata key prefixes.
Gemma 4 GGUFs use "gemma4.*" keys, so the probe falls back to "gemma3"
and fails with "cannot find gemma3.attention.head_count in metadata".

Add remap_gemma4_metadata() to rewrite "gemma4.*" keys to "gemma3.*"
before passing the content to from_gguf(). Gemma 4 shares the same
transformer architecture as Gemma 3, so the loader handles the data
correctly once the prefix is normalised. The remap only runs when
arch == "gemma4" so all other models are unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…active count

list_local_agents was built entirely from registry.all_advertisements(),
which only holds the 4 compiled agents. Catalog agents seeded into the DB
(300+ TOML entries) were loaded for DID enrichment but never emitted —
leaving TOTAL stuck at 4.

Fix: after collecting registry ads, append any DB agent whose DID wasn't
already in the registry. This covers catalog agents that are available on
disk but haven't been loaded into the runtime registry yet (first-launch
timing, production builds without a bundled catalog directory).

Also narrow active_count to source == "compiled" only. The prior filter
included "catalog", which would have inflated ACTIVE to ~309 once catalog
agents load. ACTIVE represents agents with running compiled Rust handlers;
catalog agents belong in TOTAL but not in the online count.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add `live: bool` to `AgentInfo` to distinguish agents that have a live
runtime handler (registry-backed, invocable) from agents that exist only
in the local DB but failed to load into the runtime registry.

Problem: `CatalogState.build_catalog()` was built from all agents returned
by `list_local_agents`, including DB-only catalog entries. A `pap://agent-name`
URI would resolve to a DB-only agent's DID, which has no registered handler,
silently falling back to the On-Device AI (AskAction) — the wrong agent.

Fix:
- `AgentInfo.live` (with `#[serde(default)]`) — true for registry agents,
  false for DB-only agents added for visibility only
- `list_local_agents`: tags live registry ads as `live=true`; DB-only agents
  appended for fleet visibility are tagged `live=false`
- `catalog.rs build_catalog()`: skips `!agent.live`, ensuring only invocable
  agents are reachable via `pap://` name resolution
- `registry.rs ad_to_info()`: remote registry agents are live=true

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When the user types `pap://` in the InlinePrompt, a live dropdown surfaces
matching agent names from the CatalogState (live agents only, thanks to the
live-field gate added in 1a1b83c).

- Reactive `pap_suggestions` memo filters catalog keys by the typed prefix,
  sorted alphabetically, capped at 8 results
- Up/Down arrow key navigation with cursor signal; Enter confirms selection
  or submits if no suggestion is highlighted; Escape clears selection
- `pap://` scheme rendered in purple mono, agent name in text-1 mono — no
  arrow glyph (overrides .palette-suggestion::before)
- `.palette-suggestion--active` CSS class for keyboard-selected row
- Existing quick-start prompts unchanged; shown only when input is empty

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Existing databases were created before the `version TEXT` and
`schema_version INTEGER` columns were added to the agents table.
`CREATE TABLE IF NOT EXISTS` is a no-op on an existing table so the
columns were never added, causing every catalog agent seed to fail with
"table agents has no column named version".

Added two `ALTER TABLE agents ADD COLUMN` statements at the end of
`migrate()` with errors suppressed — SQLite returns "duplicate column
name" when the column already exists, which is the correct idempotent
behavior for forward migrations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Polish the app chrome to match a browser UX idiom:

- Brand: "PAPILLON_SYS" → "Papillon"; butterfly logo + name flush-left
  in a 64px zone that aligns with the sidebar column below it. Clicking
  the brand opens the canvas switcher dropdown (replacing the hamburger).
- Address bar: the InlinePrompt is promoted to a full-width pill input
  in the topbar center zone, always accessible regardless of page.
  pap:// autocomplete and arrow-key navigation are preserved.
- Status: the READY badge, DID display, and settings gear are removed
  from the topbar — settings lives in the sidebar, status is shown as
  a single 8px dot (teal/gold/blue) in the right end zone.
- Canvas page: canvas-prompt-bar removed; blocks/empty-state render
  directly below the topbar with no extra gap layer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The 64px brand button was clipping the "Papillon" text label since
icon + text together exceed the sidebar-width constraint. Hide the
name span (display: none) so the zone shows only the butterfly icon,
matching the sidebar's icon-only style. Tooltip carries the label.
Bumped icon from 22px → 26px for better visual weight at center.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 12, 2026

Benchmark Regression Report

PAP Protocol Benchmark Regression Check
========================================
Baseline: .bench-baseline/baseline.json
Threshold: 30%

  ed25519_keypair_generation                22.1 µs  (baseline: 22.1 µs, +0.0%)  [ok]
  did_key_derivation                         1.6 µs  (baseline: 1.6 µs, +0.1%)  [ok]
  mandate_create_sign                       26.6 µs  (baseline: 26.6 µs, +0.0%)  [ok]
  mandate_chain_verify_depth3              132.9 µs  (baseline: 132.5 µs, +0.3%)  [ok]
  sd_jwt_issue_5claims                      31.2 µs  (baseline: 31.1 µs, +0.3%)  [ok]
  sd_jwt_verify_disclose_3of5               45.8 µs  (baseline: 46.3 µs, -0.9%)  [ok]
  session_open_full_lifecycle              123.4 µs  (baseline: 126.4 µs, -2.3%)  [ok]
  receipt_create_cosign                     53.3 µs  (baseline: 53.3 µs, +0.0%)  [ok]
  federation_announce_local                 60.0 µs  (baseline: 60.7 µs, -1.1%)  [ok]

All benchmarks within 30% of baseline.

Threshold: 10% regression vs baseline from main

…sign

Replace removed selectors (.topbar-menu-btn, .topbar-settings-btn,
.topbar-identity, .topbar-status, .palette-input) with their new
equivalents after the browser-chrome topbar refactor (a3dffe7 + 24d8994):
- .topbar-menu-btn → .topbar-brand (canvas dropdown trigger)
- .topbar-settings-btn → a[href="/settings"] (sidebar link)
- .topbar-identity → .topbar-brand-icon (DID no longer shown in topbar)
- .topbar-status + text → .topbar-dot.ready / .topbar-dot.agents-only
- .palette-input → .topbar-address-input (prompt moved to address bar)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@toadkicker toadkicker merged commit 0a22d09 into main Apr 12, 2026
24 checks passed
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.

1 participant