Skip to content

feat: ask_user β€” structured questions from the agent with web card, channel buttons, and text answers#109922

Merged
steipete merged 20 commits into
mainfrom
feat/ask-user-tool
Jul 17, 2026
Merged

feat: ask_user β€” structured questions from the agent with web card, channel buttons, and text answers#109922
steipete merged 20 commits into
mainfrom
feat/ask-user-tool

Conversation

@steipete

Copy link
Copy Markdown
Contributor

Related: #109724 (Codex-parity slice 1: this PR is the provider-neutral question RPC that PR deliberately deferred)

What Problem This Solves

Agents had no first-class way to ask the human a structured question and wait for the answer. The embedded agent could only guess or write prose questions into chat; Codex harness questions got a text-only prompt on channels; and there was no provider-neutral pause/prompt/resume primitive that web UI and message channels could share (the pattern Claude Code ships as AskUserQuestion and Codex ships as request_user_input).

Why This Change Was Made

This adds the provider-neutral question runtime deferred by #109724, modeled on the existing exec-approval subsystem (the established blocking pause→prompt→resume template):

  • Gateway question runtime: transient in-memory question.request / question.waitAnswer / question.resolve / question.get / question.list RPCs plus question.requested / question.resolved broadcasts under a new operator.questions scope (additive; no protocol version bump). Answers are validated against the stored record (unknown ids, cardinality, option membership) and canonicalized before terminalizing; isSecret and duplicate option labels are rejected at the request boundary.
  • ask_user tool for the embedded agent (main sessions only, not subagents): 1–3 questions, 2–4 options each (labels ≀64 chars), multiSelect, free-text "Other" always available, recommended-option-first convention, timeoutSeconds 30–3600 (default 900). The tool blocks like exec approvals; expiry returns a no_answer result telling the model to proceed with best judgment.
  • Chat delivery: the question is delivered to the originating conversation while the tool blocks β€” as a MessagePresentation with native tap-to-answer buttons via a new runtime-authored {type:"question"} presentation action (Telegram inline keyboards tgq1: ≀64 bytes, Discord custom ids ocq ≀100 chars, Slack Block Kit slq1:), degrading to numbered text on button-less channels. A plain text reply (number, label, or free text) answers on any channel; the reply is consumed as the answer instead of steering into the run.
  • Control UI: one unified in-thread question card serving both gateway ask_user questions (broadcast-driven, click/multi-select/free-text, resolve over the gateway, terminal states incl. answered-elsewhere/expired) and the existing Codex stream questions from feat(codex): surface native questions and goalsΒ #109724 (composer submit path unchanged).

Codex upstream contract checked directly at openai/codex@9ff47868eb: codex-rs/core/src/tools/handlers/request_user_input_spec.rs, codex-rs/protocol/src/request_user_input.rs, codex-rs/app-server-protocol/src/protocol/v2/item.rs:1585-1637 (schema conventions: header ≀12 chars, recommended-first, forced free-text "Other", root-thread-only β€” mirrored here). Converging the Codex/Copilot harness bridges onto this runtime is a named follow-up, not part of this PR.

User Impact

Agents can now pause and ask a real question with buttons. Users answer by clicking in the web Control UI, tapping a native button on Telegram/Discord/Slack, or just replying in text on any channel; the agent resumes with structured answers. Docs: docs/tools/ask-user.md.

Pending card (web):
pending
Answered:
answered
MultiSelect:
multiselect
Terminal states (answered elsewhere / expired):
terminal

