diff --git a/codex-cli/src/components/singlepass-cli-app.tsx b/codex-cli/src/components/singlepass-cli-app.tsx index 56d1d913..b57b40e4 100644 --- a/codex-cli/src/components/singlepass-cli-app.tsx +++ b/codex-cli/src/components/singlepass-cli-app.tsx @@ -5,7 +5,13 @@ import type { FileOperation } from "../utils/singlepass/file_ops"; import Spinner from "./vendor/ink-spinner"; // Third‑party / vendor components import TextInput from "./vendor/ink-text-input"; -import { OPENAI_TIMEOUT_MS, getBaseUrl, getApiKey } from "../utils/config"; +import { + OPENAI_TIMEOUT_MS, + OPENAI_ORGANIZATION, + OPENAI_PROJECT, + getBaseUrl, + getApiKey, +} from "../utils/config"; import { generateDiffSummary, generateEditSummary, @@ -393,10 +399,19 @@ export function SinglePassApp({ files, }); + const headers: Record = {}; + if (OPENAI_ORGANIZATION) { + headers["OpenAI-Organization"] = OPENAI_ORGANIZATION; + } + if (OPENAI_PROJECT) { + headers["OpenAI-Project"] = OPENAI_PROJECT; + } + const openai = new OpenAI({ apiKey: getApiKey(config.provider), baseURL: getBaseUrl(config.provider), timeout: OPENAI_TIMEOUT_MS, + defaultHeaders: headers, }); const chatResp = await openai.beta.chat.completions.parse({ model: config.model, diff --git a/codex-cli/src/utils/agent/agent-loop.ts b/codex-cli/src/utils/agent/agent-loop.ts index aff0e38c..bfbcd95d 100644 --- a/codex-cli/src/utils/agent/agent-loop.ts +++ b/codex-cli/src/utils/agent/agent-loop.ts @@ -11,7 +11,13 @@ import type { } from "openai/resources/responses/responses.mjs"; import type { Reasoning } from "openai/resources.mjs"; -import { OPENAI_TIMEOUT_MS, getApiKey, getBaseUrl } from "../config.js"; +import { + OPENAI_TIMEOUT_MS, + OPENAI_ORGANIZATION, + OPENAI_PROJECT, + getApiKey, + getBaseUrl, +} from "../config.js"; import { log } from "../logger/log.js"; import { parseToolCallArguments } from "../parsers.js"; import { responsesCreateViaChatCompletions } from "../responses.js"; @@ -302,6 +308,10 @@ export class AgentLoop { originator: ORIGIN, version: CLI_VERSION, session_id: this.sessionId, + ...(OPENAI_ORGANIZATION + ? { "OpenAI-Organization": OPENAI_ORGANIZATION } + : {}), + ...(OPENAI_PROJECT ? { "OpenAI-Project": OPENAI_PROJECT } : {}), }, ...(timeoutMs !== undefined ? { timeout: timeoutMs } : {}), }); diff --git a/codex-cli/src/utils/config.ts b/codex-cli/src/utils/config.ts index d2b59680..7bd6052e 100644 --- a/codex-cli/src/utils/config.ts +++ b/codex-cli/src/utils/config.ts @@ -36,6 +36,8 @@ export const OPENAI_TIMEOUT_MS = parseInt(process.env["OPENAI_TIMEOUT_MS"] || "0", 10) || undefined; export const OPENAI_BASE_URL = process.env["OPENAI_BASE_URL"] || ""; export let OPENAI_API_KEY = process.env["OPENAI_API_KEY"] || ""; +export const OPENAI_ORGANIZATION = process.env["OPENAI_ORGANIZATION"] || ""; +export const OPENAI_PROJECT = process.env["OPENAI_PROJECT"] || ""; export function setApiKey(apiKey: string): void { OPENAI_API_KEY = apiKey; diff --git a/codex-cli/src/utils/model-utils.ts b/codex-cli/src/utils/model-utils.ts index 5670fc44..0d370f27 100644 --- a/codex-cli/src/utils/model-utils.ts +++ b/codex-cli/src/utils/model-utils.ts @@ -1,7 +1,12 @@ import type { ResponseItem } from "openai/resources/responses/responses.mjs"; import { approximateTokensUsed } from "./approximate-tokens-used.js"; -import { getBaseUrl, getApiKey } from "./config"; +import { + OPENAI_ORGANIZATION, + OPENAI_PROJECT, + getBaseUrl, + getApiKey, +} from "./config"; import { type SupportedModelId, openAiModelInfo } from "./model-info.js"; import OpenAI from "openai"; @@ -22,9 +27,18 @@ async function fetchModels(provider: string): Promise> { } try { + const headers: Record = {}; + if (OPENAI_ORGANIZATION) { + headers["OpenAI-Organization"] = OPENAI_ORGANIZATION; + } + if (OPENAI_PROJECT) { + headers["OpenAI-Project"] = OPENAI_PROJECT; + } + const openai = new OpenAI({ apiKey: getApiKey(provider), baseURL: getBaseUrl(provider), + defaultHeaders: headers, }); const list = await openai.models.list(); const models: Array = [];