Skip to content

Commit 2ea61b2

Browse files
committed
Make Codex AskUserQuestion fallback interactive
1 parent 3bef43b commit 2ea61b2

3 files changed

Lines changed: 45 additions & 13 deletions

File tree

scripts/resolvers/preamble/generate-ask-user-format.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,37 @@
11
import type { TemplateContext } from '../types';
22

33
export function generateAskUserFormat(_ctx: TemplateContext): string {
4-
return `## AskUserQuestion Format
4+
const toolResolution = _ctx.host === 'codex'
5+
? `"AskUserQuestion" can resolve to multiple interactive surfaces at runtime:
56
6-
### Tool resolution (read first)
7+
- the **host MCP variant** (e.g. \`mcp__conductor__AskUserQuestion\`) when the host registers it;
8+
- Codex's **\`request_user_input\`** tool, but only when it is present in the current tool list and the active mode/instructions allow calling it;
9+
- a **normal chat question fallback** when the Codex session is interactive but no AskUserQuestion-like tool is callable.
710
8-
"AskUserQuestion" can resolve to two tools at runtime: the **host MCP variant** (e.g. \`mcp__conductor__AskUserQuestion\` — appears in your tool list when the host registers it) or the **native** Claude Code tool.
11+
**Rule:** if any \`mcp__*__AskUserQuestion\` variant is in your tool list, prefer it. If \`request_user_input\` is present and current Codex instructions allow it, use that next. If neither tool is callable in Codex, ask the same decision brief as a concise normal chat question and wait for the user's answer. This fallback is degraded UI, not a gstack failure.
12+
13+
**If no callable AskUserQuestion-like tool appears in a Codex session, do NOT report \`BLOCKED -- AskUserQuestion unavailable\` by default.** Use the normal chat fallback for interactive sessions. Report \`BLOCKED -- AskUserQuestion unavailable\` only when the run is non-interactive, no user turn can be awaited, and no explicit \`/plan-tune\` AUTO_DECIDE or skill-specific non-interactive auto-decision rule applies. Never silently auto-decide.`
14+
: `"AskUserQuestion" can resolve to two tools at runtime: the **host MCP variant** (e.g. \`mcp__conductor__AskUserQuestion\` \u2014 appears in your tool list when the host registers it) or the **native** Claude Code tool.
915
1016
**Rule:** if any \`mcp__*__AskUserQuestion\` variant is in your tool list, prefer it. Hosts may disable native AUQ via \`--disallowedTools AskUserQuestion\` (Conductor does, by default) and route through their MCP variant; calling native there silently fails. Same questions/options shape; same decision-brief format applies.
1117
12-
**If no AskUserQuestion variant appears in your tool list, this skill is BLOCKED.** Stop, report \`BLOCKED — AskUserQuestion unavailable\`, and wait for the user. Do not write decisions to the plan file as a substitute, do not emit them as prose and stop, and do not silently auto-decide (only \`/plan-tune\` AUTO_DECIDE opt-ins authorize auto-picking).
18+
**If no AskUserQuestion variant appears in your tool list, this skill is BLOCKED.** Stop, report \`BLOCKED \u2014 AskUserQuestion unavailable\`, and wait for the user. Do not write decisions to the plan file as a substitute, do not emit them as prose and stop, and do not silently auto-decide (only \`/plan-tune\` AUTO_DECIDE opt-ins authorize auto-picking).`;
19+
const deliveryRule = _ctx.host === 'codex'
20+
? "Every AskUserQuestion is a decision brief. Send it as tool_use when a callable AskUserQuestion-like tool is available; in Codex chat fallback, render the same decision brief as normal prose and stop for the user's answer."
21+
: 'Every AskUserQuestion is a decision brief and must be sent as tool_use, not prose.';
22+
const deliveryChecklist = _ctx.host === 'codex'
23+
? 'You are calling the tool, or using the Codex chat fallback because no AskUserQuestion-like tool is callable'
24+
: 'You are calling the tool, not writing prose';
25+
26+
return `## AskUserQuestion Format
27+
28+
### Tool resolution (read first)
29+
30+
${toolResolution}
1331
1432
### Format
1533
16-
Every AskUserQuestion is a decision brief and must be sent as tool_use, not prose.
34+
${deliveryRule}
1735
1836
\`\`\`
1937
D<N> — <one-line question title>
@@ -106,7 +124,7 @@ Before calling AskUserQuestion, verify:
106124
- [ ] (recommended) label on one option (even for neutral-posture)
107125
- [ ] Dual-scale effort labels on effort-bearing options (human / CC)
108126
- [ ] Net line closes the decision
109-
- [ ] You are calling the tool, not writing prose
127+
- [ ] ${deliveryChecklist}
110128
- [ ] Non-ASCII characters (CJK / accents) written directly, NOT \\u-escaped
111129
- [ ] If you had 5+ options, you split (or batched into ≤4-groups) — did NOT drop any
112130
- [ ] If you split, you checked dependencies between options before firing the chain

scripts/resolvers/preamble/generate-completion-status.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,23 @@ import type { TemplateContext } from '../types';
2020
* the full rationale.
2121
*/
2222
export function generatePlanModeInfo(_ctx: TemplateContext): string {
23+
if (_ctx.host !== 'codex') {
24+
return `## Plan Mode Safe Operations
25+
26+
In plan mode, allowed because they inform the plan: \`$B\`, \`$D\`, \`codex exec\`/\`codex review\`, writes to \`~/.gstack/\`, writes to the plan file, and \`open\` for generated artifacts.
27+
28+
## Skill Invocation During Plan Mode
29+
30+
If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant \u2014 \`mcp__*__AskUserQuestion\` or native; see "AskUserQuestion Format \u2192 Tool resolution") satisfies plan mode's end-of-turn requirement. If no variant is callable, the skill is BLOCKED \u2014 stop and report \`BLOCKED \u2014 AskUserQuestion unavailable\` per the AskUserQuestion Format rule. At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION \u2014 ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.`;
31+
}
32+
2333
return `## Plan Mode Safe Operations
2434
2535
In plan mode, allowed because they inform the plan: \`$B\`, \`$D\`, \`codex exec\`/\`codex review\`, writes to \`~/.gstack/\`, writes to the plan file, and \`open\` for generated artifacts.
2636
2737
## Skill Invocation During Plan Mode
2838
29-
If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant — \`mcp__*__AskUserQuestion\` or native; see "AskUserQuestion Format → Tool resolution") satisfies plan mode's end-of-turn requirement. If no variant is callable, the skill is BLOCKED — stop and report \`BLOCKED — AskUserQuestion unavailable\` per the AskUserQuestion Format rule. At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.`;
39+
If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant -- \`mcp__*__AskUserQuestion\` or native; see "AskUserQuestion Format -> Tool resolution") satisfies plan mode's end-of-turn requirement. If no AskUserQuestion-like tool is callable in Codex, use the Codex chat fallback from "AskUserQuestion Format -> Tool resolution": ask the decision brief as a normal chat question and wait for the user. Report BLOCKED only for a genuinely non-interactive run with no allowed auto-decision. At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION -- ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.`;
3040
}
3141

