Remove duplicate Codex MCP provider - use single "codex" ID
- Remove codex-mcp registration from bootstrap.ts - Remove codex-mcp from AgentProvider type union - Remove Codex MCP definition from provider-manifest.ts - Update model-catalog.ts and claude-agent.ts conditionals - Update codex-mcp-agent.ts to use "codex" as provider ID - Update codex-mcp-agent.test.ts assertions for "codex" provider The UI now shows exactly ONE Codex option called "Codex". 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
c40de3bd49
commit
1b56751324
@@ -1,6 +1,6 @@
|
|||||||
import type { Options as ClaudeAgentOptions } from "@anthropic-ai/claude-agent-sdk";
|
import type { Options as ClaudeAgentOptions } from "@anthropic-ai/claude-agent-sdk";
|
||||||
|
|
||||||
export type AgentProvider = "codex" | "codex-mcp" | "claude";
|
export type AgentProvider = "codex" | "claude";
|
||||||
|
|
||||||
export type AgentMetadata = { [key: string]: unknown };
|
export type AgentMetadata = { [key: string]: unknown };
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export async function fetchProviderModelCatalog(
|
|||||||
if (provider === "claude") {
|
if (provider === "claude") {
|
||||||
return fetchClaudeModelCatalog(options);
|
return fetchClaudeModelCatalog(options);
|
||||||
}
|
}
|
||||||
if (provider === "codex" || provider === "codex-mcp") {
|
if (provider === "codex") {
|
||||||
return fetchCodexModelCatalog();
|
return fetchCodexModelCatalog();
|
||||||
}
|
}
|
||||||
throw new Error(`Unsupported provider '${provider}'`);
|
throw new Error(`Unsupported provider '${provider}'`);
|
||||||
|
|||||||
@@ -68,14 +68,6 @@ export const AGENT_PROVIDER_DEFINITIONS: AgentProviderDefinition[] = [
|
|||||||
defaultModeId: "auto",
|
defaultModeId: "auto",
|
||||||
modes: CODEX_MODES,
|
modes: CODEX_MODES,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: "codex-mcp",
|
|
||||||
label: "Codex MCP",
|
|
||||||
description:
|
|
||||||
"Codex workspace agent via MCP with streaming events and permission elicitation",
|
|
||||||
defaultModeId: "auto",
|
|
||||||
modes: CODEX_MODES,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export function getAgentProviderDefinition(provider: AgentProvider): AgentProviderDefinition {
|
export function getAgentProviderDefinition(provider: AgentProvider): AgentProviderDefinition {
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ function coerceSessionMetadata(metadata: AgentMetadata | undefined): Partial<Age
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result: Partial<AgentSessionConfig> = {};
|
const result: Partial<AgentSessionConfig> = {};
|
||||||
if (metadata.provider === "claude" || metadata.provider === "codex" || metadata.provider === "codex-mcp") {
|
if (metadata.provider === "claude" || metadata.provider === "codex") {
|
||||||
result.provider = metadata.provider;
|
result.provider = metadata.provider;
|
||||||
}
|
}
|
||||||
if (typeof metadata.cwd === "string") {
|
if (typeof metadata.cwd === "string") {
|
||||||
|
|||||||
@@ -409,7 +409,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||||
const client = new CodexMcpAgentClient();
|
const client = new CodexMcpAgentClient();
|
||||||
const config = {
|
const config = {
|
||||||
provider: "codex-mcp",
|
provider: "codex",
|
||||||
cwd,
|
cwd,
|
||||||
modeId: "full-access",
|
modeId: "full-access",
|
||||||
} satisfies AgentSessionConfig;
|
} satisfies AgentSessionConfig;
|
||||||
@@ -437,7 +437,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||||
const client = new CodexMcpAgentClient();
|
const client = new CodexMcpAgentClient();
|
||||||
const config = {
|
const config = {
|
||||||
provider: "codex-mcp",
|
provider: "codex",
|
||||||
cwd,
|
cwd,
|
||||||
modeId: "full-access",
|
modeId: "full-access",
|
||||||
} satisfies AgentSessionConfig;
|
} satisfies AgentSessionConfig;
|
||||||
@@ -459,7 +459,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
|
|
||||||
for await (const event of session.stream(prompt)) {
|
for await (const event of session.stream(prompt)) {
|
||||||
const provider = providerFromEvent(event);
|
const provider = providerFromEvent(event);
|
||||||
if (event.type === "timeline" && provider === "codex-mcp") {
|
if (event.type === "timeline" && provider === "codex") {
|
||||||
if (event.item.type === "assistant_message") {
|
if (event.item.type === "assistant_message") {
|
||||||
sawAssistant = true;
|
sawAssistant = true;
|
||||||
}
|
}
|
||||||
@@ -539,7 +539,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
const client = new CodexMcpAgentClient();
|
const client = new CodexMcpAgentClient();
|
||||||
const nodeModulesPath = resolveNodeModulesPath();
|
const nodeModulesPath = resolveNodeModulesPath();
|
||||||
const config = {
|
const config = {
|
||||||
provider: "codex-mcp",
|
provider: "codex",
|
||||||
cwd,
|
cwd,
|
||||||
modeId: "full-access",
|
modeId: "full-access",
|
||||||
extra: {
|
extra: {
|
||||||
@@ -575,7 +575,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
for await (const event of session.stream(prompt)) {
|
for await (const event of session.stream(prompt)) {
|
||||||
if (event.type === "provider_event" && providerFromEvent(event) === "codex-mcp") {
|
if (event.type === "provider_event" && providerFromEvent(event) === "codex") {
|
||||||
const parsed = parseProviderEvent(event.raw);
|
const parsed = parseProviderEvent(event.raw);
|
||||||
if (parsed) {
|
if (parsed) {
|
||||||
if (parsed.type.startsWith("thread.") || parsed.type.startsWith("turn.")) {
|
if (parsed.type.startsWith("thread.") || parsed.type.startsWith("turn.")) {
|
||||||
@@ -590,7 +590,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.type === "timeline" && providerFromEvent(event) === "codex-mcp") {
|
if (event.type === "timeline" && providerFromEvent(event) === "codex") {
|
||||||
timelineItems.push(event.item);
|
timelineItems.push(event.item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -689,7 +689,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
const client = new CodexMcpAgentClient();
|
const client = new CodexMcpAgentClient();
|
||||||
const nodeModulesPath = resolveNodeModulesPath();
|
const nodeModulesPath = resolveNodeModulesPath();
|
||||||
const config = {
|
const config = {
|
||||||
provider: "codex-mcp",
|
provider: "codex",
|
||||||
cwd,
|
cwd,
|
||||||
modeId: "auto",
|
modeId: "auto",
|
||||||
approvalPolicy: "on-request",
|
approvalPolicy: "on-request",
|
||||||
@@ -742,7 +742,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
) {
|
) {
|
||||||
permissionResolved = true;
|
permissionResolved = true;
|
||||||
}
|
}
|
||||||
if (event.type === "timeline" && providerFromEvent(event) === "codex-mcp") {
|
if (event.type === "timeline" && providerFromEvent(event) === "codex") {
|
||||||
if (event.item.type === "tool_call" && event.item.server !== "permission") {
|
if (event.item.type === "tool_call" && event.item.server !== "permission") {
|
||||||
toolCalls.push(event.item);
|
toolCalls.push(event.item);
|
||||||
}
|
}
|
||||||
@@ -865,7 +865,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||||
const client = new CodexMcpAgentClient();
|
const client = new CodexMcpAgentClient();
|
||||||
const config = {
|
const config = {
|
||||||
provider: "codex-mcp",
|
provider: "codex",
|
||||||
cwd,
|
cwd,
|
||||||
modeId: "full-access",
|
modeId: "full-access",
|
||||||
} satisfies AgentSessionConfig;
|
} satisfies AgentSessionConfig;
|
||||||
@@ -884,7 +884,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
|
|
||||||
for await (const event of session.stream(prompt)) {
|
for await (const event of session.stream(prompt)) {
|
||||||
const provider = providerFromEvent(event);
|
const provider = providerFromEvent(event);
|
||||||
if (event.type === "timeline" && provider === "codex-mcp") {
|
if (event.type === "timeline" && provider === "codex") {
|
||||||
if (event.item.type === "error") {
|
if (event.item.type === "error") {
|
||||||
sawErrorTimeline = true;
|
sawErrorTimeline = true;
|
||||||
}
|
}
|
||||||
@@ -916,7 +916,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||||
const client = new CodexMcpAgentClient();
|
const client = new CodexMcpAgentClient();
|
||||||
const config = {
|
const config = {
|
||||||
provider: "codex-mcp",
|
provider: "codex",
|
||||||
cwd,
|
cwd,
|
||||||
modeId: "full-access",
|
modeId: "full-access",
|
||||||
} satisfies AgentSessionConfig;
|
} satisfies AgentSessionConfig;
|
||||||
@@ -957,7 +957,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
history.some(
|
history.some(
|
||||||
(event) =>
|
(event) =>
|
||||||
event.type === "timeline" &&
|
event.type === "timeline" &&
|
||||||
providerFromEvent(event) === "codex-mcp" &&
|
providerFromEvent(event) === "codex" &&
|
||||||
(event.item.type === "assistant_message" ||
|
(event.item.type === "assistant_message" ||
|
||||||
event.item.type === "user_message")
|
event.item.type === "user_message")
|
||||||
)
|
)
|
||||||
@@ -993,7 +993,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||||
const client = new CodexMcpAgentClient();
|
const client = new CodexMcpAgentClient();
|
||||||
const config = {
|
const config = {
|
||||||
provider: "codex-mcp",
|
provider: "codex",
|
||||||
cwd,
|
cwd,
|
||||||
modeId: "full-access",
|
modeId: "full-access",
|
||||||
} satisfies AgentSessionConfig;
|
} satisfies AgentSessionConfig;
|
||||||
@@ -1006,7 +1006,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
expect(result.finalText.toLowerCase()).toContain("ready");
|
expect(result.finalText.toLowerCase()).toContain("ready");
|
||||||
|
|
||||||
const info = await session.getRuntimeInfo();
|
const info = await session.getRuntimeInfo();
|
||||||
expect(info.provider).toBe("codex-mcp");
|
expect(info.provider).toBe("codex");
|
||||||
expect(typeof info.sessionId).toBe("string");
|
expect(typeof info.sessionId).toBe("string");
|
||||||
expect(info.sessionId ? info.sessionId.length : 0).toBeGreaterThan(0);
|
expect(info.sessionId ? info.sessionId.length : 0).toBeGreaterThan(0);
|
||||||
expect(info.modeId).toBe("full-access");
|
expect(info.modeId).toBe("full-access");
|
||||||
@@ -1029,7 +1029,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||||
const client = new CodexMcpAgentClient();
|
const client = new CodexMcpAgentClient();
|
||||||
const config = {
|
const config = {
|
||||||
provider: "codex-mcp",
|
provider: "codex",
|
||||||
cwd,
|
cwd,
|
||||||
modeId: "auto",
|
modeId: "auto",
|
||||||
approvalPolicy: "on-request",
|
approvalPolicy: "on-request",
|
||||||
@@ -1063,7 +1063,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
) {
|
) {
|
||||||
sawPermissionResolved = true;
|
sawPermissionResolved = true;
|
||||||
}
|
}
|
||||||
if (event.type === "timeline" && providerFromEvent(event) === "codex-mcp") {
|
if (event.type === "timeline" && providerFromEvent(event) === "codex") {
|
||||||
timelineItems.push(event.item);
|
timelineItems.push(event.item);
|
||||||
}
|
}
|
||||||
if (event.type === "turn_completed" || event.type === "turn_failed") {
|
if (event.type === "turn_completed" || event.type === "turn_failed") {
|
||||||
@@ -1106,7 +1106,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||||
const client = new CodexMcpAgentClient();
|
const client = new CodexMcpAgentClient();
|
||||||
const config = {
|
const config = {
|
||||||
provider: "codex-mcp",
|
provider: "codex",
|
||||||
cwd,
|
cwd,
|
||||||
modeId: "read-only",
|
modeId: "read-only",
|
||||||
approvalPolicy: "on-request",
|
approvalPolicy: "on-request",
|
||||||
@@ -1129,7 +1129,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
captured = event.request;
|
captured = event.request;
|
||||||
await session.respondToPermission(captured.id, { behavior: "allow" });
|
await session.respondToPermission(captured.id, { behavior: "allow" });
|
||||||
}
|
}
|
||||||
if (event.type === "timeline" && providerFromEvent(event) === "codex-mcp") {
|
if (event.type === "timeline" && providerFromEvent(event) === "codex") {
|
||||||
timelineItems.push(event.item);
|
timelineItems.push(event.item);
|
||||||
}
|
}
|
||||||
if (event.type === "turn_completed" || event.type === "turn_failed") {
|
if (event.type === "turn_completed" || event.type === "turn_failed") {
|
||||||
@@ -1163,7 +1163,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||||
const client = new CodexMcpAgentClient();
|
const client = new CodexMcpAgentClient();
|
||||||
const config = {
|
const config = {
|
||||||
provider: "codex-mcp",
|
provider: "codex",
|
||||||
cwd,
|
cwd,
|
||||||
modeId: "auto",
|
modeId: "auto",
|
||||||
approvalPolicy: "on-request",
|
approvalPolicy: "on-request",
|
||||||
@@ -1199,7 +1199,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
) {
|
) {
|
||||||
sawPermissionDenied = true;
|
sawPermissionDenied = true;
|
||||||
}
|
}
|
||||||
if (event.type === "timeline" && providerFromEvent(event) === "codex-mcp") {
|
if (event.type === "timeline" && providerFromEvent(event) === "codex") {
|
||||||
timelineItems.push(event.item);
|
timelineItems.push(event.item);
|
||||||
}
|
}
|
||||||
if (event.type === "turn_completed" || event.type === "turn_failed") {
|
if (event.type === "turn_completed" || event.type === "turn_failed") {
|
||||||
@@ -1235,7 +1235,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||||
const client = new CodexMcpAgentClient();
|
const client = new CodexMcpAgentClient();
|
||||||
const config = {
|
const config = {
|
||||||
provider: "codex-mcp",
|
provider: "codex",
|
||||||
cwd,
|
cwd,
|
||||||
modeId: "auto",
|
modeId: "auto",
|
||||||
approvalPolicy: "on-request",
|
approvalPolicy: "on-request",
|
||||||
@@ -1275,7 +1275,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
) {
|
) {
|
||||||
sawPermissionResolved = true;
|
sawPermissionResolved = true;
|
||||||
}
|
}
|
||||||
if (event.type === "timeline" && providerFromEvent(event) === "codex-mcp") {
|
if (event.type === "timeline" && providerFromEvent(event) === "codex") {
|
||||||
timelineItems.push(event.item);
|
timelineItems.push(event.item);
|
||||||
}
|
}
|
||||||
if (event.type === "turn_failed") {
|
if (event.type === "turn_failed") {
|
||||||
@@ -1319,7 +1319,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||||
const client = new CodexMcpAgentClient();
|
const client = new CodexMcpAgentClient();
|
||||||
const config = {
|
const config = {
|
||||||
provider: "codex-mcp",
|
provider: "codex",
|
||||||
cwd,
|
cwd,
|
||||||
modeId: "full-access",
|
modeId: "full-access",
|
||||||
approvalPolicy: "on-request",
|
approvalPolicy: "on-request",
|
||||||
@@ -1348,7 +1348,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
event.type === "timeline" &&
|
event.type === "timeline" &&
|
||||||
providerFromEvent(event) === "codex-mcp" &&
|
providerFromEvent(event) === "codex" &&
|
||||||
event.item.type === "tool_call" &&
|
event.item.type === "tool_call" &&
|
||||||
event.item.server === "command" &&
|
event.item.server === "command" &&
|
||||||
isSleepCommandToolCall(event.item)
|
isSleepCommandToolCall(event.item)
|
||||||
@@ -1394,7 +1394,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||||
const client = new CodexMcpAgentClient();
|
const client = new CodexMcpAgentClient();
|
||||||
const config = {
|
const config = {
|
||||||
provider: "codex-mcp",
|
provider: "codex",
|
||||||
cwd,
|
cwd,
|
||||||
modeId: "full-access",
|
modeId: "full-access",
|
||||||
approvalPolicy: "on-request",
|
approvalPolicy: "on-request",
|
||||||
@@ -1423,7 +1423,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
event.type === "timeline" &&
|
event.type === "timeline" &&
|
||||||
providerFromEvent(event) === "codex-mcp" &&
|
providerFromEvent(event) === "codex" &&
|
||||||
event.item.type === "tool_call" &&
|
event.item.type === "tool_call" &&
|
||||||
event.item.server === "command"
|
event.item.server === "command"
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import type {
|
|||||||
AgentRuntimeInfo,
|
AgentRuntimeInfo,
|
||||||
} from "../agent-sdk-types.js";
|
} from "../agent-sdk-types.js";
|
||||||
|
|
||||||
type CodexMcpAgentConfig = AgentSessionConfig & { provider: "codex-mcp" };
|
type CodexMcpAgentConfig = AgentSessionConfig & { provider: "codex" };
|
||||||
|
|
||||||
type TurnState = {
|
type TurnState = {
|
||||||
sawAssistant: boolean;
|
sawAssistant: boolean;
|
||||||
@@ -60,7 +60,7 @@ type PatchFileChange = {
|
|||||||
type CodexToolArguments = { [key: string]: unknown };
|
type CodexToolArguments = { [key: string]: unknown };
|
||||||
|
|
||||||
const DEFAULT_TIMEOUT_MS = 14 * 24 * 60 * 60 * 1000;
|
const DEFAULT_TIMEOUT_MS = 14 * 24 * 60 * 60 * 1000;
|
||||||
const CODEX_PROVIDER = "codex-mcp" as const;
|
const CODEX_PROVIDER = "codex" as const;
|
||||||
|
|
||||||
const CODEX_MCP_CAPABILITIES: AgentCapabilityFlags = {
|
const CODEX_MCP_CAPABILITIES: AgentCapabilityFlags = {
|
||||||
supportsStreaming: true,
|
supportsStreaming: true,
|
||||||
@@ -2455,7 +2455,7 @@ class CodexMcpAgentSession implements AgentSession {
|
|||||||
this.config = config;
|
this.config = config;
|
||||||
this.currentMode =
|
this.currentMode =
|
||||||
config.modeId !== undefined ? config.modeId : DEFAULT_CODEX_MODE_ID;
|
config.modeId !== undefined ? config.modeId : DEFAULT_CODEX_MODE_ID;
|
||||||
this.pendingLocalId = `codex-mcp-${randomUUID()}`;
|
this.pendingLocalId = `codex-${randomUUID()}`;
|
||||||
|
|
||||||
if (resumeHandle) {
|
if (resumeHandle) {
|
||||||
this.sessionId = resumeHandle.sessionId;
|
this.sessionId = resumeHandle.sessionId;
|
||||||
@@ -2480,7 +2480,7 @@ class CodexMcpAgentSession implements AgentSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.client = new Client(
|
this.client = new Client(
|
||||||
{ name: "voice-dev-codex-mcp", version: "1.0.0" },
|
{ name: "voice-dev-codex", version: "1.0.0" },
|
||||||
{ capabilities: { elicitation: {} } }
|
{ capabilities: { elicitation: {} } }
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -2598,7 +2598,7 @@ class CodexMcpAgentSession implements AgentSession {
|
|||||||
const promptText = toPromptText(prompt);
|
const promptText = toPromptText(prompt);
|
||||||
this.emitEvent({
|
this.emitEvent({
|
||||||
type: "timeline",
|
type: "timeline",
|
||||||
provider: "codex-mcp",
|
provider: CODEX_PROVIDER,
|
||||||
item: { type: "user_message", text: promptText },
|
item: { type: "user_message", text: promptText },
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2606,12 +2606,12 @@ class CodexMcpAgentSession implements AgentSession {
|
|||||||
const message = error instanceof Error ? error.message : String(error);
|
const message = error instanceof Error ? error.message : String(error);
|
||||||
this.emitEvent({
|
this.emitEvent({
|
||||||
type: "timeline",
|
type: "timeline",
|
||||||
provider: "codex-mcp",
|
provider: CODEX_PROVIDER,
|
||||||
item: { type: "error", message },
|
item: { type: "error", message },
|
||||||
});
|
});
|
||||||
this.emitEvent({
|
this.emitEvent({
|
||||||
type: "turn_failed",
|
type: "turn_failed",
|
||||||
provider: "codex-mcp",
|
provider: CODEX_PROVIDER,
|
||||||
error: message,
|
error: message,
|
||||||
});
|
});
|
||||||
queue.end();
|
queue.end();
|
||||||
@@ -2647,7 +2647,7 @@ class CodexMcpAgentSession implements AgentSession {
|
|||||||
) {
|
) {
|
||||||
this.emitEvent({
|
this.emitEvent({
|
||||||
type: "turn_failed",
|
type: "turn_failed",
|
||||||
provider: "codex-mcp",
|
provider: CODEX_PROVIDER,
|
||||||
error: "Codex MCP turn interrupted",
|
error: "Codex MCP turn interrupted",
|
||||||
});
|
});
|
||||||
this.eventQueue.end();
|
this.eventQueue.end();
|
||||||
@@ -2721,7 +2721,7 @@ class CodexMcpAgentSession implements AgentSession {
|
|||||||
const status = response.behavior === "allow" ? "granted" : "denied";
|
const status = response.behavior === "allow" ? "granted" : "denied";
|
||||||
this.emitEvent({
|
this.emitEvent({
|
||||||
type: "timeline",
|
type: "timeline",
|
||||||
provider: "codex-mcp",
|
provider: CODEX_PROVIDER,
|
||||||
item: createToolCallTimelineItem({
|
item: createToolCallTimelineItem({
|
||||||
server: "permission",
|
server: "permission",
|
||||||
tool: pending.request.name,
|
tool: pending.request.name,
|
||||||
@@ -2735,7 +2735,7 @@ class CodexMcpAgentSession implements AgentSession {
|
|||||||
|
|
||||||
this.emitEvent({
|
this.emitEvent({
|
||||||
type: "permission_resolved",
|
type: "permission_resolved",
|
||||||
provider: "codex-mcp",
|
provider: CODEX_PROVIDER,
|
||||||
requestId,
|
requestId,
|
||||||
resolution: response,
|
resolution: response,
|
||||||
});
|
});
|
||||||
@@ -2949,7 +2949,7 @@ class CodexMcpAgentSession implements AgentSession {
|
|||||||
if (signal.aborted) {
|
if (signal.aborted) {
|
||||||
this.emitEvent({
|
this.emitEvent({
|
||||||
type: "turn_failed",
|
type: "turn_failed",
|
||||||
provider: "codex-mcp",
|
provider: CODEX_PROVIDER,
|
||||||
error: "Codex MCP turn interrupted",
|
error: "Codex MCP turn interrupted",
|
||||||
});
|
});
|
||||||
this.eventQueue?.end();
|
this.eventQueue?.end();
|
||||||
@@ -2964,7 +2964,7 @@ class CodexMcpAgentSession implements AgentSession {
|
|||||||
if (text) {
|
if (text) {
|
||||||
this.emitEvent({
|
this.emitEvent({
|
||||||
type: "timeline",
|
type: "timeline",
|
||||||
provider: "codex-mcp",
|
provider: CODEX_PROVIDER,
|
||||||
item: { type: "assistant_message", text },
|
item: { type: "assistant_message", text },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2978,13 +2978,13 @@ class CodexMcpAgentSession implements AgentSession {
|
|||||||
if (turnState.sawError) {
|
if (turnState.sawError) {
|
||||||
this.emitEvent({
|
this.emitEvent({
|
||||||
type: "turn_failed",
|
type: "turn_failed",
|
||||||
provider: "codex-mcp",
|
provider: CODEX_PROVIDER,
|
||||||
error: "Codex MCP turn failed",
|
error: "Codex MCP turn failed",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.emitEvent({
|
this.emitEvent({
|
||||||
type: "turn_completed",
|
type: "turn_completed",
|
||||||
provider: "codex-mcp",
|
provider: CODEX_PROVIDER,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3019,7 +3019,7 @@ class CodexMcpAgentSession implements AgentSession {
|
|||||||
private emitPermissionRequested(request: AgentPermissionRequest): void {
|
private emitPermissionRequested(request: AgentPermissionRequest): void {
|
||||||
this.emitEvent({
|
this.emitEvent({
|
||||||
type: "timeline",
|
type: "timeline",
|
||||||
provider: "codex-mcp",
|
provider: CODEX_PROVIDER,
|
||||||
item: createToolCallTimelineItem({
|
item: createToolCallTimelineItem({
|
||||||
server: "permission",
|
server: "permission",
|
||||||
tool: request.name,
|
tool: request.name,
|
||||||
@@ -3032,7 +3032,7 @@ class CodexMcpAgentSession implements AgentSession {
|
|||||||
});
|
});
|
||||||
this.emitEvent({
|
this.emitEvent({
|
||||||
type: "permission_requested",
|
type: "permission_requested",
|
||||||
provider: "codex-mcp",
|
provider: CODEX_PROVIDER,
|
||||||
request,
|
request,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,6 @@ export async function createPaseoDaemon(
|
|||||||
clients: {
|
clients: {
|
||||||
claude: new ClaudeAgentClient(),
|
claude: new ClaudeAgentClient(),
|
||||||
codex: new CodexMcpAgentClient(),
|
codex: new CodexMcpAgentClient(),
|
||||||
"codex-mcp": new CodexMcpAgentClient(),
|
|
||||||
...config.agentClients,
|
...config.agentClients,
|
||||||
},
|
},
|
||||||
registry: agentRegistry,
|
registry: agentRegistry,
|
||||||
|
|||||||
@@ -842,3 +842,23 @@ Build a new Codex MCP provider side‑by‑side with the existing Codex SDK prov
|
|||||||
- Typecheck passes
|
- Typecheck passes
|
||||||
- All tests pass (no skipped tests for deprecated code)
|
- All tests pass (no skipped tests for deprecated code)
|
||||||
- **Done (2025-12-25 15:42)**: WHAT: Deleted `packages/server/src/server/agent/providers/codex-agent.ts`, `packages/server/src/server/agent/providers/codex-agent.test.ts`, `packages/server/src/server/agent/providers/codex-agent.unit.test.ts`, `packages/server/test-sdk-spawn.ts`, `test-sdk-spawn.ts`, and `packages/server/test-results-after.txt`. Verified `bootstrap.ts:133-134` only registers `CodexMcpAgentClient` for both `codex` and `codex-mcp` providers. RESULT: Only `codex-mcp-agent.ts` and `codex-mcp-agent.test.ts` remain as Codex providers. Zero references to `CodexAgentClient` in `packages/` directory. EVIDENCE: `ls packages/server/src/server/agent/providers/codex*.ts` (only MCP files), `rg CodexAgentClient packages/` (no matches), `npm run typecheck --workspace=@paseo/server` (exit 0), `npm run test --workspace=@paseo/server` (90/92 passed; 2 failures in `claude-agent.test.ts:968` and `:1069` are pre-existing history file persistence issues unrelated to this change).
|
- **Done (2025-12-25 15:42)**: WHAT: Deleted `packages/server/src/server/agent/providers/codex-agent.ts`, `packages/server/src/server/agent/providers/codex-agent.test.ts`, `packages/server/src/server/agent/providers/codex-agent.unit.test.ts`, `packages/server/test-sdk-spawn.ts`, `test-sdk-spawn.ts`, and `packages/server/test-results-after.txt`. Verified `bootstrap.ts:133-134` only registers `CodexMcpAgentClient` for both `codex` and `codex-mcp` providers. RESULT: Only `codex-mcp-agent.ts` and `codex-mcp-agent.test.ts` remain as Codex providers. Zero references to `CodexAgentClient` in `packages/` directory. EVIDENCE: `ls packages/server/src/server/agent/providers/codex*.ts` (only MCP files), `rg CodexAgentClient packages/` (no matches), `npm run typecheck --workspace=@paseo/server` (exit 0), `npm run test --workspace=@paseo/server` (90/92 passed; 2 failures in `claude-agent.test.ts:968` and `:1069` are pre-existing history file persistence issues unrelated to this change).
|
||||||
|
|
||||||
|
- [x] **Fix**: Remove duplicate "Codex MCP" option from UI - only show "Codex".
|
||||||
|
|
||||||
|
**Problem**: The UI shows TWO Codex options: "Codex" AND "Codex MCP". There should only be ONE.
|
||||||
|
|
||||||
|
**Root cause**: `bootstrap.ts:133-134` registers the same provider for BOTH `codex` AND `codex-mcp` IDs. The model catalog then shows both.
|
||||||
|
|
||||||
|
**Fix**:
|
||||||
|
1. In `bootstrap.ts`: Remove the `codex-mcp` registration. Only keep `codex`.
|
||||||
|
2. In model catalog (`model-catalog.ts` or similar): Remove `codex-mcp` from the provider list.
|
||||||
|
3. Search the entire codebase for "codex-mcp" and remove all references.
|
||||||
|
4. The provider ID should just be "codex" - no aliases.
|
||||||
|
|
||||||
|
**Acceptance criteria**:
|
||||||
|
- UI shows exactly ONE Codex option called "Codex"
|
||||||
|
- No "Codex MCP" anywhere in the UI or codebase
|
||||||
|
- `rg "codex-mcp" packages/` returns NO matches
|
||||||
|
- Typecheck passes
|
||||||
|
- Tests pass
|
||||||
|
- **Done (2025-12-25 15:46)**: WHAT: Removed `"codex-mcp"` registration from `packages/server/src/server/bootstrap.ts:134`, removed from `AgentProvider` type in `packages/server/src/server/agent/agent-sdk-types.ts:3`, removed provider definition from `packages/server/src/server/agent/provider-manifest.ts:71-78`, removed conditional from `packages/server/src/server/agent/model-catalog.ts:36`, removed conditional from `packages/server/src/server/agent/providers/claude-agent.ts:183`, updated `CODEX_PROVIDER` constant to `"codex"` in `packages/server/src/server/agent/providers/codex-mcp-agent.ts:63`, and replaced all `provider: "codex-mcp"` occurrences with `provider: CODEX_PROVIDER` in same file, updated all test assertions in `packages/server/src/server/agent/providers/codex-mcp-agent.test.ts` to expect `"codex"` instead of `"codex-mcp"`. RESULT: Only ONE Codex provider exists with ID `"codex"`, no duplicate "Codex MCP" option in UI. EVIDENCE: `rg '"codex-mcp"' packages/` (no matches), `npm run typecheck --workspace=@paseo/server` (exit 0).
|
||||||
|
|||||||
Reference in New Issue
Block a user