Skip to content
Merged
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
38 changes: 38 additions & 0 deletions codex-cli/src/utils/openai-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ import {
OPENAI_ORGANIZATION,
OPENAI_PROJECT,
} from "./config.js";
import fs from "fs";
import OpenAI, { AzureOpenAI } from "openai";
import * as Errors from "openai/error";
import os from "os";
import path from "path";

const COPILOT_TOKEN_FILE = path.join(os.homedir(), ".codex", "copilot-token.json");

type OpenAIClientConfig = {
provider: string;
Expand Down Expand Up @@ -82,6 +87,22 @@ export class GithubCopilotClient extends OpenAI {
) {
return this.copilotToken;
}
try {
const disk = JSON.parse(fs.readFileSync(COPILOT_TOKEN_FILE, "utf-8"));
Copy link

Copilot AI Jun 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses synchronous file I/O within an async function, which can block the event loop. Consider using fs.promises.readFile or other async APIs to avoid blocking.

Suggested change
const disk = JSON.parse(fs.readFileSync(COPILOT_TOKEN_FILE, "utf-8"));
const disk = JSON.parse(await fs.promises.readFile(COPILOT_TOKEN_FILE, "utf-8"));

Copilot uses AI. Check for mistakes.
if (
typeof disk.token === "string" &&
typeof disk.expiration === "string"
) {
const exp = new Date(disk.expiration);
if (exp.getTime() > Date.now()) {
this.copilotToken = disk.token;
this.copilotTokenExpiration = exp;
return this.copilotToken;
}
}
} catch {
/* ignore */
Comment on lines +103 to +104
Copy link

Copilot AI Jun 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Silently swallowing all errors may make debugging difficult. Consider logging or handling specific error cases to aid in diagnosing cache read failures.

Suggested change
} catch {
/* ignore */
} catch (error) {
console.error("Failed to read Copilot token from disk:", error);

Copilot uses AI. Check for mistakes.
}
const resp = await fetch(
"https://api.github.com/copilot_internal/v2/token",
{
Expand All @@ -106,6 +127,23 @@ export class GithubCopilotClient extends OpenAI {
}
this.copilotToken = token;
this.copilotTokenExpiration = new Date(Date.now() + refresh_in * 1000);
try {
fs.mkdirSync(path.dirname(COPILOT_TOKEN_FILE), { recursive: true });
fs.writeFileSync(
COPILOT_TOKEN_FILE,
JSON.stringify(
{
token: this.copilotToken,
expiration: this.copilotTokenExpiration.toISOString(),
},
null,
2,
),
{ mode: 0o600 },
);
} catch {
/* ignore */
}
return token;
}

Expand Down