mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-27 04:07:05 +00:00
📡 fix: Refresh MCP Tools After List-Changed Notifications (#14686)
* fix(mcp): handle dynamic tool list changes Co-authored-by: Pascal Garber <pascal@artandcode.studio> * test(mcp): fix CI validation * fix(mcp): keep dynamic tool catalogs live * fix(mcp): harden dynamic catalog lifecycle * test(mcp): use typed startup connection * test(mcp): isolate dynamic e2e fixtures * fix(mcp): refresh tools after reconnect * fix(mcp): close dynamic catalog cache gaps * test(mcp): update OAuth connection mocks * fix(mcp): preserve app snapshot ownership * style(mcp): sort connection imports * fix(mcp): close review race conditions * fix(mcp): preserve cache ownership edges * fix(mcp): harden recovery lifecycle * fix(mcp): guard tool-less app refresh * fix(mcp): fence distributed cache races * fix(mcp): retire stale connection state * fix(mcp): keep tool snapshots authoritative * fix(mcp): fence stale app tool publications * style(mcp): sort repository test imports * test(mcp): mock empty startup publication * fix(mcp): preserve app publication generations * fix(mcp): harden publication recovery races * fix(mcp): address tool catalogs by runtime config * fix(mcp): load scoped catalogs for assistant writes * fix(mcp): harden catalog publication recovery * fix(mcp): serialize forced connection replacement * fix(mcp): serialize ordinary creation with replacements * fix(mcp): harden catalog fallback boundaries * fix(mcp): close lifecycle fencing gaps * fix(mcp): preserve catalog authority on failures * fix(mcp): compensate failed catalog mutations * fix(mcp): fence catalog refresh ordering * style(mcp): sort agent loader imports * fix(mcp): cancel stale connection creation * fix(mcp): fence catalog coordination * fix(mcp): close catalog race windows * fix(mcp): harden cross-pod catalog fencing * fix(mcp): close catalog lifecycle edges * style(mcp): sort assistant imports * fix(mcp): reject stale recovery authority * fix(mcp): restore static catalog on every startup * fix(mcp): order app catalog publications * style(mcp): sort catalog revision imports * fix(mcp): separate catalog allocation and commit fences --------- Co-authored-by: Pascal Garber <pascal@artandcode.studio>
This commit is contained in:
parent
ef38f362ec
commit
1bccc2bc18
60 changed files with 8046 additions and 831 deletions
118
.github/workflows/playwright-mock.yml
vendored
118
.github/workflows/playwright-mock.yml
vendored
|
|
@ -164,6 +164,116 @@ jobs:
|
|||
retention-days: 7
|
||||
if-no-files-found: ignore
|
||||
|
||||
mcp_tool_list_changed:
|
||||
name: MCP list_changed (replica count ${{ matrix.replicas }})
|
||||
if: >-
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(github.event_name == 'pull_request' &&
|
||||
github.event.pull_request != null &&
|
||||
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association))
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
replicas: [1, 2]
|
||||
env:
|
||||
CI: 'true'
|
||||
E2E_CHROMIUM_CHANNEL: chrome
|
||||
E2E_MCP_LIST_CHANGED: 'true'
|
||||
E2E_REPLICAS: ${{ matrix.replicas }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Use Node.js 24.16.0
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '24.16.0'
|
||||
|
||||
- name: Restore node_modules cache
|
||||
id: cache-node-modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
node_modules
|
||||
client/node_modules
|
||||
packages/client/node_modules
|
||||
packages/data-provider/node_modules
|
||||
packages/data-schemas/node_modules
|
||||
packages/api/node_modules
|
||||
api/node_modules
|
||||
key: node-modules-e2e-${{ runner.os }}-24.16.0-${{ hashFiles('package-lock.json') }}
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cache-node-modules.outputs.cache-hit != 'true'
|
||||
run: npm ci
|
||||
|
||||
- name: Build e2e dependencies
|
||||
run: npm run e2e:prepare
|
||||
|
||||
- name: Install Playwright and Redis runtime dependencies
|
||||
timeout-minutes: 5
|
||||
run: |
|
||||
google-chrome --version
|
||||
npx playwright install-deps chrome
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y redis-server redis-tools
|
||||
|
||||
- name: Start standalone Redis and Redis Cluster
|
||||
run: |
|
||||
redis-server --daemonize yes --port 6379
|
||||
redis-cli -p 6379 ping
|
||||
chmod +x redis-config/start-cluster.sh redis-config/stop-cluster.sh
|
||||
./redis-config/start-cluster.sh
|
||||
redis-cli -p 7001 cluster info
|
||||
|
||||
- name: Test MCP notifications with in-memory cache
|
||||
env:
|
||||
E2E_STREAM_STORE: memory
|
||||
run: >-
|
||||
npx playwright test --config=e2e/playwright.config.mock.ts
|
||||
mcp-tool-list-changed.spec.ts --retries=0
|
||||
|
||||
- name: Test MCP notifications with standalone Redis cache
|
||||
env:
|
||||
E2E_STREAM_STORE: redis
|
||||
REDIS_URI: redis://127.0.0.1:6379
|
||||
run: >-
|
||||
npx playwright test --config=e2e/playwright.config.mock.ts
|
||||
mcp-tool-list-changed.spec.ts --retries=0
|
||||
|
||||
- name: Test MCP notifications with Redis Cluster cache
|
||||
env:
|
||||
E2E_STREAM_STORE: redis-cluster
|
||||
REDIS_URI: redis://127.0.0.1:7001,redis://127.0.0.1:7002,redis://127.0.0.1:7003
|
||||
run: >-
|
||||
npx playwright test --config=e2e/playwright.config.mock.ts
|
||||
mcp-tool-list-changed.spec.ts --retries=0
|
||||
|
||||
- name: Upload Playwright HTML report
|
||||
if: ${{ !cancelled() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: playwright-mcp-list-changed-${{ matrix.replicas }}-replicas
|
||||
path: e2e/playwright-report/**
|
||||
retention-days: 7
|
||||
if-no-files-found: ignore
|
||||
|
||||
- name: Upload traces & screenshots
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: playwright-mcp-list-changed-results-${{ matrix.replicas }}-replicas
|
||||
path: e2e/specs/.test-results/**
|
||||
retention-days: 7
|
||||
if-no-files-found: ignore
|
||||
|
||||
- name: Stop Redis processes
|
||||
if: always()
|
||||
run: |
|
||||
./redis-config/stop-cluster.sh || true
|
||||
redis-cli -p 6379 shutdown || true
|
||||
|
||||
e2e:
|
||||
name: e2e
|
||||
if: >-
|
||||
|
|
@ -172,9 +282,11 @@ jobs:
|
|||
(github.event_name == 'pull_request' &&
|
||||
github.event.pull_request != null &&
|
||||
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association)))
|
||||
needs: e2e_shards
|
||||
needs: [e2e_shards, mcp_tool_list_changed]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Verify every Playwright shard passed
|
||||
if: needs.e2e_shards.result != 'success'
|
||||
- name: Verify every Playwright job passed
|
||||
if: >-
|
||||
needs.e2e_shards.result != 'success' ||
|
||||
needs.mcp_tool_list_changed.result != 'success'
|
||||
run: exit 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue