Skip to content

Commit 3ca6e89

Browse files
authored
feat: support google_genai provider type (#323)
Signed-off-by: Richard Chien <[email protected]>
1 parent 2cd286c commit 3ca6e89

File tree

6 files changed

+235
-90
lines changed

6 files changed

+235
-90
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ Internal builds may append content to the Unreleased section.
99
Only write entries that are worth mentioning to users.
1010
-->
1111

12+
## [Unreleased]
13+
14+
- LLM: Add support for Google GenAI provider
15+
1216
## [0.55] - 2025-11-18
1317

1418
- Lib: Add `kimi_cli.app.enable_logging` function to enable logging when directly using `KimiCLI` class

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ dependencies = [
99
"aiofiles==25.1.0",
1010
"aiohttp==3.13.2",
1111
"typer==0.20.0",
12-
"kosong==0.25.1",
12+
"kosong==0.26.1",
1313
"loguru==0.7.3",
1414
"patch-ng==1.19.0",
1515
"prompt-toolkit==3.0.52",

src/kimi_cli/llm.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,14 @@
1212
if TYPE_CHECKING:
1313
from kimi_cli.config import LLMModel, LLMProvider
1414

15-
type ProviderType = Literal["kimi", "openai_legacy", "openai_responses", "anthropic", "_chaos"]
15+
type ProviderType = Literal[
16+
"kimi",
17+
"openai_legacy",
18+
"openai_responses",
19+
"anthropic",
20+
"google_genai",
21+
"_chaos",
22+
]
1623

1724
type ModelCapability = Literal["image_in", "thinking"]
1825
ALL_MODEL_CAPABILITIES: set[ModelCapability] = set(get_args(ModelCapability))
@@ -116,6 +123,14 @@ def create_llm(
116123
api_key=provider.api_key.get_secret_value(),
117124
default_max_tokens=50000,
118125
)
126+
case "google_genai":
127+
from kosong.contrib.chat_provider.google_genai import GoogleGenAI
128+
129+
chat_provider = GoogleGenAI(
130+
model=model.model,
131+
base_url=provider.base_url,
132+
api_key=provider.api_key.get_secret_value(),
133+
)
119134
case "_chaos":
120135
from kosong.chat_provider.chaos import ChaosChatProvider, ChaosConfig
121136

tests/test_default_agent.py

Lines changed: 57 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -165,28 +165,25 @@ async def test_default_agent(runtime: Runtime):
165165
However, do not get stuck in a rut. Be flexible. Sometimes, you may try to use todo list at first, then realize the task is too simple and you can simply stop using it; or, sometimes, you may realize the task is complex after a few steps and then you can start using todo list to break it down.
166166
""",
167167
parameters={
168-
"$defs": {
169-
"Todo": {
170-
"properties": {
171-
"title": {
172-
"description": "The title of the todo",
173-
"minLength": 1,
174-
"type": "string",
175-
},
176-
"status": {
177-
"description": "The status of the todo",
178-
"enum": ["Pending", "In Progress", "Done"],
179-
"type": "string",
180-
},
181-
},
182-
"required": ["title", "status"],
183-
"type": "object",
184-
}
185-
},
186168
"properties": {
187169
"todos": {
188170
"description": "The updated todo list",
189-
"items": {"$ref": "#/$defs/Todo"},
171+
"items": {
172+
"properties": {
173+
"title": {
174+
"description": "The title of the todo",
175+
"minLength": 1,
176+
"type": "string",
177+
},
178+
"status": {
179+
"description": "The status of the todo",
180+
"enum": ["Pending", "In Progress", "Done"],
181+
"type": "string",
182+
},
183+
},
184+
"required": ["title", "status"],
185+
"type": "object",
186+
},
190187
"type": "array",
191188
}
192189
},
@@ -447,36 +444,54 @@ async def test_default_agent(runtime: Runtime):
447444
- You should prefer this tool over WriteFile tool and Bash `sed` command.
448445
""",
449446
parameters={
450-
"$defs": {
451-
"Edit": {
452-
"properties": {
453-
"old": {
454-
"description": "The old string to replace. Can be multi-line.",
455-
"type": "string",
456-
},
457-
"new": {
458-
"description": "The new string to replace with. Can be multi-line.",
459-
"type": "string",
460-
},
461-
"replace_all": {
462-
"default": False,
463-
"description": "Whether to replace all occurrences.",
464-
"type": "boolean",
465-
},
466-
},
467-
"required": ["old", "new"],
468-
"type": "object",
469-
}
470-
},
471447
"properties": {
472448
"path": {
473449
"description": "The absolute path to the file to edit.",
474450
"type": "string",
475451
},
476452
"edit": {
477453
"anyOf": [
478-
{"$ref": "#/$defs/Edit"},
479-
{"items": {"$ref": "#/$defs/Edit"}, "type": "array"},
454+
{
455+
"properties": {
456+
"old": {
457+
"description": "The old string to replace. Can be multi-line.",
458+
"type": "string",
459+
},
460+
"new": {
461+
"description": "The new string to replace with. Can be multi-line.",
462+
"type": "string",
463+
},
464+
"replace_all": {
465+
"default": False,
466+
"description": "Whether to replace all occurrences.",
467+
"type": "boolean",
468+
},
469+
},
470+
"required": ["old", "new"],
471+
"type": "object",
472+
},
473+
{
474+
"items": {
475+
"properties": {
476+
"old": {
477+
"description": "The old string to replace. Can be multi-line.",
478+
"type": "string",
479+
},
480+
"new": {
481+
"description": "The new string to replace with. Can be multi-line.",
482+
"type": "string",
483+
},
484+
"replace_all": {
485+
"default": False,
486+
"description": "Whether to replace all occurrences.",
487+
"type": "boolean",
488+
},
489+
},
490+
"required": ["old", "new"],
491+
"type": "object",
492+
},
493+
"type": "array",
494+
},
480495
],
481496
"description": "The edit(s) to apply to the file. You can provide a single edit or a list of edits here.",
482497
},

tests/test_tool_schemas.py

Lines changed: 57 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -81,28 +81,25 @@ def test_set_todo_list_params_schema(set_todo_list_tool: SetTodoList):
8181
"""Test the schema of SetTodoList tool parameters."""
8282
assert set_todo_list_tool.base.parameters == snapshot(
8383
{
84-
"$defs": {
85-
"Todo": {
86-
"properties": {
87-
"title": {
88-
"description": "The title of the todo",
89-
"minLength": 1,
90-
"type": "string",
91-
},
92-
"status": {
93-
"description": "The status of the todo",
94-
"enum": ["Pending", "In Progress", "Done"],
95-
"type": "string",
96-
},
97-
},
98-
"required": ["title", "status"],
99-
"type": "object",
100-
}
101-
},
10284
"properties": {
10385
"todos": {
10486
"description": "The updated todo list",
105-
"items": {"$ref": "#/$defs/Todo"},
87+
"items": {
88+
"properties": {
89+
"title": {
90+
"description": "The title of the todo",
91+
"minLength": 1,
92+
"type": "string",
93+
},
94+
"status": {
95+
"description": "The status of the todo",
96+
"enum": ["Pending", "In Progress", "Done"],
97+
"type": "string",
98+
},
99+
},
100+
"required": ["title", "status"],
101+
"type": "object",
102+
},
106103
"type": "array",
107104
}
108105
},
@@ -290,36 +287,54 @@ def test_str_replace_file_params_schema(str_replace_file_tool: StrReplaceFile):
290287
"""Test the schema of StrReplaceFile tool parameters."""
291288
assert str_replace_file_tool.base.parameters == snapshot(
292289
{
293-
"$defs": {
294-
"Edit": {
295-
"properties": {
296-
"old": {
297-
"description": "The old string to replace. Can be multi-line.",
298-
"type": "string",
299-
},
300-
"new": {
301-
"description": "The new string to replace with. Can be multi-line.",
302-
"type": "string",
303-
},
304-
"replace_all": {
305-
"default": False,
306-
"description": "Whether to replace all occurrences.",
307-
"type": "boolean",
308-
},
309-
},
310-
"required": ["old", "new"],
311-
"type": "object",
312-
}
313-
},
314290
"properties": {
315291
"path": {
316292
"description": "The absolute path to the file to edit.",
317293
"type": "string",
318294
},
319295
"edit": {
320296
"anyOf": [
321-
{"$ref": "#/$defs/Edit"},
322-
{"items": {"$ref": "#/$defs/Edit"}, "type": "array"},
297+
{
298+
"properties": {
299+
"old": {
300+
"description": "The old string to replace. Can be multi-line.",
301+
"type": "string",
302+
},
303+
"new": {
304+
"description": "The new string to replace with. Can be multi-line.",
305+
"type": "string",
306+
},
307+
"replace_all": {
308+
"default": False,
309+
"description": "Whether to replace all occurrences.",
310+
"type": "boolean",
311+
},
312+
},
313+
"required": ["old", "new"],
314+
"type": "object",
315+
},
316+
{
317+
"items": {
318+
"properties": {
319+
"old": {
320+
"description": "The old string to replace. Can be multi-line.",
321+
"type": "string",
322+
},
323+
"new": {
324+
"description": "The new string to replace with. Can be multi-line.",
325+
"type": "string",
326+
},
327+
"replace_all": {
328+
"default": False,
329+
"description": "Whether to replace all occurrences.",
330+
"type": "boolean",
331+
},
332+
},
333+
"required": ["old", "new"],
334+
"type": "object",
335+
},
336+
"type": "array",
337+
},
323338
],
324339
"description": "The edit(s) to apply to the file. You can provide a single edit or a list of edits here.",
325340
},

0 commit comments

Comments
 (0)