@astrosheep/keiyaku 4.0.3 → 4.0.5
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/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +4 -4
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +15 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +3 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +34 -13
- package/build/src/akuma/akuma.d.ts +34 -12
- package/build/src/akuma/akuma.js +118 -63
- package/build/src/akuma/allowed.d.ts +7 -0
- package/build/src/akuma/allowed.js +33 -0
- package/build/src/akuma/archetype.d.ts +7 -4
- package/build/src/akuma/archetype.js +15 -16
- package/build/src/akuma/body.d.ts +6 -1
- package/build/src/akuma/body.js +36 -27
- package/build/src/akuma/heart/facts.d.ts +82 -14
- package/build/src/akuma/heart/index.d.ts +5 -18
- package/build/src/akuma/heart/index.js +14 -84
- package/build/src/akuma/heart/request-authority.d.ts +12 -0
- package/build/src/akuma/heart/request-authority.js +119 -0
- package/build/src/akuma/heart/request-rows.d.ts +16 -0
- package/build/src/akuma/heart/request-rows.js +88 -0
- package/build/src/akuma/heart/rows.d.ts +1 -26
- package/build/src/akuma/heart/rows.js +0 -50
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +22 -10
- package/build/src/akuma/heart/soul.js +2 -36
- package/build/src/akuma/heart/storage.d.ts +1 -0
- package/build/src/akuma/heart/storage.js +15 -0
- package/build/src/akuma/heart/timeline.d.ts +1 -5
- package/build/src/akuma/heart/timeline.js +8 -17
- package/build/src/akuma/index.d.ts +5 -2
- package/build/src/akuma/index.js +1 -0
- package/build/src/akuma/projection.d.ts +17 -3
- package/build/src/akuma/projection.js +40 -3
- package/build/src/akuma/provider-recipe.js +1 -11
- package/build/src/akuma/provider.d.ts +2 -7
- package/build/src/akuma/provider.js +2 -1
- package/build/src/akuma/providers/acp/core.d.ts +3 -1
- package/build/src/akuma/providers/acp/core.js +10 -6
- package/build/src/akuma/providers/acp/events.d.ts +11 -3
- package/build/src/akuma/providers/acp/events.js +78 -4
- package/build/src/akuma/providers/acp/index.js +0 -1
- package/build/src/akuma/providers/claude/events.js +62 -3
- package/build/src/akuma/providers/claude/index.d.ts +0 -4
- package/build/src/akuma/providers/claude/index.js +7 -3
- package/build/src/akuma/providers/codex-app-server/events.js +1 -13
- package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
- package/build/src/akuma/providers/codex-app-server/index.js +0 -2
- package/build/src/akuma/providers/grok-build/index.d.ts +2 -1
- package/build/src/akuma/providers/grok-build/index.js +72 -3
- package/build/src/akuma/providers/opencode-sdk/events.js +71 -6
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
- package/build/src/akuma/providers/opencode-sdk/index.js +8 -4
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +1 -1
- package/build/src/akuma/providers/opencode-sdk/session.js +1 -1
- package/build/src/akuma/providers/pi/events.js +17 -3
- package/build/src/akuma/providers/pi/index.js +11 -4
- package/build/src/akuma/providers/unified-patch.d.ts +4 -0
- package/build/src/akuma/providers/unified-patch.js +14 -0
- package/build/src/akuma/publication.d.ts +1 -1
- package/build/src/akuma/publication.js +1 -1
- package/build/src/akuma/request-serve.d.ts +87 -0
- package/build/src/akuma/request-serve.js +484 -0
- package/build/src/akuma/request-wire.d.ts +124 -0
- package/build/src/akuma/request-wire.js +380 -0
- package/build/src/akuma/requests.d.ts +41 -41
- package/build/src/akuma/requests.js +75 -374
- package/build/src/akuma-body.d.ts +8 -0
- package/build/src/akuma-body.js +84 -0
- package/build/src/body/arc.js +4 -29
- package/build/src/body/decode.js +5 -39
- package/build/src/body/envelope.d.ts +7 -0
- package/build/src/body/envelope.js +37 -0
- package/build/src/cli/accepted.d.ts +4 -1
- package/build/src/cli/accepted.js +39 -9
- package/build/src/cli/commands/akuma-invoke.d.ts +8 -7
- package/build/src/cli/commands/akuma-invoke.js +18 -10
- package/build/src/cli/commands/akuma.d.ts +11 -2
- package/build/src/cli/commands/akuma.js +67 -28
- package/build/src/cli/commands/amend.d.ts +1 -1
- package/build/src/cli/commands/amend.js +1 -1
- package/build/src/cli/commands/contract.d.ts +8 -8
- package/build/src/cli/commands/contract.js +3 -3
- package/build/src/cli/commands/install.js +2 -2
- package/build/src/cli/commands/task-invoke.js +98 -9
- package/build/src/cli/commands/task-query.d.ts +1 -1
- package/build/src/cli/commands/task-query.js +11 -5
- package/build/src/cli/coordinates.d.ts +2 -0
- package/build/src/cli/coordinates.js +12 -5
- package/build/src/cli/invoke.d.ts +1 -0
- package/build/src/cli/invoke.js +116 -75
- package/build/src/cli/main.d.ts +2 -0
- package/build/src/cli/main.js +29 -4
- package/build/src/cli/parse.d.ts +3 -2
- package/build/src/cli/parse.js +25 -8
- package/build/src/cli/render/akuma.d.ts +2 -2
- package/build/src/cli/render/akuma.js +138 -24
- package/build/src/cli/render/audit.js +18 -8
- package/build/src/cli/render/contract.d.ts +2 -0
- package/build/src/cli/render/contract.js +243 -36
- package/build/src/cli/render/kanshi.js +64 -29
- package/build/src/cli/render/receipt.d.ts +2 -1
- package/build/src/cli/render/receipt.js +37 -2
- package/build/src/cli/render/terminal.d.ts +0 -2
- package/build/src/cli/render/terminal.js +0 -29
- package/build/src/cli/render/text.js +3 -1
- package/build/src/cli/result.d.ts +52 -9
- package/build/src/cli/selectors.d.ts +1 -0
- package/build/src/cli/selectors.js +9 -6
- package/build/src/contract-worktree.d.ts +1 -2
- package/build/src/contract-worktree.js +7 -9
- package/build/src/core/facts/codec.js +9 -0
- package/build/src/core/facts/fold.js +13 -1
- package/build/src/core/facts/types.d.ts +8 -1
- package/build/src/core/subject.js +4 -3
- package/build/src/core/verbs/placement.d.ts +9 -1
- package/build/src/core/verbs/placement.js +24 -6
- package/build/src/core/verbs/reintegrate.d.ts +13 -0
- package/build/src/core/verbs/reintegrate.js +24 -0
- package/build/src/dispatch/index.d.ts +1 -1
- package/build/src/dispatch/index.js +50 -39
- package/build/src/git/admission.d.ts +2 -1
- package/build/src/git/hooks.d.ts +0 -4
- package/build/src/git/hooks.js +0 -36
- package/build/src/git/integration.d.ts +7 -8
- package/build/src/git/integration.js +62 -9
- package/build/src/git/observe.d.ts +2 -1
- package/build/src/git/observe.js +6 -5
- package/build/src/git/process.d.ts +26 -0
- package/build/src/git/process.js +94 -0
- package/build/src/git/read-observation.d.ts +2 -1
- package/build/src/git/read-observation.js +3 -2
- package/build/src/git/reconcile.d.ts +8 -2
- package/build/src/git/reconcile.js +63 -14
- package/build/src/git/repository.d.ts +2 -29
- package/build/src/git/repository.js +4 -118
- package/build/src/git/scratch.d.ts +1 -1
- package/build/src/git/scratch.js +1 -1
- package/build/src/git/target-placement.d.ts +1 -1
- package/build/src/git/target-placement.js +9 -7
- package/build/src/git/tender.d.ts +20 -5
- package/build/src/git/tender.js +45 -13
- package/build/src/git/terminal-seal.d.ts +16 -2
- package/build/src/git/terminal-seal.js +15 -5
- package/build/src/git/workspace.d.ts +2 -1
- package/build/src/git/workspace.js +13 -5
- package/build/src/index.d.ts +1 -2
- package/build/src/index.js +1 -1
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +9 -1
- package/build/src/kanshi/read.js +91 -37
- package/build/src/kanshi/report.d.ts +1 -0
- package/build/src/library/address.d.ts +5 -14
- package/build/src/library/address.js +27 -23
- package/build/src/library/akuma-creation.d.ts +4 -2
- package/build/src/library/akuma-creation.js +43 -26
- package/build/src/library/audit.d.ts +2 -1
- package/build/src/library/audit.js +1 -1
- package/build/src/library/bind.d.ts +2 -1
- package/build/src/library/bind.js +4 -4
- package/build/src/library/catalog.d.ts +1 -2
- package/build/src/library/catalog.js +11 -6
- package/build/src/library/configuration.d.ts +5 -1
- package/build/src/library/configuration.js +71 -18
- package/build/src/library/contract.d.ts +70 -3
- package/build/src/library/contract.js +213 -27
- package/build/src/library/delivery.d.ts +1 -1
- package/build/src/library/fleet.d.ts +70 -12
- package/build/src/library/fleet.js +236 -56
- package/build/src/library/input.d.ts +0 -1
- package/build/src/library/input.js +1 -5
- package/build/src/library/keiyaku.d.ts +4 -4
- package/build/src/library/keiyaku.js +1 -2
- package/build/src/library/mutation.d.ts +2 -1
- package/build/src/library/reconcile.d.ts +2 -1
- package/build/src/library/reconcile.js +3 -1
- package/build/src/library/region.d.ts +1 -1
- package/build/src/library/repo.d.ts +3 -1
- package/build/src/library/repo.js +8 -4
- package/build/src/protocol/abandon.d.ts +9 -0
- package/build/src/protocol/abandon.js +15 -0
- package/build/src/protocol/amend.d.ts +16 -0
- package/build/src/protocol/amend.js +77 -0
- package/build/src/protocol/arc.d.ts +6 -0
- package/build/src/protocol/arc.js +12 -0
- package/build/src/protocol/attempt.d.ts +2 -1
- package/build/src/protocol/audit.d.ts +53 -0
- package/build/src/protocol/audit.js +140 -0
- package/build/src/protocol/bind.d.ts +2 -3
- package/build/src/protocol/bind.js +2 -16
- package/build/src/protocol/completion.d.ts +32 -0
- package/build/src/protocol/completion.js +130 -0
- package/build/src/protocol/deliver.d.ts +37 -0
- package/build/src/protocol/deliver.js +160 -0
- package/build/src/protocol/intent.d.ts +1 -1
- package/build/src/protocol/intent.js +1 -1
- package/build/src/protocol/operations.d.ts +65 -198
- package/build/src/protocol/operations.js +21 -634
- package/build/src/protocol/placement.d.ts +4 -13
- package/build/src/protocol/placement.js +3 -15
- package/build/src/protocol/read/status.d.ts +4 -2
- package/build/src/protocol/read/status.js +27 -15
- package/build/src/protocol/reconcile.d.ts +35 -0
- package/build/src/protocol/reconcile.js +41 -0
- package/build/src/protocol/reintegrate.d.ts +31 -0
- package/build/src/protocol/reintegrate.js +74 -0
- package/build/src/protocol/review.d.ts +33 -0
- package/build/src/protocol/review.js +148 -0
- package/build/src/protocol/run.d.ts +1 -1
- package/build/src/runtime/proc/run.d.ts +1 -0
- package/build/src/runtime/proc/run.js +9 -2
- package/build/src/settlement/fence.d.ts +1 -1
- package/build/src/settlement/holder.d.ts +1 -1
- package/build/src/settlement/settle.d.ts +2 -1
- package/build/src/settlement/settle.js +4 -1
- package/build/src/task/board.d.ts +18 -4
- package/build/src/task/board.js +73 -29
- package/build/src/task/compose.d.ts +1 -1
- package/build/src/task/compose.js +11 -4
- package/build/src/task/index.d.ts +4 -4
- package/build/src/task/index.js +8 -131
- package/build/src/task/input.d.ts +18 -0
- package/build/src/task/input.js +189 -0
- package/build/src/task/mutation.d.ts +39 -0
- package/build/src/task/mutation.js +85 -0
- package/build/src/task/operations.d.ts +4 -19
- package/build/src/task/operations.js +64 -18
- package/build/src/task/query.d.ts +9 -2
- package/build/src/task/query.js +32 -64
- package/build/src/task/store.js +0 -2
- package/build/src/verification/execution.d.ts +1 -1
- package/build/src/verification/execution.js +2 -1
- package/build/src/workspace-place.d.ts +1 -4
- package/build/src/workspace-place.js +0 -15
- package/package.json +5 -3
|
@@ -1,5 +1,72 @@
|
|
|
1
|
-
import { startAcpSession } from "../acp/core.js";
|
|
1
|
+
import { startAcpSession, } from "../acp/core.js";
|
|
2
2
|
const INTERJECT_METHOD = "x.ai/interject";
|
|
3
|
+
function nonblank(value) {
|
|
4
|
+
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
|
|
5
|
+
}
|
|
6
|
+
function object(value) {
|
|
7
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
8
|
+
? value
|
|
9
|
+
: undefined;
|
|
10
|
+
}
|
|
11
|
+
function nativeName(update) {
|
|
12
|
+
const wire = update;
|
|
13
|
+
return nonblank(update.name) ?? nonblank(wire.toolName);
|
|
14
|
+
}
|
|
15
|
+
function readCall(name, input) {
|
|
16
|
+
if (name !== "read_file" && name !== "hashline_read")
|
|
17
|
+
return undefined;
|
|
18
|
+
const sourcePath = nonblank(input.target_file);
|
|
19
|
+
const capturedPath = name === "read_file" ? nonblank(input.path) : undefined;
|
|
20
|
+
const path = sourcePath ?? capturedPath;
|
|
21
|
+
return path === undefined ? undefined : { kind: "read", path };
|
|
22
|
+
}
|
|
23
|
+
function contentSearchCall(name, input) {
|
|
24
|
+
if (name !== "grep" && name !== "hashline_grep")
|
|
25
|
+
return undefined;
|
|
26
|
+
const query = nonblank(input.pattern);
|
|
27
|
+
if (query === undefined)
|
|
28
|
+
return undefined;
|
|
29
|
+
const path = nonblank(input.path);
|
|
30
|
+
const glob = nonblank(input.glob);
|
|
31
|
+
return {
|
|
32
|
+
kind: "search",
|
|
33
|
+
query,
|
|
34
|
+
scope: "content",
|
|
35
|
+
...(path === undefined ? {} : { path }),
|
|
36
|
+
...(glob === undefined ? {} : { glob }),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function runCall(name, input) {
|
|
40
|
+
if (name !== "run_terminal_cmd")
|
|
41
|
+
return undefined;
|
|
42
|
+
const command = nonblank(input.command);
|
|
43
|
+
return command === undefined ? undefined : { kind: "run", command };
|
|
44
|
+
}
|
|
45
|
+
function webSearchCall(name, input) {
|
|
46
|
+
if (name !== "web_search")
|
|
47
|
+
return undefined;
|
|
48
|
+
const query = nonblank(input.query);
|
|
49
|
+
return query === undefined ? undefined : { kind: "search", query, scope: "web" };
|
|
50
|
+
}
|
|
51
|
+
function fileChangeCall(name, input) {
|
|
52
|
+
if (name !== "search_replace")
|
|
53
|
+
return undefined;
|
|
54
|
+
const path = nonblank(input.file_path);
|
|
55
|
+
return path === undefined
|
|
56
|
+
? undefined
|
|
57
|
+
: { kind: "fileChange", changes: [{ op: "unspecified", path }] };
|
|
58
|
+
}
|
|
59
|
+
export const interpretGrokTool = (update) => {
|
|
60
|
+
const name = nativeName(update);
|
|
61
|
+
const input = object(update.rawInput);
|
|
62
|
+
if (name === undefined || input === undefined)
|
|
63
|
+
return undefined;
|
|
64
|
+
return readCall(name, input)
|
|
65
|
+
?? contentSearchCall(name, input)
|
|
66
|
+
?? runCall(name, input)
|
|
67
|
+
?? webSearchCall(name, input)
|
|
68
|
+
?? fileChangeCall(name, input);
|
|
69
|
+
};
|
|
3
70
|
function optionAdmission(options) {
|
|
4
71
|
if (options.network !== undefined) {
|
|
5
72
|
return { kind: "refused", diagnostic: "Grok Build does not support the network option" };
|
|
@@ -59,10 +126,12 @@ export function createGrokBuildProvider(execution, dependencies = {}) {
|
|
|
59
126
|
argv: argv(execution, input.options),
|
|
60
127
|
...(execution.env === undefined ? {} : { env: execution.env }),
|
|
61
128
|
};
|
|
62
|
-
return withInterject(await startAcpSession(launch, input,
|
|
129
|
+
return withInterject(await startAcpSession(launch, input, {
|
|
130
|
+
...dependencies,
|
|
131
|
+
interpretTool: interpretGrokTool,
|
|
132
|
+
}));
|
|
63
133
|
};
|
|
64
134
|
return {
|
|
65
|
-
confinement: () => ({ kind: "unconfined" }),
|
|
66
135
|
admitOptions: optionAdmission,
|
|
67
136
|
start: async (input) => await drive(input),
|
|
68
137
|
resume: async (input) => await drive(input),
|
|
@@ -59,6 +59,61 @@ function diagnostic(value) {
|
|
|
59
59
|
function positiveLine(value) {
|
|
60
60
|
return typeof value === "number" && Number.isSafeInteger(value) && value >= 1 ? value : undefined;
|
|
61
61
|
}
|
|
62
|
+
function nonnegativeCount(value) {
|
|
63
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : undefined;
|
|
64
|
+
}
|
|
65
|
+
function diffstat(value) {
|
|
66
|
+
if (value === undefined)
|
|
67
|
+
return undefined;
|
|
68
|
+
const added = nonnegativeCount(value.additions);
|
|
69
|
+
const removed = nonnegativeCount(value.deletions);
|
|
70
|
+
return added === undefined || removed === undefined ? undefined : { added, removed };
|
|
71
|
+
}
|
|
72
|
+
function fileChange(changes) {
|
|
73
|
+
return changes.length === 0 ? undefined : { kind: "fileChange", changes };
|
|
74
|
+
}
|
|
75
|
+
function change(op, path, stats) {
|
|
76
|
+
return stats === undefined ? { op, path } : { op, path, diffstat: stats };
|
|
77
|
+
}
|
|
78
|
+
function editCall(input, metadata) {
|
|
79
|
+
const path = text(input?.filePath);
|
|
80
|
+
if (path === undefined)
|
|
81
|
+
return undefined;
|
|
82
|
+
return fileChange([change("update", path, diffstat(object(metadata?.filediff)))]);
|
|
83
|
+
}
|
|
84
|
+
function writeCall(input, metadata) {
|
|
85
|
+
const path = text(metadata?.filepath) ?? text(input?.filePath);
|
|
86
|
+
const op = metadata?.exists === false ? "add"
|
|
87
|
+
: metadata?.exists === true ? "update" : undefined;
|
|
88
|
+
return path === undefined || op === undefined ? undefined : fileChange([change(op, path, undefined)]);
|
|
89
|
+
}
|
|
90
|
+
function applyPatchFile(value) {
|
|
91
|
+
const file = object(value);
|
|
92
|
+
if (file === undefined)
|
|
93
|
+
return undefined;
|
|
94
|
+
const type = file.type;
|
|
95
|
+
const op = type === "add" ? "add"
|
|
96
|
+
: type === "delete" ? "delete"
|
|
97
|
+
: type === "update" || type === "modify" || type === "move"
|
|
98
|
+
? "update" : undefined;
|
|
99
|
+
const path = type === "move" ? text(file.movePath) : text(file.filePath);
|
|
100
|
+
return op === undefined || path === undefined ? undefined : change(op, path, diffstat(file));
|
|
101
|
+
}
|
|
102
|
+
function applyPatchCall(metadata) {
|
|
103
|
+
if (!Array.isArray(metadata?.files))
|
|
104
|
+
return undefined;
|
|
105
|
+
return fileChange(metadata.files.flatMap((value) => {
|
|
106
|
+
const next = applyPatchFile(value);
|
|
107
|
+
return next === undefined ? [] : [next];
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
function strongerCall(previous, next) {
|
|
111
|
+
if (next === undefined)
|
|
112
|
+
return previous;
|
|
113
|
+
if (previous?.kind === "fileChange" && next.kind !== "fileChange")
|
|
114
|
+
return previous;
|
|
115
|
+
return next;
|
|
116
|
+
}
|
|
62
117
|
function runCall(name, value) {
|
|
63
118
|
return name === "bash" || name === "shell"
|
|
64
119
|
? { kind: "run", command: text(value?.command) ?? name }
|
|
@@ -96,8 +151,9 @@ function searchCall(name, value) {
|
|
|
96
151
|
...(scope === "content" && glob !== undefined ? { glob } : {}),
|
|
97
152
|
};
|
|
98
153
|
}
|
|
99
|
-
function callFor(name, input) {
|
|
154
|
+
function callFor(name, input, metadata) {
|
|
100
155
|
const value = object(input);
|
|
156
|
+
const meta = object(metadata);
|
|
101
157
|
const lower = name.toLowerCase();
|
|
102
158
|
if (lower === "bash" || lower === "shell")
|
|
103
159
|
return runCall(lower, value);
|
|
@@ -105,6 +161,12 @@ function callFor(name, input) {
|
|
|
105
161
|
return readCall(lower, value);
|
|
106
162
|
if (lower === "grep" || lower === "glob" || lower === "search")
|
|
107
163
|
return searchCall(lower, value);
|
|
164
|
+
if (lower === "edit")
|
|
165
|
+
return editCall(value, meta) ?? { kind: "other", display: name };
|
|
166
|
+
if (lower === "write")
|
|
167
|
+
return writeCall(value, meta) ?? { kind: "other", display: name };
|
|
168
|
+
if (lower === "apply_patch")
|
|
169
|
+
return applyPatchCall(meta) ?? { kind: "other", display: name };
|
|
108
170
|
return { kind: "other", display: name };
|
|
109
171
|
}
|
|
110
172
|
function belongs(part, state) {
|
|
@@ -139,12 +201,12 @@ function mapToolPart(part, events, state) {
|
|
|
139
201
|
const toolState = object(part.state);
|
|
140
202
|
if (id === undefined || name === undefined || toolState === undefined)
|
|
141
203
|
return;
|
|
204
|
+
const next = callFor(name, toolState.input, toolState.metadata);
|
|
142
205
|
if ((toolState.status === "pending" || toolState.status === "running")
|
|
143
206
|
&& !state.tools.has(id) && !state.completedTools.has(id)) {
|
|
144
|
-
|
|
145
|
-
if (call === undefined)
|
|
207
|
+
if (next === undefined)
|
|
146
208
|
return;
|
|
147
|
-
const observed = { name, call };
|
|
209
|
+
const observed = { name, call: next };
|
|
148
210
|
state.tools.set(id, observed);
|
|
149
211
|
events.emit({ type: "tool", phase: "started", id, ...observed });
|
|
150
212
|
return;
|
|
@@ -152,14 +214,17 @@ function mapToolPart(part, events, state) {
|
|
|
152
214
|
if ((toolState.status !== "completed" && toolState.status !== "error") || state.completedTools.has(id))
|
|
153
215
|
return;
|
|
154
216
|
const started = state.tools.get(id);
|
|
155
|
-
const call = started?.call
|
|
217
|
+
const call = strongerCall(started?.call, next);
|
|
156
218
|
if (call === undefined)
|
|
157
219
|
return;
|
|
158
|
-
const observed = started ??
|
|
220
|
+
const observed = { name: started?.name ?? name, call };
|
|
159
221
|
if (!state.tools.has(id)) {
|
|
160
222
|
state.tools.set(id, observed);
|
|
161
223
|
events.emit({ type: "tool", phase: "started", id, ...observed });
|
|
162
224
|
}
|
|
225
|
+
else {
|
|
226
|
+
state.tools.set(id, observed);
|
|
227
|
+
}
|
|
163
228
|
state.completedTools.add(id);
|
|
164
229
|
events.emit({
|
|
165
230
|
type: "tool",
|
|
@@ -1,33 +1,7 @@
|
|
|
1
|
-
import { type ProviderAdapter
|
|
2
|
-
import type {
|
|
3
|
-
import type { ProviderExecution, ProviderOptions } from "../../provider-recipe.js";
|
|
1
|
+
import { type ProviderAdapter } from "../../provider.js";
|
|
2
|
+
import type { ProviderExecution } from "../../provider-recipe.js";
|
|
4
3
|
import { type OpencodeSdkLoader } from "./session.js";
|
|
5
4
|
export type OpencodeProviderTestOptions = Readonly<{
|
|
6
5
|
loader?: OpencodeSdkLoader;
|
|
7
6
|
}>;
|
|
8
7
|
export declare function createOpencodeProvider(input?: ProviderExecution | OpencodeProviderTestOptions): ProviderAdapter;
|
|
9
|
-
export declare const opencodeProvider: Readonly<{
|
|
10
|
-
confinement(input: Readonly<{
|
|
11
|
-
cwd: string;
|
|
12
|
-
options: ProviderOptions;
|
|
13
|
-
}>): import("../../heart/facts.js").Confinement;
|
|
14
|
-
admitOptions(options: ProviderOptions): import("../../provider.js").ProviderOptionAdmission;
|
|
15
|
-
fork?(input: Readonly<{
|
|
16
|
-
session: ResumeCoordinate;
|
|
17
|
-
at: string;
|
|
18
|
-
cwd: string;
|
|
19
|
-
}>): Promise<Readonly<{
|
|
20
|
-
session: ResumeCoordinate;
|
|
21
|
-
}>>;
|
|
22
|
-
start(input: import("../../provider.js").DriveInput & Readonly<{
|
|
23
|
-
session: Readonly<{
|
|
24
|
-
kind: "fresh";
|
|
25
|
-
}>;
|
|
26
|
-
}>): Promise<Session>;
|
|
27
|
-
resume?(input: import("../../provider.js").DriveInput & Readonly<{
|
|
28
|
-
session: Readonly<{
|
|
29
|
-
kind: "resume";
|
|
30
|
-
coordinate: ResumeCoordinate;
|
|
31
|
-
}>;
|
|
32
|
-
}>): Promise<Session>;
|
|
33
|
-
}>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { abortable } from "../../abort.js";
|
|
3
|
-
import { AgentEventChannel } from "../../provider.js";
|
|
3
|
+
import { AKUMA_REQUESTS_ENV, AgentEventChannel, } from "../../provider.js";
|
|
4
4
|
import { createEventState, mapEvent } from "./events.js";
|
|
5
5
|
import { coordinate, loadOpencode, OPENCODE_SDK_PROVIDER, parseModel } from "./session.js";
|
|
6
6
|
function object(value) {
|
|
@@ -205,7 +205,13 @@ async function drive(execution, input, loader) {
|
|
|
205
205
|
const abortSetup = () => abortController.abort(signal.reason);
|
|
206
206
|
signal.addEventListener("abort", abortSetup, { once: true });
|
|
207
207
|
signal.throwIfAborted();
|
|
208
|
-
const runtime = await abortable(loadOpencode(
|
|
208
|
+
const runtime = await abortable(loadOpencode({
|
|
209
|
+
...execution,
|
|
210
|
+
env: {
|
|
211
|
+
...execution.env,
|
|
212
|
+
...(input.requests === undefined ? {} : { [AKUMA_REQUESTS_ENV]: input.requests.dir }),
|
|
213
|
+
},
|
|
214
|
+
}, input.cwd, abortController.signal, loader), abortController.signal, async (late) => await late.close());
|
|
209
215
|
let closing;
|
|
210
216
|
let iterator;
|
|
211
217
|
const closeOnce = () => {
|
|
@@ -263,7 +269,6 @@ export function createOpencodeProvider(input = { name: OPENCODE_SDK_PROVIDER, ki
|
|
|
263
269
|
const execution = "kind" in input ? input : { name: OPENCODE_SDK_PROVIDER, kind: "opencode-sdk" };
|
|
264
270
|
const loader = "loader" in input ? input.loader : undefined;
|
|
265
271
|
return {
|
|
266
|
-
confinement: ({ cwd }) => ({ kind: "declared", writableRoots: [cwd] }),
|
|
267
272
|
admitOptions(options) {
|
|
268
273
|
try {
|
|
269
274
|
admit(options);
|
|
@@ -305,4 +310,3 @@ export function createOpencodeProvider(input = { name: OPENCODE_SDK_PROVIDER, ki
|
|
|
305
310
|
},
|
|
306
311
|
};
|
|
307
312
|
}
|
|
308
|
-
export const opencodeProvider = createOpencodeProvider();
|
|
@@ -3,7 +3,7 @@ import type { ResumeCoordinate } from "../../heart/index.js";
|
|
|
3
3
|
import type { ProviderExecution } from "../../provider-recipe.js";
|
|
4
4
|
export type OpencodeSdkSession = Pick<OpencodeClient["session"], "create" | "get" | "fork" | "abort" | "promptAsync" | "messages">;
|
|
5
5
|
export type OpencodeSdkEvent = Pick<OpencodeClient["event"], "subscribe">;
|
|
6
|
-
export type OpencodeSdkLoader = (cwd: string) => Promise<Readonly<{
|
|
6
|
+
export type OpencodeSdkLoader = (cwd: string, execution: ProviderExecution) => Promise<Readonly<{
|
|
7
7
|
client: {
|
|
8
8
|
session: OpencodeSdkSession;
|
|
9
9
|
event: OpencodeSdkEvent;
|
|
@@ -40,7 +40,7 @@ async function availablePort() {
|
|
|
40
40
|
}
|
|
41
41
|
export async function loadOpencode(execution, cwd, signal, loader) {
|
|
42
42
|
if (loader) {
|
|
43
|
-
const loaded = await loader(cwd);
|
|
43
|
+
const loaded = await loader(cwd, execution);
|
|
44
44
|
return { client: loaded.client, close: async () => { await loaded.close?.(); } };
|
|
45
45
|
}
|
|
46
46
|
const port = await availablePort();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { noteEvent, unknownEvent } from "../../provider.js";
|
|
2
|
+
import { diffstatFromUnifiedPatch } from "../unified-patch.js";
|
|
2
3
|
export const PI_EVENT_DISPOSITIONS = {
|
|
3
4
|
agent_end: "drop",
|
|
4
5
|
agent_settled: "drop",
|
|
@@ -82,9 +83,21 @@ function searchCall(name, value) {
|
|
|
82
83
|
};
|
|
83
84
|
}
|
|
84
85
|
function fileChangeCall(name, value) {
|
|
85
|
-
if (
|
|
86
|
+
if (name !== "edit" || typeof value.path !== "string")
|
|
86
87
|
return undefined;
|
|
87
|
-
return { kind: "fileChange", changes: [{ op:
|
|
88
|
+
return { kind: "fileChange", changes: [{ op: "update", path: value.path }] };
|
|
89
|
+
}
|
|
90
|
+
function refineEditCall(call, result) {
|
|
91
|
+
if (call.kind !== "fileChange")
|
|
92
|
+
return call;
|
|
93
|
+
const details = record(record(result)?.details);
|
|
94
|
+
if (typeof details?.patch !== "string")
|
|
95
|
+
return call;
|
|
96
|
+
const diffstat = diffstatFromUnifiedPatch(details.patch);
|
|
97
|
+
const change = call.changes[0];
|
|
98
|
+
if (diffstat === undefined || change === undefined)
|
|
99
|
+
return call;
|
|
100
|
+
return { kind: "fileChange", changes: [{ ...change, diffstat }] };
|
|
88
101
|
}
|
|
89
102
|
function toolCall(name, args) {
|
|
90
103
|
const value = record(args) ?? {};
|
|
@@ -108,9 +121,10 @@ function translateToolEnd(event, state) {
|
|
|
108
121
|
const started = state.tools.get(event.toolCallId);
|
|
109
122
|
state.tools.delete(event.toolCallId);
|
|
110
123
|
const name = started?.name ?? event.toolName;
|
|
124
|
+
const call = started?.call ?? { kind: "other", display: name };
|
|
111
125
|
return [{
|
|
112
126
|
type: "tool", phase: "completed", id: event.toolCallId, name,
|
|
113
|
-
call:
|
|
127
|
+
call: event.isError ? call : refineEditCall(call, event.result),
|
|
114
128
|
result: { status: event.isError ? "error" : "ok" },
|
|
115
129
|
}];
|
|
116
130
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { createAgentSession, DefaultResourceLoader, getAgentDir, ModelRuntime, SessionManager, } from "@earendil-works/pi-coding-agent";
|
|
1
|
+
import { createAgentSession, createBashToolDefinition, DefaultResourceLoader, getAgentDir, ModelRuntime, SessionManager, } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { abortable } from "../../abort.js";
|
|
3
|
-
import { AgentEventChannel } from "../../provider.js";
|
|
3
|
+
import { AKUMA_REQUESTS_ENV, AgentEventChannel, } from "../../provider.js";
|
|
4
4
|
import { piTerminalFailure, translatePiEvent } from "./events.js";
|
|
5
5
|
const PI_THINKING_LEVELS = new Set(["minimal", "low", "medium", "high", "xhigh", "max"]);
|
|
6
|
-
const MODEL_PATTERN = /^[^/\s]+\/[
|
|
6
|
+
const MODEL_PATTERN = /^[^/\s]+\/[^\s]+$/u;
|
|
7
7
|
function diagnostic(error) { return error instanceof Error ? error.message : String(error); }
|
|
8
8
|
function admitPiOptions(options) {
|
|
9
9
|
if (options.network !== undefined)
|
|
@@ -48,6 +48,14 @@ async function piCreateOptions(sdk, input) {
|
|
|
48
48
|
...(resourceLoader === undefined ? {} : { resourceLoader }),
|
|
49
49
|
...(input.options.effort === undefined ? {} : { thinkingLevel: input.options.effort }),
|
|
50
50
|
...(input.options.readonly === undefined ? {} : { tools: ["read", "grep", "find", "ls"] }),
|
|
51
|
+
...(input.requests === undefined || input.options.readonly === true
|
|
52
|
+
? {}
|
|
53
|
+
: { customTools: [createBashToolDefinition(input.cwd, {
|
|
54
|
+
spawnHook: (context) => ({
|
|
55
|
+
...context,
|
|
56
|
+
env: { ...context.env, [AKUMA_REQUESTS_ENV]: input.requests.dir },
|
|
57
|
+
}),
|
|
58
|
+
})] }),
|
|
51
59
|
};
|
|
52
60
|
}
|
|
53
61
|
async function createPiSession(sdk, input, signal) {
|
|
@@ -176,7 +184,6 @@ export function createPiProvider(execution = { name: "pi", kind: "pi" }, load =
|
|
|
176
184
|
return drivePi(await abortable(load(), signal), input, signal);
|
|
177
185
|
};
|
|
178
186
|
return {
|
|
179
|
-
confinement: ({ cwd }) => ({ kind: "declared", writableRoots: [cwd] }),
|
|
180
187
|
admitOptions: admitPiOptions,
|
|
181
188
|
start: drive,
|
|
182
189
|
resume: async (input) => {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function diffstatFromUnifiedPatch(patch) {
|
|
2
|
+
const lines = patch.split("\n");
|
|
3
|
+
if (!lines.some((line) => /^@@ -\d+(?:,\d+)? \+\d+(?:,\d+)? @@/u.test(line)))
|
|
4
|
+
return undefined;
|
|
5
|
+
let added = 0;
|
|
6
|
+
let removed = 0;
|
|
7
|
+
for (const line of lines) {
|
|
8
|
+
if (line.startsWith("+") && !line.startsWith("+++"))
|
|
9
|
+
added += 1;
|
|
10
|
+
if (line.startsWith("-") && !line.startsWith("---"))
|
|
11
|
+
removed += 1;
|
|
12
|
+
}
|
|
13
|
+
return { added, removed };
|
|
14
|
+
}
|
|
@@ -2,7 +2,7 @@ import { HeldAkumaLeash, initializeHeart, readHeart, readSeal, readSoul, } from
|
|
|
2
2
|
import { allocateAkumaDirectory, } from "./identity.js";
|
|
3
3
|
import { abortableDelay } from "./abort.js";
|
|
4
4
|
const POLL_MS = 25;
|
|
5
|
-
export const BIRTH_TIMEOUT_MS =
|
|
5
|
+
export const BIRTH_TIMEOUT_MS = 30_000;
|
|
6
6
|
function diagnostic(error) {
|
|
7
7
|
return error instanceof Error ? error.message : String(error);
|
|
8
8
|
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { type KillEvidence, type Soul } from "./heart/index.js";
|
|
2
|
+
import { type AkuId, type AkumaPaths } from "./identity.js";
|
|
3
|
+
import { type TaskMutationRequest } from "../task/mutation.js";
|
|
4
|
+
export type RequestChildLaunch = Readonly<{
|
|
5
|
+
paths: AkumaPaths;
|
|
6
|
+
seed: Omit<Soul, "createdAt">;
|
|
7
|
+
initialBody: string;
|
|
8
|
+
}>;
|
|
9
|
+
type UpstreamCall = Readonly<{
|
|
10
|
+
signal: AbortSignal;
|
|
11
|
+
}>;
|
|
12
|
+
type RequesterCall = UpstreamCall & Readonly<{
|
|
13
|
+
requester: AkuId;
|
|
14
|
+
}>;
|
|
15
|
+
type ContractCall = RequesterCall & Readonly<{
|
|
16
|
+
repoRoot: string;
|
|
17
|
+
contractId: string;
|
|
18
|
+
}>;
|
|
19
|
+
export type UpstreamExecutionPort = Readonly<{
|
|
20
|
+
wait(input: UpstreamCall & Readonly<{
|
|
21
|
+
targets: readonly AkuId[];
|
|
22
|
+
completion: "any" | "all";
|
|
23
|
+
timeoutMs?: number;
|
|
24
|
+
}>): Promise<unknown>;
|
|
25
|
+
tell(input: UpstreamCall & Readonly<{
|
|
26
|
+
target: AkuId;
|
|
27
|
+
body: string;
|
|
28
|
+
tellId: string;
|
|
29
|
+
recordedAt: string;
|
|
30
|
+
}>): Promise<unknown>;
|
|
31
|
+
kill(input: Readonly<{
|
|
32
|
+
targets: readonly AkuId[];
|
|
33
|
+
signal: AbortSignal;
|
|
34
|
+
}>): Promise<Readonly<{
|
|
35
|
+
result: unknown;
|
|
36
|
+
service: readonly Readonly<{
|
|
37
|
+
id: AkuId;
|
|
38
|
+
evidence: KillEvidence;
|
|
39
|
+
}>[];
|
|
40
|
+
}>>;
|
|
41
|
+
deliver(input: ContractCall & Readonly<{
|
|
42
|
+
message?: string;
|
|
43
|
+
includeDirty: boolean;
|
|
44
|
+
}>): Promise<Readonly<{
|
|
45
|
+
result: unknown;
|
|
46
|
+
deliveryFactId?: string;
|
|
47
|
+
}>>;
|
|
48
|
+
review(input: ContractCall & Readonly<{
|
|
49
|
+
verdict: "satisfied" | "unsatisfied";
|
|
50
|
+
summary?: string;
|
|
51
|
+
}>): Promise<Readonly<{
|
|
52
|
+
result: unknown;
|
|
53
|
+
reviewFactId?: string;
|
|
54
|
+
}>>;
|
|
55
|
+
task(input: RequesterCall & Readonly<{
|
|
56
|
+
world: string;
|
|
57
|
+
request: TaskMutationRequest;
|
|
58
|
+
}>): Promise<unknown>;
|
|
59
|
+
}>;
|
|
60
|
+
type PumpInput = Readonly<{
|
|
61
|
+
paths: AkumaPaths;
|
|
62
|
+
parent: Soul;
|
|
63
|
+
bodySequence: number;
|
|
64
|
+
now(): string;
|
|
65
|
+
spawn(launch: RequestChildLaunch): Promise<void>;
|
|
66
|
+
upstream?: UpstreamExecutionPort;
|
|
67
|
+
signal: AbortSignal;
|
|
68
|
+
}>;
|
|
69
|
+
export declare class BodyRequestPump {
|
|
70
|
+
private readonly input;
|
|
71
|
+
readonly directory: string;
|
|
72
|
+
readonly failure: Promise<never>;
|
|
73
|
+
private readonly closeSignal;
|
|
74
|
+
private readonly executionSignal;
|
|
75
|
+
private readonly handled;
|
|
76
|
+
private readonly running;
|
|
77
|
+
private readonly cancelBody;
|
|
78
|
+
private admissionClosed;
|
|
79
|
+
private constructor();
|
|
80
|
+
static open(input: PumpInput): Promise<BodyRequestPump>;
|
|
81
|
+
private run;
|
|
82
|
+
close(): Promise<void>;
|
|
83
|
+
stopAdmission(): void;
|
|
84
|
+
}
|
|
85
|
+
export declare function clearBodyRequestTransport(paths: AkumaPaths): Promise<void>;
|
|
86
|
+
export declare function settleBodyRequests(paths: AkumaPaths, parent: Soul, now: () => string, signal?: AbortSignal): Promise<"settled" | "pending">;
|
|
87
|
+
export {};
|