feat(proxy): add model-like search tool access control

Treat search tools like models by adding team/key allowed_search_tools controls, enforcing search tool authorization checks, and moving credential ownership to search tool config only to avoid exposing secrets in team metadata.

Made-with: Cursor
This commit is contained in:
Sameer Kankute 2026-04-28 18:53:32 +05:30
parent 2d2f540480
commit c4e074f277
No known key found for this signature in database
49 changed files with 1597 additions and 478 deletions

View File

@ -0,0 +1,439 @@
# Search Tools Access Control
Control which teams and keys can access specific search tools using model-like allowlists.
## Overview
Search tools in LiteLLM Proxy use the same access control pattern as models:
- **Team-level allowlist**: `allowed_search_tools` on teams
- **Key-level allowlist**: `allowed_search_tools` on keys
- **Tool-only credentials**: API keys stored ONLY in search tool configuration
- **Secure by default**: Credentials never exposed in team/key metadata
## Quick Start
### Step 1: Configure Search Tools
Define search tools in your `proxy_server_config.yaml`:
```yaml
search_tools:
- search_tool_name: perplexity-search
litellm_params:
search_provider: perplexity
api_key: os.environ/PERPLEXITYAI_API_KEY
- search_tool_name: tavily-search
litellm_params:
search_provider: tavily
api_key: os.environ/TAVILY_API_KEY
- search_tool_name: tavily-marketing
litellm_params:
search_provider: tavily
api_key: os.environ/TAVILY_MARKETING_API_KEY
- search_tool_name: brave-search
litellm_params:
search_provider: brave
api_key: os.environ/BRAVE_API_KEY
```
### Step 2: Create Teams with Search Tool Access
```bash
curl -X POST 'http://localhost:4000/team/new' \
-H 'Authorization: Bearer <master-key>' \
-H 'Content-Type: application/json' \
-d '{
"team_alias": "marketing-team",
"models": ["gpt-4"],
"allowed_search_tools": ["tavily-marketing", "perplexity-search"]
}'
```
### Step 3: Generate Keys for Teams
```bash
curl -X POST 'http://localhost:4000/key/generate' \
-H 'Authorization: Bearer <master-key>' \
-H 'Content-Type: application/json' \
-d '{
"team_id": "<team-id>",
"models": ["gpt-4"],
"allowed_search_tools": ["tavily-marketing"]
}'
```
### Step 4: Use Search Tools
```bash
curl -X POST 'http://localhost:4000/v1/search/tavily-marketing' \
-H 'Authorization: Bearer sk-...' \
-d '{"query": "latest marketing trends"}'
```
## Access Control Rules
### Authorization Flow
```mermaid
flowchart TD
Request["/v1/search/tavily-search"] --> KeyCheck{Key has access?}
KeyCheck -->|No| Deny403[403 Forbidden]
KeyCheck -->|Yes| TeamCheck{Team has access?}
TeamCheck -->|No| Deny403
TeamCheck -->|Yes| GetCreds[Get credentials from tool config]
GetCreds --> CallAPI[Call Tavily API]
```
### Allowlist Behavior
| Allowlist Value | Behavior |
|----------------|----------|
| `[]` (empty) | Access to **all** search tools |
| `["tool-a", "tool-b"]` | Access only to `tool-a` and `tool-b` |
| Not set / `null` | Access to **all** search tools |
### Examples
**Example 1: Team restricts tools, key further restricts**
```yaml
# Team allows 3 tools
team.allowed_search_tools = ["tavily", "perplexity", "brave"]
# Key only allows 1 tool
key.allowed_search_tools = ["tavily"]
# Result: Key can ONLY access "tavily"
```
**Example 2: Empty allowlists grant full access**
```yaml
# Team allows all
team.allowed_search_tools = []
# Key allows all
key.allowed_search_tools = []
# Result: Key can access ANY search tool
```
**Example 3: Team blocks access even if key allows**
```yaml
# Team restricts to perplexity
team.allowed_search_tools = ["perplexity"]
# Key allows tavily
key.allowed_search_tools = ["tavily"]
# Result: Access DENIED - team doesn't allow tavily
```
## Configuration Patterns
### Pattern 1: Per-Team Search Tool Isolation
Each team gets their own search tool with dedicated credentials:
```yaml
search_tools:
- search_tool_name: tavily-team-a
litellm_params:
search_provider: tavily
api_key: os.environ/TAVILY_TEAM_A_KEY
- search_tool_name: tavily-team-b
litellm_params:
search_provider: tavily
api_key: os.environ/TAVILY_TEAM_B_KEY
```
```bash
# Create teams with isolated tools
curl -X POST 'http://localhost:4000/team/new' \
-H 'Authorization: Bearer <master-key>' \
-d '{
"team_alias": "team-a",
"allowed_search_tools": ["tavily-team-a"]
}'
```
**Benefits**:
- Complete cost isolation (different Tavily accounts)
- Separate rate limits per team
- Independent billing
### Pattern 2: Shared Tools with Access Control
Share search tools across teams with allowlist restrictions:
```yaml
search_tools:
- search_tool_name: tavily-premium
litellm_params:
search_provider: tavily
api_key: os.environ/TAVILY_PREMIUM_KEY
- search_tool_name: perplexity-standard
litellm_params:
search_provider: perplexity
api_key: os.environ/PERPLEXITY_KEY
```
```bash
# Enterprise team gets premium tools
curl -X POST 'http://localhost:4000/team/new' \
-d '{
"team_alias": "enterprise",
"allowed_search_tools": ["tavily-premium", "perplexity-standard"]
}'
# Regular team gets standard tools only
curl -X POST 'http://localhost:4000/team/new' \
-d '{
"team_alias": "standard",
"allowed_search_tools": ["perplexity-standard"]
}'
```
### Pattern 3: Open Access with Cost Tracking
Allow all teams to access tools, track costs via `team_id`:
```yaml
search_tools:
- search_tool_name: tavily-shared
litellm_params:
search_provider: tavily
api_key: os.environ/TAVILY_SHARED_KEY
```
```bash
# Teams with empty allowlists can access all tools
curl -X POST 'http://localhost:4000/team/new' \
-d '{
"team_alias": "team-a",
"allowed_search_tools": []
}'
```
Query spend by team:
```sql
SELECT
team_id,
SUM(spend) as total_spend,
COUNT(*) as request_count
FROM "LiteLLM_SpendLogs"
WHERE call_type = 'search'
AND model LIKE 'tavily%'
GROUP BY team_id;
```
## Security Model
### Credentials Storage
**Secure**: Credentials stored ONLY in search tool configuration
```yaml
# ✅ CORRECT - Credentials in tool config
search_tools:
- search_tool_name: tavily-search
litellm_params:
api_key: os.environ/TAVILY_API_KEY # Stored here
```
**Never in team/key metadata**:
```json
{
"team_id": "team-123",
"allowed_search_tools": ["tavily-search"],
"metadata": {} // ✅ No credentials here
}
```
### Access Control Only
Teams and keys only specify **which tools** they can access, not credentials:
```json
{
"team": {
"allowed_search_tools": ["tool-a", "tool-b"] // Access control
},
"key": {
"allowed_search_tools": ["tool-a"] // Access control
}
}
```
## API Reference
### Create Team with Search Tools
```bash
POST /team/new
{
"team_alias": "marketing",
"models": ["gpt-4"],
"allowed_search_tools": ["tavily-search", "perplexity-search"]
}
```
### Update Team Search Tools
```bash
POST /team/update
{
"team_id": "team-123",
"allowed_search_tools": ["brave-search"]
}
```
### Generate Key with Search Tools
```bash
POST /key/generate
{
"team_id": "team-123",
"models": ["gpt-4"],
"allowed_search_tools": ["tavily-search"]
}
```
### List Available Search Tools
```bash
GET /v1/search/tools
# Response:
{
"object": "list",
"data": [
{
"search_tool_name": "tavily-search",
"search_provider": "tavily"
}
]
}
```
## Cost Attribution
Search requests are automatically attributed to the team via `team_id` in spend logs:
```sql
SELECT
team_id,
model as search_tool,
SUM(spend) as cost,
COUNT(*) as requests
FROM "LiteLLM_SpendLogs"
WHERE call_type = 'search'
AND created_at >= NOW() - INTERVAL '30 days'
GROUP BY team_id, model
ORDER BY cost DESC;
```
**Example output**:
| team_id | search_tool | cost | requests |
|---------|-------------|------|----------|
| team-marketing | tavily-search | $45.20 | 904 |
| team-engineering | perplexity-search | $32.15 | 643 |
| team-research | brave-search | $8.50 | 170 |
## Migration from Legacy Approach
If you previously stored credentials in team metadata, migrate to the new approach:
### Before (Insecure)
```json
{
"team": {
"metadata": {
"search_provider_config": {
"tavily": {"api_key": "tvly-..."} // ❌ Exposed
}
}
}
}
```
### After (Secure)
```yaml
# 1. Move credentials to search tool config
search_tools:
- search_tool_name: tavily-marketing
litellm_params:
search_provider: tavily
api_key: os.environ/TAVILY_MARKETING_KEY # ✅ Secure
# 2. Update team with allowlist
team:
allowed_search_tools: ["tavily-marketing"] # ✅ Access control only
```
## Troubleshooting
### 403 Forbidden Error
```json
{
"error": "Key not allowed to access search tool: tavily-search.
Allowed search tools: [perplexity-search]"
}
```
**Solution**: Add the search tool to key's `allowed_search_tools`:
```bash
curl -X POST 'http://localhost:4000/key/update' \
-d '{
"key": "sk-...",
"allowed_search_tools": ["tavily-search", "perplexity-search"]
}'
```
### Search Tool Not Found
```json
{"error": "Search tool not found: tavily-search"}
```
**Solution**: Add the search tool to your `proxy_server_config.yaml`:
```yaml
search_tools:
- search_tool_name: tavily-search
litellm_params:
search_provider: tavily
api_key: os.environ/TAVILY_API_KEY
```
## Best Practices
1. **Use descriptive tool names**: `tavily-marketing` vs `tavily-1`
2. **Empty allowlists for admins**: Grant full access to admin teams
3. **Restrict by role**: Marketing gets marketing tools, engineering gets code search
4. **Monitor costs per team**: Query spend logs regularly
5. **Rotate credentials in tools**: Update environment variables, not team metadata
6. **Start restrictive**: Add tools to allowlists as needed
## Related
- [Search API Reference](./search.md)
- [Team Management](./team_budgets.md)
- [Cost Tracking](./cost_tracking.md)

View File

