@pwguler/pi-pengepul-provider 0.2.0 → 0.2.1
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/extensions/models.ts +33 -7
- package/package.json +1 -1
package/extensions/models.ts
CHANGED
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
*
|
|
10
10
|
* The relay advertises id/owned_by and, since pengepul 0.6.0, optional
|
|
11
11
|
* per-model metadata: `context_window`, `max_output_tokens`,
|
|
12
|
-
* `input_modalities`, and `
|
|
13
|
-
* this relay actually serves, so it wins. The rollout is
|
|
12
|
+
* `input_modalities`, `pricing`, and `reasoning`. That is the first-party
|
|
13
|
+
* truth for what this relay actually serves, so it wins. The rollout is
|
|
14
|
+
* partial (some ids
|
|
14
15
|
* still come back with ids only), so two fallbacks remain: pi's builtin
|
|
15
16
|
* catalog - pengepul forwards the same ids upstream, so pi's numbers are the
|
|
16
17
|
* next best source - and then family heuristics. The catalog lookup is
|
|
@@ -32,8 +33,8 @@ export const DEFAULT_MODELS_TIMEOUT_MS = 10_000
|
|
|
32
33
|
const DEFAULT_CONTEXT_WINDOW = 200_000
|
|
33
34
|
const DEFAULT_MAX_TOKENS = 64_000
|
|
34
35
|
const ZERO_COST: ModelCostRates = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }
|
|
35
|
-
/**
|
|
36
|
-
const MODEL_CACHE_VERSION =
|
|
36
|
+
/** v5 cached entries predate the relay-uniform off/minimal overlay (foreign catalog maps offered levels the relay 400s); reject it. */
|
|
37
|
+
const MODEL_CACHE_VERSION = 6
|
|
37
38
|
|
|
38
39
|
export type ModelInput = ("text" | "image")[]
|
|
39
40
|
|
|
@@ -74,7 +75,7 @@ export interface PengepulModel {
|
|
|
74
75
|
cost: ModelCostRates
|
|
75
76
|
contextWindow: number
|
|
76
77
|
maxTokens: number
|
|
77
|
-
/** Level-to-wire mapping inherited
|
|
78
|
+
/** Level-to-wire mapping (inherited, relay-unsafe levels nulled); undefined = pi's default. */
|
|
78
79
|
thinkingLevelMap?: Record<string, string | null>
|
|
79
80
|
}
|
|
80
81
|
|
|
@@ -117,6 +118,8 @@ function heuristicMeta(id: string): BuiltinModelMeta {
|
|
|
117
118
|
/**
|
|
118
119
|
* Metadata pengepul itself advertises for a model (pengepul >= 0.6.0).
|
|
119
120
|
* Every field is optional: the rollout is partial and older relays send none.
|
|
121
|
+
* `reasoning` is the relay's first-party say on whether the upstream accepts
|
|
122
|
+
* reasoning params; absent or non-boolean falls back to the catalog.
|
|
120
123
|
* Returns undefined when the entry carries no usable metadata at all.
|
|
121
124
|
*/
|
|
122
125
|
export function metaFromRelayEntry(
|
|
@@ -126,16 +129,19 @@ export function metaFromRelayEntry(
|
|
|
126
129
|
const maxTokens = optionalPositiveNumber(entry["max_output_tokens"])
|
|
127
130
|
const input = optionalInputModalities(entry["input_modalities"])
|
|
128
131
|
const cost = optionalPricing(entry["pricing"])
|
|
132
|
+
const reasoning = optionalBoolean(entry["reasoning"])
|
|
129
133
|
|
|
130
134
|
if (
|
|
131
135
|
contextWindow === undefined &&
|
|
132
136
|
maxTokens === undefined &&
|
|
133
137
|
input === undefined &&
|
|
134
|
-
cost === undefined
|
|
138
|
+
cost === undefined &&
|
|
139
|
+
reasoning === undefined
|
|
135
140
|
) {
|
|
136
141
|
return undefined
|
|
137
142
|
}
|
|
138
143
|
return {
|
|
144
|
+
...(reasoning !== undefined ? { reasoning } : {}),
|
|
139
145
|
...(contextWindow !== undefined ? { contextWindow } : {}),
|
|
140
146
|
...(maxTokens !== undefined ? { maxTokens } : {}),
|
|
141
147
|
...(input !== undefined ? { input } : {}),
|
|
@@ -147,6 +153,10 @@ function optionalPositiveNumber(value: unknown): number | undefined {
|
|
|
147
153
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : undefined
|
|
148
154
|
}
|
|
149
155
|
|
|
156
|
+
function optionalBoolean(value: unknown): boolean | undefined {
|
|
157
|
+
return typeof value === "boolean" ? value : undefined
|
|
158
|
+
}
|
|
159
|
+
|
|
150
160
|
function optionalInputModalities(value: unknown): ModelInput | undefined {
|
|
151
161
|
if (!Array.isArray(value)) return undefined
|
|
152
162
|
const input = value.filter(
|
|
@@ -206,6 +216,22 @@ function toPengepulModel(
|
|
|
206
216
|
// capable, even when pi's catalog does not know its exact id yet.
|
|
207
217
|
const reasoning = meta.reasoning || ownedBy === "anthropic"
|
|
208
218
|
|
|
219
|
+
// The relay enforces reasoning_effort low|medium|high|xhigh|max at its
|
|
220
|
+
// request layer, uniformly across families: `minimal` 400s and its
|
|
221
|
+
// thinking toggle never actually disables thinking. That holds regardless
|
|
222
|
+
// of where the reasoning knowledge came from, so every openai-completions
|
|
223
|
+
// reasoning model gets off/minimal nulled — inherited catalogs were
|
|
224
|
+
// written for other upstreams and do offer the unsafe levels (observed:
|
|
225
|
+
// openrouter muse-spark `minimal: "minimal"`, opencode-go hy4-preview
|
|
226
|
+
// `off: "none"`). Overlay, never replace: inherited strings stay valid on
|
|
227
|
+
// the wire and inherited nulls keep their levels hidden. The Messages
|
|
228
|
+
// dialect needs no overlay: it folds `minimal` into `low` and already
|
|
229
|
+
// nulls `off` via forceAdaptiveThinking.
|
|
230
|
+
let thinkingLevelMap = meta.thinkingLevelMap ? { ...meta.thinkingLevelMap } : undefined
|
|
231
|
+
if (reasoning && dialect === "openai-completions") {
|
|
232
|
+
thinkingLevelMap = { ...(thinkingLevelMap ?? {}), off: null, minimal: null }
|
|
233
|
+
}
|
|
234
|
+
|
|
209
235
|
return {
|
|
210
236
|
id,
|
|
211
237
|
name: displayName(id),
|
|
@@ -215,7 +241,7 @@ function toPengepulModel(
|
|
|
215
241
|
cost: { ...meta.cost },
|
|
216
242
|
contextWindow: meta.contextWindow,
|
|
217
243
|
maxTokens: meta.maxTokens,
|
|
218
|
-
...(
|
|
244
|
+
...(thinkingLevelMap ? { thinkingLevelMap } : {}),
|
|
219
245
|
}
|
|
220
246
|
}
|
|
221
247
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pwguler/pi-pengepul-provider",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "pi custom provider for pengepul, a local relay that pools your Claude/Codex subscriptions. Connects pi to http://127.0.0.1:8317 over the native Anthropic Messages and OpenAI Chat Completions wires.",
|
|
6
6
|
"license": "MIT",
|