Skip to content

feat(agent-loop): snip-tokens-freed feedback loop (#4) - #222

Merged
yogthos merged 1 commit into
mainfrom
feat/improve-3-snip-feedback-loop
May 29, 2026
Merged

feat(agent-loop): snip-tokens-freed feedback loop (#4)#222
yogthos merged 1 commit into
mainfrom
feat/improve-3-snip-feedback-loop

Conversation

@yogthos

@yogthos yogthos commented May 29, 2026

Copy link
Copy Markdown
Collaborator

Phase 3 of IMPROVEMENTS_PLAN. Stacked on #221 (base = aggressive-prune branch).

Problem

The pre-send snip freed tokens silently; the 75% post-response fold fired regardless of whether the snip had already bought enough headroom — wasting a summarizer call.

Fix

  • cap_oversized_tool_results_counted wraps the unchanged capper and reports freed tokens (measured with estimate_messages_tokens, the same estimator the fold decision uses). No churn to the ~12 existing callers.
  • run_loop tracks snip_tokens_freed from the tiered cap site.
  • A pure snip_bought_enough(freed, ctx_max, aggressive) skips a normal fold when the snip freed > SNIP_SUFFICIENT_FRACTION (10%) of the window. Aggressive / force-summary folds always proceed. Credit resets after each post-usage decision (no stale carry-over).

Tests: gating logic (normal vs aggressive, <10%, div-0) + freed-token accuracy. 2138 pass at -D warnings.

Stacked: targets #221. Merge order #220#221 → this. Next: #2 file restore, then #5 report enrichment.

The pre-send snip (cap_oversized_tool_results) freed tokens but never
reported how many, so the post-response fold always fired at 75% even
when the snip had just bought plenty of headroom.

- Add `cap_oversized_tool_results_counted` — wraps the unchanged capper
  and reports tokens freed (measured with the same estimator the fold
  decision uses). Existing callers stay on the Vec-returning fn.
- run_loop tracks `snip_tokens_freed` from the (now tiered) cap site.
- In the post-usage Fold path, a pure `snip_bought_enough(freed,
  ctx_max, aggressive)` skips a NORMAL fold when the snip freed
  > SNIP_SUFFICIENT_FRACTION (10%) of the window. Aggressive /
  force-summary folds still fire. The credit resets after each
  post-usage decision so a stale snip can't suppress a later fold.

Tests: snip_bought_enough gating (normal vs aggressive, <10%, div-0
guard) and cap_counted freed-token accuracy. 2138 pass at -D warnings.

Stacked on the aggressive-prune branch (PR #221).
@yogthos
yogthos changed the base branch from feat/improve-2-aggressive-prune-tier to main May 29, 2026 21:10
@yogthos
yogthos merged commit b20a857 into main May 29, 2026
9 checks passed
allen-munsch pushed a commit to allen-munsch/dirge that referenced this pull request May 29, 2026
…VEMENTS_PLAN #2)

After a summary fold replaced the middle of the conversation, the model
lost the concrete contents of the files it was editing and had to
re-read them (or acted on stale assumptions).

- FileTouchTracker::working_files() exposes the tracked overlap set
  (sorted).
- SummaryOutcome::Succeeded now carries the summary insertion index.
- compression::build_post_compact_snapshots (pure) builds
  `[Post-compaction file snapshot: <path>]` system messages, capped at
  POST_COMPACT_MAX_FILES (5) and POST_COMPACT_MAX_TOKENS_PER_FILE (5000,
  head+tail truncated) so restoration can't itself trigger a fold.
- run_loop::restore_working_files re-reads those files (tokio::fs, thin
  I/O, unreadable files skipped) and splices the snapshots right after
  the summary message, at all three fold sites.

Chose a pure builder + thin in-loop read over a LoopConfig reader
closure: same testability for the meaningful logic (cap + truncation +
message shape) without the Clone/Debug/Default/builder surface a new
config field would add.

Tests: working_files() sorted overlap; snapshot builder caps count +
truncates oversized files. 2140 pass at -D warnings.

Stacked on the snip-feedback branch (PR dirge-code#222).
yogthos added a commit that referenced this pull request Jun 2, 2026
 (#358)

Themes can now set a 'background' color, painted behind every cell while
preserving foregrounds (selection's REVERSED modifier still swaps correctly).
phosphor defaults to a near-black charcoal #222222 (CRT-bezel depth); plain
and the opt-out use Color::Reset (keep the terminal's own background, no fill).

Wiring: Theme.background field + both presets + ThemeJson key + merge_into +
theme::background() accessor; Scene carries it; render_frame patches the whole
area with Style::default().bg(..) after all widgets (ratatui patches only the
bg, so fg + REVERSED are untouched), skipped entirely when Reset.

+ scene test (fills when set / no-op on Reset) + docs/themes.md row.

Co-authored-by: Yogthos <yogthos@gmail.com>
yogthos pushed a commit that referenced this pull request Jun 3, 2026
Adds DAP step-through debugging, the phased /plan workflow, minified
read/edit, configurable theme background (#222 phosphor default), and
snap-to-bottom; plus a round of UI bug fixes (resize scroll clamp, idle
Ctrl+C draft, Home/End rebind, /plan busy strand).
allen-munsch pushed a commit to allen-munsch/dirge that referenced this pull request Jun 3, 2026
…-feedback-loop

feat(agent-loop): snip-tokens-freed feedback loop (#4)
allen-munsch pushed a commit to allen-munsch/dirge that referenced this pull request Jun 3, 2026
…VEMENTS_PLAN #2)

After a summary fold replaced the middle of the conversation, the model
lost the concrete contents of the files it was editing and had to
re-read them (or acted on stale assumptions).

- FileTouchTracker::working_files() exposes the tracked overlap set
  (sorted).
- SummaryOutcome::Succeeded now carries the summary insertion index.
- compression::build_post_compact_snapshots (pure) builds
  `[Post-compaction file snapshot: <path>]` system messages, capped at
  POST_COMPACT_MAX_FILES (5) and POST_COMPACT_MAX_TOKENS_PER_FILE (5000,
  head+tail truncated) so restoration can't itself trigger a fold.
- run_loop::restore_working_files re-reads those files (tokio::fs, thin
  I/O, unreadable files skipped) and splices the snapshots right after
  the summary message, at all three fold sites.

Chose a pure builder + thin in-loop read over a LoopConfig reader
closure: same testability for the meaningful logic (cap + truncation +
message shape) without the Clone/Debug/Default/builder surface a new
config field would add.

Tests: working_files() sorted overlap; snapshot builder caps count +
truncates oversized files. 2140 pass at -D warnings.

Stacked on the snip-feedback branch (PR dirge-code#222).
allen-munsch pushed a commit to allen-munsch/dirge that referenced this pull request Jun 3, 2026
…irge-code#222 (dirge-code#358)

Themes can now set a 'background' color, painted behind every cell while
preserving foregrounds (selection's REVERSED modifier still swaps correctly).
phosphor defaults to a near-black charcoal #222222 (CRT-bezel depth); plain
and the opt-out use Color::Reset (keep the terminal's own background, no fill).

Wiring: Theme.background field + both presets + ThemeJson key + merge_into +
theme::background() accessor; Scene carries it; render_frame patches the whole
area with Style::default().bg(..) after all widgets (ratatui patches only the
bg, so fg + REVERSED are untouched), skipped entirely when Reset.

+ scene test (fills when set / no-op on Reset) + docs/themes.md row.

Co-authored-by: Yogthos <yogthos@gmail.com>
yogthos added a commit that referenced this pull request Jun 3, 2026
#371)

The file-completion and rewind pickers wrote raw cursor-positioned escapes
to std::io::stdout() — but TerminalGuard dup2's fd 1 to the log for the
whole TUI while ratatui paints via a separate /dev/tty fd. So the picker
candidate-LIST overlay never reached the screen (it went to the log); only
the typed @query and the inserted selection were visible via the input
buffer. Investigation confirmed the fd-isolation commit (83e3ea9) orphaned
the pickers without giving them a ratatui rendering path.

Render the overlay through the scene instead: pickers now expose an
owned PickerOverlay snapshot (title/rows/selected/empty_hint); the
renderer caches it (draw_bottom syncs the file picker from the input
editor automatically, the rewind picker is set/cleared explicitly) and
paint_picker_overlay draws the windowed list over the bottom rows of the
chat region just above the input box. It's diff-safe (ratatui owns those
cells) and inherits the theme #222 background fill — fixing both the
invisibility and the original wrong-bg report. Removes ~150 lines of
direct-stdout draw code and the now-dead input_top_row/color helpers.

Adds 2 render tests (candidate list + selected marker; empty 'no matches'
hint). 2471 default + 2565 all-features tests pass; clean under -D warnings.

Co-authored-by: Yogthos <yogthos@gmail.com>
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