@ -1725,7 +1725,7 @@ class TeamBase(LiteLLMPydanticObjectBase):
members: list = []
members_with_roles: List[Member] = []
team_member_permissions: Optional[List[str]] = None
metadata: Optional[dict] = None # may include search_provider_config
metadata: Optional[dict] = None
tpm_limit: Optional[int] = None
rpm_limit: Optional[int] = None
@ -1738,6 +1738,7 @@ class TeamBase(LiteLLMPydanticObjectBase):
)
models: list = []
allowed_search_tools: list = [] # list of search_tool_name values team can access
blocked: bool = False
router_settings: Optional[dict] = None
access_group_ids: Optional[List[str]] = None
@ -1845,13 +1846,6 @@ class UpdateTeamRequest(LiteLLMPydanticObjectBase):
)
class TeamSearchProviderConfigUpdateRequest(LiteLLMPydanticObjectBase):
team_id: str
provider: str
api_key: Optional[str] = None
api_base: Optional[str] = None
class ResetTeamBudgetRequest(LiteLLMPydanticObjectBase):
"""
internal type used to reset the budget on a team
@ -2451,6 +2445,7 @@ class LiteLLM_VerificationToken(LiteLLMPydanticObjectBase):
max_budget: Optional[float] = None
expires: Optional[Union[str, datetime]] = None
models: List = []
allowed_search_tools: List = [] # list of search_tool_name values key can access
aliases: Dict = {}
config: Dict = {}
user_id: Optional[str] = None

View File

@ -2962,6 +2962,100 @@ async def can_user_call_model(
)
def _can_object_call_search_tool(
search_tool_name: str,
allowed_search_tools: List[str],
object_type: Literal["key", "team", "project"],
) -> Literal[True]:
"""
Check if an object (key/team/project) can access a specific search tool.
Similar to _can_object_call_model but for search tools.
Args:
search_tool_name: The search tool being requested
allowed_search_tools: List of allowed search tool names for this object
object_type: Type of object for error messaging
Returns:
True if access is allowed
Raises:
ProxyException if access is denied
"""
# Empty list means all search tools are allowed
if not allowed_search_tools:
return True
# Check if the search tool is in the allowlist
if search_tool_name in allowed_search_tools:
return True
# Access denied
raise ProxyException(
message=f"{object_type.capitalize()} not allowed to access search tool: {search_tool_name}. "
f"Allowed search tools: {allowed_search_tools}",
type=ProxyErrorTypes.key_model_access_denied,
param="search_tool_name",
code=status.HTTP_403_FORBIDDEN,
)
async def can_key_call_search_tool(
search_tool_name: str,
valid_token: UserAPIKeyAuth,
) -> Literal[True]:
"""
Check if a key can access a specific search tool.
Similar to can_key_call_model but for search tools.
Args:
search_tool_name: The search tool being requested
valid_token: The authenticated key
Returns:
True if access is allowed
Raises:
ProxyException if access is denied
"""
return _can_object_call_search_tool(
search_tool_name=search_tool_name,
allowed_search_tools=valid_token.allowed_search_tools or [],
object_type="key",
)
async def can_team_call_search_tool(
search_tool_name: str,
team_object: Optional[LiteLLM_TeamTable],
) -> Literal[True]:
"""
Check if a team can access a specific search tool.
Similar to can_team_access_model but for search tools.
Args:
search_tool_name: The search tool being requested
team_object: The team object
Returns:
True if access is allowed
Raises:
ProxyException if access is denied
"""
if team_object is None:
return True
return _can_object_call_search_tool(
search_tool_name=search_tool_name,
allowed_search_tools=team_object.allowed_search_tools or [],
object_type="team",
)
async def is_valid_fallback_model(
model: str,
llm_router: Optional[Router],

View File

@ -59,7 +59,6 @@ from litellm.proxy._types import (
TeamMemberUpdateResponse,
TeamModelAddRequest,
TeamModelDeleteRequest,
TeamSearchProviderConfigUpdateRequest,
UpdateTeamRequest,
UserAPIKeyAuth,
)
@ -1857,108 +1856,6 @@ async def update_team( # noqa: PLR0915
raise handle_exception_on_proxy(e)
@router.post(
"/team/search_provider_config/update",
tags=["team management"],
dependencies=[Depends(user_api_key_auth)],
)
@management_endpoint_wrapper
async def update_team_search_provider_config(
data: TeamSearchProviderConfigUpdateRequest,
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
):
"""
Update per-team search provider credentials in team metadata.
Stored under:
metadata.search_provider_config.<provider>.{api_key, api_base}
"""
from litellm.proxy.auth.auth_checks import _cache_team_object
from litellm.proxy.proxy_server import (
prisma_client,
proxy_logging_obj,
user_api_key_cache,
)
if prisma_client is None:
raise HTTPException(
status_code=500,
detail={"error": CommonProxyErrors.db_not_connected_error.value},
)
provider = data.provider.strip().lower()
if provider == "":
raise HTTPException(
status_code=400, detail={"error": "provider cannot be empty"}
)
existing_team_row = await prisma_client.db.litellm_teamtable.find_unique(
where={"team_id": data.team_id}
)
if existing_team_row is None:
raise HTTPException(
status_code=404,
detail={"error": f"Team not found, passed team_id={data.team_id}"},
)
await _verify_team_access(
team_obj=LiteLLM_TeamTable(**existing_team_row.model_dump()),
user_api_key_dict=user_api_key_dict,
)
metadata: Dict[str, Any] = {}
if isinstance(existing_team_row.metadata, dict):
metadata = dict(existing_team_row.metadata)
search_provider_config = metadata.get("search_provider_config")
if not isinstance(search_provider_config, dict):
search_provider_config = {}
provider_config = search_provider_config.get(provider)
if not isinstance(provider_config, dict):
provider_config = {}
if data.api_key is not None:
provider_config["api_key"] = data.api_key
if data.api_base is not None:
provider_config["api_base"] = data.api_base
if provider_config.get("api_key") in (None, "") and provider_config.get(
"api_base"
) in (
None,
"",
):
search_provider_config.pop(provider, None)
else:
search_provider_config[provider] = provider_config
metadata["search_provider_config"] = search_provider_config
team_row: Optional[LiteLLM_TeamTable] = (
await prisma_client.db.litellm_teamtable.update(
where={"team_id": data.team_id},
data={"metadata": metadata},
include={"litellm_model_table": True}, # type: ignore
)
)
if team_row is not None and team_row.team_id is not None:
await _cache_team_object(
team_id=team_row.team_id,
team_table=LiteLLM_TeamTableCachedObj(**team_row.model_dump()),
user_api_key_cache=user_api_key_cache,
proxy_logging_obj=proxy_logging_obj,
)
return {
"message": "Team search provider configuration updated",
"team_id": data.team_id,
"provider": provider,
"search_provider_config": search_provider_config,
}
def _set_budget_reset_at(data: UpdateTeamRequest, updated_kv: dict) -> None:
"""Set budget_reset_at in updated_kv if budget_duration is provided."""
if data.budget_duration is not None:

View File

@ -127,6 +127,7 @@ model LiteLLM_TeamTable {
soft_budget Float?
spend Float @default(0.0)
models String[]
allowed_search_tools String[] @default([]) // search_tool_name values team can access
max_parallel_requests Int?
tpm_limit BigInt?
rpm_limit BigInt?
@ -369,6 +370,7 @@ model LiteLLM_VerificationToken {
spend Float @default(0.0)
expires DateTime?
models String[]
allowed_search_tools String[] @default([]) // search_tool_name values key can access
aliases Json @default("{}")
config Json @default("{}")
router_settings Json? @default("{}")

View File

@ -134,10 +134,41 @@ async def search(
if "search_tool_name" in data and data["search_tool_name"]:
data["model"] = data["search_tool_name"]
search_tool_name_value = data["search_tool_name"]
# Authorization check: verify key can access this search tool
from litellm.proxy.auth.auth_checks import (
can_key_call_search_tool,
can_team_call_search_tool,
get_team_object,
)
try:
# Check key-level access
await can_key_call_search_tool(
search_tool_name=search_tool_name_value,
valid_token=user_api_key_dict,
)
# Check team-level access if key is associated with a team
if user_api_key_dict.team_id:
team_object = await get_team_object(
team_id=user_api_key_dict.team_id,
user_api_key_cache=None, # Will use internal cache
parent_otel_span=None,
proxy_logging_obj=None,
)
await can_team_call_search_tool(
search_tool_name=search_tool_name_value,
team_object=team_object,
)
except Exception as e:
verbose_proxy_logger.error(
f"Search tool authorization failed for {search_tool_name_value}: {str(e)}"
)
raise
if llm_router is not None and hasattr(llm_router, "search_tools"):
search_tool_name_value = data["search_tool_name"]
verbose_proxy_logger.debug(
f"Search endpoint - Looking for search_tool_name: {search_tool_name_value}. "
f"Available search tools in router: {[tool.get('search_tool_name') for tool in llm_router.search_tools]}. "

View File

@ -56,58 +56,19 @@ class SearchAPIRouter:
team_config: Optional[Dict[str, Any]] = None,
) -> Tuple[Optional[str], Optional[str]]:
"""
Resolve search provider credentials with precedence:
1. request metadata.search_provider_config.{provider}
2. team metadata.search_provider_config.{provider}
3. default_team_settings.search_provider_config.{provider}
4. search_tool.litellm_params
5. env fallback in provider validate_environment()
Resolve search provider credentials from tool configuration ONLY.
Credentials are stored only in search_tool.litellm_params, never in team/key metadata.
This ensures secrets are not exposed in team/key API responses.
Args:
tool_litellm_params: Search tool litellm_params with credentials
Returns:
Tuple of (api_key, api_base) from tool configuration
"""
resolved_api_key: Optional[str] = None
resolved_api_base: Optional[str] = None
request_provider_config = {}
if isinstance(request_metadata, dict):
search_provider_config = request_metadata.get("search_provider_config")
if isinstance(search_provider_config, dict):
request_provider_config = search_provider_config.get(
search_provider, {}
)
team_provider_config = {}
if isinstance(team_metadata, dict):
search_provider_config = team_metadata.get("search_provider_config")
if isinstance(search_provider_config, dict):
team_provider_config = search_provider_config.get(search_provider, {})
team_settings_provider_config = {}
if isinstance(team_config, dict):
search_provider_config = team_config.get("search_provider_config")
if isinstance(search_provider_config, dict):
team_settings_provider_config = search_provider_config.get(
search_provider, {}
)
if isinstance(request_provider_config, dict):
resolved_api_key = request_provider_config.get("api_key")
resolved_api_base = request_provider_config.get("api_base")
if resolved_api_key is None and isinstance(team_provider_config, dict):
resolved_api_key = team_provider_config.get("api_key")
if resolved_api_base is None and isinstance(team_provider_config, dict):
resolved_api_base = team_provider_config.get("api_base")
if resolved_api_key is None and isinstance(team_settings_provider_config, dict):
resolved_api_key = team_settings_provider_config.get("api_key")
if resolved_api_base is None and isinstance(
team_settings_provider_config, dict
):
resolved_api_base = team_settings_provider_config.get("api_base")
if resolved_api_key is None:
resolved_api_key = tool_litellm_params.get("api_key")
if resolved_api_base is None:
resolved_api_base = tool_litellm_params.get("api_base")
resolved_api_key: Optional[str] = tool_litellm_params.get("api_key")
resolved_api_base: Optional[str] = tool_litellm_params.get("api_base")
return resolved_api_key, resolved_api_base

659
proxy_server.log Normal file
View File

@ -0,0 +1,659 @@
<frozen runpy>:128: RuntimeWarning: 'litellm.proxy.proxy_cli' found in sys.modules after import of package 'litellm.proxy', but prior to execution of 'litellm.proxy.proxy_cli'; this may result in unpredictable behaviour
2026-04-28 18:52:10,288 - litellm_proxy_extras - INFO - Running prisma migrate deploy
2026-04-28 18:52:13,736 - litellm_proxy_extras - INFO - prisma migrate deploy stdout: Environment variables loaded from ../../.env
Prisma schema loaded from schema.prisma
Datasource "client": PostgreSQL database "litellm", schema "public" at "localhost:5432"
118 migrations found in prisma/migrations
No pending migrations to apply.
2026-04-28 18:52:13,737 - litellm_proxy_extras - INFO - prisma migrate deploy completed
2026-04-28 18:52:13,737 - litellm_proxy_extras - INFO - No pending migrations — skipping post-migration sanity check
INFO: Started server process [19856]
INFO: Waiting for application startup.
18:52:13 - LiteLLM Proxy:DEBUG: proxy_server.py:803 - litellm.proxy.proxy_server.py::startup() - CHECKING PREMIUM USER - True
18:52:13 - LiteLLM Proxy:DEBUG: proxy_server.py:816 - worker_config: {"model": null, "alias": null, "api_base": null, "api_version": "2025-02-01-preview", "debug": false, "detailed_debug": true, "temperature": null, "max_tokens": null, "request_timeout": null, "max_budget": null, "telemetry": true, "drop_params": false, "add_function_to_prompt": false, "headers": null, "save": false, "config": "proxy_server_config.yaml", "use_queue": false}
LiteLLM Proxy: Using default (v1) migration resolver. If your deployment has seen schema thrashing during rolling deploys, try --use_v2_migration_resolver (safer: avoids the diff-and-force recovery that caused the thrash).
██╗ ██╗████████╗███████╗██╗ ██╗ ███╗ ███╗
██║ ██║╚══██╔══╝██╔════╝██║ ██║ ████╗ ████║
██║ ██║ ██║ █████╗ ██║ ██║ ██╔████╔██║
██║ ██║ ██║ ██╔══╝ ██║ ██║ ██║╚██╔╝██║
███████╗██║ ██║ ███████╗███████╗███████╗██║ ╚═╝ ██║
╚══════╝╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝
18:52:13 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': '170fb9c8e18f87663825b69e7e54393b7a3392d1ecbfb0d6a8a543f0723173fd', 'combined_model_name': '170fb9c8e18f87663825b69e7e54393b7a3392d1ecbfb0d6a8a543f0723173fd', 'stripped_model_name': '170fb9c8e18f87663825b69e7e54393b7a3392d1ecbfb0d6a8a543f0723173fd', 'combined_stripped_model_name': '170fb9c8e18f87663825b69e7e54393b7a3392d1ecbfb0d6a8a543f0723173fd', 'custom_llm_provider': None}
18:52:13 - LiteLLM:DEBUG: utils.py:5921 - Error getting model info: This model isn't mapped yet. Add it here - https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json
18:52:13 - LiteLLM:DEBUG: utils.py:2900 - added/updated model=170fb9c8e18f87663825b69e7e54393b7a3392d1ecbfb0d6a8a543f0723173fd in litellm.model_cost: 170fb9c8e18f87663825b69e7e54393b7a3392d1ecbfb0d6a8a543f0723173fd
18:52:13 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': 'gpt-5.3-codex', 'combined_model_name': 'openai/gpt-5.3-codex', 'stripped_model_name': 'gpt-5.3-codex', 'combined_stripped_model_name': 'openai/gpt-5.3-codex', 'custom_llm_provider': 'openai'}
18:52:13 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': 'gpt-5.3-codex', 'combined_model_name': 'openai/gpt-5.3-codex', 'stripped_model_name': 'gpt-5.3-codex', 'combined_stripped_model_name': 'openai/gpt-5.3-codex', 'custom_llm_provider': 'openai'}
18:52:13 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': 'gpt-5.3-codex', 'combined_model_name': 'openai/gpt-5.3-codex', 'stripped_model_name': 'openai/gpt-5.3-codex', 'combined_stripped_model_name': 'openai/gpt-5.3-codex', 'custom_llm_provider': 'openai'}
18:52:13 - LiteLLM:DEBUG: utils.py:2900 - added/updated model=gpt-5.3-codex in litellm.model_cost: gpt-5.3-codex
18:52:13 - LiteLLM Router:DEBUG: router.py:7223 -
Initialized Model List ['gpt-5.3-codex']
18:52:13 - LiteLLM Router:INFO: router.py:812 - Routing strategy: simple-shuffle
18:52:13 - LiteLLM Proxy:DEBUG: proxy_server.py:3915 - Policy engine: no policies in config, skipping
18:52:13 - LiteLLM Proxy:DEBUG: utils.py:2460 - Creating Prisma Client..
18:52:13 - LiteLLM Proxy:DEBUG: utils.py:2527 - Success - Created Prisma Client
18:52:13 - LiteLLM Proxy:DEBUG: utils.py:3745 - PrismaClient: connect() called Attempting to Connect to DB
18:52:13 - LiteLLM Proxy:DEBUG: utils.py:3749 - PrismaClient: DB not connected, Attempting to Connect to DB
query-engine ac9d7041ed77bcc8a8dbd2ab6616b39013829574
18:52:13 - LiteLLM Proxy:DEBUG: prisma_client.py:247 - IAM token auth not enabled, skipping token refresh task
18:52:13 - LiteLLM Proxy:INFO: utils.py:4307 - Started Prisma DB health watchdog (interval=30s, reconnect_cooldown=15s, probe_timeout=5.0s, reconnect_timeout=30.0s)
18:52:13 - LiteLLM Proxy:INFO: utils.py:4062 - Found prisma-query-engine at PID 20355.
18:52:13 - LiteLLM Proxy:INFO: utils.py:4066 - Watching engine PID 20355 via waitpid thread.
18:52:13 - LiteLLM:DEBUG: logging_callback_manager.py:336 - Custom logger of type SkillsInjectionHook, key: SkillsInjectionHook-max_iterations=10-sandbox_timeout=120-message_logging=True-turn_off_message_logging=False already exists in [<litellm.proxy.hooks.litellm_skills.main.SkillsInjectionHook object at 0x114eb7620>, <litellm.proxy.hooks.model_max_budget_limiter._PROXY_VirtualKeyModelMaxBudgetLimiter object at 0x1561309e0>, <litellm.proxy.hooks.proxy_track_cost_callback._ProxyDBLogger object at 0x16f90b9e0>, <litellm.proxy.hooks.max_budget_limiter._PROXY_MaxBudgetLimiter object at 0x16f90ba40>, <litellm.proxy.hooks.parallel_request_limiter_v3._PROXY_MaxParallelRequestsHandler_v3 object at 0x16f909040>, <litellm.proxy.hooks.cache_control_check._PROXY_CacheControlCheck object at 0x16f90bd10>, <litellm.proxy.hooks.responses_id_security.ResponsesIDSecurity object at 0x16f77fc50>], not adding again..
18:52:13 - LiteLLM Proxy:DEBUG: proxy_server.py:895 - About to initialize semantic tool filter
18:52:13 - LiteLLM Proxy:DEBUG: proxy_server.py:898 - litellm_settings keys = []
18:52:13 - LiteLLM Proxy:DEBUG: proxy_server.py:6220 - Semantic tool filter not configured or not enabled, skipping initialization
18:52:13 - LiteLLM Proxy:DEBUG: proxy_server.py:905 - After semantic tool filter initialization
18:52:13 - LiteLLM Proxy:DEBUG: proxy_server.py:919 - prisma_client: <litellm.proxy.utils.PrismaClient object at 0x16f787950>
18:52:13 - LiteLLM Proxy:INFO: proxy_server.py:6467 - Tag spend update job scheduled at 25s interval (2.3x main job interval)
18:52:13 - LiteLLM Proxy:DEBUG: hanging_request_check.py:148 - Checking for hanging requests....
18:52:13 - LiteLLM Proxy:INFO: utils.py:5083 - Starting spend logs queue monitor (threshold: 100, poll_interval: 2.0s)
18:52:14 - LiteLLM Proxy:INFO: utils.py:2634 - All necessary views exist!
18:52:14 - LiteLLM Proxy:INFO: proxy_server.py:874 - Password migration: No plaintext passwords found
18:52:14 - LiteLLM Proxy:DEBUG: proxy_server.py:4256 - len new_models: 2
18:52:14 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': '88d4dde8-817a-4c20-9bec-442961096d25', 'combined_model_name': '88d4dde8-817a-4c20-9bec-442961096d25', 'stripped_model_name': '88d4dde8-817a-4c20-9bec-442961096d25', 'combined_stripped_model_name': '88d4dde8-817a-4c20-9bec-442961096d25', 'custom_llm_provider': None}
18:52:14 - LiteLLM:DEBUG: utils.py:5921 - Error getting model info: This model isn't mapped yet. Add it here - https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json
18:52:14 - LiteLLM:DEBUG: utils.py:2900 - added/updated model=88d4dde8-817a-4c20-9bec-442961096d25 in litellm.model_cost: 88d4dde8-817a-4c20-9bec-442961096d25
18:52:14 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': '2ab3179b-62e9-4720-9ba7-0a2f12536cfa', 'combined_model_name': '2ab3179b-62e9-4720-9ba7-0a2f12536cfa', 'stripped_model_name': '2ab3179b-62e9-4720-9ba7-0a2f12536cfa', 'combined_stripped_model_name': '2ab3179b-62e9-4720-9ba7-0a2f12536cfa', 'custom_llm_provider': None}
18:52:14 - LiteLLM:DEBUG: utils.py:5921 - Error getting model info: This model isn't mapped yet. Add it here - https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json
18:52:14 - LiteLLM:DEBUG: utils.py:2900 - added/updated model=2ab3179b-62e9-4720-9ba7-0a2f12536cfa in litellm.model_cost: 2ab3179b-62e9-4720-9ba7-0a2f12536cfa
18:52:14 - LiteLLM Proxy:DEBUG: proxy_server.py:5461 - guardrails from the DB []
18:52:14 - LiteLLM Proxy:INFO: policy_registry.py:577 - Synced 0 production policies and 0 draft/published (by ID) from DB to in-memory registry
18:52:14 - LiteLLM Proxy:INFO: attachment_registry.py:481 - Synced 0 attachments from DB to in-memory registry
18:52:14 - LiteLLM Proxy:DEBUG: proxy_server.py:5497 - Successfully synced policies and attachments from DB
18:52:14 - LiteLLM:DEBUG: mcp_server_manager.py:2644 - Loading MCP servers from database into registry...
18:52:14 - LiteLLM:INFO: mcp_server_manager.py:2664 - Found 1 MCP servers in database
18:52:14 - LiteLLM:DEBUG: mcp_server_manager.py:2688 - Building server from DB: 28a195c6-0224-4765-af9b-46f7a7f65ccb (deepwiki)
18:52:14 - LiteLLM:DEBUG: mcp_server_manager.py:2697 - MCP registry refreshed (1 servers in registry)
18:52:14 - LiteLLM Proxy:DEBUG: pass_through_endpoints.py:2409 - initializing pass through endpoints
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.weave
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.litellm_agent
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.dotprompt
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:65 - Found prompt_initializer_registry in litellm.integrations.dotprompt: ['dotprompt']
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.gitlab
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:65 - Found prompt_initializer_registry in litellm.integrations.gitlab: ['gitlab']
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.azure_sentinel
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.arize
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:65 - Found prompt_initializer_registry in litellm.integrations.arize: ['arize_phoenix']
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.agentops
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.compression_interception
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.focus
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.prometheus_helpers
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.generic_prompt_management
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:65 - Found prompt_initializer_registry in litellm.integrations.generic_prompt_management: ['generic_prompt_management']
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.levo
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.websearch_interception
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.deepeval
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.bitbucket
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:65 - Found prompt_initializer_registry in litellm.integrations.bitbucket: ['bitbucket']
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:54 - Discovering prompt integrations in: litellm.integrations.vantage
18:52:14 - LiteLLM Proxy:DEBUG: prompt_registry.py:76 - Discovered 5 prompt initializers: ['dotprompt', 'gitlab', 'arize_phoenix', 'generic_prompt_management', 'bitbucket']
18:52:14 - LiteLLM Proxy:INFO: proxy_server.py:5640 - Loading 0 search tool(s) from database into router
18:52:14 - LiteLLM Proxy:DEBUG: proxy_server.py:5660 - No search tools found in database, keeping config-loaded search tools (if any)
18:52:14 - LiteLLM Proxy:INFO: tool_registry_writer.py:329 - ToolPolicyRegistry: synced 17 tool policies and 1 object permissions from DB
18:52:14 - LiteLLM Proxy:DEBUG: proxy_server.py:5517 - Successfully synced tool policy from DB
18:52:14 - LiteLLM:DEBUG: focus_logger.py:167 - No Focus export logger registered; skipping scheduler
18:52:14 - LiteLLM Proxy:DEBUG: proxy_server.py:6759 - key_rotation_enabled: False
18:52:14 - LiteLLM Proxy:DEBUG: proxy_server.py:6793 - Key rotation disabled (set LITELLM_KEY_ROTATION_ENABLED=true to enable)
18:52:14 - LiteLLM Proxy:DEBUG: proxy_server.py:6824 - expired_ui_session_key_cleanup_enabled: False
18:52:14 - LiteLLM Proxy:DEBUG: proxy_server.py:6869 - Expired UI session key cleanup disabled (set LITELLM_EXPIRED_UI_SESSION_KEY_CLEANUP_ENABLED=true to enable)
18:52:14 - LiteLLM Proxy:INFO: proxy_server.py:6622 - Batch cost check job scheduled successfully
18:52:14 - LiteLLM Proxy:INFO: proxy_server.py:6653 - Responses cost check job scheduled successfully
18:52:14 - LiteLLM Proxy:INFO: proxy_server.py:6672 - APScheduler started with memory leak prevention settings: removed jitter, increased intervals, misfire_grace_time=3600
18:52:14 - LiteLLM Proxy:DEBUG: proxy_server.py:7036 - LiteLLM: Pyroscope profiling is disabled (set LITELLM_ENABLE_PYROSCOPE=true to enable).
18:52:14 - LiteLLM Proxy:INFO: proxy_server.py:755 - SESSION REUSE: Created shared aiohttp session for connection pooling (ID: 6165409104, limit=1000, limit_per_host=500)
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:4000 (Press CTRL+C to quit)
18:52:21 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/organization/list
18:52:21 - LiteLLM:DEBUG: user_api_key_auth.py:1023 - api key not found in cache.
18:52:21 - LiteLLM Proxy:DEBUG: utils.py:3061 - PrismaClient: find_unique for token: 00f60cfa9df317dade7cb93c0bdb83b44250c865daf6920ea0de433d523a894e
18:52:21 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/team/list
18:52:21 - LiteLLM:DEBUG: user_api_key_auth.py:1023 - api key not found in cache.
18:52:21 - LiteLLM Proxy:DEBUG: utils.py:3061 - PrismaClient: find_unique for token: 00f60cfa9df317dade7cb93c0bdb83b44250c865daf6920ea0de433d523a894e
18:52:21 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/tag/list
18:52:21 - LiteLLM:DEBUG: user_api_key_auth.py:1023 - api key not found in cache.
18:52:21 - LiteLLM Proxy:DEBUG: utils.py:3061 - PrismaClient: find_unique for token: 00f60cfa9df317dade7cb93c0bdb83b44250c865daf6920ea0de433d523a894e
18:52:21 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/key/list
18:52:21 - LiteLLM:DEBUG: user_api_key_auth.py:1023 - api key not found in cache.
18:52:21 - LiteLLM Proxy:DEBUG: utils.py:3061 - PrismaClient: find_unique for token: 00f60cfa9df317dade7cb93c0bdb83b44250c865daf6920ea0de433d523a894e
#------------------------------------------------------------#
# #
# 'The thing I wish you improved is...' #
# https://github.com/BerriAI/litellm/issues/new #
# #
#------------------------------------------------------------#
Thank you for using LiteLLM! - Krrish & Ishaan
Give Feedback / Get Help: https://github.com/BerriAI/litellm/issues/new
LiteLLM: Proxy initialized with Config, Set models:
 gpt-5.3-codex
INFO: 127.0.0.1:65291 - "GET /project/list HTTP/1.1" 404 Not Found
INFO: 127.0.0.1:65293 - "HEAD / HTTP/1.1" 200 OK
INFO: 127.0.0.1:65293 - "GET /__next._tree.txt?_rsc=1r34m HTTP/1.1" 404 Not Found
18:52:21 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:21.984645+00:00
18:52:21 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:21.987707+00:00
18:52:21 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:21.988286+00:00
18:52:21 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:21.988897+00:00
18:52:21 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:22 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:22 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:22 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:22 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:22 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:22 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:22 - LiteLLM Proxy:DEBUG: key_management_endpoints.py:4526 - Entering list_keys function
18:52:22 - LiteLLM Proxy:DEBUG: key_management_endpoints.py:4950 - Filter conditions: {'OR': [{'team_id': None}, {'team_id': {'not': 'litellm-dashboard'}}]}
18:52:22 - LiteLLM Proxy:DEBUG: key_management_endpoints.py:5020 - Pagination: skip=0, take=50
18:52:22 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
INFO: 127.0.0.1:65283 - "GET /organization/list HTTP/1.1" 200 OK
18:52:22 - LiteLLM Proxy:DEBUG: key_management_endpoints.py:5062 - Fetched 4 keys
18:52:22 - LiteLLM Proxy:DEBUG: key_management_endpoints.py:5074 - Total count of keys: 4
INFO: 127.0.0.1:65285 - "GET /team/list HTTP/1.1" 200 OK
18:52:22 - LiteLLM Proxy:DEBUG: key_management_endpoints.py:4604 - Successfully prepared response
INFO: 127.0.0.1:65290 - "GET /key/list?page=1&size=50&sort_by=created_at&sort_order=desc&expand=user&return_full_object=true&include_team_keys=true&include_created_by_keys=true HTTP/1.1" 200 OK
INFO: 127.0.0.1:65288 - "GET /tag/list HTTP/1.1" 200 OK
INFO: 127.0.0.1:65290 - "GET /project/list HTTP/1.1" 404 Not Found
18:52:24 - LiteLLM Proxy:DEBUG: spend_update_queue.py:39 - Aggregating updates by entity type: []
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1122 - User Spend transactions: {}
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1165 - End-User Spend transactions: {}
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1180 - KEY Spend transactions: {}
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1221 - Team Spend transactions: {}
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1269 - Team Membership Spend transactions: {}
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1342 - Org Spend transactions: {}
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Tag Spend transactions: {}
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Agent Spend transactions: {}
18:52:24 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily User Spend transactions: 0
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily user spend update
18:52:24 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Team Spend transactions: 0
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily team spend update
18:52:24 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Org Spend transactions: 0
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily org spend update
18:52:24 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily End_user Spend transactions: 0
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily end_user spend update
18:52:24 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Agent Spend transactions: 0
18:52:24 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily agent spend update
18:52:24 - LiteLLM Proxy:DEBUG: utils.py:4936 - Spend Logs transactions: 0
INFO: 127.0.0.1:65290 - "GET /project/list HTTP/1.1" 404 Not Found
18:52:28 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/organization/list
18:52:28 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:28.414705+00:00
18:52:28 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/team/list
18:52:28 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:28.416982+00:00
18:52:28 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/models
18:52:28 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:28.426995+00:00
18:52:28 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/v2/user/info
18:52:28 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:28.430882+00:00
18:52:28 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/v1/access_group
18:52:28 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:28.434375+00:00
18:52:28 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/v1/mcp/server
18:52:28 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:28.437819+00:00
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:28 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:28 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:28 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
INFO: 127.0.0.1:65326 - "GET /v2/user/info HTTP/1.1" 200 OK
18:52:28 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:28 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/v1/mcp/access_groups
18:52:28 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:28.460826+00:00
18:52:28 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
INFO: 127.0.0.1:65324 - "GET /models?include_model_access_groups=True&return_wildcard_routes=True&scope=expand HTTP/1.1" 200 OK
18:52:28 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/v1/mcp/toolset
18:52:28 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:28.463333+00:00
INFO: 127.0.0.1:65290 - "GET /organization/list HTTP/1.1" 200 OK
INFO: 127.0.0.1:65328 - "GET /v1/access_group HTTP/1.1" 200 OK
18:52:28 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:28 - LiteLLM:DEBUG: mcp_server_manager.py:796 - Admin user without explicit object_permission - returning all servers
INFO: 127.0.0.1:65329 - "GET /v1/mcp/server HTTP/1.1" 200 OK
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:28 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
INFO: 127.0.0.1:65321 - "GET /team/list HTTP/1.1" 200 OK
18:52:28 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:28 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:28 - LiteLLM Proxy:WARNING: toolset_db.py:60 - litellm.proxy._experimental.mcp_server.toolset_db::list_mcp_toolsets - 'Prisma' object has no attribute 'litellm_mcptoolsettable'
INFO: 127.0.0.1:65324 - "GET /v1/mcp/toolset HTTP/1.1" 200 OK
INFO: 127.0.0.1:65326 - "GET /v1/mcp/access_groups HTTP/1.1" 200 OK
18:52:30 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/organization/list
18:52:30 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:30 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:30.307066+00:00
18:52:30 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/team/list
18:52:30 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:30 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:30.310005+00:00
INFO: 127.0.0.1:65321 - "GET /project/list HTTP/1.1" 404 Not Found
18:52:30 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/tag/list
18:52:30 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:30 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:30.314509+00:00
18:52:30 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:30 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:30 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:30 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:30 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:30 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
INFO: 127.0.0.1:65326 - "GET /organization/list HTTP/1.1" 200 OK
INFO: 127.0.0.1:65324 - "GET /team/list HTTP/1.1" 200 OK
INFO: 127.0.0.1:65329 - "GET /tag/list HTTP/1.1" 200 OK
INFO: 127.0.0.1:65329 - "GET /project/list HTTP/1.1" 404 Not Found
18:52:34 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/organization/list
18:52:34 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:34 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:34.018157+00:00
18:52:34 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/team/list
18:52:34 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:34 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:34.038105+00:00
18:52:34 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/tag/list
18:52:34 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:34 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:34.045120+00:00
INFO: 127.0.0.1:65321 - "GET /project/list HTTP/1.1" 404 Not Found
18:52:34 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:34 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:34 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:34 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:34 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:34 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
INFO: 127.0.0.1:65329 - "GET /organization/list HTTP/1.1" 200 OK
INFO: 127.0.0.1:65324 - "GET /team/list HTTP/1.1" 200 OK
INFO: 127.0.0.1:65326 - "GET /tag/list HTTP/1.1" 200 OK
18:52:35 - LiteLLM Proxy:DEBUG: spend_update_queue.py:39 - Aggregating updates by entity type: []
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1122 - User Spend transactions: {}
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1165 - End-User Spend transactions: {}
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1180 - KEY Spend transactions: {}
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1221 - Team Spend transactions: {}
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1269 - Team Membership Spend transactions: {}
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1342 - Org Spend transactions: {}
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Tag Spend transactions: {}
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Agent Spend transactions: {}
18:52:35 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily User Spend transactions: 0
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily user spend update
18:52:35 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Team Spend transactions: 0
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily team spend update
18:52:35 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Org Spend transactions: 0
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily org spend update
18:52:35 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily End_user Spend transactions: 0
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily end_user spend update
18:52:35 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Agent Spend transactions: 0
18:52:35 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily agent spend update
18:52:35 - LiteLLM Proxy:DEBUG: utils.py:4936 - Spend Logs transactions: 0
INFO: 127.0.0.1:65326 - "GET /project/list HTTP/1.1" 404 Not Found
18:52:39 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:44 - LiteLLM Proxy:DEBUG: proxy_server.py:4256 - len new_models: 2
18:52:44 - LiteLLM Proxy:DEBUG: proxy_server.py:5461 - guardrails from the DB []
18:52:44 - LiteLLM Proxy:INFO: policy_registry.py:577 - Synced 0 production policies and 0 draft/published (by ID) from DB to in-memory registry
18:52:44 - LiteLLM Proxy:INFO: attachment_registry.py:481 - Synced 0 attachments from DB to in-memory registry
18:52:44 - LiteLLM Proxy:DEBUG: proxy_server.py:5497 - Successfully synced policies and attachments from DB
18:52:44 - LiteLLM:DEBUG: mcp_server_manager.py:2644 - Loading MCP servers from database into registry...
18:52:44 - LiteLLM:INFO: mcp_server_manager.py:2664 - Found 1 MCP servers in database
18:52:44 - LiteLLM:DEBUG: mcp_server_manager.py:2697 - MCP registry refreshed (1 servers in registry)
18:52:44 - LiteLLM Proxy:DEBUG: pass_through_endpoints.py:2409 - initializing pass through endpoints
18:52:44 - LiteLLM Proxy:INFO: proxy_server.py:5640 - Loading 0 search tool(s) from database into router
18:52:44 - LiteLLM Proxy:DEBUG: proxy_server.py:5660 - No search tools found in database, keeping config-loaded search tools (if any)
18:52:44 - LiteLLM Proxy:INFO: tool_registry_writer.py:329 - ToolPolicyRegistry: synced 17 tool policies and 1 object permissions from DB
18:52:44 - LiteLLM Proxy:DEBUG: proxy_server.py:5517 - Successfully synced tool policy from DB
18:52:46 - LiteLLM Proxy:DEBUG: spend_update_queue.py:39 - Aggregating updates by entity type: []
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1122 - User Spend transactions: {}
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1165 - End-User Spend transactions: {}
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1180 - KEY Spend transactions: {}
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1221 - Team Spend transactions: {}
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1269 - Team Membership Spend transactions: {}
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1342 - Org Spend transactions: {}
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Tag Spend transactions: {}
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Agent Spend transactions: {}
18:52:46 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily User Spend transactions: 0
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily user spend update
18:52:46 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Team Spend transactions: 0
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily team spend update
18:52:46 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Org Spend transactions: 0
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily org spend update
18:52:46 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily End_user Spend transactions: 0
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily end_user spend update
18:52:46 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Agent Spend transactions: 0
18:52:46 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily agent spend update
18:52:46 - LiteLLM Proxy:DEBUG: utils.py:4936 - Spend Logs transactions: 0
18:52:54 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/organization/list
18:52:54 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:54 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:54.075515+00:00
18:52:54 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/team/list
18:52:54 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:54 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:54.133027+00:00
INFO: 127.0.0.1:65389 - "GET /project/list HTTP/1.1" 404 Not Found
18:52:54 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/tag/list
18:52:54 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:54 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:54.284965+00:00
18:52:54 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/key/list
18:52:54 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:52:54 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:22:54.295543+00:00
18:52:54 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:54 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:54 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:54 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:52:54 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:54 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:54 - LiteLLM Proxy:DEBUG: key_management_endpoints.py:4526 - Entering list_keys function
18:52:54 - LiteLLM Proxy:DEBUG: key_management_endpoints.py:4950 - Filter conditions: {'OR': [{'team_id': None}, {'team_id': {'not': 'litellm-dashboard'}}]}
18:52:54 - LiteLLM Proxy:DEBUG: key_management_endpoints.py:5020 - Pagination: skip=0, take=50
18:52:54 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:52:54 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
INFO: 127.0.0.1:65385 - "GET /organization/list HTTP/1.1" 200 OK
18:52:54 - LiteLLM Proxy:DEBUG: key_management_endpoints.py:5062 - Fetched 4 keys
INFO: 127.0.0.1:65392 - "GET /tag/list HTTP/1.1" 200 OK
INFO: 127.0.0.1:65387 - "GET /team/list HTTP/1.1" 200 OK
18:52:54 - LiteLLM Proxy:DEBUG: key_management_endpoints.py:5074 - Total count of keys: 4
18:52:54 - LiteLLM Proxy:DEBUG: key_management_endpoints.py:4604 - Successfully prepared response
INFO: 127.0.0.1:65393 - "GET /key/list?page=1&size=50&sort_by=created_at&sort_order=desc&expand=user&return_full_object=true&include_team_keys=true&include_created_by_keys=true HTTP/1.1" 200 OK
INFO: 127.0.0.1:65393 - "GET /project/list HTTP/1.1" 404 Not Found
18:52:58 - LiteLLM Proxy:DEBUG: spend_update_queue.py:39 - Aggregating updates by entity type: []
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1122 - User Spend transactions: {}
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1165 - End-User Spend transactions: {}
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1180 - KEY Spend transactions: {}
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1221 - Team Spend transactions: {}
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1269 - Team Membership Spend transactions: {}
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1342 - Org Spend transactions: {}
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Tag Spend transactions: {}
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Agent Spend transactions: {}
18:52:58 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily User Spend transactions: 0
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily user spend update
18:52:58 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Team Spend transactions: 0
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily team spend update
18:52:58 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Org Spend transactions: 0
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily org spend update
18:52:58 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily End_user Spend transactions: 0
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily end_user spend update
18:52:58 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Agent Spend transactions: 0
18:52:58 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily agent spend update
18:52:58 - LiteLLM Proxy:DEBUG: utils.py:4936 - Spend Logs transactions: 0
18:53:04 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:05 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/health/readiness
18:53:05 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/organization/list
18:53:05 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:05 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:05.652862+00:00
18:53:06 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/team/list
18:53:06 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:06 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:06.042541+00:00
18:53:06 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/tag/list
18:53:06 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:06 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:06.085990+00:00
INFO: 127.0.0.1:65443 - "GET /project/list HTTP/1.1" 404 Not Found
18:53:06 - LiteLLM:DEBUG: http_handler.py:840 - Using AiohttpTransport...
INFO: 127.0.0.1:65436 - "GET /health/readiness HTTP/1.1" 200 OK
18:53:06 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:06 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:06 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:06 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:53:06 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:53:06 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
INFO: 127.0.0.1:65438 - "GET /organization/list HTTP/1.1" 200 OK
INFO: 127.0.0.1:65442 - "GET /tag/list HTTP/1.1" 200 OK
INFO: 127.0.0.1:65440 - "GET /team/list HTTP/1.1" 200 OK
18:53:08 - LiteLLM Proxy:DEBUG: spend_update_queue.py:39 - Aggregating updates by entity type: []
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1122 - User Spend transactions: {}
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1165 - End-User Spend transactions: {}
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1180 - KEY Spend transactions: {}
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1221 - Team Spend transactions: {}
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1269 - Team Membership Spend transactions: {}
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1342 - Org Spend transactions: {}
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Tag Spend transactions: {}
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Agent Spend transactions: {}
18:53:09 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily User Spend transactions: 0
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily user spend update
18:53:09 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Team Spend transactions: 0
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily team spend update
18:53:09 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Org Spend transactions: 0
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily org spend update
18:53:09 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily End_user Spend transactions: 0
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily end_user spend update
18:53:09 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Agent Spend transactions: 0
18:53:09 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily agent spend update
18:53:09 - LiteLLM Proxy:DEBUG: utils.py:4936 - Spend Logs transactions: 0
18:53:09 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/v1/mcp/server
18:53:09 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:09.447694+00:00
18:53:09 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/v1/mcp/toolset
18:53:09 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:09.480143+00:00
18:53:09 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/get/mcp_semantic_filter_settings
18:53:09 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:09.511525+00:00
18:53:09 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/model_group/info
18:53:09 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:09.521031+00:00
18:53:09 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/config/list
18:53:09 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:09.525741+00:00
18:53:09 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/v1/mcp/network/client-ip
18:53:09 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:09.533092+00:00
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:09 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
INFO: 127.0.0.1:65461 - "GET /v1/mcp/network/client-ip HTTP/1.1" 200 OK
18:53:09 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:53:09 - LiteLLM Proxy:DEBUG: model_checks.py:131 - ALL KEY MODELS - 0
18:53:09 - LiteLLM Proxy:DEBUG: model_checks.py:166 - ALL TEAM MODELS - 0
18:53:09 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': 'gpt-5.3-codex', 'combined_model_name': 'openai/gpt-5.3-codex', 'stripped_model_name': 'gpt-5.3-codex', 'combined_stripped_model_name': 'openai/gpt-5.3-codex', 'custom_llm_provider': 'openai'}
18:53:09 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': 'gpt-5.3-codex', 'combined_model_name': 'openai/gpt-5.3-codex', 'stripped_model_name': 'gpt-5.3-codex', 'combined_stripped_model_name': 'openai/gpt-5.3-codex', 'custom_llm_provider': 'openai'}
18:53:09 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': 'gpt-5.3-codex', 'combined_model_name': 'openai/gpt-5.3-codex', 'stripped_model_name': 'openai/gpt-5.3-codex', 'combined_stripped_model_name': 'openai/gpt-5.3-codex', 'custom_llm_provider': 'openai'}
18:53:09 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': 'oia-gpt-realtime', 'combined_model_name': 'azure/oia-gpt-realtime', 'stripped_model_name': 'azure/oia-gpt-realtime', 'combined_stripped_model_name': 'azure/oia-gpt-realtime', 'custom_llm_provider': 'azure'}
18:53:09 - LiteLLM:DEBUG: utils.py:5921 - Error getting model info: This model isn't mapped yet. Add it here - https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json
18:53:09 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': 'oia-gpt-realtime', 'combined_model_name': 'azure/oia-gpt-realtime', 'stripped_model_name': 'azure/oia-gpt-realtime', 'combined_stripped_model_name': 'azure/oia-gpt-realtime', 'custom_llm_provider': 'azure'}
18:53:09 - LiteLLM:DEBUG: utils.py:5921 - Error getting model info: This model isn't mapped yet. Add it here - https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json
18:53:09 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': 'gemini-3.1-flash-image-preview', 'combined_model_name': 'vertex_ai/gemini-3.1-flash-image-preview', 'stripped_model_name': 'gemini-3.1-flash-image-preview', 'combined_stripped_model_name': 'vertex_ai/gemini-3.1-flash-image-preview', 'custom_llm_provider': 'vertex_ai'}
18:53:09 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': 'gemini-3.1-flash-image-preview', 'combined_model_name': 'gemini-3.1-flash-image-preview', 'stripped_model_name': 'gemini-3.1-flash-image-preview', 'combined_stripped_model_name': 'gemini-3.1-flash-image-preview', 'custom_llm_provider': 'vertex_ai'}
18:53:09 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/v1/mcp/server/submissions
18:53:09 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:09.669506+00:00
18:53:09 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:53:09 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:53:09 - LiteLLM:DEBUG: mcp_server_manager.py:796 - Admin user without explicit object_permission - returning all servers
INFO: 127.0.0.1:65440 - "GET /v1/mcp/server HTTP/1.1" 200 OK
18:53:09 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:53:09 - LiteLLM Proxy:WARNING: toolset_db.py:60 - litellm.proxy._experimental.mcp_server.toolset_db::list_mcp_toolsets - 'Prisma' object has no attribute 'litellm_mcptoolsettable'
INFO: 127.0.0.1:65442 - "GET /v1/mcp/toolset HTTP/1.1" 200 OK
18:53:09 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:53:09 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/v1/mcp/server/health
18:53:09 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:09.692446+00:00
INFO: 127.0.0.1:65442 - "HEAD / HTTP/1.1" 200 OK
INFO: 127.0.0.1:65436 - "GET /model_group/info HTTP/1.1" 200 OK
INFO: 127.0.0.1:65443 - "GET /config/list?config_type=general_settings HTTP/1.1" 200 OK
18:53:09 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/config/list
18:53:09 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:09.731878+00:00
INFO: 127.0.0.1:65436 - "GET /ui/assets/logos/github.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65443 - "GET /ui/assets/logos/slack.svg HTTP/1.1" 304 Not Modified
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
INFO: 127.0.0.1:65436 - "GET /ui/assets/logos/notion.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65443 - "GET /ui/assets/logos/linear.svg HTTP/1.1" 304 Not Modified
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
INFO: 127.0.0.1:65436 - "GET /ui/assets/logos/jira.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65438 - "GET /get/mcp_semantic_filter_settings HTTP/1.1" 200 OK
INFO: 127.0.0.1:65443 - "GET /ui/assets/logos/figma.svg HTTP/1.1" 304 Not Modified
18:53:09 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:53:09 - LiteLLM:DEBUG: mcp_server_manager.py:796 - Admin user without explicit object_permission - returning all servers
18:53:09 - LiteLLM:DEBUG: client.py:273 - litellm headers for streamable_http_client: {}
18:53:09 - LiteLLM:DEBUG: client.py:402 - MCP client using SSL configuration: SSLContext
18:53:09 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
INFO: 127.0.0.1:65436 - "GET /ui/assets/logos/gmail.svg HTTP/1.1" 304 Not Modified
18:53:09 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/model_group/info
18:53:09 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:09 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:09.989425+00:00
INFO: 127.0.0.1:65443 - "GET /ui/assets/logos/stripe.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65438 - "GET /ui/assets/logos/google_drive.svg HTTP/1.1" 304 Not Modified
18:53:09 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
INFO: 127.0.0.1:65443 - "GET /ui/assets/logos/shopify.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65438 - "GET /ui/assets/logos/salesforce.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65442 - "GET /config/list?config_type=general_settings HTTP/1.1" 200 OK
INFO: 127.0.0.1:65438 - "GET /ui/assets/logos/hubspot.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65443 - "GET /ui/assets/logos/twilio.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65461 - "GET /v1/mcp/server/submissions HTTP/1.1" 200 OK
INFO: 127.0.0.1:65442 - "GET /ui/assets/logos/cloudflare.svg HTTP/1.1" 304 Not Modified
18:53:10 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
INFO: 127.0.0.1:65438 - "GET /ui/assets/logos/postgresql.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65443 - "GET /ui/assets/logos/sentry.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65461 - "GET /ui/assets/logos/snowflake.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65442 - "GET /ui/assets/logos/zapier.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65461 - "GET /__next._tree.txt?_rsc=1r34m HTTP/1.1" 404 Not Found
18:53:10 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:53:10 - LiteLLM Proxy:DEBUG: model_checks.py:131 - ALL KEY MODELS - 0
18:53:10 - LiteLLM Proxy:DEBUG: model_checks.py:166 - ALL TEAM MODELS - 0
18:53:10 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': 'oia-gpt-realtime', 'combined_model_name': 'azure/oia-gpt-realtime', 'stripped_model_name': 'azure/oia-gpt-realtime', 'combined_stripped_model_name': 'azure/oia-gpt-realtime', 'custom_llm_provider': 'azure'}
18:53:10 - LiteLLM:DEBUG: utils.py:5921 - Error getting model info: This model isn't mapped yet. Add it here - https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json
18:53:10 - LiteLLM:DEBUG: utils.py:5620 - checking potential_model_names in litellm.model_cost: {'split_model': 'oia-gpt-realtime', 'combined_model_name': 'azure/oia-gpt-realtime', 'stripped_model_name': 'azure/oia-gpt-realtime', 'combined_stripped_model_name': 'azure/oia-gpt-realtime', 'custom_llm_provider': 'azure'}
18:53:10 - LiteLLM:DEBUG: utils.py:5921 - Error getting model info: This model isn't mapped yet. Add it here - https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json
INFO: 127.0.0.1:65443 - "GET /ui/assets/logos/gitlab.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65438 - "GET /ui/assets/logos/google.svg HTTP/1.1" 304 Not Modified
INFO: 127.0.0.1:65436 - "GET /model_group/info HTTP/1.1" 200 OK
INFO: 127.0.0.1:65440 - "GET /v1/mcp/server/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:65440 - "GET / HTTP/1.1" 200 OK
18:53:17 - LiteLLM Proxy:DEBUG: custom_openapi_spec.py:311 - Successfully added ProxyChatCompletionRequest schema to OpenAPI spec
18:53:17 - LiteLLM Proxy:DEBUG: custom_openapi_spec.py:311 - Successfully added EmbeddingRequest schema to OpenAPI spec
18:53:17 - LiteLLM Proxy:DEBUG: custom_openapi_spec.py:315 - Could not get schema for ResponsesAPIRequestParams
INFO: 127.0.0.1:65440 - "GET /openapi.json HTTP/1.1" 200 OK
18:53:17 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/organization/list
18:53:17 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:17 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:17.073159+00:00
18:53:17 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/team/list
18:53:17 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:17 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:17.085893+00:00
18:53:17 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/v1/mcp/server
18:53:17 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:17 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:17.089077+00:00
18:53:17 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/v1/mcp/server/health
18:53:17 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:17 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:17.093754+00:00
18:53:17 - LiteLLM Proxy:DEBUG: http_parsing_utils.py:529 - populate_request_with_path_params: No vector_store_id present in path=/v1/mcp/toolset
18:53:17 - LiteLLM:DEBUG: user_api_key_auth.py:1099 - 404: {'error': "Team doesn't exist in cache + check_cache_only=True. Team=litellm-dashboard."}
18:53:17 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1348 - Checking if token expired, expiry time 2026-04-29 11:16:22.190000+00:00 and current time 2026-04-28 13:23:17.096736+00:00
18:53:17 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:17 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:17 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:17 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:17 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:53:17 - LiteLLM:DEBUG: mcp_server_manager.py:796 - Admin user without explicit object_permission - returning all servers
INFO: 127.0.0.1:65438 - "GET /v1/mcp/server HTTP/1.1" 200 OK
18:53:17 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:53:17 - LiteLLM Proxy:DEBUG: user_api_key_auth.py:1567 - centralized auth: team fetch failed (HTTPException: 404: {'error': "Team doesn't exist in db. Team=litellm-dashboard. Create team via `/team/new` call."})
18:53:17 - LiteLLM Proxy:DEBUG: proxy_server.py:4256 - len new_models: 2
18:53:17 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:53:17 - LiteLLM:DEBUG: mcp_server_manager.py:796 - Admin user without explicit object_permission - returning all servers
18:53:17 - LiteLLM:DEBUG: client.py:273 - litellm headers for streamable_http_client: {}
18:53:17 - LiteLLM:DEBUG: client.py:402 - MCP client using SSL configuration: SSLContext
18:53:17 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
18:53:17 - LiteLLM Proxy:WARNING: toolset_db.py:60 - litellm.proxy._experimental.mcp_server.toolset_db::list_mcp_toolsets - 'Prisma' object has no attribute 'litellm_mcptoolsettable'
INFO: 127.0.0.1:65442 - "GET /v1/mcp/toolset HTTP/1.1" 200 OK
18:53:17 - LiteLLM Proxy:DEBUG: auth_checks.py:4036 - Vector store registry not found, skipping vector store access check
INFO: 127.0.0.1:65436 - "GET /organization/list HTTP/1.1" 200 OK
INFO: 127.0.0.1:65443 - "GET /team/list HTTP/1.1" 200 OK
18:53:17 - LiteLLM Proxy:DEBUG: proxy_server.py:5461 - guardrails from the DB []
18:53:17 - LiteLLM Proxy:INFO: policy_registry.py:577 - Synced 0 production policies and 0 draft/published (by ID) from DB to in-memory registry
18:53:17 - LiteLLM Proxy:INFO: attachment_registry.py:481 - Synced 0 attachments from DB to in-memory registry
18:53:17 - LiteLLM Proxy:DEBUG: proxy_server.py:5497 - Successfully synced policies and attachments from DB
18:53:17 - LiteLLM:DEBUG: mcp_server_manager.py:2644 - Loading MCP servers from database into registry...
18:53:17 - LiteLLM:INFO: mcp_server_manager.py:2664 - Found 1 MCP servers in database
18:53:17 - LiteLLM:DEBUG: mcp_server_manager.py:2697 - MCP registry refreshed (1 servers in registry)
18:53:17 - LiteLLM Proxy:DEBUG: pass_through_endpoints.py:2409 - initializing pass through endpoints
18:53:17 - LiteLLM Proxy:INFO: proxy_server.py:5640 - Loading 0 search tool(s) from database into router
18:53:17 - LiteLLM Proxy:DEBUG: proxy_server.py:5660 - No search tools found in database, keeping config-loaded search tools (if any)
18:53:17 - LiteLLM Proxy:INFO: tool_registry_writer.py:329 - ToolPolicyRegistry: synced 17 tool policies and 1 object permissions from DB
18:53:17 - LiteLLM Proxy:DEBUG: proxy_server.py:5517 - Successfully synced tool policy from DB
INFO: 127.0.0.1:65461 - "GET /v1/mcp/server/health HTTP/1.1" 200 OK
18:53:19 - LiteLLM Proxy:DEBUG: spend_update_queue.py:39 - Aggregating updates by entity type: []
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1122 - User Spend transactions: {}
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1165 - End-User Spend transactions: {}
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1180 - KEY Spend transactions: {}
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1221 - Team Spend transactions: {}
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1269 - Team Membership Spend transactions: {}
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1342 - Org Spend transactions: {}
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Tag Spend transactions: {}
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Agent Spend transactions: {}
18:53:20 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily User Spend transactions: 0
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily user spend update
18:53:20 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Team Spend transactions: 0
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily team spend update
18:53:20 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Org Spend transactions: 0
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily org spend update
18:53:20 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily End_user Spend transactions: 0
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily end_user spend update
18:53:20 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Agent Spend transactions: 0
18:53:20 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily agent spend update
18:53:20 - LiteLLM Proxy:DEBUG: utils.py:4936 - Spend Logs transactions: 0
18:53:29 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: spend_update_queue.py:39 - Aggregating updates by entity type: []
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1122 - User Spend transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1165 - End-User Spend transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1180 - KEY Spend transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1221 - Team Spend transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1269 - Team Membership Spend transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1342 - Org Spend transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Tag Spend transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1435 - Agent Spend transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily User Spend transactions: 0
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily user spend update
18:53:31 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Team Spend transactions: 0
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily team spend update
18:53:31 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Org Spend transactions: 0
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily org spend update
18:53:31 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily End_user Spend transactions: 0
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily end_user spend update
18:53:31 - LiteLLM Proxy:DEBUG: daily_spend_update_queue.py:99 - Aggregated daily spend update transactions: {}
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1576 - Daily Agent Spend transactions: 0
18:53:31 - LiteLLM Proxy:DEBUG: db_spend_update_writer.py:1609 - No new transactions to process for daily agent spend update
18:53:31 - LiteLLM Proxy:DEBUG: utils.py:4936 - Spend Logs transactions: 0

View File

@ -1,231 +1,7 @@
model_list:
- model_name: gpt-3.5-turbo-end-user-test
# Gemini 2.5 Flash Native Audio (Latest - recommended)
- model_name: gpt-5.3-codex
litellm_params:
model: gpt-3.5-turbo
region_name: "eu"
model_info:
id: "1"
- model_name: gpt-3.5-turbo-end-user-test
litellm_params:
model: openai/gpt-4.1-mini
api_key: os.environ/OPENAI_API_KEY # The `os.environ/` prefix tells litellm to read this from the env. See https://docs.litellm.ai/docs/simple_proxy#load-api-keys-from-vault
- model_name: gpt-3.5-turbo
litellm_params:
model: openai/gpt-4.1-mini
api_key: os.environ/OPENAI_API_KEY # The `os.environ/` prefix tells litellm to read this from the env. See https://docs.litellm.ai/docs/simple_proxy#load-api-keys-from-vault
- model_name: gpt-3.5-turbo-large
litellm_params:
model: "gpt-3.5-turbo-1106"
model: openai/gpt-5.3-codex
api_key: os.environ/OPENAI_API_KEY
rpm: 480
timeout: 300
stream_timeout: 60
- model_name: gpt-4
litellm_params:
model: openai/gpt-4.1-mini
api_key: os.environ/OPENAI_API_KEY # The `os.environ/` prefix tells litellm to read this from the env. See https://docs.litellm.ai/docs/simple_proxy#load-api-keys-from-vault
rpm: 480
timeout: 300
stream_timeout: 60
- model_name: sagemaker-completion-model
litellm_params:
model: sagemaker/berri-benchmarking-Llama-2-70b-chat-hf-4
input_cost_per_second: 0.000420
- model_name: text-embedding-ada-002
litellm_params:
model: openai/text-embedding-ada-002
api_key: os.environ/OPENAI_API_KEY
model_info:
mode: embedding
base_model: text-embedding-ada-002
- model_name: dall-e-2 # some tests use dall-e-2 which is now deprecated, alias to dall-e-3
litellm_params:
model: openai/dall-e-3
- model_name: openai-dall-e-3
litellm_params:
model: dall-e-3
- model_name: fake-openai-endpoint
litellm_params:
model: openai/gpt-3.5-turbo
api_key: fake-key
api_base: https://exampleopenaiendpoint-production.up.railway.app/
- model_name: fake-openai-endpoint-2
litellm_params:
model: openai/my-fake-model
api_key: my-fake-key
api_base: https://exampleopenaiendpoint-production.up.railway.app/
stream_timeout: 0.001
rpm: 1
- model_name: fake-openai-endpoint-3
litellm_params:
model: openai/my-fake-model
api_key: my-fake-key
api_base: https://exampleopenaiendpoint-production.up.railway.app/
stream_timeout: 0.001
rpm: 1000
- model_name: fake-openai-endpoint-4
litellm_params:
model: openai/my-fake-model
api_key: my-fake-key
api_base: https://exampleopenaiendpoint-production.up.railway.app/
num_retries: 50
- model_name: fake-openai-endpoint-3
litellm_params:
model: openai/my-fake-model-2
api_key: my-fake-key
api_base: https://exampleopenaiendpoint-production.up.railway.app/
stream_timeout: 0.001
rpm: 1000
- model_name: bad-model
litellm_params:
model: openai/bad-model
api_key: os.environ/OPENAI_API_KEY
api_base: https://exampleopenaiendpoint-production.up.railway.app/
mock_timeout: True
timeout: 60
rpm: 1000
model_info:
health_check_timeout: 1
- model_name: good-model
litellm_params:
model: openai/bad-model
api_key: os.environ/OPENAI_API_KEY
api_base: https://exampleopenaiendpoint-production.up.railway.app/
rpm: 1000
model_info:
health_check_timeout: 1
- model_name: "*"
litellm_params:
model: openai/*
api_key: os.environ/OPENAI_API_KEY
- model_name: realtime-v1
litellm_params:
model: azure/gpt-realtime-20250828-standard
api_version: "2025-08-28"
realtime_protocol: GA # Possible values: "GA"/ "v1", "beta"
- model_name: realtime-beta
litellm_params:
model: azure/gpt-realtime-20250828-standard
api_version: 2025-04-01-preview
# provider specific wildcard routing
- model_name: "anthropic/*"
litellm_params:
model: "anthropic/*"
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: "bedrock/*"
litellm_params:
model: "bedrock/*"
- model_name: "groq/*"
litellm_params:
model: "groq/*"
api_key: os.environ/GROQ_API_KEY
- model_name: mistral-embed
litellm_params:
model: mistral/mistral-embed
- model_name: gpt-instruct # [PROD TEST] - tests if `/health` automatically infers this to be a text completion model
litellm_params:
model: text-completion-openai/gpt-3.5-turbo-instruct
- model_name: fake-openai-endpoint-5
litellm_params:
model: openai/my-fake-model
api_key: my-fake-key
api_base: https://exampleopenaiendpoint-production.up.railway.app/
timeout: 1
- model_name: badly-configured-openai-endpoint
litellm_params:
model: openai/my-fake-model
api_key: my-fake-key
api_base: https://exampleopenaiendpoint-production.up.railway.appxxxx/
- model_name: gemini-1.5-flash
litellm_params:
model: gemini/gemini-1.5-flash
api_key: os.environ/GOOGLE_API_KEY
- model_name: gpt-4o
litellm_params:
model: gpt-4o
api_key: os.environ/OPENAI_API_KEY
litellm_settings:
# set_verbose: True # Uncomment this if you want to see verbose logs; not recommended in production
drop_params: True
success_callback: ["prometheus"]
# max_budget: 100
# budget_duration: 30d
num_retries: 5
request_timeout: 600
telemetry: False
context_window_fallbacks: [{"gpt-3.5-turbo": ["gpt-3.5-turbo-large"]}]
default_team_settings:
- team_id: team-1
success_callback: ["langfuse"]
failure_callback: ["langfuse"]
langfuse_public_key: os.environ/LANGFUSE_PROJECT1_PUBLIC # Project 1
langfuse_secret: os.environ/LANGFUSE_PROJECT1_SECRET # Project 1
- team_id: team-2
success_callback: ["langfuse"]
failure_callback: ["langfuse"]
langfuse_public_key: os.environ/LANGFUSE_PROJECT2_PUBLIC # Project 2
langfuse_secret: os.environ/LANGFUSE_PROJECT2_SECRET # Project 2
langfuse_host: https://us.cloud.langfuse.com
# cache: true # [OPTIONAL] use for caching responses
# enable_caching_on_provider_specific_optional_params: True # Include provider-specific params in cache keys
# cache_params: # And for shared health check
# type: redis
# host: localhost
# port: 6379
# For /fine_tuning/jobs endpoints
finetune_settings:
- custom_llm_provider: azure
api_base: os.environ/AZURE_API_BASE
api_key: os.environ/AZURE_API_KEY
api_version: "2023-03-15-preview"
- custom_llm_provider: openai
api_key: os.environ/OPENAI_API_KEY
# for /files endpoints
files_settings:
- custom_llm_provider: azure
api_base: os.environ/AZURE_API_BASE
api_key: os.environ/AZURE_API_KEY
api_version: "2023-03-15-preview"
- custom_llm_provider: openai
api_key: os.environ/OPENAI_API_KEY
router_settings:
routing_strategy: usage-based-routing-v2
redis_host: os.environ/REDIS_HOST
redis_password: os.environ/REDIS_PASSWORD
redis_port: os.environ/REDIS_PORT
enable_pre_call_checks: true
model_group_alias: {"my-special-fake-model-alias-name": "fake-openai-endpoint-3"}
general_settings:
master_key: sk-1234 # [OPTIONAL] Use to enforce auth on proxy. See - https://docs.litellm.ai/docs/proxy/virtual_keys
store_model_in_db: True
proxy_budget_rescheduler_min_time: 60
proxy_budget_rescheduler_max_time: 64
proxy_batch_write_at: 1
database_connection_pool_limit: 10
# background_health_checks: true
# use_shared_health_check: true
# health_check_interval: 30
# database_url: "postgresql://<user>:<password>@<host>:<port>/<dbname>" # [OPTIONAL] use for token-based auth to proxy
pass_through_endpoints:
- path: "/v1/rerank" # route you want to add to LiteLLM Proxy Server
target: "https://api.cohere.com/v1/rerank" # URL this route should forward requests to
headers: # headers to forward to this URL
content-type: application/json # (Optional) Extra Headers to pass to this endpoint
accept: application/json
forward_headers: True
# environment_variables:
# settings for using redis caching
# REDIS_HOST: redis-16337.c322.us-east-1-2.ec2.cloud.redislabs.com
# REDIS_PORT: "16337"
# REDIS_PASSWORD:

View File

@ -0,0 +1,212 @@
"""
Test search tool authorization - verify model-like access control for search tools.
Tests that:
1. Keys can only access search tools in their allowed_search_tools list
2. Teams can only access search tools in their allowed_search_tools list
3. Empty allowlists grant access to all search tools
4. Credentials are never exposed in team/key metadata
"""
import pytest
from unittest.mock import MagicMock, patch
from fastapi import HTTPException
# Import types and functions to test
from litellm.proxy._types import LiteLLM_TeamTable, UserAPIKeyAuth
from litellm.proxy.auth.auth_checks import (
can_key_call_search_tool,
can_team_call_search_tool,
)
@pytest.mark.asyncio
async def test_key_can_access_allowed_search_tool():
"""Test that a key can access a search tool in its allowlist."""
# Create a mock key with allowed_search_tools
mock_key = UserAPIKeyAuth(
token="sk-test-key",
models=["gpt-4"],
allowed_search_tools=["tavily-search", "perplexity-search"],
)
# Should succeed - tool is in allowlist
result = await can_key_call_search_tool(
search_tool_name="tavily-search",
valid_token=mock_key,
)
assert result is True
@pytest.mark.asyncio
async def test_key_denied_non_allowed_search_tool():
"""Test that a key is denied access to a search tool not in its allowlist."""
mock_key = UserAPIKeyAuth(
token="sk-test-key",
models=["gpt-4"],
allowed_search_tools=["tavily-search"], # Only tavily allowed
)
# Should raise exception - brave-search not in allowlist
with pytest.raises(Exception) as exc_info:
await can_key_call_search_tool(
search_tool_name="brave-search",
valid_token=mock_key,
)
assert "not allowed to access search tool" in str(exc_info.value)
assert "brave-search" in str(exc_info.value)
@pytest.mark.asyncio
async def test_key_empty_allowlist_grants_all_access():
"""Test that an empty allowlist grants access to all search tools."""
mock_key = UserAPIKeyAuth(
token="sk-test-key",
models=["gpt-4"],
allowed_search_tools=[], # Empty = all allowed
)
# Should succeed - empty list allows all
result = await can_key_call_search_tool(
search_tool_name="any-search-tool",
valid_token=mock_key,
)
assert result is True
@pytest.mark.asyncio
async def test_team_can_access_allowed_search_tool():
"""Test that a team can access a search tool in its allowlist."""
mock_team = LiteLLM_TeamTable(
team_id="team-123",
team_alias="Marketing Team",
models=["gpt-4"],
allowed_search_tools=["tavily-search", "exa-search"],
)
# Should succeed - tool is in allowlist
result = await can_team_call_search_tool(
search_tool_name="tavily-search",
team_object=mock_team,
)
assert result is True
@pytest.mark.asyncio
async def test_team_denied_non_allowed_search_tool():
"""Test that a team is denied access to a search tool not in its allowlist."""
mock_team = LiteLLM_TeamTable(
team_id="team-123",
team_alias="Engineering Team",
models=["gpt-4"],
allowed_search_tools=["perplexity-search"], # Only perplexity allowed
)
# Should raise exception - tavily-search not in allowlist
with pytest.raises(Exception) as exc_info:
await can_team_call_search_tool(
search_tool_name="tavily-search",
team_object=mock_team,
)
assert "not allowed to access search tool" in str(exc_info.value)
assert "tavily-search" in str(exc_info.value)
@pytest.mark.asyncio
async def test_team_empty_allowlist_grants_all_access():
"""Test that an empty team allowlist grants access to all search tools."""
mock_team = LiteLLM_TeamTable(
team_id="team-123",
team_alias="Admin Team",
models=["gpt-4"],
allowed_search_tools=[], # Empty = all allowed
)
# Should succeed - empty list allows all
result = await can_team_call_search_tool(
search_tool_name="any-search-tool",
team_object=mock_team,
)
assert result is True
@pytest.mark.asyncio
async def test_team_none_allowed_search_tools():
"""Test that None for allowed_search_tools (not set) grants access to all."""
mock_team = LiteLLM_TeamTable(
team_id="team-123",
team_alias="Legacy Team",
models=["gpt-4"],
allowed_search_tools=None, # Not set = all allowed
)
# Should succeed - None allows all
result = await can_team_call_search_tool(
search_tool_name="any-search-tool",
team_object=mock_team,
)
assert result is True
def test_credentials_not_in_team_metadata():
"""Verify that search provider credentials are never stored in team metadata."""
mock_team = LiteLLM_TeamTable(
team_id="team-123",
team_alias="Test Team",
models=["gpt-4"],
allowed_search_tools=["tavily-search"],
metadata={"custom_field": "value"}, # No search_provider_config
)
# Verify metadata does not contain search_provider_config
assert mock_team.metadata is not None
assert "search_provider_config" not in mock_team.metadata
assert "api_key" not in str(mock_team.metadata)
def test_credentials_not_in_key_metadata():
"""Verify that search provider credentials are never stored in key metadata."""
mock_key = UserAPIKeyAuth(
token="sk-test-key",
models=["gpt-4"],
allowed_search_tools=["tavily-search"],
metadata={"user_info": "test"}, # No search_provider_config
)
# Verify metadata does not contain search_provider_config
assert mock_key.metadata is not None
assert "search_provider_config" not in mock_key.metadata
assert "api_key" not in str(mock_key.metadata)
@pytest.mark.asyncio
async def test_both_key_and_team_checks_required():
"""Test that both key-level and team-level checks are enforced."""
# Key has access to tool
mock_key = UserAPIKeyAuth(
token="sk-test-key",
models=["gpt-4"],
allowed_search_tools=["tavily-search"],
)
# Team does NOT have access to tool
mock_team = LiteLLM_TeamTable(
team_id="team-123",
team_alias="Restricted Team",
models=["gpt-4"],
allowed_search_tools=["perplexity-search"], # Different tool
)
# Key check passes
await can_key_call_search_tool(
search_tool_name="tavily-search",
valid_token=mock_key,
)
# Team check fails
with pytest.raises(Exception) as exc_info:
await can_team_call_search_tool(
search_tool_name="tavily-search",
team_object=mock_team,
)
assert "not allowed to access search tool" in str(exc_info.value)

View File

@ -15,7 +15,15 @@ import ModelAliasManager from "@/components/common_components/ModelAliasManager"
import React, { useEffect, useState } from "react";
import { useQueryClient } from "@tanstack/react-query";
import NotificationsManager from "@/components/molecules/notifications_manager";
import { fetchMCPAccessGroups, getGuardrailsList, getPoliciesList, Organization, Team, teamCreateCall } from "@/components/networking";
import {
fetchMCPAccessGroups,
fetchSearchTools,
getGuardrailsList,
getPoliciesList,
Organization,
Team,
teamCreateCall,
} from "@/components/networking";
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
import { organizationKeys } from "@/app/(dashboard)/hooks/organizations/useOrganizations";
import MCPToolPermissions from "@/components/mcp_server_management/MCPToolPermissions";
@ -80,6 +88,7 @@ const CreateTeamModal = ({
const [modelsToPick, setModelsToPick] = useState<string[]>([]);
const [guardrailsList, setGuardrailsList] = useState<string[]>([]);
const [policiesList, setPoliciesList] = useState<string[]>([]);
const [searchToolNames, setSearchToolNames] = useState<string[]>([]);
const [mcpAccessGroups, setMcpAccessGroups] = useState<string[]>([]);
const [mcpAccessGroupsLoaded, setMcpAccessGroupsLoaded] = useState(false);
@ -158,6 +167,24 @@ const CreateTeamModal = ({
fetchPolicies();
}, [accessToken]);
useEffect(() => {
const loadSearchTools = async () => {
try {
if (!accessToken) return;
const response = await fetchSearchTools(accessToken);
const tools = Array.isArray(response?.data) ? response.data : [];
setSearchToolNames(
tools
.map((tool: any) => tool?.search_tool_name)
.filter((name: unknown): name is string => typeof name === "string" && name.length > 0),
);
} catch (error) {
console.error("Failed to fetch search tools for team create modal:", error);
}
};
loadSearchTools();
}, [accessToken]);
const handleCreate = async (formValues: Record<string, any>) => {
try {
console.log(`formValues: ${JSON.stringify(formValues)}`);
@ -395,6 +422,27 @@ const CreateTeamModal = ({
</Select2>
</Form.Item>
<Form.Item
label={
<span>
Allowed Search Tools{" "}
<Tooltip title="Select which search tools this team can access. Leave empty to allow all search tools.">
<InfoCircleOutlined style={{ marginLeft: "4px" }} />
</Tooltip>
</span>
}
name="allowed_search_tools"
>
<Select2
mode="multiple"
placeholder="Select search tools (empty = all search tools allowed)"
style={{ width: "100%" }}
options={searchToolNames.map((name) => ({ label: name, value: name }))}
showSearch
optionFilterProp="label"
/>
</Form.Item>
<Accordion className="mt-8 mb-8">
<AccordionHeader>
<b>Team Member Settings</b>

View File

@ -57,7 +57,14 @@ import type { KeyResponse, Team } from "./key_team_helpers/key_list";
import MCPServerSelector from "./mcp_server_management/MCPServerSelector";
import MCPToolPermissions from "./mcp_server_management/MCPToolPermissions";
import NotificationsManager from "./molecules/notifications_manager";
import { Organization, fetchMCPAccessGroups, getGuardrailsList, getPoliciesList, teamDeleteCall } from "./networking";
import {
Organization,
fetchMCPAccessGroups,
fetchSearchTools,
getGuardrailsList,
getPoliciesList,
teamDeleteCall,
} from "./networking";
import NumericalInput from "./shared/numerical_input";
import VectorStoreSelector from "./vector_store_management/VectorStoreSelector";
@ -267,6 +274,7 @@ const Teams: React.FC<TeamProps> = ({
// Add this state near the other useState declarations
const [guardrailsList, setGuardrailsList] = useState<string[]>([]);
const [policiesList, setPoliciesList] = useState<string[]>([]);
const [searchToolNames, setSearchToolNames] = useState<string[]>([]);
const [loggingSettings, setLoggingSettings] = useState<any[]>([]);
const [mcpAccessGroups, setMcpAccessGroups] = useState<string[]>([]);
const [mcpAccessGroupsLoaded, setMcpAccessGroupsLoaded] = useState(false);
@ -334,6 +342,24 @@ const Teams: React.FC<TeamProps> = ({
fetchPolicies();
}, [accessToken]);
useEffect(() => {
const loadSearchTools = async () => {
try {
if (!accessToken) return;
const response = await fetchSearchTools(accessToken);
const tools = Array.isArray(response?.data) ? response.data : [];
setSearchToolNames(
tools
.map((tool: any) => tool?.search_tool_name)
.filter((name: unknown): name is string => typeof name === "string" && name.length > 0),
);
} catch (error) {
console.error("Failed to fetch search tools:", error);
}
};
loadSearchTools();
}, [accessToken]);
const fetchMcpAccessGroups = async () => {
try {
if (accessToken == null) {
@ -1207,6 +1233,27 @@ const Teams: React.FC<TeamProps> = ({
/>
</Form.Item>
<Form.Item
label={
<span>
Allowed Search Tools{" "}
<Tooltip title="Select which search tools this team can access. Leave empty to allow all search tools.">
<InfoCircleOutlined style={{ marginLeft: "4px" }} />
</Tooltip>
</span>
}
name="allowed_search_tools"
>
<Select
mode="multiple"
placeholder="Select search tools (empty = all search tools allowed)"
style={{ width: "100%" }}
options={searchToolNames.map((name) => ({ label: name, value: name }))}
showSearch
optionFilterProp="label"
/>
</Form.Item>
<Form.Item label="Max Budget (USD)" name="max_budget">
<NumericalInput step={0.01} precision={2} width={200} />
</Form.Item>

View File

@ -3725,40 +3725,6 @@ export const teamUpdateCall = async (
}
};
export const updateTeamSearchProviderConfigCall = async (
accessToken: string,
formValues: {
team_id: string;
provider: string;
api_key?: string | null;
api_base?: string | null;
},
) => {
try {
const url = proxyBaseUrl
? `${proxyBaseUrl}/team/search_provider_config/update`
: `/team/search_provider_config/update`;
const response = await fetch(url, {
method: "POST",
headers: {
[globalLitellmHeaderName]: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(formValues),
});
if (!response.ok) {
const errorData = await response.text();
handleError(errorData);
throw new Error(errorData);
}
return await response.json();
} catch (error) {
console.error("Failed to update team search provider config:", error);
throw error;
}
};
/**
* Patch update a model
*

View File

@ -3,6 +3,7 @@ import { organizationKeys, useOrganizations } from "@/app/(dashboard)/hooks/orga
import { useQueryClient } from "@tanstack/react-query";
import UserSearchModal from "@/components/common_components/user_search_modal";
import {
fetchSearchTools,
getPoliciesList,
getPolicyInfoWithGuardrails,
Member,
@ -102,6 +103,7 @@ export interface TeamData {
} | null;
created_at: string;
access_group_ids?: string[];
allowed_search_tools?: string[];
default_team_member_models?: string[];
access_group_models?: string[];
access_group_mcp_server_ids?: string[];
@ -191,6 +193,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
const { data: guardrailsData, isLoading: isGuardrailsLoading } = useGuardrails();
const globalGuardrailNames = guardrailsData?.globalGuardrailNames ?? new Set<string>();
const [policiesList, setPoliciesList] = useState<string[]>([]);
const [searchToolNames, setSearchToolNames] = useState<string[]>([]);
const [policyGuardrails, setPolicyGuardrails] = useState<Record<string, string[]>>({});
const [loadingPolicies, setLoadingPolicies] = useState(false);
const [memberToDelete, setMemberToDelete] = useState<Member | null>(null);
@ -300,6 +303,24 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
fetchPolicies();
}, [accessToken]);
useEffect(() => {
const loadSearchTools = async () => {
try {
if (!accessToken) return;
const response = await fetchSearchTools(accessToken);
const tools = Array.isArray(response?.data) ? response.data : [];
setSearchToolNames(
tools
.map((tool: any) => tool?.search_tool_name)
.filter((name: unknown): name is string => typeof name === "string" && name.length > 0),
);
} catch (error) {
console.error("Failed to fetch search tools in team info:", error);
}
};
loadSearchTools();
}, [accessToken]);
// Fetch resolved guardrails for all policies
useEffect(() => {
const fetchPolicyGuardrails = async () => {
@ -457,26 +478,13 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
try {
const rawMetadata = values.metadata ? JSON.parse(values.metadata) : {};
// Exclude soft_budget_alerting_emails from parsed metadata since it's handled separately
const { soft_budget_alerting_emails, search_provider_config, ...rest } = rawMetadata;
const { soft_budget_alerting_emails, ...rest } = rawMetadata;
parsedMetadata = rest;
} catch (e) {
NotificationsManager.fromBackend("Invalid JSON in metadata field");
return;
}
let searchProviderConfig: Record<string, any> | undefined;
if (typeof values.search_provider_config === "string") {
const trimmedSearchProviderConfig = values.search_provider_config.trim();
if (trimmedSearchProviderConfig.length > 0) {
try {
searchProviderConfig = JSON.parse(trimmedSearchProviderConfig);
} catch (e) {
NotificationsManager.fromBackend("Invalid JSON in search provider configuration");
return;
}
}
}
let secretManagerSettings: Record<string, any> | undefined;
if (typeof values.secret_manager_settings === "string") {
const trimmedSecretConfig = values.secret_manager_settings.trim();
@ -517,6 +525,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
team_id: teamId,
team_alias: values.team_alias,
models: values.models,
allowed_search_tools: values.allowed_search_tools || [],
tpm_limit: sanitizeNumeric(values.tpm_limit),
rpm_limit: sanitizeNumeric(values.rpm_limit),
model_tpm_limit: modelTpmLimit,
@ -526,7 +535,6 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
budget_duration: values.budget_duration,
metadata: {
...parsedMetadata,
...(searchProviderConfig !== undefined ? { search_provider_config: searchProviderConfig } : {}),
guardrails: (values.guardrails || []).filter((n: string) => !globalGuardrailNames.has(n)),
opted_out_global_guardrails: optedOutGlobalGuardrails,
...(values.logging_settings?.length > 0 ? { logging: values.logging_settings } : {}),
@ -940,6 +948,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
models: info.models,
tpm_limit: info.tpm_limit,
rpm_limit: info.rpm_limit,
allowed_search_tools: info.allowed_search_tools || [],
modelLimits: Array.from(
new Set([
...Object.keys(info.metadata?.model_tpm_limit ?? {}),
@ -966,14 +975,11 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
: "",
metadata: info.metadata
? JSON.stringify(
(({ logging, secret_manager_settings, soft_budget_alerting_emails, search_provider_config, model_tpm_limit, model_rpm_limit, ...rest }) => rest)(info.metadata),
(({ logging, secret_manager_settings, soft_budget_alerting_emails, model_tpm_limit, model_rpm_limit, ...rest }) => rest)(info.metadata),
null,
2,
)
: "",
search_provider_config: info.metadata?.search_provider_config
? JSON.stringify(info.metadata.search_provider_config, null, 2)
: "",
logging_settings: info.metadata?.logging || [],
secret_manager_settings: info.metadata?.secret_manager_settings
? JSON.stringify(info.metadata.secret_manager_settings, null, 2)
@ -1025,6 +1031,23 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
/>
</Form.Item>
<Form.Item
label="Allowed Search Tools"
name="allowed_search_tools"
tooltip="Select which search tools this team can access. Leave empty to allow all search tools."
>
<Select
mode="multiple"
placeholder="Select search tools (empty = all tools allowed)"
style={{ width: "100%" }}
options={searchToolNames.map((name) => ({ label: name, value: name }))}
showSearch
filterOption={(input, option) =>
(option?.label ?? "").toLowerCase().includes(input.toLowerCase())
}
/>
</Form.Item>
<Form.Item label="Max Budget (USD)" name="max_budget">
<NumericalInput step={0.01} precision={2} style={{ width: "100%" }} />
</Form.Item>
@ -1416,29 +1439,6 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
/>
</Form.Item>
<Form.Item
label="Search Provider Configuration"
name="search_provider_config"
tooltip='Team-level provider credentials. Example: {"tavily": {"api_key": "tvly-...", "api_base": "https://api.tavily.com"}}'
rules={[
{
validator: async (_, value) => {
if (!value || (typeof value === "string" && value.trim() === "")) {
return Promise.resolve();
}
try {
JSON.parse(value);
return Promise.resolve();
} catch (error) {
return Promise.reject(new Error("Please enter valid JSON"));
}
},
},
]}
>
<Input.TextArea rows={8} placeholder='{"tavily":{"api_key":"tvly-...","api_base":"https://api.tavily.com"}}' />
</Form.Item>
<Form.Item
label="Secret Manager Settings"
name="secret_manager_settings"
@ -1655,14 +1655,6 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
</div>
)}
{info.metadata?.search_provider_config && (
<div className="pt-4 border-t border-gray-200">
<Text className="font-medium">Search Provider Configuration</Text>
<pre className="mt-2 bg-gray-50 p-3 rounded text-xs overflow-x-auto">
{JSON.stringify(info.metadata.search_provider_config, null, 2)}
</pre>
</div>
)}
</div>
)}
</Card>