ling-playground / models.py
cafe3310's picture
feat: Initial clean commit
a9fb7e9
raw
history blame
4.85 kB
import httpx
import json
import logging
import html
from config import ANTCHAT_BASE_URL, ANTCHAT_API_KEY, CHAT_MODEL_SPECS
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s [%(levelname)s] %(message)s"
)
logger = logging.getLogger(__name__)
def get_model_response(model_id, history, system_prompt, temperature, escape_html=True):
"""
与 AntChat API 交互以获取模型响应。
"""
# The model_id passed in is now the ground truth, potentially overridden by local.py
api_model_id = CHAT_MODEL_SPECS[model_id]["model_id"]
headers = {
"Authorization": f"Bearer {ANTCHAT_API_KEY}",
"Content-Type": "application/json",
}
# 构建消息历史
messages = [{"role": "system", "content": system_prompt}]
for user_msg, assistant_msg in history:
# 关键修复:只处理包含用户消息的轮次,以过滤掉UI的初始欢迎语
if user_msg:
messages.append({"role": "user", "content": user_msg})
# 只有在用户消息之后,才可能追加对应的助手消息
if assistant_msg:
messages.append({"role": "assistant", "content": assistant_msg})
json_data = {
"model": api_model_id,
"messages": messages,
"stream": True,
"temperature": temperature,
}
logger.debug(f"请求 URL: {ANTCHAT_BASE_URL}/chat/completions")
logger.debug(f"请求头: {headers}")
logger.debug(f"请求体: {json.dumps(json_data, ensure_ascii=False)}")
try:
with httpx.stream(
"POST",
f"{ANTCHAT_BASE_URL}/chat/completions",
headers=headers,
json=json_data,
timeout=120,
) as response:
logger.debug(f"响应状态码: {response.status_code}")
response.raise_for_status()
for chunk in response.iter_lines():
if chunk.startswith("data:"):
chunk = chunk[5:]
if chunk.strip() == "[DONE]":
break
try:
data = json.loads(chunk)
if "choices" in data and data["choices"]:
delta = data["choices"][0].get("delta", {})
content_chunk = delta.get("content")
if content_chunk:
yield html.escape(content_chunk) if escape_html else content_chunk
elif "tool_calls" in delta:
tool_calls = delta.get("tool_calls", [])
if tool_calls:
func_chunk = tool_calls[0].get("function", {})
args_chunk = func_chunk.get("arguments")
if args_chunk:
yield html.escape(args_chunk) if escape_html else args_chunk
except json.JSONDecodeError as e:
logger.error(f"JSON 解析错误: {e}, 数据: {chunk}")
except Exception as e:
logger.error(f"请求异常: {e}")
def perform_web_search(query):
# 调用 Tavily 或 Serper API
#...
return "搜索结果摘要"
def generate_code_for_tab(system_prompt, user_prompt, code_type, model_choice):
"""
为代码生成标签页调用 Ring 模型。
"""
logger.info(f"为 '{code_type}' 类型生成代码,Prompt: '{user_prompt}', Model: '{model_choice}'")
if code_type == "静态页面":
# 从 UI 的选项中解析出模型名称
if "inclusionai/ling-1t" in model_choice:
model_name = "inclusionai/ling-1t"
elif "inclusionai/ring-flash-2.0" in model_choice:
model_name = "inclusionai/ring-flash-2.0"
else:
# 默认或备用模型
model_name = "inclusionai/ling-1t"
logger.warning(f"未知的模型选项 '{model_choice}', 回退到默认模型 'inclusionai/ling-1t'")
history = [[user_prompt, None]]
temperature = 0.7
# For code, we don't want to escape HTML entities
yield from get_model_response(model_name, history, system_prompt, temperature, escape_html=False)
elif code_type == "Gradio 应用":
# Currently mocked
yield f"""
import gradio as gr
def greet(name):
return f"Hello, {user_prompt} a.k.a. {{name}}!"
with gr.Blocks() as demo:
gr.Markdown("## Simple Greeting App")
name_input = gr.Textbox(label="Enter your name")
greet_button = gr.Button("Greet")
output_text = gr.Textbox(label="Output")
greet_button.click(fn=greet, inputs=name_input, outputs=output_text)
demo.launch()
"""
else:
return
yield