> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Gemini CLI Integration

> Integrate Google's Gemini CLI for AI-powered code analysis and generation

# Gemini CLI Integration

PraisonAI provides integration with Google's Gemini CLI for AI-powered code analysis, generation, and refactoring tasks.

## Installation

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Install Gemini CLI
npm install -g @anthropic-ai/gemini-cli

# Verify installation
gemini --version
```

## Quick Start

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.integrations import GeminiCLIIntegration

# Create integration
gemini = GeminiCLIIntegration(
    workspace="/path/to/project",
    model="gemini-2.5-pro"
)

# Execute a coding task
result = await gemini.execute("Analyze this codebase and suggest improvements")
print(result)
```

## Use as Agent Backend

Delegate an Agent's LLM turns to `gemini -p` instead of the Gemini API — uses your Google account.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent

agent = Agent(name="assistant", cli_backend="gemini-cli")
agent.start("Hello")
```

<Note>
  `cli_backend=` is deprecated (removal in 2.0.0). Prefer `runtime="gemini-cli"`. Run `praisonai doctor fix --execute` to auto-migrate YAML.
</Note>

### Backend Configuration

The `gemini-cli` backend ships with this default configuration:

| Option       | Type        | Default                                                 | Description                                |
| ------------ | ----------- | ------------------------------------------------------- | ------------------------------------------ |
| `command`    | `str`       | `"gemini"`                                              | CLI command (must be on PATH)              |
| `args`       | `List[str]` | `["--yolo", "--skip-trust", "--output-format", "text"]` | Default flags passed on every turn         |
| `output`     | `str`       | `"text"`                                                | Output format expected from the CLI        |
| `input`      | `str`       | `"single"`                                              | Prompt is passed as a single `-p` argument |
| `timeout_ms` | `int`       | `300000`                                                | Subprocess timeout (5 minutes)             |

### Backend CLI Flags

The backend builds the `gemini` command with these flags:

| Flag                    | Purpose                                                |
| ----------------------- | ------------------------------------------------------ |
| `--yolo`                | Skip approval prompts                                  |
| `--skip-trust`          | Skip workspace-trust prompt                            |
| `--output-format text`  | Plain-text output                                      |
| `--resume <session_id>` | Resume a prior session (only when `session.is_resume`) |
| `-p <prompt>`           | User turn (system prompt is prepended to the prompt)   |

<Note>
  Gemini has no `--system-prompt` flag, so PraisonAI prepends the system prompt to the user prompt with `\n\n` (`f"{system_prompt}\n\n{prompt}"`).
</Note>

## Configuration Options

| Option                | Type | Default          | Description                                  |
| --------------------- | ---- | ---------------- | -------------------------------------------- |
| `workspace`           | str  | "."              | Working directory for CLI execution          |
| `timeout`             | int  | 300              | Timeout in seconds                           |
| `output_format`       | str  | "json"           | Output format: "json", "text", "stream-json" |
| `model`               | str  | "gemini-2.5-pro" | Gemini model to use                          |
| `include_directories` | list | None             | Additional directories to include in context |
| `sandbox`             | bool | False            | Run in sandbox mode                          |

## Examples

### Basic Execution

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.integrations import GeminiCLIIntegration

gemini = GeminiCLIIntegration(workspace="/project")

result = await gemini.execute("Explain the architecture of this codebase")
print(result)
```

### Model Selection

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Use Gemini 2.5 Flash for faster responses
gemini = GeminiCLIIntegration(
    workspace="/project",
    model="gemini-2.5-flash"
)

result = await gemini.execute("Quick code review")
```

### Multi-Directory Context

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
gemini = GeminiCLIIntegration(
    workspace="/project/src",
    include_directories=["../lib", "../docs", "../tests"]
)

result = await gemini.execute("Analyze the entire project structure")
```

### With Usage Stats

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
gemini = GeminiCLIIntegration(workspace="/project")