Evidence

  • Live end-to-end proof on a source-checkout gateway (isolated --dev state dir, anthropic/claude-opus-4-8): agent called ask_user with a single-select + multiSelect pair, blocked 1m03s, the web card rendered in-thread, options were clicked (Staging + Integration/E2E), the gateway resolved, and the agent resumed enumerating exactly those answers. This live run also caught and fixed a gating bug (isEmbeddedMode() is the TUI-host flag, not the embedded-runner flag β€” ask_user was invisible to normal gateway runs until commit ce0251e6bb9's fix).
  • Playwright e2e ui/src/e2e/question-flow.e2e.test.ts (3 tests, mock gateway): render β†’ resolve payload shape ({answers:{deploy_target:{answers:["Staging (Recommended)"]}}}) β†’ resolved state; multiSelect arrays; answered-elsewhere + expired terminal states. Screenshots above are its artifacts.
  • Focused suites (local, node scripts/run-vitest.mjs): gateway question manager + RPC handlers + protocol validators, ask_user tool (normalize/execute/claim/abort races), subscriber delivery, outbound presentation precedence, per-channel envelope round-trips incl. byte limits, UI prompt state machine + card + thread placement β€” all green (500+ tests across the touched files).
  • Typecheck/lint: tsgo:core, tsgo:core:test, tsgo:extensions, tsgo:extensions:test, tsgo:ui, tsgo:test:ui, targeted oxlint β€” green (Testbox + local fallback when Testbox returned 429).
  • Build: full pnpm build green, no [INEFFECTIVE_DYNAMIC_IMPORT].
  • Autoreview (Codex gpt-5.6-sol, xhigh): three iterations; 7 findings accepted and fixed (answer validation at resolve, isSecret fail-closed, duplicate-label rejection, UI retry latch, reconnect QUESTION_NOT_FOUND terminalization, option-label bound, answer canonicalization); final run clean β€” "no accepted/actionable findings".

Follow-ups (intentionally out of scope): converge Codex/Copilot harness user-input bridges onto the question runtime; reaction-based answering on WhatsApp/Signal/iMessage; unbind channel buttons after resolution; MCP elicitation routing (pending the 2026-07-28 MRTR spec).

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord channel: slack Channel integration: slack channel: telegram Channel integration: telegram app: web-ui App: web-ui gateway Gateway runtime scripts Repository scripts agents Agent runtime and tooling size: XL maintainer Maintainer-authored PR labels Jul 17, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f86c661a13

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +71 to +72
"question.requested",
"question.resolved",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Map question broadcasts in the public SDK

When these Gateway events are added, SDK consumers still cannot observe them as stable question events: packages/sdk/src/normalize.ts:157-166 only maps approval/task/session broadcasts and otherwise returns raw, even though packages/sdk/src/types.ts:291-292 already exposes question event types. Any integration using normalizeGatewayEvent will see ask_user question broadcasts as raw events instead of question.requested/question.answered, so please add the corresponding normalization cases with tests.

Useful? React with πŸ‘Β / πŸ‘Ž.

Comment on lines +472 to +477
if (
current &&
missingResult?.status === "rejected" &&
isQuestionNotFoundError(missingResult.reason)
) {
markResolvedElsewhere(state, current);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve locally expired question state on reconnect

If the UI has already marked a prompt locallyExpired, then reconnects after the Gateway's terminal-record grace window, question.get returns QUESTION_NOT_FOUND and this path rewrites the card to answeredElsewhere. That makes an expired ask_user prompt show the wrong terminal state; keep the existing expired state when current.locallyExpired is true instead of calling markResolvedElsewhere.

Useful? React with πŸ‘Β / πŸ‘Ž.

@steipete
steipete force-pushed the feat/ask-user-tool branch from f86c661 to 8520893 Compare July 17, 2026 10:54
@clawsweeper clawsweeper Bot added proof: πŸ“Έ screenshot Contributor real behavior proof includes screenshot evidence. rating: πŸ¦ͺ silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: πŸ“£ needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. labels Jul 17, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 85208937b9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

...(params.config?.tools?.deny ?? []),
...(params.pluginToolDenylist ?? []),
]);
return isPrimaryBootstrapRun(sessionKey) && isToolAllowedByPolicyName("ask_user", { deny });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude cron runs from ask_user registration

When a scheduled/background run has a cron session key such as agent:main:cron:job:run:abc, this gate still returns true because isPrimaryBootstrapRun only filters subagent/ACP keys. That exposes the blocking ask_user tool outside an interactive user turn, so a cron job that calls it can stall for the default 15-minute timeout and any prompt is tied to the run-scoped cron session instead of the user's active chat. Please exclude cron/background session keys or require an interactive inbound run before registering the tool.

Useful? React with πŸ‘Β / πŸ‘Ž.

@clawsweeper
clawsweeper Bot temporarily deployed to qa-live-shared July 17, 2026 11:05 Inactive
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. and removed rating: πŸ¦ͺ silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 17, 2026
@clawsweeper

