* fix: enforce RBAC on agent endpoints — block non-admin create/update/delete
- Add /v1/agents/{agent_id} to agent_routes so internal users can
access GET-by-ID (previously returned 403 due to missing route pattern)
- Add _check_agent_management_permission() guard to POST, PUT, PATCH,
DELETE agent endpoints — only PROXY_ADMIN may mutate agents
- Add user_api_key_dict param to delete_agent so the role check works
- Add comprehensive unit tests for RBAC enforcement across all roles
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix: mock prisma_client in internal user get-agent-by-id test
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* feat(ui): hide agent create/delete controls for non-admin users
Match MCP servers pattern: wrap '+ Add New Agent' button in
isAdmin conditional so internal users see a read-only agents view.
Delete buttons in card and table were already gated.
Update empty-state copy for non-admin users.
Add 7 Vitest tests covering role-based visibility.
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
These three methods legitimately need many statements for their
event/message transformation logic. Suppress the lint warning rather
than artificially splitting the methods.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PR #22271 added the LiteLLM_ClaudeCodePluginTable model to
schema.prisma but did not include a corresponding migration file,
causing test_aaaasschema_migration_check to fail.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Commit 99c62ca40e removed "azure" from _RESPONSES_API_PROVIDERS,
routing Azure models through litellm.completion instead of
litellm.responses. The test was not updated to match, causing it
to assert against the wrong mock.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The revert in 8565c70e53 removed the parallel_tool_calls handling from
map_openai_params, and the subsequent fix d0445e1e33 only re-added the
transform_request consumption but forgot to re-add the map_openai_params
producer that sets _parallel_tool_use_config. This meant parallel_tool_calls
was silently ignored for all Bedrock models.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests were asserting no response.create/conversation.item.create sent to
backend when guardrail blocks, but the implementation intentionally sends
these to have the LLM voice the guardrail violation message to the user.
Updated assertions to verify the correct guardrail flow:
- response.cancel is sent to stop any in-progress response
- conversation.item.create with violation message is injected
- response.create is sent to voice the violation
- original blocked content is NOT forwarded
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests were mocking the old method name `filter_server_ids_by_ip` but production
code at server.py:774 calls `filter_server_ids_by_ip_with_info` which returns
a (server_ids, blocked_count) tuple. The unmocked method on AsyncMock returned
a coroutine, causing "cannot unpack non-iterable coroutine object" errors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a gunicorn worker exits (e.g. from max_requests recycling), its
per-process prometheus .db files remain on disk. For gauges using
livesum/liveall mode, this means the dead worker's last-known values
persist as if the process were still alive. Wire gunicorn's child_exit
hook to call mark_process_dead() so live-tracking gauges accurately
reflect only running workers.
* fix: add missing LiteLLM_ClaudeCodePluginTable to schema.prisma
- Claude Code Plugin Marketplace endpoints (/claude-code/marketplace.json,
/claude-code/plugins) were returning 500 errors because
LiteLLM_ClaudeCodePluginTable model was missing from both schema.prisma files
- Prisma client was generated without this table causing AttributeError:
'Prisma' object has no attribute 'litellm_claudecodeplugintable'
- Added missing model definition to root schema.prisma and
litellm/proxy/schema.prisma
Fixes#21310
* test: add regression test for LiteLLM_ClaudeCodePluginTable schema
* fix: address greptile review - add @updatedAt, clean up test imports
The /project/list endpoint was not returning created_at and updated_at timestamps because these fields were not defined in LiteLLM_ProjectTable. Added these fields to the model so FastAPI includes them in the response (values come from the database). This allows the UI to display project creation and last-updated times.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Replace the hardcoded NATIVE_OPENROUTER_MODELS set approach with a
pattern-based check in _get_openai_compatible_provider_info: after
stripping the outer "openrouter/" provider prefix, if the remaining
model name still starts with "openrouter/", return immediately without
further stripping.
This fixes openrouter/openrouter/aurora-alpha, openrouter/openrouter/polaris-alpha,
and any future native OpenRouter models — not just the three hard-coded
ones (auto, free, bodybuilder) from the previous approach.
Fixes#16353
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolve conflict in model_prices_and_context_window.json by keeping both
the new minimax-m2.5 model from upstream and the OpenRouter native models
from this branch.
Add a new Projects page under ACCESS CONTROL in the left nav, positioned
between Teams and Internal Users. Projects sit between teams and keys in
the hierarchy for use-case management.
- ProjectsPage with Ant Design table (list, search, pagination)
- CreateProjectModal with team-scoped model selection
- React-query hooks for /project/list and /project/new
- New badge on Projects, removed from Access Groups
- Page metadata entry for test compliance
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tests go through the real get_async_httpx_client() code path to verify
clients remain usable after both capacity eviction and TTL expiry.
Regression tests for PR #22247.