@smallnest: Rewrote pi agent in Go again. Previously rewrote to replicate openclaw, this time purely for its small size and agility. Also wrote a book for the project: https://github.com/smallnest/pigo

X AI KOLs Timeline Tools

Summary

pigo is a command-line AI Agent rewritten in Go, supporting headless script mode and interactive REPL, capable of reading/writing files, executing commands, searching code, and compatible with multiple large model protocols, accompanied by an e-book.

Rewrote pi agent in Go again. Previously rewrote to replicate openclaw, this time purely for its smallness and agility. Also wrote a book for the project: https://t.co/QuYqXR4CZW https://t.co/jIiZhn79Q7
Original Article
View Cached Full Text

Cached at: 07/24/26, 07:06 AM

Rewriting pi agent in Go again. The previous rewrite was to clone openclaw; this time it’s purely for its small and lightweight nature. I also wrote a book specifically for this project: https://t.co/QuYqXR4CZW https://t.co/jIiZhn79Q7 — # smallnest/pigo Source: https://github.com/smallnest/pigo # pigo CI (https://github.com/smallnest/pigo/actions/workflows/ci.yml) Release (https://github.com/smallnest/pigo/actions/workflows/release.yml) A Go port of the pi (https://pi.dev) AI Agent — a coding agent for the command line that supports both headless script mode and interactive REPL. pigo can read and write files, execute commands, search code, fetch web pages, and leverage large models to complete the cycle from “understanding requirements” to “modifying code.” It is compatible with multiple protocol gateways such as OpenAI / Anthropic, and supports session resumption, project trust, skills, plugins, and package management. > Module path: github.com/smallnest/pigo · Go 1.27+ > 📖 Companion eBook “Writing a pi Agent in Go”: write_pi_agent_in_go.pdf (https://github.com/smallnest/ebooks/blob/master/write_pi_agent_in_go.pdf) — ## Table of Contents - Features at a Glance - Architecture Overview - Installation & Building - Quick Start - Command-Line Arguments - Models & Providers - Built-in Tools - Operation Modes - System Prompt Assembly - Project Trust - Skills - Plugins - Package Management - Release - Directories & Environment Variables - Security Notes — ## Features at a Glance - Two modes: Headless -p for one-shot execution (ideal for scripts/CI), or directly enter interactive REPL. - Multiple Providers: OpenRouter (default), local Ollama, NVIDIA NIM, Anthropic, and any OpenAI-compatible endpoint. - Built-in tool set: read / write / edit / grep / find / bash / todo / webfetch. - Session resumption: --list-sessions / --resume / --continue, supported in both headless and REPL modes. - stream-json output: Line-by-line JSON events; the first event carries a session_id for caller correlation. - Layered system prompt assembly: base instructions + environment block + AGENTS.md (general → specific) + --append-system-prompt. - Project trust: Side-effect tools (bash/write/edit) require confirmation in untrusted directories; --approve grants one-time authorization. - Skills and Plugins: /slash commands from ~/.agents/skills, external plugins from ~/.pigo/plugins. - Automatic context compression: Summarizes when approaching the context window limit; /compact also triggers manually. - Package management: pigo install npm: to install pi ecosystem extensions / skills / prompts / themes. — ## Architecture Overview pigo’s runtime layered architecture: Request path goes from user through CLI, Agent loop, Provider layer to the LLM gateway; tool path from loop through tool executor and trust gate to local environment; complemented by session storage and context compression, with trust boundaries and external network boundaries marked. pigo Architecture Overview > More layered diagrams (event skeleton, unified Provider, batch tool execution, sub-agent delegation, etc.) are available in the companion eBook. ### Agent Two-Layer Loop The core at runtime is the two-layer loop in internal/runtime/loop.go: the inner turn loop repeatedly executes “stream reply → dispatch on stop reason → execute tool → backfill” until a conversation turn ends without tool calls; the outer loop, after the inner loop converges, consumes GetFollowUpMessages; if there are subsequent messages, it re-enters the inner loop, otherwise ends. All termination paths (natural end / error / aborted / stop hook / no follow-up messages) converge at the single exit finish(). pigo Agent Two-Layer Loop > The interactive version (with summary card) is at docs/agent-loop-flowchart.html. — ## Installation & Building Requires Go 1.27 or higher. bash # Clone the repository git clone https://github.com/smallnest/pigo.git cd pigo # Build the binary (produces ./pigo) go build ./cmd/pigo # Or install to $GOPATH/bin go install ./cmd/pigo # Or run directly without building go run ./cmd/pigo -p "1+1=?" After building, check the version (version number injected by goreleaser during official releases; source builds show dev): bash pigo --version # pigo dev (commit none, built unknown) ### One-Line Install Script (Linux / macOS) install.sh automatically detects the OS/architecture, downloads the latest pre-built binary from GitHub Releases, and installs it to a common PATH directory: bash curl -fsSL https://raw.githubusercontent.com/smallnest/pigo/master/install.sh | sh Environment variables to override defaults: | Variable | Description | |–––––|———––| | PIGO_VERSION | Specify installation version (e.g., v0.2.0); defaults to latest release | | PIGO_INSTALL_DIR | Install directory, default /usr/local/bin (falls back to ~/.local/bin if not writable) | | GITHUB_TOKEN | Optional, for higher GitHub API rate limits | bash # Specify version and install directory PIGO_VERSION=v0.2.0 PIGO_INSTALL_DIR="$HOME/bin" \ curl -fsSL https://raw.githubusercontent.com/smallnest/pigo/master/install.sh | sh > Windows: Download .zip from the Releases page and extract manually. ### Download Pre-built Binaries The Releases page provides pre-built packages for Linux / macOS / Windows on amd64 and arm64 (built by goreleaser). Download the archive for your platform and extract it. — ## Quick Start bash # 1. Configure default Provider (OpenRouter) API Key export OPENROUTER_API_KEY=sk-or-... # 2. Headless mode: run a prompt and print the final answer pigo -p "Read the README and summarize it in three sentences" # 3. Enter interactive REPL (if no -p and stdout is a terminal, automatically enters) pigo # 4. Use local Ollama model, no internet needed pigo -m ollama/qwen2.5-coder -u http://localhost:11434/v1 -p "Explain what main.go does" — ## Command-Line Arguments | Long Argument | Short | Default | Description | |—————|—––|———|———––| | --print | -p | "" | Prompt for headless print mode (also accepts positional argument) | | --model | -m | openrouter/free | Model ID to use | | --base-url | -u | "" | Override Provider base URL (e.g., local Ollama) | | --api-key | -k | "" | Specify Provider API Key (overrides env/config, otherwise reads _API_KEY) | | --protocol | -P | "" | Force wire protocol: openai or anthropic (inferred from model ID by default) | | --output-format | -o | text | Output format: text or stream-json | | --no-tools | -n | false | Disable built-in file/shell tools (also skips plugin discovery) | | --list-sessions | -l | false | List stored sessions and exit | | --resume | -r | "" | Resume a session with the given ID | | --continue | -c | false | Resume the most recent session | | --approve | -a | false | Trust the working directory for this run: skip initial trust prompt, no per-confirmation for side-effect tools | | --no-skills | | false | Disable skill discovery (don’t load ~/.agents/skills as /skill-name commands) | | --system-prompt | | "" | Replace the default coding-assistant prompt with a custom system prompt | | --append-system-prompt | | nil | Append text or file content to the end of the system prompt; can be repeated | | --version | -v | false | Print version info and exit | > --subagent-rpc is an internal parameter (for sub-agent process-isolated JSON-RPC server), not for direct use. Usage examples: bash # Positional argument equivalent to -p pigo "Rename getUserName to getUsername in utils.go" # Specify model pigo -m anthropic/claude-3.5-sonnet -p "Review foo.go for concurrency safety" # Custom system prompt (replaces default) pigo --system-prompt "You are a Go expert who only answers in Chinese" -p "What is a goroutine leak?" # Append system prompt: can be repeated; if value is a file path, read file content, otherwise use literal text pigo --append-system-prompt ./CONVENTIONS.md \ --append-system-prompt "Keep answers concise" \ -p "Add unit tests for this package" # Authorize working directory for one run, skipping per-confirmation for bash/write/edit pigo -a -p "Run go test ./... and fix failing tests" — ## Models & Providers The model ID is mapped to a specific Provider via heuristic rules (--protocol takes highest priority when explicitly specified): 1. Explicit --protocolopenai (requires --base-url) or anthropic (default public Anthropic API). 2. Pre-configured directory match → uses the Provider declared in the built-in directory (use /models in REPL to view, /model to switch). 3. ollama/ prefix or base URL containing 11434 → local Ollama. 4. nvidia/ prefix → NVIDIA NIM. 5. Inference from model name → when --provider/--protocol/--base-url are not set, infer from known prefixes of the model name to its first-party built-in Provider (e.g., -m claude-opus-4-8 directly connects to Anthropic, no need to write --provider). 6. Everything else → OpenRouter (default). > Priority: Explicit flags (--provider > --protocol) > Pre-configured directory > ollama//nvidia/ prefix > Model name inference > OpenRouter default. Explicit --provider always wins; if --base-url is given, it is treated as a custom endpoint signal, skipping step 5 inference. Model name prefix inference table (only infers prefixes that uniquely determine a Provider; llama-*, qwq-*, gemma-*, mixtral-* and other families served by multiple gateways, and routed IDs like provider/model, are not inferred, falling back to OpenRouter): | Model Name Prefix | Inferred Provider | |—————––|—————––| | claude-* | anthropic | | gpt-* / o1-* / o3-* / o4-* | openai | | gemini-* | google | | deepseek-* | deepseek | | glm-* | zai | | kimi-* / moonshot-* | moonshotai | | qwen-* | dashscope | | ernie-* | qianfan | | doubao-* | volcengine | | grok-* | xai | | mistral-* / codestral-* / devstral-* | mistral | | hunyuan-* | hunyuan | | minimax-* | minimax | | mimo-* | xiaomi | Matching is case-insensitive. Once inferred, it follows the same resolution path as explicit --provider, using that Provider’s default base URL, protocol, and _API_KEY environment variable. | Provider | Wire Format | Default Base URL | API Key Environment Variable | |–––––|———––|—————–|—————————––| | OpenRouter (default) | OpenAI Chat Completions | https://openrouter.ai/api/v1 | OPENROUTER_API_KEY | | Ollama (local) | OpenAI compatible | http://localhost:11434/v1 | None (local) | | NVIDIA NIM | OpenAI compatible | https://integrate.api.nvidia.com/v1 | NVIDIA_API_KEY / NVIDIA_NIM_API_KEY | | OpenAI compatible | OpenAI Chat Completions | Must provide --base-url | OPENAI_API_KEY | | Anthropic | Anthropic Messages | https://api.anthropic.com/v1 | ANTHROPIC_API_KEY / CLAUDE_API_KEY | Key resolution order: OAuth token → --api-key → environment variable → config file. Other Providers (google/deepseek/xai/groq/mistral, etc.) follow _API_KEY convention. Usage examples: bash # Default OpenRouter export OPENROUTER_API_KEY=sk-or-... pigo -p "Write a quicksort" # Any OpenAI-compatible endpoint, force openai protocol pigo -P openai -u https://my-gateway.example.com/v1 -m my-model -k $MY_KEY -p "..." # Public Anthropic API export ANTHROPIC_API_KEY=sk-ant-... pigo -P anthropic -m claude-3-5-sonnet-20241022 -p "..." — ## Built-in Tools The tools operate relative to the current working directory; --no-tools disables them entirely. | Tool | Description | |——|———––| | read | Read a text file by path, supports line offset/limit, output with line numbers, truncates large files | | write | Create or overwrite a file, creating parent directories as needed | | edit | Precise string replacement (old_string must be unique unless replace_all), returns diff | | grep | Regex search in file content, supports glob filters, skips .gitignore paths | | find | Search for files by name glob, skips .gitignore paths | | bash | Execute shell commands, streaming stdout/stderr, supports timeout and cancellation | | todo | Record/update structured task list; submits the entire list each time (pending/in_progress/completed) | | webfetch | Fetch a URL and convert to concise Markdown body; HTTP auto-upgrades to HTTPS | > bash / write / edit are “side-effect tools” and require confirmation in untrusted directories (see Project Trust). — ## Operation Modes bash # Headless print mode: only output the final answer text pigo -p "Summarize the architecture of this repository" # stream-json: line-by-line JSON events, first event includes session_id pigo -p "List all Go files" --output-format stream-json # Interactive REPL: enter when no -p and stdout is a terminal pigo # Session management pigo --list-sessions # List sessions pigo --resume 20260720-1530-abcd # Resume a specific session (headless/REPL both work) pigo --continue # Resume the most recent session Built-in slash commands in REPL include /model, /models, /help, /compact, /fork, /clone, /tree, /export, /import, /copy, /session, /exit, and more. When typing in the interactive terminal, pigo shows gray text hinting at the most recent matching input or slash command; typing /model also matches from recently used models and the built-in model directory. Press Tab or right arrow to accept the current hint; when multiple matches exist, press up/down arrows to cycle through candidates; continuing typing narrows the match in real time. — ## System Prompt Assembly The system prompt is assembled in three layers (internal/runtime/prompt.go): 1. Base instructions: The default coding-assistant prompt; can be replaced entirely with --system-prompt. 2. Environment block: Working directory, OS/architecture, current date. 3. AGENTS.md injection: From the repository root to the current working directory, from general to specific concatenation — the AGENTS.md closer to the working directory (more specific) is placed later, thus higher priority. Content from --append-system-prompt is appended at the end, in argument order; each value is read from a file if it exists and is a regular file, otherwise used as literal text; empty entries are skipped. — ## Project Trust Side-effect tools (bash / write / edit) require per-confirmation in untrusted or undecided directories. Trust state is persisted as JSON per directory in three states: Trusted / Untrusted / Undecided. - When first starting REPL in a directory, you will be asked whether to trust it. - --approve / -a grants session-level trust for this run, skipping the initial prompt and per-confirmation. — ## Skills Skills are Markdown files with YAML frontmatter (name, description, optional allowed-tools, model) located in ~/.agents/skills (overridable with PIGO_SKILLS_DIR): - Supports flat *.md files and nested /SKILL.md files. - Each skill is exposed in REPL as a /skill-name slash command (expands the body as a prompt, supports $ARGUMENTS substitution), and can also be run as a sub-agent tool. - --no-skills disables skill discovery; malformed skills are non-fatally skipped. — ## Plugins External plugins are discovered from $PIGO_HOME/plugins (default ~/.pigo/plugins): - Fault-tolerant discovery: plugins that fail to start are logged and skipped. - Plugins can provide additional tools and subscribe to Agent lifecycle events. - --no-tools will skip plugin discovery entirely. — ## Package Management Install packages from the pi ecosystem (extensions / skills / prompts / themes). install requires npm in PATH. bash # Install (currently only supports npm: source, supports scoped packages and version pinning) pigo install npm:pi-mcp-adapter pigo install npm:@scope/[email protected] # List installed packages pigo list # Update (update all if no arguments) pigo update pigo update pi-mcp-adapter # Uninstall pigo uninstall pi-mcp-adapter Package types (extension / skill / prompt / theme) are distributed to their respective directories; install records are written to a lockfile. — ## Release Uses goreleaser to build cross-platform binaries and publish to GitHub Releases. bash # Validate configuration goreleaser check # Local dry-run (snapshot, no publish) goreleaser release --snapshot --clean # Official release: create and push a tag; GitHub Actions triggers automatically git tag -a v0.2.0 -m "v0.2.0" git push origin v0.2.0 Pushing a v* tag triggers .github/workflows/release.yml, which uses goreleaser to build archives for Linux/macOS/Windows × amd64/arm64, generate checksums, and create a Release. Version / commit / build time are injected via -ldflags into the main package; view with pigo --version. — ## Directories & Environment Variables | Variable / Path | Purpose | |—————–|———| | PIGO_HOME | Override ~/.pigo base directory (affects plugins and commands) | | PIGO_SKILLS_DIR | Override skills directory (default ~/.agents/skills) | | ~/.pigo/sessions | Session storage (JSONL) | | ~/.pigo/plugins | External plugins | | ~/.pigo/commands | User-defined command templates | | _API_KEY | API Key for each Provider (see Models & Providers) | ### Built-in Provider Overview (--provider) --provider directly selects a built-in Provider, using its default base URL, protocol, and API Key environment variable (overridable with --base-url or _BASE_URL, and key via --api-key or the corresponding environment variable). The table below matches the registry in internal/provider/registry.go; pigo --help also lists the same reference. | provider | Environment Variable (priority order) | Default base_url | Protocol | |–––––|––––––––––––––––––––|——————|–––––| | anthropic | ANTHROPIC_OAUTH_TOKEN / ANTHROPIC_API_KEY / CLAUDE_API_KEY | https://api.anthropic.com/v1 | anthropic | | openai | OPENAI_API_KEY | https://api.openai.com/v1 | openai | | ant-ling | ANT_LING_API_KEY | https://api.ant-ling.com/v1 | openai | | deepseek | DEEPSEEK_API_KEY | https://api.deepseek.com | openai | | nvidia | NVIDIA_API_KEY / NVIDIA_NIM_API_KEY | https://integrate.api.nvidia.com/v1 | openai | | google | GEMINI_API_KEY / GOOGLE_API_KEY | https://generativelanguage.googleapis.com/v1beta | openai | | groq | GROQ_API_KEY | https://api.groq.com/openai/v1 | openai | | cerebras | CEREBRAS_API_KEY | https://api.cerebras.ai/v1 | openai | | xai | XAI_API_KEY | https://api.x.ai/v1 | openai | | openrouter | OPENROUTER_API_KEY | https://openrouter.ai/api/v1 | openai | | vercel-ai-gateway | AI_GATEWAY_API_KEY | https://ai-gateway.vercel.sh | openai | | zai | ZAI_API_KEY | https://api.z.ai/api/coding/paas/v4 | openai | | zai-coding-cn | ZAI_CODING_CN_API_KEY | https://open.bigmodel.cn/api/coding/paas/v4 | openai | | mistral | MISTRAL_API_KEY | https://api.mistral.ai | openai | | minimax | MINIMAX_API_KEY | https://api.minimax.io/anthropic | anthropic | | minimax-cn | MINIMAX_CN_API_KEY | https://api.minimaxi.com/anthropic | anthropic | | moonshotai | MOONSHOT_API_KEY | https://api.moonshot.ai/v1 | openai | | moonshotai-cn | MOONSHOT_API_KEY | https://api.moonshot.cn/v1 | openai | | huggingface | HF_TOKEN | https://router.huggingface.co/v1 | openai | | fireworks | FIREWORKS_API_KEY | https://api.fireworks.ai/inference | openai | | together | TOGETHER_API_KEY | https://api.together.ai/v1 | openai | | opencode | OPENCODE_API_KEY | https://opencode.ai/zen | openai | | opencode-go | OPENCODE_API_KEY | https://opencode.ai/zen/go | openai | | kimi-coding | KIMI_API_KEY | https://api.kimi.com/coding | openai | | xiaomi | XIAOMI_API_KEY | https://api.xiaomimimo.com/v1 | openai | | xiaomi-token-plan-cn | XIAOMI_TOKEN_PLAN_CN_API_KEY | https://token-plan-cn.xiaomimimo.com/v1 | openai | | xiaomi-token-plan-ams | XIAOMI_TOKEN_PLAN_AMS_API_KEY | https://token-plan-ams.xiaomimimo.com/v1 | openai | | xiaomi-token-plan-sgp | XIAOMI_TOKEN_PLAN_SGP_API_KEY | https://token-plan-sgp.xiaomimimo.com/v1 | openai | | qianfan | QIANFAN_API_KEY | https://qianfan.baidubce.com/v2 | openai | | volcengine | ARK_API_KEY / VOLCENGINE_API_KEY | https://ark.cn-beijing.volces.com/api/v3 | openai | | dashscope | DASHSCOPE_API_KEY | https://dashscope.aliyuncs.com/compatible-mode/v1 | openai | | hunyuan | HUNYUAN_API_KEY | https://api.hunyuan.cloud.tencent.com/v1 | openai | | azure-openai-responses | AZURE_OPENAI_API_KEY (+ AZURE_OPENAI_BASE_URL / AZURE_OPENAI_RESOURCE_NAME) | Assembled from environment variables | openai (Azure) | | amazon-bedrock | AWS_BEARER_TOKEN_BEDROCK (or AWS_PROFILE / AWS_ACCESS_KEY_ID+AWS_SECRET_ACCESS_KEY; AWS_REGION defaults to us-east-1) | https://bedrock-runtime.{AWS_REGION}.amazonaws.com | anthropic | | google-vertex | GOOGLE_CLOUD_API_KEY (or ADC) + GOOGLE_CLOUD_PROJECT + GOOGLE_CLOUD_LOCATION | https://{location}-aiplatform.googleapis.com | openai | | cloudflare-workers-ai | CLOUDFLARE_API_KEY + CLOUDFLARE_ACCOUNT_ID | https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1 | openai | | cloudflare-ai-gateway | CLOUDFLARE_API_KEY + CLOUDFLARE_ACCOUNT_ID + CLOUDFLARE_GATEWAY_ID | https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/anthropic | anthropic | > base_url override priority: --base-url > provider-specific *_BASE_URL environment variable > generalized _BASE_URL (uppercase provider name, - to _) > registry default. Any Provider also supports the generalized _API_KEY convention as a key fallback. > For Volcano Engine (volcengine), some models need to be called with an endpoint ID rather than the model name; use -m to specify accordingly. The pre-configured doubao-seed-1-6 uses the model name approach. — ## Security Notes - pigo makes external network requests to the resolved Provider endpoints. - bash / write / edit produce local side effects, guarded only by the project trust mechanism; --approve skips per-confirmation, use only in trusted directories, weighing convenience against safety. - Content from external sources (files, command output, web pages, etc.) should be treated as untrusted data. — ## License See LICENSE in the repository root.

