pi-neuralwatt-provider 1.0.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.
Files changed (41) hide show
  1. package/.github/FUNDING.yml +4 -0
  2. package/.github/workflows/update-models.yml +51 -0
  3. package/.pi/autoresearch/session-id +1 -0
  4. package/.pi/messenger/channels/memory.jsonl +1 -0
  5. package/.pi/messenger/session-id +1 -0
  6. package/LICENSE +21 -0
  7. package/README.md +238 -0
  8. package/assets/screenshot.jpg +0 -0
  9. package/chad-mcr-upstream.ts +1059 -0
  10. package/custom-models.json +368 -0
  11. package/docs/sse-payloads.md +117 -0
  12. package/index.ts +1357 -0
  13. package/knip.json +6 -0
  14. package/models.json +294 -0
  15. package/neuralwatt-mcr.ts +190 -0
  16. package/npm-shrinkwrap.json +2232 -0
  17. package/package.json +48 -0
  18. package/patch.json +129 -0
  19. package/scripts/probe-flex.mjs +238 -0
  20. package/scripts/probe-full-chunks.mjs +56 -0
  21. package/scripts/probe-headers.mjs +37 -0
  22. package/scripts/probe-metadata-chunk-timing.mjs +95 -0
  23. package/scripts/probe-metadata.mjs +128 -0
  24. package/scripts/probe-non-stream.mjs +57 -0
  25. package/scripts/probe-stream-headers.mjs +39 -0
  26. package/scripts/probe-usage-chunk.mjs +68 -0
  27. package/scripts/probe-vision-models.mjs +132 -0
  28. package/scripts/test-image-limit-stream.mjs +83 -0
  29. package/scripts/test-image-limit.mjs +89 -0
  30. package/scripts/update-models.js +410 -0
  31. package/tests/__mocks__/pi-ai.ts +19 -0
  32. package/tests/__mocks__/pi-coding-agent.ts +19 -0
  33. package/tests/config.test.ts +282 -0
  34. package/tests/energy-reader.test.ts +436 -0
  35. package/tests/flex-models.test.ts +239 -0
  36. package/tests/neuralwatt-mcr.test.ts +481 -0
  37. package/tests/progressive-disclosure.test.ts +294 -0
  38. package/tests/transform.test.ts +114 -0
  39. package/transform.ts +59 -0
  40. package/tsconfig.json +15 -0
  41. package/vitest.config.ts +17 -0
