fix(opencode): provide mcp fallback for provider env
This commit is contained in:
parent
eb1b333879
commit
f96d62dc20
3 changed files with 97 additions and 0 deletions
46
src/main/services/runtime/agentTeamsMcpLaunchEnv.ts
Normal file
46
src/main/services/runtime/agentTeamsMcpLaunchEnv.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import { resolveAgentTeamsMcpLaunchSpec } from '@main/services/team/TeamMcpConfigBuilder';
|
||||
import { createLogger } from '@shared/utils/logger';
|
||||
|
||||
import type { McpLaunchSpec } from '@main/services/team/TeamMcpConfigBuilder';
|
||||
|
||||
const logger = createLogger('Runtime:AgentTeamsMcpLaunchEnv');
|
||||
|
||||
const MCP_COMMAND_ENV = 'CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND';
|
||||
const MCP_ENTRY_ENV = 'CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY';
|
||||
const MCP_ARGS_JSON_ENV = 'CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON';
|
||||
|
||||
export type AgentTeamsMcpLaunchEnv = Record<string, string | undefined>;
|
||||
|
||||
export function hasAgentTeamsMcpLocalLaunchEnv(env: AgentTeamsMcpLaunchEnv): boolean {
|
||||
return Boolean(
|
||||
env[MCP_COMMAND_ENV]?.trim() && env[MCP_ENTRY_ENV]?.trim() && env[MCP_ARGS_JSON_ENV]?.trim()
|
||||
);
|
||||
}
|
||||
|
||||
export async function ensureAgentTeamsMcpLocalLaunchEnv(
|
||||
env: AgentTeamsMcpLaunchEnv,
|
||||
resolveLaunchSpec: () => Promise<McpLaunchSpec> = resolveAgentTeamsMcpLaunchSpec
|
||||
): Promise<void> {
|
||||
if (hasAgentTeamsMcpLocalLaunchEnv(env)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const launchSpec = await resolveLaunchSpec();
|
||||
const entry = launchSpec.args[0]?.trim();
|
||||
const command = launchSpec.command.trim();
|
||||
if (!command || !entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
env[MCP_COMMAND_ENV] = command;
|
||||
env[MCP_ENTRY_ENV] = entry;
|
||||
env[MCP_ARGS_JSON_ENV] = JSON.stringify(launchSpec.args);
|
||||
} catch (error) {
|
||||
logger.warn(
|
||||
`Unable to resolve Agent Teams MCP local launch env: ${
|
||||
error instanceof Error ? error.message : String(error)
|
||||
}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ import { getCachedShellEnv } from '@main/utils/shellEnv';
|
|||
|
||||
import { resolveVerifiedAppManagedOpenCodeRuntimeBinaryPath } from '../infrastructure/OpenCodeRuntimeInstallerService';
|
||||
|
||||
import { ensureAgentTeamsMcpLocalLaunchEnv } from './agentTeamsMcpLaunchEnv';
|
||||
import { buildRuntimeBaseEnv } from './buildRuntimeBaseEnv';
|
||||
import { providerConnectionService } from './ProviderConnectionService';
|
||||
|
||||
|
|
@ -58,6 +59,9 @@ export async function buildProviderAwareCliEnv(
|
|||
) {
|
||||
env.CODEX_CLI_PATH = appManagedCodexBinary;
|
||||
}
|
||||
if (!resolvedProviderId || resolvedProviderId === 'opencode') {
|
||||
await ensureAgentTeamsMcpLocalLaunchEnv(env);
|
||||
}
|
||||
|
||||
if (options.providerId) {
|
||||
if (!resolvedProviderId) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const getConfiguredConnectionIssuesMock = vi.fn();
|
|||
const getConfiguredConnectionLaunchArgsMock = vi.fn();
|
||||
const resolveVerifiedAppManagedOpenCodeRuntimeBinaryPathMock = vi.fn();
|
||||
const resolveVerifiedAppManagedCodexRuntimeBinaryPathMock = vi.fn();
|
||||
const resolveAgentTeamsMcpLaunchSpecMock = vi.fn();
|
||||
|
||||
vi.mock('@main/utils/cliEnv', () => ({
|
||||
buildEnrichedEnv: (...args: Parameters<typeof buildEnrichedEnvMock>) =>
|
||||
|
|
@ -68,6 +69,10 @@ vi.mock('@features/codex-runtime-installer/main', () => ({
|
|||
resolveVerifiedAppManagedCodexRuntimeBinaryPathMock(),
|
||||
}));
|
||||
|
||||
vi.mock('@main/services/team/TeamMcpConfigBuilder', () => ({
|
||||
resolveAgentTeamsMcpLaunchSpec: () => resolveAgentTeamsMcpLaunchSpecMock(),
|
||||
}));
|
||||
|
||||
describe('buildProviderAwareCliEnv', () => {
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
|
|
@ -95,6 +100,10 @@ describe('buildProviderAwareCliEnv', () => {
|
|||
getConfiguredConnectionIssuesMock.mockResolvedValue({});
|
||||
resolveVerifiedAppManagedOpenCodeRuntimeBinaryPathMock.mockResolvedValue(null);
|
||||
resolveVerifiedAppManagedCodexRuntimeBinaryPathMock.mockResolvedValue(null);
|
||||
resolveAgentTeamsMcpLaunchSpecMock.mockResolvedValue({
|
||||
command: 'node',
|
||||
args: ['/app/mcp-server/index.js'],
|
||||
});
|
||||
});
|
||||
|
||||
it('builds provider-pinned CLI env and returns provider-specific issues', async () => {
|
||||
|
|
@ -168,6 +177,44 @@ describe('buildProviderAwareCliEnv', () => {
|
|||
expect(result.connectionIssues).toEqual({});
|
||||
expect(result.providerArgs).toEqual([]);
|
||||
expect(result.env.OPENCODE_DISABLE_AUTOUPDATE).toBe('1');
|
||||
expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND).toBe('node');
|
||||
expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY).toBe('/app/mcp-server/index.js');
|
||||
expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON).toBe(
|
||||
'["/app/mcp-server/index.js"]'
|
||||
);
|
||||
});
|
||||
|
||||
it('adds local Agent Teams MCP launch env for OpenCode provider runtime commands', async () => {
|
||||
const { buildProviderAwareCliEnv } =
|
||||
await import('../../../../src/main/services/runtime/providerAwareCliEnv');
|
||||
const result = await buildProviderAwareCliEnv({
|
||||
providerId: 'opencode',
|
||||
});
|
||||
|
||||
expect(resolveAgentTeamsMcpLaunchSpecMock).toHaveBeenCalledTimes(1);
|
||||
expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND).toBe('node');
|
||||
expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY).toBe('/app/mcp-server/index.js');
|
||||
expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON).toBe(
|
||||
'["/app/mcp-server/index.js"]'
|
||||
);
|
||||
});
|
||||
|
||||
it('preserves explicit local Agent Teams MCP launch env for OpenCode provider commands', async () => {
|
||||
const { buildProviderAwareCliEnv } =
|
||||
await import('../../../../src/main/services/runtime/providerAwareCliEnv');
|
||||
const result = await buildProviderAwareCliEnv({
|
||||
providerId: 'opencode',
|
||||
env: {
|
||||
CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND: 'custom-node',
|
||||
CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY: '/custom/mcp.js',
|
||||
CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON: '["/custom/mcp.js"]',
|
||||
},
|
||||
});
|
||||
|
||||
expect(resolveAgentTeamsMcpLaunchSpecMock).not.toHaveBeenCalled();
|
||||
expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND).toBe('custom-node');
|
||||
expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY).toBe('/custom/mcp.js');
|
||||
expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON).toBe('["/custom/mcp.js"]');
|
||||
});
|
||||
|
||||
it('allows OpenCode auto-update only behind an explicit app override', async () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue