import { spawn } from 'node:child_process'; import fs from 'node:fs'; import readline from 'node:readline'; const configPath = process.env.AGC_CONFIG_PATH ?? 'C:/Users/kdletters/AppData/Roaming/world.genarrative.ai-game-creator/game-creator.config.json'; const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); const args = [ 'app-server', '--stdio', '-c', 'web_search="disabled"', '-c', 'agents.enabled=false', ]; for (const feature of [ 'apps', 'browser_use', 'browser_use_external', 'browser_use_full_cdp_access', 'computer_use', 'goals', 'image_generation', 'in_app_browser', 'plugins', 'remote_plugin', 'shell_tool', 'tool_suggest', 'unified_exec', 'workspace_dependencies', ]) args.push('--disable', feature); args.push( '-c', 'model_provider="genarrative_agc"', '-c', 'model_providers.genarrative_agc.name="Genarrative AGC"', '-c', `model_providers.genarrative_agc.base_url="${config.llm.baseUrl.replace(/\/$/, '')}"`, '-c', 'model_providers.genarrative_agc.env_key="GENARRATIVE_AGC_API_KEY"', '-c', 'model_providers.genarrative_agc.wire_api="responses"', ); const child = spawn( 'C:/Program Files/nodejs/node.exe', [ 'C:/Users/kdletters/AppData/Roaming/npm/node_modules/@openai/codex/bin/codex.js', ...args, ], { cwd: process.cwd(), env: { ...process.env, GENARRATIVE_AGC_API_KEY: config.llm.apiKey }, stdio: ['pipe', 'pipe', 'pipe'], }, ); const send = (value) => child.stdin.write(`${JSON.stringify(value)}\n`); const timer = setTimeout( () => { console.log('smoke-timeout'); child.kill(); process.exit(1); }, Number(process.env.DIRECT_SMOKE_TIMEOUT_MS ?? 180000), ); readline.createInterface({ input: child.stdout }).on('line', (line) => { let message; try { message = JSON.parse(line); } catch { return; } if (message.id === 2) { console.log('thread-start-ok'); const write = process.env.DIRECT_SMOKE_WRITE === '1'; send({ id: 3, method: 'turn/start', params: { threadId: message.result.thread.id, input: [ { type: 'text', text: process.env.DIRECT_SMOKE_PROMPT ?? (write ? '在当前工作区创建 smoke-marker.txt,写入 DIRECT_CODEX_WRITE_OK,然后回复已完成。' : '只回复 DIRECT_CODEX_SMOKE_OK,不要修改文件。'), }, ], model: config.llm.model, approvalPolicy: 'never', sandboxPolicy: write ? { type: 'workspaceWrite', writableRoots: [process.cwd()], networkAccess: true, } : { type: 'readOnly', networkAccess: false }, }, }); } if (message.id === 3 && message.error) { console.log(`turn-start-error:${message.error.message}`); clearTimeout(timer); child.kill(); process.exit(1); } if (message.method === 'turn/completed') { console.log(`turn-completed:${message.params?.turn?.status}`); clearTimeout(timer); child.kill(); process.exit(message.params?.turn?.status === 'completed' ? 0 : 1); } }); send({ id: 1, method: 'initialize', params: { clientInfo: { name: 'agc-direct-smoke', version: '0.1' }, capabilities: { experimentalApi: true }, }, }); send({ method: 'initialized', params: {} }); send({ id: 2, method: 'thread/start', params: { cwd: process.cwd(), model: config.llm.model, approvalPolicy: 'never', sandbox: process.env.DIRECT_SMOKE_WRITE === '1' ? 'workspace-write' : 'read-only', ephemeral: true, }, });