- Change no_output_timeout from 120m/60m to 15m across all test jobs
- Fix multi-line YAML formatting for no_output_timeout entries
- Reduce Playwright per-test timeout from 4min to 3min
- Add 15s actionTimeout and 30s navigationTimeout to Playwright config
Hanging tests now fail in 15min instead of 2hrs, cutting wasted CI time.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Reduce RENDER_BATCH_SIZE from 5 to 3 for more frequent chart updates
- Add LoadingOutlined spinner at the start of all fetching Alert banners
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace subtle loading text with antd Alert banners that clearly communicate
pagination status, and batch state flushes to reduce chart re-renders.
- Replace inline loading text with warning Alert banners showing progress,
"open a new tab" link with ExportOutlined icon, and primary Stop button
- Batch setData calls every 5 pages instead of per-page to cut re-renders ~80%
- Reduce fetch delay from 500ms to 300ms for faster data loading
- Add "Charts will update periodically" messaging to set expectations
- Fix pre-existing TS error: Button icon prop was using render function instead of ReactNode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Replace ...args spread in useEffect deps with JSON.stringify(args) key
to prevent infinite re-renders when callers pass unstable array references.
2. Add missing agentCancelled partial-data message in EntityUsage so the
outer condition no longer renders an empty div.
3. Store setTimeout ID in a ref and clearTimeout on cleanup/cancel to avoid
orphaned timers under rapid re-renders.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The test's partial vi.mock of @/components/networking was missing the daily
activity call exports now imported by EntityUsage via ENTITY_FETCH_FNS.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, EntityUsage only fetched page 1 of paginated daily spend endpoints,
showing incomplete data. UsagePageView fetched all pages but blocked the UI until
completion. This adds a reusable usePaginatedDailyActivity hook that fetches pages
sequentially with 500ms delays, updates charts progressively, and supports
cancellation on unmount or user action.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite Default Team Settings UI from Tremor to antd with hardcoded fields,
fix default team params not applying during team creation or persisting
across proxy restarts, remove dead code, and add comprehensive tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(security): bump tar to 7.5.11 and tornado to 6.5.5
- tar >=7.5.11: fixes CVE-2026-31802 (HIGH) in node-pkg
- tornado >=6.5.5: fixes CVE-2026-31958 (HIGH) and GHSA-78cv-mqj4-43f7 (MEDIUM) in python-pkg
Addresses vulnerabilities found in ghcr.io/berriai/litellm:main-v1.82.0-stable Trivy scan.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: document tar override is enforced via Dockerfile, not npm
* fix: revert invalid JSON comment in package.json tar override
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Tests for HelpLink, ScoreChart, AgentCard, ToolPoliciesView, and CostBreakdownViewer (33 tests total).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The model dropdown menus in the Add Fallbacks modal were rendering behind
the modal overlay because Ant Design portals Select dropdowns to document.body
by default. By setting getPopupContainer to attach the dropdown to its parent
element, the dropdown inherits the modal's stacking context and renders above
the modal.
Fixes#17895
- OrganizationDropdown: renders options, calls onChange on selection,
applies disabled state, handles empty list
- CreateKey: org dropdown renders, disabled for non-admin users,
enabled for admins, form state updates on org selection
- KeyEditView: org dropdown renders, disabled for non-admin,
enabled for admin, initializes from keyData.organization_id
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Backend: Use request model from hidden_params for Azure Model Router additional_costs when response has actual model
- Backend: Add additional_costs to total cost calculation
- UI: Show all non-null/non-zero additional_costs in CostBreakdownViewer
- UI: Render cost breakdown when only additional_costs exist
- Tests: Backend test for hidden_params flow; frontend tests for additional_costs
Made-with: Cursor
Cover utils, types, MCPStandardsSettings, MCPLogoSelector, and
mcp_connection_status with 44 behavior-focused Vitest tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Keep both sets of tests: upstream's OAuth2 token injection test and
our case-insensitive tool matching tests. Use upstream's version of
the bedrock output_config test (more comprehensive).
- user_dashboard.tsx: Replace userInfoCall with userGetInfoV2 for spend data,
remove keys/teams logic (keys come from props/useKeys hook, teams from fetchTeams)
- user_info_view.tsx: Replace userInfoCall with userGetInfoV2, flatten data
structure from nested {user_info: {...}} to flat response, fetch team details
separately using teamInfoCall, remove keys display (Virtual Keys section)
- Update user_dashboard.test.tsx and user_info_view.test.tsx mocks
Co-authored-by: yuneng-jiang <yuneng-jiang@users.noreply.github.com>
- Add UserInfoV2Response type and userGetInfoV2() function in networking.tsx
- Migrate useCurrentUser hook from userInfoCall to userGetInfoV2
- Update useCurrentUser.test.ts to test new v2 API integration
- The hook no longer needs userRole since the endpoint handles auth itself
Co-authored-by: yuneng-jiang <yuneng-jiang@users.noreply.github.com>
* fix(mcp): OAuth2 chat connect - tools fetch, auth flow, and status fixes
- schema.prisma: add missing MCP table fields (approval_status, submitted_by, submitted_at, reviewed_at, review_notes) to prevent destructive migrations
- rest_endpoints.py: inject user OAuth token via extra_headers for OAuth2 servers so tools list is populated; add server name->UUID resolution so MCPConnectPicker name lookups work
- mcp_registry.json: fix Atlassian defaults (transport: http, url: .../v1/mcp)
- ChatPage.tsx: read mcpOauthReturn param to init sidebarView="apps" on OAuth return, clean up param after mount
- MCPAppsPanel.tsx: auto-add OAuth2 servers to selectedServers when credential detected; onConnect also enables server for chat; disconnect removes from selectedServers
- mcp_servers.tsx: sort servers by created_at DESC
- useUserMcpOAuthFlow.tsx: append mcpOauthReturn=apps to return URL so Apps panel is mounted on return
* address greptile review feedback (greploop iteration 1)
* fix(mcp): inject stored OAuth2 token when fetching tools via /responses API
When a user has connected an OAuth2 MCP server (e.g. Atlassian) and then
uses the /responses endpoint with that server, tool listing was failing
because the stored per-user OAuth token was never injected.
Two fixes:
1. server.py: add _get_user_oauth_extra_headers_from_db() helper; call it
in _get_tools_from_mcp_servers when oauth2_headers is None for an OAuth2
server, falling back to the user's stored token in LiteLLM_MCPUserCredentials
2. litellm_proxy_mcp_handler.py: also intercept MCP tools whose server_url
matches */mcp/<server_name> (e.g. http://localhost:4000/mcp/atlassian_test)
by rewriting them to litellm_proxy/mcp/<server_name> so they go through
the internal handler (and get the OAuth token injected) instead of being
forwarded to OpenAI raw where localhost is unreachable
* address greptile review feedback (greploop iteration 2)
* test(mcp): add unit test for OAuth2 token injection in _get_tools_from_mcp_servers
Verifies that when _get_tools_from_mcp_servers is called for an OAuth2 MCP
server without oauth2_headers in the request, the implementation:
- calls _prefetch_oauth_creds_for_user once (not per-server) to avoid N+1 queries
- passes the stored token as extra_headers={"Authorization": "Bearer ..."} to
_get_tools_from_server so the upstream OAuth2 MCP server authenticates correctly
* address greptile review feedback (greploop iteration 3)
* address greptile review feedback (greploop iteration 4)
* address greptile review feedback (greploop iteration 5)
* redesign credentials table to use Tremor table layout matching Keys page
* fix: /server/oauth authorize 422 - make client_id optional, fall back to real DB server
* fix: mcp_token client_id optional, resolve from server record
* fix: look up real server by UUID (get_mcp_server_by_id) before falling back to name
* Update litellm/responses/mcp/litellm_proxy_mcp_handler.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* fix: address greptile feedback - client_id guards, dict spread, helper refactor, tests
- mcp_management_endpoints: raise 400 when resolved_client_id is empty in
mcp_authorize and mcp_token instead of forwarding "" to upstream
- litellm_proxy_mcp_handler: use {**tool, "server_url": ...} spread instead
of dict(tool) + mutation for shallow copy safety
- rest_endpoints: extract _oauth2_server_ids set comprehension to a named
_get_oauth2_server_ids() helper for clarity; add Set to typing imports
- test_rest_endpoints: add tests for name→UUID resolution path,
access-denied when resolved UUID not in allowed list, and OAuth2 user
token injection for single-server requests; fix fake_get_tools signature
to accept extra_headers kwarg
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* feat(ui): group MCP tools by CRUD risk category in tool permission panels
Adds a CRUD-classification layer to the MCP tool allowlist UI so admins
can allow/block an entire risk category (Read / Create / Update / Delete)
with a single toggle instead of managing a flat list of individual tools.
- New `mcpToolCrudClassification.ts` utility: regex-based classifier that
buckets tool names/descriptions into read/create/update/delete/unknown
- New `McpCrudPermissionPanel` component: collapsible sections per CRUD
group, group-level Switch toggle, individual tool checkboxes, risk badges
(green Safe / yellow Medium / red High Risk)
- `mcp_tool_configuration.tsx`: adds "Risk Groups / Flat List" radio toggle;
defaults to the CRUD-grouped view, flat list is still accessible
- `MCPToolPermissions.tsx` (key/team assignment): replaces flat checkboxes
with the CRUD panel; adds per-server view toggle; delete tools are blocked
by default for newly-added servers (safer default for key/team scoping)
No backend or schema changes — uses existing `allowed_tools` and
`mcp_tool_permissions` fields.
* fix(mcp): OAuth2 chat connect - tools fetch, auth flow, and status fixes
- schema.prisma: add missing MCP table fields (approval_status, submitted_by, submitted_at, reviewed_at, review_notes) to prevent destructive migrations
- rest_endpoints.py: inject user OAuth token via extra_headers for OAuth2 servers so tools list is populated; add server name->UUID resolution so MCPConnectPicker name lookups work
- mcp_registry.json: fix Atlassian defaults (transport: http, url: .../v1/mcp)
- ChatPage.tsx: read mcpOauthReturn param to init sidebarView="apps" on OAuth return, clean up param after mount
- MCPAppsPanel.tsx: auto-add OAuth2 servers to selectedServers when credential detected; onConnect also enables server for chat; disconnect removes from selectedServers
- mcp_servers.tsx: sort servers by created_at DESC
- useUserMcpOAuthFlow.tsx: append mcpOauthReturn=apps to return URL so Apps panel is mounted on return
* fix(mcp-crud-ui): address greptile review feedback
- use Checkbox (not Switch) for group toggle so indeterminate works
- add toolPermissionsRef to avoid stale closure race on concurrent server fetches
- remove unused blockDeleteByDefault prop from McpCrudPermissionPanel
- classify tools by name first; fall back to description only when name yields no match
- add Risk Groups / Flat List toggle to mcp_tool_configuration.tsx
* fix(mcp-crud-ui): address greptile 3/5 review
- remove non-functional XIcon remove-server button (no onRemoveServer prop wired)
- fix stale closure in MCPAppsPanel auto-enable effect: use serversRef/selectedServersRef
- remove utility re-export from McpCrudPermissionPanel (classifyToolOp, groupToolsByCrud)
- remove redundant selectedTools.length === 0 guard (always true when !toolPermissions[id])
* fix(mcp-crud-ui): address greptile 3/5 review round 2
- check READ_RE before DELETE_RE in classifyToolOp so tools like
get_removed_entries are not silently blocked by delete-by-default
- expand undefined (allow-all) to full tool name list instead of
collapsing to [] (allow-none) in MCPToolPermissions and mcp_tool_configuration
- log OAuth credential fetch failures instead of silently swallowing them
* fix: cursor-pointer on read-only rows, stable sort, simplify handleCrudPanelChange
* fix: sanitize user_id/server_id in log to prevent log injection
* fix: add OAuth headers to call_tool_rest_api, fix stale accessToken closure, fix group toggle on filtered subset
* fix: batch OAuth creds query, hide empty CRUD groups on search, onChange stability
* fix: double-add race, conditional bulk query, narrow DELETE_RE, hoist search input
* fix(mcp): clear oauthConnected on deselect; null guard on allowedTools prop
* fix(mcp): remove user-provided values from debug log to fix log-injection lint
* fix(mcp): fix allowedTools undefined semantics; remove unused import and color field
Expand the existing expand=user lookup on /key/list to also resolve
created_by user IDs, and display the result in the Created By column
with alias > email > UUID fallback and a popover showing all three.