Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions agents/adapters/claude.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export function startClaudeInvocation(request: AgentAdapterRequest,
try { network = createVendorNetwork(request.invocation, request.imageId, Math.min(60_000, remaining())); }
catch (error) {
if (error instanceof VendorNetworkCreationCleanupError)
return retainSetupCleanup(request.invocation, error.retryCleanup, error.startupError, error,
'network creation cleanup');
return retainSetupCleanup(request.invocation, budget => error.retryCleanup(budget), error.startupError, error,
'network creation cleanup', () => error.resources);
throw error;
}
try {
Expand All @@ -38,13 +38,13 @@ export function startClaudeInvocation(request: AgentAdapterRequest,
if (error instanceof ProfileCreationCleanupError) {
const retryCleanup = (networkTimeoutMs = 30_000) => {
const failures: unknown[] = [];
try { error.retryCleanup(); } catch (cleanupError) { failures.push(cleanupError); }
try { error.retryCleanup(networkTimeoutMs); } catch (cleanupError) { failures.push(cleanupError); }
try { removeVendorNetwork(network, networkTimeoutMs); } catch (cleanupError) { failures.push(cleanupError); }
if (failures.length) throw new AggregateError(failures, 'Adapter setup cleanup did not settle.');
};
try { retryCleanup(Math.min(30_000, remaining())); }
catch (cleanupError) { return retainSetupCleanup(request.invocation, () => retryCleanup(),
error.startupError, cleanupError, 'profile and network cleanup'); }
catch (cleanupError) { return retainSetupCleanup(request.invocation, budget => retryCleanup(budget),
error.startupError, cleanupError, 'profile and network cleanup', () => error.resources); }
throw error.startupError;
}
try { removeVendorNetwork(network, Math.min(30_000, remaining())); }
Expand Down
21 changes: 14 additions & 7 deletions agents/adapters/codex.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { InvocationHandle } from '../contract.ts';
import { createContainerProfile, ProfileCreationCleanupError } from '../container/profile.ts';
import { createContainerProfile, ProfileCreationCleanupError, type ContainerProfile } from '../container/profile.ts';
import { agentContainerId } from '../container/run.ts';
import { createVendorNetwork, removeVendorNetwork, VendorNetworkCreationCleanupError,
type VendorNetwork } from '../network/network.ts';
import { createCodexCommand, createPhasePolicy } from '../policy.ts';
Expand All @@ -8,6 +9,12 @@ import { readBoundedContainerFile, retainNetworkCleanup, retainSetupCleanup,
import { createAdapterInvocationBudget, type AgentAdapterOptions, type AgentAdapterRequest } from './types.ts';

export const CODEX_OUTPUT_FILE = '/run/codeboost-output/final.txt';
// Read the output from the container this invocation created, by ID; a same-named replacement must not answer.
const codexContainer = (profile: ContainerProfile) => {
const id = agentContainerId(profile);
if (!id) throw new Error('The Codex container ID is unknown.');
return id;
};

export async function readCodexOutput(container: string, maximumBytes: number, timeoutMs = 30_000,
signal?: AbortSignal) {
Expand All @@ -25,8 +32,8 @@ export function startCodexInvocation(request: AgentAdapterRequest,
try { network = createVendorNetwork(request.invocation, request.imageId, Math.min(60_000, remaining())); }
catch (error) {
if (error instanceof VendorNetworkCreationCleanupError)
return retainSetupCleanup(request.invocation, error.retryCleanup, error.startupError, error,
'network creation cleanup');
return retainSetupCleanup(request.invocation, budget => error.retryCleanup(budget), error.startupError, error,
'network creation cleanup', () => error.resources);
throw error;
}
try {
Expand All @@ -36,18 +43,18 @@ export function startCodexInvocation(request: AgentAdapterRequest,
return startProfileInvocation(profile, { ...options,
invocationBudget: remaining,
decode: (current, _raw, maximum, timeoutMs, signal) =>
readCodexOutput(current.name, maximum, timeoutMs, signal) });
readCodexOutput(codexContainer(current), maximum, timeoutMs, signal) });
} catch (error) {
if (error instanceof ProfileCreationCleanupError) {
const retryCleanup = (networkTimeoutMs = 30_000) => {
const failures: unknown[] = [];
try { error.retryCleanup(); } catch (cleanupError) { failures.push(cleanupError); }
try { error.retryCleanup(networkTimeoutMs); } catch (cleanupError) { failures.push(cleanupError); }
try { removeVendorNetwork(network, networkTimeoutMs); } catch (cleanupError) { failures.push(cleanupError); }
if (failures.length) throw new AggregateError(failures, 'Adapter setup cleanup did not settle.');
};
try { retryCleanup(Math.min(30_000, remaining())); }
catch (cleanupError) { return retainSetupCleanup(request.invocation, () => retryCleanup(),
error.startupError, cleanupError, 'profile and network cleanup'); }
catch (cleanupError) { return retainSetupCleanup(request.invocation, budget => retryCleanup(budget),
error.startupError, cleanupError, 'profile and network cleanup', () => error.resources); }
throw error.startupError;
}
try { removeVendorNetwork(network, Math.min(30_000, remaining())); }
Expand Down
Loading
Loading