mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
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:
@@ -1,6 +1,6 @@
|
||||
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 };
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ export async function fetchProviderModelCatalog(
|
||||
if (provider === "claude") {
|
||||
return fetchClaudeModelCatalog(options);
|
||||
}
|
||||
if (provider === "codex" || provider === "codex-mcp") {
|
||||
if (provider === "codex") {
|
||||
return fetchCodexModelCatalog();
|
||||
}
|
||||
throw new Error(`Unsupported provider '${provider}'`);
|
||||
|
||||
@@ -68,14 +68,6 @@ export const AGENT_PROVIDER_DEFINITIONS: AgentProviderDefinition[] = [
|
||||
defaultModeId: "auto",
|
||||
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 {
|
||||
|
||||
@@ -180,7 +180,7 @@ function coerceSessionMetadata(metadata: AgentMetadata | undefined): Partial<Age
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if (typeof metadata.cwd === "string") {
|
||||
|
||||
@@ -409,7 +409,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||
const client = new CodexMcpAgentClient();
|
||||
const config = {
|
||||
provider: "codex-mcp",
|
||||
provider: "codex",
|
||||
cwd,
|
||||
modeId: "full-access",
|
||||
} satisfies AgentSessionConfig;
|
||||
@@ -437,7 +437,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||
const client = new CodexMcpAgentClient();
|
||||
const config = {
|
||||
provider: "codex-mcp",
|
||||
provider: "codex",
|
||||
cwd,
|
||||
modeId: "full-access",
|
||||
} satisfies AgentSessionConfig;
|
||||
@@ -459,7 +459,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
|
||||
for await (const event of session.stream(prompt)) {
|
||||
const provider = providerFromEvent(event);
|
||||
if (event.type === "timeline" && provider === "codex-mcp") {
|
||||
if (event.type === "timeline" && provider === "codex") {
|
||||
if (event.item.type === "assistant_message") {
|
||||
sawAssistant = true;
|
||||
}
|
||||
@@ -539,7 +539,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
const client = new CodexMcpAgentClient();
|
||||
const nodeModulesPath = resolveNodeModulesPath();
|
||||
const config = {
|
||||
provider: "codex-mcp",
|
||||
provider: "codex",
|
||||
cwd,
|
||||
modeId: "full-access",
|
||||
extra: {
|
||||
@@ -575,7 +575,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
].join("\n");
|
||||
|
||||
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);
|
||||
if (parsed) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -689,7 +689,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
const client = new CodexMcpAgentClient();
|
||||
const nodeModulesPath = resolveNodeModulesPath();
|
||||
const config = {
|
||||
provider: "codex-mcp",
|
||||
provider: "codex",
|
||||
cwd,
|
||||
modeId: "auto",
|
||||
approvalPolicy: "on-request",
|
||||
@@ -742,7 +742,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
) {
|
||||
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") {
|
||||
toolCalls.push(event.item);
|
||||
}
|
||||
@@ -865,7 +865,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||
const client = new CodexMcpAgentClient();
|
||||
const config = {
|
||||
provider: "codex-mcp",
|
||||
provider: "codex",
|
||||
cwd,
|
||||
modeId: "full-access",
|
||||
} satisfies AgentSessionConfig;
|
||||
@@ -884,7 +884,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
|
||||
for await (const event of session.stream(prompt)) {
|
||||
const provider = providerFromEvent(event);
|
||||
if (event.type === "timeline" && provider === "codex-mcp") {
|
||||
if (event.type === "timeline" && provider === "codex") {
|
||||
if (event.item.type === "error") {
|
||||
sawErrorTimeline = true;
|
||||
}
|
||||
@@ -916,7 +916,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||
const client = new CodexMcpAgentClient();
|
||||
const config = {
|
||||
provider: "codex-mcp",
|
||||
provider: "codex",
|
||||
cwd,
|
||||
modeId: "full-access",
|
||||
} satisfies AgentSessionConfig;
|
||||
@@ -957,7 +957,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
history.some(
|
||||
(event) =>
|
||||
event.type === "timeline" &&
|
||||
providerFromEvent(event) === "codex-mcp" &&
|
||||
providerFromEvent(event) === "codex" &&
|
||||
(event.item.type === "assistant_message" ||
|
||||
event.item.type === "user_message")
|
||||
)
|
||||
@@ -993,7 +993,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||
const client = new CodexMcpAgentClient();
|
||||
const config = {
|
||||
provider: "codex-mcp",
|
||||
provider: "codex",
|
||||
cwd,
|
||||
modeId: "full-access",
|
||||
} satisfies AgentSessionConfig;
|
||||
@@ -1006,7 +1006,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
expect(result.finalText.toLowerCase()).toContain("ready");
|
||||
|
||||
const info = await session.getRuntimeInfo();
|
||||
expect(info.provider).toBe("codex-mcp");
|
||||
expect(info.provider).toBe("codex");
|
||||
expect(typeof info.sessionId).toBe("string");
|
||||
expect(info.sessionId ? info.sessionId.length : 0).toBeGreaterThan(0);
|
||||
expect(info.modeId).toBe("full-access");
|
||||
@@ -1029,7 +1029,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||
const client = new CodexMcpAgentClient();
|
||||
const config = {
|
||||
provider: "codex-mcp",
|
||||
provider: "codex",
|
||||
cwd,
|
||||
modeId: "auto",
|
||||
approvalPolicy: "on-request",
|
||||
@@ -1063,7 +1063,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
) {
|
||||
sawPermissionResolved = true;
|
||||
}
|
||||
if (event.type === "timeline" && providerFromEvent(event) === "codex-mcp") {
|
||||
if (event.type === "timeline" && providerFromEvent(event) === "codex") {
|
||||
timelineItems.push(event.item);
|
||||
}
|
||||
if (event.type === "turn_completed" || event.type === "turn_failed") {
|
||||
@@ -1106,7 +1106,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||
const client = new CodexMcpAgentClient();
|
||||
const config = {
|
||||
provider: "codex-mcp",
|
||||
provider: "codex",
|
||||
cwd,
|
||||
modeId: "read-only",
|
||||
approvalPolicy: "on-request",
|
||||
@@ -1129,7 +1129,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
captured = event.request;
|
||||
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);
|
||||
}
|
||||
if (event.type === "turn_completed" || event.type === "turn_failed") {
|
||||
@@ -1163,7 +1163,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||
const client = new CodexMcpAgentClient();
|
||||
const config = {
|
||||
provider: "codex-mcp",
|
||||
provider: "codex",
|
||||
cwd,
|
||||
modeId: "auto",
|
||||
approvalPolicy: "on-request",
|
||||
@@ -1199,7 +1199,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
) {
|
||||
sawPermissionDenied = true;
|
||||
}
|
||||
if (event.type === "timeline" && providerFromEvent(event) === "codex-mcp") {
|
||||
if (event.type === "timeline" && providerFromEvent(event) === "codex") {
|
||||
timelineItems.push(event.item);
|
||||
}
|
||||
if (event.type === "turn_completed" || event.type === "turn_failed") {
|
||||
@@ -1235,7 +1235,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||
const client = new CodexMcpAgentClient();
|
||||
const config = {
|
||||
provider: "codex-mcp",
|
||||
provider: "codex",
|
||||
cwd,
|
||||
modeId: "auto",
|
||||
approvalPolicy: "on-request",
|
||||
@@ -1275,7 +1275,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
) {
|
||||
sawPermissionResolved = true;
|
||||
}
|
||||
if (event.type === "timeline" && providerFromEvent(event) === "codex-mcp") {
|
||||
if (event.type === "timeline" && providerFromEvent(event) === "codex") {
|
||||
timelineItems.push(event.item);
|
||||
}
|
||||
if (event.type === "turn_failed") {
|
||||
@@ -1319,7 +1319,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||
const client = new CodexMcpAgentClient();
|
||||
const config = {
|
||||
provider: "codex-mcp",
|
||||
provider: "codex",
|
||||
cwd,
|
||||
modeId: "full-access",
|
||||
approvalPolicy: "on-request",
|
||||
@@ -1348,7 +1348,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
|
||||
if (
|
||||
event.type === "timeline" &&
|
||||
providerFromEvent(event) === "codex-mcp" &&
|
||||
providerFromEvent(event) === "codex" &&
|
||||
event.item.type === "tool_call" &&
|
||||
event.item.server === "command" &&
|
||||
isSleepCommandToolCall(event.item)
|
||||
@@ -1394,7 +1394,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
const { CodexMcpAgentClient } = await loadCodexMcpAgentClient();
|
||||
const client = new CodexMcpAgentClient();
|
||||
const config = {
|
||||
provider: "codex-mcp",
|
||||
provider: "codex",
|
||||
cwd,
|
||||
modeId: "full-access",
|
||||
approvalPolicy: "on-request",
|
||||
@@ -1423,7 +1423,7 @@ describe("CodexMcpAgentClient (MCP integration)", () => {
|
||||
|
||||
if (
|
||||
event.type === "timeline" &&
|
||||
providerFromEvent(event) === "codex-mcp" &&
|
||||
providerFromEvent(event) === "codex" &&
|
||||
event.item.type === "tool_call" &&
|
||||
event.item.server === "command"
|
||||
) {
|
||||
|
||||
@@ -24,7 +24,7 @@ import type {
|
||||
AgentRuntimeInfo,
|
||||
} from "../agent-sdk-types.js";
|
||||
|
||||
type CodexMcpAgentConfig = AgentSessionConfig & { provider: "codex-mcp" };
|
||||
type CodexMcpAgentConfig = AgentSessionConfig & { provider: "codex" };
|
||||
|
||||
type TurnState = {
|
||||
sawAssistant: boolean;
|
||||
@@ -60,7 +60,7 @@ type PatchFileChange = {
|
||||
type CodexToolArguments = { [key: string]: unknown };
|
||||
|
||||
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 = {
|
||||
supportsStreaming: true,
|
||||
@@ -2455,7 +2455,7 @@ class CodexMcpAgentSession implements AgentSession {
|
||||
this.config = config;
|
||||
this.currentMode =
|
||||
config.modeId !== undefined ? config.modeId : DEFAULT_CODEX_MODE_ID;
|
||||
this.pendingLocalId = `codex-mcp-${randomUUID()}`;
|
||||
this.pendingLocalId = `codex-${randomUUID()}`;
|
||||
|
||||
if (resumeHandle) {
|
||||
this.sessionId = resumeHandle.sessionId;
|
||||
@@ -2480,7 +2480,7 @@ class CodexMcpAgentSession implements AgentSession {
|
||||
}
|
||||
|
||||
this.client = new Client(
|
||||
{ name: "voice-dev-codex-mcp", version: "1.0.0" },
|
||||
{ name: "voice-dev-codex", version: "1.0.0" },
|
||||
{ capabilities: { elicitation: {} } }
|
||||
);
|
||||
|
||||
@@ -2598,7 +2598,7 @@ class CodexMcpAgentSession implements AgentSession {
|
||||
const promptText = toPromptText(prompt);
|
||||
this.emitEvent({
|
||||
type: "timeline",
|
||||
provider: "codex-mcp",
|
||||
provider: CODEX_PROVIDER,
|
||||
item: { type: "user_message", text: promptText },
|
||||
});
|
||||
|
||||
@@ -2606,12 +2606,12 @@ class CodexMcpAgentSession implements AgentSession {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
this.emitEvent({
|
||||
type: "timeline",
|
||||
provider: "codex-mcp",
|
||||
provider: CODEX_PROVIDER,
|
||||
item: { type: "error", message },
|
||||
});
|
||||
this.emitEvent({
|
||||
type: "turn_failed",
|
||||
provider: "codex-mcp",
|
||||
provider: CODEX_PROVIDER,
|
||||
error: message,
|
||||
});
|
||||
queue.end();
|
||||
@@ -2647,7 +2647,7 @@ class CodexMcpAgentSession implements AgentSession {
|
||||
) {
|
||||
this.emitEvent({
|
||||
type: "turn_failed",
|
||||
provider: "codex-mcp",
|
||||
provider: CODEX_PROVIDER,
|
||||
error: "Codex MCP turn interrupted",
|
||||
});
|
||||
this.eventQueue.end();
|
||||
@@ -2721,7 +2721,7 @@ class CodexMcpAgentSession implements AgentSession {
|
||||
const status = response.behavior === "allow" ? "granted" : "denied";
|
||||
this.emitEvent({
|
||||
type: "timeline",
|
||||
provider: "codex-mcp",
|
||||
provider: CODEX_PROVIDER,
|
||||
item: createToolCallTimelineItem({
|
||||
server: "permission",
|
||||
tool: pending.request.name,
|
||||
@@ -2735,7 +2735,7 @@ class CodexMcpAgentSession implements AgentSession {
|
||||
|
||||
this.emitEvent({
|
||||
type: "permission_resolved",
|
||||
provider: "codex-mcp",
|
||||
provider: CODEX_PROVIDER,
|
||||
requestId,
|
||||
resolution: response,
|
||||
});
|
||||
@@ -2949,7 +2949,7 @@ class CodexMcpAgentSession implements AgentSession {
|
||||
if (signal.aborted) {
|
||||
this.emitEvent({
|
||||
type: "turn_failed",
|
||||
provider: "codex-mcp",
|
||||
provider: CODEX_PROVIDER,
|
||||
error: "Codex MCP turn interrupted",
|
||||
});
|
||||
this.eventQueue?.end();
|
||||
@@ -2964,7 +2964,7 @@ class CodexMcpAgentSession implements AgentSession {
|
||||
if (text) {
|
||||
this.emitEvent({
|
||||
type: "timeline",
|
||||
provider: "codex-mcp",
|
||||
provider: CODEX_PROVIDER,
|
||||
item: { type: "assistant_message", text },
|
||||
});
|
||||
}
|
||||
@@ -2978,13 +2978,13 @@ class CodexMcpAgentSession implements AgentSession {
|
||||
if (turnState.sawError) {
|
||||
this.emitEvent({
|
||||
type: "turn_failed",
|
||||
provider: "codex-mcp",
|
||||
provider: CODEX_PROVIDER,
|
||||
error: "Codex MCP turn failed",
|
||||
});
|
||||
} else {
|
||||
this.emitEvent({
|
||||
type: "turn_completed",
|
||||
provider: "codex-mcp",
|
||||
provider: CODEX_PROVIDER,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3019,7 +3019,7 @@ class CodexMcpAgentSession implements AgentSession {
|
||||
private emitPermissionRequested(request: AgentPermissionRequest): void {
|
||||
this.emitEvent({
|
||||
type: "timeline",
|
||||
provider: "codex-mcp",
|
||||
provider: CODEX_PROVIDER,
|
||||
item: createToolCallTimelineItem({
|
||||
server: "permission",
|
||||
tool: request.name,
|
||||
@@ -3032,7 +3032,7 @@ class CodexMcpAgentSession implements AgentSession {
|
||||
});
|
||||
this.emitEvent({
|
||||
type: "permission_requested",
|
||||
provider: "codex-mcp",
|
||||
provider: CODEX_PROVIDER,
|
||||
request,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -131,7 +131,6 @@ export async function createPaseoDaemon(
|
||||
clients: {
|
||||
claude: new ClaudeAgentClient(),
|
||||
codex: new CodexMcpAgentClient(),
|
||||
"codex-mcp": new CodexMcpAgentClient(),
|
||||
...config.agentClients,
|
||||
},
|
||||
registry: agentRegistry,
|
||||
|
||||
20
plan.md
20
plan.md
@@ -842,3 +842,23 @@ Build a new Codex MCP provider side‑by‑side with the existing Codex SDK prov
|
||||
- Typecheck passes
|
||||
- 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).
|
||||
|
||||
- [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