|
3 | 3 | acknowledgeBridgeDelivery, |
4 | 4 | readNextPendingBridgeMessage, |
5 | 5 | } from "./bridge-dispatch"; |
| 6 | +import { quotedBridgeTool } from "./bridge-guidance"; |
6 | 7 | import { formatCodexBridgeMessage } from "./bridge-message-format"; |
7 | 8 | import { getLastClaudeSessionId } from "./claude-sdk-server"; |
8 | 9 | import { getLastCodexThreadId } from "./codex-app-server"; |
@@ -100,30 +101,31 @@ const bridgeGuidance = (agent: Agent): string => { |
100 | 101 | const target = agent === "claude" ? "codex" : "claude"; |
101 | 102 | return [ |
102 | 103 | "Paired mode:", |
103 | | - `You are in a persistent Claude/Codex pair. Use the MCP tool "send_message" with ${bridgeTargetLiteral(target)} when you want ${peer} to act, review, or answer.`, |
104 | | - 'Do not ask the human to relay messages between agents or answer the human on the other agent\'s behalf. Use "bridge_status" only if delivery looks stuck.', |
105 | | - 'Use "receive_messages" only if "bridge_status" shows pending messages addressed to you and direct delivery looks stuck.', |
| 104 | + `You are in a persistent Claude/Codex pair. Use the MCP tool ${quotedBridgeTool(agent, "send_message")} with ${bridgeTargetLiteral(target)} when you want ${peer} to act, review, or answer.`, |
| 105 | + `Do not ask the human to relay messages between agents or answer the human on the other agent's behalf. Use ${quotedBridgeTool(agent, "bridge_status")} only if delivery looks stuck.`, |
| 106 | + `Use ${quotedBridgeTool(agent, "receive_messages")} only if ${quotedBridgeTool(agent, "bridge_status")} shows pending messages addressed to you and direct delivery looks stuck.`, |
106 | 107 | ].join("\n"); |
107 | 108 | }; |
108 | 109 |
|
109 | | -const bridgeToolGuidance = [ |
110 | | - 'You can use the MCP tools "send_message", "bridge_status", and "receive_messages" for direct Claude/Codex coordination.', |
111 | | - 'Only use "bridge_status" or "receive_messages" when delivery looks stuck.', |
112 | | - "Do not ask the human to relay messages between agents.", |
113 | | -].join("\n"); |
| 110 | +const bridgeToolGuidance = (agent: Agent): string => |
| 111 | + [ |
| 112 | + `You can use the MCP tools ${quotedBridgeTool(agent, "send_message")}, ${quotedBridgeTool(agent, "bridge_status")}, and ${quotedBridgeTool(agent, "receive_messages")} for direct Claude/Codex coordination.`, |
| 113 | + `Only use ${quotedBridgeTool(agent, "bridge_status")} or ${quotedBridgeTool(agent, "receive_messages")} when delivery looks stuck.`, |
| 114 | + "Do not ask the human to relay messages between agents.", |
| 115 | + ].join("\n"); |
114 | 116 |
|
115 | 117 | const reviewDeliveryGuidance = (reviewer: Agent, opts: Options): string => { |
116 | 118 | if (reviewer === opts.agent) { |
117 | 119 | return "If review is needed, keep the actionable notes in your review body before the final review signal."; |
118 | 120 | } |
119 | 121 |
|
120 | | - return `If review is needed, send the actionable notes to ${capitalize(opts.agent)} with "send_message" using ${bridgeTargetLiteral(opts.agent)} before returning your final review signal.`; |
| 122 | + return `If review is needed, send the actionable notes to ${capitalize(opts.agent)} with ${quotedBridgeTool(reviewer, "send_message")} using ${bridgeTargetLiteral(opts.agent)} before returning your final review signal.`; |
121 | 123 | }; |
122 | 124 |
|
123 | 125 | const reviewToolGuidance = (reviewer: Agent, opts: Options): string => |
124 | 126 | reviewer === opts.agent |
125 | 127 | ? "Use the review body itself for follow-up notes. No bridge message is needed for a self-review." |
126 | | - : bridgeToolGuidance; |
| 128 | + : bridgeToolGuidance(reviewer); |
127 | 129 |
|
128 | 130 | const formatSelfReviewNotes = ( |
129 | 131 | failures: ReviewFailure[], |
@@ -158,22 +160,26 @@ const forwardBridgePrompt = ({ |
158 | 160 | }: { |
159 | 161 | message: string; |
160 | 162 | source: Agent; |
161 | | -}): string => |
162 | | - (source === "claude" |
163 | | - ? [ |
164 | | - formatCodexBridgeMessage(source, message), |
165 | | - "Treat this as direct agent-to-agent coordination. Do not reply to the human.", |
166 | | - 'Send a message to the other agent with "send_message" only when you have something useful for them to act on.', |
167 | | - "Do not acknowledge receipt without new information.", |
168 | | - ] |
169 | | - : [ |
170 | | - `Message from ${capitalize(source)} via the loop bridge:`, |
171 | | - message.trim(), |
172 | | - "Treat this as direct agent-to-agent coordination. Do not reply to the human.", |
173 | | - 'Send a message to the other agent with "send_message" only when you have something useful for them to act on.', |
174 | | - "Do not acknowledge receipt without new information.", |
175 | | - ] |
| 163 | +}): string => { |
| 164 | + const agent = source === "claude" ? "codex" : "claude"; |
| 165 | + const replyGuidance = `Send a message to the other agent with ${quotedBridgeTool(agent, "send_message")} only when you have something useful for them to act on.`; |
| 166 | + return ( |
| 167 | + source === "claude" |
| 168 | + ? [ |
| 169 | + formatCodexBridgeMessage(source, message), |
| 170 | + "Treat this as direct agent-to-agent coordination. Do not reply to the human.", |
| 171 | + replyGuidance, |
| 172 | + "Do not acknowledge receipt without new information.", |
| 173 | + ] |
| 174 | + : [ |
| 175 | + `Message from ${capitalize(source)} via the loop bridge:`, |
| 176 | + message.trim(), |
| 177 | + "Treat this as direct agent-to-agent coordination. Do not reply to the human.", |
| 178 | + replyGuidance, |
| 179 | + "Do not acknowledge receipt without new information.", |
| 180 | + ] |
176 | 181 | ).join("\n\n"); |
| 182 | +}; |
177 | 183 |
|
178 | 184 | const updateIds = (state: PairedState): void => { |
179 | 185 | const next = touchRunManifest( |
|
0 commit comments