fix: handle None message content across codebase (fixes #276)

The OpenAI API returns content: null on assistant messages with tool
calls. msg.get('content', '') returns None when the key exists with
value None, causing TypeError on len(), string concatenation, and
.strip() in downstream code paths.

Fixed 4 locations that process conversation messages:
- agent/auxiliary_client.py:84 — None passed to API calls
- cli.py:1288 — crash on content[:200] and len(content)
- run_agent.py:3444 — crash on None.strip()
- honcho_integration/session.py:445 — 'None' rendered in transcript

13 other instances were verified safe (already protected, only process
user/tool messages, or use the safe pattern).

Pattern: msg.get('content', '') → msg.get('content') or ''

Fixes #276
This commit is contained in:
teknium1 2026-03-02 02:23:53 -08:00
parent 1cb2311bad
commit 33ab5cec82
4 changed files with 4 additions and 4 deletions

View File

@ -81,7 +81,7 @@ class _CodexCompletionsAdapter:
input_msgs: List[Dict[str, Any]] = []
for msg in messages:
role = msg.get("role", "user")
content = msg.get("content", "")
content = msg.get("content") or ""
if role == "system":
instructions = content
else:

2
cli.py
View File

@ -1285,7 +1285,7 @@ class HermesCLI:
for i, msg in enumerate(self.conversation_history, 1):
role = msg.get("role", "unknown")
content = msg.get("content", "")
content = msg.get("content") or ""
if role == "user":
print(f"\n [You #{i}]")

View File

@ -442,7 +442,7 @@ class HonchoSessionManager:
for msg in messages:
ts = msg.get("timestamp", "?")
role = msg.get("role", "unknown")
content = msg.get("content", "")
content = msg.get("content") or ""
lines.append(f"[{ts}] {role}: {content}")
lines.append("")

View File

@ -3441,7 +3441,7 @@ class AIAgent:
self._codex_incomplete_retries += 1
interim_msg = self._build_assistant_message(assistant_message, finish_reason)
interim_has_content = bool(interim_msg.get("content", "").strip())
interim_has_content = bool((interim_msg.get("content") or "").strip())
interim_has_reasoning = bool(interim_msg.get("reasoning", "").strip()) if isinstance(interim_msg.get("reasoning"), str) else False
if interim_has_content or interim_has_reasoning: