@astrosheep/keiyaku 4.0.0 → 4.0.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/README.md +2 -9
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +4 -4
- package/build/integrations/marketplace/plugins/keiyaku/opencode.js +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/package.json +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +11 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +9 -6
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +94 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/agents/openai.yaml +4 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +41 -6
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +162 -45
- package/build/src/akuma/akuma.d.ts +33 -25
- package/build/src/akuma/akuma.js +93 -61
- package/build/src/akuma/archetype.d.ts +8 -0
- package/build/src/akuma/archetype.js +28 -9
- package/build/src/akuma/body.js +196 -84
- package/build/src/akuma/coordinate.d.ts +9 -0
- package/build/src/akuma/coordinate.js +22 -0
- package/build/src/akuma/heart/facts.d.ts +67 -15
- package/build/src/akuma/heart/facts.js +3 -3
- package/build/src/akuma/heart/index.d.ts +41 -29
- package/build/src/akuma/heart/index.js +72 -193
- package/build/src/akuma/heart/rows.d.ts +30 -53
- package/build/src/akuma/heart/rows.js +91 -111
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +55 -8
- package/build/src/akuma/heart/storage.d.ts +33 -0
- package/build/src/akuma/heart/storage.js +164 -0
- package/build/src/akuma/heart/tells.d.ts +12 -0
- package/build/src/akuma/heart/tells.js +79 -0
- package/build/src/akuma/heart/timeline.d.ts +15 -0
- package/build/src/akuma/heart/timeline.js +86 -0
- package/build/src/akuma/index.d.ts +4 -2
- package/build/src/akuma/index.js +1 -1
- package/build/src/akuma/projection.d.ts +97 -0
- package/build/src/akuma/projection.js +145 -0
- package/build/src/akuma/provider.d.ts +57 -11
- package/build/src/akuma/provider.js +57 -37
- package/build/src/akuma/providers/{claude.d.ts → claude/events.d.ts} +9 -41
- package/build/src/akuma/providers/claude/events.js +185 -0
- package/build/src/akuma/providers/claude/index.d.ts +46 -0
- package/build/src/akuma/providers/claude/index.js +265 -0
- package/build/src/akuma/providers/claude/input.d.ts +13 -0
- package/build/src/akuma/providers/claude/input.js +109 -0
- package/build/src/akuma/providers/codex-app-server/events.d.ts +1 -1
- package/build/src/akuma/providers/codex-app-server/events.js +12 -12
- package/build/src/akuma/providers/codex-app-server/index.d.ts +13 -11
- package/build/src/akuma/providers/codex-app-server/index.js +73 -22
- package/build/src/akuma/providers/index.js +22 -8
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +48 -0
- package/build/src/akuma/providers/opencode-sdk/events.js +116 -0
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +32 -0
- package/build/src/akuma/providers/opencode-sdk/index.js +203 -0
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +41 -0
- package/build/src/akuma/providers/opencode-sdk/session.js +62 -0
- package/build/src/akuma/providers/pi/events.d.ts +33 -0
- package/build/src/akuma/providers/pi/events.js +128 -0
- package/build/src/akuma/providers/pi/index.d.ts +11 -0
- package/build/src/akuma/providers/pi/index.js +162 -0
- package/build/src/akuma/requests.d.ts +1 -0
- package/build/src/akuma/requests.js +5 -2
- package/build/src/alias/index.d.ts +4 -3
- package/build/src/alias/index.js +2 -3
- package/build/src/body/render.js +2 -1
- package/build/src/body/shape.js +7 -1
- package/build/src/body/verification.js +19 -4
- package/build/src/cli/accepted.d.ts +2 -0
- package/build/src/cli/accepted.js +2 -1
- package/build/src/cli/commands/akuma-invoke.d.ts +42 -18
- package/build/src/cli/commands/akuma-invoke.js +94 -50
- package/build/src/cli/commands/akuma.d.ts +15 -7
- package/build/src/cli/commands/akuma.js +94 -56
- package/build/src/cli/commands/contract.d.ts +142 -0
- package/build/src/cli/commands/contract.js +14 -0
- package/build/src/cli/commands/install.js +2 -0
- package/build/src/cli/commands/task-invoke.d.ts +3 -1
- package/build/src/cli/commands/task-invoke.js +27 -2
- package/build/src/cli/commands/task.js +2 -2
- package/build/src/cli/invoke.d.ts +6 -1
- package/build/src/cli/invoke.js +241 -43
- package/build/src/cli/main.js +20 -1
- package/build/src/cli/parse.d.ts +13 -116
- package/build/src/cli/parse.js +51 -78
- package/build/src/cli/render/akuma-tool.d.ts +2 -0
- package/build/src/cli/render/akuma-tool.js +6 -2
- package/build/src/cli/render/akuma.d.ts +2 -1
- package/build/src/cli/render/akuma.js +157 -217
- package/build/src/cli/render/catalog.d.ts +2 -0
- package/build/src/cli/render/catalog.js +16 -0
- package/build/src/cli/render/contract.d.ts +1 -1
- package/build/src/cli/render/contract.js +38 -5
- package/build/src/cli/render/kanshi.js +53 -5
- package/build/src/cli/render/refusal.js +17 -0
- package/build/src/cli/render/terminal.d.ts +13 -0
- package/build/src/cli/render/terminal.js +75 -0
- package/build/src/cli/render/text.js +5 -0
- package/build/src/cli/result.d.ts +15 -3
- package/build/src/contract-worktree.d.ts +43 -0
- package/build/src/contract-worktree.js +213 -0
- package/build/src/coordination/durable-file.d.ts +3 -0
- package/build/src/coordination/durable-file.js +44 -1
- package/build/src/core/facts/codec.js +23 -4
- package/build/src/core/facts/eligibility.d.ts +1 -10
- package/build/src/core/facts/eligibility.js +0 -49
- package/build/src/core/facts/observation.d.ts +3 -0
- package/build/src/core/facts/observation.js +12 -0
- package/build/src/core/facts/types.d.ts +10 -3
- package/build/src/core/subject.js +2 -2
- package/build/src/core/verbs/amend.js +12 -16
- package/build/src/core/verbs/bind.js +2 -16
- package/build/src/core/verbs/deliver.js +20 -4
- package/build/src/core/verbs/placement.js +3 -8
- package/build/src/dispatch/index.d.ts +3 -1
- package/build/src/dispatch/index.js +14 -5
- package/build/src/duration.d.ts +10 -0
- package/build/src/duration.js +22 -0
- package/build/src/git/admission.d.ts +2 -2
- package/build/src/git/admission.js +26 -16
- package/build/src/git/hooks.d.ts +15 -0
- package/build/src/git/hooks.js +57 -5
- package/build/src/git/identity.d.ts +5 -1
- package/build/src/git/identity.js +23 -4
- package/build/src/git/integration.d.ts +49 -0
- package/build/src/git/integration.js +214 -0
- package/build/src/git/observe.d.ts +25 -13
- package/build/src/git/observe.js +175 -72
- package/build/src/git/read-observation.d.ts +41 -0
- package/build/src/git/read-observation.js +361 -0
- package/build/src/git/reconcile.d.ts +15 -5
- package/build/src/git/reconcile.js +238 -85
- package/build/src/git/repository.d.ts +19 -4
- package/build/src/git/repository.js +77 -43
- package/build/src/git/scratch.d.ts +13 -0
- package/build/src/git/scratch.js +66 -0
- package/build/src/git/target-placement.d.ts +56 -0
- package/build/src/git/target-placement.js +255 -0
- package/build/src/git/tender.d.ts +48 -0
- package/build/src/git/tender.js +82 -0
- package/build/src/git/terminal-seal.d.ts +24 -0
- package/build/src/git/terminal-seal.js +87 -0
- package/build/src/git/tree.d.ts +2 -2
- package/build/src/git/tree.js +4 -0
- package/build/src/git/workspace.d.ts +21 -0
- package/build/src/git/workspace.js +104 -0
- package/build/src/identity/selector.d.ts +6 -0
- package/build/src/identity/selector.js +19 -0
- package/build/src/index.d.ts +4 -2
- package/build/src/index.js +2 -1
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.d.ts +5 -2
- package/build/src/kanshi/read.js +154 -45
- package/build/src/kanshi/report.d.ts +31 -6
- package/build/src/kanshi/select.js +1 -1
- package/build/src/library/address.d.ts +48 -0
- package/build/src/library/address.js +134 -0
- package/build/src/library/akuma-creation.d.ts +10 -6
- package/build/src/library/akuma-creation.js +12 -11
- package/build/src/library/bind.d.ts +21 -0
- package/build/src/library/bind.js +56 -0
- package/build/src/library/catalog.d.ts +58 -0
- package/build/src/library/catalog.js +72 -0
- package/build/src/library/configuration.d.ts +6 -15
- package/build/src/library/configuration.js +14 -17
- package/build/src/library/contract.d.ts +21 -46
- package/build/src/library/contract.js +193 -183
- package/build/src/library/delivery.d.ts +23 -0
- package/build/src/library/delivery.js +21 -0
- package/build/src/library/fleet.d.ts +65 -0
- package/build/src/library/fleet.js +189 -0
- package/build/src/library/input.d.ts +3 -0
- package/build/src/library/input.js +19 -0
- package/build/src/library/keiyaku.d.ts +16 -2
- package/build/src/library/keiyaku.js +11 -1
- package/build/src/library/mutation.d.ts +38 -0
- package/build/src/library/mutation.js +39 -0
- package/build/src/library/refusal.d.ts +21 -0
- package/build/src/library/refusal.js +29 -0
- package/build/src/library/region.d.ts +2 -1
- package/build/src/library/region.js +3 -3
- package/build/src/library/repo.d.ts +4 -1
- package/build/src/library/repo.js +31 -16
- package/build/src/protocol/attempt.d.ts +16 -3
- package/build/src/protocol/attempt.js +39 -8
- package/build/src/protocol/bind.d.ts +9 -2
- package/build/src/protocol/bind.js +47 -39
- package/build/src/protocol/intent.d.ts +42 -18
- package/build/src/protocol/intent.js +36 -75
- package/build/src/protocol/operations.d.ts +93 -35
- package/build/src/protocol/operations.js +235 -123
- package/build/src/protocol/outcome.d.ts +7 -2
- package/build/src/protocol/outcome.js +9 -3
- package/build/src/protocol/placement.d.ts +30 -0
- package/build/src/protocol/placement.js +114 -0
- package/build/src/protocol/read/audit.d.ts +9 -3
- package/build/src/protocol/read/audit.js +25 -9
- package/build/src/protocol/read/documents.d.ts +2 -2
- package/build/src/protocol/read/documents.js +4 -4
- package/build/src/protocol/read/status.d.ts +11 -5
- package/build/src/protocol/read/status.js +28 -15
- package/build/src/protocol/run.d.ts +49 -7
- package/build/src/protocol/run.js +53 -25
- package/build/src/runtime/proc/line-rpc.d.ts +1 -0
- package/build/src/runtime/proc/line-rpc.js +21 -0
- package/build/src/runtime/proc/run.d.ts +18 -2
- package/build/src/runtime/proc/run.js +34 -8
- package/build/src/settings.d.ts +6 -0
- package/build/src/settings.js +29 -14
- package/build/src/settlement/fence.d.ts +9 -0
- package/build/src/settlement/fence.js +23 -0
- package/build/src/settlement/holder.d.ts +25 -4
- package/build/src/settlement/holder.js +102 -28
- package/build/src/settlement/settle.d.ts +8 -0
- package/build/src/settlement/settle.js +102 -28
- package/build/src/task/board.d.ts +20 -2
- package/build/src/task/board.js +11 -1
- package/build/src/task/compose.d.ts +2 -2
- package/build/src/task/compose.js +2 -2
- package/build/src/task/context.js +2 -7
- package/build/src/task/index.d.ts +9 -9
- package/build/src/task/index.js +15 -12
- package/build/src/task/operations.d.ts +31 -12
- package/build/src/task/operations.js +8 -4
- package/build/src/task/store.d.ts +4 -6
- package/build/src/task/store.js +3 -3
- package/build/src/verification/declaration.d.ts +1 -0
- package/build/src/verification/execution.d.ts +49 -0
- package/build/src/verification/execution.js +104 -0
- package/build/src/world.d.ts +13 -0
- package/build/src/world.js +103 -0
- package/package.json +7 -4
- package/build/src/akuma/activity.d.ts +0 -66
- package/build/src/akuma/activity.js +0 -139
- package/build/src/akuma/providers/claude.js +0 -305
- package/build/src/context-root.d.ts +0 -4
- package/build/src/context-root.js +0 -15
- package/build/src/git/delivery.d.ts +0 -20
- package/build/src/git/delivery.js +0 -109
- package/build/src/git/verification.d.ts +0 -14
- package/build/src/git/verification.js +0 -56
- package/build/src/verification/producer.d.ts +0 -23
- package/build/src/verification/producer.js +0 -54
package/build/src/akuma/body.js
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import { fileURLToPath } from "node:url";
|
|
2
|
-
import { HeldAkumaLeash,
|
|
2
|
+
import { HeldAkumaLeash, appendActivity, beginTurn, breakBody, endTurn, finishBodyIfIdle, heartExists, pauseRequested, readHeart, recordBody, recordSession, recordTellDeliveries, recordTellReceipt, stopRequested, } from "./heart/index.js";
|
|
3
3
|
import { encodeAgentEvent } from "./provider.js";
|
|
4
4
|
import { providerNamed } from "./providers/index.js";
|
|
5
|
-
import { BodyRequestPump, settleBodyRequests, } from "./requests.js";
|
|
5
|
+
import { BodyRequestPump, clearBodyRequestTransport, settleBodyRequests, } from "./requests.js";
|
|
6
6
|
import { currentProcessCollar, probeProcessTree, putDownProcessTree, spawnDetachedProcess, } from "../runtime/proc/run.js";
|
|
7
7
|
const LEASH_RETRY_MS = 25;
|
|
8
8
|
function wait(milliseconds) {
|
|
9
9
|
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
10
10
|
}
|
|
11
|
+
function serializeEffects() {
|
|
12
|
+
let tail = Promise.resolve();
|
|
13
|
+
return async (effect) => {
|
|
14
|
+
const before = tail;
|
|
15
|
+
let release;
|
|
16
|
+
tail = new Promise((resolve) => { release = resolve; });
|
|
17
|
+
await before;
|
|
18
|
+
try {
|
|
19
|
+
return await effect();
|
|
20
|
+
}
|
|
21
|
+
finally {
|
|
22
|
+
release();
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
11
26
|
function missing(error) {
|
|
12
27
|
return error.code === "ENOENT";
|
|
13
28
|
}
|
|
@@ -50,6 +65,13 @@ async function settlePredecessor(paths) {
|
|
|
50
65
|
}
|
|
51
66
|
async function startTurnDrive(input) {
|
|
52
67
|
const { cwd, options, session } = turnRecipe(input.paths, input.soul);
|
|
68
|
+
if (session !== undefined && input.adapter.resume === undefined)
|
|
69
|
+
return { kind: "resume-unsupported" };
|
|
70
|
+
const turn = beginTurn(input.paths, {
|
|
71
|
+
bodySequence: input.bodySequence,
|
|
72
|
+
startedAt: input.now(),
|
|
73
|
+
...(input.call === undefined ? {} : { call: input.call }),
|
|
74
|
+
});
|
|
53
75
|
const requests = input.soul.confinement.kind === "declared"
|
|
54
76
|
? new BodyRequestPump({
|
|
55
77
|
paths: input.paths,
|
|
@@ -60,94 +82,181 @@ async function startTurnDrive(input) {
|
|
|
60
82
|
})
|
|
61
83
|
: null;
|
|
62
84
|
try {
|
|
63
|
-
const
|
|
64
|
-
|
|
85
|
+
const driveInput = {
|
|
86
|
+
body: input.body,
|
|
87
|
+
launchTells: input.launchTells.map((tell) => ({ id: tell.id, text: tell.body })),
|
|
65
88
|
cwd,
|
|
66
89
|
options,
|
|
67
|
-
...(session === undefined ? {} : { session }),
|
|
68
90
|
...(requests === null ? {} : { requests: { dir: requests.directory } }),
|
|
69
|
-
}
|
|
91
|
+
};
|
|
92
|
+
const selected = session === undefined
|
|
93
|
+
? await input.adapter.start({ ...driveInput, session: { kind: "fresh" } })
|
|
94
|
+
: await input.adapter.resume({ ...driveInput, session: { kind: "resume", coordinate: session } });
|
|
95
|
+
if (input.launchTells.length > 0) {
|
|
96
|
+
recordTellDeliveries(input.paths, input.launchTells.map((tell) => ({
|
|
97
|
+
tellId: tell.id,
|
|
98
|
+
route: "launch",
|
|
99
|
+
turnSequence: turn.sequence,
|
|
100
|
+
fence: selected.admission.fence,
|
|
101
|
+
deliveredAt: input.now(),
|
|
102
|
+
})));
|
|
103
|
+
}
|
|
70
104
|
if (requests !== null)
|
|
71
|
-
void
|
|
72
|
-
return { drive, requests, cwd, options,
|
|
105
|
+
void selected.completion.then(() => requests.stopAdmission());
|
|
106
|
+
return { turnSequence: turn.sequence, drive: selected, requests, cwd, options,
|
|
107
|
+
...(session === undefined ? {} : { resume: session }) };
|
|
73
108
|
}
|
|
74
109
|
catch (error) {
|
|
75
110
|
if (requests !== null)
|
|
76
111
|
await requests.close();
|
|
77
|
-
|
|
112
|
+
const diagnostic = error instanceof Error ? error.message : String(error);
|
|
113
|
+
endTurn(input.paths, {
|
|
114
|
+
turnSequence: turn.sequence,
|
|
115
|
+
outcome: { kind: "failed", diagnostic },
|
|
116
|
+
completedAt: input.now(),
|
|
117
|
+
});
|
|
118
|
+
return { kind: "start-failed", turnSequence: turn.sequence, diagnostic };
|
|
78
119
|
}
|
|
79
120
|
}
|
|
121
|
+
function pumpReceipts(input, turnSequence, drive, writeWitness) {
|
|
122
|
+
return (async () => {
|
|
123
|
+
if (drive.receipts === undefined)
|
|
124
|
+
return;
|
|
125
|
+
for await (const receipt of drive.receipts) {
|
|
126
|
+
await writeWitness(() => recordTellReceipt(input.paths, receipt.evidence === "exact"
|
|
127
|
+
? { ...receipt, receivedAt: input.now() }
|
|
128
|
+
: { ...receipt, turnSequence, receivedAt: input.now() }));
|
|
129
|
+
}
|
|
130
|
+
})();
|
|
131
|
+
}
|
|
132
|
+
async function submitPendingLiveTells(input, turnSequence, drive, attempted, writeWitness) {
|
|
133
|
+
if (drive.tell === undefined)
|
|
134
|
+
return "live";
|
|
135
|
+
for (const tell of readHeart(input.paths).pending) {
|
|
136
|
+
if (attempted.has(tell.id))
|
|
137
|
+
continue;
|
|
138
|
+
attempted.add(tell.id);
|
|
139
|
+
const outcome = await writeWitness(async () => {
|
|
140
|
+
const submission = await drive.tell({ id: tell.id, text: tell.body });
|
|
141
|
+
if (submission.kind === "turn-ended")
|
|
142
|
+
return "turn-ended";
|
|
143
|
+
recordTellDeliveries(input.paths, [{
|
|
144
|
+
tellId: tell.id,
|
|
145
|
+
route: "live",
|
|
146
|
+
turnSequence,
|
|
147
|
+
fence: submission.fence,
|
|
148
|
+
receipt: drive.receipts === undefined ? "unavailable" : "required",
|
|
149
|
+
deliveredAt: input.now(),
|
|
150
|
+
}]);
|
|
151
|
+
return "accepted";
|
|
152
|
+
});
|
|
153
|
+
if (outcome === "turn-ended")
|
|
154
|
+
return "turn-ended";
|
|
155
|
+
}
|
|
156
|
+
return "live";
|
|
157
|
+
}
|
|
80
158
|
async function consumeTurnDrive(input, active) {
|
|
81
|
-
const { drive, requests, cwd, options,
|
|
82
|
-
let turnSession =
|
|
83
|
-
|
|
159
|
+
const { turnSequence, drive, requests, cwd, options, resume } = active;
|
|
160
|
+
let turnSession = resume;
|
|
161
|
+
const attempted = new Set(input.launchTells.map((tell) => tell.id));
|
|
162
|
+
const writeWitness = serializeEffects();
|
|
163
|
+
const receiptPump = pumpReceipts(input, turnSequence, drive, writeWitness);
|
|
164
|
+
const receiptFailure = receiptPump.then(() => new Promise(() => { }), (error) => Promise.reject(error));
|
|
84
165
|
const iterator = drive.events[Symbol.asyncIterator]();
|
|
85
166
|
let pending = iterator.next();
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
167
|
+
let liveTells = true;
|
|
168
|
+
try {
|
|
169
|
+
for (;;) {
|
|
170
|
+
if (stopRequested(input.paths, input.bodySequence) || pauseRequested(input.paths)) {
|
|
171
|
+
const draining = requests?.close();
|
|
172
|
+
try {
|
|
173
|
+
await drive.abort();
|
|
174
|
+
}
|
|
175
|
+
finally {
|
|
176
|
+
await draining;
|
|
177
|
+
await receiptPump;
|
|
178
|
+
}
|
|
179
|
+
return { kind: "stopped" };
|
|
91
180
|
}
|
|
92
|
-
|
|
93
|
-
await
|
|
181
|
+
if (liveTells) {
|
|
182
|
+
liveTells = await submitPendingLiveTells(input, turnSequence, drive, attempted, writeWitness) === "live";
|
|
94
183
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
184
|
+
const next = await Promise.race([
|
|
185
|
+
pending,
|
|
186
|
+
wait(LEASH_RETRY_MS).then(() => null),
|
|
187
|
+
receiptFailure,
|
|
188
|
+
...(requests === null ? [] : [requests.failure]),
|
|
189
|
+
]);
|
|
190
|
+
if (next === null)
|
|
191
|
+
continue;
|
|
192
|
+
if (next.done)
|
|
193
|
+
break;
|
|
194
|
+
const event = next.value;
|
|
195
|
+
const at = input.now();
|
|
196
|
+
if (event.type === "session") {
|
|
197
|
+
turnSession = event.coordinate;
|
|
198
|
+
recordSession(input.paths, {
|
|
199
|
+
provider: input.soul.provider.name,
|
|
200
|
+
coordinate: event.coordinate,
|
|
201
|
+
cwd,
|
|
202
|
+
options,
|
|
203
|
+
admittedAt: at,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
appendActivity(input.paths, {
|
|
207
|
+
turnSequence,
|
|
208
|
+
event: encodeAgentEvent(event),
|
|
209
|
+
at,
|
|
116
210
|
});
|
|
211
|
+
pending = iterator.next();
|
|
117
212
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
advanceTell(input.paths, input.tellId, "seen");
|
|
126
|
-
advanceTell(input.paths, input.tellId, "consumed");
|
|
127
|
-
}
|
|
128
|
-
pending = iterator.next();
|
|
213
|
+
const result = await drive.completion;
|
|
214
|
+
await receiptPump;
|
|
215
|
+
if (requests !== null)
|
|
216
|
+
await requests.close();
|
|
217
|
+
return result.kind === "answered"
|
|
218
|
+
? { ...result, ...(turnSession === undefined ? {} : { session: turnSession }) }
|
|
219
|
+
: result;
|
|
129
220
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
221
|
+
catch (error) {
|
|
222
|
+
const draining = requests?.close();
|
|
223
|
+
try {
|
|
224
|
+
await drive.abort();
|
|
225
|
+
}
|
|
226
|
+
catch { /* the pump failure owns the turn result */ }
|
|
227
|
+
try {
|
|
228
|
+
await receiptPump;
|
|
229
|
+
}
|
|
230
|
+
catch { /* preserve the first pump failure */ }
|
|
231
|
+
try {
|
|
232
|
+
await draining;
|
|
233
|
+
}
|
|
234
|
+
catch { /* preserve the first pump failure */ }
|
|
235
|
+
return { kind: "failed", diagnostic: error instanceof Error ? error.message : String(error) };
|
|
136
236
|
}
|
|
137
|
-
return result.kind === "answered"
|
|
138
|
-
? { ...result, ...(turnSession === undefined ? {} : { session: turnSession }) }
|
|
139
|
-
: result;
|
|
140
237
|
}
|
|
141
238
|
async function driveTurn(input) {
|
|
142
|
-
|
|
239
|
+
let active;
|
|
240
|
+
try {
|
|
241
|
+
const started = await startTurnDrive(input);
|
|
242
|
+
if ("kind" in started)
|
|
243
|
+
return started;
|
|
244
|
+
active = started;
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
if (!heartExists(input.paths))
|
|
248
|
+
return { kind: "heart-gone" };
|
|
249
|
+
throw error;
|
|
250
|
+
}
|
|
143
251
|
try {
|
|
144
|
-
return await consumeTurnDrive(input, active);
|
|
252
|
+
return { ...await consumeTurnDrive(input, active), turnSequence: active.turnSequence };
|
|
145
253
|
}
|
|
146
254
|
catch (error) {
|
|
147
255
|
const draining = active.requests?.close();
|
|
148
256
|
if (heartExists(input.paths)) {
|
|
149
257
|
await draining;
|
|
150
|
-
|
|
258
|
+
return { kind: "failed", diagnostic: error instanceof Error ? error.message : String(error),
|
|
259
|
+
turnSequence: active.turnSequence };
|
|
151
260
|
}
|
|
152
261
|
try {
|
|
153
262
|
await active.drive.abort();
|
|
@@ -162,10 +271,8 @@ async function driveTurn(input) {
|
|
|
162
271
|
}
|
|
163
272
|
function bornSoul(launch, leash, now) {
|
|
164
273
|
const before = readHeart(launch.paths);
|
|
165
|
-
if (before.death !== null)
|
|
166
|
-
return null;
|
|
167
274
|
if (before.soul !== null) {
|
|
168
|
-
|
|
275
|
+
leash.clearPause(launch.paths);
|
|
169
276
|
return before.soul;
|
|
170
277
|
}
|
|
171
278
|
if (launch.seed === undefined)
|
|
@@ -190,9 +297,9 @@ function launchCwd(launch) {
|
|
|
190
297
|
? snapshot.latestSession.cwd
|
|
191
298
|
: soul.cwd;
|
|
192
299
|
}
|
|
193
|
-
function persistTurn(paths,
|
|
194
|
-
|
|
195
|
-
|
|
300
|
+
function persistTurn(paths, turnSequence, result, completedAt) {
|
|
301
|
+
endTurn(paths, {
|
|
302
|
+
turnSequence,
|
|
196
303
|
outcome: result.kind === "answered" && result.session !== undefined
|
|
197
304
|
? { kind: "answered", historyId: result.historyId, session: result.session, answer: result.answer }
|
|
198
305
|
: result.kind === "answered"
|
|
@@ -213,11 +320,14 @@ function defaultRuntime() {
|
|
|
213
320
|
function childSpawner(runtime) {
|
|
214
321
|
return runtime.spawnChild ?? spawnAkumaBody;
|
|
215
322
|
}
|
|
216
|
-
async function beginBody(paths, soul, runtime) {
|
|
323
|
+
async function beginBody(paths, soul, leash, runtime) {
|
|
217
324
|
if (!await settlePredecessor(paths))
|
|
218
325
|
return null;
|
|
326
|
+
leash.settleStop(paths);
|
|
219
327
|
const body = recordBody(paths, { collar: runtime.collar, leashTakenAt: runtime.now() });
|
|
220
|
-
|
|
328
|
+
const requests = await settleBodyRequests(paths, soul, runtime.now);
|
|
329
|
+
clearBodyRequestTransport(paths);
|
|
330
|
+
if (requests === "settled")
|
|
221
331
|
return body;
|
|
222
332
|
breakBody(paths, { sequence: body.sequence, end: "broke-off", at: runtime.now() });
|
|
223
333
|
return null;
|
|
@@ -231,34 +341,28 @@ export async function driveAkumaBody(launch, adapter, runtime = defaultRuntime()
|
|
|
231
341
|
if (soul === null)
|
|
232
342
|
return;
|
|
233
343
|
const selected = adapter ?? providerNamed(soul.provider);
|
|
234
|
-
const body = await beginBody(launch.paths, soul, runtime);
|
|
344
|
+
const body = await beginBody(launch.paths, soul, leash, runtime);
|
|
235
345
|
if (body === null)
|
|
236
346
|
return;
|
|
237
347
|
let initial = launch.initialBody;
|
|
238
348
|
for (;;) {
|
|
239
349
|
const snapshot = readHeart(launch.paths);
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
const tell = initial === undefined ? snapshot.pending[0] : undefined;
|
|
245
|
-
const prompt = initial ?? tell?.body;
|
|
246
|
-
if (prompt === undefined) {
|
|
350
|
+
const launchTells = snapshot.pending;
|
|
351
|
+
if (initial === undefined && launchTells.length === 0) {
|
|
247
352
|
const finished = finishBodyIfIdle(launch.paths, { sequence: body.sequence, at: runtime.now() });
|
|
248
353
|
if (finished.kind === "finished")
|
|
249
354
|
return;
|
|
250
355
|
continue;
|
|
251
356
|
}
|
|
252
|
-
if (tell !== undefined)
|
|
253
|
-
advanceTell(launch.paths, tell.id, "delivered");
|
|
254
357
|
const result = await driveTurn({
|
|
255
358
|
paths: launch.paths,
|
|
256
359
|
soul,
|
|
257
360
|
adapter: selected,
|
|
258
361
|
bodySequence: body.sequence,
|
|
259
362
|
runtimeSpawn: childSpawner(runtime),
|
|
260
|
-
|
|
261
|
-
...(
|
|
363
|
+
body: initial ?? "",
|
|
364
|
+
...(initial === undefined ? {} : { call: initial }),
|
|
365
|
+
launchTells,
|
|
262
366
|
now: runtime.now,
|
|
263
367
|
});
|
|
264
368
|
if (result.kind === "heart-gone") {
|
|
@@ -269,7 +373,15 @@ export async function driveAkumaBody(launch, adapter, runtime = defaultRuntime()
|
|
|
269
373
|
breakBody(launch.paths, { sequence: body.sequence, end: "put-down", at: runtime.now() });
|
|
270
374
|
return;
|
|
271
375
|
}
|
|
272
|
-
if (
|
|
376
|
+
if (result.kind === "resume-unsupported") {
|
|
377
|
+
breakBody(launch.paths, { sequence: body.sequence, end: "broke-off", at: runtime.now() });
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
if (result.kind === "start-failed") {
|
|
381
|
+
breakBody(launch.paths, { sequence: body.sequence, end: "broke-off", at: runtime.now() });
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
if (persistTurn(launch.paths, result.turnSequence, result, runtime.now()) === "failed") {
|
|
273
385
|
breakBody(launch.paths, { sequence: body.sequence, end: "broke-off", at: runtime.now() });
|
|
274
386
|
return;
|
|
275
387
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type ResumeCoordinate = Readonly<{
|
|
2
|
+
sessionId: string;
|
|
3
|
+
sessionFile?: never;
|
|
4
|
+
}> | Readonly<{
|
|
5
|
+
sessionFile: string;
|
|
6
|
+
sessionId?: string;
|
|
7
|
+
}>;
|
|
8
|
+
export declare function decodeResumeCoordinate(value: unknown): ResumeCoordinate | null;
|
|
9
|
+
export declare function encodeResumeCoordinate(coordinate: ResumeCoordinate): unknown;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
function record(value) {
|
|
2
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
3
|
+
? value : null;
|
|
4
|
+
}
|
|
5
|
+
export function decodeResumeCoordinate(value) {
|
|
6
|
+
const coordinate = record(value);
|
|
7
|
+
if (coordinate === null)
|
|
8
|
+
return null;
|
|
9
|
+
const keys = Object.keys(coordinate);
|
|
10
|
+
if (typeof coordinate.sessionFile === "string" && coordinate.sessionFile.trim().length > 0
|
|
11
|
+
&& (coordinate.sessionId === undefined || (typeof coordinate.sessionId === "string" && coordinate.sessionId.trim().length > 0))
|
|
12
|
+
&& keys.every((key) => key === "sessionFile" || key === "sessionId")) {
|
|
13
|
+
return { sessionFile: coordinate.sessionFile, ...(coordinate.sessionId === undefined ? {} : { sessionId: coordinate.sessionId }) };
|
|
14
|
+
}
|
|
15
|
+
return typeof coordinate.sessionId === "string" && coordinate.sessionId.trim().length > 0 && keys.length === 1
|
|
16
|
+
? { sessionId: coordinate.sessionId } : null;
|
|
17
|
+
}
|
|
18
|
+
export function encodeResumeCoordinate(coordinate) {
|
|
19
|
+
return "sessionFile" in coordinate
|
|
20
|
+
? { sessionFile: coordinate.sessionFile, ...(coordinate.sessionId === undefined ? {} : { sessionId: coordinate.sessionId }) }
|
|
21
|
+
: { sessionId: coordinate.sessionId };
|
|
22
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { AkuId } from "../identity.js";
|
|
2
|
+
import type { ResumeCoordinate } from "../coordinate.js";
|
|
3
|
+
export type { ResumeCoordinate } from "../coordinate.js";
|
|
2
4
|
export type Confinement = Readonly<{
|
|
3
5
|
kind: "unconfined";
|
|
4
6
|
}> | Readonly<{
|
|
@@ -14,7 +16,7 @@ export type ProviderOptions = Readonly<{
|
|
|
14
16
|
}>;
|
|
15
17
|
export type ProviderExecution = Readonly<{
|
|
16
18
|
name: string;
|
|
17
|
-
kind: "claude-agent-sdk" | "codex-app-server";
|
|
19
|
+
kind: "claude-agent-sdk" | "codex-app-server" | "opencode-sdk" | "pi";
|
|
18
20
|
executable?: string;
|
|
19
21
|
config?: Readonly<Record<string, unknown>>;
|
|
20
22
|
env?: Readonly<Record<string, string>>;
|
|
@@ -23,7 +25,7 @@ export type AkumaOrigin = Readonly<{
|
|
|
23
25
|
kind: "direct";
|
|
24
26
|
}> | Readonly<{
|
|
25
27
|
kind: "request";
|
|
26
|
-
|
|
28
|
+
parent: AkuId;
|
|
27
29
|
requestId: string;
|
|
28
30
|
}> | Readonly<{
|
|
29
31
|
kind: "fork";
|
|
@@ -55,9 +57,6 @@ export type BodyFact = Readonly<{
|
|
|
55
57
|
end?: BodyEnd;
|
|
56
58
|
endedAt?: string;
|
|
57
59
|
}>;
|
|
58
|
-
export type ResumeCoordinate = Readonly<{
|
|
59
|
-
sessionId: string;
|
|
60
|
-
}>;
|
|
61
60
|
export type SessionFact = Readonly<{
|
|
62
61
|
sequence: number;
|
|
63
62
|
provider: string;
|
|
@@ -82,19 +81,66 @@ export type TurnOutcome = Readonly<{
|
|
|
82
81
|
kind: "failed";
|
|
83
82
|
diagnostic: string;
|
|
84
83
|
}>;
|
|
85
|
-
export type
|
|
84
|
+
export type TurnStartFact = Readonly<{
|
|
85
|
+
kind: "turn-start";
|
|
86
86
|
sequence: number;
|
|
87
87
|
bodySequence: number;
|
|
88
|
+
startedAt: string;
|
|
89
|
+
}>;
|
|
90
|
+
export type TurnEndFact = Readonly<{
|
|
91
|
+
kind: "turn-end";
|
|
92
|
+
sequence: number;
|
|
93
|
+
turnSequence: number;
|
|
88
94
|
outcome: TurnOutcome;
|
|
89
95
|
completedAt: string;
|
|
90
96
|
}>;
|
|
91
|
-
export type
|
|
97
|
+
export type TurnFact = TurnStartFact & Readonly<{
|
|
98
|
+
end?: TurnEndFact;
|
|
99
|
+
}>;
|
|
100
|
+
export type CallFact = Readonly<{
|
|
101
|
+
kind: "call";
|
|
102
|
+
sequence: number;
|
|
103
|
+
turnSequence: number;
|
|
104
|
+
body: string;
|
|
105
|
+
at: string;
|
|
106
|
+
}>;
|
|
107
|
+
export type TellDelivery = Readonly<{
|
|
108
|
+
turnSequence: number;
|
|
109
|
+
route: "launch" | "live";
|
|
110
|
+
receipt?: "unavailable" | "required";
|
|
111
|
+
deliveredAt: string;
|
|
112
|
+
}>;
|
|
92
113
|
export type TellFact = Readonly<{
|
|
114
|
+
kind: "tell";
|
|
115
|
+
sequence: number;
|
|
93
116
|
id: string;
|
|
94
117
|
body: string;
|
|
95
|
-
state: TellState;
|
|
96
118
|
recordedAt: string;
|
|
97
|
-
|
|
119
|
+
state: "pending" | "told";
|
|
120
|
+
deliveries: readonly TellDelivery[];
|
|
121
|
+
}>;
|
|
122
|
+
export type TellDeliveryInput = Readonly<{
|
|
123
|
+
tellId: string;
|
|
124
|
+
turnSequence: number;
|
|
125
|
+
fence: string;
|
|
126
|
+
deliveredAt: string;
|
|
127
|
+
}> & (Readonly<{
|
|
128
|
+
route: "launch";
|
|
129
|
+
}> | Readonly<{
|
|
130
|
+
route: "live";
|
|
131
|
+
receipt: "unavailable" | "required";
|
|
132
|
+
}>);
|
|
133
|
+
export type TellReceiptInput = Readonly<{
|
|
134
|
+
kind: string;
|
|
135
|
+
receivedAt: string;
|
|
136
|
+
}> & (Readonly<{
|
|
137
|
+
evidence: "exact";
|
|
138
|
+
tellId: string;
|
|
139
|
+
}> | Readonly<{
|
|
140
|
+
evidence: "fence";
|
|
141
|
+
turnSequence: number;
|
|
142
|
+
fence: string;
|
|
143
|
+
}>);
|
|
98
144
|
export type RequestInput = Readonly<{
|
|
99
145
|
id: string;
|
|
100
146
|
archetype: string;
|
|
@@ -120,11 +166,17 @@ export type RequestFact = RequestInput & Readonly<{
|
|
|
120
166
|
state: "voided";
|
|
121
167
|
evidence: string;
|
|
122
168
|
}>);
|
|
123
|
-
export type KillEvidence = "killed" | "already-
|
|
124
|
-
export type
|
|
125
|
-
|
|
169
|
+
export type KillEvidence = "killed" | "already-killed" | "alive-after-sigkill" | "unavailable";
|
|
170
|
+
export type KillFact = Readonly<{
|
|
171
|
+
sequence: number;
|
|
172
|
+
bodySequence: number;
|
|
173
|
+
evidence: "killed";
|
|
126
174
|
at: string;
|
|
127
175
|
}>;
|
|
176
|
+
export type StopFact = Readonly<{
|
|
177
|
+
bodySequence: number;
|
|
178
|
+
requestedAt: string;
|
|
179
|
+
}>;
|
|
128
180
|
export type SealFact = Readonly<{
|
|
129
181
|
evidence: string;
|
|
130
182
|
at: string;
|
|
@@ -139,12 +191,12 @@ export type CollarProbe = Readonly<{
|
|
|
139
191
|
kind: "unverifiable";
|
|
140
192
|
diagnostic: string;
|
|
141
193
|
}>;
|
|
142
|
-
export type AkumaLife = "running" | "asleep" | "stranded" | "headless" | "
|
|
194
|
+
export type AkumaLife = "running" | "asleep" | "stranded" | "headless" | "killed";
|
|
143
195
|
export type HeartSnapshot = Readonly<{
|
|
144
196
|
soul: Soul | null;
|
|
145
197
|
latestBody: BodyFact | null;
|
|
146
198
|
latestSession: SessionFact | null;
|
|
147
199
|
pending: readonly TellFact[];
|
|
148
|
-
|
|
200
|
+
latestKill: KillFact | null;
|
|
149
201
|
}>;
|
|
150
|
-
export declare function life(leashProbe: LeashProbe, collarProbe: CollarProbe,
|
|
202
|
+
export declare function life(leashProbe: LeashProbe, collarProbe: CollarProbe, latestBody: BodyFact | null, latestKill: KillFact | null): AkumaLife;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export function life(leashProbe, collarProbe,
|
|
2
|
-
if (deathRow !== null)
|
|
3
|
-
return "dead";
|
|
1
|
+
export function life(leashProbe, collarProbe, latestBody, latestKill) {
|
|
4
2
|
if (leashProbe === "held")
|
|
5
3
|
return "running";
|
|
6
4
|
if (collarProbe.kind !== "gone")
|
|
7
5
|
return "headless";
|
|
6
|
+
if (latestBody !== null && latestKill?.bodySequence === latestBody.sequence)
|
|
7
|
+
return "killed";
|
|
8
8
|
return collarProbe.end === "exited" ? "asleep" : "stranded";
|
|
9
9
|
}
|