@astrosheep/keiyaku 4.1.0 → 4.1.2
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 +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +3 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -6
- package/build/src/akuma/akuma-errors.d.ts +6 -0
- package/build/src/akuma/akuma-errors.js +9 -0
- package/build/src/akuma/akuma-handle.d.ts +39 -0
- package/build/src/akuma/akuma-handle.js +263 -0
- package/build/src/akuma/akuma-observe.d.ts +19 -0
- package/build/src/akuma/akuma-observe.js +74 -0
- package/build/src/akuma/akuma-product-symbols.d.ts +1 -0
- package/build/src/akuma/akuma-product-symbols.js +1 -0
- package/build/src/akuma/akuma-product.d.ts +18 -0
- package/build/src/akuma/akuma-product.js +154 -0
- package/build/src/akuma/akuma.d.ts +37 -81
- package/build/src/akuma/akuma.js +39 -447
- package/build/src/akuma/allowed.d.ts +1 -0
- package/build/src/akuma/allowed.js +6 -0
- package/build/src/akuma/archetype.js +8 -5
- package/build/src/akuma/body-supervisor.d.ts +26 -0
- package/build/src/akuma/body-supervisor.js +89 -0
- package/build/src/akuma/body.d.ts +45 -4
- package/build/src/akuma/body.js +145 -35
- package/build/src/akuma/coordinate.js +17 -7
- package/build/src/akuma/heart/facts.js +1 -1
- package/build/src/akuma/heart/index.d.ts +1 -1
- package/build/src/akuma/heart/index.js +2 -4
- package/build/src/akuma/heart/request-authority.js +4 -4
- package/build/src/akuma/heart/request-rows.js +27 -16
- package/build/src/akuma/heart/rows.js +79 -41
- package/build/src/akuma/heart/soul.js +1 -1
- package/build/src/akuma/heart/storage.d.ts +1 -0
- package/build/src/akuma/heart/storage.js +76 -11
- package/build/src/akuma/heart/tells.js +35 -18
- package/build/src/akuma/heart/timeline.js +19 -11
- package/build/src/akuma/identity.d.ts +1 -0
- package/build/src/akuma/identity.js +1 -0
- package/build/src/akuma/index.d.ts +3 -3
- package/build/src/akuma/index.js +1 -1
- package/build/src/akuma/nuke.js +106 -14
- package/build/src/akuma/projection-read.d.ts +17 -0
- package/build/src/akuma/projection-read.js +135 -0
- package/build/src/akuma/projection.d.ts +1 -16
- package/build/src/akuma/projection.js +77 -154
- package/build/src/akuma/provider-recipe.js +11 -5
- package/build/src/akuma/provider.js +105 -62
- package/build/src/akuma/providers/acp/config.js +5 -6
- package/build/src/akuma/providers/acp/core.js +17 -10
- package/build/src/akuma/providers/acp/events.js +38 -29
- package/build/src/akuma/providers/acp/index.js +13 -9
- package/build/src/akuma/providers/claude/events.js +8 -12
- package/build/src/akuma/providers/claude/index.d.ts +1 -0
- package/build/src/akuma/providers/claude/index.js +55 -26
- package/build/src/akuma/providers/claude/input.js +6 -2
- package/build/src/akuma/providers/codex-app-server/events.js +61 -36
- package/build/src/akuma/providers/codex-app-server/index.js +25 -13
- package/build/src/akuma/providers/grok-build/index.js +22 -25
- package/build/src/akuma/providers/index.js +2 -18
- package/build/src/akuma/providers/opencode-sdk/events.js +32 -18
- package/build/src/akuma/providers/opencode-sdk/index.js +26 -17
- package/build/src/akuma/providers/opencode-sdk/session.js +21 -5
- package/build/src/akuma/providers/pi/events.js +26 -19
- package/build/src/akuma/providers/pi/index.js +58 -40
- package/build/src/akuma/publication.js +9 -9
- package/build/src/akuma/request-execution.d.ts +6 -0
- package/build/src/akuma/request-execution.js +86 -0
- package/build/src/akuma/request-serve.d.ts +12 -1
- package/build/src/akuma/request-serve.js +19 -122
- package/build/src/akuma/request-wire.d.ts +2 -2
- package/build/src/akuma/request-wire.js +75 -102
- package/build/src/akuma/requests.js +2 -2
- package/build/src/akuma/{body-turn.d.ts → turn-drive.d.ts} +2 -25
- package/build/src/akuma/{body-turn.js → turn-drive.js} +20 -103
- package/build/src/akuma-body.js +6 -5
- package/build/src/body/amend.d.ts +4 -1
- package/build/src/body/amend.js +14 -6
- package/build/src/body/decode.js +2 -4
- package/build/src/body/envelope.js +2 -4
- package/build/src/body/region.d.ts +1 -2
- package/build/src/body/region.js +2 -70
- package/build/src/body/render.js +17 -12
- package/build/src/body/shape.js +1 -7
- package/build/src/cli/accepted.d.ts +1 -1
- package/build/src/cli/accepted.js +8 -1
- package/build/src/cli/commands/akuma-invoke.js +18 -6
- package/build/src/cli/commands/akuma.d.ts +0 -6
- package/build/src/cli/commands/akuma.js +11 -24
- package/build/src/cli/commands/amend.d.ts +2 -2
- package/build/src/cli/commands/amend.js +2 -4
- package/build/src/cli/commands/bind.d.ts +4 -4
- package/build/src/cli/commands/bind.js +16 -6
- package/build/src/cli/commands/contract-invoke.d.ts +25 -0
- package/build/src/cli/commands/contract-invoke.js +193 -0
- package/build/src/cli/commands/contract.d.ts +109 -10
- package/build/src/cli/commands/contract.js +339 -16
- package/build/src/cli/commands/install.d.ts +1 -1
- package/build/src/cli/commands/install.js +23 -15
- package/build/src/cli/commands/task-invoke.js +187 -67
- package/build/src/cli/commands/task-query.js +48 -24
- package/build/src/cli/commands/task.js +150 -38
- package/build/src/cli/coordinates.js +2 -4
- package/build/src/cli/invoke.js +92 -208
- package/build/src/cli/main.js +4 -2
- package/build/src/cli/parse.d.ts +3 -90
- package/build/src/cli/parse.js +27 -233
- package/build/src/cli/render/akuma-activity.d.ts +38 -0
- package/build/src/cli/render/akuma-activity.js +362 -0
- package/build/src/cli/render/akuma-tool-command.js +6 -7
- package/build/src/cli/render/akuma-tool.js +10 -8
- package/build/src/cli/render/akuma.d.ts +1 -1
- package/build/src/cli/render/akuma.js +61 -353
- package/build/src/cli/render/audit.js +5 -15
- package/build/src/cli/render/board.d.ts +1 -0
- package/build/src/cli/render/board.js +17 -0
- package/build/src/cli/render/catalog.js +81 -8
- package/build/src/cli/render/contract-history.d.ts +2 -0
- package/build/src/cli/render/contract-history.js +83 -0
- package/build/src/cli/render/contract-observation.d.ts +10 -0
- package/build/src/cli/render/contract-observation.js +58 -0
- package/build/src/cli/render/contract.d.ts +1 -2
- package/build/src/cli/render/contract.js +41 -142
- package/build/src/cli/render/kanshi.js +239 -215
- package/build/src/cli/render/receipt.js +2 -9
- package/build/src/cli/render/refusal.js +10 -15
- package/build/src/cli/render/region.js +22 -6
- package/build/src/cli/render/settings.js +4 -4
- package/build/src/cli/render/task.js +34 -14
- package/build/src/cli/render/terminal.js +16 -5
- package/build/src/cli/result.d.ts +3 -3
- package/build/src/cli/runtime.d.ts +6 -1
- package/build/src/cli/runtime.js +84 -63
- package/build/src/cli/selectors.js +2 -4
- package/build/src/cli/usage.js +6 -5
- package/build/src/contract-worktree.d.ts +1 -23
- package/build/src/contract-worktree.js +79 -155
- package/build/src/coordination/durable-file.js +7 -3
- package/build/src/coordination/sqlite-transaction-lock.js +29 -12
- package/build/src/core/facts/codec.js +7 -3
- package/build/src/core/facts/types.d.ts +1 -1
- package/build/src/core/subject.js +16 -9
- package/build/src/core/verbs/abandon.d.ts +1 -1
- package/build/src/core/verbs/abandon.js +1 -1
- package/build/src/core/verbs/amend.d.ts +1 -1
- package/build/src/core/verbs/amend.js +7 -7
- package/build/src/core/verbs/attestation.js +4 -1
- package/build/src/core/verbs/bind.d.ts +1 -1
- package/build/src/core/verbs/bind.js +1 -1
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +10 -8
- package/build/src/dispatch/index.js +8 -6
- package/build/src/duration.js +5 -1
- package/build/src/git/admission.js +5 -3
- package/build/src/git/hooks.d.ts +8 -0
- package/build/src/git/hooks.js +63 -14
- package/build/src/git/identity.js +1 -4
- package/build/src/git/integration.d.ts +2 -3
- package/build/src/git/integration.js +32 -39
- package/build/src/git/nuke.d.ts +1 -1
- package/build/src/git/nuke.js +110 -57
- package/build/src/git/observe.d.ts +13 -1
- package/build/src/git/observe.js +51 -44
- package/build/src/git/process.js +4 -2
- package/build/src/git/read-observation.js +10 -8
- package/build/src/git/reconcile.d.ts +22 -2
- package/build/src/git/reconcile.js +38 -274
- package/build/src/git/repository.d.ts +2 -0
- package/build/src/git/repository.js +13 -22
- package/build/src/git/scratch.d.ts +8 -5
- package/build/src/git/scratch.js +29 -2
- package/build/src/git/target-placement.d.ts +9 -10
- package/build/src/git/target-placement.js +59 -62
- package/build/src/git/tender.js +13 -46
- package/build/src/git/terminal-reconcile.d.ts +21 -0
- package/build/src/git/terminal-reconcile.js +278 -0
- package/build/src/git/terminal-seal.js +15 -12
- package/build/src/git/tree.js +5 -2
- package/build/src/git/workspace.d.ts +24 -2
- package/build/src/git/workspace.js +120 -16
- package/build/src/identity/coordinates.js +3 -1
- package/build/src/identity/selector.js +6 -3
- package/build/src/kanshi/fleet.d.ts +6 -0
- package/build/src/kanshi/fleet.js +27 -0
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.js +60 -48
- package/build/src/kanshi/report.d.ts +11 -23
- package/build/src/kanshi/select.js +25 -24
- package/build/src/library/address.d.ts +2 -1
- package/build/src/library/address.js +7 -8
- package/build/src/library/akuma-creation.js +20 -12
- package/build/src/library/audit.d.ts +0 -1
- package/build/src/library/audit.js +1 -2
- package/build/src/library/bind.d.ts +53 -5
- package/build/src/library/bind.js +98 -22
- package/build/src/library/catalog.d.ts +1 -0
- package/build/src/library/catalog.js +6 -3
- package/build/src/library/configuration.js +3 -1
- package/build/src/library/continuation.d.ts +15 -4
- package/build/src/library/continuation.js +24 -16
- package/build/src/library/contract-bind.d.ts +26 -0
- package/build/src/library/contract-bind.js +106 -0
- package/build/src/library/contract-operations.d.ts +77 -0
- package/build/src/library/contract-operations.js +130 -0
- package/build/src/library/contract-types.d.ts +95 -0
- package/build/src/library/contract-types.js +1 -0
- package/build/src/library/contract.d.ts +19 -154
- package/build/src/library/contract.js +46 -261
- package/build/src/library/fleet.d.ts +1 -1
- package/build/src/library/fleet.js +19 -11
- package/build/src/library/input.d.ts +2 -0
- package/build/src/library/input.js +14 -0
- package/build/src/library/keiyaku.d.ts +8 -7
- package/build/src/library/keiyaku.js +3 -3
- package/build/src/library/nuke.js +14 -5
- package/build/src/library/reconcile.d.ts +9 -4
- package/build/src/library/reconcile.js +30 -24
- package/build/src/library/refusal.d.ts +13 -5
- package/build/src/library/refusal.js +7 -0
- package/build/src/library/region.d.ts +8 -7
- package/build/src/library/region.js +31 -11
- package/build/src/library/repo.js +2 -2
- package/build/src/markdown/lex.js +9 -2
- package/build/src/markdown/parse.js +11 -7
- package/build/src/markdown/query.js +4 -2
- package/build/src/protocol/amend.js +3 -1
- package/build/src/protocol/attempt.d.ts +7 -3
- package/build/src/protocol/attempt.js +9 -5
- package/build/src/protocol/audit.d.ts +1 -1
- package/build/src/protocol/audit.js +4 -14
- package/build/src/protocol/bind.d.ts +19 -6
- package/build/src/protocol/bind.js +28 -13
- package/build/src/protocol/completion.d.ts +0 -1
- package/build/src/protocol/completion.js +1 -3
- package/build/src/protocol/deliver.d.ts +1 -3
- package/build/src/protocol/deliver.js +15 -39
- package/build/src/protocol/intent.d.ts +1 -0
- package/build/src/protocol/intent.js +9 -7
- package/build/src/protocol/operations.d.ts +3 -7
- package/build/src/protocol/operations.js +5 -3
- package/build/src/protocol/placement.d.ts +0 -1
- package/build/src/protocol/placement.js +6 -6
- package/build/src/protocol/read/observation.d.ts +11 -0
- package/build/src/protocol/read/observation.js +37 -0
- package/build/src/protocol/read/status.d.ts +23 -12
- package/build/src/protocol/read/status.js +90 -72
- package/build/src/protocol/reconcile.d.ts +1 -0
- package/build/src/protocol/reconcile.js +2 -3
- package/build/src/protocol/reintegrate.js +1 -1
- package/build/src/protocol/review.d.ts +0 -1
- package/build/src/protocol/review.js +15 -22
- package/build/src/protocol/run.d.ts +1 -0
- package/build/src/protocol/run.js +4 -5
- package/build/src/runtime/proc/launch.d.ts +33 -0
- package/build/src/runtime/proc/launch.js +98 -0
- package/build/src/runtime/proc/line-rpc.js +9 -3
- package/build/src/runtime/proc/run.d.ts +12 -6
- package/build/src/runtime/proc/run.js +78 -21
- package/build/src/runtime/proc/stdio.js +7 -10
- package/build/src/settings.js +6 -2
- package/build/src/settlement/holder.js +13 -10
- package/build/src/settlement/settle.js +39 -6
- package/build/src/task/board.js +12 -6
- package/build/src/task/compose.js +85 -22
- package/build/src/task/context.js +21 -8
- package/build/src/task/document.js +46 -10
- package/build/src/task/identity.js +5 -2
- package/build/src/task/index.d.ts +0 -1
- package/build/src/task/index.js +119 -34
- package/build/src/task/input.js +29 -7
- package/build/src/task/mutation.js +61 -19
- package/build/src/task/operations.d.ts +6 -1
- package/build/src/task/operations.js +83 -29
- package/build/src/task/query.js +55 -26
- package/build/src/task/store.d.ts +3 -1
- package/build/src/task/store.js +81 -17
- package/build/src/verification/execution.js +14 -11
- package/build/src/workspace-place.js +19 -7
- package/build/src/world.js +16 -6
- package/package.json +8 -3
|
@@ -5,7 +5,8 @@ import { createEventState, mapEvent } from "./events.js";
|
|
|
5
5
|
import { coordinate, loadOpencode, OPENCODE_SDK_PROVIDER, parseModel } from "./session.js";
|
|
6
6
|
function object(value) {
|
|
7
7
|
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
8
|
-
? value
|
|
8
|
+
? value
|
|
9
|
+
: undefined;
|
|
9
10
|
}
|
|
10
11
|
function text(value) {
|
|
11
12
|
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
|
|
@@ -135,10 +136,7 @@ function nativeProgress(type, properties, busy) {
|
|
|
135
136
|
function startsTurn(value, sessionId, messageID) {
|
|
136
137
|
const event = object(value);
|
|
137
138
|
const info = object(object(event?.properties)?.info);
|
|
138
|
-
return event?.type === "message.updated"
|
|
139
|
-
&& info?.sessionID === sessionId
|
|
140
|
-
&& info.role === "user"
|
|
141
|
-
&& info.id === messageID;
|
|
139
|
+
return (event?.type === "message.updated" && info?.sessionID === sessionId && info.role === "user" && info.id === messageID);
|
|
142
140
|
}
|
|
143
141
|
async function observeTurn(input) {
|
|
144
142
|
let active = false;
|
|
@@ -206,9 +204,7 @@ async function forceDisposeOpencode(abortController, close, finish) {
|
|
|
206
204
|
async function drive(execution, input, loader) {
|
|
207
205
|
admit(input.options);
|
|
208
206
|
const signal = input.signal ?? new AbortController().signal;
|
|
209
|
-
const resumeSessionId = input.session.kind === "resume"
|
|
210
|
-
? opencodeSessionId(input.session.coordinate)
|
|
211
|
-
: undefined;
|
|
207
|
+
const resumeSessionId = input.session.kind === "resume" ? opencodeSessionId(input.session.coordinate) : undefined;
|
|
212
208
|
const abortController = new AbortController();
|
|
213
209
|
const abortSetup = () => abortController.abort(signal.reason);
|
|
214
210
|
signal.addEventListener("abort", abortSetup, { once: true });
|
|
@@ -240,11 +236,20 @@ async function drive(execution, input, loader) {
|
|
|
240
236
|
const messageID = `msg_${randomUUID().replaceAll("-", "")}`;
|
|
241
237
|
const submissionState = { started: false };
|
|
242
238
|
events.emit({ type: "session", coordinate: coordinate(sessionId) });
|
|
243
|
-
const streamResult = await abortable(runtime.client.event.subscribe({ query: { directory: input.cwd } }), abortController.signal, async (late) => {
|
|
239
|
+
const streamResult = await abortable(runtime.client.event.subscribe({ query: { directory: input.cwd } }), abortController.signal, async (late) => {
|
|
240
|
+
await late.stream[Symbol.asyncIterator]().return?.(undefined);
|
|
241
|
+
});
|
|
244
242
|
iterator = streamResult.stream[Symbol.asyncIterator]();
|
|
245
243
|
const { completion, finish } = terminalSettlement(events, closeOnce);
|
|
246
244
|
const observation = observeTurn({
|
|
247
|
-
iterator,
|
|
245
|
+
iterator,
|
|
246
|
+
session,
|
|
247
|
+
sessionId,
|
|
248
|
+
cwd: input.cwd,
|
|
249
|
+
messageID,
|
|
250
|
+
events,
|
|
251
|
+
state,
|
|
252
|
+
submissionState,
|
|
248
253
|
});
|
|
249
254
|
submissionState.started = true;
|
|
250
255
|
await abortable(session.promptAsync({
|
|
@@ -261,7 +266,9 @@ async function drive(execution, input, loader) {
|
|
|
261
266
|
completion,
|
|
262
267
|
abort: async () => {
|
|
263
268
|
abortController.abort();
|
|
264
|
-
void session
|
|
269
|
+
void session
|
|
270
|
+
.abort({ path: { id: sessionId }, query: { directory: input.cwd }, throwOnError: true })
|
|
271
|
+
.catch(() => undefined);
|
|
265
272
|
await finish({ kind: "failed", diagnostic: "OpenCode session interrupted" });
|
|
266
273
|
},
|
|
267
274
|
forceDispose: () => forceDisposeOpencode(abortController, closeOnce, finish),
|
|
@@ -288,12 +295,14 @@ export function createOpencodeProvider(input = { name: OPENCODE_SDK_PROVIDER, ki
|
|
|
288
295
|
return {
|
|
289
296
|
kind: "admitted",
|
|
290
297
|
options: Object.freeze({ ...options }),
|
|
291
|
-
...(options.readonly === undefined
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
298
|
+
...(options.readonly === undefined
|
|
299
|
+
? {}
|
|
300
|
+
: {
|
|
301
|
+
readonly: {
|
|
302
|
+
enforcement: "none",
|
|
303
|
+
diagnostic: "OpenCode V1 cannot remove task-surface mutation capabilities",
|
|
304
|
+
},
|
|
305
|
+
}),
|
|
297
306
|
};
|
|
298
307
|
},
|
|
299
308
|
start: (input) => drive(execution, input, loader),
|
|
@@ -33,20 +33,29 @@ async function availablePort() {
|
|
|
33
33
|
reject(new Error("OpenCode port unavailable"));
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
|
-
server.close((error) => error === undefined ? resolve(address.port) : reject(error));
|
|
36
|
+
server.close((error) => (error === undefined ? resolve(address.port) : reject(error)));
|
|
37
37
|
});
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
export async function loadOpencode(execution, cwd, signal, loader) {
|
|
41
41
|
if (loader) {
|
|
42
42
|
const loaded = await loader(cwd, execution);
|
|
43
|
-
return {
|
|
43
|
+
return {
|
|
44
|
+
client: loaded.client,
|
|
45
|
+
close: async () => {
|
|
46
|
+
await loaded.close?.();
|
|
47
|
+
},
|
|
48
|
+
};
|
|
44
49
|
}
|
|
45
50
|
const port = await availablePort();
|
|
46
51
|
const owned = await spawnDetachedProcess({
|
|
47
52
|
argv: [execution.executable ?? "opencode", "serve", "--hostname", "127.0.0.1", "--port", String(port)],
|
|
48
53
|
cwd,
|
|
49
|
-
env: {
|
|
54
|
+
env: {
|
|
55
|
+
...process.env,
|
|
56
|
+
...(execution.config === undefined ? {} : { OPENCODE_CONFIG_CONTENT: JSON.stringify(execution.config) }),
|
|
57
|
+
...execution.env,
|
|
58
|
+
},
|
|
50
59
|
log: `${cwd}/.opencode.log`,
|
|
51
60
|
});
|
|
52
61
|
const { createOpencodeClient } = await import("@opencode-ai/sdk");
|
|
@@ -58,6 +67,13 @@ export async function loadOpencode(execution, cwd, signal, loader) {
|
|
|
58
67
|
await owned.terminate();
|
|
59
68
|
throw error;
|
|
60
69
|
}
|
|
61
|
-
return {
|
|
70
|
+
return {
|
|
71
|
+
client,
|
|
72
|
+
close: async () => {
|
|
73
|
+
await owned.terminate();
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export function coordinate(sessionId) {
|
|
78
|
+
return { sessionId };
|
|
62
79
|
}
|
|
63
|
-
export function coordinate(sessionId) { return { sessionId }; }
|
|
@@ -23,25 +23,29 @@ export const PI_EVENT_DISPOSITIONS = {
|
|
|
23
23
|
};
|
|
24
24
|
function record(value) {
|
|
25
25
|
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
26
|
-
? value
|
|
26
|
+
? value
|
|
27
|
+
: null;
|
|
27
28
|
}
|
|
28
29
|
function textContent(content) {
|
|
29
30
|
if (typeof content === "string")
|
|
30
31
|
return content;
|
|
31
32
|
if (!Array.isArray(content))
|
|
32
33
|
return "";
|
|
33
|
-
return content
|
|
34
|
+
return content
|
|
35
|
+
.map((block) => {
|
|
34
36
|
const value = record(block);
|
|
35
37
|
return value?.type === "text" && typeof value.text === "string" ? value.text : "";
|
|
36
|
-
})
|
|
38
|
+
})
|
|
39
|
+
.join("");
|
|
37
40
|
}
|
|
38
41
|
function hasTextContent(content) {
|
|
39
42
|
if (typeof content === "string")
|
|
40
43
|
return true;
|
|
41
|
-
return Array.isArray(content) &&
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
return (Array.isArray(content) &&
|
|
45
|
+
content.some((block) => {
|
|
46
|
+
const value = record(block);
|
|
47
|
+
return value?.type === "text" && typeof value.text === "string";
|
|
48
|
+
}));
|
|
45
49
|
}
|
|
46
50
|
function positiveLine(value) {
|
|
47
51
|
return typeof value === "number" && Number.isSafeInteger(value) && value >= 1 ? value : undefined;
|
|
@@ -50,9 +54,7 @@ function optionalText(value) {
|
|
|
50
54
|
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
|
|
51
55
|
}
|
|
52
56
|
function runCall(name, value) {
|
|
53
|
-
return name === "bash" && typeof value.command === "string"
|
|
54
|
-
? { kind: "run", command: value.command }
|
|
55
|
-
: undefined;
|
|
57
|
+
return name === "bash" && typeof value.command === "string" ? { kind: "run", command: value.command } : undefined;
|
|
56
58
|
}
|
|
57
59
|
function readCall(name, value) {
|
|
58
60
|
if (name !== "read" || typeof value.path !== "string")
|
|
@@ -101,11 +103,10 @@ function refineEditCall(call, result) {
|
|
|
101
103
|
}
|
|
102
104
|
function toolCall(name, args) {
|
|
103
105
|
const value = record(args) ?? {};
|
|
104
|
-
return runCall(name, value)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
?? { kind: "other", display: name };
|
|
106
|
+
return (runCall(name, value) ??
|
|
107
|
+
readCall(name, value) ??
|
|
108
|
+
searchCall(name, value) ??
|
|
109
|
+
fileChangeCall(name, value) ?? { kind: "other", display: name });
|
|
109
110
|
}
|
|
110
111
|
function translateNote(event) {
|
|
111
112
|
if (event.type === "auto_retry_start")
|
|
@@ -122,11 +123,16 @@ function translateToolEnd(event, state) {
|
|
|
122
123
|
state.tools.delete(event.toolCallId);
|
|
123
124
|
const name = started?.name ?? event.toolName;
|
|
124
125
|
const call = started?.call ?? { kind: "other", display: name };
|
|
125
|
-
return [
|
|
126
|
-
|
|
126
|
+
return [
|
|
127
|
+
{
|
|
128
|
+
type: "tool",
|
|
129
|
+
phase: "completed",
|
|
130
|
+
id: event.toolCallId,
|
|
131
|
+
name,
|
|
127
132
|
call: event.isError ? call : refineEditCall(call, event.result),
|
|
128
133
|
result: { status: event.isError ? "error" : "ok" },
|
|
129
|
-
}
|
|
134
|
+
},
|
|
135
|
+
];
|
|
130
136
|
}
|
|
131
137
|
function translateMessage(event, state) {
|
|
132
138
|
const message = record(event.message);
|
|
@@ -174,7 +180,8 @@ export function piTerminalFailure(messages) {
|
|
|
174
180
|
if (message.stopReason !== "error")
|
|
175
181
|
return null;
|
|
176
182
|
return typeof message.errorMessage === "string" && message.errorMessage.trim().length > 0
|
|
177
|
-
? message.errorMessage
|
|
183
|
+
? message.errorMessage
|
|
184
|
+
: "Pi provider ended with an error";
|
|
178
185
|
}
|
|
179
186
|
return null;
|
|
180
187
|
}
|
|
@@ -3,7 +3,9 @@ import { AKUMA_REQUESTS_ENV, AgentEventChannel, } from "../../provider.js";
|
|
|
3
3
|
import { piTerminalFailure, translatePiEvent } from "./events.js";
|
|
4
4
|
const PI_THINKING_LEVELS = new Set(["minimal", "low", "medium", "high", "xhigh", "max"]);
|
|
5
5
|
const MODEL_PATTERN = /^[^/\s]+\/[^\s]+$/u;
|
|
6
|
-
function diagnostic(error) {
|
|
6
|
+
function diagnostic(error) {
|
|
7
|
+
return error instanceof Error ? error.message : String(error);
|
|
8
|
+
}
|
|
7
9
|
function admitPiOptions(options) {
|
|
8
10
|
if (options.network !== undefined)
|
|
9
11
|
return { kind: "refused", diagnostic: "Pi provider does not support the network option" };
|
|
@@ -29,27 +31,33 @@ async function piCreateOptions(sdk, input) {
|
|
|
29
31
|
if (model === undefined)
|
|
30
32
|
throw new Error(`Pi model '${input.options.model}' is unavailable`);
|
|
31
33
|
}
|
|
32
|
-
const resourceLoader = input.options.systemPrompt === undefined
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
const resourceLoader = input.options.systemPrompt === undefined
|
|
35
|
+
? undefined
|
|
36
|
+
: new sdk.DefaultResourceLoader({
|
|
37
|
+
cwd: input.cwd,
|
|
38
|
+
agentDir: sdk.getAgentDir(),
|
|
39
|
+
...(input.options.systemPromptMode === "append"
|
|
40
|
+
? { appendSystemPromptOverride: (base) => [...base, input.options.systemPrompt] }
|
|
41
|
+
: { systemPromptOverride: () => input.options.systemPrompt }),
|
|
42
|
+
});
|
|
39
43
|
await resourceLoader?.reload();
|
|
40
44
|
const sessionManager = input.session.kind === "fresh"
|
|
41
45
|
? sdk.SessionManager.create(input.cwd)
|
|
42
46
|
: "sessionFile" in input.session.coordinate
|
|
43
47
|
? sdk.SessionManager.open(input.session.coordinate.sessionFile)
|
|
44
|
-
: (() => {
|
|
48
|
+
: (() => {
|
|
49
|
+
throw new Error("Pi resume requires sessionFile");
|
|
50
|
+
})();
|
|
45
51
|
const customTools = input.requests === undefined || input.options.readonly === true
|
|
46
52
|
? undefined
|
|
47
|
-
: [
|
|
53
|
+
: [
|
|
54
|
+
(await import("@earendil-works/pi-coding-agent")).createBashToolDefinition(input.cwd, {
|
|
48
55
|
spawnHook: (context) => ({
|
|
49
56
|
...context,
|
|
50
57
|
env: { ...context.env, [AKUMA_REQUESTS_ENV]: input.requests.dir },
|
|
51
58
|
}),
|
|
52
|
-
})
|
|
59
|
+
}),
|
|
60
|
+
];
|
|
53
61
|
return {
|
|
54
62
|
cwd: input.cwd,
|
|
55
63
|
sessionManager,
|
|
@@ -60,8 +68,13 @@ async function piCreateOptions(sdk, input) {
|
|
|
60
68
|
...(customTools === undefined ? {} : { customTools }),
|
|
61
69
|
};
|
|
62
70
|
}
|
|
63
|
-
async function createPiSession(sdk, input, signal) {
|
|
64
|
-
const setup = piCreateOptions(sdk, input).then(async (options) =>
|
|
71
|
+
async function createPiSession(sdk, execution, input, signal) {
|
|
72
|
+
const setup = piCreateOptions(sdk, input).then(async (options) => {
|
|
73
|
+
if (execution.config !== undefined) {
|
|
74
|
+
throw new TypeError("Pi provider config cannot be consumed by native CreateAgentSessionOptions");
|
|
75
|
+
}
|
|
76
|
+
return await sdk.createAgentSession(options);
|
|
77
|
+
});
|
|
65
78
|
return await abortable(setup, signal, (created) => created.session.dispose());
|
|
66
79
|
}
|
|
67
80
|
function forceDisposePi(dispose, settle, setAborting) {
|
|
@@ -70,8 +83,8 @@ function forceDisposePi(dispose, settle, setAborting) {
|
|
|
70
83
|
settle({ kind: "failed", diagnostic: "Pi session force-disposed" });
|
|
71
84
|
return Promise.resolve();
|
|
72
85
|
}
|
|
73
|
-
async function drivePi(sdk, input, signal) {
|
|
74
|
-
const created = await createPiSession(sdk, input, signal);
|
|
86
|
+
async function drivePi(sdk, execution, input, signal) {
|
|
87
|
+
const created = await createPiSession(sdk, execution, input, signal);
|
|
75
88
|
const native = created.session;
|
|
76
89
|
if (signal.aborted) {
|
|
77
90
|
native.dispose();
|
|
@@ -112,7 +125,9 @@ async function drivePi(sdk, input, signal) {
|
|
|
112
125
|
});
|
|
113
126
|
events.emit({ type: "session", coordinate: { sessionFile: native.sessionFile, sessionId: native.sessionId } });
|
|
114
127
|
let settleCompletion;
|
|
115
|
-
const completion = new Promise((resolve) => {
|
|
128
|
+
const completion = new Promise((resolve) => {
|
|
129
|
+
settleCompletion = resolve;
|
|
130
|
+
});
|
|
116
131
|
const settle = (result) => {
|
|
117
132
|
if (settled)
|
|
118
133
|
return;
|
|
@@ -123,24 +138,22 @@ async function drivePi(sdk, input, signal) {
|
|
|
123
138
|
void (async () => {
|
|
124
139
|
try {
|
|
125
140
|
await native.prompt([input.body, ...input.launchTells.map((tell) => tell.text)].join("\n\n"));
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
141
|
+
let result;
|
|
142
|
+
if (aborting)
|
|
143
|
+
result = { kind: "failed", diagnostic: "Pi session aborted" };
|
|
144
|
+
else if (terminalFailure !== null)
|
|
145
|
+
result = { kind: "failed", diagnostic: terminalFailure };
|
|
146
|
+
else if (!state.assistantSeen)
|
|
147
|
+
result = { kind: "failed", diagnostic: "Pi completed without a native assistant answer" };
|
|
148
|
+
else {
|
|
149
|
+
const historyId = native.sessionManager.getLeafId();
|
|
150
|
+
result = {
|
|
151
|
+
kind: "answered",
|
|
152
|
+
answer: state.answer,
|
|
153
|
+
...(historyId === null ? {} : { historyId }),
|
|
154
|
+
};
|
|
133
155
|
}
|
|
134
|
-
|
|
135
|
-
settle({ kind: "failed", diagnostic: "Pi completed without a native assistant answer" });
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
const historyId = native.sessionManager.getLeafId();
|
|
139
|
-
settle({
|
|
140
|
-
kind: "answered",
|
|
141
|
-
answer: state.answer,
|
|
142
|
-
...(historyId === null ? {} : { historyId }),
|
|
143
|
-
});
|
|
156
|
+
settle(result);
|
|
144
157
|
}
|
|
145
158
|
catch (error) {
|
|
146
159
|
settle(aborting
|
|
@@ -149,7 +162,9 @@ async function drivePi(sdk, input, signal) {
|
|
|
149
162
|
}
|
|
150
163
|
})();
|
|
151
164
|
return {
|
|
152
|
-
admission: { fence: native.sessionId },
|
|
165
|
+
admission: { fence: native.sessionId },
|
|
166
|
+
events,
|
|
167
|
+
completion,
|
|
153
168
|
abort: () => {
|
|
154
169
|
abortRequest ??= (async () => {
|
|
155
170
|
if (settled)
|
|
@@ -158,12 +173,16 @@ async function drivePi(sdk, input, signal) {
|
|
|
158
173
|
try {
|
|
159
174
|
await native.abort();
|
|
160
175
|
}
|
|
161
|
-
catch {
|
|
176
|
+
catch {
|
|
177
|
+
/* prompt settlement still proves local cleanup */
|
|
178
|
+
}
|
|
162
179
|
settle({ kind: "failed", diagnostic: "Pi session aborted" });
|
|
163
180
|
})();
|
|
164
181
|
return abortRequest;
|
|
165
182
|
},
|
|
166
|
-
forceDispose: () => forceDisposePi(dispose, settle, () => {
|
|
183
|
+
forceDispose: () => forceDisposePi(dispose, settle, () => {
|
|
184
|
+
aborting = true;
|
|
185
|
+
}),
|
|
167
186
|
};
|
|
168
187
|
}
|
|
169
188
|
function piSessionFile(coordinate) {
|
|
@@ -190,16 +209,15 @@ async function loadPiSdk() {
|
|
|
190
209
|
};
|
|
191
210
|
}
|
|
192
211
|
export function createPiProvider(execution = { name: "pi", kind: "pi" }, load = loadPiSdk) {
|
|
193
|
-
if (execution.executable !== undefined
|
|
194
|
-
throw new TypeError("Pi provider does not support executable
|
|
195
|
-
}
|
|
212
|
+
if (execution.executable !== undefined)
|
|
213
|
+
throw new TypeError("Pi provider does not support executable");
|
|
196
214
|
if (execution.env !== undefined && Object.keys(execution.env).length > 0) {
|
|
197
215
|
throw new TypeError("env injection not supported for provider pi");
|
|
198
216
|
}
|
|
199
217
|
const drive = async (input) => {
|
|
200
218
|
const signal = input.signal ?? new AbortController().signal;
|
|
201
219
|
signal.throwIfAborted();
|
|
202
|
-
return drivePi(await abortable(load(), signal), input, signal);
|
|
220
|
+
return drivePi(await abortable(load(), signal), execution, input, signal);
|
|
203
221
|
};
|
|
204
222
|
return {
|
|
205
223
|
admitOptions: admitPiOptions,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { HeldAkumaLeash, initializeHeart, readHeart, readSeal, readSoul
|
|
2
|
-
import { allocateAkumaDirectory
|
|
1
|
+
import { HeldAkumaLeash, initializeHeart, readHeart, readSeal, readSoul } from "./heart/index.js";
|
|
2
|
+
import { allocateAkumaDirectory } from "./identity.js";
|
|
3
3
|
import { abortableDelay } from "./abort.js";
|
|
4
|
-
const POLL_MS =
|
|
4
|
+
const POLL_MS = 100;
|
|
5
5
|
export const BIRTH_TIMEOUT_MS = 30_000;
|
|
6
6
|
function diagnostic(error) {
|
|
7
7
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -22,9 +22,7 @@ async function settleTimedOutBirth(paths) {
|
|
|
22
22
|
}
|
|
23
23
|
if (result === "sealed") {
|
|
24
24
|
const seal = await readSeal(paths);
|
|
25
|
-
throw new Error(seal?.evidence === "call-timeout" || seal === null
|
|
26
|
-
? "Akuma body failed before birth"
|
|
27
|
-
: seal.evidence);
|
|
25
|
+
throw new Error(seal?.evidence === "call-timeout" || seal === null ? "Akuma body failed before birth" : seal.evidence);
|
|
28
26
|
}
|
|
29
27
|
const soul = await readSoul(paths);
|
|
30
28
|
if (soul === null)
|
|
@@ -57,7 +55,7 @@ async function awaitBirth(paths, signal) {
|
|
|
57
55
|
if (settled !== null)
|
|
58
56
|
return settled;
|
|
59
57
|
}
|
|
60
|
-
await abortableDelay(POLL_MS, signal);
|
|
58
|
+
await abortableDelay(Math.min(POLL_MS, Math.max(0, deadline - performance.now())), signal);
|
|
61
59
|
}
|
|
62
60
|
}
|
|
63
61
|
async function takeLeashUntil(paths, deadline) {
|
|
@@ -67,7 +65,7 @@ async function takeLeashUntil(paths, deadline) {
|
|
|
67
65
|
return leash;
|
|
68
66
|
if (performance.now() >= deadline)
|
|
69
67
|
return null;
|
|
70
|
-
await abortableDelay(POLL_MS);
|
|
68
|
+
await abortableDelay(Math.min(POLL_MS, Math.max(0, deadline - performance.now())));
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
async function awaitAsleepBirth(paths) {
|
|
@@ -98,7 +96,9 @@ async function sealLocalFailure(allocated, error) {
|
|
|
98
96
|
leash.release();
|
|
99
97
|
}
|
|
100
98
|
}
|
|
101
|
-
catch {
|
|
99
|
+
catch {
|
|
100
|
+
/* the original local publication failure remains authoritative */
|
|
101
|
+
}
|
|
102
102
|
}
|
|
103
103
|
export async function publishAkuma(input) {
|
|
104
104
|
input.signal?.throwIfAborted();
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { UpstreamRequestService } from "./heart/index.js";
|
|
2
|
+
import type { ServeInput, UpstreamFact } from "./request-serve.js";
|
|
3
|
+
export declare function executeRequest(input: ServeInput, request: UpstreamFact): Promise<Readonly<{
|
|
4
|
+
result: unknown;
|
|
5
|
+
service?: UpstreamRequestService;
|
|
6
|
+
}>>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export async function executeRequest(input, request) {
|
|
2
|
+
if (input.upstream === undefined)
|
|
3
|
+
throw new Error("upstream execution port is unavailable");
|
|
4
|
+
if (request.action === "akuma.wait")
|
|
5
|
+
return {
|
|
6
|
+
result: await input.upstream.wait({
|
|
7
|
+
targets: request.targets,
|
|
8
|
+
completion: request.completion,
|
|
9
|
+
...(request.timeoutMs === undefined ? {} : { timeoutMs: request.timeoutMs }),
|
|
10
|
+
signal: input.signal,
|
|
11
|
+
}),
|
|
12
|
+
service: { action: request.action },
|
|
13
|
+
};
|
|
14
|
+
if (request.action === "akuma.tell")
|
|
15
|
+
return {
|
|
16
|
+
result: await input.upstream.tell({
|
|
17
|
+
target: request.target,
|
|
18
|
+
body: request.body,
|
|
19
|
+
tellId: request.id,
|
|
20
|
+
recordedAt: request.admittedAt,
|
|
21
|
+
signal: input.signal,
|
|
22
|
+
}),
|
|
23
|
+
service: { action: request.action, target: request.target, tellId: request.id },
|
|
24
|
+
};
|
|
25
|
+
if (request.action === "akuma.kill") {
|
|
26
|
+
const served = await input.upstream.kill({ targets: request.targets, signal: input.signal });
|
|
27
|
+
return { result: served.result, service: { action: request.action, results: served.service } };
|
|
28
|
+
}
|
|
29
|
+
if (request.action === "contract.deliver") {
|
|
30
|
+
const served = await input.upstream.deliver({
|
|
31
|
+
repoRoot: request.repoRoot,
|
|
32
|
+
contractId: request.contractId,
|
|
33
|
+
...(request.message === undefined ? {} : { message: request.message }),
|
|
34
|
+
includeDirty: request.includeDirty,
|
|
35
|
+
materializeConflict: request.materializeConflict,
|
|
36
|
+
requester: request.requester,
|
|
37
|
+
signal: input.signal,
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
result: served.result,
|
|
41
|
+
...(served.deliveryFactId === undefined
|
|
42
|
+
? {}
|
|
43
|
+
: {
|
|
44
|
+
service: {
|
|
45
|
+
action: request.action,
|
|
46
|
+
repoRoot: request.repoRoot,
|
|
47
|
+
contractId: request.contractId,
|
|
48
|
+
deliveryFactId: served.deliveryFactId,
|
|
49
|
+
},
|
|
50
|
+
}),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (request.action === "contract.review") {
|
|
54
|
+
const served = await input.upstream.review({
|
|
55
|
+
repoRoot: request.repoRoot,
|
|
56
|
+
contractId: request.contractId,
|
|
57
|
+
verdict: request.verdict,
|
|
58
|
+
...(request.summary === undefined ? {} : { summary: request.summary }),
|
|
59
|
+
requester: request.requester,
|
|
60
|
+
signal: input.signal,
|
|
61
|
+
});
|
|
62
|
+
return {
|
|
63
|
+
result: served.result,
|
|
64
|
+
...(served.reviewFactId === undefined
|
|
65
|
+
? {}
|
|
66
|
+
: {
|
|
67
|
+
service: {
|
|
68
|
+
action: request.action,
|
|
69
|
+
repoRoot: request.repoRoot,
|
|
70
|
+
contractId: request.contractId,
|
|
71
|
+
reviewFactId: served.reviewFactId,
|
|
72
|
+
},
|
|
73
|
+
}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const task = request;
|
|
77
|
+
return {
|
|
78
|
+
result: await input.upstream.task({
|
|
79
|
+
world: task.world,
|
|
80
|
+
request: task.request,
|
|
81
|
+
requester: task.requester,
|
|
82
|
+
signal: input.signal,
|
|
83
|
+
}),
|
|
84
|
+
service: { action: task.action },
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type KillEvidence, type Soul } from "./heart/index.js";
|
|
1
|
+
import { type KillEvidence, type RequestFact, type Soul } from "./heart/index.js";
|
|
2
2
|
import { type AkuId, type AkumaPaths } from "./identity.js";
|
|
3
|
+
import { type StructuralRequestClaim } from "./request-wire.js";
|
|
3
4
|
import { type TaskMutationRequest } from "../task/mutation.js";
|
|
4
5
|
export type RequestChildLaunch = Readonly<{
|
|
5
6
|
paths: AkumaPaths;
|
|
@@ -67,6 +68,16 @@ type PumpInput = Readonly<{
|
|
|
67
68
|
upstream?: UpstreamExecutionPort;
|
|
68
69
|
signal: AbortSignal;
|
|
69
70
|
}>;
|
|
71
|
+
export type ServeInput = Omit<PumpInput, "bodySequence"> & Readonly<{
|
|
72
|
+
directory: string;
|
|
73
|
+
claim: StructuralRequestClaim;
|
|
74
|
+
admissionOpen(): boolean;
|
|
75
|
+
}>;
|
|
76
|
+
export type UpstreamFact = Exclude<Extract<RequestFact, {
|
|
77
|
+
state: "admitted";
|
|
78
|
+
}>, Extract<RequestFact, {
|
|
79
|
+
action: "akuma.call";
|
|
80
|
+
}>>;
|
|
70
81
|
export declare class BodyRequestPump {
|
|
71
82
|
private readonly input;
|
|
72
83
|
readonly directory: string;
|