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:
67
scripts/install.sh
Executable file
67
scripts/install.sh
Executable file
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env bash
|
||||
# Plexum-gemini-provider installer.
|
||||
#
|
||||
# Builds + installs the plugin under ~/.plexum/plugins/.
|
||||
# Operator config (~/.plexum/plugins/plexum-gemini-provider/config.json)
|
||||
# is optional — defaults work if `gemini` is on PATH and authenticated.
|
||||
set -euo pipefail
|
||||
|
||||
REPO="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
PROFILE_DIR="${HOME}/.plexum"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--profile) PROFILE_DIR="$2"; shift 2 ;;
|
||||
-h|--help) sed -n '2,/^set -euo/p' "$0" | sed -n '/^#/p' | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||
*) echo "unknown flag: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
log() { printf '\033[1;34m[gemini-install]\033[0m %s\n' "$*"; }
|
||||
command -v go >/dev/null || { echo "go not found on PATH" >&2; exit 1; }
|
||||
command -v gemini >/dev/null || log "WARN: gemini CLI not on PATH yet (operator must install before first turn)"
|
||||
|
||||
PLUGIN_DIR="${PROFILE_DIR}/plugins/plexum-gemini-provider"
|
||||
mkdir -p "${PLUGIN_DIR}"
|
||||
|
||||
cd "${REPO}"
|
||||
VERSION="$(git describe --tags --always 2>/dev/null || echo dev)"
|
||||
LDFLAGS="-X main.Version=${VERSION}"
|
||||
log "building plexum-gemini-provider-plugin (v=${VERSION})"
|
||||
CGO_ENABLED=0 go build -ldflags="${LDFLAGS}" \
|
||||
-o "${PLUGIN_DIR}/plexum-gemini-provider-plugin" \
|
||||
./cmd/plexum-gemini-provider-plugin
|
||||
|
||||
cat > "${PLUGIN_DIR}/manifest.json" <<'EOF'
|
||||
{
|
||||
"name": "plexum-gemini-provider",
|
||||
"version": "0.1.0",
|
||||
"activation": "lazy",
|
||||
"executable": "plexum-gemini-provider-plugin",
|
||||
"contracts": {
|
||||
"provider": {
|
||||
"models": ["gemini", "gemini-pro", "gemini-flash", "gemini-flash-lite"]
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
cat <<EOF
|
||||
|
||||
[gemini-install] done.
|
||||
plugin binary: ${PLUGIN_DIR}/plexum-gemini-provider-plugin
|
||||
manifest: ${PLUGIN_DIR}/manifest.json
|
||||
models: gemini / gemini-pro / gemini-flash / gemini-flash-lite
|
||||
|
||||
Optional config: ${PLUGIN_DIR}/config.json
|
||||
{"binary": "gemini", "extra_args": []}
|
||||
|
||||
No api_key needed here — the gemini CLI handles auth via its own
|
||||
~/.gemini/ state (OAuth or GEMINI_API_KEY).
|
||||
|
||||
Next steps:
|
||||
1. Allow plugin in ${PROFILE_DIR}/plexum.json:
|
||||
.plugins.allow += ["plexum-gemini-provider"]
|
||||
2. plexum agent-add --model gemini-flash <agent-id>
|
||||
3. systemctl --user restart plexum
|
||||
EOF
|
||||
Reference in New Issue
Block a user