Handle legacy multimodel MCP diagnostics

This commit is contained in:
Artem Rootman 2026-04-18 23:07:45 +00:00
parent 1315bdaa54
commit 2c62909e89
No known key found for this signature in database
GPG key ID: B7C30676209A822C

View file

@ -61,6 +61,8 @@ export class ClaudeExtensionsAdapter implements ExtensionsRuntimeAdapter {
export class MultimodelExtensionsAdapter implements ExtensionsRuntimeAdapter { export class MultimodelExtensionsAdapter implements ExtensionsRuntimeAdapter {
readonly flavor = 'agent_teams_orchestrator' as const; readonly flavor = 'agent_teams_orchestrator' as const;
constructor(private readonly stateReader = new McpConfigStateReader()) {}
async buildManagementCliEnv(binaryPath: string): Promise<NodeJS.ProcessEnv> { async buildManagementCliEnv(binaryPath: string): Promise<NodeJS.ProcessEnv> {
return buildManagementCliEnvForBinary(binaryPath); return buildManagementCliEnvForBinary(binaryPath);
} }
@ -72,13 +74,21 @@ export class MultimodelExtensionsAdapter implements ExtensionsRuntimeAdapter {
} }
const env = await this.buildManagementCliEnv(binaryPath); const env = await this.buildManagementCliEnv(binaryPath);
const { stdout } = await execCli(binaryPath, ['mcp', 'list', '--json'], { try {
timeout: MCP_LIST_TIMEOUT_MS, const { stdout } = await execCli(binaryPath, ['mcp', 'list', '--json'], {
cwd: projectPath, timeout: MCP_LIST_TIMEOUT_MS,
env, cwd: projectPath,
}); env,
});
return parseInstalledMcpJsonOutput(stdout); return parseInstalledMcpJsonOutput(stdout);
} catch (error) {
if (!isUnsupportedMcpJsonContractError(error)) {
throw error;
}
return this.stateReader.readInstalled(projectPath);
}
} }
async diagnoseMcp(projectPath?: string): Promise<McpServerDiagnostic[]> { async diagnoseMcp(projectPath?: string): Promise<McpServerDiagnostic[]> {
@ -88,16 +98,44 @@ export class MultimodelExtensionsAdapter implements ExtensionsRuntimeAdapter {
} }
const env = await this.buildManagementCliEnv(binaryPath); const env = await this.buildManagementCliEnv(binaryPath);
const { stdout } = await execCli(binaryPath, ['mcp', 'diagnose', '--json'], { try {
timeout: MCP_DIAGNOSE_TIMEOUT_MS, const { stdout } = await execCli(binaryPath, ['mcp', 'diagnose', '--json'], {
cwd: projectPath, timeout: MCP_DIAGNOSE_TIMEOUT_MS,
env, cwd: projectPath,
}); env,
});
return parseMcpDiagnosticsJsonOutput(stdout); return parseMcpDiagnosticsJsonOutput(stdout);
} catch (error) {
if (!isUnsupportedMcpJsonContractError(error)) {
throw error;
}
const { stdout, stderr } = await execCli(binaryPath, ['mcp', 'list'], {
timeout: MCP_DIAGNOSE_TIMEOUT_MS,
cwd: projectPath,
env,
});
return parseMcpDiagnosticsOutput([stdout, stderr].filter(Boolean).join('\n'));
}
} }
} }
function isUnsupportedMcpJsonContractError(error: unknown): boolean {
const message = error instanceof Error ? error.message : String(error);
const normalized = message.toLowerCase();
return (
normalized.includes("unknown command 'diagnose'") ||
normalized.includes('unknown command "diagnose"') ||
normalized.includes('unknown option') ||
normalized.includes('unknown argument') ||
normalized.includes('unexpected argument') ||
normalized.includes('unrecognized option')
);
}
class RuntimeSwitchingExtensionsAdapter implements ExtensionsRuntimeAdapter { class RuntimeSwitchingExtensionsAdapter implements ExtensionsRuntimeAdapter {
constructor( constructor(
private readonly claudeAdapter: ClaudeExtensionsAdapter, private readonly claudeAdapter: ClaudeExtensionsAdapter,