← Back to PRs

#20081: feat: post-compaction triage UX — fuzzy ok + stage-2 gate + Discord buttons (Issue #90)

by PrivacySmurf open 2026-02-18 13:59 View on GitHub →
channel: discord app: web-ui gateway agents size: XL
## Summary Implements Issue #90 in three phases: ### Phase 1: Fuzzy OK Detection - New `src/auto-reply/reply/compaction-ack.ts` with `isCompactionAck()` helper - Accepts: `ok`, `okay`, `ok go`, `looks good`, `lgtm`, `go ahead`, `continue`, `resume`, `proceed`, `sure`, `yes`, `yeah`, `yep`, `yup`, `got it`, `do it` - All case-insensitive + trimmed - 33 unit tests ### Phase 2: Stage-2 Triage Gate - When user acks AND held messages exist → enter `compactionTriagePending` state, show numbered triage prompt - User replies with `do Q1` / `do all` / `skip Q2` / `skip all` / freeform instruction - `parseTriageResponse()` parses decision using strict Q-number patterns (no false positives on freeform text) - `buildTriagePrompt()` produces numbered queue message for user - `buildAgentFreezeContext()` updated to accept `approvedMessages` + `trageInstruction` (freeform) - New `SessionEntry` fields: `compactionTriagePending`, `compactionApprovedMessages` - 43 unit tests for parsing + formatting ### Phase 3: Discord Inline Buttons (Foundation) - New `src/discord/monitor/compaction-triage.ts` with custom ID builder/parser and event text map - `buildCompactionTriageCustomId(action)`, `parseCompactionTriageCustomId(id)` - `COMPACTION_TRIAGE_EVENT_TEXT` maps `do_all → 'do all'` and `skip_all → 'skip all'` - Button labels: `✅ Do All` / `⏭️ Skip All` - Full Discord button sending (attaching action rows to the triage message) marked as TODO in get-reply-run.ts with wiring instructions - 13 unit tests ## Test Results 132 tests across 6 test files, all passing. ## Files Changed - `src/auto-reply/reply/compaction-ack.ts` (new) - `src/auto-reply/reply/compaction-ack.test.ts` (new) - `src/auto-reply/reply/compaction-held-messages.ts` (+triage parsing helpers) - `src/auto-reply/reply/compaction-held-messages.test.ts` (+triage tests) - `src/auto-reply/reply/get-reply-run.ts` (stage-2 gate wiring) - `src/config/sessions/types.ts` (+compactionTriagePending, +compactionApprovedMessages) - `src/discord/monitor/compaction-triage.ts` (new) - `src/discord/monitor/compaction-triage.test.ts` (new) ## Acceptance Criteria Status - [x] 'ok', 'okay', 'ok go', 'looks good', etc. all trigger compaction ack - [x] Stage-2 triage gate prevents queued items from auto-executing - [x] Discord button foundation in place (full wiring pending outbound path changes) <!-- greptile_comment --> <h3>Greptile Summary</h3> Large multi-feature PR implementing post-compaction triage UX across three phases: fuzzy ack detection, stage-2 triage gate with held message queue, and Discord inline button foundation. Also includes several related improvements: `shellGate` cron payload type, model switch context guard with auto-compaction, pre-prompt hook infrastructure, session write-lock retry logic, and various config additions. - **Compaction triage core** (Phase 1-2): Clean architecture with `isCompactionAck()` fuzzy matching, `parseTriageResponse()` for structured triage decisions, and `buildAgentFreezeContext()` for invisible system context injection. Well-tested (130+ tests). - **Discord buttons** (Phase 3): Foundation only — custom ID builder/parser and event text map. Full wiring is left as TODO with clear instructions. - **Session lock retry**: Adds backoff-and-retry (3 attempts, 5s delay) when session file is locked, preventing message drops during concurrent access. - **Model switch context guard**: Blocks switches to smaller-context models when session exceeds target window, with auto-compaction and `--force` bypass. - **`shellGate` cron type**: Runs a shell command first and only spawns an agent turn if the command produces output. **Bug: the tool documentation tells agents to use `{{stdout}}` as the template placeholder, but the runtime replaces `{{output}}`** — jobs created following the docs will have broken template substitution. - **Pre-prompt hook**: External command injection before each agent turn, with user message passed via env var to avoid shell injection. - **Missing `sessionKey` guard**: One `updateSessionStore` call in the stage-1 non-ack path lacks the `sessionKey` truthiness check present in all other similar calls. <h3>Confidence Score: 3/5</h3> - Mostly safe to merge but has one confirmed bug (shellGate placeholder mismatch) and a minor consistency issue (missing sessionKey guard). - The core compaction triage feature is well-implemented and thoroughly tested. However, the shellGate `{{stdout}}` vs `{{output}}` placeholder mismatch is a functional bug that will cause template substitution to silently fail for any agent-created shellGate cron job. The missing sessionKey guard is a minor issue. The PR is large (44 files, 2700+ lines added) which makes comprehensive review difficult, but the new code is well-structured and follows existing patterns. - Pay close attention to `src/agents/tools/cron-tool.ts` (placeholder mismatch bug) and `src/auto-reply/reply/get-reply-run.ts` (250+ lines of gate logic with missing guard). <sub>Last reviewed commit: 353e37a</sub> <!-- greptile_other_comments_section --> <sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs