Skip to content

Add Webhooks sidebar filter parity - #4957

Closed
MaudeBot wants to merge 1 commit into
nesquena:masterfrom
MaudeCode:webhook-sidebar-filter
Closed

MaudeBot wants to merge 1 commit into
nesquena:masterfrom
MaudeCode:webhook-sidebar-filter

Conversation

@MaudeBot

Copy link
Copy Markdown
Contributor

Summary

  • classify webhook-origin sessions as session_source="webhook" with a Webhook label
  • add a dedicated Webhooks system project/chip and hide webhook sessions from the default sidebar by default
  • add show_webhook_sessions settings/UI/i18n plumbing parallel to show_cron_sessions
  • add a webhook source-filtered rescue pass so older webhook sessions remain available under the Webhooks chip

Closes #4956

Tests

  • /Users/maudebot/.hermes/hermes-agent/venv/bin/python -m pytest tests/test_webhook_project_sessions.py tests/test_issue2841_show_cron_sessions_toggle.py tests/test_gateway_sync.py::test_agent_session_source_normalization_contract -q
  • /Users/maudebot/.hermes/hermes-agent/venv/bin/python -m pytest tests/test_webhook_project_sessions.py tests/test_1079_cron_session_project.py tests/test_issue3019_cron_project_sessions.py tests/test_issue4385_cron_archive_reappears.py tests/test_claude_code_session_import.py::test_get_cli_sessions_cache_invalidates_when_sqlite_wal_changes tests/test_issue3585_cron_session_overflow.py::test_cron_sessions_recovered_by_second_pass tests/test_issue4842_cron_projection_perf.py tests/test_issue4842_cli_sessions_streaming_freeze.py tests/test_issue4766_sidebar_source_pushdown.py tests/test_issue4775_sidebar_hidden_zero_message_pushdown.py -q

@greptile-apps

greptile-apps Bot commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds Webhooks sidebar filter parity. The main changes are:

  • Classifies webhook sessions with a Webhook source label.
  • Adds a dedicated Webhooks project chip and default-hidden sidebar behavior.
  • Adds show_webhook_sessions settings, UI, cache, and i18n wiring.
  • Adds a webhook rescue pass for older state-backed webhook sessions.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
api/routes.py Threads show_webhook_sessions through session payload building and settings-save cache invalidation.
api/route_session_list_cache.py Adds show_webhook_sessions to the session-list cache key.
api/models.py Adds webhook source handling, Webhooks project assignment, default hiding, and rescue loading.
static/panels.js Adds settings load, autosave, and explicit-save wiring for webhook session visibility.

Reviews (6): Last reviewed commit: "feat: add Webhooks sidebar filter parity" | Re-trigger Greptile

Comment thread api/routes.py
@MaudeBot
MaudeBot force-pushed the webhook-sidebar-filter branch from 470a06d to ac12ee5 Compare June 26, 2026 02:00
@nesquena-hermes nesquena-hermes added the size:L Large PR (>10 files or >250 LOC) label Jun 26, 2026
@nesquena-hermes

Copy link
Copy Markdown
Collaborator

🔬 Gate certification — GREEN (logic) ✅ · BLOCKED on rebase ⚠️

Certified head: sha:73d6368762cf · PR: #4957 · MaudeBot — "Add Webhooks sidebar filter parity"
Verdict: The implementation is correct, safe, and a faithful 1:1 parity with the existing cron-session machinery — Opus APPROVE, clean full suite, all PR + cron tests pass, server-side display gating verified. But it does NOT rebase cleanly onto current master (stale i18n translations + a session-list-cache refactor landed since its base), so it needs a rebase before merge. Recommend: warm-up re-rebase → then it's ready.

What I ran (isolated worktree /tmp/wt-gate-4957)

Gate Result
Codex (reproduce) SHIP ONLY WITH FIXES — 6/7 findings are stale-base artifacts; 1 real-but-harmless (below)
Opus (full review) APPROVE — "clean, well-tested 1:1 parity with cron; no regressions"
Full pytest suite (-p no:xdist, clean tree) 11063 passed, 0 failed
PR's own tests + edited cron tests (32) 32 passed
In-process gating verification server-side display gate confirmed (see below)
i18n parity 2 new keys in all 13 locales ✓

