@plurnk/plurnk-providers 1.10.0 → 1.11.0
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/.env.defaults +2 -0
- package/SPEC.md +18 -2
- package/dist/AiSdkProvider.d.ts +1 -1
- package/dist/AiSdkProvider.d.ts.map +1 -1
- package/dist/AiSdkProvider.js +18 -1
- package/dist/AiSdkProvider.js.map +1 -1
- package/dist/aiSdkTransport.d.ts +1 -0
- package/dist/aiSdkTransport.d.ts.map +1 -1
- package/dist/aiSdkTransport.js +40 -11
- package/dist/aiSdkTransport.js.map +1 -1
- package/dist/catalogProvider.d.ts.map +1 -1
- package/dist/catalogProvider.js +7 -3
- package/dist/catalogProvider.js.map +1 -1
- package/dist/notices.d.ts +1 -1
- package/dist/notices.d.ts.map +1 -1
- package/dist/sdkModels.d.ts +2 -2
- package/dist/sdkModels.d.ts.map +1 -1
- package/dist/sdkModels.js +9 -2
- package/dist/sdkModels.js.map +1 -1
- package/package.json +6 -6
- package/src/AiSdkProvider.test.ts +21 -4
- package/src/AiSdkProvider.ts +18 -1
- package/src/ProviderRegistry.test.ts +6 -5
- package/src/aiSdkTransport.test.ts +41 -1
- package/src/aiSdkTransport.ts +38 -9
- package/src/catalogProvider.test.ts +92 -0
- package/src/catalogProvider.ts +6 -3
- package/src/discover.test.ts +1 -1
- package/src/notices.ts +1 -1
- package/src/sdkModels.test.ts +16 -0
- package/src/sdkModels.ts +14 -2
package/src/catalogProvider.ts
CHANGED
|
@@ -32,7 +32,7 @@ const reasoningStyleFromEnv = (
|
|
|
32
32
|
if (value === undefined || value.length === 0) return undefined;
|
|
33
33
|
const styles: readonly ReasoningStyle[] = [
|
|
34
34
|
"none", "think", "include_reasoning", "effort",
|
|
35
|
-
"effort_explicit", "thinking_effort", "template", "anthropic",
|
|
35
|
+
"effort_explicit", "effort_required", "thinking_effort", "template", "anthropic",
|
|
36
36
|
];
|
|
37
37
|
if (!styles.includes(value as ReasoningStyle)) {
|
|
38
38
|
throw new Error(`${name} provider: PLURNK_PROVIDERS_PROVIDER_${prefix}_REASONING_STYLE has invalid value "${value}"`);
|
|
@@ -89,6 +89,7 @@ const supportedReasoningPolicies = ({
|
|
|
89
89
|
return REASONING_POLICIES;
|
|
90
90
|
}
|
|
91
91
|
if (style === "effort" || style === "effort_explicit") return REASONING_POLICIES;
|
|
92
|
+
if (style === "effort_required") return reasoningWithoutOff;
|
|
92
93
|
if (style === "thinking_effort") return deepSeekPolicies;
|
|
93
94
|
return activationPolicies;
|
|
94
95
|
};
|
|
@@ -189,8 +190,10 @@ export const providerFromSdkModel = ({
|
|
|
189
190
|
maxOutputTokens,
|
|
190
191
|
);
|
|
191
192
|
const reasoning = reasoningFromEnv(env, name, envelope.reasoningBudget);
|
|
192
|
-
const reasoningStyle = reasoningStyleFromEnv(env, name) ?? "none";
|
|
193
193
|
const reasoningCapable = info?.reasoning === true;
|
|
194
|
+
const reasoningStyle = info?.reasoning === false
|
|
195
|
+
? "none"
|
|
196
|
+
: reasoningStyleFromEnv(env, name) ?? "none";
|
|
194
197
|
const adaptiveReasoning = adaptiveReasoningProjection({
|
|
195
198
|
sdkPackage,
|
|
196
199
|
model,
|
|
@@ -285,7 +288,7 @@ export const catalogProviderFromEnv = (
|
|
|
285
288
|
);
|
|
286
289
|
}
|
|
287
290
|
const wireModel = resolved?.id ?? model;
|
|
288
|
-
const sdk = createSdkModel(name, wireModel, env, baseUrlOverride);
|
|
291
|
+
const sdk = createSdkModel(name, wireModel, env, baseUrlOverride, reasoningFromEnv(env, name).mode);
|
|
289
292
|
if (sdk === null) return null;
|
|
290
293
|
|
|
291
294
|
const info = resolved?.info;
|
package/src/discover.test.ts
CHANGED
|
@@ -30,7 +30,7 @@ test("discover: the node_modules scan is scope-agnostic — third-party scopes a
|
|
|
30
30
|
"@acme/acme-provider-foo": { name: "@acme/acme-provider-foo", plurnk: { kind: "provider", name: "foo" } },
|
|
31
31
|
"unscoped-provider-bar": { name: "unscoped-provider-bar", plurnk: { kind: "provider", name: "bar" } },
|
|
32
32
|
"left-pad": { name: "left-pad" }, // no plurnk block → ignored
|
|
33
|
-
"@
|
|
33
|
+
"@acme/acme-execs-wrong-kind": { name: "@acme/acme-execs-wrong-kind", plurnk: { kind: "exec", runtimes: [] } }, // wrong kind → ignored
|
|
34
34
|
});
|
|
35
35
|
const { registry } = await discover({ cwd: root });
|
|
36
36
|
assert.deepEqual([...registry.keys()].sort(), ["bar", "foo", "native"]);
|
package/src/notices.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type ProviderNoticeKind = "grammar_unenforced" | "provider_warning";
|
|
1
|
+
export type ProviderNoticeKind = "grammar_unenforced" | "provider_warning" | "provider_retry";
|
|
2
2
|
|
|
3
3
|
// Observations about a completed model exchange. These never represent a
|
|
4
4
|
// failed provider operation; transport failures throw ProviderError with an
|
package/src/sdkModels.test.ts
CHANGED
|
@@ -123,6 +123,22 @@ test("createSdkModel constructs Cerebras from Models.dev facts", () => {
|
|
|
123
123
|
assert.equal(sdk?.compatible, undefined);
|
|
124
124
|
});
|
|
125
125
|
|
|
126
|
+
test("{§provider-reasoning-policy} createSdkModel represents a fixed OpenRouter policy in the model settings", () => {
|
|
127
|
+
const env = {
|
|
128
|
+
OPENROUTER_API_KEY: "test-key",
|
|
129
|
+
OPENROUTER_HTTP_REFERER: "https://github.com/plurnk/plurnk-service",
|
|
130
|
+
OPENROUTER_APP_TITLE: "Plurnk",
|
|
131
|
+
};
|
|
132
|
+
const settings = (reasoning?: "off" | "adaptive" | "low" | "medium" | "high"): unknown =>
|
|
133
|
+
(createSdkModel("openrouter", "z-ai/glm-5.3-flash", env, undefined, reasoning)?.languageModel as { settings?: { reasoning?: unknown } } | undefined)?.settings?.reasoning;
|
|
134
|
+
assert.deepEqual(settings("low"), { effort: "low" });
|
|
135
|
+
assert.deepEqual(settings("medium"), { effort: "medium" });
|
|
136
|
+
assert.deepEqual(settings("high"), { effort: "high" });
|
|
137
|
+
assert.deepEqual(settings("off"), { effort: "none" });
|
|
138
|
+
assert.equal(settings("adaptive"), undefined);
|
|
139
|
+
assert.equal(settings(), undefined);
|
|
140
|
+
});
|
|
141
|
+
|
|
126
142
|
test("{§openrouter-app-attribution} attribution rejects malformed URLs and the retired title name", () => {
|
|
127
143
|
assert.throws(
|
|
128
144
|
() => createSdkModel("openrouter", "openai/gpt-5", {
|
package/src/sdkModels.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
providerCatalogSnapshot,
|
|
16
16
|
type ProviderInfo,
|
|
17
17
|
} from "@plurnk/plurnk-models";
|
|
18
|
-
import { Validator, type ModelReadiness, type ModelReadinessCause } from "@plurnk/plurnk-contracts";
|
|
18
|
+
import { Validator, type ModelReadiness, type ModelReadinessCause, type ReasoningPolicy } from "@plurnk/plurnk-contracts";
|
|
19
19
|
import type { LanguageModel } from "ai";
|
|
20
20
|
import { providerCostNormalizer } from "./accounting.ts";
|
|
21
21
|
import type { AiSdkProviderOptions, CacheAffinity } from "./AiSdkProvider.ts";
|
|
@@ -286,11 +286,23 @@ const requireApiKey = (
|
|
|
286
286
|
return key;
|
|
287
287
|
};
|
|
288
288
|
|
|
289
|
+
// {§provider-reasoning-policy} — the OpenRouter SDK builds its request from the model
|
|
290
|
+
// settings alone (neither the generic `reasoning` call setting nor provider options reach
|
|
291
|
+
// its body), so a fixed policy and `off` are represented there; `adaptive` leaves the
|
|
292
|
+
// route's provider default.
|
|
293
|
+
const openRouterReasoningSettings = (
|
|
294
|
+
reasoning: ReasoningPolicy | undefined,
|
|
295
|
+
): { reasoning?: { effort: "none" | "low" | "medium" | "high" } } =>
|
|
296
|
+
reasoning === undefined || reasoning === "adaptive"
|
|
297
|
+
? {}
|
|
298
|
+
: { reasoning: { effort: reasoning === "off" ? "none" : reasoning } };
|
|
299
|
+
|
|
289
300
|
export const createSdkModel = (
|
|
290
301
|
provider: string,
|
|
291
302
|
model: string,
|
|
292
303
|
env: NodeJS.ProcessEnv,
|
|
293
304
|
baseUrlOverride?: string,
|
|
305
|
+
reasoning?: ReasoningPolicy,
|
|
294
306
|
): SdkModel | null => {
|
|
295
307
|
const catalog = lookupProvider(provider) ?? configuredProviderInfo(provider, env);
|
|
296
308
|
if (catalog === null) return null;
|
|
@@ -386,7 +398,7 @@ export const createSdkModel = (
|
|
|
386
398
|
apiKey: requireApiKey(provider, env, catalog),
|
|
387
399
|
baseURL: url,
|
|
388
400
|
headers: openRouterHeaders(provider, env, catalog),
|
|
389
|
-
}).languageModel(model),
|
|
401
|
+
}).languageModel(model, openRouterReasoningSettings(reasoning)),
|
|
390
402
|
...(catalog.id === "openrouter"
|
|
391
403
|
? { cacheAffinity: { target: "header" as const, name: "x-session-id" } }
|
|
392
404
|
: {}),
|