Similar Articles

@oragnes: Recently discovered a hardcore open-source project from Harness: pi (recently moved under earendil-works from badlogic). It is an all-in-one AI Agent infrastructure suite plus a terminal programming assistant CLI designed to backstop developers. Stop reinventing the wheel: it provides a ready-made…

X AI KOLs Timeline

Pi is an open-source AI Agent infrastructure suite and terminal programming assistant CLI. It offers a unified API to bridge differences between multiple models, supports concurrent tool calling to reduce latency, and allows developers to control the thinking budget.

@qloog: #DailyRecommendation Google ADK Go - An open-source Agent development framework released by Google. Objective: Build AI Agents using software engineering principles. Core design philosophy: 1. Code-first: Define Agent logic, tools, and orchestration using Go code, rather than...

X AI KOLs Timeline

Google has released ADK for Go, an open-source Agent development framework, designed to build AI agents through software engineering principles, supporting code-first approaches, model-agnosticism, and cloud-native deployment.

@GitHub_Daily: Today on the GitHub Trending list, I saw oh-my-pi, an open-source coding agent that brings the core capabilities of an IDE directly into the terminal. It's quite interesting. It comes with 32 built-in tools that can interface with the editor's language services and debugger. Operations like renaming, jumping to references, and breakpoint debugging can be done by the AI itself without manual switching...

X AI KOLs Timeline

oh-my-pi is an open-source coding agent that integrates core IDE capabilities (such as language services and debugger) into the terminal, featuring 32 built-in tools, support for parallel processing with multiple sub-agents, and compatibility with over 40 model providers.