⚠️ Merge prerequisite #1 — CONFLICTING on rebase (warm-up's job)

GitHub reports MERGEABLE (state BEHIND) because it merges via merge-commit, but a rebase onto current master conflicts in 2 files:

  • static/i18n.js (2 hunks): master added French translations for the cron/settings keys since this PR's base; the PR branch still has the older English strings → conflict. A merge-as-is would clobber master's French settings_label_cron_sessions etc. with English — a subtle i18n regression.
  • api/routes.py (1 hunk): master refactored the session-list-cache into a __getattr__ dynamic-export module; the PR still has the old inline _session_list_cache_key → conflict.

These are stale-base reconciliation conflicts (the i18n-translation-clobber class), squarely warm-up's rebase domain. The PR should be rebased onto current master before merge so it adds only the 2 new webhook keys (English fallback, per convention) on top of master's translations and reconciles with the cache refactor. I did not resolve them here (rebase/re-warm is the warm-up layer's role, not the gate's).

Codex findings triage

6 of 7 are stale-base artifacts (code from other shipped PRs the stale base appears to "revert"): session-media PDF/HTML auth (#5157), gateway-restart (#5181), update-order, macOS git resolution (#5175), settings-search blob, todo-renderer content??text. None are in this PR's actual webhook delta — they'll vanish on rebase.

1 finding is real but non-blocking (pre-existing pattern):

  • /api/settings direct POST can persist show_webhook_sessions=true while show_cli_sessions=false (the route saves body before dependency normalization; save_settings only bool-coerces). I reproduced it — but it's behaviorally harmless: the session-list builder consumes show_webhook_sessions ONLY inside if show_cli_sessions: (routes.py:1752), so webhook rows never render when CLI is off regardless of the stored bool (defense in depth, verified). Master's cron toggle has the identical property — this PR faithfully mirrors it rather than introducing a new defect. Optional hardening (not a blocker): normalize both show_cron_sessions and show_webhook_sessions to false server-side when show_cli_sessions is false, before save_settings(body) — would fix the cosmetically-inconsistent persisted bool for both toggles.

Findings (the feature is sound)

  • ✅ Parity, not a new stacked filter (Nathan's concern): it's a Settings toggle "Show webhook sessions" mirroring "Show cron sessions" exactly (gated on CLI sessions, defaults off, same flood rationale) — NOT a new sidebar filter chip.
  • ✅ Gating correct at render time: both frontend save paths gate show_cli && show_webhook, AND the server short-circuits (webhook surfacing only inside if show_cli_sessions:).
  • ✅ Detection by source metadata, not session_id (avoids the cron id-pattern misclassification bug class) — test-covered.
  • ✅ Default-hidden: webhook rows returned-but-hidden unless toggle on; no cron/CLI/messaging regression (32 tests pass).
  • ✅ i18n parity (all 13 locales, English-fallback convention per the repo).

Recommendation to the next agent

Logic is GREEN — but do NOT merge as-is; it needs a rebase first. Send it back through warm-up to rebase onto current master (resolve the i18n-translation + session-cache-refactor conflicts so it adds only the 2 webhook keys on top of master), then it re-gates clean and merges. Optional: fold in the server-side toggle-normalization hardening (applies to cron too). It's a Settings-toggle parity feature (not a stacked sidebar filter), Opus-approved, faithful to the #4956 design. I applied gate-pass for the logic but the rebase is a hard merge prerequisite — flagging rather than self-resolving (warm-up's role). Cert valid only at sha:73d6368762cf; the rebase will move the head → re-gate.


Gate-certifier layer (warm-up → gate → release). I do not merge/tag/deploy/close, and I do not rebase CONFLICTING PRs (that's warm-up). Cert valid only at sha:73d6368762cf.

@nesquena-hermes nesquena-hermes added the gate-pass Full gate passed (Codex+Opus+suite+browser); queued Tier 1 for release agent label Jun 29, 2026
@nesquena-hermes

Copy link
Copy Markdown
Collaborator

🔬 Gate re-check — BLOCKED on rebase ⚠️ (prior GREEN invalidated; needs cross-module re-integration)

Re-checked head: sha:e5e97776c81e · PR: #4957 · MaudeBot — "Add Webhooks sidebar filter parity" · prior GREEN cert was at sha:73d6368762cf
Verdict: My earlier GREEN cert is invalidated — the only new commit is a Merge branch 'master', but master has since relocated the entire session-list cache into a new module, which collides structurally with this PR's cache-key change. The feature is still wanted (not in master) and the logic was GREEN before, but it now needs a non-trivial rebase that re-integrates show_webhook_sessions into the relocated cache module — that's the contributor's to do correctly (knows all the cache call-sites), not a mechanical resolution I should hand-apply blind on cache-key logic.

Why this isn't a self-rebase (it's a refactor-collision, not a CHANGELOG conflict)

Rebasing e5e97776 onto current master (31000a9e) conflicts in 2 files:

  1. api/routes.py — structural (the blocker). Master moved the whole inline session-list cache (_session_list_cache_key, _session_list_cache_get/set, source-stamp, etc.) into api/route_session_list_cache.py, leaving a __getattr__ delegation shim in routes.py. This PR's commit still carries 345 lines of the old inline cache with show_webhook_sessions woven into _session_list_cache_key. So the conflict isn't a text overlap — the code the PR edits no longer lives in routes.py.
    • Note: master's route_session_list_cache.py already has source_filter + sidebar_source in _session_list_cache_key (absorbed independently) but NOT show_webhook_sessions — that param is this PR's unique addition and must be threaded into the module's cache-key + every relocated call-site.
  2. static/i18n.js — trivial/additive. Master added the French settings_label_cron_sessions translation; the PR added the English settings_label_webhook_sessions. Standard "keep both" union (I'd resolve this part myself; it's not the blocker).

Confirmed still needed (not superseded)

  • Master does not have the webhook filter: show_webhook_sessions count in route_session_list_cache.py = 0; webhook mentions in master panels.js = 0. The PR's panels.js feature (settingsShowWebhookSessions checkbox + gating on CLI sessions) is genuinely its own contribution.

Re-integration spec (for the contributor / next rebase)

  1. Rebase onto current master; take master's routes.py __getattr__ cache shim (cache lives in api/route_session_list_cache.py now).
  2. In api/route_session_list_cache.py, add show_webhook_sessions: bool = False to _session_list_cache_key's signature and its returned tuple (alongside the existing show_cron_sessions / source_filter / sidebar_source), preserving order.
  3. Thread show_webhook_sessions through every relocated cache call-site that the PR previously passed it to in routes.py (find them in the module now).
  4. Resolve the i18n.js conflict as a union (keep master's fr settings_label_cron_sessions + the PR's settings_label_webhook_sessions), and ensure settings_label_webhook_sessions is present in all 14 locales (English fallback OK for not-yet-translated).
  5. Re-run the suite (esp. test_webhook_project_sessions.py, test_session_sidebar_cache.py, the cron-session toggle tests) + then re-gate.

Recommendation to the next agent / Nathan

BLOCKED on a structural rebase — do NOT merge the stale head. The webhook-sidebar-filter feature was GREEN at 73d6368762cf and is still wanted, but master's session-list-cache module refactor collides with it; it needs the show_webhook_sessions param re-integrated into api/route_session_list_cache.py (the relocated module) + a trivial i18n union. This is a genuine refactor-collision (the edited code moved modules), not a CHANGELOG-class conflict — best done by the contributor (MaudeBot) who knows all the cache call-sites, then re-gated. I did NOT hand-resolve the cache-key logic (risk of a subtle cache-key mismatch). T2 — decision-ready with the re-integration spec above. No gate-pass/gate-fail label applied (it's a rebase-blocked re-check, not a verdict on the code). Prior GREEN logic stands once correctly rebased.


