mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-05 18:00:22 +00:00
feat: allow compaction model override via config (#38753)
Merged via squash.
Prepared head SHA: a3d6d6c845
Co-authored-by: starbuck100 <25417736+starbuck100@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
This commit is contained in:
@@ -52,7 +52,10 @@ describe("models-config merge helpers", () => {
|
||||
it("merges explicit providers onto trimmed keys", () => {
|
||||
const merged = mergeProviders({
|
||||
explicit: {
|
||||
" custom ": { api: "openai-responses", models: [] } as ProviderConfig,
|
||||
" custom ": {
|
||||
api: "openai-responses",
|
||||
models: [] as ProviderConfig["models"],
|
||||
} as ProviderConfig,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -271,8 +271,31 @@ export async function compactEmbeddedPiSessionDirect(
|
||||
const resolvedWorkspace = resolveUserPath(params.workspaceDir);
|
||||
const prevCwd = process.cwd();
|
||||
|
||||
const provider = (params.provider ?? DEFAULT_PROVIDER).trim() || DEFAULT_PROVIDER;
|
||||
const modelId = (params.model ?? DEFAULT_MODEL).trim() || DEFAULT_MODEL;
|
||||
// Resolve compaction model: prefer config override, then fall back to caller-supplied model
|
||||
const compactionModelOverride = params.config?.agents?.defaults?.compaction?.model?.trim();
|
||||
let provider: string;
|
||||
let modelId: string;
|
||||
// When switching provider via override, drop the primary auth profile to avoid
|
||||
// sending the wrong credentials (e.g. OpenAI profile token to OpenRouter).
|
||||
let authProfileId: string | undefined = params.authProfileId;
|
||||
if (compactionModelOverride) {
|
||||
const slashIdx = compactionModelOverride.indexOf("/");
|
||||
if (slashIdx > 0) {
|
||||
provider = compactionModelOverride.slice(0, slashIdx).trim();
|
||||
modelId = compactionModelOverride.slice(slashIdx + 1).trim() || DEFAULT_MODEL;
|
||||
// Provider changed — drop primary auth profile so getApiKeyForModel
|
||||
// falls back to provider-based key resolution for the override model.
|
||||
if (provider !== (params.provider ?? "").trim()) {
|
||||
authProfileId = undefined;
|
||||
}
|
||||
} else {
|
||||
provider = (params.provider ?? DEFAULT_PROVIDER).trim() || DEFAULT_PROVIDER;
|
||||
modelId = compactionModelOverride;
|
||||
}
|
||||
} else {
|
||||
provider = (params.provider ?? DEFAULT_PROVIDER).trim() || DEFAULT_PROVIDER;
|
||||
modelId = (params.model ?? DEFAULT_MODEL).trim() || DEFAULT_MODEL;
|
||||
}
|
||||
const fail = (reason: string): EmbeddedPiCompactResult => {
|
||||
log.warn(
|
||||
`[compaction-diag] end runId=${runId} sessionKey=${params.sessionKey ?? params.sessionId} ` +
|
||||
@@ -302,7 +325,7 @@ export async function compactEmbeddedPiSessionDirect(
|
||||
const apiKeyInfo = await getApiKeyForModel({
|
||||
model,
|
||||
cfg: params.config,
|
||||
profileId: params.authProfileId,
|
||||
profileId: authProfileId,
|
||||
agentDir,
|
||||
});
|
||||
|
||||
|
||||
@@ -639,6 +639,72 @@ describe("prependSystemPromptAddition", () => {
|
||||
});
|
||||
|
||||
describe("buildAfterTurnLegacyCompactionParams", () => {
|
||||
it("uses primary model when compaction.model is not set", () => {
|
||||
const legacy = buildAfterTurnLegacyCompactionParams({
|
||||
attempt: {
|
||||
sessionKey: "agent:main:session:abc",
|
||||
messageChannel: "slack",
|
||||
messageProvider: "slack",
|
||||
agentAccountId: "acct-1",
|
||||
authProfileId: "openai:p1",
|
||||
config: {} as OpenClawConfig,
|
||||
skillsSnapshot: undefined,
|
||||
senderIsOwner: true,
|
||||
provider: "openai-codex",
|
||||
modelId: "gpt-5.3-codex",
|
||||
thinkLevel: "off",
|
||||
reasoningLevel: "on",
|
||||
extraSystemPrompt: "extra",
|
||||
ownerNumbers: ["+15555550123"],
|
||||
},
|
||||
workspaceDir: "/tmp/workspace",
|
||||
agentDir: "/tmp/agent",
|
||||
});
|
||||
|
||||
expect(legacy).toMatchObject({
|
||||
provider: "openai-codex",
|
||||
model: "gpt-5.3-codex",
|
||||
});
|
||||
});
|
||||
|
||||
it("passes primary model through even when compaction.model is set (override resolved in compactDirect)", () => {
|
||||
const legacy = buildAfterTurnLegacyCompactionParams({
|
||||
attempt: {
|
||||
sessionKey: "agent:main:session:abc",
|
||||
messageChannel: "slack",
|
||||
messageProvider: "slack",
|
||||
agentAccountId: "acct-1",
|
||||
authProfileId: "openai:p1",
|
||||
config: {
|
||||
agents: {
|
||||
defaults: {
|
||||
compaction: {
|
||||
model: "openrouter/anthropic/claude-sonnet-4-5",
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
skillsSnapshot: undefined,
|
||||
senderIsOwner: true,
|
||||
provider: "openai-codex",
|
||||
modelId: "gpt-5.3-codex",
|
||||
thinkLevel: "off",
|
||||
reasoningLevel: "on",
|
||||
extraSystemPrompt: "extra",
|
||||
ownerNumbers: ["+15555550123"],
|
||||
},
|
||||
workspaceDir: "/tmp/workspace",
|
||||
agentDir: "/tmp/agent",
|
||||
});
|
||||
|
||||
// buildAfterTurnLegacyCompactionParams no longer resolves the override;
|
||||
// compactEmbeddedPiSessionDirect does it centrally for both auto + manual paths.
|
||||
expect(legacy).toMatchObject({
|
||||
provider: "openai-codex",
|
||||
model: "gpt-5.3-codex",
|
||||
});
|
||||
});
|
||||
|
||||
it("includes resolved auth profile fields for context-engine afterTurn compaction", () => {
|
||||
const legacy = buildAfterTurnLegacyCompactionParams({
|
||||
attempt: {
|
||||
|
||||
Reference in New Issue
Block a user