mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-18 04:31:10 +00:00
fix: align gemini cli live backend runs
This commit is contained in:
@@ -9,14 +9,23 @@ const GEMINI_MODEL_ALIASES: Record<string, string> = {
|
||||
flash: "gemini-3.1-flash-preview",
|
||||
"flash-lite": "gemini-3.1-flash-lite-preview",
|
||||
};
|
||||
const GEMINI_CLI_DEFAULT_MODEL_REF = "google-gemini-cli/gemini-3.1-pro-preview";
|
||||
|
||||
export function buildGoogleGeminiCliBackend(): CliBackendPlugin {
|
||||
return {
|
||||
id: "google-gemini-cli",
|
||||
liveTest: {
|
||||
defaultModelRef: GEMINI_CLI_DEFAULT_MODEL_REF,
|
||||
defaultImageProbe: true,
|
||||
docker: {
|
||||
npmPackage: "@google/gemini-cli",
|
||||
binaryName: "gemini",
|
||||
},
|
||||
},
|
||||
config: {
|
||||
command: "gemini",
|
||||
args: ["--prompt", "--output-format", "json"],
|
||||
resumeArgs: ["--resume", "{sessionId}", "--prompt", "--output-format", "json"],
|
||||
args: ["--output-format", "json", "--prompt", "{prompt}"],
|
||||
resumeArgs: ["--resume", "{sessionId}", "--output-format", "json", "--prompt", "{prompt}"],
|
||||
output: "json",
|
||||
input: "arg",
|
||||
modelArg: "--model",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
OPENCLAW_DOCKER_LIVE_AUTH_ALL=(.minimax)
|
||||
OPENCLAW_DOCKER_LIVE_AUTH_ALL=(.gemini .minimax)
|
||||
OPENCLAW_DOCKER_LIVE_AUTH_FILES_ALL=(
|
||||
.codex/auth.json
|
||||
.codex/config.toml
|
||||
@@ -30,6 +30,9 @@ openclaw_live_should_include_auth_dir_for_provider() {
|
||||
local provider
|
||||
provider="$(openclaw_live_trim "${1:-}")"
|
||||
case "$provider" in
|
||||
gemini | gemini-cli | google-gemini-cli)
|
||||
printf '%s\n' ".gemini"
|
||||
;;
|
||||
minimax | minimax-portal)
|
||||
printf '%s\n' ".minimax"
|
||||
;;
|
||||
@@ -50,9 +53,6 @@ openclaw_live_should_include_auth_file_for_provider() {
|
||||
printf '%s\n' ".claude/settings.json"
|
||||
printf '%s\n' ".claude/settings.local.json"
|
||||
;;
|
||||
gemini | gemini-cli | google-gemini-cli)
|
||||
printf '%s\n' ".gemini/settings.json"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ let createEmptyPluginRegistry: typeof import("../plugins/registry.js").createEmp
|
||||
let setActivePluginRegistry: typeof import("../plugins/runtime.js").setActivePluginRegistry;
|
||||
let normalizeClaudeBackendConfig: typeof import("./cli-backends.js").normalizeClaudeBackendConfig;
|
||||
let resolveCliBackendConfig: typeof import("./cli-backends.js").resolveCliBackendConfig;
|
||||
let resolveCliBackendLiveTest: typeof import("./cli-backends.js").resolveCliBackendLiveTest;
|
||||
|
||||
function createBackendEntry(params: {
|
||||
pluginId: string;
|
||||
@@ -22,6 +23,35 @@ function createBackendEntry(params: {
|
||||
config: params.config,
|
||||
...(params.bundleMcp ? { bundleMcp: params.bundleMcp } : {}),
|
||||
...(params.normalizeConfig ? { normalizeConfig: params.normalizeConfig } : {}),
|
||||
liveTest: {
|
||||
defaultModelRef:
|
||||
params.id === "claude-cli"
|
||||
? "claude-cli/claude-sonnet-4-6"
|
||||
: params.id === "codex-cli"
|
||||
? "codex-cli/gpt-5.4"
|
||||
: params.id === "google-gemini-cli"
|
||||
? "google-gemini-cli/gemini-3.1-pro-preview"
|
||||
: undefined,
|
||||
defaultImageProbe: true,
|
||||
docker: {
|
||||
npmPackage:
|
||||
params.id === "claude-cli"
|
||||
? "@anthropic-ai/claude-code"
|
||||
: params.id === "codex-cli"
|
||||
? "@openai/codex"
|
||||
: params.id === "google-gemini-cli"
|
||||
? "@google/gemini-cli"
|
||||
: undefined,
|
||||
binaryName:
|
||||
params.id === "claude-cli"
|
||||
? "claude"
|
||||
: params.id === "codex-cli"
|
||||
? "codex"
|
||||
: params.id === "google-gemini-cli"
|
||||
? "gemini"
|
||||
: undefined,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -32,7 +62,8 @@ beforeEach(async () => {
|
||||
vi.resetModules();
|
||||
({ createEmptyPluginRegistry } = await import("../plugins/registry.js"));
|
||||
({ setActivePluginRegistry } = await import("../plugins/runtime.js"));
|
||||
({ normalizeClaudeBackendConfig, resolveCliBackendConfig } = await import("./cli-backends.js"));
|
||||
({ normalizeClaudeBackendConfig, resolveCliBackendConfig, resolveCliBackendLiveTest } =
|
||||
await import("./cli-backends.js"));
|
||||
const registry = createEmptyPluginRegistry();
|
||||
registry.cliBackends = [
|
||||
createBackendEntry({
|
||||
@@ -103,16 +134,7 @@ beforeEach(async () => {
|
||||
"workspace-write",
|
||||
"--skip-git-repo-check",
|
||||
],
|
||||
resumeArgs: [
|
||||
"exec",
|
||||
"resume",
|
||||
"{sessionId}",
|
||||
"--color",
|
||||
"never",
|
||||
"--sandbox",
|
||||
"workspace-write",
|
||||
"--skip-git-repo-check",
|
||||
],
|
||||
resumeArgs: ["exec", "resume", "{sessionId}", "--dangerously-bypass-approvals-and-sandbox"],
|
||||
reliability: {
|
||||
watchdog: {
|
||||
fresh: {
|
||||
@@ -135,8 +157,8 @@ beforeEach(async () => {
|
||||
bundleMcp: false,
|
||||
config: {
|
||||
command: "gemini",
|
||||
args: ["--prompt", "--output-format", "json"],
|
||||
resumeArgs: ["--resume", "{sessionId}", "--prompt", "--output-format", "json"],
|
||||
args: ["--output-format", "json", "--prompt", "{prompt}"],
|
||||
resumeArgs: ["--resume", "{sessionId}", "--output-format", "json", "--prompt", "{prompt}"],
|
||||
modelArg: "--model",
|
||||
sessionMode: "existing",
|
||||
sessionIdFields: ["session_id", "sessionId"],
|
||||
@@ -165,11 +187,7 @@ describe("resolveCliBackendConfig reliability merge", () => {
|
||||
"exec",
|
||||
"resume",
|
||||
"{sessionId}",
|
||||
"--color",
|
||||
"never",
|
||||
"--sandbox",
|
||||
"workspace-write",
|
||||
"--skip-git-repo-check",
|
||||
"--dangerously-bypass-approvals-and-sandbox",
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -205,6 +223,26 @@ describe("resolveCliBackendConfig reliability merge", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveCliBackendLiveTest", () => {
|
||||
it("returns plugin-owned live smoke metadata for codex", () => {
|
||||
expect(resolveCliBackendLiveTest("codex-cli")).toEqual({
|
||||
defaultModelRef: "codex-cli/gpt-5.4",
|
||||
defaultImageProbe: true,
|
||||
dockerNpmPackage: "@openai/codex",
|
||||
dockerBinaryName: "codex",
|
||||
});
|
||||
});
|
||||
|
||||
it("returns plugin-owned live smoke metadata for gemini", () => {
|
||||
expect(resolveCliBackendLiveTest("google-gemini-cli")).toEqual({
|
||||
defaultModelRef: "google-gemini-cli/gemini-3.1-pro-preview",
|
||||
defaultImageProbe: true,
|
||||
dockerNpmPackage: "@google/gemini-cli",
|
||||
dockerBinaryName: "gemini",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveCliBackendConfig claude-cli defaults", () => {
|
||||
it("uses non-interactive permission-mode defaults for fresh and resume args", () => {
|
||||
const resolved = resolveCliBackendConfig("claude-cli");
|
||||
@@ -585,13 +623,14 @@ describe("resolveCliBackendConfig google-gemini-cli defaults", () => {
|
||||
|
||||
expect(resolved).not.toBeNull();
|
||||
expect(resolved?.bundleMcp).toBe(false);
|
||||
expect(resolved?.config.args).toEqual(["--prompt", "--output-format", "json"]);
|
||||
expect(resolved?.config.args).toEqual(["--output-format", "json", "--prompt", "{prompt}"]);
|
||||
expect(resolved?.config.resumeArgs).toEqual([
|
||||
"--resume",
|
||||
"{sessionId}",
|
||||
"--prompt",
|
||||
"--output-format",
|
||||
"json",
|
||||
"--prompt",
|
||||
"{prompt}",
|
||||
]);
|
||||
expect(resolved?.config.modelArg).toBe("--model");
|
||||
expect(resolved?.config.sessionMode).toBe("existing");
|
||||
|
||||
@@ -142,6 +142,28 @@ describe("buildCliArgs", () => {
|
||||
}),
|
||||
).toEqual(["-p", "--append-system-prompt", "Stable prefix\nDynamic suffix"]);
|
||||
});
|
||||
|
||||
it("replaces prompt placeholders before falling back to a trailing positional prompt", () => {
|
||||
expect(
|
||||
buildCliArgs({
|
||||
backend: {
|
||||
command: "gemini",
|
||||
modelArg: "--model",
|
||||
},
|
||||
baseArgs: ["--output-format", "json", "--prompt", "{prompt}"],
|
||||
modelId: "gemini-3.1-pro-preview",
|
||||
promptArg: "describe the image",
|
||||
useResume: false,
|
||||
}),
|
||||
).toEqual([
|
||||
"--output-format",
|
||||
"json",
|
||||
"--prompt",
|
||||
"describe the image",
|
||||
"--model",
|
||||
"gemini-3.1-pro-preview",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("writeCliImages", () => {
|
||||
|
||||
@@ -250,8 +250,8 @@ function buildGoogleGeminiCliBackendFixture(): CliBackendPlugin {
|
||||
id: "google-gemini-cli",
|
||||
config: {
|
||||
command: "gemini",
|
||||
args: ["--prompt", "--output-format", "json"],
|
||||
resumeArgs: ["--resume", "{sessionId}", "--prompt", "--output-format", "json"],
|
||||
args: ["--output-format", "json", "--prompt", "{prompt}"],
|
||||
resumeArgs: ["--resume", "{sessionId}", "--output-format", "json", "--prompt", "{prompt}"],
|
||||
output: "json",
|
||||
input: "arg",
|
||||
modelArg: "--model",
|
||||
|
||||
@@ -333,6 +333,16 @@ export function buildCliArgs(params: {
|
||||
}
|
||||
}
|
||||
if (params.promptArg !== undefined) {
|
||||
let replacedPromptPlaceholder = false;
|
||||
for (let i = 0; i < args.length; i += 1) {
|
||||
if (args[i] === "{prompt}") {
|
||||
args[i] = params.promptArg;
|
||||
replacedPromptPlaceholder = true;
|
||||
}
|
||||
}
|
||||
if (replacedPromptPlaceholder) {
|
||||
return args;
|
||||
}
|
||||
args.push(params.promptArg);
|
||||
}
|
||||
return args;
|
||||
|
||||
@@ -7,7 +7,7 @@ import JSON5 from "json5";
|
||||
|
||||
type RestoreEntry = { key: string; value: string | undefined };
|
||||
|
||||
const LIVE_EXTERNAL_AUTH_DIRS = [".claude", ".codex", ".minimax"] as const;
|
||||
const LIVE_EXTERNAL_AUTH_DIRS = [".claude", ".codex", ".gemini", ".minimax"] as const;
|
||||
const LIVE_EXTERNAL_AUTH_FILES = [".claude.json"] as const;
|
||||
const requireFromHere = createRequire(import.meta.url);
|
||||
|
||||
@@ -366,6 +366,7 @@ function stageLiveTestState(params: {
|
||||
}
|
||||
const tempStateDir = path.join(params.tempHome, ".openclaw");
|
||||
fs.mkdirSync(tempStateDir, { recursive: true });
|
||||
fs.mkdirSync(path.join(params.tempHome, ".gemini"), { recursive: true });
|
||||
|
||||
const realConfigPath = params.env.OPENCLAW_CONFIG_PATH?.trim()
|
||||
? resolveHomeRelativePath(params.env.OPENCLAW_CONFIG_PATH, params.realHome)
|
||||
|
||||
Reference in New Issue
Block a user