Skip to content

🪴 fix: Surface Persistent Memory Before First Save - #16301

Merged
danny-avila merged 2 commits into
devfrom
lia/memory-empty-state
Sep 24, 2026
Merged

danny-avila merged 2 commits into
devfrom
lia/memory-empty-state

Conversation

@lia-by-librechat

@lia-by-librechat lia-by-librechat Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Related to #16304 (backend prompt and tool-description localization follow-up).

When an eligible user has no saved memories, the chat prompt omits persistent-memory guidance even though a memory tool or separately enabled extractor can save the user's first memory. The assistant may then say it cannot remember information while the platform successfully records it for future conversations.

Always provide memory-capability guidance when the authorized memory result is empty, and include the existing-memory list only when it has entries. Keep the same opt-out, permission, per-agent tool registration, keyed/unkeyed partition, and request-cache rules. Use neutral wording that never promises a write or claims a memory action succeeded without confirmation. An unavailable or failed memory read still adds no context. Failed reads carry an explicit marker rather than being mistaken for an empty store; automatic extraction skips that turn and token-limited writes fail closed.

How it works

getFormattedMemories → authorized empty result → formatMemoryContext('') → capability guidance
getFormattedMemories → populated result → formatMemoryContext(text) → guidance + existing memories
memory unavailable → formatMemoryContext(undefined) → no new context

The shared formatter lives in packages/api/src/agents/memory.ts; normal chat and the inline agents used by Chat Completions and Responses all call it. The data-schemas result distinguishes an empty partition from a failed read. Automatic extraction reuses the same request-scoped snapshot as chat, so normal runs add no database read. No database schema or configuration changes are required.

Type of change

  • Bug fix
  • Tests / tooling / CI

Testing

Tested environments/configuration: Node.js 24; focused coverage for first empty memory, read-only chat, automatic extraction, inline-tool registration, missing access, load failure and both API controllers. A provider-backed fresh-session smoke test has not been run.

Automated tests: Added regressions in packages/data-schemas/src/methods/memory.spec.ts, packages/api/src/agents/memory.spec.ts, and api/server/controllers/agents/{client.test.js,__tests__/openai.spec.js,__tests__/responses.unit.spec.js} for real failed reads versus empty stores, first-save guidance, automatic extraction, token-limited tools, and context handoff. CI at f6ce2a2f55b549400cfe65437b1c5fe1d5137822 passed the package build, workspace TypeScript checks, backend unit-test shards, integration tests, static checks, Lighthouse, and API runtime smoke. Local JS syntax, touched-file Prettier, import sorting and whitespace checks passed. Local focused Jest could not start (@mongodb-js/saslprep is missing from the shared dependency installation); local npx tsc --noEmit in packages/api and packages/data-schemas stopped on missing installed @types dependencies. Local npm run lighthouse stopped at build:data-provider because tsdown is absent there; the CI Lighthouse lane passed. The local staged-only static-check script found no staged files after commit; CI ran the actual static checks on the pushed diff.

Screenshots / recordings

Not applicable: no client UI or styles changed; this changes model-bound instructions, so resulting provider prose is nondeterministic.

@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Review head: 3ff1d48a55e166c6c27af4497027d353231e911f. This head adds empty-state persistent-memory guidance for eligible chat and inline/API agents via a shared formatter, preserves access and per-agent scoping, and adds formatter and controller regression tests. CI and local focused checks are in progress.

@danny-avila

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3ff1d48a55

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}
return memory
? `${memoryInstructions}\n\n# Existing memory about the user:\n${memory}`
: memoryInstructions;

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 Badge Distinguish failed reads before advertising memory

When MongoDB memory loading fails, getFormattedMemories catches the exception and resolves with withKeys: '' and withoutKeys: '' (packages/data-schemas/src/methods/memory.ts:312-319), so callers never produce the undefined state this formatter reserves for unavailable memory. This empty-string branch therefore advertises persistent memory during read failures, while the added rejected-promise test exercises a behavior the real dependency does not expose. Preserve an explicit failure signal through the data-schemas method before treating '' as an eligible empty store.

AGENTS.md reference: AGENTS.md:L42-L44

Useful? React with 👍 / 👎.

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.

