mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-02 20:30:23 +00:00
refactor: move provider replay runtime ownership into plugins (#60126)
* refactor: move provider replay runtime ownership into plugins * fix(provider-runtime): address review followups --------- Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
@@ -39,24 +39,6 @@ export function resolveReasoningOutputMode(params: {
|
||||
return pluginMode;
|
||||
}
|
||||
|
||||
const normalized = provider.toLowerCase();
|
||||
|
||||
// Check for exact matches or known prefixes/substrings for reasoning providers.
|
||||
// Note: Ollama is intentionally excluded - its OpenAI-compatible endpoint
|
||||
// handles reasoning natively via the `reasoning` field in streaming chunks,
|
||||
// so tag-based enforcement is unnecessary and causes all output to be
|
||||
// discarded as "(no output)" (#2279).
|
||||
// Note: MiniMax is also intentionally excluded. In production it does not
|
||||
// reliably wrap user-visible output in <final> tags, so forcing tag
|
||||
// enforcement suppresses normal assistant replies.
|
||||
if (
|
||||
normalized === "google" ||
|
||||
normalized === "google-gemini-cli" ||
|
||||
normalized === "google-generative-ai"
|
||||
) {
|
||||
return "tagged";
|
||||
}
|
||||
|
||||
return "native";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,35 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { parseBooleanValue } from "./boolean.js";
|
||||
import { isReasoningTagProvider } from "./provider-utils.js";
|
||||
import { splitShellArgs } from "./shell-argv.js";
|
||||
|
||||
const resolveProviderReasoningOutputModeWithPluginMock = vi.fn((params: { provider: string }) => {
|
||||
switch (params.provider.toLowerCase()) {
|
||||
case "google":
|
||||
case "google-gemini-cli":
|
||||
case "google-generative-ai":
|
||||
case "minimax":
|
||||
case "minimax-cn":
|
||||
return "tagged" as const;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
vi.mock("../plugins/provider-runtime.js", () => ({
|
||||
resolveProviderReasoningOutputModeWithPlugin: (params: { provider: string }) =>
|
||||
resolveProviderReasoningOutputModeWithPluginMock(params),
|
||||
}));
|
||||
|
||||
let isReasoningTagProvider: typeof import("./provider-utils.js").isReasoningTagProvider;
|
||||
|
||||
beforeAll(async () => {
|
||||
({ isReasoningTagProvider } = await import("./provider-utils.js"));
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
resolveProviderReasoningOutputModeWithPluginMock.mockClear();
|
||||
});
|
||||
|
||||
describe("parseBooleanValue", () => {
|
||||
it("handles boolean inputs", () => {
|
||||
expect(parseBooleanValue(true)).toBe(true);
|
||||
@@ -45,7 +72,7 @@ describe("parseBooleanValue", () => {
|
||||
describe("isReasoningTagProvider", () => {
|
||||
it.each([
|
||||
{
|
||||
name: "returns false for ollama - native reasoning field, no tags needed (#2279)",
|
||||
name: "returns false for ollama when the provider plugin has no tagged override",
|
||||
value: "ollama",
|
||||
expected: false,
|
||||
},
|
||||
@@ -55,7 +82,7 @@ describe("isReasoningTagProvider", () => {
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "returns true for google (gemini-api-key auth provider)",
|
||||
name: "returns true for google via provider hook",
|
||||
value: "google",
|
||||
expected: true,
|
||||
},
|
||||
@@ -64,21 +91,21 @@ describe("isReasoningTagProvider", () => {
|
||||
value: "Google",
|
||||
expected: true,
|
||||
},
|
||||
{ name: "returns true for google-gemini-cli", value: "google-gemini-cli", expected: true },
|
||||
{
|
||||
name: "returns true for google-generative-ai",
|
||||
value: "google-generative-ai",
|
||||
name: "returns true for google-gemini-cli via provider hook",
|
||||
value: "google-gemini-cli",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "returns false for minimax - does not reliably honor <final> wrappers in production",
|
||||
value: "minimax",
|
||||
expected: false,
|
||||
name: "returns true for google-generative-ai via provider hook",
|
||||
value: "google-generative-ai",
|
||||
expected: true,
|
||||
},
|
||||
{ name: "returns true for minimax via provider hook", value: "minimax", expected: true },
|
||||
{
|
||||
name: "returns false for minimax-cn",
|
||||
name: "returns true for minimax-cn via provider hook alias",
|
||||
value: "minimax-cn",
|
||||
expected: false,
|
||||
expected: true,
|
||||
},
|
||||
{ name: "returns false for null", value: null, expected: false },
|
||||
{ name: "returns false for undefined", value: undefined, expected: false },
|
||||
@@ -91,7 +118,7 @@ describe("isReasoningTagProvider", () => {
|
||||
value: string | null | undefined;
|
||||
expected: boolean;
|
||||
}>)("$name", ({ value, expected }) => {
|
||||
expect(isReasoningTagProvider(value, { workspaceDir: process.cwd() })).toBe(expected);
|
||||
expect(isReasoningTagProvider(value)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user