Summary
Codex app-server source replies can finish successfully without any visible channel reply when source delivery resolves to message_tool_only and the active tool profile filters out the message dynamic tool.
This is especially confusing on WhatsApp direct chats: the inbound message is queued and processed, the Codex run completes with assistant text in the session/trajectory, but no message.delivery.* event fires and no WhatsApp reply is sent.
Observed behavior
- WhatsApp inbound direct message is accepted and routed to the Codex-backed agent.
- The Codex app-server run completes successfully and records assistant text.
- OpenClaw does not send an outbound channel reply.
- Manual
openclaw agent --deliver --reply-channel whatsapp --reply-account ... delivery still succeeds, so the WhatsApp account and outbound transport are healthy.
Root cause
The dispatch layer can resolve source replies to message_tool_only for Codex and intentionally suppress automatic final delivery. It also treats the message tool as available by adding a runtime policy allowance.
The Codex app-server dynamic-tool build path did not pass that same force flag into createOpenClawCodingTools(). With a common config like tools.profile = "coding", message is filtered out, leaving the model instructed to use a tool that is not actually present. The run can then complete privately with no visible channel output.
Expected behavior
When OpenClaw selects message_tool_only source delivery for Codex, the Codex dynamic tool list should include message even under restrictive profiles that normally omit messaging tools.
Fix direction
Pass forceMessageTool from the Codex app-server run params when sourceReplyDeliveryMode === "message_tool_only", matching the existing embedded-runner behavior, and cover the coding-profile case with a regression test.
Summary
Codex app-server source replies can finish successfully without any visible channel reply when source delivery resolves to
message_tool_onlyand the active tool profile filters out themessagedynamic tool.This is especially confusing on WhatsApp direct chats: the inbound message is queued and processed, the Codex run completes with assistant text in the session/trajectory, but no
message.delivery.*event fires and no WhatsApp reply is sent.Observed behavior
openclaw agent --deliver --reply-channel whatsapp --reply-account ...delivery still succeeds, so the WhatsApp account and outbound transport are healthy.Root cause
The dispatch layer can resolve source replies to
message_tool_onlyfor Codex and intentionally suppress automatic final delivery. It also treats the message tool as available by adding a runtime policy allowance.The Codex app-server dynamic-tool build path did not pass that same force flag into
createOpenClawCodingTools(). With a common config liketools.profile = "coding",messageis filtered out, leaving the model instructed to use a tool that is not actually present. The run can then complete privately with no visible channel output.Expected behavior
When OpenClaw selects
message_tool_onlysource delivery for Codex, the Codex dynamic tool list should includemessageeven under restrictive profiles that normally omit messaging tools.Fix direction
Pass
forceMessageToolfrom the Codex app-server run params whensourceReplyDeliveryMode === "message_tool_only", matching the existing embedded-runner behavior, and cover the coding-profile case with a regression test.