mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-03-18 12:40:06 +08:00
fix: issues with empty tool calls and handling excessively long tool results
This commit is contained in:
@@ -628,9 +628,28 @@ def _handle_linkai_stream_response(self, base_url, headers, body):
|
||||
break
|
||||
try:
|
||||
chunk = json.loads(line)
|
||||
yield chunk
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
|
||||
# Check for error responses within the stream
|
||||
# Some providers (e.g., MiniMax via LinkAI) return errors as:
|
||||
# {'type': 'error', 'error': {'type': '...', 'message': '...', 'http_code': '400'}}
|
||||
if chunk.get("type") == "error" or (
|
||||
isinstance(chunk.get("error"), dict) and "message" in chunk.get("error", {})
|
||||
):
|
||||
error_data = chunk.get("error", {})
|
||||
error_msg = error_data.get("message", "Unknown error") if isinstance(error_data, dict) else str(error_data)
|
||||
http_code = error_data.get("http_code", "") if isinstance(error_data, dict) else ""
|
||||
status_code = int(http_code) if http_code and str(http_code).isdigit() else 400
|
||||
logger.error(f"[LinkAI] stream error: {error_msg} (http_code={http_code})")
|
||||
yield {
|
||||
"error": True,
|
||||
"message": error_msg,
|
||||
"status_code": status_code
|
||||
}
|
||||
return
|
||||
|
||||
yield chunk
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"[LinkAI] stream response error: {e}")
|
||||
|
||||
@@ -285,10 +285,16 @@ class MinimaxBot(Bot):
|
||||
text_parts.append(block.get("text", ""))
|
||||
elif block.get("type") == "tool_result":
|
||||
# Tool result should be a separate message with role="tool"
|
||||
tool_call_id = block.get("tool_use_id") or ""
|
||||
if not tool_call_id:
|
||||
logger.warning(f"[MINIMAX] tool_result missing tool_use_id")
|
||||
result_content = block.get("content", "")
|
||||
if not isinstance(result_content, str):
|
||||
result_content = json.dumps(result_content, ensure_ascii=False)
|
||||
tool_results.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": block.get("tool_use_id"),
|
||||
"content": str(block.get("content", ""))
|
||||
"tool_call_id": tool_call_id,
|
||||
"content": result_content
|
||||
})
|
||||
|
||||
if text_parts:
|
||||
|
||||
@@ -233,56 +233,66 @@ class OpenAICompatibleBot:
|
||||
# Separate text content and tool_result blocks
|
||||
text_parts = []
|
||||
tool_results = []
|
||||
|
||||
|
||||
for block in content:
|
||||
if block.get("type") == "text":
|
||||
text_parts.append(block.get("text", ""))
|
||||
elif block.get("type") == "tool_result":
|
||||
tool_results.append(block)
|
||||
|
||||
|
||||
# First, add tool result messages (must come immediately after assistant with tool_calls)
|
||||
for block in tool_results:
|
||||
tool_call_id = block.get("tool_use_id") or ""
|
||||
if not tool_call_id:
|
||||
logger.warning(f"[OpenAICompatible] tool_result missing tool_use_id, using empty string")
|
||||
# Ensure content is a string (some providers require string content)
|
||||
result_content = block.get("content", "")
|
||||
if not isinstance(result_content, str):
|
||||
result_content = json.dumps(result_content, ensure_ascii=False)
|
||||
openai_messages.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": block.get("tool_use_id"),
|
||||
"content": block.get("content", "")
|
||||
"tool_call_id": tool_call_id,
|
||||
"content": result_content
|
||||
})
|
||||
|
||||
|
||||
# Then, add text content as a separate user message if present
|
||||
if text_parts:
|
||||
openai_messages.append({
|
||||
"role": "user",
|
||||
"content": " ".join(text_parts)
|
||||
})
|
||||
|
||||
|
||||
# Check if this is an assistant message with tool_use blocks
|
||||
elif role == "assistant":
|
||||
# Separate text content and tool_use blocks
|
||||
text_parts = []
|
||||
tool_calls = []
|
||||
|
||||
|
||||
for block in content:
|
||||
if block.get("type") == "text":
|
||||
text_parts.append(block.get("text", ""))
|
||||
elif block.get("type") == "tool_use":
|
||||
tool_id = block.get("id") or ""
|
||||
if not tool_id:
|
||||
logger.warning(f"[OpenAICompatible] tool_use missing id for '{block.get('name')}'")
|
||||
tool_calls.append({
|
||||
"id": block.get("id"),
|
||||
"id": tool_id,
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": block.get("name"),
|
||||
"arguments": json.dumps(block.get("input", {}))
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
# Build OpenAI format assistant message
|
||||
openai_msg = {
|
||||
"role": "assistant",
|
||||
"content": " ".join(text_parts) if text_parts else None
|
||||
}
|
||||
|
||||
|
||||
if tool_calls:
|
||||
openai_msg["tool_calls"] = tool_calls
|
||||
|
||||
|
||||
openai_messages.append(openai_msg)
|
||||
else:
|
||||
# Other list content, keep as is
|
||||
|
||||
Reference in New Issue
Block a user