refactor(agents): hide execution contract resolver

This commit is contained in:
Vincent Koc 2026-06-17 09:57:26 +08:00
parent e5ff835c01
commit 2f222cdc1c
No known key found for this signature in database
2 changed files with 27 additions and 30 deletions

View file

@ -1,12 +1,9 @@
// Covers provider/model gates for strict agentic execution-contract activation.
import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import {
isStrictAgenticExecutionContractActive,
resolveEffectiveExecutionContract,
} from "./execution-contract.js";
import { isStrictAgenticExecutionContractActive } from "./execution-contract.js";
describe("resolveEffectiveExecutionContract", () => {
describe("isStrictAgenticExecutionContractActive", () => {
const supportedProvider = "openai";
const unsupportedProvider = "anthropic";
const emptyConfig: OpenClawConfig = {};
@ -14,57 +11,57 @@ describe("resolveEffectiveExecutionContract", () => {
describe("supported provider + model detection", () => {
it("auto-activates on bare gpt-5 model ids", () => {
expect(
resolveEffectiveExecutionContract({
isStrictAgenticExecutionContractActive({
config: emptyConfig,
provider: supportedProvider,
modelId: "gpt-5.4",
}),
).toBe("strict-agentic");
).toBe(true);
});
it("auto-activates on the mock-openai qa lane", () => {
expect(
resolveEffectiveExecutionContract({
isStrictAgenticExecutionContractActive({
config: emptyConfig,
provider: "mock-openai",
modelId: "mock-openai/gpt-5.4",
}),
).toBe("strict-agentic");
).toBe(true);
});
it("auto-activates on gpt-5o and variants without a separator", () => {
for (const modelId of ["gpt-5", "gpt-5o", "gpt-5o-mini"]) {
expect(
resolveEffectiveExecutionContract({
isStrictAgenticExecutionContractActive({
config: emptyConfig,
provider: supportedProvider,
modelId,
}),
).toBe("strict-agentic");
).toBe(true);
}
});
it("auto-activates on dot-separated variants", () => {
for (const modelId of ["gpt-5.0", "gpt-5.4", "gpt-5.4-alt", "gpt-5.99"]) {
expect(
resolveEffectiveExecutionContract({
isStrictAgenticExecutionContractActive({
config: emptyConfig,
provider: supportedProvider,
modelId,
}),
).toBe("strict-agentic");
).toBe(true);
}
});
it("auto-activates on dash-separated variants", () => {
for (const modelId of ["gpt-5-preview", "gpt-5-turbo", "gpt-5-2025-03"]) {
expect(
resolveEffectiveExecutionContract({
isStrictAgenticExecutionContractActive({
config: emptyConfig,
provider: supportedProvider,
modelId,
}),
).toBe("strict-agentic");
).toBe(true);
}
});
@ -81,24 +78,24 @@ describe("resolveEffectiveExecutionContract", () => {
" OPENAI:GPT-5.4 ",
]) {
expect(
resolveEffectiveExecutionContract({
isStrictAgenticExecutionContractActive({
config: emptyConfig,
provider: supportedProvider,
modelId,
}),
).toBe("strict-agentic");
).toBe(true);
}
});
it("is case-insensitive", () => {
for (const modelId of ["GPT-5.4", "Gpt-5O", "OPENAI/GPT-5.4"]) {
expect(
resolveEffectiveExecutionContract({
isStrictAgenticExecutionContractActive({
config: emptyConfig,
provider: supportedProvider,
modelId,
}),
).toBe("strict-agentic");
).toBe(true);
}
});
@ -113,12 +110,12 @@ describe("resolveEffectiveExecutionContract", () => {
"mistral-large",
]) {
expect(
resolveEffectiveExecutionContract({
isStrictAgenticExecutionContractActive({
config: emptyConfig,
provider: supportedProvider,
modelId,
}),
).toBe("default");
).toBe(false);
}
});
@ -126,12 +123,12 @@ describe("resolveEffectiveExecutionContract", () => {
// Model naming alone is insufficient; unsupported providers must not
// inherit OpenAI-specific strict-agentic handling by accident.
expect(
resolveEffectiveExecutionContract({
isStrictAgenticExecutionContractActive({
config: emptyConfig,
provider: unsupportedProvider,
modelId: "gpt-5.4",
}),
).toBe("default");
).toBe(false);
});
});
@ -147,12 +144,12 @@ describe("resolveEffectiveExecutionContract", () => {
},
};
expect(
resolveEffectiveExecutionContract({
isStrictAgenticExecutionContractActive({
config,
provider: supportedProvider,
modelId: "gpt-5.4",
}),
).toBe("strict-agentic");
).toBe(true);
});
it("honors explicit default opt-out even on the supported lane", () => {
@ -166,12 +163,12 @@ describe("resolveEffectiveExecutionContract", () => {
},
};
expect(
resolveEffectiveExecutionContract({
isStrictAgenticExecutionContractActive({
config,
provider: supportedProvider,
modelId: "gpt-5.4",
}),
).toBe("default");
).toBe(false);
});
it("collapses explicit strict-agentic to default on an unsupported lane", () => {
@ -185,12 +182,12 @@ describe("resolveEffectiveExecutionContract", () => {
},
};
expect(
resolveEffectiveExecutionContract({
isStrictAgenticExecutionContractActive({
config,
provider: unsupportedProvider,
modelId: "claude-opus-4-6",
}),
).toBe("default");
).toBe(false);
});
});

View file

@ -83,7 +83,7 @@ export function isStrictAgenticSupportedProviderModel(params: {
* Explicit opt-out still works. Assistant prose is never classified to decide
* whether a turn represents planning, progress, or completion.
*/
export function resolveEffectiveExecutionContract(params: {
function resolveEffectiveExecutionContract(params: {
config?: OpenClawConfig;
sessionKey?: string;
agentId?: string | null;