mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:20:43 +00:00
fix(agent): apply configured fast mode to embedded runs
This commit is contained in:
@@ -48,6 +48,7 @@ import { resolveAgentRunContext } from "./command/run-context.js";
|
||||
import { resolveSession } from "./command/session.js";
|
||||
import type { AgentCommandIngressOpts, AgentCommandOpts } from "./command/types.js";
|
||||
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "./defaults.js";
|
||||
import { resolveFastModeState } from "./fast-mode.js";
|
||||
import { AGENT_LANE_SUBAGENT } from "./lanes.js";
|
||||
import { LiveSessionModelSwitchError } from "./live-model-switch.js";
|
||||
import { loadModelCatalog } from "./model-catalog.js";
|
||||
@@ -978,6 +979,13 @@ async function agentCommandInternal(
|
||||
body,
|
||||
isFallbackRetry,
|
||||
resolvedThinkLevel,
|
||||
fastMode: resolveFastModeState({
|
||||
cfg,
|
||||
provider: providerOverride,
|
||||
model: modelOverride,
|
||||
agentId: sessionAgentId,
|
||||
sessionEntry,
|
||||
}).enabled,
|
||||
timeoutMs,
|
||||
runId,
|
||||
opts,
|
||||
|
||||
@@ -324,6 +324,7 @@ export function runAgentAttempt(params: {
|
||||
body: string;
|
||||
isFallbackRetry: boolean;
|
||||
resolvedThinkLevel: ThinkLevel;
|
||||
fastMode?: boolean;
|
||||
timeoutMs: number;
|
||||
runId: string;
|
||||
opts: AgentCommandOpts & { senderIsOwner: boolean };
|
||||
@@ -577,6 +578,7 @@ export function runAgentAttempt(params: {
|
||||
authProfileId,
|
||||
authProfileIdSource: authProfileId ? harnessAuthSelection.authProfileIdSource : undefined,
|
||||
thinkLevel: params.resolvedThinkLevel,
|
||||
fastMode: params.fastMode,
|
||||
verboseLevel: params.resolvedVerboseLevel,
|
||||
timeoutMs: params.timeoutMs,
|
||||
runId: params.runId,
|
||||
|
||||
@@ -54,6 +54,69 @@ describe("resolveFastModeState", () => {
|
||||
expect(state.source).toBe("config");
|
||||
});
|
||||
|
||||
it("uses model config when the runtime passes a provider-qualified model ref", () => {
|
||||
const cfg = {
|
||||
agents: {
|
||||
defaults: {
|
||||
models: {
|
||||
"openai/gpt-5.5": { params: { fastMode: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
const state = resolveFastModeState({
|
||||
cfg,
|
||||
provider: "openai",
|
||||
model: "openai/gpt-5.5",
|
||||
});
|
||||
|
||||
expect(state.enabled).toBe(true);
|
||||
expect(state.source).toBe("config");
|
||||
});
|
||||
|
||||
it("uses canonical provider/model config for slash-containing model ids", () => {
|
||||
const cfg = {
|
||||
agents: {
|
||||
defaults: {
|
||||
models: {
|
||||
"openrouter/anthropic/claude-sonnet-4-6": { params: { fastMode: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
const state = resolveFastModeState({
|
||||
cfg,
|
||||
provider: "openrouter",
|
||||
model: "anthropic/claude-sonnet-4-6",
|
||||
});
|
||||
|
||||
expect(state.enabled).toBe(true);
|
||||
expect(state.source).toBe("config");
|
||||
});
|
||||
|
||||
it("does not use another provider's slash-containing model config", () => {
|
||||
const cfg = {
|
||||
agents: {
|
||||
defaults: {
|
||||
models: {
|
||||
"anthropic/claude-sonnet-4-6": { params: { fastMode: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
const state = resolveFastModeState({
|
||||
cfg,
|
||||
provider: "openrouter",
|
||||
model: "anthropic/claude-sonnet-4-6",
|
||||
});
|
||||
|
||||
expect(state.enabled).toBe(false);
|
||||
expect(state.source).toBe("default");
|
||||
});
|
||||
|
||||
it("defaults to off when unset", () => {
|
||||
const state = resolveFastModeState({
|
||||
cfg: {} as OpenClawConfig,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { normalizeFastMode } from "../auto-reply/thinking.shared.js";
|
||||
import type { SessionEntry } from "../config/sessions.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { resolveAgentConfig } from "./agent-scope.js";
|
||||
import { modelKey } from "./model-ref-shared.js";
|
||||
|
||||
export type FastModeState = {
|
||||
enabled: boolean;
|
||||
@@ -13,8 +14,8 @@ function resolveConfiguredFastModeRaw(params: {
|
||||
provider: string;
|
||||
model: string;
|
||||
}): unknown {
|
||||
const modelKey = `${params.provider}/${params.model}`;
|
||||
const modelConfig = params.cfg?.agents?.defaults?.models?.[modelKey];
|
||||
const modelConfig =
|
||||
params.cfg?.agents?.defaults?.models?.[modelKey(params.provider, params.model)];
|
||||
return modelConfig?.params?.fastMode ?? modelConfig?.params?.fast_mode;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,7 @@ vi.mock("../agents/command/attempt-execution.runtime.js", () => {
|
||||
authProfileId,
|
||||
authProfileIdSource: authProfileId ? sessionEntry?.authProfileOverrideSource : undefined,
|
||||
thinkLevel: params.resolvedThinkLevel,
|
||||
fastMode: params.fastMode,
|
||||
verboseLevel: params.resolvedVerboseLevel,
|
||||
timeoutMs: params.timeoutMs,
|
||||
runId: params.runId,
|
||||
@@ -385,6 +386,29 @@ describe("agentCommand", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("passes configured fast mode to embedded runs", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const store = path.join(home, "sessions.json");
|
||||
mockConfig(home, store, {
|
||||
model: "openai/gpt-5.5",
|
||||
models: {
|
||||
"openai/gpt-5.5": { params: { fastMode: true } },
|
||||
},
|
||||
});
|
||||
|
||||
await agentCommand({ message: "ping", agentId: "main" }, runtime);
|
||||
|
||||
const callArgs = getLastEmbeddedCall();
|
||||
expect(callArgs).toEqual(
|
||||
expect.objectContaining({
|
||||
provider: "openai",
|
||||
model: "gpt-5.5",
|
||||
fastMode: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("does not load the full model catalog for trusted explicit overrides without an allowlist", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const store = path.join(home, "sessions.json");
|
||||
|
||||
Reference in New Issue
Block a user