Skip to content

[dotnet-port-api] Add compaction-backed history provider - #1092

Open
Michelle Clayton (michelle-clayton-work) wants to merge 2 commits into
mainfrom
copilot/dotnet-port-api-compaction-history-provider-fdbbd9f2ce32e8b7
Open

Michelle Clayton (michelle-clayton-work) wants to merge 2 commits into
mainfrom
copilot/dotnet-port-api-compaction-history-provider-fdbbd9f2ce32e8b7

Conversation

@michelle-clayton-work

Copy link
Copy Markdown
Contributor

Tip

Your pull request is ready to create! 🎉 ✅

Everything is OK—the changes have been pushed to branch copilot/dotnet-port-api-compaction-history-provider-fdbbd9f2ce32e8b7. Please review the changes, including any protected files, before creating the pull request.

Create the pull request

The original pull request description is below.


Summary

Add a compaction-backed history provider in agent/compaction so Go agents can apply reducer-triggered history compaction directly on the history-provider surface instead of only through a separate context provider. The change adds the new provider, covers compacted persistence and summary replay in tests, updates the additional-context sample to use the new API, and refreshes the parity doc to reflect the reduced .NET chat-history gap.

Ported .NET PRs

Breaking Changes

No.

Tests and Examples

  • go test ./agent ./agent/compaction ./examples/02-agents/agents/step17_additional_ai_context
  • Added agent/compaction/historyprovider_test.go
  • Updated examples/02-agents/agents/step17_additional_ai_context/main.go

Notes

  • The live upstream-agent-framework/main fetch was blocked in this environment, so this PR ports the documented chat-history parity gap as a narrow Go realignment instead of tying the change to a freshly inspected upstream PR.
  • Other broader chat-history/storage parity gaps remain out of scope for this PR.

Closes #1053

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 16, 2026 18:45
@github-actions github-actions Bot added area:agent Changes files in the agent area area:examples Changes files in the examples area size:xlarge More than 300 changed lines or 10 files labels Sep 16, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Two critical correctness issues remain in the history provider.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds a compaction-backed history provider with persistence, tests, an updated example, and refreshed .NET parity documentation.

Changes:

  • Adds compaction.NewHistoryProvider.
  • Adds compaction persistence and summary replay tests.
  • Updates the additional-context example.
  • Refreshes the .NET/Go feature comparison.
File summaries
File Summary
examples/02-agents/agents/step17_additional_ai_context/main.go Uses the new bounded history provider.
docs/dotnet-go-sdk-feature-comparison.md Updates chat-history parity status.
agent/compaction/historyprovider.go Implements persisted compaction. Critical issues remain around including current input before compaction and applying filters before generated summaries; a concurrency test is also needed.
agent/compaction/historyprovider_test.go Tests compacted persistence and summary replay.
agent/compaction/doc.go Documents history-provider support.
Review details

Suppressed comments (1)

agent/compaction/historyprovider.go:146

  • This provider rewrites shared session state after appending and compacting each turn, but the new tests only exercise sequential Invoked calls. The existing in-memory provider has a same-session concurrent store/race test (agent/history_test.go:80-118); add the analogous test here with a real truncation strategy to verify that concurrent turns are not lost while compaction runs.
			compacted, err := compactHistory(ctx, cfg.Strategy, messages, cfg.TokenCounter, cfg.Logger)
  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread agent/compaction/historyprovider.go Outdated
Comment thread agent/compaction/historyprovider.go Outdated
@github-actions github-actions Bot added kind:code Changes production behavior or code kind:docs Changes documentation or comments kind:examples Changes examples or example-support metadata kind:tests Changes tests, fixtures, or test infrastructure labels Sep 16, 2026
@github-actions

This comment has been minimized.

@github-actions github-actions Bot added the public-api-change Pull Request changes public APIs label Sep 16, 2026
@michelle-clayton-work

Copy link
Copy Markdown
Contributor Author

Copilot address PR feedback

Co-authored-by: michelle-clayton-work <262183035+michelle-clayton-work@users.noreply.github.com>

Copilot AI commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Copilot address PR feedback

Addressed the review feedback in 941efbc: pre-call compaction now includes filtered persisted history plus the current request exactly once, and filtering occurs before summarization. Added regression coverage for both cases.

@github-actions

Copy link
Copy Markdown
Contributor

Scope: public API, user-visible behavior

