Skip to content

Commit a6abe1b

Browse files
Merge branch 'main' into phorcys420/docker-build-disclaimer
2 parents a882b16 + d9b223a commit a6abe1b

File tree

11 files changed

+343
-118
lines changed

11 files changed

+343
-118
lines changed
Lines changed: 100 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,41 @@
11
---
22
display_name: Gemini CLI
3+
description: Run Gemini CLI in your workspace for AI pair programming
34
icon: ../../../../.icons/gemini.svg
4-
description: Run Gemini CLI in your workspace with AgentAPI integration
55
verified: true
66
tags: [agent, gemini, ai, google, tasks]
77
---
88

99
# Gemini CLI
1010

11-
Run [Gemini CLI](https://ai.google.dev/gemini-api/docs/cli) in your workspace to access Google's Gemini AI models, and custom pre/post install scripts. This module integrates with [AgentAPI](https://github.com/coder/agentapi) for Coder Tasks compatibility.
11+
Run [Gemini CLI](https://github.com/google-gemini/gemini-cli) in your workspace to access Google's Gemini AI models for interactive coding assistance and automated task execution.
1212

1313
```tf
1414
module "gemini" {
15-
source = "registry.coder.com/coder-labs/gemini/coder"
16-
version = "1.0.1"
17-
agent_id = coder_agent.example.id
18-
gemini_api_key = var.gemini_api_key
19-
gemini_model = "gemini-2.5-pro"
20-
install_gemini = true
21-
gemini_version = "latest"
22-
agentapi_version = "latest"
15+
source = "registry.coder.com/coder-labs/gemini/coder"
16+
version = "1.1.0"
17+
agent_id = coder_agent.example.id
18+
folder = "/home/coder/project"
2319
}
2420
```
2521

22+
## Features
23+
24+
- **Interactive AI Assistance**: Run Gemini CLI directly in your terminal for coding help
25+
- **Automated Task Execution**: Execute coding tasks automatically via AgentAPI integration
26+
- **Multiple AI Models**: Support for Gemini 2.5 Pro, Flash, and other Google AI models
27+
- **API Key Integration**: Seamless authentication with Gemini API
28+
- **MCP Server Integration**: Built-in Coder MCP server for task reporting
29+
- **Persistent Sessions**: Maintain context across workspace sessions
30+
2631
## Prerequisites
2732

28-
- You must add the [Coder Login](https://registry.coder.com/modules/coder-login/coder) module to your template
2933
- Node.js and npm will be installed automatically if not present
34+
- The [Coder Login](https://registry.coder.com/modules/coder/coder-login) module is required
3035

31-
## Usage Example
36+
## Examples
3237

33-
- Example 1:
38+
### Basic setup
3439

3540
```tf
3641
variable "gemini_api_key" {
@@ -40,39 +45,97 @@ variable "gemini_api_key" {
4045
}
4146
4247
module "gemini" {
43-
count = data.coder_workspace.me.start_count
44-
source = "registry.coder.com/coder-labs/gemini/coder"
45-
version = "1.0.1"
46-
agent_id = coder_agent.example.id
47-
gemini_api_key = var.gemini_api_key # we recommend providing this parameter inorder to have a smoother experience (i.e. no google sign-in)
48-
gemini_model = "gemini-2.5-flash"
49-
install_gemini = true
50-
gemini_version = "latest"
51-
gemini_instruction_prompt = "Start every response with `Gemini says:`"
48+
source = "registry.coder.com/coder-labs/gemini/coder"
49+
version = "1.1.0"
50+
agent_id = coder_agent.example.id
51+
gemini_api_key = var.gemini_api_key
52+
folder = "/home/coder/project"
5253
}
5354
```
5455

55-
## How it Works
56+
This basic setup will:
57+
58+
- Install Gemini CLI in the workspace
59+
- Configure authentication with your API key
60+
- Set Gemini to run in `/home/coder/project` directory
61+
- Enable interactive use from the terminal
62+
- Set up MCP server integration for task reporting
63+
64+
### Automated task execution (Experimental)
65+
66+
> This functionality is in early access and is still evolving.
67+
> For now, we recommend testing it in a demo or staging environment,
68+
> rather than deploying to production
69+
>
70+
> Learn more in [the Coder documentation](https://coder.com/docs/ai-coder)
71+
72+
```tf
73+
variable "gemini_api_key" {
74+
type = string
75+
description = "Gemini API key"
76+
sensitive = true
77+
}
78+
79+
module "coder-login" {
80+
count = data.coder_workspace.me.start_count
81+
source = "registry.coder.com/coder/coder-login/coder"
82+
version = "~> 1.0"
83+
agent_id = coder_agent.example.id
84+
}
5685
57-
- **Install**: The module installs Gemini CLI using npm (installs Node.js via NVM if needed)
58-
- **Instruction Prompt**: If `GEMINI_INSTRUCTION_PROMPT` and `GEMINI_START_DIRECTORY` are set, creates the directory (if needed) and writes the prompt to `GEMINI.md`
59-
- **Start**: Launches Gemini CLI in the specified directory, wrapped by AgentAPI
60-
- **Environment**: Sets `GEMINI_API_KEY`, `GOOGLE_GENAI_USE_VERTEXAI`, `GEMINI_MODEL` for the CLI (if variables provided)
86+
data "coder_parameter" "ai_prompt" {
87+
type = "string"
88+
name = "AI Prompt"
89+
default = ""
90+
description = "Task prompt for automated Gemini execution"
91+
mutable = true
92+
}
93+
94+
module "gemini" {
95+
count = data.coder_workspace.me.start_count
96+
source = "registry.coder.com/coder-labs/gemini/coder"
97+
version = "1.1.0"
98+
agent_id = coder_agent.example.id
99+
gemini_api_key = var.gemini_api_key
100+
gemini_model = "gemini-2.5-flash"
101+
folder = "/home/coder/project"
102+
task_prompt = data.coder_parameter.ai_prompt.value
103+
enable_yolo_mode = true # Auto-approve all tool calls for automation
104+
gemini_system_prompt = <<-EOT
105+
You are a helpful coding assistant. Always explain your code changes clearly.
106+
YOU MUST REPORT ALL TASKS TO CODER.
107+
EOT
108+
}
109+
```
110+
111+
> [!WARNING]
112+
> YOLO mode automatically approves all tool calls without user confirmation. The agent has access to your machine's file system and terminal. Only enable in trusted, isolated environments.
113+
114+
### Using Vertex AI (Enterprise)
115+
116+
For enterprise users who prefer Google's Vertex AI platform:
117+
118+
```tf
119+
module "gemini" {
120+
source = "registry.coder.com/coder-labs/gemini/coder"
121+
version = "1.1.0"
122+
agent_id = coder_agent.example.id
123+
gemini_api_key = var.gemini_api_key
124+
folder = "/home/coder/project"
125+
use_vertexai = true
126+
}
127+
```
61128

62129
## Troubleshooting
63130

64-
- If Gemini CLI is not found, ensure `install_gemini = true` and your API key is valid
65-
- Node.js and npm are installed automatically if missing (using NVM)
66-
- Check logs in `/home/coder/.gemini-module/` for install/start output
67-
- We highly recommend using the `gemini_api_key` variable, this also ensures smooth tasks running without needing to sign in to Google.
131+
- If Gemini CLI is not found, ensure your API key is valid (`install_gemini` defaults to `true`)
132+
- Check logs in `~/.gemini-module/` for install/start output
133+
- Use the `gemini_api_key` variable to avoid requiring Google sign-in
68134

69-
> [!IMPORTANT]
70-
> To use tasks with Gemini CLI, ensure you have the `gemini_api_key` variable set, and **you pass the `AI Prompt` Parameter**.
71-
> By default we inject the "theme": "Default" and "selectedAuthType": "gemini-api-key" to your ~/.gemini/settings.json along with the coder mcp server.
72-
> In `gemini_instruction_prompt` and `AI Prompt` text we recommend using (\`\`) backticks instead of quotes to avoid escaping issues. Eg: gemini_instruction_prompt = "Start every response with \`Gemini says:\` "
135+
The module creates log files in the workspace's `~/.gemini-module` directory for debugging purposes.
73136

74137
## References
75138

76-
- [Gemini CLI Documentation](https://ai.google.dev/gemini-api/docs/cli)
139+
- [Gemini CLI Documentation](https://github.com/google-gemini/gemini-cli/blob/main/docs/index.md)
77140
- [AgentAPI Documentation](https://github.com/coder/agentapi)
78-
- [Coder AI Agents Guide](https://coder.com/docs/tutorials/ai-agents)
141+
- [Coder AI Agents Guide](https://coder.com/docs/ai-coder)

registry/coder-labs/modules/gemini/main.test.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
} from "bun:test";
99
import { execContainer, readFileContainer, runTerraformInit } from "~test";
1010
import {
11-
loadTestFile,
1211
writeExecutable,
1312
setup as setupUtil,
1413
execModuleScript,
@@ -54,10 +53,24 @@ const setup = async (props?: SetupProps): Promise<{ id: string }> => {
5453
agentapiMockScript: props?.agentapiMockScript,
5554
});
5655
if (!props?.skipGeminiMock) {
56+
const geminiMockContent = `#!/bin/bash
57+
58+
if [[ "$1" == "--version" ]]; then
59+
echo "HELLO: $(bash -c env)"
60+
echo "gemini version v2.5.0"
61+
exit 0
62+
fi
63+
64+
set -e
65+
66+
while true; do
67+
echo "$(date) - gemini-mock"
68+
sleep 15
69+
done`;
5770
await writeExecutable({
5871
containerId: id,
5972
filePath: "/usr/bin/gemini",
60-
content: await loadTestFile(import.meta.dir, "gemini-mock.sh"),
73+
content: geminiMockContent,
6174
});
6275
}
6376
return { id };
@@ -70,7 +83,7 @@ describe("gemini", async () => {
7083
await runTerraformInit(import.meta.dir);
7184
});
7285

73-
test("happy-path", async () => {
86+
test("agent-api", async () => {
7487
const { id } = await setup();
7588
await execModuleScript(id);
7689
await expectAgentAPIStarted(id);
@@ -117,7 +130,7 @@ describe("gemini", async () => {
117130
await execModuleScript(id);
118131

119132
const resp = await readFileContainer(id, "/home/coder/.gemini-module/agentapi-start.log");
120-
expect(resp).toContain("gemini_api_key provided !");
133+
expect(resp).toContain("Using direct Gemini API with API key");
121134
});
122135

123136
test("use-vertexai", async () => {
@@ -197,6 +210,20 @@ describe("gemini", async () => {
197210
expect(resp).toContain(prompt);
198211
});
199212

213+
test("task-prompt", async () => {
214+
const taskPrompt = "Create a simple Hello World function";
215+
const { id } = await setup({
216+
moduleVariables: {
217+
task_prompt: taskPrompt,
218+
},
219+
});
220+
await execModuleScript(id, {
221+
GEMINI_TASK_PROMPT: taskPrompt,
222+
});
223+
const resp = await readFileContainer(id, "/home/coder/.gemini-module/agentapi-start.log");
224+
expect(resp).toContain("Running automated task:");
225+
});
226+
200227
test("start-without-prompt", async () => {
201228
const { id } = await setup();
202229
await execModuleScript(id);

registry/coder-labs/modules/gemini/main.tf

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,14 @@ variable "use_vertexai" {
7474

7575
variable "install_agentapi" {
7676
type = bool
77-
description = "Whether to install AgentAPI."
77+
description = "Whether to install AgentAPI for web UI and task automation."
7878
default = true
7979
}
8080

8181
variable "agentapi_version" {
8282
type = string
8383
description = "The version of AgentAPI to install."
84-
default = "v0.3.0"
84+
default = "v0.2.3"
8585
}
8686

8787
variable "gemini_model" {
@@ -102,12 +102,10 @@ variable "post_install_script" {
102102
default = null
103103
}
104104

105-
data "coder_parameter" "ai_prompt" {
106-
type = "string"
107-
name = "AI Prompt"
105+
variable "task_prompt" {
106+
type = string
107+
description = "Task prompt for automated Gemini execution"
108108
default = ""
109-
description = "Initial prompt for the Gemini CLI"
110-
mutable = true
111109
}
112110

113111
variable "additional_extensions" {
@@ -122,12 +120,24 @@ variable "gemini_system_prompt" {
122120
default = ""
123121
}
124122

123+
variable "enable_yolo_mode" {
124+
type = bool
125+
description = "Enable YOLO mode to automatically approve all tool calls without user confirmation. Use with caution."
126+
default = false
127+
}
128+
125129
resource "coder_env" "gemini_api_key" {
126130
agent_id = var.agent_id
127131
name = "GEMINI_API_KEY"
128132
value = var.gemini_api_key
129133
}
130134

135+
resource "coder_env" "google_api_key" {
136+
agent_id = var.agent_id
137+
name = "GOOGLE_API_KEY"
138+
value = var.gemini_api_key
139+
}
140+
131141
resource "coder_env" "gemini_use_vertex_ai" {
132142
agent_id = var.agent_id
133143
name = "GOOGLE_GENAI_USE_VERTEXAI"
@@ -181,22 +191,7 @@ module "agentapi" {
181191
agentapi_version = var.agentapi_version
182192
pre_install_script = var.pre_install_script
183193
post_install_script = var.post_install_script
184-
start_script = <<-EOT
185-
#!/bin/bash
186-
set -o errexit
187-
set -o pipefail
188-
189-
echo -n '${base64encode(local.start_script)}' | base64 -d > /tmp/start.sh
190-
chmod +x /tmp/start.sh
191-
GEMINI_API_KEY='${var.gemini_api_key}' \
192-
GOOGLE_GENAI_USE_VERTEXAI='${var.use_vertexai}' \
193-
GEMINI_MODEL='${var.gemini_model}' \
194-
GEMINI_START_DIRECTORY='${var.folder}' \
195-
GEMINI_TASK_PROMPT='${base64encode(data.coder_parameter.ai_prompt.value)}' \
196-
/tmp/start.sh
197-
EOT
198-
199-
install_script = <<-EOT
194+
install_script = <<-EOT
200195
#!/bin/bash
201196
set -o errexit
202197
set -o pipefail
@@ -209,7 +204,23 @@ module "agentapi" {
209204
BASE_EXTENSIONS='${base64encode(replace(local.base_extensions, "'", "'\\''"))}' \
210205
ADDITIONAL_EXTENSIONS='${base64encode(replace(var.additional_extensions != null ? var.additional_extensions : "", "'", "'\\''"))}' \
211206
GEMINI_START_DIRECTORY='${var.folder}' \
212-
GEMINI_INSTRUCTION_PROMPT='${base64encode(var.gemini_system_prompt)}' \
207+
GEMINI_SYSTEM_PROMPT='${base64encode(var.gemini_system_prompt)}' \
213208
/tmp/install.sh
214209
EOT
210+
start_script = <<-EOT
211+
#!/bin/bash
212+
set -o errexit
213+
set -o pipefail
214+
215+
echo -n '${base64encode(local.start_script)}' | base64 -d > /tmp/start.sh
216+
chmod +x /tmp/start.sh
217+
GEMINI_API_KEY='${var.gemini_api_key}' \
218+
GOOGLE_API_KEY='${var.gemini_api_key}' \
219+
GOOGLE_GENAI_USE_VERTEXAI='${var.use_vertexai}' \
220+
GEMINI_YOLO_MODE='${var.enable_yolo_mode}' \
221+
GEMINI_MODEL='${var.gemini_model}' \
222+
GEMINI_START_DIRECTORY='${var.folder}' \
223+
GEMINI_TASK_PROMPT='${var.task_prompt}' \
224+
/tmp/start.sh
225+
EOT
215226
}

0 commit comments

Comments
 (0)