Skip to content

Commit 950e7d5

Browse files
authored
Revert "fix: prompt Codex to send visible channel replies (#84397)"
This reverts commit 47eb4ca.
1 parent 5c39e00 commit 950e7d5

16 files changed

Lines changed: 48 additions & 64 deletions

File tree

CHANGELOG.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ Docs: https://docs.openclaw.ai
2929
- Docker: keep the bundled Codex plugin in official release image keep lists so the default OpenAI agent harness remains available after Docker pruning. Fixes #83613. (#83626) Thanks @YuanHanzhong.
3030
- CLI/channels: preserve the first line of `openclaw channels logs` output when the rolling tail window starts exactly on a line boundary, mirroring the already-fixed `readLogSlice` behavior in `src/logging/log-tail.ts`.
3131
- Control UI: treat terminal session status as authoritative over stale active-run flags so completed terminal runs stop showing abort/live UI. (#84057)
32-
- Codex/message: tell message-tool-only Codex turns to send visible channel output with `message(action="send")` before ending, so direct replies do not stay private. Fixes #84129. (#84397) Thanks @joshavant.
3332
- CLI: preserve embedded equals signs in inline root option values instead of truncating after the second separator. (#83995) Thanks @ThiagoCAltoe.
3433
- Matrix/config: accept `messages.queue.byChannel.matrix` queue overrides and keep queue provider schema/type keys aligned for Matrix, Google Chat, and Mattermost. Thanks @bdjben.
3534
- CLI: format `openclaw acp client` failures through the shared error formatter so object-shaped errors stay readable instead of printing `[object Object]`. Fixes #83904. (#84080)

extensions/codex/src/app-server/run-attempt.test.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,12 +1402,7 @@ describe("runCodexAppServerAttempt", () => {
14021402
testing.buildDeveloperInstructions(params, {
14031403
dynamicTools: [createMessageDynamicTool("Message test tool")],
14041404
}),
1405-
).toContain('call `message` with `action="send"` before ending the turn');
1406-
expect(
1407-
testing.buildDeveloperInstructions(params, {
1408-
dynamicTools: [createMessageDynamicTool("Message test tool")],
1409-
}),
1410-
).toContain("Do not rely on normal final assistant text for visible delivery");
1405+
).toContain("To send a visible message, use the `message` tool.");
14111406

14121407
const withoutMessageToolInstructions = testing.buildDeveloperInstructions(params, {
14131408
dynamicTools: [],
@@ -1418,7 +1413,7 @@ describe("runCodexAppServerAttempt", () => {
14181413
params.sourceReplyDeliveryMode = "automatic";
14191414
const automaticInstructions = testing.buildDeveloperInstructions(params);
14201415
expect(automaticInstructions).toContain("active Codex delivery path");
1421-
expect(automaticInstructions).not.toContain('call `message` with `action="send"`');
1416+
expect(automaticInstructions).not.toContain("use the `message` tool");
14221417
});
14231418

14241419
it("includes Codex app-server scoped plugin command guidance in developer instructions", () => {

extensions/codex/src/app-server/thread-lifecycle.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -884,12 +884,7 @@ function buildVisibleReplyInstruction(
884884
? dynamicTools.some((tool) => tool.name.trim() === "message")
885885
: params.disableMessageTool !== true;
886886
if (params.sourceReplyDeliveryMode === "message_tool_only" && messageToolAvailable) {
887-
return [
888-
"Preserve channel/session context.",
889-
'If this turn needs visible output in the current channel, call `message` with `action="send"` before ending the turn.',
890-
"Do not rely on normal final assistant text for visible delivery; final text is private to OpenClaw/Codex in this mode.",
891-
'If no visible channel response is needed, do not call `message(action="send")`.',
892-
].join(" ");
887+
return "To send a visible message, use the `message` tool.";
893888
}
894889
return "To send a visible reply, use the active Codex delivery path.";
895890
}

src/agents/tools/message-tool.test.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -385,18 +385,16 @@ describe("message tool secret scoping", () => {
385385
const defaultTool = createMessageTool();
386386

387387
expect(scopedTool.description).toContain(
388-
'if visible output is needed in the current source conversation, call action="send" with message before ending',
388+
'use action="send" with message for visible replies to the current source conversation',
389389
);
390390
expect(scopedTool.description).toContain("target defaults to the current source conversation");
391-
expect(scopedTool.description).toContain(
392-
"Normal final answers stay private and are not visible in this mode",
393-
);
391+
expect(scopedTool.description).toContain("Normal final answers stay private");
394392
expect(explicitTargetTool.description).toContain("Include target when sending");
395393
expect(explicitTargetTool.description).not.toContain(
396394
"target defaults to the current source conversation",
397395
);
398396
expect(defaultTool.description).not.toContain(
399-
"if visible output is needed in the current source conversation",
397+
"visible replies to the current source conversation",
400398
);
401399
});
402400

@@ -407,7 +405,7 @@ describe("message tool secret scoping", () => {
407405
}).find((candidate) => candidate.name === "message");
408406

409407
expect(tool?.description).toContain(
410-
'if visible output is needed in the current source conversation, call action="send" with message before ending',
408+
'use action="send" with message for visible replies to the current source conversation',
411409
);
412410
});
413411

src/agents/tools/message-tool.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,7 @@ function appendMessageToolVisibleReplyHint(
859859
const targetGuidance = requireExplicitTarget
860860
? "Include target when sending."
861861
: "target defaults to the current source conversation; omit unless sending elsewhere.";
862-
return `${description} This turn: if visible output is needed in the current source conversation, call action="send" with message before ending. ${targetGuidance} Normal final answers stay private and are not visible in this mode.`;
862+
return `${description} This turn: use action="send" with message for visible replies to the current source conversation. ${targetGuidance} Normal final answers stay private.`;
863863
}
864864

865865
function appendMessageToolReadHint(

src/auto-reply/reply/dispatch-acp.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ describe("tryDispatchAcpReply", () => {
513513
expect(managerMocks.runTurn).toHaveBeenCalledTimes(1);
514514
const text = runTurnCall().text;
515515
expect(text).toContain("Source channel delivery is private by default");
516-
expect(text).toContain('call `message` with `action="send"` before ending');
516+
expect(text).toContain("message(action=send)");
517517
expect(text).toContain("The target defaults to the current source channel");
518518
expect(text).toContain("reply privately unless you send explicitly");
519519
});

src/auto-reply/reply/dispatch-acp.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ function resolveAcpTurnText(params: {
127127
[
128128
"Source channel delivery is private by default for this turn.",
129129
"Normal ACP final output will not be automatically posted to the source channel.",
130-
'If visible output is needed in the current source channel, call `message` with `action="send"` before ending. The target defaults to the current source channel.',
130+
"To send visible output, use message(action=send). The target defaults to the current source channel.",
131131
].join(" "),
132132
);
133133
return params.promptText ? `${guidance}\n\n${params.promptText}` : guidance;

src/auto-reply/reply/groups.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ describe("group runtime loading", () => {
4545
silentToken: "NO_REPLY",
4646
});
4747
expect(toolOnlyContext).toContain("Normal final replies are private");
48-
expect(toolOnlyContext).toContain('message tool with action="send" before ending');
48+
expect(toolOnlyContext).toContain("message tool with action=send");
4949
expect(toolOnlyContext).toContain("Be a good group participant");
5050
expect(toolOnlyContext).toContain("wrap bare URLs");
5151
expect(toolOnlyContext).toContain("<https://example.com>");
52-
expect(toolOnlyContext).toContain('do not call message(action="send")');
52+
expect(toolOnlyContext).toContain("do not call message(action=send)");
5353
expect(toolOnlyContext).not.toContain('reply with exactly "NO_REPLY"');
5454
expect(
5555
isolatedGroups.buildGroupIntro({
@@ -82,8 +82,8 @@ describe("group runtime loading", () => {
8282
sourceReplyDeliveryMode: "message_tool_only",
8383
});
8484
expect(toolOnlyContext).toContain("Normal final replies are private");
85-
expect(toolOnlyContext).toContain('message tool with action="send" before ending');
86-
expect(toolOnlyContext).toContain('do not call message(action="send")');
85+
expect(toolOnlyContext).toContain("message tool with action=send");
86+
expect(toolOnlyContext).toContain("do not call message(action=send)");
8787
expect(toolOnlyContext).not.toContain("NO_REPLY");
8888
expect(toolOnlyContext).not.toContain("Your replies are automatically sent");
8989
});

src/auto-reply/reply/groups.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ export function buildGroupChatContext(params: {
231231
lines.push(`You are in a ${providerLabel} group chat.`);
232232
if (messageToolOnly) {
233233
lines.push(
234-
'Normal final replies are private and are not automatically sent to this group chat. If this turn needs visible output here, call the message tool with action="send" before ending; the target defaults to this group chat.',
234+
"Normal final replies are private and are not automatically sent to this group chat. To post visible output here, use the message tool with action=send; the target defaults to this group chat.",
235235
);
236236
} else {
237237
lines.push(
@@ -255,7 +255,7 @@ export function buildGroupChatContext(params: {
255255
!messageToolOnly && params.silentToken && params.silentReplyPolicy !== "disallow";
256256
if (messageToolOnly) {
257257
lines.push(
258-
'If no visible group response is needed, do not call message(action="send"). Your normal final answer stays private and will not be posted to the group.',
258+
"If no visible group response is needed, do not call message(action=send). Your normal final answer stays private and will not be posted to the group.",
259259
);
260260
}
261261
if (canUseSilentReply) {
@@ -286,10 +286,10 @@ export function buildDirectChatContext(params: {
286286
lines.push(`You are in a ${providerLabel} direct conversation.`);
287287
if (messageToolOnly) {
288288
lines.push(
289-
'Normal final replies are private and are not automatically sent to this conversation. If this turn needs visible output here, call the message tool with action="send" before ending; the target defaults to this conversation.',
289+
"Normal final replies are private and are not automatically sent to this conversation. To post visible output here, use the message tool with action=send; the target defaults to this conversation.",
290290
);
291291
lines.push(
292-
'If no visible direct response is needed, do not call message(action="send"). Your normal final answer stays private and will not be posted to the conversation.',
292+
"If no visible direct response is needed, do not call message(action=send). Your normal final answer stays private and will not be posted to the conversation.",
293293
);
294294
return lines.join(" ");
295295
}

src/auto-reply/reply/inbound-meta.test.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,7 @@ describe("buildInboundUserContextPrefix", () => {
300300
{ sourceReplyDeliveryMode: "message_tool_only" },
301301
);
302302

303-
expect(text).toContain(
304-
'Delivery: if this turn needs visible output in the current source conversation, call `message` with `action="send"` before ending.',
305-
);
303+
expect(text).toContain("Delivery: to send a message, use the `message` tool.");
306304
expect(text.indexOf("Delivery:")).toBeLessThan(text.indexOf("Conversation info"));
307305
expect(text).toContain("Conversation info (untrusted metadata):");
308306
});
@@ -319,7 +317,7 @@ describe("buildInboundUserContextPrefix", () => {
319317
{ sourceReplyDeliveryMode: "automatic" },
320318
);
321319

322-
expect(text).not.toContain("Delivery: if this turn needs visible output");
320+
expect(text).not.toContain("Delivery: to send a message");
323321
expect(text).toContain("Conversation info (untrusted metadata):");
324322
});
325323

0 commit comments

Comments
 (0)