3242
export function generateCompletionStatus(ctx: TemplateContext): string {

test/fixtures/golden/codex-ship-SKILL.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ In plan mode, allowed because they inform the plan: `$B`, `$D`, `codex exec`/`co
115115

116116
## Skill Invocation During Plan Mode
117117

118-
If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant — `mcp__*__AskUserQuestion` or native; see "AskUserQuestion Format → Tool resolution") satisfies plan mode's end-of-turn requirement. If no variant is callable, the skill is BLOCKED — stop and report `BLOCKED — AskUserQuestion unavailable` per the AskUserQuestion Format rule. At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.
118+
If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant -- `mcp__*__AskUserQuestion` or native; see "AskUserQuestion Format -> Tool resolution") satisfies plan mode's end-of-turn requirement. If no AskUserQuestion-like tool is callable in Codex, use the Codex chat fallback from "AskUserQuestion Format -> Tool resolution": ask the decision brief as a normal chat question and wait for the user. Report BLOCKED only for a genuinely non-interactive run with no allowed auto-decision. At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION -- ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.
119119

120120
If `PROACTIVE` is `"false"`, do not auto-invoke or proactively suggest skills. If a skill seems useful, ask: "I think /skillname might help here — want me to run it?"
121121

@@ -283,15 +283,19 @@ AI orchestrator (e.g., OpenClaw). In spawned sessions:
283283

284284
### Tool resolution (read first)
285285

286-
"AskUserQuestion" can resolve to two tools at runtime: the **host MCP variant** (e.g. `mcp__conductor__AskUserQuestion` — appears in your tool list when the host registers it) or the **native** Claude Code tool.
286+
"AskUserQuestion" can resolve to multiple interactive surfaces at runtime:
287287

288-
**Rule:** if any `mcp__*__AskUserQuestion` variant is in your tool list, prefer it. Hosts may disable native AUQ via `--disallowedTools AskUserQuestion` (Conductor does, by default) and route through their MCP variant; calling native there silently fails. Same questions/options shape; same decision-brief format applies.
288+
- the **host MCP variant** (e.g. `mcp__conductor__AskUserQuestion`) when the host registers it;
289+
- Codex's **`request_user_input`** tool, but only when it is present in the current tool list and the active mode/instructions allow calling it;
290+
- a **normal chat question fallback** when the Codex session is interactive but no AskUserQuestion-like tool is callable.
289291

290-
**If no AskUserQuestion variant appears in your tool list, this skill is BLOCKED.** Stop, report `BLOCKED — AskUserQuestion unavailable`, and wait for the user. Do not write decisions to the plan file as a substitute, do not emit them as prose and stop, and do not silently auto-decide (only `/plan-tune` AUTO_DECIDE opt-ins authorize auto-picking).
292+
**Rule:** if any `mcp__*__AskUserQuestion` variant is in your tool list, prefer it. If `request_user_input` is present and current Codex instructions allow it, use that next. If neither tool is callable in Codex, ask the same decision brief as a concise normal chat question and wait for the user's answer. This fallback is degraded UI, not a gstack failure.
293+
294+
**If no callable AskUserQuestion-like tool appears in a Codex session, do NOT report `BLOCKED -- AskUserQuestion unavailable` by default.** Use the normal chat fallback for interactive sessions. Report `BLOCKED -- AskUserQuestion unavailable` only when the run is non-interactive, no user turn can be awaited, and no explicit `/plan-tune` AUTO_DECIDE or skill-specific non-interactive auto-decision rule applies. Never silently auto-decide.
291295

292296
### Format
293297

294-
Every AskUserQuestion is a decision brief and must be sent as tool_use, not prose.
298+
Every AskUserQuestion is a decision brief. Send it as tool_use when a callable AskUserQuestion-like tool is available; in Codex chat fallback, render the same decision brief as normal prose and stop for the user's answer.
295299

296300
```
297301
D<N> — <one-line question title>
@@ -384,7 +388,7 @@ Before calling AskUserQuestion, verify:
384388
- [ ] (recommended) label on one option (even for neutral-posture)
385389
- [ ] Dual-scale effort labels on effort-bearing options (human / CC)
386390
- [ ] Net line closes the decision
387-
- [ ] You are calling the tool, not writing prose
391+
- [ ] You are calling the tool, or using the Codex chat fallback because no AskUserQuestion-like tool is callable
388392
- [ ] Non-ASCII characters (CJK / accents) written directly, NOT \u-escaped
389393
- [ ] If you had 5+ options, you split (or batched into ≤4-groups) — did NOT drop any
390394
- [ ] If you split, you checked dependencies between options before firing the chain

0 commit comments

Comments
 (0)