-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathserver.py
More file actions
139 lines (105 loc) · 4.08 KB
/
Copy pathserver.py
File metadata and controls
139 lines (105 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import json
import os
import uvicorn
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from contextlib import asynccontextmanager
from dotenv import load_dotenv
load_dotenv()
from adapter import MiniMaxAdapter
adapter = None
@asynccontextmanager
async def lifespan(app: FastAPI):
global adapter
adapter = MiniMaxAdapter()
try:
await adapter.ensure_session()
print(f"[OK] Session created: {adapter._session_id}")
except Exception as e:
print(f"[WARN] Session init: {e}")
yield
if adapter:
await adapter.close()
app = FastAPI(title="MiniMax Agent Web2API", version="1.0.0", lifespan=lifespan)
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])
class ChatMessage(BaseModel):
role: str
content: str | list | None = None
class FunctionDef(BaseModel):
name: str
description: str = ""
parameters: dict = {}
class ToolDef(BaseModel):
type: str = "function"
function: FunctionDef
class ChatRequest(BaseModel):
model: str | None = "MiniMax-M3"
messages: list[ChatMessage]
stream: bool | None = False
temperature: float | None = None
max_tokens: int | None = None
top_p: float | None = None
tools: list[ToolDef] | None = None
tool_choice: str | None = None
class ModelInfo(BaseModel):
id: str
object: str = "model"
created: int
owned_by: str = "minimax"
@app.get("/v1/models")
async def list_models():
return {
"object": "list",
"data": [
ModelInfo(id="MiniMax-M3", created=1700000000),
],
}
@app.get("/health")
async def health():
return {"status": "ok", "session_id": adapter._session_id if adapter else None}
@app.post("/v1/chat/completions")
async def chat_completions(request: ChatRequest):
global adapter
if adapter is None:
adapter = MiniMaxAdapter()
try:
await adapter.ensure_session()
except Exception as e:
if request.stream:
from fastapi.responses import StreamingResponse
async def err():
yield f"data: {json.dumps({'choices': [{'delta': {'content': f'[SESSION ERROR] {e}'}, 'index': 0}]})}\n\n"
yield f"data: {json.dumps({'choices': [{'delta': {}, 'finish_reason': 'stop', 'index': 0}]})}\n\n"
yield "data: [DONE]\n\n"
return StreamingResponse(err(), media_type="text/event-stream")
raise HTTPException(status_code=500, detail=str(e))
messages_dict = [m.model_dump() for m in request.messages]
tools_dict = None
if request.tools:
tools_dict = [t.model_dump() for t in request.tools]
if request.stream:
return await _stream_response(messages_dict, tools_dict, request.tool_choice)
else:
return await _non_stream_response(messages_dict, tools_dict, request.tool_choice)
async def _stream_response(messages: list, tools: list | None = None, tool_choice: str | None = None):
from fastapi.responses import StreamingResponse
async def generate():
yield f"data: {json.dumps({'choices': [{'delta': {'role': 'assistant'}, 'index': 0}]})}\n\n"
try:
async for chunk in adapter.stream_chat(messages, tools=tools, tool_choice=tool_choice):
yield f"data: {json.dumps(chunk)}\n\n"
except Exception as e:
yield f"data: {json.dumps({'choices': [{'delta': {'content': f'[ERROR] {str(e)}'}, 'index': 0}]})}\n\n"
yield "data: [DONE]\n\n"
return StreamingResponse(generate(), media_type="text/event-stream")
async def _non_stream_response(messages: list, tools: list | None = None, tool_choice: str | None = None):
try:
result = await adapter.non_stream_chat(messages, tools=tools, tool_choice=tool_choice)
return result
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
port = int(os.getenv("PORT", "8000"))
host = os.getenv("HOST", "0.0.0.0")
uvicorn.run("server:app", host=host, port=port, reload=False)