Skip to content

feat(dialog): render whole-form ask requests natively - #474

Closed
andrebrait wants to merge 1 commit into
mainfrom
feat/native-form-dialog
Closed

andrebrait wants to merge 1 commit into
mainfrom
feat/native-form-dialog

Conversation

@andrebrait

Copy link
Copy Markdown
Collaborator

Summary

  • Render extension_ui_request with method: "form" unconditionally in the existing composer-attached or overlay dialog, with native controls, constraint validation, typed FormData submission, hidden values, and free-text Other answers for radio/checkbox groups.
  • Parse inertly and allowlist-sanitize model HTML with the already-installed HAST sanitizer behind rehype-sanitize; strip scripts, handlers, styles, form actions/ownership attributes and unsafe image URLs before React rendering. No new dependencies.
  • Register forms as blocking dialogs so notifications, replay, shared-daemon first-answer settlement, cancellations and expiry use the existing lifecycle. Preserve absolute deadlines across reconnect replay; send {cancelled:true,timedOut:true} on host timeout.
  • Send the transitional set_form_dialog {enabled:true} alongside existing startup settings (including daemon-owned starts, legacy adoption and restarts). Unknown-command replies are harmless. Rendering does not depend on negotiation; existing select/input/editor behavior remains intact.
  • Localize form controls in English, Japanese, Simplified Chinese and the newly merged Traditional Chinese locale.

Upstream contract

Prepared against can1357/oh-my-pi#18646 at 8ee5e89894 (docs/rpc.md and packages/coding-agent/src/modes/rpc/wire/frames.ts). This is how omp's ask reaches omp-web starting with the omp release that includes that change, not a user-facing opt-in. If upstream makes forms unconditional and removes set_form_dialog, its absence remains harmless.

Existing extension ui.select/input/editor requests remain supported. This change does not add a per-field fallback or change the select branch from #451; #451 and can1357/oh-my-pi#18929 are already merged.

Verification

  • 318 tests passed across 10 files: native form and all ExtensionDialog component tests, rpc-manager, daemon-channels, hub-v7 and pending-requests (bun test --parallel --timeout 30000).
  • npm run typecheck.
  • ESLint over changed TypeScript files.
  • /root/.local/bin/bun scripts/build-client.ts (existing CSS highlight selector warnings).
  • Regression coverage includes exact scalar/array/number/hidden data, defaults, required/min constraints, Other, disabled options, hostile HTML, submit/cancel/timeout response shapes, expired replay, native cancellation, shared-host settlement, and old omp rejecting set_form_dialog while still handling legacy select.

Not verified

  • Visual/browser verification was not run: this worker has neither a working managed browser daemon (omp.browser.headless unavailable) nor an installed Chromium binary. A temporary component harness was prepared, but browser launch failed; harness files and service were removed.
  • Real upstream-branch omp --mode rpc-ui against omp-web was not run: /root/git/oh-my-pi is absent on this worker. No services were deployed or restarted.
  • Full repository test suite was not run; verification was limited to the affected dialog and lifecycle paths.

The feature becomes usable with an omp release containing can1357/oh-my-pi#18646; current runtimes retain their existing dialogs.

Summary by CodeRabbit

  • New Features

    • Added support for interactive HTML forms in extension dialogs, with native validation, “Other” answers, submission and cancellation, and timeout handling.
    • Form requests can be replayed after reconnecting, including on local and linked hosts.
    • Added translations for “Other” answer labels and guidance in English, Japanese, Simplified Chinese, and Traditional Chinese.
  • Bug Fixes

    • The chat composer now loses focus when a form dialog opens.

Moved from #457 (head branch now on this repository).

# Conflicts:
#	CHANGELOG.md
#	components/ExtensionDialog.tsx
#	hooks/useAgentSession.ts
#	lib/i18n/locales/en.json
#	lib/i18n/locales/ja.json
#	lib/i18n/locales/zh-CN.json
@coderabbitai

coderabbitai Bot commented Nov 13, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 6 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 472bc158-57b4-43b0-b1b4-7f527aff1ecf
Commits

Reviewing files that changed from the base of the PR and between ca8b2c1 and 0228b03.

Files selected for processing: 21

  • CHANGELOG.md
  • components/ChatWindow.tsx
  • components/ExtensionDialog.form.test.mjs
  • components/ExtensionDialog.tsx
  • components/FormDialog.test.mjs
  • components/FormDialog.tsx
  • hooks/useAgentSession-stream.ts
  • hooks/useAgentSession.ts
  • lib/hosts/daemon-channels.test.mjs
  • lib/hosts/daemon-channels.ts
  • lib/hosts/hub-v7.test.mjs
  • lib/hosts/pending-requests.test.mjs
  • lib/i18n/locales/en.json
  • lib/i18n/locales/ja.json
  • lib/i18n/locales/zh-CN.json
  • lib/i18n/locales/zh-TW.json
  • lib/notification-events.ts
  • lib/pi-types.ts
  • lib/rpc-manager.test.mjs
  • lib/rpc-manager.ts
  • lib/types.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@kilo-code-bot

kilo-code-bot Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Code Review Roast 🔥

Verdict: No Issues Found | Recommendation: Merge

Oh wait, this PR is actually clean. I need to sit down. I had my flamethrower warmed up and everything.

📊 Overall: Like finding a unicorn in production — I didn't think clean PRs existed anymore, but here we are.

Files Reviewed (21 files)
  • CHANGELOG.md
  • components/ChatWindow.tsx
  • components/ExtensionDialog.form.test.mjs
  • components/ExtensionDialog.tsx
  • components/FormDialog.test.mjs
  • components/FormDialog.tsx
  • hooks/useAgentSession-stream.ts
  • hooks/useAgentSession.ts
  • lib/hosts/daemon-channels.test.mjs
  • lib/hosts/daemon-channels.ts
  • lib/hosts/hub-v7.test.mjs
  • lib/hosts/pending-requests.test.mjs
  • lib/i18n/locales/en.json
  • lib/i18n/locales/ja.json
  • lib/i18n/locales/zh-CN.json
  • lib/i18n/locales/zh-TW.json
  • lib/notification-events.ts
  • lib/pi-types.ts
  • lib/rpc-manager.test.mjs
  • lib/rpc-manager.ts
  • lib/types.ts

Reviewed by free · Input: 113.5K · Output: 40.8K · Cached: 620K

@andrebrait

Copy link
Copy Markdown
Collaborator Author

Superseded by #473: ompweb's own runner delivers omp's whole-form ask natively, without RPC or set_form_dialog.

@andrebrait andrebrait closed this Nov 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant