@plurnk/plurnk-providers 1.29.0 → 3.0.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.
Files changed (43) hide show
  1. package/.env.defaults +20 -14
  2. package/README.md +8 -8
  3. package/SPEC.md +45 -28
  4. package/dist/AiSdkProvider.d.ts +9 -3
  5. package/dist/AiSdkProvider.d.ts.map +1 -1
  6. package/dist/AiSdkProvider.js +36 -10
  7. package/dist/AiSdkProvider.js.map +1 -1
  8. package/dist/AiSdkRequestBody.d.ts +2 -1
  9. package/dist/AiSdkRequestBody.d.ts.map +1 -1
  10. package/dist/AiSdkRequestBody.js +7 -3
  11. package/dist/AiSdkRequestBody.js.map +1 -1
  12. package/dist/Pool.d.ts +2 -2
  13. package/dist/Pool.d.ts.map +1 -1
  14. package/dist/Pool.js.map +1 -1
  15. package/dist/ProviderRegistry.d.ts.map +1 -1
  16. package/dist/ProviderRegistry.js +3 -3
  17. package/dist/ProviderRegistry.js.map +1 -1
  18. package/dist/RequestFields.d.ts +0 -1
  19. package/dist/RequestFields.d.ts.map +1 -1
  20. package/dist/RequestFields.js +1 -12
  21. package/dist/RequestFields.js.map +1 -1
  22. package/dist/aiSdkTransport.js +2 -2
  23. package/dist/aiSdkTransport.js.map +1 -1
  24. package/dist/catalogProvider.d.ts +5 -4
  25. package/dist/catalogProvider.d.ts.map +1 -1
  26. package/dist/catalogProvider.js +3 -1
  27. package/dist/catalogProvider.js.map +1 -1
  28. package/dist/discover.js.map +1 -1
  29. package/dist/env.d.ts.map +1 -1
  30. package/dist/env.js +6 -49
  31. package/dist/env.js.map +1 -1
  32. package/dist/index.d.ts +2 -2
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +1 -1
  35. package/dist/index.js.map +1 -1
  36. package/dist/notices.d.ts +1 -1
  37. package/dist/sdkModels.d.ts +2 -1
  38. package/dist/sdkModels.d.ts.map +1 -1
  39. package/dist/sdkModels.js +11 -5
  40. package/dist/sdkModels.js.map +1 -1
  41. package/dist/types.d.ts +3 -3
  42. package/dist/types.d.ts.map +1 -1
  43. package/package.json +20 -19
package/.env.defaults CHANGED
@@ -12,6 +12,8 @@
12
12
  # PLURNK_BASEURL_local=http://127.0.0.1:8080/v1
13
13
  # PLURNK_MODEL=cloud
14
14
  # PLURNK_MODEL=deepseek/deepseek-v4-flash
15
+ # Any declared alias's own endpoint, overriding its provider's.
16
+ # PLURNK_BASEURL_<alias>=<url>
15
17
 
16
18
  # --- Capacity ---
17
19
  # Simultaneous inference attempts per resolved endpoint in this process; -1 = unrestricted.
@@ -43,20 +45,20 @@ PLURNK_PROVIDERS_EFFORT_FALLBACK=high
43
45
  PLURNK_PROVIDERS_REASONING_RESPONSE_STYLE=verbatim
44
46
  # Compatible wire declarations below supplement Models.dev; native SDKs own their protocols.
45
47
  # Route knobs use the same suffix, e.g. PLURNK_PROVIDERS_REASONING_BUDGET_PATH_<alias>.