clawsweeper Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 17, 2026, 5:17 PM ET / 21:17 UTC.

Summary
Adds a provider-neutral ask_user tool backed by transient Gateway question RPCs, Control UI cards, native Telegram/Discord/Slack choice controls, text-answer handling, protocol/SDK models, docs, and supporting CI updates.

Reproducibility: yes. from source: use a limited-scope native client lacking operator.questions, or force a same-channel delivery failure after the dispatcher enqueues an ask_user prompt; both paths leave the intended question flow unavailable or waiting.

Review metrics: 1 noteworthy metric.

  • Public interaction contract: 5 Gateway RPCs, 2 broadcasts, 1 operator scope, 1 plugin SDK subpath added. This is a durable cross-client and plugin-facing API expansion, so compatibility and ownership need an explicit maintainer decision before merge.

Stored data model
Persistent data-model change detected: migration/backfill/repair: .github/workflows/ci.yml, unknown-truncated-pull-files. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦐 gold shrimp
Patch quality: 🦐 gold shrimp
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Update native limited-scope profile issuance and add focused regression coverage.
  • Make prompt delivery confirmation or failure terminalize the blocking question correctly.
  • Attach a redacted final-head Telegram, Discord, or Slack live run showing delivery, answer, and resume.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The provided Telegram recording is positive but predates the final head; add redacted final-head proof showing channel delivery, answer resolution, and the resumed agent, with private identifiers and endpoints removed. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Mantis proof suggestion
A final-head Telegram recording would directly verify the changed native button delivery and answer-resume path that the available older candidate proof does not cover. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis telegram desktop proof: verify final-head ask_user question delivery, native button answer resolution, and resumed agent output with redacted evidence.

Risk before merge

  • [P1] Existing limited-scope native clients may silently lose access to question RPCs and broadcasts because their issued profiles do not include the new operator.questions scope.
  • [P2] A channel send failure can leave an agent waiting for the full question timeout even though the user never received the prompt.
  • [P1] The final head lacks after-fix live evidence covering delivery, answer resolution, and resume on an affected channel.

Maintainer options:

  1. Repair client scope and delivery confirmation (recommended)
    Update every native limited-scope issuance path and make ask_user settle only after a concrete delivery result, with regression coverage for both failures.
  2. Accept a staged client rollout
    Merge only if maintainers explicitly accept that existing limited-scope native clients require reissue or upgrade before they can observe questions.
  3. Pause the shared API contract
    Defer this broad Gateway/plugin surface if maintainers do not want to support the new permission and delivery guarantees across clients yet.

Next step before merge

  • [P1] The identified fixes are mechanical, but the protected maintainer label and new permanent Gateway/plugin contract require a human product-direction decision before automation proceeds.

Maintainer decision needed

  • Question: Should OpenClaw adopt question.*, operator.questions, and plugin-sdk/question-gateway-runtime as the permanent cross-client/plugin contract for provider-neutral human input?
  • Rationale: This PR introduces a new durable Gateway permission family and public plugin SDK subpath; the repository policy treats those compatibility-sensitive surfaces as requiring maintainer-visible direction beyond a mechanical patch review.
  • Likely owner: steipete β€” They authored the merged adjacent question surface and this proposed shared-runtime continuation.
  • Options:
    • Sponsor the provider-neutral contract (recommended): Keep the new Gateway and SDK surface, first fixing native scope compatibility and delivery settlement before merge.
    • Narrow to an existing owner surface: Retain the user-facing capability but remove or redesign the new public plugin SDK contract around an already-approved interaction seam.
    • Defer the shared runtime: Keep the existing Codex-specific flow and reopen provider-neutral questions only with an approved cross-client API proposal.

Security
Cleared: The broad diff includes CI and protocol work, but the reviewed changes show no concrete credential, permission-escalation, dependency-source, or supply-chain defect.

Review findings

  • [P2] Grant operator.questions to native operator profiles β€” src/gateway/operator-scopes.ts:6
  • [P2] Await prompt delivery before enabling an answer β€” src/auto-reply/reply/dispatch-from-config.ts:2364-2369
Review details

Best possible solution:

