|
Download packages/coding-agent/src/experimental/mini/README.md from SaylorTwift/pi: direct link, hf CLI and curl.
- Browser
- Download file 5.86 kB
-
https://huggingface.co/SaylorTwift/pi/resolve/main/packages/coding-agent/src/experimental/mini/README.md
- Command line
-
hf download hf://SaylorTwift/pi/packages/coding-agent/src/experimental/mini/README.md
-
curl -L -o README.md https://huggingface.co/SaylorTwift/pi/resolve/main/packages/coding-agent/src/experimental/mini/README.md
5.86 kB
| # mini | |
| A minimal coding agent on the durable `AgentHarness`, split across three processes that talk JSON | |
| over a socket and a pipe. It exists to exercise the harness from a real client and to find out what | |
| an RPC-shaped presentation actually needs from it. | |
| ```bash | |
| node packages/coding-agent/src/experimental/mini/main.ts [--continue] | |
| # while the harness is changing under us, run from source instead of built dist: | |
| ./node_modules/.bin/tsx --tsconfig tsconfig.json packages/coding-agent/src/experimental/mini/main.ts | |
| ``` | |
| `--continue` attaches to the newest session for the current directory. Starting `mini` twice attaches | |
| two presentations to the same session; both see the same transcript, live. | |
| ## Topology | |
| ```text | |
| tui tui tui presentations: render, no agent state | |
| \ | / | |
| \ | / unix socket, ~/.pi/agent/experimental/mini.sock | |
| \ | / | |
| server routes calls, fans out events, spawns workers | |
| / \ | |
| / \ child process stdio pipes | |
| worker worker one per session: harness, storage, model runtime | |
| ``` | |
| A presentation holds one connection and reaches every service through it. The server answers | |
| `sessions` itself and forwards anything else to the worker that connection is attached to, so the TUI | |
| never learns which host answers what. The same rule runs backwards: a worker calling `sessions.list` | |
| is answered by the server. | |
| The first `mini` to start spawns the server detached. The server kills a worker when its last | |
| presentation disconnects, and retires itself ten seconds after the last presentation leaves, so the | |
| next start always runs current code. If that worker held an open durable operation, its replacement | |
| automatically resumes the operation from the last recorded recovery state. | |
| ## Layout | |
| | path | role | | |
| | --- | --- | | |
| | `main.ts` | the `mini` command | | |
| | `shared/transport.ts` | `Connection`: newline-delimited JSON over any duplex pair | | |
| | `shared/rpc.ts` | frames, named services, routing, liveness, cancellation | | |
| | `shared/protocol.ts` | service tokens, contracts, wire types | | |
| | `server/run.ts` | routes, worker supervision, event fan-out | | |
| | `worker/run.ts` | opens the session, builds the harness, provides services | | |
| | `worker/lane-service.ts` | `Lane`: watch subscriptions and lane commands | | |
| | `worker/models-service.ts` | `Models`: catalog, accounts, interactive login | | |
| | `tui/run.ts` | presentation host: ensure server, attach, run the view | | |
| | `tui/session.ts` | attach, subscribe, hold the replicated snapshot | | |
| | `tui/view.ts` | alt-screen rendering, reusing interactive-mode components | | |
| ## RPC | |
| Two verbs. **Call** asks a question and gets one answer; **emit** publishes to whoever listens. Both | |
| directions on every connection. | |
| ```ts | |
| const peer = createPeer(connection, { forward }); // forward handles names this peer lacks | |
| peer.provide(Lane, laneService); // register and announce | |
| const lane = peer.use(Lane); // Remote<LaneServiceApi> | |
| await lane.prompt("hi"); // -> { kind: "call", id, method: "lane.prompt" } | |
| peer.on(Lane, (event) => fold(event)); // typed by the token | |
| ``` | |
| The wire is six frame kinds: `call`, `result`, `error`, `cancel`, `event`, `announce`, `ping`. | |
| Replies correlate by `id` and resolve one promise; events carry a service name and no id, so the two | |
| never interfere — a five-minute `lane.prompt` sits pending while its stream of events flows past. | |
| Services are plain objects registered under a token, and a token carries the name plus the call and | |
| event types, so `provide` checks the implementation and `use` checks the caller. Names are announced | |
| on registration, so routing is a lookup and an unroutable call fails with both inventories named. | |
| Failure handling: a closed connection rejects every pending call and aborts every in-flight handler; | |
| peers ping every five seconds and declare a silent line dead after fifteen, which catches a wedged | |
| process that never closes; callers may pass a `signal` (sends `cancel`) or a `timeoutMs`. Timeouts | |
| are opt-in per call site, because an agent turn has no bounded duration. | |
| ## State replication | |
| The worker holds every live object. A presentation holds a `LaneSnapshot` and nothing else. | |
| Each presentation gets **its own** `lane.watch()` in the worker, in the harness's two phases: | |
| `watch()` captures a snapshot while the harness buffers that subscription's events, and `start()` | |
| drains them. Because the harness pairs snapshot and stream with no gap and no duplicate, the client | |
| needs no buffering or ordering logic of its own — it applies events with the harness's own | |
| `reduceLaneSnapshot`. When the fold answers `{ rebase: true }`, which a completed navigation does, the | |
| presentation takes a fresh subscription and drops the old one. First attach and rebase are the same | |
| function. | |
| Rendering is a pure function of that snapshot. Transcript entries are keyed by id and appended, so a | |
| streamed token costs one markdown rebuild rather than a repaint; the view repaints wholesale only | |
| when the entry-id prefix diverges, which is what compaction and navigation do. | |
| ## What it is not | |
| No slash-command system, extensions, skills, hooks, themes beyond the shared one, session picker, or | |
| tree navigation. Interactive login and model selection exist because they proved the awkward | |
| directions of the protocol: server-to-client requests, and identity-based configuration. | |
| Two known shortcuts: the server broadcasts a worker's events to every attached presentation, so with | |
| N presentations each event crosses N² times and each client discards the copies that are not its own; | |
| and cancelling an interactive login only interrupts at a prompt, since the worker's login has no | |
| abort path yet. | |