修复 Codex MCP type 配置并更新发布包

This commit is contained in:
shiyue
2026-10-08 14:55:58 +08:00
parent caf8947cd9
commit 747771a048
17 changed files with 181 additions and 4 deletions

View File

@@ -8540,6 +8540,7 @@ async function main() {
.split('\n')
.find((line) => line.includes(`"event":"process_spawn"`) && line.includes(crossTargetSession.sessionId.slice(0, 8)));
assert(mcpSpawnLine && mcpSpawnLine.includes('mcp_servers.ccweb.command') && mcpSpawnLine.includes('mcp_servers.ccweb.env_vars'), 'Codex spawn should inject ccweb MCP config');
assert(!mcpSpawnLine.includes('mcp_servers.ccweb.type'), 'Codex CLI ccweb MCP 配置应省略服务器顶层 type');
assert(mcpSpawnLine.includes('server.js') && mcpSpawnLine.includes('--ccweb-mcp-server'), 'Codex spawn should launch ccweb MCP through server.js in Node mode');
assert(!mcpSpawnLine.includes(internalMcpToken), 'Codex spawn log should not expose internal MCP token');
const projectMcpSpawnLine = processLogAfterMcp
@@ -8547,6 +8548,7 @@ async function main() {
.split('\n')
.find((line) => line.includes(`"event":"process_spawn"`) && line.includes(codexSession.sessionId.slice(0, 8)));
assert(projectMcpSpawnLine && projectMcpSpawnLine.includes('mcp_servers.reg-project.command'), 'Codex spawn should inject project MCP config from session cwd');
assert(!projectMcpSpawnLine.includes('mcp_servers.reg-project.type'), 'Codex CLI project MCP config should omit the server top-level type');
ws.send(JSON.stringify({ type: 'list_cwd_suggestions' }));
const cwdSuggestions = await nextMessage(messages, ws, (msg) => msg.type === 'cwd_suggestions');
@@ -8826,6 +8828,8 @@ async function main() {
const codexAppEnabledSearchDynamicTool = await nextMessage(messages, ws, (msg) => msg.type === 'tool_end' && msg.sessionId === codexAppSession.sessionId && msg.toolUseId === 'mcp-ccweb-list');
assert(/"threadStartWebSearchMode": "live"/.test(codexAppEnabledSearchDynamicTool.result || ''), 'Codex App thread/start should pass web_search=live when Web Search is enabled');
assert(/"webSearchMode": "live"/.test(codexAppEnabledSearchDynamicTool.result || ''), 'Codex App thread config should keep web_search=live while Web Search is enabled');
assert(/"ccwebHasTopLevelType": false/.test(codexAppEnabledSearchDynamicTool.result || ''), 'Codex App thread/start 的 ccweb 配置应省略顶层 type');
assert(/"projectHasTopLevelType": false/.test(codexAppEnabledSearchDynamicTool.result || ''), 'Codex App thread/start 的旧项目配置应省略顶层 type');
assert(!/"webSearchToolConfig"/.test(codexAppEnabledSearchDynamicTool.result || ''), 'Codex App should use top-level web_search instead of tools.web_search as the mode switch');
await nextMessage(messages, ws, (msg) => msg.type === 'done' && msg.sessionId === codexAppSession.sessionId);
@@ -8857,6 +8861,8 @@ async function main() {
ws.send(JSON.stringify({ type: 'message', text: 'codexapp dynamic after web search disabled prompt', sessionId: codexAppSession.sessionId, mode: 'yolo', agent: 'codexapp' }));
const codexAppDisabledSearchDynamicTool = await nextMessage(messages, ws, (msg) => msg.type === 'tool_end' && msg.sessionId === codexAppSession.sessionId && msg.toolUseId === 'mcp-ccweb-list');
assert(/"threadConfigMethod": "thread\/resume"/.test(codexAppDisabledSearchDynamicTool.result || ''), 'Codex App existing thread should refresh config through thread/resume');
assert(/"ccwebHasTopLevelType": false/.test(codexAppDisabledSearchDynamicTool.result || ''), 'Codex App thread/resume 的 ccweb 配置应省略顶层 type');
assert(/"projectHasTopLevelType": false/.test(codexAppDisabledSearchDynamicTool.result || ''), 'Codex App thread/resume 的项目配置应省略顶层 type');
assert(/"webSearchMode": "disabled"/.test(codexAppDisabledSearchDynamicTool.result || ''), 'Codex App thread/resume should pass web_search=disabled after Web Search is disabled');
assert(!/"webSearchToolConfig"/.test(codexAppDisabledSearchDynamicTool.result || ''), 'Codex App should not use tools.web_search as the Web Search mode switch');
await nextMessage(messages, ws, (msg) => msg.type === 'done' && msg.sessionId === codexAppSession.sessionId);
@@ -9141,6 +9147,8 @@ async function main() {
assert(/currentConversationId/.test(codexAppDynamicTool.result || ''), 'Codex App MCP tool should return ccweb conversation data');
assert(/"hasCcwebMcpConfig": true/.test(codexAppDynamicTool.result || ''), 'Codex App thread/start should pass ccweb MCP config');
assert(/"hasProjectMcpConfig": true/.test(codexAppDynamicTool.result || ''), 'Codex App thread/start should pass project MCP config from session cwd');
assert(/"ccwebHasTopLevelType": false/.test(codexAppDynamicTool.result || ''), 'Codex App ccweb MCP config should omit the server top-level type');
assert(/"projectHasTopLevelType": false/.test(codexAppDynamicTool.result || ''), 'Codex App project MCP config should omit the server top-level type');
assert(/"ccwebType": "streamable_http"/.test(codexAppDynamicTool.result || ''), 'Codex App ccweb MCP should default to shared streamable HTTP');
assert(/"ccwebUrl": "http:\/\/127\.0\.0\.1:\d+\/api\/internal\/mcp\/stream\?/.test(codexAppDynamicTool.result || ''), 'Codex App ccweb MCP should point to the shared cc-web HTTP endpoint');
assert(/"ccwebBearerTokenEnvVar": "CC_WEB_CODEX_APP_MCP_TOKEN"/.test(codexAppDynamicTool.result || ''), 'Codex App ccweb MCP should use bearer_token_env_var for the shared endpoint');