fix: make mcp suggestions runtime-backed

This commit is contained in:
shiyue
2026-06-24 11:10:45 +08:00
parent 54edeec802
commit ca97d92a8d
4 changed files with 321 additions and 130 deletions

View File

@@ -30,6 +30,24 @@ function createAgentRuntime(deps) {
return `[${values.map((value) => tomlString(value)).join(',')}]`;
}
function tomlKeySegment(value) {
const raw = String(value || '').trim();
if (/^[A-Za-z0-9_-]+$/.test(raw)) return raw;
return tomlString(raw);
}
function tomlValue(value) {
if (Array.isArray(value)) return `[${value.map((item) => tomlValue(item)).join(',')}]`;
if (value && typeof value === 'object') {
return `{${Object.entries(value)
.map(([key, item]) => `${tomlKeySegment(key)}=${tomlValue(item)}`)
.join(',')}}`;
}
if (typeof value === 'boolean') return value ? 'true' : 'false';
if (typeof value === 'number' && Number.isFinite(value)) return String(value);
return tomlString(value);
}
function createCcwebMcpEnv(session, options = {}) {
if (!ccwebMcpServerArg || !internalMcpUrl || !internalMcpToken || !session?.id) return null;
const rawHopCount = Number.parseInt(String(options.mcpContext?.hopCount || 0), 10);
@@ -55,6 +73,22 @@ function createAgentRuntime(deps) {
);
}
function appendProjectMcpConfig(args, mcpServer) {
const server = String(mcpServer?.server || mcpServer?.name || '').trim();
const config = mcpServer?.config && typeof mcpServer.config === 'object' ? mcpServer.config : null;
if (!server || !config) return;
const prefix = `mcp_servers.${tomlKeySegment(server)}`;
for (const key of ['type', 'command', 'args', 'env', 'env_vars', 'url', 'startup_timeout_sec', 'tool_timeout_sec']) {
if (!Object.prototype.hasOwnProperty.call(config, key)) continue;
args.push('-c', `${prefix}.${key}=${tomlValue(config[key])}`);
}
}
function appendProjectMcpConfigs(args, mcpServers) {
if (!Array.isArray(mcpServers)) return;
for (const mcpServer of mcpServers) appendProjectMcpConfig(args, mcpServer);
}
function buildClaudeSpawnSpec(session, options = {}) {
const hasAttachments = Array.isArray(options.attachments) && options.attachments.length > 0;
const args = ['-p', '--output-format', 'stream-json', '--verbose'];
@@ -110,10 +144,11 @@ function createAgentRuntime(deps) {
return { error: runtimeConfig.error };
}
const runtimeId = getRuntimeSessionId(session);
const args = ['exec'];
args.push('--json', '--skip-git-repo-check');
const args = ['exec'];
args.push('--json', '--skip-git-repo-check');
const ccwebMcpEnv = createCcwebMcpEnv(session, options);
appendCcwebMcpConfig(args, ccwebMcpEnv);
appendProjectMcpConfigs(args, options.projectMcpConfigs);
const permMode = session.permissionMode || 'yolo';
// `-s/--sandbox` is an option for `codex exec`, but not for `codex exec resume`.