44from fastapi .middleware .cors import CORSMiddleware
55from typing import Annotated , Optional , Dict , Any , List
66from pydantic import BaseModel , Field
7+ from pydantic .config import ConfigDict
78from datetime import datetime
89import uuid
910import json
2930)
3031
3132from services .llm_service import call_llm
33+ from services .user_service import get_user_service , UserService
3234
3335# Import the shared provider configuration
3436from config .provider_config import PROVIDER_CONFIG as APP_PROVIDER_CONFIG
3537from config .routes_config import RouterConfig , resolve_router_configs
3638from models .agent import (
37- GenerateCodeRequest , GenerateCodeResponse , RunCodeRequest ,
39+ GenerateCodeRequest , GenerateCodeResponse , RunCodeRequest ,
3840 RunCodeResponse , Agent , CreateAgentRequest , Deployment , DeployedApi
3941)
4042from models .demo import (
4143 GenerateDemoCodeRequest , GenerateDemoCodeResponse ,
4244 CreateDemoAppRequest , DemoApp
4345)
46+ from models .user import User
4447
4548from agent_factory .remote_mcp_client import RemoteMCPClient
4649
@@ -122,6 +125,31 @@ class ClientLogPayload(BaseModel):
122125class FetchSpecRequest (BaseModel ):
123126 url : str
124127
128+
129+ class UpdateMonthlyAllowanceRequest (BaseModel ):
130+ monthly_allowance : float = Field (..., alias = "monthlyAllowance" )
131+
132+ model_config = ConfigDict (populate_by_name = True )
133+
134+
135+ class UpdateResetDateRequest (BaseModel ):
136+ allowance_reset_date : float = Field (..., alias = "allowanceResetDate" )
137+
138+ model_config = ConfigDict (populate_by_name = True )
139+
140+
141+ class UpdateSpendRemainingRequest (BaseModel ):
142+ spend_remaining : float = Field (..., alias = "spendRemaining" )
143+
144+ model_config = ConfigDict (populate_by_name = True )
145+
146+
147+ class AddUsageRequest (BaseModel ):
148+ response_cost : float = Field (..., alias = "responseCost" )
149+ metadata : Optional [Dict [str , Any ]] = None
150+
151+ model_config = ConfigDict (populate_by_name = True )
152+
125153# Import models after defining local ones to avoid circular dependencies
126154from models .chat import ChatRequest , ChatMessage , ChatResponse , ProviderConfig , SessionData
127155
@@ -134,11 +162,19 @@ def get_logger() -> ObservabilityService:
134162 """Dependency to get the observability service instance."""
135163 return get_observability_service ()
136164
165+ def get_user_service_dep (db : DatabaseService = Depends (get_db )) -> UserService :
166+ return get_user_service (db )
167+
137168# Background task for LLM processing
138169async def process_chat (ticket_id : str , request : ChatRequest , user : dict , req : Request ):
139170 # Background tasks don't have access to dependency injection, so we get service instances directly
140171 db_service = get_database_service (settings )
172+ user_service = get_user_service (db_service )
141173 logger = get_observability_service ()
174+ user_basic_info = {
175+ "email" : user .get ("email" ),
176+ "name" : user .get ("name" ) or user .get ("displayName" )
177+ }
142178 try :
143179 # Update ticket status
144180 ticket_data = {
@@ -207,8 +243,11 @@ async def process_chat(ticket_id: str, request: ChatRequest, user: dict, req: Re
207243 model = request .model ,
208244 messages = messages ,
209245 parameters = request .parameters ,
210- tools = built_in_tools if built_in_tools else None
211- )
246+ tools = built_in_tools if built_in_tools else None ,
247+ user_service = user_service ,
248+ user_id = user .get ("uid" ),
249+ user_basic_info = user_basic_info ,
250+ )
212251
213252 # Update ticket with success
214253 ticket_data .update ({
@@ -349,6 +388,52 @@ def get_model_config(provider: str, model: str):
349388 raise HTTPException (status_code = 404 , detail = "Model not found" )
350389 return available_providers [provider ]["models" ][model ]
351390
391+
392+ @router .get ("/users/me" , response_model = User )
393+ def get_current_user_profile (user : dict = Depends (get_current_user ), user_service : UserService = Depends (get_user_service_dep )):
394+ return user_service .get_user (user .get ("uid" , "anonymous" ), user )
395+
396+
397+ @router .put ("/users/me/monthly-allowance" , response_model = User )
398+ def set_monthly_allowance (
399+ request : UpdateMonthlyAllowanceRequest ,
400+ user : dict = Depends (get_current_user ),
401+ user_service : UserService = Depends (get_user_service_dep ),
402+ ):
403+ return user_service .set_monthly_allowance (user .get ("uid" , "anonymous" ), request .monthly_allowance , user )
404+
405+
406+ @router .put ("/users/me/allowance-reset-date" , response_model = User )
407+ def set_allowance_reset_date (
408+ request : UpdateResetDateRequest ,
409+ user : dict = Depends (get_current_user ),
410+ user_service : UserService = Depends (get_user_service_dep ),
411+ ):
412+ return user_service .set_reset_date (user .get ("uid" , "anonymous" ), request .allowance_reset_date , user )
413+
414+
415+ @router .post ("/users/me/reset-allowance" , response_model = User )
416+ def reset_allowance (user : dict = Depends (get_current_user ), user_service : UserService = Depends (get_user_service_dep )):
417+ return user_service .reset_allowance (user .get ("uid" , "anonymous" ), user )
418+
419+
420+ @router .put ("/users/me/spend-remaining" , response_model = User )
421+ def update_spend_remaining (
422+ request : UpdateSpendRemainingRequest ,
423+ user : dict = Depends (get_current_user ),
424+ user_service : UserService = Depends (get_user_service_dep ),
425+ ):
426+ return user_service .update_spend_remaining (user .get ("uid" , "anonymous" ), request .spend_remaining , user )
427+
428+
429+ @router .post ("/users/me/usage" , response_model = User )
430+ def add_usage_entry (
431+ request : AddUsageRequest ,
432+ user : dict = Depends (get_current_user ),
433+ user_service : UserService = Depends (get_user_service_dep ),
434+ ):
435+ return user_service .add_usage (user .get ("uid" , "anonymous" ), request .response_cost , request .metadata , user )
436+
352437@router .post ("/chat" )
353438async def chat (request : ChatRequest , req : Request , background_tasks : BackgroundTasks , user : dict = Depends (get_current_user )):
354439 """Submit a chat request and get a ticket ID"""
0 commit comments