mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-22 17:22:47 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df081a06ed | ||
|
|
c6a4ae81c9 |
@@ -1117,6 +1117,42 @@ describe("Codex app-server provider", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("starts a session without a model on the project's Codex model and effort", async () => {
|
||||||
|
const cwd = "/workspace/project";
|
||||||
|
const appServer = createFakeCodexAppServer({
|
||||||
|
"config/read": (params) => ({
|
||||||
|
config:
|
||||||
|
(params as { cwd?: unknown }).cwd === cwd
|
||||||
|
? { model: "project-model", model_reasoning_effort: "high" }
|
||||||
|
: { model: "global-model", model_reasoning_effort: "low" },
|
||||||
|
}),
|
||||||
|
getUserSavedConfig: () => ({
|
||||||
|
config: { model: "global-model", modelReasoningEffort: "low" },
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const session = new CodexAppServerAgentSession(
|
||||||
|
createConfig({ cwd, model: undefined }),
|
||||||
|
null,
|
||||||
|
createTestLogger(),
|
||||||
|
async () => appServer.child,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await session.startTurn("use project defaults");
|
||||||
|
|
||||||
|
await expect(appServer.waitForRequest("thread/start")).resolves.toMatchObject({
|
||||||
|
model: "project-model",
|
||||||
|
});
|
||||||
|
await expect(appServer.waitForTurnStart()).resolves.toMatchObject({
|
||||||
|
model: "project-model",
|
||||||
|
effort: "high",
|
||||||
|
});
|
||||||
|
appServer.assertNoErrors();
|
||||||
|
} finally {
|
||||||
|
await session.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test("preserves cwd-resolved Codex writable roots under an explicit workflow mode", async () => {
|
test("preserves cwd-resolved Codex writable roots under an explicit workflow mode", async () => {
|
||||||
const appServer = createFakeCodexAppServer({
|
const appServer = createFakeCodexAppServer({
|
||||||
"config/read": () => ({
|
"config/read": () => ({
|
||||||
|
|||||||
@@ -3100,10 +3100,32 @@ const CodexNotificationSchema = z.union([
|
|||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// config/read resolves the effective layered config, including a trusted project's
|
||||||
|
// .codex/config.toml when given its cwd; getUserSavedConfig predates it.
|
||||||
async function readCodexConfiguredDefaults(
|
async function readCodexConfiguredDefaults(
|
||||||
client: CodexAppServerClient,
|
client: CodexAppServerClient,
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
|
cwd: string | null,
|
||||||
): Promise<CodexConfiguredDefaults> {
|
): Promise<CodexConfiguredDefaults> {
|
||||||
|
let configReadDefaults: CodexConfiguredDefaults = {};
|
||||||
|
try {
|
||||||
|
const response = toObjectRecord(await client.request("config/read", { cwd }));
|
||||||
|
const config = toObjectRecord(response?.config);
|
||||||
|
const modelValue = typeof config?.model === "string" ? config.model : undefined;
|
||||||
|
const thinkingOptionValue =
|
||||||
|
typeof config?.model_reasoning_effort === "string" ? config.model_reasoning_effort : null;
|
||||||
|
configReadDefaults = {
|
||||||
|
model: normalizeCodexModelId(modelValue),
|
||||||
|
thinkingOptionId: normalizeCodexThinkingOptionId(thinkingOptionValue),
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
logger.debug({ error }, "Failed to read Codex config defaults");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configReadDefaults.model && configReadDefaults.thinkingOptionId) {
|
||||||
|
return configReadDefaults;
|
||||||
|
}
|
||||||
|
|
||||||
let savedConfigDefaults: CodexConfiguredDefaults = {};
|
let savedConfigDefaults: CodexConfiguredDefaults = {};
|
||||||
try {
|
try {
|
||||||
const response = toObjectRecord(await client.request("getUserSavedConfig", {}));
|
const response = toObjectRecord(await client.request("getUserSavedConfig", {}));
|
||||||
@@ -3119,26 +3141,7 @@ async function readCodexConfiguredDefaults(
|
|||||||
logger.debug({ error }, "Failed to read Codex saved config defaults");
|
logger.debug({ error }, "Failed to read Codex saved config defaults");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (savedConfigDefaults.model && savedConfigDefaults.thinkingOptionId) {
|
return mergeCodexConfiguredDefaults(configReadDefaults, savedConfigDefaults);
|
||||||
return savedConfigDefaults;
|
|
||||||
}
|
|
||||||
|
|
||||||
let configReadDefaults: CodexConfiguredDefaults = {};
|
|
||||||
try {
|
|
||||||
const response = toObjectRecord(await client.request("config/read", {}));
|
|
||||||
const config = toObjectRecord(response?.config);
|
|
||||||
const modelValue = typeof config?.model === "string" ? config.model : undefined;
|
|
||||||
const thinkingOptionValue =
|
|
||||||
typeof config?.model_reasoning_effort === "string" ? config.model_reasoning_effort : null;
|
|
||||||
configReadDefaults = {
|
|
||||||
model: normalizeCodexModelId(modelValue),
|
|
||||||
thinkingOptionId: normalizeCodexThinkingOptionId(thinkingOptionValue),
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
logger.debug({ error }, "Failed to read Codex config defaults");
|
|
||||||
}
|
|
||||||
|
|
||||||
return mergeCodexConfiguredDefaults(savedConfigDefaults, configReadDefaults);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CodexSkillPromptBlock {
|
interface CodexSkillPromptBlock {
|
||||||
@@ -5119,7 +5122,11 @@ export class CodexAppServerAgentSession implements AgentSession {
|
|||||||
let model = this.config.model;
|
let model = this.config.model;
|
||||||
let thinkingOptionId = normalizeCodexThinkingOptionId(this.config.thinkingOptionId);
|
let thinkingOptionId = normalizeCodexThinkingOptionId(this.config.thinkingOptionId);
|
||||||
if (!model || !thinkingOptionId) {
|
if (!model || !thinkingOptionId) {
|
||||||
configuredDefaults = await readCodexConfiguredDefaults(this.client, this.logger);
|
configuredDefaults = await readCodexConfiguredDefaults(
|
||||||
|
this.client,
|
||||||
|
this.logger,
|
||||||
|
this.config.cwd ?? null,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (!model) {
|
if (!model) {
|
||||||
model = configuredDefaults.model;
|
model = configuredDefaults.model;
|
||||||
@@ -7323,7 +7330,7 @@ export class CodexAppServerAgentClient implements AgentClient {
|
|||||||
const parsedResponse = CodexModelListResponseSchema.safeParse(rawResponse);
|
const parsedResponse = CodexModelListResponseSchema.safeParse(rawResponse);
|
||||||
const models = parsedResponse.success ? (parsedResponse.data.data ?? []) : [];
|
const models = parsedResponse.success ? (parsedResponse.data.data ?? []) : [];
|
||||||
const configuredDefaults = await runProviderRefreshActivity(context, "config/read", () =>
|
const configuredDefaults = await runProviderRefreshActivity(context, "config/read", () =>
|
||||||
readCodexConfiguredDefaults(client!, this.logger),
|
readCodexConfiguredDefaults(client!, this.logger, null),
|
||||||
);
|
);
|
||||||
const configuredDefaultModelId = configuredDefaults.model;
|
const configuredDefaultModelId = configuredDefaults.model;
|
||||||
const configuredDefaultThinkingOptionId = configuredDefaults.thinkingOptionId;
|
const configuredDefaultThinkingOptionId = configuredDefaults.thinkingOptionId;
|
||||||
|
|||||||
@@ -355,7 +355,8 @@ test.each([
|
|||||||
await resumed?.close();
|
await resumed?.close();
|
||||||
await original?.close();
|
await original?.close();
|
||||||
await client.shutdown();
|
await client.shutdown();
|
||||||
await rm(root, { recursive: true, force: true });
|
// OpenCode can still hold its ripgrep download open on Windows right after shutdown.
|
||||||
|
await rm(root, { recursive: true, force: true, maxRetries: 10, retryDelay: 200 });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
240_000,
|
240_000,
|
||||||
|
|||||||
Reference in New Issue
Block a user