# Get result with usage statistics
result, stats = await gemini.execute_with_stats("Analyze main.py")

print(f"Result: {result}")
print(f"Stats: {stats}")
# Stats includes token usage, latency, tool calls, etc.
```

### Streaming Output

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
gemini = GeminiCLIIntegration(workspace="/project")

async for event in gemini.stream("Generate comprehensive documentation"):
    event_type = event.get("type")
    content = event.get("content", "")
    print(f"[{event_type}] {content}")
```

### As Agent Tool

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai import Agent
from praisonai.integrations import GeminiCLIIntegration

gemini = GeminiCLIIntegration(
    workspace="/project",
    model="gemini-2.5-pro"
)

# Create tool
tool = gemini.as_tool()

# Use with agent
agent = Agent(
    name="Code Analyst",
    role="Software Architect",
    goal="Analyze and improve code architecture",
    tools=[tool]
)

result = agent.start("Review the codebase and suggest improvements")
```

### As a native async agent tool

Preferred when the agent runs on `agent.astart(...)` (or any async entrypoint) — the tool is awaited directly on the running loop with no thread hop.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai.integrations import GeminiCLIIntegration

gemini = GeminiCLIIntegration(workspace="/project", model="gemini-2.5-pro")

agent = Agent(
    name="Code Analyst",
    role="Software Architect",
    goal="Analyze and improve code architecture",
    tools=[gemini.as_async_tool()],   # registers as `gemini_atool`
)

await agent.astart("Review the codebase and suggest improvements")
```

`as_async_tool()` was added in PraisonAI PR #4022; `as_tool()` still works and is now also safe to call from inside an async agent runtime.

## Environment Variables

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# API Key (required)
export GEMINI_API_KEY=your-key
# or
export GOOGLE_API_KEY=your-key
```

## CLI Flags Used

The integration uses the following Gemini CLI flags:

| Flag                    | Description                    |
| ----------------------- | ------------------------------ |
| `-p`                    | Print mode (headless)          |
| `-m`                    | Model selection                |
| `--output-format json`  | JSON output for parsing        |
| `--include-directories` | Include additional directories |
| `--sandbox`             | Run in sandbox mode            |

## JSON Output Schema

The JSON output includes:

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "response": "The main AI-generated content",
  "stats": {
    "models": {
      "gemini-2.5-pro": {
        "api": {
          "totalRequests": 2,
          "totalErrors": 0,
          "totalLatencyMs": 5053
        },
        "tokens": {
          "prompt": 24939,
          "candidates": 20,
          "total": 25113,
          "cached": 21263
        }
      }
    },
    "tools": {
      "totalCalls": 1,
      "totalSuccess": 1,
      "totalFail": 0
    },
    "files": {
      "totalLinesAdded": 0,
      "totalLinesRemoved": 0
    }
  }
}
```

## Error Handling

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.integrations import GeminiCLIIntegration

gemini = GeminiCLIIntegration(timeout=120)

try:
    result = await gemini.execute("Complex analysis task")
except TimeoutError:
    print("Task timed out")
except Exception as e:
    print(f"Error: {e}")
```

## Robustness (PR #4111)

* A subprocess `TimeoutError` is now returned as `CliBackendResult(error=...)` instead of escaping as an exception.
* On `CalledProcessError`, the CLI's actual stderr diagnostic is surfaced (previously only the exit status was shown).
* `-m` (model) and cwd are threaded through, so scheduled runs can pin a model and run in a workspace.
* `CliSessionBinding.is_resume` is now set on the second turn of a session, so the resume branch runs instead of re-sending the system prompt every turn.

## Best Practices

1. **Use gemini-2.5-flash** for quick tasks
2. **Use gemini-2.5-pro** for complex analysis
3. **Include relevant directories** for better context
4. **Use execute\_with\_stats()** to monitor usage
5. **Set appropriate timeouts** for large codebases
