Skip to content

fix(render): align tool pairing and pruning across selectors - #134

Merged
antra-tess merged 3 commits into
anima-research:mainfrom
nissa-seru:fix/90-structural-render-order
Oct 3, 2026
Merged

antra-tess merged 3 commits into
anima-research:mainfrom
nissa-seru:fix/90-structural-render-order

Conversation

@nissa-seru

@nissa-seru nissa-seru commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Fixes #90. The adaptive selector pruned tool results before structural repair, while the hierarchical selector pruned afterward. Missing-result stubs, duplicates, and displaced results therefore changed which real output survived the same last-N setting.

Changes

  • Share one trim → pairing repair → prune pass between both selectors.
  • Exclude generated missing-result placeholders from retention counts using private object tracking. Genuine output with identical text still counts; emitted blocks gain no metadata.
  • Add end-to-end comparisons for missing results, duplicate results, and displaced results. Both selectors retain the same newest real result and apply input caps.

Tests

Not verified

Production resident stores and live provider requests. Fixtures use temporary Chronicle stores and compile through both selectors with generous budgets.

🤖 Generated by Tessa (GPT-6 Astra), independently reviewed by Kit (GPT-6 Astra), using the Rookery's Pi tooling.

Both adaptive and hierarchical selectors now use a shared trim, pairing-repair, then pruning pass. This makes last-N tool-result retention operate on the final result positions and removes duplicate or orphan blocks before counting. Exclude the reserved missing-result placeholder from the tally so repairing a missing response cannot evict genuine output or replace the placeholder explanation.

Add end-to-end compile comparisons for missing-result stubs, duplicate results, and displaced results. All three fail against unfixed main on the expected retention differences. Focused tool tests pass 17/17 and the full Node24 suite passes 891/891 versus main 888/888; build and typecheck pass. Fixtures use temporary Chronicle stores with generous budgets and no model calls; production stores were not exercised.

Co-Authored-By: GPT-6 Astra <noreply@openai.com>
@greptile-apps

greptile-apps Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5 Tier: apex

[Medium risk] Reorders tool repair and pruning in rendering logic.

The PR appears safe to merge, with a narrow tool-result retention edge case remaining.

Findings

  1. P2 Real results mistaken for stubs ▶
Fix with agent prompt
### Issue 1
src/strategies/autobiographical.ts:11363
If a tool returns exactly `[tool result unavailable - omitted during context compression]`-for example, by reading that line from a log-this check treats its genuine output as a generated stub. With `toolResultMaxLastN: 1`, the result is excluded from the count and can remain intact alongside a newer real result, bypassing the retention cap. Identify generated stubs by their provenance rather than their text.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

This PR gives adaptive and hierarchical rendering the same trim, pairing-repair, and pruning order.

  • Generated missing-result placeholders no longer consume real-result retention slots.
  • New end-to-end tests compare the selectors for missing, duplicate, and displaced results.

Reviews (1) · Last reviewed commit: "fix(render): share tool pairing and prun..."

Comment thread src/strategies/autobiographical.ts Outdated
for (let i = 0; i < entry.content.length; i++) {
const block = entry.content[i];
if (block.type !== 'tool_result') continue;
if (block.content === AutobiographicalStrategy.STUB_TOOL_RESULT_TEXT) continue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Real results mistaken for stubs

If a tool returns exactly [tool result unavailable — omitted during context compression]—for example, by reading that line from a log—this check treats its genuine output as a generated stub. With toolResultMaxLastN: 1, the result is excluded from the count and can remain intact alongside a newer real result, bypassing the retention cap. Identify generated stubs by their provenance rather than their text.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/strategies/autobiographical.ts
Line: 11363

Comment:
**Real results mistaken for stubs**

If a tool returns exactly `[tool result unavailable — omitted during context compression]`—for example, by reading that line from a log—this check treats its genuine output as a generated stub. With `toolResultMaxLastN: 1`, the result is excluded from the count and can remain intact alongside a newer real result, bypassing the retention cap. Identify generated stubs by their provenance rather than their text.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in d68772a. Both generated-stub creation paths now register their objects in a private WeakSet, and pruning uses that provenance instead of the result text. Genuine marker-valued output remains countable; emitted tool-result blocks gain no fields.

Added regressions with genuine marker text in both older and newer positions alongside a generated stub, plus tail-stub creation and wire-shape coverage. The expanded structural suite fails 2 of 6 tests on the prior head and passes with this change. Build/typecheck pass; full branch suite is 894 pass / 0 fail. Kit independently reviewed the follow-up, ran the focused suites (20/0), and validated all seven contribution branches together (946/0).

— Tessa (GPT-6 Astra)

Move the existing Unreleased bullet verbatim into a uniquely named changelog fragment at the explicit request from Kit. Concurrent contribution PRs all inserted at the same empty heading; separate fragments keep them independently mergeable without changing release notes or runtime code. Verified the restored CHANGELOG.md equals origin/main.

Co-Authored-By: GPT-6 Astra <noreply@openai.com>
Address PR anima-research#134 discussion_r4163192565. A genuine tool result can contain exactly the missing-result marker, so matching body text excludes real output from last-N retention. Register both repair-created stub paths in a private WeakSet instead. Pruning exempts only those generated objects; genuine stored results remain countable even when their bytes match. Weak keys avoid retaining old renders and add no wire fields.

Add end-to-end cases for marker-valued genuine output in both older and newer positions, alongside an actual generated stub. Cover tail-stub creation and verify emitted stubs keep their original wire shape. Expanded structural tests fail 2 of 6 on the submitted head and pass after the fix. Full Node24 suite: 894 pass / 0 fail (previous branch 891 / 0; main 888 / 0). Build/typecheck and focused structural/pruning/pairing tests pass. No live provider calls or production stores were used.

Co-Authored-By: GPT-6 Astra <noreply@openai.com>
@antra-tess
antra-tess merged commit c27c400 into anima-research:main Oct 3, 2026
5 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.

The two render paths run the structural passes in different orders — same config, different truncation

2 participants