Land a single provider-neutral question contract only after native scope issuance is updated, prompt delivery is coupled to a real delivery outcome, and redacted final-head channel proof shows prompt delivery, answer resolution, and agent resume.

Do we have a high-confidence way to reproduce the issue?

Yes, from source: use a limited-scope native client lacking operator.questions, or force a same-channel delivery failure after the dispatcher enqueues an ask_user prompt; both paths leave the intended question flow unavailable or waiting.

Is this the best way to solve the issue?

No. The shared runtime is plausible, but it must preserve existing native operator access and couple the blocking tool to real prompt-delivery success before it is a safe permanent contract.

Full review comments:

  • [P2] Grant operator.questions to native operator profiles β€” src/gateway/operator-scopes.ts:6
    Adding the new scope to the Gateway methods is not enough: limited-scope native profiles still omit it, so previously paired non-admin clients cannot subscribe to question events or call question.*. Add the scope to each profile issuance/allowlist path and cover the upgrade behavior.
    Confidence: 0.94
  • [P2] Await prompt delivery before enabling an answer β€” src/auto-reply/reply/dispatch-from-config.ts:2364-2369
    The ask_user path becomes answerable after the dispatcher enqueue returns, but actual channel delivery happens later and failures are swallowed. A failed send therefore leaves the run blocked until timeout without a user-visible question; settle from a real delivery result or cancel with the existing delivery-failed path.
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.87

AGENTS.md: unclear because the file could not be read completely.

Codex review notes: model internal, reasoning high; reviewed against 84f5d6d978c8.

Label changes

Label justifications:

  • P2: The feature is broadly useful, but the demonstrated gaps affect limited-scope clients and failed channel-delivery handling rather than an active emergency regression.
  • merge-risk: 🚨 compatibility: Adding operator.questions without updating existing limited-scope native profiles can make otherwise-authorized clients unable to use the new feature after upgrade.
  • merge-risk: 🚨 message-delivery: The new pause-and-answer workflow can wait for an answer even when the channel prompt was never delivered.
  • merge-risk: 🚨 availability: A failed prompt delivery can stall an affected agent run until the configured question timeout expires.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🦐 gold shrimp.
  • status: πŸ“£ needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The provided Telegram recording is positive but predates the final head; add redacted final-head proof showing channel delivery, answer resolution, and the resumed agent, with private identifiers and endpoints removed. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • proof: πŸŽ₯ video: Contributor real behavior proof includes video or recording evidence. The provided Telegram recording is positive but predates the final head; add redacted final-head proof showing channel delivery, answer resolution, and the resumed agent, with private identifiers and endpoints removed.
  • mantis: telegram-visible-proof: Mantis should capture Telegram visible proof. Telegram inline question buttons and answer feedback are directly user-visible and are suitable for a short final-head desktop recording.
Evidence reviewed

What I checked:

  • New operator scope: The branch adds operator.questions and gates question broadcasts behind it, creating a new permission requirement for all question-capable clients. (src/gateway/operator-scopes.ts:6, 167f6842aa30)
  • Native profile compatibility gap: The prior review verified that native limited-scope profile allowlists in src/shared/device-bootstrap-profile.ts, apps/shared/OpenClawKit/Sources/OpenClawKit/GatewayChannelSupport.swift, and Android GatewaySession.kt still omit operator.questions; those clients cannot call the new RPCs or subscribe to its events until their profiles are updated or reissued. (src/shared/device-bootstrap-profile.ts:22, 167f6842aa30)
  • Delivery settlement remains asynchronous: The current review discussion identifies that onToolResult enqueues channel delivery through the dispatcher, while later delivery failures are swallowed by its send chain; marking the question answerable at enqueue time can leave the agent blocked until timeout after a failed Telegram, Discord, or Slack send. (src/auto-reply/reply/dispatch-from-config.ts:2364, 167f6842aa30)
  • Final-head proof mismatch: The Mantis Telegram desktop evidence covers candidate SHA 85208937b9615cc700da9bcb7e89c1e7b0d274f3, whereas the current PR head is 167f6842aa305e932a5aaec9fdafa6085a1f9988; it therefore does not demonstrate the final code path after the later fixes. (167f6842aa30)
  • Related merged predecessor: Merged feat(codex): surface native questions and goalsΒ #109724 established the Codex-specific structured-question/UI slice and explicitly deferred this provider-neutral runtime, so this PR remains a distinct feature rather than duplicate work. (2b18ef742648)

