@astrosheep/keiyaku 2.8.4 → 2.9.0
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 +35 -15
- package/build/.tsbuildinfo +1 -1
- package/build/agents/{call-terms_v2.js → call-terms.js} +12 -8
- package/build/agents/harness/control-types.js +1 -0
- package/build/agents/harness/execution-handle.js +23 -3
- package/build/agents/harness/index.js +6 -607
- package/build/agents/harness/outcome.js +141 -0
- package/build/agents/harness/projection.js +310 -0
- package/build/agents/harness/router.js +201 -0
- package/build/agents/harness/runtime.js +2 -1
- package/build/agents/{launch-snapshot_v2.js → launch-snapshot/model.js} +69 -74
- package/build/agents/launch-snapshot/resolve.js +72 -0
- package/build/agents/opencode-sdk.js +24 -3
- package/build/agents/providers/{claude-agent-sdk.js → claude-agent-sdk/adapter.js} +46 -368
- package/build/agents/providers/claude-agent-sdk/events.js +218 -0
- package/build/agents/providers/claude-agent-sdk/session.js +158 -0
- package/build/agents/providers/codex-app-server/adapter.js +347 -0
- package/build/agents/providers/codex-app-server/events.js +352 -0
- package/build/agents/providers/codex-app-server/session.js +266 -0
- package/build/agents/providers/codex-sdk.js +23 -5
- package/build/agents/providers/opencode-sdk/adapter.js +344 -0
- package/build/agents/providers/opencode-sdk/events.js +354 -0
- package/build/agents/providers/opencode-sdk/session.js +180 -0
- package/build/agents/providers/pi/adapter.js +269 -0
- package/build/agents/providers/pi/checkpoint.js +41 -0
- package/build/agents/providers/pi/events.js +282 -0
- package/build/agents/{selector_v2.js → selector.js} +8 -6
- package/build/cli/commands/akuma/akuma/handler.js +4 -0
- package/build/cli/commands/akuma/akuma/meta.js +16 -0
- package/build/cli/commands/akuma/catalog.js +8 -0
- package/build/cli/commands/akuma/list/handler.js +15 -0
- package/build/cli/commands/akuma/list/meta-ls.js +9 -0
- package/build/cli/commands/akuma/view/handler.js +34 -0
- package/build/cli/commands/akuma/view/meta.js +8 -0
- package/build/cli/commands/akuma.js +1 -1
- package/build/cli/commands/contract/amend/handler.js +10 -0
- package/build/cli/commands/contract/amend/meta.js +12 -0
- package/build/cli/commands/contract/arc/handler.js +9 -0
- package/build/cli/commands/contract/arc/meta.js +26 -0
- package/build/cli/commands/contract/bind/handler.js +23 -0
- package/build/cli/commands/contract/bind/meta.js +30 -0
- package/build/cli/commands/contract/catalog.js +16 -0
- package/build/cli/commands/contract/forfeit/handler.js +13 -0
- package/build/cli/commands/contract/forfeit/meta.js +12 -0
- package/build/cli/commands/contract/log/handler.js +12 -0
- package/build/cli/commands/contract/log/meta.js +12 -0
- package/build/cli/commands/contract/petition/handler.js +26 -0
- package/build/cli/commands/contract/petition/meta.js +23 -0
- package/build/cli/commands/contract/renew/handler.js +10 -0
- package/build/cli/commands/contract/renew/meta.js +17 -0
- package/build/cli/commands/projection/call/handler.js +39 -0
- package/build/cli/commands/projection/call/meta.js +9 -0
- package/build/cli/commands/projection/catalog.js +14 -0
- package/build/cli/commands/projection/kill/handler.js +35 -0
- package/build/cli/commands/projection/kill/meta.js +11 -0
- package/build/cli/commands/projection/revive/handler.js +53 -0
- package/build/cli/commands/projection/revive/meta.js +9 -0
- package/build/cli/commands/projection/status/handler.js +23 -0
- package/build/cli/commands/projection/status/meta.js +9 -0
- package/build/cli/commands/projection/tell/handler.js +34 -0
- package/build/cli/commands/projection/tell/meta.js +9 -0
- package/build/cli/commands/projection/wait/handler.js +21 -0
- package/build/cli/commands/projection/wait/meta.js +11 -0
- package/build/cli/commands/registry.js +100 -0
- package/build/cli/commands/shared.js +71 -0
- package/build/cli/commands/skills/catalog.js +6 -0
- package/build/cli/commands/skills/install/handler.js +10 -0
- package/build/cli/commands/skills/install/meta.js +9 -0
- package/build/cli/commands/skills/skills/handler.js +4 -0
- package/build/cli/commands/skills/skills/meta.js +10 -0
- package/build/cli/commands/system/catalog.js +8 -0
- package/build/cli/commands/system/completion/handler.js +10 -0
- package/build/cli/commands/system/completion/meta.js +9 -0
- package/build/cli/commands/system/dump-env/handler.js +3 -0
- package/build/cli/commands/system/dump-env/meta.js +10 -0
- package/build/cli/commands/system/guide/handler.js +4 -0
- package/build/cli/commands/system/guide/meta.js +9 -0
- package/build/cli/commands/task/add/handler.js +21 -0
- package/build/cli/commands/task/add/meta.js +8 -0
- package/build/cli/commands/task/catalog.js +22 -0
- package/build/cli/commands/task/doctor/handler.js +4 -0
- package/build/cli/commands/task/doctor/meta.js +8 -0
- package/build/cli/commands/task/done/handler.js +17 -0
- package/build/cli/commands/task/done/meta.js +8 -0
- package/build/cli/commands/task/drop/handler.js +6 -0
- package/build/cli/commands/task/drop/meta.js +8 -0
- package/build/cli/commands/task/ls/handler.js +13 -0
- package/build/cli/commands/task/ls/meta.js +8 -0
- package/build/cli/commands/task/shared.js +131 -0
- package/build/cli/commands/task/start/handler.js +6 -0
- package/build/cli/commands/task/start/meta.js +8 -0
- package/build/cli/commands/task/stop/handler.js +17 -0
- package/build/cli/commands/task/stop/meta.js +8 -0
- package/build/cli/commands/task/task/handler.js +5 -0
- package/build/cli/commands/task/task/meta.js +11 -0
- package/build/cli/commands/task/update/handler.js +18 -0
- package/build/cli/commands/task/update/meta.js +8 -0
- package/build/cli/commands/task/view/handler.js +14 -0
- package/build/cli/commands/task/view/meta.js +8 -0
- package/build/cli/completion.js +26 -27
- package/build/cli/flags.js +79 -2
- package/build/cli/help.js +27 -49
- package/build/cli/index.js +121 -374
- package/build/cli/output-stream-error-policy.js +17 -0
- package/build/cli/parse.js +159 -72
- package/build/cli/projection-address.js +5 -0
- package/build/cli/render/arc.js +1 -1
- package/build/cli/render/errors.js +4 -3
- package/build/cli/render/format.js +14 -0
- package/build/cli/render/kanshi.js +106 -0
- package/build/cli/render/petition.js +24 -1
- package/build/cli/render/projection-activity.js +5 -1
- package/build/cli/render/shared.js +2 -2
- package/build/cli/render/status.js +79 -13
- package/build/cli/render/task.js +113 -0
- package/build/cli/render/wait.js +23 -3
- package/build/cli/types.js +1 -1
- package/build/config/{akuma-loader_v2.js → akuma-loader.js} +2 -2
- package/build/config/env.js +9 -4
- package/build/config/settings/disease.js +26 -0
- package/build/config/settings/knobs.js +8 -0
- package/build/config/settings/loader.js +244 -0
- package/build/config/settings/schema.js +276 -0
- package/build/core/addressing.js +1 -1
- package/build/core/amend.js +3 -3
- package/build/core/arc.js +5 -4
- package/build/core/bind-workspace.js +123 -0
- package/build/core/bind.js +75 -155
- package/build/core/call/call.js +224 -0
- package/build/core/call/context.js +238 -0
- package/build/core/call/execution.js +217 -0
- package/build/core/call/prompt.js +42 -0
- package/build/core/call/reference.js +24 -0
- package/build/core/call-persist.js +1 -1
- package/build/core/claim-delivery.js +247 -0
- package/build/core/claim.js +39 -277
- package/build/core/context.js +2 -1
- package/build/core/{render.js → contract-view.js} +12 -140
- package/build/core/draft.js +107 -9
- package/build/core/entry.js +9 -1
- package/build/core/execution-coordinate.js +4 -20
- package/build/core/execution-pact.js +16 -31
- package/build/core/forfeit.js +35 -22
- package/build/core/hints.js +2 -2
- package/build/core/log.js +2 -2
- package/build/core/petition-claim-gates.js +8 -6
- package/build/core/petition-preview.js +97 -0
- package/build/core/petition-run.js +3 -2
- package/build/core/petition.js +39 -26
- package/build/core/projection/generation/database.js +306 -0
- package/build/core/projection/generation/identity.js +84 -0
- package/build/core/projection/generation/model.js +201 -0
- package/build/core/projection/generation/store.js +73 -0
- package/build/core/projection/generation/transitions.js +258 -0
- package/build/core/projection/heart.js +0 -307
- package/build/core/projection/tell/database.js +109 -0
- package/build/core/projection/tell/model.js +97 -0
- package/build/core/{projection-tells.js → projection/tell/store.js} +3 -158
- package/build/core/projection-activity.js +23 -2
- package/build/core/projection-core.js +2 -1
- package/build/core/projection-execution-observer.js +259 -0
- package/build/core/projection-generation-continuation.js +1 -1
- package/build/core/projection-generation-execution.js +90 -20
- package/build/core/projection-generation-launcher.js +1 -1
- package/build/core/projection-generation-runner.js +198 -4
- package/build/core/projection-identity.js +1 -1
- package/build/core/projection-kill.js +50 -17
- package/build/core/projection-life-observer.js +1 -1
- package/build/core/projection-life-protocol.js +10 -0
- package/build/core/projection-mint.js +1 -1
- package/build/core/projection-status.js +45 -32
- package/build/core/projection-wait.js +12 -2
- package/build/core/projection-wake.js +5 -2
- package/build/core/{queue_v2.js → queue.js} +2 -1
- package/build/core/registry.js +1 -1
- package/build/core/renew.js +7 -7
- package/build/core/response-artifact-catalog-sqlite.js +112 -0
- package/build/core/response-artifact-catalog.js +7 -0
- package/build/core/seal.js +44 -16
- package/build/core/status/board.js +286 -0
- package/build/core/status/drift.js +99 -0
- package/build/core/status/lifecycle.js +84 -0
- package/build/core/status/reconciliation.js +131 -0
- package/build/core/stored-agent-event.js +28 -4
- package/build/core/target-ref.js +10 -0
- package/build/core/task/board.js +175 -0
- package/build/core/task/commands.js +211 -0
- package/build/core/task/document.js +189 -0
- package/build/core/task/model.js +1 -0
- package/build/core/task/settlement-git.js +207 -0
- package/build/core/task/settlement-policy.js +82 -0
- package/build/core/task/source-board.js +84 -0
- package/build/core/task/source-model.js +1 -0
- package/build/core/task/validation.js +44 -0
- package/build/core/task-contract.js +224 -0
- package/build/core/task-doctor.js +14 -0
- package/build/core/task-git-actor.js +38 -0
- package/build/core/task-git-runtime.js +34 -0
- package/build/core/task-git-store.js +375 -0
- package/build/core/task-repository.js +1 -0
- package/build/core/task-store-repository.js +86 -0
- package/build/core/task-store.js +1 -0
- package/build/core/task-worktree.js +51 -0
- package/build/core/task.js +4 -0
- package/build/core/transcripts.js +138 -56
- package/build/core/validation.js +17 -0
- package/build/core/verdict.js +2 -2
- package/build/core/worktree-path.js +24 -6
- package/build/flow-error.js +3 -2
- package/build/generated/version.js +1 -1
- package/build/git/commits.js +3 -0
- package/build/git/diff/parsers.js +0 -94
- package/build/index.js +2 -0
- package/build/keiyaku-constants.js +2 -0
- package/build/keiyaku.js +4 -3
- package/package.json +3 -2
- package/skills/keiyaku/SKILL.md +1 -1
- package/skills/keiyaku-akuma/SKILL.md +11 -6
- package/build/agents/harness/pump.js +0 -158
- package/build/agents/providers/codex-app-server.js +0 -864
- package/build/agents/providers/opencode-sdk.js +0 -363
- package/build/agents/providers/pi.js +0 -557
- package/build/config/settings.js +0 -533
- package/build/core/call.js +0 -686
- package/build/core/projection/generation.js +0 -412
- package/build/core/projection/identity.js +0 -81
- package/build/core/projection/mint.js +0 -174
- package/build/core/projection-generation-store.js +0 -707
- package/build/core/status.js +0 -539
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { appendDebugLog } from "../../../telemetry/debug-log.js";
|
|
3
|
+
import { SUBAGENT_SESSION_VERSION } from "../../session.js";
|
|
4
|
+
import { createProjectionDriver } from "../../harness/execution-handle.js";
|
|
5
|
+
import { buildSubagentEnv, createAbortError, emitProviderEvidence, coerceString } from "../../harness/runtime.js";
|
|
6
|
+
import { CodexAppServerProcess } from "./session.js";
|
|
7
|
+
import { createCodexAppServerTurnMonitor, createCodexAppServerTurnState, recordTurnStartResponse, } from "./events.js";
|
|
8
|
+
/** Identity-only opacity boundary for codex-app-server turn/start effort. */
|
|
9
|
+
function toCodexAppServerEffort(effort) {
|
|
10
|
+
return effort;
|
|
11
|
+
}
|
|
12
|
+
/** Session handle for codex-app-server: thread id plus optional CODEX_HOME for cross-process resume. */
|
|
13
|
+
export const codexAppServerSessionSchema = z.object({
|
|
14
|
+
threadId: z.string().trim().min(1),
|
|
15
|
+
codexHome: z.string().trim().min(1).optional(),
|
|
16
|
+
});
|
|
17
|
+
const CODEX_APP_SERVER_PROVIDER = "codex-app-server";
|
|
18
|
+
const MINIMUM_CODEX_APP_SERVER_VERSION = { major: 0, minor: 143, patch: 0 };
|
|
19
|
+
/** Non-interactive defaults for turn/start (faye #316 policy A). */
|
|
20
|
+
export const CODEX_APP_SERVER_TURN_APPROVAL_POLICY = "never";
|
|
21
|
+
export function buildCodexAppServerWorkspaceWriteSandboxPolicy(input) {
|
|
22
|
+
return {
|
|
23
|
+
type: "workspaceWrite",
|
|
24
|
+
writableRoots: [...input.writableRoots],
|
|
25
|
+
networkAccess: input.networkAccess,
|
|
26
|
+
excludeTmpdirEnvVar: false,
|
|
27
|
+
excludeSlashTmp: false,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** True when config.* already owns approval policy — omit turn-level approvalPolicy default. */
|
|
31
|
+
export function configOwnsApprovalPolicy(config) {
|
|
32
|
+
if (!config)
|
|
33
|
+
return false;
|
|
34
|
+
return Object.prototype.hasOwnProperty.call(config, "approval_policy");
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* True when config.* already owns sandbox settings — omit turn-level sandboxPolicy default.
|
|
38
|
+
* Matches `sandbox_mode` or any `sandbox_workspace_write` / `sandbox_workspace_write.*` key.
|
|
39
|
+
*/
|
|
40
|
+
export function configOwnsSandboxPolicy(config) {
|
|
41
|
+
if (!config)
|
|
42
|
+
return false;
|
|
43
|
+
for (const key of Object.keys(config)) {
|
|
44
|
+
if (key === "sandbox_mode" || key === "sandbox_workspace_write" || key.startsWith("sandbox_workspace_write.")) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
function parseSemver(version) {
|
|
51
|
+
const match = version.trim().match(/(\d+)\.(\d+)\.(\d+)/);
|
|
52
|
+
if (!match)
|
|
53
|
+
return undefined;
|
|
54
|
+
return {
|
|
55
|
+
major: Number(match[1]),
|
|
56
|
+
minor: Number(match[2]),
|
|
57
|
+
patch: Number(match[3]),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export function isCodexAppServerVersionBelowMinimum(version) {
|
|
61
|
+
if (!version)
|
|
62
|
+
return false;
|
|
63
|
+
const parsed = parseSemver(version);
|
|
64
|
+
if (!parsed)
|
|
65
|
+
return false;
|
|
66
|
+
if (parsed.major !== MINIMUM_CODEX_APP_SERVER_VERSION.major) {
|
|
67
|
+
return parsed.major < MINIMUM_CODEX_APP_SERVER_VERSION.major;
|
|
68
|
+
}
|
|
69
|
+
if (parsed.minor !== MINIMUM_CODEX_APP_SERVER_VERSION.minor) {
|
|
70
|
+
return parsed.minor < MINIMUM_CODEX_APP_SERVER_VERSION.minor;
|
|
71
|
+
}
|
|
72
|
+
return parsed.patch < MINIMUM_CODEX_APP_SERVER_VERSION.patch;
|
|
73
|
+
}
|
|
74
|
+
function extractVersionFromInitialize(result) {
|
|
75
|
+
if (!result || typeof result !== "object")
|
|
76
|
+
return undefined;
|
|
77
|
+
const record = result;
|
|
78
|
+
const userAgent = coerceString(record.userAgent);
|
|
79
|
+
if (userAgent) {
|
|
80
|
+
const match = userAgent.match(/(\d+\.\d+\.\d+)/);
|
|
81
|
+
if (match)
|
|
82
|
+
return match[1];
|
|
83
|
+
}
|
|
84
|
+
return coerceString(record.version) ?? coerceString(record.cliVersion);
|
|
85
|
+
}
|
|
86
|
+
/** Gate-facing production entry: the harness owns clocks, capture, classification, and outcome construction. */
|
|
87
|
+
export async function startCodexAppServer(prompt, cwd, options = {}) {
|
|
88
|
+
const executable = options.executable?.trim() || "codex";
|
|
89
|
+
const resumeThreadId = options.threadId?.trim();
|
|
90
|
+
let server;
|
|
91
|
+
const turnState = createCodexAppServerTurnState();
|
|
92
|
+
let activeThreadId;
|
|
93
|
+
let interruptRequested = false;
|
|
94
|
+
let builderDiagnostic;
|
|
95
|
+
let emitTurnStarted;
|
|
96
|
+
const pendingTells = [];
|
|
97
|
+
let drainingTells = false;
|
|
98
|
+
let failActiveTurn;
|
|
99
|
+
let finishAfterTellDrain;
|
|
100
|
+
const rejectPendingTells = (error) => {
|
|
101
|
+
for (const pending of pendingTells.splice(0))
|
|
102
|
+
pending.reject(error);
|
|
103
|
+
};
|
|
104
|
+
appendDebugLog(`startCodexAppServer: executable=${executable} model=${options.model ?? "default"} mode=${resumeThreadId ? "resume" : "fresh"}`, { cwd, section: CODEX_APP_SERVER_PROVIDER });
|
|
105
|
+
const submitSteer = async (tell, turnId) => {
|
|
106
|
+
// turn/steer response {turnId} = enqueue acceptance (submitted), not consumption.
|
|
107
|
+
// clientUserMessageId = tell.id for later delivered proof via userMessage item clientId.
|
|
108
|
+
// tell.text is already core-rendered; send byte-for-byte — never parse or rewrite.
|
|
109
|
+
const ack = await server.request("turn/steer", {
|
|
110
|
+
threadId: activeThreadId,
|
|
111
|
+
expectedTurnId: turnId,
|
|
112
|
+
clientUserMessageId: tell.id,
|
|
113
|
+
input: [{ type: "text", text: tell.text }],
|
|
114
|
+
});
|
|
115
|
+
const acknowledgedTurnId = coerceString(ack.turnId) ?? turnId;
|
|
116
|
+
if (acknowledgedTurnId !== turnId) {
|
|
117
|
+
throw new Error(`${CODEX_APP_SERVER_PROVIDER} turn/steer acknowledgement mismatched active turn: expected=${turnId}, actual=${acknowledgedTurnId}`);
|
|
118
|
+
}
|
|
119
|
+
// Accepted same-native-turn steer opens the next public conversation turn.
|
|
120
|
+
emitTurnStarted?.();
|
|
121
|
+
if (options.onEvidence) {
|
|
122
|
+
emitProviderEvidence(options.onEvidence, {
|
|
123
|
+
type: "ack",
|
|
124
|
+
provider: CODEX_APP_SERVER_PROVIDER,
|
|
125
|
+
fence: { kind: "turn", turnId: acknowledgedTurnId },
|
|
126
|
+
outbound: "steer",
|
|
127
|
+
}, builderDiagnostic);
|
|
128
|
+
}
|
|
129
|
+
return { fence: { kind: "turn", turnId: acknowledgedTurnId } };
|
|
130
|
+
};
|
|
131
|
+
const startTellTurn = async (tell) => {
|
|
132
|
+
const started = await server.request("turn/start", {
|
|
133
|
+
threadId: activeThreadId,
|
|
134
|
+
input: [{ type: "text", text: tell.text }],
|
|
135
|
+
...(options.model ? { model: options.model } : {}),
|
|
136
|
+
...(tell.effort ? { effort: toCodexAppServerEffort(tell.effort) } : {}),
|
|
137
|
+
...(!configOwnsApprovalPolicy(options.config) ? { approvalPolicy: options.approvalPolicy ?? CODEX_APP_SERVER_TURN_APPROVAL_POLICY } : {}),
|
|
138
|
+
...(!configOwnsSandboxPolicy(options.config)
|
|
139
|
+
? {
|
|
140
|
+
sandboxPolicy: options.sandboxPolicy ?? buildCodexAppServerWorkspaceWriteSandboxPolicy({
|
|
141
|
+
writableRoots: [cwd],
|
|
142
|
+
networkAccess: false,
|
|
143
|
+
}),
|
|
144
|
+
}
|
|
145
|
+
: {}),
|
|
146
|
+
});
|
|
147
|
+
const startedTurn = started && typeof started === "object"
|
|
148
|
+
? (started.turn ?? undefined)
|
|
149
|
+
: undefined;
|
|
150
|
+
const newTurnId = recordTurnStartResponse(turnState, startedTurn?.id);
|
|
151
|
+
if (options.onEvidence)
|
|
152
|
+
emitProviderEvidence(options.onEvidence, { type: "ack", provider: CODEX_APP_SERVER_PROVIDER, fence: { kind: "turn", turnId: newTurnId }, outbound: "run" }, builderDiagnostic);
|
|
153
|
+
return { fence: { kind: "turn", turnId: newTurnId } };
|
|
154
|
+
};
|
|
155
|
+
const drainPendingTells = async () => {
|
|
156
|
+
if (drainingTells)
|
|
157
|
+
return;
|
|
158
|
+
drainingTells = true;
|
|
159
|
+
try {
|
|
160
|
+
while (pendingTells.length > 0 && server && activeThreadId) {
|
|
161
|
+
const pending = pendingTells[0];
|
|
162
|
+
if (pending.tell.effort && turnState.activeTurnId)
|
|
163
|
+
return;
|
|
164
|
+
if (!pending.tell.effort && turnState.activeTurnId && !turnState.activeTurnAcceptingSteer)
|
|
165
|
+
return;
|
|
166
|
+
pendingTells.shift();
|
|
167
|
+
try {
|
|
168
|
+
const ack = turnState.activeTurnId
|
|
169
|
+
? await submitSteer(pending.tell, turnState.activeTurnId)
|
|
170
|
+
: await startTellTurn(pending.tell);
|
|
171
|
+
pending.resolve(ack);
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
pending.reject(error);
|
|
175
|
+
failActiveTurn?.(error);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
finally {
|
|
181
|
+
drainingTells = false;
|
|
182
|
+
const finish = finishAfterTellDrain;
|
|
183
|
+
finishAfterTellDrain = undefined;
|
|
184
|
+
finish?.();
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const enqueue = async (tell) => {
|
|
188
|
+
if (!server || !activeThreadId) {
|
|
189
|
+
throw new Error(`${CODEX_APP_SERVER_PROVIDER} cannot steer: no active turn`);
|
|
190
|
+
}
|
|
191
|
+
return await new Promise((resolve, reject) => {
|
|
192
|
+
pendingTells.push({ tell, resolve, reject });
|
|
193
|
+
void drainPendingTells();
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
return createProjectionDriver({
|
|
197
|
+
steerMode: "mid-execution",
|
|
198
|
+
initialTurn: options.initialTurn,
|
|
199
|
+
enqueue,
|
|
200
|
+
onIngress: options.onIngress,
|
|
201
|
+
async abort(mode) {
|
|
202
|
+
interruptRequested = true;
|
|
203
|
+
if (mode === "force") {
|
|
204
|
+
await server?.close("force");
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (server && activeThreadId && turnState.activeTurnId) {
|
|
208
|
+
try {
|
|
209
|
+
// RPC acknowledgement is NOT terminal proof; wait for turn/completed interrupted.
|
|
210
|
+
await server.request("turn/interrupt", {
|
|
211
|
+
threadId: activeThreadId,
|
|
212
|
+
turnId: turnState.activeTurnId,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
// idle interrupt may error; still rely on process teardown
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
await server?.close("graceful");
|
|
220
|
+
},
|
|
221
|
+
async run(builder) {
|
|
222
|
+
builderDiagnostic = (text) => builder.emit({ type: "diagnostic", text });
|
|
223
|
+
emitTurnStarted = () => builder.emit({ type: "turn", phase: "started" });
|
|
224
|
+
const env = buildSubagentEnv(options.env);
|
|
225
|
+
server = new CodexAppServerProcess(executable, env, options.codexHome, options.onEvidence, (text) => builder.emit({ type: "diagnostic", text }));
|
|
226
|
+
const { turnCompleted } = createCodexAppServerTurnMonitor({
|
|
227
|
+
server,
|
|
228
|
+
builder,
|
|
229
|
+
state: turnState,
|
|
230
|
+
builderDiagnostic,
|
|
231
|
+
onEvidence: options.onEvidence,
|
|
232
|
+
onSyncCheckpoint: options.onSyncCheckpoint,
|
|
233
|
+
onDeliveryOpportunity: options.onDeliveryOpportunity,
|
|
234
|
+
enqueue,
|
|
235
|
+
drainPendingTells: () => { void drainPendingTells(); },
|
|
236
|
+
rejectPendingTells,
|
|
237
|
+
setFailActiveTurn: (fail) => { failActiveTurn = fail; },
|
|
238
|
+
pendingTellCount: () => pendingTells.length,
|
|
239
|
+
isDrainingTells: () => drainingTells,
|
|
240
|
+
setFinishAfterTellDrain: (finish) => { finishAfterTellDrain = finish; },
|
|
241
|
+
});
|
|
242
|
+
try {
|
|
243
|
+
const initResult = await server.request("initialize", {
|
|
244
|
+
clientInfo: {
|
|
245
|
+
name: "keiyaku",
|
|
246
|
+
title: "keiyaku",
|
|
247
|
+
version: "0.0.0",
|
|
248
|
+
},
|
|
249
|
+
capabilities: {
|
|
250
|
+
experimentalApi: false,
|
|
251
|
+
requestAttestation: false,
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
const version = extractVersionFromInitialize(initResult);
|
|
255
|
+
if (isCodexAppServerVersionBelowMinimum(version)) {
|
|
256
|
+
const message = `${CODEX_APP_SERVER_PROVIDER} refused: initialize version '${version}' is below minimum supported version 0.143.0`;
|
|
257
|
+
builder.emit({ type: "fail", message });
|
|
258
|
+
throw new Error(message);
|
|
259
|
+
}
|
|
260
|
+
const initRecord = (initResult && typeof initResult === "object" ? initResult : {});
|
|
261
|
+
const serverCodexHome = coerceString(initRecord.codexHome) ?? options.codexHome;
|
|
262
|
+
server.notify("initialized");
|
|
263
|
+
const threadParams = {
|
|
264
|
+
cwd,
|
|
265
|
+
...(options.model ? { model: options.model } : {}),
|
|
266
|
+
...(options.config ? { config: options.config } : {}),
|
|
267
|
+
...(options.developerInstructions ? { developerInstructions: options.developerInstructions } : {}),
|
|
268
|
+
};
|
|
269
|
+
const threadResult = resumeThreadId
|
|
270
|
+
? await server.request("thread/resume", {
|
|
271
|
+
threadId: resumeThreadId,
|
|
272
|
+
...threadParams,
|
|
273
|
+
})
|
|
274
|
+
: await server.request("thread/start", threadParams);
|
|
275
|
+
const thread = threadResult && typeof threadResult === "object"
|
|
276
|
+
? (threadResult.thread ??
|
|
277
|
+
threadResult)
|
|
278
|
+
: undefined;
|
|
279
|
+
activeThreadId = coerceString(thread?.id) ?? resumeThreadId;
|
|
280
|
+
if (!activeThreadId) {
|
|
281
|
+
const message = `${CODEX_APP_SERVER_PROVIDER} exec could not determine thread id`;
|
|
282
|
+
builder.emit({ type: "fail", message });
|
|
283
|
+
throw new Error(message);
|
|
284
|
+
}
|
|
285
|
+
if (options.onEvidence)
|
|
286
|
+
emitProviderEvidence(options.onEvidence, { type: "session", provider: CODEX_APP_SERVER_PROVIDER, threadId: activeThreadId }, builderDiagnostic);
|
|
287
|
+
// Policy A defaults, but omit when config.* already owns that surface (thread/start config wins).
|
|
288
|
+
const turnStartParams = {
|
|
289
|
+
threadId: activeThreadId,
|
|
290
|
+
input: [{ type: "text", text: prompt }],
|
|
291
|
+
...(options.model ? { model: options.model } : {}),
|
|
292
|
+
...(options.effort ? { effort: toCodexAppServerEffort(options.effort) } : {}),
|
|
293
|
+
};
|
|
294
|
+
if (!configOwnsApprovalPolicy(options.config)) {
|
|
295
|
+
turnStartParams.approvalPolicy = options.approvalPolicy ?? CODEX_APP_SERVER_TURN_APPROVAL_POLICY;
|
|
296
|
+
}
|
|
297
|
+
if (!configOwnsSandboxPolicy(options.config)) {
|
|
298
|
+
turnStartParams.sandboxPolicy = options.sandboxPolicy ?? buildCodexAppServerWorkspaceWriteSandboxPolicy({
|
|
299
|
+
writableRoots: [cwd],
|
|
300
|
+
networkAccess: false,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
turnState.activeTurnId = undefined;
|
|
304
|
+
turnState.activeTurnSource = undefined;
|
|
305
|
+
turnState.activeTurnAcceptingSteer = false;
|
|
306
|
+
const turnStart = await server.request("turn/start", turnStartParams);
|
|
307
|
+
const turn = turnStart && typeof turnStart === "object"
|
|
308
|
+
? (turnStart.turn ?? undefined)
|
|
309
|
+
: undefined;
|
|
310
|
+
const turnId = recordTurnStartResponse(turnState, turn?.id);
|
|
311
|
+
if (options.onEvidence)
|
|
312
|
+
emitProviderEvidence(options.onEvidence, { type: "checkpoint", provider: CODEX_APP_SERVER_PROVIDER, fence: { kind: "turn", turnId }, source: "response" }, builderDiagnostic);
|
|
313
|
+
const completed = await turnCompleted;
|
|
314
|
+
if (completed.status === "interrupted" || interruptRequested) {
|
|
315
|
+
throw createAbortError(`${CODEX_APP_SERVER_PROVIDER} turn interrupted`);
|
|
316
|
+
}
|
|
317
|
+
if (completed.status === "failed") {
|
|
318
|
+
const message = `${CODEX_APP_SERVER_PROVIDER} turn failed`;
|
|
319
|
+
builder.emit({ type: "fail", message });
|
|
320
|
+
throw new Error(message);
|
|
321
|
+
}
|
|
322
|
+
if (completed.status !== "completed") {
|
|
323
|
+
const message = `${CODEX_APP_SERVER_PROVIDER} turn ended with status '${completed.status}'`;
|
|
324
|
+
builder.emit({ type: "fail", message });
|
|
325
|
+
throw new Error(message);
|
|
326
|
+
}
|
|
327
|
+
// Successful turn/completed is consumption evidence; interrupt ack alone is not terminal proof.
|
|
328
|
+
const session = {
|
|
329
|
+
provider: "codex-app-server",
|
|
330
|
+
version: SUBAGENT_SESSION_VERSION,
|
|
331
|
+
handle: {
|
|
332
|
+
threadId: activeThreadId,
|
|
333
|
+
...(serverCodexHome ? { codexHome: serverCodexHome } : {}),
|
|
334
|
+
},
|
|
335
|
+
};
|
|
336
|
+
const finalMessage = turnState.lastAgentMessage;
|
|
337
|
+
builder.emit({ type: "done", finalMessage, session });
|
|
338
|
+
return { finalMessage, session };
|
|
339
|
+
}
|
|
340
|
+
finally {
|
|
341
|
+
rejectPendingTells(new Error(`${CODEX_APP_SERVER_PROVIDER} execution ended before queued tell acceptance`));
|
|
342
|
+
await server?.close();
|
|
343
|
+
server = undefined;
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
});
|
|
347
|
+
}
|