fix(coding-agent): guarded fork cache on scoped models
- Treated startup scoped model selection as a prompt-cache shape override before inheriting fork cache keys. - Covered the --models fork path so a scoped startup model cannot reuse the parent prompt_cache_key. Fixes #5035
This commit is contained in:
@@ -789,7 +789,8 @@ export function applyResolvedSystemPromptInputs(
|
||||
}
|
||||
}
|
||||
|
||||
async function buildSessionOptions(
|
||||
/** Builds startup session options from parsed CLI flags, scoped models, and resolved session lineage. */
|
||||
export async function buildSessionOptions(
|
||||
parsed: Args,
|
||||
scopedModels: ScopedModel[],
|
||||
sessionManager: SessionManager | undefined,
|
||||
@@ -825,7 +826,9 @@ async function buildSessionOptions(
|
||||
options.providerPromptCacheKeySource = "explicit";
|
||||
} else {
|
||||
const header = sessionManager?.getHeader();
|
||||
const scopedModelOverride = scopedModels.length > 0 && !parsed.continue && !parsed.resume;
|
||||
const forkCacheShapeChanged =
|
||||
scopedModelOverride ||
|
||||
parsed.model !== undefined ||
|
||||
parsed.thinking !== undefined ||
|
||||
parsed.systemPrompt !== undefined ||
|
||||
|
||||
@@ -4,7 +4,10 @@ import * as path from "node:path";
|
||||
import { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
||||
import { getBundledModel } from "@oh-my-pi/pi-catalog/models";
|
||||
import { type Args, parseArgs } from "@oh-my-pi/pi-coding-agent/cli/args";
|
||||
import { ModelRegistry } from "@oh-my-pi/pi-coding-agent/config/model-registry";
|
||||
import type { ScopedModel } from "@oh-my-pi/pi-coding-agent/config/model-resolver";
|
||||
import { Settings } from "@oh-my-pi/pi-coding-agent/config/settings";
|
||||
import { buildSessionOptions } from "@oh-my-pi/pi-coding-agent/main";
|
||||
import { type CreateAgentSessionOptions, createAgentSession } from "@oh-my-pi/pi-coding-agent/sdk";
|
||||
import type { AgentSession } from "@oh-my-pi/pi-coding-agent/session/agent-session";
|
||||
import { AuthStorage } from "@oh-my-pi/pi-coding-agent/session/auth-storage";
|
||||
@@ -191,4 +194,40 @@ describe("provider prompt-cache key session affinity", () => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("does not pre-pin parent prompt-cache affinity when a scoped model selects the startup route", async () => {
|
||||
using tempDir = TempDir.createSync("@omp-prompt-cache-scoped-model-");
|
||||
const source = await createSourceSessionFixture(tempDir, "parent-cache-session-scoped");
|
||||
const forkedManager = await SessionManager.forkFrom(source.sourceFile, source.cwd, source.forkSessionDir);
|
||||
const authStorage = await AuthStorage.create(tempDir.join("scoped-auth.db"));
|
||||
authStorage.setRuntimeApiKey(OPENAI_TEST_MODEL.provider, "test-key");
|
||||
try {
|
||||
const modelRegistry = new ModelRegistry(authStorage, tempDir.join("models.yml"));
|
||||
const parsed = parseArgs([
|
||||
"--cwd",
|
||||
source.cwd,
|
||||
"--models",
|
||||
`${OPENAI_TEST_MODEL.provider}/${OPENAI_TEST_MODEL.id}`,
|
||||
]);
|
||||
const scopedModels: ScopedModel[] = [
|
||||
{
|
||||
model: OPENAI_TEST_MODEL,
|
||||
explicitThinkingLevel: false,
|
||||
},
|
||||
];
|
||||
|
||||
const options = await buildSessionOptions(
|
||||
parsed,
|
||||
scopedModels,
|
||||
forkedManager,
|
||||
modelRegistry,
|
||||
Settings.isolated({ "marketplace.autoUpdate": "off" }),
|
||||
);
|
||||
|
||||
expect(options.model).toBe(OPENAI_TEST_MODEL);
|
||||
expect(options.providerPromptCacheKey).toBeUndefined();
|
||||
} finally {
|
||||
authStorage.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user