feat: add compact Codex child agent tracking

This commit is contained in:
shiyue
2026-06-16 18:16:41 +08:00
parent 51838a2ce1
commit 7e01f24e61
5 changed files with 477 additions and 93 deletions

View File

@@ -2,6 +2,7 @@ const http = require('http');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const os = require('os');
const { spawn, spawnSync } = require('child_process');
const { WebSocketServer } = require('ws');
const { createAgentRuntime } = require('./lib/agent-runtime');
@@ -69,6 +70,50 @@ const CROSS_CONVERSATION_MAX_CONTENT_CHARS = readPositiveIntEnv('CC_WEB_CROSS_CO
const MCP_CREATE_CONVERSATION_MAX_HOP_COUNT = readPositiveIntEnv('CC_WEB_MCP_CREATE_CONVERSATION_MAX_HOP_COUNT', 3, { min: 1, max: 20 });
const CODEX_APP_WORKER_DISABLED = /^(0|false|no|off)$/i.test(String(process.env.CC_WEB_CODEX_APP_WORKER || ''));
const CODEX_APP_WORKER_ENABLED = !CODEX_APP_WORKER_DISABLED;
const CODEX_APP_PROCESS_ENV_STRIP_KEYS = [
'CC_WEB_MCP_URL',
'CC_WEB_MCP_TOKEN',
'CC_WEB_SOURCE_SESSION_ID',
'CC_WEB_CROSS_HOP_COUNT',
'CODEX_THREAD_ID',
'CODEX_CI',
];
const PROCESS_CLEAN_PATH_FALLBACK = [
path.join(os.homedir(), '.local/bin'),
'/usr/local/sbin',
'/usr/local/bin',
'/usr/sbin',
'/usr/bin',
'/sbin',
'/bin',
].join(path.delimiter);
function isCodexInjectedPathEntry(value) {
const normalized = String(value || '').replace(/\\/g, '/');
if (!normalized) return true;
if (normalized.includes('/.codex/tmp/arg0')) return true;
return normalized.includes('/node_modules/@openai/codex/')
&& /\/(?:codex-path|path)$/.test(normalized);
}
function cleanProcessPathValue(value) {
const override = String(process.env.CC_WEB_PROCESS_CLEAN_PATH || '').trim();
const source = override || value || PROCESS_CLEAN_PATH_FALLBACK;
const fallbackEntries = PROCESS_CLEAN_PATH_FALLBACK.split(path.delimiter).filter(Boolean);
const output = [];
const seen = new Set();
const addEntry = (entry) => {
const text = String(entry || '').trim();
if (!text || seen.has(text) || isCodexInjectedPathEntry(text)) return;
seen.add(text);
output.push(text);
};
String(source).split(path.delimiter).forEach(addEntry);
fallbackEntries.forEach(addEntry);
return output.length > 0 ? output.join(path.delimiter) : PROCESS_CLEAN_PATH_FALLBACK;
}
const PERSIST_TRUNCATED_TEXT = '[cc-web: 内容过大,已截断以保护服务稳定性]';
const IMAGE_MIME_TYPES = new Set(['image/png', 'image/jpeg', 'image/webp', 'image/gif']);
const TEXT_PREVIEW_EXTENSIONS = new Set([
@@ -6260,6 +6305,12 @@ function buildCodexAppClientSpec() {
if (runtimeConfig?.error) return { error: runtimeConfig.error };
const env = { ...process.env };
const strippedEnvKeys = [];
for (const key of CODEX_APP_PROCESS_ENV_STRIP_KEYS) {
if (Object.prototype.hasOwnProperty.call(env, key)) strippedEnvKeys.push(key);
delete env[key];
}
env.PATH = cleanProcessPathValue(env.PATH);
delete env.CC_WEB_PASSWORD;
delete env.CLAUDECODE;
delete env.CLAUDE_CODE;
@@ -6286,6 +6337,7 @@ function buildCodexAppClientSpec() {
env,
cwd: process.env.HOME || process.env.USERPROFILE || process.cwd(),
signature,
strippedEnvKeys,
};
}
@@ -6328,6 +6380,7 @@ function getCodexAppClient() {
plog('INFO', 'codex_app_client_created', {
worker: CODEX_APP_WORKER_ENABLED,
command: path.basename(spec.command || ''),
strippedEnvKeys: spec.strippedEnvKeys || [],
});
}