Commit graph

5084 commits

Author SHA1 Message Date
yuneng-jiang
50dc7b520c
Update ui/litellm-dashboard/src/components/Projects/ProjectModals/CreateProjectModal.tsx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-27 22:11:04 -08:00
yuneng-jiang
061703abc0 [Feature] UI - Projects: Add Project Details page with Edit modal
- Add ProjectDetailsPage with header, details card, spend/budget progress,
  model spend bar chart, keys placeholder, and team info card
- Refactor CreateProjectModal into base form pattern (ProjectBaseForm)
  shared between Create and Edit flows
- Add EditProjectModal with pre-filled form data from backend
- Add useProjectDetails and useUpdateProject hooks
- Add duplicate key validation for model limits and metadata
- Wire project ID click in table to navigate to detail view
- Move pagination inline with search bar

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-27 21:35:21 -08:00
yuneng-jiang
85590e4538
Merge pull request #22354 from BerriAI/litellm_cost_tracking_vitest
[Test] UI - CostTrackingSettings: Add comprehensive Vitest coverage
2026-02-27 21:24:02 -08:00
yuneng-jiang
c4a0174e00 test: add comprehensive Vitest coverage for CostTrackingSettings
Add 88 tests across 9 test files for the CostTrackingSettings component directory:
- provider_display_helpers.test.ts: 9 tests for helper functions
- how_it_works.test.tsx: 9 tests for discount calculator component
- add_provider_form.test.tsx: 7 tests for provider form validation
- add_margin_form.test.tsx: 9 tests for margin form with type toggle
- provider_discount_table.test.tsx: 12 tests for table editing and interactions
- provider_margin_table.test.tsx: 13 tests for margin table with sorting
- use_discount_config.test.ts: 11 tests for discount hook logic
- use_margin_config.test.ts: 12 tests for margin hook logic
- cost_tracking_settings.test.tsx: 15 tests for main component and role-based rendering

