@astrosheep/keiyaku 4.6.19 → 4.6.21
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 +7 -3
- package/build/plugins/pi/README.md +111 -0
- package/build/plugins/pi/akuma-tools.ts +310 -0
- package/build/plugins/pi/keiyaku.ts +2 -0
- package/build/src/akuma/akuma-call.d.ts +4 -1
- package/build/src/akuma/akuma-call.js +24 -7
- package/build/src/akuma/akuma-instance.d.ts +28 -8
- package/build/src/akuma/akuma-instance.js +85 -42
- package/build/src/akuma/akuma-owner.d.ts +18 -9
- package/build/src/akuma/akuma-owner.js +31 -25
- package/build/src/akuma/akuma-selection-execution.d.ts +4 -1
- package/build/src/akuma/akuma-selection-execution.js +8 -4
- package/build/src/akuma/akuma.d.ts +17 -0
- package/build/src/akuma/body-launch.d.ts +107 -0
- package/build/src/akuma/body-launch.js +57 -0
- package/build/src/akuma/body-supervisor.d.ts +7 -6
- package/build/src/akuma/body-supervisor.js +17 -12
- package/build/src/akuma/body.d.ts +13 -94
- package/build/src/akuma/body.js +124 -296
- package/build/src/akuma/call-input.d.ts +2 -0
- package/build/src/akuma/call-input.js +21 -1
- package/build/src/akuma/call-request.d.ts +6 -2
- package/build/src/akuma/call-request.js +9 -1
- package/build/src/akuma/detached-body.d.ts +9 -0
- package/build/src/akuma/detached-body.js +94 -0
- package/build/src/akuma/execution-instructions.d.ts +8 -0
- package/build/src/akuma/execution-instructions.js +17 -0
- package/build/src/akuma/heart/facts.d.ts +21 -1
- package/build/src/akuma/heart/facts.js +10 -0
- package/build/src/akuma/heart/index.d.ts +16 -1
- package/build/src/akuma/heart/index.js +95 -30
- package/build/src/akuma/heart/rows.d.ts +14 -2
- package/build/src/akuma/heart/rows.js +48 -4
- package/build/src/akuma/heart/schema.d.ts +4 -1
- package/build/src/akuma/heart/schema.js +87 -30
- package/build/src/akuma/heart/soul.js +4 -0
- package/build/src/akuma/heart/storage.d.ts +1 -0
- package/build/src/akuma/heart/storage.js +59 -15
- package/build/src/akuma/heart/timeline.d.ts +6 -4
- package/build/src/akuma/heart/timeline.js +14 -4
- package/build/src/akuma/in-process-body.d.ts +5 -0
- package/build/src/akuma/in-process-body.js +57 -0
- package/build/src/akuma/index.d.ts +1 -1
- package/build/src/akuma/projection.d.ts +44 -1
- package/build/src/akuma/projection.js +13 -1
- package/build/src/akuma/provider.d.ts +4 -0
- package/build/src/akuma/providers/acp/core.js +1 -1
- package/build/src/akuma/providers/acp/index.js +3 -0
- package/build/src/akuma/providers/claude/index.js +8 -5
- package/build/src/akuma/providers/codex-app-server/configuration.d.ts +5 -0
- package/build/src/akuma/providers/codex-app-server/configuration.js +72 -0
- package/build/src/akuma/providers/codex-app-server/index.js +7 -10
- package/build/src/akuma/providers/execution-environment.d.ts +8 -2
- package/build/src/akuma/providers/execution-environment.js +10 -1
- package/build/src/akuma/providers/grok-build/index.js +23 -16
- package/build/src/akuma/providers/index.d.ts +1 -0
- package/build/src/akuma/providers/index.js +8 -0
- package/build/src/akuma/providers/opencode-sdk/index.js +9 -0
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +6 -0
- package/build/src/akuma/providers/opencode-sdk/session.js +4 -3
- package/build/src/akuma/providers/paseo/index.js +8 -2
- package/build/src/akuma/providers/pi/index.js +27 -10
- package/build/src/akuma/publication.d.ts +4 -3
- package/build/src/akuma/publication.js +21 -18
- package/build/src/akuma/selection-observation.d.ts +51 -0
- package/build/src/akuma/selection-owner-port.d.ts +2 -1
- package/build/src/akuma/selection-owner-port.js +4 -3
- package/build/src/akuma/turn-drive.d.ts +4 -2
- package/build/src/akuma/turn-drive.js +58 -21
- package/build/src/akuma-body.d.ts +0 -10
- package/build/src/akuma-body.js +13 -118
- package/build/src/body-host.d.ts +28 -0
- package/build/src/body-host.js +86 -0
- package/build/src/body-requests.d.ts +13 -0
- package/build/src/body-requests.js +131 -0
- package/build/src/cli/commands/akuma-grammar.d.ts +8 -1
- package/build/src/cli/commands/akuma-grammar.js +36 -6
- package/build/src/cli/commands/akuma.js +11 -0
- package/build/src/cli/commands/report.d.ts +6 -0
- package/build/src/cli/commands/report.js +31 -0
- package/build/src/cli/parse.js +1 -0
- package/build/src/cli/render/akuma-activity.js +27 -17
- package/build/src/cli/render/terminal.d.ts +5 -0
- package/build/src/cli/render/terminal.js +7 -0
- package/build/src/cli/runtime.js +4 -1
- package/build/src/index.d.ts +3 -1
- package/build/src/index.js +1 -0
- package/build/src/library/akuma-creation.d.ts +7 -3
- package/build/src/library/akuma-creation.js +23 -11
- package/build/src/library/akumas.d.ts +4 -1
- package/build/src/library/akumas.js +13 -5
- package/build/src/library/selection.d.ts +2 -1
- package/build/src/library/selection.js +6 -3
- package/build/src/plugin/public.d.ts +11 -0
- package/build/src/plugin/runtime.js +1 -0
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/package.json +3 -3
- package/plugins/paseo/plugin/server/keiyaku.ts +1 -0
- package/plugins/paseo/plugin/server/mirror.ts +2 -2
- package/plugins/pi/README.md +111 -0
- package/plugins/pi/akuma-tools.ts +310 -0
- package/plugins/pi/keiyaku.ts +2 -0
|
@@ -15,6 +15,14 @@ declare const callRowSchema: z.ZodObject<{
|
|
|
15
15
|
at: z.ZodString;
|
|
16
16
|
text: z.ZodString;
|
|
17
17
|
}, z.core.$strict>;
|
|
18
|
+
declare const reportRowSchema: z.ZodObject<{
|
|
19
|
+
kind: z.ZodLiteral<"report">;
|
|
20
|
+
sequence: z.ZodNumber;
|
|
21
|
+
bodySequence: z.ZodNumber;
|
|
22
|
+
turnSequence: z.ZodNumber;
|
|
23
|
+
text: z.ZodString;
|
|
24
|
+
at: z.ZodString;
|
|
25
|
+
}, z.core.$strict>;
|
|
18
26
|
declare const textRowSchema: (kind: "said" | "thought" | "note") => z.ZodObject<{
|
|
19
27
|
kind: z.ZodLiteral<"note" | "thought" | "said">;
|
|
20
28
|
sequence: z.ZodNumber;
|
|
@@ -70,6 +78,9 @@ declare const outcomeRowSchema: z.ZodObject<{
|
|
|
70
78
|
kind: z.ZodLiteral<"failed">;
|
|
71
79
|
historyId: z.ZodString;
|
|
72
80
|
diagnostic: z.ZodString;
|
|
81
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
82
|
+
kind: z.ZodLiteral<"canceled">;
|
|
83
|
+
historyId: z.ZodString;
|
|
73
84
|
}, z.core.$strict>]>;
|
|
74
85
|
}, z.core.$strict>;
|
|
75
86
|
declare const activeToolRowSchema: z.ZodObject<{
|
|
@@ -238,6 +249,13 @@ declare const unsettledToolRowSchema: z.ZodObject<{
|
|
|
238
249
|
truncated: z.ZodOptional<z.ZodLiteral<true>>;
|
|
239
250
|
}, z.core.$strict>;
|
|
240
251
|
declare const openSnapshotRowSchema: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
|
|
252
|
+
kind: z.ZodLiteral<"report">;
|
|
253
|
+
sequence: z.ZodNumber;
|
|
254
|
+
bodySequence: z.ZodNumber;
|
|
255
|
+
turnSequence: z.ZodNumber;
|
|
256
|
+
text: z.ZodString;
|
|
257
|
+
at: z.ZodString;
|
|
258
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
241
259
|
kind: z.ZodLiteral<"call">;
|
|
242
260
|
sequence: z.ZodNumber;
|
|
243
261
|
turnSequence: z.ZodNumber;
|
|
@@ -409,6 +427,13 @@ declare const openSnapshotRowSchema: z.ZodUnion<readonly [z.ZodUnion<readonly [z
|
|
|
409
427
|
truncated: z.ZodOptional<z.ZodLiteral<true>>;
|
|
410
428
|
}, z.core.$strict>]>;
|
|
411
429
|
declare const idleSnapshotRowSchema: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
|
|
430
|
+
kind: z.ZodLiteral<"report">;
|
|
431
|
+
sequence: z.ZodNumber;
|
|
432
|
+
bodySequence: z.ZodNumber;
|
|
433
|
+
turnSequence: z.ZodNumber;
|
|
434
|
+
text: z.ZodString;
|
|
435
|
+
at: z.ZodString;
|
|
436
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
412
437
|
kind: z.ZodLiteral<"call">;
|
|
413
438
|
sequence: z.ZodNumber;
|
|
414
439
|
turnSequence: z.ZodNumber;
|
|
@@ -601,6 +626,13 @@ export declare const activitySnapshotSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
601
626
|
}, z.core.$strict>, z.ZodObject<{
|
|
602
627
|
kind: z.ZodLiteral<"row">;
|
|
603
628
|
row: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
|
|
629
|
+
kind: z.ZodLiteral<"report">;
|
|
630
|
+
sequence: z.ZodNumber;
|
|
631
|
+
bodySequence: z.ZodNumber;
|
|
632
|
+
turnSequence: z.ZodNumber;
|
|
633
|
+
text: z.ZodString;
|
|
634
|
+
at: z.ZodString;
|
|
635
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
604
636
|
kind: z.ZodLiteral<"call">;
|
|
605
637
|
sequence: z.ZodNumber;
|
|
606
638
|
turnSequence: z.ZodNumber;
|
|
@@ -806,6 +838,9 @@ export declare const activitySnapshotSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
806
838
|
kind: z.ZodLiteral<"failed">;
|
|
807
839
|
historyId: z.ZodString;
|
|
808
840
|
diagnostic: z.ZodString;
|
|
841
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
842
|
+
kind: z.ZodLiteral<"canceled">;
|
|
843
|
+
historyId: z.ZodString;
|
|
809
844
|
}, z.core.$strict>]>;
|
|
810
845
|
}, z.core.$strict>>;
|
|
811
846
|
entries: z.ZodReadonly<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
@@ -814,6 +849,13 @@ export declare const activitySnapshotSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
814
849
|
}, z.core.$strict>, z.ZodObject<{
|
|
815
850
|
kind: z.ZodLiteral<"row">;
|
|
816
851
|
row: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
|
|
852
|
+
kind: z.ZodLiteral<"report">;
|
|
853
|
+
sequence: z.ZodNumber;
|
|
854
|
+
bodySequence: z.ZodNumber;
|
|
855
|
+
turnSequence: z.ZodNumber;
|
|
856
|
+
text: z.ZodString;
|
|
857
|
+
at: z.ZodString;
|
|
858
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
817
859
|
kind: z.ZodLiteral<"call">;
|
|
818
860
|
sequence: z.ZodNumber;
|
|
819
861
|
turnSequence: z.ZodNumber;
|
|
@@ -941,7 +983,8 @@ type CallRow = z.infer<typeof callRowSchema>;
|
|
|
941
983
|
type SaidRow = z.infer<ReturnType<typeof textRowSchema>>;
|
|
942
984
|
type ThoughtRow = z.infer<ReturnType<typeof textRowSchema>>;
|
|
943
985
|
type NoteRow = z.infer<ReturnType<typeof textRowSchema>>;
|
|
944
|
-
type
|
|
986
|
+
export type ReportRow = z.infer<typeof reportRowSchema>;
|
|
987
|
+
type TurnNarrationRow = CallRow | SaidRow | ThoughtRow | NoteRow | ReportRow;
|
|
945
988
|
export type { TellRow } from "./heart/facts.js";
|
|
946
989
|
export type OutcomeRow = z.infer<typeof outcomeRowSchema>;
|
|
947
990
|
export type ActiveToolRow = z.infer<typeof activeToolRowSchema>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toolCallSchema, toolResultSchema, toolInputSchema, fileChangeSchema, diffstatSchema, } from "./heart/activity-schema.js";
|
|
2
|
-
import { projectTell } from "./heart/facts.js";
|
|
2
|
+
import { projectTell, reportFactSchema } from "./heart/facts.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
const nonblankTextSchema = z.string().refine((value) => value.trim() !== "");
|
|
5
5
|
const countSchema = z.number().int().nonnegative();
|
|
@@ -47,6 +47,7 @@ const callRowSchema = z
|
|
|
47
47
|
text: z.string(),
|
|
48
48
|
})
|
|
49
49
|
.strict();
|
|
50
|
+
const reportRowSchema = reportFactSchema;
|
|
50
51
|
const textRowSchema = (kind) => z
|
|
51
52
|
.object({
|
|
52
53
|
kind: z.literal(kind),
|
|
@@ -78,6 +79,7 @@ const outcomeSchema = z.union([
|
|
|
78
79
|
})
|
|
79
80
|
.strict(),
|
|
80
81
|
z.object({ kind: z.literal("failed"), historyId: nonblankTextSchema, diagnostic: z.string() }).strict(),
|
|
82
|
+
z.object({ kind: z.literal("canceled"), historyId: nonblankTextSchema }).strict(),
|
|
81
83
|
]);
|
|
82
84
|
const outcomeRowSchema = z
|
|
83
85
|
.object({
|
|
@@ -129,6 +131,7 @@ const unsettledToolRowSchema = z
|
|
|
129
131
|
})
|
|
130
132
|
.strict();
|
|
131
133
|
const snapshotFactRowSchema = z.union([
|
|
134
|
+
reportRowSchema,
|
|
132
135
|
callRowSchema,
|
|
133
136
|
textRowSchema("said"),
|
|
134
137
|
textRowSchema("thought"),
|
|
@@ -200,6 +203,8 @@ function publicOutcome(turnSequence, outcome) {
|
|
|
200
203
|
const historyId = `turn/${turnSequence}`;
|
|
201
204
|
if (outcome.kind === "answered")
|
|
202
205
|
return { kind: "answered", historyId, answer: outcome.answer };
|
|
206
|
+
if (outcome.kind === "canceled")
|
|
207
|
+
return { kind: "canceled", historyId };
|
|
203
208
|
return { kind: "failed", historyId, diagnostic: outcome.diagnostic };
|
|
204
209
|
}
|
|
205
210
|
export function selectExactHistory(rows, id) {
|
|
@@ -409,6 +414,13 @@ export function projectTurns(facts, retained = {
|
|
|
409
414
|
else
|
|
410
415
|
turn.rows.push(row);
|
|
411
416
|
}
|
|
417
|
+
else if (fact.kind === "report") {
|
|
418
|
+
const turn = state.turnsBySequence.get(fact.turnSequence);
|
|
419
|
+
if (turn === undefined)
|
|
420
|
+
state.orphanRows.push(fact);
|
|
421
|
+
else
|
|
422
|
+
turn.rows.push(fact);
|
|
423
|
+
}
|
|
412
424
|
else if (fact.kind === "tell") {
|
|
413
425
|
state.tells.push(projectTell(fact));
|
|
414
426
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ResumeCoordinate } from "./coordinate.js";
|
|
2
|
+
import type { ExecutionCoordinate } from "./providers/execution-environment.js";
|
|
2
3
|
import type { ProviderOptions } from "./provider-recipe.js";
|
|
3
4
|
export type { ResumeCoordinate } from "./coordinate.js";
|
|
4
5
|
export { AKUMA_REQUESTS_ENV, AKUMA_REQUESTS_ENTRY_ENV } from "./providers/execution-environment.js";
|
|
@@ -130,7 +131,10 @@ export type DriveInput = Readonly<{
|
|
|
130
131
|
}>[];
|
|
131
132
|
cwd: string;
|
|
132
133
|
options: ProviderOptions;
|
|
134
|
+
/** Fresh execution context, never part of the persisted personality recipe. */
|
|
135
|
+
runtimeInstructions?: string;
|
|
133
136
|
signal: AbortSignal;
|
|
137
|
+
execution?: ExecutionCoordinate;
|
|
134
138
|
requests: Readonly<{
|
|
135
139
|
dir: string;
|
|
136
140
|
entry?: string;
|
|
@@ -169,7 +169,7 @@ export async function startAcpSession(launch, input, dependencies = {}, custody)
|
|
|
169
169
|
const child = (dependencies.spawnProcess ?? spawnStdioProcess)({
|
|
170
170
|
argv: launch.argv,
|
|
171
171
|
cwd: input.cwd,
|
|
172
|
-
env: akumaExecutionEnvironment(globalThis.process.env, launch.env, input.requests?.dir),
|
|
172
|
+
env: akumaExecutionEnvironment(globalThis.process.env, launch.env, input.requests?.dir, [], input.execution),
|
|
173
173
|
});
|
|
174
174
|
let abortOwned = async () => await child.close(true);
|
|
175
175
|
let forceDisposeOwned = async () => await child.close(true);
|
|
@@ -47,6 +47,9 @@ export function createAcpProvider(execution, dependencies = {}) {
|
|
|
47
47
|
throw new TypeError("ACP provider execution requires executable");
|
|
48
48
|
const config = decodeAcpConfig(execution.config);
|
|
49
49
|
const drive = async (input, custody) => {
|
|
50
|
+
if (input.runtimeInstructions !== undefined) {
|
|
51
|
+
throw new Error("ACP has no verified native runtime-instruction channel; call with bare to omit the Keiyaku section");
|
|
52
|
+
}
|
|
50
53
|
const launch = {
|
|
51
54
|
argv: argv(execution, config, input.options),
|
|
52
55
|
...(execution.env === undefined ? {} : { env: execution.env }),
|
|
@@ -54,24 +54,27 @@ function claudeSessionId(coordinate) {
|
|
|
54
54
|
return coordinate.sessionId;
|
|
55
55
|
}
|
|
56
56
|
function claudeQueryOptions(input, execution, abortController) {
|
|
57
|
+
const instructions = [input.options.systemPrompt, input.runtimeInstructions]
|
|
58
|
+
.filter((part) => part !== undefined && part.length > 0)
|
|
59
|
+
.join("\n\n");
|
|
57
60
|
return {
|
|
58
61
|
...(execution.config ?? {}),
|
|
59
62
|
cwd: input.cwd,
|
|
60
63
|
abortController,
|
|
61
64
|
...(input.requests === undefined ? {} : { additionalDirectories: [input.requests.dir] }),
|
|
62
65
|
...(execution.executable === undefined ? {} : { pathToClaudeCodeExecutable: execution.executable }),
|
|
63
|
-
env: akumaExecutionEnvironment(process.env, execution.env, input.requests?.dir),
|
|
66
|
+
env: akumaExecutionEnvironment(process.env, execution.env, input.requests?.dir, [], input.execution),
|
|
64
67
|
permissionMode: "bypassPermissions",
|
|
65
68
|
allowDangerouslySkipPermissions: true,
|
|
66
69
|
settingSources: ["user", "project", "local"],
|
|
67
70
|
...(input.options.model === undefined ? {} : { model: input.options.model }),
|
|
68
71
|
...(input.options.effort === undefined ? {} : { effort: input.options.effort }),
|
|
69
|
-
...(
|
|
72
|
+
...(instructions.length === 0
|
|
70
73
|
? {}
|
|
71
74
|
: {
|
|
72
|
-
systemPrompt: input.options.systemPromptMode === "replace"
|
|
73
|
-
?
|
|
74
|
-
: { type: "preset", preset: "claude_code", append:
|
|
75
|
+
systemPrompt: input.options.systemPromptMode === "replace" && (input.options.systemPrompt?.length ?? 0) > 0
|
|
76
|
+
? instructions
|
|
77
|
+
: { type: "preset", preset: "claude_code", append: instructions },
|
|
75
78
|
}),
|
|
76
79
|
...(input.session.kind === "fresh" ? {} : { resume: claudeSessionId(input.session.coordinate) }),
|
|
77
80
|
...(input.schemaJson === undefined
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { LineRpcProcess } from "../../../runtime/proc/line-rpc.js";
|
|
2
|
+
import { type ProviderExecution } from "../../provider-recipe.js";
|
|
3
|
+
export declare function initializeCodex(server: LineRpcProcess): Promise<void>;
|
|
4
|
+
/** Native config precedence belongs to Codex, including profiles and dotted overrides. */
|
|
5
|
+
export declare function withCodexWritableDirectories(execution: ProviderExecution, cwd: string, directories: readonly string[], signal?: AbortSignal): Promise<ProviderExecution>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { LineRpcProcess } from "../../../runtime/proc/line-rpc.js";
|
|
2
|
+
import { createProviderAttempt } from "../../provider.js";
|
|
3
|
+
import { decodeProviderRecipe } from "../../provider-recipe.js";
|
|
4
|
+
import { akumaExecutionEnvironment } from "../execution-environment.js";
|
|
5
|
+
import { codexObject } from "./events.js";
|
|
6
|
+
export async function initializeCodex(server) {
|
|
7
|
+
await server.request("initialize", {
|
|
8
|
+
clientInfo: { name: "keiyaku", title: "keiyaku", version: "4" },
|
|
9
|
+
capabilities: { experimentalApi: true, requestAttestation: false },
|
|
10
|
+
});
|
|
11
|
+
server.notify("initialized");
|
|
12
|
+
}
|
|
13
|
+
/** Native config precedence belongs to Codex, including profiles and dotted overrides. */
|
|
14
|
+
export async function withCodexWritableDirectories(execution, cwd, directories, signal) {
|
|
15
|
+
const attempt = createProviderAttempt(signal, async (custody) => {
|
|
16
|
+
custody.signal.throwIfAborted();
|
|
17
|
+
const server = new LineRpcProcess({
|
|
18
|
+
argv: [execution.executable ?? "codex", "app-server", "--listen", "stdio://"],
|
|
19
|
+
cwd,
|
|
20
|
+
env: akumaExecutionEnvironment(process.env, execution.env),
|
|
21
|
+
});
|
|
22
|
+
const closed = new Promise((resolve) => server.onExit(() => resolve()));
|
|
23
|
+
custody.own({ closed, forceDispose: () => server.close(true) });
|
|
24
|
+
try {
|
|
25
|
+
custody.signal.throwIfAborted();
|
|
26
|
+
await initializeCodex(server);
|
|
27
|
+
const response = codexObject(await server.request("thread/start", {
|
|
28
|
+
cwd,
|
|
29
|
+
ephemeral: true,
|
|
30
|
+
...(execution.config === undefined ? {} : { config: execution.config }),
|
|
31
|
+
}));
|
|
32
|
+
custody.signal.throwIfAborted();
|
|
33
|
+
const sandbox = codexObject(response?.sandbox);
|
|
34
|
+
if (sandbox?.type !== "workspaceWrite" || response?.activePermissionProfile != null)
|
|
35
|
+
throw new TypeError("writableDirectories requires Codex native workspace-write sandbox configuration");
|
|
36
|
+
const roots = sandbox.writableRoots;
|
|
37
|
+
if (!Array.isArray(roots) ||
|
|
38
|
+
!roots.every((root) => typeof root === "string") ||
|
|
39
|
+
typeof sandbox.networkAccess !== "boolean" ||
|
|
40
|
+
typeof sandbox.excludeTmpdirEnvVar !== "boolean" ||
|
|
41
|
+
typeof sandbox.excludeSlashTmp !== "boolean")
|
|
42
|
+
throw new TypeError("Codex did not return its effective workspace-write configuration");
|
|
43
|
+
const config = { ...execution.config };
|
|
44
|
+
// Remove conflicting spellings of only the fields this native snapshot owns.
|
|
45
|
+
for (const key of ["writable_roots", "network_access", "exclude_tmpdir_env_var", "exclude_slash_tmp"])
|
|
46
|
+
delete config[`sandbox_workspace_write.${key}`];
|
|
47
|
+
return decodeProviderRecipe({
|
|
48
|
+
...execution,
|
|
49
|
+
config: {
|
|
50
|
+
...config,
|
|
51
|
+
sandbox_mode: "workspace-write",
|
|
52
|
+
sandbox_workspace_write: {
|
|
53
|
+
...codexObject(config.sandbox_workspace_write),
|
|
54
|
+
writable_roots: [...new Set([...roots, ...directories])],
|
|
55
|
+
network_access: sandbox.networkAccess,
|
|
56
|
+
exclude_tmpdir_env_var: sandbox.excludeTmpdirEnvVar,
|
|
57
|
+
exclude_slash_tmp: sandbox.excludeSlashTmp,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
await server.endInputAndDrain();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
try {
|
|
67
|
+
return await attempt.result;
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
await attempt.closed;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -3,17 +3,11 @@ import { AgentEventChannel, createProviderAttempt, launchPrompt, modelEvent, } f
|
|
|
3
3
|
import { akumaExecutionEnvironment } from "../execution-environment.js";
|
|
4
4
|
import { providerLifecycle } from "../lifecycle.js";
|
|
5
5
|
import { codexNotificationResult, codexObject, codexText } from "./events.js";
|
|
6
|
+
import { initializeCodex } from "./configuration.js";
|
|
6
7
|
export { CODEX_ITEM_DISPOSITIONS, CODEX_NOTIFICATION_DISPOSITIONS } from "./events.js";
|
|
7
8
|
function diagnostic(error) {
|
|
8
9
|
return error instanceof Error ? error.message : String(error);
|
|
9
10
|
}
|
|
10
|
-
async function initialize(server) {
|
|
11
|
-
await server.request("initialize", {
|
|
12
|
-
clientInfo: { name: "keiyaku", title: "keiyaku", version: "4" },
|
|
13
|
-
capabilities: { experimentalApi: false, requestAttestation: false },
|
|
14
|
-
});
|
|
15
|
-
server.notify("initialized");
|
|
16
|
-
}
|
|
17
11
|
function threadId(result, fallback) {
|
|
18
12
|
const value = codexObject(result);
|
|
19
13
|
const thread = codexObject(value?.thread) ?? value;
|
|
@@ -56,7 +50,7 @@ async function steerTurn(server, state, tell) {
|
|
|
56
50
|
return { kind: "accepted", fence: `${accepted}:${tell.id}` };
|
|
57
51
|
}
|
|
58
52
|
async function admitTurn(server, input, state, events, config) {
|
|
59
|
-
await
|
|
53
|
+
await initializeCodex(server);
|
|
60
54
|
const threadParams = {
|
|
61
55
|
cwd: input.cwd,
|
|
62
56
|
...(config === undefined ? {} : { config }),
|
|
@@ -90,6 +84,9 @@ async function admitTurn(server, input, state, events, config) {
|
|
|
90
84
|
...(input.options.model === undefined ? {} : { model: input.options.model }),
|
|
91
85
|
...(input.options.effort === undefined ? {} : { effort: input.options.effort }),
|
|
92
86
|
approvalPolicy: "never",
|
|
87
|
+
...(input.runtimeInstructions === undefined
|
|
88
|
+
? {}
|
|
89
|
+
: { additionalContext: { keiyaku_execution: { kind: "application", value: input.runtimeInstructions } } }),
|
|
93
90
|
...(input.schemaJson === undefined ? {} : { outputSchema: JSON.parse(input.schemaJson) }),
|
|
94
91
|
}));
|
|
95
92
|
}
|
|
@@ -108,7 +105,7 @@ async function forkCodex(execution, input, custody) {
|
|
|
108
105
|
forceDispose: async () => await server.close(true),
|
|
109
106
|
});
|
|
110
107
|
try {
|
|
111
|
-
await
|
|
108
|
+
await initializeCodex(server);
|
|
112
109
|
const child = threadId(await server.request("thread/fork", {
|
|
113
110
|
threadId: input.session.sessionId,
|
|
114
111
|
lastTurnId: input.at,
|
|
@@ -130,7 +127,7 @@ function codexServer(execution, input) {
|
|
|
130
127
|
return new LineRpcProcess({
|
|
131
128
|
argv: [execution.executable ?? "codex", "app-server", "--listen", "stdio://"],
|
|
132
129
|
cwd: input.cwd,
|
|
133
|
-
env: akumaExecutionEnvironment(process.env, execution.env, input.requests?.dir),
|
|
130
|
+
env: akumaExecutionEnvironment(process.env, execution.env, input.requests?.dir, [], input.execution),
|
|
134
131
|
});
|
|
135
132
|
}
|
|
136
133
|
async function startCodex(execution, input, custody) {
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
export declare const AKUMA_REQUESTS_ENV = "AKUMA_REQUESTS";
|
|
2
2
|
export declare const AKUMA_REQUESTS_ENTRY_ENV = "AKUMA_REQUESTS_ENTRY";
|
|
3
|
-
|
|
3
|
+
export type ExecutionCoordinate = Readonly<{
|
|
4
|
+
akumaId: string;
|
|
5
|
+
world: string;
|
|
6
|
+
bodySequence: number;
|
|
7
|
+
turnSequence: number;
|
|
8
|
+
}>;
|
|
9
|
+
declare const PARENT_HARNESS_IDENTITY_KEYS: readonly ["KEIYAKU_BODY_SEQUENCE", "KEIYAKU_TURN_SEQUENCE", "CLAUDE_CODE_SESSION_ID", "CLAUDE_CODE_CHILD_SESSION", "CLAUDECODE", "CODEX_THREAD_ID", "OPENCODE_SESSION_ID", "PI_SESSION_ID", "PI_SESSION_FILE", "PASEO_AGENT_ID", "SQUARE_PARTICIPANT_NAME", "KEIYAKU_INITIATOR", "KEIYAKU_EXTERNAL_CALLER"];
|
|
4
10
|
type Environment = Readonly<Record<string, string | undefined>>;
|
|
5
11
|
/** Construct the environment for one isolated Akuma execution or native child. */
|
|
6
|
-
export declare function akumaExecutionEnvironment(inherited: Environment, overrides?: Environment, requests?: string, nativeIdentity?: readonly (typeof PARENT_HARNESS_IDENTITY_KEYS)[number][]): Record<string, string>;
|
|
12
|
+
export declare function akumaExecutionEnvironment(inherited: Environment, overrides?: Environment, requests?: string, nativeIdentity?: readonly (typeof PARENT_HARNESS_IDENTITY_KEYS)[number][], execution?: ExecutionCoordinate): Record<string, string>;
|
|
7
13
|
export {};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export const AKUMA_REQUESTS_ENV = "AKUMA_REQUESTS";
|
|
2
2
|
export const AKUMA_REQUESTS_ENTRY_ENV = "AKUMA_REQUESTS_ENTRY";
|
|
3
3
|
const PARENT_HARNESS_IDENTITY_KEYS = [
|
|
4
|
+
"KEIYAKU_BODY_SEQUENCE",
|
|
5
|
+
"KEIYAKU_TURN_SEQUENCE",
|
|
4
6
|
"CLAUDE_CODE_SESSION_ID",
|
|
5
7
|
"CLAUDE_CODE_CHILD_SESSION",
|
|
6
8
|
"CLAUDECODE",
|
|
@@ -14,7 +16,7 @@ const PARENT_HARNESS_IDENTITY_KEYS = [
|
|
|
14
16
|
"KEIYAKU_EXTERNAL_CALLER",
|
|
15
17
|
];
|
|
16
18
|
/** Construct the environment for one isolated Akuma execution or native child. */
|
|
17
|
-
export function akumaExecutionEnvironment(inherited, overrides = {}, requests, nativeIdentity = []) {
|
|
19
|
+
export function akumaExecutionEnvironment(inherited, overrides = {}, requests, nativeIdentity = [], execution) {
|
|
18
20
|
const preserved = Object.fromEntries(nativeIdentity.flatMap((key) => (inherited[key] === undefined ? [] : [[key, inherited[key]]])));
|
|
19
21
|
const environment = Object.fromEntries(Object.entries({ ...inherited, ...overrides }).flatMap(([key, value]) => value === undefined ? [] : [[key, value]]));
|
|
20
22
|
for (const key of PARENT_HARNESS_IDENTITY_KEYS)
|
|
@@ -24,5 +26,12 @@ export function akumaExecutionEnvironment(inherited, overrides = {}, requests, n
|
|
|
24
26
|
delete environment[AKUMA_REQUESTS_ENTRY_ENV];
|
|
25
27
|
if (requests !== undefined)
|
|
26
28
|
environment[AKUMA_REQUESTS_ENV] = requests;
|
|
29
|
+
if (execution !== undefined)
|
|
30
|
+
Object.assign(environment, {
|
|
31
|
+
KEIYAKU_ACTOR_ID: execution.akumaId,
|
|
32
|
+
KEIYAKU_ACTOR_WORLD: execution.world,
|
|
33
|
+
KEIYAKU_BODY_SEQUENCE: String(execution.bodySequence),
|
|
34
|
+
KEIYAKU_TURN_SEQUENCE: String(execution.turnSequence),
|
|
35
|
+
});
|
|
27
36
|
return environment;
|
|
28
37
|
}
|
|
@@ -65,24 +65,31 @@ function optionAdmission(options) {
|
|
|
65
65
|
options,
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
|
-
function grokSessionMeta(config,
|
|
69
|
-
//
|
|
70
|
-
//
|
|
68
|
+
function grokSessionMeta(config, input) {
|
|
69
|
+
// Grok appends rules only when creating a session; ordinary load preserves
|
|
70
|
+
// that immutable execution context without requiring a hot-update channel.
|
|
71
|
+
const options = input.options;
|
|
71
72
|
const sessionMeta = { ...(config ?? {}), askUserQuestion: false };
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
const meta = {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
freshSessionMeta: { ...sessionMeta, ...meta },
|
|
82
|
-
loadSessionMeta: { ...sessionMeta, ...meta },
|
|
73
|
+
const replacement = options.systemPromptMode === "replace" && options.systemPrompt?.trim()
|
|
74
|
+
? options.systemPrompt
|
|
75
|
+
: typeof config?.systemPromptOverride === "string" && config.systemPromptOverride.trim()
|
|
76
|
+
? config.systemPromptOverride
|
|
77
|
+
: undefined;
|
|
78
|
+
if (replacement !== undefined) {
|
|
79
|
+
const meta = {
|
|
80
|
+
...sessionMeta,
|
|
81
|
+
systemPromptOverride: [replacement, input.runtimeInstructions].filter((part) => part !== undefined).join("\n\n"),
|
|
83
82
|
};
|
|
83
|
+
return { freshSessionMeta: meta, loadSessionMeta: meta };
|
|
84
84
|
}
|
|
85
|
-
|
|
85
|
+
const rules = options.systemPromptMode === "append" ? options.systemPrompt : config?.rules;
|
|
86
|
+
const appended = [typeof rules === "string" ? rules : undefined, input.runtimeInstructions]
|
|
87
|
+
.filter((part) => part !== undefined && part.length > 0)
|
|
88
|
+
.join("\n\n");
|
|
89
|
+
return {
|
|
90
|
+
freshSessionMeta: { ...sessionMeta, ...(appended === "" ? {} : { rules: appended }) },
|
|
91
|
+
loadSessionMeta: sessionMeta,
|
|
92
|
+
};
|
|
86
93
|
}
|
|
87
94
|
function argv(execution, options) {
|
|
88
95
|
if (execution.executable === undefined)
|
|
@@ -127,7 +134,7 @@ export function createGrokBuildProvider(execution, dependencies = {}) {
|
|
|
127
134
|
argv: argv(execution, input.options),
|
|
128
135
|
...(execution.env === undefined ? {} : { env: execution.env }),
|
|
129
136
|
};
|
|
130
|
-
const sessionMeta = grokSessionMeta(execution.config, input
|
|
137
|
+
const sessionMeta = grokSessionMeta(execution.config, input);
|
|
131
138
|
live = await startAcpSession(launch, input, {
|
|
132
139
|
...dependencies,
|
|
133
140
|
configureClient: (client) => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ProviderAdapter } from "../provider.js";
|
|
2
2
|
import type { ProviderExecution } from "../provider-recipe.js";
|
|
3
3
|
export { decodeProviderRecipe as decodeProviderExecution } from "../provider-recipe.js";
|
|
4
|
+
export declare function withWritableDirectories(execution: ProviderExecution, cwd: string, directories: readonly string[], signal?: AbortSignal): Promise<ProviderExecution>;
|
|
4
5
|
export declare function resolveProviderExecution(execution: ProviderExecution): Promise<Readonly<{
|
|
5
6
|
execution: ProviderExecution;
|
|
6
7
|
adapter: ProviderAdapter;
|
|
@@ -20,6 +20,14 @@ async function adapterFor(execution) {
|
|
|
20
20
|
return (await import("./pi/index.js")).createPiProvider(execution);
|
|
21
21
|
throw new TypeError(`unknown Akuma provider kind ${execution.kind}`);
|
|
22
22
|
}
|
|
23
|
+
export async function withWritableDirectories(execution, cwd, directories, signal) {
|
|
24
|
+
if (directories.length === 0)
|
|
25
|
+
return execution;
|
|
26
|
+
if (execution.kind !== "codex-app-server")
|
|
27
|
+
throw new TypeError(`writableDirectories is unsupported by provider ${execution.kind}`);
|
|
28
|
+
const { withCodexWritableDirectories } = await import("./codex-app-server/configuration.js");
|
|
29
|
+
return await withCodexWritableDirectories(execution, cwd, directories, signal);
|
|
30
|
+
}
|
|
23
31
|
export async function resolveProviderExecution(execution) {
|
|
24
32
|
return Object.freeze({ execution, adapter: await adapterFor(execution) });
|
|
25
33
|
}
|
|
@@ -181,6 +181,14 @@ async function configureSession(runtime, input, id, info, model) {
|
|
|
181
181
|
// and fork. Updating the same entry announces an upstream instruction change.
|
|
182
182
|
await session.instructions({ id, text: input.options.systemPrompt });
|
|
183
183
|
}
|
|
184
|
+
if (input.runtimeInstructions === undefined) {
|
|
185
|
+
// Native forks copy current entries. Absence must remove the inherited
|
|
186
|
+
// runtime entry, not leave the source identity active in a bare child.
|
|
187
|
+
await session.removeInstruction({ id, key: "keiyaku.runtime" });
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
await session.instructions({ id, key: "keiyaku.runtime", text: input.runtimeInstructions });
|
|
191
|
+
}
|
|
184
192
|
}
|
|
185
193
|
async function openSession(runtime, input) {
|
|
186
194
|
const model = input.options.model === undefined
|
|
@@ -217,6 +225,7 @@ async function openResources(execution, input, loader, custody) {
|
|
|
217
225
|
onRuntime: (ready) => {
|
|
218
226
|
runtimeOwner = ownRuntime(custody, ready);
|
|
219
227
|
},
|
|
228
|
+
...(input.execution === undefined ? {} : { executionCoordinate: input.execution }),
|
|
220
229
|
...(input.requests === undefined ? {} : { requests: input.requests.dir }),
|
|
221
230
|
});
|
|
222
231
|
const stream = ownEventStream({
|
|
@@ -15,6 +15,11 @@ export type OpencodeSdkSession = Readonly<{
|
|
|
15
15
|
instructions(input: {
|
|
16
16
|
id: string;
|
|
17
17
|
text: string;
|
|
18
|
+
key?: string;
|
|
19
|
+
}): Promise<unknown>;
|
|
20
|
+
removeInstruction(input: {
|
|
21
|
+
id: string;
|
|
22
|
+
key: string;
|
|
18
23
|
}): Promise<unknown>;
|
|
19
24
|
active(): Promise<unknown>;
|
|
20
25
|
fork(input: {
|
|
@@ -75,6 +80,7 @@ type LoadOpencodeInput = Readonly<{
|
|
|
75
80
|
signal: AbortSignal;
|
|
76
81
|
loader?: OpencodeSdkLoader;
|
|
77
82
|
onRuntime?: (runtime: OpencodeRuntime) => void;
|
|
83
|
+
executionCoordinate?: import("../execution-environment.js").ExecutionCoordinate;
|
|
78
84
|
requests?: string;
|
|
79
85
|
}>;
|
|
80
86
|
export declare function loadOpencode(input: LoadOpencodeInput): Promise<OpencodeRuntime>;
|
|
@@ -80,7 +80,7 @@ async function loadInjectedOpencode(input, loader) {
|
|
|
80
80
|
const { execution, cwd, signal, onRuntime, requests } = input;
|
|
81
81
|
const loaded = await abortable(loader(cwd, {
|
|
82
82
|
...execution,
|
|
83
|
-
env: akumaExecutionEnvironment(process.env, execution.env, requests),
|
|
83
|
+
env: akumaExecutionEnvironment(process.env, execution.env, requests, [], input.executionCoordinate),
|
|
84
84
|
}, signal), signal);
|
|
85
85
|
let closing;
|
|
86
86
|
const runtime = {
|
|
@@ -117,7 +117,7 @@ async function loadNativeOpencode(input) {
|
|
|
117
117
|
...execution.env,
|
|
118
118
|
OPENCODE_PASSWORD: password,
|
|
119
119
|
OPENCODE_SERVER_PASSWORD: password,
|
|
120
|
-
}, requests),
|
|
120
|
+
}, requests, [], input.executionCoordinate),
|
|
121
121
|
log: `${cwd}/.opencode.log`,
|
|
122
122
|
});
|
|
123
123
|
const native = createNativeClient(`http://127.0.0.1:${port}`, password);
|
|
@@ -129,7 +129,8 @@ async function loadNativeOpencode(input) {
|
|
|
129
129
|
create: async ({ body }) => ({ data: await native.sdk.session.create(body, options) }),
|
|
130
130
|
get: async ({ id }) => ({ data: await native.sdk.session.get({ sessionID: id }, options) }),
|
|
131
131
|
switchModel: ({ id, model }) => native.sdk.session.switchModel({ sessionID: id, model }, options),
|
|
132
|
-
instructions: ({ id, text }) => native.sdk.session.instructions.entry.put({ sessionID: id, key
|
|
132
|
+
instructions: ({ id, text, key = "keiyaku.system" }) => native.sdk.session.instructions.entry.put({ sessionID: id, key, value: text }, options),
|
|
133
|
+
removeInstruction: ({ id, key }) => native.sdk.session.instructions.entry.remove({ sessionID: id, key }, options),
|
|
133
134
|
active: async () => ({ data: await native.sdk.session.active(options) }),
|
|
134
135
|
fork: async ({ id, before }) => ({ data: await native.sdk.session.fork({ sessionID: id, before }, options) }),
|
|
135
136
|
interrupt: ({ id }) => native.sdk.session.interrupt({ sessionID: id, resume: false }),
|
|
@@ -207,6 +207,9 @@ class PaseoDrive {
|
|
|
207
207
|
});
|
|
208
208
|
}
|
|
209
209
|
async establish(input, config, coordinate) {
|
|
210
|
+
const systemPrompt = [input.options.systemPrompt, input.runtimeInstructions]
|
|
211
|
+
.filter((part) => part !== undefined && part.length > 0)
|
|
212
|
+
.join("\n\n");
|
|
210
213
|
const entry = input.requests.entry;
|
|
211
214
|
if (entry === undefined || !isAbsolute(entry) || resolve(entry) !== entry)
|
|
212
215
|
throw new Error("Paseo requires the Body's stable request entry");
|
|
@@ -216,8 +219,11 @@ class PaseoDrive {
|
|
|
216
219
|
? await setup(input.signal, () => this.client.createAgent({
|
|
217
220
|
provider: config.provider,
|
|
218
221
|
cwd: input.cwd,
|
|
219
|
-
...(
|
|
220
|
-
env: {
|
|
222
|
+
...(systemPrompt === "" ? {} : { systemPrompt }),
|
|
223
|
+
env: {
|
|
224
|
+
...akumaExecutionEnvironment(process.env, this.environment, undefined, [], input.execution),
|
|
225
|
+
[AKUMA_REQUESTS_ENTRY_ENV]: entry,
|
|
226
|
+
},
|
|
221
227
|
autoArchive: false,
|
|
222
228
|
}))
|
|
223
229
|
: await this.existingAgent(coordinate, input.signal);
|