Changed Go contract: New exported compaction.NewHistoryProvider(HistoryProviderConfig) returning agent.HistoryProvider, plus the HistoryProviderConfig struct (Strategy, SourceID, StateKey, StateInitializer, ProvideOutputMessageFilter, StoreInputRequestMessageFilter, StoreInputResponseMessageFilter, TokenCounter, Logger). Runtime behavior: the provider applies Strategy.Compact unconditionally inside both Invoking (pre-retrieval, transient) and Invoked (pre-write, persisted) on every turn.

Upstream evidence reviewed:

  • dotnet/src/Microsoft.Agents.AI.Abstractions/InMemoryChatHistoryProvider.cs — reducer runs at exactly one lifecycle point, selected via ReducerTriggerEvent (BeforeMessagesRetrieval default, or AfterMessageAdded), never both.
  • dotnet/src/Microsoft.Agents.AI.Abstractions/InMemoryChatHistoryProviderOptions.cs — documents the single-trigger-event contract and its default.
  • dotnet/src/Microsoft.Agents.AI/Compaction/CompactionProvider.cs and CompactionStrategy.cs — describe "in-run", "pre-write", and "on existing storage" as three distinct usage patterns, each requiring its own explicit wiring (e.g., CompactionProvider for in-run vs. a chat-history-provider reducer for pre-write), not one provider auto-applying compaction at every point.
  • dotnet/samples/02-agents/Agents/Agent_Step13_ChatReduction/Program.cs — sample explicitly notes the reducer runs once per turn at the configured trigger point, and that the most-recent messages are still visible until the next retrieval.

Result: findings reported

Finding: compaction.NewHistoryProvider (agent/compaction/historyprovider.go) always compacts twice per turn — once transiently in Invoking for the outgoing model context, and again in Invoked before persisting to session state — with no way to select a single trigger point. .NET's equivalent (InMemoryChatHistoryProviderOptions.ReducerTriggerEvent) exposes exactly one configurable trigger and defaults to firing only before retrieval, specifically to avoid running the reducer/strategy redundantly. For SummarizationStrategy, which invokes an LLM summarizer, this means the Go provider issues an extra LLM summarization call every turn compared to the .NET pattern. Suggest either running the strategy at only one of the two points (configurable, defaulting to pre-retrieval to match .NET), or documenting/justifying the double-application as an intentional divergence if it's meant to keep the persisted state permanently compacted regardless of retrieval timing.

Everything else (source stamping, request/response filters, session-state keying, example usage) lines up conceptually with InMemoryChatHistoryProvider/InMemoryChatHistoryProviderOptions.

Generated by Go API Consistency Review Agent for #1092 · copilot · auto · 117 AIC · ⌖ 6.8 AIC · ⊞ 9.6K ·

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Generated by Go API Consistency Review Agent for #1092 · copilot · auto · 117 AIC · ⌖ 6.8 AIC · ⊞ 9.6K

}
messages = append(messages, filteredRequest...)
messages = append(messages, filteredResponse...)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

NewHistoryProvider applies Strategy.Compact in both Invoking (line ~137, transient history returned to the model) and Invoked (line ~199, persisted session state), i.e. twice per turn with no way to select a single trigger point.

Upstream InMemoryChatHistoryProviderOptions.ReducerTriggerEvent (dotnet/src/Microsoft.Agents.AI.Abstractions/InMemoryChatHistoryProviderOptions.cs) only ever fires the reducer at one configurable point — BeforeMessagesRetrieval (default) or AfterMessageAdded — precisely to avoid redundant reducer invocations. InMemoryChatHistoryProvider.cs (ProvideChatHistoryAsync/StoreChatHistoryAsync) shows the reducer is gated by if (this.ReducerTriggerEvent is ... ) at each site, never both.

For SummarizationStrategy (LLM-backed), this divergence causes an extra summarizer call every turn versus the .NET pattern. Consider adding a trigger-point option (defaulting to pre-retrieval only, matching .NET) or applying the strategy at just one of the two lifecycle points, unless the double application to keep persisted state always-compacted is an intentional, documented divergence.

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

Labels

area:agent Changes files in the agent area area:examples Changes files in the examples area kind:code Changes production behavior or code kind:docs Changes documentation or comments kind:examples Changes examples or example-support metadata kind:tests Changes tests, fixtures, or test infrastructure public-api-change Pull Request changes public APIs size:xlarge More than 300 changed lines or 10 files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[dotnet-port-api] Add compaction-backed history provider

3 participants