feat: add compact Codex child agent tracking
This commit is contained in:
53
server.js
53
server.js
@@ -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 || [],
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user