fix: handle non-string content from OpenAI-compatible servers (#759)
Some local LLM servers (llama-server, etc.) return message.content as a dict or list instead of a plain string. This caused AttributeError 'dict object has no attribute strip' on every API call. Normalizes content to string immediately after receiving the response: - dict: extracts 'text' or 'content' field, falls back to json.dumps - list: extracts text parts (OpenAI multimodal content format) - other: str() conversion Applied at the single point where response.choices[0].message is read in the main agent loop, so all downstream .strip()/.startswith()/[:100] operations work regardless of server implementation. Closes #759
This commit is contained in:
21
run_agent.py
21
run_agent.py
@@ -3834,6 +3834,27 @@ class AIAgent:
|
|||||||
else:
|
else:
|
||||||
assistant_message = response.choices[0].message
|
assistant_message = response.choices[0].message
|
||||||
|
|
||||||
|
# Normalize content to string — some OpenAI-compatible servers
|
||||||
|
# (llama-server, etc.) return content as a dict or list instead
|
||||||
|
# of a plain string, which crashes downstream .strip() calls.
|
||||||
|
if assistant_message.content is not None and not isinstance(assistant_message.content, str):
|
||||||
|
raw = assistant_message.content
|
||||||
|
if isinstance(raw, dict):
|
||||||
|
assistant_message.content = raw.get("text", "") or raw.get("content", "") or json.dumps(raw)
|
||||||
|
elif isinstance(raw, list):
|
||||||
|
# Multimodal content list — extract text parts
|
||||||
|
parts = []
|
||||||
|
for part in raw:
|
||||||
|
if isinstance(part, str):
|
||||||
|
parts.append(part)
|
||||||
|
elif isinstance(part, dict) and part.get("type") == "text":
|
||||||
|
parts.append(part.get("text", ""))
|
||||||
|
elif isinstance(part, dict) and "text" in part:
|
||||||
|
parts.append(str(part["text"]))
|
||||||
|
assistant_message.content = "\n".join(parts)
|
||||||
|
else:
|
||||||
|
assistant_message.content = str(raw)
|
||||||
|
|
||||||
# Handle assistant response
|
# Handle assistant response
|
||||||
if assistant_message.content and not self.quiet_mode:
|
if assistant_message.content and not self.quiet_mode:
|
||||||
print(f"{self.log_prefix}🤖 Assistant: {assistant_message.content[:100]}{'...' if len(assistant_message.content) > 100 else ''}")
|
print(f"{self.log_prefix}🤖 Assistant: {assistant_message.content[:100]}{'...' if len(assistant_message.content) > 100 else ''}")
|
||||||
|
|||||||
Reference in New Issue
Block a user