@pwguler/pi-pengepul-provider 0.5.1 → 0.5.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 +5 -0
- package/extensions/credential.ts +28 -0
- package/extensions/provider.ts +14 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -141,6 +141,11 @@ box:
|
|
|
141
141
|
}
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
+
`env` is read off the credential by this provider, not by pi core: a provider
|
|
145
|
+
that brings its own `resolve()` has to hand the values back, and pengepul does.
|
|
146
|
+
Re-add them after `/login pengepul` — pi replaces the whole credential on login,
|
|
147
|
+
so a key rotation drops the block and, with it, the tier.
|
|
148
|
+
|
|
144
149
|
Idle warming covers gaps up to 30 minutes, pi's own safety limit, and pi only
|
|
145
150
|
triggers it when the expected saving clears a threshold of its own — a small
|
|
146
151
|
prompt is left to expire rather than refreshed. The long tier is what carries a
|
package/extensions/credential.ts
CHANGED
|
@@ -20,6 +20,8 @@ export interface PengepulCredential {
|
|
|
20
20
|
type?: unknown
|
|
21
21
|
key?: unknown
|
|
22
22
|
baseUrl?: unknown
|
|
23
|
+
/** Provider-scoped environment values pi stores alongside the key. */
|
|
24
|
+
env?: unknown
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
function nonEmptyString(value: unknown): string | undefined {
|
|
@@ -38,6 +40,32 @@ export function credentialApiKey(credential: PengepulCredential | undefined): st
|
|
|
38
40
|
return nonEmptyString(credential?.key)
|
|
39
41
|
}
|
|
40
42
|
|
|
43
|
+
/**
|
|
44
|
+
* The provider-scoped environment the credential carries, when it holds any.
|
|
45
|
+
*
|
|
46
|
+
* pi core fills an `AuthResult.env` from here only for providers that bring no
|
|
47
|
+
* `resolve()` of their own; this provider brings one, so the values have to be
|
|
48
|
+
* passed through or they never reach a request. They are how a user sets
|
|
49
|
+
* `PI_CACHE_RETENTION=long` for the relay without exporting it in every shell
|
|
50
|
+
* that starts pi, and losing them is silent: the cache quietly falls back to
|
|
51
|
+
* the five-minute tier and re-bills whole prefixes.
|
|
52
|
+
*
|
|
53
|
+
* Non-string values are dropped rather than stringified — an env var is a
|
|
54
|
+
* string, and a nested object here is a typo, not a value.
|
|
55
|
+
*/
|
|
56
|
+
export function credentialEnv(
|
|
57
|
+
credential: PengepulCredential | undefined,
|
|
58
|
+
): Record<string, string> | undefined {
|
|
59
|
+
const raw = credential?.env
|
|
60
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return undefined
|
|
61
|
+
|
|
62
|
+
const env: Record<string, string> = {}
|
|
63
|
+
for (const [name, value] of Object.entries(raw)) {
|
|
64
|
+
if (typeof value === "string") env[name] = value
|
|
65
|
+
}
|
|
66
|
+
return Object.keys(env).length > 0 ? env : undefined
|
|
67
|
+
}
|
|
68
|
+
|
|
41
69
|
export interface RelayBaseSources {
|
|
42
70
|
/** The `PENGEPUL_BASE_URL` environment value. */
|
|
43
71
|
environment?: string | undefined
|
package/extensions/provider.ts
CHANGED
|
@@ -30,6 +30,7 @@ import { anthropicMessagesApi, lazyStream, openAICompletionsApi } from "@earendi
|
|
|
30
30
|
import { API_KEY_ENV, RELAY_BASE_ENV } from "./config.ts"
|
|
31
31
|
import {
|
|
32
32
|
credentialApiKey,
|
|
33
|
+
credentialEnv,
|
|
33
34
|
credentialRelayBase,
|
|
34
35
|
resolveApiKey,
|
|
35
36
|
resolveRelayBase,
|
|
@@ -211,9 +212,21 @@ export function createPengepulProvider(options: PengepulProviderOptions): Provid
|
|
|
211
212
|
resolve: async (input): Promise<AuthResult | undefined> => {
|
|
212
213
|
const resolved = resolveKey(input.credential)
|
|
213
214
|
if (!resolved) return undefined
|
|
215
|
+
const env = credentialEnv(input.credential as PengepulCredential | undefined)
|
|
214
216
|
// No `baseUrl` here on purpose: pi would apply it to every model and
|
|
215
217
|
// collapse the two dialect base URLs into one.
|
|
216
|
-
|
|
218
|
+
//
|
|
219
|
+
// `env` is here because pi only reads it off the credential itself
|
|
220
|
+
// when the provider brings no `resolve()` of its own — this one does,
|
|
221
|
+
// so a value like PI_CACHE_RETENTION=long is dropped unless it is
|
|
222
|
+
// handed back. Dropping it is silent and costs money: the cache falls
|
|
223
|
+
// back to the five-minute tier and re-bills the prefix on every
|
|
224
|
+
// return.
|
|
225
|
+
return {
|
|
226
|
+
auth: { apiKey: resolved.key },
|
|
227
|
+
...(env ? { env } : {}),
|
|
228
|
+
source: resolved.source,
|
|
229
|
+
}
|
|
217
230
|
},
|
|
218
231
|
},
|
|
219
232
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pwguler/pi-pengepul-provider",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "pi custom provider for pengepul, a relay that pools your Claude/Codex subscriptions. Key and relay base live in auth.json; both native wires (Anthropic Messages, OpenAI Chat Completions) come from one catalog.",
|
|
6
6
|
"license": "MIT",
|