Likely related people:

  • steipete: Authored the merged Codex structured-question predecessor and the proposed provider-neutral follow-up, making them the strongest available routing candidate for the question-runtime boundary. (role: recent adjacent feature contributor; confidence: medium; commits: 2b18ef742648; files: ui/src/pages/chat/components/chat-question-card.ts, src/gateway/question-manager.ts)
What the crustacean ranks mean
  • πŸ¦€ challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • πŸ¦ͺ silver shellfish: thin signal; proof, validation, or implementation needs work.
  • πŸ§‚ unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (8 earlier review cycles)
  • reviewed 2026-07-17T11:10:05.061Z sha 8520893 :: needs real behavior proof before merge. :: [P2] Normalize question broadcasts in the public SDK | [P2] Exclude cron and background runs from ask_user
  • reviewed 2026-07-17T11:27:06.979Z sha 78cf16e :: needs real behavior proof before merge. :: [P2] Normalize question events before exposing SDK variants | [P2] Exclude cron and background runs from ask_user
  • reviewed 2026-07-17T11:56:31.384Z sha e94ca58 :: found issues before merge. :: [P1] Preserve ask_user through default progress suppression | [P2] Key question reservations by the run session | [P2] Normalize question broadcasts before returning SDK events | [P2] Exclude scheduled runs from ask_user registration
  • reviewed 2026-07-17T17:27:17.726Z sha 8c64e76 :: found issues before merge. :: [P2] Treat partial text answers as retryable non-resolutions | [P2] Generate the Swift wait and resolve question models
  • reviewed 2026-07-17T19:39:19.503Z sha b5a9a22 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-17T20:16:17.545Z sha 1f7fe11 :: needs real behavior proof before merge. :: [P2] Grant operator.questions to native operator profiles
  • reviewed 2026-07-17T20:25:15.024Z sha 4d09284 :: needs real behavior proof before merge. :: [P2] Grant operator.questions to native operator profiles
  • reviewed 2026-07-17T20:35:12.252Z sha 167f684 :: needs real behavior proof before merge. :: [P2] Grant operator.questions to native operator profiles

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 78cf16efb3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1908 to +1910
if (hasAskUserPayload(payload)) {
return payload;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve ask_user prompts through progress suppression

When channel runs use the default verbose setting, this new hasAskUserPayload pass-through is still dropped by the later default-progress gate at dispatch-from-config.ts:2351-2358, which only allows media or exec approvals. In Slack/Discord/Telegram default sessions, an ask_user prompt has channelData.askUser but no media/exec approval and isForcedToolProgress is false, so the user never sees the question and the tool blocks until timeout; carry the ask_user exemption through that later gate too.

Useful? React with πŸ‘Β / πŸ‘Ž.

}