46
- # PLURNK_PROVIDERS_OUTPUT_PATH_<alias>=/max_completion_tokens
47
- # PLURNK_PROVIDERS_REASONING_EFFORT_PATH_<alias>=/reasoning_effort
48
- # PLURNK_PROVIDERS_REASONING_CONTROLS_<alias>=exclusive
49
- # PLURNK_PROVIDERS_REASONING_ON_BODY_<alias>='{"enable_thinking":true}'
50
- # PLURNK_PROVIDERS_REASONING_OFF_BODY_<alias>='{"enable_thinking":false}'
51
- # PLURNK_PROVIDERS_REASONING_EFFORTS_<alias>=low,medium,high
52
- # PLURNK_PROVIDERS_REASONING_TRANSPORT_EFFORTS_<alias>=none,low,medium,high
53
- # PLURNK_PROVIDERS_OPTIONS_NAMESPACE_<alias>=openrouter
54
- # PLURNK_PROVIDERS_REASONING_ADAPTIVE_BODY_<alias>='{}'
55
- # PLURNK_PROVIDERS_REASONING_TOGGLE_BODY_<alias>='{"reasoning":{"enabled":true}}'
56
- # PLURNK_PROVIDERS_ADAPTIVE_OPTIONS_<alias>='[{"models":["*"],"options":{"<sdk-namespace>":{…}}}]'
57
- # PLURNK_PROVIDERS_SYSTEM_CACHE_OPTIONS_<alias>=
58
- # PLURNK_PROVIDERS_APP_URL_<alias>=https://example.test/app
59
- # PLURNK_PROVIDERS_APP_NAME_<alias>=Example
48
+ # PLURNK_PROVIDERS_OUTPUT_PATH=/max_completion_tokens
49
+ # PLURNK_PROVIDERS_REASONING_EFFORT_PATH=/reasoning_effort
50
+ # PLURNK_PROVIDERS_REASONING_CONTROLS=exclusive
51
+ # PLURNK_PROVIDERS_REASONING_ON_BODY='{"enable_thinking":true}'
52
+ # PLURNK_PROVIDERS_REASONING_OFF_BODY='{"enable_thinking":false}'
53
+ # PLURNK_PROVIDERS_REASONING_EFFORTS=low,medium,high
54
+ # PLURNK_PROVIDERS_REASONING_TRANSPORT_EFFORTS=none,low,medium,high
55
+ # PLURNK_PROVIDERS_OPTIONS_NAMESPACE=openrouter
56
+ # PLURNK_PROVIDERS_REASONING_ADAPTIVE_BODY='{}'
57
+ # PLURNK_PROVIDERS_REASONING_TOGGLE_BODY='{"reasoning":{"enabled":true}}'
58
+ # PLURNK_PROVIDERS_ADAPTIVE_OPTIONS='[{"models":["*"],"options":{"<sdk-namespace>":{…}}}]'
59
+ # PLURNK_PROVIDERS_SYSTEM_CACHE_OPTIONS=
60
+ # PLURNK_PROVIDERS_APP_URL=https://example.test/app
61
+ # PLURNK_PROVIDERS_APP_NAME=Example
60
62
 
61
63
  # --- Sampling ---
62
64
  # Temperature; empty = omit, retaining the provider's sampling default.
@@ -97,6 +99,7 @@ PLURNK_PROVIDERS_PROVIDER_FIREWORKS_AI_CACHE_AFFINITY_FIELD='{"target":"header",
97
99
  # off = no explicit writes. This is distinct from affinity and can affect billing.
98
100
  PLURNK_PROVIDERS_CACHE_WRITE_POLICY=stable-system
99
101
  # Provider service tier; unset = provider default. Usually set per alias: routing can change cost.
102
+ # Native routes send it only where the SDK documents one ({§provider-request-controls}); others warn.
100
103
  # PLURNK_PROVIDERS_SERVICE_TIER=
101
104
  # PLURNK_PROVIDERS_SERVICE_TIER_myfireworks=priority
102
105
  # USD per million tokens, merged over Models.dev rates; omitted categories retain catalog values.
@@ -131,6 +134,7 @@ PLURNK_PROVIDERS_PROBE_DELAY=250
131
134
 
132
135
  # --- Evidence capture ---
133
136
  # OpenAI top_logprobs: off/unset = none; 0 = chosen token only; N > 0 = alternatives.
137
+ # Compatible routes and native OpenAI send it; other native routes warn ({§provider-request-controls}).
134
138
  # PLURNK_PROVIDERS_TOP_LOGPROBS=3
135
139
  # Retain raw wire body: unset/empty/0 = off; other values = on. Usually isolate to one capture alias.
136
140
  # PLURNK_PROVIDERS_RAWBODY=1
@@ -157,6 +161,8 @@ PLURNK_PROVIDERS_PROBE_DELAY=250
157
161
  # PLURNK_PROVIDERS_PROVIDER_ACME_REASONING_ON_BODY='{"reasoning":{"enabled":true}}'
158
162
  # PLURNK_PROVIDERS_PROVIDER_ACME_REASONING_OFF_BODY='{"reasoning":{"enabled":false}}'
159
163
  # PLURNK_PROVIDERS_PROVIDER_ACME_REASONING_ADAPTIVE_BODY='{}'
164
+ # The form of every provider declaration; NAME is the route's provider segment.
165
+ # PLURNK_PROVIDERS_PROVIDER_<NAME>_<SETTING>=<value>
160
166
  PLURNK_PROVIDERS_PROVIDER_FIREWORKS_AI_REASONING_EFFORT_PATH=/reasoning_effort