All tests passing. Coverage includes form validation, user interactions, API calls, state management, and conditional rendering.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-27 21:16:41 -08:00
Ishaan Jaff
eea083fa4b
fix(mcp): default available_on_public_internet to true (#22331)
* fix(mcp): default available_on_public_internet to true

MCPs were defaulting to private (available_on_public_internet=false) which
was a breaking change. This reverts the default to public (true) across:
- Pydantic models (AddMCPServerRequest, UpdateMCPServerRequest, LiteLLM_MCPServerTable)
- Prisma schema @default
- mcp_server_manager.py YAML config + DB loading fallbacks
- UI form initialValue and setFieldValue defaults

* fix(ui): add forceRender to Collapse.Panel so toggle defaults render correctly

Ant Design's Collapse.Panel lazy-renders children by default. Without
forceRender, the Form.Item for 'Available on Public Internet' isn't
mounted when the useEffect fires form.setFieldValue, causing the Switch
to visually show OFF even though the intended default is true.

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* fix(mcp): update remaining schema copies and MCPServer type default to true

Missed in previous commit per Greptile review:
- schema.prisma (root)
- litellm-proxy-extras/litellm_proxy_extras/schema.prisma
- litellm/types/mcp_server/mcp_server_manager.py MCPServer class

* ui(mcp): reframe network access as 'Internal network only' restriction

Replace scary 'Available on Public Internet' toggle with 'Internal network only'
opt-in restriction. Toggle OFF (default) = all networks allowed. Toggle ON =
restricted to internal network only. Auth is always required either way.

- MCPPermissionManagement: new label/tooltip/description, invert display via
  getValueProps/getValueFromEvent so underlying available_on_public_internet
  value is unchanged
- mcp_server_view: 'Public' → 'All networks', 'Internal' → 'Internal only' (orange)
- mcp_server_columns: same badge updates

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
2026-02-27 20:06:07 -08:00
Ishaan Jaff
8ce358e303
[Feat] Agent RBAC Permission Fix - Ensure Internal Users cannot create agents (#22329)
* 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>
2026-02-27 18:32:39 -08:00
Chesars
ab8ffb0573 Merge upstream/main into fix-model-management-ui 2026-02-27 19:01:58 -03:00
Alejandro Tapia
18bc0d4ec9 reusable-credentials 2026-02-27 13:37:23 -08:00
yuneng-jiang
2613277ede [Feature] UI - Projects: Add Projects page with list and create flows
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>
2026-02-27 13:31:17 -08:00
Sameer Kankute
d9af321610 Fix free models working from UI 2026-02-27 10:08:44 +05:30
Dibyo Mukherjee
518cd3ef60 feat(ui): add key creation deep-links with SSO return URL support
Enables deep-linking directly to the key creation modal with prefilled
form data via URL parameters, including support for preserving these
deep-links through SSO authentication flows.

Key Creation Deep-links:
- Auto-open key creation modal via ?create=true parameter
- Prefill form fields from URL parameters (team_id, key_alias, models, etc.)
- Role-based access control for auto-open (requires write access)
- Race condition protection for redirect handling

Example: /ui?create=true&team_id=abc&key_alias=my-key&models=gpt-4,claude-3

SSO Return URL Preservation:
- Cookie-based return URL storage (works across ports for SSO flows)
- URL validation to prevent open redirect attacks
- Support for both dev and production environments

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 15:41:54 -05:00
yuneng-jiang
c3c79b9d80 [Fix] Virtual Keys pagination displays stale totals when filtering
When applying a key_alias filter on the Virtual Keys page, the pagination display (total count, page count) showed stale unfiltered values. The bug was that the table component tracked total_count only from the unfiltered useKeys hook, not from the filtered API response returned by useFilterLogic.

Fixes: When selecting a key alias that matches 1 key, the UI previously showed "Showing 1-50 of 509 results" and "Page 1 of 11" instead of the correct "Showing 1-1 of 1 results" and "Page 1 of 1".

Changes:
- Added filteredTotalCount state to useFilterLogic to track the total_count from filtered API responses
- Updated VirtualKeysTable to use filteredTotalCount (when set) instead of always using the unfiltered total
- Added comprehensive tests to prevent regression of pagination display logic

Type: 🐛 Bug Fix,  Test

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-26 12:28:43 -08:00
yuneng-jiang
947586b62d Merge remote-tracking branch 'origin' into litellm_paginated_key_alias 2026-02-26 10:28:35 -08:00
Ishaan Jaff
965ca117bc
feat(realtime guardrails): end_session_after_n_fails + Endpoint Settings wizard step (#22165)
* feat(realtime guardrails): end_session_after_n_fails + Endpoint Settings wizard step

Adds per-session violation thresholds and an optional endpoint-settings step
to the guardrail wizard for /v1/realtime.

Backend:
- Add end_session_after_n_fails, on_violation, realtime_violation_message fields
  to BaseLitellmParams (no DB migration — stored in existing JSON column)
- Store same fields on CustomGuardrail instance attrs
- Pass through in litellm_content_filter initializer
- Track _violation_count per RealTimeStreaming session; close backend_ws when
  on_violation=end_session OR violation count >= end_session_after_n_fails
- Use realtime_violation_message as the spoken text (falls back to guardrail
  error string if not configured)

UI (add_guardrail_form.tsx):
- Rename "Default Categories" step to "Topics"
- Add step 5 "Endpoint Settings (Optional)" for content filter guardrails
- Call type dropdown shows /v1/realtime
- Settings are in a collapsed accordion (closed by default)
- "End session after X violations" + on_violation radio + spoken message field

Tests: 2 new tests in test_realtime_streaming.py
- test_end_session_after_n_fails_closes_connection
- test_on_violation_end_session_closes_on_first_fail

* fix(test): move inline imports to module level in realtime streaming tests

* Update ui/litellm-dashboard/src/components/guardrails/add_guardrail_form.tsx

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-25 23:49:03 -08:00
Ishaan Jaff
3545584a00
Development environment setup (#22160)
* feat: add pretty view for realtime API logs in dashboard

- Create RealtimePrettyView component that renders structured session
  config, conversation turns with transcripts, and token breakdowns
- Update PrettyMessagesView to detect realtime responses (via
  isRealtimeResponse helper) and delegate to the new component
- Session card shows model, voice, modalities, temperature, instructions
  in a collapsible panel
- Conversation turns show status, per-turn token usage, and audio/text
  transcripts with appropriate icons
- Add 24 tests for RealtimePrettyView and 3 tests for PrettyMessagesView
- All 75 LogDetailsDrawer tests pass

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* chore: remove dev_config.yaml from tracked files

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* feat: show turn count in realtime pretty view session header and output header

- Add purple 'N turns' tag to Session card header for at-a-glance turn count
- Add 'Turns: N' to the Output section header next to tokens/cost
- Extend SectionHeader to accept optional turnCount prop
- Add 3 new tests for turn count display (singular, plural, output header)

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* fix: address Greptile review feedback

- Remove response.audio.done and conversation.item.created from
  isRealtimeResponse() detection since the view doesn't render them;
  prevents misleading fallback for responses with only those events
- Remove dead code: index >= 0 is always true in .map() callback

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>
2026-02-25 23:20:03 -08:00
yuneng-jiang
ac3cfff93f Merge remote-tracking branch 'origin' into litellm_paginated_key_alias 2026-02-25 22:32:36 -08:00
yuneng-jiang
5a123f0e75 fixing ui build 2026-02-25 22:29:34 -08:00
yuneng-jiang
701ec62da6 [Feature] UI - Paginated Key Alias Select
Replace the non-paginated Key Alias filter with a new PaginatedKeyAliasSelect component that mirrors the existing PaginatedModelSelect pattern. This aligns the UI with the paginated /key/aliases endpoint from PR #22137.

Changes:
- Added useInfiniteKeyAliases hook for paginated key alias fetching
- Created PaginatedKeyAliasSelect component with infinite scroll (80% threshold)
- Updated keyAliasesCall in networking to accept page/size/search params
- Replaced Key Alias filter in Request Logs and Virtual Keys tables to use customComponent
- Removed fetchAllKeyAliases helper and related upfront fetching logic
- Added 22 tests for new component and hook; all existing tests pass (54 tests)

Fixes the issue where the UI was fetching all key aliases at once, causing performance issues with large key sets.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-25 22:21:32 -08:00
Krish Dholakia
a9cb2674c0
feat(add-new-block_code_execution-guardrail): prevent agent from executing code (#22154)
Adds a new block_code_execution guardrail that detects markdown fenced code blocks
in request/response content and blocks or masks them by language. Includes full
UI integration, type definitions, compliance test dataset, and 26 unit tests.

Key guardrail capabilities:
- Regex-based fenced code block detection with configurable blocked languages
- Confidence scoring with tunable threshold
- Execution-intent heuristics (request-side only) with conflict resolution
- Block or mask actions for detected code
- Support for pre_call, post_call, and during_call event hooks

Security hardening:
- Response-side blocking skips intent heuristics (LLM output doesn't contain
  user intent phrases, so checking would silently disable post_call blocking)
- No-execution short-circuit includes conflict resolution: if both no-execution
  and execution phrases match, execution intent wins
- Tightened overly broad phrases to prevent trivial bypass
- _normalize_escaped_newlines only applies to pure-escaped payloads to avoid
  corrupting content that discusses escape sequences

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 22:02:14 -08:00
Ishaan Jaff
82cd14ea1d
feat(realtime): guardrails support for /v1/realtime WebSocket endpoint (#22152)
* feat(realtime): add guardrails query param to /v1/realtime WebSocket endpoint

- Add 'guardrails' query param (comma-separated) to realtime_websocket_endpoint
- Import websockets and websockets.exceptions at module level (fixes NameError in except clause)
- Split try/except into Phase 1 (pre-call) and Phase 2 (routing) so guardrail
  errors send back a typed error event before closing, while upstream errors
  close silently with 1011

* feat(ui): pass selectedGuardrails from sidebar to RealtimePlayground WebSocket URL

* docs(realtime): add guardrails section with dynamic passing examples
2026-02-25 21:34:22 -08:00
Krish Dholakia
c2c8870d2d
Add claims agent guardrails (5 categories + policy template) (#22113)
* Add claims agent guardrails with 243-case eval dataset

5 new category guardrails for healthcare claims agent chatbots:
- claims_fraud_coaching: fraud coaching, exaggeration, document forgery
- claims_phi_disclosure: unauthorized PHI access, bulk data extraction
- claims_prior_auth_gaming: code manipulation, medical necessity misrepresentation
- claims_system_override: system injection, rule bypass, role impersonation
- claims_medical_advice: medical advice (claims-context-aware)

Plus claims_agent_safety.yaml policy template combining all 5.

All 5 eval suites pass at 100% precision/recall/F1 (243 test cases).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add claims agent chatbot safety policy template

Combines the 5 claims guardrails into a single deployable policy template:
fraud coaching, PHI disclosure, prior-auth gaming, system override, and medical advice.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add guardrail benchmark results and UI compliance prompts

Adds benchmark results for claims, discrimination, and content filter guardrails.
Updates UI compliance prompt data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove duplicate "file an appeal" exception in claims_prior_auth_gaming.yaml

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove unused claims_agent_safety.yaml policy template

The claims-agent-safety template in policy_templates.json references
individual category files in categories/, not this combined file.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 18:09:38 -08:00
yuneng-jiang
88bf8de3cf
Merge pull request #22119 from BerriAI/litellm_ui_mcp_auth_non_req
[Fix] UI - MCP Servers: Make auth value optional for create flow
2026-02-25 16:48:08 -08:00
yuneng-jiang
6ac3ed6b4e
Merge pull request #22122 from BerriAI/litellm_ui_spend_logs_duration
[Feature] UI - Logs: Use backend request_duration_ms and make Duration sortable
2026-02-25 16:47:22 -08:00
Krish Dholakia
4b9aba8fac
feat: add UI banner warning for detailed debug mode (#21527)
Add a prominent warning banner to the UI dashboard when detailed debug
mode (LITELLM_LOG=DEBUG) is enabled. This alerts users to significant
performance degradation caused by extensive diagnostic logging.

Backend changes:
- Enhanced /health/readiness endpoint to include log_level and
  is_detailed_debug fields
- Added detection using verbose_logger.getEffectiveLevel()
- Backward compatible - old clients ignore new fields

Frontend changes:
- Updated useHealthReadiness TypeScript interface
- Created DebugWarningBanner component using Ant Design Alert
- Integrated banner into dashboard layout below navbar
- Banner only shows when DEBUG level is active
- Non-dismissible to ensure users are aware of performance impact

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 16:32:59 -08:00
Ishaan Jaff
adba088df2
Realtime API: spend log storage, playground UI, tools logging, and guardrail support (#22105)
Backend - Spend Log Storage for Realtime Calls:
- Collect user voice transcripts and text input during WebSocket sessions
- Store collected messages in spend logs when store_prompts_in_spend_logs enabled
- Capture tool definitions from session.update and tool calls from response.done
- Enrich proxy_server_request with tools and response with tool_calls for UI

Backend - WebSocket Auth:
- Support browser-based auth via Sec-WebSocket-Protocol subprotocol
- Echo back subprotocol on WebSocket accept

UI - Realtime Playground:
- New RealtimePlayground component with WebSocket voice+text chat
- Mic recording (PCM16 24kHz), server VAD, audio playback, text input
- Handle binary WebSocket frames (Blob/ArrayBuffer decoding)
- Add /v1/realtime endpoint option to playground endpoint selector

UI - Tools Section for Realtime Logs:
- Extract tool calls from realtime response format (response.tool_calls
  and response.results[].response.output[].type=function_call)

Tests:
- 15 new backend tests for realtime streaming and spend log storage
- 4 new UI tests for realtime tool call extraction

Fixes pre-existing build errors:
- ToolPolicies.tsx: duplicate import, antd styles type
- create_key_button.tsx: missing message import

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
2026-02-25 14:55:27 -08:00
yuneng-jiang
5140062c09 [Feature] UI - Logs: Use backend request_duration_ms and make Duration sortable
Use the backend-provided request_duration_ms field instead of computing
duration client-side from startTime/endTime. Add sort support for the
Duration column, which sends sortBy=request_duration_ms to the API.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-25 12:24:11 -08:00
yuneng-jiang
a4fd75fd31 [Fix] UI - MCP Servers: Make auth value optional for create flow
The backend validator and frontend form both enforced auth_value as
required when auth_type is api_key, bearer_token, or basic. Users who
want to provide auth dynamically (via per-request headers or OAuth2
flows) could not skip the field.

- Remove required validation from auth_value in create_mcp_server.tsx
  (keep whitespace-only rejection, matching the edit flow)
- Remove validate_credentials_requirements in NewMCPServerRequest
  (all downstream code already treats auth_value as optional)
- Add tests for the create MCP server component

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-25 12:04:00 -08:00
Krish Dholakia
12c4876891
Agents - assign tools (#22064)
* feat(proxy): add max_iterations limiter for agent session loops (#22058)

Adds a new proxy hook that enforces a per-session cap on the number of
LLM calls an agentic loop can make. Callers send a session_id with each
request, and the hook counts calls per session, returning 429 when the
configured max_iterations limit is exceeded.

- Uses Redis Lua script for atomic increment (multi-instance safe)
- Falls back to in-memory cache when Redis unavailable
- Follows parallel_request_limiter_v3 pattern
- Configurable via key metadata: {"max_iterations": 25}
- Session counters auto-expire via TTL (default 1hr)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add new code execution dataset

* feat(agent_endpoints/): allow giving agents keys

* fix: ui fixes

* feat: allow assigning mcp servers to agents

* fix: eliminate duplicate DB queries in MCP agent auth and N+1 in agent listing (#22110)

- Extract _get_agent_object_permission helper so _get_allowed_mcp_servers_for_agent
  and _get_agent_tool_permissions_for_server share a single DB fetch instead of
  each independently querying the same agent row (was 1+N queries per MCP request)
- Use include={"object_permission": True} on find_many in get_all_agents_from_db
  to eagerly load permissions in one query instead of N+1
- Use include={"object_permission": True} on create/update/find_unique in all
  agent CRUD operations, removing attach_object_permission_to_dict follow-up calls

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 11:44:30 -08:00
yuneng-jiang
30e8151288 fixing build and tests 2026-02-25 11:30:09 -08:00
yuneng-jiang
b9d3fdf93e Merge remote-tracking branch 'origin' into ui_build_fix_feb25 2026-02-25 10:51:50 -08:00
yuneng-jiang
cd41b49061 fixing build 2026-02-25 10:51:42 -08:00
yuneng-jiang
243771f99a
Merge pull request #22108 from BerriAI/litellm_pricing_calc_tests
[Test] UI - Pricing Calculator: Add comprehensive unit tests
2026-02-25 10:51:12 -08:00
Krish Dholakia
5662228e20
feat(ui): add user filtering to usage page (#22059)
* feat(ui): add user filtering to usage page

Adds "User Usage" as a new view option in the usage page dropdown,
allowing admins to view and filter usage data by individual users
via the existing /user/daily/activity backend endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(ui/): working usage filtering

* fix(ui): use single-select for user filter and add tests

The user entity type's backend endpoint only accepts a single user_id,
so the filter now uses single-select mode instead of multi-select.
Added tests for the new user entity type in EntityUsage and
UsageViewSelect. Updated CLAUDE.md and AGENTS.md with guidance on
UI/backend contract consistency and test coverage for new entity types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* revert: remove unintended package-lock.json changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* revert: restore package-lock.json to merge base state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 10:37:45 -08:00
yuneng-jiang
6ae7e84a0b [Test] UI - Pricing Calculator: Add comprehensive unit tests
Added unit tests for all pricing calculator components with 64 passing tests across 5 test files:
- multi_export_utils.test.ts (16 tests for PDF/CSV export functions)
- use_multi_cost_estimate.test.ts (15 tests for cost estimation hook)
- multi_export_dropdown.test.tsx (8 tests for export dropdown component)
- multi_cost_results.test.tsx (15 tests for results display and UI states)
- index.test.tsx (10 tests for main calculator component)

Also fixed missing page description for tool-policies page in page_metadata.ts.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-25 10:25:25 -08:00
Shin
115b9a2d29 fix(ui): remove duplicate antd import in ToolPolicies
Duplicate import was causing UI build to fail:
- Line 4: import { Select, Switch, Tooltip } from 'antd'
- Line 5: import { Select, Tooltip } from 'antd' (duplicate)

Removed the duplicate line 5.
2026-02-25 18:09:17 +00:00
Krish Dholakia
00ab4d2067
feat: add new code execution dataset (#22065) 2026-02-24 20:58:23 -08:00
Ishaan Jaff
60bcb26dc8
feat(agents): assign virtual keys to agents (#22045)
* feat(agents): assign virtual keys to agents

- Add agent_id field to LiteLLM_VerificationToken (schema.prisma + _types.py)
- Pass agent_id through key generation endpoint so keys can be scoped to an agent
- Refactor Add Agent wizard to 3-step flow (Configure → Assign Key → Ready)
  - Configure: all agent fields, custom/other type with just name+description
  - Assign Key: create new key or reassign existing key to agent
  - URL is now optional for easy discovery
- Add "Agent" ownership option to Create Key modal on Virtual Keys page
  with agent selector dropdown
- Extract CreatedKeyDisplay into shared component, reused in both flows
- Add keyCreateForAgentCall networking helper
- Add test for agent_id key generation

* fix(agents): code quality fixes from self-review

- Fix test_generate_key_helper_fn_agent_id: remove bare except clause,
  use explicit assert mock_insert.called, use .kwargs for clean arg access
- Remove no-op conditional in handleNext (both branches were identical)
- Validate selectedExistingKey before calling keyUpdateCall
- Validate selectedAgentId before setting on formValues in create_key_button

* fix(ui): replace deprecated Tremor Button with Ant Design Button in CreatedKeyDisplay
2026-02-24 18:28:16 -08:00
Ishaan Jaff
4e84e4c607
fix(ui): show real tool names in logs for Anthropic format tools (#22048) 2026-02-24 18:16:04 -08:00
yuneng-jiang
3f1554c099
Merge pull request #21071 from atapia27/feat/healthcheck-model_id-fix
healthcheck-model_id-fix
2026-02-24 17:15:07 -08:00
Alejandro Tapia
80c09295ad Merge upstream/main - resolve health check conflicts 2026-02-24 17:09:05 -08:00
yuneng-jiang
9837a1bd2a
Merge pull request #22047 from BerriAI/litellm_key_info_page_email
[Feature] UI - Virtual Keys: Add KeyInfoHeader component
2026-02-24 17:04:17 -08:00
yuneng-jiang
50ba6986ef [Feature] UI - Virtual Keys: Add KeyInfoHeader component with metadata display
Add a reusable KeyInfoHeader component to replace the inline header in KeyInfoView.
Extract LabeledField as a common component for labeled metadata display with copyable
support, default_user_id handling, and empty value placeholders.

- Migrate all icons from lucide-react/heroicons to @ant-design/icons
- Use antd native copyable with descriptive tooltips (Copy Key Alias, Copy Key ID, etc.)
- Show DefaultProxyAdminTag for default_user_id values
- Add canModifyKey, regenerateDisabled, regenerateTooltip props for permission gating
- Add tests for KeyInfoHeader (19 tests) and LabeledField (8 tests)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-24 16:46:26 -08:00
Ishaan Jaff
360643e213
[Feat] UI - Allow using AI to understand Usage patterns (#22042)
* Add Ask AI chat component to Usage page

- Create UsageAIChatModal component with streaming chat interface
- Integrate with existing model hub for model selection
- Pass usage data context (spend, models, providers, keys) to AI
- Add Ask AI button next to Export Data button in global view
- Add tests for the new component and integration

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Convert Ask AI from modal to right-side sliding panel

- Replace UsageAIChatModal with UsageAIChatPanel
- Panel slides in from right side, usage page stays visible
- Full-height panel with header, model selector, chat area, and input
- Smooth CSS transition for open/close animation
- Update tests for new panel component (34 tests passing)

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Remove build output directory from tracking

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Add backend AI usage chat endpoint with tool calling

Backend:
- New /usage/ai/chat SSE streaming endpoint
- AI agent has get_usage_data tool that queries /user/daily/activity/aggregated
- Follows same architecture as policy AI suggest (litellm.acompletion + tools)
- Non-admin users are restricted to their own data
- 12 backend unit tests

Frontend:
- Panel now calls /usage/ai/chat backend endpoint via SSE
- Removed direct OpenAI client calls from frontend
- Added usageAiChatStream networking function following enrichPolicyTemplateStream pattern

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Make model selection optional, default to gpt-4o-mini on backend

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Add team/tag tools, status indicators, and improved AI agent

- AI agent now has 3 tools: get_usage_data, get_team_usage_data, get_tag_usage_data
- Stream status events (Thinking... Fetching... Analyzing...) to UI
- Frontend shows spinner + status text during tool execution
- Better system prompt guiding tool selection
- Entity summariser for team/tag data with ranked breakdowns
- 13 backend tests, 34 frontend tests passing

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Fix: inject today's date into system prompt so AI resolves relative dates correctly

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Show tool calls as distinct steps + render markdown in responses

- Backend emits tool_call events with tool_name, label, args, and status
- Frontend shows each tool call as a step with ✓/spinner/✗ indicator
- Tool call steps show icon, label, date range, and filters
- AI responses rendered with ReactMarkdown (bold, lists, tables, code)
- Cursor-like UX: Thinking → tool calls → Analyzing → streamed answer

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Refactor backend for code quality: proper types, constants, all functions ≤50 LOC

- TypedDict for SSE events (SSEStatusEvent, SSEToolCallEvent, etc.) and ToolHandler
- Constants for table names, entity fields, temperature, page sizes, top-N limits
- Shared _query_activity() eliminates duplicated fetch logic
- _accumulate_breakdown() + _ranked_lines() replace inline aggregation loops
- Extracted _process_tool_call() and _stream_final_response() from main stream fn
- Black + Ruff clean, all 15 functions verified ≤50 LOC
- Replaced Tremor Button with Antd Button in panel (Tremor deprecated per AGENTS.md)

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Address greptile review: security fixes and input validation

- Restrict team/tag tools to admin-only users (non-admins only get get_usage_data)
- Constrain ChatMessage.role to Literal['user', 'assistant'] to prevent system prompt injection
- Add test for base tools restriction (non-admin gets 1 tool, admin gets 3)
- Issues 3 (unused imports) and 4 (inline datetime) were already fixed in prior commit

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Address greptile round 2: sanitize errors, defense-in-depth allowlist, revert tsconfig

- Sanitize error messages: generic 'An internal error occurred' sent to client,
  full exception logged server-side via verbose_proxy_logger
- Defense-in-depth: _process_tool_call validates fn_name against role-based
  allowlist before dispatch (even though LLM only receives allowed tools)
- Revert tsconfig.json jsx back to 'preserve' (Next.js recommended default)

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Role-scoped system prompt + additional test coverage

- System prompt is now role-aware: admin sees all 3 tool descriptions,
  non-admin only sees get_usage_data (consistent with tool filtering)
- Added tests: non-admin prompt excludes team/tag tools, date injection
- 15 backend tests, 34 frontend tests passing

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Fix LLM arg validation + cap conversation size at 20 messages

- _resolve_fetch_kwargs uses .get() with ValueError for missing dates
  (handles malformed LLM tool arguments gracefully)
- MAX_CHAT_MESSAGES = 20 constant; backend truncates to last 20
- Frontend also sends only last 20 messages per request
- Prevents excessive token usage and context-length errors

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>
2026-02-24 16:40:04 -08:00
Ishaan Jaff
6ee50ff73e
feat(proxy): tool policies - auto-discover tools + policy enforcement guardrail (#22041)
* feat(proxy): tool policies - auto-discover tools, manage policies, guardrail enforcement

- New LiteLLM_ToolTable in schema.prisma to store discovered tools
- Auto-discovery: tools seen in LLM responses get upserted via ToolDiscoveryQueue
  (hooks into DBSpendUpdateWriter, same pipeline as spend tracking)
- Management endpoints: GET /v1/tool/list, GET /v1/tool/{name}, POST /v1/tool/policy
- ToolPolicyGuardrail: blocks tool_calls in responses based on policy setting
- UI: Tool Policies page under Guardrails section with policy selector,
  filters by policy/team/key, live tail, sortable table
- Unit tests for queue, writer, endpoints, guardrail

* feat(tool-policies): track call_count + discover tools from request body and /messages API

- Add call_count column to LiteLLM_ToolTable; incremented on every flush
- Extract tools from request body too (not just response tool_calls):
  - OpenAI /chat/completions: tools[].function.name
  - Anthropic /messages pass-through: request_body.tools[].name
- Show call_count column in UI table (sortable)
- UI: drop dual_llm option, keep only trusted/blocked

* fix: address greptile review feedback

- Remove redundant @@index([tool_name]) from schema.prisma (tool_name has @unique which already creates an index)
- Replace gen_random_uuid()::text with str(uuid.uuid4()) for portability
- Rewrite test_tool_registry_writer.py to mock execute_raw/query_raw (actual implementation) instead of Prisma model methods
- Fix test patches in test_tool_management_endpoints.py to target source modules since imports are inside function bodies
- Add "Tool Policies" page title to ToolPolicies.tsx

* fix: address greptile review round 2

- Replace NOW() with Python datetime parameter in tool_registry_writer (SQLite portability)
- Fix cache key collision in tool_policy_guardrail: use null-byte separator instead of colon
- Remove type==function filter from request-side tool extraction to match response-side behavior
- Clear seen_tool_names on flush so call_count increments per batch cycle not per pod lifetime

* fix: address greptile review round 3

- Fix test_seen_names_persist_across_flushes to match actual per-flush-cycle behavior
- Update module docstring in tool_discovery_queue.py to accurately describe flush behavior
- Add created_at/updated_at to raw SQL INSERT in batch_upsert_tools and update_tool_policy

* fix: cache tool policies per tool name not per combination

Previously the cache key was built from the full set of tool names in a
request, so each unique combination of tools got its own cold cache entry
and triggered a separate DB query. With N distinct tools across requests
this was effectively a DB hit on every request.

Now each tool name is cached individually. Cache hits are checked per
tool, only missing tools are fetched from DB in a single batch query,
and each result is cached separately. Once a tool's policy is warm,
any subsequent request using that tool benefits from the cache regardless
of what other tools are in the request.

* Update ui/litellm-dashboard/src/components/ToolPolicies.tsx

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-24 16:27:06 -08:00
yuneng-jiang
26e5482abb address greptile review feedback (greploop iteration 2)
- Wait for strategy select (API data loaded) before clicking Save
- Assert specific payload content in setCallbacksCall
- Move NotificationsManager import to top of file
2026-02-24 15:52:15 -08:00
yuneng-jiang
784af16cb4 address greptile review feedback (greploop iteration 1)
- Replace document.querySelector/querySelectorAll with screen.getByRole
- Replace raw dispatchEvent with userEvent.selectOptions
2026-02-24 15:48:31 -08:00
yuneng-jiang
b3bb744aa4 [Test] Add unit tests for router_settings components
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 15:26:06 -08:00
yuneng-jiang
4321bc9285
Merge pull request #21985 from BerriAI/litellm_ui_testing_coverage_00
[Fix] UI - Virtual Keys: restrict Edit Settings to key owners
2026-02-24 10:16:40 -08:00
Harshit28j
132e2ed671 Merge branch 'main' of https://github.com/BerriAI/litellm into litellm_fix_CVE
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2026-02-24 21:09:16 +05:30
Harshit28j
3e6c10a071 security: fix critical/high CVEs in OS-level libs and NPM transitive 2026-02-24 19:40:09 +05:30