@gtrabanco/pi-nan-provider 0.7.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +70 -23
- package/README.es.md +67 -37
- package/README.md +66 -40
- package/package.json +5 -5
- package/scripts/check-nan-mcp-server.ts +11 -3
- package/scripts/check-pi-sdk-versions.mjs +392 -0
- package/scripts/generate-models.ts +64 -12
- package/scripts/manual-overrides.ts +20 -8
- package/scripts/models.generated.ts +55 -52
- package/src/commands.ts +132 -52
- package/src/context-overflow-classifier.ts +1 -1
- package/src/cross-model-thinking-guard.ts +1 -1
- package/src/index.ts +81 -41
- package/src/mcp/api-key.ts +76 -0
- package/src/mcp/media-server.ts +56 -0
- package/src/provider-factory.ts +7 -2
- package/src/usage.ts +352 -175
- package/src/mcp/nan-media.ts +0 -236
- package/src/mcp/nan-search.ts +0 -241
- package/src/mcp/stdio-client.ts +0 -222
package/AGENTS.md
CHANGED
|
@@ -51,7 +51,7 @@ maintainer's quota, so they are **permission-gated**:
|
|
|
51
51
|
gate covers ad-hoc diagnosis only, never `bun test`.
|
|
52
52
|
- **Default to `qwen3.6` — it is unlimited.**
|
|
53
53
|
- **For massive/bulk probes prefer a model the maintainer uses less with a large
|
|
54
|
-
token budget, e.g. `mimo-v2.
|
|
54
|
+
token budget, e.g. `mimo-v2.6-flash`** (1M context, 1.0B monthly quota).
|
|
55
55
|
- **When the model under investigation is the point** (e.g. reproducing a
|
|
56
56
|
model-specific 400), use it, but minimize tokens: smallest viable prompt,
|
|
57
57
|
lowest `max_tokens`, stop at the first decisive response.
|
|
@@ -77,7 +77,7 @@ Every PR that changes code MUST bump `package.json` version in the same PR; CI p
|
|
|
77
77
|
|
|
78
78
|
## Verified API facts (do not re-derive from stale docs)
|
|
79
79
|
|
|
80
|
-
- **Extension-side pi-ai imports + streaming-API instance binding (v0.6.10; verified on pi-ai 0.83.0–0.
|
|
80
|
+
- **Extension-side pi-ai imports + streaming-API instance binding (v0.6.10; verified on pi-ai 0.83.0–0.87.1 and pi 0.87.1):**
|
|
81
81
|
statically import ONLY the bare `@earendil-works/pi-ai` root from `src/`. pi's
|
|
82
82
|
extension loader maps that specifier to the compat entrypoint on the bundled
|
|
83
83
|
CLI, Node-mode jiti aliases and compiled-binary virtualModules, and compat
|
|
@@ -107,7 +107,7 @@ Every PR that changes code MUST bump `package.json` version in the same PR; CI p
|
|
|
107
107
|
`openAICompletionsApi`; `createProvider` and `envApiKeyAuth(name, envVars)` are
|
|
108
108
|
on the root. `envApiKeyAuth` implements exactly: stored credential key wins →
|
|
109
109
|
first set env var → unconfigured; `login()` prompts with `{ type: "secret" }`.
|
|
110
|
-
- pi awaits extension factories (`await factory(api)`) on 0.83.0
|
|
110
|
+
- pi awaits extension factories (`await factory(api)`) on 0.83.0 through 0.87.1
|
|
111
111
|
alike, so the extension entrypoint may be async (v0.5.0: streaming-API
|
|
112
112
|
resolution needs it).
|
|
113
113
|
- pi-ai 0.83.0 runtime surface verified identical for this package's needs:
|
|
@@ -116,6 +116,26 @@ Every PR that changes code MUST bump `package.json` version in the same PR; CI p
|
|
|
116
116
|
`fetchModels(context)`, `filterModels(models, credential)`, `api`) and
|
|
117
117
|
`RefreshModelsContext.credential` match 0.84.4; `registerProvider` has both
|
|
118
118
|
the full-`Provider` and `(name, config)` overloads in 0.83's ExtensionAPI.
|
|
119
|
+
(pi-ai 0.86 changed provider stream entry points to a branded `TranscriptContext`
|
|
120
|
+
— see next bullet — but this package's runtime is untouched.)
|
|
121
|
+
- **pi-ai 0.86.0 `TranscriptContext` migration (verified 2026-09-29):** provider
|
|
122
|
+
stream entry points (`Provider.stream`, `ProviderStreams.stream/streamSimple`,
|
|
123
|
+
`StreamFunction`) now take a branded `TranscriptContext = { messages: Message[] }`
|
|
124
|
+
instead of the public `Context = { systemPrompt?: string; messages; tools? }`.
|
|
125
|
+
`normalizeContext(context: Context): TranscriptContext` (exported from the pi-ai
|
|
126
|
+
root) folds prompt + tools into a leading system message
|
|
127
|
+
`{ role: "system", content: <prompt>, toolsAdded: <tools>, timestamp: 0 }`.
|
|
128
|
+
`Context` itself still exists and is what the public entry points accept, so raw
|
|
129
|
+
`Context` literals only fail where a *provider-level* stream is called directly
|
|
130
|
+
(the 6 test call sites). Tests now build contexts with `normalizeContext(...)`.
|
|
131
|
+
This package's `src/` files never hand-build a provider context, so no `src/`
|
|
132
|
+
code changed: `wrapApiForStrictSanitization` forwards `context` untouched, and
|
|
133
|
+
`withContextOverflowClassification` only *reads* it for the estimate, which still
|
|
134
|
+
counts prompt + tools because they ride inside `messages[0]`.
|
|
135
|
+
- pi 0.87 rejects extension tools that declare no parameter schema at registration;
|
|
136
|
+
all this package's MCP tools declare TypeBox `parameters`, so they register fine.
|
|
137
|
+
pi 0.87 also changed `pi.on()` to return an unsubscribe function (unused by
|
|
138
|
+
this package).
|
|
119
139
|
- `pi.registerProvider(provider)` accepts a complete pi-ai `Provider`; pi's Models
|
|
120
140
|
runtime then drives `fetchModels` refreshes (network refresh at interactive
|
|
121
141
|
startup and periodically, cache-only at registration) and persists the overlay.
|
|
@@ -132,20 +152,37 @@ Every PR that changes code MUST bump `package.json` version in the same PR; CI p
|
|
|
132
152
|
override (maintainer-confirmed 2026-09-05) was withdrawn 2026-09-07 — the
|
|
133
153
|
updated NaN docs still say 262K "the model's native window" and models.dev
|
|
134
154
|
agrees at 262,144.
|
|
135
|
-
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
155
|
+
- **Which models exist**: https://nan.builders/docs/models is the source of
|
|
156
|
+
truth (maintainer instruction, reaffirmed 2026-09-29), cross-checked against
|
|
157
|
+
the `model` param description in https://nan.builders/openapi.json; models.dev
|
|
158
|
+
(provider `nan`) supplies the numeric limits for the ids it documents, and
|
|
159
|
+
every divergence or exclusion is recorded with provenance.
|
|
160
|
+
Official chat models (checked 2026-09-29): community `deepseek-v4-flash`,
|
|
161
|
+
`mimo-v2.6-flash`, `qwen3.8-flash`, `glm5.3-flash`, `qwen3.6`, `gemma4`
|
|
162
|
+
(all text+image vision) + premium-tier `glm5.3`
|
|
139
163
|
(~753B MoE, text-only input, 1M context, 400M tokens/rolling 4h window).
|
|
140
164
|
glm5.3 is now documented by models.dev too (1M context / 131,072 max output,
|
|
141
165
|
checked 2026-09-13) but stays out of the static catalog via
|
|
142
166
|
`LIVE_ONLY_MODEL_IDS` (premium tier) so a non-premium key never sees a
|
|
143
167
|
model it cannot call when the live `/models` fetch is unavailable; premium
|
|
144
168
|
keys still receive it live with conservative placeholder limits.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
169
|
+
Removed by the provider: `glm5.2` (2026-09-05) and `mimo-v2.5` (checked
|
|
170
|
+
2026-09-29 — zero mentions in the docs and in openapi.json, and models.dev
|
|
171
|
+
dropped it too; superseded by `mimo-v2.6-flash`). models.dev may re-list a
|
|
172
|
+
removed id, so the generator excludes them via `PROVIDER_REMOVED_MODEL_IDS`,
|
|
173
|
+
and the four community ids the docs require (`qwen3.6`, `gemma4`,
|
|
174
|
+
`deepseek-v4-flash`, `mimo-v2.6-flash`) are `REQUIRED_MODEL_IDS` — if one
|
|
175
|
+
never reaches the catalog (from models.dev or from a manual-only entry),
|
|
176
|
+
generation exits non-zero instead of inventing data.
|
|
177
|
+
`mimo-v2.6-flash` entered through `MANUAL_ONLY_MODEL_IDS` while models.dev
|
|
178
|
+
lacked it; models.dev started listing it on 2026-09-29, and the generator
|
|
179
|
+
then skips the manual entry (attaching its note to the models.dev-derived
|
|
180
|
+
entry) so the id is never emitted twice.
|
|
181
|
+
Non-chat endpoints: qwen3-embedding, rerank, kokoro (TTS), whisper (STT),
|
|
182
|
+
flux-2-klein and qwen-image-2.1 (images) — MCP-bridge territory, not chat
|
|
183
|
+
catalog models; `qwen-image-2.1` also sits on models.dev with
|
|
184
|
+
`limit.output: 0`, so generation excludes it via `NON_CHAT_MODEL_IDS`
|
|
185
|
+
instead of flagging it "needs manual verification" forever.
|
|
149
186
|
- NaN can close an SSE stream **before** `finish_reason`. The catalog sets
|
|
150
187
|
`supportsFinishReason: true` so pi-ai raises the retryable
|
|
151
188
|
`Stream ended without finish_reason` (pi-ai's `RETRYABLE_PROVIDER_ERROR_PATTERN`
|
|
@@ -178,19 +215,29 @@ Every PR that changes code MUST bump `package.json` version in the same PR; CI p
|
|
|
178
215
|
`test/context-overflow-classifier.test.ts`; issue #3.
|
|
179
216
|
- Relative imports inside this package use `.ts` extensions (pi's official
|
|
180
217
|
extension examples do the same; pi transpiles extension sources).
|
|
181
|
-
- pi
|
|
182
|
-
|
|
218
|
+
- pi 0.87 breaking changes NOT used by this package: `ContextEditEntry` added to
|
|
219
|
+
the `SessionEntry` union, expanded `TurnEndEvent`, removed `shouldStopAfterTurn`,
|
|
220
|
+
`SessionManager` canonical for provider context. The package touches none of them.
|
|
221
|
+
- Since 0.10.0, this package uses native MCP via `pi.registerMcpServer()`.
|
|
222
|
+
Both servers are session-scoped, visible in `/mcp` with source "extension".
|
|
223
|
+
Server names and tool IDs:
|
|
224
|
+
- `nan-search` → tools: `mcp__nan-search__web_search`
|
|
225
|
+
(official remote, HTTP, `Authorization: Bearer <key>` header)
|
|
226
|
+
- `nan-media` → tools: `mcp__nan-media__generate_image/edit_image/text_to_speech/list_voices/speech_to_text`
|
|
227
|
+
(community stdio, `npx -y nan-mcp-server@1.1.2`, 120s timeout)
|
|
228
|
+
- `exposure: "direct"` on both — tools are declared to the model.
|
|
229
|
+
- User `mcp.json` entries with the same name take precedence.
|
|
230
|
+
- `/nan-mcp enable/disable` calls `pi.registerMcpServer()` / `pi.unregisterMcpServer()` directly.
|
|
231
|
+
- Missing `NAN_API_KEY` at load: web-search server NOT registered (console.warn).
|
|
232
|
+
NaN integration facts remain:
|
|
183
233
|
- NaN's official remote MCP server: `https://api.nan.builders/mcp` (host
|
|
184
234
|
root, NOT /v1; JSON-RPC 2.0 over streamable HTTP, stateless; same `sk-`
|
|
185
235
|
key, shared rate limit/quota). Spec: https://nan.builders/openapi.json
|
|
186
|
-
(tag "MCP"). Currently exposes `web_search
|
|
187
|
-
"growing registry" — use tools/list to discover.
|
|
236
|
+
(tag "MCP"). Currently exposes `web_search`.
|
|
188
237
|
- Community `nan-mcp-server` (https://github.com/luciferfran/nan-mcp-server):
|
|
189
|
-
stdio MCP server,
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
compares the npm registry against the pin weekly and files a `dependencies` issue
|
|
196
|
-
with a breaking/safe verdict from the live server tool surface (unpkg).
|
|
238
|
+
stdio MCP server, version-pinned via NAN_MEDIA_MCP_VERSION (default 1.1.2)
|
|
239
|
+
or full command override via NAN_MEDIA_MCP_COMMAND. Tools: generate_image,
|
|
240
|
+
edit_image, text_to_speech, list_voices, speech_to_text.
|
|
241
|
+
- Automated check (scripts/check-nan-mcp-server.ts) compares the npm registry
|
|
242
|
+
against the pin weekly and files a `dependencies` issue when a newer release
|
|
243
|
+
exists, with a breaking/safe verdict from the live server tool surface.
|
package/README.es.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# @gtrabanco/pi-nan-provider
|
|
2
2
|
|
|
3
3
|
[](https://opensource.org/licenses/MIT)
|
|
4
|
-
[](https://github.com/gtrabanco/pi-nan-provider/releases)
|
|
5
5
|
|
|
6
|
-
[NaN Builders](https://nan.builders) model provider + MCP
|
|
6
|
+
[NaN Builders](https://nan.builders) model provider + MCP nativo para [pi](https://github.com/earendil-works/pi).
|
|
7
7
|
|
|
8
|
-
Registra el proveedor `nan` vía `pi.registerProvider()` usando la API OpenAI-compatible de NaN (`https://api.nan.builders/v1`), y
|
|
8
|
+
Registra el proveedor `nan` vía `pi.registerProvider()` usando la API OpenAI-compatible de NaN (`https://api.nan.builders/v1`), y registra servidores MCP nativos con `pi.registerMcpServer()`.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -97,11 +97,11 @@ Puedes sobrescribir el `compat` de cualquier modelo en `~/.pi/agent/models.json`
|
|
|
97
97
|
|
|
98
98
|
Consigue una clave en la [plataforma NaN](https://cloud.nan.builders/r/7GK06FX8) (ajustes de usuario → API Keys; enlace de referidos).
|
|
99
99
|
|
|
100
|
-
## 🔌
|
|
100
|
+
## 🔌 MCP nativo
|
|
101
101
|
|
|
102
|
-
Dado que [pi
|
|
102
|
+
Dado que [pi 0.99.0 incluye un cliente MCP integrado](https://github.com/earendil-works/pi/blob/main/docs/usage.md), este paquete migra sus puentes a MCP nativo (requiere `pi >=0.99` — cambio rotundo).
|
|
103
103
|
|
|
104
|
-
Ambos puentes están **activados
|
|
104
|
+
Ambos puentes están **activados por defecto** (por sesión, visibles en `/mcp`). Usa `/nan-mcp` para gestionarlos.
|
|
105
105
|
|
|
106
106
|
### 🛠️ Comando de Gestión: `/nan-mcp`
|
|
107
107
|
|
|
@@ -116,21 +116,21 @@ Ambos puentes están **activados y son perezosos (lazy) por defecto**. Usa `/nan
|
|
|
116
116
|
### 1. Servidor MCP oficial de NaN
|
|
117
117
|
*Puente oficial para herramientas remotas vía [https://api.nan.builders/mcp](https://nan.builders/docs/api).*
|
|
118
118
|
|
|
119
|
-
- **`
|
|
119
|
+
- **`mcp__nan-search__web_search(query, ...)`**: Realiza búsquedas web a través del gateway de NaN.
|
|
120
120
|
|
|
121
121
|
### 2. Servidor MCP de Media (Comunidad)
|
|
122
122
|
*Conecta [`nan-mcp-server`](https://github.com/luciferfran/nan-mcp-server) mediante un cliente stdio local mínimo.*
|
|
123
123
|
|
|
124
|
-
- **
|
|
124
|
+
- **Por sesión**: El servidor se conecta al registrarse (eager). Aparece en `/mcp` con fuente "extension".
|
|
125
125
|
- **Configuración**: Los archivos se guardan en `~/nan-mcp-output/`.
|
|
126
126
|
|
|
127
127
|
| Herramienta | Propósito |
|
|
128
128
|
| :--- | :--- |
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
133
|
-
| `
|
|
129
|
+
| `mcp__nan-media__generate_image` | Generación de imágenes (flux-2-klein) |
|
|
130
|
+
| `mcp__nan-media__edit_image` | Edición imagen→imagen (flux-2-klein) |
|
|
131
|
+
| `mcp__nan-media__text_to_speech` | Síntesis de audio (kokoro) |
|
|
132
|
+
| `mcp__nan-media__list_voices` | Listar voces disponibles |
|
|
133
|
+
| `mcp__nan-media__speech_to_text` | Transcripción de audio (whisper) |
|
|
134
134
|
|
|
135
135
|
#### 🔧 Configuración del Puente de Media
|
|
136
136
|
|
|
@@ -156,74 +156,99 @@ bun run check-nan-mcp-server --issue # crea/refresca el issue
|
|
|
156
156
|
|
|
157
157
|
## 📊 Uso de Cuotas: `/nan-usage`
|
|
158
158
|
|
|
159
|
-
Muestra tu uso de tokens de NaN por modelo
|
|
159
|
+
Muestra tu uso de tokens de NaN por modelo combinado con los límites mensuales documentados, los totales de la ventana, tus totales acumulados y el tiempo hasta el reinicio del ciclo de facturación.
|
|
160
160
|
|
|
161
161
|
### Cómo funciona
|
|
162
162
|
|
|
163
|
-
`/nan-usage`
|
|
163
|
+
`/nan-usage` llama al endpoint [`GET /v1/usage`](https://nan.builders/docs/api#tag/usage) de NaN con **la misma API key que ya usas para chat** — la credencial guardada en pi (`/login nan`) o `NAN_API_KEY`. Sin login de la CLI, sin cookie de sesión, sin configuración extra.
|
|
164
|
+
|
|
165
|
+
El endpoint devuelve tu uso (filas por fecha y modelo) y los totales de la ventana solicitada — máximo 90 días inclusivos. El comando lee esos totales y los combina con los límites publicados en la [documentación de NaN](https://nan.builders/docs/models) para mostrarte qué porcentaje de cada cuota mensual has consumido. `/usage` solo reporta consumo, así que los límites siempre vienen de la tabla documentada (comprobado 2026-09-27).
|
|
166
|
+
|
|
167
|
+
Límite de tasa: 30 peticiones por minuto para `/usage`, separado del de los endpoints de modelos.
|
|
168
|
+
|
|
169
|
+
### Uso
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
/nan-usage # mes en curso en UTC (coincide con las cuotas mensuales)
|
|
173
|
+
/nan-usage 7 # ventana móvil de 7 días (1-90)
|
|
174
|
+
/nan-usage 30 # ventana móvil de 30 días
|
|
175
|
+
/nan-usage help # muestra la línea de uso
|
|
176
|
+
```
|
|
164
177
|
|
|
165
178
|
### Configuración
|
|
166
179
|
|
|
167
|
-
1. **
|
|
168
|
-
```bash
|
|
169
|
-
curl -fsSL https://nan.builders/install | sh
|
|
180
|
+
1. **Autentica el proveedor `nan` en pi** con tu clave `sk-...`:
|
|
170
181
|
```
|
|
171
|
-
|
|
182
|
+
/login nan
|
|
183
|
+
```
|
|
184
|
+
o expórtala en su lugar:
|
|
172
185
|
```bash
|
|
173
|
-
|
|
186
|
+
export NAN_API_KEY=sk-...
|
|
174
187
|
```
|
|
175
|
-
|
|
176
|
-
3. **Usa en pi**:
|
|
188
|
+
2. **Úsalo en pi**:
|
|
177
189
|
```
|
|
178
190
|
/nan-usage
|
|
179
191
|
```
|
|
180
192
|
|
|
181
193
|
> [!TIP]
|
|
182
|
-
>
|
|
194
|
+
> ¿No se resuelve ninguna API key? El comando muestra la tabla estática de cuotas de la documentación y te indica cómo autenticarte.
|
|
183
195
|
|
|
184
196
|
### Lo que ves
|
|
185
197
|
|
|
186
|
-
**Con
|
|
198
|
+
**Con API key** (uso real):
|
|
187
199
|
```
|
|
188
|
-
📊 NaN
|
|
200
|
+
📊 NaN Usage
|
|
201
|
+
|
|
202
|
+
🗓️ Window: 2026-09-01 → 2026-09-27 UTC (27 days)
|
|
189
203
|
|
|
190
|
-
⏱️ Next billing reset: 2026-
|
|
204
|
+
⏱️ Next billing reset: 2026-09-30 UTC (2d 14h 30m 0s)
|
|
191
205
|
|
|
192
206
|
Models with monthly caps:
|
|
193
207
|
|
|
194
208
|
DeepSeek V4 Flash:
|
|
195
|
-
[████████░░░░░░░░░░░░] 40.
|
|
196
|
-
Used: 1.2B / 3.0B (1.8B remaining)
|
|
209
|
+
[████████░░░░░░░░░░░░] 40.0% of monthly cap
|
|
210
|
+
Used: 1.2B / 3.0B (1.8B remaining) · 5,120 requests
|
|
197
211
|
|
|
198
212
|
MiMo V2.5:
|
|
199
|
-
[
|
|
200
|
-
Used: 125.0M / 1.0B (875.0M remaining)
|
|
213
|
+
[███░░░░░░░░░░░░░░░░░] 12.5% of monthly cap
|
|
214
|
+
Used: 125.0M / 1.0B (875.0M remaining) · 840 requests
|
|
215
|
+
|
|
216
|
+
GLM 5.3 👑:
|
|
217
|
+
[████████░░░░░░░░░░░░] 40.0% of monthly cap
|
|
218
|
+
Used: 1.2B / 3.0B (1.8B remaining) · 2,400 requests
|
|
219
|
+
↳ rolling window: 400.0M / 4h (daily granularity — /usage cannot break it down)
|
|
201
220
|
|
|
202
221
|
Uncapped models:
|
|
203
222
|
|
|
204
|
-
Qwen 3.6: 890.5K used
|
|
205
|
-
|
|
223
|
+
Qwen 3.6: 890.5K used · 123 requests
|
|
224
|
+
|
|
225
|
+
Window totals: 2.6B tokens (2.0B prompt / 640.0M completion) · 18,432 requests
|
|
226
|
+
All time: 13.2B tokens · 41,250 requests (cached 2026-02-01)
|
|
227
|
+
💡 Source: GET /v1/usage · caps from https://nan.builders/docs/models
|
|
206
228
|
```
|
|
207
229
|
|
|
208
|
-
**Sin
|
|
230
|
+
**Sin API key** (solo límites estáticos):
|
|
209
231
|
```
|
|
210
232
|
📊 NaN Quota Status (static limits)
|
|
211
233
|
|
|
212
|
-
⏱️ Next billing reset: 2026-
|
|
234
|
+
⏱️ Next billing reset: 2026-09-30 UTC (2d 14h 30m 0s)
|
|
213
235
|
|
|
214
236
|
Model Monthly Cap
|
|
215
237
|
─────────────────────────────────────────────────
|
|
216
238
|
DeepSeek V4 Flash 3.0B
|
|
217
239
|
MiMo V2.5 1.0B
|
|
240
|
+
MiMo V2.6 Flash 1.0B
|
|
218
241
|
Qwen 3.6 uncapped
|
|
219
242
|
Gemma 4 uncapped
|
|
220
243
|
Qwen 3.8 Flash 500.0M
|
|
221
244
|
GLM 5.3 Flash 2.0B
|
|
222
|
-
GLM 5.3
|
|
245
|
+
GLM 5.3 3.0B 👑 (rolling 400.0M/4h)
|
|
223
246
|
|
|
224
|
-
💡
|
|
247
|
+
💡 Set NAN_API_KEY or run `/login nan` to see real usage (GET /v1/usage).
|
|
225
248
|
```
|
|
226
249
|
|
|
250
|
+
Los errores siguen siendo accionables: `401` → ejecuta `/login nan` o corrige `NAN_API_KEY`, `404` → la cuenta no tiene identidad de uso que reportar, `429` → reintenta tras los segundos de `Retry-After`.
|
|
251
|
+
|
|
227
252
|
---
|
|
228
253
|
|
|
229
254
|
## 📊 Modelos
|
|
@@ -235,10 +260,15 @@ Catálogo base (verificado contra [docs de NaN](https://nan.builders/docs/models
|
|
|
235
260
|
| `qwen3.6` | 262,144 | 65,536 | texto, imagen | ✅ |
|
|
236
261
|
| `gemma4` | 262,144 | 32,768 | texto, imagen | ✅ |
|
|
237
262
|
| `deepseek-v4-flash` | 1,000,000 | 384,000 | texto, imagen | ✅ |
|
|
238
|
-
| `mimo-v2.
|
|
263
|
+
| `mimo-v2.6-flash` | 1,048,576 | 131,072 | texto, imagen | ✅ |
|
|
239
264
|
| `glm5.3-flash` | 1,000,000 | 131,072 | texto, imagen | ✅ |
|
|
240
265
|
| `qwen3.8-flash` | 262,144 | 131,072 | texto, imagen | ✅ |
|
|
241
266
|
|
|
267
|
+
> [!NOTE]
|
|
268
|
+
> `mimo-v2.6-flash` está servido por NaN y desde el 2026-09-29 aparece también en models.dev (proveedor `nan`); la entrada manual que lo sostenía se conserva como fallback y su nota de procedencia sigue unida a la entrada generada.
|
|
269
|
+
>
|
|
270
|
+
> `mimo-v2.5` fue eliminado por NaN: ya no aparece ni en [los docs de NaN](https://nan.builders/docs/models) ni en la [lista de modelos del OpenAPI](https://nan.builders/openapi.json) (comprobado 2026-09-29), así que sale del catálogo — lo sustituye `mimo-v2.6-flash` (mismos límites 1,048,576 / 131,072 y cuota mensual de 1.0B). El consumo histórico de `mimo-v2.5` en `/nan-usage` sigue apareciendo en la sección de modelos no documentados.
|
|
271
|
+
|
|
242
272
|
---
|
|
243
273
|
|
|
244
274
|
## 🚀 Desarrollo
|
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# @gtrabanco/pi-nan-provider
|
|
2
2
|
|
|
3
3
|
[](https://opensource.org/licenses/MIT)
|
|
4
|
-
[](https://github.com/gtrabanco/pi-nan-provider/releases)
|
|
5
5
|
|
|
6
|
-
[NaN Builders](https://nan.builders) model provider + MCP
|
|
6
|
+
[NaN Builders](https://nan.builders) model provider + native MCP servers for [pi](https://github.com/earendil-works/pi).
|
|
7
7
|
|
|
8
|
-
Registers the `nan` provider via `pi.registerProvider()` using NaN's OpenAI-compatible API (`https://api.nan.builders/v1`), and
|
|
8
|
+
Registers the `nan` provider via `pi.registerProvider()` using NaN's OpenAI-compatible API (`https://api.nan.builders/v1`), and registers MCP servers via pi's native `pi.registerMcpServer()`.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -97,11 +97,11 @@ You can override any model's `compat` per-model in `~/.pi/agent/models.json` (pi
|
|
|
97
97
|
|
|
98
98
|
Get a key from the [NaN platform](https://cloud.nan.builders/r/7GK06FX8) (user settings → API Keys; referral link).
|
|
99
99
|
|
|
100
|
-
## 🔌 MCP
|
|
100
|
+
## 🔌 Native MCP Servers
|
|
101
101
|
|
|
102
|
-
Since [pi
|
|
102
|
+
Since [pi 0.99.0 ships a built-in MCP client](https://github.com/earendil-works/pi/blob/main/docs/usage.md), this package migrates its bridges to native MCP (requires `pi >=0.99` — breaking).
|
|
103
103
|
|
|
104
|
-
Both bridges are **enabled
|
|
104
|
+
Both bridges are **enabled by default** (session-scoped, visible in `/mcp`). Use `/nan-mcp` to manage them.
|
|
105
105
|
|
|
106
106
|
### 🛠️ Management Command: `/nan-mcp`
|
|
107
107
|
|
|
@@ -114,23 +114,23 @@ Both bridges are **enabled and lazy by default**. Use `/nan-mcp` to manage them.
|
|
|
114
114
|
---
|
|
115
115
|
|
|
116
116
|
### 1. Official NaN MCP Server
|
|
117
|
-
*Official
|
|
117
|
+
*Official remote MCP server registered natively via `pi.registerMcpServer()`.*
|
|
118
118
|
|
|
119
|
-
- **`
|
|
119
|
+
- **`mcp__nan-search__web_search(query, ...)`**: Performs web searches through NaN's gateway.
|
|
120
120
|
|
|
121
121
|
### 2. Community Media MCP Server
|
|
122
122
|
*Bridges [`nan-mcp-server`](https://github.com/luciferfran/nan-mcp-server) via a minimal local stdio client.*
|
|
123
123
|
|
|
124
|
-
- **
|
|
124
|
+
- **Session-scoped**: The server connects at registration time (eager). Appears in `/mcp` with source "extension".
|
|
125
125
|
- **Config**: Files land in `~/nan-mcp-output/`.
|
|
126
126
|
|
|
127
127
|
| Tool | Purpose |
|
|
128
128
|
| :--- | :--- |
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
133
|
-
| `
|
|
129
|
+
| `mcp__nan-media__generate_image` | Image generation (flux-2-klein) |
|
|
130
|
+
| `mcp__nan-media__edit_image` | Image-to-image editing (flux-2-klein) |
|
|
131
|
+
| `mcp__nan-media__text_to_speech` | Audio synthesis (kokoro) |
|
|
132
|
+
| `mcp__nan-media__list_voices` | List available voices |
|
|
133
|
+
| `mcp__nan-media__speech_to_text` | Audio transcription (whisper) |
|
|
134
134
|
|
|
135
135
|
#### 🔧 Media Bridge Configuration
|
|
136
136
|
|
|
@@ -156,74 +156,99 @@ bun run check-nan-mcp-server --issue # create/refresh the issue
|
|
|
156
156
|
|
|
157
157
|
## 📊 Quota Usage: `/nan-usage`
|
|
158
158
|
|
|
159
|
-
Shows your NaN token usage per model
|
|
159
|
+
Shows your NaN token usage per model merged with the documented monthly caps, the window totals, your all-time totals, and the time until the billing cycle resets.
|
|
160
160
|
|
|
161
161
|
### How it works
|
|
162
162
|
|
|
163
|
-
`/nan-usage`
|
|
163
|
+
`/nan-usage` calls NaN's [`GET /v1/usage`](https://nan.builders/docs/api#tag/usage) endpoint with the **same API key you already use for chat** — pi's stored credential (`/login nan`) or `NAN_API_KEY`. No CLI login, no session cookie, no extra setup.
|
|
164
|
+
|
|
165
|
+
The endpoint returns your usage (rows per date and model) plus totals covering the requested window — at most 90 inclusive days. The command reads those totals and merges them with the caps published in the [NaN docs](https://nan.builders/docs/models) to show how much of each monthly cap you have consumed. `/usage` reports consumption only, so the caps themselves always come from the documented table (checked 2026-09-27).
|
|
166
|
+
|
|
167
|
+
Rate limit: 30 requests per minute for `/usage`, separate from the model endpoints.
|
|
168
|
+
|
|
169
|
+
### Usage
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
/nan-usage # current UTC month (matches the monthly caps)
|
|
173
|
+
/nan-usage 7 # rolling 7-day window (1-90)
|
|
174
|
+
/nan-usage 30 # rolling 30-day window
|
|
175
|
+
/nan-usage help # show the usage line
|
|
176
|
+
```
|
|
164
177
|
|
|
165
178
|
### Setup
|
|
166
179
|
|
|
167
|
-
1. **
|
|
168
|
-
```
|
|
169
|
-
|
|
180
|
+
1. **Authenticate the `nan` provider in pi** with your `sk-...` key:
|
|
181
|
+
```
|
|
182
|
+
/login nan
|
|
170
183
|
```
|
|
171
|
-
|
|
184
|
+
or export it instead:
|
|
172
185
|
```bash
|
|
173
|
-
|
|
186
|
+
export NAN_API_KEY=sk-...
|
|
174
187
|
```
|
|
175
|
-
|
|
176
|
-
3. **Use in pi**:
|
|
188
|
+
2. **Use in pi**:
|
|
177
189
|
```
|
|
178
190
|
/nan-usage
|
|
179
191
|
```
|
|
180
192
|
|
|
181
193
|
> [!TIP]
|
|
182
|
-
>
|
|
194
|
+
> No API key resolves? The command falls back to the static quota table from the docs and tells you how to authenticate.
|
|
183
195
|
|
|
184
196
|
### What you see
|
|
185
197
|
|
|
186
|
-
**With
|
|
198
|
+
**With an API key** (real usage):
|
|
187
199
|
```
|
|
188
|
-
📊 NaN
|
|
200
|
+
📊 NaN Usage
|
|
201
|
+
|
|
202
|
+
🗓️ Window: 2026-09-01 → 2026-09-27 UTC (27 days)
|
|
189
203
|
|
|
190
|
-
⏱️ Next billing reset: 2026-
|
|
204
|
+
⏱️ Next billing reset: 2026-09-30 UTC (2d 14h 30m 0s)
|
|
191
205
|
|
|
192
206
|
Models with monthly caps:
|
|
193
207
|
|
|
194
208
|
DeepSeek V4 Flash:
|
|
195
|
-
[████████░░░░░░░░░░░░] 40.
|
|
196
|
-
Used: 1.2B / 3.0B (1.8B remaining)
|
|
209
|
+
[████████░░░░░░░░░░░░] 40.0% of monthly cap
|
|
210
|
+
Used: 1.2B / 3.0B (1.8B remaining) · 5,120 requests
|
|
197
211
|
|
|
198
212
|
MiMo V2.5:
|
|
199
|
-
[
|
|
200
|
-
Used: 125.0M / 1.0B (875.0M remaining)
|
|
213
|
+
[███░░░░░░░░░░░░░░░░░] 12.5% of monthly cap
|
|
214
|
+
Used: 125.0M / 1.0B (875.0M remaining) · 840 requests
|
|
215
|
+
|
|
216
|
+
GLM 5.3 👑:
|
|
217
|
+
[████████░░░░░░░░░░░░] 40.0% of monthly cap
|
|
218
|
+
Used: 1.2B / 3.0B (1.8B remaining) · 2,400 requests
|
|
219
|
+
↳ rolling window: 400.0M / 4h (daily granularity — /usage cannot break it down)
|
|
201
220
|
|
|
202
221
|
Uncapped models:
|
|
203
222
|
|
|
204
|
-
Qwen 3.6: 890.5K used
|
|
205
|
-
|
|
223
|
+
Qwen 3.6: 890.5K used · 123 requests
|
|
224
|
+
|
|
225
|
+
Window totals: 2.6B tokens (2.0B prompt / 640.0M completion) · 18,432 requests
|
|
226
|
+
All time: 13.2B tokens · 41,250 requests (cached 2026-02-01)
|
|
227
|
+
💡 Source: GET /v1/usage · caps from https://nan.builders/docs/models
|
|
206
228
|
```
|
|
207
229
|
|
|
208
|
-
**Without
|
|
230
|
+
**Without an API key** (static limits only):
|
|
209
231
|
```
|
|
210
232
|
📊 NaN Quota Status (static limits)
|
|
211
233
|
|
|
212
|
-
⏱️ Next billing reset: 2026-
|
|
234
|
+
⏱️ Next billing reset: 2026-09-30 UTC (2d 14h 30m 0s)
|
|
213
235
|
|
|
214
236
|
Model Monthly Cap
|
|
215
237
|
─────────────────────────────────────────────────
|
|
216
238
|
DeepSeek V4 Flash 3.0B
|
|
217
239
|
MiMo V2.5 1.0B
|
|
240
|
+
MiMo V2.6 Flash 1.0B
|
|
218
241
|
Qwen 3.6 uncapped
|
|
219
242
|
Gemma 4 uncapped
|
|
220
243
|
Qwen 3.8 Flash 500.0M
|
|
221
244
|
GLM 5.3 Flash 2.0B
|
|
222
|
-
GLM 5.3
|
|
245
|
+
GLM 5.3 3.0B 👑 (rolling 400.0M/4h)
|
|
223
246
|
|
|
224
|
-
💡
|
|
247
|
+
💡 Set NAN_API_KEY or run `/login nan` to see real usage (GET /v1/usage).
|
|
225
248
|
```
|
|
226
249
|
|
|
250
|
+
Failures stay actionable: `401` → run `/login nan` or fix `NAN_API_KEY`, `404` → the account has no usage identity to report, `429` → retry after the `Retry-After` seconds.
|
|
251
|
+
|
|
227
252
|
---
|
|
228
253
|
|
|
229
254
|
## 📊 Models
|
|
@@ -235,13 +260,14 @@ Baseline catalog (verified against [NaN docs](https://nan.builders/docs/models)
|
|
|
235
260
|
| `qwen3.6` | 262,144 | 65,536 | text, image | ✅ |
|
|
236
261
|
| `gemma4` | 262,144 | 32,768 | text, image | ✅ |
|
|
237
262
|
| `deepseek-v4-flash` | 1,000,000 | 384,000 | text, image | ✅ |
|
|
238
|
-
| `mimo-v2.5` | 1,048,576 | 131,072 | text, image | ✅ |
|
|
239
263
|
| `mimo-v2.6-flash` | 1,048,576 | 131,072 | text, image | ✅ |
|
|
240
264
|
| `glm5.3-flash` | 1,000,000 | 131,072 | text, image | ✅ |
|
|
241
265
|
| `qwen3.8-flash` | 262,144 | 131,072 | text, image | ✅ |
|
|
242
266
|
|
|
243
267
|
> [!NOTE]
|
|
244
|
-
> `mimo-v2.6-flash` is served by NaN
|
|
268
|
+
> `mimo-v2.6-flash` is served by NaN and has been listed by models.dev provider `nan` since 2026-09-29. Before that it entered the catalog through a manual-only entry; that entry is kept as a fallback (re-emitted automatically if models.dev drops the model again) and its provenance note stays attached to the generated entry.
|
|
269
|
+
>
|
|
270
|
+
> `mimo-v2.5` was removed by NaN: it no longer appears in the [NaN docs](https://nan.builders/docs/models) nor in the [OpenAPI model list](https://nan.builders/openapi.json) (checked 2026-09-29), so it is out of the catalog — `mimo-v2.6-flash` replaces it (same 1,048,576 / 131,072 limits, 1.0B monthly quota). Historical `/nan-usage` consumption for `mimo-v2.5` still shows under the undocumented-models section.
|
|
245
271
|
|
|
246
272
|
---
|
|
247
273
|
|
|
@@ -253,7 +279,7 @@ NaN's `reasoning_effort` parameter controls how much the model thinks before ans
|
|
|
253
279
|
| :--- | :--- | :--- |
|
|
254
280
|
| `glm5.3`, `glm5.3-flash` | `low` · `medium` · `high` · `max` | Fully controllable — higher values let the model reason longer |
|
|
255
281
|
| `qwen3.6`, `gemma4` | `none` · `minimal` · `low` · `medium` · `high` · `max` | `none`/`minimal` skip reasoning entirely; others cap at 2K / 8K / 16K / 32K tokens |
|
|
256
|
-
| `deepseek-v4-flash`, `qwen3.8-flash`, `mimo-v2.
|
|
282
|
+
| `deepseek-v4-flash`, `qwen3.8-flash`, `mimo-v2.6-flash` | *(accepted but not adjustable)* | The parameter is accepted and never rejected, but the model manages its own reasoning depth — it is never an error to send a value these models don't adjust |
|
|
257
283
|
|
|
258
284
|
---
|
|
259
285
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gtrabanco/pi-nan-provider",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "NaN Builders (api.nan.builders) model provider for pi - OpenAI-compatible registration with a models.dev-generated fallback, tier-aware live catalog, and MCP bridges (official web search + optional community media server)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi",
|
|
@@ -42,12 +42,12 @@
|
|
|
42
42
|
"check-pi-sdk-versions": "node scripts/check-pi-sdk-versions.mjs --report"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"@earendil-works/pi-ai": ">=0.
|
|
46
|
-
"@earendil-works/pi-coding-agent": ">=0.
|
|
45
|
+
"@earendil-works/pi-ai": ">=0.99.0 <1",
|
|
46
|
+
"@earendil-works/pi-coding-agent": ">=0.99.0 <1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@earendil-works/pi-ai": "0.
|
|
50
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
49
|
+
"@earendil-works/pi-ai": "0.99.1",
|
|
50
|
+
"@earendil-works/pi-coding-agent": "0.99.1",
|
|
51
51
|
"@types/bun": "1.4",
|
|
52
52
|
"typescript": "7"
|
|
53
53
|
},
|
|
@@ -42,8 +42,16 @@
|
|
|
42
42
|
|
|
43
43
|
import {
|
|
44
44
|
DEFAULT_NAN_MEDIA_MCP_VERSION,
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
} from "../src/mcp/media-server.ts";
|
|
46
|
+
|
|
47
|
+
/** The audio/image/transcription scope we bridge from the community server. */
|
|
48
|
+
const bridgedtools = [
|
|
49
|
+
"generate_image",
|
|
50
|
+
"edit_image",
|
|
51
|
+
"text_to_speech",
|
|
52
|
+
"list_voices",
|
|
53
|
+
"speech_to_text",
|
|
54
|
+
] as const;
|
|
47
55
|
|
|
48
56
|
/** npm package name of the community stdio MCP server we bridge. */
|
|
49
57
|
export const NAN_MCP_SERVER_PACKAGE = "nan-mcp-server";
|
|
@@ -143,7 +151,7 @@ export function assessUpdate(latestTools: string[]): {
|
|
|
143
151
|
removedTools: string[];
|
|
144
152
|
reason: string;
|
|
145
153
|
} {
|
|
146
|
-
const bridged: readonly string[] = [...
|
|
154
|
+
const bridged: readonly string[] = [...bridgedtools];
|
|
147
155
|
const latest = new Set(latestTools.map((t) => t.trim()));
|
|
148
156
|
|
|
149
157
|
const removedTools = bridged.filter((tool) => !latest.has(tool));
|