Skip to content

Make Foundry MemoryProvider store request/response message filters configurable - #680

Open
PratikDhanave (PratikDhanave) wants to merge 4 commits into
microsoft:mainfrom
PratikDhanaveFork:foundry-memory-store-filters
Open

Make Foundry MemoryProvider store request/response message filters configurable#680
PratikDhanave (PratikDhanave) wants to merge 4 commits into
microsoft:mainfrom
PratikDhanaveFork:foundry-memory-store-filters

Conversation

@PratikDhanave

Copy link
Copy Markdown
Contributor

What

Adds two fields to MemoryProviderConfig in provider/foundryprovider/memory.go:

  • StoreInputRequestFilter messagefilter.Filter — filters request messages before they are stored as memories (default ExternalOnly).
  • StoreInputResponseFilter messagefilter.Filter — filters response messages before they are stored as memories (default PassThrough).

newMemoryProvider now defaults these to ExternalOnly / PassThrough when nil and passes both into the underlying agent.ContextProviderConfig (StoreInputRequestMessageFilter / StoreInputResponseMessageFilter).

Why

Previously the request store filter was hardcoded to ExternalOnly and the response store filter was left unset, so callers had no way to customize which request or response messages get persisted as memories — even though the base agent/context.go already supports all three store/provide filters.

The chosen defaults preserve current behavior and match the .NET / Python SDKs, where an unset request filter defaults to external-only and an unset response filter defaults to pass-through. This closes a missing-configurability parity gap without changing observable defaults.

Tests

provider/foundryprovider/memory_test.go:

  • TestNewMemoryProviderUsesCustomStoreFilters — supplies custom request and response store filters and asserts both are invoked during Invoked (mirrors the existing TestNewMemoryProviderUsesCustomSearchInputFilter).
  • TestNewMemoryProviderStoreFiltersDefaultToExternalOnlyRequestAndPassThroughResponse — with no filters set, a non-external request message is dropped (default ExternalOnly) while a non-external response message is kept (default PassThrough), verified through the recorded update request.

go build ./..., go vet ./provider/foundryprovider/..., and go test ./provider/foundryprovider/... all pass.

Open design questions

  • Scope: kept to the two store filters plus their defaults; ProvideInputMessageFilter is already exposed via SearchInputFilter, so no rename is proposed here.
  • API shape: field names StoreInputRequestFilter / StoreInputResponseFilter mirror SearchInputFilter in this config rather than the longer ...MessageFilter names used on the base ContextProviderConfig. Happy to align to either convention.
  • Follow-ups: none required; defaults are unchanged so this is backwards compatible.

@github-actions

This comment has been minimized.

@github-actions github-actions Bot added the public-api-change Pull Request changes public APIs label Jul 24, 2026
Add StoreInputRequestFilter and StoreInputResponseFilter to
MemoryProviderConfig and wire them into the underlying
ContextProviderConfig. Previously the request store filter was
hardcoded to ExternalOnly and the response store filter was left
unset, so callers could not customize which request or response
messages are persisted as memories.

Defaults are preserved to match .NET/Python parity: request messages
default to ExternalOnly and response messages default to PassThrough.
@github-actions

This comment has been minimized.

@github-actions github-actions Bot added the parity-approved Go API consistency review found no parity issues label Jul 24, 2026
@PratikDhanave
PratikDhanave (PratikDhanave) marked this pull request as ready for review August 4, 2026 06:06
@PratikDhanave
PratikDhanave (PratikDhanave) requested a review from a team as a code owner August 4, 2026 06:06
Copilot AI lite review requested due to automatic review settings August 4, 2026 06:06

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.

🟢 Ready to approve

The changes are small, preserve existing defaults, correctly wire through existing filtering hooks, and include targeted tests for both customization and default behavior.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

This PR extends the Foundry MemoryProviderConfig to allow callers to configure which request and response messages are persisted as memories, aligning Foundry provider behavior with the already-supported filtering capabilities in agent.ContextProviderConfig.

Changes:

  • Add configurable StoreInputRequestFilter and StoreInputResponseFilter fields to MemoryProviderConfig, with defaults ExternalOnly and PassThrough.
  • Wire the new filters into agent.ContextProviderConfig (StoreInputRequestMessageFilter / StoreInputResponseMessageFilter) in newMemoryProvider.
  • Add unit tests verifying both custom filter invocation and default filter behavior.
File summaries
File Description
provider/foundryprovider/memory.go Adds store filter config fields, sets defaults, and passes them into the underlying context provider config.
provider/foundryprovider/memory_test.go Adds tests ensuring custom store filters are called and default request/response store filtering matches expected behavior.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

@github-actions

This comment has been minimized.

@qmuntal Quim Muntal (qmuntal) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks!

