pi-zengate-models 1.0.1 → 1.0.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/CHANGELOG.md +16 -0
- package/README.md +34 -4
- package/extensions/zengate-models.ts +35 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.2] - 2026-11-04
|
|
4
|
+
|
|
5
|
+
- Read `baseUrl` and `apiKey` from the `opencode2api` provider in
|
|
6
|
+
`<agent-dir>/models.json` when the environment and `zengate.json` are empty.
|
|
7
|
+
A machine the gateway sync already prepared needs no second copy, and the
|
|
8
|
+
session warning stops for those machines.
|
|
9
|
+
- Name all three sources in that warning.
|
|
10
|
+
- Pin the install lines to `1.0.2`.
|
|
11
|
+
|
|
12
|
+
## [Unreleased]
|
|
13
|
+
|
|
14
|
+
- Add `scripts/setup.ps1` and `scripts/setup.sh`. They ask for the gateway URL
|
|
15
|
+
and key, write `<agent-dir>/zengate.json` without a BOM, and move a stale
|
|
16
|
+
`models.json` that holds only the static provider.
|
|
17
|
+
- Document the text-editor route for a machine without an agent.
|
|
18
|
+
|
|
3
19
|
## [1.0.1] - 2026-11-04
|
|
4
20
|
|
|
5
21
|
- Remove the built-in gateway URL. Every machine sets `OPENCODE2API_BASE_URL`
|
package/README.md
CHANGED
|
@@ -22,16 +22,19 @@ This package ships no endpoint and no key. Each machine supplies both.
|
|
|
22
22
|
## Install
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
pi install npm:pi-zengate-models
|
|
25
|
+
pi install npm:pi-zengate-models@1.0.2
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
From git, or from a local checkout:
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
pi install git:github.com/ham-zax/pi-zengate@v1.0.
|
|
31
|
+
pi install git:github.com/ham-zax/pi-zengate@v1.0.2
|
|
32
32
|
pi install /path/to/pi-zengate
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
Pin the npm version. An older `0.0.0-stage` publish still holds the `latest` tag
|
|
36
|
+
until it is removed, and that version has no extension.
|
|
37
|
+
|
|
35
38
|
## Configure
|
|
36
39
|
|
|
37
40
|
Every machine needs its own gateway URL and key. Set them in the environment:
|
|
@@ -53,8 +56,35 @@ or in `<agent-dir>/zengate.json`, which avoids environment variables:
|
|
|
53
56
|
```
|
|
54
57
|
|
|
55
58
|
`<agent-dir>` is `~/.pi/agent` by default, or `PI_CODING_AGENT_DIR` when set.
|
|
56
|
-
The
|
|
57
|
-
|
|
59
|
+
The extension also reads `providers.opencode2api.baseUrl` and `.apiKey` from
|
|
60
|
+
`<agent-dir>/models.json`, so a machine the gateway sync prepared needs no second
|
|
61
|
+
copy. Precedence is environment, then `zengate.json`, then `models.json`. Without
|
|
62
|
+
any URL the extension registers no provider and warns once per session.
|
|
63
|
+
|
|
64
|
+
## Setup helpers
|
|
65
|
+
|
|
66
|
+
The fastest manual way is a text editor. On Windows:
|
|
67
|
+
|
|
68
|
+
```powershell
|
|
69
|
+
notepad "$env:USERPROFILE\.pi\agent\zengate.json"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Paste the two fields, save, restart Pi. On Linux, macOS or WSL create
|
|
73
|
+
`~/.pi/agent/zengate.json` the same way.
|
|
74
|
+
|
|
75
|
+
Two scripts ask for the URL and the key and then write the file, so neither
|
|
76
|
+
script contains a secret:
|
|
77
|
+
|
|
78
|
+
```powershell
|
|
79
|
+
iex (irm "<raw URL of scripts/setup.ps1>") # Windows
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
curl -fsSL "<raw URL of scripts/setup.sh>" | bash # Linux, macOS, WSL
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Both scripts write the file with mode `0600` and print the model count. A
|
|
87
|
+
`models.json` that holds only `opencode2api` moves to `models.json.disabled`.
|
|
58
88
|
|
|
59
89
|
## Verify
|
|
60
90
|
|
|
@@ -147,6 +147,10 @@ export function configPath(): string {
|
|
|
147
147
|
return join(agentDir(), "zengate.json");
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
export function modelsConfigPath(): string {
|
|
151
|
+
return join(agentDir(), "models.json");
|
|
152
|
+
}
|
|
153
|
+
|
|
150
154
|
export function cachePath(): string {
|
|
151
155
|
return join(agentDir(), "cache", "zengate-models.json");
|
|
152
156
|
}
|
|
@@ -165,25 +169,49 @@ function normalizeBaseUrl(value: string): string {
|
|
|
165
169
|
}
|
|
166
170
|
|
|
167
171
|
/**
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
|
|
172
|
+
* A machine prepared by the gateway sync already holds the endpoint and the key
|
|
173
|
+
* in models.json. Read them so the client needs no second copy of either.
|
|
174
|
+
*/
|
|
175
|
+
function gatewayFromModelsConfig(): { baseUrl?: string; apiKey?: string } {
|
|
176
|
+
const file = readJson(modelsConfigPath()) ?? {};
|
|
177
|
+
const providers = file.providers;
|
|
178
|
+
const provider =
|
|
179
|
+
providers && typeof providers === "object"
|
|
180
|
+
? (providers as Record<string, unknown>)[PROVIDER_ID]
|
|
181
|
+
: undefined;
|
|
182
|
+
if (!provider || typeof provider !== "object") return {};
|
|
183
|
+
const record = provider as Record<string, unknown>;
|
|
184
|
+
const baseUrl =
|
|
185
|
+
typeof record.baseUrl === "string" && record.baseUrl.trim() ? record.baseUrl : undefined;
|
|
186
|
+
const apiKey =
|
|
187
|
+
typeof record.apiKey === "string" && record.apiKey.trim() ? record.apiKey.trim() : undefined;
|
|
188
|
+
return { baseUrl, apiKey };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Settings precedence: environment, then <agent-dir>/zengate.json, then the
|
|
193
|
+
* `opencode2api` provider in <agent-dir>/models.json. The last source means a
|
|
194
|
+
* machine the gateway sync already prepared needs no extra file. This package
|
|
195
|
+
* ships no endpoint: every machine supplies its own.
|
|
171
196
|
*/
|
|
172
197
|
export function readSettings(): { baseUrl?: string; apiKey?: string; keySource: string } {
|
|
173
198
|
const file = readJson(configPath()) ?? {};
|
|
174
199
|
const fileBase = typeof file.baseUrl === "string" && file.baseUrl.trim() ? file.baseUrl : undefined;
|
|
175
200
|
const fileKey = typeof file.apiKey === "string" && file.apiKey.trim() ? file.apiKey.trim() : undefined;
|
|
201
|
+
const synced = gatewayFromModelsConfig();
|
|
176
202
|
const envBase = process.env[BASE_URL_ENV];
|
|
177
203
|
const envKey = process.env[KEY_ENV]?.trim();
|
|
178
|
-
const base = envBase || fileBase;
|
|
204
|
+
const base = envBase || fileBase || synced.baseUrl;
|
|
179
205
|
return {
|
|
180
206
|
baseUrl: base ? normalizeBaseUrl(base) : undefined,
|
|
181
|
-
apiKey: envKey || fileKey,
|
|
182
|
-
keySource: envKey ? KEY_ENV : fileKey ? "zengate.json" : "none",
|
|
207
|
+
apiKey: envKey || fileKey || synced.apiKey,
|
|
208
|
+
keySource: envKey ? KEY_ENV : fileKey ? "zengate.json" : synced.apiKey ? "models.json" : "none",
|
|
183
209
|
};
|
|
184
210
|
}
|
|
185
211
|
|
|
186
|
-
const configureHint = (): string =>
|
|
212
|
+
const configureHint = (): string =>
|
|
213
|
+
`No gateway endpoint found. Set ${BASE_URL_ENV}, baseUrl in ${configPath()}, ` +
|
|
214
|
+
`or providers.${PROVIDER_ID}.baseUrl in ${modelsConfigPath()}.`;
|
|
187
215
|
|
|
188
216
|
export default async function (pi: ExtensionAPI) {
|
|
189
217
|
const settings = readSettings();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-zengate-models",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Pi provider extension that discovers free models and their metadata from an OpenAI-compatible gateway catalog, with a local cache and no scheduler.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|