mirror of
https://github.com/xszyou/Fay.git
synced 2026-09-01 15:12:25 +08:00
接口模块
【增加】embedding透传接口。
This commit is contained in:
+79
-21
@@ -111,6 +111,22 @@ def _build_llm_url(base_url: str) -> str:
|
||||
return url + "/chat/completions"
|
||||
return url + "/v1/chat/completions"
|
||||
|
||||
|
||||
|
||||
def _build_embedding_url(base_url: str) -> str:
|
||||
if not base_url:
|
||||
return ""
|
||||
url = base_url.rstrip("/")
|
||||
if url.endswith("/v1/embeddings") or url.endswith("/embeddings"):
|
||||
return url
|
||||
if url.endswith("/v1/chat/completions"):
|
||||
return url[:-len("/v1/chat/completions")] + "/v1/embeddings"
|
||||
if url.endswith("/chat/completions"):
|
||||
return url[:-len("/chat/completions")] + "/embeddings"
|
||||
if url.endswith("/v1"):
|
||||
return url + "/embeddings"
|
||||
return url + "/v1/embeddings"
|
||||
|
||||
@__app.route('/api/submit', methods=['post'])
|
||||
def api_submit():
|
||||
data = request.values.get('data')
|
||||
@@ -353,7 +369,7 @@ def api_send_v1_chat_completions():
|
||||
# 处理聊天完成请求
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
return jsonify({'error': '未提供数据'})
|
||||
return jsonify({'error': 'missing request body'})
|
||||
try:
|
||||
model = data.get('model', 'fay')
|
||||
if model == 'llm':
|
||||
@@ -411,30 +427,30 @@ def api_send_v1_chat_completions():
|
||||
except Exception as exc:
|
||||
return jsonify({'error': f'LLM request failed: {exc}'}), 500
|
||||
|
||||
last_content = ""
|
||||
username = "User"
|
||||
messages = data.get("messages")
|
||||
if isinstance(messages, list) and messages:
|
||||
last_message = messages[-1] or {}
|
||||
username = last_message.get("role", "User") or "User"
|
||||
if username == "user":
|
||||
username = "User"
|
||||
last_content = last_message.get("content") or ""
|
||||
elif isinstance(messages, str):
|
||||
last_content = messages
|
||||
last_content = ""
|
||||
username = "User"
|
||||
messages = data.get("messages")
|
||||
if isinstance(messages, list) and messages:
|
||||
last_message = messages[-1] or {}
|
||||
username = last_message.get("role", "User") or "User"
|
||||
if username == "user":
|
||||
username = "User"
|
||||
last_content = last_message.get("content") or ""
|
||||
elif isinstance(messages, str):
|
||||
last_content = messages
|
||||
|
||||
observation = data.get('observation', '')
|
||||
# 检查请求中是否指定了流式传输
|
||||
stream_requested = data.get('stream', False)
|
||||
no_reply = _as_bool(data.get('no_reply', data.get('noReply', False)))
|
||||
obs_text = ""
|
||||
if observation is not None:
|
||||
obs_text = observation.strip() if isinstance(observation, str) else str(observation).strip()
|
||||
message_text = last_content.strip() if isinstance(last_content, str) else str(last_content).strip()
|
||||
if not message_text and not obs_text:
|
||||
return jsonify({'error': 'messages and observation are both empty'}), 400
|
||||
if not message_text and obs_text:
|
||||
no_reply = True
|
||||
no_reply = _as_bool(data.get('no_reply', data.get('noReply', False)))
|
||||
obs_text = ""
|
||||
if observation is not None:
|
||||
obs_text = observation.strip() if isinstance(observation, str) else str(observation).strip()
|
||||
message_text = last_content.strip() if isinstance(last_content, str) else str(last_content).strip()
|
||||
if not message_text and not obs_text:
|
||||
return jsonify({'error': 'messages and observation are both empty'}), 400
|
||||
if not message_text and obs_text:
|
||||
no_reply = True
|
||||
if no_reply:
|
||||
interact = Interact("text", 1, {'user': username, 'msg': last_content, 'observation': str(observation), 'stream': bool(stream_requested), 'no_reply': True})
|
||||
util.printInfo(1, username, '[text chat no_reply]{}'.format(interact.data["msg"]), time.time())
|
||||
@@ -862,6 +878,48 @@ def gpt_stream_response(last_content, username):
|
||||
return Response(generate(), mimetype='text/event-stream')
|
||||
|
||||
# 处理非流式响应
|
||||
@__app.route('/v1/embeddings', methods=['post'])
|
||||
@__app.route('/api/send/v1/embeddings', methods=['post'])
|
||||
def api_send_v1_embeddings():
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
return jsonify({'error': 'missing request body'})
|
||||
try:
|
||||
config_util.load_config()
|
||||
base_url = config_util.embedding_api_base_url or config_util.gpt_base_url
|
||||
api_key = config_util.embedding_api_key or config_util.key_gpt_api_key
|
||||
model_name = config_util.embedding_api_model
|
||||
except Exception as exc:
|
||||
return jsonify({'error': f'Embedding config load failed: {exc}'}), 500
|
||||
|
||||
embed_url = _build_embedding_url(base_url)
|
||||
if not embed_url:
|
||||
return jsonify({'error': 'Embedding base_url is not configured'}), 500
|
||||
|
||||
payload = dict(data) if isinstance(data, dict) else {}
|
||||
req_model = payload.get('model')
|
||||
if (not req_model) or str(req_model).lower() in ('embedding', 'fay-embedding', 'fay', 'default'):
|
||||
if model_name:
|
||||
payload['model'] = model_name
|
||||
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
if api_key:
|
||||
headers['Authorization'] = f'Bearer {api_key}'
|
||||
|
||||
try:
|
||||
resp = requests.post(embed_url, headers=headers, json=payload, timeout=60)
|
||||
content_type = resp.headers.get("Content-Type", "application/json")
|
||||
if "charset=" not in content_type.lower():
|
||||
content_type = f"{content_type}; charset=utf-8"
|
||||
return Response(
|
||||
resp.content,
|
||||
status=resp.status_code,
|
||||
content_type=content_type,
|
||||
)
|
||||
except Exception as exc:
|
||||
return jsonify({'error': f'Embedding request failed: {exc}'}), 500
|
||||
|
||||
|
||||
def non_streaming_response(last_content, username):
|
||||
sm = stream_manager.new_instance()
|
||||
_, nlp_Stream = sm.get_Stream(username)
|
||||
|
||||
Reference in New Issue
Block a user