AntSeed — Integration Skill
This file is the agent-readable companion to https://antseed.com/integrations.
It tells any AI agent (Claude, Codex, OpenClaw, Hermes, custom) exactly
how to wire its tool of choice up to the AntSeed peer-to-peer inference network.
What is AntSeed?
AntSeed is a peer-to-peer marketplace for AI inference. Buyers run a small
local daemon (the buyer proxy) that exposes an HTTP API at
http://localhost:8377 speaking the three caller-facing LLM API protocols:
Anthropic Messages, OpenAI Chat Completions, and OpenAI Responses. Legacy
OpenAI Completions is supported internally for adapter translation. The proxy
discovers providers on a DHT, routes the
request to a peer, translates between protocols when needed (via
@antseed/api-adapter), and settles in USDC on Base.
Important: AntSeed is for value-added AI services (specialized models, agents,
TEEs, fine-tunes, managed workflows), not raw resale of API keys or subscription
access. Providers must comply with upstream terms of service.
From the perspective of any tool, SDK, or agent, AntSeed is just a local
OpenAI/Anthropic-compatible endpoint — point a base_url at it and you are done.
Glossary (mental model)
Buyer proxy — the local server on localhost:8377 that accepts API calls
from your tools and forwards them to AntSeed peers. It is the only thing your
editor / agent / SDK ever talks to.
Peer — someone selling inference. Each peer has a peerId (40-char hex),
a display name, and a list of services. List with antseed network browse.
Service — a single model id like claude-sonnet-4-6 or deepseek-v4-flash.
This is what you pass as model in your tool's config. Each service has its
own native protocol list and its own in / cachedIn / out pricing.
Protocols (per service) — the wire formats a service accepts natively,
advertised on each peer in providerServiceApiProtocols[provider].services[service].
Values are anthropic-messages,
openai-chat-completions, openai-responses, openai-completions. This is
the field to match your tool's wire format against. If your tool's wire format
is in this list, the request passes through untouched; if not, the api-adapter
translates on the fly.
Cached input pricing — services charge a separate, much lower rate
(typically 4–10×) for tokens that are reused across requests: system prompts,
tool schemas, prior conversation turns, long files you keep referencing. The CLI
exposes it as cachedInputUsdPerMillion. For long-running agents and chatbots,
this is often the dominant cost line.
Pin — telling the buyer proxy "route requests to this peer." In the
default manual flow, there is no peer auto-selection; you must choose a peer,
send a per-request pin header, or start the proxy with a router plugin that
performs selection. Common explicit routes:
- Session pin:
antseed buyer connection set --peer <peerId>. Persists in
~/.antseed/buyer.state.json and applies to every request until you change it.
- Per-request header:
x-antseed-pin-peer: <peerId> on each call. Overrides
the session pin for that request, and works without any session pin at all.
- Model prefix: set
model to <peerId>@<service>. The proxy uses the
prefix as the peer pin and forwards only <service> to the seller.
If both header and model-prefix pins are present, the header selects the peer;
the model prefix is still stripped before routing.
Until at least one of these is in effect, every request returns no_peer_pinned.
Universal setup (do this once)
Option A — AntStation desktop app (easiest)
Download from https://antseed.com — it ships the buyer proxy, a wallet, and a
peer browser in a GUI. While the app is open the proxy is reachable at
http://localhost:8377.
Option B — CLI (headless / servers / agents)
# 1. Install
npm install -g @antseed/cli
# 2. Identity (an EVM private key — 64 hex chars). Save this somewhere safe;
# you will reuse it across machines and it controls your USDC deposits.
export ANTSEED_IDENTITY_HEX=$(openssl rand -hex 32)
# SECURITY: never paste this key into chat, logs, GitHub issues, or a file
# committed to git. It controls the buyer identity and access to deposits.
# 3. Start the buyer proxy on :8377
antseed buyer start &
# 4. Browse the network and list every service (= model) each peer offers,
# along with its native protocols and USD-per-1M-tokens pricing.
# `service` is the model id you pass to your tool. `protocols` is the
# wire format(s) the service accepts natively — match it against your
# tool. `in` / `cachedIn` / `out` are fresh-input / cached-input / output.
antseed network browse --json --top 5 \
| jq '.peers | map({
peerId, name: .displayName,
services: [
(.providerServiceApiProtocols | to_entries[]) as $p
| ($p.value.services | to_entries[]) as $s
| {
service: $s.key,
protocols: $s.value,
in: (.providerPricing[$p.key].services[$s.key].inputUsdPerMillion // .providerPricing[$p.key].defaults.inputUsdPerMillion),
cachedIn: (.providerPricing[$p.key].services[$s.key].cachedInputUsdPerMillion // null),
out: (.providerPricing[$p.key].services[$s.key].outputUsdPerMillion // .providerPricing[$p.key].defaults.outputUsdPerMillion)
}
]
})'
# 5. Inspect one peer in detail. Use `matchingServices[]` for pricing/tags and
# `peer.providerServiceApiProtocols` for native protocol support.
# `cachedIn` is typically 4–10× cheaper than `in` and often dominates the
# cost line for long-running agents and chatbots — always include it when
# comparing peers.
antseed network peer <peerId> --json \
| jq '{
peer: (.peer | { peerId, name: .displayName,
sessions: .onChainChannelCount,
ghosts: .onChainGhostCount }),
services: [
(.peer.providerServiceApiProtocols | to_entries[]) as $p
| ($p.value.services | to_entries[]) as $s
| (.matchingServices[] | select(.provider == $p.key and .service == $s.key)) as $m
| {
provider: $p.key,
service: $s.key,
protocols: $s.value,
in: $m.inputUsdPerMillion,
cachedIn: $m.cachedInputUsdPerMillion,
out: $m.outputUsdPerMillion,
tags: $m.tags
}
]
}'
# 6. Pin a peer (session-wide). Until you do, every request returns
# `no_peer_pinned` UNLESS the request includes an `x-antseed-pin-peer`
# header (see Per-request peer selection below).
antseed buyer connection set --peer <peerId>
# 7. Verify the proxy advertises the services you expect
curl -s http://localhost:8377/v1/models | jq '.data[].id'
# 8. (Optional) Deposit USDC on Base for paid services
antseed payments # opens portal at 127.0.0.1:3118?token=<hex> — connect a wallet, deposit USDC
Security notes for agents and deploys
- Treat
ANTSEED_IDENTITY_HEX / ~/.antseed/identity.key as a hot wallet key.
Never print it, paste it into chat, commit it, or copy it off the buyer host.
- Keep the buyer proxy bound to
127.0.0.1 / localhost. Do not expose
:8377 directly to the public internet; use SSH tunnels or a private network
if another process must reach it remotely.
- Start with small USDC deposits and conservative reserve caps for autonomous
agents. The funding wallet does not need to stay connected after depositing.
- If a tool requires an API key, use a non-secret placeholder such as
antseed;
the buyer proxy authenticates with the local identity key instead.
Endpoints exposed by the buyer proxy
| Path |
Wire format |
Common callers |
POST /v1/messages |
Anthropic Messages |
Claude Code, Anthropic SDKs, OpenClaw |
POST /v1/chat/completions |
OpenAI Chat Completions |
Codex, Hermes, OpenAI SDKs, Vercel AI SDK, LangChain, most tools |
POST /v1/responses |
OpenAI Responses |
Codex (newer builds), tools using the Responses API |
All four protocols (including legacy openai-completions) are supported by
@antseed/api-adapter for translation, but only the three endpoints above are
exposed to callers. Translation is automatic: a request that arrives in one
format and is routed to a peer whose service advertises a different protocols
value is transformed both directions (request and streaming response).
No Authorization header is required by the buyer proxy. It authenticates and
pays peers using the local node's identity key and on-chain USDC deposits.
Per-request peer selection (no session pin needed)
Two ways to tell the proxy which peer to use:
- Session pin —
antseed buyer connection set --peer <peerId>. Persists in
~/.antseed/buyer.state.json (pinnedPeerId) and applies to every request
until you change it. Best for single-tenant setups (laptops, dedicated agents).
- Per-request header — send
x-antseed-pin-peer: <peerId> on each call.
Overrides the session pin for that one request. You do not need to call
antseed buyer connection set at all if every request includes this header
— the proxy will accept and route them. Best for scripts, schedulers, and
multi-tenant deployments that need to fan out to different peers per call.
Example (per-request, no session pin):
curl http://localhost:8377/v1/chat/completions \
-H 'content-type: application/json' \
-H 'x-antseed-pin-peer: 4668854ba3e8b094e6f48fbeb59cec1cfde162f2' \
-d '{ "model": "minimax-m2.7", "messages": [{"role":"user","content":"hi"}] }'
Other optional headers:
x-antseed-provider: <providerName> — when a peer exposes the same service
through more than one seller-plugin (rare), force a specific one. Most tools
never need this.
Files the CLI creates in ~/.antseed/
Knowing what lives in ~/.antseed/ matters for backups, container deploys,
and debugging. The directory is created on first antseed buyer start (or
first run of any antseed command that needs it).
| Path |
Purpose |
Survives restart? |
Safe to delete? |
identity.key |
Raw 32-byte EVM private key for the buyer wallet. Fallback when ANTSEED_IDENTITY_HEX is not set. |
yes |
NO — deleting loses access to your USDC deposits. Back this up. |
identity.enc |
Encrypted copy of identity.key (when the desktop app sets a passphrase). |
yes |
only if identity.key is also intact |
config.json |
Static settings: chain id, proxy port, max-pricing caps, bootstrap nodes, payments preferences. Hand-editable. |
yes |
yes (defaults are sane) |
buyer.state.json |
Live runtime state: pinnedPeerId, the discovered-peers cache (discoveredPeers), on-chain stats, the proxy pid and port. Re-built from the network on next start. |
yes (the pin survives restart) |
yes (you lose the pin and the cached peer list — next browse will repopulate) |
metering.db |
SQLite log of every request the proxy served (model, peer, tokens, USDC). Used by antseed buyer status and the payments portal. |
yes |
yes (you lose request history; settlement is unaffected) |
payments/ |
Per-channel state used by the seller-side settlement flow (only relevant if you also run antseed seller). |
yes |
only if you do not run a seller |
plugins/ |
Cache of downloaded provider plugins. |
yes |
yes (re-downloaded on next use) |
chat/, projects/ |
Used by the desktop app for local chat history. Empty on a CLI-only setup. |
yes |
yes |
config.json (commonly edited)
{
"buyer": {
"proxyPort": 8377, // change if 8377 conflicts on the host
"minPeerReputation": 0, // optional: raise to filter lower-reputation peers
"maxPricing": { // refuse to route to peers above this rate
"defaults": { "inputUsdPerMillion": 100, "outputUsdPerMillion": 100 }
}
},
"payments": {
"preferredMethod": "crypto",
"crypto": { "chainId": "base-mainnet" } // or "base-sepolia" for testnet
},
"network": { "bootstrapNodes": [] } // empty = use built-in defaults
}
Edit, then restart the buyer proxy. Do not hardcode contract addresses —
the chain preset (base-mainnet / base-sepolia) resolves Deposits, Channels,
USDC, and the RPC URL automatically.
buyer.state.json (read-only in practice)
Top-level fields that an agent might want to inspect:
pinnedPeerId — the currently pinned peer (or null).
pid / port — the running proxy. If pid is non-null but the process is gone, antseed buyer start will detect the stale lockfile and clean up.
discoveredPeers — cached peer list from the last DHT browse. Refreshed on antseed network browse.
peersUpdatedAt, onChainStatsRefreshedAt — cache timestamps (epoch millis).
To force a clean reset of pin + caches without losing your wallet:
antseed buyer stop || true
rm ~/.antseed/buyer.state.json
antseed buyer start &
How to integrate
Below is every integration we currently document. Find your tool, copy the
config block, done. If your tool is not listed but accepts a custom OpenAI or
Anthropic base URL, follow the closest example (or look at the curl / Raw
HTTP entry — the contract is stable).
Claude Code
Anthropic's official CLI agent — launch through AntSeed with antseed claude.
TL;DR for agents: Prefer antseed claude --model <service-id>. It sets ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY for Claude Code. Manual equivalent: set ANTHROPIC_BASE_URL=http://localhost:8377 and ANTHROPIC_API_KEY=antseed, then run claude --model <service-id>.
Claude Code is the official CLI coding agent from Anthropic. It speaks the Anthropic Messages API natively, so it slots into AntSeed through the antseed claude wrapper or by pointing ANTHROPIC_BASE_URL at your local proxy.
antseed claude resolves the active buyer proxy, sets the placeholder Anthropic API key for the child process, and forwards the rest of your Claude Code flags unchanged. Manual environment variables still work if you want to run claude directly.
No real Anthropic API key is needed — the AntSeed proxy authenticates each request with your local identity (ANTSEED_IDENTITY_HEX) and settles payments on-chain. The ANTHROPIC_API_KEY value is required by the Anthropic SDK only as a non-empty placeholder.
When Claude Code calls the Messages API, the proxy forwards the request to the peer you pinned in step 3 of the setup above. Whichever service ids that peer advertises (visible in antseed network peer <peerId>) become the valid --model values.
Install
Configure
antseed claude --model claude-sonnet-4-6
Recommended: the wrapper reads the active buyer proxy from buyer.state.json or config, sets ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY for Claude Code, and forwards extra Claude args. Add --antseed-base-url http://host:port only when your proxy is somewhere else.
export ANTHROPIC_BASE_URL="http://localhost:8377"
export ANTHROPIC_API_KEY="antseed"
Manual equivalent if you want to run claude directly instead of through antseed claude.
Suggested models: claude-sonnet-4-6, claude-opus-4-7, deepseek-v4-flash
antseed claude --model <service-id> passes the value to Claude Code unchanged. The valid set is whatever your pinned peer advertises — see the discovery commands below.
Test it
- See which models your pinned peer offers
curl -s http://localhost:8377/v1/models | jq '.data[].id'
Example response:"claude-opus-4-7"
"claude-sonnet-4-6"
"deepseek-v4-flash"
"gpt-oss-120b"
These are the only ids that work with --model. To switch peers, run antseed network browse, then antseed buyer connection set --peer <peerId> and re-check this list.
- Start a Claude Code session through the wrapper
antseed claude --model claude-sonnet-4-6
Manual equivalent after exporting the env vars above: claude --model claude-sonnet-4-6.
Troubleshooting
- "invalid x-api-key" or 401 from Anthropic SDK —
antseed claude sets ANTHROPIC_API_KEY=antseed for you. If you run claude directly, set the variable to any non-empty string; the proxy ignores the value.
- Hangs forever on first message — No peer is pinned. Run
antseed network browse to see peers, then antseed buyer connection set --peer <peerId>.
model_not_found for a model name you expected to work — The pinned peer doesn't advertise that service id. Check what it does offer with antseed network peer <peerId> (or curl http://localhost:8377/v1/models). Pin a different peer if needed.
- Want to confirm a request actually went through AntSeed (not Anthropic direct) — After the request completes, run
antseed buyer metering — you'll see the channel for the peer Claude Code routed to, with token counts and the USDC settled. antseed buyer status shows the snapshot (pinned peer, active-channel count, deposits).
How Claude Code talks to AntSeed
- Wire format sent by Claude Code: Anthropic Messages (hits
/v1/messages on the buyer proxy).
- Best-fit services: any service whose
protocols array contains anthropic-messages — that is what the peer advertises as natively-supported, so traffic passes through with zero translation overhead.
- How to check a peer: run
antseed network peer <peerId> --json and look at peer.providerServiceApiProtocols[provider].services[service] for each model. The browse command exposes the same field per peer.
- When protocols differ: AntSeed's
@antseed/api-adapter translates between Anthropic Messages and the service's native protocol on the fly. So a request from Claude Code can still reach a service that only advertises a different protocol — just with a small transform step.
- Caveat: services whose only advertised protocol is
openai-responses require streaming. If Claude Code sends a non-streaming request and the proxy routes it to one of those services, the call fails with HTTP 400: Stream must be set to true. Pick a service whose protocols includes anthropic-messages (or another non-responses protocol) to avoid this.
Links
OpenAI Codex CLI
OpenAI's official CLI coding agent — use antseed codex for per-run proxy config.
TL;DR for agents: Prefer antseed codex --model <service-id>. It injects the AntSeed Codex provider for one run using base_url=http://localhost:8377/v1 and wire_api="responses". Manual alternative: create user-level ~/.codex/antseed.config.toml with top-level model/model_provider plus [model_providers.antseed], then run codex --profile antseed.
Codex is OpenAI's terminal coding agent. Recent versions ignore OPENAI_BASE_URL and instead read provider config from Codex settings.
antseed codex supplies that provider config for one run with Codex -c overrides, points it at the active buyer proxy, sets the placeholder API key, and leaves your real CODEX_HOME untouched.
If you prefer a persistent manual setup, create ~/.codex/antseed.config.toml and launch Codex with codex --profile antseed; the wrapper is still the shortest path for one-off sessions.
Install
Configure
antseed codex --model claude-sonnet-4-6
Recommended: the wrapper resolves the proxy URL, injects an AntSeed model provider with wire_api = "responses", sets ANTSEED_API_KEY=antseed, and forwards extra Codex args. Put child flags after -- when they look like wrapper flags.
# Loaded by: codex --profile antseed
# Set this to a service id returned by http://localhost:8377/v1/models
# after pinning an AntSeed peer.
model = "claude-sonnet-4-6"
model_provider = "antseed"
[model_providers.antseed]
name = "AntSeed"
base_url = "http://localhost:8377/v1"
wire_api = "responses"
Manual profile only: this must be your user-level ~/.codex/antseed.config.toml, then launch with codex --profile antseed. If your buyer proxy uses a non-default port, update base_url to match it. Project-local ./.codex/config.toml provider blocks are ignored by Codex.
GUI:
No real OpenAI key is needed. The AntSeed proxy authenticates with your local buyer identity; the wrapper and manual profile both point Codex at the local proxy instead of OpenAI.
Suggested models: claude-sonnet-4-6, deepseek-v3.1, kimi-k2.5, qwen-3-coder-480b
Pass the peer service id to antseed codex --model <service-id>. For a manual profile, set top-level model = "<service-id>" in ~/.codex/antseed.config.toml or override with codex --profile antseed --model <service-id>.
Test it
- See which service ids your pinned peer exposes
curl -s http://localhost:8377/v1/models | jq '.data[].id'
Example response:"claude-opus-4-7"
"claude-sonnet-4-6"
"deepseek-v4-flash"
"gpt-oss-120b"
Whatever appears here is a valid value for top-level model = ... in ~/.codex/antseed.config.toml (or for codex --profile antseed --model <id>).
- Run Codex through the wrapper
antseed codex --model deepseek-v4-flash
Manual profile equivalent: codex --profile antseed --model deepseek-v4-flash.
- Verify inference is actually paid through AntSeed
open http://localhost:3118 # or: antseed buyer status
What to look for after one real prompt:Deposits available: 4.289391 USDC → 3.289391 USDC
Deposits reserved: 0 USDC → 1 USDC
The buyer dashboard at http://localhost:3118 is the authoritative real-time signal: a non-zero Reserved (channel opened) and/or a drop in Available (settled spend) after a real prompt confirms AntSeed served the request. The antseed buyer status CLI output is cached and may lag the dashboard — refresh the web view for confirmation. Do not rely on lsof -i | grep codex or ~/.codex/log/codex-tui.log: Codex keeps persistent TCP connections to Cloudflare/ChatGPT IPs (e.g. 172.64.0.0/13) for non-inference purposes (the cause was not isolated during testing), and the provider=OpenAI lines in the TUI log are not a reliable indicator that inference went to OpenAI — the on-chain numbers can show AntSeed served the request despite that log line.
Troubleshooting
OPENAI_BASE_URL / OPENAI_API_KEY are being ignored — Expected on recent Codex builds. Use antseed codex --model <service-id> so the wrapper injects the provider config for the current run, or use the manual ~/.codex/antseed.config.toml profile above.
- How can I tell if Codex is actually routing through AntSeed? — Check the buyer dashboard at http://localhost:3118 (or
antseed buyer status) after sending a test prompt. Reserved going from $0 to a non-zero value (a channel was opened) and/or Available dropping (spend settled) confirms AntSeed served the request. If both stay flat after a real prompt, the profile is not being applied. Do not trust lsof connections to Cloudflare IPs or provider=OpenAI lines in ~/.codex/log/codex-tui.log — neither is a reliable routing signal.
- Codex prints
Ignored unsupported project-local config keys … model_provider, model_providers — Provider settings must live in your user-level Codex profile file. For this manual flow, put the top-level model, model_provider, and [model_providers.antseed] block in ~/.codex/antseed.config.toml, then relaunch with codex --profile antseed. Codex silently rejects provider blocks in project-local ./.codex/config.toml and falls back to its default provider.
- Hand-written Codex
-c provider overrides behave inconsistently — Use antseed codex --model <service-id> so AntSeed supplies the complete provider block (base_url, wire_api, and model_provider) for the current run. If managing config yourself, keep the full provider/profile in user-level ~/.codex/antseed.config.toml.
- Streaming stops after the first chunk with a manual profile — Use
antseed codex, or set wire_api = "responses" in the manual [model_providers.antseed] block.
unknown profile: antseed — Codex caches profile config on launch. Make sure you saved ~/.codex/antseed.config.toml, then start a fresh codex --profile antseed session.
- Hangs forever on first message — No peer is pinned. Run
antseed network browse, then antseed buyer connection set --peer <peerId>.
How OpenAI Codex CLI talks to AntSeed
- Wire format sent by OpenAI Codex CLI: OpenAI Chat Completions (hits
/v1/chat/completions on the buyer proxy).
- Best-fit services: any service whose
protocols array contains openai-chat-completions — that is what the peer advertises as natively-supported, so traffic passes through with zero translation overhead.
- How to check a peer: run
antseed network peer <peerId> --json and look at peer.providerServiceApiProtocols[provider].services[service] for each model. The browse command exposes the same field per peer.
- When protocols differ: AntSeed's
@antseed/api-adapter translates between OpenAI Chat Completions and the service's native protocol on the fly. So a request from OpenAI Codex CLI can still reach a service that only advertises a different protocol — just with a small transform step.
- Caveat: services whose only advertised protocol is
openai-responses require streaming. If OpenAI Codex CLI sends a non-streaming request and the proxy routes it to one of those services, the call fails with HTTP 400: Stream must be set to true. Pick a service whose protocols includes openai-chat-completions (or another non-responses protocol) to avoid this.
Links
OpenCode
Open-source AI coding agent — launch through AntSeed with antseed opencode.
TL;DR for agents: Prefer antseed opencode --model <service-id>. It creates a temporary OpenCode provider config using npm="@ai-sdk/openai-compatible", baseURL="http://localhost:8377/v1", apiKey="antseed", and one model entry. Manual alternative: put the same provider in opencode.json and run opencode.
OpenCode is an MIT-licensed terminal coding agent built on the Vercel AI SDK. It supports 75+ providers out of the box and lets you register custom ones via opencode.json.
antseed opencode creates that custom provider config in a temporary opencode.json, points OpenCode at it for the child process, and deletes it when the session exits. Manual project or global config still works if you want OpenCode to remember AntSeed outside the wrapper.
AntSeed plugs in as a custom provider using the @ai-sdk/openai-compatible adapter — the same one OpenCode recommends for any OpenAI-compatible endpoint (LM Studio, llama.cpp, Atomic Chat, etc.). No ANTHROPIC_BASE_URL: OpenCode reads provider config from JSON.
Each model you want to use must be listed under models. The id has to match what the buyer proxy returns from GET /v1/models — i.e. a service id advertised by your currently-pinned peer.
Install
Configure
antseed opencode --model gpt-oss-120b
Recommended: the wrapper resolves the proxy URL, writes a temporary OpenCode config with one AntSeed model, sets OPENCODE_CONFIG for the child process, and forwards extra OpenCode args.
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"antseed": {
"npm": "@ai-sdk/openai-compatible",
"name": "AntSeed (peer-to-peer)",
"options": {
"baseURL": "http://localhost:8377/v1",
"apiKey": "antseed"
},
"models": {
"claude-sonnet-4-6": { "name": "Claude Sonnet 4.6 (via AntSeed)" },
"deepseek-v4-flash": { "name": "DeepSeek v4 Flash (via AntSeed)" },
"gpt-oss-120b": { "name": "gpt-oss 120B (via AntSeed)" }
}
}
}
}
Manual equivalent if you want OpenCode to keep AntSeed in its normal project or global config.
Suggested models: claude-sonnet-4-6, claude-opus-4-7, deepseek-v4-flash, gpt-oss-120b
antseed opencode --model <service-id> generates a temporary config for that one id. In manual config, the keys under models must exactly match service ids returned by curl http://localhost:8377/v1/models.
Test it
- Confirm the proxy lists the same ids your config references
curl -s http://localhost:8377/v1/models | jq '.data[].id'
Example response:"claude-opus-4-7"
"claude-sonnet-4-6"
"deepseek-v4-flash"
"gpt-oss-120b"
Add or remove entries under models in opencode.json so they match this list.
- Launch OpenCode through the wrapper
antseed opencode --model gpt-oss-120b
Extra OpenCode args are forwarded, so antseed opencode --model gpt-oss-120b run works too. Manual config equivalent: run opencode, then pick one of the AntSeed entries from /models.
Troubleshooting
- AntSeed doesn't appear in
/connect or /models — With antseed opencode, pass the service id via --model; the wrapper supplies a temporary config. With manual config, make sure opencode.json is in your project root (or ~/.config/opencode/opencode.json) and that the JSON is valid — a stray comma silently disables the whole provider.
- Model is listed but every call returns
model_not_found — The pinned peer doesn't advertise that service id. Run antseed network peer <peerId> to see what it actually offers, or pin a different peer.
- OpenCode prompts for an API key — The proxy ignores auth, but the AI SDK sometimes asks anyway. Either skip the prompt (press enter on empty input) or set
"apiKey": "antseed" inside options in opencode.json.
How OpenCode talks to AntSeed
- Wire format sent by OpenCode: OpenAI Chat Completions (hits
/v1/chat/completions on the buyer proxy).
- Best-fit services: any service whose
protocols array contains openai-chat-completions — that is what the peer advertises as natively-supported, so traffic passes through with zero translation overhead.
- How to check a peer: run
antseed network peer <peerId> --json and look at peer.providerServiceApiProtocols[provider].services[service] for each model. The browse command exposes the same field per peer.
- When protocols differ: AntSeed's
@antseed/api-adapter translates between OpenAI Chat Completions and the service's native protocol on the fly. So a request from OpenCode can still reach a service that only advertises a different protocol — just with a small transform step.
- Caveat: services whose only advertised protocol is
openai-responses require streaming. If OpenCode sends a non-streaming request and the proxy routes it to one of those services, the call fails with HTTP 400: Stream must be set to true. Pick a service whose protocols includes openai-chat-completions (or another non-responses protocol) to avoid this.
Links
Pi
Open-source terminal coding agent with a first-class AntSeed extension.
TL;DR for agents: Install Pi: npm install -g @mariozechner/pi-coding-agent. Install the AntSeed extension: pi install git:github.com/AntSeed/pi-antseed. Restart or /reload. The extension calls pi.registerProvider("antseed", { api: "openai-responses", baseUrl: "http://localhost:8377/v1" }) and auto-discovers models from the pinned peer via GET /v1/models. Switch with /model antseed/<service-id>. Override base URL with ANTSEED_BASE_URL env var; auth with ANTSEED_API_KEY.
What Pi is. Pi (@mariozechner/pi-coding-agent) is a minimal, hackable terminal coding agent by Mario Zechner — the same lineage as pi-mono. It ships with four default tools (read, write, edit, bash) and lets you extend everything else — commands, providers, themes, even the editor UI — through TypeScript extensions, skills, and prompt templates. No fork required.
What the AntSeed extension does. pi-antseed is a Pi extension that registers the local buyer proxy as a Pi provider named antseed. Once installed, every service your pinned peer advertises shows up under antseed/<id> in Pi's model picker (Ctrl+L or /model) — you switch with /model antseed/minimax-m2.7 just like any built-in.
Why an extension instead of env vars. Pi already speaks dozens of provider protocols natively. The extension calls pi.registerProvider("antseed", { api: "openai-responses", authHeader: true, baseUrl: "http://localhost:8377/v1" }) — Pi then handles auth headers, streaming, retries, and tool-calling. The Responses API path preserves reasoning items across turns for reasoning-capable models, while the extension still auto-refreshes the model list from GET /v1/models so the menu reflects what your pinned peer can serve.
Install
Configure
export ANTSEED_BASE_URL="http://localhost:8377/v1"
GUI:
No GUI config needed in the common case — the extension reads ANTSEED_BASE_URL (default http://localhost:8377/v1) and discovers models from the pinned peer automatically. Only set ANTSEED_API_KEY if you front the buyer proxy with your own auth layer, or ANTSEED_MODELS="id1,id2" to skip discovery and register a fixed list.
Suggested models: minimax-m2.7, claude-sonnet-4-6, deepseek-v4-flash, qwen3-coder-480b
The extension auto-discovers from GET /v1/models after Pi loads, so anything your pinned peer advertises shows up under antseed/.... After re-pinning a different peer, run /reload in Pi to refresh the model list.
Test it
Troubleshooting
pi: command not found after install — Your global npm bin is not on PATH. Run npm prefix -g to find it, then add <that-path>/bin to PATH in your shell rc. Or use a Node version manager (nvm, fnm, volta) which handles this automatically.
antseed doesn't appear in the model picker (/model or Ctrl+L) — The extension didn't load. Re-run pi install git:github.com/AntSeed/pi-antseed, restart Pi, and watch the startup header — it lists every loaded extension and surfaces load errors there.
- Picker only shows a few hard-coded
antseed/... ids, not what my peer offers — Pi started before the buyer proxy was up, so the extension fell back to its built-in seed list. Make sure antseed buyer start is running and a peer is pinned, then run /reload inside Pi to refresh the model list.
- Empty
/v1/models from the proxy — No peer is connected. Run antseed network browse to see options, then antseed buyer connection set --peer <peerId>. Or launch the proxy with antseed buyer start --router <name> for automatic peer selection.
- 5xx from the proxy mid-conversation — Usually means the pinned peer doesn't offer the model you asked for, or has just gone offline. Re-pin via
antseed buyer connection set --peer <peerId> and /reload in Pi.
- Want to use a custom buyer proxy URL (remote host, custom port) — Set
ANTSEED_BASE_URL=http://your-host:8377/v1 in the shell that launches pi. The extension reads this on startup. If your proxy is fronted by auth, also set ANTSEED_API_KEY=<token>.
How Pi talks to AntSeed
- Wire format sent by Pi: OpenAI Responses (hits
/v1/responses on the buyer proxy).
- Best-fit services: any service whose
protocols array contains openai-responses — that is what the peer advertises as natively-supported, so traffic passes through with zero translation overhead.
- How to check a peer: run
antseed network peer <peerId> --json and look at peer.providerServiceApiProtocols[provider].services[service] for each model. The browse command exposes the same field per peer.
- When protocols differ: AntSeed's
@antseed/api-adapter translates between OpenAI Responses and the service's native protocol on the fly. So a request from Pi can still reach a service that only advertises a different protocol — just with a small transform step.
Links
OpenClaw
Open-source autonomous agent runtime — register AntSeed as a custom provider in openclaw.json.
…(truncated)
1---
2name: antseed-connect
3description: Connect coding agents, AI SDKs, and LLM tools to the AntSeed buyer proxy. Use when configuring Claude Code, Codex, OpenCode, Pi, OpenClaw, Hermes, GenLayer Studio, Vercel AI SDK, LangChain, or raw HTTP to route inference through AntSeed at localhost:8377.
4---
5
6# AntSeed — Integration Skill
7
8> This file is the agent-readable companion to https://antseed.com/integrations.
9> It tells any AI agent (Claude, Codex, OpenClaw, Hermes, custom) exactly
10> how to wire its tool of choice up to the AntSeed peer-to-peer inference network.
11
12## What is AntSeed?
13
14AntSeed is a peer-to-peer marketplace for AI inference. Buyers run a small
15local daemon (the **buyer proxy**) that exposes an HTTP API at
16`http://localhost:8377` speaking the three caller-facing LLM API protocols:
17Anthropic Messages, OpenAI Chat Completions, and OpenAI Responses. Legacy
18OpenAI Completions is supported internally for adapter translation. The proxy
19discovers providers on a DHT, routes the
20request to a peer, translates between protocols when needed (via
21`@antseed/api-adapter`), and settles in USDC on Base.
22
23Important: AntSeed is for value-added AI services (specialized models, agents,
24TEEs, fine-tunes, managed workflows), not raw resale of API keys or subscription
25access. Providers must comply with upstream terms of service.
26
27From the perspective of any tool, SDK, or agent, **AntSeed is just a local
28OpenAI/Anthropic-compatible endpoint** — point a `base_url` at it and you are done.
29
30## Glossary (mental model)
31
32- **Buyer proxy** — the local server on `localhost:8377` that accepts API calls
33 from your tools and forwards them to AntSeed peers. It is the only thing your
34 editor / agent / SDK ever talks to.
35- **Peer** — someone selling inference. Each peer has a `peerId` (40-char hex),
36 a display name, and a list of services. List with `antseed network browse`.
37- **Service** — a single model id like `claude-sonnet-4-6` or `deepseek-v4-flash`.
38 *This is what you pass as `model` in your tool's config.* Each service has its
39 own native protocol list and its own `in` / `cachedIn` / `out` pricing.
40- **Protocols** (per service) — the wire formats a service accepts *natively*,
41 advertised on each peer in `providerServiceApiProtocols[provider].services[service]`.
42 Values are `anthropic-messages`,
43 `openai-chat-completions`, `openai-responses`, `openai-completions`. **This is
44 the field to match your tool's wire format against.** If your tool's wire format
45 is in this list, the request passes through untouched; if not, the api-adapter
46 translates on the fly.
47- **Cached input pricing** — services charge a separate, much lower rate
48 (typically 4–10×) for tokens that are reused across requests: system prompts,
49 tool schemas, prior conversation turns, long files you keep referencing. The CLI
50 exposes it as `cachedInputUsdPerMillion`. For long-running agents and chatbots,
51 this is often the dominant cost line.
52- **Pin** — telling the buyer proxy "route requests to *this* peer." In the
53 default manual flow, there is no peer auto-selection; you must choose a peer,
54 send a per-request pin header, or start the proxy with a router plugin that
55 performs selection. Common explicit routes:
56 - **Session pin**: `antseed buyer connection set --peer <peerId>`. Persists in
57 `~/.antseed/buyer.state.json` and applies to every request until you change it.
58 - **Per-request header**: `x-antseed-pin-peer: <peerId>` on each call. Overrides
59 the session pin for that request, and works *without* any session pin at all.
60 - **Model prefix**: set `model` to `<peerId>@<service>`. The proxy uses the
61 prefix as the peer pin and forwards only `<service>` to the seller.
62
63 If both header and model-prefix pins are present, the header selects the peer;
64 the model prefix is still stripped before routing.
65 Until at least one of these is in effect, every request returns `no_peer_pinned`.
66
67## Universal setup (do this once)
68
69### Option A — AntStation desktop app (easiest)
70
71Download from https://antseed.com — it ships the buyer proxy, a wallet, and a
72peer browser in a GUI. While the app is open the proxy is reachable at
73`http://localhost:8377`.
74
75### Option B — CLI (headless / servers / agents)
76
77```bash
78# 1. Install
79npm install -g @antseed/cli
80
81# 2. Identity (an EVM private key — 64 hex chars). Save this somewhere safe;
82# you will reuse it across machines and it controls your USDC deposits.
83export ANTSEED_IDENTITY_HEX=$(openssl rand -hex 32)
84# SECURITY: never paste this key into chat, logs, GitHub issues, or a file
85# committed to git. It controls the buyer identity and access to deposits.
86
87# 3. Start the buyer proxy on :8377
88antseed buyer start &
89
90# 4. Browse the network and list every service (= model) each peer offers,
91# along with its native protocols and USD-per-1M-tokens pricing.
92# `service` is the model id you pass to your tool. `protocols` is the
93# wire format(s) the service accepts natively — match it against your
94# tool. `in` / `cachedIn` / `out` are fresh-input / cached-input / output.
95antseed network browse --json --top 5 \
96 | jq '.peers | map({
97 peerId, name: .displayName,
98 services: [
99 (.providerServiceApiProtocols | to_entries[]) as $p
100 | ($p.value.services | to_entries[]) as $s
101 | {
102 service: $s.key,
103 protocols: $s.value,
104 in: (.providerPricing[$p.key].services[$s.key].inputUsdPerMillion // .providerPricing[$p.key].defaults.inputUsdPerMillion),
105 cachedIn: (.providerPricing[$p.key].services[$s.key].cachedInputUsdPerMillion // null),
106 out: (.providerPricing[$p.key].services[$s.key].outputUsdPerMillion // .providerPricing[$p.key].defaults.outputUsdPerMillion)
107 }
108 ]
109 })'
110
111# 5. Inspect one peer in detail. Use `matchingServices[]` for pricing/tags and
112# `peer.providerServiceApiProtocols` for native protocol support.
113# `cachedIn` is typically 4–10× cheaper than `in` and often dominates the
114# cost line for long-running agents and chatbots — always include it when
115# comparing peers.
116antseed network peer <peerId> --json \
117 | jq '{
118 peer: (.peer | { peerId, name: .displayName,
119 sessions: .onChainChannelCount,
120 ghosts: .onChainGhostCount }),
121 services: [
122 (.peer.providerServiceApiProtocols | to_entries[]) as $p
123 | ($p.value.services | to_entries[]) as $s
124 | (.matchingServices[] | select(.provider == $p.key and .service == $s.key)) as $m
125 | {
126 provider: $p.key,
127 service: $s.key,
128 protocols: $s.value,
129 in: $m.inputUsdPerMillion,
130 cachedIn: $m.cachedInputUsdPerMillion,
131 out: $m.outputUsdPerMillion,
132 tags: $m.tags
133 }
134 ]
135 }'
136
137# 6. Pin a peer (session-wide). Until you do, every request returns
138# `no_peer_pinned` UNLESS the request includes an `x-antseed-pin-peer`
139# header (see Per-request peer selection below).
140antseed buyer connection set --peer <peerId>
141
142# 7. Verify the proxy advertises the services you expect
143curl -s http://localhost:8377/v1/models | jq '.data[].id'
144
145# 8. (Optional) Deposit USDC on Base for paid services
146antseed payments # opens portal at 127.0.0.1:3118?token=<hex> — connect a wallet, deposit USDC
147```
148
149### Security notes for agents and deploys
150
151- Treat `ANTSEED_IDENTITY_HEX` / `~/.antseed/identity.key` as a hot wallet key.
152 Never print it, paste it into chat, commit it, or copy it off the buyer host.
153- Keep the buyer proxy bound to `127.0.0.1` / `localhost`. Do not expose
154 `:8377` directly to the public internet; use SSH tunnels or a private network
155 if another process must reach it remotely.
156- Start with small USDC deposits and conservative reserve caps for autonomous
157 agents. The funding wallet does not need to stay connected after depositing.
158- If a tool requires an API key, use a non-secret placeholder such as `antseed`;
159 the buyer proxy authenticates with the local identity key instead.
160
161## Endpoints exposed by the buyer proxy
162
163| Path | Wire format | Common callers |
164|------|-------------|----------------|
165| `POST /v1/messages` | Anthropic Messages | Claude Code, Anthropic SDKs, OpenClaw |
166| `POST /v1/chat/completions` | OpenAI Chat Completions | Codex, Hermes, OpenAI SDKs, Vercel AI SDK, LangChain, most tools |
167| `POST /v1/responses` | OpenAI Responses | Codex (newer builds), tools using the Responses API |
168
169All four protocols (including legacy `openai-completions`) are supported by
170`@antseed/api-adapter` for translation, but only the three endpoints above are
171exposed to callers. Translation is automatic: a request that arrives in one
172format and is routed to a peer whose service advertises a different `protocols`
173value is transformed both directions (request and streaming response).
174
175No `Authorization` header is required by the buyer proxy. It authenticates and
176pays peers using the local node's identity key and on-chain USDC deposits.
177
178### Per-request peer selection (no session pin needed)
179
180Two ways to tell the proxy which peer to use:
181
1821. **Session pin** — `antseed buyer connection set --peer <peerId>`. Persists in
183 `~/.antseed/buyer.state.json` (`pinnedPeerId`) and applies to every request
184 until you change it. Best for single-tenant setups (laptops, dedicated agents).
1852. **Per-request header** — send `x-antseed-pin-peer: <peerId>` on each call.
186 Overrides the session pin for that one request. **You do not need to call
187 `antseed buyer connection set` at all** if every request includes this header
188 — the proxy will accept and route them. Best for scripts, schedulers, and
189 multi-tenant deployments that need to fan out to different peers per call.
190
191Example (per-request, no session pin):
192
193```bash
194curl http://localhost:8377/v1/chat/completions \
195 -H 'content-type: application/json' \
196 -H 'x-antseed-pin-peer: 4668854ba3e8b094e6f48fbeb59cec1cfde162f2' \
197 -d '{ "model": "minimax-m2.7", "messages": [{"role":"user","content":"hi"}] }'
198```
199
200Other optional headers:
201
202- `x-antseed-provider: <providerName>` — when a peer exposes the same service
203 through more than one seller-plugin (rare), force a specific one. Most tools
204 never need this.
205
206## Files the CLI creates in `~/.antseed/`
207
208Knowing what lives in `~/.antseed/` matters for backups, container deploys,
209and debugging. The directory is created on first `antseed buyer start` (or
210first run of any `antseed` command that needs it).
211
212| Path | Purpose | Survives restart? | Safe to delete? |
213|------|---------|--------------------|------------------|
214| `identity.key` | Raw 32-byte EVM private key for the buyer wallet. Fallback when `ANTSEED_IDENTITY_HEX` is not set. | yes | NO — deleting loses access to your USDC deposits. Back this up. |
215| `identity.enc` | Encrypted copy of `identity.key` (when the desktop app sets a passphrase). | yes | only if `identity.key` is also intact |
216| `config.json` | Static settings: chain id, proxy port, max-pricing caps, bootstrap nodes, payments preferences. Hand-editable. | yes | yes (defaults are sane) |
217| `buyer.state.json` | Live runtime state: `pinnedPeerId`, the discovered-peers cache (`discoveredPeers`), on-chain stats, the proxy `pid` and `port`. Re-built from the network on next start. | yes (the pin survives restart) | yes (you lose the pin and the cached peer list — next browse will repopulate) |
218| `metering.db` | SQLite log of every request the proxy served (model, peer, tokens, USDC). Used by `antseed buyer status` and the payments portal. | yes | yes (you lose request history; settlement is unaffected) |
219| `payments/` | Per-channel state used by the seller-side settlement flow (only relevant if you also run `antseed seller`). | yes | only if you do not run a seller |
220| `plugins/` | Cache of downloaded provider plugins. | yes | yes (re-downloaded on next use) |
221| `chat/`, `projects/` | Used by the desktop app for local chat history. Empty on a CLI-only setup. | yes | yes |
222
223### `config.json` (commonly edited)
224
225```json title="~/.antseed/config.json"
226{
227 "buyer": {
228 "proxyPort": 8377, // change if 8377 conflicts on the host
229 "minPeerReputation": 0, // optional: raise to filter lower-reputation peers
230 "maxPricing": { // refuse to route to peers above this rate
231 "defaults": { "inputUsdPerMillion": 100, "outputUsdPerMillion": 100 }
232 }
233 },
234 "payments": {
235 "preferredMethod": "crypto",
236 "crypto": { "chainId": "base-mainnet" } // or "base-sepolia" for testnet
237 },
238 "network": { "bootstrapNodes": [] } // empty = use built-in defaults
239}
240```
241
242Edit, then restart the buyer proxy. **Do not hardcode contract addresses** —
243the chain preset (`base-mainnet` / `base-sepolia`) resolves Deposits, Channels,
244USDC, and the RPC URL automatically.
245
246### `buyer.state.json` (read-only in practice)
247
248Top-level fields that an agent might want to inspect:
249
250- `pinnedPeerId` — the currently pinned peer (or `null`).
251- `pid` / `port` — the running proxy. If `pid` is non-null but the process is gone, `antseed buyer start` will detect the stale lockfile and clean up.
252- `discoveredPeers` — cached peer list from the last DHT browse. Refreshed on `antseed network browse`.
253- `peersUpdatedAt`, `onChainStatsRefreshedAt` — cache timestamps (epoch millis).
254
255To force a clean reset of pin + caches without losing your wallet:
256
257```bash
258antseed buyer stop || true
259rm ~/.antseed/buyer.state.json
260antseed buyer start &
261```
262
263## How to integrate <your tool>
264
265Below is every integration we currently document. Find your tool, copy the
266config block, done. If your tool is not listed but accepts a custom OpenAI or
267Anthropic base URL, follow the closest example (or look at the **curl / Raw
268HTTP** entry — the contract is stable).
269
270## Claude Code
271
272*Anthropic's official CLI agent — launch through AntSeed with `antseed claude`.*
273
274- **Category:** Coding agents
275- **Wire format:** Anthropic Messages
276- **Setup time:** ~2 min
277- **Page:** https://antseed.com/integrations/claude-code
278
279**TL;DR for agents:** Prefer `antseed claude --model <service-id>`. It sets ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY for Claude Code. Manual equivalent: set ANTHROPIC_BASE_URL=http://localhost:8377 and ANTHROPIC_API_KEY=antseed, then run `claude --model <service-id>`.
280
281Claude Code is the official CLI coding agent from Anthropic. It speaks the Anthropic Messages API natively, so it slots into AntSeed through the `antseed claude` wrapper or by pointing `ANTHROPIC_BASE_URL` at your local proxy.
282
283`antseed claude` resolves the active buyer proxy, sets the placeholder Anthropic API key for the child process, and forwards the rest of your Claude Code flags unchanged. Manual environment variables still work if you want to run `claude` directly.
284
285No real Anthropic API key is needed — the AntSeed proxy authenticates each request with your local identity (`ANTSEED_IDENTITY_HEX`) and settles payments on-chain. The `ANTHROPIC_API_KEY` value is required by the Anthropic SDK only as a non-empty placeholder.
286
287When Claude Code calls the Messages API, the proxy forwards the request to the peer you pinned in step 3 of the setup above. Whichever *service ids* that peer advertises (visible in `antseed network peer <peerId>`) become the valid `--model` values.
288
289**Install**
290
291- **Install Claude Code globally**
292 ```bash
293 npm install -g @anthropic-ai/claude-code
294 ```
295- **Verify it runs**
296 ```bash
297 claude --version
298 ```
299 *Example output:*
300 ```
301 1.4.2 (Claude Code)
302 ```
303
304**Configure**
305
306```bash
307antseed claude --model claude-sonnet-4-6
308```
309
310_Recommended: the wrapper reads the active buyer proxy from `buyer.state.json` or config, sets `ANTHROPIC_BASE_URL` and `ANTHROPIC_API_KEY` for Claude Code, and forwards extra Claude args. Add `--antseed-base-url http://host:port` only when your proxy is somewhere else._
311
312```bash
313export ANTHROPIC_BASE_URL="http://localhost:8377"
314export ANTHROPIC_API_KEY="antseed"
315```
316
317_Manual equivalent if you want to run `claude` directly instead of through `antseed claude`._
318
319**Suggested models:** `claude-sonnet-4-6`, `claude-opus-4-7`, `deepseek-v4-flash`
320
321`antseed claude --model <service-id>` passes the value to Claude Code unchanged. The valid set is whatever your pinned peer advertises — see the discovery commands below.
322
323**Test it**
324
325- **See which models your pinned peer offers**
326 ```bash
327 curl -s http://localhost:8377/v1/models | jq '.data[].id'
328 ```
329 *Example response:*
330 ```
331 "claude-opus-4-7"
332 "claude-sonnet-4-6"
333 "deepseek-v4-flash"
334 "gpt-oss-120b"
335 ```
336 > These are the only ids that work with `--model`. To switch peers, run `antseed network browse`, then `antseed buyer connection set --peer <peerId>` and re-check this list.
337- **Start a Claude Code session through the wrapper**
338 ```bash
339 antseed claude --model claude-sonnet-4-6
340 ```
341 > Manual equivalent after exporting the env vars above: `claude --model claude-sonnet-4-6`.
342
343**Troubleshooting**
344
345- *"invalid x-api-key" or 401 from Anthropic SDK* — `antseed claude` sets `ANTHROPIC_API_KEY=antseed` for you. If you run `claude` directly, set the variable to any non-empty string; the proxy ignores the value.
346- *Hangs forever on first message* — No peer is pinned. Run `antseed network browse` to see peers, then `antseed buyer connection set --peer <peerId>`.
347- *`model_not_found` for a model name you expected to work* — The pinned peer doesn't advertise that service id. Check what it does offer with `antseed network peer <peerId>` (or `curl http://localhost:8377/v1/models`). Pin a different peer if needed.
348- *Want to confirm a request actually went through AntSeed (not Anthropic direct)* — After the request completes, run `antseed buyer metering` — you'll see the channel for the peer Claude Code routed to, with token counts and the USDC settled. `antseed buyer status` shows the snapshot (pinned peer, active-channel count, deposits).
349
350**How Claude Code talks to AntSeed**
351
352- **Wire format sent by Claude Code:** Anthropic Messages (hits `/v1/messages` on the buyer proxy).
353- **Best-fit services:** any service whose `protocols` array contains `anthropic-messages` — that is what the peer advertises as natively-supported, so traffic passes through with zero translation overhead.
354- **How to check a peer:** run `antseed network peer <peerId> --json` and look at `peer.providerServiceApiProtocols[provider].services[service]` for each model. The browse command exposes the same field per peer.
355- **When protocols differ:** AntSeed's `@antseed/api-adapter` translates between Anthropic Messages and the service's native protocol on the fly. So a request from Claude Code can still reach a service that only advertises a different protocol — just with a small transform step.
356- **Caveat:** services whose only advertised protocol is `openai-responses` require streaming. If Claude Code sends a non-streaming request and the proxy routes it to one of those services, the call fails with `HTTP 400: Stream must be set to true`. Pick a service whose `protocols` includes `anthropic-messages` (or another non-responses protocol) to avoid this.
357
358**Links**
359
360- [Claude Code docs](https://docs.anthropic.com/en/docs/claude-code)
361- [AntSeed skill: join-buyer](https://github.com/AntSeed/antseed/tree/main/skills/join-buyer)
362
363---
364
365## OpenAI Codex CLI
366
367*OpenAI's official CLI coding agent — use `antseed codex` for per-run proxy config.*
368
369- **Category:** Coding agents
370- **Wire format:** OpenAI Chat Completions
371- **Setup time:** ~2 min
372- **Page:** https://antseed.com/integrations/codex
373
374**TL;DR for agents:** Prefer `antseed codex --model <service-id>`. It injects the AntSeed Codex provider for one run using base_url=http://localhost:8377/v1 and wire_api="responses". Manual alternative: create user-level ~/.codex/antseed.config.toml with top-level model/model_provider plus [model_providers.antseed], then run `codex --profile antseed`.
375
376Codex is OpenAI's terminal coding agent. Recent versions ignore `OPENAI_BASE_URL` and instead read provider config from Codex settings.
377
378`antseed codex` supplies that provider config for one run with Codex `-c` overrides, points it at the active buyer proxy, sets the placeholder API key, and leaves your real `CODEX_HOME` untouched.
379
380If you prefer a persistent manual setup, create `~/.codex/antseed.config.toml` and launch Codex with `codex --profile antseed`; the wrapper is still the shortest path for one-off sessions.
381
382**Install**
383
384- **Install Codex globally**
385 ```bash
386 npm install -g @openai/codex
387 ```
388- **Verify it runs**
389 ```bash
390 codex --version
391 ```
392
393**Configure**
394
395```bash
396antseed codex --model claude-sonnet-4-6
397```
398
399_Recommended: the wrapper resolves the proxy URL, injects an AntSeed model provider with `wire_api = "responses"`, sets `ANTSEED_API_KEY=antseed`, and forwards extra Codex args. Put child flags after `--` when they look like wrapper flags._
400
401```toml title="~/.codex/antseed.config.toml"
402# Loaded by: codex --profile antseed
403# Set this to a service id returned by http://localhost:8377/v1/models
404# after pinning an AntSeed peer.
405model = "claude-sonnet-4-6"
406model_provider = "antseed"
407
408[model_providers.antseed]
409name = "AntSeed"
410base_url = "http://localhost:8377/v1"
411wire_api = "responses"
412```
413
414_Manual profile only: this must be your **user-level** `~/.codex/antseed.config.toml`, then launch with `codex --profile antseed`. If your buyer proxy uses a non-default port, update `base_url` to match it. Project-local `./.codex/config.toml` provider blocks are ignored by Codex._
415
416> **GUI:**
417>
418> No real OpenAI key is needed. The AntSeed proxy authenticates with your local buyer identity; the wrapper and manual profile both point Codex at the local proxy instead of OpenAI.
419
420**Suggested models:** `claude-sonnet-4-6`, `deepseek-v3.1`, `kimi-k2.5`, `qwen-3-coder-480b`
421
422Pass the peer service id to `antseed codex --model <service-id>`. For a manual profile, set top-level `model = "<service-id>"` in `~/.codex/antseed.config.toml` or override with `codex --profile antseed --model <service-id>`.
423
424**Test it**
425
426- **See which service ids your pinned peer exposes**
427 ```bash
428 curl -s http://localhost:8377/v1/models | jq '.data[].id'
429 ```
430 *Example response:*
431 ```
432 "claude-opus-4-7"
433 "claude-sonnet-4-6"
434 "deepseek-v4-flash"
435 "gpt-oss-120b"
436 ```
437 > Whatever appears here is a valid value for top-level `model = ...` in `~/.codex/antseed.config.toml` (or for `codex --profile antseed --model <id>`).
438- **Run Codex through the wrapper**
439 ```bash
440 antseed codex --model deepseek-v4-flash
441 ```
442 > Manual profile equivalent: `codex --profile antseed --model deepseek-v4-flash`.
443- **Verify inference is actually paid through AntSeed**
444 ```bash
445 open http://localhost:3118 # or: antseed buyer status
446 ```
447 *What to look for after one real prompt:*
448 ```
449 Deposits available: 4.289391 USDC → 3.289391 USDC
450 Deposits reserved: 0 USDC → 1 USDC
451 ```
452 > The buyer dashboard at http://localhost:3118 is the authoritative real-time signal: a non-zero `Reserved` (channel opened) and/or a drop in `Available` (settled spend) after a real prompt confirms AntSeed served the request. The `antseed buyer status` CLI output is cached and may lag the dashboard — refresh the web view for confirmation. Do not rely on `lsof -i | grep codex` or `~/.codex/log/codex-tui.log`: Codex keeps persistent TCP connections to Cloudflare/ChatGPT IPs (e.g. 172.64.0.0/13) for non-inference purposes (the cause was not isolated during testing), and the `provider=OpenAI` lines in the TUI log are not a reliable indicator that inference went to OpenAI — the on-chain numbers can show AntSeed served the request despite that log line.
453
454**Troubleshooting**
455
456- *`OPENAI_BASE_URL` / `OPENAI_API_KEY` are being ignored* — Expected on recent Codex builds. Use `antseed codex --model <service-id>` so the wrapper injects the provider config for the current run, or use the manual `~/.codex/antseed.config.toml` profile above.
457- *How can I tell if Codex is actually routing through AntSeed?* — Check the buyer dashboard at http://localhost:3118 (or `antseed buyer status`) after sending a test prompt. `Reserved` going from $0 to a non-zero value (a channel was opened) and/or `Available` dropping (spend settled) confirms AntSeed served the request. If both stay flat after a real prompt, the profile is not being applied. Do not trust `lsof` connections to Cloudflare IPs or `provider=OpenAI` lines in `~/.codex/log/codex-tui.log` — neither is a reliable routing signal.
458- *Codex prints `Ignored unsupported project-local config keys … model_provider, model_providers`* — Provider settings must live in your **user-level** Codex profile file. For this manual flow, put the top-level `model`, `model_provider`, and `[model_providers.antseed]` block in `~/.codex/antseed.config.toml`, then relaunch with `codex --profile antseed`. Codex silently rejects provider blocks in project-local `./.codex/config.toml` and falls back to its default provider.
459- *Hand-written Codex `-c` provider overrides behave inconsistently* — Use `antseed codex --model <service-id>` so AntSeed supplies the complete provider block (`base_url`, `wire_api`, and `model_provider`) for the current run. If managing config yourself, keep the full provider/profile in user-level `~/.codex/antseed.config.toml`.
460- *Streaming stops after the first chunk with a manual profile* — Use `antseed codex`, or set `wire_api = "responses"` in the manual `[model_providers.antseed]` block.
461- *`unknown profile: antseed`* — Codex caches profile config on launch. Make sure you saved `~/.codex/antseed.config.toml`, then start a fresh `codex --profile antseed` session.
462- *Hangs forever on first message* — No peer is pinned. Run `antseed network browse`, then `antseed buyer connection set --peer <peerId>`.
463
464**How OpenAI Codex CLI talks to AntSeed**
465
466- **Wire format sent by OpenAI Codex CLI:** OpenAI Chat Completions (hits `/v1/chat/completions` on the buyer proxy).
467- **Best-fit services:** any service whose `protocols` array contains `openai-chat-completions` — that is what the peer advertises as natively-supported, so traffic passes through with zero translation overhead.
468- **How to check a peer:** run `antseed network peer <peerId> --json` and look at `peer.providerServiceApiProtocols[provider].services[service]` for each model. The browse command exposes the same field per peer.
469- **When protocols differ:** AntSeed's `@antseed/api-adapter` translates between OpenAI Chat Completions and the service's native protocol on the fly. So a request from OpenAI Codex CLI can still reach a service that only advertises a different protocol — just with a small transform step.
470- **Caveat:** services whose only advertised protocol is `openai-responses` require streaming. If OpenAI Codex CLI sends a non-streaming request and the proxy routes it to one of those services, the call fails with `HTTP 400: Stream must be set to true`. Pick a service whose `protocols` includes `openai-chat-completions` (or another non-responses protocol) to avoid this.
471
472**Links**
473
474- [Codex repo](https://github.com/openai/codex)
475- [Codex sample config](https://developers.openai.com/codex/config-sample)
476
477---
478
479## OpenCode
480
481*Open-source AI coding agent — launch through AntSeed with `antseed opencode`.*
482
483- **Category:** Coding agents
484- **Wire format:** OpenAI Chat Completions
485- **Setup time:** ~2 min
486- **Page:** https://antseed.com/integrations/opencode
487
488**TL;DR for agents:** Prefer `antseed opencode --model <service-id>`. It creates a temporary OpenCode provider config using npm="@ai-sdk/openai-compatible", baseURL="http://localhost:8377/v1", apiKey="antseed", and one model entry. Manual alternative: put the same provider in opencode.json and run `opencode`.
489
490OpenCode is an MIT-licensed terminal coding agent built on the Vercel AI SDK. It supports 75+ providers out of the box and lets you register custom ones via `opencode.json`.
491
492`antseed opencode` creates that custom provider config in a temporary `opencode.json`, points OpenCode at it for the child process, and deletes it when the session exits. Manual project or global config still works if you want OpenCode to remember AntSeed outside the wrapper.
493
494AntSeed plugs in as a **custom provider** using the `@ai-sdk/openai-compatible` adapter — the same one OpenCode recommends for any OpenAI-compatible endpoint (LM Studio, llama.cpp, Atomic Chat, etc.). No `ANTHROPIC_BASE_URL`: OpenCode reads provider config from JSON.
495
496Each model you want to use must be listed under `models`. The id has to match what the buyer proxy returns from `GET /v1/models` — i.e. a service id advertised by your currently-pinned peer.
497
498**Install**
499
500- **Install OpenCode**
501 ```bash
502 npm install -g opencode-ai
503 ```
504- **Verify it runs**
505 ```bash
506 opencode --version
507 ```
508
509**Configure**
510
511```bash
512antseed opencode --model gpt-oss-120b
513```
514
515_Recommended: the wrapper resolves the proxy URL, writes a temporary OpenCode config with one AntSeed model, sets `OPENCODE_CONFIG` for the child process, and forwards extra OpenCode args._
516
517```json title="opencode.json (project root, or ~/.config/opencode/opencode.json for global)"
518{
519 "$schema": "https://opencode.ai/config.json",
520 "provider": {
521 "antseed": {
522 "npm": "@ai-sdk/openai-compatible",
523 "name": "AntSeed (peer-to-peer)",
524 "options": {
525 "baseURL": "http://localhost:8377/v1",
526 "apiKey": "antseed"
527 },
528 "models": {
529 "claude-sonnet-4-6": { "name": "Claude Sonnet 4.6 (via AntSeed)" },
530 "deepseek-v4-flash": { "name": "DeepSeek v4 Flash (via AntSeed)" },
531 "gpt-oss-120b": { "name": "gpt-oss 120B (via AntSeed)" }
532 }
533 }
534 }
535}
536```
537
538_Manual equivalent if you want OpenCode to keep AntSeed in its normal project or global config._
539
540**Suggested models:** `claude-sonnet-4-6`, `claude-opus-4-7`, `deepseek-v4-flash`, `gpt-oss-120b`
541
542`antseed opencode --model <service-id>` generates a temporary config for that one id. In manual config, the keys under `models` must exactly match service ids returned by `curl http://localhost:8377/v1/models`.
543
544**Test it**
545
546- **Confirm the proxy lists the same ids your config references**
547 ```bash
548 curl -s http://localhost:8377/v1/models | jq '.data[].id'
549 ```
550 *Example response:*
551 ```
552 "claude-opus-4-7"
553 "claude-sonnet-4-6"
554 "deepseek-v4-flash"
555 "gpt-oss-120b"
556 ```
557 > Add or remove entries under `models` in `opencode.json` so they match this list.
558- **Launch OpenCode through the wrapper**
559 ```bash
560 antseed opencode --model gpt-oss-120b
561 ```
562 > Extra OpenCode args are forwarded, so `antseed opencode --model gpt-oss-120b run` works too. Manual config equivalent: run `opencode`, then pick one of the AntSeed entries from `/models`.
563
564**Troubleshooting**
565
566- *AntSeed doesn't appear in `/connect` or `/models`* — With `antseed opencode`, pass the service id via `--model`; the wrapper supplies a temporary config. With manual config, make sure `opencode.json` is in your project root (or `~/.config/opencode/opencode.json`) and that the JSON is valid — a stray comma silently disables the whole provider.
567- *Model is listed but every call returns `model_not_found`* — The pinned peer doesn't advertise that service id. Run `antseed network peer <peerId>` to see what it actually offers, or pin a different peer.
568- *OpenCode prompts for an API key* — The proxy ignores auth, but the AI SDK sometimes asks anyway. Either skip the prompt (press enter on empty input) or set `"apiKey": "antseed"` inside `options` in `opencode.json`.
569
570**How OpenCode talks to AntSeed**
571
572- **Wire format sent by OpenCode:** OpenAI Chat Completions (hits `/v1/chat/completions` on the buyer proxy).
573- **Best-fit services:** any service whose `protocols` array contains `openai-chat-completions` — that is what the peer advertises as natively-supported, so traffic passes through with zero translation overhead.
574- **How to check a peer:** run `antseed network peer <peerId> --json` and look at `peer.providerServiceApiProtocols[provider].services[service]` for each model. The browse command exposes the same field per peer.
575- **When protocols differ:** AntSeed's `@antseed/api-adapter` translates between OpenAI Chat Completions and the service's native protocol on the fly. So a request from OpenCode can still reach a service that only advertises a different protocol — just with a small transform step.
576- **Caveat:** services whose only advertised protocol is `openai-responses` require streaming. If OpenCode sends a non-streaming request and the proxy routes it to one of those services, the call fails with `HTTP 400: Stream must be set to true`. Pick a service whose `protocols` includes `openai-chat-completions` (or another non-responses protocol) to avoid this.
577
578**Links**
579
580- [OpenCode docs → Custom provider](https://opencode.ai/docs/providers/#custom-provider)
581- [OpenCode repo](https://github.com/sst/opencode)
582
583---
584
585## Pi
586
587*Open-source terminal coding agent with a first-class AntSeed extension.*
588
589- **Category:** Coding agents
590- **Wire format:** OpenAI Responses
591- **Setup time:** ~3 min
592- **Page:** https://antseed.com/integrations/pi
593
594**TL;DR for agents:** Install Pi: `npm install -g @mariozechner/pi-coding-agent`. Install the AntSeed extension: `pi install git:github.com/AntSeed/pi-antseed`. Restart or `/reload`. The extension calls `pi.registerProvider("antseed", { api: "openai-responses", baseUrl: "http://localhost:8377/v1" })` and auto-discovers models from the pinned peer via GET /v1/models. Switch with `/model antseed/<service-id>`. Override base URL with `ANTSEED_BASE_URL` env var; auth with `ANTSEED_API_KEY`.
595
596**What Pi is.** Pi (`@mariozechner/pi-coding-agent`) is a minimal, hackable terminal coding agent by Mario Zechner — the same lineage as [pi-mono](https://github.com/badlogic/pi-mono). It ships with four default tools (`read`, `write`, `edit`, `bash`) and lets you extend everything else — commands, providers, themes, even the editor UI — through TypeScript *extensions*, *skills*, and *prompt templates*. No fork required.
597
598**What the AntSeed extension does.** [`pi-antseed`](https://github.com/AntSeed/pi-antseed) is a Pi extension that registers the local buyer proxy as a Pi provider named `antseed`. Once installed, every service your pinned peer advertises shows up under `antseed/<id>` in Pi's model picker (Ctrl+L or `/model`) — you switch with `/model antseed/minimax-m2.7` just like any built-in.
599
600**Why an extension instead of env vars.** Pi already speaks dozens of provider protocols natively. The extension calls `pi.registerProvider("antseed", { api: "openai-responses", authHeader: true, baseUrl: "http://localhost:8377/v1" })` — Pi then handles auth headers, streaming, retries, and tool-calling. The Responses API path preserves reasoning items across turns for reasoning-capable models, while the extension still auto-refreshes the model list from `GET /v1/models` so the menu reflects what your pinned peer can serve.
601
602**Install**
603
604- **Install Pi itself (the coding agent CLI)**
605 ```bash
606 npm install -g @mariozechner/pi-coding-agent
607 ```
608 > Pi requires Node.js 20+. The binary is `pi`. Verify with `pi --version`. Without any extensions, Pi can already talk to Claude / GPT / Gemini / Groq / etc. via API key or OAuth — the AntSeed extension below is what teaches it to route through your local buyer proxy.
609- **Install the AntSeed extension into Pi**
610 ```bash
611 pi install git:github.com/AntSeed/pi-antseed
612 ```
613 > Pi extensions install from a git URL or a local path. Alternatives: `pi -e git:github.com/AntSeed/pi-antseed` runs the extension once without installing, useful for trying it out. `pi install ./pi-antseed` works from a local clone.
614- **Reload Pi so the new provider is picked up**
615 ```bash
616 /reload
617 ```
618 > Run this inside the Pi REPL (after typing `pi` to launch it). It re-scans extensions, skills, prompt templates, keybindings, and context files. A full restart works too.
619
620**Configure**
621
622```bash
623export ANTSEED_BASE_URL="http://localhost:8377/v1"
624```
625
626> **GUI:**
627>
628> No GUI config needed in the common case — the extension reads `ANTSEED_BASE_URL` (default `http://localhost:8377/v1`) and discovers models from the pinned peer automatically. Only set `ANTSEED_API_KEY` if you front the buyer proxy with your own auth layer, or `ANTSEED_MODELS="id1,id2"` to skip discovery and register a fixed list.
629
630**Suggested models:** `minimax-m2.7`, `claude-sonnet-4-6`, `deepseek-v4-flash`, `qwen3-coder-480b`
631
632The extension auto-discovers from `GET /v1/models` after Pi loads, so anything your pinned peer advertises shows up under `antseed/...`. After re-pinning a different peer, run `/reload` in Pi to refresh the model list.
633
634**Test it**
635
636- **Launch Pi**
637 ```bash
638 pi
639 ```
640 > You'll see Pi's startup header, which lists loaded extensions. Look for `antseed` (or `pi-antseed`) in that list — if it's there, the extension loaded successfully.
641- **Open the model picker and pick an AntSeed-routed model**
642 ```bash
643 /model
644 ```
645 > Or press Ctrl+L. The picker is fuzzy-searchable; type "antseed" to filter. You should see entries like `antseed/claude-sonnet-4-6`, `antseed/deepseek-v4-flash`, etc. — one for each service your pinned peer advertises.
646- **Or switch directly via slash command**
647 ```bash
648 /model antseed/minimax-m2.7
649 ```
650 > Replace `minimax-m2.7` with any id from `curl http://localhost:8377/v1/models`. After this, every prompt routes through AntSeed → your pinned peer → the model.
651
652**Troubleshooting**
653
654- *`pi: command not found` after install* — Your global npm bin is not on `PATH`. Run `npm prefix -g` to find it, then add `<that-path>/bin` to `PATH` in your shell rc. Or use a Node version manager (nvm, fnm, volta) which handles this automatically.
655- *`antseed` doesn't appear in the model picker (`/model` or Ctrl+L)* — The extension didn't load. Re-run `pi install git:github.com/AntSeed/pi-antseed`, restart Pi, and watch the startup header — it lists every loaded extension and surfaces load errors there.
656- *Picker only shows a few hard-coded `antseed/...` ids, not what my peer offers* — Pi started before the buyer proxy was up, so the extension fell back to its built-in seed list. Make sure `antseed buyer start` is running and a peer is pinned, then run `/reload` inside Pi to refresh the model list.
657- *Empty `/v1/models` from the proxy* — No peer is connected. Run `antseed network browse` to see options, then `antseed buyer connection set --peer <peerId>`. Or launch the proxy with `antseed buyer start --router <name>` for automatic peer selection.
658- *5xx from the proxy mid-conversation* — Usually means the pinned peer doesn't offer the model you asked for, or has just gone offline. Re-pin via `antseed buyer connection set --peer <peerId>` and `/reload` in Pi.
659- *Want to use a custom buyer proxy URL (remote host, custom port)* — Set `ANTSEED_BASE_URL=http://your-host:8377/v1` in the shell that launches `pi`. The extension reads this on startup. If your proxy is fronted by auth, also set `ANTSEED_API_KEY=<token>`.
660
661**How Pi talks to AntSeed**
662
663- **Wire format sent by Pi:** OpenAI Responses (hits `/v1/responses` on the buyer proxy).
664- **Best-fit services:** any service whose `protocols` array contains `openai-responses` — that is what the peer advertises as natively-supported, so traffic passes through with zero translation overhead.
665- **How to check a peer:** run `antseed network peer <peerId> --json` and look at `peer.providerServiceApiProtocols[provider].services[service]` for each model. The browse command exposes the same field per peer.
666- **When protocols differ:** AntSeed's `@antseed/api-adapter` translates between OpenAI Responses and the service's native protocol on the fly. So a request from Pi can still reach a service that only advertises a different protocol — just with a small transform step.
667
668**Links**
669
670- [Pi coding agent (npm)](https://www.npmjs.com/package/@mariozechner/pi-coding-agent)
671- [Pi source (badlogic/pi-mono)](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent)
672- [pi-antseed extension](https://github.com/AntSeed/pi-antseed)
673
674---
675
676## OpenClaw
677
678*Open-source autonomous agent runtime — register AntSeed as a custom provider in `openclaw.json`.*
679
680- **Category:** Autonomous agents
681- **Wire format:** Anthropic Messages
682- **Setup time:** ~3 min
683- **Page:** https://antseed.com/integrations/openclaw
684
685**TL;DR for agents:** Edit ~/.openclaw/openclaw.json: under models.providers, add an `antseed` entry with baseUrl=http://127.0.0.1:8377, api="anthropic-messages", apiKey="antseed-p2p", and a `models[]` array whose `id` values match service ids from GET /v1/models. Optionally `openclaw config set agents.defaults.model.primary "antseed/<id>"`. Reload with `openclaw config reload`.
686
687**What OpenClaw is.** OpenClaw is an open-source agent runtime for autonomous, long-running tasks (research, coding, web automation). It loads its provider catalog from `~/.openclaw/openclaw.json` — each entry is an HTTP endpoint plus a wire protocol (`anthropic-messages`, `openai-chat`, etc.) and a list of models.
688
689**How AntSeed plugs in.** Add a provider entry called `antseed` that points at `http://127.0.0.1:8377` with `api: "anthropic-messages"`. Each model id you list under that provider must be a service id your pinned peer advertises — OpenClaw will surface them in its model picker as `antseed/<service-id>`.
690
691**Why a config entry instead of env vars.** OpenClaw runs many providers in parallel (one per task, sometimes one per agent). A single base-URL override would force every agent through AntSeed; a named provider lets you mix AntSeed with hosted Anthropic, OpenAI, or local models on a per-agent basis.
692
693**Install**
694
695- **Install OpenClaw**
696 ```bash
697 npm install -g openclaw
698 ```
699 > Verify with `openclaw --version`. The config file lives at `~/.openclaw/openclaw.json` and is created on first launch.
700
701**Configure**
702
703```json title="~/.openclaw/openclaw.json (merge into the existing `models.providers` object)"
704{
705 "models": {
706 "providers": {
707 "antseed": {
708 "baseUrl": "http://127.0.0.1:8377",
709 "apiKey": "antseed-p2p",
710 "api": "anthropic-messages",
711 "models": [
712 {
713 "id": "claude-sonnet-4-6",
714 "name": "Claude Sonnet 4.6 (via AntSeed)",
715 "reasoning": false,
716 "input": ["text"],
717 "contextWindow": 200000,
718 "maxTokens": 8192
719 },
720 {
721 "id": "deepseek-v4-flash",
722 "name": "DeepSeek v4 Flash (via AntSeed)",
723 "reasoning": false,
724 "input": ["text"],
725 "contextWindow": 128000,
726 "maxTokens": 8192
727 }
728 ]
729 }
730 }
731 }
732}
733```
734
735```bash
736# Set AntSeed as the default model for new agents:
737openclaw config set agents.defaults.model.primary "antseed/claude-sonnet-4-6"
738```
739
740**Suggested models:** `claude-sonnet-4-6`, `claude-opus-4-7`, `deepseek-v4-flash`, `gpt-oss-120b`
741
742Each `id` under `models[]` must match a service id from `curl http://127.0.0.1:8377/v1/models`. `apiKey` is required by OpenClaw's validator but ignored by the proxy — any non-empty string works. The `"antseed-p2p"` value is just convention.
743
744**Test it**
745
746- **Confirm the proxy advertises the service ids you put in config**
747 ```bash
748 curl -s http://127.0.0.1:8377/v1/models | jq '.data[].id'
749 ```
750 *Example response:*
751 ```
752 "claude-opus-4-7"
753 "claude-sonnet-4-6"
754 "deepseek-v4-flash"
755 "gpt-oss-120b"
756 ```
757 > If a model id you listed in `openclaw.json` doesn't appear here, your pinned peer doesn't serve it. Pin a different peer or remove the entry.
758- **Reload OpenClaw and check the provider list**
759 ```bash
760 openclaw config reload && openclaw providers list
761 ```
762 > Or restart OpenClaw. You should see `antseed` with the model count you configured.
763- **Run an agent against AntSeed**
764 ```bash
765 openclaw run "Summarize the README in this repo" --model antseed/claude-sonnet-4-6
766 ```
767
768**Troubleshooting**
769
770- *`provider "antseed" not found` when launching an agent* — JSON parse error in `openclaw.json`, or you put the entry in the wrong nesting level. The provider must live under `models.providers.antseed`. Run `openclaw config validate` to surface parse errors.
771- *OpenClaw lists `antseed/<id>` but every call returns `404 model_not_found`* — The pinned peer doesn't advertise that service id. Run `antseed network peer <peerId>` to see what it actually offers, or pin a different peer with `antseed buyer connection set --peer <peerId>`.
772- *Streaming errors on long-running agents* — AntSeed supports SSE streaming. If you see truncated responses, check that no proxy in front of OpenClaw is buffering (Cloudflare, nginx). The buyer proxy itself does not buffer.
773- *Agent stalls on first request after a deploy* — AntSeed opens a payment channel on the first request to a new peer (one on-chain transaction, ~5–15s on Base). Subsequent requests reuse the channel. Pre-warm by running a quick `curl` before launching the agent.
774
775**How OpenClaw talks to AntSeed**
776
777- **Wire format sent by OpenClaw:** Anthropic Messages (hits `/v1/messages` on the buyer proxy).
778- **Best-fit services:** any service whose `protocols` array contains `anthropic-messages` — that is what the peer advertises as natively-supported, so traffic passes through with zero translation overhead.
779- **How to check a peer:** run `antseed network peer <peerId> --json` and look at `peer.providerServiceApiProtocols[provider].services[service]` for each model. The browse command exposes the same field per peer.
780- **When protocols differ:** AntSeed's `@antseed/api-adapter` translates between Anthropic Messages and the service's native protocol on the fly. So a request from OpenClaw can still reach a service that only advertises a different protocol — just with a small transform step.
781- **Caveat:** services whose only advertised protocol is `openai-responses` require streaming. If OpenClaw sends a non-streaming request and the proxy routes it to one of those services, the call fails with `HTTP 400: Stream must be set to true`. Pick a service whose `protocols` includes `anthropic-messages` (or another non-responses protocol) to avoid this.
782
783**Links**
784
785- [OpenClaw repo](https://github.com/openclaw/openclaw)
786- [AntSeed skill: openclaw-antseed (full walkthrough)](https://github.com/AntSeed/antseed/tree/main/skills/openclaw-antseed)
787
788---
789
790## Hermes
791
792*Nous Research's agent framework — register AntSeed as a custom provider in `config.yaml`.*
793
794- **Category:** Autonomous agents
795- **Wire format:** OpenAI Chat Completions
796- **Setup time:** ~3 min
797- **Page:** https://antseed.com/integrations/hermes
798
799**TL;DR for agents:** Edit ~/.hermes/config.yaml: add a `custom_providers` entry named `antseed` with base_url=http://127.0.0.1:8377/v1, api_mode=chat_completions, api_key="antseed-p2p", and a `models:` list whose ids match service ids from GET /v1/models. Set `model.default` to one of those ids and `model.provider: antseed`. Pin `auxiliary.title_generation.model` and `auxiliary.compression.model` to a chat_completions model to avoid streaming errors against openai-responses peers.
800
801**What Hermes is.** Hermes is the agent framework from [Nous Research](https://nousresearch.com/) (successor to OpenClaw's lineage). It's designed for autonomous, multi-step workflows — research agents, coding agents, swarms — and reads its model catalog from `~/.hermes/config.yaml`.
802
803**How AntSeed plugs in.** Add an entry under `custom_providers` with `base_url: http://127.0.0.1:8377/v1`, `api_mode: chat_completions`, and a list of `models`. Each model id must be a service id your pinned peer advertises. Then point `model.default` at the one you want as primary.
804
805**One Hermes-specific gotcha.** Some peers serve GPT-style models via the `openai-responses` protocol, which *requires* streaming. Hermes' auxiliary calls (title generation, context compression) are non-streaming and will fail against those models with `HTTP 400: Stream must be set to true`. Pin auxiliary slots to a `chat_completions` model (config example below).
806
807**Install**
808
809- **Install or build Hermes**
810 ```bash
811 # Follow Nous Research setup at https://github.com/NousResearch/hermes-agent
812 ```
813 > Hermes is typically run as a long-lived process (often under systemd on a server). The config file `~/.hermes/config.yaml` is read at startup — changes require a restart.
814
815**Configure**
816
817```yaml title="~/.hermes/config.yaml (merge into your existing config)"
818model:
819 default: claude-sonnet-4-6
820 provider: antseed
821
822custom_providers:
823 - name: antseed
824 base_url: http://127.0.0.1:8377/v1
825 api_key: antseed-p2p
826 api_mode: chat_completions
827 models:
828 - claude-sonnet-4-6
829 - claude-opus-4-7
830 - deepseek-v4-flash
831 - gpt-oss-120b
832 - minimax-m2.7
833
834# Pin auxiliary calls to a chat_completions model so non-streaming
835# requests (title generation, compression) don't break against
836# openai-responses peers.
837auxiliary:
838 title_generation:
839 provider: antseed
840 model: minimax-m2.7
841 compression:
842 provider: antseed
843 model: minimax-m2.7
844```
845
846**Suggested models:** `claude-sonnet-4-6`, `minimax-m2.7`, `deepseek-v4-flash`, `gpt-oss-120b`
847
848Only ids listed under `models:` show up in Hermes' picker — mirror it against `curl http://127.0.0.1:8377/v1/models` so you don't advertise models no peer serves. `model.provider: antseed` pins the default to this custom provider.
849
850**Test it**
851
852- **Confirm the proxy advertises the same ids your config references**
853 ```bash
854 curl -s http://127.0.0.1:8377/v1/models | jq '.data[].id'
855 ```
856 *Example response:*
857 ```
858 "claude-opus-4-7"
859 "claude-sonnet-4-6"
860 "deepseek-v4-flash"
861 "gpt-oss-120b"
862 "minimax-m2.7"
863 ```
864- **Restart Hermes to pick up the new provider**
865 ```bash
866 sudo systemctl restart hermes
867 ```
868 > Or whatever supervisor you use. Then check the journal: `sudo journalctl -u hermes --no-pager -n 30`.
869- **After the first request, confirm a channel opened and is being metered**
870 ```bash
871 antseed buyer status
872 antseed buyer metering
873 ```
874 > `status` shows `Active channels: 1` once the first request settles (~5–15s on Base — one on-chain tx to open the channel). `metering` shows the per-peer token + USDC totals for each channel. To poll: `watch -n 1 antseed buyer metering`.
875
876**Troubleshooting**
877
878- *`HTTP 400: Stream must be set to true` from auxiliary calls* — You're routing through a peer that serves the model via `openai-responses` (which requires streaming), but Hermes' auxiliaries are non-streaming. Pin the `auxiliary.*` slots to a `chat_completions` model (see the config block above). Confirm a model's protocol with `antseed network peer <peerId>` — look for `protocols: openai-chat-completions` vs `openai-responses`.
879- *Hermes loads the provider but every call returns `no_peer_pinned`* — In the default manual flow AntSeed does not auto-select a peer — pin one with `antseed buyer connection set --peer <peerId>`, send `x-antseed-pin-peer` per request, or start the buyer with a router plugin. The session pin survives buyer-proxy restarts (it's persisted to `~/.antseed/buyer.state.json`).
880- *Hermes runs on a remote host and can't reach `127.0.0.1:8377`* — Either run the buyer proxy on the same host as Hermes (recommended — keeps the hot signing key local), or expose the proxy via SSH tunnel: `ssh -N -L 127.0.0.1:8377:127.0.0.1:8377 user@hermes-host`. Do not bind the buyer proxy to a public interface.
881- *Want to swap the routed model without restarting AntSeed* — Edit `model.default` (and `models:` if needed) in `config.yaml`, re-pin a peer that serves it (`antseed buyer connection set --peer <peerId>`), then `sudo systemctl restart hermes`. The buyer proxy stays up; no contract calls.
882
883**How Hermes talks to AntSeed**
884
885- **Wire format sent by Hermes:** OpenAI Chat Completions (hits `/v1/chat/completions` on the buyer proxy).
886- **Best-fit services:** any service whose `protocols` array contains `openai-chat-completions` — that is what the peer advertises as natively-supported, so traffic passes through with zero translation overhead.
887- **How to check a peer:** run `antseed network peer <peerId> --json` and look at `peer.providerServiceApiProtocols[provider].services[service]` for each model. The browse command exposes the same field per peer.
888- **When protocols differ:** AntSeed's `@antseed/api-adapter` translates between OpenAI Chat Completions and the service's native protocol on the fly. So a request from Hermes can still reach a service that only advertises a different protocol — just with a small transform step.
889- **Caveat:** services whose only advertised protocol is `openai-responses` require streaming. If Hermes sends a non-streaming request and the proxy routes it to one of those services, the call fails with `HTTP 400: Stream must be set to true`. Pick a service whose `protocols` includes `openai-chat-completions` (or another non-responses protocol) to avoid this.
890
891**Links**
892
893- [Hermes Agent (Nous Research)](https://github.com/NousResearch/hermes-agent)
894- [AntSeed skill: hermes-antseed (full walkthrough including systemd, remote hosts, payment portal)](https://github.com/AntSeed/antseed/tree/main/skills/hermes-antseed)
895
896---
897
898## GenLayer Studio
899
900*Use AntSeed as an inference provider inside GenLayer Studio validators.*
901
902- **Category:** Frameworks
903- **Wire format:** OpenAI Chat Completions
904- **Setup time:** ~5 min
905- **Page:** https://antseed.com/integrations/genlayer-studio
906
907**TL;DR for agents:** In GenLayer Studio: drop one JSON file per model into `backend/node/create_nodes/default_providers/` with `provider: "antseed"`, `plugin: "openai-compatible"`, `model: "<service-id>"`, and `plugin_config.api_url: "http://host.docker.internal:8377"` (NO `/v1` suffix — the plugin appends it). Add `"antseed"` to the provider enum and an if/then rule to BOTH `backend/.../providers_schema.json` and `frontend/.../providers_schema.json`. Set `ANTSEED_API_KEY=antseed` in `.env`. Restart with `genlayer up --reset`. The user must run AntStation or `antseed buyer start` and pin a peer that serves the listed `model` ids.
908
909**What GenLayer Studio is.** Studio runs *Intelligent Contract* validators that consult LLMs to reach consensus. Each validator is configured with a provider entry that has a `provider` name, a `plugin` (one of `openai-compatible` / `anthropic` / `google` / `ollama` / `custom`), a `model` id, and a `plugin_config` with `api_url` and `api_key_env_var`.
910
911**How AntSeed plugs in.** Drop one JSON file per model into `backend/node/create_nodes/default_providers/` with `plugin: "openai-compatible"` and `api_url: "http://host.docker.internal:8377"`. Studio's openai-compatible plugin appends `/v1/chat/completions` automatically, so the buyer proxy receives a standard OpenAI Chat request and routes it to your pinned peer. Mirror the existing LibertAI entry (PR #1526) — it is the closest analogue: an openai-compatible host with a hosted base URL replaced by your local proxy.
912
913**Why `host.docker.internal`, not `localhost`.** Studio's backend runs in Docker via `genlayer up`. From inside the container, `localhost` means the container itself, not your host machine — it cannot reach the AntSeed buyer proxy on the host. Mac/Windows Docker exposes the host as `host.docker.internal`; on Linux you must add `extra_hosts: ["host.docker.internal:host-gateway"]` to the backend service in `docker-compose.yml` or run with `--network=host`.
914
915**Prerequisites**
916
917- GenLayer Studio cloned and running locally with `genlayer up` (see https://docs.genlayer.com/developers/intelligent-contracts/tools/genlayer-studio)
918
919**Install**
920
921- **On Linux only — make `host.docker.internal` resolve from inside the backend container**
922 ```yaml
923 # docker-compose.yml — patch the backend (jsonrpc) service
924 services:
925 jsonrpc:
926 extra_hosts:
927 - "host.docker.internal:host-gateway"
928 ```
929 > Mac and Windows Docker Desktop already expose the host as `host.docker.internal` automatically — skip this step on those platforms. Restart with `genlayer up --reset` after editing.
930
931**Configure**
932
933```json title="backend/node/create_nodes/default_providers/antseed_claude-sonnet-4-6.json"
934{
935 "provider": "antseed",
936 "plugin": "openai-compatible",
937 "model": "claude-sonnet-4-6",
938 "config": {},
939 "plugin_config": {
940 "api_key_env_var": "ANTSEED_API_KEY",
941 "api_url": "http://host.docker.internal:8377"
942 }
943}
944```
945
946```json title="backend/node/create_nodes/default_providers/antseed_deepseek-v4-flash.json"
947{
948 "provider": "antseed",
949 "plugin": "openai-compatible",
950 "model": "deepseek-v4-flash",
951 "config": {},
952 "plugin_config": {
953 "api_key_env_var": "ANTSEED_API_KEY",
954 "api_url": "http://host.docker.internal:8377"
955 }
956}
957```
958
959```bash title=".env (next to docker-compose.yml)"
960# AntSeed authenticates with your local identity key, not this value.
961# Studio's openai-compatible plugin still requires the env var to be set.
962ANTSEED_API_KEY=antseed
963```
964
965```json title="backend/node/create_nodes/providers_schema.json AND frontend/src/assets/schemas/providers_schema.json"
966// In each schema, add "antseed" to the provider enum's examples…
967"provider": {
968 "type": "string",
969 "examples": ["ollama", "openrouter", "libertai", "antseed", …]
970},
971
972// …and add an if/then block locking provider:antseed to plugin:openai-compatible
973{
974 "if": { "properties": { "provider": { "const": "antseed" } } },
975 "then": { "properties": { "plugin": { "const": "openai-compatible" } } }
976}
977```
978
979_Both schema files must be kept in sync — the backend uses one for validation, the frontend uses the other for the UI dropdown. This is exactly what PR #1526 did for LibertAI._
980
981**Suggested models:** `claude-sonnet-4-6`, `deepseek-v4-flash`, `gpt-oss-120b`, `qwen3-coder-480b`
982
983Each provider JSON file pins exactly one `model`. Studio enumerates these into the validator-creation UI; pick services you know your pinned peer offers (check `antseed network peer <peerId> --json | jq '.matchingServices[].service'`). To expose more models later, drop in more `antseed_<model>.json` files — no schema edit needed.
984
985**Test it**
986
987- **Restart Studio so it re-scans `default_providers/`**
988 ```bash
989 genlayer up --reset
990 ```
991 > `get_default_providers()` in `backend/node/create_nodes/providers.py` reads every `*.json` in that folder once on boot, validates against `providers_schema.json`, and caches the result. Schema-validation errors abort startup with the offending file path — watch the logs.
992- **In the Studio UI, create a new validator with provider "antseed"**
993 > You should see your `antseed_*.json` model ids in the dropdown. Save and trigger a contract that calls `genlayer.eq_principle.prompt(…)` — the request hits `http://host.docker.internal:8377/v1/chat/completions` on the AntSeed proxy and is forwarded to your pinned peer.
994- **Confirm the validator call hit AntSeed**
995 ```bash
996 antseed buyer metering
997 ```
998 > Each validator call adds tokens + USDC to the channel for the peer you pinned. Run after a Studio request to see the totals update. To poll live: `watch -n 1 antseed buyer metering`.
999
1000**Troubleshooting**
1001
1002- *`Error validating file … antseed_*.json` on `genlayer up`* — The schema rejected your provider JSON. Most common cause: missing the if/then rule for `provider:antseed`, so it falls through with the wrong `plugin`. Add the rule to *both* `backend/.../providers_schema.json` and `frontend/.../providers_schema.json`. Run `genlayer up --reset` after editing.
1003- *Validator hangs, then errors with `Connection refused` to `host.docker.internal:8377`* — The backend container can't see your host. On Linux, add `extra_hosts: ["host.docker.internal:host-gateway"]` under the backend service in `docker-compose.yml` (see install step 2). On Mac/Windows, confirm Docker Desktop is running and the AntSeed proxy is up: `curl http://host.docker.internal:8377/v1/models` from inside the container with `docker compose exec jsonrpc curl …`.
1004- *Validator returns `no_peer_pinned`* — No peer is pinned in the buyer proxy. Run `antseed network browse`, pick one, then `antseed buyer connection set --peer <peerId>`. Alternatively, send a per-request `x-antseed-pin-peer` header by extending the openai-compatible plugin — not currently exposed in the standard schema, so session pin is the path of least resistance.
1005- *`404 model_not_found` from a validator using e.g. `claude-sonnet-4-6`* — Your pinned peer doesn't advertise that service id. Run `antseed network peer <peerId> --json | jq '.matchingServices[].service'` to see what it does serve. Either pin a different peer or remove that `antseed_<model>.json` file.
1006- *First call after a restart takes 5–15 seconds* — AntSeed opens a payment channel on the first request to a new peer (one Base-mainnet transaction). Subsequent calls reuse the channel. Pre-warm with `curl -s http://localhost:8377/v1/chat/completions -d '{"model":"<id>","messages":[{"role":"user","content":"hi"}]}'` before triggering Studio.
1007
1008**Caveats**
1009
1010- AntSeed is a local daemon, not a hosted endpoint. Every Studio operator must run AntStation or `antseed buyer start` on their own machine and fund their wallet — there is no central account.
1011- Free services exist on the AntSeed network (`in: 0, out: 0`), but using paid ones requires a USDC deposit on Base. AntStation guides users through this on first launch; the CLI exposes it as `antseed payments`.
1012
1013**How GenLayer Studio talks to AntSeed**
1014
1015- **Wire format sent by GenLayer Studio:** OpenAI Chat Completions (hits `/v1/chat/completions` on the buyer proxy).
1016- **Best-fit services:** any service whose `protocols` array contains `openai-chat-completions` — that is what the peer advertises as natively-supported, so traffic passes through with zero translation overhead.
1017- **How to check a peer:** run `antseed network peer <peerId> --json` and look at `peer.providerServiceApiProtocols[provider].services[service]` for each model. The browse command exposes the same field per peer.
1018- **When protocols differ:** AntSeed's `@antseed/api-adapter` translates between OpenAI Chat Completions and the service's native protocol on the fly. So a request from GenLayer Studio can still reach a service that only advertises a different protocol — just with a small transform step.
1019- **Caveat:** services whose only advertised protocol is `openai-responses` require streaming. If GenLayer Studio sends a non-streaming request and the proxy routes it to one of those services, the call fails with `HTTP 400: Stream must be set to true`. Pick a service whose `protocols` includes `openai-chat-completions` (or another non-responses protocol) to avoid this.
1020
1021**Links**
1022
1023- [GenLayer Studio repo](https://github.com/genlayerlabs/genlayer-studio)
1024- [Studio docs](https://docs.genlayer.com/developers/intelligent-contracts/tools/genlayer-studio)
1025- [Reference PR (LibertAI)](https://github.com/genlayerlabs/genlayer-studio/pull/1526)
1026- [providers_schema.json (source of truth)](https://github.com/genlayerlabs/genlayer-studio/blob/main/backend/node/create_nodes/providers_schema.json)
1027
1028---
1029
1030## Vercel AI SDK
1031
1032*Use `@ai-sdk/openai-compatible` to call AntSeed from `generateText` / `streamText` / `generateObject`.*
1033
1034- **Category:** Frameworks
1035- **Wire format:** OpenAI Chat Completions
1036- **Setup time:** ~5 min
1037- **Page:** https://antseed.com/integrations/vercel-ai-sdk
1038
1039**TL;DR for agents:** createOpenAICompatible({ name: 'antseed', baseURL: 'http://localhost:8377/v1', apiKey: 'antseed' }), then antseed('<service-id>') as the model. Use @ai-sdk/openai-compatible (NOT @ai-sdk/openai). Service ids come from GET http://localhost:8377/v1/models. Per-request peer override: pass headers: { 'x-antseed-pin-peer': '<peerId>' } in generateText/streamText.
1040
1041**What the AI SDK is.** Vercel's `ai` package is a provider-agnostic TypeScript toolkit for building LLM apps and agents. You pick a *provider* (a small adapter package), instantiate a model from it, and pass that model into one of the framework's primitives: `generateText`, `streamText`, `generateObject`, or `streamObject`. The AI SDK handles tool-calling, structured output, message history, and streaming for you.
1042
1043**How AntSeed plugs in.** AntSeed is OpenAI-Chat-compatible at `http://localhost:8377/v1`, so the right adapter is `@ai-sdk/openai-compatible` (not `@ai-sdk/openai`). The official OpenAI provider is locked to OpenAI's API surface and quietly drops third-party fields; the openai-compatible provider is the one Vercel's own docs recommend for proxies, gateways, and any non-OpenAI server that speaks Chat Completions. You point it at the AntSeed proxy with `baseURL` and pass any non-empty `apiKey` placeholder — the proxy authenticates with your local identity key, not with this header.
1044
1045**Which model ids work.** The first argument to the provider call is the AntSeed *service id* (e.g. `claude-sonnet-4-6`, `deepseek-v4-flash`). It must match a service your pinned peer advertises — confirm with `curl http://localhost:8377/v1/models`.
1046
1047**Prerequisites**
1048
1049- Node.js 18 or newer
1050
1051**Install**
1052
1053- **Install the SDK and the openai-compatible provider**
1054 ```bash
1055 npm install ai @ai-sdk/openai-compatible zod
1056 ```
1057 > `zod` is only needed if you call `generateObject` / `streamObject`. Skip it for plain text generation.
1058
1059**Configure**
1060
1061```typescript
1062// antseed.ts — a single provider instance you can import everywhere
1063import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
1064
1065export const antseed = createOpenAICompatible({
1066 name: 'antseed',
1067 baseURL: 'http://localhost:8377/v1',
1068 apiKey: 'antseed', // any non-empty string — proxy ignores this header
1069 includeUsage: true, // surface token counts in streaming responses too
1070});
1071```
1072
1073```typescript
1074// stream.ts
1075import { streamText } from 'ai';
1076import { antseed } from './antseed';
1077
1078const result = streamText({
1079 model: antseed('claude-sonnet-4-6'), // an AntSeed service id
1080 prompt: 'Why is the sky blue?',
1081});
1082
1083for await (const chunk of result.textStream) {
1084 process.stdout.write(chunk);
1085}
1086
1087console.log('\nusage:', await result.usage);
1088```
1089
1090```typescript
1091// structured.ts — generateObject works the same way
1092import { generateObject } from 'ai';
1093import { z } from 'zod';
1094import { antseed } from './antseed';
1095
1096const { object } = await generateObject({
1097 model: antseed('claude-sonnet-4-6'),
1098 schema: z.object({
1099 title: z.string(),
1100 bullets: z.array(z.string()).min(3).max(5),
1101 }),
1102 prompt: 'Summarize the AntSeed buyer-proxy README as a slide.',
1103});
1104console.log(object);
1105```
1106
1107**Suggested models:** `claude-sonnet-4-6`, `deepseek-v4-flash`, `gpt-oss-120b`, `qwen3-coder-480b`
1108
1109The string you pass to `antseed('<id>')` is forwarded verbatim as `model` in the OpenAI Chat request. Run `curl -s http://localhost:8377/v1/models | jq '.data[].id'` to see exactly what your pinned peer offers.
1110
1111**Test it**
1112
1113- **Run a smoke test with `tsx`**
1114 ```bash
1115 npx tsx stream.ts
1116 ```
1117 *Example output:*
1118 ```
1119 The sky is blue because shorter (blue) wavelengths of sunlight
1120 scatter much more than longer (red) wavelengths in Earth's atmosphere…
1121
1122 usage: { promptTokens: 14, completionTokens: 78, totalTokens: 92 }
1123 ```
1124 > If you see `404 model_not_found`, the pinned peer does not advertise the id you passed. If you see `no_peer_pinned`, run `antseed buyer connection set --peer <peerId>` first — or send the per-request header (next step).
1125- **Per-request peer override (no session pin needed)**
1126 ```typescript
1127 // Use `headers` to fan out to different peers per call.
1128 const result = streamText({
1129 model: antseed('claude-sonnet-4-6'),
1130 prompt: 'hi',
1131 headers: {
1132 'x-antseed-pin-peer': 'cccccccccccccccccccccccccccccccccccccccc',
1133 },
1134 });
1135 ```
1136 > Useful when one Node process serves many tenants and you want each request routed to a different peer. The header overrides the session pin for that single call.
1137
1138**Troubleshooting**
1139
1140- *TypeScript complains that `antseed` has no call signature* — You imported from `@ai-sdk/openai` instead of `@ai-sdk/openai-compatible`. Switch the package — the SDK's official OpenAI provider is locked to OpenAI's service ids and rejects unknown ones.
1141- *`generateObject` returns malformed JSON* — The AI SDK is strict about JSON Schema support. Pass `supportsStructuredOutputs: true` to `createOpenAICompatible` only if your pinned peer's service supports OpenAI-style structured outputs natively. If unsure, leave it off — the SDK falls back to tool-call-based JSON which works everywhere.
1142- *`includeUsage` is set but `result.usage` is undefined* — Some upstream providers behind AntSeed do not emit usage on streamed responses. Try `generateText` instead of `streamText` for definitive token counts; otherwise run `antseed buyer metering` for the authoritative per-channel token + USDC totals AntSeed itself measured.
1143- *Browser/edge runtime fails with `fetch` errors* — The AntSeed proxy listens on `127.0.0.1:8377`, which is not reachable from a browser tab on a deployed site. The AI SDK is designed to run on the server (Route Handlers, Server Actions, edge functions on your own machine, or a Node process); don't call it from a client component when the model is AntSeed.
1144
1145**How Vercel AI SDK talks to AntSeed**
1146
1147- **Wire format sent by Vercel AI SDK:** OpenAI Chat Completions (hits `/v1/chat/completions` on the buyer proxy).
1148- **Best-fit services:** any service whose `protocols` array contains `openai-chat-completions` — that is what the peer advertises as natively-supported, so traffic passes through with zero translation overhead.
1149- **How to check a peer:** run `antseed network peer <peerId> --json` and look at `peer.providerServiceApiProtocols[provider].services[service]` for each model. The browse command exposes the same field per peer.
1150- **When protocols differ:** AntSeed's `@antseed/api-adapter` translates between OpenAI Chat Completions and the service's native protocol on the fly. So a request from Vercel AI SDK can still reach a service that only advertises a different protocol — just with a small transform step.
1151- **Caveat:** services whose only advertised protocol is `openai-responses` require streaming. If Vercel AI SDK sends a non-streaming request and the proxy routes it to one of those services, the call fails with `HTTP 400: Stream must be set to true`. Pick a service whose `protocols` includes `openai-chat-completions` (or another non-responses protocol) to avoid this.
1152
1153**Links**
1154
1155- [AI SDK docs](https://ai-sdk.dev/docs)
1156- [@ai-sdk/openai-compatible provider docs](https://ai-sdk.dev/providers/openai-compatible-providers)
1157- [`ai` on npm](https://www.npmjs.com/package/ai)
1158
1159---
1160
1161## LangChain (Python)
1162
1163*Drop-in `ChatOpenAI(base_url=…)` — works in chains, LCEL, and LangGraph agents.*
1164
1165- **Category:** Frameworks
1166- **Wire format:** OpenAI Chat Completions
1167- **Setup time:** ~5 min
1168- **Page:** https://antseed.com/integrations/langchain-python
1169
1170**TL;DR for agents:** ChatOpenAI(model='<service-id>', base_url='http://localhost:8377/v1', api_key='antseed') from langchain-openai. Drops into LCEL, create_react_agent, RAG, with_structured_output. Per-request peer override: extra_headers={'x-antseed-pin-peer': '<peerId>'}. Service ids come from GET http://localhost:8377/v1/models. Reasoning traces (reasoning_content, etc.) are NOT preserved by ChatOpenAI — use the Responses endpoint for those.
1171
1172**What LangChain is.** LangChain is the Python framework for composing LLMs with tools, retrievers, memory, and agents. The chat-model interface is `BaseChatModel`; `ChatOpenAI` from `langchain-openai` is a concrete subclass that talks the OpenAI Chat Completions wire format.
1173
1174**How AntSeed plugs in.** Pass `base_url="http://localhost:8377/v1"` and any non-empty `api_key` to `ChatOpenAI`. Once you have an instance, every primitive that accepts a chat model — LCEL pipes (`prompt | llm | parser`), tool-calling agents, `create_react_agent`, LangGraph nodes, RAG chains, structured-output binding via `with_structured_output` — will route through AntSeed without any further changes.
1175
1176**One thing to know.** LangChain's `ChatOpenAI` is OpenAI-strict by design: it will not preserve non-standard response fields like `reasoning_content`, `reasoning`, or `reasoning_details` that some third-party servers emit. For chat, tool-calling, and structured output this is fine. If you specifically need a model's reasoning traces, consider using the AntSeed buyer proxy with the OpenAI Responses endpoint (`/v1/responses`) via a different provider package, or use a model that returns reasoning inline.
1177
1178**Prerequisites**
1179
1180- Python 3.10 or newer
1181
1182**Install**
1183
1184- **Install LangChain and the OpenAI integration**
1185 ```bash
1186 pip install -U langchain langchain-openai
1187 ```
1188
1189**Configure**
1190
1191```python
1192# antseed_llm.py — import this once, reuse everywhere.
1193from langchain_openai import ChatOpenAI
1194
1195antseed = ChatOpenAI(
1196 model="claude-sonnet-4-6", # an AntSeed service id
1197 base_url="http://localhost:8377/v1",
1198 api_key="antseed", # any non-empty string
1199 temperature=0.7,
1200 # max_completion_tokens=2048, # uncomment for hard caps
1201)
1202
1203print(antseed.invoke("Hello").content)
1204```
1205
1206```python
1207# pipeline.py — LCEL chain. Identical to OpenAI; the swap is invisible.
1208from langchain_core.prompts import ChatPromptTemplate
1209from langchain_core.output_parsers import StrOutputParser
1210from antseed_llm import antseed
1211
1212prompt = ChatPromptTemplate.from_messages([
1213 ("system", "You are a concise technical writer."),
1214 ("human", "Explain {topic} in one paragraph."),
1215])
1216
1217chain = prompt | antseed | StrOutputParser()
1218print(chain.invoke({"topic": "payment channels"}))
1219```
1220
1221```python
1222# tools.py — tool-calling agent. Works because AntSeed forwards OpenAI tool calls verbatim.
1223from langchain_core.tools import tool
1224from langgraph.prebuilt import create_react_agent
1225from antseed_llm import antseed
1226
1227@tool
1228def get_weather(city: str) -> str:
1229 """Return the current weather for a city."""
1230 return f"It's 22°C and sunny in {city}."
1231
1232agent = create_react_agent(antseed, [get_weather])
1233result = agent.invoke({
1234 "messages": [("user", "What's the weather in Lisbon?")]
1235})
1236print(result["messages"][-1].content)
1237```
1238
1239**Suggested models:** `claude-sonnet-4-6`, `deepseek-v4-flash`, `gpt-oss-120b`, `qwen3-coder-480b`
1240
1241Pick services whose `protocols` array includes `openai-chat-completions` (most do natively; the rest are translated automatically by `@antseed/api-adapter`). Tool calling and structured output rely on the service supporting OpenAI-style function-call syntax — confirm with a quick smoke test before building large agents.
1242
1243**Test it**
1244
1245- **Run the basic example**
1246 ```bash
1247 python antseed_llm.py
1248 ```
1249 *Example output:*
1250 ```
1251 Hello! How can I help you today?
1252 ```
1253- **Per-request peer override (no session pin needed)**
1254 ```python
1255 # extra_headers is forwarded as-is to the proxy.
1256 from langchain_openai import ChatOpenAI
1257
1258 llm = ChatOpenAI(
1259 model="claude-sonnet-4-6",
1260 base_url="http://localhost:8377/v1",
1261 api_key="antseed",
1262 extra_headers={
1263 "x-antseed-pin-peer": "cccccccccccccccccccccccccccccccccccccccc",
1264 },
1265 )
1266 print(llm.invoke("hi").content)
1267 ```
1268 > Use this when a single Python process needs to fan out to different peers per call (multi-tenant, scheduled jobs, A/B tests across peers).
1269- **Verify it actually went through AntSeed**
1270 ```bash
1271 antseed buyer metering
1272 ```
1273 > `buyer metering` reads the local SQLite log and prints per-channel token + USDC totals. After your `python` call, the channel for the peer you pinned should show non-zero input/output tokens. (`buyer status` is a snapshot view — it shows the active-channel count but not per-call usage.)
1274
1275**Troubleshooting**
1276
1277- *`openai.NotFoundError: 404 … model_not_found`* — The pinned peer does not advertise the id you passed. Confirm with `curl http://localhost:8377/v1/models | jq` and either pin a different peer or change the `model=` argument.
1278- *`openai.APIConnectionError: Connection refused`* — The buyer proxy is not running. Start it with `antseed buyer start` (or open AntStation desktop). Confirm `curl http://localhost:8377/v1/models` works before retrying from Python.
1279- *`with_structured_output` returns the right schema but empty fields* — Either the model behind the pinned peer does not support OpenAI tool-call syntax, or you used `method="json_mode"` against a service that does not honor it. Try `method="function_calling"` (the default), and prefer services tagged `coding` or `tools` in `antseed network peer <peerId> --json`.
1280- *Streaming with `stream=True` truncates mid-response* — A buffering proxy (nginx, Cloudflare) sits between your code and the buyer proxy. The AntSeed proxy itself does not buffer SSE. Either bypass the intermediate proxy or set its buffering off (`proxy_buffering off;` in nginx).
1281- *Reasoning traces missing on a model you know emits them* — See the third paragraph above: `langchain-openai` does not preserve non-standard response fields. For first-class reasoning support, route the request through the OpenAI Responses endpoint (`POST /v1/responses` on the proxy) using a Responses-aware client, or pick a model that puts reasoning inline in `content`.
1282
1283**How LangChain (Python) talks to AntSeed**
1284
1285- **Wire format sent by LangChain (Python):** OpenAI Chat Completions (hits `/v1/chat/completions` on the buyer proxy).
1286- **Best-fit services:** any service whose `protocols` array contains `openai-chat-completions` — that is what the peer advertises as natively-supported, so traffic passes through with zero translation overhead.
1287- **How to check a peer:** run `antseed network peer <peerId> --json` and look at `peer.providerServiceApiProtocols[provider].services[service]` for each model. The browse command exposes the same field per peer.
1288- **When protocols differ:** AntSeed's `@antseed/api-adapter` translates between OpenAI Chat Completions and the service's native protocol on the fly. So a request from LangChain (Python) can still reach a service that only advertises a different protocol — just with a small transform step.
1289- **Caveat:** services whose only advertised protocol is `openai-responses` require streaming. If LangChain (Python) sends a non-streaming request and the proxy routes it to one of those services, the call fails with `HTTP 400: Stream must be set to true`. Pick a service whose `protocols` includes `openai-chat-completions` (or another non-responses protocol) to avoid this.
1290
1291**Links**
1292
1293- [LangChain docs](https://python.langchain.com)
1294- [ChatOpenAI integration page](https://docs.langchain.com/oss/python/integrations/chat/openai)
1295- [`langchain-openai` on PyPI](https://pypi.org/project/langchain-openai/)
1296
1297---
1298
1299## curl / raw HTTP
1300
1301*Hit the proxy with plain HTTP — useful for scripts and debugging.*
1302
1303- **Category:** Raw HTTP
1304- **Wire format:** Multi-format
1305- **Setup time:** ~1 min
1306- **Page:** https://antseed.com/integrations/curl
1307
1308**TL;DR for agents:** POST JSON to http://localhost:8377/v1/messages, /v1/chat/completions, or /v1/responses. No Authorization header required.
1309
1310The buyer proxy is a vanilla HTTP server. Anything that can issue an HTTP POST works. Three endpoints are exposed:
1311
1312• `POST /v1/messages` — Anthropic Messages format
1313• `POST /v1/chat/completions` — OpenAI Chat Completions
1314• `POST /v1/responses` — OpenAI Responses API
1315
1316**Configure**
1317
1318```bash
1319# Anthropic format
1320curl http://localhost:8377/v1/messages \
1321 -H 'content-type: application/json' \
1322 -d '{
1323 "model": "claude-sonnet-4-6",
1324 "max_tokens": 1024,
1325 "messages": [{"role": "user", "content": "Hello"}]
1326 }'
1327
1328# OpenAI Chat format
1329curl http://localhost:8377/v1/chat/completions \
1330 -H 'content-type: application/json' \
1331 -d '{
1332 "model": "deepseek-v3.1",
1333 "messages": [{"role": "user", "content": "Hello"}]
1334 }'
1335```
1336
1337**How curl / raw HTTP talks to AntSeed**
1338
1339curl / raw HTTP can send any of AntSeed's supported wire formats. Match the request format against each service's `protocols` array (advertised per service in `providerServiceApiProtocols`) — when it matches, the request passes through untouched; when it does not, `@antseed/api-adapter` translates on the fly.
1340
1341| Endpoint | Wire format | Native fit (services advertising) |
1342|----------|-------------|------------------------------------|
1343| `/v1/messages` | Anthropic Messages | `anthropic-messages` |
1344| `/v1/chat/completions` | OpenAI Chat Completions | `openai-chat-completions` |
1345| `/v1/responses` | OpenAI Responses | `openai-responses` |
1346
1347---
1348
1349## For agents writing integrations
1350
1351If you are a coding agent helping a user wire up AntSeed, the canonical flow is:
1352
13531. Detect what tool the user is using.
13542. Look it up in this file by name.
13553. Run the **Install** steps if the tool is not present.
13564. Before editing config files, read the existing file, preserve unrelated
1357 user settings, and merge only the AntSeed provider/profile block.
13585. Apply the **Configure** block (env vars, config file edit, or GUI instruction).
13596. Verify with the **Test it** command.
13607. Pick a peer: `antseed network browse` → `antseed network peer <peerId> --json`.
1361 Match the tool's wire format against the service's `protocols` array — NOT the
1362 `provider` field. Then `antseed buyer connection set --peer <peerId>`.
13638. If the tool is not listed: pick the **curl / Raw HTTP** entry and adapt — the
1364 contract is stable.
1365
1366If a step fails, read the **Troubleshooting** entries; most failures map cleanly.
1367
1368## Adding a new integration
1369
1370Edit `apps/website/src/integrations/integrations.ts` in
1371https://github.com/AntSeed/antseed and open a PR. The hub at /integrations, the
1372per-tool page, and this skill.md are all generated from that single file.