Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/code/scripts/download-binaries.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const DEST_DIR = join(__dirname, "..", "resources", "codex-acp");
const BINARIES = [
{
name: "codex-acp",
version: "0.11.1",
version: "0.12.0",
getUrl: (version, target) => {
const ext = target.includes("windows") ? "zip" : "tar.gz";
return `https://github.com/zed-industries/codex-acp/releases/download/v${version}/codex-acp-${version}-${target}.${ext}`;
Expand Down
16 changes: 16 additions & 0 deletions packages/agent/src/adapters/codex/codex-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import {
} from "../../utils/streams";
import { BaseAcpAgent, type BaseSession } from "../base-acp-agent";
import { createCodexClient } from "./codex-client";
import { normalizeCodexConfigOptions } from "./models";
import {
type CodexSessionState,
createSessionState,
Expand Down Expand Up @@ -265,6 +266,9 @@ export class CodexAcpAgent extends BaseAcpAgent {
const requestedPermissionMode = toCodexPermissionMode(meta?.permissionMode);

const response = await this.codexConnection.newSession(params);
response.configOptions = normalizeCodexConfigOptions(
response.configOptions,
);

// Initialize session state
this.sessionState = createSessionState(response.sessionId, params.cwd, {
Expand Down Expand Up @@ -302,6 +306,9 @@ export class CodexAcpAgent extends BaseAcpAgent {

async loadSession(params: LoadSessionRequest): Promise<LoadSessionResponse> {
const response = await this.codexConnection.loadSession(params);
response.configOptions = normalizeCodexConfigOptions(
response.configOptions,
);
const meta = params._meta as NewSessionMeta | undefined;
const currentPermissionMode = getCurrentPermissionMode(
response.modes?.currentModeId,
Expand Down Expand Up @@ -341,6 +348,9 @@ export class CodexAcpAgent extends BaseAcpAgent {
cwd: params.cwd,
mcpServers: params.mcpServers ?? [],
});
loadResponse.configOptions = normalizeCodexConfigOptions(
loadResponse.configOptions,
);

const meta = params._meta as NewSessionMeta | undefined;
const currentPermissionMode = getCurrentPermissionMode(
Expand Down Expand Up @@ -380,6 +390,9 @@ export class CodexAcpAgent extends BaseAcpAgent {
mcpServers: params.mcpServers ?? [],
_meta: params._meta,
});
newResponse.configOptions = normalizeCodexConfigOptions(
newResponse.configOptions,
);

const meta = params._meta as NewSessionMeta | undefined;
const requestedPermissionMode = toCodexPermissionMode(meta?.permissionMode);
Expand Down Expand Up @@ -665,6 +678,9 @@ export class CodexAcpAgent extends BaseAcpAgent {
): Promise<SetSessionConfigOptionResponse> {
const response = await this.codexConnection.setSessionConfigOption(params);
if (response.configOptions) {
response.configOptions = normalizeCodexConfigOptions(
response.configOptions,
) as typeof response.configOptions;
this.sessionState.configOptions = response.configOptions;
}
if (params.configId === "mode" && typeof params.value === "string") {
Expand Down
50 changes: 50 additions & 0 deletions packages/agent/src/adapters/codex/models.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import type {
SessionConfigOption,
SessionConfigSelectGroup,
SessionConfigSelectOption,
} from "@agentclientprotocol/sdk";

interface ReasoningEffortOption {
value: string;
name: string;
Expand All @@ -14,3 +20,47 @@ export function getReasoningEffortOptions(
): ReasoningEffortOption[] {
return CODEX_REASONING_EFFORT_OPTIONS;
}

const CODEX_ACRONYMS: Record<string, string> = {
gpt: "GPT",
};

export function formatCodexModelName(value: string): string {
const normalized = value.replace(/(\d)-(\d)/g, "$1.$2");
return normalized
.split("-")
.map((part) => {
const lower = part.toLowerCase();
if (CODEX_ACRONYMS[lower]) return CODEX_ACRONYMS[lower];
if (/^[0-9.]+$/.test(part)) return part;
return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
})
.join("-");
}

export function normalizeCodexConfigOptions(
configOptions: SessionConfigOption[] | null | undefined,
): SessionConfigOption[] | null | undefined {
if (!configOptions) return configOptions;
const formatOption = (
opt: SessionConfigSelectOption,
): SessionConfigSelectOption => ({
...opt,
name: formatCodexModelName(opt.value),
});
Comment thread
jonathanlab marked this conversation as resolved.
return configOptions.map((option) => {
if (option.category !== "model" || option.type !== "select") return option;
const options = option.options;
if (options.length === 0) return option;
const isGroup = "group" in options[0];
return {
...option,
options: isGroup
? (options as SessionConfigSelectGroup[]).map((group) => ({
...group,
options: group.options.map(formatOption),
}))
: (options as SessionConfigSelectOption[]).map(formatOption),
} as SessionConfigOption;
});
Comment thread
jonathanlab marked this conversation as resolved.
}
Loading