feat: add persistent chat agent and indexed batch workflows
This commit is contained in:
@@ -101,6 +101,36 @@ class DeepSeekClient:
|
||||
time.sleep(min(2 ** attempt, 5))
|
||||
raise ModelError(f"模型请求或JSON校验失败({last_error}),已重试{self.retries}次")
|
||||
|
||||
def tool_call(self, messages: list[dict], tools: list[dict], *, tool_choice="auto"):
|
||||
"""OpenAI-compatible native tool calls. Credentials and provider bodies never enter logs."""
|
||||
body = {"model": self.model, "messages": messages, "tools": tools,
|
||||
"tool_choice": tool_choice, "temperature": 0}
|
||||
try:
|
||||
with httpx.Client(timeout=min(self.timeout, 180), transport=self.transport) as client:
|
||||
response = client.post(self.base_url + "/chat/completions", json=body,
|
||||
headers={"Authorization": f"Bearer {self.api_key}"})
|
||||
if response.status_code in (400, 404, 422):
|
||||
raise ModelError("当前端点或模型不支持原生 tool_calls;请在模型设置中配置支持工具调用的 OpenAI 兼容端点和模型")
|
||||
response.raise_for_status()
|
||||
message = response.json()["choices"][0]["message"]
|
||||
if not isinstance(message, dict) or not isinstance(message.get("tool_calls", []), list):
|
||||
raise ModelError("模型返回格式不包含有效的 tool_calls 消息")
|
||||
return {"role": "assistant", "content": message.get("content"), "tool_calls": message.get("tool_calls", [])}
|
||||
except ModelError:
|
||||
raise
|
||||
except (httpx.HTTPError, KeyError, IndexError, ValueError, TypeError) as exc:
|
||||
raise ModelError(f"对话模型请求失败({type(exc).__name__});请检查端点、模型和网络") from exc
|
||||
|
||||
def verify_tool_support(self):
|
||||
"""Small capability probe without student or course content."""
|
||||
probe = [{"type": "function", "function": {"name": "wisegrade_ping",
|
||||
"description": "Return a ping for compatibility verification.",
|
||||
"parameters": {"type": "object", "properties": {}, "additionalProperties": False}}}]
|
||||
# Some compatible endpoints implement auto tool selection but reject "required".
|
||||
response = self.tool_call([{"role": "user", "content": "For compatibility verification, call wisegrade_ping now and do not answer in text."}], probe)
|
||||
if not any(call.get("function", {}).get("name") == "wisegrade_ping" for call in response["tool_calls"]):
|
||||
raise ModelError("当前端点或模型未返回原生 tool_calls;请配置支持工具调用的端点和模型")
|
||||
|
||||
|
||||
def validate_score(result: ScoreResult, criterion: dict, chunks: list[dict]):
|
||||
if result.criterion_id != criterion["criterion_id"] or result.max_score != criterion["max_score"]:
|
||||
|
||||
Reference in New Issue
Block a user