Archived
docs: document Pi extension dialogs and extensionDialogsTimeoutMs
Add the close-out documentation for extension dialog support: - docs/config.md (+ synchronized config.html): extensionDialogsTimeoutMs in the config matrix, reload/restart guidance, the global config example, and a new Extension dialogs key-detail section covering the unattended-dialog safety valve (default 5 min, 0 = forever, effective deadline is the sooner of the extension's own timeout and this knob). - docs/plugins.md (+ synchronized plugins.html): new Pi extension dialogs in PI WEB behavior note for extension authors — confirm/select/ input render inline in the transcript and resolve with the real answer, answers use a dedicated daemon channel (never the prompt queue, so tool_call hooks park safely), session_start dialogs are reachable during create and open, reload rehydration, first-answer-wins across tabs, abort/runtime-replacement settlement, and the reload-mid-startup browser-local caveat. - Add the extension-dialogs changeset (patch) for the release notes.
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@jmfederico/pi-web": patch
|
||||
---
|
||||
|
||||
Support Pi extension dialogs in the browser: `ctx.ui.confirm()`, `ctx.ui.select()`, and `ctx.ui.input()` now render as cards inline in the session transcript and resolve with the user's actual answer — including dialogs opened from `session_start` hooks while the session is still starting and from in-flight `tool_call` hooks, which previously resolved `false` immediately despite `hasUI === true`. Answers travel over a dedicated session-daemon channel rather than the prompt queue, so a dialog parked inside a `tool_call` hook cannot deadlock the run. Open dialogs survive browser reloads, the first answer wins across browser tabs, and unanswered dialogs settle safely on run abort, runtime replacement, or timeout. Adds the `extensionDialogsTimeoutMs` config key (default 5 minutes, `0` waits forever) as the unattended-dialog safety valve; dialog support is always on. Other `ExtensionUIContext` surfaces (widgets, status, editor, `custom`) remain unimplemented.
|
||||
+37
-1
@@ -102,6 +102,7 @@
|
||||
<a href="#pi-extension-provider-baseline">Pi extension providers</a>
|
||||
<a href="#catalog-refresh">Model catalog refresh</a>
|
||||
<a href="#session-tools">Session tools</a>
|
||||
<a href="#extension-dialogs">Extension dialogs</a>
|
||||
<a href="#completion-tools">Completion tools</a>
|
||||
</aside>
|
||||
|
||||
@@ -173,7 +174,7 @@
|
||||
<ul>
|
||||
<li><code>host</code> / <code>port</code>: restart the gateway web/API service or process.</li>
|
||||
<li><code>maxUploadBytes</code>: restart both the web/API process and the session daemon on that machine.</li>
|
||||
<li><code>agent.command</code> / <code>agent.dir</code> / <code>spawnSessions</code> / <code>subsessions</code> / <code>askUser</code>: restart the session daemon on that machine.</li>
|
||||
<li><code>agent.command</code> / <code>agent.dir</code> / <code>spawnSessions</code> / <code>subsessions</code> / <code>askUser</code> / <code>extensionDialogsTimeoutMs</code>: restart the session daemon on that machine.</li>
|
||||
<li><code>pathAccess</code>: applies on the next request; existing file views may need a browser refresh.</li>
|
||||
<li><code>uploads.defaultFolder</code>: applies to newly opened Files upload dialogs and new direct drag/drop batches after config/workspace refresh.</li>
|
||||
<li><code>plugins</code>: reload the browser tab after changing PI WEB plugin enablement.</li>
|
||||
@@ -213,6 +214,7 @@
|
||||
"spawnSessions": true,
|
||||
"subsessions": false,
|
||||
"askUser": true,
|
||||
"extensionDialogsTimeoutMs": 300000,
|
||||
"plugins": {
|
||||
"workspace-tasks": { "enabled": true },
|
||||
"updates": { "enabled": true },
|
||||
@@ -376,6 +378,14 @@
|
||||
<td>Not supported locally</td>
|
||||
<td>Restart session daemon on that machine</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Extension dialog auto-cancel timeout</td>
|
||||
<td><code>extensionDialogsTimeoutMs</code></td>
|
||||
<td>—</td>
|
||||
<td>Global/session daemon</td>
|
||||
<td>Not supported locally</td>
|
||||
<td>Restart session daemon on that machine</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PI WEB plugin enablement/settings</td>
|
||||
<td><code>plugins.<id>.enabled</code>, <code>plugins.<id>.settings</code></td>
|
||||
@@ -842,6 +852,32 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="extension-dialogs">
|
||||
<h2>Extension dialogs</h2>
|
||||
<p>
|
||||
Pi extensions can ask the user questions from <code>ctx.ui.confirm()</code>,
|
||||
<code>ctx.ui.select()</code>, and <code>ctx.ui.input()</code> — including from
|
||||
<code>session_start</code> hooks and in-flight <code>tool_call</code> hooks. PI WEB renders these dialogs
|
||||
inline in the session transcript and answers them through a dedicated session-daemon channel, never the
|
||||
prompt queue, so a dialog parked inside a <code>tool_call</code> hook cannot deadlock the run. Dialog
|
||||
support is always on; there is no enable flag. See
|
||||
<a href="plugins#pi-extension-dialogs">Pi extension dialogs in PI WEB</a> for behavior details and author
|
||||
guidance.
|
||||
</p>
|
||||
<p>
|
||||
<code>extensionDialogsTimeoutMs</code> is the unattended-dialog safety valve: how long the session daemon
|
||||
waits for an answer before settling the dialog with its kind's cancel value (<code>false</code> for
|
||||
confirm, <code>undefined</code> for select and input). It defaults to <code>300000</code> (5 minutes);
|
||||
set it to <code>0</code> to wait forever. An extension's own <code>timeout</code> option still applies,
|
||||
and the effective deadline is the sooner of the two.
|
||||
</p>
|
||||
<div class="callout warning">
|
||||
<strong>Restart required:</strong> <code>extensionDialogsTimeoutMs</code> is edited directly in the global
|
||||
config file. Restart the session daemon after changing it — for the systemd user service, run
|
||||
<code>systemctl --user restart pi-web-sessiond</code>.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="completion-tools">
|
||||
<h2>Optional completion tools</h2>
|
||||
|
||||
+11
-1
@@ -39,7 +39,7 @@ Process restarts depend on the key:
|
||||
|
||||
- `host` / `port`: restart the gateway web/API service or process.
|
||||
- `maxUploadBytes`: restart both the web/API process and the session daemon on that machine.
|
||||
- `agent.command` / `agent.dir` / `spawnSessions` / `subsessions` / `askUser`: restart the session daemon on that machine.
|
||||
- `agent.command` / `agent.dir` / `spawnSessions` / `subsessions` / `askUser` / `extensionDialogsTimeoutMs`: restart the session daemon on that machine.
|
||||
- `pathAccess`: applies on the next request; existing file views may need a browser refresh.
|
||||
- `uploads.defaultFolder`: applies to newly opened Files upload dialogs and new direct drag/drop batches after config/workspace refresh.
|
||||
- `plugins`: reload the browser tab after changing PI WEB plugin enablement.
|
||||
@@ -66,6 +66,7 @@ Process restarts depend on the key:
|
||||
"spawnSessions": true,
|
||||
"subsessions": false,
|
||||
"askUser": true,
|
||||
"extensionDialogsTimeoutMs": 300000,
|
||||
"plugins": {
|
||||
"workspace-tasks": { "enabled": true },
|
||||
"updates": { "enabled": true },
|
||||
@@ -118,6 +119,7 @@ Rows with JSON key `—` are runtime-only environment variables, not config-file
|
||||
| Agent can spawn sessions | `spawnSessions` | `PI_WEB_SPAWN_SESSIONS` | Global/session daemon | Not supported locally | Restart session daemon on that machine |
|
||||
| Tracked subsessions (beta) | `subsessions` | `PI_WEB_SUBSESSIONS` | Global/session daemon | Not supported locally; also requires `spawnSessions` | Restart session daemon on that machine |
|
||||
| Agent can post question forms | `askUser` | `PI_WEB_ASK_USER` | Global/session daemon | Not supported locally | Restart session daemon on that machine |
|
||||
| Extension dialog auto-cancel timeout | `extensionDialogsTimeoutMs` | — | Global/session daemon | Not supported locally | Restart session daemon on that machine |
|
||||
| Plugin enablement/settings | `plugins.<id>.enabled`, `plugins.<id>.settings` | — | Global | Not core local config; plugins may read their own project files | Reload browser tab |
|
||||
| Keyboard shortcuts | `shortcuts.<actionId>` | — | Global | Not supported locally | Applies after settings save/config refresh |
|
||||
| Project config version | `version` | — | Project | Project-local only; must be `1` when present | Next project-config read |
|
||||
@@ -289,6 +291,14 @@ Sending an ordinary chat message while a form is open voids the form: the card c
|
||||
|
||||
Restart the session daemon after changing `askUser` or after upgrading PI WEB to a version that introduces this tool. For the systemd user service, run `systemctl --user restart pi-web-sessiond`.
|
||||
|
||||
### Extension dialogs
|
||||
|
||||
Pi extensions can ask the user questions from `ctx.ui.confirm()`, `ctx.ui.select()`, and `ctx.ui.input()` — including from `session_start` hooks and in-flight `tool_call` hooks. PI WEB renders these dialogs inline in the session transcript and answers them through a dedicated session-daemon channel, never the prompt queue, so a dialog parked inside a `tool_call` hook cannot deadlock the run. Dialog support is always on; there is no enable flag. See [Pi extension dialogs in PI WEB](https://pi-web.dev/plugins#pi-extension-dialogs) for behavior details and author guidance.
|
||||
|
||||
`extensionDialogsTimeoutMs` is the unattended-dialog safety valve: how long the session daemon waits for an answer before settling the dialog with its kind's cancel value (`false` for confirm, `undefined` for select and input). It defaults to `300000` (5 minutes); set it to `0` to wait forever. An extension's own `timeout` option still applies, and the effective deadline is the sooner of the two.
|
||||
|
||||
The key is edited directly in the global config file. Restart the session daemon after changing it — for the systemd user service, run `systemctl --user restart pi-web-sessiond`.
|
||||
|
||||
### Plugin config
|
||||
|
||||
The `plugins` key is only for PI WEB browser plugin enablement/settings on the machine whose config you are editing. It does not install, remove, or update Pi packages; use **Settings → Pi packages** or Pi's package manager for package operations. In a federated setup, **Settings → PI WEB plugins** and **Settings → Pi packages** both target the currently selected machine, and each panel labels where changes will be saved or run.
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
<strong>On this page</strong>
|
||||
<a href="#extend">What can be extended</a>
|
||||
<a href="#packages-vs-plugins">Pi packages, extensions, and plugins</a>
|
||||
<a href="#pi-extension-dialogs">Pi extension dialogs</a>
|
||||
<a href="#ask-ai">What to ask AI to build</a>
|
||||
<a href="#example">Canonical example</a>
|
||||
<a href="#built-in-plugins">Built-in plugins</a>
|
||||
@@ -174,6 +175,32 @@
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="pi-extension-dialogs">
|
||||
<h2>Pi extension dialogs in PI WEB</h2>
|
||||
<p>
|
||||
Pi extensions running under PI WEB's session daemon can ask the user questions with
|
||||
<code>ctx.ui.confirm()</code>, <code>ctx.ui.select()</code>, and <code>ctx.ui.input()</code>. For these
|
||||
three methods <code>ctx.hasUI</code> is true in fact: the call renders a dialog card inline in the
|
||||
session transcript — including from <code>session_start</code> hooks while the session is still starting
|
||||
and from in-flight <code>tool_call</code> hooks — and resolves with the user's actual answer.
|
||||
</p>
|
||||
<p>
|
||||
Answers travel over a dedicated session-daemon channel, never the prompt queue, so a parked
|
||||
<code>tool_call</code> hook cannot deadlock the run. Open dialogs survive browser reloads, the first
|
||||
answer wins across tabs, and unanswered dialogs settle safely: aborting the run or replacing the runtime
|
||||
resolves them immediately with the kind's cancel value (<code>false</code> for confirm,
|
||||
<code>undefined</code> for select and input), and the effective deadline — the sooner of the extension's
|
||||
own <code>timeout</code> and the daemon's <code>extensionDialogsTimeoutMs</code> safety valve (default 5
|
||||
minutes, <code>0</code> waits forever) — does the same when no one answers. Other
|
||||
<code>ExtensionUIContext</code> surfaces (widgets, status, editor, <code>custom</code>) remain no-ops
|
||||
despite <code>hasUI === true</code>.
|
||||
</p>
|
||||
<p>
|
||||
For the full behavior notes and author guidance, read <a href="plugins.md">plugins.md</a>; for the
|
||||
timeout key, see <a href="config#extension-dialogs">Extension dialogs</a> in the configuration reference.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="ask-ai">
|
||||
<h2>What to ask AI to build</h2>
|
||||
<p>
|
||||
|
||||
@@ -29,6 +29,19 @@ Use **Settings → PI WEB plugins** to enable or disable discovered PI WEB brows
|
||||
|
||||
After installing, removing, or updating a Pi package, type `/reload` in each idle PI WEB session on the target machine to refresh ordinary Pi resources such as extensions, skills, prompt templates, themes, and context/system prompt files. Reload the browser page separately for newly discovered or changed PI WEB browser plugins. A provider-registering Pi extension follows a separate daemon-start policy; see [Pi extension provider baseline](https://pi-web.dev/config#pi-extension-provider-baseline).
|
||||
|
||||
## Pi extension dialogs in PI WEB
|
||||
|
||||
Pi extensions running under PI WEB's session daemon can ask the user questions with `ctx.ui.confirm()`, `ctx.ui.select()`, and `ctx.ui.input()`. PI WEB reports `ctx.hasUI === true`, and for these three dialog methods that is true in fact: the call renders a dialog card inline in the session transcript and the returned Promise resolves with the user's actual answer — a boolean for confirm, the chosen option for select, the typed text for input.
|
||||
|
||||
- **Works from hooks, without the prompt queue.** Answers travel over a dedicated session-daemon channel, so a dialog opened inside an in-flight `tool_call` hook parks safely — the agent loop waits for the hook and the run continues with the answer. Consent-gating a tool from a `tool_call` hook is a supported pattern.
|
||||
- **`session_start` dialogs are reachable.** A dialog opened from a `session_start` hook is answerable while the session is still starting, both when creating a session and when opening an existing one; startup completes once the dialog settles.
|
||||
- **Survives browser reloads; first answer wins.** Reloading the browser re-renders open dialogs from the session status. With several tabs on the same session, the first answer settles the dialog and the other tabs re-render the settled card.
|
||||
- **Timeouts.** The extension's own `timeout` option applies, and the daemon adds an unattended-dialog safety valve, `extensionDialogsTimeoutMs` (default 5 minutes, `0` waits forever — see [Extension dialogs](https://pi-web.dev/config#extension-dialogs)). The effective deadline is the sooner of the two. A dialog that closes without an answer resolves with its kind's cancel value: `false` for confirm, `undefined` for select and input.
|
||||
- **Abort and runtime replacement.** Aborting the current run settles a dialog opened during that run immediately, at abort-request time, with its cancel value. Replacing the session runtime (`/reload`, session disposal) settles any still-open dialog the same way; hooks on the new runtime open fresh dialogs. The extension's own `AbortSignal` is honored: aborting it dismisses the dialog and resolves with the cancel value.
|
||||
- **Other UI surfaces are still no-ops.** `ExtensionUIContext` methods beyond the three dialogs (widgets, status, editor, `custom`) remain unimplemented under PI WEB even though `hasUI` is `true`; do not rely on `hasUI` alone to detect them.
|
||||
|
||||
One browser-local caveat: reloading the browser while a new session is still being created loses the browser-local pending-start row, so the dialog card disappears from view. The daemon-side dialog still settles at its deadline and the session appears in the sidebar once creation completes.
|
||||
|
||||
## Trust model
|
||||
|
||||
Plugins run as JavaScript in the browser app. Treat them as trusted code:
|
||||
|
||||
Reference in New Issue
Block a user