pi-cliproxyapi-autoconnect 1.2.1 → 1.2.2
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/README.md +155 -149
- package/index.ts +3 -3
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,170 +1,171 @@
|
|
|
1
1
|
# pi-cliproxyapi-autoconnect
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A **CLIProxyAPI provider for [pi](https://github.com/earendil-works/pi)**.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
After installation, `/login` shows a **CLIProxy** entry under **“Sign in with an API key”**. Select it and:
|
|
6
6
|
|
|
7
|
-
1.
|
|
8
|
-
2.
|
|
9
|
-
3.
|
|
10
|
-
4.
|
|
11
|
-
5.
|
|
7
|
+
1. Enter the CLIProxy **bound domain** (for example `proxy.example.com`);
|
|
8
|
+
2. Enter the **API key**;
|
|
9
|
+
3. The plugin derives every compatible endpoint and tries them automatically in this order: **OpenAI → Gemini → Anthropic** (OpenAI first);
|
|
10
|
+
4. Every discovered model is registered with pi and becomes available in `/model`;
|
|
11
|
+
5. Only when every endpoint fails are you asked to pick an endpoint manually (or enter a custom one) and type model IDs.
|
|
12
12
|
|
|
13
|
-
API
|
|
13
|
+
The API key is stored by pi in `~/.pi/agent/auth.json`. The plugin's own config file only stores the domain, endpoint and model cache; it **never stores the key**.
|
|
14
14
|
|
|
15
|
-
>
|
|
15
|
+
> Verified on pi `1.2.0` and `1.3.0`: provider registration, `/model` listing, model discovery and fallback, and real streaming chat requests over the OpenAI-compatible API.
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
##
|
|
19
|
+
## Install
|
|
20
20
|
|
|
21
|
-
###
|
|
21
|
+
### Option A: install from npm (recommended)
|
|
22
22
|
|
|
23
23
|
```powershell
|
|
24
24
|
pi install npm:pi-cliproxyapi-autoconnect
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Then restart pi (or run `/reload` inside pi).
|
|
28
28
|
|
|
29
|
-
npm
|
|
29
|
+
The npm package contains only `index.ts`, `README.md` and `LICENSE`; pi's npm installer downloads it. The next two options are only for local development.
|
|
30
30
|
|
|
31
|
-
###
|
|
31
|
+
### Option B: install from a local directory
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
Plugin directory: `F:\Desktop\pi-cliproxyapi-autoconnect`.
|
|
34
34
|
|
|
35
35
|
```powershell
|
|
36
36
|
pi install F:\Desktop\pi-cliproxyapi-autoconnect
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Then restart pi (or run `/reload` inside pi).
|
|
40
40
|
|
|
41
|
-
###
|
|
41
|
+
### Option C: copy into the extensions directory
|
|
42
42
|
|
|
43
43
|
```powershell
|
|
44
44
|
powershell -ExecutionPolicy Bypass -File F:\Desktop\pi-cliproxyapi-autoconnect\install.ps1
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
The script copies the plugin to:
|
|
48
48
|
|
|
49
49
|
```text
|
|
50
50
|
%USERPROFILE%\.pi\agent\extensions\pi-cliproxyapi-autoconnect\
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
If `PI_CODING_AGENT_DIR` is set, it copies to `extensions\pi-cliproxyapi-autoconnect\` under that directory instead.
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
You can also copy the whole `pi-cliproxyapi-autoconnect` folder into `%USERPROFILE%\.pi\agent\extensions\`; make sure the entry point is:
|
|
56
56
|
|
|
57
57
|
```text
|
|
58
58
|
%USERPROFILE%\.pi\agent\extensions\pi-cliproxyapi-autoconnect\index.ts
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
pi
|
|
61
|
+
pi automatically loads subfolders under `extensions` whose entry point is `index.ts`.
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
After installation, verify that the plugin loads and models are available:
|
|
64
64
|
|
|
65
65
|
```powershell
|
|
66
66
|
pi --list-models
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
###
|
|
69
|
+
### Migrating from the old `pi-cliproxy` package
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
The package was renamed to `pi-cliproxyapi-autoconnect`. The provider ID is still `cliproxy`, and the existing `cliproxy.json` and `auth.json` credentials remain valid.
|
|
72
72
|
|
|
73
73
|
```powershell
|
|
74
74
|
pi remove npm:pi-cliproxy
|
|
75
75
|
pi install npm:pi-cliproxyapi-autoconnect
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
Then restart pi. Models are still listed as `cliproxy/<model-id>`; no config or cache rebuild is required.
|
|
79
79
|
|
|
80
80
|
---
|
|
81
81
|
|
|
82
|
-
##
|
|
82
|
+
## Usage
|
|
83
83
|
|
|
84
|
-
1.
|
|
85
|
-
2.
|
|
86
|
-
3.
|
|
87
|
-
4.
|
|
84
|
+
1. Restart pi and run `/login`.
|
|
85
|
+
2. Choose **“Sign in with an API key”** (not “Sign in with an account”).
|
|
86
|
+
3. Select **CLIProxy** from the list.
|
|
87
|
+
4. Enter the bound domain, for example:
|
|
88
88
|
- `proxy.example.com`
|
|
89
89
|
- `https://proxy.example.com`
|
|
90
90
|
- `http://192.168.1.10:8317`
|
|
91
|
-
-
|
|
92
|
-
5.
|
|
93
|
-
6.
|
|
91
|
+
- a complete URL such as `https://proxy.example.com/v1` also works
|
|
92
|
+
5. Enter the CLIProxy API key (the value in CLIProxy's `access.api-keys`).
|
|
93
|
+
6. The plugin tries every compatible endpoint in this order:
|
|
94
94
|
|
|
95
95
|
```text
|
|
96
|
-
https
|
|
97
|
-
https
|
|
98
|
-
https
|
|
96
|
+
https://<domain>/v1/models OpenAI (highest priority)
|
|
97
|
+
https://<domain>/v1beta/models Gemini
|
|
98
|
+
https://<domain>/v1/models Anthropic (x-api-key, best effort)
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
7.
|
|
101
|
+
The first endpoint that returns a non-empty model list is selected and saved. The models are immediately visible in `/model`.
|
|
102
|
+
If you entered a bare domain without a scheme, every endpoint is also tried with the alternate scheme (https/http), for at most 6 probes.
|
|
103
|
+
7. Run `/model` and select `cliproxy/<model-id>`.
|
|
104
104
|
|
|
105
|
-
###
|
|
105
|
+
### Address formatting
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
The input is first normalized to a root URL: trailing `/`, `/v1`, `/v1beta`, `/v1/models` and similar suffixes are removed, while any path prefix is preserved. The plugin then derives:
|
|
108
108
|
|
|
109
|
-
|
|
|
109
|
+
| Purpose | Derived endpoint |
|
|
110
110
|
| --- | --- |
|
|
111
|
-
| OpenAI
|
|
112
|
-
| Gemini
|
|
113
|
-
| Anthropic
|
|
111
|
+
| OpenAI compatible (highest priority) | `https://<domain>/v1`; model discovery uses `/v1/models` |
|
|
112
|
+
| Gemini compatible | `https://<domain>/v1beta`; model discovery uses `/v1beta/models` |
|
|
113
|
+
| Anthropic compatible | `https://<domain>` (the SDK appends `/v1/messages`; model discovery tries `/v1/models` as a best effort) |
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
Local and private addresses (`localhost`, `127.0.0.1`, `10.*`, `192.168.*`, `172.16-31.*`, `.local`, `.lan`) default to `http://`; everything else defaults to `https://`. Without an explicit scheme, each compatible endpoint is also tried with the alternate scheme.
|
|
116
116
|
|
|
117
|
-
###
|
|
117
|
+
### Fallback when discovery fails
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
The plugin first tries every compatible endpoint automatically. After that:
|
|
120
120
|
|
|
121
|
-
1.
|
|
122
|
-
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
2.
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
- Anthropic
|
|
130
|
-
- Gemini
|
|
131
|
-
-
|
|
132
|
-
3.
|
|
133
|
-
4.
|
|
121
|
+
1. If **any** endpoint returned 401/403, the key is the more likely problem:
|
|
122
|
+
- The plugin prompts for the key once more;
|
|
123
|
+
- It retries every endpoint;
|
|
124
|
+
- If authentication still fails, login aborts and **nothing is saved**.
|
|
125
|
+
2. If there are only other failures (404, timeout, format error, etc.) and no endpoint returned a model list:
|
|
126
|
+
- The plugin reports the failure for each endpoint and probes `/healthz` to check whether the service is CLIProxyAPI;
|
|
127
|
+
- It shows an endpoint picker:
|
|
128
|
+
- Retry OpenAI compatible: `https://<domain>/v1`
|
|
129
|
+
- Anthropic compatible: `https://<domain>`
|
|
130
|
+
- Gemini compatible: `https://<domain>/v1beta`
|
|
131
|
+
- Custom compatible endpoint (enter a full base URL and choose a protocol)
|
|
132
|
+
3. If the selected endpoint still returns no model list, you can enter model IDs manually (comma or space separated, or leave empty).
|
|
133
|
+
4. If every endpoint returns HTTP 200 with an empty model list, the picker is skipped and you go straight to manual input (usually because the upstream account has no available credentials).
|
|
134
134
|
|
|
135
|
-
Anthropic
|
|
135
|
+
An Anthropic-compatible endpoint does not always expose a model list. If `/v1/models` returns 404/405, automatic discovery skips it; after selecting that endpoint, enter model IDs manually. Gemini-compatible endpoints are probed at `/v1beta/models`.
|
|
136
136
|
|
|
137
137
|
---
|
|
138
138
|
|
|
139
|
-
## `/cliproxy`
|
|
139
|
+
## `/cliproxy` command
|
|
140
140
|
|
|
141
141
|
```text
|
|
142
|
-
/cliproxy
|
|
143
|
-
/cliproxy refresh
|
|
142
|
+
/cliproxy Show the current config, model count and last error
|
|
143
|
+
/cliproxy refresh Refresh the model list immediately
|
|
144
144
|
```
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
The model catalog is cached for **5 minutes** by default: opening `/model` does not hit the upstream every time. `/cliproxy refresh` forces a refresh.
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
To reconfigure (new domain or key), run `/login` → `CLIProxy` again. If you switched to a completely different domain and the old models are still visible, run `/reload` so the plugin rebuilds the provider from the new config.
|
|
149
149
|
|
|
150
|
-
###
|
|
150
|
+
### Relationship to pi update commands
|
|
151
151
|
|
|
152
|
-
- **`pi update --models`
|
|
153
|
-
|
|
154
|
-
-
|
|
155
|
-
- **`pi update --extensions`**
|
|
152
|
+
- **`pi update --models` does not refresh this plugin's model list.**
|
|
153
|
+
It creates a temporary ModelRuntime without extensions and refreshes pi's built-in or `models.json` catalog; plugin providers are not included. It does not break the plugin, but `cliproxy/*` models are not updated.
|
|
154
|
+
- To refresh plugin models, use `/cliproxy refresh`, open `/model`, or restart pi (interactive startup refreshes dynamic providers).
|
|
155
|
+
- **`pi update --extensions`** updates the npm package itself (the plugin code); restart pi after updating.
|
|
156
|
+
- To update only this plugin, run `pi update npm:pi-cliproxyapi-autoconnect`.
|
|
156
157
|
|
|
157
158
|
---
|
|
158
159
|
|
|
159
|
-
##
|
|
160
|
+
## Files and security
|
|
160
161
|
|
|
161
|
-
|
|
|
162
|
+
| Content | Location |
|
|
162
163
|
| --- | --- |
|
|
163
|
-
| API
|
|
164
|
-
|
|
|
165
|
-
|
|
|
164
|
+
| API key | `~/.pi/agent/auth.json` (written by pi's login flow) |
|
|
165
|
+
| Domain, endpoint, model cache | `~/.pi/agent/cliproxy.json` |
|
|
166
|
+
| pi model catalog cache (maintained by pi) | `~/.pi/agent/models-store.json` |
|
|
166
167
|
|
|
167
|
-
`cliproxy.json
|
|
168
|
+
Example `cliproxy.json`:
|
|
168
169
|
|
|
169
170
|
```json
|
|
170
171
|
{
|
|
@@ -190,51 +191,50 @@ Anthropic 兼容接口不一定提供模型列表;如果 `/v1/models` 返回 4
|
|
|
190
191
|
}
|
|
191
192
|
```
|
|
192
193
|
|
|
193
|
-
|
|
194
|
+
Notes:
|
|
194
195
|
|
|
195
|
-
-
|
|
196
|
-
-
|
|
197
|
-
|
|
198
|
-
-
|
|
199
|
-
-
|
|
200
|
-
- 删除插件不会删除 `auth.json` 里的凭据;如需清理,可在 pi 里 `/logout` 选择 CLIProxy,或手动编辑 `auth.json`。
|
|
196
|
+
- Since 1.1.0, complete model metadata (`reasoning` / `input` / `cost` / `contextWindow` / `maxTokens`) is written directly to `cliproxy.json`, not just model IDs.
|
|
197
|
+
- The previous version is saved as `cliproxy.json.bak` before each write, for manual recovery.
|
|
198
|
+
- The plugin never writes the key to `cliproxy.json` and never prints it to logs.
|
|
199
|
+
- The key prompt is **not masked** in pi's current TUI (pi renders `secret` and normal text prompts the same way). Be aware of your surroundings.
|
|
200
|
+
- Removing the plugin does not remove credentials from `auth.json`. To clean up, run `/logout` in pi and select CLIProxy, or edit `auth.json` manually.
|
|
201
201
|
|
|
202
202
|
---
|
|
203
203
|
|
|
204
|
-
##
|
|
204
|
+
## Model capabilities
|
|
205
205
|
|
|
206
|
-
`/v1/models`
|
|
206
|
+
`/v1/models` only returns model IDs (and possibly `owned_by`). It does not include context length, image support or reasoning support.
|
|
207
207
|
|
|
208
|
-
|
|
208
|
+
The plugin resolves capability fields (`name`, `reasoning`, `input`, `cost`, `contextWindow`, `maxTokens`) in this order:
|
|
209
209
|
|
|
210
|
-
1. `~/.pi/agent/models.json`
|
|
211
|
-
2. `cliproxy.json
|
|
212
|
-
3. `~/.pi/agent/models-store.json`
|
|
213
|
-
4. pi
|
|
214
|
-
5.
|
|
210
|
+
1. A model with the same ID in `~/.pi/agent/models.json` (explicit user config, highest priority);
|
|
211
|
+
2. Metadata already stored in `cliproxy.json`;
|
|
212
|
+
3. A model with the same ID cached by pi in `~/.pi/agent/models-store.json` (preserves information when upgrading from an older version);
|
|
213
|
+
4. pi's built-in model catalog (after stripping prefixes such as `cn:`, `global:` and `models/`);
|
|
214
|
+
5. Conservative guesses based on the model name.
|
|
215
215
|
|
|
216
|
-
|
|
216
|
+
In other words, if you previously hand-wrote a provider pointing at the same CLIProxyAPI instance, the new `cliproxy` provider inherits the more accurate metadata; upgrading from 1.0.x does not lose it either.
|
|
217
217
|
|
|
218
|
-
|
|
218
|
+
When no metadata is available, the plugin uses conservative guesses:
|
|
219
219
|
|
|
220
|
-
- `claude*` / Anthropic
|
|
221
|
-
- `gemini*` / Gemini
|
|
222
|
-
- `gpt-5*` / `gpt-6
|
|
223
|
-
-
|
|
224
|
-
-
|
|
220
|
+
- `claude*` / Anthropic protocol: 200K context, 64K max output;
|
|
221
|
+
- `gemini*` / Gemini protocol: 1M context, 64K max output;
|
|
222
|
+
- `gpt-5*` / `gpt-6*`: 272K context, 128K max output;
|
|
223
|
+
- everything else: 128K context, 32K max output;
|
|
224
|
+
- text input only, `reasoning` disabled, cost set to 0.
|
|
225
225
|
|
|
226
|
-
|
|
226
|
+
If a model's real capabilities differ:
|
|
227
227
|
|
|
228
|
-
-
|
|
229
|
-
-
|
|
228
|
+
- Add its metadata to `~/.pi/agent/models.json` (the plugin inherits it); or
|
|
229
|
+
- Edit `guessLimits()` / `toModel()` in `index.ts` and run `/reload`.
|
|
230
230
|
|
|
231
231
|
---
|
|
232
232
|
|
|
233
|
-
##
|
|
233
|
+
## Troubleshooting
|
|
234
234
|
|
|
235
235
|
### 401 / Invalid API key
|
|
236
236
|
|
|
237
|
-
CLIProxyAPI
|
|
237
|
+
CLIProxyAPI's client key lives in `access.api-keys` in the v8 config (the top-level `api-keys` in older versions). Check:
|
|
238
238
|
|
|
239
239
|
```yaml
|
|
240
240
|
access:
|
|
@@ -242,96 +242,102 @@ access:
|
|
|
242
242
|
- sk-your-real-key
|
|
243
243
|
```
|
|
244
244
|
|
|
245
|
-
`/v1/models`
|
|
245
|
+
`/v1/models` requires authentication by default, unless the server has no keys configured at all.
|
|
246
246
|
|
|
247
|
-
|
|
247
|
+
Since 1.2.0, login tries every compatible endpoint first (OpenAI first):
|
|
248
248
|
|
|
249
|
-
-
|
|
250
|
-
-
|
|
251
|
-
-
|
|
249
|
+
- If an endpoint returns models, it is used immediately;
|
|
250
|
+
- If no endpoint returns models and at least one returned 401/403, the plugin prompts for the key again and retries every endpoint;
|
|
251
|
+
- If authentication still fails, login aborts and does not save the config.
|
|
252
252
|
|
|
253
253
|
### 403 `unsafe_example_api_key`
|
|
254
254
|
|
|
255
|
-
CLIProxyAPI
|
|
255
|
+
CLIProxyAPI detected that the example key (`your-api-key-1`, etc.) is still in use. Replace `access.api-keys` with a real key and restart CLIProxyAPI.
|
|
256
256
|
|
|
257
|
-
### `/v1/models`
|
|
257
|
+
### `/v1/models` returns an empty list
|
|
258
258
|
|
|
259
|
-
|
|
259
|
+
This is a valid result: there are currently no available upstream credentials, or all of them are cooling down. Sign in to or configure the upstream accounts in CLIProxyAPI, then run `/cliproxy refresh`.
|
|
260
260
|
|
|
261
|
-
###
|
|
261
|
+
### Only `/healthz` works; `/v1/models` returns 404
|
|
262
262
|
|
|
263
|
-
CLIProxyAPI
|
|
263
|
+
CLIProxyAPI itself does not support a path prefix. If nginx/Caddy is in front and adds a prefix, make the reverse proxy remove it, for example:
|
|
264
264
|
|
|
265
265
|
```nginx
|
|
266
266
|
location /cliproxy/ {
|
|
267
|
-
proxy_pass http://127.0.0.1:8317/; #
|
|
267
|
+
proxy_pass http://127.0.0.1:8317/; # trailing slash removes the /cliproxy prefix
|
|
268
268
|
}
|
|
269
269
|
```
|
|
270
270
|
|
|
271
|
-
|
|
271
|
+
Alternatively, choose “Custom compatible endpoint” in the plugin and enter the full base URL exposed by the reverse proxy.
|
|
272
272
|
|
|
273
|
-
###
|
|
273
|
+
### Streaming disconnects mid-response / long answers time out
|
|
274
274
|
|
|
275
|
-
CLIProxyAPI
|
|
275
|
+
CLIProxyAPI recommends increasing nginx's `proxy_read_timeout`. Cloudflare's free-plan 100-second timeout can also truncate long streaming responses.
|
|
276
276
|
|
|
277
|
-
### `/model`
|
|
277
|
+
### No models visible in `/model`
|
|
278
278
|
|
|
279
|
-
- `/model`
|
|
280
|
-
-
|
|
281
|
-
-
|
|
282
|
-
-
|
|
279
|
+
- `/model` only lists models from providers with configured authentication; complete `/login` first.
|
|
280
|
+
- Run `/cliproxy` to check the model count and last error.
|
|
281
|
+
- Run `/cliproxy refresh` to retry.
|
|
282
|
+
- Confirm that `pi --list-models` shows `cliproxy/*`.
|
|
283
283
|
|
|
284
|
-
###
|
|
284
|
+
### Models look wrong after changing the domain
|
|
285
285
|
|
|
286
|
-
|
|
286
|
+
Run `/reload`, or restart pi after editing the plugin. The model list refreshes whenever `/model` is opened.
|
|
287
287
|
|
|
288
288
|
---
|
|
289
289
|
|
|
290
|
-
##
|
|
290
|
+
## Changelog
|
|
291
|
+
|
|
292
|
+
### 1.2.2
|
|
293
|
+
|
|
294
|
+
- Rewrote this README in English for the npm package page and the pi package gallery.
|
|
295
|
+
- Translated the npm package description to English.
|
|
296
|
+
- The pi TUI remains fully English.
|
|
291
297
|
|
|
292
298
|
### 1.2.1
|
|
293
299
|
|
|
294
|
-
- pi TUI
|
|
295
|
-
- provider
|
|
300
|
+
- All pi TUI strings are now English: login prompts, endpoint picker, errors and `/cliproxy` output.
|
|
301
|
+
- The provider display name remains `CLIProxy`; the `/login` entry, `/cliproxy` command and `cliproxy/` model prefix are unchanged.
|
|
296
302
|
|
|
297
303
|
### 1.2.0
|
|
298
304
|
|
|
299
|
-
-
|
|
300
|
-
-
|
|
301
|
-
-
|
|
302
|
-
-
|
|
303
|
-
-
|
|
304
|
-
- `/cliproxy refresh`
|
|
305
|
+
- Renamed the package from `pi-cliproxy` to `pi-cliproxyapi-autoconnect`; the provider ID, `cliproxy.json`, `/cliproxy` command and `cliproxy/` model prefix are unchanged.
|
|
306
|
+
- Login now tries every compatible endpoint automatically: **OpenAI → Gemini → Anthropic**, OpenAI first; the first non-empty model list wins.
|
|
307
|
+
- A bare domain also tries both https and http for every protocol, for up to 6 candidates.
|
|
308
|
+
- Best-effort discovery of Anthropic's `/v1/models`; if the endpoint is missing (404/405), fall back to manual model IDs instead of skipping Anthropic entirely.
|
|
309
|
+
- When every endpoint fails and at least one returned 401/403, the plugin asks for the key again. When every endpoint returns an empty list, it skips the endpoint picker and goes straight to manual input.
|
|
310
|
+
- `/cliproxy refresh` silently keeps the cache when the Anthropic endpoint has no model list; it does not persist a refresh error in that case.
|
|
305
311
|
|
|
306
312
|
### 1.1.0
|
|
307
313
|
|
|
308
|
-
-
|
|
309
|
-
- `cliproxy.json`
|
|
310
|
-
-
|
|
311
|
-
-
|
|
312
|
-
-
|
|
314
|
+
- On 401/403 during login, prompt for the key again instead of incorrectly entering the endpoint picker; if the second attempt fails, abort without saving the config.
|
|
315
|
+
- `cliproxy.json` now stores complete model metadata (reasoning / input / cost / contextWindow / maxTokens) and keeps a `.bak` backup.
|
|
316
|
+
- Model refresh now has a 5-minute TTL; `/cliproxy refresh` still forces a refresh.
|
|
317
|
+
- Capability metadata now also comes from `models-store.json` and pi's built-in catalog, so upgrading from an older config does not lose information.
|
|
318
|
+
- Refresh failures persist `lastError` to the config, so `/cliproxy` can show the last error after a restart.
|
|
313
319
|
|
|
314
320
|
---
|
|
315
321
|
|
|
316
|
-
##
|
|
322
|
+
## Development and debugging
|
|
317
323
|
|
|
318
324
|
```powershell
|
|
319
|
-
#
|
|
325
|
+
# Load a local file temporarily (does not write settings)
|
|
320
326
|
pi --extension F:\Desktop\pi-cliproxyapi-autoconnect\index.ts
|
|
321
327
|
|
|
322
|
-
#
|
|
328
|
+
# List models only
|
|
323
329
|
pi --list-models
|
|
324
330
|
```
|
|
325
331
|
|
|
326
|
-
|
|
332
|
+
The plugin only depends on pi's host-provided peer packages and has no third-party runtime dependencies:
|
|
327
333
|
|
|
328
334
|
- `@earendil-works/pi-ai`
|
|
329
335
|
- `@earendil-works/pi-coding-agent`
|
|
330
336
|
|
|
331
|
-
|
|
337
|
+
The core implementation is in `index.ts`:
|
|
332
338
|
|
|
333
|
-
- `runLogin()
|
|
334
|
-
- `refreshProviderModels()
|
|
335
|
-
- `buildProvider()
|
|
339
|
+
- `runLogin()`: domain + key + model discovery + fallback;
|
|
340
|
+
- `refreshProviderModels()`: dynamic refresh on startup, `/model` and `/cliproxy refresh`;
|
|
341
|
+
- `buildProvider()`: registers the native pi-ai provider (`apiKey.login` makes it appear in `/login`).
|
|
336
342
|
|
|
337
|
-
CLIProxyAPI
|
|
343
|
+
CLIProxyAPI reference: <https://github.com/router-for-me/CLIProxyAPI>
|
package/index.ts
CHANGED
|
@@ -638,7 +638,7 @@ async function fetchOpenAIModels(baseUrl: string, apiKey: string, signal: AbortS
|
|
|
638
638
|
headers: {
|
|
639
639
|
Accept: "application/json",
|
|
640
640
|
Authorization: `Bearer ${apiKey}`,
|
|
641
|
-
"User-Agent": "pi-cliproxyapi-autoconnect/1.2.
|
|
641
|
+
"User-Agent": "pi-cliproxyapi-autoconnect/1.2.2",
|
|
642
642
|
},
|
|
643
643
|
signal: requestSignal,
|
|
644
644
|
});
|
|
@@ -662,7 +662,7 @@ async function fetchGeminiModels(baseUrl: string, apiKey: string, signal: AbortS
|
|
|
662
662
|
const { signal: requestSignal, cleanup } = abortSignalWithTimeout(signal, REQUEST_TIMEOUT_MS);
|
|
663
663
|
try {
|
|
664
664
|
const response = await fetch(url, {
|
|
665
|
-
headers: { Accept: "application/json", "User-Agent": "pi-cliproxyapi-autoconnect/1.2.
|
|
665
|
+
headers: { Accept: "application/json", "User-Agent": "pi-cliproxyapi-autoconnect/1.2.2" },
|
|
666
666
|
signal: requestSignal,
|
|
667
667
|
});
|
|
668
668
|
if (!response.ok) {
|
|
@@ -703,7 +703,7 @@ async function fetchAnthropicModels(baseUrl: string, apiKey: string, signal: Abo
|
|
|
703
703
|
// Anthropic's x-api-key header; sending both is harmless upstream.
|
|
704
704
|
Authorization: `Bearer ${apiKey}`,
|
|
705
705
|
"anthropic-version": "2023-06-01",
|
|
706
|
-
"User-Agent": "pi-cliproxyapi-autoconnect/1.2.
|
|
706
|
+
"User-Agent": "pi-cliproxyapi-autoconnect/1.2.2",
|
|
707
707
|
},
|
|
708
708
|
signal: requestSignal,
|
|
709
709
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-cliproxyapi-autoconnect",
|
|
3
|
-
"version": "1.2.
|
|
4
|
-
"description": "CLIProxyAPI
|
|
3
|
+
"version": "1.2.2",
|
|
4
|
+
"description": "CLIProxyAPI auto-connect provider for pi: sign in with a bound domain and API key, automatically discover OpenAI/Gemini/Anthropic-compatible endpoints, and register models in /model.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"engines": {
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
"cliproxyapi",
|
|
15
15
|
"autoconnect",
|
|
16
16
|
"autodiscover",
|
|
17
|
+
"model-discovery",
|
|
18
|
+
"provider",
|
|
17
19
|
"openai-compatible"
|
|
18
20
|
],
|
|
19
21
|
"pi": {
|