Spaces:
Sleeping
Sleeping
File size: 4,052 Bytes
40610d7 bf7211c 40610d7 bf7211c 40610d7 bf7211c 40610d7 bf7211c fb31778 bf7211c fb31778 bf7211c 40610d7 e196795 bf7211c e196795 bf7211c | 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 | import os
import json
import asyncio
import httpx
import traceback
from fastapi import FastAPI, Request
from fastapi.responses import StreamingResponse, JSONResponse
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
AIROPS_API_KEY = os.environ.get("AIROPS_API_KEY", "")
AIROPS_APP_ID = os.environ.get("AIROPS_APP_ID", "")
INPUT_VAR = os.environ.get("INPUT_VAR_NAME", "input")
@app.post("/v1/chat/completions")
async def chat_completions(request: Request):
try:
try:
body = await request.json()
except:
body = {}
messages = body.get("messages", [])
# 将所有历史消息和设定拼接成一个长剧本
full_context = ""
for msg in messages:
# 强制转换为字符串,防止特殊格式报错
role = str(msg.get("role", "user")).upper()
content = str(msg.get("content", ""))
if role == "SYSTEM":
full_context += f"[系统设定及角色卡]:\n{content}\n\n"
elif role == "ASSISTANT":
full_context += f"[角色回复]:\n{content}\n\n"
else:
full_context += f"[我的输入]:\n{content}\n\n"
if not full_context.strip():
full_context = "[我的输入]:\n你好"
headers = {
"Authorization": f"Bearer {AIROPS_API_KEY}",
"Content-Type": "application/json"
}
payload = {
"inputs": {
INPUT_VAR: full_context.strip()
}
}
async def generate():
# 同样保持 300 秒超时,给 AI 充分的思考时间
async with httpx.AsyncClient(timeout=300.0) as client:
url = f"https://app.airops.com/public_api/airops_apps/{AIROPS_APP_ID}/execute"
try:
response = await client.post(url, headers=headers, json=payload)
if response.status_code == 200:
data = response.json()
result_text = data.get("result", "")
if isinstance(result_text, (dict, list)):
result_text = json.dumps(result_text, ensure_ascii=False)
# 模拟 OpenAI 流式打字机效果
chunk_size = 3
for i in range(0, len(result_text), chunk_size):
chunk = result_text[i:i+chunk_size]
openai_chunk = {
"id": "chatcmpl-airops",
"object": "chat.completion.chunk",
"choices": [{"delta": {"content": chunk}}]
}
yield f"data: {json.dumps(openai_chunk)}\n\n"
await asyncio.sleep(0.01)
yield "data: [DONE]\n\n"
else:
print(f"AirOps Error: {response.status_code} - {response.text}")
err = {"error": f"AirOps 接口报错: {response.status_code}"}
yield f"data: {json.dumps(err)}\n\n"
yield "data: [DONE]\n\n"
except Exception as e:
traceback.print_exc()
err = {"error": f"代理服务器内部错误: {repr(e)}"}
yield f"data: {json.dumps(err)}\n\n"
yield "data: [DONE]\n\n"
return StreamingResponse(generate(), media_type="text/event-stream")
except Exception as e:
traceback.print_exc()
return JSONResponse(status_code=500, content={"error": f"请求解析错误: {repr(e)}"}) |