pi-superagent 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ADAPTATION.md +29 -31
- package/README.md +69 -122
- package/docs/architecture.md +103 -124
- package/docs/design-decisions.md +128 -228
- package/docs/formal-verification.md +48 -52
- package/docs/operator-guide.md +101 -89
- package/formal/README.md +20 -20
- package/package.json +1 -1
package/ADAPTATION.md
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
# Adaptation ledger
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
If you follow a request from GitHub into the code, you’ll cross a boundary at `src/core/`.
|
|
4
|
+
DeepSeek’s dsh-superagent-prototype supplies the rules for opening a ticket, assigning a worker
|
|
5
|
+
and recording the outcome. This project supplies the pieces that talk to GitHub, run pi and keep
|
|
6
|
+
the worker’s terminal open in herdr.
|
|
7
|
+
|
|
8
|
+
That split gives maintainers a place to start. For a question about what a *ready* report means,
|
|
9
|
+
look in the engine. For a question about how that report becomes a GitHub comment, look in
|
|
10
|
+
`src/pi/`. The tables below identify the upstream files and the local code on either side.
|
|
6
11
|
|
|
7
12
|
## The baseline
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
`vendor/dsh-superagent/UPSTREAM_SHA`.
|
|
14
|
+
The files below match upstream commit `8c32a9dc5d72c033816c6a8110b37f40cf94fba4` byte for byte.
|
|
15
|
+
The pinned revision is recorded in `vendor/dsh-superagent/UPSTREAM_SHA`.
|
|
11
16
|
|
|
12
17
|
| Here | Upstream |
|
|
13
18
|
| --- | --- |
|
|
@@ -16,7 +21,7 @@ Upstream commit `8c32a9dc5d72c033816c6a8110b37f40cf94fba4`, also recorded in
|
|
|
16
21
|
| `vendor/dsh-superagent/docs/` | `docs/` |
|
|
17
22
|
| `vendor/dsh-superagent/LICENSE` | `LICENSE` |
|
|
18
23
|
|
|
19
|
-
|
|
24
|
+
Run these comparisons from the repository root. Each `diff` exits successfully for an exact match.
|
|
20
25
|
|
|
21
26
|
```sh
|
|
22
27
|
git clone https://github.com/deepseek-ai/dsh-superagent-prototype /tmp/upstream
|
|
@@ -24,50 +29,43 @@ git -C /tmp/upstream checkout "$(cat vendor/dsh-superagent/UPSTREAM_SHA)"
|
|
|
24
29
|
diff -r /tmp/upstream/src/core src/core
|
|
25
30
|
diff /tmp/upstream/tests/core-engine.spec.ts test/core-engine.spec.ts
|
|
26
31
|
diff -r /tmp/upstream/docs vendor/dsh-superagent/docs
|
|
32
|
+
diff /tmp/upstream/LICENSE vendor/dsh-superagent/LICENSE
|
|
27
33
|
```
|
|
28
34
|
|
|
29
35
|
## Deviations
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
There are currently no local deviations. Record any future change here with the affected file, upstream
|
|
38
|
+
revision and reason. Maintainers will need that history when they apply the next upstream fix.
|
|
33
39
|
|
|
34
|
-
##
|
|
40
|
+
## Local adapters
|
|
35
41
|
|
|
36
|
-
The engine is synchronous and does no I/O of its own.
|
|
37
|
-
|
|
38
|
-
lives in `src/pi/`:
|
|
42
|
+
The engine is synchronous and does no I/O of its own. The interfaces in `src/core/ports.ts` connect it to storage, processes and
|
|
43
|
+
models. Their implementations live in `src/pi/`.
|
|
39
44
|
|
|
40
45
|
| Port | Bound in | How |
|
|
41
46
|
| --- | --- | --- |
|
|
42
47
|
| `Repositories` | `store.ts` | synchronous `node:sqlite` in WAL mode with `synchronous=FULL`, one transaction per engine command |
|
|
43
48
|
| `Policy` | `router.ts` (`policyOf`) | admits a trigger only from a person who is not on the bot list |
|
|
44
|
-
| `SourceScope` | `
|
|
49
|
+
| `SourceScope` | `router.ts` (`scopeOf`) | filters incoming authors by GitHub association or the configured login list |
|
|
45
50
|
| `Assessor` | `assessor.ts`, `judge.ts` | candidates go one at a time to a headless pi judge, which answers with `ticket_decide` |
|
|
46
51
|
| `Executor` | `executor.ts`, `herdr-workers.ts` | one pi session per assignment, in its own herdr tab, reached through files that outlive the router |
|
|
47
52
|
| `Outbox` | `outbox.ts` | GitHub comments, queued once per id and marked sent only once GitHub accepts them |
|
|
48
53
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
vendored: this repository replaces them with pi sessions in herdr, the GitHub source above, the panel in
|
|
54
|
-
`server.ts`, and the store in `store.ts`.
|
|
55
|
-
|
|
56
|
-
Two of upstream's rules carry through every binding:
|
|
54
|
+
The engine accepts triggers directly. `source-github.ts` converts issues, comments and reviews
|
|
55
|
+
into triggers and saves its read positions in the engine’s SQLite database. Upstream also ships a
|
|
56
|
+
Feishu source, an executor, a panel and a store. This project supplies its own GitHub integration,
|
|
57
|
+
herdr workers, panel (`server.ts`) and storage adapter (`store.ts`).
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
- **Only the engine writes a ticket.** A worker that could edit its own ticket could mark its own work
|
|
61
|
-
done.
|
|
59
|
+
Only the engine writes a ticket. The worker submits its assignment outcome through
|
|
60
|
+
`ticket_report`. A *blocked* report carries the question that the router posts for the requester.
|
|
62
61
|
|
|
63
62
|
## Tests
|
|
64
63
|
|
|
65
|
-
`test/core-engine.spec.ts` is upstream
|
|
66
|
-
same 113 cases against the SQLite
|
|
67
|
-
against a store that survives the process.
|
|
64
|
+
`test/core-engine.spec.ts` is the upstream engine suite. `test/sqlite-engine.spec.ts` runs the
|
|
65
|
+
same 113 cases against the local SQLite adapter, exercising the same transitions with persistent storage.
|
|
68
66
|
|
|
69
67
|
## Taking an upstream change
|
|
70
68
|
|
|
71
|
-
Copy
|
|
72
|
-
`
|
|
73
|
-
|
|
69
|
+
Copy the files listed in the baseline table to their corresponding local paths and update
|
|
70
|
+
`vendor/dsh-superagent/UPSTREAM_SHA`. If a ticket transition changed, update `formal/Ticket.tla`.
|
|
71
|
+
Run `npm run check` and `scripts/check-formal` against the new baseline.
|
package/README.md
CHANGED
|
@@ -1,67 +1,21 @@
|
|
|
1
1
|
# pi-superagent
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
over. The worker finishes by calling a report tool, and the result arrives on the issue as a reply. Work
|
|
10
|
-
that changes a repository arrives as a pull request, and the ticket stays open until it is merged.
|
|
11
|
-
|
|
12
|
-
There are no labels to learn and no board to tend. The issue is the request, a comment is a follow-up,
|
|
13
|
-
and closing the issue is the stop.
|
|
14
|
-
|
|
15
|
-
The ticket engine underneath is DeepSeek's
|
|
16
|
-
[dsh-superagent-prototype](https://github.com/deepseek-ai/dsh-superagent-prototype), vendored
|
|
17
|
-
byte-for-byte. This repository binds it to pi, herdr and GitHub.
|
|
18
|
-
|
|
19
|
-
## How a request travels
|
|
20
|
-
|
|
21
|
-
1. **Trigger.** A new issue is a request; so is a comment on an issue or a pull request, and so is a
|
|
22
|
-
submitted review. Only people with write access to the repository are heard: on a public repository
|
|
23
|
-
anyone can open an issue, and a request starts a worker with a shell on your machine. On its first
|
|
24
|
-
look at a repository the router records what is already there and fires none of it.
|
|
25
|
-
2. **Judgement.** The judge, a headless pi session, reads the request with its link and answers through
|
|
26
|
-
a tool: *accept*, *ignore* (chatter, a note to a colleague, a thread that already has a ticket) or
|
|
27
|
-
*stop*.
|
|
28
|
-
3. **Work.** An accept opens a ticket and posts the judge's acknowledgement on the issue. A worker starts
|
|
29
|
-
in a workspace of its own, briefed with the ticket's mandate. Every later comment a person writes on
|
|
30
|
-
the thread goes straight to that worker.
|
|
31
|
-
4. **Report.** The worker ends every run by calling `ticket_report`, and the router posts the report on
|
|
32
|
-
the issue. A *blocked* report asks you a question there, and your reply goes straight back to the
|
|
33
|
-
worker. A run that ends without a report, a worker that crashes, and a launch that fails are posted
|
|
34
|
-
too, each with what you can do next. A crashed worker is replaced once, without anyone asking.
|
|
35
|
-
5. **Pull request.** Work that changes a repository, in any repository, goes out as a pull request the
|
|
36
|
-
worker opens and names in its report. The ticket then waits for review: comments and reviews on the
|
|
37
|
-
pull request go to the same worker. The merge ends the ticket, and the issue hears it is done; closing
|
|
38
|
-
the pull request unmerged ends it too. Work that changes no repository, such as an answer, an
|
|
39
|
-
investigation or a deployment, ends with its report.
|
|
40
|
-
|
|
41
|
-
Closing the issue stops its ticket and says so on the thread. Reopening the issue starts the request again.
|
|
42
|
-
|
|
43
|
-
## Why it is built this way
|
|
44
|
-
|
|
45
|
-
pi-superagent grew out of a setup where agents polled markdown cards, prompts were typed into terminal
|
|
46
|
-
panes, and a classifier guessed from prose whether a person had answered. Every failure there was the
|
|
47
|
-
same defect in a different hat: **state recorded as text, transitions guessed by readers.** Three rules
|
|
48
|
-
answer it:
|
|
49
|
-
|
|
50
|
-
- **A worker reports through a tool call, never in prose.** "Done" in a chat message changes nothing.
|
|
51
|
-
- **Only the engine writes a ticket.** A worker that could edit its own ticket could mark its own work done.
|
|
52
|
-
- **A restart loses nothing and repeats nothing.** A read position commits only once the engine holds
|
|
53
|
-
what it produced, every trigger carries an id the engine accepts once, and every outgoing message
|
|
54
|
-
carries an id the outbox posts once.
|
|
55
|
-
|
|
56
|
-
The ticket lifecycle, the GitHub intake and the worker sweep are specified in TLA+ and checked
|
|
57
|
-
exhaustively, 1.5 million distinct states in all, by one command.
|
|
3
|
+
Open a GitHub issue and tell pi-superagent what you’d like to change. A coding agent works on it
|
|
4
|
+
in a checkout on your machine and opens a pull request for you to review. If you ask for a
|
|
5
|
+
revision, the same agent picks it up.
|
|
6
|
+
|
|
7
|
+
You can follow the conversation on GitHub or open the agent’s terminal to see what it’s trying
|
|
8
|
+
and lend a hand.
|
|
58
9
|
|
|
59
10
|
## Install
|
|
60
11
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
12
|
+
You’ll need Git, Node 22.19 or later, and three tools on a Mac or Linux machine. Pi runs the coding
|
|
13
|
+
sessions. Herdr gives each session a terminal tab. The GitHub CLI (`gh`) lets the agent read issues
|
|
14
|
+
and open pull requests using your account. [pi](https://github.com/earendil-works/pi) ·
|
|
15
|
+
[herdr](https://herdr.dev) · [GitHub CLI](https://cli.github.com)
|
|
16
|
+
|
|
17
|
+
Sign in to a model provider in pi and check that your model appears in `pi --list-models`. Then
|
|
18
|
+
sign in to GitHub with an account that can write to the repository you want to use.
|
|
65
19
|
|
|
66
20
|
```sh
|
|
67
21
|
gh auth login
|
|
@@ -70,83 +24,76 @@ pi install npm:pi-superagent
|
|
|
70
24
|
npm install -g pi-superagent
|
|
71
25
|
```
|
|
72
26
|
|
|
73
|
-
|
|
74
|
-
|
|
27
|
+
The first install gives pi the extension. The second gives you the `superagent` command to start,
|
|
28
|
+
stop and check on it. Keep the two at the same version when you update.
|
|
75
29
|
|
|
76
|
-
##
|
|
30
|
+
## Try it on one issue
|
|
77
31
|
|
|
78
|
-
|
|
79
|
-
and your GitHub access, then saves the repository in `~/.pi/superagent/config.env`.
|
|
32
|
+
Choose a repository and open herdr in your terminal.
|
|
80
33
|
|
|
81
34
|
```sh
|
|
82
35
|
superagent init your-org/your-repo
|
|
83
|
-
herdr
|
|
36
|
+
herdr
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Leave herdr open. In a second terminal, start the **router**, the background session that watches
|
|
40
|
+
your repository and sends work to the right agent.
|
|
41
|
+
|
|
42
|
+
```sh
|
|
84
43
|
superagent start
|
|
85
44
|
superagent status
|
|
86
45
|
```
|
|
87
46
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
| `src/pi/source-github.ts`, `gh-api.ts` | GitHub in: issues, comments and reviews become triggers |
|
|
128
|
-
| `src/pi/pulls.ts` | pull requests: bound to their ticket, followed until merged or closed |
|
|
129
|
-
| `src/pi/assessor.ts`, `judge.ts` | the judge: one candidate at a time, answered through `ticket_decide` |
|
|
130
|
-
| `src/pi/executor.ts`, `herdr-workers.ts` | workers: pi sessions in herdr tabs, and records that outlive the router |
|
|
131
|
-
| `src/pi/worker-role.ts`, `report-tool.ts`, `workspace.ts` | inside a worker: the report tool, the guard, the workspace |
|
|
132
|
-
| `src/pi/outbox.ts`, `receipts.ts` | GitHub out: what each ending says, each message posted once |
|
|
133
|
-
| `src/pi/store.ts` | the engine's SQLite store |
|
|
134
|
-
| `src/pi/server.ts` | the panel and its local API |
|
|
135
|
-
| `scripts/superagent` | start, stop, restart and status, with exit codes a health check can read |
|
|
136
|
-
| `formal/` | the TLA+ specifications |
|
|
47
|
+
In herdr, find the `superagent` workspace and wait for the first GitHub poll in the **engine log**
|
|
48
|
+
tab. That first look records the issues already open. Now open a new issue with a small request.
|
|
49
|
+
For example, “Show the keyboard shortcut next to Export in the Help menu.”
|
|
50
|
+
|
|
51
|
+
When the router accepts the request, it replies on the issue and opens a **ticket**, its record of
|
|
52
|
+
the work. A **worker** is the pi session assigned to that ticket. It gets its own checkout and a
|
|
53
|
+
tab labeled with the issue number. You can type into the tab, though usually a comment on the
|
|
54
|
+
issue is enough. If the worker needs a decision, it asks there.
|
|
55
|
+
|
|
56
|
+
A code change comes back as a pull request. Review the diff as usual. The ticket stays open while
|
|
57
|
+
you discuss the change and ends when you merge or close the PR. You can also ask a question, such
|
|
58
|
+
as where the shortcut is defined. For that, an answer on the issue can finish the job.
|
|
59
|
+
|
|
60
|
+
## While the worker runs
|
|
61
|
+
|
|
62
|
+
- **On GitHub**, reply on the issue to add a detail, or on the pull request to request a revision.
|
|
63
|
+
To stop work before there’s a PR, close the issue. Reopening it makes a fresh request.
|
|
64
|
+
- **In herdr**, open the tab with the issue number to see the worker’s commands and output. The
|
|
65
|
+
**engine log** tab shows what the router picked up and which requests it accepted.
|
|
66
|
+
- **In the local panel**, look under *Needs a person* to see who’s waiting for an answer. You can
|
|
67
|
+
also see running workers, queued work and recent decisions. [Open the panel](http://127.0.0.1:8788/)
|
|
68
|
+
|
|
69
|
+
By default, the router listens to authors GitHub identifies as owners, organization members or
|
|
70
|
+
collaborators. You can choose particular logins, give the router its own GitHub account, or supply
|
|
71
|
+
a custom workspace setup. Run `superagent stop` when you want to stop the router.
|
|
72
|
+
[Operator guide](docs/operator-guide.md) · [Configuration examples](config.example.env)
|
|
73
|
+
|
|
74
|
+
## How it works
|
|
75
|
+
|
|
76
|
+
A separate pi session called the **judge** reads a new request and decides whether there’s work to
|
|
77
|
+
do. Once a ticket is open, follow-up comments go straight to its worker. The worker reports the
|
|
78
|
+
outcome through a tool call, which lets the router distinguish a finished run from a question or
|
|
79
|
+
a crash. The router stores the ticket on disk, so after a restart it can find the worker and pick
|
|
80
|
+
up the conversation. [Architecture](docs/architecture.md) · [Design decisions](docs/design-decisions.md)
|
|
81
|
+
|
|
82
|
+
The ticket engine comes from DeepSeek’s dsh-superagent-prototype. Three TLA+ models check how
|
|
83
|
+
tickets, incoming messages and worker tabs behave when events arrive in different orders.
|
|
84
|
+
[Upstream project](https://github.com/deepseek-ai/dsh-superagent-prototype) ·
|
|
85
|
+
[Adaptation ledger](ADAPTATION.md) · [Formal verification](docs/formal-verification.md)
|
|
137
86
|
|
|
138
87
|
## Development
|
|
139
88
|
|
|
140
89
|
```sh
|
|
141
90
|
npm install
|
|
142
|
-
npm run check #
|
|
143
|
-
npm run check:packed #
|
|
144
|
-
scripts/check-formal #
|
|
91
|
+
npm run check # Type-check and run the test suite
|
|
92
|
+
npm run check:packed # Install the tarball and exercise both the CLI and the pi extension
|
|
93
|
+
scripts/check-formal # Check all three models (about five minutes with a JDK)
|
|
145
94
|
```
|
|
146
95
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
The suite clears every `PI_SUPERAGENT_*` variable before it runs (`test/setup.ts`), so no test can reach a
|
|
150
|
-
live router.
|
|
96
|
+
The test suite clears `PI_SUPERAGENT_*` settings to isolate its router from yours.
|
|
97
|
+
Publishing runs both npm checks before uploading the package.
|
|
151
98
|
|
|
152
|
-
|
|
99
|
+
Both projects use the MIT license. [Upstream attribution](NOTICE)
|