Enable fact and instruction memories from Chat admin settings without agents or actions - #1356
Merged
Paul Lizer (paullizer) merged 3 commits intoAug 25, 2026
Conversation
Fact memory was configured only from Agents & Actions, which hid a plain-chat capability behind an agents workflow, and memory writes genuinely required agents because FactMemoryPlugin was only attached to a kernel with automatic function calling on the Semantic Kernel agent path. Move the control to Chat > Chat Experience as the single source of truth, reusing enable_fact_memory_plugin so no migration is needed. The Actions pane now carries a read-only dependency note, mirroring how Tabular Processing points at Enhanced Citations. The Actions toggle previously saved through POST /api/admin/plugins/settings where the key was a REQUIRED field, so removing the input without relaxing that contract would have made the browser post enable_fact_memory_plugin: false. Toggling any unrelated core action would then have silently disabled fact memory. The key moves to deprecated_optional_keys: accepted for older clients, never written from that endpoint. Add agent-free memory writes via functions_fact_memory_autosave.py, a small kernel carrying only the fact-memory plugin, modeled on the existing tabular mini-SK runner. It runs after the assistant response is finalized in both the standard and streaming paths, so it cannot alter or delay the answer, and is gated by user_requested_memory_update() so ordinary turns pay no extra model call. The pass must run inside the originating request because the plugin resolves its authorization boundary from g.authorized_chat_context, which is what keeps a tool call inside the caller's own user or group scope. All failures are contained and logged. Also repairs a stale feature-doc path in test_fact_memory_profile_and_mini_sk that broke when the doc moved into docs/explanation/features/v0.241.001/. Version locked at 0.261.001. Refs #1352 Partially advances #1153 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…-facts-memories-toggle # Conflicts: # docs/_data/app_surface.yml
The in-app Latest Features catalog still described fact memory as a profile-only experience. Update the card so it reflects that the assistant now saves, changes, and removes memories during normal chat when a user asks, and that profile remains the place to review and edit everything saved. Refs #1352 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1352
Partially advances #1153
Version locked at 0.261.001.
Problem
Fact memory was presented purely as an agent action, which caused two distinct problems.
Discoverability. The only control was
enable_fact_memory_pluginin Agents & Actions → Actions, labeled "Enable Fact Memory Action". An admin running plain chat had no reason to open that tab, so they never found the switch — even though memory recall already worked without agents.A real functional gap. Recall was agent-free, but creating, updating, and deleting memories was not.
FactMemoryPluginwas only attached to a kernel with automatic function calling on the Semantic Kernel agent path, so "remember that I prefer bullet points" or "stop calling me Paul" silently did nothing unless agents were enabled.Approach
Mirrors the existing Tabular Processing precedent: the capability is owned by the tab it actually belongs to, and the Actions pane keeps a read-only dependency note.
Admin control moved to Chat
enable_fact_memory_pluginremains the single settings key, so existing deployments keep their value and no migration is required. What changed is ownership:fact-memory-section), saved by the main admin settings form.fact-memory-dependency-notepointing at Chat, exactly liketabular-processing-dependency-notepoints at Enhanced Citations.is_fact_memory_enabled()tofunctions_settings.pyand registered the section inadmin_settings_nav.py.The Actions toggle saved through
POST /api/admin/plugins/settings, whereenable_fact_memory_pluginwas a required field. Removing the input without relaxing that contract would have madeadmin_settings.jsresolve the element tonulland postenable_fact_memory_plugin: false— meaning toggling any unrelated core action would have silently disabled fact memory.The key moves to
deprecated_optional_keys: accepted so older clients don't 400, never written from that endpoint. The JS no longer sends it, and instead refreshes the Actions note from the GET response.Agent-free memory writes
New
application/single_app/functions_fact_memory_autosave.py, modeled on the existing tabular mini-SK runner:user_requested_memory_update()— pure intent pre-filter in the style of the existinguser_requested_chart_visualization(). Matches explicit save/change/forget language and screens out recall questions ("do you remember…") so the broadrememberpattern doesn't fire a write pass on every such turn.should_run_fact_memory_autosave()— combines the filter with the admin toggle, and skips when an agent ran since that path already had the tool inline.run_fact_memory_autosave()— aKernelcarrying onlyFactMemoryPlugin, service idfact-memory-autosave, executed withFunctionChoiceBehavior.Autofiltered to thefact_memoryplugin.Design constraints that shaped this:
FactMemoryPluginresolves its authorization boundary fromg.authorized_chat_context, which is what prevents a tool call from writing outside the caller's own user or group scope. This rules out background execution.Changes surface as
fact_memoryprocessing thoughts in both paths.flowchart TD A[User turn] --> B{enable_fact_memory_plugin?} B -- no --> Z[Normal chat, no memory] B -- yes --> C[Recall: inject instruction + relevant fact memories] C --> D[Generate assistant response] D --> E{Agent path handled it?} E -- yes --> Y[Agent already had fact_memory tool - skip] E -- no --> F{user_requested_memory_update?} F -- no --> Y2[Skip - no extra model call] F -- yes --> G[Mini-SK kernel: FactMemoryPlugin only] G --> H[set_fact / update_fact / delete_fact] H --> I[Emit fact_memory thought + persist message]Validation
New coverage:
test_chat_fact_memory_admin_placement.pytest_chat_fact_memory_autosave.pyExisting suites re-run green:
test_fact_memory_profile_and_mini_sk.py,test_admin_settings_field_contract.py(451 baseline fields intact, no duplicate field names),test_docs_app_surface_coverage.py,test_docs_site_quality.py, and all threeroute_tests/policy suites.Nine adjacent tests fail, but they fail identically on a clean worktree at
HEAD— verified withgit worktree add --detach— so no regressions were introduced by this change.Also repairs a stale path in
test_fact_memory_profile_and_mini_sk.pythat had been silently breaking since the feature doc moved intodocs/explanation/features/v0.241.001/.Documentation
docs/explanation/features/v0.261.001/CHAT_FACT_MEMORY_WITHOUT_AGENTS.mddocs/admin/chat.md— new Fact Memory section and settings rowdocs/admin/agents-actions.mdanddocs/reference/actions/fact-memory.md— now point at Chatdocs/_data/features.yml— key re-claimed under a newchat-memoryfeature (admin_tab: chat), removed fromcore-actionsdocs/_data/app_surface.yml— regenerated viascripts/build_docs_inventory.pydocs/explanation/release_notes.md— newv0.261.001sectionNotes for reviewers
@swagger_routedecorators are needed; route policy suites confirm this.static/js/admin/admin_settings.js.deployers/changed, sodeployers/version.txtis untouched.