Skip to content

Interactive parity with the Codex runtime: ask-user-question · plan mode · goal mode — the roadmap #102260

Description

@100yenadmin

The agent that asks, plans, and pursues. OpenClaw runs on the Codex runtime, but OpenClaw users don't get the three interactive primitives Codex-native users take for granted: the agent can't ask a structured question, can't enter a reviewable plan mode, and can't be handed a long-running goal it pursues on its own. This issue is the master hub for the series that closes that gap: the architecture, the PR, exactly how to try and test each feature, and the follow-up roadmap.

Interactive parity demo: mode selector → plan mode with a live checklist in the right sidebar → inline approval → agent question answered inline

The full flow — plan mode, the live plan pane, inline approval, and an inline agent question. A 30s narrated walkthrough covers goal mode too.

The gap, precisely (verified against both codebases)

Capability Codex-native OpenClaw before this series Delivered
Structured questions request_user_input — options + "(Recommended)" + free-text "Other"; the turn waits Codex sessions: degraded to plain text; native sessions: nothing Native ask_user_question + one question pipeline for both lanes, rendered on every surface, answerable cross-surface
Plan checklist update_plan → live turn/plan/updated Tool merged but experimental-flagged; events rendered as a bare text line Promoted default-on + a live plan panel
Plan mode ModeKind::Plan collaboration mode + /plan Nothing Read-only mode enforced at the tool choke point + approve-to-execute + plan artifact
Goal mode goal tools + an idle-continuation loop + "Pursuing goal" UI Goal state tools + /goal start|resume merged; no driver, no UI A gated, debounced continuation driver + goal chip + full lifecycle

The pattern worth noticing: the primitives were already merged (update_plan, goal state, a codex user-input bridge, stream:plan events, approval UIs, channel buttons) — this series is the completion layer. Every feature rides an existing choke point rather than inventing a parallel system: the question manager mirrors the exec-approval manager; the plan gate lives in the one before-tool-call hook every tool execution funnels through; the goal driver fires through the cron system-event path. That's why the diff stays small for what it delivers.

The mental model: one interaction pipeline, two producers

  • Native tools (all models)ask_user_question, plan-mode lifecycle tools, the goal driver: first-class OpenClaw features that work on Anthropic/Google/any model.
  • Codex pass-through (codex-runtime sessions) — the runtime's own request_user_input converges onto the same question pipeline (a structured answer and the legacy free-text path race; the loser is cancelled). Plan/goal wire bridges are documented follow-up seams.
  • One rendering surface, Codex-Desktop-shaped — in the Control UI, questions and plan-approval render as inline cards in the chat composer (not page-locking modals), the active plan docks in the right sidebar (always viewable, full checklist), a mode selector by the gear toggles plan/goal (mutually exclusive), and the goal editor is a focused modal. Telegram inline keyboards, Slack Block Kit, and numbered-text + /answer /plan /goal on every other channel. Ask on one surface, answer from another: resolution is global with scope/turn-source visibility, exactly like exec approvals today.
flowchart LR
  subgraph Producers["Two producers, one dialect"]
    N["🤖 Native tools (all models)<br/>ask_user_question · update_plan · plan mode · goal driver"]
    X["⚙️ Codex runtime pass-through<br/>item/tool/requestUserInput · turn/plan/updated"]
  end
  N --> GW["Gateway<br/>global QuestionManager (cross-surface resolve)<br/>plan state · goal state + goal.updated"]
  X --> GW
  GW --> UI["🖥️ Control UI<br/>inline composer cards · right-sidebar plan · mode selector · goal modal · Pursuing-goal pill"]
  GW --> TG["Telegram<br/>inline keyboards"]
  GW --> SL["Slack<br/>Block Kit buttons"]
  GW --> TXT["Every channel<br/>numbered text · /answer · /plan · /goal"]
Loading

Why the goal driver is safe to leave running

sequenceDiagram
  participant T as Turn completes
  participant D as Goal driver (debounced)
  participant G as 4 gates
  participant S as System-event turn
  T->>D: arm (debounce + jitter) — the ONLY thing that arms it
  D->>G: on wake: goal active? · no active run? · queue empty? · ceiling not hit?
  G-->>D: any gate fails → re-arm silently (no fire)
  G->>S: all pass → enqueue steering prompt + heartbeat wake
  S->>T: turn runs with NORMAL privileges — exec approvals still block (tested)
  Note over D: after a FIRE the driver never self-re-arms —<br/>only the next turn-completion arms it. No tight loop, by construction.
Loading

Layered brakes: debounce+jitter · the four gates · a durable no-progress ceiling (auto-pause, default 3) · budget limits (budget_limited disarms mid-wait) · an experimental flag (default off) · host-only pause/stop (the model can only mark complete|blocked, mirroring Codex).

🔍 Try it (per-feature test map)

Feature Do this Observe
Questions Ask something ambiguous, or have the agent call ask_user_question Inline card in the composer (not a modal); buttons pushed to Telegram/Slack; first option "(Recommended)"; "Other" free text; answer from a different surface than you asked
Modes Click the mode selector by the gear → Plan or Goal Mutually exclusive (can't have both); reflects /plan & /goal commands; switching while active confirms
Cross-surface Ask via a Telegram session, answer in the Control UI (or /answer 2 from anywhere) The parked tool resolves; the agent's next turn uses your answer
Restart safety Restart the gateway with a question pending question.expired fires; nothing hangs; the agent isn't stranded
Codex lane Trigger request_user_input in a codex-runtime session The same structured card (was: plain text); legacy free-text answering still works
Plan mode Mode selector → Plan (or /plan) → ask for a refactor plan Mutating tools refused with guidance; checklist ticks live in the right-sidebar plan pane; exit_plan_modeinline approval card in the composer; reject-with-feedback → revised plan; approve → executes
Plan artifact After approval ~/.openclaw/agents/<id>/plans/plan-<date>-<slug>.md; /plan show renders in-channel
Gate hardness In plan mode, try exec / an MCP tool / a plugin tool / spawning a subagent All vetoed at the single choke point (adversarial suite in-PR)
Goal mode /goal set "<objective>" --budget <n> (flag on) and walk away "Pursuing goal" chip; turns continue unattended; auto-pause on ceiling/budget; `/goal pause
Goal safety Trigger an exec approval during a driver-continued turn It blocks normally — the driver grants nothing

The PR

Follow-ups (filed as the post-merge roadmap; deliberately out of the first PR)

  • Codex plan-collaboration bridge — map OpenClaw plan mode onto ModeKind::Plan via thread settings (no plumbing exists in the codex extension today; documented seam).
  • Codex goal bridge — thread/goal/set|get|clear + thread/goal/updated ↔ session goal (same: seam documented, zero plumbing today).
  • Plan-mode power-ups — archetype prompting, escalating retry, plan-tier model routing (proven in a 156-case-parity-hardened plugin implementation; ported only if maintainers want them in core).
  • Question multi-select + secret inputs (isSecret is already in the shared schema).
  • Research-subagent allowance in plan mode (currently vetoed for gate hardness; relaxable by policy).

How this stays lean

No new dependencies anywhere in the series. Every human-in-the-loop interaction (questions, exit-plan approval, goal edit) is ONE pipeline — the same global-manager + scope-visibility pattern exec approvals already use. Features cluster in additive dirs; the tool gate is one policy at one choke point; the driver is one scheduler wired to two existing seams.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:ux-frictionUser-facing flow adds avoidable confusion or support burden without fully blocking progress.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.maturity:stableIssue affects a taxonomy feature currently scored M4/M5.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions