summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThePrimeagen <the.primeagen@gmail.com>2026-02-18 18:11:04 -0700
committerGitHub <noreply@github.com>2026-02-18 18:11:04 -0700
commitd34e4dcbcc1f95d8f31f851baad18da12c59e7df (patch)
treeb4cf1089fde21a8afffc6b541d5dac6cfd8cda20
parentcb99c2bad78a572b9dfd73500e12fc2b365a25b8 (diff)
parentf98529b6dabfcd3126a031f431d7469fb2d5aaf1 (diff)
downloada4-d34e4dcbcc1f95d8f31f851baad18da12c59e7df.tar.xz
a4-d34e4dcbcc1f95d8f31f851baad18da12c59e7df.zip
Merge pull request #121 from chhsia0/gemini-cli-provider
feat: add Gemini CLI as a provider
-rw-r--r--lua/99/providers.lua33
-rw-r--r--lua/99/test/providers_spec.lua33
2 files changed, 66 insertions, 0 deletions
diff --git a/lua/99/providers.lua b/lua/99/providers.lua
index 1b5c4d9..82f8b6a 100644
--- a/lua/99/providers.lua
+++ b/lua/99/providers.lua
@@ -236,10 +236,43 @@ function KiroProvider._get_default_model()
return "claude-sonnet-4.5"
end
+--- @class GeminiCLIProvider : _99.Providers.BaseProvider
+local GeminiCLIProvider = setmetatable({}, { __index = BaseProvider })
+
+--- @param query string
+--- @param request _99.Request
+--- @return string[]
+function GeminiCLIProvider._build_command(_, query, request)
+ return {
+ "gemini",
+ "--approval-mode",
+ -- Allow writing to temp files by default. See:
+ -- https://geminicli.com/docs/core/policy-engine/#default-policies
+ "auto_edit",
+ "--model",
+ request.context.model,
+ "--prompt",
+ query,
+ }
+end
+
+--- @return string
+function GeminiCLIProvider._get_provider_name()
+ return "GeminiCLIProvider"
+end
+
+--- @return string
+function GeminiCLIProvider._get_default_model()
+ -- Default to auto-routing between pro and flash. See:
+ -- https://geminicli.com/docs/cli/model/
+ return "auto"
+end
+
return {
BaseProvider = BaseProvider,
OpenCodeProvider = OpenCodeProvider,
ClaudeCodeProvider = ClaudeCodeProvider,
CursorAgentProvider = CursorAgentProvider,
KiroProvider = KiroProvider,
+ GeminiCLIProvider = GeminiCLIProvider,
}
diff --git a/lua/99/test/providers_spec.lua b/lua/99/test/providers_spec.lua
index 809080b..9c72d0e 100644
--- a/lua/99/test/providers_spec.lua
+++ b/lua/99/test/providers_spec.lua
@@ -66,6 +66,27 @@ describe("providers", function()
end)
end)
+ describe("GeminiCLIProvider", function()
+ it("builds correct command with model", function()
+ local request = { context = { model = "gemini-2.5-pro" } }
+ local cmd =
+ Providers.GeminiCLIProvider._build_command(nil, "test query", request)
+ eq({
+ "gemini",
+ "--approval-mode",
+ "auto_edit",
+ "--model",
+ "gemini-2.5-pro",
+ "--prompt",
+ "test query",
+ }, cmd)
+ end)
+
+ it("has correct default model", function()
+ eq("auto", Providers.GeminiCLIProvider._get_default_model())
+ end)
+ end)
+
describe("provider integration", function()
it("can be set as provider override", function()
local _99 = require("99")
@@ -108,6 +129,17 @@ describe("providers", function()
end
)
+ it(
+ "uses GeminiCLIProvider default model when provider specified but no model",
+ function()
+ local _99 = require("99")
+
+ _99.setup({ provider = Providers.GeminiCLIProvider })
+ local state = _99.__get_state()
+ eq("auto", state.model)
+ end
+ )
+
it("uses custom model when both provider and model specified", function()
local _99 = require("99")
@@ -125,6 +157,7 @@ describe("providers", function()
eq("function", type(Providers.OpenCodeProvider.make_request))
eq("function", type(Providers.ClaudeCodeProvider.make_request))
eq("function", type(Providers.CursorAgentProvider.make_request))
+ eq("function", type(Providers.GeminiCLIProvider.make_request))
end)
end)
end)