From 116b9607cf4535d10b94a40b5f5e75af24f531a3 Mon Sep 17 00:00:00 2001
From: Samrath <102617759+samrathreddy@users.noreply.github.com>
Date: Thu, 13 Aug 2026 00:56:50 +0530
Subject: [PATCH 1/2] docs(integrate): replace manual agent setup with pioneer
integrate CLI flow
Rewrite the following pages around the pioneer integrate CLI flow:
- opencode.mdx
- openclaw.mdx
- hermes.mdx
- claude-code.mdx
- codex.mdx
---
claude-code.mdx | 554 +++---------------------------------------------
codex.mdx | 326 +++-------------------------
hermes.mdx | 199 ++++-------------
openclaw.mdx | 353 ++++--------------------------
opencode.mdx | 88 +++++---
5 files changed, 211 insertions(+), 1309 deletions(-)
diff --git a/claude-code.mdx b/claude-code.mdx
index 3e86433..4204ab3 100644
--- a/claude-code.mdx
+++ b/claude-code.mdx
@@ -1,549 +1,53 @@
---
title: "Claude Code"
-description: "Point Claude Code at Pioneer for multi-model inference with router-backed pioneer/auto routing, model discovery, and full /model picker support inside the CLI."
+description: "Run Claude Code on Pioneer with pioneer integrate claude, a non-invasive launch that points Claude Code at Pioneer for the session."
---
-Pioneer exposes an [Anthropic-compatible API](/api-reference/inference/anthropic-compatible). Claude Code can use it like a custom gateway: set `ANTHROPIC_BASE_URL`, authenticate with your Pioneer API key, and switch models with `/model` or `pioneer/auto`.
+`pioneer integrate claude` launches Claude Code pointed at Pioneer's Anthropic-compatible API, using your existing Pioneer CLI login. It is non-invasive: it configures Pioneer for the launched session only, so your normal `claude` setup and its own login stay untouched.
-## Quick setup
+## Prerequisites
-
-
- Download and [set up Claude Code](https://code.claude.com/docs/en/quickstart).
-
-
- Create `~/.pioneer/env` with these contents:
+- Claude Code installed. See the [Claude Code quickstart](https://code.claude.com/docs/en/quickstart).
+- The Pioneer CLI installed and authenticated. See [CLI installation](/CLI-Installation).
- ```bash
- unset ANTHROPIC_AUTH_TOKEN CLAUDE_CODE_OAUTH_TOKEN
- export ANTHROPIC_API_KEY=""
- export ANTHROPIC_BASE_URL="https://api.pioneer.ai"
- export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1
- export ANTHROPIC_CUSTOM_MODEL_OPTION="pioneer/auto"
- ```
-
-
- ```bash
- mkdir -p ~/.pioneer
- cat > ~/.pioneer/env <<'EOF'
- unset ANTHROPIC_AUTH_TOKEN CLAUDE_CODE_OAUTH_TOKEN
- export ANTHROPIC_API_KEY=""
- export ANTHROPIC_BASE_URL="https://api.pioneer.ai"
- export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1
- export ANTHROPIC_CUSTOM_MODEL_OPTION="pioneer/auto"
- EOF
- chmod 600 ~/.pioneer/env
- RC=~/.zshrc
- [ -n "$BASH_VERSION" ] && RC=~/.bashrc
- grep -qsF '. ~/.pioneer/env' "$RC" || printf '\n# Pioneer inference\n. ~/.pioneer/env\n' >> "$RC"
- . ~/.pioneer/env
- ```
-
-
-
- Sign out of Claude.ai so Claude Code uses your Pioneer key:
+## Integrate
+
+
```bash
- claude auth logout >/dev/null 2>&1 || true
+ npm install -g @fastino-ai/pioneer-cli
+ pioneer auth login
```
-
- If Claude Code previously asked whether to trust this API key and you chose **No**, move the key tail from `customApiKeyResponses.rejected` to `approved` in `~/.claude.json`, or rerun setup from the Pioneer dashboard integration guide (it repairs this automatically).
-
- When you use `pioneer/auto`, Pioneer stamps `pioneer_savings` on each response — the per-1M-token price difference between the model the router picked and a frontier reference model. Claude Code does not surface that by default, so install a **Stop** hook (Claude Code's end-of-turn hook) that multiplies those rate differences by your actual token usage, sums them across the session, and ends each turn with a line like:
-
- ```text
- Pioneer routing saved ~$1.43 this session (vs claude-opus-4-7)
- ```
-
-
- ```bash
- mkdir -p ~/.pioneer/hooks
- cat > ~/.pioneer/hooks/show-pioneer-routed-model.sh <<'PIONEER_ROUTED_MODEL_HOOK'
- #!/usr/bin/env bash
- # Claude Code hook: surface how much pioneer/auto's routing has saved this session.
- #
- # Instead of the raw backend model, this shows cumulative money saved: for each
- # pioneer/auto turn the backend stamps a per-1M-token savings rate diff vs a
- # frontier reference (pioneer_savings) on the response; this hook multiplies it
- # by the per-turn token usage Claude Code records and sums across the session.
- # On a turn where the routed model changed (cold prompt cache), cache-write
- # savings are dropped so the figure stays honest. For a *direct* (non-auto)
- # model it keeps nudging toward pioneer/auto via X-Pioneer-Router-Tip.
- # No-op when not on a Pioneer gateway, when no signal is present, or when
- # cumulative savings are not positive.
-
- set -euo pipefail
-
- INPUT_FILE=$(mktemp)
- trap 'rm -f "$INPUT_FILE"' EXIT
- cat > "$INPUT_FILE"
-
- python3 - "$INPUT_FILE" <<'PY' 2>/dev/null || true
- from __future__ import annotations
-
- import json
- import os
- import re
- import sys
- import time
- from pathlib import Path
-
-
- ANSI_RE = re.compile(r"\x1b\[[0-9;]*m")
- SET_MODEL_RE = re.compile(r"Set model to\s+(.+?)\s+and saved as your default")
- AUTO_ROUTER_ALIASES = {
- "pioneer/auto",
- "anthropic/pioneer-auto",
- "anthropic/pioneer/auto",
- }
- GATEWAY_ALIAS_PREFIX = "anthropic/pioneer/"
- FRONTIER_REFERENCE_MODEL = "claude-opus-4-7"
- DEFAULT_ROUTER_TIP = (
- "Tip: use model=pioneer/auto to let Pioneer route each request automatically; "
- "named models pin that concrete model."
- )
- TOKENS_PER_MILLION = 1_000_000.0
- USAGE_TOKEN_KEYS = (
- "input_tokens",
- "output_tokens",
- "cache_read_input_tokens",
- "cache_creation_input_tokens",
- "cache_read_tokens",
- "cache_write_tokens",
- )
-
-
- def collect_pioneer_signals(
- value: object, routed_models: list[str], router_tips: list[str]
- ) -> None:
- if isinstance(value, dict):
- for key, nested in value.items():
- key_normalized = str(key).lower().replace("_", "-")
- if key_normalized == "pioneer-routed-model":
- if isinstance(nested, str) and nested:
- routed_models.append(nested)
- continue
- if key_normalized == "x-pioneer-router-tip":
- if isinstance(nested, str) and nested:
- router_tips.append(nested)
- continue
- collect_pioneer_signals(nested, routed_models, router_tips)
- elif isinstance(value, list):
- for item in value:
- collect_pioneer_signals(item, routed_models, router_tips)
-
-
- def find_first(value: object, target_key: str) -> object:
- if isinstance(value, dict):
- for key, nested in value.items():
- if str(key).lower().replace("_", "-") == target_key:
- return nested
- for nested in value.values():
- found = find_first(nested, target_key)
- if found is not None:
- return found
- elif isinstance(value, list):
- for item in value:
- found = find_first(item, target_key)
- if found is not None:
- return found
- return None
-
-
- def find_usage(value: object) -> dict | None:
- if isinstance(value, dict):
- if any(key in value for key in USAGE_TOKEN_KEYS):
- return value
- for nested in value.values():
- found = find_usage(nested)
- if found is not None:
- return found
- elif isinstance(value, list):
- for item in value:
- found = find_usage(item)
- if found is not None:
- return found
- return None
-
-
- def normalize_model_id(model: str) -> str:
- model = model.strip()
- lowered = model.lower()
- if lowered in AUTO_ROUTER_ALIASES:
- return "pioneer/auto"
- if lowered.startswith(GATEWAY_ALIAS_PREFIX):
- return model[len(GATEWAY_ALIAS_PREFIX) :].strip().lower()
- return lowered
-
-
- def iter_strings(value: object):
- if isinstance(value, str):
- yield value
- elif isinstance(value, dict):
- for nested in value.values():
- yield from iter_strings(nested)
- elif isinstance(value, list):
- for item in value:
- yield from iter_strings(item)
-
-
- def is_real_user_turn(payload: object) -> bool:
- if not isinstance(payload, dict) or payload.get("isMeta") is True:
- return False
- if payload.get("type") != "user":
- return False
- return "promptSource" in payload
-
-
- def _token_count(usage: dict, *keys: str) -> int:
- for key in keys:
- value = usage.get(key)
- if isinstance(value, bool):
- continue
- if isinstance(value, (int, float)):
- return max(int(value), 0)
- return 0
-
-
- def _turn_savings_usd(usage: dict, diff: dict, *, drop_cache_write: bool) -> float:
- def rate(name: str) -> float:
- value = diff.get(name)
- return float(value) if isinstance(value, (int, float)) else 0.0
-
- input_tokens = _token_count(usage, "input_tokens")
- output_tokens = _token_count(usage, "output_tokens")
- cache_read = _token_count(usage, "cache_read_input_tokens", "cache_read_tokens")
- cache_write = _token_count(
- usage, "cache_creation_input_tokens", "cache_write_tokens"
- )
- total = (
- input_tokens * rate("input")
- + output_tokens * rate("output")
- + cache_read * rate("cache_read")
- )
- if not drop_cache_write:
- total += cache_write * rate("cache_write")
- return total / TOKENS_PER_MILLION
-
-
- def session_savings(records: list[tuple[int, object]]) -> tuple[float, str]:
- """Sum savings across distinct assistant turns, honoring cold-cache switches."""
- total = 0.0
- baseline = ""
- previous_routed: str | None = None
- seen_turns: set = set()
- for line_number, payload in records:
- if not isinstance(payload, dict) or payload.get("type") != "assistant":
- continue
- routed = find_first(payload, "pioneer-routed-model")
- savings = find_first(payload, "pioneer-savings")
- usage = find_usage(payload)
- if not isinstance(savings, dict) or not isinstance(usage, dict):
- if isinstance(routed, str) and routed:
- previous_routed = routed
- continue
- turn_id = payload.get("uuid") or line_number
- if turn_id in seen_turns:
- continue
- seen_turns.add(turn_id)
- diff = savings.get("rate_diff_per_mtok")
- if not isinstance(diff, dict):
- diff = {}
- baseline = savings.get("baseline_model") or baseline
- switched = (
- isinstance(routed, str)
- and bool(routed)
- and previous_routed is not None
- and routed != previous_routed
- )
- turn_total = _turn_savings_usd(usage, diff, drop_cache_write=switched)
- if turn_total > 0:
- total += turn_total
- if isinstance(routed, str) and routed:
- previous_routed = routed
- return total, baseline
-
-
- def format_usd(amount: float) -> str:
- if amount >= 1:
- return f"${amount:.2f}"
- if amount >= 0.01:
- return f"${amount:.3f}"
- return f"${amount:.4f}"
-
-
- def parse_transcript(
- transcript_path: str, attempts: int = 1
- ) -> tuple[str, str, str, float, str]:
- """Return (routed, tip, selected_model, savings_total, savings_baseline)."""
- path = Path(transcript_path)
- for attempt in range(attempts):
- if path.is_file():
- latest_user_line = 0
- latest_selected_model = ""
- records: list[tuple[int, object]] = []
- for line_number, line in enumerate(
- path.read_text(encoding="utf-8").splitlines(),
- start=1,
- ):
- line = line.strip()
- if not line:
- continue
- try:
- payload = json.loads(line)
- except json.JSONDecodeError:
- continue
- records.append((line_number, payload))
- if is_real_user_turn(payload):
- latest_user_line = line_number
- for text in iter_strings(payload):
- clean = ANSI_RE.sub("", text)
- match = SET_MODEL_RE.search(clean)
- if match:
- latest_selected_model = match.group(1).strip()
-
- latest_routed = ""
- latest_tip = ""
- for line_number, payload in records:
- if line_number <= latest_user_line:
- continue
- routed_models: list[str] = []
- router_tips: list[str] = []
- collect_pioneer_signals(payload, routed_models, router_tips)
- if router_tips:
- latest_tip = router_tips[-1]
- if routed_models:
- latest_routed = routed_models[-1]
- elif router_tips:
- latest_routed = ""
-
- savings_total, savings_baseline = session_savings(records)
- if (
- latest_routed
- or latest_tip
- or latest_selected_model
- or savings_total > 0
- ):
- return (
- latest_routed,
- latest_tip,
- latest_selected_model,
- savings_total,
- savings_baseline,
- )
- if attempt + 1 < attempts:
- time.sleep(0.05)
- return "", "", "", 0.0, ""
-
-
- input_path = Path(sys.argv[1])
- payload = json.loads(input_path.read_text(encoding="utf-8"))
- event_name = payload.get("hook_event_name") or "Stop"
-
- if event_name == "Stop" and payload.get("stop_hook_active") is True:
- sys.exit(0)
- if event_name == "MessageDisplay" and int(payload.get("index", -1)) != 0:
- sys.exit(0)
-
- transcript_path = payload.get("transcript_path") or ""
- if not transcript_path:
- sys.exit(0)
-
- routed, router_tip, selected_model, savings_total, savings_baseline = parse_transcript(
- transcript_path,
- attempts=5,
- )
- session = selected_model or os.environ.get("ANTHROPIC_CUSTOM_MODEL_OPTION", "pioneer/auto")
- normalized_session = normalize_model_id(session)
- message = ""
- if normalized_session == "pioneer/auto":
- # Hide the routed model; surface cumulative savings only when positive.
- if savings_total > 0:
- reference = savings_baseline or FRONTIER_REFERENCE_MODEL
- message = (
- f"Pioneer routing saved ~{format_usd(savings_total)} this session "
- f"(vs {reference})"
- )
- elif routed:
- # Direct (pinned) gateway model: nudge toward pioneer/auto without
- # framing the pinned model as a routing decision.
- message = f"Using {routed} — {router_tip or DEFAULT_ROUTER_TIP}"
- elif router_tip:
- message = router_tip
- if not message:
- sys.exit(0)
-
- if event_name == "MessageDisplay":
- delta = payload.get("delta") or ""
- print(
- json.dumps(
- {
- "hookSpecificOutput": {
- "hookEventName": "MessageDisplay",
- "displayContent": f"{message}\n\n{delta}",
- }
- }
- )
- )
- sys.exit(0)
-
- print(
- json.dumps(
- {"systemMessage": message, "suppressOutput": True}
- )
- )
- PY
- PIONEER_ROUTED_MODEL_HOOK
- chmod +x ~/.pioneer/hooks/show-pioneer-routed-model.sh
- python3 <<'PY'
- import json
- from pathlib import Path
-
- hook = Path.home() / ".pioneer" / "hooks" / "show-pioneer-routed-model.sh"
- settings_path = Path.home() / ".claude" / "settings.json"
- command = str(hook)
- settings = json.loads(settings_path.read_text()) if settings_path.exists() else {}
- hooks = settings.setdefault("hooks", {})
-
- # Drop any prior registration of this hook (e.g. an older MessageDisplay one)
- # so the savings summary is surfaced exactly once per turn, at Stop.
- for event_name in list(hooks):
- kept = [
- group
- for group in hooks.get(event_name, [])
- if not any(entry.get("command") == command for entry in group.get("hooks", []))
- ]
- if kept:
- hooks[event_name] = kept
- else:
- hooks.pop(event_name, None)
-
- hooks.setdefault("Stop", []).append(
- {"hooks": [{"type": "command", "command": command, "timeout": 5}]}
- )
- settings_path.parent.mkdir(parents=True, exist_ok=True)
- settings_path.write_text(json.dumps(settings, indent=2) + "\n")
- PY
- ```
-
-
-
- Claude Code reads gateway models from `~/.claude/cache/gateway-models.json`. Seed it once after setup (and again if the catalog changes):
-
-
- ```bash
- python3 <<'PY'
- import json, os, re, time, urllib.request
- base = os.environ.get("ANTHROPIC_BASE_URL", "").rstrip("/")
- key = os.environ.get("ANTHROPIC_API_KEY", "")
- if not base or not key:
- raise SystemExit("ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY must be set")
- url = f"{base}/v1/models?limit=1000"
- req = urllib.request.Request(url, headers={"x-api-key": key, "anthropic-version": "2023-06-01"})
- data = json.load(urllib.request.urlopen(req, timeout=10))
- models = [
- {"id": x["id"], **({"display_name": x["display_name"]} if x.get("display_name") else {})}
- for x in data.get("data", [])
- if re.match(r"^(claude|anthropic)", x["id"], re.I)
- ]
- cache_dir = os.path.expanduser("~/.claude/cache")
- os.makedirs(cache_dir, exist_ok=True)
- path = os.path.join(cache_dir, "gateway-models.json")
- with open(path, "w") as f:
- json.dump({"baseUrl": base, "fetchedAt": int(time.time() * 1000), "models": models}, f)
- os.chmod(path, 0o600)
- print(f"Seeded {len(models)} models for /model")
- PY
- ```
-
-
-
+
```bash
- claude --model pioneer/auto
+ pioneer integrate claude
```
-
- Use `/model` inside Claude Code to pick a specific Pioneer model, or keep `pioneer/auto` to use the [Code Router](/concepts/router).
+
+
+ Choose a model in the interactive picker, or skip it with `--model pioneer/auto`. `pioneer/auto` uses the Pioneer [Code Router](/concepts/router).
-
- The Pioneer dashboard **Integrations** guide copies a single shell block that runs all of the steps above with your API key filled in.
-
-
-## Use the Code Router (`pioneer/auto`)
-
-`pioneer/auto` sends each turn through Pioneer's [Code Router](/concepts/router). The router picks the cheapest model that meets your quality bar for that specific prompt.
-
-- Set `ANTHROPIC_CUSTOM_MODEL_OPTION=pioneer/auto` so Claude Code treats it as a first-class custom model.
-- Launch with `claude --model pioneer/auto`, or select it from `/model`.
-- After each turn, the Stop hook shows how much `pioneer/auto` routing has saved you this session.
-
-### What does `Stop says:` mean?
-
-Claude Code has a [hooks](https://code.claude.com/docs/en/hooks) system. **Stop** is one hook event — it runs after the assistant finishes a turn (not when you exit the session).
-
-The Pioneer setup registers a Stop hook in `~/.claude/settings.json`. That script reads the `pioneer_savings` rate differences and the per-turn token usage from the session transcript, sums the savings across the session, and emits a short message. Claude Code labels hook output with the hook name, so the UI shows:
-
-```text
-Stop says: Pioneer routing saved ~$1.43 this session (vs claude-opus-4-7)
-```
-
-This is informational. **Stop** is Claude Code's name for the end-of-turn hook — not a warning and not a command to halt. The amount is cumulative for the session and only appears once the [Code Router](/concepts/router) has actually saved money versus the frontier reference model.
+## What the command does
-Pioneer also includes `pioneer_routed_model` and `pioneer_savings` on Anthropic-compatible responses (streaming `message_start` frames and non-streaming bodies) if you want to build your own tooling around routing metadata.
+`pioneer integrate claude` launches Claude Code with Pioneer's Anthropic-compatible endpoint configured through in-process environment variables only. Nothing is written to your Claude Code config, and your Claude.ai login is not changed. Select `pioneer/auto` to use the [Code Router](/concepts/router).
-## Full model list in `/model`
+## Switch models
-Claude Code only shows third-party gateway models whose IDs start with `claude` or `anthropic`. Pioneer publishes discovery aliases such as `anthropic/pioneer/gpt-5.4` on `GET /v1/models` so non-Claude decoder models appear in the picker while still resolving to the canonical Pioneer model ID at inference time.
+Use `/model` inside Claude Code to pick a specific Pioneer model, or keep `pioneer/auto`.
-Requirements:
+## Options
-- `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`
-- `ANTHROPIC_BASE_URL` pointing at Pioneer
-- A populated `~/.claude/cache/gateway-models.json` (see setup step above)
+- `--model ` launches with a specific model and skips the picker.
+- `--level ` sets the reasoning level on models that support it.
+- Anything after the agent name, or after `--`, is passed to Claude Code unchanged.
+- `pioneer integrate --help` shows the full command surface.
-
- If `~/.claude/settings.json` sets `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1`, Claude Code skips live gateway discovery. Remove that flag or rerun the cache seed step whenever you need an updated `/model` list.
-
+## Undo
-## Troubleshooting
+Nothing to undo. The wiring exists only in the launched session, so a plain `claude` still uses your own setup.
-
-
- This usually means Claude Code did not pick up a usable Pioneer API key for the current shell. It is not asking you to sign in to Claude.ai.
-
- 1. Run `. ~/.pioneer/env`, then restart Claude Code.
- 2. If Claude Code asks whether to use the environment API key, accept it.
- 3. Run `/status` and confirm:
- - **API key** is `ANTHROPIC_API_KEY`
- - **Anthropic base URL** is your Pioneer endpoint
- - **Auth token** is `none`
- 4. If `/status` points at Pioneer but the error persists, check `~/.claude.json`. Under `customApiKeyResponses`, make sure the suffix for your current Pioneer key is in `approved`, not `rejected`.
- 5. If you are using a non-production Pioneer endpoint, make sure the API key comes from the same environment.
-
-
-
- If you see `Both claude.ai and ANTHROPIC_API_KEY set · auth may not work as expected`, Claude Code is still using Claude.ai OAuth instead of your Pioneer key.
-
- 1. Run `claude auth logout` (or `/logout` inside Claude Code).
- 2. Relaunch with `claude --model pioneer/auto`. When prompted about the environment API key, accept it.
- 3. Verify with `/status`:
- - **Auth token** should be `none`
- - **API key** should be `ANTHROPIC_API_KEY`
- - **Anthropic base URL** should be your Pioneer endpoint
-
- On macOS, if the warning persists, open Keychain Access, search for **Claude Code**, delete stored credentials, and relaunch.
-
-
-
- 1. Confirm `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` is set in `~/.pioneer/env` and sourced.
- 2. Check that `~/.claude/cache/gateway-models.json` exists and its `baseUrl` matches `ANTHROPIC_BASE_URL`.
- 3. Remove `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` from `~/.claude/settings.json` if present.
- 4. Rerun the cache seed step from setup.
-
-
-
- Install the Stop hook from the setup section. It only runs when `ANTHROPIC_BASE_URL` points at Pioneer, and the line appears only once `pioneer/auto` routing has actually saved money versus the frontier reference model this session. A brand-new session, or one where the router picked the frontier model itself, will show nothing until there are positive savings to report.
-
-
\ No newline at end of file
+
+ For a persistent, always-on Pioneer setup (environment-based, plus the routing-savings hook), use the Pioneer dashboard Integrations guide, which generates a single shell block with your API key filled in.
+
diff --git a/codex.mdx b/codex.mdx
index 4e6e252..98a2836 100644
--- a/codex.mdx
+++ b/codex.mdx
@@ -1,309 +1,53 @@
---
title: "Codex"
-description: "Configure the OpenAI Codex CLI to run against Pioneer's OpenAI-compatible endpoint, load a fresh model catalog, and default to pioneer/auto routing."
+description: "Run Codex on Pioneer with pioneer integrate codex, a non-invasive launch wired to Pioneer inference."
---
-Steps to integrate Codex with Pioneer:
+`pioneer integrate codex` launches Codex wired to Pioneer inference, using your existing Pioneer CLI login. It is non-invasive: it configures Pioneer per run, so your `~/.codex/config.toml` is not modified.
-1. Download and [set up](https://developers.openai.com/codex/quickstart?setup=cli) the Codex CLI.
-2. Run Codex
- ```shellscript
- codex
- ```
-3. Log in with option 3 and enter your `PIONEER_API_KEY`
-4. Open `~/.codex/config.toml` and add these lines
+## Prerequisites
-```bash
-openai_base_url = "https://api.pioneer.ai/v1"
-model = "pioneer/auto"
-```
+- Codex CLI installed. See the [Codex quickstart](https://developers.openai.com/codex/quickstart?setup=cli).
+- The Pioneer CLI installed and authenticated. See [CLI installation](/CLI-Installation).
-5. Restart Codex
-6. Enter the following prompt into Codex
+## Integrate
-```text
-Set up this machine's Codex CLI to use Pioneer, including a fresh local model catalog.
- Do exactly this, in order:
- 1. Read my Pioneer API key from the PIONEER_API_KEY environment variable. If it is not set, stop and ask me for it — never
- guess or hardcode a key, and never print the key value.
- 2. Determine this user's absolute home directory (e.g. run `echo "$HOME"`). Call it HOME_ABS. Everywhere below, use the
- literal absolute path — do NOT write "~" or "$HOME" into any file, because Codex does not expand them in config.toml.
- 3. Fetch the Pioneer model list:
- curl -fsS https://api.pioneer.ai/v1/models -H "Authorization: Bearer $PIONEER_API_KEY"
- If the request fails (non-200), show me the status and body and STOP without changing any files.
- 4. From the JSON response, take ONLY the top-level "models" array (not "data"). Wrap it as {"models": [ ... ]} and write it
- pretty-printed to:
- HOME_ABS/.codex/model-catalogs/pioneer.json
- Create HOME_ABS/.codex/model-catalogs/ if needed. Overwrite the file if it exists.
- 5. Back up HOME_ABS/.codex/config.toml to config.toml.bak (skip if config.toml doesn't exist yet). Then ensure config.toml
- has exactly these Pioneer settings, written as TOP-LEVEL keys plus the [model_providers.pioneer] table (substitute HOME_ABS
- into the catalog path):
- model = "pioneer/auto"
- model_provider = "pioneer"
- model_reasoning_effort = "medium"
- model_catalog_json = "HOME_ABS/.codex/model-catalogs/pioneer.json"
- [model_providers.pioneer]
- name = "Pioneer"
- base_url = "https://api.pioneer.ai/v1"
- wire_api = "responses"
- supports_websockets = false
- Preserve any unrelated existing sections (e.g. [projects.*], [tui.*], other providers). Only set/replace the keys above
- and the [model_providers.pioneer] table. Make sure model_catalog_json is a top-level key, NOT nested inside
- [model_providers.pioneer].
- 6. Report how many models were written to the catalog, confirm the config keys are set, and remind me to restart Codex so
- the /model picker reloads.
-```
+
+
+ ```bash
+ npm install -g @fastino-ai/pioneer-cli
+ pioneer auth login
+ ```
+
+
+ ```bash
+ pioneer integrate codex
+ ```
+
+
+ Choose a model in the interactive picker, or skip it with `--model pioneer/auto`. `pioneer/auto` uses the Pioneer [Code Router](/concepts/router).
+
+
-7. Install the routing-savings hook. Codex strips Pioneer's custom response fields from its on-disk rollout, so the hook reads your session id and asks Pioneer how much `pioneer/auto` has saved this session. Make sure `PIONEER_API_KEY` is set, then paste this block:
+## What the command does
-```bash
-: "${PIONEER_API_KEY:?Set PIONEER_API_KEY first}"
-mkdir -p ~/.pioneer/hooks ~/.pioneer/state
+`pioneer integrate codex` launches Codex per run with the Pioneer model provider and your Pioneer key supplied through the environment. It does not modify your Codex config files. Select `pioneer/auto` to use the [Code Router](/concepts/router).
-# Credentials the hook reads (sourcing is optional - the hook also reads this file directly)
-cat > ~/.pioneer/codex-env < ~/.pioneer/hooks/show-pioneer-signals.py <<'PIONEER_CODEX_HOOK'
-#!/usr/bin/env python3
-"""Codex Stop hook that surfaces how much pioneer/auto routing saved.
+Use `/model` inside Codex to switch between Pioneer models.
-Codex talks to Pioneer over the OpenAI Responses API but strips Pioneer's custom
-response fields (``pioneer_savings`` / ``pioneer_routed_model``) before writing
-its on-disk session rollout, so — unlike the Claude Code hook — this hook cannot
-compute savings from the transcript. Instead Pioneer accumulates each turn's
-savings server-side, keyed by the ``prompt_cache_key`` Codex sends on every
-request (its session id). This hook derives that same session id from the
-rollout and queries the cumulative figure, then prints it once per change.
+## Options
-For a *direct* (non-auto) model it nudges toward pioneer/auto once per session.
-No-op on any error, when the API key is unknown, or when there is nothing to
-show — a Stop hook must never disrupt the session.
-"""
+- `--model ` launches with a specific model and skips the picker.
+- `--level ` sets the reasoning level on models that support it.
+- Anything after the agent name, or after `--`, is passed to Codex unchanged.
+- `pioneer integrate --help` shows the full command surface.
-from __future__ import annotations
+## Undo
-import json
-import os
-import re
-import sys
-import urllib.error
-import urllib.request
-from pathlib import Path
-
-AUTO_ROUTER_MODELS = {"pioneer/auto", "auto"}
-FRONTIER_REFERENCE_MODEL = "claude-opus-4-7"
-DEFAULT_BASE_URL = "https://api.pioneer.ai/v1"
-DEFAULT_ROUTER_TIP = (
- "Tip: use model=pioneer/auto to let Pioneer route each request automatically; "
- "named models pin that concrete model."
-)
-ENV_FILE = Path.home() / ".pioneer" / "codex-env"
-STATE_PATH = Path.home() / ".pioneer" / "state" / "codex-pioneer-signals-hook.json"
-REQUEST_TIMEOUT_S = 3.0
-_UUID_RE = re.compile(
- r"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-"
- r"[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"
-)
-
-
-def _read_env_file() -> dict[str, str]:
- """Parse ``~/.pioneer/codex-env`` into a dict (so sourcing is optional).
-
- Accepts ``KEY=value``, ``export KEY=value``, and quoted values. Missing or
- unreadable files yield an empty dict.
- """
- try:
- text = ENV_FILE.read_text(encoding="utf-8")
- except OSError:
- return {}
- values: dict[str, str] = {}
- for line in text.splitlines():
- line = line.strip()
- if not line or line.startswith("#"):
- continue
- if line.startswith("export "):
- line = line[len("export ") :]
- if "=" not in line:
- continue
- key, _, value = line.partition("=")
- values[key.strip()] = value.strip().strip('"').strip("'")
- return values
-
-
-def _config(name: str, env_values: dict[str, str], default: str = "") -> str:
- """Resolve a config value from the process env, then the env file."""
- return os.environ.get(name) or env_values.get(name) or default
-
-
-def _session_id(payload: dict[str, object], transcript_path: str | None) -> str:
- """Derive the Codex session id (== request ``prompt_cache_key``).
-
- Prefers the hook payload's ``session_id``; falls back to the UUID embedded
- in the rollout filename, which Codex uses verbatim as the prompt cache key.
- """
- session_id = payload.get("session_id")
- if isinstance(session_id, str) and session_id:
- return session_id
- if transcript_path:
- match = _UUID_RE.search(Path(transcript_path).name)
- if match:
- return match.group(0)
- return ""
-
-
-def _fetch_savings(base_url: str, api_key: str, session_id: str) -> dict[str, object]:
- """GET cumulative session savings from Pioneer (empty dict on any failure)."""
- if not (base_url and api_key and session_id):
- return {}
- url = f"{base_url.rstrip('/')}/codex/session-savings/{session_id}"
- request = urllib.request.Request(url, method="GET")
- request.add_header("Authorization", f"Bearer {api_key}")
- request.add_header("Accept", "application/json")
- try:
- with urllib.request.urlopen(request, timeout=REQUEST_TIMEOUT_S) as response:
- body = response.read().decode("utf-8")
- except (urllib.error.URLError, OSError, ValueError):
- return {}
- try:
- parsed = json.loads(body)
- except json.JSONDecodeError:
- return {}
- return parsed if isinstance(parsed, dict) else {}
-
-
-def _format_usd(amount: float) -> str:
- """Format a USD savings amount with magnitude-appropriate precision."""
- if amount >= 1:
- return f"${amount:.2f}"
- if amount >= 0.01:
- return f"${amount:.3f}"
- return f"${amount:.4f}"
-
-
-def _is_auto_router_model(model: str) -> bool:
- """Return True when a Codex model value is the Pioneer auto-router."""
- normalized = model.strip().lower()
- return normalized in AUTO_ROUTER_MODELS or normalized.endswith("/pioneer/auto")
-
-
-def _load_state() -> dict[str, str]:
- """Load the last surfaced message per session."""
- try:
- raw = json.loads(STATE_PATH.read_text(encoding="utf-8"))
- except (OSError, json.JSONDecodeError):
- return {}
- if not isinstance(raw, dict):
- return {}
- return {str(k): str(v) for k, v in raw.items() if isinstance(v, str)}
-
-
-def _write_state(state: dict[str, str]) -> None:
- """Persist hook state so an unchanged message is not repeated."""
- try:
- STATE_PATH.parent.mkdir(parents=True, exist_ok=True)
- STATE_PATH.write_text(json.dumps(state, indent=2) + "\n", encoding="utf-8")
- except OSError:
- pass
-
-
-def _savings_message(savings: dict[str, object]) -> str:
- """Build the savings line from the endpoint response, or '' when none."""
- if not savings.get("found"):
- return ""
- amount = savings.get("savings_usd")
- if not isinstance(amount, (int, float)) or isinstance(amount, bool) or amount <= 0:
- return ""
- baseline = savings.get("baseline_model")
- reference = baseline if isinstance(baseline, str) and baseline else (
- FRONTIER_REFERENCE_MODEL
- )
- return (
- f"Pioneer auto-routing savings this session: ~{_format_usd(float(amount))} "
- f"(vs {reference})"
- )
-
-
-def _message_for(payload: dict[str, object], savings: dict[str, object]) -> str:
- """Pick the systemMessage: savings for the router, a tip for direct models."""
- model = str(payload.get("model") or "pioneer/auto")
- if _is_auto_router_model(model):
- return _savings_message(savings)
- return DEFAULT_ROUTER_TIP
-
-
-def main() -> int:
- """Read Codex hook input from stdin and emit a systemMessage when needed."""
- try:
- payload = json.loads(sys.stdin.read() or "{}")
- except json.JSONDecodeError:
- return 0
- if not isinstance(payload, dict) or payload.get("stop_hook_active") is True:
- return 0
-
- transcript_path = payload.get("transcript_path")
- transcript_path = transcript_path if isinstance(transcript_path, str) else None
- session_id = _session_id(payload, transcript_path)
-
- env_values = _read_env_file()
- savings = _fetch_savings(
- base_url=_config("PIONEER_BASE_URL", env_values, DEFAULT_BASE_URL),
- api_key=_config("PIONEER_API_KEY", env_values),
- session_id=session_id,
- )
-
- message = _message_for(payload, savings)
- if not message:
- return 0
-
- state = _load_state()
- state_key = session_id or transcript_path or "default"
- if state.get(state_key) == message:
- return 0
- state[state_key] = message
- _write_state(state)
- print(json.dumps({"systemMessage": message}))
- return 0
-
-
-if __name__ == "__main__":
- raise SystemExit(main())
-PIONEER_CODEX_HOOK
-chmod +x ~/.pioneer/hooks/show-pioneer-signals.py
-
-# Register it as a Codex Stop hook
-python3 <<'PY'
-import json
-from pathlib import Path
-
-hook = Path.home() / ".pioneer" / "hooks" / "show-pioneer-signals.py"
-hooks_path = Path.home() / ".codex" / "hooks.json"
-command = f"python3 {hook}"
-config = json.loads(hooks_path.read_text()) if hooks_path.exists() else {}
-stop_groups = config.setdefault("hooks", {}).setdefault("Stop", [])
-if not any(h.get("command") == command for g in stop_groups for h in g.get("hooks", [])):
- stop_groups.append({"hooks": [{"type": "command", "command": command, "timeout": 5, "statusMessage": "Checking Pioneer routing signals"}]})
-hooks_path.parent.mkdir(parents=True, exist_ok=True)
-hooks_path.write_text(json.dumps(config, indent=2) + "\n")
-print("Installed Pioneer Codex Stop hook")
-PY
-```
-
-Restart Codex and run `/hooks` to trust the hook. Each turn that routes to a model cheaper than the frontier reference then ends with:
-
-```text
-Pioneer auto-routing savings this session: ~$1.43 (vs claude-opus-4-7)
-```
-
-8. Switch between models with `/model` command.
-
-- The `pioneer/auto` router will automatically route your request to the cheapest model!
-- You should also be able to see our entire Pioneer Model Catalog with `/model` command
+Nothing to undo. The wiring applies only to the launched run, so a plain `codex` still uses your own config.
- The Pioneer dashboard **Integrations** guide copies this same block with your API key already filled in.
-
\ No newline at end of file
+ For a persistent Codex setup (config-based, with a local model catalog and the routing-savings hook), use the Pioneer dashboard Integrations guide, which generates a single shell block with your API key filled in.
+
diff --git a/hermes.mdx b/hermes.mdx
index 89ac913..69c4c5a 100644
--- a/hermes.mdx
+++ b/hermes.mdx
@@ -1,187 +1,64 @@
---
title: "Hermes Agent"
-description: "Configure Hermes Agent with Pioneer using a one-time setup command that imports a filtered model catalog and defaults to pioneer/auto routing."
+description: "Run Hermes Agent on Pioneer with pioneer integrate hermes, using an isolated Hermes home so your normal Hermes setup stays untouched."
---
-Steps to integrate Hermes Agent with Pioneer:
+`pioneer integrate hermes` runs Hermes Agent against Pioneer from an isolated Hermes home, so your normal Hermes configuration is left untouched. It uses your existing Pioneer CLI login.
-1. Download and [set up](https://hermes-agent.nousresearch.com/docs/getting-started/installation) Hermes Agent.
-2. Set your Pioneer API key for the one-time setup command:
+## Prerequisites
-```bash
-export PIONEER_API_KEY=""
-```
-
-3. Run this one-time setup command. It fetches the live `GET /v1/models` catalog, filters out Claude Code discovery aliases, stores your Pioneer API key in Hermes' local environment file at `~/.hermes/.env`, writes the filtered Pioneer provider to `~/.hermes/config.yaml`, and sets `pioneer/auto` as the default model so Pioneer can route each request automatically.
-
-The command requires `jq` and `ruby`. It creates a timestamped backup of your existing Hermes config before updating the Pioneer section.
-
-```bash
-: "${PIONEER_API_KEY:?Set PIONEER_API_KEY first}"
-
-command -v jq >/dev/null || { echo "jq is required"; exit 1; }
-command -v ruby >/dev/null || { echo "ruby is required"; exit 1; }
-
-CONFIG_FILE="$(hermes config path)"
-CONFIG_TMP="$(mktemp)"
-MODELS_JSON="$(mktemp)"
-trap 'rm -f "$CONFIG_TMP" "$MODELS_JSON"' EXIT
-
-mkdir -p "$(dirname "$CONFIG_FILE")"
-[ -f "$CONFIG_FILE" ] || printf '{}\n' > "$CONFIG_FILE"
-cp "$CONFIG_FILE" "$CONFIG_FILE.bak.$(date +%Y%m%d%H%M%S)"
-
-hermes config set PIONEER_API_KEY "$PIONEER_API_KEY"
-
-curl -fsS "https://api.pioneer.ai/v1/models" \
- -H "Authorization: Bearer $PIONEER_API_KEY" \
- | jq '
- def dedupe:
- reduce .[] as $item ([]; if index($item) then . else . + [$item] end);
-
- def catalog_models:
- (.models // []) as $models
- | if (($models | type) == "array" and ($models | length) > 0) then $models else (.data // []) end;
-
- def model_id:
- .slug // .id;
-
- (["pioneer/auto"] + [
- catalog_models[]
- | select(.deprecated != true)
- | model_id
- | select(type == "string" and length > 0)
- # Hide Claude Code discovery aliases so Hermes does not show every model twice.
- | select(startswith("anthropic/") | not)
- | select(. != "pioneer/auto" and . != "auto")
- ]) | dedupe
- ' > "$MODELS_JSON"
-
-ruby -ryaml -rjson -e '
- config_path, models_path, out_path = ARGV
- cfg = File.exist?(config_path) ? (YAML.safe_load(File.read(config_path), aliases: true) || {}) : {}
- abort "#{config_path} must contain a YAML mapping" unless cfg.is_a?(Hash)
-
- models = JSON.parse(File.read(models_path))
- cfg["providers"] = {} unless cfg["providers"].is_a?(Hash)
- cfg["providers"]["pioneer"] = {
- "name" => "Pioneer",
- "base_url" => "https://api.pioneer.ai/v1",
- "key_env" => "PIONEER_API_KEY",
- "api_mode" => "chat_completions",
- "discover_models" => false,
- "default_model" => "pioneer/auto",
- "models" => models
- }
-
- cfg["model"] = {} unless cfg["model"].is_a?(Hash)
- cfg["model"]["provider"] = "pioneer"
- cfg["model"]["default"] = "pioneer/auto"
- cfg["model"]["base_url"] = "https://api.pioneer.ai/v1"
- cfg["model"]["api_mode"] = "chat_completions"
-
- File.write(out_path, YAML.dump(cfg))
-' "$CONFIG_FILE" "$MODELS_JSON" "$CONFIG_TMP"
-
-mv "$CONFIG_TMP" "$CONFIG_FILE"
-chmod 600 "$CONFIG_FILE"
-```
-
-4. Start Hermes normally:
+- Hermes Agent installed. See the [Hermes setup guide](https://hermes-agent.nousresearch.com/docs/getting-started/installation).
+- The Pioneer CLI installed and authenticated. See [CLI installation](/CLI-Installation).
-```bash
-hermes
-```
+## Integrate
-5. Switch between saved Pioneer models with `/model` inside Hermes. Use `--global` when you want the change to persist in `~/.hermes/config.yaml`:
+
+
+ ```bash
+ npm install -g @fastino-ai/pioneer-cli
+ pioneer auth login
+ ```
+
+
+ ```bash
+ pioneer integrate hermes
+ ```
+
+
+ Choose a model in the interactive picker, or skip it with `--model pioneer/auto`. `pioneer/auto` uses the Pioneer [Code Router](/concepts/router).
+
+
-```text
-/model
-/model claude-opus-4-8 --provider pioneer
-/model gpt-5.5 --provider pioneer --global
-/model pioneer/auto --provider pioneer --global
-```
+## What the command does
-
- `hermes model` is Hermes' full provider setup wizard. `/model` inside an active Hermes session only switches between providers you have already configured. The setup above configures a named `pioneer` provider, so `/model` can switch among saved Pioneer models without re-entering your API key.
-
+`pioneer integrate hermes` launches Hermes from an isolated home at `~/.pioneer/hermes-home`, writes a Pioneer provider config there, sets `pioneer/auto` as the default, and passes your Pioneer key through the environment. Your everyday `hermes` setup is not modified.
-
- The model list is pulled when you run the setup command. Re-run the setup command when you want Hermes to pick up newly added Pioneer models. The command sets `discover_models: false` because Pioneer's live catalog also includes `anthropic/*` aliases for Claude Code, which would otherwise make Hermes show duplicate rows.
-
+## Switch models
-## Verify setup
+Use `/model` inside Hermes to switch between Pioneer models.
-Run a quick non-interactive check:
+## Options
-```bash
-hermes chat -q "Reply with exactly PIONEER_HERMES_OK"
-```
+- `--model ` launches with a specific model and skips the picker.
+- `--level ` sets the reasoning level on models that support it.
+- Anything after the agent name, or after `--`, is passed to Hermes unchanged.
+- `pioneer integrate --help` shows the full command surface.
-Or inspect the filtered catalog directly:
+## Undo
```bash
-curl -fsS "https://api.pioneer.ai/v1/models" \
- -H "Authorization: Bearer $PIONEER_API_KEY" \
- | jq -r '
- def catalog_models:
- (.models // []) as $models
- | if (($models | type) == "array" and ($models | length) > 0) then $models else (.data // []) end;
-
- catalog_models[]
- | (.slug // .id)
- | select(type == "string" and length > 0)
- | select(startswith("anthropic/") | not)
- ' \
- | head
+pioneer integrate restore hermes
```
-
- After setup, Hermes reads `PIONEER_API_KEY` from `~/.hermes/.env`, so you do not need to export it in every terminal. Keep exporting it only when you want to run shell commands like the catalog check above.
-
+This removes the Pioneer provider config from the isolated Hermes home. Your Hermes sessions there are preserved.
## Troubleshooting
- Re-run the setup command above, then restart Hermes. The setup writes both the named provider and the filtered `providers.pioneer.models` list that `/model` reads.
-
- Confirm the active provider:
-
- ```bash
- hermes config show
- ```
-
- Make sure `Model` shows `provider: pioneer`, then start a new Hermes session. If you are already inside a Hermes session, `/model` can switch models but cannot run the full provider setup wizard.
-
-
-
- Re-run the setup command above. The duplicate entries are Claude Code discovery aliases from the raw Pioneer catalog, such as `anthropic/pioneer/gpt-5.5`. Hermes does not filter generic live discovery in v0.18, so the setup stores a filtered list and sets `providers.pioneer.discover_models` to `false`.
+ Rerun `pioneer integrate hermes` to rewrite the provider config in the isolated home, then start Hermes again.
-
-
- Store the key again:
-
- ```bash
- export PIONEER_API_KEY=""
- hermes config set PIONEER_API_KEY "$PIONEER_API_KEY"
- ```
-
- Hermes stores API keys in `~/.hermes/.env`, not directly in `config.yaml`.
-
-
-
- Switch Hermes back to the provider you want:
-
- ```bash
- hermes model
- ```
-
- Or set another provider directly:
-
- ```bash
- hermes config set model.provider openrouter
- hermes config set model.default anthropic/claude-sonnet-4
- ```
+
+ Confirm the CLI is logged in with `pioneer auth status`, then rerun the integration.
-
\ No newline at end of file
+
diff --git a/openclaw.mdx b/openclaw.mdx
index a6dbe0e..c65adbd 100644
--- a/openclaw.mdx
+++ b/openclaw.mdx
@@ -1,338 +1,75 @@
---
-title: "Use Pioneer with OpenClaw as a custom provider"
-description: "Configure OpenClaw to use Pioneer's OpenAI-compatible endpoint, discover models via /v1/models, and run the local gateway with Pioneer Auto."
+title: "OpenClaw"
+description: "Run OpenClaw on Pioneer with pioneer integrate openclaw, which configures the Pioneer provider, starts the local gateway, and opens the Web UI."
---
-Pioneer exposes an OpenAI-compatible inference endpoint, so OpenClaw can use Pioneer as a custom provider today. This guide covers the custom-provider setup until Pioneer is available as an official OpenClaw provider.
+The fastest way to use OpenClaw with Pioneer is the Pioneer CLI. `pioneer integrate openclaw` configures the Pioneer provider in OpenClaw, registers the live Pioneer model catalog, starts the local gateway, and opens the Web UI, using your existing CLI login.
- OpenClaw is a third-party local agent tool. Keep the gateway bound to loopback unless you have intentionally hardened remote access, channel allowlists, and tool permissions.
+ OpenClaw runs a local gateway. Keep it bound to loopback unless you have intentionally hardened remote access, channel allowlists, and tool permissions.
-### Prerequisites
+## Prerequisites
-- OpenClaw installed:
+- OpenClaw installed: `npm install -g openclaw@latest`
+- The Pioneer CLI installed and authenticated. See [CLI installation](/CLI-Installation).
-```shellscript
-npm install -g openclaw@latest
-```
-
-- A Pioneer API key from the Pioneer dashboard.
-- `jq` installed for converting the live Pioneer model catalog into OpenClaw config.
-- Check to see if OpenClaw is available:
-
-```shellscript
-openclaw --version
-```
-
-### Setup steps
-
-1. Save Pioneer auth in OpenClaw
- - Paste your Pioneer API key once. OpenClaw stores it in the local auth profile store and the gateway reuses it across terminal sessions.
- ```shellscript
- openclaw models auth paste-api-key --provider pioneer
- ```
-
- Do not paste real API keys into docs, screenshots, shared shell history, or issue trackers. Rotate the key if it has been exposed.
-
-2. Discover and register Pioneer models
- - Pioneer's supported inference models can change over time. Use the OpenAI-compatible `GET /v1/models` catalog as the source of truth and convert it directly into OpenClaw model config.
- - This command reads the Pioneer key from the OpenClaw auth profile saved in step 1, uses it for the catalog fetch, and writes the discovered model catalog into `~/.openclaw/openclaw.json`.
- ```shellscript
- AUTH_DB="$(openclaw models auth list --provider pioneer --json | jq -r '.authStatePath')"
- case "$AUTH_DB" in
- "~/"*) AUTH_DB="$HOME/${AUTH_DB#"~/"}" ;;
- esac
- PIONEER_API_KEY="$(sqlite3 "$AUTH_DB" "select json_extract(store_json, '$.profiles.\"pioneer:manual\".key') from auth_profile_store where store_key = 'primary';")"
- : "${PIONEER_API_KEY:?Run openclaw models auth paste-api-key --provider pioneer first}"
- CONFIG_FILE="$(openclaw config file)"
- case "$CONFIG_FILE" in
- "~/"*) CONFIG_FILE="$HOME/${CONFIG_FILE#"~/"}" ;;
- esac
- [ -f "$CONFIG_FILE" ] || printf '{}\n' > "$CONFIG_FILE"
- curl -fsS "https://api.pioneer.ai/v1/models" \
- -H "Authorization: Bearer $PIONEER_API_KEY" \
- | jq --slurpfile current "$CONFIG_FILE" -c '
- def dedupe:
- reduce .[] as $item ([]; if index($item) then . else . + [$item] end);
- def catalog_models:
- (.models // []) as $models
- | if (($models | type) == "array" and ($models | length) > 0) then $models else (.data // []) end;
- def model_id:
- .slug // .id;
- def model_name:
- (.display_name // .name // .id // .slug)
- | split("/") | last
- | gsub("_"; " ")
- | gsub("-"; " ")
- | sub(" (?[0-9]+) (?[0-9]+)(?= |$)"; " \(.major).\(.minor)")
- | gsub("\\bGpt\\b"; "GPT")
- | gsub("\\bOss\\b"; "OSS")
- | gsub("\\bAi\\b"; "AI")
- | gsub("(?[0-9]+(\\.[0-9]+)?)b\\b"; "\(.n)B");
- def bool_supported($value):
- $value == true or (($value | type) == "object" and $value.supported == true);
- def input_modalities:
- . as $row
- | (
- [
- ($row.input // $row.inputs // $row.modalities // $row.input_modalities // $row.inputModalities // $row.capabilities.input // $row.capabilities.inputs // $row.capabilities.modalities // [])
- | .[]?
- | select(type == "string")
- | ascii_downcase
- | select(. == "text" or . == "image" or . == "audio" or . == "video")
- ]
- | dedupe
- ) as $inputs
- | (if ($inputs | length) > 0 then $inputs else ["text"] end) as $base
- | if ($row.capabilities.image_input.supported == true and (($base | index("image")) | not)) then $base + ["image"] else $base end;
- def reasoning_levels:
- [
- (.supported_reasoning_levels // .reasoning_levels // .supported_reasoning_efforts // .supportedReasoningLevels // .supportedReasoningEfforts // [])
- | .[]?
- | if type == "string" then . else (.effort // .id // .level // .name // empty) end
- | select(type == "string" and length > 0)
- ] | dedupe;
- def supports_reasoning:
- (reasoning_levels | length) > 0
- or bool_supported(.reasoning)
- or bool_supported(.supports_reasoning)
- or bool_supported(.supportsReasoning)
- or bool_supported(.thinking)
- or bool_supported(.capabilities.reasoning)
- or bool_supported(.capabilities.thinking);
- def openclaw_model_id($id):
- if $id | startswith("pioneer/") then $id else "pioneer/" + $id end;
- (
- [
- {
- id: "pioneer/auto",
- name: "Pioneer Auto",
- input: ["text"],
- contextWindow: 1000000,
- maxTokens: 16000
- }
- ] + (
- [
- catalog_models[]
- | select(.deprecated != true)
- | select(.object == null or .object == "model")
- | select(model_id != null)
- | select(model_id | startswith("anthropic/") | not)
- | select(model_id != "pioneer/auto" and model_id != "auto")
- | (reasoning_levels) as $levels
- | ({
- id: model_id,
- name: model_name,
- reasoning: supports_reasoning,
- input: input_modalities,
- contextWindow: (.max_input_tokens // .context_window // .contextWindow // .context_length // .contextLength // 128000),
- maxTokens: (.max_output_tokens // .max_tokens // .maxTokens // .max_completion_tokens // .maxCompletionTokens // 16000)
- } + (if ($levels | length) > 0 then {compat: {supportedReasoningEfforts: $levels}} else {} end))
- ]
- | unique_by(.id)
- | sort_by(.id)
- )
- ) as $pioneer_models
- | ($current[0].agents.defaults.models // {}) as $current_agent_models
- | {
- models: {
- providers: {
- pioneer: {
- baseUrl: "https://api.pioneer.ai/v1",
- api: "openai-completions",
- models: $pioneer_models
- }
- }
- },
- agents: {
- defaults: {
- model: {primary: "pioneer/auto"},
- models: (
- ($current_agent_models | with_entries(select(.key | startswith("pioneer/") | not)))
- + (
- $pioneer_models
- | map({key: openclaw_model_id(.id), value: {alias: .name}})
- | from_entries
- )
- )
- }
- }
- }' \
- | openclaw config patch \
- --stdin \
- --replace-path models.providers.pioneer.models \
- --replace-path agents.defaults.models
- ```
- - The command manually adds `pioneer/auto` for Pioneer Auto, then reads the top-level `.models[]` catalog when present and falls back to `.data[]`, deduplicates by `id`, filters `anthropic/*` Claude Code discovery aliases so OpenClaw does not show duplicate models, and exposes every Pioneer model under `agents.defaults.models` for the model picker and `openclaw models status`.
- - OpenClaw uses `/think` for reasoning controls. Models that advertise `supported_reasoning_levels`, `reasoning`, `supports_reasoning`, or `thinking` metadata are registered with `reasoning: true`; when Pioneer advertises exact reasoning levels, the command also writes `compat.supportedReasoningEfforts` so OpenClaw can include levels such as `xhigh`.
- - To refresh the catalog later, re-run the same command. It replaces the Pioneer provider models and Pioneer agent allowlist while preserving non-Pioneer agent model entries.
-3. Start the local gateway and open the Web UI
- - The model-discovery command already sets `pioneer/auto` as the default model. You do not need to run `openclaw models set pioneer/auto` separately.
- - Use the LaunchAgent service for normal local setup. Do not run `openclaw gateway run` unless you are intentionally debugging in the foreground.
- ```shellscript
- openclaw config set gateway.mode local
- GATEWAY_TOKEN="$(openclaw config get gateway.auth.token 2>/dev/null || true)"
- if [ -z "$GATEWAY_TOKEN" ] || [ "$GATEWAY_TOKEN" = "null" ]; then
- GATEWAY_TOKEN="$(openssl rand -hex 32)"
- openclaw config set gateway.auth.token "$GATEWAY_TOKEN"
- fi
- openclaw gateway install --force
- openclaw gateway restart
- openclaw dashboard
- unset GATEWAY_TOKEN
- ```
- - This avoids the noisy full `openclaw doctor` flow during normal setup. `openclaw gateway install --force` keeps the macOS LaunchAgent service definition current, including the service environment. `openclaw gateway restart` then applies the Pioneer model config and gateway token.
- - `openclaw dashboard` may print a clean URL such as `http://127.0.0.1:18789/` while copying a token-authenticated URL to your clipboard.
- - In the Web UI, choose a reasoning-capable Pioneer model and use the thinking selector to switch levels. From the CLI or chat input, send `/think low`, `/think medium`, `/think high`, or `/think off`. Send `/think` with no argument to see the current effective level.
-4. Verify the setup **(optional)**
- - These checks are useful when validating a fresh setup or debugging a user report:
- ```shellscript
- openclaw models status --json \
- | jq '{defaultModel, allowed_count: (.allowed | length), first_allowed: .allowed[0:5]}'
- openclaw models status --probe --probe-provider pioneer
- ```
- - Expected result: `defaultModel` is `pioneer/auto`, `allowed_count` is greater than `1`, and the Pioneer auth probe succeeds.
- - OpenClaw may probe only the default/effective target even when the agent allowlist contains many Pioneer models. That is fine as long as the configured model count is greater than `1` and `pioneer/auto` probes successfully.
-5. Run a first agent message from the CLI **(optional)**
- - OpenClaw needs a target session for agent messages. A plain `--message` is not enough.
- ```shellscript
- openclaw agent --agent main --session-key cli-test --message "hello"
- ```
- - To continue the same local session:
- ```shellscript
- openclaw agent --agent main --session-key cli-test --message "summarize the previous answer"
- ```
- - You can list sessions with:
- ```shellscript
- openclaw sessions list
- ```
+## Integrate
-### Troubleshooting OpenClaw integration
-
-
-
- OpenClaw does not have a Pioneer auth profile. Run:
-
- ```shellscript
- openclaw models auth paste-api-key --provider pioneer
- openclaw models status --probe --probe-provider pioneer
+
+
+ ```bash
+ npm install -g @fastino-ai/pioneer-cli
+ pioneer auth login
```
-
-
-
- The catalog fetch likely did not read the saved OpenClaw auth profile. Confirm the Pioneer profile exists, then rerun the discovery command.
-
- Confirm the saved auth profile exists:
-
- ```shellscript
- openclaw models auth list --provider pioneer
+
+
+ ```bash
+ pioneer integrate openclaw
```
+
+
+ Choose a model in the interactive picker, or skip it with `--model pioneer/auto`. `pioneer/auto` uses the Pioneer [Code Router](/concepts/router).
+
+
- Confirm the catalog exposes the expected Pioneer router models before rerunning the discovery command:
-
- ```shellscript
- AUTH_DB="$(openclaw models auth list --provider pioneer --json | jq -r '.authStatePath')"
- case "$AUTH_DB" in "~/"*) AUTH_DB="$HOME/${AUTH_DB#"~/"}" ;; esac
- PIONEER_API_KEY="$(sqlite3 "$AUTH_DB" "select json_extract(store_json, '$.profiles.\"pioneer:manual\".key') from auth_profile_store where store_key = 'primary';")"
+## What the command does
- curl -fsS "https://api.pioneer.ai/v1/models" \
- -H "Authorization: Bearer $PIONEER_API_KEY" \
- | jq -r '.data[].id | select(test("^pioneer/(auto|auto_v1|general)$"))'
- ```
+`pioneer integrate openclaw` persists a `pioneer` provider in your OpenClaw config (backing the config up first), stores your Pioneer key in OpenClaw's local auth store, registers the live Pioneer model catalog, starts the local gateway service, and opens the dashboard. It sets `pioneer/auto` as the default model.
- Expected output includes at least `pioneer/auto`. Versioned router entries such as `pioneer/auto_v1.1`, `pioneer/auto_v1.2`, and `pioneer/general` appear when they are exposed by the production catalog for your key. If the catalog output is correct, rerun the discovery command and restart the gateway.
-
+## Switch models
-
- This usually means the config points at an environment variable that is not visible to the OpenClaw process or gateway service. Prefer the auth-profile setup:
+Pick a model in the Web UI, or use `/think low`, `/think medium`, `/think high`, or `/think off` to control reasoning on models that support it.
- ```shellscript
- openclaw models auth paste-api-key --provider pioneer
- ```
+## Options
- If you intentionally use an env reference, confirm the variable is visible to the process that runs OpenClaw:
+- `--model ` launches with a specific model and skips the picker.
+- `--level ` sets the reasoning level on models that support it.
+- Anything after the agent name, or after `--`, is passed to OpenClaw unchanged.
+- `pioneer integrate --help` shows the full command surface.
- ```shellscript
- test -n "$PIONEER_API_KEY" && echo "set" || echo "not set"
- ```
+## Undo
- For launchd, `launchctl setenv` does not persist across reboots and may not be enough if OpenClaw uses a generated service environment wrapper.
-
-
-
- Reinstall and restart the LaunchAgent:
-
- ```shellscript
- openclaw gateway install --force
- openclaw gateway restart
- openclaw gateway status
- ```
-
-
-
- Pass a session target:
-
- ```shellscript
- openclaw agent --agent main --session-key cli-test --message "hello"
- ```
-
-
-
- This usually means the LaunchAgent service is already bound to the gateway port. That is normal; do not start a second gateway with `openclaw gateway run`.
-
- For normal use, restart the service and open the Web UI:
-
- ```shellscript
- openclaw gateway restart
- openclaw dashboard
- ```
-
- If `gateway status` says the service config is out of date, repair and restart:
+```bash
+pioneer integrate restore openclaw
+```
- ```shellscript
- openclaw doctor --repair
- openclaw gateway restart
- ```
+This stops the gateway and restores your pre-Pioneer OpenClaw config. Restores touch only settings; your OpenClaw sessions are preserved.
- For foreground debugging only, stop the service first, then run the gateway in the foreground:
+## Troubleshooting
- ```shellscript
- openclaw gateway stop
- openclaw gateway run
- ```
+
+
+ Run `pioneer integrate restore openclaw`, then `pioneer integrate openclaw` again to re-register the full catalog.
+
+ Print the configured token and paste it into the Web UI `Gateway Token` field:
-
- Use the configured shared gateway token. The Control UI expects the same token from `gateway.auth.token` or `OPENCLAW_GATEWAY_TOKEN`:
-
- ```shellscript
+ ```bash
openclaw config get gateway.auth.token
```
-
- Paste that value into the Web UI `Gateway Token` field and click **Connect**.
-
- If the command is empty, create a token and restart the gateway:
-
- ```shellscript
- GATEWAY_TOKEN="$(openssl rand -hex 32)"
- openclaw config set gateway.auth.token "$GATEWAY_TOKEN"
- openclaw gateway install --force
- openclaw gateway restart
- openclaw dashboard
- unset GATEWAY_TOKEN
- ```
-
- Do not manually extract tokens from OpenClaw's SQLite state database.
-
-
- Check reachability and logs:
-
- ```shellscript
- openclaw gateway status
- openclaw gateway probe
- openclaw logs --follow
- ```
+
+ Rerun `pioneer integrate openclaw`, which reinstalls and restarts the local gateway service.
diff --git a/opencode.mdx b/opencode.mdx
index 83a96fb..64181ce 100644
--- a/opencode.mdx
+++ b/opencode.mdx
@@ -1,41 +1,81 @@
---
title: "OpenCode"
-description: "Connect the OpenCode CLI or desktop app to Pioneer to route model calls, switch between 70+ models, and optionally enable Exa-powered web search."
+description: "Run OpenCode on Pioneer with a single pioneer integrate opencode command that syncs the latest Pioneer models and launches OpenCode."
---
-## Setup steps
+The fastest way to use OpenCode with Pioneer is the Pioneer CLI. `pioneer integrate opencode` syncs the latest Pioneer models into your OpenCode config and launches OpenCode wired to Pioneer inference, using your existing CLI login. There are no config files, keys, or model catalogs to maintain by hand.
-**Integrate OpenCode CLI with Pioneer:**
+## Prerequisites
-
+- [OpenCode](https://opencode.ai/download) installed.
+- The Pioneer CLI installed and authenticated. See [CLI installation](/CLI-Installation).
-1. Download and [set up](https://opencode.ai/download) the OpenCode CLI.
-2. Sign into Pioneer and get your API key from [agent.pioneer.ai/api-keys](https://agent.pioneer.ai/api-keys)
-3. In a fresh terminal, start OpenCode. Include `OPENCODE_ENABLE_EXA=1` if you want web search (OpenCode disables it for custom providers by default):
+## Integrate
+
+
+
+ ```bash
+ npm install -g @fastino-ai/pioneer-cli
+ pioneer auth login
+ ```
+
+
+ ```bash
+ pioneer integrate opencode
+ ```
+
+
+ Choose a model in the interactive picker (per-model thinking levels are shown where supported), or skip the picker with `--model`:
+
+ ```bash
+ pioneer integrate opencode --model pioneer/auto
+ ```
+
+ `pioneer/auto` sends each request through the Pioneer [Code Router](/concepts/router), which picks the cheapest model that meets your quality bar.
+
+
+
+## What the command does
+
+OpenCode ships an official Pioneer provider, but its model list comes from models.dev, so new Pioneer models can lag. `pioneer integrate opencode` diffs the live Pioneer catalog against models.dev and writes only the missing models into your OpenCode config, then launches OpenCode reading your Pioneer key from the environment. It backs up your config first, so the change is reversible.
+
+## Keep the model list current
+
+Re-sync whenever Pioneer adds models, without launching OpenCode:
```bash
-OPENCODE_ENABLE_EXA=1 opencode
+pioneer integrate opencode sync # add newly available Pioneer models
+pioneer integrate opencode sync --dry-run # preview the changes only
+pioneer integrate opencode sync --all # write the full live catalog
```
-4. Type `/connect` and select `Pioneer` from the drop-down list.
+Switch models inside a running OpenCode session with `/models`.
+
+## Options
-
- 
-
+- `--model ` launches with a specific model and skips the picker.
+- `--level ` sets the reasoning level on models that support it.
+- Anything after the agent name, or after `--`, is passed to OpenCode unchanged.
+- `pioneer integrate --help` shows the full command surface.
-5. Add your Pioneer API key.
-6. Choose `Pioneer Auto` to use Pioneer's model router. Learn more about our model router [here](/concepts/router).
-7. To switch between models, use the `/models` command and select one from our catalog of 70\+ models (and growing).
+## Undo
-Web search runs through OpenCode's built-in Exa tool when `OPENCODE_ENABLE_EXA=1` is set. Allow the `websearch` permission if OpenCode prompts for it. Omit the flag to keep search off.
+```bash
+pioneer integrate restore opencode
+```
-**Integrate OpenCode Desktop app with Pioneer:**
+This reverts the model sync to its pre-integration state. Restores touch only settings; your OpenCode chat history is stored separately and is preserved.
-1. Download and install OpenCode Desktop app
-2. In the app: go to Settings → Providers → Pioneer
-3. Enter your Pioneer API key
-4. In Settings → Models: toggle on the models available in Pioneer model catalog that you'd like to use. Make sure to toggle on `Pioneer Auto` if you'd like to use Pioneer's model router.
+## Troubleshooting
-
- 
-
+
+
+ Run `pioneer integrate opencode sync` to add the rest of the live catalog, then reopen the `/models` picker.
+
+
+ Confirm OpenCode is installed and on your `PATH` (`opencode --version`), then rerun `pioneer integrate opencode`.
+
+
+ Confirm the CLI is logged in with `pioneer auth status`, then rerun the integration so the current key is used.
+
+
From 78192c9986fb953a2dcdac3d1b51507cd3d95c1d Mon Sep 17 00:00:00 2001
From: Samrath <102617759+samrathreddy@users.noreply.github.com>
Date: Thu, 13 Aug 2026 02:19:30 +0530
Subject: [PATCH 2/2] ENG-5731 docs(integrate): CLI-first flags, drop-in key,
kimi-k3 examples
Refine the pioneer integrate rewrite for the 5 agent pages:
- Add a note that pioneer auth login prompts you to drop in your API key.
- Remove pioneer/auto and Code Router references; use kimi-k3 as the model example.
- Add a dedicated ## Flags section (after the steps) documenting the two flag
namespaces truthfully: pioneer integrate --help vs running the agent's own
--help directly, and that Pioneer flags (--model/--level) go before the agent
name while anything after the agent name is forwarded to it.
- Codex and Claude Code show a forwarded dangerous-bypass flag as the example.
- Fix --model ordering to place the flag before the agent name.
---
claude-code.mdx | 27 +++++++++++++++++++--------
codex.mdx | 25 ++++++++++++++++++-------
hermes.mdx | 24 +++++++++++++++++-------
openclaw.mdx | 26 ++++++++++++++++++--------
opencode.mdx | 24 ++++++++++++++----------
5 files changed, 86 insertions(+), 40 deletions(-)
diff --git a/claude-code.mdx b/claude-code.mdx
index 4204ab3..b57f161 100644
--- a/claude-code.mdx
+++ b/claude-code.mdx
@@ -18,6 +18,8 @@ description: "Run Claude Code on Pioneer with pioneer integrate claude, a non-in
npm install -g @fastino-ai/pioneer-cli
pioneer auth login
```
+
+ `pioneer auth login` prompts you to drop in your Pioneer API key.
```bash
@@ -25,24 +27,33 @@ description: "Run Claude Code on Pioneer with pioneer integrate claude, a non-in
```
- Choose a model in the interactive picker, or skip it with `--model pioneer/auto`. `pioneer/auto` uses the Pioneer [Code Router](/concepts/router).
+ Choose a model in the interactive picker, or skip it by passing `--model` before the agent name:
+
+ ```bash
+ pioneer integrate --model kimi-k3 claude
+ ```
## What the command does
-`pioneer integrate claude` launches Claude Code with Pioneer's Anthropic-compatible endpoint configured through in-process environment variables only. Nothing is written to your Claude Code config, and your Claude.ai login is not changed. Select `pioneer/auto` to use the [Code Router](/concepts/router).
+`pioneer integrate claude` launches Claude Code with Pioneer's Anthropic-compatible endpoint configured through in-process environment variables only. Nothing is written to your Claude Code config, and your Claude.ai login is not changed.
## Switch models
-Use `/model` inside Claude Code to pick a specific Pioneer model, or keep `pioneer/auto`.
+Use `/model` inside Claude Code to switch between Pioneer models.
+
+## Flags
-## Options
+The Pioneer CLI has its own flags, and Claude Code has its own. Pioneer flags go before the agent name; anything after the agent name is forwarded to Claude Code.
-- `--model ` launches with a specific model and skips the picker.
-- `--level ` sets the reasoning level on models that support it.
-- Anything after the agent name, or after `--`, is passed to Claude Code unchanged.
-- `pioneer integrate --help` shows the full command surface.
+```bash
+pioneer integrate --help # the Pioneer CLI's integrate options
+pioneer integrate --model kimi-k3 claude # a Pioneer flag: pick a model, then launch
+pioneer integrate --level high claude # a Pioneer flag: set the reasoning level
+pioneer integrate claude --dangerously-skip-permissions # forwarded to Claude Code
+claude --help # Claude Code's own options (run Claude Code directly)
+```
## Undo
diff --git a/codex.mdx b/codex.mdx
index 98a2836..cdcb7ab 100644
--- a/codex.mdx
+++ b/codex.mdx
@@ -18,6 +18,8 @@ description: "Run Codex on Pioneer with pioneer integrate codex, a non-invasive
npm install -g @fastino-ai/pioneer-cli
pioneer auth login
```
+
+ `pioneer auth login` prompts you to drop in your Pioneer API key.
```bash
@@ -25,24 +27,33 @@ description: "Run Codex on Pioneer with pioneer integrate codex, a non-invasive
```
- Choose a model in the interactive picker, or skip it with `--model pioneer/auto`. `pioneer/auto` uses the Pioneer [Code Router](/concepts/router).
+ Choose a model in the interactive picker, or skip it by passing `--model` before the agent name:
+
+ ```bash
+ pioneer integrate --model kimi-k3 codex
+ ```
## What the command does
-`pioneer integrate codex` launches Codex per run with the Pioneer model provider and your Pioneer key supplied through the environment. It does not modify your Codex config files. Select `pioneer/auto` to use the [Code Router](/concepts/router).
+`pioneer integrate codex` launches Codex per run with the Pioneer model provider and your Pioneer key supplied through the environment. It does not modify your Codex config files.
## Switch models
Use `/model` inside Codex to switch between Pioneer models.
-## Options
+## Flags
+
+The Pioneer CLI has its own flags, and Codex has its own. Pioneer flags go before the agent name; anything after the agent name is forwarded to Codex.
-- `--model ` launches with a specific model and skips the picker.
-- `--level ` sets the reasoning level on models that support it.
-- Anything after the agent name, or after `--`, is passed to Codex unchanged.
-- `pioneer integrate --help` shows the full command surface.
+```bash
+pioneer integrate --help # the Pioneer CLI's integrate options
+pioneer integrate --model kimi-k3 codex # a Pioneer flag: pick a model, then launch
+pioneer integrate --level high codex # a Pioneer flag: set the reasoning level
+pioneer integrate codex --dangerously-bypass-approvals-and-sandbox # forwarded to Codex
+codex --help # Codex's own options (run Codex directly)
+```
## Undo
diff --git a/hermes.mdx b/hermes.mdx
index 69c4c5a..d11da80 100644
--- a/hermes.mdx
+++ b/hermes.mdx
@@ -18,6 +18,8 @@ description: "Run Hermes Agent on Pioneer with pioneer integrate hermes, using a
npm install -g @fastino-ai/pioneer-cli
pioneer auth login
```
+
+ `pioneer auth login` prompts you to drop in your Pioneer API key.
```bash
@@ -25,24 +27,32 @@ description: "Run Hermes Agent on Pioneer with pioneer integrate hermes, using a
```
- Choose a model in the interactive picker, or skip it with `--model pioneer/auto`. `pioneer/auto` uses the Pioneer [Code Router](/concepts/router).
+ Choose a model in the interactive picker, or skip it by passing `--model` before the agent name:
+
+ ```bash
+ pioneer integrate --model kimi-k3 hermes
+ ```
## What the command does
-`pioneer integrate hermes` launches Hermes from an isolated home at `~/.pioneer/hermes-home`, writes a Pioneer provider config there, sets `pioneer/auto` as the default, and passes your Pioneer key through the environment. Your everyday `hermes` setup is not modified.
+`pioneer integrate hermes` launches Hermes from an isolated home at `~/.pioneer/hermes-home`, writes a Pioneer provider config there, sets a default model, and passes your Pioneer key through the environment. Your everyday `hermes` setup is not modified.
## Switch models
Use `/model` inside Hermes to switch between Pioneer models.
-## Options
+## Flags
-- `--model ` launches with a specific model and skips the picker.
-- `--level ` sets the reasoning level on models that support it.
-- Anything after the agent name, or after `--`, is passed to Hermes unchanged.
-- `pioneer integrate --help` shows the full command surface.
+The Pioneer CLI has its own flags, and Hermes has its own. Pioneer flags go before the agent name; anything after the agent name is forwarded to Hermes.
+
+```bash
+pioneer integrate --help # the Pioneer CLI's integrate options
+pioneer integrate --model kimi-k3 hermes # a Pioneer flag: pick a model, then launch
+pioneer integrate --level high hermes # a Pioneer flag: set the reasoning level
+hermes --help # Hermes's own options (run Hermes directly)
+```
## Undo
diff --git a/openclaw.mdx b/openclaw.mdx
index c65adbd..379e4a7 100644
--- a/openclaw.mdx
+++ b/openclaw.mdx
@@ -22,6 +22,8 @@ The fastest way to use OpenClaw with Pioneer is the Pioneer CLI. `pioneer integr
npm install -g @fastino-ai/pioneer-cli
pioneer auth login
```
+
+ `pioneer auth login` prompts you to drop in your Pioneer API key.
```bash
@@ -29,24 +31,32 @@ The fastest way to use OpenClaw with Pioneer is the Pioneer CLI. `pioneer integr
```
- Choose a model in the interactive picker, or skip it with `--model pioneer/auto`. `pioneer/auto` uses the Pioneer [Code Router](/concepts/router).
+ Choose a model in the interactive picker, or skip it by passing `--model` before the agent name:
+
+ ```bash
+ pioneer integrate --model kimi-k3 openclaw
+ ```
## What the command does
-`pioneer integrate openclaw` persists a `pioneer` provider in your OpenClaw config (backing the config up first), stores your Pioneer key in OpenClaw's local auth store, registers the live Pioneer model catalog, starts the local gateway service, and opens the dashboard. It sets `pioneer/auto` as the default model.
+`pioneer integrate openclaw` persists a `pioneer` provider in your OpenClaw config (backing the config up first), stores your Pioneer key in OpenClaw's local auth store, registers the live Pioneer model catalog, starts the local gateway service, and opens the dashboard. It selects a default model for you.
## Switch models
Pick a model in the Web UI, or use `/think low`, `/think medium`, `/think high`, or `/think off` to control reasoning on models that support it.
-## Options
+## Flags
-- `--model ` launches with a specific model and skips the picker.
-- `--level ` sets the reasoning level on models that support it.
-- Anything after the agent name, or after `--`, is passed to OpenClaw unchanged.
-- `pioneer integrate --help` shows the full command surface.
+The Pioneer CLI has its own flags, and OpenClaw has its own. Pioneer flags go before the agent name; anything after the agent name is forwarded to OpenClaw.
+
+```bash
+pioneer integrate --help # the Pioneer CLI's integrate options
+pioneer integrate --model kimi-k3 openclaw # a Pioneer flag: pick a model, then launch
+pioneer integrate --level high openclaw # a Pioneer flag: set the reasoning level
+openclaw --help # OpenClaw's own options (run OpenClaw directly)
+```
## Undo
@@ -59,7 +69,7 @@ This stops the gateway and restores your pre-Pioneer OpenClaw config. Restores t
## Troubleshooting
-
+
Run `pioneer integrate restore openclaw`, then `pioneer integrate openclaw` again to re-register the full catalog.
diff --git a/opencode.mdx b/opencode.mdx
index 64181ce..3588a79 100644
--- a/opencode.mdx
+++ b/opencode.mdx
@@ -18,6 +18,8 @@ The fastest way to use OpenCode with Pioneer is the Pioneer CLI. `pioneer integr
npm install -g @fastino-ai/pioneer-cli
pioneer auth login
```
+
+ `pioneer auth login` prompts you to drop in your Pioneer API key.
```bash
@@ -25,13 +27,11 @@ The fastest way to use OpenCode with Pioneer is the Pioneer CLI. `pioneer integr
```
- Choose a model in the interactive picker (per-model thinking levels are shown where supported), or skip the picker with `--model`:
+ Choose a model in the interactive picker (per-model thinking levels are shown where supported), or skip it by passing `--model` before the agent name:
```bash
- pioneer integrate opencode --model pioneer/auto
+ pioneer integrate --model kimi-k3 opencode
```
-
- `pioneer/auto` sends each request through the Pioneer [Code Router](/concepts/router), which picks the cheapest model that meets your quality bar.
@@ -51,12 +51,16 @@ pioneer integrate opencode sync --all # write the full live catalog
Switch models inside a running OpenCode session with `/models`.
-## Options
+## Flags
+
+The Pioneer CLI has its own flags, and OpenCode has its own. Pioneer flags go before the agent name; anything after the agent name is forwarded to OpenCode.
-- `--model ` launches with a specific model and skips the picker.
-- `--level ` sets the reasoning level on models that support it.
-- Anything after the agent name, or after `--`, is passed to OpenCode unchanged.
-- `pioneer integrate --help` shows the full command surface.
+```bash
+pioneer integrate --help # the Pioneer CLI's integrate options
+pioneer integrate --model kimi-k3 opencode # a Pioneer flag: pick a model, then launch
+pioneer integrate --level high opencode # a Pioneer flag: set the reasoning level
+opencode --help # OpenCode's own options (run OpenCode directly)
+```
## Undo
@@ -69,7 +73,7 @@ This reverts the model sync to its pre-integration state. Restores touch only se
## Troubleshooting
-
+
Run `pioneer integrate opencode sync` to add the rest of the live catalog, then reopen the `/models` picker.