Repository navigation
🎒 feat: Carry Project Context Across Conversations - #15684
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The project context key and prompt formatting have correctness issues that can affect resume fencing/warm-context invalidation and the exact system prompt content.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR extends Chat Projects into persistent “workspace context” by adding model-facing instructions and reusable reference-file associations, wiring them through the backend agent runtimes (including pause/resume fencing) and exposing the feature end-to-end via new API endpoints, data-provider types, UI surfaces, and documentation.
Changes:
- Add persisted Project instructions + file associations (
contextRevision,file_ids) with limits, atomic attach/detach, and list summaries (hasInstructions,fileCount). - Resolve/propagate Project context into agent execution (instructions + file-search resources), and fence warm-context + HITL resume using a stable project context key.
- Update client UX (inline metadata editing, instructions editor, file picker, accessible menus) and add docs + tests (unit + e2e).
File summaries
| File | Description |
|---|---|
| packages/data-schemas/src/types/chatProject.ts | Add project context fields |
| packages/data-schemas/src/schema/chatProject.ts | Persist instructions/files + limits |
| packages/data-schemas/src/methods/conversation.ts | Prevent stale saves reassigning project |
| packages/data-schemas/src/methods/conversation.spec.ts | Add stale-save membership tests |
| packages/data-schemas/src/methods/chatProject.ts | Instructions/files methods + list aggregate |
| packages/data-schemas/src/methods/chatProject.spec.ts | Add persistent context tests |
| packages/data-provider/src/types/files.ts | Add expiredAt to TFile |
| packages/data-provider/src/types/agents.ts | Add server-only projectContextKey |
| packages/data-provider/src/types.ts | Extend project + add file view type |
| packages/data-provider/src/limits.ts | Add project instruction/file limits |
| packages/data-provider/src/keys.ts | Add project files query/mutations keys |
| packages/data-provider/src/data-service.ts | Add project files API calls |
| packages/data-provider/src/config.ts | Export new limits + ragEnabled |
| packages/data-provider/src/api-endpoints.ts | Add project files endpoints |
| packages/client/src/components/OGDialogTemplate.tsx | Allow onOpenAutoFocus passthrough |
| packages/api/src/types/http.ts | Add request-scoped project context/files |
| packages/api/src/stream/GenerationJobManager.ts | Clarify server-only projection fields |
| packages/api/src/projects/resources.ts | Resolve/list project file resources |
| packages/api/src/projects/resources.spec.ts | Unit tests for resource hydration |
| packages/api/src/projects/index.ts | Export projects resources/context |
| packages/api/src/projects/handlers.ts | Add files endpoints + instructions validation |
| packages/api/src/projects/handlers.spec.ts | Unit tests for handlers validation |
| packages/api/src/projects/context.ts | Resolve context + key + prompt formatting |
| packages/api/src/projects/context.spec.ts | Unit tests for context resolution/key |
| packages/api/src/agents/runtime.ts | Carry project context in execution context |
| packages/api/src/agents/initialize.ts | Inject project instructions + file_search resources |
| packages/api/src/agents/hitl/policy.ts | Carry/omit projectContextKey in pending actions |
| packages/api/src/agents/hitl/policy.spec.ts | Verify projectContextKey omitted to client |
| packages/api/src/agents/compatibility.ts | Include projectContextKey in fingerprint |
| packages/api/src/agents/compatibility.spec.ts | Verify fingerprint changes with project key |
| packages/api/src/agents/tests/initialize.test.ts | Tests for project context injection/hydration |
| e2e/specs/mock/projects.spec.ts | E2E for instructions/files + layout/accessibility |
| e2e/setup/fake-model.js | Add system-only project context assertions |
| docs/projects.md | Document persistent project context behavior |
| client/src/locales/en/translation.json | Add i18n strings for project UI |
| client/src/data-provider/Projects/queries.ts | Add useProjectFilesQuery |
| client/src/data-provider/Projects/mutations.ts | Add attach/detach project file mutations |
| client/src/components/Projects/ProjectWorkspace.tsx | New workspace UI: instructions/resources/editing |
| client/src/components/Projects/ProjectsView.tsx | Inline editor on project cards |
| client/src/components/Projects/ProjectResources.tsx | Add files UI: upload + choose existing |
| client/src/components/Projects/ProjectResources.spec.tsx | Unit tests for resources UI |
| client/src/components/Projects/ProjectInstructionsDialog.tsx | Instructions editor dialog |
| client/src/components/Projects/ProjectInstructionsDialog.spec.tsx | Unit tests for instructions dialog |
| client/src/components/Projects/ProjectEditor.tsx | Shared inline project editor |
| client/src/components/Projects/ProjectEditDialog.tsx | Remove legacy edit dialog |
| client/src/components/Projects/ProjectDeleteDialog.tsx | Support triggerRef for menu integration |
| client/src/components/Projects/ProjectChatList.tsx | Improve list a11y roles/labels |
| client/src/components/Conversations/ProjectsSection.tsx | Route to workspace editor via query param |
| client/src/components/Chat/ChatView.tsx | Add “Open workspace” project badge |
| CLAUDE.md | Document DropdownPopup + Ariakit menu pattern |
| api/server/services/Endpoints/agents/initialize.js | Resolve project context for agents init |
| api/server/routes/projects.js | Add project file routes |
| api/server/routes/config.js | Add ragEnabled capability flag |
| api/server/routes/tests/config.spec.js | Tests for ragEnabled exposure rules |
| api/server/controllers/assistants/chatV2.js | Inject project instructions for assistants v2 |
| api/server/controllers/assistants/chatV1.js | Inject project instructions for assistants v1 |
| api/server/controllers/agents/resume.js | Fence resume on project context key |
| api/server/controllers/agents/responses.js | Resolve project context for responses API |
| api/server/controllers/agents/request.js | Seed chatProjectId from resolved context |
| api/server/controllers/agents/openai.js | Resolve project context for OpenAI API |
| api/server/controllers/agents/client.js | Include project key in warm fingerprint + pause |
| api/server/controllers/agents/tests/resume.spec.js | Tests for resume fencing behavior |
| api/server/controllers/agents/tests/responses.unit.spec.js | Mock project context resolver |
| api/server/controllers/agents/tests/openai.spec.js | Mock project context resolver |
| api/app/clients/BaseClient.js | Prevent non-insert saves from changing projectId |
Review details
- Files reviewed: 65/65 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
d084d72 to
5fcf42b
Compare
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c2cf6d3423
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 633b81edc4
ℹ️ 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".
1c83b82 to
77f10e3
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 77f10e3da4
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3abb9a2460
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d6d82cf177
ℹ️ 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".
00ce5b5 to
c9a413a
Compare
53fd096 to
c7707fb
Compare
|
Codex Review: Didn't find any major issues. Hooray! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
1a037d5 to
4dc4bd9
Compare
|
@codex review Please review the current PR head 50fca1c. State the exact reviewed commit and ignore findings that apply only to earlier heads. Purpose supplied by the requester: 2 changes since reviewed head c2b8a3a: agent-context fingerprint keeps a no-project turn's digest unchanged (1a037d5), and the long-metadata e2e loads at phone width before driving the mobile drawer (test only); plus content-free rebases onto canary |
…eep file deletes independent of project cleanup - Attaching a project file now fails, with nothing attached, when the file's temporary upload hold cannot be released, instead of attaching a file that can still expire. - A failed project cleanup after a file delete is logged rather than failing a delete that already happened, and a user-wide delete clears that user's project references without reading every file first. - Both resize handles share the orientation-aware grip, so a primary handle in a vertical group renders a rotated grip like the alternate one.
…ile limit when attaching an existing file - Listing a project's attached files now returns not found when the project belongs to another tenant, matching the available-file listing and the chat context resolver. - Choosing an existing file for a full project now names the project file limit instead of the generic attach error, like the upload path.
A caller whose tenant id is an empty string was refused its own tenantless project when listing attached or available files, because the handlers compared '' with null. The project handlers and the chat context resolver now share one comparison that treats an empty tenant id as no tenant, the rule the project file queries already follow.
… acting in the long-metadata spec The desktop title was measured while the phone layout could still be the one rendered, and the sidebar row menu was opened before the mobile drawer committed its open state, which closes a menu opened ahead of it. The spec now waits for the workspace's phone-only sidebar toggle to leave and for the drawer to drop inert, the same drawer signal the agents helpers use.
… unchanged Every turn now passes a project context key into the agent context fingerprint, and a turn outside any project passed the no-project sentinel, which changed the digest of every existing no-project checkpoint. An agent event conversation written before this change then cold-started and reloaded its history on its next event. The fingerprint now hashes the no-project key as absent, so those checkpoints keep matching.
…obile drawer The spec crossed back from desktop to phone width without a reload, which leaves the drawer on the desktop toggle path whose delayed focus handoff to the close button dismissed the row menu roughly 200ms after it opened. The spec now reloads at phone width, as a phone arrives, and waits for the drawer's own focus handoff before opening the menu.
50fca1c to
b3c89a8
Compare
|
@codex review Please review the current PR head b3c89a8. State the exact reviewed commit and ignore findings that apply only to earlier heads. Purpose supplied by the requester: Retry of round 15, which hit the Codex usage limit: 2 changes since reviewed head c2b8a3a (agent-context fingerprint keeps a no-project turn's digest unchanged; long-metadata e2e loads at phone width before driving the mobile drawer, test only), plus content-free rebases onto canary |
|
Codex Review: Didn't find any major issues. Hooray! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
* 🎒 feat: Carry Project Context Across Conversations * fix: fail a project attach whose upload hold cannot be released and keep file deletes independent of project cleanup - Attaching a project file now fails, with nothing attached, when the file's temporary upload hold cannot be released, instead of attaching a file that can still expire. - A failed project cleanup after a file delete is logged rather than failing a delete that already happened, and a user-wide delete clears that user's project references without reading every file first. - Both resize handles share the orientation-aware grip, so a primary handle in a vertical group renders a rotated grip like the alternate one. * fix: treat an empty tenant id as no tenant in the project file picker * fix: attach nothing when a project file is deleted while the attach is in flight * fix: localize project file association failures instead of showing server text * test: expect a localized reason for a rejected project file association * fix: scope project file listing to the caller's tenant and name the file limit when attaching an existing file - Listing a project's attached files now returns not found when the project belongs to another tenant, matching the available-file listing and the chat context resolver. - Choosing an existing file for a full project now names the project file limit instead of the generic attach error, like the upload path. * fix: treat an empty tenant id as no tenant in every project tenant check A caller whose tenant id is an empty string was refused its own tenantless project when listing attached or available files, because the handlers compared '' with null. The project handlers and the chat context resolver now share one comparison that treats an empty tenant id as no tenant, the rule the project file queries already follow. * test: wait for the workspace layout swap and the mobile drawer before acting in the long-metadata spec The desktop title was measured while the phone layout could still be the one rendered, and the sidebar row menu was opened before the mobile drawer committed its open state, which closes a menu opened ahead of it. The spec now waits for the workspace's phone-only sidebar toggle to leave and for the drawer to drop inert, the same drawer signal the agents helpers use. * fix: keep the agent context fingerprint of a turn outside any project unchanged Every turn now passes a project context key into the agent context fingerprint, and a turn outside any project passed the no-project sentinel, which changed the digest of every existing no-project checkpoint. An agent event conversation written before this change then cold-started and reloaded its history on its next event. The fingerprint now hashes the no-project key as absent, so those checkpoints keep matching. * test: load the long-metadata spec at phone width before driving the mobile drawer The spec crossed back from desktop to phone width without a reload, which leaves the drawer on the desktop toggle path whose delayed focus handoff to the close button dismissed the row menu roughly 200ms after it opened. The spec now reloads at phone width, as a phone arrives, and waits for the drawer's own focus handoff before opening the menu. (cherry picked from commit 4062bc3) Original-PR: LibreChat-AI#15684
An MCP tool that returns an image on an OpenAI-compatible custom endpoint (e.g. `wengoagent`) reached the model as text: the image item was JSON-stringified, base64 included, into the tool result, so the model could not see it and paid for the encoding as text tokens. MCP formats results by provider and flattens them to a string for a name it does not recognize. Execution-time tools take that provider from the agent in the tool context, and since LibreChat-AI#15684 the primary agent is initialized on a copy, so the stored agent keeps its endpoint's name (`wengoagent`) instead of the provider `initializeAgent` resolved (`openAI`). Handoff agents, initialized in place, already got image parts, as did custom endpoints whose names happen to match a recognized provider (`OpenRouter`, `Ollama`). buildAgentToolContext now gives the tool context's agent the run's provider, which covers the chat, OpenAI-compatible and Responses controllers. The SDK already projects tool images into image_url parts for that provider. `vertexai` joins the recognized providers: Google agents with Vertex credentials resolve to it, and would otherwise lose images now that the resolved provider reaches the formatter. on_tool_execute └ loadToolsForExecution({ agent: ctx.agent }) ctx from buildAgentToolContext └ createMCPTool({ provider: agent.provider }) └ formatToolContent(result, provider) 'openai' → image artifacts
Summary
Adds reusable instructions and searchable file references to Chat Projects, so conversations can share explicitly managed context without changing model selection, tool permissions, or historical messages. Project instructions and references to indexed files are persisted, and authorized project context is applied to future turns across supported runtimes.
Owner and tenant boundaries, file eligibility, conversation membership, and paused-run compatibility are preserved, with no server-only replay state exposed. The UI gains inline metadata editing, responsive text clamping, accessible action menus, and New chat placed immediately left of the header options menu. Files is hidden when RAG is not configured (Instructions fills the row), and only an authenticated capability boolean is exposed, never the RAG service URL.
Project reference files require the existing RAG service configuration; Instructions work without RAG. No new external package dependencies.
Change Type
Testing
npm run frontend: production package and frontend builds passed.npx tsc --noEmitforclientandpackages/data-provider: passed.npx jest server/routes/__tests__/config.spec.js --runInBand(fromapi): 54 tests passed.npx playwright test --config=e2e/playwright.config.mock.ts projects.spec.tswithRAG_API_URL=: 8 tests passed, covering inline editing, 320px layout, project-scoped chats, and the no-RAG layout.npm run lighthouse:runwithCHROME_PATH=/usr/bin/google-chrome: LCP, CLS, and TBT budgets passed with 250ms injected database-query latency.Test Configuration:
CHROME_PATH=/usr/bin/google-chromerequired for Lighthouse on WSL).Checklist