Coverage for .venv/lib/python3.13/site-packages/litellm/proxy/management_endpoints/usage_endpoints/endpoints.py: 93%
25 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 12:01 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 12:01 +0000
1"""
2USAGE AI CHAT ENDPOINTS
4/usage/ai/chat - Stream AI chat responses about usage data
5"""
7from typing import Final, Literal
9from fastapi import APIRouter, Depends, Request
10from fastapi.responses import StreamingResponse
11from pydantic import BaseModel, Field
13import litellm
14from litellm.proxy._types import UserAPIKeyAuth
15from litellm.proxy.auth.user_api_key_auth import user_api_key_auth
16from litellm.proxy.common_utils.sse_keepalive import (
17 SSE_COMMENT_PING,
18 wrap_sse_stream_with_keepalive_pings,
19)
21router: Final = APIRouter()
24class ChatMessage(BaseModel):
25 role: Literal["user", "assistant"]
26 content: str
29class UsageAIChatRequest(BaseModel):
30 messages: list[ChatMessage] = Field(..., description="Chat messages (user/assistant history)")
31 model: str | None = Field(default=None, description="Model to use for AI chat")
34@router.post(
35 "/usage/ai/chat",
36 tags=["Budget & Spend Tracking"],
37 dependencies=[Depends(user_api_key_auth)],
38)
39async def usage_ai_chat(
40 data: UsageAIChatRequest,
41 request: Request,
42 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
43):
44 """
45 AI chat about usage data. Streams SSE events with the AI response.
46 The AI agent has access to tools that query aggregated daily activity data.
47 """
48 from litellm.proxy.management_endpoints.common_utils import (
49 _user_has_admin_view,
50 require_caller_user_id_for_non_admin,
51 )
52 from litellm.proxy.management_endpoints.usage_endpoints.ai_usage_chat import (
53 stream_usage_ai_chat,
54 )
56 is_admin: Final = _user_has_admin_view(user_api_key_dict)
57 if is_admin: 57 ↛ 60line 57 didn't jump to line 60 because the condition on line 57 was always true
58 user_id = user_api_key_dict.user_id
59 else:
60 user_id = require_caller_user_id_for_non_admin(user_api_key_dict)
61 messages: Final = [{"role": m.role, "content": m.content} for m in data.messages]
63 return StreamingResponse(
64 wrap_sse_stream_with_keepalive_pings(
65 stream_usage_ai_chat(
66 messages=messages,
67 model=data.model,
68 user_id=user_id,
69 is_admin=is_admin,
70 ),
71 ping_interval_seconds=litellm.sse_keepalive_ping_interval_seconds,
72 ping_chunk=SSE_COMMENT_PING,
73 ),
74 media_type="text/event-stream",
75 headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"},
76 )