[PR #5080] [CLOSED] fix: persist agent and query-refusal chats to thread history via API #5295

Closed
opened 2026-06-05 15:20:53 -04:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/Mintplex-Labs/anything-llm/pull/5080
Author: @angelplusultra
Created: 2/27/2026
Status: Closed

Base: masterHead: 5060-bug-agent-interactions-agent-are-not-persisted-to-thread-history-via-api


📝 Commits (8)

  • 709e9ff fix synchronous chats via API from not persisting
  • 88bc836 add threadId and user to query-mode refusal for persisting the chat
  • b77f756 Merge branch 'master' into 5060-bug-agent-interactions-agent-are-not-persisted-to-thread-history-via-api
  • bbf0520 fix: consistent API chat persistence and UI visibility across sync/stream handlers
  • 6af3e23 fix: add sessionId support to thread endpoints and reject userId + sessionId
  • e7158f9 move request validation in a middleware
  • 1f8b1e7 rename where clause variable to conditions
  • 23a17d8 Merge branch 'master' of github.com:Mintplex-Labs/anything-llm into 5060-bug-agent-interactions-agent-are-not-persisted-to-thread-history-via-api

📊 Changes

3 files changed (+62 additions, -19 deletions)

View changed files

📝 server/endpoints/api/workspaceThread/index.js (+24 -2)
📝 server/utils/chats/apiChatHandler.js (+25 -6)
📝 server/utils/chats/index.js (+13 -11)

📄 Description

Pull Request Type

  • feat (New feature)
  • 🐛 fix (Bug fix)
  • ♻️ refactor (Code refactoring without changing behavior)
  • 💄 style (UI style changes)
  • 🔨 chore (Build, CI, maintenance)
  • 📝 docs (Documentation updates)

Relevant Issues

resolves #5060

Description

API chats via chatSync and streamChat had inconsistent behavior around UI visibility, thread association, and conversation history. This PR unifies both handlers so all code paths behave identically.

Root causes:

  1. chatSync agent path was missing threadId and user, so agent chats were saved as orphan records with no thread association
  2. include was hardcoded inconsistently — some paths used true, some false, some relied on the default (true). There was no unified logic
  3. recentChatHistory always filtered include: true, which meant any chat saved with include: false (ephemeral session chats) was invisible to the LLM on subsequent calls — breaking conversation continuity for sessionId-based API usage

Changes:

  1. apiChatHandler.js — Both chatSync and streamChat now derive shouldIncludeInUI = !sessionId at the top. Every WorkspaceChats.new call uses this value, and consistently passes threadId, user, and apiSessionId.

  2. chats/index.jsrecentChatHistory no longer filters on include: true when apiSessionId is present, so ephemeral session chats are still available as LLM context.

Expected behavior with these changes:

UI Visibility

Condition include Visible in UI?
sessionId provided false No — ephemeral session, hidden from UI
userId provided, no sessionId true Yes — visible to that user
Neither provided (single-user mode) true Yes — no user scoping needed
Neither provided (multi-user mode) true Effectively no — user_id is null so no user's frontend query matches it

LLM Conversation History

Condition LLM receives prior messages? Scoped by
sessionId provided Yes api_session_id match
userId provided, no sessionId Yes user_id + thread_id + include: true
Neither provided Yes (single-user) / No (multi-user, messages effectively vanish) thread_id + include: true

Consistency across handlers

Code path chatSync streamChat
Agent shouldIncludeInUI, threadId , user shouldIncludeInUI, threadId , user
Query refusal (no embeddings) shouldIncludeInUI, threadId , user shouldIncludeInUI, threadId , user
Query refusal (no context) shouldIncludeInUI, threadId , user shouldIncludeInUI, threadId , user
Regular chat shouldIncludeInUI, threadId , user shouldIncludeInUI, threadId , user

Additional Information

  • The frontend websocket chat handler (stream.js) is unaffected — it does not go through apiChatHandler.js
  • Workspace-level API endpoints (/v1/workspace/:slug/chat) do not currently accept userId in the request body — user is always null. Only thread-level endpoints support userId.

Developer Validations

  • I ran yarn lint from the root of the repo & committed changes
  • Relevant documentation has been updated (if applicable)
  • I have tested my code functionality
  • Docker build succeeds locally

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/Mintplex-Labs/anything-llm/pull/5080 **Author:** [@angelplusultra](https://github.com/angelplusultra) **Created:** 2/27/2026 **Status:** ❌ Closed **Base:** `master` ← **Head:** `5060-bug-agent-interactions-agent-are-not-persisted-to-thread-history-via-api` --- ### 📝 Commits (8) - [`709e9ff`](https://github.com/Mintplex-Labs/anything-llm/commit/709e9ff32d27d34bca7a388abb6ae2b0614ba2c6) fix synchronous chats via API from not persisting - [`88bc836`](https://github.com/Mintplex-Labs/anything-llm/commit/88bc836b1610b5a166cb8344652aae0b03179097) add threadId and user to query-mode refusal for persisting the chat - [`b77f756`](https://github.com/Mintplex-Labs/anything-llm/commit/b77f75645a05be524a468694d0c7059d405e06be) Merge branch 'master' into 5060-bug-agent-interactions-agent-are-not-persisted-to-thread-history-via-api - [`bbf0520`](https://github.com/Mintplex-Labs/anything-llm/commit/bbf052010cc1a667b428956f06fb137e7cbcc238) fix: consistent API chat persistence and UI visibility across sync/stream handlers - [`6af3e23`](https://github.com/Mintplex-Labs/anything-llm/commit/6af3e23676df867e794f43f73faa9774126b2405) fix: add sessionId support to thread endpoints and reject userId + sessionId - [`e7158f9`](https://github.com/Mintplex-Labs/anything-llm/commit/e7158f933fe13e288c5c3d0db6a59dbe19c25676) move request validation in a middleware - [`1f8b1e7`](https://github.com/Mintplex-Labs/anything-llm/commit/1f8b1e75af73d7f781dc62892dc70c07687396b9) rename where clause variable to conditions - [`23a17d8`](https://github.com/Mintplex-Labs/anything-llm/commit/23a17d86c0141534a53dda11205b97c19cc2ac38) Merge branch 'master' of github.com:Mintplex-Labs/anything-llm into 5060-bug-agent-interactions-agent-are-not-persisted-to-thread-history-via-api ### 📊 Changes **3 files changed** (+62 additions, -19 deletions) <details> <summary>View changed files</summary> 📝 `server/endpoints/api/workspaceThread/index.js` (+24 -2) 📝 `server/utils/chats/apiChatHandler.js` (+25 -6) 📝 `server/utils/chats/index.js` (+13 -11) </details> ### 📄 Description ### Pull Request Type - [ ] ✨ feat (New feature) - [x] 🐛 fix (Bug fix) - [ ] ♻️ refactor (Code refactoring without changing behavior) - [ ] 💄 style (UI style changes) - [ ] 🔨 chore (Build, CI, maintenance) - [ ] 📝 docs (Documentation updates) ### Relevant Issues resolves #5060 ### Description API chats via `chatSync` and `streamChat` had inconsistent behavior around UI visibility, thread association, and conversation history. This PR unifies both handlers so all code paths behave identically. **Root causes:** 1. `chatSync` agent path was missing `threadId` and `user`, so agent chats were saved as orphan records with no thread association 2. `include` was hardcoded inconsistently — some paths used `true`, some `false`, some relied on the default (`true`). There was no unified logic 3. `recentChatHistory` always filtered `include: true`, which meant any chat saved with `include: false` (ephemeral session chats) was invisible to the LLM on subsequent calls — breaking conversation continuity for `sessionId`-based API usage **Changes:** 1. **`apiChatHandler.js`** — Both `chatSync` and `streamChat` now derive `shouldIncludeInUI = !sessionId` at the top. Every `WorkspaceChats.new` call uses this value, and consistently passes `threadId`, `user`, and `apiSessionId`. 2. **`chats/index.js`** — `recentChatHistory` no longer filters on `include: true` when `apiSessionId` is present, so ephemeral session chats are still available as LLM context. **Expected behavior with these changes:** #### UI Visibility | Condition | `include` | Visible in UI? | |---|---|---| | `sessionId` provided | `false` | No — ephemeral session, hidden from UI | | `userId` provided, no `sessionId` | `true` | Yes — visible to that user | | Neither provided (single-user mode) | `true` | Yes — no user scoping needed | | Neither provided (multi-user mode) | `true` | Effectively no — `user_id` is `null` so no user's frontend query matches it | #### LLM Conversation History | Condition | LLM receives prior messages? | Scoped by | |---|---|---| | `sessionId` provided | Yes | `api_session_id` match | | `userId` provided, no `sessionId` | Yes | `user_id` + `thread_id` + `include: true` | | Neither provided | Yes (single-user) / No (multi-user, messages effectively vanish) | `thread_id` + `include: true` | #### Consistency across handlers | Code path | `chatSync` | `streamChat` | |---|---|---| | Agent | `shouldIncludeInUI`, `threadId` ✅, `user` ✅ | `shouldIncludeInUI`, `threadId` ✅, `user` ✅ | | Query refusal (no embeddings) | `shouldIncludeInUI`, `threadId` ✅, `user` ✅ | `shouldIncludeInUI`, `threadId` ✅, `user` ✅ | | Query refusal (no context) | `shouldIncludeInUI`, `threadId` ✅, `user` ✅ | `shouldIncludeInUI`, `threadId` ✅, `user` ✅ | | Regular chat | `shouldIncludeInUI`, `threadId` ✅, `user` ✅ | `shouldIncludeInUI`, `threadId` ✅, `user` ✅ | ### Additional Information - The frontend websocket chat handler (`stream.js`) is unaffected — it does not go through `apiChatHandler.js` - Workspace-level API endpoints (`/v1/workspace/:slug/chat`) do not currently accept `userId` in the request body — `user` is always `null`. Only thread-level endpoints support `userId`. ### Developer Validations - [x] I ran `yarn lint` from the root of the repo & committed changes - [x] Relevant documentation has been updated (if applicable) - [x] I have tested my code functionality - [x] Docker build succeeds locally --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-06-05 15:20:53 -04:00
yindo closed this issue 2026-06-05 15:20:53 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Mintplex-Labs/anything-llm#5295