Gate-certifier layer (warm-up → gate → release). I do not merge/tag/deploy/close. Prior GREEN cert 73d6368762cf is invalidated by the new head; needs rebase + re-gate.

@MaudeBot
MaudeBot force-pushed the webhook-sidebar-filter branch from e5e9777 to 39e3691 Compare June 29, 2026 22:40
Co-authored-by: Kilian Tyler <kilian@kil.dev>
@MaudeBot
MaudeBot force-pushed the webhook-sidebar-filter branch from 39e3691 to 0142e21 Compare June 29, 2026 22:41
@nesquena-hermes

Copy link
Copy Markdown
Collaborator

🔬 Gate certification — GREEN ✅ (re-cert: structural rebase resolved, cross-module re-integration verified)

Certified head: sha:0142e21701a0 · PR: #4957 · MaudeBot — "Add Webhooks sidebar filter parity" · concept fit: 4/5
Verdict: The blocked-on-rebase structural collision is resolved. The contributor re-integrated show_webhook_sessions into master's relocated route_session_list_cache.py module (the exact spec from my prior blocked-rebase re-check) AND preserved #5200's archived-paging (the trap #5075 fell into — this one got it right). Fresh-based on current master, Codex SAFE, suite green. Ready to merge.

What I ran (isolated worktree /tmp/wt-gate-4957c @ live head 0142e217)

Gate Result
Codex (reproduce, vs current master) SAFE TO SHIP (no findings — cache-key re-integration correct, #5200 intact, no regression)
Full pytest suite (-p no:xdist) 11161 passed, 0 failed
PR's webhook/cron-session/cache tests 42 passed
node --check static/panels.js OK
Fresh-based merge-base == current master (dd4d4b2e), behind 0 — no rebase needed

Findings (clean — the re-integration I asked for)

  • ✅ Cross-module re-integration done right — show_webhook_sessions is now threaded through the relocated api/route_session_list_cache.py _session_list_cache_key (×2: signature + returned tuple) + api/routes.py (×10 call-sites) + the static/panels.js settingsShowWebhookSessions checkbox (×3). Codex verified the cache-key position/order is correct (capped vs uncapped responses don't share cache entries).
  • ✅ perf(sessions): page archived sidebar rows #5200 archived-paging PRESERVED — archived_limit ×6 in the module (the contributor re-merged onto current master dd4d4b2e which includes perf(sessions): page archived sidebar rows #5200, and did NOT drop it — unlike feat(composer): allow footer control reordering #5075's merge which reverted it). This is the correct handling of a hot-shared-file merge against fast-moving master.
  • ✅ Webhook sessions gated on CLI sessions (server short-circuits otherwise); the 42 webhook/cron-session/cache tests pass; node-check clean; no session-list-cache or cron-toggle regression (Codex confirmed).
  • ✅ Fresh-based on current master (BLOCKED status is just the missing gate-pass label, not a conflict).

Concept: 4/5 — webhook-session sidebar filter parity (matches the existing CLI/cron/messaging session filters); a sensible, low-risk sidebar-filter addition.

Recommendation to the next agent

Ready to merge — cert fresh for sha:0142e21701a0. The previously blocked-on-rebase structural collision (master's cache-module relocation) is cleanly resolved: show_webhook_sessions threaded through the relocated module + all call-sites, #5200 archived-paging preserved, Codex SAFE, suite green, 42 targeted tests, fresh-based on current master. Prior GREEN logic + this clean re-integration = ship-ready. Concept 4/5. Cert valid only at sha:0142e21701a0.


Gate-certifier layer (warm-up → gate → release). I do not merge/tag/deploy/close. Cert valid only at sha:0142e21701a0; a new push invalidates it → re-gate.

nesquena-hermes added a commit that referenced this pull request Jun 30, 2026
@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Shipped in v0.51.767 (Wave 3 batch, via release PR #5280). Thanks @MaudeBot! Codex SAFE (clean re-gate) + full suite green.

Loukky pushed a commit to Loukky/hermes-webui that referenced this pull request Jun 30, 2026
@cutter-sh

cutter-sh Bot commented Jun 30, 2026

Copy link
Copy Markdown

🎬 Cutter preview — PR #4957

Toggle 'Show webhook sessions' setting
Toggle 'Show webhook sessions' setting — Preferences gains a Show webhook sessions toggle to surface webhook runs in the sidebar alongside non-WebUI sessions.

@nesquena-hermes

Copy link
Copy Markdown
Collaborator

This shipped in v0.51.767 (verified: the change is on master + has a CHANGELOG entry). The release landed via a batched release PR, which didn't auto-close this one — closing now. Thanks @MaudeBot! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gate-pass Full gate passed (Codex+Opus+suite+browser); queued Tier 1 for release agent size:L Large PR (>10 files or >250 LOC)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Webhooks sidebar filter/project parity with Cron Jobs

2 participants