@fitlab-ai/agent-infra 0.11.10 → 0.11.12
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 +27 -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 +222 -210
- package/dist/lib/agent-clients/adapters/codex-orchestration.js +468 -0
- package/dist/lib/agent-clients/adapters/codex-sandbox.js +13 -0
- package/dist/lib/agent-clients/adapters/codex.js +44 -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/manual-validation.js +2 -2
- package/dist/lib/internal/platform-pr.js +4 -5
- package/dist/lib/internal/task-artifact.js +1 -1
- package/dist/lib/internal/task-create.js +15 -1
- package/dist/lib/internal/task-finalization.js +1 -3
- package/dist/lib/internal/task-operation-registry.js +5 -139
- package/dist/lib/internal/task-validate.js +1 -1
- package/dist/lib/platform/issues.js +18 -6
- package/dist/lib/platform/pr-summary.js +45 -8
- package/dist/lib/platform/pull-requests.js +79 -14
- package/dist/lib/platform/verification-sync.js +17 -14
- 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 +19 -2
- package/dist/lib/sandbox/commands/enter.js +47 -33
- package/dist/lib/sandbox/control/agent-operation.js +34 -0
- package/dist/lib/sandbox/control/client.js +68 -161
- package/dist/lib/sandbox/control/executor.js +13 -87
- package/dist/lib/sandbox/control/host-recovery.js +218 -0
- package/dist/lib/sandbox/control/protocol.js +15 -44
- package/dist/lib/sandbox/control/server.js +57 -51
- package/dist/lib/sandbox/environment.js +150 -0
- package/dist/lib/sandbox/mounts.js +2 -1
- package/dist/lib/sandbox/recovery.js +11 -1
- package/dist/lib/sandbox/removal.js +9 -5
- package/dist/lib/sandbox/workspace-identity.js +0 -14
- package/dist/lib/sandbox/workspace-view.js +41 -23
- package/dist/lib/task/artifact-command.js +7 -2
- package/dist/lib/task/artifact-lifecycle.js +2 -1
- package/dist/lib/task/capabilities.js +4 -1
- package/dist/lib/task/control-authority.js +54 -266
- package/dist/lib/task/control-recovery.js +1 -1
- package/dist/lib/task/create.js +2 -2
- package/dist/lib/task/delegation-receipts.js +74 -161
- package/dist/lib/task/events.js +89 -45
- package/dist/lib/task/finalization.js +58 -60
- package/dist/lib/task/frontmatter.js +24 -1
- package/dist/lib/task/ledger-intents.js +2 -1
- package/dist/lib/task/lifecycle.js +84 -97
- package/dist/lib/task/orchestration.js +182 -129
- package/dist/lib/task/platform-operation-journal.js +12 -0
- package/dist/lib/task/platform-operation-recovery.js +14 -7
- package/dist/lib/task/resolve-ref.js +8 -3
- package/dist/lib/task/runtime-paths.js +10 -0
- package/dist/lib/task/verification-engine.js +28 -15
- package/dist/lib/task/workspace-snapshot.js +1 -1
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-clients/adapter.ts +61 -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 +272 -223
- package/lib/agent-clients/adapters/codex-orchestration.ts +632 -0
- package/lib/agent-clients/adapters/codex-sandbox.ts +13 -0
- package/lib/agent-clients/adapters/codex.ts +48 -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/manual-validation.ts +2 -2
- package/lib/internal/platform-pr.ts +3 -4
- package/lib/internal/task-artifact.ts +1 -1
- package/lib/internal/task-create.ts +15 -2
- package/lib/internal/task-finalization.ts +1 -3
- package/lib/internal/task-operation-registry.ts +5 -151
- package/lib/internal/task-validate.ts +1 -1
- package/lib/platform/issues.ts +18 -6
- package/lib/platform/pr-summary.ts +43 -7
- package/lib/platform/pull-requests.ts +74 -13
- package/lib/platform/verification-sync.ts +18 -14
- package/lib/runtime/agent-runtime.ts +6 -41
- package/lib/sandbox/commands/control-status.ts +1 -0
- package/lib/sandbox/commands/create.ts +25 -2
- package/lib/sandbox/commands/enter.ts +42 -39
- package/lib/sandbox/control/agent-operation.ts +49 -0
- package/lib/sandbox/control/client.ts +86 -210
- package/lib/sandbox/control/executor.ts +17 -96
- package/lib/sandbox/control/host-recovery.ts +195 -0
- package/lib/sandbox/control/protocol.ts +24 -55
- package/lib/sandbox/control/server.ts +54 -52
- package/lib/sandbox/environment.ts +162 -0
- package/lib/sandbox/mounts.ts +2 -1
- package/lib/sandbox/recovery.ts +13 -1
- package/lib/sandbox/removal.ts +12 -5
- package/lib/sandbox/tool-types.ts +1 -0
- package/lib/sandbox/workspace-identity.ts +0 -26
- package/lib/sandbox/workspace-view.ts +42 -24
- package/lib/task/artifact-command.ts +9 -2
- package/lib/task/artifact-lifecycle.ts +2 -1
- package/lib/task/capabilities.ts +5 -2
- package/lib/task/control-authority.ts +65 -382
- package/lib/task/control-recovery.ts +2 -2
- package/lib/task/create.ts +3 -3
- package/lib/task/delegation-receipts.ts +87 -231
- package/lib/task/events.ts +101 -43
- package/lib/task/finalization.ts +57 -58
- package/lib/task/frontmatter.ts +25 -1
- package/lib/task/ledger-intents.ts +2 -1
- package/lib/task/lifecycle.ts +82 -87
- package/lib/task/orchestration.ts +237 -176
- package/lib/task/platform-operation-journal.ts +29 -2
- package/lib/task/platform-operation-recovery.ts +12 -6
- package/lib/task/resolve-ref.ts +8 -3
- package/lib/task/runtime-paths.ts +12 -0
- package/lib/task/verification-engine.ts +27 -16
- 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 -2
- package/templates/.agents/rules/README.zh-CN.md +2 -2
- package/templates/.agents/rules/issue-sync.en.md +1 -1
- package/templates/.agents/rules/issue-sync.zh-CN.md +1 -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/no-mid-flow-questions.en.md +19 -0
- package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +19 -0
- package/templates/.agents/rules/review-handshake.en.md +3 -0
- package/templates/.agents/rules/review-handshake.zh-CN.md +3 -0
- package/templates/.agents/rules/task-management.en.md +1 -1
- package/templates/.agents/rules/task-management.zh-CN.md +1 -1
- package/templates/.agents/skills/analyze-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/block-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/cancel-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/cancel-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/close-codescan/SKILL.en.md +3 -0
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +3 -0
- package/templates/.agents/skills/close-dependabot/SKILL.en.md +3 -0
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +3 -0
- package/templates/.agents/skills/code-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/code-task/reference/branch-management.en.md +1 -1
- package/templates/.agents/skills/code-task/reference/branch-management.zh-CN.md +1 -1
- package/templates/.agents/skills/code-task/reference/dual-mode.en.md +2 -0
- package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +2 -0
- package/templates/.agents/skills/code-task/reference/fix-mode.en.md +1 -1
- package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +1 -1
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +1 -2
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +1 -2
- package/templates/.agents/skills/complete-task/SKILL.en.md +0 -3
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +0 -3
- package/templates/.agents/skills/create-pr/SKILL.en.md +1 -1
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/create-pr/reference/branch-strategy.en.md +2 -2
- package/templates/.agents/skills/create-pr/reference/branch-strategy.zh-CN.md +2 -2
- package/templates/.agents/skills/create-task/SKILL.en.md +3 -5
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +3 -4
- package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-issue/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/plan-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +1 -1
- 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 +5 -5
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +5 -5
- 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/review-pr/SKILL.en.md +1 -1
- package/templates/.agents/skills/review-pr/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/test/SKILL.en.md +4 -1
- package/templates/.agents/skills/test/SKILL.zh-CN.md +4 -1
- package/templates/.agents/skills/test-integration/SKILL.en.md +5 -2
- package/templates/.agents/skills/test-integration/SKILL.zh-CN.md +5 -2
- package/templates/.agents/skills/update-agent-infra/SKILL.en.md +4 -1
- package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +4 -1
- package/templates/.agents/skills/upgrade-dependency/SKILL.en.md +5 -2
- package/templates/.agents/skills/upgrade-dependency/SKILL.zh-CN.md +5 -2
- package/templates/.agents/skills/watch-pr/SKILL.en.md +2 -2
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +1 -1
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.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/dist/lib/task/finalization-handoff.js +0 -93
- 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
- package/lib/task/finalization-handoff.ts +0 -105
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { getAgentClientAdapter } from '../../agent-clients/registry.js';
|
|
2
|
+
function operationFor(request) {
|
|
3
|
+
const adapter = getAgentClientAdapter(request.agentClient);
|
|
4
|
+
const operation = adapter.sandboxControlOperation;
|
|
5
|
+
if (!operation)
|
|
6
|
+
throw new Error('SANDBOX_CONTROL_AGENT_OPERATION_UNSUPPORTED');
|
|
7
|
+
return operation;
|
|
8
|
+
}
|
|
9
|
+
function validateAgentClientOperation(request, manifest) {
|
|
10
|
+
operationFor(request).validate({
|
|
11
|
+
operation: request.operation,
|
|
12
|
+
payload: request.payload,
|
|
13
|
+
manifest
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function executeAgentClientOperation(request, manifest, manifestPath, override) {
|
|
17
|
+
return (override ?? operationFor(request)).execute({
|
|
18
|
+
operation: request.operation,
|
|
19
|
+
payload: request.payload,
|
|
20
|
+
manifest,
|
|
21
|
+
manifestPath
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function recoverAgentClientOperation(params) {
|
|
25
|
+
const operation = operationFor(params.request);
|
|
26
|
+
return operation.recover?.({
|
|
27
|
+
operation: params.request.operation,
|
|
28
|
+
manifest: params.manifest,
|
|
29
|
+
manifestPath: params.manifestPath,
|
|
30
|
+
stdout: params.stdout
|
|
31
|
+
}) ?? { consistent: false };
|
|
32
|
+
}
|
|
33
|
+
export { executeAgentClientOperation, recoverAgentClientOperation, validateAgentClientOperation };
|
|
34
|
+
//# sourceMappingURL=agent-operation.js.map
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
-
import { hasTaskBoundMarker } from '../../internal/task-operation-registry.js';
|
|
3
2
|
import path from 'node:path';
|
|
4
3
|
import { randomUUID } from 'node:crypto';
|
|
5
4
|
import { SANDBOX_CONTROL_ADMISSION_WINDOW_MS, SANDBOX_CONTROL_MAX_BYTES, SANDBOX_CONTROL_STATUS_STALE_MS, isSandboxControlFamily } from './protocol.js';
|
|
5
|
+
import { isAgentClientId } from '../../agent-clients/types.js';
|
|
6
6
|
import { normalizeAgentToken } from '../../agent-clients/tokens.js';
|
|
7
7
|
import { readSandboxControlPayload, readSandboxControlStatus } from './state.js';
|
|
8
8
|
import { accessSandboxTaskView, taskViewFromStatus } from './task-view.js';
|
|
9
9
|
import { readSandboxControlIdentitySentinel } from './identity-sentinel.js';
|
|
10
10
|
import { configuredShortIdLength, resolveShortIdReadOnly } from '../../task/short-id.js';
|
|
11
|
+
import { hasTaskBoundMarker, isSandbox } from '../environment.js';
|
|
12
|
+
import { loadConfig } from '../config.js';
|
|
13
|
+
import { recoverSandboxControlFromHost } from './host-recovery.js';
|
|
11
14
|
const SANDBOX_CONTROL_RESPONSE_SETTLE_MS = 250;
|
|
12
15
|
const SANDBOX_TASK_FINALIZATION_RECOVERY_BUDGET_MS = 5 * 60_000;
|
|
13
16
|
export class SandboxControlClientError extends Error {
|
|
@@ -98,7 +101,7 @@ function parseResponse(raw, id, accepted = false) {
|
|
|
98
101
|
}
|
|
99
102
|
return response;
|
|
100
103
|
}
|
|
101
|
-
function readPublishedResponse(raw, id, channelDir, accepted
|
|
104
|
+
function readPublishedResponse(raw, id, channelDir, accepted, generation) {
|
|
102
105
|
const response = parseResponse(raw, id, accepted);
|
|
103
106
|
if (response.outputState !== 'available')
|
|
104
107
|
return response;
|
|
@@ -112,6 +115,7 @@ function readPublishedResponse(raw, id, channelDir, accepted = false) {
|
|
|
112
115
|
}
|
|
113
116
|
if (!response.payload || response.payload.version !== payload.version
|
|
114
117
|
|| response.payload.id !== payload.id || response.payload.generation !== payload.generation
|
|
118
|
+
|| payload.generation !== generation
|
|
115
119
|
|| response.payload.stdoutBytes !== payload.stdoutBytes || response.payload.stderrBytes !== payload.stderrBytes
|
|
116
120
|
|| response.payload.stdoutSha256 !== payload.stdoutSha256 || response.payload.stderrSha256 !== payload.stderrSha256) {
|
|
117
121
|
clientError('SANDBOX_CONTROL_RESPONSE_INVALID', 'broker payload reference is invalid', false, true, id);
|
|
@@ -216,7 +220,7 @@ function exchangeSandboxControl(request, params) {
|
|
|
216
220
|
try {
|
|
217
221
|
// The request-specific terminal proves the broker claimed the request; preserve recovery evidence if marker cleanup won the race.
|
|
218
222
|
accepted = true;
|
|
219
|
-
response = readPublishedResponse(raw, request.id, channelDir, accepted);
|
|
223
|
+
response = readPublishedResponse(raw, request.id, channelDir, accepted, request.generation);
|
|
220
224
|
malformedResponseRaw = null;
|
|
221
225
|
}
|
|
222
226
|
catch (error) {
|
|
@@ -264,7 +268,40 @@ export function recoverSandboxControl(requestId, params = {}) {
|
|
|
264
268
|
if (!/^[a-f0-9-]{16,64}$/u.test(requestId)) {
|
|
265
269
|
clientError('SANDBOX_CONTROL_REQUEST_INVALID', 'request id is invalid', false, true);
|
|
266
270
|
}
|
|
267
|
-
|
|
271
|
+
try {
|
|
272
|
+
if (!isSandbox()) {
|
|
273
|
+
const config = loadConfig();
|
|
274
|
+
const response = recoverSandboxControlFromHost(requestId, {
|
|
275
|
+
managedRoot: path.join(config.controlBase, config.project),
|
|
276
|
+
timeoutMs: params.timeoutMs
|
|
277
|
+
});
|
|
278
|
+
if (response.phase === 'rejected' && response.error?.code === 'SANDBOX_CONTROL_RESULT_UNKNOWN') {
|
|
279
|
+
clientError('SANDBOX_CONTROL_RESULT_UNKNOWN', 'recovery evidence is unavailable; inspect domain state before retrying', false, true, requestId);
|
|
280
|
+
}
|
|
281
|
+
return response;
|
|
282
|
+
}
|
|
283
|
+
const channelDir = process.env.AGENT_INFRA_CONTROL_DIR;
|
|
284
|
+
const statusDir = process.env.AGENT_INFRA_CONTROL_STATUS_DIR;
|
|
285
|
+
const identity = readSandboxControlIdentitySentinel(statusDir);
|
|
286
|
+
return recoverSandboxControlFromChannel(requestId, {
|
|
287
|
+
channelDir, generation: identity.generation, timeoutMs: params.timeoutMs
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
if (error instanceof SandboxControlClientError)
|
|
292
|
+
throw error;
|
|
293
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
294
|
+
const code = /^([A-Z][A-Z0-9_]+)/u.exec(message)?.[1] ?? 'SANDBOX_CONTROL_RECOVERY_INVALID';
|
|
295
|
+
clientError(code, 'sandbox control recovery evidence is invalid or unavailable', false, true, requestId);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Low-level channel reader for control integration tests and internal callers
|
|
299
|
+
// that already hold a manifest-bound channel path.
|
|
300
|
+
export function recoverSandboxControlFromChannel(requestId, params) {
|
|
301
|
+
if (!/^[a-f0-9-]{16,64}$/u.test(requestId)) {
|
|
302
|
+
clientError('SANDBOX_CONTROL_REQUEST_INVALID', 'request id is invalid', false, true);
|
|
303
|
+
}
|
|
304
|
+
const { channelDir } = params;
|
|
268
305
|
const responsePath = path.join(channelDir, 'responses', `${requestId}.json`);
|
|
269
306
|
const deadline = Date.now() + (params.timeoutMs ?? 30_000);
|
|
270
307
|
let accepted = false;
|
|
@@ -287,7 +324,7 @@ export function recoverSandboxControl(requestId, params = {}) {
|
|
|
287
324
|
try {
|
|
288
325
|
// The request-specific terminal proves the broker claimed the request; preserve recovery evidence if marker cleanup won the race.
|
|
289
326
|
accepted = true;
|
|
290
|
-
response = readPublishedResponse(raw, requestId, channelDir, accepted);
|
|
327
|
+
response = readPublishedResponse(raw, requestId, channelDir, accepted, params.generation);
|
|
291
328
|
malformedResponseRaw = null;
|
|
292
329
|
}
|
|
293
330
|
catch (error) {
|
|
@@ -332,17 +369,34 @@ function authority(params) {
|
|
|
332
369
|
export function requestSandboxControl(params) {
|
|
333
370
|
if (!isSandboxControlFamily(params.family))
|
|
334
371
|
clientError('SANDBOX_CONTROL_COMMAND_DENIED', `'${params.family}' is not allowed`, false);
|
|
335
|
-
if (params.family === 'task-create' || params.family === '
|
|
372
|
+
if (params.family === 'task-create' || params.family === 'agent-client' || params.family === 'task-finalization') {
|
|
336
373
|
clientError('SANDBOX_CONTROL_COMMAND_DENIED', `'${params.family}' requires a typed request`, false);
|
|
337
374
|
}
|
|
338
375
|
const auth = authority(params);
|
|
339
376
|
const issuedAt = Date.now();
|
|
340
377
|
const request = {
|
|
341
|
-
version:
|
|
378
|
+
version: 4, id: randomUUID(), ...auth, issuedAt,
|
|
379
|
+
expiresAt: issuedAt + SANDBOX_CONTROL_ADMISSION_WINDOW_MS,
|
|
380
|
+
family: params.family, args: params.args
|
|
381
|
+
};
|
|
382
|
+
return exchangeSandboxControl(request, params);
|
|
383
|
+
}
|
|
384
|
+
export function requestSandboxAgentOperation(params) {
|
|
385
|
+
if (!isAgentClientId(params.agentClient)) {
|
|
386
|
+
clientError('SANDBOX_CONTROL_REQUEST_INVALID', 'agent-client id is invalid', false);
|
|
387
|
+
}
|
|
388
|
+
const auth = authority(params);
|
|
389
|
+
const issuedAt = Date.now();
|
|
390
|
+
const request = {
|
|
391
|
+
version: 4,
|
|
392
|
+
id: randomUUID(),
|
|
393
|
+
...auth,
|
|
394
|
+
issuedAt,
|
|
342
395
|
expiresAt: issuedAt + SANDBOX_CONTROL_ADMISSION_WINDOW_MS,
|
|
343
|
-
family:
|
|
344
|
-
|
|
345
|
-
|
|
396
|
+
family: 'agent-client',
|
|
397
|
+
agentClient: params.agentClient,
|
|
398
|
+
operation: params.operation,
|
|
399
|
+
payload: params.payload
|
|
346
400
|
};
|
|
347
401
|
return exchangeSandboxControl(request, params);
|
|
348
402
|
}
|
|
@@ -353,9 +407,8 @@ export function requestSandboxTaskFinalization(params) {
|
|
|
353
407
|
const auth = authority(params);
|
|
354
408
|
const issuedAt = Date.now();
|
|
355
409
|
const id = randomUUID();
|
|
356
|
-
const handoffSha256 = (params.prepareHandoff ?? (() => '0'.repeat(64)))({ generation: auth.generation, requestId: id });
|
|
357
410
|
const request = {
|
|
358
|
-
version:
|
|
411
|
+
version: 4,
|
|
359
412
|
id,
|
|
360
413
|
...auth,
|
|
361
414
|
issuedAt,
|
|
@@ -363,10 +416,7 @@ export function requestSandboxTaskFinalization(params) {
|
|
|
363
416
|
family: 'task-finalization',
|
|
364
417
|
operation: 'complete',
|
|
365
418
|
agent,
|
|
366
|
-
|
|
367
|
-
args: [],
|
|
368
|
-
controllerProcess: null,
|
|
369
|
-
controllerProof: null
|
|
419
|
+
args: []
|
|
370
420
|
};
|
|
371
421
|
let response;
|
|
372
422
|
try {
|
|
@@ -391,7 +441,7 @@ export function recoverAcceptedTaskFinalization(requestId, params, recover = rec
|
|
|
391
441
|
if (timeoutMs <= 0)
|
|
392
442
|
break;
|
|
393
443
|
try {
|
|
394
|
-
const response = recover(requestId, {
|
|
444
|
+
const response = recover(requestId, { timeoutMs });
|
|
395
445
|
if (response.phase === 'rejected' && response.error?.code === 'SANDBOX_CONTROL_RESULT_UNKNOWN')
|
|
396
446
|
continue;
|
|
397
447
|
return response;
|
|
@@ -406,156 +456,13 @@ export function recoverAcceptedTaskFinalization(requestId, params, recover = rec
|
|
|
406
456
|
}
|
|
407
457
|
clientError('SANDBOX_CONTROL_RESULT_UNKNOWN', 'accepted finalization request remained unknown after the automatic recovery budget; inspect the receipt and resume by request id', false, true, requestId);
|
|
408
458
|
}
|
|
409
|
-
function exactKeys(value, keys) {
|
|
410
|
-
return Object.keys(value).sort().join(',') === [...keys].sort().join(',');
|
|
411
|
-
}
|
|
412
|
-
function validProcess(value) {
|
|
413
|
-
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
414
|
-
return false;
|
|
415
|
-
const identity = value;
|
|
416
|
-
return exactKeys(identity, ['pid', 'startTime'])
|
|
417
|
-
&& Number.isSafeInteger(identity.pid) && identity.pid > 0
|
|
418
|
-
&& Number.isSafeInteger(identity.startTime) && identity.startTime >= 0;
|
|
419
|
-
}
|
|
420
|
-
function validBuild(value) {
|
|
421
|
-
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
422
|
-
return false;
|
|
423
|
-
const build = value;
|
|
424
|
-
return exactKeys(build, ['internalExecutableBuildHash', 'lifecycleContractHash', 'packageVersion', 'protocolVersion'])
|
|
425
|
-
&& build.protocolVersion === 3
|
|
426
|
-
&& typeof build.packageVersion === 'string' && build.packageVersion.length > 0
|
|
427
|
-
&& typeof build.internalExecutableBuildHash === 'string' && /^[a-f0-9]{64}$/u.test(build.internalExecutableBuildHash)
|
|
428
|
-
&& typeof build.lifecycleContractHash === 'string' && /^[a-f0-9]{64}$/u.test(build.lifecycleContractHash);
|
|
429
|
-
}
|
|
430
|
-
export function parseCodexControllerResult(response) {
|
|
431
|
-
if (response.phase !== 'completed' || response.error !== null || response.stderr !== '') {
|
|
432
|
-
clientError('SANDBOX_CONTROL_RESULT_INVALID', 'controller result outer response is invalid', false, true);
|
|
433
|
-
}
|
|
434
|
-
let value;
|
|
435
|
-
try {
|
|
436
|
-
if (!response.stdout.endsWith('\n') || response.stdout.slice(0, -1).includes('\n'))
|
|
437
|
-
throw new Error('not canonical');
|
|
438
|
-
value = JSON.parse(response.stdout);
|
|
439
|
-
}
|
|
440
|
-
catch {
|
|
441
|
-
clientError('SANDBOX_CONTROL_RESULT_INVALID', 'controller result payload is invalid', false, true);
|
|
442
|
-
}
|
|
443
|
-
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
444
|
-
clientError('SANDBOX_CONTROL_RESULT_INVALID', 'controller result payload is invalid', false, true);
|
|
445
|
-
}
|
|
446
|
-
const result = value;
|
|
447
|
-
const resultKeys = result.status === 'verified'
|
|
448
|
-
? ['binding', 'changed', 'error', 'lease', 'status', 'version']
|
|
449
|
-
: ['changed', 'error', 'lease', 'status', 'version'];
|
|
450
|
-
if (!exactKeys(result, resultKeys)
|
|
451
|
-
|| result.version !== 1 || !['opened', 'closed', 'failed', 'verified'].includes(result.status)) {
|
|
452
|
-
clientError('SANDBOX_CONTROL_RESULT_INVALID', 'controller result schema is invalid', false, true);
|
|
453
|
-
}
|
|
454
|
-
if (result.status === 'failed') {
|
|
455
|
-
const error = result.error;
|
|
456
|
-
if (response.exitCode !== 1 || result.changed !== false || result.lease !== null
|
|
457
|
-
|| !error || !exactKeys(error, ['code', 'message', 'retryable'])
|
|
458
|
-
|| typeof error.code !== 'string' || !/^[A-Z][A-Z0-9_]+$/u.test(error.code)
|
|
459
|
-
|| typeof error.message !== 'string' || error.retryable !== false) {
|
|
460
|
-
clientError('SANDBOX_CONTROL_RESULT_INVALID', 'controller failure result is invalid', false, true);
|
|
461
|
-
}
|
|
462
|
-
clientError(error.code, error.message, false, true);
|
|
463
|
-
}
|
|
464
|
-
if (response.exitCode !== 0 || result.error !== null) {
|
|
465
|
-
clientError('SANDBOX_CONTROL_RESULT_INVALID', 'controller success result is invalid', false, true);
|
|
466
|
-
}
|
|
467
|
-
if (result.status === 'closed') {
|
|
468
|
-
if (typeof result.changed !== 'boolean' || result.lease !== null) {
|
|
469
|
-
clientError('SANDBOX_CONTROL_RESULT_INVALID', 'controller close result is invalid', false, true);
|
|
470
|
-
}
|
|
471
|
-
return result;
|
|
472
|
-
}
|
|
473
|
-
if (result.status === 'verified') {
|
|
474
|
-
const binding = result.binding;
|
|
475
|
-
if (result.changed !== false || result.lease !== null || !binding
|
|
476
|
-
|| !exactKeys(binding, ['controllerInstanceDigest', 'controlGeneration', 'taskId'])
|
|
477
|
-
|| typeof binding.taskId !== 'string' || binding.taskId.length === 0
|
|
478
|
-
|| typeof binding.controlGeneration !== 'string' || binding.controlGeneration.length === 0
|
|
479
|
-
|| typeof binding.controllerInstanceDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(binding.controllerInstanceDigest)) {
|
|
480
|
-
clientError('SANDBOX_CONTROL_RESULT_INVALID', 'controller verify result is invalid', false, true);
|
|
481
|
-
}
|
|
482
|
-
return result;
|
|
483
|
-
}
|
|
484
|
-
const lease = result.lease;
|
|
485
|
-
if (result.changed !== true || !lease
|
|
486
|
-
|| !exactKeys(lease, [
|
|
487
|
-
'buildIdentity', 'controlGeneration', 'controllerInstanceDigest', 'controllerProcess',
|
|
488
|
-
'expiresAt', 'issuedAt', 'leaseId', 'leaseSecret', 'taskId', 'version'
|
|
489
|
-
])
|
|
490
|
-
|| lease.version !== 1
|
|
491
|
-
|| typeof lease.leaseId !== 'string' || !/^[a-f0-9]{64}$/u.test(lease.leaseId)
|
|
492
|
-
|| typeof lease.leaseSecret !== 'string' || !/^[a-f0-9]{64}$/u.test(lease.leaseSecret)
|
|
493
|
-
|| typeof lease.taskId !== 'string' || lease.taskId.length === 0
|
|
494
|
-
|| typeof lease.controlGeneration !== 'string' || lease.controlGeneration.length === 0
|
|
495
|
-
|| typeof lease.controllerInstanceDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(lease.controllerInstanceDigest)
|
|
496
|
-
|| !validProcess(lease.controllerProcess) || !validBuild(lease.buildIdentity)
|
|
497
|
-
|| !Number.isSafeInteger(lease.issuedAt) || !Number.isSafeInteger(lease.expiresAt)
|
|
498
|
-
|| lease.expiresAt <= lease.issuedAt) {
|
|
499
|
-
clientError('SANDBOX_CONTROL_RESULT_INVALID', 'controller open result is invalid', false, true);
|
|
500
|
-
}
|
|
501
|
-
return result;
|
|
502
|
-
}
|
|
503
|
-
function requestCodexController(params) {
|
|
504
|
-
const auth = authority(params);
|
|
505
|
-
const issuedAt = Date.now();
|
|
506
|
-
const request = {
|
|
507
|
-
version: 3,
|
|
508
|
-
id: randomUUID(),
|
|
509
|
-
...auth,
|
|
510
|
-
issuedAt,
|
|
511
|
-
expiresAt: issuedAt + SANDBOX_CONTROL_ADMISSION_WINDOW_MS,
|
|
512
|
-
family: 'codex-controller',
|
|
513
|
-
command: params.command,
|
|
514
|
-
args: [],
|
|
515
|
-
controllerProcess: params.controllerProcess,
|
|
516
|
-
controllerProof: params.controllerProof
|
|
517
|
-
};
|
|
518
|
-
const result = parseCodexControllerResult(exchangeSandboxControl(request, params));
|
|
519
|
-
if (result.status === 'opened'
|
|
520
|
-
&& (result.lease.controlGeneration !== auth.generation
|
|
521
|
-
|| result.lease.controllerProcess.pid !== params.controllerProcess.pid
|
|
522
|
-
|| result.lease.controllerProcess.startTime !== params.controllerProcess.startTime)) {
|
|
523
|
-
clientError('SANDBOX_CONTROL_RESULT_INVALID', 'controller result does not match the request', false, true);
|
|
524
|
-
}
|
|
525
|
-
return result;
|
|
526
|
-
}
|
|
527
|
-
export function requestCodexControllerOpen(params) {
|
|
528
|
-
const result = requestCodexController({ ...params, command: 'open', controllerProof: null });
|
|
529
|
-
if (result.status !== 'opened')
|
|
530
|
-
clientError('SANDBOX_CONTROL_RESULT_INVALID', 'controller open returned the wrong result', false, true);
|
|
531
|
-
return result;
|
|
532
|
-
}
|
|
533
|
-
export function requestCodexControllerClose(params) {
|
|
534
|
-
const result = requestCodexController({ ...params, command: 'close' });
|
|
535
|
-
if (result.status !== 'closed')
|
|
536
|
-
clientError('SANDBOX_CONTROL_RESULT_INVALID', 'controller close returned the wrong result', false, true);
|
|
537
|
-
return result;
|
|
538
|
-
}
|
|
539
|
-
export function requestCodexControllerVerify(params) {
|
|
540
|
-
const result = requestCodexController({
|
|
541
|
-
...params,
|
|
542
|
-
controllerProcess: params.controllerProof.controllerProcess,
|
|
543
|
-
command: 'verify'
|
|
544
|
-
});
|
|
545
|
-
if (result.status !== 'verified') {
|
|
546
|
-
clientError('SANDBOX_CONTROL_RESULT_INVALID', 'controller verify returned the wrong result', false, true);
|
|
547
|
-
}
|
|
548
|
-
return result;
|
|
549
|
-
}
|
|
550
459
|
export function requestSandboxTaskCreate(params) {
|
|
551
460
|
const auth = authority(params);
|
|
552
461
|
const issuedAt = Date.now();
|
|
553
462
|
const request = {
|
|
554
|
-
version:
|
|
463
|
+
version: 4, id: randomUUID(), ...auth, issuedAt,
|
|
555
464
|
expiresAt: issuedAt + SANDBOX_CONTROL_ADMISSION_WINDOW_MS,
|
|
556
465
|
family: 'task-create', candidate: params.candidate,
|
|
557
|
-
controllerProcess: null,
|
|
558
|
-
controllerProof: null
|
|
559
466
|
};
|
|
560
467
|
return exchangeSandboxControl(request, { ...params, timeoutMs: params.timeoutMs ?? 120_000 });
|
|
561
468
|
}
|
|
@@ -2,7 +2,6 @@ import { spawn } from 'node:child_process';
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
|
-
import { homedir } from 'node:os';
|
|
6
5
|
import { getProcessStartTime } from '../../server/process-state.js';
|
|
7
6
|
import { createTask, projectTaskCreateResult, taskCreateExitCode, taskCreateFailure } from '../../task/create-service.js';
|
|
8
7
|
import { applyTaskFinalization } from '../../task/finalization.js';
|
|
@@ -13,12 +12,7 @@ import { requestAuditFields, resultAuditFields, appendDiagnosticAudit, createSan
|
|
|
13
12
|
import { validateSandboxControlIdentity } from './identity-sentinel.js';
|
|
14
13
|
import { createSandboxExecutorExecutionContext, dispatchTaskControlOperation, parseTaskControlOperation } from '../../task/control-authority.js';
|
|
15
14
|
import { assertSandboxControlBrokerOwner, readSandboxControlManifest } from './lifecycle.js';
|
|
16
|
-
import {
|
|
17
|
-
import { closeCodexControllerRegistration, CodexControllerRegistrationError, openCodexControllerRegistration, resolveCodexControllerBinding } from './controller-registration.js';
|
|
18
|
-
import { shareBranchDir } from '../constants.js';
|
|
19
|
-
function handoffDirectory(manifest) {
|
|
20
|
-
return shareBranchDir({ shareBase: path.join(homedir(), '.agent-infra', 'share', manifest.project) }, manifest.branch);
|
|
21
|
-
}
|
|
15
|
+
import { executeAgentClientOperation, validateAgentClientOperation } from './agent-operation.js';
|
|
22
16
|
function sameBrokerOwner(left, right) {
|
|
23
17
|
return left.version === right.version
|
|
24
18
|
&& left.pid === right.pid
|
|
@@ -174,23 +168,6 @@ function waitForGate(nonce, timeoutMs = 2_000) {
|
|
|
174
168
|
});
|
|
175
169
|
});
|
|
176
170
|
}
|
|
177
|
-
function controllerFailure(error) {
|
|
178
|
-
const code = error instanceof CodexControllerRegistrationError
|
|
179
|
-
? error.code
|
|
180
|
-
: /^([A-Z][A-Z0-9_]+)/u.exec(error instanceof Error ? error.message : String(error))?.[1]
|
|
181
|
-
?? 'CODEX_SANDBOX_CONTROLLER_FAILED';
|
|
182
|
-
const message = error instanceof CodexControllerRegistrationError
|
|
183
|
-
? error.message
|
|
184
|
-
: `${code}: controller operation failed; inspect the sandbox controller and rebuild the sandbox if needed`;
|
|
185
|
-
const payload = {
|
|
186
|
-
version: 1,
|
|
187
|
-
status: 'failed',
|
|
188
|
-
changed: false,
|
|
189
|
-
lease: null,
|
|
190
|
-
error: { code, message, retryable: false }
|
|
191
|
-
};
|
|
192
|
-
return { exitCode: 1, stdout: `${JSON.stringify(payload)}\n`, stderr: '' };
|
|
193
|
-
}
|
|
194
171
|
function lifecycleFailure(code, message) {
|
|
195
172
|
return {
|
|
196
173
|
exitCode: 1,
|
|
@@ -233,7 +210,7 @@ function finalizationResult(result) {
|
|
|
233
210
|
async function executeRequestInner(manifest, manifestPath, request, options = {}) {
|
|
234
211
|
if (request.family === 'task-create') {
|
|
235
212
|
try {
|
|
236
|
-
const result = await createTask(request.candidate, { repoRoot: manifest.repoRoot });
|
|
213
|
+
const result = await (options.createTask ?? createTask)(request.candidate, { repoRoot: manifest.repoRoot });
|
|
237
214
|
return taskCreateExecutionResult(projectTaskCreateResult(result, {
|
|
238
215
|
requestId: request.id,
|
|
239
216
|
accepted: true,
|
|
@@ -246,65 +223,15 @@ async function executeRequestInner(manifest, manifestPath, request, options = {}
|
|
|
246
223
|
return taskCreateExecutionFailure(request.id, code, detail);
|
|
247
224
|
}
|
|
248
225
|
}
|
|
249
|
-
if (request.family === '
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const binding = (options.resolveControllerBinding ?? resolveCodexControllerBinding)({
|
|
253
|
-
manifest,
|
|
254
|
-
manifestPath,
|
|
255
|
-
proof: request.controllerProof,
|
|
256
|
-
buildIdentity: (options.buildIdentity ?? computeLifecycleBuildIdentity)(manifest.repoRoot)
|
|
257
|
-
});
|
|
258
|
-
return {
|
|
259
|
-
exitCode: 0,
|
|
260
|
-
stdout: `${JSON.stringify({
|
|
261
|
-
version: 1,
|
|
262
|
-
status: 'verified',
|
|
263
|
-
changed: false,
|
|
264
|
-
lease: null,
|
|
265
|
-
binding: {
|
|
266
|
-
taskId: manifest.taskId,
|
|
267
|
-
controlGeneration: binding.controlGeneration,
|
|
268
|
-
controllerInstanceDigest: binding.instanceDigest
|
|
269
|
-
},
|
|
270
|
-
error: null
|
|
271
|
-
})}\n`,
|
|
272
|
-
stderr: ''
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
const result = request.command === 'open'
|
|
276
|
-
? openCodexControllerRegistration({
|
|
277
|
-
manifest,
|
|
278
|
-
manifestPath,
|
|
279
|
-
controllerProcess: request.controllerProcess,
|
|
280
|
-
buildIdentity: (options.buildIdentity ?? computeLifecycleBuildIdentity)(manifest.repoRoot)
|
|
281
|
-
})
|
|
282
|
-
: closeCodexControllerRegistration({
|
|
283
|
-
manifest,
|
|
284
|
-
manifestPath,
|
|
285
|
-
proof: request.controllerProof
|
|
286
|
-
});
|
|
287
|
-
return { exitCode: 0, stdout: `${JSON.stringify(result)}\n`, stderr: '' };
|
|
288
|
-
}
|
|
289
|
-
catch (error) {
|
|
290
|
-
const errorCode = error instanceof CodexControllerRegistrationError
|
|
291
|
-
? error.code
|
|
292
|
-
: /^([A-Z][A-Z0-9_]+)/u.exec(error instanceof Error ? error.message : String(error))?.[1]
|
|
293
|
-
?? 'CODEX_SANDBOX_CONTROLLER_FAILED';
|
|
294
|
-
appendExecutorAudit(manifest, 'controller-operation-failed', {
|
|
295
|
-
...requestAuditFields(manifest, request),
|
|
296
|
-
controllerCommand: request.command,
|
|
297
|
-
errorCode,
|
|
298
|
-
errorType: error instanceof Error ? error.name : typeof error,
|
|
299
|
-
});
|
|
300
|
-
return controllerFailure(error);
|
|
301
|
-
}
|
|
226
|
+
if (request.family === 'agent-client') {
|
|
227
|
+
validateAgentClientOperation(request, manifest);
|
|
228
|
+
return executeAgentClientOperation(request, manifest, manifestPath, options.agentClientOperation);
|
|
302
229
|
}
|
|
303
230
|
if (request.family === 'task-finalization') {
|
|
304
231
|
const parsed = parseTaskControlOperation('task-finalization', [manifest.taskId, 'complete', '--agent', request.agent]);
|
|
305
232
|
if (parsed.family !== 'task-finalization')
|
|
306
233
|
throw new Error('SANDBOX_CONTROL_FINALIZATION_OPERATION_INVALID');
|
|
307
|
-
const operation =
|
|
234
|
+
const operation = parsed;
|
|
308
235
|
const result = dispatchTaskControlOperation(createSandboxExecutorExecutionContext({
|
|
309
236
|
repoRoot: manifest.repoRoot,
|
|
310
237
|
worktreeRoot: manifest.worktreeRoot,
|
|
@@ -312,8 +239,7 @@ async function executeRequestInner(manifest, manifestPath, request, options = {}
|
|
|
312
239
|
taskId: manifest.taskId,
|
|
313
240
|
generation: manifest.generation,
|
|
314
241
|
manifestPath,
|
|
315
|
-
requestId: request.id
|
|
316
|
-
handoffDirectory: handoffDirectory(manifest)
|
|
242
|
+
requestId: request.id
|
|
317
243
|
}), operation);
|
|
318
244
|
return finalizationResult(await result);
|
|
319
245
|
}
|
|
@@ -334,8 +260,7 @@ async function executeRequestInner(manifest, manifestPath, request, options = {}
|
|
|
334
260
|
taskId: manifest.taskId,
|
|
335
261
|
generation: manifest.generation,
|
|
336
262
|
manifestPath,
|
|
337
|
-
requestId: request.id
|
|
338
|
-
handoffDirectory: handoffDirectory(manifest)
|
|
263
|
+
requestId: request.id
|
|
339
264
|
});
|
|
340
265
|
const format = (value) => {
|
|
341
266
|
const result = value;
|
|
@@ -353,7 +278,8 @@ export async function executeRequest(manifest, manifestPath, request, options =
|
|
|
353
278
|
const fields = requestAuditFields(manifest, request);
|
|
354
279
|
appendExecutorAudit(manifest, 'executor-request-start', fields);
|
|
355
280
|
try {
|
|
356
|
-
|
|
281
|
+
let result;
|
|
282
|
+
result = await executeRequestInner(manifest, manifestPath, request, options);
|
|
357
283
|
appendExecutorAudit(manifest, 'executor-request-finished', {
|
|
358
284
|
requestId: request.id,
|
|
359
285
|
requestFamily: request.family,
|
|
@@ -431,13 +357,13 @@ export async function runSandboxControlExecutor(requestPath, nonce) {
|
|
|
431
357
|
return null;
|
|
432
358
|
}
|
|
433
359
|
})()
|
|
434
|
-
: null;
|
|
360
|
+
: request.family === 'agent-client' ? request.operation : null;
|
|
435
361
|
const context = createSandboxControlAuditContext(manifest, {
|
|
436
362
|
requestId: request.id,
|
|
437
363
|
family: request.family,
|
|
438
|
-
operation: operation
|
|
364
|
+
operation: operation && typeof operation === 'object' && 'family' in operation && operation.family === 'task-lifecycle'
|
|
439
365
|
? operation.request.intent
|
|
440
|
-
: request.family === 'task-finalization' ? request.operation : null,
|
|
366
|
+
: request.family === 'task-finalization' || request.family === 'agent-client' ? request.operation : null,
|
|
441
367
|
phase: 'started-committed',
|
|
442
368
|
outcome: 'in-progress'
|
|
443
369
|
});
|