Bug Description
When using delegate_task(acp_command=...) to spawn a sub-agent via the ACP bridge (CopilotACPClient), the task always fails with:
TypeError: 'types.SimpleNamespace' object is not iterable
This is classified as a non-retryable local validation error (in run_agent.py line ~12533, the is_local_validation_error check), so the task is aborted immediately instead of retrying.
Steps to Reproduce
- Configure an ACP bridge script at
/usr/local/bin/thinkbox-acp that speaks JSON-RPC 2.0 over stdio (initialize → session/new → session/prompt)
- Call
delegate_task(acp_command="/usr/local/bin/thinkbox-acp", goal="uptime")
- Observe the error
Root Cause Analysis
The flow:
delegate_task creates a child AIAgent with provider="copilot-acp", acp_command="thinkbox-acp" (delegate_tool.py lines ~1004-1036)
- The child agent calls
CopilotACPClient.chat.completions.create() → returns a SimpleNamespace response (copilot_acp_client.py lines ~401-414)
- The child agent returns its result, including the raw
SimpleNamespace response
- The parent agent tries to process/iterate the response, specifically
assistant_message.tool_calls
- A
SimpleNamespace object is being used where an iterable (list) is expected → TypeError
The CopilotACPClient._create_chat_completion() returns:
SimpleNamespace(
choices=[SimpleNamespace(
message=SimpleNamespace(content=text, tool_calls=tool_calls_list_or_empty),
finish_reason="stop" or "tool_calls"
)],
usage=SimpleNamespace(...),
model=model
)
When tool_calls=[] (no tool calls), the downstream iteration over tool_calls seems to grab the wrong object — iterating the SimpleNamespace container instead of the list attribute.
Evidence
From agent.log (three occurrences across different sessions):
[subagent-0] Non-retryable client error: 'types.SimpleNamespace' object is not iterable
Direct usage of CopilotACPClient standalone works perfectly:
client = CopilotACPClient(command="thinkbox-acp", args=["--acp", "--stdio"])
resp = client.chat.completions.create(messages=[{"role": "user", "content": "uptime"}], model="any")
print(resp.choices[0].message.content) # ✅ Works fine
Workaround
Do NOT use delegate_task(acp_command=...). Instead:
- For delegated model calls: configure
delegation.model + delegation.provider in Hermes config
- For shell commands on remote: use
terminal() with direct SSH
- For direct ACP usage: instantiate
CopilotACPClient directly in Python code
Environment
- Hermes Agent repo: NousResearch/hermes-agent
- Commit: 0159f25 (current main)
- Python: 3.11+
- OS: Ubuntu 22.04 LTS
- Provider: copilot-acp
Bug Description
When using
delegate_task(acp_command=...)to spawn a sub-agent via the ACP bridge (CopilotACPClient), the task always fails with:This is classified as a non-retryable local validation error (in
run_agent.pyline ~12533, theis_local_validation_errorcheck), so the task is aborted immediately instead of retrying.Steps to Reproduce
/usr/local/bin/thinkbox-acpthat speaks JSON-RPC 2.0 over stdio (initialize → session/new → session/prompt)delegate_task(acp_command="/usr/local/bin/thinkbox-acp", goal="uptime")Root Cause Analysis
The flow:
delegate_taskcreates a childAIAgentwithprovider="copilot-acp",acp_command="thinkbox-acp"(delegate_tool.py lines ~1004-1036)CopilotACPClient.chat.completions.create()→ returns aSimpleNamespaceresponse (copilot_acp_client.py lines ~401-414)SimpleNamespaceresponseassistant_message.tool_callsSimpleNamespaceobject is being used where an iterable (list) is expected →TypeErrorThe
CopilotACPClient._create_chat_completion()returns:When
tool_calls=[](no tool calls), the downstream iteration overtool_callsseems to grab the wrong object — iterating theSimpleNamespacecontainer instead of the list attribute.Evidence
From agent.log (three occurrences across different sessions):
Direct usage of
CopilotACPClientstandalone works perfectly:Workaround
Do NOT use
delegate_task(acp_command=...). Instead:delegation.model+delegation.providerin Hermes configterminal()with direct SSHCopilotACPClientdirectly in Python codeEnvironment