public struct QuestionGetResult: Codable, Sendable {
public let question: QuestionRequestedEvent

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Emit the missing Swift question record type

The generated model now uses QuestionRequestedEvent for question.get/question.list, but this commit never emits that type (repo-wide search finds only these references). Building OpenClawKit after this change fails with an unresolved type before any client can consume the new question API; add a concrete question record/event model or use an existing generated shape for these results.

Useful? React with πŸ‘Β / πŸ‘Ž.

@openclaw-mantis

Copy link
Copy Markdown
Contributor

Mantis Telegram Desktop Proof

Summary: Mantis captured native Telegram Desktop before/after GIFs for the deploy target question and inline answer buttons.

Main screenshot This PR screenshot
Baseline native Telegram Desktop screenshot Candidate native Telegram Desktop screenshot
Main This PR
Baseline native Telegram Desktop proof GIF Candidate native Telegram Desktop proof GIF

Motion-trimmed clips:

Raw QA files: https://artifacts.openclaw.ai/mantis/telegram-desktop/pr-109922/run-29575568650-1/index.json

@clawsweeper clawsweeper Bot added status: πŸ“£ needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed status: πŸ‘€ ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 17, 2026
@steipete
steipete force-pushed the feat/ask-user-tool branch from 38f03bd to db09a1e Compare July 17, 2026 20:02

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: db09a1ef56

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +63 to +67
{ name: "question.request", scope: "operator.questions" },
{ name: "question.waitAnswer", scope: "operator.questions" },
{ name: "question.resolve", scope: "operator.questions" },
{ name: "question.get", scope: "operator.questions" },
{ name: "question.list", scope: "operator.questions" },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add question scope to native operator profiles

These new RPCs now require operator.questions, but the native/mobile operator scope allowlists were not updated: I checked src/shared/device-bootstrap-profile.ts:22-35, apps/shared/OpenClawKit/Sources/OpenClawKit/GatewayChannelSupport.swift:50-55, and apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewaySession.kt:1081-1088, and all still omit this scope. Admin-scoped clients bypass the check, but limited QR/setup-code or non-admin stored native tokens will be unable to call question.* or receive the new question broadcasts, so paired native clients that otherwise have read/write/approval access silently miss ask_user prompts until they are reissued with the new scope.

Useful? React with πŸ‘Β / πŸ‘Ž.

@clawsweeper clawsweeper Bot removed the merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. label Jul 17, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4d092848ca

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

});
})
.then(
() => settleAskUserPromptDelivery(questionId),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Await real ask_user prompt delivery before settling

On ordinary same-channel deliveries, onToolResult only enqueues dispatcher.sendToolResult; the dispatcher returns synchronously and swallows later deliver/before-deliver failures in its send chain (src/auto-reply/reply/reply-dispatcher.ts:449-483, called from src/auto-reply/reply/dispatch-from-config.ts:2364-2369). This line therefore marks the ask_user prompt answerable before the Slack/Discord/Telegram message has actually been sent, so a send failure leaves the tool blocking until timeout instead of taking the prompt-delivery-failed cancellation path. Please settle from a real delivery outcome for ask_user payloads or otherwise await actual delivery before marking it answerable.

Useful? React with πŸ‘Β / πŸ‘Ž.

@clawsweeper clawsweeper Bot added the merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. label Jul 17, 2026
@steipete
steipete merged commit da44d52 into main Jul 17, 2026
132 checks passed
@steipete
steipete deleted the feat/ask-user-tool branch July 17, 2026 21:24
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 18, 2026
…hannel buttons, and text answers (openclaw#109922)

* feat(gateway): add transient question runtime (question.* methods + broadcasts)

* feat(agents): add blocking ask_user question tool with chat prompt delivery and text-reply claim

* feat(ui): interactive in-thread question cards for ask_user

* feat(channels): native tap-to-answer buttons for ask_user on Telegram, Discord, and Slack

* feat(ui): unify codex and gateway question cards with interactive gateway answering

* refactor(agents): collapse ask_user pending state to one registry; docs for ask_user

* fix(agents): include ask_user in normal gateway runs; add question-flow control-ui e2e

* test(ui): avoid credential-shaped fixture in question card test

* refactor(ui): reorder stream-group context keys

* fix(gateway,ui): validate question answers at resolve; reject secret/duplicate-label questions; UI retry and reconnect hardening

* fix(gateway,agents): canonicalize accepted option answers; bound ask_user option labels to 64 chars

* chore(ci): prune unused question exports, allowlist mobile question events, fix discord lint

* chore(ci): regenerate protocol/i18n/docs/tool-display artifacts for question surface

* fix(protocol): flatten QuestionRecord for native codegen; drop TS-only alias from schema registry

* chore(android): regenerate ask-user localization resources

* docs: regenerate docs map after rebase

* fix(ci): avoid stale read-only dependency disks

* test: remove stale reef lint suppression ratchet

* fix(ci): keep source locale drift advisory in release gates

* fix(ci): scope locale advisory handling to parity check
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: android App: android app: web-ui App: web-ui channel: discord Channel integration: discord channel: slack Channel integration: slack channel: telegram Channel integration: telegram docs Improvements or additions to documentation feature: ✨ showcase ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. gateway Gateway runtime maintainer Maintainer-authored PR mantis: telegram-visible-proof Mantis should capture Telegram visible proof. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. P2 Normal backlog priority with limited blast radius. proof: πŸŽ₯ video Contributor real behavior proof includes video or recording evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. scripts Repository scripts size: XL status: πŸ“£ needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant