mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-07 03:41:37 +00:00
refactor(agent): dedupe harness and command workflows
This commit is contained in:
@@ -44,6 +44,30 @@ describe("createModelSelectionState parent inheritance", () => {
|
||||
});
|
||||
}
|
||||
|
||||
async function resolveHeartbeatStoredOverrideState(hasResolvedHeartbeatModelOverride: boolean) {
|
||||
const cfg = {} as OpenClawConfig;
|
||||
const sessionKey = "agent:main:discord:channel:c1";
|
||||
const sessionEntry = makeEntry({
|
||||
providerOverride: "openai",
|
||||
modelOverride: "gpt-4o",
|
||||
});
|
||||
const sessionStore = { [sessionKey]: sessionEntry };
|
||||
|
||||
return createModelSelectionState({
|
||||
cfg,
|
||||
agentCfg: cfg.agents?.defaults,
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey,
|
||||
defaultProvider,
|
||||
defaultModel,
|
||||
provider: "anthropic",
|
||||
model: "claude-opus-4-5",
|
||||
hasModelDirective: false,
|
||||
hasResolvedHeartbeatModelOverride,
|
||||
});
|
||||
}
|
||||
|
||||
it("inherits parent override from explicit parentSessionKey", async () => {
|
||||
const cfg = {} as OpenClawConfig;
|
||||
const parentKey = "agent:main:discord:channel:c1";
|
||||
@@ -157,58 +181,14 @@ describe("createModelSelectionState parent inheritance", () => {
|
||||
});
|
||||
|
||||
it("applies stored override when heartbeat override was not resolved", async () => {
|
||||
const cfg = {} as OpenClawConfig;
|
||||
const sessionKey = "agent:main:discord:channel:c1";
|
||||
const sessionEntry = makeEntry({
|
||||
providerOverride: "openai",
|
||||
modelOverride: "gpt-4o",
|
||||
});
|
||||
const sessionStore = {
|
||||
[sessionKey]: sessionEntry,
|
||||
};
|
||||
|
||||
const state = await createModelSelectionState({
|
||||
cfg,
|
||||
agentCfg: cfg.agents?.defaults,
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey,
|
||||
defaultProvider,
|
||||
defaultModel,
|
||||
provider: "anthropic",
|
||||
model: "claude-opus-4-5",
|
||||
hasModelDirective: false,
|
||||
hasResolvedHeartbeatModelOverride: false,
|
||||
});
|
||||
const state = await resolveHeartbeatStoredOverrideState(false);
|
||||
|
||||
expect(state.provider).toBe("openai");
|
||||
expect(state.model).toBe("gpt-4o");
|
||||
});
|
||||
|
||||
it("skips stored override when heartbeat override was resolved", async () => {
|
||||
const cfg = {} as OpenClawConfig;
|
||||
const sessionKey = "agent:main:discord:channel:c1";
|
||||
const sessionEntry = makeEntry({
|
||||
providerOverride: "openai",
|
||||
modelOverride: "gpt-4o",
|
||||
});
|
||||
const sessionStore = {
|
||||
[sessionKey]: sessionEntry,
|
||||
};
|
||||
|
||||
const state = await createModelSelectionState({
|
||||
cfg,
|
||||
agentCfg: cfg.agents?.defaults,
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey,
|
||||
defaultProvider,
|
||||
defaultModel,
|
||||
provider: "anthropic",
|
||||
model: "claude-opus-4-5",
|
||||
hasModelDirective: false,
|
||||
hasResolvedHeartbeatModelOverride: true,
|
||||
});
|
||||
const state = await resolveHeartbeatStoredOverrideState(true);
|
||||
|
||||
expect(state.provider).toBe("anthropic");
|
||||
expect(state.model).toBe("claude-opus-4-5");
|
||||
@@ -219,16 +199,12 @@ describe("createModelSelectionState respects session model override", () => {
|
||||
const defaultProvider = "inferencer";
|
||||
const defaultModel = "deepseek-v3-4bit-mlx";
|
||||
|
||||
it("applies session modelOverride when set", async () => {
|
||||
async function resolveState(sessionEntry: ReturnType<typeof makeEntry>) {
|
||||
const cfg = {} as OpenClawConfig;
|
||||
const sessionKey = "agent:main:main";
|
||||
const sessionEntry = makeEntry({
|
||||
providerOverride: "kimi-coding",
|
||||
modelOverride: "k2p5",
|
||||
});
|
||||
const sessionStore = { [sessionKey]: sessionEntry };
|
||||
|
||||
const state = await createModelSelectionState({
|
||||
return createModelSelectionState({
|
||||
cfg,
|
||||
agentCfg: undefined,
|
||||
sessionEntry,
|
||||
@@ -240,29 +216,22 @@ describe("createModelSelectionState respects session model override", () => {
|
||||
model: defaultModel,
|
||||
hasModelDirective: false,
|
||||
});
|
||||
}
|
||||
|
||||
it("applies session modelOverride when set", async () => {
|
||||
const state = await resolveState(
|
||||
makeEntry({
|
||||
providerOverride: "kimi-coding",
|
||||
modelOverride: "k2p5",
|
||||
}),
|
||||
);
|
||||
|
||||
expect(state.provider).toBe("kimi-coding");
|
||||
expect(state.model).toBe("k2p5");
|
||||
});
|
||||
|
||||
it("falls back to default when no modelOverride is set", async () => {
|
||||
const cfg = {} as OpenClawConfig;
|
||||
const sessionKey = "agent:main:main";
|
||||
const sessionEntry = makeEntry();
|
||||
const sessionStore = { [sessionKey]: sessionEntry };
|
||||
|
||||
const state = await createModelSelectionState({
|
||||
cfg,
|
||||
agentCfg: undefined,
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey,
|
||||
defaultProvider,
|
||||
defaultModel,
|
||||
provider: defaultProvider,
|
||||
model: defaultModel,
|
||||
hasModelDirective: false,
|
||||
});
|
||||
const state = await resolveState(makeEntry());
|
||||
|
||||
expect(state.provider).toBe(defaultProvider);
|
||||
expect(state.model).toBe(defaultModel);
|
||||
@@ -270,54 +239,26 @@ describe("createModelSelectionState respects session model override", () => {
|
||||
|
||||
it("respects modelOverride even when session model field differs", async () => {
|
||||
// From issue #14783: stored override should beat last-used fallback model.
|
||||
const cfg = {} as OpenClawConfig;
|
||||
const sessionKey = "agent:main:main";
|
||||
const sessionEntry = makeEntry({
|
||||
model: "k2p5",
|
||||
modelProvider: "kimi-coding",
|
||||
contextTokens: 262_000,
|
||||
providerOverride: "anthropic",
|
||||
modelOverride: "claude-opus-4-5",
|
||||
});
|
||||
const sessionStore = { [sessionKey]: sessionEntry };
|
||||
|
||||
const state = await createModelSelectionState({
|
||||
cfg,
|
||||
agentCfg: undefined,
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey,
|
||||
defaultProvider,
|
||||
defaultModel,
|
||||
provider: defaultProvider,
|
||||
model: defaultModel,
|
||||
hasModelDirective: false,
|
||||
});
|
||||
const state = await resolveState(
|
||||
makeEntry({
|
||||
model: "k2p5",
|
||||
modelProvider: "kimi-coding",
|
||||
contextTokens: 262_000,
|
||||
providerOverride: "anthropic",
|
||||
modelOverride: "claude-opus-4-5",
|
||||
}),
|
||||
);
|
||||
|
||||
expect(state.provider).toBe("anthropic");
|
||||
expect(state.model).toBe("claude-opus-4-5");
|
||||
});
|
||||
|
||||
it("uses default provider when providerOverride is not set but modelOverride is", async () => {
|
||||
const cfg = {} as OpenClawConfig;
|
||||
const sessionKey = "agent:main:main";
|
||||
const sessionEntry = makeEntry({
|
||||
modelOverride: "deepseek-v3-4bit-mlx",
|
||||
});
|
||||
const sessionStore = { [sessionKey]: sessionEntry };
|
||||
|
||||
const state = await createModelSelectionState({
|
||||
cfg,
|
||||
agentCfg: undefined,
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey,
|
||||
defaultProvider,
|
||||
defaultModel,
|
||||
provider: defaultProvider,
|
||||
model: defaultModel,
|
||||
hasModelDirective: false,
|
||||
});
|
||||
const state = await resolveState(
|
||||
makeEntry({
|
||||
modelOverride: "deepseek-v3-4bit-mlx",
|
||||
}),
|
||||
);
|
||||
|
||||
expect(state.provider).toBe(defaultProvider);
|
||||
expect(state.model).toBe("deepseek-v3-4bit-mlx");
|
||||
|
||||
Reference in New Issue
Block a user