@fitlab-ai/agent-infra 0.11.11 → 0.11.13
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/dist/bin/internal-cli.js +2 -2
- package/dist/lib/agent-clients/adapter.js +7 -1
- package/dist/lib/agent-clients/adapters/claude-code.js +5 -1
- package/dist/lib/agent-clients/adapters/codex-lifecycle/app-server.js +78 -63
- package/dist/lib/agent-clients/adapters/codex-lifecycle/binding.js +114 -0
- package/dist/lib/agent-clients/adapters/codex-lifecycle/cli.js +447 -0
- package/dist/lib/agent-clients/adapters/codex-lifecycle/controller-client.js +130 -0
- package/dist/lib/agent-clients/adapters/codex-lifecycle/controller-operation.js +131 -0
- package/dist/lib/{sandbox/control → agent-clients/adapters/codex-lifecycle}/controller-registration.js +2 -2
- package/dist/lib/agent-clients/adapters/codex-lifecycle/evidence.js +48 -1
- package/dist/lib/agent-clients/adapters/codex-lifecycle/recovery.js +124 -62
- package/dist/lib/{internal/codex-sandbox-controller.js → agent-clients/adapters/codex-lifecycle/sandbox-controller-cli.js} +3 -3
- package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +3 -5
- package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +211 -213
- package/dist/lib/agent-clients/adapters/codex-orchestration.js +468 -0
- package/dist/lib/agent-clients/adapters/codex.js +40 -1
- package/dist/lib/agent-clients/adapters/index.js +2 -10
- package/dist/lib/agent-clients/tokens.js +3 -2
- package/dist/lib/internal/agent-client.js +132 -72
- package/dist/lib/internal/cli-route-inventory.js +2 -2
- package/dist/lib/internal/sandbox-control.js +1 -81
- package/dist/lib/internal/task-finalization.js +26 -19
- package/dist/lib/internal/task-lifecycle.js +1 -1
- package/dist/lib/internal/task-operation-registry.js +1 -1
- package/dist/lib/internal/task-validate.js +1 -1
- package/dist/lib/platform/github-client.js +33 -3
- package/dist/lib/platform/issues.js +18 -6
- package/dist/lib/runtime/agent-runtime.js +6 -29
- package/dist/lib/sandbox/commands/control-status.js +1 -0
- package/dist/lib/sandbox/commands/create.js +7 -2
- package/dist/lib/sandbox/commands/ls.js +4 -5
- package/dist/lib/sandbox/commands/rm.js +1 -1
- package/dist/lib/sandbox/control/agent-operation.js +34 -0
- package/dist/lib/sandbox/control/client.js +14 -201
- package/dist/lib/sandbox/control/executor.js +12 -125
- package/dist/lib/sandbox/control/lifecycle.js +66 -4
- package/dist/lib/sandbox/control/protocol.js +15 -54
- package/dist/lib/sandbox/control/server.js +216 -281
- package/dist/lib/sandbox/control/task-view.js +0 -13
- package/dist/lib/sandbox/mounts.js +9 -1
- package/dist/lib/sandbox/recovery.js +31 -10
- package/dist/lib/sandbox/removal.js +28 -5
- package/dist/lib/sandbox/workspace-identity.js +18 -6
- package/dist/lib/sandbox/workspace-view.js +56 -19
- package/dist/lib/task/commands/ls.js +3 -3
- package/dist/lib/task/control-authority.js +56 -264
- package/dist/lib/task/control-recovery.js +2 -3
- package/dist/lib/task/create.js +2 -2
- package/dist/lib/task/delegation-receipts.js +74 -161
- package/dist/lib/task/events.js +88 -44
- package/dist/lib/task/finalization.js +35 -6
- package/dist/lib/task/lifecycle.js +274 -115
- package/dist/lib/task/orchestration.js +201 -194
- package/dist/lib/task/runtime-paths.js +10 -0
- package/dist/lib/task/short-id.js +37 -27
- package/dist/lib/task/verification-engine.js +32 -26
- package/dist/lib/task/workspace-snapshot.js +1 -1
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-clients/adapter.ts +39 -0
- package/lib/agent-clients/adapters/claude-code.ts +5 -1
- package/lib/agent-clients/adapters/codex-lifecycle/app-server.ts +105 -80
- package/lib/agent-clients/adapters/codex-lifecycle/binding.ts +147 -0
- package/lib/agent-clients/adapters/codex-lifecycle/cli.ts +510 -0
- package/lib/agent-clients/adapters/codex-lifecycle/controller-client.ts +158 -0
- package/lib/agent-clients/adapters/codex-lifecycle/controller-context.ts +1 -1
- package/lib/agent-clients/adapters/codex-lifecycle/controller-operation.ts +151 -0
- package/lib/{sandbox/control → agent-clients/adapters/codex-lifecycle}/controller-registration.ts +4 -4
- package/lib/agent-clients/adapters/codex-lifecycle/evidence.ts +43 -0
- package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +8 -5
- package/lib/agent-clients/adapters/codex-lifecycle/recovery.ts +190 -65
- package/lib/{internal/codex-sandbox-controller.ts → agent-clients/adapters/codex-lifecycle/sandbox-controller-cli.ts} +2 -2
- package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +3 -5
- package/lib/agent-clients/adapters/codex-lifecycle/store.ts +270 -224
- package/lib/agent-clients/adapters/codex-orchestration.ts +632 -0
- package/lib/agent-clients/adapters/codex.ts +44 -1
- package/lib/agent-clients/adapters/index.ts +7 -20
- package/lib/agent-clients/tokens.ts +4 -3
- package/lib/internal/agent-client.ts +142 -73
- package/lib/internal/cli-route-inventory.ts +2 -2
- package/lib/internal/sandbox-control.ts +0 -97
- package/lib/internal/task-finalization.ts +30 -18
- package/lib/internal/task-lifecycle.ts +1 -1
- package/lib/internal/task-operation-registry.ts +1 -1
- package/lib/internal/task-validate.ts +1 -1
- package/lib/platform/github-client.ts +34 -3
- package/lib/platform/issues.ts +18 -6
- package/lib/runtime/agent-runtime.ts +6 -41
- package/lib/sandbox/commands/control-status.ts +1 -0
- package/lib/sandbox/commands/create.ts +7 -1
- package/lib/sandbox/commands/ls.ts +4 -5
- package/lib/sandbox/commands/rm.ts +1 -1
- package/lib/sandbox/control/agent-operation.ts +49 -0
- package/lib/sandbox/control/client.ts +20 -254
- package/lib/sandbox/control/executor.ts +13 -136
- package/lib/sandbox/control/lifecycle.ts +67 -4
- package/lib/sandbox/control/protocol.ts +22 -66
- package/lib/sandbox/control/server.ts +21 -95
- package/lib/sandbox/control/task-view.ts +0 -19
- package/lib/sandbox/mounts.ts +10 -1
- package/lib/sandbox/recovery.ts +38 -17
- package/lib/sandbox/removal.ts +33 -7
- package/lib/sandbox/workspace-identity.ts +16 -6
- package/lib/sandbox/workspace-view.ts +50 -18
- package/lib/task/commands/ls.ts +3 -3
- package/lib/task/control-authority.ts +66 -378
- package/lib/task/control-recovery.ts +3 -4
- package/lib/task/create.ts +3 -3
- package/lib/task/delegation-receipts.ts +87 -231
- package/lib/task/events.ts +100 -42
- package/lib/task/finalization.ts +37 -7
- package/lib/task/lifecycle.ts +257 -109
- package/lib/task/orchestration.ts +260 -237
- package/lib/task/runtime-paths.ts +12 -0
- package/lib/task/short-id.ts +33 -40
- package/lib/task/verification-engine.ts +30 -25
- package/lib/task/workspace-snapshot.ts +1 -1
- package/package.json +1 -1
- package/templates/.agents/hooks/lifecycle-delegation.js +1 -25
- package/templates/.agents/rules/README.en.md +2 -1
- package/templates/.agents/rules/README.zh-CN.md +2 -1
- package/templates/.agents/rules/next-step-output.en.md +6 -19
- package/templates/.agents/rules/next-step-output.zh-CN.md +6 -19
- package/templates/.agents/rules/strategy-pattern.en.md +25 -0
- package/templates/.agents/rules/strategy-pattern.zh-CN.md +25 -0
- package/templates/.agents/skills/analyze-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/check-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/code-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/code-task/reference/code-rules.en.md +4 -0
- package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +4 -0
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +0 -1
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +0 -1
- package/templates/.agents/skills/complete-task/SKILL.en.md +5 -29
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +5 -26
- package/templates/.agents/skills/plan-task/SKILL.en.md +7 -4
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +7 -4
- package/templates/.agents/skills/review-analysis/SKILL.en.md +1 -1
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/review-code/SKILL.en.md +1 -1
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/review-plan/SKILL.en.md +1 -1
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/run-manual-validation/SKILL.en.md +1 -1
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
- package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +0 -546
- package/dist/lib/internal/codex-lifecycle.js +0 -385
- package/dist/lib/task/codex-orchestration.js +0 -206
- package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +0 -776
- package/lib/internal/codex-lifecycle.ts +0 -390
- package/lib/task/codex-orchestration.ts +0 -276
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
import { preflightCodexLifecycleEvidence, resolveCodexSpawnedChild, resolveCodexTerminal, resolveCodexThread } from './codex-lifecycle/app-server.js';
|
|
2
|
+
import { createCodexLifecycleStore } from './codex-lifecycle/store.js';
|
|
3
|
+
import { computeLifecycleBuildIdentity, } from './codex-lifecycle/build-identity.js';
|
|
4
|
+
import { resolveTaskRef } from '../../task/resolve-ref.js';
|
|
5
|
+
import { activateMatchingOrchestrationDelegation, hasActivatableOrchestrationDelegation, hasSealableOrchestrationDelegation, OrchestrationStateError, pauseMatchingOrchestrationDelegation, prepareOrchestrationDelegation, reconcileMatchingOrchestrationDelegation, readDelegationAdapterEvidence, readRun, sealMatchingOrchestrationDelegation } from '../../task/orchestration.js';
|
|
6
|
+
import { managedDelegationRole } from '../../task/delegation-receipts.js';
|
|
7
|
+
import { encodeCodexLifecycleBinding, parseCodexLifecycleBinding, verifyCodexLifecycleTaskBinding } from './codex-lifecycle/binding.js';
|
|
8
|
+
import { reduceCodexLifecycleEvent } from './codex-lifecycle/evidence.js';
|
|
9
|
+
function coreOptions(options) {
|
|
10
|
+
return {
|
|
11
|
+
...options.orchestrationOptions,
|
|
12
|
+
repoRoot: options.repoRoot ?? options.orchestrationOptions?.repoRoot,
|
|
13
|
+
taskId: options.orchestrationOptions?.taskId ?? options.store?.taskId ?? undefined
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function taskRunMatchesReceipt(run, binding, nativeAgent) {
|
|
17
|
+
const receipt = run?.pendingDelegation;
|
|
18
|
+
const role = nativeAgent.endsWith('reviewer') ? 'reviewer' : 'executor';
|
|
19
|
+
return run?.status === 'running'
|
|
20
|
+
&& receipt?.runId === binding.runId
|
|
21
|
+
&& receipt.id === binding.receiptId
|
|
22
|
+
&& receipt.client === 'codex'
|
|
23
|
+
&& receipt.role === role;
|
|
24
|
+
}
|
|
25
|
+
function recordMatchesTaskReceipt(childThreadId, options) {
|
|
26
|
+
const store = requiredStore(options);
|
|
27
|
+
let record;
|
|
28
|
+
try {
|
|
29
|
+
record = store.read(childThreadId);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
throw new Error(`CODEX_LIFECYCLE_TASK_BINDING_MISMATCH: ${error instanceof Error ? error.message : String(error)}`);
|
|
33
|
+
}
|
|
34
|
+
const binding = record.taskBinding;
|
|
35
|
+
if (!binding)
|
|
36
|
+
throw new Error('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH: lifecycle record has no receipt binding');
|
|
37
|
+
const repoRoot = options.repoRoot ?? options.orchestrationOptions?.repoRoot ?? process.cwd();
|
|
38
|
+
const resolved = resolveTaskRef(binding.taskId, { repoRoot });
|
|
39
|
+
if (!resolved.ok)
|
|
40
|
+
throw new Error(`${resolved.code}: ${resolved.message}`);
|
|
41
|
+
const run = readRun(resolved.taskDir);
|
|
42
|
+
const nativeAgent = record.state.startEvidence?.nativeAgent ?? record.state.spawn?.nativeAgent ?? '';
|
|
43
|
+
if (!taskRunMatchesReceipt(run, binding, nativeAgent)) {
|
|
44
|
+
throw new Error('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH: lifecycle record does not match the current pending task receipt');
|
|
45
|
+
}
|
|
46
|
+
const receipt = run.pendingDelegation;
|
|
47
|
+
return { store, record, binding, resolved, run, receipt };
|
|
48
|
+
}
|
|
49
|
+
function sameTaskReceipt(left, right) {
|
|
50
|
+
return left.runId === right.runId && left.id === right.id;
|
|
51
|
+
}
|
|
52
|
+
function sameLifecycleRevision(left, right) {
|
|
53
|
+
return left.revision === right.revision
|
|
54
|
+
&& sameTaskBinding(left.taskBinding, right.taskBinding);
|
|
55
|
+
}
|
|
56
|
+
function sameTaskBinding(left, right) {
|
|
57
|
+
return left?.runId === right?.runId
|
|
58
|
+
&& left?.receiptId === right?.receiptId;
|
|
59
|
+
}
|
|
60
|
+
function isBindingFailure(message) {
|
|
61
|
+
return /CODEX_LIFECYCLE_TASK_BINDING_MISMATCH|CODEX_EVIDENCE_(?:IDENTITY_MISMATCH|PARENT_MISMATCH|REPLAY_CONFLICT)|task binding|identity mismatch|ambiguous active children/iu.test(message);
|
|
62
|
+
}
|
|
63
|
+
function codexSealFailure(error, options, source) {
|
|
64
|
+
if (error instanceof OrchestrationStateError)
|
|
65
|
+
return bridgeFailure(error.code, error.message);
|
|
66
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
67
|
+
if (message === 'CODEX_TURN_NOT_TERMINAL') {
|
|
68
|
+
return source === 'parent'
|
|
69
|
+
? bridgeFailure('ORCHESTRATION_DELEGATION_MISSING', 'The matching Codex child has not completed')
|
|
70
|
+
: pauseBridge('ORCHESTRATION_CODEX_STOP_FAILED', message, options);
|
|
71
|
+
}
|
|
72
|
+
if (isBindingFailure(message))
|
|
73
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', message);
|
|
74
|
+
return pauseBridge('ORCHESTRATION_CODEX_STOP_FAILED', message, options);
|
|
75
|
+
}
|
|
76
|
+
function sameBoundLifecycleRecord(bound, current) {
|
|
77
|
+
return sameTaskReceipt(bound.receipt, current.receipt)
|
|
78
|
+
&& sameLifecycleRevision(bound.record, current.record);
|
|
79
|
+
}
|
|
80
|
+
function candidateActivationState(state, events) {
|
|
81
|
+
return events.reduce((current, event) => reduceCodexLifecycleEvent(current, event), state);
|
|
82
|
+
}
|
|
83
|
+
function candidateActivationFailure(state, options) {
|
|
84
|
+
if (state.status === 'invalid') {
|
|
85
|
+
return bridgeFailure(state.error?.code ?? 'CODEX_EVIDENCE_IDENTITY_MISMATCH', state.error?.message ?? 'Codex lifecycle identity does not match');
|
|
86
|
+
}
|
|
87
|
+
if (state.status !== 'start-ready' || !state.startEvidence) {
|
|
88
|
+
return pauseBridge('ORCHESTRATION_CODEX_START_EVIDENCE_INVALID', 'Codex lifecycle start evidence is not ready', options);
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
async function collectActivationEvidence(childThreadId, options, bound) {
|
|
93
|
+
const resolved = await (options.resolveThread ?? resolveCodexThread)(childThreadId);
|
|
94
|
+
const current = recordMatchesTaskReceipt(childThreadId, options);
|
|
95
|
+
if (!sameBoundLifecycleRecord(bound, current)) {
|
|
96
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', 'task receipt or lifecycle revision changed while resolving Codex child evidence');
|
|
97
|
+
}
|
|
98
|
+
const candidateEvents = [resolved.resolution.thread, ...resolved.reroutes, resolved.resolution.settings];
|
|
99
|
+
const candidateState = candidateActivationState(bound.record.state, candidateEvents);
|
|
100
|
+
const candidateFailure = candidateActivationFailure(candidateState, options);
|
|
101
|
+
if (candidateFailure)
|
|
102
|
+
return candidateFailure;
|
|
103
|
+
const evidence = candidateState.startEvidence;
|
|
104
|
+
const repoRoot = options.repoRoot ?? process.cwd();
|
|
105
|
+
const preflight = await (options.preflight ?? preflightCodexLifecycleEvidence)(repoRoot, {
|
|
106
|
+
sessionId: evidence.parentThreadId,
|
|
107
|
+
turnId: evidence.parentTurnId,
|
|
108
|
+
toolUseId: evidence.spawnToolUseId
|
|
109
|
+
});
|
|
110
|
+
const afterPreflight = recordMatchesTaskReceipt(childThreadId, options);
|
|
111
|
+
if (!sameBoundLifecycleRecord(bound, afterPreflight)) {
|
|
112
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', 'task receipt or lifecycle revision changed while validating Codex host evidence');
|
|
113
|
+
}
|
|
114
|
+
return { preflight, events: candidateEvents, evidence };
|
|
115
|
+
}
|
|
116
|
+
function applyCollectedActivationEvidence(childThreadId, options, store, bound, events) {
|
|
117
|
+
const current = recordMatchesTaskReceipt(childThreadId, options);
|
|
118
|
+
if (!sameBoundLifecycleRecord(bound, current)) {
|
|
119
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', 'task receipt or lifecycle revision changed before Codex activation');
|
|
120
|
+
}
|
|
121
|
+
for (const event of events)
|
|
122
|
+
store.apply(event);
|
|
123
|
+
const record = store.read(childThreadId);
|
|
124
|
+
return record.state.status === 'start-ready' && record.state.startEvidence
|
|
125
|
+
? record
|
|
126
|
+
: bridgeFailure('CODEX_EVIDENCE_IDENTITY_MISMATCH', 'Codex lifecycle identity changed before activation');
|
|
127
|
+
}
|
|
128
|
+
function bridgeFailure(code, message) {
|
|
129
|
+
return {
|
|
130
|
+
status: 'failed', changed: false, taskId: null, run: null, next: null,
|
|
131
|
+
error: { code, message }
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function pauseBridge(code, message, options) {
|
|
135
|
+
const paused = pauseMatchingOrchestrationDelegation('codex', code, message, coreOptions(options));
|
|
136
|
+
return paused.error?.code === 'ORCHESTRATION_DELEGATION_MISSING'
|
|
137
|
+
? bridgeFailure(code, message)
|
|
138
|
+
: paused;
|
|
139
|
+
}
|
|
140
|
+
function requiredStore(options) {
|
|
141
|
+
if (!options.store)
|
|
142
|
+
throw new Error('Codex lifecycle store is required for orchestration bridge events');
|
|
143
|
+
return options.store;
|
|
144
|
+
}
|
|
145
|
+
async function prepareCodexOrchestrationDelegation(taskRef, input, options = {}) {
|
|
146
|
+
if (input.client !== 'codex')
|
|
147
|
+
return prepareOrchestrationDelegation(taskRef, input, coreOptions(options));
|
|
148
|
+
try {
|
|
149
|
+
const repoRoot = options.repoRoot ?? process.cwd();
|
|
150
|
+
const resolved = resolveTaskRef(taskRef, { repoRoot });
|
|
151
|
+
if (!resolved.ok)
|
|
152
|
+
return bridgeFailure(resolved.code, resolved.message);
|
|
153
|
+
await (options.preflight ?? preflightCodexLifecycleEvidence)(repoRoot, undefined, resolved.taskId);
|
|
154
|
+
const prepared = prepareOrchestrationDelegation(taskRef, input, coreOptions(options));
|
|
155
|
+
const receipt = prepared.run?.pendingDelegation;
|
|
156
|
+
if (prepared.status !== 'running' || !receipt)
|
|
157
|
+
return prepared;
|
|
158
|
+
return Object.freeze({
|
|
159
|
+
...prepared,
|
|
160
|
+
adapterContext: encodeCodexLifecycleBinding({
|
|
161
|
+
taskId: receipt.taskId,
|
|
162
|
+
runId: receipt.runId,
|
|
163
|
+
receiptId: receipt.id
|
|
164
|
+
})
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
if (error instanceof OrchestrationStateError)
|
|
169
|
+
return bridgeFailure(error.code, error.message);
|
|
170
|
+
return bridgeFailure('ORCHESTRATION_CLIENT_PREFLIGHT_FAILED', error instanceof Error ? error.message : String(error));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async function activateCodexOrchestrationDelegation(childThreadId, options = {}) {
|
|
174
|
+
try {
|
|
175
|
+
const store = requiredStore(options);
|
|
176
|
+
const bound = recordMatchesTaskReceipt(childThreadId, options);
|
|
177
|
+
if (!['prepared', 'activated', 'stage-completed'].includes(bound.receipt.status)) {
|
|
178
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', 'lifecycle task receipt is not in an activatable state');
|
|
179
|
+
}
|
|
180
|
+
if (!hasActivatableOrchestrationDelegation('codex', childThreadId, coreOptions(options))) {
|
|
181
|
+
return bridgeFailure('ORCHESTRATION_DELEGATION_MISSING', 'No matching Codex delegation is active');
|
|
182
|
+
}
|
|
183
|
+
const activationEvidence = await collectActivationEvidence(childThreadId, options, bound);
|
|
184
|
+
if ('status' in activationEvidence)
|
|
185
|
+
return activationEvidence;
|
|
186
|
+
const { evidence, events, preflight } = activationEvidence;
|
|
187
|
+
const repoRoot = options.repoRoot ?? process.cwd();
|
|
188
|
+
const record = applyCollectedActivationEvidence(childThreadId, options, store, bound, events);
|
|
189
|
+
if ('status' in record)
|
|
190
|
+
return record;
|
|
191
|
+
const buildIdentity = options.buildIdentity ?? computeLifecycleBuildIdentity(repoRoot);
|
|
192
|
+
const storedAdapterEvidence = readDelegationAdapterEvidence(bound.receipt.taskId, bound.receipt.id, 'codex', coreOptions(options));
|
|
193
|
+
const adapterState = typeof storedAdapterEvidence === 'object' && storedAdapterEvidence !== null && !Array.isArray(storedAdapterEvidence)
|
|
194
|
+
? storedAdapterEvidence
|
|
195
|
+
: {};
|
|
196
|
+
const activated = activateMatchingOrchestrationDelegation('codex', {
|
|
197
|
+
nativeAgent: evidence.nativeAgent,
|
|
198
|
+
childId: evidence.childThreadId,
|
|
199
|
+
parentId: evidence.parentThreadId,
|
|
200
|
+
spawnMode: evidence.spawnMode,
|
|
201
|
+
actualModel: evidence.actualModel.value,
|
|
202
|
+
actualReasoningEffort: evidence.actualReasoningEffort.value,
|
|
203
|
+
...(evidence.modelFallbackReason ? { modelFallbackReason: evidence.modelFallbackReason } : {}),
|
|
204
|
+
...(evidence.reasoningEffortFallbackReason
|
|
205
|
+
? { reasoningEffortFallbackReason: evidence.reasoningEffortFallbackReason }
|
|
206
|
+
: {}),
|
|
207
|
+
clientEvidence: {
|
|
208
|
+
...adapterState,
|
|
209
|
+
activationEvidence: {
|
|
210
|
+
kind: 'codex-lifecycle-v2',
|
|
211
|
+
hookDefinitionHash: evidence.hookDefinitionHash,
|
|
212
|
+
startRevision: record.revision,
|
|
213
|
+
...buildIdentity,
|
|
214
|
+
...preflight.hookProvenance,
|
|
215
|
+
capabilitySessionId: evidence.parentThreadId,
|
|
216
|
+
capabilityTurnId: evidence.parentTurnId,
|
|
217
|
+
spawnToolUseId: evidence.spawnToolUseId,
|
|
218
|
+
spawnObservedAt: record.spawnObservedAt ?? undefined,
|
|
219
|
+
controllerInstanceDigest: null,
|
|
220
|
+
controlGeneration: null
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}, coreOptions(options));
|
|
224
|
+
return activated;
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
if (error instanceof OrchestrationStateError)
|
|
228
|
+
return bridgeFailure(error.code, error.message);
|
|
229
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
230
|
+
if (isBindingFailure(message)) {
|
|
231
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', message);
|
|
232
|
+
}
|
|
233
|
+
return pauseBridge('ORCHESTRATION_CODEX_START_FAILED', message, options);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function matchingSpawnRecords(store, binding, spawn) {
|
|
237
|
+
return store.findByTaskBinding(binding).filter((record) => record.state.spawn?.sessionId === spawn.sessionId
|
|
238
|
+
&& record.state.spawn?.turnId === spawn.turnId
|
|
239
|
+
&& record.state.spawn?.toolUseId === spawn.toolUseId
|
|
240
|
+
&& record.state.spawn?.nativeAgent === spawn.nativeAgent);
|
|
241
|
+
}
|
|
242
|
+
function verifySpawnTask(binding, spawn, store, options) {
|
|
243
|
+
const resolved = resolveTaskRef(binding.taskId, { repoRoot: options.repoRoot ?? process.cwd() });
|
|
244
|
+
if (!resolved.ok)
|
|
245
|
+
return bridgeFailure(resolved.code, resolved.message);
|
|
246
|
+
const run = readRun(resolved.taskDir);
|
|
247
|
+
if (!run)
|
|
248
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', 'Codex task has no current orchestration run');
|
|
249
|
+
verifyCodexLifecycleTaskBinding(binding, run, spawn.nativeAgent, {
|
|
250
|
+
requestedModel: spawn.requestedModel,
|
|
251
|
+
requestedReasoningEffort: spawn.requestedReasoningEffort
|
|
252
|
+
});
|
|
253
|
+
return { taskDir: resolved.taskDir };
|
|
254
|
+
}
|
|
255
|
+
async function resolveCurrentSpawnChild(childThreadId, spawn, options) {
|
|
256
|
+
const resolved = await (options.resolveThread ?? resolveCodexThread)(childThreadId);
|
|
257
|
+
if (resolved.resolution.thread.childThreadId !== childThreadId
|
|
258
|
+
|| resolved.resolution.thread.parentThreadId !== spawn.sessionId
|
|
259
|
+
|| resolved.resolution.thread.nativeAgent !== spawn.nativeAgent) {
|
|
260
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', 'resolved Codex child does not match the native spawn identity');
|
|
261
|
+
}
|
|
262
|
+
return { resolved };
|
|
263
|
+
}
|
|
264
|
+
async function activateCodexSpawnDelegation(spawn, options = {}) {
|
|
265
|
+
try {
|
|
266
|
+
const store = requiredStore(options);
|
|
267
|
+
const parsed = parseCodexLifecycleBinding(spawn.taskName);
|
|
268
|
+
if (!parsed)
|
|
269
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISSING', 'Codex spawn task_name has no valid task binding');
|
|
270
|
+
const task = verifySpawnTask(parsed.binding, spawn, store, options);
|
|
271
|
+
if ('status' in task)
|
|
272
|
+
return task;
|
|
273
|
+
const candidates = matchingSpawnRecords(store, parsed.binding, spawn);
|
|
274
|
+
if (candidates.length !== 1) {
|
|
275
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', 'Codex spawn does not identify one current task lifecycle record');
|
|
276
|
+
}
|
|
277
|
+
const childThreadId = resolveCodexSpawnedChild(spawn.transcriptPath, spawn);
|
|
278
|
+
const current = await resolveCurrentSpawnChild(childThreadId, spawn, options);
|
|
279
|
+
if ('status' in current)
|
|
280
|
+
return current;
|
|
281
|
+
const latestTask = verifySpawnTask(parsed.binding, spawn, store, options);
|
|
282
|
+
if ('status' in latestTask)
|
|
283
|
+
return latestTask;
|
|
284
|
+
const latestCandidates = matchingSpawnRecords(store, parsed.binding, spawn);
|
|
285
|
+
if (latestCandidates.length !== 1 || latestCandidates[0].revision !== candidates[0].revision) {
|
|
286
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', 'Codex spawn record changed while resolving its child');
|
|
287
|
+
}
|
|
288
|
+
store.applyToSpawn({ ...spawn, taskBinding: parsed.binding }, {
|
|
289
|
+
type: 'hook-child',
|
|
290
|
+
sessionId: spawn.sessionId,
|
|
291
|
+
turnId: spawn.turnId,
|
|
292
|
+
childThreadId,
|
|
293
|
+
parentThreadId: current.resolved.resolution.thread.parentThreadId,
|
|
294
|
+
nativeAgent: spawn.nativeAgent,
|
|
295
|
+
source: 'parent-rollout'
|
|
296
|
+
}, latestCandidates[0].revision);
|
|
297
|
+
return activateCodexOrchestrationDelegation(childThreadId, {
|
|
298
|
+
...options,
|
|
299
|
+
store,
|
|
300
|
+
resolveThread: async () => current.resolved
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
if (error instanceof OrchestrationStateError)
|
|
305
|
+
return bridgeFailure(error.code, error.message);
|
|
306
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
307
|
+
if (/CODEX_LIFECYCLE_TASK_BINDING_MISMATCH|task binding|task_name|identity does not match|does not match the current pending receipt|ambiguous/iu.test(message)) {
|
|
308
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', message);
|
|
309
|
+
}
|
|
310
|
+
return pauseBridge('ORCHESTRATION_CODEX_START_FAILED', message, options);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
async function sealCodexOrchestrationDelegation(childThreadId, options = {}) {
|
|
314
|
+
try {
|
|
315
|
+
const bound = recordMatchesTaskReceipt(childThreadId, options);
|
|
316
|
+
if (!hasSealableOrchestrationDelegation('codex', childThreadId, coreOptions(options))) {
|
|
317
|
+
return bridgeFailure('ORCHESTRATION_DELEGATION_MISSING', 'No matching Codex delegation is active');
|
|
318
|
+
}
|
|
319
|
+
const store = requiredStore(options);
|
|
320
|
+
const existing = store.read(childThreadId);
|
|
321
|
+
if (!existing.consumer) {
|
|
322
|
+
const stopTurnId = existing.state.stop?.turnId;
|
|
323
|
+
if (!stopTurnId) {
|
|
324
|
+
return pauseBridge('ORCHESTRATION_CODEX_STOP_EVIDENCE_INVALID', 'Codex lifecycle stop hook is not available', options);
|
|
325
|
+
}
|
|
326
|
+
const terminal = await (options.resolveTerminal ?? resolveCodexTerminal)(childThreadId, stopTurnId);
|
|
327
|
+
const current = recordMatchesTaskReceipt(childThreadId, options);
|
|
328
|
+
if (!sameTaskReceipt(bound.receipt, current.receipt) || !sameLifecycleRevision(existing, current.record)) {
|
|
329
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', 'task receipt or lifecycle revision changed while resolving Codex terminal evidence');
|
|
330
|
+
}
|
|
331
|
+
store.apply(terminal);
|
|
332
|
+
}
|
|
333
|
+
const record = store.read(childThreadId);
|
|
334
|
+
const evidence = record.state.stopEvidence;
|
|
335
|
+
if (record.state.status !== 'stop-ready' || !evidence || !record.state.startEvidence) {
|
|
336
|
+
return pauseBridge('ORCHESTRATION_CODEX_STOP_EVIDENCE_INVALID', 'Codex lifecycle stop evidence is not ready', options);
|
|
337
|
+
}
|
|
338
|
+
const current = recordMatchesTaskReceipt(childThreadId, options);
|
|
339
|
+
const latest = store.read(childThreadId);
|
|
340
|
+
if (!sameTaskReceipt(bound.receipt, current.receipt) || !sameLifecycleRevision(record, latest)
|
|
341
|
+
|| !sameTaskBinding(latest.taskBinding, current.binding)) {
|
|
342
|
+
throw new Error('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH: task receipt changed before lifecycle evidence consumption');
|
|
343
|
+
}
|
|
344
|
+
if (current.receipt.status === 'sealed') {
|
|
345
|
+
if (latest.consumer !== current.receipt.id || !latest.consumedAt) {
|
|
346
|
+
return pauseBridge('ORCHESTRATION_CODEX_RECONCILIATION_FAILED', 'Codex lifecycle evidence was not consumed by the sealed receipt', options);
|
|
347
|
+
}
|
|
348
|
+
return reconcileMatchingOrchestrationDelegation('codex', childThreadId, coreOptions(options));
|
|
349
|
+
}
|
|
350
|
+
return sealMatchingOrchestrationDelegation('codex', { nativeAgent: record.state.startEvidence.nativeAgent, childId: childThreadId }, coreOptions(options), () => {
|
|
351
|
+
try {
|
|
352
|
+
const consumed = store.consumeWithinTaskLock(childThreadId, current.receipt.id, existing.state.spawn?.hookDefinitionHash, existing.taskBinding ?? undefined);
|
|
353
|
+
return consumed.consumer === current.receipt.id && consumed.consumedAt
|
|
354
|
+
? null
|
|
355
|
+
: bridgeFailure('ORCHESTRATION_CODEX_RECONCILIATION_FAILED', 'Codex lifecycle evidence was not consumed by the active receipt');
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
return codexSealFailure(error, options, 'child');
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
return codexSealFailure(error, options, 'child');
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
function findCurrentParentReceipt(store, repoRoot) {
|
|
367
|
+
if (!store.taskId)
|
|
368
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISSING', 'parent seal requires a task-scoped lifecycle store');
|
|
369
|
+
const resolved = resolveTaskRef(store.taskId, { repoRoot });
|
|
370
|
+
if (!resolved.ok)
|
|
371
|
+
return bridgeFailure(resolved.code, resolved.message);
|
|
372
|
+
const pending = readRun(resolved.taskDir)?.pendingDelegation;
|
|
373
|
+
if (!pending || pending.client !== 'codex') {
|
|
374
|
+
return bridgeFailure('ORCHESTRATION_DELEGATION_MISSING', 'No matching Codex delegation is active');
|
|
375
|
+
}
|
|
376
|
+
return { pending };
|
|
377
|
+
}
|
|
378
|
+
function findParentLifecycleRecord(parentThreadId, store, pending) {
|
|
379
|
+
const binding = { taskId: pending.taskId, runId: pending.runId, receiptId: pending.id };
|
|
380
|
+
const candidates = store.findByTaskBinding(binding).filter((record) => record.state.startEvidence?.parentThreadId === parentThreadId);
|
|
381
|
+
if (!candidates.length)
|
|
382
|
+
return bridgeFailure('ORCHESTRATION_DELEGATION_MISSING', 'No matching Codex delegation is active');
|
|
383
|
+
if (candidates.length !== 1) {
|
|
384
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', 'parent seal has multiple lifecycle records for the current task receipt');
|
|
385
|
+
}
|
|
386
|
+
const active = candidates[0];
|
|
387
|
+
const start = active.state.startEvidence;
|
|
388
|
+
const child = active.state.child;
|
|
389
|
+
if (!start || !child || start.childThreadId !== child.childThreadId
|
|
390
|
+
|| start.parentThreadId !== parentThreadId
|
|
391
|
+
|| active.state.spawn?.sessionId !== parentThreadId
|
|
392
|
+
|| active.state.spawn.nativeAgent !== start.nativeAgent
|
|
393
|
+
|| managedDelegationRole(start.nativeAgent) !== pending.role) {
|
|
394
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', 'parent lifecycle record does not match the current native delegation identity');
|
|
395
|
+
}
|
|
396
|
+
return { active, start, child };
|
|
397
|
+
}
|
|
398
|
+
async function collectParentTerminalIfNeeded(active, start, options) {
|
|
399
|
+
if (active.state.terminal)
|
|
400
|
+
return null;
|
|
401
|
+
const resolveTerminal = options.resolveTerminal ?? resolveCodexTerminal;
|
|
402
|
+
return active.state.stop
|
|
403
|
+
? resolveTerminal(start.childThreadId, active.state.stop.turnId)
|
|
404
|
+
: resolveTerminal(start.childThreadId);
|
|
405
|
+
}
|
|
406
|
+
function applyParentTerminalCandidate(parentThreadId, repoRoot, store, pending, active, start, child, terminal) {
|
|
407
|
+
const latestReceipt = findCurrentParentReceipt(store, repoRoot);
|
|
408
|
+
if ('status' in latestReceipt)
|
|
409
|
+
return latestReceipt;
|
|
410
|
+
if (!sameTaskReceipt(pending, latestReceipt.pending)) {
|
|
411
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', 'task receipt changed while resolving parent terminal evidence');
|
|
412
|
+
}
|
|
413
|
+
const latestMatch = findParentLifecycleRecord(parentThreadId, store, latestReceipt.pending);
|
|
414
|
+
if ('status' in latestMatch)
|
|
415
|
+
return latestMatch;
|
|
416
|
+
if (!sameLifecycleRevision(active, latestMatch.active)
|
|
417
|
+
|| !sameTaskBinding(active.taskBinding, latestMatch.active.taskBinding)) {
|
|
418
|
+
return bridgeFailure('CODEX_LIFECYCLE_TASK_BINDING_MISMATCH', 'task receipt or lifecycle revision changed while resolving parent terminal evidence');
|
|
419
|
+
}
|
|
420
|
+
if (terminal)
|
|
421
|
+
store.apply(terminal);
|
|
422
|
+
if (!store.read(start.childThreadId).state.stop) {
|
|
423
|
+
store.apply({
|
|
424
|
+
type: 'hook-stop', sessionId: parentThreadId, turnId: child.turnId,
|
|
425
|
+
childThreadId: start.childThreadId, nativeAgent: start.nativeAgent, source: 'parent-rollout'
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
return null;
|
|
429
|
+
}
|
|
430
|
+
async function sealCodexParentDelegation(parentThreadId, options = {}) {
|
|
431
|
+
try {
|
|
432
|
+
const store = requiredStore(options);
|
|
433
|
+
const repoRoot = options.repoRoot ?? options.orchestrationOptions?.repoRoot ?? process.cwd();
|
|
434
|
+
const current = findCurrentParentReceipt(store, repoRoot);
|
|
435
|
+
if ('status' in current)
|
|
436
|
+
return current;
|
|
437
|
+
const pending = current.pending;
|
|
438
|
+
const match = findParentLifecycleRecord(parentThreadId, store, pending);
|
|
439
|
+
if ('status' in match)
|
|
440
|
+
return match;
|
|
441
|
+
const { active, start, child } = match;
|
|
442
|
+
if (active.consumer)
|
|
443
|
+
return sealCodexOrchestrationDelegation(start.childThreadId, options);
|
|
444
|
+
const terminal = await collectParentTerminalIfNeeded(active, start, options);
|
|
445
|
+
const failure = applyParentTerminalCandidate(parentThreadId, repoRoot, store, pending, active, start, child, terminal);
|
|
446
|
+
if (failure)
|
|
447
|
+
return failure;
|
|
448
|
+
return sealCodexOrchestrationDelegation(start.childThreadId, options);
|
|
449
|
+
}
|
|
450
|
+
catch (error) {
|
|
451
|
+
return codexSealFailure(error, options, 'parent');
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
function reconcileCodexOrchestrationDelegation(childThreadId, options = {}) {
|
|
455
|
+
try {
|
|
456
|
+
const bound = recordMatchesTaskReceipt(childThreadId, options);
|
|
457
|
+
const record = requiredStore(options).read(childThreadId);
|
|
458
|
+
if (bound.receipt.status !== 'sealed' || record.consumer !== bound.receipt.id || !record.consumedAt) {
|
|
459
|
+
return pauseBridge('ORCHESTRATION_CODEX_RECONCILIATION_FAILED', 'Codex lifecycle evidence was not consumed by the sealed receipt', options);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
catch (error) {
|
|
463
|
+
return codexSealFailure(error, options, 'child');
|
|
464
|
+
}
|
|
465
|
+
return reconcileMatchingOrchestrationDelegation('codex', childThreadId, coreOptions(options));
|
|
466
|
+
}
|
|
467
|
+
export { activateCodexOrchestrationDelegation, activateCodexSpawnDelegation, prepareCodexOrchestrationDelegation, reconcileCodexOrchestrationDelegation, sealCodexParentDelegation, sealCodexOrchestrationDelegation };
|
|
468
|
+
//# sourceMappingURL=codex-orchestration.js.map
|
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
import { defineAgentClientAdapter } from '../adapter.js';
|
|
2
2
|
import { hostJoin } from '../../sandbox/engines/wsl2-paths.js';
|
|
3
3
|
import { codexBeforeContainerCreateHook, codexRecoveryChecks } from './codex-sandbox.js';
|
|
4
|
+
import { parseCodexLifecycleBinding } from './codex-lifecycle/binding.js';
|
|
5
|
+
import { isCodexDelegationReceiptEvidence, isCodexLifecycleActivationEvidence } from './codex-lifecycle/evidence.js';
|
|
6
|
+
import { codexControllerOperation } from './codex-lifecycle/controller-operation.js';
|
|
7
|
+
function codexCarrierError(code) {
|
|
8
|
+
const error = new Error(code);
|
|
9
|
+
error.name = code;
|
|
10
|
+
return error;
|
|
11
|
+
}
|
|
12
|
+
function codexStageToken(stage) {
|
|
13
|
+
const tokens = {
|
|
14
|
+
analysis: 'a',
|
|
15
|
+
plan: 'p',
|
|
16
|
+
code: 'c',
|
|
17
|
+
'review-analysis': 'ra',
|
|
18
|
+
'review-plan': 'rp',
|
|
19
|
+
'review-code': 'rc',
|
|
20
|
+
commit: 'm'
|
|
21
|
+
};
|
|
22
|
+
const token = tokens[stage];
|
|
23
|
+
if (!token)
|
|
24
|
+
throw codexCarrierError('CODEX_LIFECYCLE_SPAWN_IDENTITY_INVALID');
|
|
25
|
+
return token;
|
|
26
|
+
}
|
|
27
|
+
function codexLaunchCarrier(adapterContext, identity) {
|
|
28
|
+
if (!Number.isSafeInteger(identity.round) || identity.round < 1
|
|
29
|
+
|| !['executor', 'reviewer'].includes(identity.role)) {
|
|
30
|
+
throw codexCarrierError('CODEX_LIFECYCLE_SPAWN_IDENTITY_INVALID');
|
|
31
|
+
}
|
|
32
|
+
const label = `${codexStageToken(identity.stage)}_${identity.role === 'reviewer' ? 'r' : 'e'}_r${identity.round}`;
|
|
33
|
+
const taskName = `${label}${adapterContext}`;
|
|
34
|
+
const parsed = parseCodexLifecycleBinding(taskName);
|
|
35
|
+
if (!parsed)
|
|
36
|
+
throw codexCarrierError('CODEX_LIFECYCLE_LAUNCH_CONTEXT_INVALID');
|
|
37
|
+
return Object.freeze({ task_name: parsed.taskName });
|
|
38
|
+
}
|
|
4
39
|
const codexAdapter = defineAgentClientAdapter({
|
|
5
40
|
id: 'codex',
|
|
6
41
|
displayName: 'Codex',
|
|
@@ -25,8 +60,11 @@ const codexAdapter = defineAgentClientAdapter({
|
|
|
25
60
|
actualReasoningEffort: 'app-server'
|
|
26
61
|
},
|
|
27
62
|
orchestrationAdapter: {
|
|
63
|
+
validateActivationEvidence: isCodexLifecycleActivationEvidence,
|
|
64
|
+
validateReceiptEvidence: isCodexDelegationReceiptEvidence,
|
|
65
|
+
createLaunchCarrier: codexLaunchCarrier,
|
|
28
66
|
prepareDelegation: async (...args) => {
|
|
29
|
-
const { prepareCodexOrchestrationDelegation } = await import('
|
|
67
|
+
const { prepareCodexOrchestrationDelegation } = await import('./codex-orchestration.js');
|
|
30
68
|
return prepareCodexOrchestrationDelegation(...args);
|
|
31
69
|
},
|
|
32
70
|
recoverStarted: async (...args) => {
|
|
@@ -34,6 +72,7 @@ const codexAdapter = defineAgentClientAdapter({
|
|
|
34
72
|
return recoverStartedLifecycleFromAdapter(...args);
|
|
35
73
|
}
|
|
36
74
|
},
|
|
75
|
+
sandboxControlOperation: codexControllerOperation,
|
|
37
76
|
project: {
|
|
38
77
|
ownedPathPrefixes: ['.codex/'],
|
|
39
78
|
managed: ['.codex/hooks.json', '.codex/agents/'],
|
|
@@ -1,22 +1,14 @@
|
|
|
1
|
-
import { AGENT_CLIENT_IDS } from '../types.js';
|
|
2
1
|
import { claudeCodeAdapter } from './claude-code.js';
|
|
3
2
|
import { codexAdapter } from './codex.js';
|
|
4
3
|
import { antigravityCliAdapter } from './antigravity-cli.js';
|
|
5
4
|
import { opencodeAdapter } from './opencode.js';
|
|
6
5
|
import { traecliAdapter } from './traecli.js';
|
|
7
|
-
const
|
|
6
|
+
const BUILTIN_AGENT_CLIENT_ADAPTERS = Object.freeze([
|
|
8
7
|
claudeCodeAdapter,
|
|
9
8
|
codexAdapter,
|
|
10
9
|
antigravityCliAdapter,
|
|
11
10
|
opencodeAdapter,
|
|
12
11
|
traecliAdapter
|
|
13
|
-
]
|
|
14
|
-
const BUILTIN_AGENT_CLIENT_ADAPTERS = Object.freeze(AGENT_CLIENT_IDS.map((id) => {
|
|
15
|
-
const adapter = adaptersById.get(id);
|
|
16
|
-
if (!adapter) {
|
|
17
|
-
throw new Error(`Missing built-in Agent Client adapter '${id}'`);
|
|
18
|
-
}
|
|
19
|
-
return adapter;
|
|
20
|
-
}));
|
|
12
|
+
]);
|
|
21
13
|
export { BUILTIN_AGENT_CLIENT_ADAPTERS };
|
|
22
14
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
// Active AI collaborator short tokens — the write-side whitelist for the
|
|
2
2
|
// activity log. Migrated from lib/task/commands/log.ts so that the write-side
|
|
3
3
|
// internal commands and the rendering side share one definition.
|
|
4
|
-
export const
|
|
4
|
+
export const AGENT_TOKEN_VALUES = ['claude', 'codex', 'antigravity', 'opencode', 'cursor', 'traecli'];
|
|
5
|
+
export const KNOWN_AI_AGENTS = new Set(AGENT_TOKEN_VALUES);
|
|
5
6
|
// Long name -> short name mapping: `claude-code` reuses the existing
|
|
6
7
|
// orchestration precedent, and `antigravity-cli` is the active client.
|
|
7
8
|
export const AGENT_LONG_NAMES = {
|
|
8
9
|
'claude-code': 'claude',
|
|
9
10
|
'antigravity-cli': 'antigravity'
|
|
10
11
|
};
|
|
11
|
-
export const AGENT_USAGE_HINT =
|
|
12
|
+
export const AGENT_USAGE_HINT = `agent must be a short token (${AGENT_TOKEN_VALUES.join('/')}), ` +
|
|
12
13
|
"a long name (claude-code -> claude, antigravity-cli -> antigravity), or 'human'";
|
|
13
14
|
// Strict write-side validation: the value must be exactly a short token, a
|
|
14
15
|
// long name, or 'human'; returns the normalized short token, or null when
|