paseo-room 0.7.0 → 0.9.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/README.md +82 -20
- package/dist/index.js +62 -19
- package/dist/index.js.map +1 -1
- package/dist/prompts/contract/lead.md +22 -2
- package/dist/prompts/runtime/handoff-request.md +42 -0
- package/dist/prompts/runtime/successor-kickoff.md +13 -0
- package/dist/runtime-plugin/client/context-settings.tsx +93 -0
- package/dist/runtime-plugin/client/data.ts +8 -1
- package/dist/runtime-plugin/client/effort-settings.tsx +89 -0
- package/dist/runtime-plugin/client/forms.tsx +167 -77
- package/dist/runtime-plugin/client/kit.tsx +1 -10
- package/dist/runtime-plugin/client/model.ts +121 -1
- package/dist/runtime-plugin/client/pills.ts +12 -2
- package/dist/runtime-plugin/client/record.tsx +10 -1
- package/dist/runtime-plugin/client/room.tsx +85 -12
- package/dist/runtime-plugin/client/succession.tsx +279 -0
- package/dist/runtime-plugin/client/time.ts +21 -0
- package/dist/runtime-plugin/client/views.tsx +20 -5
- package/dist/runtime-plugin/index.server.ts +41 -18
- package/dist/runtime-plugin/server/attention/delivery.ts +29 -4
- package/dist/runtime-plugin/server/attention/engine.ts +141 -31
- package/dist/runtime-plugin/server/attention/log.ts +7 -1
- package/dist/runtime-plugin/server/attention/mask.ts +6 -0
- package/dist/runtime-plugin/server/attention/observer.ts +83 -27
- package/dist/runtime-plugin/server/attention/seat-starter.ts +16 -5
- package/dist/runtime-plugin/server/attention/signals.ts +53 -17
- package/dist/runtime-plugin/server/attention/succession-store.ts +109 -0
- package/dist/runtime-plugin/server/attention/succession.ts +592 -0
- package/dist/runtime-plugin/server/attention/triage.ts +41 -2
- package/dist/runtime-plugin/server/brief.ts +38 -0
- package/dist/runtime-plugin/server/context.ts +53 -7
- package/dist/runtime-plugin/server/contracts/actions.ts +5 -1
- package/dist/runtime-plugin/server/controller.ts +106 -17
- package/dist/runtime-plugin/server/domain/acceptance.ts +12 -2
- package/dist/runtime-plugin/server/domain/state.ts +20 -2
- package/dist/runtime-plugin/server/domain/views.ts +62 -4
- package/dist/runtime-plugin/server/events/schema.ts +5 -1
- package/dist/runtime-plugin/server/generated/succession.ts +11 -0
- package/dist/runtime-plugin/server/handlers/actions.ts +40 -17
- package/dist/runtime-plugin/server/handlers/peer.ts +5 -3
- package/dist/runtime-plugin/server/handlers/turns.ts +66 -5
- package/dist/runtime-plugin/server/hooks.ts +81 -0
- package/dist/runtime-plugin/server/paseo-port.ts +102 -4
- package/dist/runtime-plugin/server/recovery.ts +11 -2
- package/dist/runtime-plugin/server/rpc.ts +77 -15
- package/dist/runtime-plugin/server/timeout.ts +24 -0
- package/dist/runtime-plugin/server/tools.ts +33 -10
- package/dist/runtime-plugin/shared/effort.ts +27 -0
- package/dist/runtime-plugin/shared/limits.ts +2 -0
- package/dist/runtime-plugin/shared/rpc-contracts.ts +59 -2
- package/dist/runtime-plugin/shared/seat-context.ts +77 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -278,9 +278,9 @@ recreate an existing Claude session after setup or an update.
|
|
|
278
278
|
have none. Only the contract is dropped, never your own memory, and an earlier generation of it
|
|
279
279
|
is removed rather than left behind. The choice is recorded in `room.json`, so `verify` compares
|
|
280
280
|
against it and rejects the flag itself; `setup` without the flag restores the fallback. Keep the
|
|
281
|
-
fallback unless you have a reason not to: the plugin hook is verified, and
|
|
282
|
-
|
|
283
|
-
|
|
281
|
+
fallback unless you have a reason not to: the plugin hook is verified, and a *resumed* session
|
|
282
|
+
keeps the room prompt it was created with (on Paseo 0.9.2 a daemon restart does not refresh it),
|
|
283
|
+
but what the model actually reads is not proven, and `CLAUDE.md` is what covers that case.
|
|
284
284
|
|
|
285
285
|
Pi providers use a strict command tail:
|
|
286
286
|
|
|
@@ -406,8 +406,10 @@ npx paseo-room@<new-version> verify
|
|
|
406
406
|
First inspect the dry run, then apply it. The apply regenerates managed prompt carriers,
|
|
407
407
|
the Codex model catalogs and `AUTHENTICATION.md` from the newly resolved binaries, but
|
|
408
408
|
preserves role credential paths and the operator agent homes. Stop and restart every affected
|
|
409
|
-
seat after the apply; sending another turn to an already-running seat is not a restart.
|
|
410
|
-
|
|
409
|
+
seat after the apply; sending another turn to an already-running seat is not a restart. A
|
|
410
|
+
Claude seat keeps the contract Paseo stored when it was created, and a daemon restart resumes it
|
|
411
|
+
with that same prompt, so for Claude open a new seat instead. `setup` and `verify` prove the
|
|
412
|
+
files and live Paseo configuration, not that an existing model
|
|
411
413
|
context reloaded them. Only a newly launched seat context is expected to ingest the
|
|
412
414
|
regenerated instructions.
|
|
413
415
|
|
|
@@ -483,7 +485,9 @@ vocabulary for Lead and Peer, and exactly one body per role. TypeScript selects
|
|
|
483
485
|
that settles it rather than pre-solving the work; any plan or file list in it is provisional.
|
|
484
486
|
One moving write scope has exactly one owner, and at most one Peer is writable at a time. It
|
|
485
487
|
explicitly requests native Paseo completion/error/permission notification for Peer creation and
|
|
486
|
-
every background follow-up, then waits for events rather than polling.
|
|
488
|
+
every background follow-up, then waits for events rather than polling. A question only Human can
|
|
489
|
+
answer goes on its own `NEEDS-HUMAN:` line, and an effect beyond the work's intended scope on an
|
|
490
|
+
`INCIDENT:` line, so neither is lost in a long message. Room tools: on.
|
|
487
491
|
- **Peer** owns one bounded assignment — writable inside an assigned scope, or read-only
|
|
488
492
|
against a named candidate, question or area — under exactly one disposition Lead names in the
|
|
489
493
|
brief (Engineer, Architect, Reviewer or Scout), forms its own technical position from the code
|
|
@@ -621,10 +625,38 @@ npx paseo-room verify
|
|
|
621
625
|
working.
|
|
622
626
|
- **Lead** gains room tools such as `assignment_create`, `assignment_dispatch`, `assignment_answer`,
|
|
623
627
|
`assignment_accept`, `gate_run`, and for isolated writers `workspace_close` and `lease_reclaim`.
|
|
628
|
+
`assignment_create` refuses a base that is not a commit of the repository (`base_unknown`).
|
|
629
|
+
`gate_run` runs in the background, and a notice tells Lead when the gate ends, green, red or
|
|
630
|
+
without a trustworthy result.
|
|
631
|
+
`assignment_status` leaves out the brief Lead wrote (its outcome stays), keeps the last 10 history
|
|
632
|
+
entries, and gives a decided assignment with nothing left to close one line, unless Lead passes
|
|
633
|
+
`full: true`.
|
|
624
634
|
**Supervisor** gains `room_status`, `runtime_findings`, `message_lead` (with a `project` for a
|
|
625
|
-
Supervisor of several projects) and `attention_feedback`, and cannot change an assignment.
|
|
626
|
-
|
|
627
|
-
|
|
635
|
+
Supervisor of several projects) and `attention_feedback`, and cannot change an assignment. Its
|
|
636
|
+
status and findings cover only its portfolio and the project it stands in; `room_status` lists
|
|
637
|
+
the assignments still open or still to close, and only counts settled ones.
|
|
638
|
+
- **Peer thinking.** A runtime-dispatched Peer launches on its room profile's model and thinking
|
|
639
|
+
option. In **Settings › Room seats › Thinking Lead may choose** you can allow other thinking
|
|
640
|
+
options per Peer provider, from the ones Paseo lists for its model. Lead may then pass `thinking`
|
|
641
|
+
(with a `thinkingReason`) to `assignment_dispatch`, as the Lead contract directs. The runtime
|
|
642
|
+
refuses anything outside what you allowed or what the model offers, and always refuses `ultra` and
|
|
643
|
+
`ultracode`, which start agents on their own. It records the choice, shows it with the reason to
|
|
644
|
+
Supervisor and in the panel, and keeps it for a reclaimed Peer while you still allow it. The model
|
|
645
|
+
itself is never Lead's to change.
|
|
646
|
+
- **Seat context.** The panel and each seat's role pill show how full the seat's context is, as
|
|
647
|
+
Paseo reports it for the latest model call, and when the runtime last saw it compact. **Settings ›
|
|
648
|
+
Room seats › Seat context** sets marks per role, as a share of each seat's own model window:
|
|
649
|
+
- *Lead · report at* (30%): past it, the Lead's Supervisor gets one fact line and the panel shows
|
|
650
|
+
it with **Replace Lead…**, so you can hand over to a fresh Lead rather than let this one compact.
|
|
651
|
+
- *compact at* (Lead 50%, Supervisor and Peer off): a room Claude seat gets
|
|
652
|
+
`CLAUDE_CODE_AUTO_COMPACT_WINDOW` when its session opens, at creation or on a resume after a
|
|
653
|
+
daemon restart, so Claude compacts at that share instead of near the end of a 1M window. An open
|
|
654
|
+
session keeps what it opened with. Codex and Pi seats show their context and keep their own
|
|
655
|
+
compaction.
|
|
656
|
+
- **A runtime-dispatched Peer** is titled `<Disposition> · <outcome gist> · <assignment id>` (for
|
|
657
|
+
example `Reviewer · Review the Docker Compose dev env… · asg_…`), and the runtime's notices to Lead
|
|
658
|
+
name the assignment the same way. It gets exactly two tools, `ask` and `handoff`, for its own
|
|
659
|
+
assignment, and still no Paseo room tools. A report exists only once one of those calls is accepted; its
|
|
628
660
|
final message is never read as a report. Claude asks for permission before a Peer's first call
|
|
629
661
|
to `mcp__paseo_room__ask` or `mcp__paseo_room__handoff`: approve it in Paseo, since the runtime
|
|
630
662
|
never answers a permission for a seat. Codex and Pi Peers do not ask.
|
|
@@ -637,9 +669,11 @@ npx paseo-room verify
|
|
|
637
669
|
- **The Room runtime panel** (sidebar item, and a workspace panel that opens on its own project)
|
|
638
670
|
puts what needs you first. Below that come your projects, ordered by status, then your
|
|
639
671
|
Supervisors.
|
|
640
|
-
- A project shows its Supervisor, its Lead and Peer seats (each opens its agent in Paseo
|
|
641
|
-
runtime record: assignments, isolated
|
|
642
|
-
|
|
672
|
+
- A project shows its Supervisor, its Lead and Peer seats (each opens its agent in Paseo, and
|
|
673
|
+
shows the model and thinking option it runs with) and its runtime record: assignments, isolated
|
|
674
|
+
writers, findings and recovery.
|
|
675
|
+
- Starting a Supervisor, adding a repository, starting a Lead for a project that has none, and
|
|
676
|
+
assigning a Supervisor are guided forms.
|
|
643
677
|
- The design notes are in [docs/design/runtime-panel-ux.md](docs/design/runtime-panel-ux.md).
|
|
644
678
|
- **Settings › Room seats** shows which account each seat is signed in to (email, plan and
|
|
645
679
|
organization for Claude; login method for Codex; for Pi, only whether a credential file exists).
|
|
@@ -659,19 +693,47 @@ learn only when you ask it to check.
|
|
|
659
693
|
- They report a permission waiting on any seat for 5 minutes, and a Peer result its idle Lead has
|
|
660
694
|
not read for 10 minutes.
|
|
661
695
|
- They report the same failure twice in a row, and possible concurrent writers in one working
|
|
662
|
-
tree.
|
|
696
|
+
tree, naming each seat's files and when its turn ended. A write outside that tree does not
|
|
697
|
+
count.
|
|
663
698
|
- They report a Lead archived while its seats still work, and a Lead's finished turn that the
|
|
664
699
|
Supervisor did not prompt itself.
|
|
700
|
+
- They report, in a digest, a Lead whose context passes the rotation mark, once per crossing.
|
|
701
|
+
- The Lead contract has Lead put a question for you on a line beginning `NEEDS-HUMAN:` and an
|
|
702
|
+
incident on one beginning `INCIDENT:`. The first wakes the Supervisor and the second pages it,
|
|
703
|
+
even for a turn it prompted, once per line, and the letter quotes those lines rather than the
|
|
704
|
+
message's end.
|
|
665
705
|
- Letters are held until the Supervisor is idle, batched into digests, and limited to a few wakes
|
|
666
706
|
an hour. They are never sent while the Supervisor holds a permission, because a send would
|
|
667
707
|
deny it.
|
|
668
|
-
- Each item has an id for `attention_feedback
|
|
669
|
-
Supervisor contract has it ask or nudge the Lead, or
|
|
670
|
-
Peer.
|
|
671
|
-
- **Starting seats.** From the **Room** view, **
|
|
672
|
-
outside every repository. **
|
|
673
|
-
Supervisor you pick, and sends a fixed kickoff with your first directive verbatim
|
|
674
|
-
|
|
708
|
+
- Each item has an id for `attention_feedback`, and a letter's own id rates every item in it. A
|
|
709
|
+
letter is evidence, not an instruction: the Supervisor contract has it ask or nudge the Lead, or
|
|
710
|
+
relay a question to you, and never direct a Peer.
|
|
711
|
+
- **Starting seats.** From the **Room** view, **New Supervisor** opens one in an existing directory
|
|
712
|
+
outside every repository. **Add repository** checks a repository, opens its Lead under the
|
|
713
|
+
Supervisor you pick, and sends a fixed kickoff with your first directive verbatim; it also offers
|
|
714
|
+
the projects the room observes without a Lead. A project with no live Lead offers **Start Lead**
|
|
715
|
+
on its own screen, with its Supervisor preselected. **Assign Supervisor** moves an existing
|
|
716
|
+
project under a Supervisor.
|
|
717
|
+
- **Replacing a Lead.** **Replace Lead…** above a project's seats, or on a *context past rotation
|
|
718
|
+
mark* item, hands the project to a fresh Lead:
|
|
719
|
+
- It checks for a quiet point first: the Lead idle, every runtime assignment it leads settled, no
|
|
720
|
+
runtime notice waiting for it, no seat it opened still working. It also shows what Paseo's
|
|
721
|
+
archive does to each seat the Lead opened: those in its workspace are archived with it, and one
|
|
722
|
+
in another workspace or open in a tab is detached and kept.
|
|
723
|
+
- It asks the Lead for a handoff in fixed sections, and you review and edit it. Nothing is
|
|
724
|
+
archived until you confirm, and you may cancel until then.
|
|
725
|
+
- On **Replace Lead**, the runtime archives the Lead and starts `<repository> — Lead` with the same
|
|
726
|
+
agent under the same Supervisor. The new Lead's first message is the kickoff and your reviewed
|
|
727
|
+
handoff, verbatim, and it verifies the handoff and reports to you before it acts outside the
|
|
728
|
+
repository. The Supervisor gets one line naming the new Lead.
|
|
729
|
+
- The handoff stays on this machine, under `~/.paseo-room/runtime/v1/attention/successions/`,
|
|
730
|
+
owner-only and never sent to the sensor or in a letter. Finished replacements are pruned after 30
|
|
731
|
+
days.
|
|
732
|
+
- If the replacement stops after the archive, the project offers **Finish replacing Lead**, which
|
|
733
|
+
creates no second Lead, or cancel, which leaves the project as it is. A replacement that fails
|
|
734
|
+
before the archive stays on the project's screen for a day, with the reason.
|
|
735
|
+
- Paseo archives the seats in the Lead's workspace with it; the runtime archives them too when the
|
|
736
|
+
Lead is not running, when Paseo would take none.
|
|
675
737
|
- **Settings › Room attention.** Here you turn letters on or off, change their thresholds, and
|
|
676
738
|
configure the optional **attention sensor**.
|
|
677
739
|
- The sensor speaks the System One HTTP shape, with [TypeSafe Jev](https://docs.typesafe.ai/)
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ var init_package = __esm({
|
|
|
15
15
|
"package.json"() {
|
|
16
16
|
package_default = {
|
|
17
17
|
name: "paseo-room",
|
|
18
|
-
version: "0.
|
|
18
|
+
version: "0.9.0",
|
|
19
19
|
description: "One CLI that configures Codex, Claude Code, and Pi role homes in $HOME and registers them with your local Paseo daemon.",
|
|
20
20
|
keywords: [
|
|
21
21
|
"paseo",
|
|
@@ -691,10 +691,10 @@ async function loginRole(agentValue, roleValue, options, output) {
|
|
|
691
691
|
const childEnv = { ...env, ...invocation.env };
|
|
692
692
|
const launch = options.spawn ?? spawnLogin;
|
|
693
693
|
return new Promise((resolve5) => {
|
|
694
|
-
let
|
|
694
|
+
let settled2 = false;
|
|
695
695
|
const finish = (code2) => {
|
|
696
|
-
if (
|
|
697
|
-
|
|
696
|
+
if (settled2) return;
|
|
697
|
+
settled2 = true;
|
|
698
698
|
resolve5(code2);
|
|
699
699
|
};
|
|
700
700
|
let child;
|
|
@@ -870,6 +870,11 @@ var init_prompts = __esm({
|
|
|
870
870
|
pi: {
|
|
871
871
|
communicationStyle: { path: "pi/communication-style.md", kind: "capsule" },
|
|
872
872
|
runtime: { path: "pi/runtime.md", kind: "capsule" }
|
|
873
|
+
},
|
|
874
|
+
/** Messages the runtime plugin sends a Lead on Human's instruction; setup renders them into the plugin. */
|
|
875
|
+
runtime: {
|
|
876
|
+
handoffRequest: { path: "runtime/handoff-request.md", kind: "section" },
|
|
877
|
+
successorKickoff: { path: "runtime/successor-kickoff.md", kind: "section" }
|
|
873
878
|
}
|
|
874
879
|
};
|
|
875
880
|
PromptAssetError = class extends Error {
|
|
@@ -1688,20 +1693,20 @@ function runProbeProcess(executable, adapterEntry, env, options, cwd) {
|
|
|
1688
1693
|
const child = spawn2(executable, args, { cwd, detached: true, env, stdio: ["pipe", "pipe", "pipe"] });
|
|
1689
1694
|
const stdout = [];
|
|
1690
1695
|
let bytes = 0;
|
|
1691
|
-
let
|
|
1696
|
+
let settled2 = false;
|
|
1692
1697
|
const finish = (result) => {
|
|
1693
|
-
if (
|
|
1694
|
-
|
|
1698
|
+
if (settled2) return;
|
|
1699
|
+
settled2 = true;
|
|
1695
1700
|
clearTimeout(timer);
|
|
1696
1701
|
resolveResult(result);
|
|
1697
1702
|
};
|
|
1698
1703
|
const abort = (reason3) => {
|
|
1699
|
-
if (
|
|
1704
|
+
if (settled2) return;
|
|
1700
1705
|
terminateProbe(child);
|
|
1701
1706
|
finish({ ok: false, stdout: Buffer.concat(stdout).toString("utf8"), reason: reason3 });
|
|
1702
1707
|
};
|
|
1703
1708
|
const capture = (chunk, keep) => {
|
|
1704
|
-
if (
|
|
1709
|
+
if (settled2) return;
|
|
1705
1710
|
bytes += chunk.length;
|
|
1706
1711
|
if (bytes > outputLimit) {
|
|
1707
1712
|
abort("overflow");
|
|
@@ -2417,6 +2422,21 @@ function renderRuntimeManifestFile(agents, roles) {
|
|
|
2417
2422
|
return `${JSON.stringify(renderRuntimeManifest(agents, roles), null, 2)}
|
|
2418
2423
|
`;
|
|
2419
2424
|
}
|
|
2425
|
+
function renderSuccessionText() {
|
|
2426
|
+
return [
|
|
2427
|
+
"/** Generated by paseo-room setup. The Markdown prompt assets remain authoritative. */",
|
|
2428
|
+
"export interface SuccessionText {",
|
|
2429
|
+
" readonly request: string;",
|
|
2430
|
+
" readonly kickoff: string;",
|
|
2431
|
+
"}",
|
|
2432
|
+
"",
|
|
2433
|
+
"export const SUCCESSION_TEXT: SuccessionText | undefined = {",
|
|
2434
|
+
` request: ${typescriptTemplateLiteral(loadPromptAsset("runtime", "handoffRequest"))},`,
|
|
2435
|
+
` kickoff: ${typescriptTemplateLiteral(loadPromptAsset("runtime", "successorKickoff"))},`,
|
|
2436
|
+
"};",
|
|
2437
|
+
""
|
|
2438
|
+
].join("\n");
|
|
2439
|
+
}
|
|
2420
2440
|
function renderRuntimeLocation(layout) {
|
|
2421
2441
|
const location = { pluginDirectory: runtimePluginDir(layout), runtimeRoot: join12(layout.roomHome, "runtime", "v1") };
|
|
2422
2442
|
return [
|
|
@@ -2448,22 +2468,25 @@ function runtimePluginEntries(layout, agents, roles) {
|
|
|
2448
2468
|
...files.map((path) => ({
|
|
2449
2469
|
kind: "file",
|
|
2450
2470
|
path: join12(root, path),
|
|
2451
|
-
content: path === LOCATION_MODULE ? renderRuntimeLocation(layout) : readFileSync4(join12(BUNDLE, path), "utf8")
|
|
2471
|
+
content: path === LOCATION_MODULE ? renderRuntimeLocation(layout) : path === SUCCESSION_MODULE ? renderSuccessionText() : readFileSync4(join12(BUNDLE, path), "utf8")
|
|
2452
2472
|
})),
|
|
2453
2473
|
{ kind: "file", path: join12(root, MANIFEST_FILE), content: renderRuntimeManifestFile(agents, roles) }
|
|
2454
2474
|
];
|
|
2455
2475
|
}
|
|
2456
|
-
var BUNDLE, LOCATION_MODULE;
|
|
2476
|
+
var BUNDLE, LOCATION_MODULE, SUCCESSION_MODULE;
|
|
2457
2477
|
var init_runtime = __esm({
|
|
2458
2478
|
"src/runtime.ts"() {
|
|
2459
2479
|
"use strict";
|
|
2480
|
+
init_plugin();
|
|
2460
2481
|
init_roles();
|
|
2461
2482
|
init_instructions();
|
|
2483
|
+
init_prompts();
|
|
2462
2484
|
init_manifest();
|
|
2463
2485
|
init_identity();
|
|
2464
2486
|
init_policy();
|
|
2465
2487
|
BUNDLE = fileURLToPath(new URL("./runtime-plugin/", import.meta.url));
|
|
2466
2488
|
LOCATION_MODULE = "server/generated/location.ts";
|
|
2489
|
+
SUCCESSION_MODULE = "server/generated/succession.ts";
|
|
2467
2490
|
}
|
|
2468
2491
|
});
|
|
2469
2492
|
|
|
@@ -2481,7 +2504,7 @@ function boundedString(max = MAX_STRING_BYTES) {
|
|
|
2481
2504
|
function boundedArray(item) {
|
|
2482
2505
|
return z4.array(item).max(MAX_ARRAY_ITEMS);
|
|
2483
2506
|
}
|
|
2484
|
-
var MAX_AGGREGATE_BYTES, MAX_ARRAY_ITEMS, MAX_STRING_BYTES, MAX_COMMAND_BYTES, MAX_GATE_TIMEOUT_SECONDS, encoder, MAX_WORKTREE_LEASES;
|
|
2507
|
+
var MAX_AGGREGATE_BYTES, MAX_ARRAY_ITEMS, MAX_STRING_BYTES, MAX_COMMAND_BYTES, MAX_GATE_TIMEOUT_SECONDS, MAX_HANDOFF_BYTES, encoder, MAX_WORKTREE_LEASES;
|
|
2485
2508
|
var init_limits = __esm({
|
|
2486
2509
|
"src/runtime-plugin/shared/limits.ts"() {
|
|
2487
2510
|
"use strict";
|
|
@@ -2490,6 +2513,7 @@ var init_limits = __esm({
|
|
|
2490
2513
|
MAX_STRING_BYTES = 8 * 1024;
|
|
2491
2514
|
MAX_COMMAND_BYTES = 16 * 1024;
|
|
2492
2515
|
MAX_GATE_TIMEOUT_SECONDS = 3600;
|
|
2516
|
+
MAX_HANDOFF_BYTES = 64 * 1024;
|
|
2493
2517
|
encoder = new TextEncoder();
|
|
2494
2518
|
MAX_WORKTREE_LEASES = 3;
|
|
2495
2519
|
}
|
|
@@ -2841,6 +2865,7 @@ function reclaimed(view, event) {
|
|
|
2841
2865
|
delete copy.peerAgentId;
|
|
2842
2866
|
delete copy.observedProviderId;
|
|
2843
2867
|
delete copy.observedModel;
|
|
2868
|
+
delete copy.observedThinking;
|
|
2844
2869
|
return { ...copy, state: "dispatching", reportingState: "consumed", eventIds: [...view.eventIds, event.id] };
|
|
2845
2870
|
}
|
|
2846
2871
|
function applyReport(state, view, event) {
|
|
@@ -2923,7 +2948,13 @@ function applyEvent(state, event) {
|
|
|
2923
2948
|
const id2 = view.id;
|
|
2924
2949
|
switch (event.type) {
|
|
2925
2950
|
case "assignment.dispatch-requested":
|
|
2926
|
-
update(state, id2, {
|
|
2951
|
+
update(state, id2, {
|
|
2952
|
+
state: "dispatching",
|
|
2953
|
+
peerProviderId: event.data.peerProviderId,
|
|
2954
|
+
workspaceId: event.data.workspaceId,
|
|
2955
|
+
...event.data.thinking === void 0 ? {} : { chosenThinking: event.data.thinking },
|
|
2956
|
+
...event.data.thinkingReason === void 0 ? {} : { thinkingReason: event.data.thinkingReason }
|
|
2957
|
+
}, event);
|
|
2927
2958
|
return;
|
|
2928
2959
|
case "ownership.reserved":
|
|
2929
2960
|
state.ownership.set(id2, { assignmentId: id2, workspaceId: event.data.workspaceId, baseCommit: event.data.baseCommit, state: "reserved" });
|
|
@@ -2950,7 +2981,12 @@ function applyEvent(state, event) {
|
|
|
2950
2981
|
update(state, id2, { state: "uncertain" }, event);
|
|
2951
2982
|
return;
|
|
2952
2983
|
case "binding.published":
|
|
2953
|
-
update(state, id2, {
|
|
2984
|
+
update(state, id2, {
|
|
2985
|
+
observedProviderId: event.data.providerId,
|
|
2986
|
+
observedModel: event.data.model,
|
|
2987
|
+
workspaceId: event.data.workspaceId,
|
|
2988
|
+
...event.data.thinking === void 0 ? {} : { observedThinking: event.data.thinking }
|
|
2989
|
+
}, event);
|
|
2954
2990
|
return;
|
|
2955
2991
|
case "ownership.held":
|
|
2956
2992
|
setOwner(state, id2, { state: "held", agentId: event.data.agentId });
|
|
@@ -3281,7 +3317,11 @@ var init_actions = __esm({
|
|
|
3281
3317
|
...assignment,
|
|
3282
3318
|
peerProvider: z6.string().min(1).max(128),
|
|
3283
3319
|
isolation: z6.enum(["lead-workspace", "worktree"]).optional(),
|
|
3284
|
-
serialOnly: boundedArray(boundedString()).optional()
|
|
3320
|
+
serialOnly: boundedArray(boundedString()).optional(),
|
|
3321
|
+
// A thinking option the operator allows for that Peer provider, and why; omitted, the Peer
|
|
3322
|
+
// launches on its profile's option (docs/design/runtime-coordination-peer-effort.md E-D2).
|
|
3323
|
+
thinking: z6.string().min(1).max(64).optional(),
|
|
3324
|
+
thinkingReason: boundedString(1024).optional()
|
|
3285
3325
|
}),
|
|
3286
3326
|
assignment_answer: z6.strictObject({ ...assignment, answer: boundedString() }),
|
|
3287
3327
|
assignment_rework: z6.strictObject({ ...assignment, instructions: boundedString() }),
|
|
@@ -3295,7 +3335,7 @@ var init_actions = __esm({
|
|
|
3295
3335
|
assignment_reject: z6.strictObject({ ...assignment, reason }),
|
|
3296
3336
|
assignment_abandon: z6.strictObject({ ...assignment, reason }),
|
|
3297
3337
|
assignment_close: z6.strictObject(assignment),
|
|
3298
|
-
assignment_status: z6.strictObject({ assignmentId: assignmentIdSchema.optional() }),
|
|
3338
|
+
assignment_status: z6.strictObject({ assignmentId: assignmentIdSchema.optional(), full: z6.boolean().optional() }),
|
|
3299
3339
|
gate_run: z6.strictObject(assignment),
|
|
3300
3340
|
// Discarding a retained worktree's uncommitted work is Lead's explicit decision, with a reason.
|
|
3301
3341
|
workspace_close: z6.strictObject({ ...assignment, discardUncommitted: z6.literal(true).optional(), reason: reason.optional() }).refine((input) => input.discardUncommitted !== true || input.reason !== void 0, { message: "discardUncommitted needs a reason", path: ["reason"] }),
|
|
@@ -3402,7 +3442,7 @@ function readEvent(value) {
|
|
|
3402
3442
|
const parsed2 = readerSchema.safeParse(value);
|
|
3403
3443
|
return parsed2.success ? { ok: true, event: parsed2.data } : { ok: false, reason: "invalid", detail: z8.prettifyError(parsed2.error) };
|
|
3404
3444
|
}
|
|
3405
|
-
var EVENT_SCHEMA, id, text2, reason2, generation2, digest2, timestamp, workspaceIdSchema, branch, epoch, scopes, gateResultSchema, NOTICE_DISPOSITIONS, NOTICE_CLASSES, EVENT_PAYLOADS, EVENT_TYPES, SUPPORTED_PAYLOAD_VERSIONS, actorSchema, envelope, firstWriter, restWriters, firstReader, restReaders, writerSchema, readerSchema;
|
|
3445
|
+
var EVENT_SCHEMA, id, text2, reason2, thinkingOption, generation2, digest2, timestamp, workspaceIdSchema, branch, epoch, scopes, gateResultSchema, NOTICE_DISPOSITIONS, NOTICE_CLASSES, EVENT_PAYLOADS, EVENT_TYPES, SUPPORTED_PAYLOAD_VERSIONS, actorSchema, envelope, firstWriter, restWriters, firstReader, restReaders, writerSchema, readerSchema;
|
|
3406
3446
|
var init_schema = __esm({
|
|
3407
3447
|
"src/runtime-plugin/server/events/schema.ts"() {
|
|
3408
3448
|
"use strict";
|
|
@@ -3415,6 +3455,7 @@ var init_schema = __esm({
|
|
|
3415
3455
|
id = z8.string().min(1).max(128);
|
|
3416
3456
|
text2 = boundedString();
|
|
3417
3457
|
reason2 = boundedString(1024);
|
|
3458
|
+
thinkingOption = z8.string().min(1).max(64);
|
|
3418
3459
|
generation2 = z8.number().int().min(1);
|
|
3419
3460
|
digest2 = z8.string().regex(/^sha256:[0-9a-f]{64}$/);
|
|
3420
3461
|
timestamp = z8.iso.datetime({ offset: true });
|
|
@@ -3449,7 +3490,8 @@ var init_schema = __esm({
|
|
|
3449
3490
|
"project.ownership-resolved": { keptLeadAgentId: id, decidedBy: z8.enum(["evidence", "human"]) },
|
|
3450
3491
|
// Assignment lifecycle decided by Lead or Human (§5.1).
|
|
3451
3492
|
"assignment.created": { input: assignmentCreateSchema, leadAgentId: id, leadProviderId: id },
|
|
3452
|
-
|
|
3493
|
+
// Lead's thinking choice within the operator's envelope, and why (peer-effort delta E-D2, E-D4).
|
|
3494
|
+
"assignment.dispatch-requested": { peerProviderId: id, workspaceId: id, thinking: thinkingOption.optional(), thinkingReason: reason2.optional() },
|
|
3453
3495
|
"assignment.answered": { answer: text2 },
|
|
3454
3496
|
"assignment.rework-requested": { instructions: text2 },
|
|
3455
3497
|
"assignment.accepted": {
|
|
@@ -3492,7 +3534,8 @@ var init_schema = __esm({
|
|
|
3492
3534
|
model: z8.string().min(1).max(256),
|
|
3493
3535
|
parentAgentId: id,
|
|
3494
3536
|
workspaceId: id,
|
|
3495
|
-
roomGeneration: id
|
|
3537
|
+
roomGeneration: id,
|
|
3538
|
+
thinking: thinkingOption.optional()
|
|
3496
3539
|
},
|
|
3497
3540
|
"reporting.generation-opened": { generation: generation2, capabilityHash: digest2, turn: z8.enum(["initial", "answer", "rework", "follow-up"]) },
|
|
3498
3541
|
"run.requested": { intentId: id, generation: generation2, promptDigest: digest2 },
|