feat: add get models api

This commit is contained in:
Chenyme committed 2026-02-02 22:21:04 +08:00
1 parent 4fabe58bf9
commit 4ad7332080
6 files changed
+68 -22

No files matched your search

-5
View File
@@ -1,5 +0,0 @@
"""API V1 Package"""
from app.api.v1.chat import router as chat_router
__all__ = ["chat_router"]
+1 -1
View File
@@ -2,7 +2,7 @@
Chat Completions API 路由
"""
from typing import Any, Dict, List, Literal, Optional, Union
from typing import Any, Dict, List, Optional, Union
from fastapi import APIRouter
from fastapi.responses import StreamingResponse, JSONResponse
-1
View File
@@ -14,7 +14,6 @@ from app.services.grok.chat import GrokChatService
from app.services.grok.model import ModelService
from app.services.grok.processor import ImageStreamProcessor, ImageCollectProcessor
from app.services.token import get_token_manager
from app.core.config import get_config
from app.core.exceptions import ValidationException, AppException, ErrorType
from app.core.logger import logger
+28
View File
@@ -0,0 +1,28 @@
"""
Models API 路由
"""
from fastapi import APIRouter
from app.services.grok.model import ModelService
router = APIRouter(tags=["Models"])
@router.get("/models")
async def list_models():
"""OpenAI 兼容 models 列表接口"""
data = [
{
"id": m.model_id,
"object": "model",
"created": 0,
"owned_by": "grok2api",
}
for m in ModelService.list()
]
return {"object": "list", "data": data}
__all__ = ["router"]
+37 -15
View File
@@ -4,7 +4,7 @@ Grok Chat 服务
import uuid
import orjson
from typing import Dict, List, Any, Optional
from typing import Dict, List, Any
from dataclasses import dataclass
from curl_cffi.requests import AsyncSession
@@ -18,11 +18,11 @@ from app.core.exceptions import (
ErrorType
)
from app.services.grok.statsig import StatsigService
from app.services.grok.model import ModelService, Cost
from app.services.grok.model import ModelService
from app.services.grok.assets import UploadService
from app.services.grok.processor import StreamProcessor, CollectProcessor
from app.services.grok.retry import retry_on_status
from app.services.token import get_token_manager, EffortType
from app.services.token import get_token_manager
CHAT_API = "https://grok.com/rest/app-chat/conversations/new"
@@ -64,34 +64,38 @@ class MessageExtractor:
"""
texts = []
attachments = [] # 需要上传的附件 (URL 或 base64)
# 先抽取每条消息的文本,保留角色信息用于合并
extracted: List[Dict[str, str]] = []
for msg in messages:
role = msg.get("role", "")
content = msg.get("content", "")
parts = []
# 简单字符串内容
if isinstance(content, str):
if content.strip():
texts.append(content)
continue
parts.append(content)
# 列表格式内容
if isinstance(content, list):
elif isinstance(content, list):
for item in content:
item_type = item.get("type", "")
# 文本类型
if item_type == "text":
text = item.get("text", "")
if text.strip():
texts.append(text)
parts.append(text)
# 图片类型
elif item_type == "image_url":
image_data = item.get("image_url", {})
url = image_data.get("url", "") if isinstance(image_data, dict) else str(image_data)
if url:
attachments.append(("image", url))
# 音频类型
elif item_type == "input_audio":
if is_video:
@@ -100,7 +104,7 @@ class MessageExtractor:
data = audio_data.get("data", "") if isinstance(audio_data, dict) else str(audio_data)
if data:
attachments.append(("audio", data))
# 文件类型
elif item_type == "file":
if is_video:
@@ -112,7 +116,25 @@ class MessageExtractor:
url = file_data
if url:
attachments.append(("file", url))
if parts:
extracted.append({"role": role, "text": "\n".join(parts)})
# 合并文本
last_user_index = None
for i in range(len(extracted) - 1, -1, -1):
if extracted[i]["role"] == "user":
last_user_index = i
break
for i, item in enumerate(extracted):
role = item["role"] or "user"
text = item["text"]
if i == last_user_index:
texts.append(text)
else:
texts.append(f"{role}: {text}")
# 换行拼接文本
message = "\n\n".join(texts)
return message, attachments
+2
View File
@@ -30,6 +30,7 @@ from app.core.response_middleware import ResponseLoggerMiddleware
from app.api.v1.chat import router as chat_router
from app.api.v1.image import router as image_router
from app.api.v1.files import router as files_router
from app.api.v1.models import router as models_router
from app.services.token import get_scheduler
@@ -100,6 +101,7 @@ def create_app() -> FastAPI:
# 注册路由
app.include_router(chat_router, prefix="/v1", dependencies=[Depends(verify_api_key)])
app.include_router(image_router, prefix="/v1", dependencies=[Depends(verify_api_key)])
app.include_router(models_router, prefix="/v1", dependencies=[Depends(verify_api_key)])
app.include_router(files_router, prefix="/v1/files")
# 静态文件服务