161
167
  PLURNK_PROVIDERS_PROVIDER_FIREWORKS_AI_REASONING_OFF_BODY='{"reasoning_effort":"none"}'
162
168
  PLURNK_PROVIDERS_PROVIDER_FIREWORKS_AI_REASONING_TOGGLE_BODY='{"reasoning_effort":true}'
package/README.md CHANGED
@@ -42,7 +42,7 @@ import {
42
42
  import { ProviderError } from "@plurnk/plurnk-providers/errors";
43
43
  ```
44
44
 
45
- The package root composes the complete Node provider runtime, including plugin
45
+ The package root composes the complete Node provider runtime, including extension
46
46
  discovery and environment-file defaults.
47
47
 
48
48
  ## Configure a model
@@ -126,10 +126,10 @@ flowchart TD
126
126
  shrink known capacity or declare unknown capacity, never enlarge known limits.
127
127
  Prompt projection and initialization reasoning READ limits are separate Core policy.
128
128
 
129
- ## Provider plugins
129
+ ## Provider extensions
130
130
 
131
131
  Most integrations should use an MCP server, executor, scheme, or a provider
132
- declaration. A provider plugin is only needed for a protocol binding unavailable
132
+ declaration. A provider extension is only needed for a protocol binding unavailable
133
133
  through the catalog and installed SDK packages.
134
134
 
135
135
  It may use any npm scope. Its package manifest declares the PLURNK name:
@@ -149,16 +149,16 @@ It may use any npm scope. Its package manifest declares the PLURNK name:
149
149
 
150
150
  The default export is an AI SDK provider with
151
151
  `languageModel(modelId)`. PLURNK adapts that language model into its own
152
- contract, so plugins do not reproduce retries, usage normalization, envelopes,
152
+ contract, so extensions do not reproduce retries, usage normalization, envelopes,
153
153
  notices, or RFC 9457 failure normalization.
154
154
 
155
155
  The manifest may declare always-on `plurnk.attribution`. The default export may
156
156
  also implement synchronous `attributions(context)` and decide per provider
157
157
  attempt whether to return no, one, or many additional opaque tags
158
- ({§plugin-attribution}).
158
+ ({§extension-attribution}).
159
159
 
160
160
  Discovery is scope-agnostic and rejects duplicate names.
161
- Third-party discovery uses the shared pre-import trust contract ({§plugin-trust-boundary}).
161
+ Third-party discovery uses the shared pre-import trust contract ({§extension-trust-boundary}).
162
162
 
163
163
  ## Local endpoints
164
164
 
@@ -199,14 +199,14 @@ opt-in for endpoints that emit a leading `<think>` envelope, not a reasoning swi
199
199
  | Generation deadline | One whole-call allowance across queueing, requests and retries; caller cancellation still applies. No first-content or inter-chunk cutoff. |
200
200
  | Discovery/tokenizer HTTP | Separate non-generation fetch bound; does not limit inference. |
201
201
  | Provider-directed waits | Bounded retries honor `Retry-After`; other recoverable failures return to Core. |
202
- | Loop recovery | Core reissues within its recovery window, then parks attended loops or concludes unattended loops on the failure. |
202
+ | Loop recovery | Core reissues within its recovery window, then parks for a review-capable owner or concludes on the failure. |
203
203
  | Cache affinity | Stable Worker identity through documented provider controls; not a cache-hit guarantee. |
204
204
  | Explicit cache writes | Separate policy on supported routes; can affect billing. |
205
205
  | Service tier | Explicit route choice that may change price and availability. |
206
206
  | Cost | Provider monetary evidence wins; known usage and catalog rates yield an estimate, not a settled charge. |
207
207
 
208
208
  For uncataloged compatible endpoints, declare the SDK, URL, and credential-variable
209
- name together; the examples are in the defaults reference. A provider plugin is
209
+ name together; the examples are in the defaults reference. A provider extension is
210
210
  needed only when the protocol cannot be expressed by the installed adapters.
211
211
 
212
212
  ## Configured-provider packet conformance matrix
package/SPEC.md CHANGED
@@ -103,7 +103,9 @@ the upstream provider as capacity oracle. The curation reservation's intersectio
103
103
  exposed as `inputCapacity`, the line Core packs the room against; the wall's, as `inputWall`; `null` means the available limits cannot establish
104
104
  one. A known combined context and output budget must leave positive input
105
105
  capacity. Consumers may display or use that fact as policy, but MUST NOT
106
- substitute their own content heuristic for request-shaped admission.
106
+ substitute their own content heuristic for request-shaped admission. A consumer
107
+ may assess a request before sending it; `generate` repeats the assessment as its
108
+ own guard.
107
109
 
108
110
  `tokenize` is the separate content-token capability and exists only when the
109
111
  endpoint exposes its real vocabulary. Content tokenization does not substitute
@@ -177,7 +179,7 @@ The built-in transports preserve that intent after SDK serialization:
177
179
  | Anthropic Messages | `tools: []`, `tool_choice: {"type":"none"}` |
178
180
  | Gemini GenerateContent | `tools: []`, `toolConfig: {"functionCallingConfig":{"mode":"NONE"}}` |
179
181
  | Bedrock Converse | No tool configuration; the protocol has no `none` choice. |
180
- | Installed SDK provider plugins | Portable `none` intent; the plugin owns its wire projection. |
182
+ | Installed SDK provider extensions | Portable `none` intent; the extension owns its wire projection. |
181
183
 
182
184
  This is a text-generation contract, not provider/model tuning or prompt
183
185
  teaching. Callers cannot supply tools or override the choice through request
@@ -451,8 +453,6 @@ Native SDKs retain their own output field; `OUTPUT_PATH` is incompatible with an
451
453
  options namespace. Request-local options are projected after the effective
452
454
  envelope is known, never frozen into SDK model construction. Streaming and
453
455
  non-streaming calls use the same projection.
454
- Retired `REASONING_STYLE` selectors fail at the selected provider/alias boundary;
455
- they neither select a preset nor silently coexist with these declarations.
456
456
 
457
457
  A native SDK's portable reasoning setting has no `max`, so a native route without
458
458
  a namespace cannot send an effort the catalog documents beyond it; construction
@@ -554,12 +554,9 @@ The provider segment of a model route IS the Models.dev id (#459) —
554
554
  configurations align with the catalog end to end (`fireworks-ai/…`,
555
555
  `cloudflare-workers-ai/@cf/…`, `togetherai/…`), and the
556
556
  `PLURNK_PROVIDERS_PROVIDER_<PREFIX>_*` prefix is that id uppercased with
557
- non-alphanumerics as underscores (`FIREWORKS_AI`). A retired plurnk-local
558
- segment (`fireworks`, `cloudflare`, `together`, `moonshot`, `dashscope`,
559
- `zhipu`, `hunyuan`, `bedrock`) refuses loudly, naming the id — it never
560
- silently resolves. Custom declared providers keep their operator-chosen
561
- names; the built-in local `ollama` rail keeps its name (the catalog's
562
- `ollama-cloud` is a different provider).
557
+ non-alphanumerics as underscores (`FIREWORKS_AI`). Custom declared providers
558
+ keep their operator-chosen names; the built-in local `ollama` rail keeps its
559
+ name (the catalog's `ollama-cloud` is a different provider).
563
560
 
564
561
  `instantiateProvider` resolves in this order:
565
562
 
@@ -567,14 +564,14 @@ names; the built-in local `ollama` rail keeps its name (the catalog's
567
564
  2. An operator provider declaration:
568
565
  `PLURNK_PROVIDERS_PROVIDER_<NAME>_{NPM,BASE_URL,API_KEY_ENV}`.
569
566
  3. The local `openai` or `ollama` adapter.
570
- 4. A discovered AI SDK provider plugin.
567
+ 4. A discovered AI SDK provider extension.
571
568
  5. A precise unknown-provider error.
572
569
 
573
- Earlier sources are authoritative. Installed plugins cannot shadow a cataloged
570
+ Earlier sources are authoritative. Installed extensions cannot shadow a cataloged
574
571
  or explicitly declared name. This remains true when a named model is absent
575
572
  from the Models.dev snapshot: construction requires an explicit
576
573
  `PLURNK_PROVIDERS_CONTEXT_WINDOW` and never falls through to a same-name
577
- plugin.
574
+ extension.
578
575
 
579
576
  Model IDs resolve exactly first. A unique catalog suffix is accepted to avoid
580
577
  forcing a vendor-owned resource prefix into PLURNK aliases. Ambiguous suffixes
@@ -603,36 +600,36 @@ The named secret remains in the operator environment. `${ENV_NAME}` inside a
603
600
  catalog or declared endpoint is expanded at construction and fails clearly
604
601
  when absent.
605
602
 
606
- ## §6 Provider plugins
603
+ ## §6 Provider extensions
607
604
 
608
- Provider plugins are the escape hatch for a protocol binding not represented by
605
+ Provider extensions are the escape hatch for a protocol binding not represented by
609
606
  Models.dev, installed SDK providers, or a declaration. Most extensibility
610
607
  belongs in MCP, schemes, executors, or mimetypes instead.
611
608
 
612
- A provider plugin:
609
+ A provider extension:
613
610
 
614
- 1. declares the exact string `plurnk: { kind: "provider", name }` in `package.json` ({§plugin-family-kind});
611
+ 1. declares the exact string `plurnk: { kind: "provider", name }` in `package.json` ({§extension-kind});
615
612
  2. may declare always-on package-level `plurnk.attribution` and/or implement the
616
- synchronous runtime `attributions(context)` hook under {§plugin-attribution};
613
+ synchronous runtime `attributions(context)` hook under {§extension-attribution};
617
614
  3. may use any npm scope;
618
615
  4. default-exports an AI SDK provider with `languageModel(modelId)`;
619
616
  5. peers on compatible `ai` and `@plurnk/plurnk-providers` majors.
620
617
 
621
- §provider-grammar-transport A plugin whose backend accepts a llama.cpp-style
618
+ §provider-grammar-transport An extension whose backend accepts a llama.cpp-style
622
619
  GBNF grammar may declare `plurnk.grammarStyle: "llamacpp"` beside its kind and
623
620
  name; the discovery records it and the adapted Provider carries the capability,
624
621
  so an operator's grammar file ({§operator-grammar}) rides the wire exactly as
625
622
  on a probed llama-server. Absence or `"none"` keeps the grammar off the wire;
626
- any other value fails discovery loudly. The declaration is the plugin author's
623
+ any other value fails discovery loudly. The declaration is the extension author's
627
624
  fact about their backend; the transport evidence on each response
628
625
  ({§provider-grammar-evidence}) is where a wrong declaration shows, never by
629
626
  degrading admission.
630
627
 
631
- PLURNK adapts the returned language model. The plugin does not implement the
628
+ PLURNK adapts the returned language model. The extension does not implement the
632
629
  PLURNK `Provider`, read PLURNK tuning knobs, or reproduce transport policy.
633
630
 
634
631
  Discovery is scope-agnostic and memoized per process. Duplicate names fail hard.
635
- The common plugin trust gate applies before import ({§plugin-trust-boundary}). A plugin absent from
632
+ The common extension trust gate applies before import ({§extension-trust-boundary}). An extension absent from
636
633
  Models.dev requires an explicit context-window pin because PLURNK will not guess
637
634
  model physics. `Discovery.packageAttributions` carries the canonical package map.
638
635
 
@@ -701,14 +698,35 @@ Generic AI SDK calls accept only settings represented by the SDK's portable
701
698
  surface. Compatible endpoints may carry additional sampling keys after reserved
702
699
  keys are removed.
703
700
 
701
+ §provider-request-controls **A configured service tier or logprobs count reaches a
702
+ native route only through the per-call option its SDK documents.** On a compatible
703
+ route, `PLURNK_PROVIDERS_SERVICE_TIER` and `PLURNK_PROVIDERS_TOP_LOGPROBS` are the
704
+ body fields `service_tier`, `logprobs` and `top_logprobs`. A native route sends them
705
+ in its SDK's `providerOptions` namespace, serialized by that SDK. A control the SDK
706
+ does not document is not sent, and one process warning,
707
+ `PLURNK_REQUEST_CONTROL_UNSUPPORTED`, names it, so a configured choice never
708
+ disappears in silence. The tier passes verbatim: the SDK owns its vocabulary, and a
709
+ value it drops surfaces as its call warning ({§provider-sdk-warning}). A logprobs
710
+ count of 0 asks for the chosen token only.
711
+
712
+ | Native SDK | Namespace | Service tier | Logprobs |
713
+ | --- | --- | --- | --- |
714
+ | OpenAI | `openai` | sent | sent |
715
+ | Groq | `groq` | sent | not sent |
716
+ | Cerebras | `cerebras` | sent | not sent |
717
+ | xAI | `xai` | sent | not sent |
718
+ | Google | `google` | sent | not sent |
719
+ | Anthropic | `anthropic` | sent | not sent |
720
+ | Amazon Bedrock | `bedrock` | sent | not sent |
721
+ | Mistral, Together, DeepInfra, OpenRouter | none | not sent | not sent |
722
+
704
723
  §openrouter-app-attribution **A route on the OpenRouter SDK identifies the calling
705
724
  application only as its provider declares.** `APP_URL`, an absolute HTTP(S) URL, and
706
725
  the optional `APP_NAME` are provider declarations (`PLURNK_PROVIDERS_PROVIDER_<NAME>_`,
707
726
  overridable per route or alias); the SDK sends them as `HTTP-Referer` and
708
727
  `X-OpenRouter-Title`. The shipped floor declares them for `openrouter` only, so
709
728
  another provider on the same SDK package sends none; an empty `APP_URL` suppresses
710
- both. The retired `OPENROUTER_HTTP_REFERER`, `OPENROUTER_APP_TITLE` and
711
- `OPENROUTER_X_TITLE` fail construction.
729
+ both.
712
730
 
713
731
  ## §9 Failures, retries, and cancellation
714
732
 
@@ -997,8 +1015,7 @@ replayed. Missing output usage cannot prove a violation.
997
1015
  as `35%`. `PLURNK_PROVIDERS_REASONING_BUDGET` is optional; leaving it unset
998
1016
  preserves provider-adaptive depth. A backend known to decode without a finite
999
1017
  limit advertises `requiresOutputBudget` and fails construction when no total can
1000
- be resolved. The retired additive reserve knobs fail hard rather than creating
1001
- a second envelope contract.
1018
+ be resolved.
1002
1019
 
1003
1020
  ## §13 Inference capacity
1004
1021
 
@@ -1011,7 +1028,7 @@ alias scoping. Zero, other negative values and non-integers are invalid.
1011
1028
 
1012
1029
  | Boundary | Contract |
1013
1030
  | --- | --- |
1014
- | Identity | Provider instances and aliases sharing the resolved API base URL share one allowance. SDK/plugin-owned endpoints without a resolved URL share their provider identity. Conflicting limits for one identity fail construction, naming the identity and both values; they never create independent queues. The daemon reads its environment once at boot, so an identity's limit cannot change within a process: reconstructing a provider from that environment reuses its allowance, and in-flight leases keep counting. |
1031
+ | Identity | Provider instances and aliases sharing the resolved API base URL share one allowance. SDK- or extension-owned endpoints without a resolved URL share their provider identity. Conflicting limits for one identity fail construction, naming the identity and both values; they never create independent queues. The daemon reads its environment once at boot, so an identity's limit cannot change within a process: reconstructing a provider from that environment reuses its allowance, and in-flight leases keep counting. |
1015
1032
  | Admission | FIFO among live waiters. The lease begins before the physical request observer and ends after the complete response or transport failure settles, including streamed bodies. |
1016
1033
  | Cancellation | A queued abort removes that waiter and preserves the caller's reason. It opens no physical request or accounting row. In-flight cancellation signals the transport; capacity is released when that attempt unwinds. A transport still running despite abort does not authorize exceeding the limit. |
1017
1034
  | Retries | Backoff holds no lease. Each retry rejoins admission as a new physical attempt. |
@@ -1045,7 +1062,7 @@ complete-envelope derivation per backend before taking the minimum.
1045
1062
 
1046
1063
  Coverage MUST prove:
1047
1064
 
1048
- - catalog, declaration, local, and plugin resolution;
1065
+ - catalog, declaration, local, and extension resolution;
1049
1066
  - exact and unique-suffix model lookup;
1050
1067
  - native SDK request mapping and normalized responses;
1051
1068
  - compatible extension preservation;
@@ -4,7 +4,7 @@ import type { JSONValue } from "ai";
4
4
  import type { EffortSetting, ReasoningResponseStyle } from "./env.ts";
5
5
  import type { InputModality } from "./types.ts";
6
6
  import type { LanguageModel } from "ai";
7
- import type { PluginAttribution, PluginAttributionContext } from "@plurnk/plurnk-meta";
7
+ import type { ExtensionAttribution, ExtensionAttributionContext } from "@plurnk/plurnk-meta";
8
8
  import type RequestFields from "./RequestFields.ts";
9
9
  import type InferenceAdmission from "./InferenceAdmission.ts";
10
10
  export type ProviderFetch = typeof globalThis.fetch;
@@ -25,7 +25,7 @@ export type AiSdkProviderConfig = {
25
25
  model: string;
26
26
  url?: string;
27
27
  languageModel?: LanguageModel;
28
- attributions?: (context: PluginAttributionContext) => PluginAttribution;
28
+ attributions?: (context: ExtensionAttributionContext) => ExtensionAttribution;
29
29
  fetchTimeoutMs: number;
30
30
  operationTimeoutMs: number;
31
31
  droppedOutputTokens?: number;
@@ -54,6 +54,7 @@ export type AiSdkProviderConfig = {
54
54
  systemCacheProviderOptions?: AiSdkProviderOptions;
55
55
  reasoningResponseProviderOptions?: AiSdkProviderOptions;
56
56
  serviceTier?: string;
57
+ requestControls?: NativeRequestControls;
57
58
  streaming?: boolean;
58
59
  apiKeyRejectedMessage?: string;
59
60
  eosText?: string;
@@ -80,9 +81,14 @@ export type AiSdkProviderConfig = {
80
81
  topLogprobs?: number | null;
81
82
  rawBody?: boolean;
82
83
  };
84
+ export interface NativeRequestControls {
85
+ readonly namespace: string;
86
+ readonly serviceTier: boolean;
87
+ readonly logprobs: boolean;
88
+ }
83
89
  export default class AiSdkProvider implements Provider {
84
90
  #private;
85
- readonly attributions?: (context: PluginAttributionContext) => PluginAttribution;
91
+ readonly attributions?: (context: ExtensionAttributionContext) => ExtensionAttribution;
86
92
  tokenize?: (text: string) => Promise<number[]>;
87
93
  constructor(config: AiSdkProviderConfig);
88
94
  get contextWindow(): number | null;
@@ -1 +1 @@
1
- {"version":3,"file":"AiSdkProvider.d.ts","sourceRoot":"","sources":["../src/AiSdkProvider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AiSdkProvider.d.ts","sourceRoot":"","sources":["../src/AiSdkProvider.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  // PLURNK adapter over an AI SDK language model. Implements the universal generate()
2
2
  // spine — signal merging, the SSE call, usage mapping, finishReason
3
- // normalization, response assembly — that every sibling had duplicated.
3
+ // normalization, response assembly.
4
4
  //
5
5
  // Composition, not inheritance: an official AI SDK language model supplies the
6
- // ordinary vendor protocol. The compatible URL path remains only for PLURNK
6
+ // ordinary vendor protocol. The compatible URL path serves only PLURNK
7
7
  // extensions and local endpoint probes the SDK cannot represent.
8
8
  import { EFFORTS, MAX_TIMER_MS } from "@plurnk/plurnk-contracts";
9
9
  import { UnsupportedEffortError } from "./types.js";
@@ -82,6 +82,26 @@ const providerWarningMessage = (warning) => {
82
82
  case "other": return warning.message;
83
83
  }
84
84
  };
85
+ // {§provider-request-controls} — a native route forwards a configured control only through its
86
+ // SDK's documented provider option; a control the SDK does not document is named once and not
87
+ // sent, never dropped in silence (#988).
88
+ const nativeControlOptions = (source, controls, serviceTier, topLogprobs) => {
89
+ const options = {};
90
+ const unsupported = (knob) => emitWarningOnce(`${source}: ${knob} is not a provider option this route's SDK${controls === undefined ? "" : ` (${controls.namespace})`} documents, so it is not sent`, "PLURNK_REQUEST_CONTROL_UNSUPPORTED");
91
+ if (serviceTier !== undefined) {
92
+ if (controls?.serviceTier === true)
93
+ options.serviceTier = serviceTier;
94
+ else
95
+ unsupported("PLURNK_PROVIDERS_SERVICE_TIER");
96
+ }
97
+ if (topLogprobs !== null) {
98
+ if (controls?.logprobs === true)
99
+ options.logprobs = topLogprobs > 0 ? topLogprobs : true;
100
+ else
101
+ unsupported("PLURNK_PROVIDERS_TOP_LOGPROBS");
102
+ }
103
+ return controls === undefined || Object.keys(options).length === 0 ? undefined : { [controls.namespace]: options };
104
+ };
85
105
  export default class AiSdkProvider {
86
106
  #inferenceAdmission;
87
107
  #model;
@@ -126,6 +146,7 @@ export default class AiSdkProvider {
126
146
  #systemCacheProviderOptions;
127
147
  #reasoningResponseProviderOptions;
128
148
  #serviceTier;
149
+ #controlOptions;
129
150
  #streaming;
130
151
  #supportsSlotPinning;
131
152
  #slotCount;
@@ -181,7 +202,7 @@ export default class AiSdkProvider {
181
202
  if (!this.#supportedEfforts.includes(this.#effort.mode)) {
182
203
  throw new UnsupportedEffortError(config.source ?? "provider", this.#effort.mode, this.#supportedEfforts);
183
204
  }
184
- // Loud guard: an out-of-date consumer (stale plugin dist) omitting the
205
+ // Loud guard: an out-of-date consumer (stale extension dist) omitting the
185
206
  // required tuning fields must fail at construction, not silently send
186
207
  // undefined sampling on every grammar request.
187
208
  if (config.temperature === undefined || config.repeatPenalty === undefined) {
@@ -257,6 +278,12 @@ export default class AiSdkProvider {
257
278
  this.#supportsSlotPinning = config.supportsSlotPinning ?? false;
258
279
  this.#slotCount = config.slotCount ?? null;
259
280
  this.#topLogprobs = config.topLogprobs ?? null;
281
+ if (this.#languageModel === undefined && config.requestControls !== undefined) {
282
+ throw new Error(`${this.#source}: native request controls require an AI SDK model`);
283
+ }
284
+ this.#controlOptions = this.#languageModel === undefined
285
+ ? undefined
286
+ : nativeControlOptions(this.#source, config.requestControls, this.#serviceTier, this.#topLogprobs);
260
287
  this.#rawBody = config.rawBody ?? false;
261
288
  this.#servedModel = config.servedModel;
262
289
  this.#requiresOutputBudget = config.requiresOutputBudget;
@@ -306,7 +333,7 @@ export default class AiSdkProvider {
306
333
  return tokens;
307
334
  };
308
335
  }
309
- this.#requestBody = new AiSdkRequestBody({ reasoningBudget: this.#reasoningBudget, additiveReasoningProvider: this.#additiveReasoningProvider, effort: this.#effort, adaptiveEffortProviderOptions: this.#adaptiveEffortProviderOptions, repeatPenalty: this.#repeatPenalty, dryMultiplier: this.#dryMultiplier, dryBase: this.#dryBase, dryAllowedLength: this.#dryAllowedLength, repeatLastN: this.#repeatLastN, reasoningStyle: this.#reasoningStyle, source: this.#source, grammarStyle: this.#grammarStyle, cacheAffinity: this.#cacheAffinity, reasoningResponseProviderOptions: this.#reasoningResponseProviderOptions, supportsSlotPinning: this.#supportsSlotPinning, slotCount: this.#slotCount });
336
+ this.#requestBody = new AiSdkRequestBody({ reasoningBudget: this.#reasoningBudget, additiveReasoningProvider: this.#additiveReasoningProvider, effort: this.#effort, adaptiveEffortProviderOptions: this.#adaptiveEffortProviderOptions, repeatPenalty: this.#repeatPenalty, dryMultiplier: this.#dryMultiplier, dryBase: this.#dryBase, dryAllowedLength: this.#dryAllowedLength, repeatLastN: this.#repeatLastN, reasoningStyle: this.#reasoningStyle, source: this.#source, grammarStyle: this.#grammarStyle, cacheAffinity: this.#cacheAffinity, reasoningResponseProviderOptions: this.#reasoningResponseProviderOptions, controlOptions: this.#controlOptions, supportsSlotPinning: this.#supportsSlotPinning, slotCount: this.#slotCount });
310
337
  }
311
338
  get contextWindow() { return this.#contextWindow; }
312
339
  get inputModalities() { return this.#inputModalities; }
@@ -782,10 +809,9 @@ export default class AiSdkProvider {
782
809
  if (sendGrammar !== undefined
783
810
  && this.tokenize !== undefined
784
811
  && usage?.outputTokens !== undefined) {
785
- // Channel-escape detector: completion tokens
786
- // billed far beyond every visible channel mean the decode ESCAPED into
787
- // a server-discarded reasoning block mid-emission. This diagnostic
788
- // requires the serving vocabulary; an estimate cannot prove absence.
812
+ // {§diagnostic-observation} — billed output tokens far beyond every visible channel are reported
813
+ // as the two counts, naming no cause. The count requires the serving vocabulary; an estimate
814
+ // cannot prove absence.
789
815
  try {
790
816
  const [contentTokens, reasoningTokens] = await Promise.all([
791
817
  this.tokenize(raw.content),
@@ -795,9 +821,9 @@ export default class AiSdkProvider {
795
821
  if (usage.outputTokens > visible + 64) {
796
822
  (notices ??= []).push({
797
823
  source: this.#source,
798
- kind: "grammar_unenforced",
824
+ kind: "output_unaccounted",
799
825
  level: "warn",
800
- message: `decode escaped the grammar: ${usage.outputTokens} output tokens billed but only ${visible} visible across content+reasoning — the balance ran unconstrained in a discarded reasoning channel`,
826
+ message: `${usage.outputTokens} output tokens billed; ${visible} visible across content and reasoning.`,
801
827
  position: [...raw.content].length,
802
828
  });
803
829
  }