Skip to content

fix(agent): preserve tool-call pairs during compaction#447

Merged
brynary merged 1 commit into
mainfrom
fix/openai-compaction-tool-pairs
May 28, 2026
Merged

fix(agent): preserve tool-call pairs during compaction#447
brynary merged 1 commit into
mainfrom
fix/openai-compaction-tool-pairs

Conversation

@brynary

@brynary brynary commented May 28, 2026

Copy link
Copy Markdown
Member

Summary

Fixes OpenAI Responses requests after context compaction by ensuring preserved tool results are not separated from the assistant tool calls that produced them. The previous fixed-size preserved tail could retain a function_call_output while dropping the matching function_call, which OpenAI rejects as an orphaned tool result.

Changes

  • Extends History::compact so the preserved range moves backward until every kept tool result has its matching assistant tool call.
  • Adds a unit invariant test for compacted histories that serialize tool results.
  • Adds an OpenAI twin integration regression that forces compaction during a tool-use loop.
  • Teaches the OpenAI twin to validate orphaned function_call_output items and script response usage counts for deterministic compaction tests.

Test Plan

  • cargo +nightly-2026-04-14 fmt --check --all
  • git diff --check
  • FABRO_TEST_MODE=twin cargo nextest run -p fabro-agent --test it openai_twin_compaction_preserves_tool_call_pairs --run-ignored all
  • cargo nextest run -p fabro-agent
  • cargo nextest run -p twin-openai
  • cargo nextest run -p fabro-test
  • cargo +nightly-2026-04-14 clippy -p fabro-agent -p fabro-test -p twin-openai --all-targets --no-deps -- -D warnings

Compound Engineering
🤖 Generated with GPT-5 via Codex

Keep matching assistant tool calls when compaction preserves tool results so OpenAI receives valid function_call_output history.

Add an OpenAI twin regression that forces compaction after tool use and validates the session continues without orphaned tool outputs.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@brynary brynary merged commit 8155458 into main May 28, 2026
14 checks passed
@brynary brynary deleted the fix/openai-compaction-tool-pairs branch May 28, 2026 14:37
brynary added a commit that referenced this pull request May 28, 2026
## Summary

Follow-up to #447. This keeps context compaction's
effective preserve boundary consistent between summary generation,
history mutation, and emitted telemetry so tool-call/result pairs that
remain in raw history are not also summarized.

The branch also tightens the OpenAI twin support added for this
regression: scripted usage is modeled as a single `TokenUsage`, SSE
completion payloads reuse the canonical Responses JSON shape, and
request validation now treats custom tool-call outputs as tool outputs
instead of spreading raw item-type string checks.

## Verification

- `cargo +nightly-2026-04-14 fmt --check --all`
- `cargo nextest run -p fabro-agent compaction`
- `cargo nextest run -p twin-openai`
- `FABRO_TEST_MODE=twin cargo nextest run -p fabro-agent --profile e2e
--run-ignored only --test it
openai_twin_compaction_preserves_tool_call_pairs`
- `git diff --check origin/main...HEAD`

---

[![Compound
Engineering](https://img.shields.io/badge/Compound_Engineering-6366f1)](https://github.com/EveryInc/compound-engineering-plugin)
🤖 Generated with GPT-5 via [Codex](https://openai.com/codex)
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