feat: Plexum-gemini-provider v0.1 — Google Gemini via local CLI binary
Plexum ProviderPlugin that wraps the local `gemini` CLI binary
(Google Gemini CLI ≥0.37). Same CLI-driven approach as
Plexum-anthropic-provider's contractor mode: each Plexum turn forks
one `gemini -p` subprocess in the agent's workspace dir.
Reference: openclaw/extensions/google/cli-backend.ts.
internal/runner/ (~190 LOC):
- Run() spawns: gemini --skip-trust --output-format json [--model X]
[--resume <sid>] -p <prompt> in agent workspace
- Parses the single JSON blob gemini emits at exit
({"session_id":"...", "response":"...", "stats":{...}})
- session_id persisted at <workspace>/.plexum-gemini-session so the
next turn passes --resume — multi-turn context continuity through
the CLI's own session state
- Emits synthetic message_start + text_delta + message_end events to
match Plexum's streaming agentic-loop contract
- Tolerates the "Ripgrep is not available." stderr preamble (strips
leading non-{ bytes before json.Unmarshal)
cmd/plexum-gemini-provider-plugin/ implements ProviderPluginWithAgent
(receives AgentContext.Workspace from the host).
Models advertised in provider.models:
gemini (no --model flag; CLI default = flash-preview)
gemini-pro → CLI alias "pro" → gemini-3.1-pro-preview
gemini-flash → CLI alias "flash" → gemini-3.1-flash-preview
gemini-flash-lite → CLI alias "flash-lite" → gemini-3.1-flash-lite-preview
Unrecognized model id passes through as --model <id> so operator can
pin a specific gemini-3.x id.
HostConfig (all optional):
binary (default "gemini" — operator should set absolute path
if running under systemd; PATH won't include nvm dirs)
extra_args (appended before -p)
No api_key field — gemini CLI handles auth via ~/.gemini/ state
(OAuth or GEMINI_API_KEY env).
End-to-end verified against local install:
1. CLI embedded turn 1: "Hi, I'm Gemini, your autonomous CLI
agent for software engineering tasks."
2. CLI embedded turn 2: "I said hi as Gemini." (multi-turn ✓ via
--resume)
3. Gateway socket: {"outcome":"text","text":"pong"}
4. Fabric channel e2e: alice → bt2-clean → gem agent → gemini
CLI → outbound REST → seq=19:
"A shrimp's heart is located in its head,
which is quite an unusual biological
arrangement."
Known: when daemon runs under systemd, PATH doesn't include nvm
dirs by default. Operator must set the absolute binary path in
config.json (README notes this).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
91
README.md
Normal file
91
README.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Plexum-gemini-provider
|
||||
|
||||
Plexum ProviderPlugin that wraps the local `gemini` CLI binary
|
||||
(Google Gemini CLI) — same CLI-driven pattern as
|
||||
`Plexum-anthropic-provider`'s contractor mode. Each Plexum turn forks
|
||||
one `gemini -p` subprocess in the agent's workspace.
|
||||
|
||||
Reference: `openclaw/extensions/google/cli-backend.ts`.
|
||||
|
||||
## Status
|
||||
|
||||
**v0.1**: subprocess-per-turn, JSON output parsing, per-workspace
|
||||
session continuity via `--resume`. Models: `gemini` (CLI default),
|
||||
`gemini-pro`, `gemini-flash`, `gemini-flash-lite`.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
cd ~/Plexum-gemini-provider
|
||||
./scripts/install.sh
|
||||
```
|
||||
|
||||
Then:
|
||||
|
||||
1. **Allow** in `~/.plexum/plexum.json`:
|
||||
```json
|
||||
{"plugins": {"allow": ["plexum-gemini-provider"]}}
|
||||
```
|
||||
|
||||
2. **Bind an agent**:
|
||||
```bash
|
||||
plexum agent-add --model gemini-flash my-agent
|
||||
```
|
||||
|
||||
3. **Restart** + talk:
|
||||
```bash
|
||||
systemctl --user restart plexum
|
||||
plexum say --agent-id my-agent --session-id $(plexum new-session --agent-id my-agent) "hello"
|
||||
```
|
||||
|
||||
## Auth
|
||||
|
||||
There is no API key in this plugin's config. The `gemini` CLI handles
|
||||
auth itself via `~/.gemini/` (OAuth or `GEMINI_API_KEY`). Run
|
||||
`gemini auth login` (or set env) once, then this plugin just shells
|
||||
out.
|
||||
|
||||
## How it works
|
||||
|
||||
For each Plexum turn the plugin forks:
|
||||
|
||||
```
|
||||
gemini --skip-trust --output-format json [--model <m>] [--resume <sid>] -p "<last user msg>"
|
||||
```
|
||||
|
||||
with `cwd = <agent workspace>`. The CLI exits with a single JSON blob:
|
||||
|
||||
```json
|
||||
{
|
||||
"session_id": "uuid",
|
||||
"response": "...",
|
||||
"stats": {"models": {...}}
|
||||
}
|
||||
```
|
||||
|
||||
We capture `session_id` into `<workspace>/.plexum-gemini-session` so the
|
||||
next turn passes `--resume` and Gemini sees the full prior context. The
|
||||
`response` text is emitted as one `text_delta` followed by `message_end`.
|
||||
|
||||
## Models
|
||||
|
||||
| Plexum model id | CLI invocation |
|
||||
|---|---|
|
||||
| `gemini` | no `--model` flag (CLI default — currently `gemini-3-flash-preview`) |
|
||||
| `gemini-pro` | `--model pro` (CLI alias → `gemini-3.1-pro-preview`) |
|
||||
| `gemini-flash` | `--model flash` (CLI alias → `gemini-3.1-flash-preview`) |
|
||||
| `gemini-flash-lite` | `--model flash-lite` (CLI alias → `gemini-3.1-flash-lite-preview`) |
|
||||
|
||||
Any other id is passed through as `--model <id>` verbatim so operators
|
||||
can pin a specific Gemini model the local CLI knows about.
|
||||
|
||||
## Config options
|
||||
|
||||
| Field | Default | Notes |
|
||||
|---|---|---|
|
||||
| `binary` | `gemini` | executable name or absolute path |
|
||||
| `extra_args` | `[]` | appended after the standard flags, before `-p` |
|
||||
|
||||
## License
|
||||
|
||||
Same as Plexum.
|
||||
Reference in New Issue
Block a user