Resolved in f6ce2a2. The formatted result now marks read failures explicitly instead of returning an eligible empty string. Chat and inline contexts receive no memory text on failure; automatic extraction skips that turn and limited writes fail closed. The request-scoped snapshot is reused so the normal path adds no database read. Added storage and prompt/processor/tool regressions.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-24T12:42:42.914534Z f6ce2a2 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Review head: f6ce2a2f55b549400cfe65437b1c5fe1d5137822. This revision removes the product name from the model-facing memory instruction, distinguishes storage read failure from an empty partition, suppresses guidance and automatic extraction after failed reads, and keeps token-limited writes fail closed. Focused regression coverage includes the database result, inline context, extraction, and tool gate. The localization follow-up is #16304. CI for this head is in progress; local Jest and workspace tsc remain blocked by incomplete checkout dependencies.

@danny-avila

Copy link
Copy Markdown
Collaborator

@codex review the latest head

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: f6ce2a2f55

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danny-avila
danny-avila merged commit e6929f5 into dev Sep 24, 2026
28 checks passed
@danny-avila
danny-avila deleted the lia/memory-empty-state branch September 24, 2026 12:43
danny-avila added a commit that referenced this pull request Sep 25, 2026
The e2e fake model reported input tokens for the chat messages alone, because the SDK hands a test override model the pruned messages without the systemRunnable pipe. Once #16301 gave every memory-enabled chat a system prompt, the calibrated context snapshot put used tokens below the instructions and the gauge dropped its Messages row. Count input over the complete prompt, as a real provider bills it.
danny-avila added a commit that referenced this pull request Sep 25, 2026
…16339)

* 🐢 fix: Back Off Waiting Completion Wake-ups and Deliver Them When Ready

* fix: Signal every readiness path and make the completion wait cap configurable

* fix: Mark held completion deliveries instead of pipeline expedite, and announce store-won approval expiry

* fix: Scope settle expedites to the resumed conversation and close the remaining signal gaps

* fix: Announce a won approval expiry once and release subagent wake-up registrations

* 🧪 ci: Count System Instructions in Mock Model Usage (#16350)

The e2e fake model reported input tokens for the chat messages alone, because the SDK hands a test override model the pruned messages without the systemRunnable pipe. Once #16301 gave every memory-enabled chat a system prompt, the calibrated context snapshot put used tokens below the instructions and the gauge dropped its Messages row. Count input over the complete prompt, as a real provider bills it.

---------

Co-authored-by: Lia <lia@librechat.ai>
AnJuHyppolite pushed a commit to newjersey/nj-ai-assistant that referenced this pull request Sep 30, 2026
* fix: Surface Persistent Memory Before First Save

* fix: Distinguish Unreadable Memory From Empty Memory

---------

Co-authored-by: Lia <lia@librechat.ai>
AnJuHyppolite pushed a commit to newjersey/nj-ai-assistant that referenced this pull request Sep 30, 2026
The e2e fake model reported input tokens for the chat messages alone, because the SDK hands a test override model the pruned messages without the systemRunnable pipe. Once LibreChat-AI#16301 gave every memory-enabled chat a system prompt, the calibrated context snapshot put used tokens below the instructions and the gauge dropped its Messages row. Count input over the complete prompt, as a real provider bills it.
AnJuHyppolite pushed a commit to newjersey/nj-ai-assistant that referenced this pull request Sep 30, 2026
…ibreChat-AI#16339)

* 🐢 fix: Back Off Waiting Completion Wake-ups and Deliver Them When Ready

* fix: Signal every readiness path and make the completion wait cap configurable

* fix: Mark held completion deliveries instead of pipeline expedite, and announce store-won approval expiry

* fix: Scope settle expedites to the resumed conversation and close the remaining signal gaps

* fix: Announce a won approval expiry once and release subagent wake-up registrations

* 🧪 ci: Count System Instructions in Mock Model Usage (LibreChat-AI#16350)

The e2e fake model reported input tokens for the chat messages alone, because the SDK hands a test override model the pruned messages without the systemRunnable pipe. Once LibreChat-AI#16301 gave every memory-enabled chat a system prompt, the calibrated context snapshot put used tokens below the instructions and the gauge dropped its Messages row. Count input over the complete prompt, as a real provider bills it.

---------

Co-authored-by: Lia <lia@librechat.ai>
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.

2 participants