@iaziz786/pi-merge-gateway-login
Pi extension that adds the Merge Dev gateway (docs.merge.dev/merge-gateway) as a model provider via its OpenAI Responses API: every chat-capable model from the gateway catalog, priced at the vendor that actually serves each request.
Package details
Install @iaziz786/pi-merge-gateway-login from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@iaziz786/pi-merge-gateway-login- Package
@iaziz786/pi-merge-gateway-login- Version
0.7.1- Published
- Oct 1, 2026
- Downloads
- 1,601/mo · 228/wk
- Author
- iaziz786
- License
- MIT
- Types
- extension
- Size
- 24.3 KB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./dist/index.js"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-merge-gateway-login
pi extension that adds the Merge Dev gateway as a model provider through its OpenAI Responses API.
Install
pi install npm:@iaziz786/pi-merge-gateway-login
# or from git:
pi install git:github.com/iAziz786/pi-merge-gateway-login
Then authenticate (prompts for your key, stores it in ~/.pi/agent/auth.json):
/login merge-gateway
Permissions: outbound HTTPS to api-gateway.merge.dev only. No filesystem or subprocess access. Key stored by pi in ~/.pi/agent/auth.json.
Models
The extension registers the gateway's own catalog — every chat-capable model it
serves, under the gateway's model IDs (GET /v1/models, with context window,
output cap, input modalities, and reasoning ladder per model taken from the
model's preferred vendor). It is fetched at startup and falls back to four
bundled models when no API key is available or the gateway cannot be reached:
The catalog is scoped to what your organization is allowed to route, and that
changes: it listed 290 models earlier today and now lists one —
zai/glm-5.3-flash on its new vendor pareto, with every other vendor for that
model (Particle, z.ai, Wafer, Together AI, Baseten, Fireworks, Modal) and every
DeepSeek model returning 400 vendor_restrictions_unavailable. Nothing in the
extension decides that; the organization's vendor and region restrictions in the
gateway dashboard do.
| bundled model ID | Model | Preferred vendor |
|---|---|---|
merge-gateway/zai/glm-5.3-flash |
GLM 5.3 Flash | pareto |
merge-gateway/deepseek/deepseek-v4-flash |
DeepSeek V4 Flash (retired, resolved to V4.1) | DeepSeek |
merge-gateway/deepseek/deepseek-v4-flash-0731 |
DeepSeek V4 Flash 0731 | Particle |
merge-gateway/deepseek/deepseek-v4.1-flash |
DeepSeek V4.1 Flash | DeepSeek |
Pick via /model in pi (omp models merge-gateway lists them all). Requests are
not pinned to a vendor: the gateway picks. That
is deliberate — pi and omp generate session titles, compaction summaries, and handoff
documents through side requests that never run extension hooks, so a model ID the
gateway does not recognize, or a field only the hook could add, would break them (the
vendor-prefixed IDs this extension used to register failed exactly there: 404 Model 'fireworks/deepseek-v4.1-flash' is not supported, after which compaction fell through
to its largest-context fallback model and died on that model's output cap).
That is also why there is one entry per model rather than one per vendor: pi keys models by ID alone, so a per-vendor entry would need an invented ID that the gateway rejects on those unhooked side requests. Vendor selection belongs to the gateway, and pricing follows it — see below.
All models support:
- Reasoning: the thinking ladder is mapped per model from the vendor's declared effort values (DeepSeek takes the full
none…maxladder; GLM folds ontolow/high/max); models whose vendor declares none are registered without effort control - Prompt caching: automatic. The extension forwards the pi session ID as the body
prompt_cache_key(the gateway ignores theX-Session-Idheader on this surface), which keeps a session on the vendor whose prompt cache is warm and namespaces the provider cache key. Existing keys are preserved.
Pricing
The gateway routes each request to the cheapest eligible vendor and fails over to
the next when that vendor cannot take it, so a fixed card per model would drift. The
extension prices each turn at the vendor that actually served it: after_provider_response
fires before the response stream is consumed — and therefore before pi prices the usage —
and rewrites the model's rates from that response's x-merge-vendor header, using the
rates from the gateway's own catalog. Input, output, cache-read, and cache-write rates
all follow the serving vendor, and DeepSeek's peak windows (weekdays 01:00–04:00 and
06:00–10:00 UTC, 2×) are applied from its schedule, so the displayed cost matches the
gateway's usage.cost rather than an estimate.
If the catalog could not be fetched, the bundled cards below remain — one per model, at the preferred vendor's base rates, which is the route the gateway picks by default.
| Bundle model | Preferred vendor | Input | Output | Cache read |
|---|---|---|---|---|
zai/glm-5.3-flash |
pareto | $0.03 | $0.10 | $0.006 |
deepseek/deepseek-v4-flash |
DeepSeek | $0.15 | $0.60 | $0.003 |
deepseek/deepseek-v4-flash-0731 |
Particle | $0.035 | $0.07 | $0.007 |
deepseek/deepseek-v4.1-flash |
DeepSeek | $0.15 | $0.60 | $0.003 |
Rates are per million tokens and were verified against the gateway's own usage.cost
on live probes — cold and cache-hit turns matched to nine decimals. Cache writes are
billed only on some vendors (Anthropic and Bedrock entries, from cache_write_per_million).
Every vendor the gateway may choose, with what it charges, comes from GET /v1/models
and is applied automatically. For the four bundle models:
| Model | Eligible vendors (input / output / cache read per M) |
|---|---|
zai/glm-5.3-flash |
pareto 0.03/0.10/0.006 (only one this account may route to) · particle 0.12/0.40/0.03 · z.ai 0.075/0.25/0.015 · baseten, fireworks, together AI, wafer 0.15/0.50/0.03 · modal 0.45/1.50/0.09 |
deepseek/deepseek-v4-flash |
resolved to V4.1 Flash before routing, and billed as it |
deepseek/deepseek-v4-flash-0731 |
Particle 0.035/0.07/0.007 · Makora 0.09/0.195/0.0196 · Baseten 0.13/0.26/0.028 · Together AI 0.14/0.28/0.03 · Empiriolabs 0.14/0.28 |
deepseek/deepseek-v4.1-flash |
DeepSeek 0.15/0.60/0.003 · Particle 0.20/0.80/0.03 · Fireworks 0.22/0.66/0.007 · Baseten 0.30/1.20/0.03 |
The DeepSeek rows are what the gateway listed while those models were reachable;
they now return 400 vendor_restrictions_unavailable on this account. Vendors
without zero data retention: z.ai and Wafer AI on GLM 5.3 Flash, Empiriolabs on
V4 Flash 0731, DeepSeek on the V4.1 family — every other vendor lists
zero_data_retention: true.
GLM 5.3 Flash's rates have moved twice: pareto launched 2026-09-22 at
0.03/0.10, particle went 0.015/0.05 → 0.12/0.40, and z.ai went 0.015/0.05 →
0.075/0.25. The card in the table above and GLM_53_FLASH_COST track pareto,
which the live path reprices from x-merge-vendor regardless — the other
vendors' numbers there come from Merge's model page, since the API catalog
hides vendors the organization cannot route to.
The gateway's own usage.cost on a response is the authoritative bill; the headers
carry x-merge-vendor (the vendor that served it) and x-merge-model (the model it
resolved to). To force a vendor, send vendor in the request body or set the
organization's vendor policy in the gateway dashboard.
Routing and zero data retention
The gateway picks the vendor per request, preferring the cheapest eligible one — today GLM 5.3 Flash routes to pareto, and it is the only vendor this account may route to. Without a vendor pin there is no per-session control over where a request runs, and whether a given vendor is even reachable is decided by the organization's vendor and region restrictions (see the vendor list above for which vendors support zero data retention — pareto does). Use the organization's routing policy or vendor allow/deny lists in the gateway dashboard when a workload must stay on specific infrastructure.
Also note the retired deepseek/deepseek-v4-flash id: the gateway resolves it to V4.1
Flash, so the response comes back as V4.1 Flash (x-merge-model: deepseek/deepseek-v4.1-flash) at V4.1 rates. Pick deepseek/deepseek-v4-flash-0731 to
stay on the July snapshot.
Jev (TypeSafe) judgments in omp
omp ships a TypeSafe judge it uses for thinking-level detection, Smart unexpected-stop
detection, git AI staging, and the judge() helper in eval cells. The gateway serves the
same System One contract, but at /v1/decisions under the model typesafe/jev-1.13
while the client posts to /v1/systemone and defaults to jev-latest, so
tools/jev-bridge.ts adapts path and model id:
MERGE_GATEWAY_API_KEY=… bun tools/jev-bridge.ts # keep it running (loopback only)
# ~/.omp/agent/.env — omp loads this into $env at startup
TYPESAFE_BASE_URL=http://127.0.0.1:8787
TYPESAFE_API_KEY=<the same gateway key>
TYPESAFE_DEFAULT_MODEL=typesafe/jev-1.13
With the env key present, AuthStorage.hasAuth("typesafe") is satisfied, so the default
providers.judgmentProvider: auto sends those judgments to Jev through the gateway
instead of the tiny/smol chat fallback. Jev is not a chat model — it never appears in
/model, and chat side requests (titles, compaction) are unaffected. Billing is
$0.042/M input tokens with output free; omp's ledger shows $0 for these calls because the
judgment usage mapper reads token counts, not the gateway's usage.cost.
The bridge is repo-local tooling; the npm tarball ships dist, README.md and
LICENSE only.
Endpoint
POST https://api-gateway.merge.dev/v1/openai/responses
Authorization: Bearer <MERGE_GATEWAY_API_KEY>
Test
bun test