@plurnk/plurnk-service 0.34.0 → 0.35.0
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/SPEC.md +30 -5
- package/dist/core/ChannelWrite.d.ts +1 -0
- package/dist/core/ChannelWrite.d.ts.map +1 -1
- package/dist/core/ChannelWrite.js.map +1 -1
- package/dist/core/Engine.d.ts +8 -2
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +95 -24
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/ExecutorRegistry.d.ts +2 -0
- package/dist/core/ExecutorRegistry.d.ts.map +1 -1
- package/dist/core/ExecutorRegistry.js +1 -0
- package/dist/core/ExecutorRegistry.js.map +1 -1
- package/dist/core/SchemeRegistry.d.ts +4 -0
- package/dist/core/SchemeRegistry.d.ts.map +1 -1
- package/dist/core/SchemeRegistry.js +18 -1
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/git-membership.d.ts.map +1 -1
- package/dist/core/git-membership.js +4 -1
- package/dist/core/git-membership.js.map +1 -1
- package/dist/core/git-state.d.ts.map +1 -1
- package/dist/core/git-state.js +3 -1
- package/dist/core/git-state.js.map +1 -1
- package/dist/core/path-decode.d.ts +2 -0
- package/dist/core/path-decode.d.ts.map +1 -0
- package/dist/core/path-decode.js +8 -0
- package/dist/core/path-decode.js.map +1 -0
- package/dist/core/run-cap.d.ts +8 -0
- package/dist/core/run-cap.d.ts.map +1 -0
- package/dist/core/run-cap.js +20 -0
- package/dist/core/run-cap.js.map +1 -0
- package/dist/core/session-settings.d.ts +19 -0
- package/dist/core/session-settings.d.ts.map +1 -0
- package/dist/core/session-settings.js +44 -0
- package/dist/core/session-settings.js.map +1 -0
- package/dist/schemes/File.d.ts.map +1 -1
- package/dist/schemes/File.js +3 -1
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Run.d.ts.map +1 -1
- package/dist/schemes/Run.js +5 -1
- package/dist/schemes/Run.js.map +1 -1
- package/dist/schemes/_entry-find.d.ts.map +1 -1
- package/dist/schemes/_entry-find.js +4 -3
- package/dist/schemes/_entry-find.js.map +1 -1
- package/dist/schemes/_entry-graph.d.ts +6 -0
- package/dist/schemes/_entry-graph.d.ts.map +1 -1
- package/dist/schemes/_entry-graph.js +8 -0
- package/dist/schemes/_entry-graph.js.map +1 -1
- package/dist/schemes/_entry-manifest.d.ts.map +1 -1
- package/dist/schemes/_entry-manifest.js +13 -0
- package/dist/schemes/_entry-manifest.js.map +1 -1
- package/dist/schemes/_entry-ops.d.ts.map +1 -1
- package/dist/schemes/_entry-ops.js +4 -3
- package/dist/schemes/_entry-ops.js.map +1 -1
- package/dist/schemes/_entry-send.d.ts.map +1 -1
- package/dist/schemes/_entry-send.js +4 -3
- package/dist/schemes/_entry-send.js.map +1 -1
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +6 -0
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/envelope.d.ts +2 -0
- package/dist/server/envelope.d.ts.map +1 -1
- package/dist/server/envelope.js +8 -1
- package/dist/server/envelope.js.map +1 -1
- package/dist/server/methods/discover.d.ts.map +1 -1
- package/dist/server/methods/discover.js +6 -3
- package/dist/server/methods/discover.js.map +1 -1
- package/dist/server/methods/loop_run.d.ts.map +1 -1
- package/dist/server/methods/loop_run.js +14 -10
- package/dist/server/methods/loop_run.js.map +1 -1
- package/dist/server/methods/session_create.d.ts.map +1 -1
- package/dist/server/methods/session_create.js +51 -1
- package/dist/server/methods/session_create.js.map +1 -1
- package/dist/server/methods/session_prompts.d.ts +5 -0
- package/dist/server/methods/session_prompts.d.ts.map +1 -0
- package/dist/server/methods/session_prompts.js +29 -0
- package/dist/server/methods/session_prompts.js.map +1 -0
- package/dist/server/version-info.d.ts +14 -0
- package/dist/server/version-info.d.ts.map +1 -0
- package/dist/server/version-info.js +69 -0
- package/dist/server/version-info.js.map +1 -0
- package/dist/server/yolo.d.ts.map +1 -1
- package/dist/server/yolo.js +8 -0
- package/dist/server/yolo.js.map +1 -1
- package/migrations/0000-00-00.01_schema.sql +21 -1
- package/package.json +2 -2
package/SPEC.md
CHANGED
|
@@ -172,7 +172,7 @@ Server posture: this package is the runtime. User-facing CLI lives in `plurnk` a
|
|
|
172
172
|
|
|
173
173
|
**Migration path.** Mostly stating what the schema already carries: `runs.parent_run_id` and the parentless `sessions` exist (§lifecycle-terms); `session_constraints` is session-level (§membership); §env-delta already makes a run's timeline self-contained, so a fork's log copy suffices. Additive: `run.fork` over the wire (the engine fork is built). Two repatriations: §actor-boundary's "read-only overlay scopes a run's writable surface" becomes a *session* policy bounding every run uniformly; and the §env-delta environment door has shed its per-run snapshot — a run's only memory is its log, so drift is pulled from the shared log (other actors' edits since the run's last turn) and the filesystem narrates its own through the `plurnk` run, both already log entries, never a per-run shadow.
|
|
174
174
|
|
|
175
|
-
### §run-scheme The run:// scheme — spawn, irc, fork
|
|
175
|
+
### §run-scheme The run:// scheme — spawn, irc, fork, terminate, cap, collect
|
|
176
176
|
|
|
177
177
|
The run:// scheme makes §machine-processes addressable: a `run://` target is a sister run in the session — `run:///.` the current run, `run:///<name>` a session-scoped sibling (`runs.name`). Same-session only; a run never addresses another session's runs (§actor-boundary). Three ops, fire-and-forget — the child runs independently, lineage in `runs.parent_run_id`:
|
|
178
178
|
|
|
@@ -182,6 +182,12 @@ The run:// scheme makes §machine-processes addressable: a `run://` target is a
|
|
|
182
182
|
|
|
183
183
|
All three ride one engine seam — the daemon's inject (active→fold, idle→enqueue+drain) — so the handler creates/branches/resolves the run and hands off; the daemon owns provider + system prompt. COPY's body here is the fork's seed prompt, not a destination path: the engine routes a run:// source away from the entry-copy path before parsing the body.
|
|
184
184
|
|
|
185
|
+
Beyond the three creation ops:
|
|
186
|
+
|
|
187
|
+
- **Terminate** — `KILL(run:///<name>)` aborts a run by address (self when `.`): its active loop closes 499 and its subscriptions tear down; a name with no run is 404. The override to the fire-and-forget default — not a parent-power, whoever holds the address may end it; a run left alone simply ends at its own `SEND[200]`. {§run-scheme-terminate}
|
|
188
|
+
- **Cap** — `PLURNK_SESSION_RUNS_MAX_ACTIVE` ceilings the *concurrent* active runs per session (a run with a non-terminal loop); a spawn or fork past it fails hard (508 — no queue, no retry), irc exempt; `-1` disables it. The fork-bomb brake, sized for sessions that live for months. {§run-scheme-cap}
|
|
189
|
+
- **Collect** — a run's loop reaching a terminal status surfaces to its sisters as an ambient FOLDED delta (§env-delta): a `SEND` from `run:///<name>` carrying the loop's deliverable — the `SEND[200]` body, or for an abandonment the reason. Every death-path is stamped uniformly, so no termination is silent; collection is the shared world moving, never a verb. {§run-scheme-collect}
|
|
190
|
+
|
|
185
191
|
---
|
|
186
192
|
|
|
187
193
|
## §provider Provider Contract
|
|
@@ -345,7 +351,7 @@ No mimetype handlers ship in-tree. Framework + every handler are siblings.
|
|
|
345
351
|
|
|
346
352
|
plurnk-service is mimetype-illiterate. Engine hands channel content + mimetype label to `Mimetypes.process({content, hint})`; the manifest build uses `result.totalLines` for each channel's `lines`. Content reaches the model on READ, not as a rendered preview.
|
|
347
353
|
|
|
348
|
-
**Required
|
|
354
|
+
**Required handlers** (boot-critical, provided via the framework):
|
|
349
355
|
|
|
350
356
|
| Package | Mimetype | Why required |
|
|
351
357
|
|---|---|---|
|
|
@@ -353,7 +359,7 @@ plurnk-service is mimetype-illiterate. Engine hands channel content + mimetype l
|
|
|
353
359
|
| `@plurnk/plurnk-mimetypes-text-plain` | `text/plain` | Canonical EXEC stdout/stderr channel mimetype. |
|
|
354
360
|
| `@plurnk/plurnk-mimetypes-application-json` | `application/json`, `application/jsonc` | Service emits json for `log_entries` rx/tx, telemetry, packet serialization. |
|
|
355
361
|
|
|
356
|
-
Everything else is opt-in; framework's `discover()` picks up installed packages automatically.
|
|
362
|
+
These ride in via the framework — `@plurnk/plurnk-mimetypes` pins the core set (markdown / plain / json / xml / csv / html) as its own dependencies, so the service's exact-pin on the framework pins them transitively rather than redeclaring each. Boot relies on them (markdown is the `defaultMimetype`); their loss would be a framework-contract break. Everything else is opt-in; framework's `discover()` picks up installed packages automatically.
|
|
357
363
|
|
|
358
364
|
**Tokenize injection.** Daemon constructs `Mimetypes` with a `tokenize` lambda capturing the active provider's `countTokens`:
|
|
359
365
|
|
|
@@ -739,6 +745,16 @@ Model selection: separate alias cascade in `ProviderRegistry` (§provider-instan
|
|
|
739
745
|
|
|
740
746
|
Enforcement is per-use-site — no central most-restrictive pass; each ceiling is checked where it bites. `PLURNK_MAX_TURNS` ships **off** (`-1` = no cap; the loop ends via SEND, budget, strikes, or cycle detection) and, when an operator sets a positive value, the per-call request is `min()`-capped against it. {§operator-config-max-turns-ceiling}
|
|
741
747
|
|
|
748
|
+
**Client open-context (per session).** `session.create({settings})` carries per-session overrides, persisted on `sessions.settings` and composed against env at each knob's read-site. Two families, kept distinct so neither semantic leaks into the other; operator-arcane knobs stay env-only — this is the narrow client surface.
|
|
749
|
+
|
|
750
|
+
*Defaults — explicit-wins (the client replaces/merges freely):*
|
|
751
|
+
- `settings.manifestItems` (number) **replaces** `PLURNK_MANIFEST_ITEMS` for the session: a one-shot opens clean (`0`), a workspace full (`-1`) or capped (`N`). A single scalar — the client value wins outright. {§operator-config-session-manifest-items}
|
|
752
|
+
- `settings.mdDocs` (`[{alias, content}]`) **unions** with the server's `PLURNK_MD_*` docs, keyed by alias — a client adds its own repo docs atop the operator's systemwide policy doc. On alias collision the client wins (a deliberate shadow), but by default the policy doc rides into every session. The client sends content (it owns the file), not a path. {§operator-config-session-md-docs}
|
|
753
|
+
|
|
754
|
+
*Ceilings — most-restrictive-wins (the client may only narrow, never widen):*
|
|
755
|
+
- `settings.maxCommands` (number) **min()s** the `PLURNK_MAX_COMMANDS` per-emission cap for the session — a client tightens the runaway-op guard, never raises it past the operator's. {§operator-config-session-max-commands}
|
|
756
|
+
- `settings.git` (`false`) **denies** git for the session (`PLURNK_GIT_ALLOWED` AND session) — the client opts its session out of git membership + telemetry; it can never re-enable git past the operator's service-wide lockout. {§operator-config-session-git}
|
|
757
|
+
|
|
742
758
|
Feature-flag bools use `process.env.X === "1"` exactly — never `=== "true"`.
|
|
743
759
|
|
|
744
760
|
External plugins declare their own env vars in their own `.env.example`; service merges at boot via the cascade.
|
|
@@ -807,12 +823,18 @@ registry.register("loop.run", {
|
|
|
807
823
|
"providers": [...],
|
|
808
824
|
"schemes": [...],
|
|
809
825
|
"mimetypes": [...]
|
|
826
|
+
},
|
|
827
|
+
"versions": {
|
|
828
|
+
"service": { "installed": "0.34.0", "latest": "0.35.0" },
|
|
829
|
+
"client": { "latest": "0.15.0" }
|
|
810
830
|
}
|
|
811
831
|
}
|
|
812
832
|
```
|
|
813
833
|
|
|
814
834
|
`capabilities` lists registered plug-ins by `(kind, name)`. Cold clients call `discover` first. No hardcoded method names or capability lists in any client. {§discovery-discover}
|
|
815
835
|
|
|
836
|
+
`versions` rides the same round-trip so a client shows update status without per-invocation registry IO: `{ service: { installed, latest? }, client: { latest? } }`. `service.installed` is the daemon's own `package.json` version (honest self-report); `latest` is a **cached, best-effort** npm-registry poll (TTL `PLURNK_VERSION_POLL_TTL`) for the service (`@plurnk/plurnk-service`) and client (`@plurnk/plurnk`) packages — offline or registry-down omits `latest`, and the poll never blocks or fails `discover`. The client owns reading its own installed version and the semver compare. {§discovery-versions}
|
|
837
|
+
|
|
816
838
|
### §methods Core method set
|
|
817
839
|
|
|
818
840
|
**Liveness + introspection**
|
|
@@ -826,10 +848,11 @@ registry.register("loop.run", {
|
|
|
826
848
|
|
|
827
849
|
| Method | Params | Result | Notes |
|
|
828
850
|
|------------------------|---------------------|-------------------|-------|
|
|
829
|
-
| `session.create` | `name?: string`, `projectRoot?: string` | `{ id, name, runId, runName, projectRoot }` | Creates new session + its first run; auto-name if unprovided. Returns the auto-created run's identity so clients skip the pending-dance ({§methods-session-create}). Optional `projectRoot` pins the workspace (null/omitted = headless). |
|
|
851
|
+
| `session.create` | `name?: string`, `projectRoot?: string`, `settings?: object` | `{ id, name, runId, runName, projectRoot }` | Creates new session + its first run; auto-name if unprovided. Returns the auto-created run's identity so clients skip the pending-dance ({§methods-session-create}). Optional `projectRoot` pins the workspace (null/omitted = headless); optional `settings` carries per-session open-context overrides (§operator-config). |
|
|
830
852
|
| `session.list` | none | `{ sessions: Session[] }` | Lists all sessions. |
|
|
831
853
|
| `session.attach` | `id: number`, `runId?: number`, `runName?: string` | `{ id, name, runId, runName }` | Binds this connection to an existing session. Optional `runId` resumes that specific run (must belong to the session). Optional `runName` reuses-or-creates by name within the session. Both omitted → new auto-named run. {§methods-session-attach} |
|
|
832
854
|
| `session.runs` | `id?: number` | `{ runs: Run[] }` | Lists runs in a session (defaults to attached session); most-recent first. |
|
|
855
|
+
| `session.prompts` | `id?: number`, `limit?: number` | `{ prompts: string[] }` | A session's prior user prompts (the conversation run's loop seeds), newest-first, capped by `limit` (default 100); defaults to attached session. Lets a client seed up/down recall without log archaeology. |
|
|
833
856
|
| `session.set_root` | `projectRoot: string \| null` | `{ projectRoot }` | Update the workspace pointer on the attached session. Null reverts to headless. |
|
|
834
857
|
| `session.constrain` | `effect: "add" \| "ignore" \| "read-only"`, `glob: string` | `{ effect, glob }` | Add a workspace membership constraint (§membership overlay): `add` admits files git misses, `ignore` drops tracked matches, `read-only` admits for read but refuses edits. Immediate. |
|
|
835
858
|
| `session.unconstrain` | `effect: "add" \| "ignore" \| "read-only"`, `glob: string` | `{ effect, glob }` | Remove a membership constraint — the inverse of `session.constrain`. Immediate. |
|
|
@@ -1096,6 +1119,8 @@ Each entry: question, answer, rationale, migration path.
|
|
|
1096
1119
|
|
|
1097
1120
|
**The notification carries the flag.** `loop/proposal` carries `flags` (§notifications), `yolo` among them, so a client attached to a *server*-YOLO loop can suppress its review UI — those proposals resolve in-process before any human could react, and rendering a doomed review prompt is noise. {§dual-yolo-proposal-carries-flags}
|
|
1098
1121
|
|
|
1122
|
+
**Server-YOLO is not blind — it refuses a stale clobber.** Auto-accept is not accept-everything: when an EDIT's target diverged on disk *this turn* — a `source=file` env-delta landed in the run's log since the model's prior turn — the model's EDIT is based on a stale read, and accepting it would silently overwrite the ambient change. The engine flags such a proposal `staleClobberRisk`, and the server-YOLO listener **rejects** it (the reject's outcome is forensics-only, never in the model's rx) rather than accepting; the model sees an ordinary reject and can re-READ the current content and retry. The guard is the engine's, on the auto-accept path it owns. {§dual-yolo-stale-clobber-reject}
|
|
1123
|
+
|
|
1099
1124
|
**Why two.** They answer different questions. Server-side asks *"is a human in the loop at all?"* — and when the answer is no, dispatch must not block on a `loop.resolve` that will never come. Client-side asks *"does this human want to review each one?"* — a presentation choice that leaves the protocol untouched. Collapsing them would either force a client onto every headless run or leak an interactive preference into the engine's dispatch path. They are orthogonal by construction: the engine gate and the human gate, each bypassable on its own terms.
|
|
1100
1125
|
|
|
1101
1126
|
**Migration path.** Built. `loops.flags.yolo` persists and the `yolo` listener (`src/server/yolo.ts`) auto-resolves; `loop/proposal` already carries `flags`. Client-side YOLO is wholly the client's (`@plurnk/plurnk`) concern — the service offers nothing to build for it beyond the `loop.resolve` RPC it already has.
|
|
@@ -1128,7 +1153,7 @@ type Packet = {
|
|
|
1128
1153
|
|
|
1129
1154
|
**Prompt as a first-class entry.** Each loop's prompt is written on loop start as a plurnk-origin `EDIT` against `plurnk:///prompt/<loop_id>` (indexable, body channel, text/markdown). At render time the current loop's prompt body materializes into `packet.user.prompt`; the entry itself stays READ/FOLD-able like any other. The foisted `EDIT`'s **log row is folded by default** (`indexed=0`): the prompt body already lives in `packet.user.prompt`, so the log keeps the action for forensics while collapsing the duplicate body, re-OPENable like any fold (§open-fold). {§prompt-fold}
|
|
1130
1155
|
|
|
1131
|
-
**The entry catalog.** `plurnk:///manifest.json` is a real session entry the model READs to discover what's available — rewritten every turn as a live view of the full entry set. Built in the schemes layer (`_entry-manifest`) and materialized like any entry (the engine only orchestrates the per-turn write — the same pattern as git membership), so it's READable and queryable. Body is `application/json`: a flat, **complete, unranked** array — one item per entry across all schemes, every entry listed in no relevance order, each `{ path, channels: { <name>: { mimetype, tokens, lines } } }`. The model ranks and filters the catalog itself by querying it (task-aware); the catalog never ranks for it — the instant it did, it would be an index again. `tokens` is the provider's write-time count (budget depth), `lines` the content extent from `Mimetypes.process().totalLines`. The engine counts neither. It does not list itself. {§packet-manifest-catalog}
|
|
1156
|
+
**The entry catalog.** `plurnk:///manifest.json` is a real session entry the model READs to discover what's available — rewritten every turn as a live view of the full entry set. Built in the schemes layer (`_entry-manifest`) and materialized like any entry (the engine only orchestrates the per-turn write — the same pattern as git membership), so it's READable and queryable. Body is `application/json`: a flat, **complete, unranked** array — one item per entry across all schemes, every entry listed in no relevance order, each `{ path, tags?, channels: { <name>: { mimetype, tokens, lines } } }`. `tags` is present only when the entry carries `entry_tags` — its own categorization, surfaced so the model sees it in the directory and can `FIND` by tag without a separate read. The model ranks and filters the catalog itself by querying it (task-aware); the catalog never ranks for it — the instant it did, it would be an index again. `tokens` is the provider's write-time count (budget depth), `lines` the content extent from `Mimetypes.process().totalLines`. The engine counts neither. It does not list itself. {§packet-manifest-catalog}
|
|
1132
1157
|
|
|
1133
1158
|
### §telemetry user.telemetry — model-facing runtime telemetry
|
|
1134
1159
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChannelWrite.d.ts","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAMtE,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,YAAY,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAQvF,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;AAU9D,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,oBAAoB,GAAG,mBAAmB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ChannelWrite.d.ts","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChannelWrite.js","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,sFAAsF;AACtF,EAAE;AACF,mFAAmF;AACnF,4FAA4F;AAC5F,8EAA8E;AAC9E,2EAA2E;AAC3E,gCAAgC;
|
|
1
|
+
{"version":3,"file":"ChannelWrite.js","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"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"}
|
package/dist/core/Engine.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { Mimetypes } from "@plurnk/plurnk-mimetypes";
|
|
|
4
4
|
import type { Db } from "./Db.ts";
|
|
5
5
|
import type { WriterTier, LoopFlags } from "./scheme-types.ts";
|
|
6
6
|
import type ExecutorRegistry from "./ExecutorRegistry.ts";
|
|
7
|
-
import type { StreamEventNotify, TelemetryEventNotify, WakeRunNotify, InjectRunNotify } from "./ChannelWrite.ts";
|
|
7
|
+
import type { StreamEventNotify, TelemetryEventNotify, WakeRunNotify, InjectRunNotify, CancelRunNotify } from "./ChannelWrite.ts";
|
|
8
8
|
type ChatMessage = {
|
|
9
9
|
role: "system" | "user" | "assistant";
|
|
10
10
|
content: string;
|
|
@@ -45,6 +45,7 @@ export interface ProposalPendingEvent {
|
|
|
45
45
|
body: string;
|
|
46
46
|
attrs: object;
|
|
47
47
|
flags: LoopFlags;
|
|
48
|
+
staleClobberRisk: boolean;
|
|
48
49
|
}
|
|
49
50
|
export default class Engine {
|
|
50
51
|
#private;
|
|
@@ -57,13 +58,14 @@ export default class Engine {
|
|
|
57
58
|
period: number;
|
|
58
59
|
cycles: number;
|
|
59
60
|
};
|
|
60
|
-
constructor({ db, schemes, mimetypes, streamEventNotify, wakeRunNotify, injectRun, telemetryEventNotify, tokenize }: {
|
|
61
|
+
constructor({ db, schemes, mimetypes, streamEventNotify, wakeRunNotify, injectRun, cancelRun, telemetryEventNotify, tokenize }: {
|
|
61
62
|
db: Db;
|
|
62
63
|
schemes: SchemeRegistry;
|
|
63
64
|
mimetypes?: Mimetypes;
|
|
64
65
|
streamEventNotify?: StreamEventNotify;
|
|
65
66
|
wakeRunNotify?: WakeRunNotify;
|
|
66
67
|
injectRun?: InjectRunNotify;
|
|
68
|
+
cancelRun?: CancelRunNotify;
|
|
67
69
|
telemetryEventNotify?: TelemetryEventNotify;
|
|
68
70
|
tokenize?: (text: string) => number;
|
|
69
71
|
});
|
|
@@ -113,6 +115,10 @@ export default class Engine {
|
|
|
113
115
|
budgetStruck: boolean;
|
|
114
116
|
budgetHardStop: boolean;
|
|
115
117
|
}>;
|
|
118
|
+
docEntries(): Array<{
|
|
119
|
+
name: string;
|
|
120
|
+
content: string;
|
|
121
|
+
}>;
|
|
116
122
|
dispatch(context: DispatchContext): Promise<DispatchResult>;
|
|
117
123
|
resolveProposal(logEntryId: number, resolution: ProposalResolution): void;
|
|
118
124
|
pendingProposalIds(): number[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../src/core/Engine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAwF,MAAM,wBAAwB,CAAC;AAMpJ,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAiB,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../src/core/Engine.ts"],"names":[],"mappings":"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"}
|
package/dist/core/Engine.js
CHANGED
|
@@ -6,6 +6,9 @@ import EntryManifest from "../schemes/_entry-manifest.js";
|
|
|
6
6
|
import GitMembership from "./git-membership.js";
|
|
7
7
|
import GitState from "./git-state.js";
|
|
8
8
|
import Fork from "./fork.js";
|
|
9
|
+
import RunCap from "./run-cap.js";
|
|
10
|
+
import SessionSettings from "./session-settings.js";
|
|
11
|
+
import { decodePathParens } from "./path-decode.js";
|
|
9
12
|
import { DEFAULT_LOOP_FLAGS } from "./scheme-types.js";
|
|
10
13
|
import { LineMarkerOps, MimetypeBinary, editedSpan } from "../content/index.js";
|
|
11
14
|
import { readFile } from "node:fs/promises";
|
|
@@ -60,14 +63,12 @@ const readMaxCommands = () => {
|
|
|
60
63
|
};
|
|
61
64
|
// PLURNK_MANIFEST_ITEMS — the turn-0 manifest preview. null = off (no foist);
|
|
62
65
|
// -1 = the full manifest; positive N = the first N items. 0 / unset = off.
|
|
66
|
+
const normalizeManifestItems = (n) => (!Number.isFinite(n) || n === 0 ? null : n < 0 ? -1 : n);
|
|
63
67
|
const readManifestItems = () => {
|
|
64
68
|
const raw = process.env.PLURNK_MANIFEST_ITEMS;
|
|
65
69
|
if (raw === undefined || raw.length === 0)
|
|
66
70
|
return null;
|
|
67
|
-
|
|
68
|
-
if (!Number.isFinite(n) || n === 0)
|
|
69
|
-
return null;
|
|
70
|
-
return n < 0 ? -1 : n;
|
|
71
|
+
return normalizeManifestItems(Number.parseInt(raw, 10));
|
|
71
72
|
};
|
|
72
73
|
// Resolution timeout — proposed entries auto-cancel if nothing arrives
|
|
73
74
|
// within this window. SPEC.md §engine-rails (proposal lifecycle) + §methods (loop.resolve).
|
|
@@ -82,9 +83,9 @@ const readProposalTimeoutMs = () => {
|
|
|
82
83
|
return n;
|
|
83
84
|
};
|
|
84
85
|
const pathnameFromPath = (path) => {
|
|
85
|
-
if (path.kind === "
|
|
86
|
-
return path.
|
|
87
|
-
return path.raw;
|
|
86
|
+
if (path.kind === "regex")
|
|
87
|
+
return path.raw; // regex source — parens are syntax, never encoded
|
|
88
|
+
return decodePathParens(path.kind === "url" ? path.pathname : path.raw); // #239 item 4
|
|
88
89
|
};
|
|
89
90
|
// Default turn.status when ops were emitted but no SEND. Model is implicitly
|
|
90
91
|
// continuing; loop.status stays 102 either way (only SEND broadcast advances
|
|
@@ -241,6 +242,7 @@ class Engine {
|
|
|
241
242
|
#streamEventNotify;
|
|
242
243
|
#wakeRunNotify;
|
|
243
244
|
#injectRun;
|
|
245
|
+
#cancelRun;
|
|
244
246
|
// Telemetry event fan-out: every TelemetryEvent pushed to the loop's
|
|
245
247
|
// buffer is also broadcast live to the connected client(s) on the
|
|
246
248
|
// session. Without this, the client sees `loop/terminated` with a
|
|
@@ -249,12 +251,13 @@ class Engine {
|
|
|
249
251
|
#telemetryEventNotify;
|
|
250
252
|
// Cached plurnk GBNF — read once on the first constrained generate (#189).
|
|
251
253
|
#gbnfCache = null;
|
|
252
|
-
constructor({ db, schemes, mimetypes, streamEventNotify, wakeRunNotify, injectRun, telemetryEventNotify, tokenize }) {
|
|
254
|
+
constructor({ db, schemes, mimetypes, streamEventNotify, wakeRunNotify, injectRun, cancelRun, telemetryEventNotify, tokenize }) {
|
|
253
255
|
this.#db = db;
|
|
254
256
|
this.#schemes = schemes;
|
|
255
257
|
this.#streamEventNotify = streamEventNotify;
|
|
256
258
|
this.#wakeRunNotify = wakeRunNotify;
|
|
257
259
|
this.#injectRun = injectRun;
|
|
260
|
+
this.#cancelRun = cancelRun;
|
|
258
261
|
this.#telemetryEventNotify = telemetryEventNotify;
|
|
259
262
|
// Default to empty discovery — standalone Engine construction (in
|
|
260
263
|
// tests) gets no handlers, and content flows through the framework's
|
|
@@ -389,7 +392,7 @@ class Engine {
|
|
|
389
392
|
return { turnIds, finalStatus: row.status, hitMaxTurns: false, reason: "external" };
|
|
390
393
|
}
|
|
391
394
|
if (maxTurns >= 0 && turnIds.length >= maxTurns) {
|
|
392
|
-
await this.#db.engine_loop_cancel.run({ loop_id: loopId });
|
|
395
|
+
await this.#db.engine_loop_cancel.run({ loop_id: loopId, message: "max_turns" });
|
|
393
396
|
cleanup("forceful", "max_turns");
|
|
394
397
|
return { turnIds, finalStatus: 499, hitMaxTurns: true, reason: "max_turns" };
|
|
395
398
|
}
|
|
@@ -410,7 +413,7 @@ class Engine {
|
|
|
410
413
|
turnIds.push(turn.turnId);
|
|
411
414
|
// SPEC §grinder: budget hard-stop — packet won't fit even collapsed → abandon.
|
|
412
415
|
if (turn.budgetHardStop) {
|
|
413
|
-
await this.#db.engine_loop_cancel.run({ loop_id: loopId });
|
|
416
|
+
await this.#db.engine_loop_cancel.run({ loop_id: loopId, message: "budget_overflow" });
|
|
414
417
|
cleanup("forceful", "budget_overflow");
|
|
415
418
|
return { turnIds, finalStatus: 499, hitMaxTurns: false, reason: "budget_overflow" };
|
|
416
419
|
}
|
|
@@ -451,7 +454,7 @@ class Engine {
|
|
|
451
454
|
if (struck) {
|
|
452
455
|
state.streak++;
|
|
453
456
|
if (state.streak >= maxStrikes) {
|
|
454
|
-
await this.#db.engine_loop_cancel.run({ loop_id: loopId });
|
|
457
|
+
await this.#db.engine_loop_cancel.run({ loop_id: loopId, message: "strike_threshold" });
|
|
455
458
|
cleanup("forceful", "strike_threshold");
|
|
456
459
|
return { turnIds, finalStatus: 499, hitMaxTurns: false, reason: "strike_threshold" };
|
|
457
460
|
}
|
|
@@ -506,7 +509,10 @@ class Engine {
|
|
|
506
509
|
// §actor-boundary keystone); foist a READ of each into THIS turn-0 so the model
|
|
507
510
|
// reads them inline. It sees only the READ — the materializing EDIT
|
|
508
511
|
// lives in the plurnk run's log, never the model's.
|
|
509
|
-
|
|
512
|
+
// #231 — env docs (PLURNK_MD_*) UNION the session's client docs; foist a READ of
|
|
513
|
+
// each materialized plurnk:///<alias>.md (loop_run materialized the same set).
|
|
514
|
+
const { mdDocs } = await SessionSettings.read(this.#db, sessionId);
|
|
515
|
+
for (const doc of await SessionSettings.resolveDocs(mdDocs)) {
|
|
510
516
|
const docTarget = {
|
|
511
517
|
kind: "url", raw: `plurnk:///${doc.entryName}`, scheme: "plurnk",
|
|
512
518
|
username: null, password: null, hostname: null, port: null,
|
|
@@ -584,7 +590,9 @@ class Engine {
|
|
|
584
590
|
// manifest is JSON); off by default. AFTER the manifest write so the READ hits
|
|
585
591
|
// it, not a 404; same plurnk-origin foist as the operator docs.
|
|
586
592
|
if (seq === 1) {
|
|
587
|
-
|
|
593
|
+
// #231 — a session's client-chosen manifestItems REPLACES the env default outright.
|
|
594
|
+
const { manifestItems: sessionMI } = await SessionSettings.read(this.#db, sessionId);
|
|
595
|
+
const manifestItems = sessionMI !== null ? normalizeManifestItems(sessionMI) : readManifestItems();
|
|
588
596
|
if (manifestItems !== null) {
|
|
589
597
|
const manifestRead = {
|
|
590
598
|
op: "READ", suffix: "", signal: null, lineMarker: null,
|
|
@@ -710,7 +718,8 @@ class Engine {
|
|
|
710
718
|
// entries (avoids bloating forensics with hundreds of identical refusals)
|
|
711
719
|
// and the model gets a single telemetry signal next packet so it knows
|
|
712
720
|
// its emission was truncated.
|
|
713
|
-
|
|
721
|
+
// #232 — a session's maxCommands is a tighten-only ceiling: min() the env ceiling.
|
|
722
|
+
const maxCommands = Math.min(readMaxCommands(), (await SessionSettings.read(this.#db, sessionId)).maxCommands ?? Number.POSITIVE_INFINITY);
|
|
714
723
|
const opsToDispatch = packetAssistant.ops.slice(0, maxCommands);
|
|
715
724
|
const droppedCount = opsCount - opsToDispatch.length;
|
|
716
725
|
const statuses = [];
|
|
@@ -905,10 +914,12 @@ class Engine {
|
|
|
905
914
|
for (const t of sections.log.byTurn)
|
|
906
915
|
lines.push(`| ${t.turn} | ${t.tokens} |`);
|
|
907
916
|
}
|
|
908
|
-
// The heaviest individual
|
|
909
|
-
//
|
|
917
|
+
// The heaviest individual log items — the FOLD targets behind the weight
|
|
918
|
+
// (§tokenomics {§tokenomics-largest-entries}). "items", not "entries": the readout
|
|
919
|
+
// lists log:/// rows (log items), distinct from catalog entries (plurnk.md: "EDIT
|
|
920
|
+
// is only for entries. Do not attempt to edit log items.").
|
|
910
921
|
if (sections.log.largest.length > 0) {
|
|
911
|
-
lines.push("Heaviest
|
|
922
|
+
lines.push("Heaviest items:", "| item | tokens |", "|---|--:|");
|
|
912
923
|
for (const e of sections.log.largest)
|
|
913
924
|
lines.push(`| ${e.path} | ${e.tokens} |`);
|
|
914
925
|
}
|
|
@@ -935,13 +946,31 @@ class Engine {
|
|
|
935
946
|
// no backticks — see packet-wire.ts).
|
|
936
947
|
if (this.#executors !== undefined) {
|
|
937
948
|
for (const tag of this.#executors.availableRuntimes()) {
|
|
938
|
-
const
|
|
939
|
-
if (example)
|
|
940
|
-
tools.push(`* ${example}`);
|
|
949
|
+
const entry = this.#executors.entry(tag);
|
|
950
|
+
if (entry?.example)
|
|
951
|
+
tools.push(`* ${entry.example}`);
|
|
952
|
+
// #note12 — link the executor's fuller doc (materialized at plurnk:///docs/<tag>);
|
|
953
|
+
// its token cost rides that manifest entry, so no inline recount here.
|
|
954
|
+
if (entry?.documentation)
|
|
955
|
+
tools.push(`* docs for ${tag}: plurnk:///docs/${tag}`);
|
|
941
956
|
}
|
|
942
957
|
}
|
|
943
958
|
return tools;
|
|
944
959
|
}
|
|
960
|
+
// #note12 — the daughter-provided reference docs (schemes' + execs' `documentation`),
|
|
961
|
+
// materialized at plurnk:///docs/<name> by loop_run (like operator docs) so the
|
|
962
|
+
// catalogue's doc-links READ and the manifest carries each doc's token cost.
|
|
963
|
+
docEntries() {
|
|
964
|
+
const out = this.#schemes.docs();
|
|
965
|
+
if (this.#executors !== undefined) {
|
|
966
|
+
for (const tag of this.#executors.availableRuntimes()) {
|
|
967
|
+
const doc = this.#executors.entry(tag)?.documentation;
|
|
968
|
+
if (doc !== undefined && doc.length > 0)
|
|
969
|
+
out.push({ name: tag, content: doc });
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
return out;
|
|
973
|
+
}
|
|
945
974
|
// SPEC §grinder — the budget grinder. Runs pre-LLM (in runTurn, after the packet
|
|
946
975
|
// is built, before provider.generate); fires only on actual overflow. Two
|
|
947
976
|
// passes, re-measuring between. Folds (never deletes) — the prior turn's logs,
|
|
@@ -1096,6 +1125,19 @@ class Engine {
|
|
|
1096
1125
|
});
|
|
1097
1126
|
written++;
|
|
1098
1127
|
}
|
|
1128
|
+
// §run-scheme — loop-terminations: a sibling's loop reaching terminal surfaces the
|
|
1129
|
+
// same way an entry-change does, carrying its deliverable (the SEND body) or the
|
|
1130
|
+
// abandonment reason. Folded, attributed to the terminated run.
|
|
1131
|
+
const terms = await this.#db.engine_pull_loop_terminations.all({ session_id: sessionId, run_id: runId, since });
|
|
1132
|
+
for (const t of terms) {
|
|
1133
|
+
await this.#db.engine_insert_loop_termination_delta.run({
|
|
1134
|
+
run_id: runId, loop_id: loopId, turn_id: turnId, sequence: fromSequence + written,
|
|
1135
|
+
source: String(t.run_id), pathname: `/${t.run_name}`,
|
|
1136
|
+
rx: t.terminal_message ?? `loop "${t.prompt}" ended (${t.status})`,
|
|
1137
|
+
status: t.status,
|
|
1138
|
+
});
|
|
1139
|
+
written++;
|
|
1140
|
+
}
|
|
1099
1141
|
return written;
|
|
1100
1142
|
}
|
|
1101
1143
|
// §env-delta — the filesystem as an actor. Ambient disk divergences detected at
|
|
@@ -1223,6 +1265,9 @@ class Engine {
|
|
|
1223
1265
|
// resolve synchronously inside their handlers.
|
|
1224
1266
|
const target = this.#extractTarget(statement.target);
|
|
1225
1267
|
const flags = await this.#loadLoopFlags(loopId); // the loop/proposal notification carries flags (yolo) — §dual-yolo-proposal-carries-flags
|
|
1268
|
+
// #note10 — if the target diverged on disk this turn, the model's EDIT is based
|
|
1269
|
+
// on a stale read; flag it so a YOLO auto-accept rejects instead of clobbering.
|
|
1270
|
+
const diverged = await this.#db.engine_target_diverged_this_turn.get({ run_id: runId, turn_id: turnId, scheme: target.scheme, pathname: target.pathname });
|
|
1226
1271
|
const event = {
|
|
1227
1272
|
logEntryId, sessionId, runId, loopId, turnId,
|
|
1228
1273
|
op: statement.op,
|
|
@@ -1230,6 +1275,7 @@ class Engine {
|
|
|
1230
1275
|
body: typeof result.body === "string" ? result.body : "",
|
|
1231
1276
|
attrs: (result.attrs ?? {}),
|
|
1232
1277
|
flags,
|
|
1278
|
+
staleClobberRisk: diverged !== undefined,
|
|
1233
1279
|
};
|
|
1234
1280
|
for (const listener of this.#proposalPendingListeners) {
|
|
1235
1281
|
try {
|
|
@@ -1567,6 +1613,9 @@ class Engine {
|
|
|
1567
1613
|
}
|
|
1568
1614
|
if (ctx.injectRun === undefined)
|
|
1569
1615
|
throw new Error("run fork: injectRun capability absent");
|
|
1616
|
+
const denied = await RunCap.deny(this.#db, ctx.sessionId);
|
|
1617
|
+
if (denied !== null)
|
|
1618
|
+
return denied;
|
|
1570
1619
|
const branchRunId = await Fork.fork(this.#db, srcRunId);
|
|
1571
1620
|
const branch = await this.#db.fork_get_run.get({ id: branchRunId });
|
|
1572
1621
|
await ctx.injectRun({ sessionId: ctx.sessionId, runId: branchRunId, prompt: typeof statement.body === "string" ? statement.body : "" });
|
|
@@ -1648,6 +1697,23 @@ class Engine {
|
|
|
1648
1697
|
return { status: 501 };
|
|
1649
1698
|
return await execHandler.kill(pathnameFromPath(path), ctx);
|
|
1650
1699
|
}
|
|
1700
|
+
if (schemeName === "run") {
|
|
1701
|
+
// terminate — abort any run by address; whoever holds it may end it.
|
|
1702
|
+
// `.`/"" = self. cancelRun (→ Daemon.cancelDrain) aborts the run's signal
|
|
1703
|
+
// (its loop closes 499); an idle run is a no-op-200, a missing run 404.
|
|
1704
|
+
const name = pathnameFromPath(path).replace(/^\/+/, "");
|
|
1705
|
+
let runId = ctx.runId;
|
|
1706
|
+
if (name !== "" && name !== ".") {
|
|
1707
|
+
const row = await this.#db.run_resolve_by_name.get({ session_id: ctx.sessionId, name });
|
|
1708
|
+
if (row === undefined)
|
|
1709
|
+
return { status: 404, error: `run:///${name} not found in this session` };
|
|
1710
|
+
runId = row.id;
|
|
1711
|
+
}
|
|
1712
|
+
if (this.#cancelRun === undefined)
|
|
1713
|
+
throw new Error("run kill: cancelRun capability absent");
|
|
1714
|
+
this.#cancelRun(runId);
|
|
1715
|
+
return { status: 200 };
|
|
1716
|
+
}
|
|
1651
1717
|
const handler = this.#schemes.get(schemeName);
|
|
1652
1718
|
if (handler === undefined || typeof handler.deleteEntry !== "function")
|
|
1653
1719
|
return { status: 501 };
|
|
@@ -1750,7 +1816,10 @@ class Engine {
|
|
|
1750
1816
|
if (status === null)
|
|
1751
1817
|
return { status: 400 };
|
|
1752
1818
|
if (status === 200 || status === 499) {
|
|
1753
|
-
|
|
1819
|
+
// the loop's terminal message — its deliverable — rides the termination delta.
|
|
1820
|
+
const body = statement.body;
|
|
1821
|
+
const message = body === null ? null : typeof body === "string" ? body : body.raw;
|
|
1822
|
+
await this.#db.engine_loop_set_status.run({ status, loop_id: loopId, message });
|
|
1754
1823
|
}
|
|
1755
1824
|
return { status };
|
|
1756
1825
|
}
|
|
@@ -1872,12 +1941,14 @@ class Engine {
|
|
|
1872
1941
|
if (path === null)
|
|
1873
1942
|
return { scheme: null, username: null, password: null, hostname: null, port: null, pathname: null, params: null, fragment: null };
|
|
1874
1943
|
// `local` (bare path) and `regex` (grammar 0.46 `#pattern#flags` target) carry no URL parts — store the raw text as the pathname for the log record, scheme=null.
|
|
1875
|
-
if (path.kind === "
|
|
1876
|
-
return { scheme: null, username: null, password: null, hostname: null, port: null, pathname: path.raw, params: null, fragment: null };
|
|
1944
|
+
if (path.kind === "regex")
|
|
1945
|
+
return { scheme: null, username: null, password: null, hostname: null, port: null, pathname: path.raw, params: null, fragment: null }; // regex source — no decode
|
|
1946
|
+
if (path.kind === "local")
|
|
1947
|
+
return { scheme: null, username: null, password: null, hostname: null, port: null, pathname: decodePathParens(path.raw), params: null, fragment: null }; // #239 item 4
|
|
1877
1948
|
const scheme = path.scheme === "file" ? null : path.scheme;
|
|
1878
1949
|
return {
|
|
1879
1950
|
scheme, username: path.username, password: path.password,
|
|
1880
|
-
hostname: path.hostname, port: path.port, pathname: path.pathname,
|
|
1951
|
+
hostname: path.hostname, port: path.port, pathname: decodePathParens(path.pathname), // #239 item 4
|
|
1881
1952
|
params: JSON.stringify(path.params), fragment: path.fragment,
|
|
1882
1953
|
};
|
|
1883
1954
|
}
|