Commit graph

22 commits

Author SHA1 Message Date
Maximilian Blazek
ccff9876e7 feat(p2): a new session's first message sends at once; one composer for every screen
- New session: Send clears the composer and shows the message at once, online or not
  (plugins/chat/session-start.ts); the session is created when connected and its
  messages move to the main conversation's outbox. Refused creations go back to the
  composer; connection failures are retried.
- One composer: Main keeps the chat frame (.chat and its dock) while screens change;
  screens publish what the dock shows (useChatScreen) and portal their transcript into
  it. The composer keeps its focus and the phone's keyboard when the session opens.
- The composer stays in place: the new-session screen shows the session's empty
  context bar, and a message sent to an idle conversation stays a message until its
  entry shows instead of flashing as a queued row.
- Slots start with the registry's known table (knownRegistry), so a screen inside
  slot wrappers mounts once instead of three times.
- A message sent before a conversation has loaded shows alone until it loads.
2026-11-05 12:52:52 +00:00
Cristina Poncela Cubeiro
c5d98a78ed
feat(ui): script to build bundled (#11801)
We share the bundled UI built from p2 for Radius. This PR adds a script
to bundle it, and this gets uploaded to R2 on every green commit to
main.
2026-11-05 09:42:35 +01:00
Mario Zechner
90e2040468 fix(p2): session workers load OAuth flows and Bedrock from the worker base
The worker registers pi-ai's lazy OAuth and Bedrock loaders, so they are chunks of the
snapshot instead of pi-ai source files loaded at run time. The worker entry imports
chord/workers/child and host-packages.ts instead of plugins.ts: a fork loads no esbuild,
no server API and no provider SDK (690 to 301 modules on the phone).
2026-11-05 08:49:18 +01:00
Mario Zechner
5be85f3be3 fix(p2): a report's origin scans past mid-run error answers and compaction markers 2026-11-05 07:38:16 +00:00
Mario Zechner
fe68bf23e8 feat(p2): subagent messages start with a <sender kind="subagent"> block instead of a [subagent …] line 2026-11-05 07:23:22 +00:00
Mario Zechner
d57c2d2191 fix(p2): guest turns may use the terminal tool again, as decided (reverts 2b78884e3) 2026-11-05 00:05:40 +00:00
Mario Zechner
2b78884e3a feat(p2): the terminal tool needs a turn the owner started 2026-11-05 00:03:50 +00:00
Armin Ronacher
80cb316cd7 fix(p2): report TUI sandbox crashes with their stack
The launcher printed one message for both a heap overrun and an uncaught exception. It now says which, and prints the sanitized, bounded stack of an uncaught exception or a throwing message handler after restoring the terminal. The TUI bundle keeps names so frames are readable.
2026-11-05 00:35:13 +01:00
Mario Zechner
07c9e5b6fd feat(p2): tools declare who may call them and where, turn origin from the run's inputs, agents give their own tools
Some checks failed
CI / build-check (push) Failing after 14m3s
CI / test (coding-agent) (push) Has been cancelled
CI / test (durable) (push) Has been cancelled
CI / test (other) (push) Has been cancelled
CI / mcp-conformance (push) Has been cancelled
- P2Tool: origin (any|owner) and scope (any|main|subagent) on the tool; the worker's
  Durable registry checks them before each call (guardTool), no tool checks itself.
  owner: location tools, reload_plugins, conversations, ports, MCP tools.
  main: subagent, rename_session, conversations, ports, reload_plugins. subagent: team.
- originOf reads pi.live.run.inputs through tx.submission: the owner's only if every
  input of the run is. Agent-written inputs record the writing turn's origin: subagent
  tasks and one-shot prompts, team messages, reports (answerOrigin), peer messages.
  No peer origin any more.
- Subagents and one-shot agents get their caller's tools (default all, tools narrows),
  except scope main; with codemode the script-only tools; subagents get team. One-shot
  agents keep codemode and agent. A send takes away what the caller can no longer give.
2026-11-04 23:28:14 +00:00
Mario Zechner
43fb4e3106 feat(p2): <sender> block for the model, peer messages as p2.peer-message entries, legacy speaker reader removed 2026-11-04 22:07:38 +00:00
Armin Ronacher
474416d70b feat(p2): subagents can use code mode
codemode is choosable for subagents and in their default tools while the
codemode setting is on; one-shot agents never get it. A subagent with code
mode gets the script-only tools (MCP, terminal, agent, models.*) by name in
its Durable tools array, at spawn/configure and from the worker when the
registry's script-only tools change.
2026-11-04 21:56:56 +01:00
Armin Ronacher
617d0ef549 fix(p2): archiving closes an outdated terminal host's terminals through the viewer protocol 2026-11-04 21:56:56 +01:00
Armin Ronacher
47005dbe36 feat(p2): terminal tool for the agent, tmux-style argv, code mode only
The agent drives the session's terminals (shared with the owner's panel) with
tools.terminal({ command, args }): new-window, list-windows, send-keys, read,
capture-pane, kill-window, with waits (quiet, exit, /regex/) and plain-text
output. The terminal host keeps each terminal's last MiB of output and the
agent's read cursor, answers calls with ids, and does keyed calls once, so the
tool is replay-safe. AgentTerminals serves the session's current worker on its
environments; archiving closes a session's terminals. Without code mode the
worker registry installs tool_search once for all deferred tools.
2026-11-04 21:56:56 +01:00
Mario Zechner
04f672a18d feat(p2): render artifacts inline at the tool call site
The artifact tool takes inline: true to also show the produced version below
its transcript card: Markdown/text rendered, HTML/SVG in the sandboxed preview
frame. Drawings fill the frame's width (an SVG with a viewBox or an absolute
size scales to it; an HTML page that is only an SVG or image too) and the frame
takes the content height the preview reports, capped at 70vh. Every viewer sees
it, guests included (owner decision). The TUI renders inline Markdown and text.
SVG previews now carry the diagnostics bridge in CDATA (its && broke the XML).
2026-11-04 21:13:26 +01:00
Armin Ronacher
707888ece6 feat(p2): paste images into the composer
A paste with only images (a screenshot) attaches them through the composer's
attach flow; a paste with plain text stays a text paste.
2026-11-04 18:40:42 +01:00
Armin Ronacher
386db6130e feat(p2): MCP OAuth sign-in, MCP sheet and TUI command, footer menu
HTTP servers without an Authorization header sign in with OAuth: stored
tokens in mcp-auth.json, refreshed without a browser. /mcp/sign-in/<server>
returns to a loopback callback when the browser runs on the p2 host (the
device owner, or a relayed/public owner whose browser reaches a nonce probe
on 127.0.0.1), else to /mcp/callback on the origin p2 is reached through.
Pasting the final redirect URL always completes a waiting sign-in.

