Wilker commited on
Commit Β·
01dc751
1
Parent(s): c58fbd9
fix(app): reordena schemas de tools/Anthropic e adiciona from __future__ import annotations
Browse files
app.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
|
|
|
|
|
| 1 |
from fastapi import FastAPI, HTTPException, Form, File, UploadFile, Request, Depends
|
| 2 |
from fastapi.responses import HTMLResponse, FileResponse, PlainTextResponse, RedirectResponse, StreamingResponse, JSONResponse
|
| 3 |
from starlette.middleware.sessions import SessionMiddleware
|
|
@@ -411,6 +413,41 @@ logger.info("Construindo Γndices de conhecimento (RAG) e skills...")
|
|
| 411 |
reload_indexes()
|
| 412 |
|
| 413 |
# ββ Schemas ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 414 |
class Message(BaseModel):
|
| 415 |
role: Literal["system", "user", "assistant"]
|
| 416 |
content: constr(min_length=1, max_length=10000)
|
|
@@ -430,6 +467,8 @@ class ChatRequest(BaseModel):
|
|
| 430 |
messages: List[Message] = Field(min_length=1, description="Lista de mensagens")
|
| 431 |
max_tokens: Optional[int] = Field(default=8192, ge=1, le=1000000, description="MΓ‘ximo de tokens")
|
| 432 |
temperature: Optional[float] = Field(default=0.7, ge=0.0, le=2.0, description="Temperatura de geraΓ§Γ£o")
|
|
|
|
|
|
|
| 433 |
|
| 434 |
@field_validator("model")
|
| 435 |
@classmethod
|
|
@@ -448,6 +487,23 @@ class ChatRequest(BaseModel):
|
|
| 448 |
raise ValueError("messages nΓ£o pode estar vazio")
|
| 449 |
return v
|
| 450 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 451 |
class ImageRequest(BaseModel):
|
| 452 |
prompt: constr(min_length=1, max_length=1000) = Field(description="Prompt para geraΓ§Γ£o de imagem")
|
| 453 |
negative_prompt: Optional[constr(max_length=500)] = Field(default=None, description="Prompt negativo")
|
|
@@ -1271,43 +1327,6 @@ def list_transcription_models():
|
|
| 1271 |
]
|
| 1272 |
}
|
| 1273 |
|
| 1274 |
-
# ββ Endpoint β Anthropic-compatible /v1/messages ββββββββββββββββββββββββββββββ
|
| 1275 |
-
class AnthropicMessage(BaseModel):
|
| 1276 |
-
role: str
|
| 1277 |
-
content: str
|
| 1278 |
-
|
| 1279 |
-
|
| 1280 |
-
class AnthropicTool(BaseModel):
|
| 1281 |
-
name: str
|
| 1282 |
-
description: Optional[str] = None
|
| 1283 |
-
input_schema: Optional[dict] = Field(default=None, alias="input_schema")
|
| 1284 |
-
|
| 1285 |
-
@field_validator("input_schema", mode="before")
|
| 1286 |
-
@classmethod
|
| 1287 |
-
def coerce_input_schema(cls, v):
|
| 1288 |
-
if v is None:
|
| 1289 |
-
return {"type": "object", "properties": {}}
|
| 1290 |
-
return v
|
| 1291 |
-
|
| 1292 |
-
|
| 1293 |
-
class AnthropicRequest(BaseModel):
|
| 1294 |
-
model: Optional[str] = Field(default=DEFAULT_MODEL_KEY)
|
| 1295 |
-
messages: List[AnthropicMessage]
|
| 1296 |
-
max_tokens: Optional[int] = Field(default=8192)
|
| 1297 |
-
temperature: Optional[float] = Field(default=0.7)
|
| 1298 |
-
system: Optional[str] = None
|
| 1299 |
-
stream: Optional[bool] = False
|
| 1300 |
-
tools: Optional[List[AnthropicTool]] = Field(default=None, description="Ferramentas no formato Anthropic")
|
| 1301 |
-
tool_choice: Optional[str] = Field(default="auto", description="'auto', 'any', ou nome de uma tool")
|
| 1302 |
-
|
| 1303 |
-
@field_validator("messages")
|
| 1304 |
-
@classmethod
|
| 1305 |
-
def messages_not_empty(cls, v):
|
| 1306 |
-
if not v:
|
| 1307 |
-
raise ValueError("messages nΓ£o pode estar vazio")
|
| 1308 |
-
return v
|
| 1309 |
-
|
| 1310 |
-
|
| 1311 |
async def chat_completions_async(req: ChatRequest):
|
| 1312 |
"""VersΓ£o async do chat_completions β usada pelos endpoints SSE."""
|
| 1313 |
try:
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
from fastapi import FastAPI, HTTPException, Form, File, UploadFile, Request, Depends
|
| 4 |
from fastapi.responses import HTMLResponse, FileResponse, PlainTextResponse, RedirectResponse, StreamingResponse, JSONResponse
|
| 5 |
from starlette.middleware.sessions import SessionMiddleware
|
|
|
|
| 413 |
reload_indexes()
|
| 414 |
|
| 415 |
# ββ Schemas ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 416 |
+
class ToolFunctionParameters(BaseModel):
|
| 417 |
+
type: str = "object"
|
| 418 |
+
properties: dict = {}
|
| 419 |
+
required: Optional[List[str]] = None
|
| 420 |
+
|
| 421 |
+
|
| 422 |
+
class ToolFunction(BaseModel):
|
| 423 |
+
name: str
|
| 424 |
+
description: Optional[str] = None
|
| 425 |
+
parameters: Optional[ToolFunctionParameters] = None
|
| 426 |
+
|
| 427 |
+
|
| 428 |
+
class Tool(BaseModel):
|
| 429 |
+
type: Literal["function"] = "function"
|
| 430 |
+
function: ToolFunction
|
| 431 |
+
|
| 432 |
+
|
| 433 |
+
class AnthropicMessage(BaseModel):
|
| 434 |
+
role: str
|
| 435 |
+
content: str
|
| 436 |
+
|
| 437 |
+
|
| 438 |
+
class AnthropicTool(BaseModel):
|
| 439 |
+
name: str
|
| 440 |
+
description: Optional[str] = None
|
| 441 |
+
input_schema: Optional[dict] = Field(default=None, alias="input_schema")
|
| 442 |
+
|
| 443 |
+
@field_validator("input_schema", mode="before")
|
| 444 |
+
@classmethod
|
| 445 |
+
def coerce_input_schema(cls, v):
|
| 446 |
+
if v is None:
|
| 447 |
+
return {"type": "object", "properties": {}}
|
| 448 |
+
return v
|
| 449 |
+
|
| 450 |
+
|
| 451 |
class Message(BaseModel):
|
| 452 |
role: Literal["system", "user", "assistant"]
|
| 453 |
content: constr(min_length=1, max_length=10000)
|
|
|
|
| 467 |
messages: List[Message] = Field(min_length=1, description="Lista de mensagens")
|
| 468 |
max_tokens: Optional[int] = Field(default=8192, ge=1, le=1000000, description="MΓ‘ximo de tokens")
|
| 469 |
temperature: Optional[float] = Field(default=0.7, ge=0.0, le=2.0, description="Temperatura de geraΓ§Γ£o")
|
| 470 |
+
tools: Optional[List[Tool]] = Field(default=None, description="Ferramentas disponΓveis (formato OpenAI)")
|
| 471 |
+
tool_choice: Optional[str] = Field(default="auto", description="'auto', 'none', ou nome de uma tool")
|
| 472 |
|
| 473 |
@field_validator("model")
|
| 474 |
@classmethod
|
|
|
|
| 487 |
raise ValueError("messages nΓ£o pode estar vazio")
|
| 488 |
return v
|
| 489 |
|
| 490 |
+
class AnthropicRequest(BaseModel):
|
| 491 |
+
model: Optional[str] = Field(default=DEFAULT_MODEL_KEY)
|
| 492 |
+
messages: List[AnthropicMessage]
|
| 493 |
+
max_tokens: Optional[int] = Field(default=8192)
|
| 494 |
+
temperature: Optional[float] = Field(default=0.7)
|
| 495 |
+
system: Optional[str] = None
|
| 496 |
+
stream: Optional[bool] = False
|
| 497 |
+
tools: Optional[List[AnthropicTool]] = Field(default=None, description="Ferramentas no formato Anthropic")
|
| 498 |
+
tool_choice: Optional[str] = Field(default="auto", description="'auto', 'any', ou nome de uma tool")
|
| 499 |
+
|
| 500 |
+
@field_validator("messages")
|
| 501 |
+
@classmethod
|
| 502 |
+
def messages_not_empty(cls, v):
|
| 503 |
+
if not v:
|
| 504 |
+
raise ValueError("messages nΓ£o pode estar vazio")
|
| 505 |
+
return v
|
| 506 |
+
|
| 507 |
class ImageRequest(BaseModel):
|
| 508 |
prompt: constr(min_length=1, max_length=1000) = Field(description="Prompt para geraΓ§Γ£o de imagem")
|
| 509 |
negative_prompt: Optional[constr(max_length=500)] = Field(default=None, description="Prompt negativo")
|
|
|
|
| 1327 |
]
|
| 1328 |
}
|
| 1329 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1330 |
async def chat_completions_async(req: ChatRequest):
|
| 1331 |
"""VersΓ£o async do chat_completions β usada pelos endpoints SSE."""
|
| 1332 |
try:
|