Originally created by: yablokolabs
Some Qwen deployments behind OpenAI-compatible endpoints return tool calls as tagged text instead of native message.tool_calls, for example:
<tool_call>
<function=os.fs.read>
<parameter=path>/work/README.md</parameter>
</function>
</tool_call>
The tagged call may appear in message.content or message.reasoning_content. Atomic currently treats it as assistant text because the OpenAI response adapters only consume native message.tool_calls.
A second compatibility mismatch is that Atomic advertises flattened wire names such as os__fs__read, while the model can emit the human-facing dotted name os.fs.read.
This blocked a Tinker-hosted Qwen run on Atomic Agent v0.1.72 and remains reproducible by inspection on v0.1.73/current main (9d525ef4a004a9106608bea7a01ecd70ab279c2d).
openai-normalise-response.ts (github.com) reads native message.tool_calls, plain content, and reasoning_content, but does not recognize tagged tool syntax.
openai-tool-call-adapter.ts (github.com) advertises escaped tool names and only normalizes names after a native tool call has already been reconstructed.
Without translation, the tagged call is interpreted as ordinary assistant content or routed to reply instead of executing the requested tool.
When no native message.tool_calls are present, a provider adapter should optionally recognize valid tagged calls from content or reasoning_content, convert them to native calls, and canonicalize names against the tools actually offered in the request.
Both of these should resolve to the advertised os__fs__read tool:
os__fs__read
os.fs.read
Add a bounded compatibility parser at the OpenAI provider-adapter layer that:
<tool_call><function=...><parameter=...> format;A localhost adapter implementing this behavior enabled a meaningful 50-step Tinker/Qwen coding run.
content and reasoning_content.message.tool_calls remain the preferred path and behave unchanged.