huanx520 commited on
Commit
83b36db
·
1 Parent(s): 998a91e

fix: 清理无用路由,仅保留 DeepSeek

Browse files

- 删除 /anthropic/* /v1beta/* /api/(version|tags|show) 假端点
- /v1/models 只返回 deepseek 4 个模型
- deepseek-chat → v4-flash, deepseek-reasoner → v4-pro 别名映射

Files changed (1) hide show
  1. main.py +6 -216
main.py CHANGED
@@ -67,14 +67,6 @@ async def list_models(authorization: str = Header(...)):
67
  {"id": "deepseek-reasoner", "object": "model", "created": int(time.time()), "owned_by": "deepseek"},
68
  {"id": "deepseek-v4-flash", "object": "model", "created": int(time.time()), "owned_by": "deepseek"},
69
  {"id": "deepseek-v4-pro", "object": "model", "created": int(time.time()), "owned_by": "deepseek"},
70
- {"id": "deepseek-v4-flash-search", "object": "model", "created": int(time.time()), "owned_by": "deepseek"},
71
- {"id": "deepseek-v4-pro-search", "object": "model", "created": int(time.time()), "owned_by": "deepseek"},
72
- {"id": "deepseek-v4-vision", "object": "model", "created": int(time.time()), "owned_by": "deepseek"},
73
- {"id": "gpt-4o", "object": "model", "created": int(time.time()), "owned_by": "openai"},
74
- {"id": "gpt-4-turbo", "object": "model", "created": int(time.time()), "owned_by": "openai"},
75
- {"id": "claude-3-opus", "object": "model", "created": int(time.time()), "owned_by": "anthropic"},
76
- {"id": "claude-3-sonnet", "object": "model", "created": int(time.time()), "owned_by": "anthropic"},
77
- {"id": "gemini-pro", "object": "model", "created": int(time.time()), "owned_by": "google"},
78
  ],
79
  "object": "list",
80
  }
@@ -109,6 +101,10 @@ async def chat_completions(
109
 
110
  prompt = request.messages[-1].content
111
 
 
 
 
 
112
  account = await manager.acquire()
113
 
114
  try:
@@ -118,7 +114,7 @@ async def chat_completions(
118
  async def stream_with_cleanup():
119
  chunk_id = f"chatcmpl-{uuid.uuid4().hex[:8]}"
120
  try:
121
- async for chunk in browser.stream_message(prompt, timeout=120, model=request.model):
122
  data = {
123
  "id": chunk_id,
124
  "object": "chat.completion.chunk",
@@ -159,7 +155,7 @@ async def chat_completions(
159
  media_type="text/event-stream",
160
  )
161
 
162
- response_text = await browser.send_message(prompt, timeout=120, model=request.model)
163
 
164
  await manager.release(account)
165
 
@@ -187,212 +183,6 @@ async def chat_completions(
187
  raise HTTPException(status_code=503, detail=str(e))
188
 
189
 
190
- @app.get("/anthropic/v1/models")
191
- async def anthropic_models(authorization: str = Header(...)):
192
- verify_api_key(authorization)
193
-
194
- return {
195
- "data": [
196
- {"id": "claude-sonnet-4-6", "object": "model", "created": int(time.time()), "owned_by": "anthropic"},
197
- {"id": "claude-opus-4-6", "object": "model", "created": int(time.time()), "owned_by": "anthropic"},
198
- {"id": "claude-haiku-4-5", "object": "model", "created": int(time.time()), "owned_by": "anthropic"},
199
- ],
200
- "object": "list",
201
- }
202
-
203
-
204
- @app.post("/anthropic/v1/messages")
205
- async def anthropic_messages(request: Request, authorization: str = Header(...)):
206
- verify_api_key(authorization)
207
-
208
- body = await request.json()
209
- messages = body.get("messages", [])
210
- model = body.get("model", "claude-sonnet-4-6")
211
- stream = body.get("stream", False)
212
-
213
- if not messages:
214
- raise HTTPException(status_code=400, detail="No messages provided")
215
-
216
- prompt = messages[-1].get("content", "")
217
-
218
- account = await manager.acquire()
219
-
220
- try:
221
- browser = await manager.get_or_create_browser_with_retry(account, headless=config.browser.headless)
222
-
223
- if stream:
224
- async def stream_with_cleanup():
225
- try:
226
- async for chunk in browser.stream_message(prompt, timeout=120, model=model):
227
- data = {
228
- "type": "content_block_delta",
229
- "index": 0,
230
- "delta": {"type": "text_delta", "text": chunk},
231
- }
232
- yield f"event: content_block_delta\ndata: {json.dumps(data)}\n\n"
233
-
234
- yield f"event: message_stop\ndata: {json.dumps({'type': 'message_stop'})}\n\n"
235
- except Exception as e:
236
- yield f"event: error\ndata: {json.dumps({'type': 'error', 'error': {'type': 'server_error', 'message': str(e)}})}\n\n"
237
- finally:
238
- await manager.release(account)
239
-
240
- return StreamingResponse(
241
- stream_with_cleanup(),
242
- media_type="text/event-stream",
243
- )
244
-
245
- response_text = await browser.send_message(prompt, timeout=120, model=model)
246
-
247
- await manager.release(account)
248
-
249
- return {
250
- "id": f"msg_{uuid.uuid4().hex[:8]}",
251
- "type": "message",
252
- "role": "assistant",
253
- "model": model,
254
- "content": [{"type": "text", "text": response_text}],
255
- "stop_reason": "end_turn",
256
- "usage": {
257
- "input_tokens": len(prompt.split()),
258
- "output_tokens": len(response_text.split()),
259
- },
260
- }
261
-
262
- except Exception as e:
263
- await manager.mark_error(account)
264
- raise HTTPException(status_code=503, detail=str(e))
265
-
266
-
267
- @app.post("/v1beta/models/{model}:generateContent")
268
- async def gemini_generate(model: str, request: Request, authorization: str = Header(...)):
269
- verify_api_key(authorization)
270
-
271
- body = await request.json()
272
- contents = body.get("contents", [])
273
-
274
- if not contents:
275
- raise HTTPException(status_code=400, detail="No contents provided")
276
-
277
- prompt = contents[-1].get("parts", [{}])[0].get("text", "")
278
-
279
- account = await manager.acquire()
280
-
281
- try:
282
- browser = await manager.get_or_create_browser_with_retry(account, headless=config.browser.headless)
283
-
284
- response_text = await browser.send_message(prompt, timeout=120, model=model)
285
-
286
- await manager.release(account)
287
-
288
- return {
289
- "candidates": [
290
- {
291
- "content": {
292
- "parts": [{"text": response_text}],
293
- "role": "model",
294
- },
295
- "finishReason": "STOP",
296
- }
297
- ],
298
- "usageMetadata": {
299
- "promptTokenCount": len(prompt.split()),
300
- "candidatesTokenCount": len(response_text.split()),
301
- "totalTokenCount": len(prompt.split()) + len(response_text.split()),
302
- },
303
- }
304
-
305
- except Exception as e:
306
- await manager.mark_error(account)
307
- raise HTTPException(status_code=503, detail=str(e))
308
-
309
-
310
- @app.post("/v1beta/models/{model}:streamGenerateContent")
311
- async def gemini_stream_generate(model: str, request: Request, authorization: str = Header(...)):
312
- verify_api_key(authorization)
313
-
314
- body = await request.json()
315
- contents = body.get("contents", [])
316
-
317
- if not contents:
318
- raise HTTPException(status_code=400, detail="No contents provided")
319
-
320
- prompt = contents[-1].get("parts", [{}])[0].get("text", "")
321
-
322
- account = await manager.acquire()
323
-
324
- try:
325
- browser = await manager.get_or_create_browser_with_retry(account, headless=config.browser.headless)
326
-
327
- async def stream_with_cleanup():
328
- try:
329
- async for chunk in browser.stream_message(prompt, timeout=120, model=model):
330
- data = {
331
- "candidates": [
332
- {
333
- "content": {
334
- "parts": [{"text": chunk}],
335
- "role": "model",
336
- },
337
- }
338
- ],
339
- }
340
- yield f"data: {json.dumps(data)}\n\n"
341
-
342
- final_data = {
343
- "candidates": [
344
- {
345
- "content": {"parts": [], "role": "model"},
346
- "finishReason": "STOP",
347
- }
348
- ],
349
- "usageMetadata": {
350
- "promptTokenCount": 0,
351
- "candidatesTokenCount": 0,
352
- "totalTokenCount": 0,
353
- },
354
- }
355
- yield f"data: {json.dumps(final_data)}\n\n"
356
- except Exception as e:
357
- yield f"data: {json.dumps({'error': {'message': str(e)}})}\n\n"
358
- finally:
359
- await manager.release(account)
360
-
361
- return StreamingResponse(
362
- stream_with_cleanup(),
363
- media_type="text/event-stream",
364
- )
365
-
366
- except Exception as e:
367
- await manager.mark_error(account)
368
- raise HTTPException(status_code=503, detail=str(e))
369
-
370
-
371
- @app.get("/api/version")
372
- async def ollama_version():
373
- return {"version": "0.1.0"}
374
-
375
-
376
- @app.get("/api/tags")
377
- async def ollama_tags():
378
- return {
379
- "models": [
380
- {"name": "deepseek-chat", "model": "deepseek-chat"},
381
- {"name": "deepseek-reasoner", "model": "deepseek-reasoner"},
382
- ]
383
- }
384
-
385
-
386
- @app.post("/api/show")
387
- async def ollama_show(request: Request):
388
- body = await request.json()
389
- model = body.get("model", "deepseek-chat")
390
-
391
- return {
392
- "id": model,
393
- "capabilities": ["tools", "thinking"],
394
- }
395
-
396
 
397
  @app.get("/healthz")
398
  async def healthz():
 
67
  {"id": "deepseek-reasoner", "object": "model", "created": int(time.time()), "owned_by": "deepseek"},
68
  {"id": "deepseek-v4-flash", "object": "model", "created": int(time.time()), "owned_by": "deepseek"},
69
  {"id": "deepseek-v4-pro", "object": "model", "created": int(time.time()), "owned_by": "deepseek"},
 
 
 
 
 
 
 
 
70
  ],
71
  "object": "list",
72
  }
 
101
 
102
  prompt = request.messages[-1].content
103
 
104
+ # 模型别名: chat→flash, reasoner→pro
105
+ MODEL_ALIASES = {"deepseek-chat": "deepseek-v4-flash", "deepseek-reasoner": "deepseek-v4-pro"}
106
+ model = MODEL_ALIASES.get(request.model, request.model)
107
+
108
  account = await manager.acquire()
109
 
110
  try:
 
114
  async def stream_with_cleanup():
115
  chunk_id = f"chatcmpl-{uuid.uuid4().hex[:8]}"
116
  try:
117
+ async for chunk in browser.stream_message(prompt, timeout=120, model=model):
118
  data = {
119
  "id": chunk_id,
120
  "object": "chat.completion.chunk",
 
155
  media_type="text/event-stream",
156
  )
157
 
158
+ response_text = await browser.send_message(prompt, timeout=120, model=model)
159
 
160
  await manager.release(account)
161
 
 
183
  raise HTTPException(status_code=503, detail=str(e))
184
 
185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
 
187
  @app.get("/healthz")
188
  async def healthz():