Comment thread provider/foundryprovider/memory.go Outdated
Comment on lines +111 to +116
if config.StoreInputRequestFilter == nil {
config.StoreInputRequestFilter = messagefilter.ExternalOnly
}
if config.StoreInputResponseFilter == nil {
config.StoreInputResponseFilter = messagefilter.PassThrough
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These are already the ContextProviderConfig defaaults, no? No need to set them when nil.

@github-actions github-actions Bot added area:provider Changes files in the provider area area:provider/foundry Changes files in the provider / foundry area size:medium At most 100 changed lines across at most 5 files pending-auto-risk Automatic risk classification is in progress labels Aug 20, 2026
@github-actions

This comment has been minimized.

@github-actions github-actions Bot added failed-auto-risk Automatic risk classification was inconclusive or failed and removed pending-auto-risk Automatic risk classification is in progress labels Aug 20, 2026
…Config

Per review: ContextProviderConfig already defaults a nil StoreInput
request filter to messagefilter.ExternalOnly and a nil response filter to
messagefilter.PassThrough in Invoked, so defaulting them again in
newMemoryProvider was redundant. Leave them nil when unset and let the
context provider apply the defaults. Behavior is unchanged (the
default-behavior test still passes).

Signed-off-by: PratikDhanave <i.pratikdhanave@gmail.com>
@PratikDhanave

Copy link
Copy Markdown
Contributor Author

Good catch, thanks Quim Muntal (@qmuntal) — you're right. ContextProviderConfig.Invoked already defaults a nil store request filter to messagefilter.ExternalOnly and a nil response filter to messagefilter.PassThrough, so setting them in newMemoryProvider was redundant. Dropped both nil-defaults and left the fields nil when unset; the default-behavior test still passes since the defaults are applied downstream. PTAL.

@github-actions github-actions Bot added pending-auto-risk Automatic risk classification is in progress and removed failed-auto-risk Automatic risk classification was inconclusive or failed parity-approved Go API consistency review found no parity issues labels Aug 21, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Go API Consistency Review — PR #680

Scope: In scope — this PR adds two new exported fields to MemoryProviderConfig in provider/foundryprovider/memory.go.

What changed

Go (this PR) .NET upstream Python upstream
StoreInputRequestFilter messagefilter.Filter StorageInputRequestMessageFilter Func<...>? Not present (Python memory provider does not yet expose store filters)
StoreInputResponseFilter messagefilter.Filter StorageInputResponseMessageFilter Func<...>? Not present

Semantic / behavior parity ✅

The defaults and semantics match the .NET implementation exactly:

  • Request filter: defaults to ExternalOnly when nil — matches StorageInputRequestMessageFilter null default in FoundryMemoryProviderOptions.
  • Response filter: defaults to pass-through (no filtering) when nil — matches StorageInputResponseMessageFilter null default in .NET.

Naming parity ⚠️

The field names diverge from .NET:

  • Go uses Store prefix; .NET uses Storage prefix.
  • Go omits the Message suffix; .NET includes it.

This is a public API surface item (it was also flagged by the PR author as an open question). An inline comment has been left on the relevant lines. The parity-approved label has been removed until this naming question is resolved.

Recommendation

Pick one of:

  1. Keep current Go names — shorter, idiomatic; explicitly document the intentional divergence from .NET naming in a comment or ADR.
  2. Align to .NET names — rename to StorageInputRequestMessageFilter / StorageInputResponseMessageFilter before merging, so cross-SDK documentation and generated references stay consistent.

Either choice is acceptable; the decision just needs to be deliberate and recorded.

Generated by Go API Consistency Review Agent · sonnet46 · 32.5 AIC · ⌖ 11.2 AIC · ⊞ 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 · sonnet46 · 32.5 AIC · ⌖ 11.2 AIC · ⊞ 6K

// memories. The default is [messagefilter.ExternalOnly].
StoreInputRequestFilter messagefilter.Filter

// StoreInputResponseFilter filters response messages before they are stored as

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.

Cross-SDK naming parity note: The upstream .NET FoundryMemoryProviderOptions uses StorageInputRequestMessageFilter and StorageInputResponseMessageFilter (with Storage prefix and Message suffix), while these Go fields are named StoreInputRequestFilter / StoreInputResponseFilter (with Store prefix, no Message suffix).

The PR description calls this out as an open design question. It is worth resolving intentionally:

  • If the shorter Go names are preferred for idiom reasons, record that as a deliberate decision (e.g., in a changelog or inline comment) so future maintainers understand the divergence.
  • If alignment with .NET is preferred, renaming to StorageInputRequestMessageFilter / StorageInputResponseMessageFilter would make cross-SDK documentation and porting easier.

Upstream reference: dotnet/src/Microsoft.Agents.AI.Foundry/Memory/FoundryMemoryProviderOptions.cs

@github-actions github-actions Bot added failed-auto-risk Automatic risk classification was inconclusive or failed and removed pending-auto-risk Automatic risk classification is in progress labels Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:provider/foundry Changes files in the provider / foundry area area:provider Changes files in the provider area failed-auto-risk Automatic risk classification was inconclusive or failed public-api-change Pull Request changes public APIs size:medium At most 100 changed lines across at most 5 files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants