@astrosheep/keiyaku 4.6.8 → 4.6.9
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 +40 -14
- package/build/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/build/plugins/claude/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/claude/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/claude/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/claude/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/claude/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/claude/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/claude/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/build/plugins/codex/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/codex/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/codex/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/opencode/index.js +1 -1
- package/build/plugins/opencode/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/opencode/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/opencode/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/skills/keiyaku/SKILL.md +5 -6
- package/build/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/src/akuma/akuma-instance.d.ts +2 -0
- package/build/src/akuma/akuma-instance.js +10 -0
- package/build/src/akuma/akuma-observe.d.ts +33 -8
- package/build/src/akuma/akuma-observe.js +88 -64
- package/build/src/akuma/akuma-owner.d.ts +11 -2
- package/build/src/akuma/akuma-owner.js +45 -35
- package/build/src/akuma/akuma-selection-execution.js +9 -1
- package/build/src/akuma/akuma-stream.d.ts +22 -0
- package/build/src/akuma/akuma-stream.js +116 -0
- package/build/src/akuma/akuma-wait.d.ts +1 -40
- package/build/src/akuma/akuma-wait.js +23 -84
- package/build/src/akuma/akuma.d.ts +17 -11
- package/build/src/akuma/akuma.js +2 -0
- package/build/src/akuma/allowed.d.ts +7 -12
- package/build/src/akuma/allowed.js +13 -4
- package/build/src/akuma/body-supervisor.d.ts +5 -5
- package/build/src/akuma/body-supervisor.js +22 -20
- package/build/src/akuma/body.js +28 -1
- package/build/src/akuma/call-request.d.ts +12 -22
- package/build/src/akuma/heart/activity-schema.d.ts +12 -0
- package/build/src/akuma/heart/activity-schema.js +6 -0
- package/build/src/akuma/heart/index.d.ts +59 -2
- package/build/src/akuma/heart/index.js +87 -8
- package/build/src/akuma/heart/rows.js +5 -3
- package/build/src/akuma/heart/soul.d.ts +9 -0
- package/build/src/akuma/heart/soul.js +29 -0
- package/build/src/akuma/heart/storage.d.ts +15 -0
- package/build/src/akuma/heart/storage.js +55 -0
- package/build/src/akuma/heart/timeline.d.ts +7 -0
- package/build/src/akuma/heart/timeline.js +10 -0
- package/build/src/akuma/index.d.ts +1 -0
- package/build/src/akuma/projection.d.ts +25 -0
- package/build/src/akuma/projection.js +24 -7
- package/build/src/akuma/provider-recipe.d.ts +11 -0
- package/build/src/akuma/provider-recipe.js +23 -0
- package/build/src/akuma/provider.d.ts +25 -0
- package/build/src/akuma/provider.js +99 -7
- package/build/src/akuma/providers/acp/events.js +25 -2
- package/build/src/akuma/providers/claude/events.js +76 -10
- package/build/src/akuma/providers/claude/index.js +2 -5
- package/build/src/akuma/providers/codex-app-server/events.js +17 -2
- package/build/src/akuma/providers/codex-app-server/index.js +15 -9
- package/build/src/akuma/providers/decode.d.ts +8 -0
- package/build/src/akuma/providers/decode.js +21 -0
- package/build/src/akuma/providers/grok-build/index.js +10 -26
- package/build/src/akuma/providers/opencode-sdk/event-stream.d.ts +3 -3
- package/build/src/akuma/providers/opencode-sdk/event-stream.js +2 -25
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +7 -43
- package/build/src/akuma/providers/opencode-sdk/events.js +147 -284
- package/build/src/akuma/providers/opencode-sdk/index.js +267 -421
- package/build/src/akuma/providers/opencode-sdk/native-http.d.ts +9 -0
- package/build/src/akuma/providers/opencode-sdk/native-http.js +69 -0
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +42 -36
- package/build/src/akuma/providers/opencode-sdk/session.js +75 -82
- package/build/src/akuma/providers/paseo/events.d.ts +8 -0
- package/build/src/akuma/providers/paseo/events.js +58 -11
- package/build/src/akuma/providers/paseo/index.js +11 -7
- package/build/src/akuma/providers/pi/events.d.ts +2 -0
- package/build/src/akuma/providers/pi/events.js +32 -24
- package/build/src/akuma/providers/pi/index.js +21 -35
- package/build/src/akuma/request-lifecycle.d.ts +1 -2
- package/build/src/akuma/request-lifecycle.js +2 -8
- package/build/src/akuma/request-rendezvous.js +38 -55
- package/build/src/akuma/request-serve.d.ts +1 -1
- package/build/src/akuma/request-serve.js +77 -113
- package/build/src/akuma/selection-observation.d.ts +57 -51
- package/build/src/akuma/selection-observation.js +3 -3
- package/build/src/akuma/turn-drive.d.ts +3 -0
- package/build/src/akuma/turn-drive.js +26 -5
- package/build/src/akuma-body.js +12 -22
- package/build/src/cli/akuma-caller.js +10 -0
- package/build/src/cli/commands/akuma-grammar.js +3 -4
- package/build/src/cli/commands/akuma.js +13 -51
- package/build/src/cli/commands/contract-grammar.d.ts +7 -6
- package/build/src/cli/commands/contract-grammar.js +27 -32
- package/build/src/cli/commands/contract-help.d.ts +16 -7
- package/build/src/cli/commands/contract-help.js +20 -11
- package/build/src/cli/commands/contract.js +11 -11
- package/build/src/cli/commands/debt-grammar.d.ts +19 -0
- package/build/src/cli/commands/debt-grammar.js +323 -0
- package/build/src/cli/commands/debt-query.d.ts +5 -0
- package/build/src/cli/commands/{task-query.js → debt-query.js} +9 -9
- package/build/src/cli/commands/{task.d.ts → debt.d.ts} +2 -2
- package/build/src/cli/commands/{task.js → debt.js} +83 -143
- package/build/src/cli/coordinates.d.ts +1 -1
- package/build/src/cli/coordinates.js +1 -1
- package/build/src/cli/parse.d.ts +4 -4
- package/build/src/cli/parse.js +17 -16
- package/build/src/cli/render/akuma-activity.d.ts +11 -83
- package/build/src/cli/render/akuma-activity.js +20 -382
- package/build/src/cli/render/catalog.d.ts +2 -2
- package/build/src/cli/render/catalog.js +5 -5
- package/build/src/cli/render/contract.js +2 -2
- package/build/src/cli/render/debt.d.ts +28 -0
- package/build/src/cli/render/{task.js → debt.js} +51 -112
- package/build/src/cli/render/kanshi.js +28 -28
- package/build/src/cli/render/marks.d.ts +5 -5
- package/build/src/cli/render/marks.js +4 -10
- package/build/src/cli/render/nuke.js +1 -1
- package/build/src/cli/runtime.js +3 -3
- package/build/src/cli/scan.d.ts +1 -1
- package/build/src/cli/usage.d.ts +1 -1
- package/build/src/cli/usage.js +4 -4
- package/build/src/contract-worktree.js +3 -3
- package/build/src/debt/board.d.ts +160 -0
- package/build/src/{task → debt}/board.js +89 -89
- package/build/src/debt/catalog.d.ts +11 -0
- package/build/src/debt/catalog.js +59 -0
- package/build/src/{task → debt}/context.d.ts +1 -1
- package/build/src/{task → debt}/context.js +1 -1
- package/build/src/{task → debt}/created-observation.d.ts +6 -10
- package/build/src/{task → debt}/created-observation.js +7 -7
- package/build/src/debt/document.d.ts +37 -0
- package/build/src/{task → debt}/document.js +37 -37
- package/build/src/debt/identity.d.ts +21 -0
- package/build/src/{task → debt}/identity.js +35 -35
- package/build/src/debt/index.d.ts +111 -0
- package/build/src/debt/index.js +203 -0
- package/build/src/{task → debt}/input.d.ts +8 -8
- package/build/src/{task → debt}/input.js +21 -21
- package/build/src/debt/lifecycle-operations.d.ts +6 -0
- package/build/src/{task → debt}/lifecycle-operations.js +27 -31
- package/build/src/debt/mutation-result.d.ts +981 -0
- package/build/src/debt/mutation-result.js +109 -0
- package/build/src/debt/mutation.d.ts +424 -0
- package/build/src/debt/mutation.js +223 -0
- package/build/src/debt/operation-types.d.ts +71 -0
- package/build/src/debt/operations.d.ts +28 -0
- package/build/src/{task → debt}/operations.js +59 -60
- package/build/src/debt/query.d.ts +76 -0
- package/build/src/{task → debt}/query.js +55 -55
- package/build/src/{task → debt}/store.d.ts +13 -13
- package/build/src/{task → debt}/store.js +58 -49
- package/build/src/debt/view.d.ts +4 -0
- package/build/src/debt/view.js +7 -0
- package/build/src/identity/coordinates.d.ts +1 -1
- package/build/src/index.d.ts +13 -13
- package/build/src/index.js +9 -9
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.js +33 -33
- package/build/src/kanshi/report.d.ts +7 -7
- package/build/src/kanshi/select.js +4 -4
- package/build/src/library/akumas.d.ts +2 -3
- package/build/src/library/bind.d.ts +3 -3
- package/build/src/library/bind.js +5 -5
- package/build/src/library/contract-creation.js +5 -5
- package/build/src/library/contract-execution.js +4 -4
- package/build/src/library/contract-types.d.ts +2 -2
- package/build/src/library/input.d.ts +2 -2
- package/build/src/library/input.js +5 -5
- package/build/src/library/invocation.js +2 -2
- package/build/src/library/nuke.js +3 -3
- package/build/src/library/outcome.d.ts +126 -126
- package/build/src/library/outcome.js +3 -3
- package/build/src/library/selection.d.ts +1 -4
- package/build/src/library/selection.js +11 -62
- package/build/src/plugin/public.d.ts +5 -0
- package/build/src/plugin/runtime.js +3 -1
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settlement/fence.d.ts +3 -3
- package/build/src/settlement/fence.js +4 -4
- package/build/src/settlement/holder.d.ts +16 -16
- package/build/src/settlement/holder.js +69 -63
- package/build/src/settlement/settle.d.ts +5 -5
- package/build/src/settlement/settle.js +53 -53
- package/package.json +12 -6
- package/plugins/paseo/plugin/index.server.ts +17 -0
- package/plugins/paseo/plugin/paseo-plugin.json +4 -0
- package/plugins/paseo/plugin/server/attach.ts +52 -0
- package/plugins/paseo/plugin/server/keiyaku.ts +44 -0
- package/plugins/paseo/plugin/server/message.ts +60 -0
- package/plugins/paseo/plugin/server/mirror.ts +193 -0
- package/plugins/paseo/plugin/server/model.ts +14 -0
- package/plugins/paseo/plugin/server/provider.ts +276 -0
- package/plugins/paseo/plugin/server/sdk-worker.ts +237 -0
- package/plugins/paseo/plugin/server/sdk.ts +289 -0
- package/plugins/paseo/plugin/server/stop.ts +26 -0
- package/plugins/paseo/plugin/server/transport.ts +35 -0
- package/plugins/paseo/plugin/shared/attach-rpc.ts +10 -0
- package/plugins/paseo/plugin/shared/refresh-rpc.ts +6 -0
- package/plugins/paseo/plugin/tsconfig.json +6 -0
- package/skills/keiyaku/SKILL.md +5 -6
- package/skills/keiyaku-akuma/SKILL.md +1 -1
- package/skills/keiyaku-akuma/references/automation.md +8 -8
- package/skills/keiyaku-babysit/SKILL.md +1 -1
- package/skills/keiyaku-bind/SKILL.md +9 -9
- package/skills/keiyaku-debt/SKILL.md +91 -0
- package/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/claude/skills/keiyaku-task/SKILL.md +0 -104
- package/build/plugins/codex/skills/keiyaku-task/SKILL.md +0 -104
- package/build/plugins/opencode/skills/keiyaku-task/SKILL.md +0 -104
- package/build/skills/keiyaku-task/SKILL.md +0 -104
- package/build/src/cli/commands/task-grammar.d.ts +0 -19
- package/build/src/cli/commands/task-grammar.js +0 -384
- package/build/src/cli/commands/task-query.d.ts +0 -5
- package/build/src/cli/render/task.d.ts +0 -39
- package/build/src/task/board.d.ts +0 -168
- package/build/src/task/catalog.d.ts +0 -11
- package/build/src/task/catalog.js +0 -59
- package/build/src/task/compose-language.d.ts +0 -57
- package/build/src/task/compose-language.js +0 -364
- package/build/src/task/compose-parser.d.ts +0 -32
- package/build/src/task/compose-parser.js +0 -180
- package/build/src/task/compose.d.ts +0 -16
- package/build/src/task/compose.js +0 -189
- package/build/src/task/document.d.ts +0 -39
- package/build/src/task/identity.d.ts +0 -21
- package/build/src/task/index.d.ts +0 -138
- package/build/src/task/index.js +0 -269
- package/build/src/task/lifecycle-operations.d.ts +0 -6
- package/build/src/task/mutation-result.d.ts +0 -1726
- package/build/src/task/mutation-result.js +0 -198
- package/build/src/task/mutation.d.ts +0 -590
- package/build/src/task/mutation.js +0 -262
- package/build/src/task/operation-types.d.ts +0 -71
- package/build/src/task/operations.d.ts +0 -28
- package/build/src/task/query.d.ts +0 -76
- package/build/src/task/view.d.ts +0 -4
- package/build/src/task/view.js +0 -7
- package/skills/keiyaku-task/SKILL.md +0 -104
- /package/build/src/{task → debt}/operation-types.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { abortable } from "../../abort.js";
|
|
2
2
|
import { akumaExecutionEnvironment } from "../execution-environment.js";
|
|
3
|
-
import { AgentEventChannel, createProviderAttempt, } from "../../provider.js";
|
|
4
|
-
import { piTerminalFailure, translatePiEvent } from "./events.js";
|
|
3
|
+
import { AgentEventChannel, createProviderAttempt, launchPrompt, modelEvent, tellRegistry, } from "../../provider.js";
|
|
4
|
+
import { piSessionModel, piTerminalFailure, translatePiEvent } from "./events.js";
|
|
5
5
|
const PI_THINKING_LEVELS = new Set(["minimal", "low", "medium", "high", "xhigh", "max"]);
|
|
6
6
|
const MODEL_PATTERN = /^[^/\s]+\/[^\s]+$/u;
|
|
7
7
|
function diagnostic(error) {
|
|
@@ -83,15 +83,7 @@ async function createPiSession(sdk, execution, input) {
|
|
|
83
83
|
}
|
|
84
84
|
async function runPiPrompt(native, input, events, state, settle) {
|
|
85
85
|
try {
|
|
86
|
-
|
|
87
|
-
.filter((part) => part.length > 0)
|
|
88
|
-
.join("\n\n");
|
|
89
|
-
const schemaPrompt = input.schemaJson === undefined
|
|
90
|
-
? prompt
|
|
91
|
-
: [prompt, "Respond with JSON matching this JSON Schema and no other text:", input.schemaJson]
|
|
92
|
-
.filter((part) => part.length > 0)
|
|
93
|
-
.join("\n\n");
|
|
94
|
-
await native.prompt(schemaPrompt);
|
|
86
|
+
await native.prompt(launchPrompt(input.body, input.launchTells, input.schemaJson));
|
|
95
87
|
let result;
|
|
96
88
|
if (state.aborting)
|
|
97
89
|
result = { kind: "failed", diagnostic: "Pi session aborted" };
|
|
@@ -162,17 +154,15 @@ async function drivePi(sdk, execution, input, signal, custody) {
|
|
|
162
154
|
aborting: false,
|
|
163
155
|
settled: false,
|
|
164
156
|
};
|
|
165
|
-
const
|
|
166
|
-
const endPendingTells = () => {
|
|
167
|
-
for (const waiter of pendingTells.values())
|
|
168
|
-
waiter.resolve({ kind: "turn-ended" });
|
|
169
|
-
pendingTells.clear();
|
|
170
|
-
};
|
|
157
|
+
const tells = tellRegistry((id) => `${native.sessionId}:${id}`);
|
|
171
158
|
let settleCompletion;
|
|
172
159
|
const completion = new Promise((resolve) => {
|
|
173
160
|
settleCompletion = resolve;
|
|
174
161
|
});
|
|
175
162
|
const agent = native.agent;
|
|
163
|
+
// Tells are harness input, not interactive typing: deliver every queued one at
|
|
164
|
+
// the next boundary regardless of the user's interactive Pi setting.
|
|
165
|
+
agent.steeringMode = "all";
|
|
176
166
|
let unsubscribeAgent;
|
|
177
167
|
let unsubscribe;
|
|
178
168
|
let binding;
|
|
@@ -180,7 +170,7 @@ async function drivePi(sdk, execution, input, signal, custody) {
|
|
|
180
170
|
if (state.settled)
|
|
181
171
|
return closed;
|
|
182
172
|
state.settled = true;
|
|
183
|
-
|
|
173
|
+
tells.end();
|
|
184
174
|
let failure;
|
|
185
175
|
try {
|
|
186
176
|
unsubscribe?.();
|
|
@@ -219,13 +209,8 @@ async function drivePi(sdk, execution, input, signal, custody) {
|
|
|
219
209
|
custody?.own({ closed, abort: forceDispose, forceDispose });
|
|
220
210
|
try {
|
|
221
211
|
unsubscribeAgent = agent.subscribe((event) => {
|
|
222
|
-
if (event.type === "message_end")
|
|
223
|
-
|
|
224
|
-
if (waiter !== undefined) {
|
|
225
|
-
pendingTells.delete(event.message);
|
|
226
|
-
waiter.resolve({ kind: "accepted", fence: `${native.sessionId}:${waiter.id}` });
|
|
227
|
-
}
|
|
228
|
-
}
|
|
212
|
+
if (event.type === "message_end")
|
|
213
|
+
tells.accept(event.message);
|
|
229
214
|
});
|
|
230
215
|
unsubscribe = native.subscribe((event) => {
|
|
231
216
|
if (event.type === "agent_end" && !event.willRetry) {
|
|
@@ -251,6 +236,9 @@ async function drivePi(sdk, execution, input, signal, custody) {
|
|
|
251
236
|
await abortable(binding, signal);
|
|
252
237
|
signal.throwIfAborted();
|
|
253
238
|
events.emit({ type: "session", coordinate: { sessionFile: native.sessionFile, sessionId: native.sessionId } });
|
|
239
|
+
const sessionModel = piSessionModel(native.model);
|
|
240
|
+
if (sessionModel !== undefined)
|
|
241
|
+
events.emit(modelEvent(sessionModel));
|
|
254
242
|
void runPiPrompt(native, input, eventState, state, (result) => {
|
|
255
243
|
void settle(result).catch(() => undefined);
|
|
256
244
|
});
|
|
@@ -266,16 +254,14 @@ async function drivePi(sdk, execution, input, signal, custody) {
|
|
|
266
254
|
content: [{ type: "text", text: tell.text }],
|
|
267
255
|
timestamp: new Date().getTime(),
|
|
268
256
|
};
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
});
|
|
257
|
+
const submission = tells.register(message, tell.id);
|
|
258
|
+
try {
|
|
259
|
+
agent.steer(message);
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
tells.fail(message, error);
|
|
263
|
+
}
|
|
264
|
+
return submission;
|
|
279
265
|
},
|
|
280
266
|
abort: () => {
|
|
281
267
|
state.abortRequest ??= (async () => {
|
|
@@ -14,7 +14,7 @@ type ServeClaim = (input: PumpInput & Readonly<{
|
|
|
14
14
|
claim: RequestEnvelope;
|
|
15
15
|
signal: AbortSignal;
|
|
16
16
|
admissionOpen(): boolean;
|
|
17
|
-
}>) => Promise<
|
|
17
|
+
}>) => Promise<void>;
|
|
18
18
|
export declare class BodyRequestPump {
|
|
19
19
|
private readonly input;
|
|
20
20
|
private readonly serveClaim;
|
|
@@ -23,7 +23,6 @@ export declare class BodyRequestPump {
|
|
|
23
23
|
readonly failure: Promise<never>;
|
|
24
24
|
private readonly closeSignal;
|
|
25
25
|
private readonly executionSignal;
|
|
26
|
-
private readonly handled;
|
|
27
26
|
private readonly running;
|
|
28
27
|
private readonly cancelBody;
|
|
29
28
|
private admissionClosed;
|
|
@@ -14,7 +14,6 @@ export class BodyRequestPump {
|
|
|
14
14
|
failure;
|
|
15
15
|
closeSignal = new AbortController();
|
|
16
16
|
executionSignal = new AbortController();
|
|
17
|
-
handled = new Set();
|
|
18
17
|
running;
|
|
19
18
|
cancelBody;
|
|
20
19
|
admissionClosed = false;
|
|
@@ -54,8 +53,6 @@ export class BodyRequestPump {
|
|
|
54
53
|
if (this.closeSignal.signal.aborted)
|
|
55
54
|
return;
|
|
56
55
|
const transportId = name.slice(0, -".request.json".length);
|
|
57
|
-
if (this.handled.has(transportId))
|
|
58
|
-
continue;
|
|
59
56
|
const path = join(this.directory, name);
|
|
60
57
|
let serialized;
|
|
61
58
|
try {
|
|
@@ -69,11 +66,10 @@ export class BodyRequestPump {
|
|
|
69
66
|
const claim = decodeEnvelope(serialized, transportId);
|
|
70
67
|
if (claim === null) {
|
|
71
68
|
await rm(path, { force: true });
|
|
72
|
-
this.handled.add(transportId);
|
|
73
69
|
continue;
|
|
74
70
|
}
|
|
75
71
|
if (!this.admissionClosed) {
|
|
76
|
-
|
|
72
|
+
await this.serveClaim({
|
|
77
73
|
directory: this.directory,
|
|
78
74
|
transportId,
|
|
79
75
|
claim,
|
|
@@ -81,10 +77,8 @@ export class BodyRequestPump {
|
|
|
81
77
|
signal: this.executionSignal.signal,
|
|
82
78
|
admissionOpen: () => !this.admissionClosed,
|
|
83
79
|
});
|
|
84
|
-
if (!served)
|
|
85
|
-
await rm(path, { force: true });
|
|
86
80
|
}
|
|
87
|
-
|
|
81
|
+
await rm(path, { force: true });
|
|
88
82
|
}
|
|
89
83
|
try {
|
|
90
84
|
await abortableDelay(POLL_MS, this.closeSignal.signal);
|
|
@@ -19,15 +19,6 @@ export class AkumaBodyRequestError extends Error {
|
|
|
19
19
|
this.name = "AkumaBodyRequestError";
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
function throwVoidedRequestFailure(action, evidence, failure, decodeFailure, requestId) {
|
|
23
|
-
const ownerFailure = decodeOwnerFailure(failure, decodeFailure);
|
|
24
|
-
if (ownerFailure !== null)
|
|
25
|
-
throw withRequestMetadata(ownerFailure, requestId, action);
|
|
26
|
-
throw new AkumaBodyRequestError(action, "voided", evidence, requestId);
|
|
27
|
-
}
|
|
28
|
-
function throwUnprovenRequestFailure(action, evidence, requestId, ownerFailure) {
|
|
29
|
-
throw new AkumaBodyRequestError(action, "unproven", evidence, requestId, ownerFailure === null ? undefined : { cause: ownerFailure });
|
|
30
|
-
}
|
|
31
22
|
function decodeOwnerFailure(failure, decodeFailure) {
|
|
32
23
|
if (failure === undefined || decodeFailure === undefined)
|
|
33
24
|
return null;
|
|
@@ -46,59 +37,49 @@ function withRequestMetadata(response, id, action) {
|
|
|
46
37
|
return response;
|
|
47
38
|
}
|
|
48
39
|
async function readRequestReceipt(input, path, id) {
|
|
40
|
+
let bytes;
|
|
49
41
|
try {
|
|
50
|
-
|
|
51
|
-
if (receipt === null)
|
|
52
|
-
throw new Error(`Akuma body request ${id} has an invalid receipt`);
|
|
53
|
-
if (receipt.state === "refused") {
|
|
54
|
-
throw new AkumaBodyRequestError(receipt.action, "refused", receipt.diagnostic, receipt.id);
|
|
55
|
-
}
|
|
56
|
-
if (receipt.state === "voided" && receipt.outcome !== undefined) {
|
|
57
|
-
let result;
|
|
58
|
-
try {
|
|
59
|
-
result = input.command.decodeResult(receipt.outcome);
|
|
60
|
-
}
|
|
61
|
-
catch (error) {
|
|
62
|
-
throw new Error(`transport integrity: invalid voided live result: ${error instanceof Error ? error.message : String(error)}`);
|
|
63
|
-
}
|
|
64
|
-
return withRequestMetadata({ kind: "returned", result }, id, input.command.action);
|
|
65
|
-
}
|
|
66
|
-
if (receipt.state === "voided") {
|
|
67
|
-
throwVoidedRequestFailure(receipt.action, receipt.evidence, receipt.failure, input.command.decodeFailure, receipt.id);
|
|
68
|
-
}
|
|
69
|
-
if (receipt.state === "unproven") {
|
|
70
|
-
throwUnprovenRequestFailure(receipt.action, receipt.evidence, receipt.id, decodeOwnerFailure(receipt.failure, input.command.decodeFailure));
|
|
71
|
-
}
|
|
72
|
-
if ("reference" in receipt) {
|
|
73
|
-
let reference;
|
|
74
|
-
try {
|
|
75
|
-
reference = input.command.decodeReference(receipt.reference);
|
|
76
|
-
}
|
|
77
|
-
catch (error) {
|
|
78
|
-
const diagnostic = error instanceof Error ? error.message : String(error);
|
|
79
|
-
throw new Error(`transport integrity: request ${id} action ${input.command.action} returned an invalid durable reference: ${diagnostic}`);
|
|
80
|
-
}
|
|
81
|
-
return withRequestMetadata({ kind: "reference", reference }, id, input.command.action);
|
|
82
|
-
}
|
|
83
|
-
if (receipt.outcome.kind === "failed") {
|
|
84
|
-
const failure = receipt.outcome.failure;
|
|
85
|
-
throw new Error(failure.kind === "failed" ? failure.diagnostic : `Akuma ${failure.id} was not born`);
|
|
86
|
-
}
|
|
87
|
-
let result;
|
|
88
|
-
try {
|
|
89
|
-
result = input.command.decodeResult(receipt.outcome.result);
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
const diagnostic = error instanceof Error ? error.message : String(error);
|
|
93
|
-
throw new Error(`transport integrity: request ${id} action ${input.command.action} returned an invalid live result: ${diagnostic}`);
|
|
94
|
-
}
|
|
95
|
-
return withRequestMetadata({ kind: "returned", result }, id, input.command.action);
|
|
42
|
+
bytes = await readFile(path, "utf8");
|
|
96
43
|
}
|
|
97
44
|
catch (error) {
|
|
98
45
|
if (error.code === "ENOENT")
|
|
99
46
|
return undefined;
|
|
100
47
|
throw error;
|
|
101
48
|
}
|
|
49
|
+
return decodeRequestReceipt(input.command, bytes, id);
|
|
50
|
+
}
|
|
51
|
+
function decodeRequestReceipt(command, bytes, id) {
|
|
52
|
+
const receipt = decodeReceiptEnvelope(bytes, id, command.action);
|
|
53
|
+
if (receipt === null)
|
|
54
|
+
throw new Error(`Akuma body request ${id} has an invalid receipt`);
|
|
55
|
+
if (receipt.state === "refused") {
|
|
56
|
+
throw new AkumaBodyRequestError(receipt.action, "refused", receipt.diagnostic, receipt.id);
|
|
57
|
+
}
|
|
58
|
+
if (receipt.state === "unproven" || (receipt.state === "voided" && receipt.outcome === undefined)) {
|
|
59
|
+
const failure = decodeOwnerFailure(receipt.failure, command.decodeFailure);
|
|
60
|
+
if (receipt.state === "voided" && failure !== null)
|
|
61
|
+
throw withRequestMetadata(failure, id, command.action);
|
|
62
|
+
throw new AkumaBodyRequestError(command.action, receipt.state, receipt.evidence, id, failure === null ? undefined : { cause: failure });
|
|
63
|
+
}
|
|
64
|
+
if (receipt.state === "served" && "outcome" in receipt && receipt.outcome.kind === "failed") {
|
|
65
|
+
const failure = receipt.outcome.failure;
|
|
66
|
+
throw new Error(failure.kind === "failed" ? failure.diagnostic : `Akuma ${failure.id} was not born`);
|
|
67
|
+
}
|
|
68
|
+
const label = "reference" in receipt ? "durable reference" : receipt.state === "voided" ? "voided live result" : "live result";
|
|
69
|
+
try {
|
|
70
|
+
if ("reference" in receipt) {
|
|
71
|
+
return withRequestMetadata({ kind: "reference", reference: command.decodeReference(receipt.reference) }, id, command.action);
|
|
72
|
+
}
|
|
73
|
+
const value = receipt.state === "voided"
|
|
74
|
+
? receipt.outcome
|
|
75
|
+
: receipt.outcome.kind === "returned"
|
|
76
|
+
? receipt.outcome.result
|
|
77
|
+
: undefined;
|
|
78
|
+
return withRequestMetadata({ kind: "returned", result: command.decodeResult(value) }, id, command.action);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
throw new Error(`transport integrity: request ${id} action ${command.action} returned an invalid ${label}: ${error instanceof Error ? error.message : String(error)}`);
|
|
82
|
+
}
|
|
102
83
|
}
|
|
103
84
|
/** Generic rendezvous only: operation owners supply their own request and result codecs. */
|
|
104
85
|
export async function requestBodyCommand(input) {
|
|
@@ -126,6 +107,8 @@ export async function requestBodyCommand(input) {
|
|
|
126
107
|
async function observePublishedRequest(input, id, transportId, path) {
|
|
127
108
|
let observedSequence = 0;
|
|
128
109
|
const consumeProgress = async () => {
|
|
110
|
+
if (input.onProgress === undefined && input.onProgressGap === undefined)
|
|
111
|
+
return;
|
|
129
112
|
const snapshot = await readRequestProgress({
|
|
130
113
|
directory: input.directory,
|
|
131
114
|
transportId,
|
|
@@ -10,7 +10,7 @@ export type ServeInput = Omit<PumpInput, "bodySequence"> & Readonly<{
|
|
|
10
10
|
claim: RequestEnvelope;
|
|
11
11
|
admissionOpen(): boolean;
|
|
12
12
|
}>;
|
|
13
|
-
export declare function serveRequest(input: ServeInput): Promise<
|
|
13
|
+
export declare function serveRequest(input: ServeInput): Promise<void>;
|
|
14
14
|
export declare class BodyRequestPump extends LifecycleBodyRequestPump {
|
|
15
15
|
static open(input: PumpInput): Promise<BodyRequestPump>;
|
|
16
16
|
}
|
|
@@ -21,33 +21,22 @@ function replayReference(fact, command) {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
async function projectCommandReceipt(input, fact, command, outcome, failure) {
|
|
24
|
+
const identity = { id: fact.id, action: fact.action };
|
|
24
25
|
const receipt = fact.state === "refused"
|
|
25
|
-
? {
|
|
26
|
-
: fact.state === "voided"
|
|
26
|
+
? { ...identity, state: fact.state, diagnostic: fact.diagnostic }
|
|
27
|
+
: fact.state === "voided" || fact.state === "unproven"
|
|
27
28
|
? {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
state: "voided",
|
|
29
|
+
...identity,
|
|
30
|
+
state: fact.state,
|
|
31
31
|
evidence: fact.evidence,
|
|
32
32
|
...(failure === undefined ? {} : { failure }),
|
|
33
|
-
...(
|
|
33
|
+
...(fact.state === "voided" && outcome !== undefined ? { outcome: outcome.result } : {}),
|
|
34
34
|
}
|
|
35
|
-
:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
evidence: fact.evidence,
|
|
41
|
-
...(failure === undefined ? {} : { failure }),
|
|
42
|
-
}
|
|
43
|
-
: outcome === undefined
|
|
44
|
-
? {
|
|
45
|
-
id: fact.id,
|
|
46
|
-
action: fact.action,
|
|
47
|
-
state: "served",
|
|
48
|
-
reference: replayReference(fact, command),
|
|
49
|
-
}
|
|
50
|
-
: { id: fact.id, action: fact.action, state: "served", outcome };
|
|
35
|
+
: {
|
|
36
|
+
...identity,
|
|
37
|
+
state: "served",
|
|
38
|
+
...(outcome === undefined ? { reference: replayReference(fact, command) } : { outcome }),
|
|
39
|
+
};
|
|
51
40
|
try {
|
|
52
41
|
await atomicJson(receiptPath(input.directory, input.transportId), receipt);
|
|
53
42
|
}
|
|
@@ -64,51 +53,39 @@ async function serveResolvedCommand(input, command, request, execute) {
|
|
|
64
53
|
admittedAt: input.now(),
|
|
65
54
|
permitted: request.isPermitted(input.allowed),
|
|
66
55
|
});
|
|
67
|
-
if (fact.state
|
|
68
|
-
await projectCommandReceipt(input, fact, command);
|
|
69
|
-
return true;
|
|
70
|
-
}
|
|
71
|
-
if (!input.admissionOpen()) {
|
|
56
|
+
if (fact.state === "admitted" && !input.admissionOpen()) {
|
|
72
57
|
fact = await voidRequest(input.paths, fact.id, "body closed request admission");
|
|
58
|
+
}
|
|
59
|
+
if (fact.state !== "admitted") {
|
|
73
60
|
await projectCommandReceipt(input, fact, command);
|
|
74
|
-
return
|
|
61
|
+
return;
|
|
75
62
|
}
|
|
63
|
+
const observation = {
|
|
64
|
+
directory: input.directory,
|
|
65
|
+
transportId: input.transportId,
|
|
66
|
+
id: fact.id,
|
|
67
|
+
action: fact.action,
|
|
68
|
+
};
|
|
69
|
+
const progress = publishRequestProgress(observation);
|
|
70
|
+
const cancellation = command.completion === "service" && request.supportsCancellation
|
|
71
|
+
? observeRequestCancellation(observation)
|
|
72
|
+
: undefined;
|
|
73
|
+
let outcome;
|
|
74
|
+
let failure;
|
|
76
75
|
try {
|
|
77
|
-
const
|
|
78
|
-
directory: input.directory,
|
|
79
|
-
transportId: input.transportId,
|
|
80
|
-
id: fact.id,
|
|
81
|
-
action: fact.action,
|
|
82
|
-
});
|
|
83
|
-
const cancellation = command.completion === "service" && request.supportsCancellation
|
|
84
|
-
? observeRequestCancellation({
|
|
85
|
-
directory: input.directory,
|
|
86
|
-
transportId: input.transportId,
|
|
87
|
-
id: fact.id,
|
|
88
|
-
action: fact.action,
|
|
89
|
-
})
|
|
90
|
-
: undefined;
|
|
91
|
-
const facts = {
|
|
76
|
+
const served = await execute(fact, {
|
|
92
77
|
id: fact.id,
|
|
93
78
|
admittedAt: fact.admittedAt,
|
|
94
79
|
requester: fact.requester,
|
|
95
80
|
signal: cancellation === undefined ? input.signal : AbortSignal.any([input.signal, cancellation.signal]),
|
|
96
81
|
admissionOpen: input.admissionOpen,
|
|
97
82
|
progress: progress.progress,
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
fact = served.fact;
|
|
102
|
-
await progress.flush();
|
|
103
|
-
await projectCommandReceipt(input, fact, command, served.outcome);
|
|
104
|
-
}
|
|
105
|
-
finally {
|
|
106
|
-
await progress.close();
|
|
107
|
-
await cancellation?.close();
|
|
108
|
-
}
|
|
83
|
+
});
|
|
84
|
+
fact = served.fact;
|
|
85
|
+
outcome = served.outcome;
|
|
109
86
|
}
|
|
110
87
|
catch (error) {
|
|
111
|
-
|
|
88
|
+
failure = encodedFailure(request, error);
|
|
112
89
|
const current = await readRequest(input.paths, fact.id);
|
|
113
90
|
if (current === null)
|
|
114
91
|
throw error;
|
|
@@ -117,7 +94,7 @@ async function serveResolvedCommand(input, command, request, execute) {
|
|
|
117
94
|
if (parent === null)
|
|
118
95
|
throw new Error("reserved request settlement requires a born parent Soul");
|
|
119
96
|
if (!(await settleReserved(input.paths, parent, current, input.now, input.signal)))
|
|
120
|
-
return
|
|
97
|
+
return;
|
|
121
98
|
fact = (await readRequest(input.paths, fact.id)) ?? current;
|
|
122
99
|
}
|
|
123
100
|
else {
|
|
@@ -130,49 +107,45 @@ async function serveResolvedCommand(input, command, request, execute) {
|
|
|
130
107
|
: await unproveRequest(input.paths, fact.id, diagnostic(error))
|
|
131
108
|
: current;
|
|
132
109
|
}
|
|
133
|
-
await projectCommandReceipt(input, fact, command, undefined, failure);
|
|
134
110
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
outcome: { kind: "returned", result: served.result },
|
|
146
|
-
};
|
|
147
|
-
});
|
|
111
|
+
finally {
|
|
112
|
+
try {
|
|
113
|
+
await progress.close();
|
|
114
|
+
}
|
|
115
|
+
finally {
|
|
116
|
+
await cancellation?.close();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Transport failure cannot re-enter execution settlement.
|
|
120
|
+
await projectCommandReceipt(input, fact, command, outcome, failure);
|
|
148
121
|
}
|
|
149
|
-
async function
|
|
150
|
-
const request = command.
|
|
122
|
+
async function serveCommand(input, command) {
|
|
123
|
+
const { completion, request } = command.completion === "child"
|
|
124
|
+
? { completion: "child", request: command.resolve(input.claim.payload) }
|
|
125
|
+
: { completion: "service", request: command.resolve(input.claim.payload) };
|
|
151
126
|
if (request === null)
|
|
152
127
|
throw new Error(`registered request action ${input.claim.action} rejected its payload`);
|
|
153
128
|
return await serveResolvedCommand(input, command, request, async (fact, facts) => {
|
|
129
|
+
if (completion === "child") {
|
|
130
|
+
const served = await request.execute(facts);
|
|
131
|
+
return {
|
|
132
|
+
fact: await serveChildRequest(input.paths, fact.id, served.child),
|
|
133
|
+
outcome: { kind: "returned", result: served.result },
|
|
134
|
+
};
|
|
135
|
+
}
|
|
154
136
|
await beginRequest(input.paths, fact.id);
|
|
155
137
|
const served = await request.execute(facts);
|
|
156
|
-
|
|
157
|
-
|
|
138
|
+
return served.kind === "voided"
|
|
139
|
+
? {
|
|
158
140
|
fact: await voidRequest(input.paths, fact.id, "returned owner outcome was voided"),
|
|
159
141
|
outcome: { kind: "returned", result: served.outcome },
|
|
142
|
+
}
|
|
143
|
+
: {
|
|
144
|
+
fact: await serveUpstreamRequest(input.paths, fact.id, served.serviceJson),
|
|
145
|
+
outcome: { kind: "returned", result: served.result },
|
|
160
146
|
};
|
|
161
|
-
}
|
|
162
|
-
return {
|
|
163
|
-
fact: await serveUpstreamRequest(input.paths, fact.id, served.serviceJson),
|
|
164
|
-
outcome: { kind: "returned", result: served.result },
|
|
165
|
-
};
|
|
166
147
|
});
|
|
167
148
|
}
|
|
168
|
-
async function serveCommand(input, command) {
|
|
169
|
-
switch (command.completion) {
|
|
170
|
-
case "child":
|
|
171
|
-
return await serveChildCommand(input, command);
|
|
172
|
-
case "service":
|
|
173
|
-
return await serveServiceCommand(input, command);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
149
|
function diagnostic(error) {
|
|
177
150
|
return error instanceof Error ? error.message : String(error);
|
|
178
151
|
}
|
|
@@ -190,35 +163,26 @@ function provesNoProductEffect(failure) {
|
|
|
190
163
|
}
|
|
191
164
|
export async function serveRequest(input) {
|
|
192
165
|
const command = input.commands[input.claim.action];
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
async function serveTransportClaim(input) {
|
|
205
|
-
try {
|
|
206
|
-
return await serveRequest(input);
|
|
207
|
-
}
|
|
208
|
-
catch (error) {
|
|
209
|
-
if (!isRequestInputConflict(error))
|
|
210
|
-
throw error;
|
|
211
|
-
await atomicJson(receiptPath(input.directory, input.transportId), {
|
|
212
|
-
id: input.claim.id,
|
|
213
|
-
action: input.claim.action,
|
|
214
|
-
state: "refused",
|
|
215
|
-
diagnostic: error.message,
|
|
216
|
-
});
|
|
217
|
-
return true;
|
|
166
|
+
let diagnostic = `request action ${input.claim.action} is not registered`;
|
|
167
|
+
if (command !== undefined) {
|
|
168
|
+
try {
|
|
169
|
+
return await serveCommand(input, command);
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
if (!isRequestInputConflict(error))
|
|
173
|
+
throw error;
|
|
174
|
+
diagnostic = error.message;
|
|
175
|
+
}
|
|
218
176
|
}
|
|
177
|
+
await atomicJson(receiptPath(input.directory, input.transportId), {
|
|
178
|
+
id: input.claim.id,
|
|
179
|
+
action: input.claim.action,
|
|
180
|
+
state: "refused",
|
|
181
|
+
diagnostic,
|
|
182
|
+
});
|
|
219
183
|
}
|
|
220
184
|
export class BodyRequestPump extends LifecycleBodyRequestPump {
|
|
221
185
|
static async open(input) {
|
|
222
|
-
return (await LifecycleBodyRequestPump.openWithService(input, async (claim) => await
|
|
186
|
+
return (await LifecycleBodyRequestPump.openWithService(input, async (claim) => await serveRequest({ ...claim, commands: input.commands })));
|
|
223
187
|
}
|
|
224
188
|
}
|