@pwguler/pi-pengepul-provider 0.5.2 → 0.5.3

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.
@@ -10,7 +10,7 @@
10
10
  * override, then the credential, then the loopback default pengepul binds to.
11
11
  */
12
12
 
13
- import { API_KEY_ENV } from "./config.ts"
13
+ import { API_KEY_ENV, RELAY_BASE_ENV } from "./config.ts"
14
14
  import { normalizeRootBaseUrl } from "./dialect.ts"
15
15
  import { DEFAULT_RELAY_BASE } from "./models.ts"
16
16
 
@@ -30,9 +30,18 @@ function nonEmptyString(value: unknown): string | undefined {
30
30
  return trimmed === "" ? undefined : trimmed
31
31
  }
32
32
 
33
- /** The relay base stored on the credential, when the user set one. */
33
+ /**
34
+ * The relay base stored on the credential, when the user set one.
35
+ *
36
+ * `baseUrl` is where the stored credential keeps it. The credential pi hands
37
+ * the network phase of a refresh is not the stored one: pi rebuilds it from
38
+ * `resolve()` as `{ type, key, env }`, so the base only survives as the
39
+ * `PENGEPUL_BASE_URL` entry `resolve()` writes into `env`. Missing that
40
+ * fallback sends the catalog fetch to loopback - which on any machine but the
41
+ * relay's is some other listener, or nothing.
42
+ */
34
43
  export function credentialRelayBase(credential: PengepulCredential | undefined): string | undefined {
35
- return nonEmptyString(credential?.baseUrl)
44
+ return nonEmptyString(credential?.baseUrl) ?? credentialEnv(credential)?.[RELAY_BASE_ENV]
36
45
  }
37
46
 
38
47
  /** The API key stored on the credential, when the user set one. */
@@ -212,11 +212,20 @@ export function createPengepulProvider(options: PengepulProviderOptions): Provid
212
212
  resolve: async (input): Promise<AuthResult | undefined> => {
213
213
  const resolved = resolveKey(input.credential)
214
214
  if (!resolved) return undefined
215
- const env = credentialEnv(input.credential as PengepulCredential | undefined)
215
+ const credential = input.credential as PengepulCredential | undefined
216
+ const relayBase = credentialRelayBase(credential)
217
+ const credentialVars = credentialEnv(credential)
218
+ const env =
219
+ credentialVars || relayBase
220
+ ? { ...credentialVars, ...(relayBase ? { [RELAY_BASE_ENV]: relayBase } : {}) }
221
+ : undefined
216
222
  // No `baseUrl` here on purpose: pi would apply it to every model and
217
- // collapse the two dialect base URLs into one.
223
+ // collapse the two dialect base URLs into one. The relay base rides
224
+ // in `env` instead, because the network phase of a refresh gets a
225
+ // credential pi rebuilds from this result, and `env` is the only
226
+ // field of ours that survives the rebuild.
218
227
  //
219
- // `env` is here because pi only reads it off the credential itself
228
+ // The credential's own `env` is here because pi only reads it off the credential itself
220
229
  // when the provider brings no `resolve()` of its own — this one does,
221
230
  // so a value like PI_CACHE_RETENTION=long is dropped unless it is
222
231
  // handed back. Dropping it is silent and costs money: the cache falls
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pwguler/pi-pengepul-provider",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
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",