Fix Paseo Agent ChatGPT auth home lookup

This commit is contained in:
Mohamed Boudra
2026-07-02 08:38:27 +02:00
parent 4086f65096
commit 9665ba07a3
2 changed files with 43 additions and 3 deletions
@@ -8,6 +8,7 @@ import { createTestLogger } from "../../../../test-utils/test-logger.js";
import type { AgentSessionConfig } from "../../agent-sdk-types.js";
import { PaseoAgentClient } from "./agent.js";
import { PaseoAgentConfigSchema, type PaseoAgentConfig } from "./config.js";
import { storeCodexOAuthCredential } from "./oauth-store.js";
function makeConfig(): PaseoAgentConfig {
return PaseoAgentConfigSchema.parse({
@@ -65,6 +66,38 @@ describe("PaseoAgentClient", () => {
expect(await empty.isAvailable()).toBe(false);
});
it("checks ChatGPT OAuth credentials in the configured Paseo home", async () => {
const paseoHome = mkdtempSync(join(tmpdir(), "paseo-agent-client-"));
const wrongHome = mkdtempSync(join(tmpdir(), "paseo-agent-wrong-home-"));
tempDirs.push(paseoHome, wrongHome);
const previousPaseoHome = process.env.PASEO_HOME;
process.env.PASEO_HOME = wrongHome;
storeCodexOAuthCredential({
providerInstance: "chatgpt",
credential: { type: "oauth", access: "access-token", refresh: "refresh-token", expires: 0 },
env: { PASEO_HOME: paseoHome },
});
const config = PaseoAgentConfigSchema.parse({
providers: {
chatgpt: {
type: "openai-codex",
options: { models: [{ id: "gpt-5.3-codex" }] },
},
},
});
try {
const client = new PaseoAgentClient({ logger: createTestLogger(), config, paseoHome });
expect(await client.isAvailable()).toBe(true);
} finally {
if (previousPaseoHome === undefined) {
delete process.env.PASEO_HOME;
} else {
process.env.PASEO_HOME = previousPaseoHome;
}
}
});
it("lists only configured models, never Pi disk/default models", async () => {
const client = new PaseoAgentClient({ logger: createTestLogger(), config: makeConfig() });
const models = await client.listModels({ cwd: process.cwd(), force: false });
@@ -83,6 +83,10 @@ function resolveIsolatedAgentDir(): string {
return join(base, "pi-harness");
}
function envForPaseoHome(paseoHome: string | undefined): NodeJS.ProcessEnv {
return paseoHome ? { ...process.env, PASEO_HOME: paseoHome } : process.env;
}
interface PaseoAgentClientOptions {
logger: Logger;
config: PaseoAgentConfig;
@@ -539,7 +543,9 @@ export class PaseoAgentClient implements AgentClient {
// OAuth providers (ChatGPT/Codex) use a Paseo-owned, file-backed AuthStorage so Pi
// reads the stored credential and persists refreshed tokens (rotation) back to it.
const usesOAuth = inferenceProviders.some((provider) => provider.oauth);
const authStorage = usesOAuth ? createPaseoAgentAuthStorage() : undefined;
const authStorage = usesOAuth
? createPaseoAgentAuthStorage(envForPaseoHome(this.paseoHome))
: undefined;
// Bridge Paseo-injected MCP servers (e.g. the `paseo` HTTP server) into Pi tools.
const mcpBridge = await createMcpToolBridge({
@@ -574,8 +580,9 @@ export class PaseoAgentClient implements AgentClient {
}
async isAvailable(): Promise<boolean> {
return paseoAgentHasUsableModel(this.config, process.env, (providerInstance) =>
hasStoredOAuthCredential(providerInstance),
const env = envForPaseoHome(this.paseoHome);
return paseoAgentHasUsableModel(this.config, env, (providerInstance) =>
hasStoredOAuthCredential(providerInstance, env),
);
}