@plurnk/plurnk-service 0.49.0 → 0.51.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/.env.example +2 -2
- package/SPEC.md +15 -3
- package/dist/core/Engine.d.ts +1 -0
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +60 -19
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/Engine.sql +19 -2
- package/dist/core/session-settings.d.ts +5 -0
- package/dist/core/session-settings.d.ts.map +1 -1
- package/dist/core/session-settings.js +10 -1
- package/dist/core/session-settings.js.map +1 -1
- package/dist/schemes/_entry-semantic.d.ts.map +1 -1
- package/dist/schemes/_entry-semantic.js +6 -5
- package/dist/schemes/_entry-semantic.js.map +1 -1
- package/dist/server/Daemon.d.ts +1 -0
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +23 -5
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/MethodRegistry.d.ts +2 -0
- package/dist/server/MethodRegistry.d.ts.map +1 -1
- package/dist/server/envelope.d.ts.map +1 -1
- package/dist/server/envelope.js +9 -0
- package/dist/server/envelope.js.map +1 -1
- package/dist/server/methods/loop_run.d.ts.map +1 -1
- package/dist/server/methods/loop_run.js +7 -1
- package/dist/server/methods/loop_run.js.map +1 -1
- package/dist/server/methods/providers_list.d.ts.map +1 -1
- package/dist/server/methods/providers_list.js +15 -8
- package/dist/server/methods/providers_list.js.map +1 -1
- package/dist/server/methods/session_create.d.ts.map +1 -1
- package/dist/server/methods/session_create.js +12 -4
- package/dist/server/methods/session_create.js.map +1 -1
- package/migrations/0000-00-00.01_schema.sql +6 -0
- package/package.json +7 -5
- package/requirements.md +3 -3
package/.env.example
CHANGED
|
@@ -124,8 +124,8 @@ PLURNK_MANIFEST_ITEMS=-1
|
|
|
124
124
|
# Prompt-preview cap: the loop's prompt renders in user.prompt every turn, and a fat prompt
|
|
125
125
|
# replays each turn (bloat). Show the first N CHARS of the body + a pointer to the full
|
|
126
126
|
# prompt (always READable at its plurnk://prompt/<loop>/<seq> entry — nothing is lost).
|
|
127
|
-
# -1 = no cap (render the full prompt every turn).
|
|
128
|
-
PLURNK_PROMPT_PREVIEW_CHARS=
|
|
127
|
+
# -1 = no cap (render the full prompt every turn).
|
|
128
|
+
PLURNK_PROMPT_PREVIEW_CHARS=1024
|
|
129
129
|
|
|
130
130
|
# Session-tier ceiling on CONCURRENT active runs (a run with a non-terminal loop)
|
|
131
131
|
# — the fork-bomb / destabilization brake. -1 = no cap (default); only concurrency
|
package/SPEC.md
CHANGED
|
@@ -152,7 +152,7 @@ Server posture: this package is the runtime. User-facing CLI lives in `plurnk` a
|
|
|
152
152
|
|
|
153
153
|
**Question.** §actor-boundary isolates runs and lets the runtime self-host, but it stands on an ownership model it never states: what does a *session* own versus a *run*; what is shared versus private; and what does a fork carry? Unstated, the downstream questions — which run `log.read` reads, what a fork copies, where a per-client window onto the workspace would live — grow subtle, then metastasize. Drawn once, they vanish.
|
|
154
154
|
|
|
155
|
-
**Decision — the session is the world; a run is a log on it.** A **session** is the world: one shared filesystem — the `session`-scoped entries, surfaced as `plurnk:///manifest.json` (§packet) — under one membership overlay (§membership). Exactly one filesystem and one overlay per session; neither is per-run. A **run** is a process whose
|
|
155
|
+
**Decision — the session is the world; a run is a log on it.** A **session** is the world: one shared filesystem — the `session`-scoped entries, surfaced as `plurnk:///manifest.json` (§packet) — under one membership overlay (§membership). Exactly one filesystem and one overlay per session; neither is per-run. A **run** is a process whose private memory is its **log** (§lifecycle-terms) — its loops, turns, and rows, each row carrying its own content, attribution (`origin`/`source`, §env-delta), and fold-state (`expanded`). A run owns **no membership**; even its visibility is not a possession but a bit on its own rows. It is a *history over the shared world, not a world*.
|
|
156
156
|
|
|
157
157
|
**One filesystem.** The entries are the session's: `entries.session_id`, never a run. A write by any run is a write to the one filesystem every run reads; there is no per-run entry set. {§machine-processes-one-filesystem}
|
|
158
158
|
|
|
@@ -235,7 +235,9 @@ The engine unions the declared tags of the active plugin families (schemes, exec
|
|
|
235
235
|
|
|
236
236
|
**The `@plurnk/` namespace is reserved.** A package may declare an `@plurnk/` tag only if it is itself `@plurnk/`-scoped (npm enforces scope ownership at publish); otherwise it fails hard. {§attribution-plurnk-namespace-reserved}
|
|
237
237
|
|
|
238
|
-
|
|
238
|
+
**The session's `client` id rides the same wire.** A frontend self-identifies (e.g. `plurnk.nvim/1.4.0`) at `session.create({ settings: { client } })`; the engine forwards it per turn on `generate({ client })`, which only the `plurnk` provider emits (as `Plurnk-Client`). Session-stable and self-reported — distinct from attribution's install-grounded tags — and omitted when unset. {§client-telemetry}
|
|
239
|
+
|
|
240
|
+
Deferred (#249): grounding the attribution value in real per-turn value flow rather than the active-plugin placeholder, token-weighting, and entry-level attribution. Native surfacing of the field in each framework's `discover()` supersedes the service-side manifest read and extends collection to mimetype + provider plugins.
|
|
239
241
|
|
|
240
242
|
### §provider-instantiation Provider instantiation
|
|
241
243
|
|
|
@@ -259,6 +261,16 @@ First path segment = provider plugin; rest = provider's own model id.
|
|
|
259
261
|
|
|
260
262
|
Author-facing contract: [plurnk-schemes#1](https://github.com/plurnk/plurnk-schemes/issues/1). Below: what plurnk-service exposes to schemes and orchestrates over them.
|
|
261
263
|
|
|
264
|
+
### §scheme-address Address resolution (RFC 3986)
|
|
265
|
+
|
|
266
|
+
Every op targets a URI; the entry key is `(scope, scheme, pathname)`. The URI parses per RFC 3986 (`scheme://[authority]/path`) and maps to that key by one rule — no per-scheme carve-out:
|
|
267
|
+
|
|
268
|
+
- A **registered** scheme is a plurnk namespace: its authority is a leading path segment, folded into the pathname (`Engine.#extractTarget` → `foldAuthorityIntoPath`). So `known://x`, `known:///x`, and pathname `/x` are the same entry — the authority is never a host, and the two-slash and three-slash forms are not distinct resources. {§scheme-address-namespace-fold}
|
|
269
|
+
- A **foreign** scheme (unregistered — `http`/`https`) is a real web host: its authority stays in `hostname`, never folded.
|
|
270
|
+
- `file` persists `scheme = NULL`; a relative path resolves against the workspace root to the namespace-absolute `/rel` key (RFC §5 reference resolution), and a path escaping the root is 403 (§membership).
|
|
271
|
+
|
|
272
|
+
Storage keys on the resolved `(scheme, pathname)` **verbatim** — the leading slash is the namespace origin, not a filesystem absolute, and is never re-normalized at the storage boundary.
|
|
273
|
+
|
|
262
274
|
### §scheme-manifest Manifest
|
|
263
275
|
|
|
264
276
|
Per author contract. Each scheme declares a `static manifest: SchemeManifest` with `name`, `channels`, `defaultChannel`, `category`, `scope`, `writableBy`, `volatile`, `modelVisible`, optional `flags`. {§scheme-manifest-manifest} Identity match enforced at plugin load: `manifest.name` must equal `package.json#plurnk.name`.
|
|
@@ -1228,7 +1240,7 @@ Strike accounting, cycle detection, sudden-death thresholds, and no-ops bookkeep
|
|
|
1228
1240
|
|
|
1229
1241
|
### §tools user.tools — the capability sheet
|
|
1230
1242
|
|
|
1231
|
-
|
|
1243
|
+
The tools capability lines render **titleless**, directly under the `definition` (plurnk.md) section — the examples flow on from plurnk.md with no separate header — and **above** `# Plurnk System Requirements`, so the model sees what it can *do* before the rules it must follow. Each enabled capability contributes one line via `Engine.#collectTools`; the section is omitted when nothing is enabled. {§tools-capability-sheet}
|
|
1232
1244
|
|
|
1233
1245
|
**Contributors: the wired executor tags.** Each available executor tag *with an example* contributes ONE line — its canonical usage — plus a `(docs: plurnk://docs/<tag>.md)` pointer when its package ships documentation, via the shared `teachingLine` (identical shape to the scheme directory, §schemes). A tag with no example contributes nothing; `PLURNK_DOCS_EXCLUDE` drops a named tag's line + doc. The boot `ExecutorRegistry` probes availability per tag, retiring the model's blind `<<EXEC[sh]…`.
|
|
1234
1246
|
|
package/dist/core/Engine.d.ts
CHANGED
|
@@ -74,6 +74,7 @@ export default class Engine {
|
|
|
74
74
|
promptTokens: number;
|
|
75
75
|
completionTokens: number;
|
|
76
76
|
costPico: number;
|
|
77
|
+
contextTokens: number;
|
|
77
78
|
}>;
|
|
78
79
|
runLoop({ provider, messages, requirements, sessionId, runId, loopId, maxTurns, maxStrikes, minCycles, maxCyclePeriod, origin, signal, onDispatch, }: {
|
|
79
80
|
provider: Provider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../src/core/Engine.ts"],"names":[],"mappings":"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
|
|
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
|
@@ -312,6 +312,9 @@ class Engine {
|
|
|
312
312
|
promptTokens: row?.prompt ?? 0,
|
|
313
313
|
completionTokens: row?.completion ?? 0,
|
|
314
314
|
costPico: row?.cost_pico ?? 0,
|
|
315
|
+
// #263 — the last turn's prompt tokens = current window occupancy (gauge numerator), NOT the
|
|
316
|
+
// summed promptTokens above, which overcounts a context that grows across turns.
|
|
317
|
+
contextTokens: row?.context ?? 0,
|
|
315
318
|
};
|
|
316
319
|
}
|
|
317
320
|
#pushTelemetry(sessionId, loopId, event) {
|
|
@@ -495,6 +498,13 @@ class Engine {
|
|
|
495
498
|
// writes consume low indices; model ops continue from there.
|
|
496
499
|
const seqRow = await this.#db.engine_next_turn_sequence.get({ loop_id: loopId });
|
|
497
500
|
const seq = seqRow.next;
|
|
501
|
+
// #269 — loops.sequence is the loop's ordinal WITHIN the run. Turn-0 foists that belong to the
|
|
502
|
+
// RUN (manifest preview, AGENTS, operator docs) gate on the run's FIRST loop, not every loop's
|
|
503
|
+
// first turn; per-loop foists (the prompt, @file) still fire each loop. Read once, turn-1 only.
|
|
504
|
+
const loopRow = seq === 1
|
|
505
|
+
? await this.#db.engine_get_loop_prompt.get({ loop_id: loopId })
|
|
506
|
+
: undefined;
|
|
507
|
+
const runFirstLoop = (loopRow?.sequence ?? 0) === 1;
|
|
498
508
|
const openRow = await this.#db.engine_open_turn.get({
|
|
499
509
|
loop_id: loopId, sequence: seq,
|
|
500
510
|
});
|
|
@@ -522,7 +532,8 @@ class Engine {
|
|
|
522
532
|
// #231 — env docs (PLURNK_MD_*) UNION the session's client docs; foist a READ of
|
|
523
533
|
// each materialized plurnk:///<alias>.md (loop_run materialized the same set).
|
|
524
534
|
const { mdDocs } = await SessionSettings.read(this.#db, sessionId);
|
|
525
|
-
|
|
535
|
+
// #269 — operator docs are run-once; foist them only on the run's first loop.
|
|
536
|
+
for (const doc of runFirstLoop ? await SessionSettings.resolveDocs(mdDocs) : []) {
|
|
526
537
|
const docTarget = {
|
|
527
538
|
kind: "url", raw: `plurnk:///${doc.entryName}`, scheme: "plurnk",
|
|
528
539
|
username: null, password: null, hostname: null, port: null,
|
|
@@ -538,7 +549,7 @@ class Engine {
|
|
|
538
549
|
});
|
|
539
550
|
nextActionIndex++;
|
|
540
551
|
}
|
|
541
|
-
const promptRow =
|
|
552
|
+
const promptRow = loopRow; // #269 — already read above (per-loop; fires every loop's turn 1)
|
|
542
553
|
if (promptRow !== undefined && typeof promptRow.prompt === "string" && promptRow.prompt.length > 0) {
|
|
543
554
|
const promptPath = {
|
|
544
555
|
kind: "url", raw: `plurnk://prompt/${loopId}/${seq}`,
|
|
@@ -604,7 +615,7 @@ class Engine {
|
|
|
604
615
|
// #231 — a session's client-chosen manifestItems REPLACES the env default outright.
|
|
605
616
|
const { manifestItems: sessionMI, autoReadAgents } = await SessionSettings.read(this.#db, sessionId);
|
|
606
617
|
const manifestItems = sessionMI !== null ? normalizeManifestItems(sessionMI) : readManifestItems();
|
|
607
|
-
if (manifestItems !== null) {
|
|
618
|
+
if (manifestItems !== null && runFirstLoop) { // #269 — manifest preview is run-once
|
|
608
619
|
const manifestRead = {
|
|
609
620
|
op: "READ", suffix: "", signal: null, lineMarker: null,
|
|
610
621
|
target: {
|
|
@@ -621,20 +632,23 @@ class Engine {
|
|
|
621
632
|
});
|
|
622
633
|
nextActionIndex++;
|
|
623
634
|
}
|
|
624
|
-
// #
|
|
625
|
-
//
|
|
626
|
-
//
|
|
627
|
-
//
|
|
628
|
-
|
|
629
|
-
if (
|
|
630
|
-
const
|
|
631
|
-
|
|
635
|
+
// #268 — auto-READ the configured AGENTS file(s) into THIS first model turn. Env-driven
|
|
636
|
+
// (PLURNK_AGENTS_AUTO / PLURNK_AGENTS_FILES), overridable per-session by autoReadAgents; the
|
|
637
|
+
// matching files are auto-PICKed into membership at session setup (envelope). The model sees
|
|
638
|
+
// only the READ — a normal file:/// member READ, read-write so it edits the scratchpad back.
|
|
639
|
+
const { auto: agentsAuto, files: agentsFiles } = SessionSettings.resolveAgentsAutoload(autoReadAgents);
|
|
640
|
+
if (agentsAuto && runFirstLoop) { // #269 — run-once, the run's first loop
|
|
641
|
+
for (const file of agentsFiles) {
|
|
642
|
+
const pathname = file.startsWith("/") ? file : `/${file}`;
|
|
643
|
+
const member = await this.#db.crud_get_member_sig.get({ session_id: sessionId, scheme: null, pathname });
|
|
644
|
+
if (member === undefined)
|
|
645
|
+
continue; // absent / non-git session → not a member → skip
|
|
632
646
|
const agentsRead = {
|
|
633
647
|
op: "READ", suffix: "", signal: null, lineMarker: null,
|
|
634
648
|
target: {
|
|
635
|
-
kind: "url", raw:
|
|
649
|
+
kind: "url", raw: `file://${pathname}`, scheme: "file",
|
|
636
650
|
username: null, password: null, hostname: null, port: null,
|
|
637
|
-
pathname
|
|
651
|
+
pathname, params: {}, fragment: null,
|
|
638
652
|
},
|
|
639
653
|
body: null, position: { line: 1, column: 1 },
|
|
640
654
|
};
|
|
@@ -645,6 +659,27 @@ class Engine {
|
|
|
645
659
|
nextActionIndex++;
|
|
646
660
|
}
|
|
647
661
|
}
|
|
662
|
+
// #260 — foist a turn-0 READ of each client-passed @file path so its content sits in front
|
|
663
|
+
// of the model. Daemon owns the workspace → a normal file:/// member READ; a missing or
|
|
664
|
+
// non-member path surfaces its READ outcome (4xx) in the log, visible to the model.
|
|
665
|
+
const openPathsRow = await this.#db.engine_get_loop_open_paths.get({ loop_id: loopId });
|
|
666
|
+
for (const raw of JSON.parse(openPathsRow?.open_paths ?? "[]")) {
|
|
667
|
+
const pathname = raw.startsWith("/") ? raw : `/${raw}`;
|
|
668
|
+
const fileRead = {
|
|
669
|
+
op: "READ", suffix: "", signal: null, lineMarker: null,
|
|
670
|
+
target: {
|
|
671
|
+
kind: "url", raw: `file://${pathname}`, scheme: "file",
|
|
672
|
+
username: null, password: null, hostname: null, port: null,
|
|
673
|
+
pathname, params: {}, fragment: null,
|
|
674
|
+
},
|
|
675
|
+
body: null, position: { line: 1, column: 1 },
|
|
676
|
+
};
|
|
677
|
+
await this.dispatch({
|
|
678
|
+
statement: fileRead, sessionId, runId, loopId, turnId,
|
|
679
|
+
sequence: nextActionIndex, origin: "plurnk", onDispatch,
|
|
680
|
+
});
|
|
681
|
+
nextActionIndex++;
|
|
682
|
+
}
|
|
648
683
|
}
|
|
649
684
|
// §env-delta — pre-seed environment deltas (changes since this run last
|
|
650
685
|
// reconciled) as system EDIT rows, before the packet composes; advance
|
|
@@ -692,8 +727,13 @@ class Engine {
|
|
|
692
727
|
// #249 — plugin attribution tags onto the per-turn generate() wire. Value is the
|
|
693
728
|
// active-plugin set (placeholder); real per-turn grounding is deferred.
|
|
694
729
|
const attributions = [...new Set([...this.#schemes.attributions(), ...(this.#executors?.attributions() ?? [])])].toSorted();
|
|
730
|
+
// #249 — tag the loop (the activity) with its active plugins' attribution tags, write-once.
|
|
731
|
+
if (attributions.length > 0)
|
|
732
|
+
await this.#db.engine_tag_loop_attributions.run({ loop_id: loopId, attributions: JSON.stringify(attributions) });
|
|
733
|
+
// #249 — session-stable frontend id, forwarded as Plurnk-Client by the plurnk provider only.
|
|
734
|
+
const { client } = await SessionSettings.read(this.#db, sessionId);
|
|
695
735
|
try {
|
|
696
|
-
response = await provider.generate({ messages: modelMessages, runId: String(runId), signal, grammar: await this.#grammarConstraint(), maxTokens, attributions: attributions.length > 0 ? attributions : undefined }); // §provider-surface-generate §provider-guarantees-single-call §provider-guarantees-signal-wired §attribution-plurnk-namespace-reserved
|
|
736
|
+
response = await provider.generate({ messages: modelMessages, runId: String(runId), signal, grammar: await this.#grammarConstraint(), maxTokens, attributions: attributions.length > 0 ? attributions : undefined, client: client ?? undefined }); // §provider-surface-generate §provider-guarantees-single-call §provider-guarantees-signal-wired §attribution-plurnk-namespace-reserved §client-telemetry
|
|
697
737
|
}
|
|
698
738
|
catch (err) {
|
|
699
739
|
// Every provider error surfaces as telemetry (the client/model sees the cause). #256:
|
|
@@ -938,7 +978,7 @@ class Engine {
|
|
|
938
978
|
const inject = await readPacketInject(); // #240 — operator section, per-turn, fail-hard on a broken path
|
|
939
979
|
const defaults = [
|
|
940
980
|
{ name: "definition", slot: "system", header: null, content: system_definition, tokens: 0 },
|
|
941
|
-
{ name: "tools", slot: "system", header:
|
|
981
|
+
{ name: "tools", slot: "system", header: null, content: tools.join("\n"), tokens: 0 }, // titleless — the examples flow on from plurnk.md (definition) directly above
|
|
942
982
|
{ name: "schemes", slot: "system", header: "Plurnk System Schemes", content: this.#schemes.teach(), tokens: 0 },
|
|
943
983
|
...(inject !== null ? [{ name: "inject", slot: "system", header: "Plurnk Operator Notes", content: inject, tokens: 0 }] : []),
|
|
944
984
|
{ name: "log", slot: "system", header: "Plurnk System Log", content: PacketWire.renderLog(log), tokens: 0 },
|
|
@@ -2027,10 +2067,11 @@ class Engine {
|
|
|
2027
2067
|
if (path.kind === "local")
|
|
2028
2068
|
return { scheme: null, username: null, password: null, hostname: null, port: null, pathname: decodePathParens(path.raw), params: null, fragment: null }; // #239 item 4
|
|
2029
2069
|
const scheme = path.scheme === "file" ? null : path.scheme;
|
|
2030
|
-
// plurnk uses its authority as a namespace — fold
|
|
2031
|
-
//
|
|
2032
|
-
//
|
|
2033
|
-
|
|
2070
|
+
// Every registered (plurnk-namespace) scheme uses its authority as a namespace segment — fold
|
|
2071
|
+
// it into the canonical pathname so known://x ≡ known:///x ≡ /x and the log keys identically to
|
|
2072
|
+
// the entry (/prompt/<loop>, /docs/x.md). A foreign web host (http://, unregistered) is NOT a
|
|
2073
|
+
// namespace: keep it in hostname.
|
|
2074
|
+
const foldNs = scheme !== null && this.#schemes.has(scheme);
|
|
2034
2075
|
return {
|
|
2035
2076
|
scheme, username: path.username, password: path.password,
|
|
2036
2077
|
hostname: foldNs ? null : path.hostname, port: path.port,
|