@@ -0,0 +1,4 @@
1
+ github: monotykamary
2
+ ko_fi: monotykamary
3
+ buy_me_a_coffee: monotykamary
4
+ polar: monotykamary
@@ -0,0 +1,51 @@
1
+ name: Update Neuralwatt Models
2
+
3
+ on:
4
+ schedule:
5
+ # Run daily at 00:00 UTC
6
+ - cron: '0 0 * * *'
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: write
11
+ pull-requests: write
12
+
13
+ jobs:
14
+ update-models:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - name: Checkout repository
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Setup Node.js
21
+ uses: actions/setup-node@v4
22
+ with:
23
+ node-version: '20'
24
+
25
+ - name: Fetch and update models
26
+ run: node scripts/update-models.js
27
+
28
+ - name: Check for changes
29
+ id: check-changes
30
+ run: |
31
+ if git diff --quiet; then
32
+ echo "changed=false" >> $GITHUB_OUTPUT
33
+ else
34
+ echo "changed=true" >> $GITHUB_OUTPUT
35
+ fi
36
+
37
+ - name: Create Pull Request
38
+ if: steps.check-changes.outputs.changed == 'true'
39
+ uses: peter-evans/create-pull-request@v6
40
+ with:
41
+ token: ${{ secrets.GITHUB_TOKEN }}
42
+ commit-message: 'feat: update neuralwatt models from API'
43
+ title: 'feat: update neuralwatt models from API'
44
+ body: |
45
+ Automated update of Neuralwatt models from https://api.neuralwatt.com/v1/models
46
+
47
+ Changes include:
48
+ - Updated models in `models.json`
49
+ - Updated model table in `README.md`
50
+ branch: update-neuralwatt-models
51
+ delete-branch: true
@@ -0,0 +1 @@
1
+ 019e2ca5-c86b-7705-aa78-225c135a3144
@@ -0,0 +1 @@
1
+ {"_meta":true,"v":1,"id":"memory","type":"named","createdAt":"2026-05-23T01:54:08.851Z","description":"Cross-session knowledge and insights"}
@@ -0,0 +1 @@
1
+ 019e9272-aa36-7f8b-8373-5182876ff15d
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,238 @@
1
+ <div align="center">
2
+
3
+ # ⚡ pi-neuralwatt-provider
4
+
5
+ **Models + energy tracking via [Neuralwatt](https://neuralwatt.com)**
6
+
7
+ _Kimi, GLM, Qwen, DeepSeek — with real-time ⚡ energy/cost per session for [pi](https://github.com/earendil-works/pi-coding-agent)._
8
+
9
+ [![pi extension](https://img.shields.io/badge/pi-extension-blueviolet)](https://github.com/earendil-works/pi-coding-agent)
10
+ [![license](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)
11
+
12
+ </div>
13
+
14
+ ---
15
+
16
+ ![Energy Reporting Status Widget](assets/screenshot.jpg)
17
+
18
+ ## Features
19
+
20
+ - **OpenAI-compatible API** - Uses Neuralwatt's `/v1/chat/completions` endpoint
21
+ - **Reasoning models** - Support for thinking models with `reasoning_effort` parameter
22
+ - **Vision models** - Image input support on Kimi K2.5, K2.6, and Devstral
23
+ - **Tool use** - Function calling support
24
+ - **Streaming** - Real-time token streaming
25
+ - **Fast variants** - Optimized "Fast" versions of popular models for quicker responses
26
+ - **Energy reporting** - Displays energy consumption (⚡J/mWh/Wh/kWh) and actual billed cost ($) in a dedicated status widget below the editor, tracked per-session
27
+ - **Quota display** - Shows subscription plan, kWh allocation, and credits remaining from your Neuralwatt account, right-aligned in the status widget
28
+ - **Configurable display** - Energy and quota can each be shown in the below-editor widget, the built-in status bar, or turned off entirely via a config file
29
+
30
+ ## Available Models
31
+
32
+ | Model | Context | Vision | Reasoning | Input $/M | Output $/M |
33
+ |-------|---------|--------|-----------|-----------|------------|
34
+ | Devstral-Small-2-24B-Instruct-2512 | 262K | ✅ | ❌ | $0.12 | $0.35 |
35
+ | GLM-5 Fast | 203K | ❌ | ❌ | $1.10 | $3.60 |
36
+ | GLM-5.1 | 203K | ❌ | ✅ | $1.10 | $3.60 |
37
+ | GLM-5.1 Fast | 203K | ❌ | ❌ | $1.10 | $3.60 |
38
+ | GPT-OSS 20B | 16K | ❌ | ✅ | $0.03 | $0.16 |
39
+ | Kimi K2.5 | 262K | ✅ | ✅ | $0.52 | $2.59 |
40
+ | Kimi K2.5 Fast | 262K | ✅ | ❌ | $0.52 | $2.59 |
41
+ | Kimi K2.6 | 262K | ✅ | ✅ | $0.69 | $3.22 |
42
+ | Kimi K2.6 Fast | 262K | ✅ | ❌ | $0.69 | $3.22 |
43
+ | MiniMax M2.5 | 197K | ❌ | ✅ | $0.35 | $1.38 |
44
+ | Qwen3.5 397B | 262K | ❌ | ✅ | $0.69 | $4.14 |
45
+ | Qwen3.5 397B Fast | 262K | ❌ | ❌ | $0.69 | $4.14 |
46
+ | Qwen3.6 35B | 131K | ✅ | ✅ | $0.29 | $1.15 |
47
+ | Qwen3.6 35B Fast | 131K | ✅ | ❌ | $0.29 | $1.15 |
48
+ | GLM-5.1 Canary | 203K | ❌ | ✅ | $1.10 | $3.60 |
49
+ | GLM-5.1 NVFP4 Canary | 203K | ❌ | ✅ | $1.10 | $3.60 |
50
+ | Kimi K2.6 Canary | 262K | ✅ | ✅ | $0.69 | $3.22 |
51
+ | GLM-5.1 Flex | 203K | ❌ | ✅ | $1.10 | $3.60 |
52
+ | Kimi K2.6 Flex | 262K | ✅ | ✅ | $0.69 | $3.22 |
53
+ | GLM-5 Long (MCR 1M) | 1.0M | ❌ | ✅ | $1.10 | $3.60 |
54
+ | GLM-5.1 Long (MCR 1M) | 1.0M | ❌ | ✅ | $1.10 | $3.60 |
55
+ | GLM-5.1 Long Coherence (MCR 1M Canary) | 1.0M | ❌ | ✅ | $1.10 | $3.60 |
56
+ | GLM-5.1 Fast Long (MCR 1M) | 1.0M | ❌ | ❌ | $1.10 | $3.60 |
57
+ | Kimi K2.6 Long (MCR 1M) | 1.0M | ✅ | ✅ | $0.69 | $3.22 |
58
+ | Kimi K2.5 Long (MCR 1M) | 1.0M | ✅ | ✅ | $0.52 | $2.59 |
59
+ | Claude Opus (Cached) | 1.0M | ❌ | ✅ | $0.00 | $0.00 |
60
+
61
+ ## Authentication
62
+
63
+ The Neuralwatt API key can be configured in multiple ways (resolved in this order):
64
+
65
+ 1. **`auth.json`** (recommended) — Add to `~/.pi/agent/auth.json`:
66
+ ```json
67
+ { "neuralwatt": { "type": "api_key", "key": "your-api-key" } }
68
+ ```
69
+ The `key` field supports literal values, env var names, and shell commands (prefix with `!`). See [pi's auth file docs](https://github.com/badlogic/pi-mono) for details.
70
+ 2. **Runtime override** — Use the `--api-key` CLI flag
71
+ 3. **Environment variable** — Set `NEURALWATT_API_KEY`
72
+
73
+ Get your API key from [neuralwatt.com](https://neuralwatt.com).
74
+
75
+ ## Installation
76
+
77
+ ### Option 1: Using `pi install` (Recommended)
78
+
79
+ Install directly from GitHub:
80
+
81
+ ```bash
82
+ pi install https://github.com/monotykamary/pi-neuralwatt-provider
83
+ ```
84
+
85
+ Then authenticate and run pi:
86
+ ```bash
87
+ # Recommended: add to auth.json
88
+ # See Authentication section below
89
+
90
+ # Or set as environment variable
91
+ export NEURALWATT_API_KEY=your-api-key-here
92
+
93
+ pi
94
+ ```
95
+
96
+ ### Option 2: Manual Clone
97
+
98
+ 1. Clone this repository:
99
+ ```bash
100
+ git clone git@github.com:monotykamary/pi-neuralwatt-provider.git
101
+ cd pi-neuralwatt-provider
102
+ ```
103
+
104
+ 2. Configure your Neuralwatt API key:
105
+ ```bash
106
+ # Recommended: add to auth.json
107
+ # See Authentication section below
108
+
109
+ # Or set as environment variable
110
+ export NEURALWATT_API_KEY=your-api-key-here
111
+ ```
112
+
113
+ 3. Run pi with the extension:
114
+ ```bash
115
+ pi -e /path/to/pi-neuralwatt-provider
116
+ ```
117
+
118
+ ## Environment Variables
119
+
120
+ | Variable | Required | Description |
121
+ |----------|----------|-------------|
122
+ | `NEURALWATT_API_KEY` | No | Your Neuralwatt API key (fallback if not in auth.json) |
123
+
124
+ ## Configuration
125
+
126
+ ### Compat Settings
127
+
128
+ Neuralwatt's API now provides compatibility and capability metadata (pricing, reasoning, vision, developer_role, reasoning_effort, max_images) directly in the `/v1/models` response. The `update-models.js` script reads these and writes them into `models.json`. Only genuinely incorrect API data needs a manual override in `patch.json`.
129
+
130
+ Currently configured compat settings (all sourced from the API):
131
+
132
+ - **`supportsDeveloperRole: false`** — All models. vLLM doesn't support the `developer` role; pi sends system prompts as `system` messages instead.
133
+ - **`supportsReasoningEffort: true`** — GPT-OSS. Sends `reasoning_effort` parameter (maps to pi's `/reasoning` command levels).
134
+
135
+ ### Custom Stream Handler
136
+
137
+ This extension registers a custom `streamSimple` provider (`api: "neuralwatt"`) that wraps pi-ai's built-in `streamOpenAICompletions`. A temporary `globalThis.fetch` override tees the HTTP response body so the OpenAI SDK handles all standard chunk parsing (text, thinking, tool calls, usage) while the extension reads the tee for Neuralwatt's SSE comment lines (`: energy {...}`, `: cost {...}`) that the SDK discards.
138
+
139
+ ### Pi Configuration
140
+
141
+ Add to your pi configuration for automatic loading:
142
+
143
+ ```json
144
+ {
145
+ "extensions": [
146
+ "/path/to/pi-neuralwatt-provider"
147
+ ]
148
+ }
149
+ ```
150
+
151
+ ## Usage
152
+
153
+ Once loaded, select a model with:
154
+
155
+ ```
156
+ /model neuralwatt kimi-k2.5
157
+ ```
158
+
159
+ Or use `/models` to browse all available Neuralwatt models.
160
+
161
+ ### Reasoning Effort
162
+
163
+ For reasoning models, control thinking depth:
164
+
165
+ ```
166
+ /reasoning high
167
+ ```
168
+
169
+ Values: `none`, `low`, `medium`, `high`
170
+
171
+ ## Display Configuration
172
+
173
+ Energy and quota are independently configurable. Create `~/.pi/agent/extensions/neuralwatt.json`:
174
+
175
+ ```json
176
+ {
177
+ "energy": "widget",
178
+ "quota": "widget"
179
+ }
180
+ ```
181
+
182
+ The file is auto-populated with defaults on first run.
183
+
184
+ | Key | Values | Default | Description |
185
+ |-----|--------|---------|-------------|
186
+ | `energy` | `"widget"`, `"statusbar"`, `"off"` | `"widget"` | Energy/cost display mode |
187
+ | `quota` | `"widget"`, `"statusbar"`, `"off"` | `"widget"` | Quota display mode |
188
+
189
+ **Display modes:**
190
+
191
+ - **`"widget"`** — Shown in the dedicated below-editor status line. Energy on the left, quota on the right, padded to terminal width.
192
+ - **`"statusbar"`** — Shown in the built-in pi status bar. When both are set to `"statusbar"`, they're combined with a ` | ` separator: `⚡X J $Y | plan ● kWh ∙ $bal`.
193
+ - **`"off"`** — Hidden entirely. For `"quota": "off"`, the `/v1/quota` API fetch is also skipped (saving a network round-trip). Energy data is still parsed from the SSE stream and persisted to the session even when `"off"`.
194
+
195
+ **Example — custom quota footer:** If you use your own unified quota footer extension, disable the built-in quota display to avoid duplication:
196
+
197
+ ```json
198
+ {
199
+ "energy": "widget",
200
+ "quota": "off"
201
+ }
202
+ ```
203
+
204
+ ## Energy Reporting
205
+
206
+ Neuralwatt provides real-time energy consumption data with every API response. This extension captures it and displays a running total in a dedicated status widget between the editor and the pi footer:
207
+
208
+ | Segment | Meaning |
209
+ |---------|----------|
210
+ | `⚡0.8mWh` | Cumulative session energy consumption (auto-scaled: J → mWh → Wh → kWh) |
211
+ | `$0.003952` | Cumulative session actual billed cost from Neuralwatt |
212
+ | `pro` | Your Neuralwatt subscription plan |
213
+ | `●` | Subscription status indicator (● = active, ⊘ = past due/paused) |
214
+ | `31.7/33.0 kWh` | kWh remaining / kWh included in your plan |
215
+ | `∙ $64.55` | Credits remaining on your account |
216
+ | `🔑 .../.../mo` | Key allowance usage (if set on your API key) |
217
+
218
+ The energy and cost data comes from Neuralwatt's SSE stream comments (`: energy` and `: cost`), which the standard OpenAI SDK discards. This extension uses a custom stream handler that parses raw SSE to capture them.
219
+
220
+ Energy is measured directly from GPU hardware using NVIDIA's NVML. For concurrent requests, Neuralwatt uses token-weighted attribution to fairly calculate your share. See [Neuralwatt's energy methodology](https://portal.neuralwatt.com/docs/energy-methodology) for details.
221
+
222
+ ### Persistence
223
+
224
+ Energy and cost data is persisted per-request as custom session entries. On session resume or tree navigation, the totals are rebuilt by replaying all events in the current branch. This means:
225
+
226
+ - **Session resume** — Energy/cost totals are restored when you continue a session
227
+ - **Branching** — Navigating to a different point in the session tree shows the correct totals for that branch
228
+ - **Forking** — Forked sessions carry their energy history forward
229
+
230
+ ## API Documentation
231
+
232
+ - Neuralwatt API: `https://api.neuralwatt.com/v1`
233
+ - Models endpoint: `https://api.neuralwatt.com/v1/models`
234
+ - Chat completions: `https://api.neuralwatt.com/v1/chat/completions`
235
+
236
+ ## License
237
+
238
+ MIT
Binary file