Web: an MCP sheet (status, restart, sign in/out, paste). TUI: /mcp and
/mcp paste. The sidebar footer's owner entries move into a More menu.
2026-11-04 18:34:13 +01:00
David Brailovsky
d6339fb097 feat(p2): TUI side panel; /artifacts opens artifacts beside the chat
- Runtime: ctx.panel shows one component right of the screen's body (about 40%,
  hidden below 100 columns, dock stays full width). F2 moves the focus into it
  (viewport and select keys scroll it, Escape returns), /close-panel closes it.
  Closes on conversation switch and facet reload, like overlays.
- Artifacts: Enter opens the artifact in the panel when the terminal fits it,
  else inline as before; the panel follows the artifact's newest version.
- Fix: /artifacts rows are keyed by name and version, so every version of an
  artifact can be selected.
2026-11-04 17:51:48 +01:00
Mario Zechner
0a180b049a feat(p2): keep serving older Sessions, Catalog and SessionTree versions
Pages and TUIs loaded before a deploy hold the contracts they were built
with; without accepts they wait unbound (contract_mismatch) until they
reload. The histories are now written with evolve from the released
versions, and the providers accept them:

- Sessions 3 (rows without main and branches) and 4 (a null branch label
  reads as the session title); v4's treeSelf arguments pass as they are
- Catalog 2 and 3, the same row mappings
- SessionTree 1: the tree without labels (no branches, no node
  conversation); rename is new and needs nothing

test/p2/contract-versions.test.ts binds the released declarations
against the current server.
2026-11-04 15:38:43 +01:00
Mario Zechner
0a730c8a76 fix(p2): archiving a viewed session shows no error and starts no refused worker
Archiving from the session sheet navigates away first, which unmounted SessionOptions and released its Sessions
reference; Chord cancels a released reference's calls, so the archive call rejected with "p2.sessions: released",
shown as the composer toast over the owner-notice lane. The archive now holds a reference of its own until it is done,
and the server runs its steps in a root of its own.

The archive stopped the worker with Hosts.stop, which restarts it for its holders: the page's lingering
conversation started a worker the archived session refused (resolve_failed, "Worker: Session is archived" notice).
SessionWorkerControl.suspend stops it and leaves its holders suspended until a restore (retry) or their release;
archive, a failed fork's archived copy and an archived session's index rebuild use it.
2026-11-04 13:19:01 +01:00
David Brailovsky
a7a75a9dc6 fix(p2): apply the hideThinkingBlock setting to the TUI thinking view
The setting was saved but never read: thinking always started hidden.
It now sets the view whenever its effective value changes (unset = hidden);
the toggle overrides it until then and survives reloads.
2026-11-03 22:38:20 +01:00
Armin Ronacher
7dc38ff0e9 feat(p2): MCP servers on the host, on environments and from projects
A manager on the p2 server owns every MCP connection and process. Session
workers hold one view each and lease the locations their conversations
work at; the manager runs the owner's mcp.json servers there (stdio per
session and location, or shared; HTTP shared by default) and offers their
tools as deferred Durable tools found through tool_search.

Stdio servers on an environment start through its pi-env daemon, one
connection per environment shared by its instances, through cmd.exe on
Windows. A project's .pi/mcp.json, read by the worker at each location,
may add stdio servers that run there and switch the owner's servers on or
off; the manager refuses everything else. A lease gets servers only on
environments its session works on.
2026-11-03 16:48:38 +01:00
Mario Zechner
05dc8d239d feat: add apps/p2 (imported from pi-private at 7dadff697)
p2 (Pi Mobile on Chord v2) moves from pi-private into pi as one commit. Root scripts that loop all workspaces
use --if-present; npm test, ./test.sh and the release script cover packages/* only (p2: cd apps/p2 && npm test);
sync-versions also updates apps' workspace pins.
2026-11-03 13:39:06 +00:00