fix: tighten codex runtime config ownership

This commit is contained in:
Andrey Avtomonov 2026-06-01 17:41:20 +02:00
parent 074c9c3d97
commit f07f3f320b
4 changed files with 11 additions and 19 deletions

View file

@ -12,18 +12,14 @@ export interface BuildCodexRuntimeConfigInput {
export interface CodexRuntimeConfig { export interface CodexRuntimeConfig {
configOverrides: Record<string, unknown>; configOverrides: Record<string, unknown>;
env: NodeJS.ProcessEnv; env: Record<string, string>;
} }
export function buildCodexRuntimeConfig(input: BuildCodexRuntimeConfigInput): CodexRuntimeConfig { export function buildCodexRuntimeConfig(input: BuildCodexRuntimeConfigInput): CodexRuntimeConfig {
const configOverrides: Record<string, unknown> = { const configOverrides: Record<string, unknown> = {
model: input.model,
approval_policy: 'never',
sandbox_mode: 'read-only',
web_search: 'disabled',
history: { persistence: 'none' }, history: { persistence: 'none' },
}; };
const env: NodeJS.ProcessEnv = {}; const env: Record<string, string> = {};
if (input.mcp) { if (input.mcp) {
configOverrides.mcp_servers = { configOverrides.mcp_servers = {

View file

@ -79,6 +79,10 @@ async function mcpForTools(input: {
}); });
} }
function runtimeToolNames(toolSet: KtxRuntimeToolSet | undefined): string[] {
return Object.values(toolSet ?? {}).map((descriptor) => descriptor.name);
}
export class CodexKtxLlmRuntime implements KtxLlmRuntimePort { export class CodexKtxLlmRuntime implements KtxLlmRuntimePort {
private readonly runner: CodexSdkRunner; private readonly runner: CodexSdkRunner;
private readonly logger: KtxLogger; private readonly logger: KtxLogger;
@ -105,7 +109,7 @@ export class CodexKtxLlmRuntime implements KtxLlmRuntimePort {
url: mcp.url, url: mcp.url,
bearerTokenEnvVar: mcp.bearerTokenEnvVar, bearerTokenEnvVar: mcp.bearerTokenEnvVar,
bearerToken: mcp.bearerToken, bearerToken: mcp.bearerToken,
toolNames: Object.keys(input.tools ?? {}), toolNames: runtimeToolNames(input.tools),
}, },
} }
: {}), : {}),
@ -146,7 +150,7 @@ export class CodexKtxLlmRuntime implements KtxLlmRuntimePort {
url: mcp.url, url: mcp.url,
bearerTokenEnvVar: mcp.bearerTokenEnvVar, bearerTokenEnvVar: mcp.bearerTokenEnvVar,
bearerToken: mcp.bearerToken, bearerToken: mcp.bearerToken,
toolNames: Object.keys(input.tools ?? {}), toolNames: runtimeToolNames(input.tools),
}, },
} }
: {}), : {}),
@ -187,7 +191,7 @@ export class CodexKtxLlmRuntime implements KtxLlmRuntimePort {
url: mcp.url, url: mcp.url,
bearerTokenEnvVar: mcp.bearerTokenEnvVar, bearerTokenEnvVar: mcp.bearerTokenEnvVar,
bearerToken: mcp.bearerToken, bearerToken: mcp.bearerToken,
toolNames: Object.keys(params.toolSet), toolNames: runtimeToolNames(params.toolSet),
}, },
} }
: {}), : {}),

View file

@ -2,13 +2,9 @@ import { describe, expect, it } from 'vitest';
import { buildCodexRuntimeConfig } from '../../../src/context/llm/codex-runtime-config.js'; import { buildCodexRuntimeConfig } from '../../../src/context/llm/codex-runtime-config.js';
describe('buildCodexRuntimeConfig', () => { describe('buildCodexRuntimeConfig', () => {
it('builds deny-by-default config without MCP tools', () => { it('builds generic config without SDK thread-option fields', () => {
expect(buildCodexRuntimeConfig({ model: 'gpt-5.3-codex' })).toEqual({ expect(buildCodexRuntimeConfig({ model: 'gpt-5.3-codex' })).toEqual({
configOverrides: { configOverrides: {
model: 'gpt-5.3-codex',
approval_policy: 'never',
sandbox_mode: 'read-only',
web_search: 'disabled',
history: { persistence: 'none' }, history: { persistence: 'none' },
}, },
env: {}, env: {},
@ -28,10 +24,6 @@ describe('buildCodexRuntimeConfig', () => {
}), }),
).toEqual({ ).toEqual({
configOverrides: { configOverrides: {
model: 'gpt-5.3-codex',
approval_policy: 'never',
sandbox_mode: 'read-only',
web_search: 'disabled',
history: { persistence: 'none' }, history: { persistence: 'none' },
mcp_servers: { mcp_servers: {
ktx: { ktx: {

View file

@ -119,7 +119,7 @@ describe('CodexKtxLlmRuntime', () => {
telemetryTags: {}, telemetryTags: {},
onStepFinish, onStepFinish,
toolSet: { toolSet: {
wiki_search: { aliased_wiki_tool: {
name: 'wiki_search', name: 'wiki_search',
description: 'Search wiki', description: 'Search wiki',
inputSchema: z.object({ query: z.string() }), inputSchema: z.object({ query: z.string() }),