@plurnk/plurnk-providers 1.3.12 → 1.4.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 (132) hide show
  1. package/.env.defaults +39 -22
  2. package/README.md +65 -4
  3. package/SPEC.md +222 -56
  4. package/dist/AiSdkProvider.d.ts +18 -5
  5. package/dist/AiSdkProvider.d.ts.map +1 -1
  6. package/dist/AiSdkProvider.js +240 -153
  7. package/dist/AiSdkProvider.js.map +1 -1
  8. package/dist/Mock.d.ts +14 -15
  9. package/dist/Mock.d.ts.map +1 -1
  10. package/dist/Mock.js +26 -10
  11. package/dist/Mock.js.map +1 -1
  12. package/dist/Pool.d.ts +8 -2
  13. package/dist/Pool.d.ts.map +1 -1
  14. package/dist/Pool.js +41 -8
  15. package/dist/Pool.js.map +1 -1
  16. package/dist/ProviderRegistry.d.ts +4 -1
  17. package/dist/ProviderRegistry.d.ts.map +1 -1
  18. package/dist/ProviderRegistry.js +7 -3
  19. package/dist/ProviderRegistry.js.map +1 -1
  20. package/dist/aiSdkTransport.d.ts +4 -2
  21. package/dist/aiSdkTransport.d.ts.map +1 -1
  22. package/dist/aiSdkTransport.js +18 -3
  23. package/dist/aiSdkTransport.js.map +1 -1
  24. package/dist/catalogProvider.d.ts +3 -1
  25. package/dist/catalogProvider.d.ts.map +1 -1
  26. package/dist/catalogProvider.js +20 -7
  27. package/dist/catalogProvider.js.map +1 -1
  28. package/dist/compatibleProvider.d.ts.map +1 -1
  29. package/dist/compatibleProvider.js +11 -4
  30. package/dist/compatibleProvider.js.map +1 -1
  31. package/dist/cost.d.ts +11 -0
  32. package/dist/cost.d.ts.map +1 -0
  33. package/dist/cost.js +64 -0
  34. package/dist/cost.js.map +1 -0
  35. package/dist/discover.d.ts +2 -0
  36. package/dist/discover.d.ts.map +1 -1
  37. package/dist/discover.js +15 -9
  38. package/dist/discover.js.map +1 -1
  39. package/dist/env.d.ts +4 -0
  40. package/dist/env.d.ts.map +1 -1
  41. package/dist/env.js +29 -9
  42. package/dist/env.js.map +1 -1
  43. package/dist/errors.d.ts +27 -0
  44. package/dist/errors.d.ts.map +1 -0
  45. package/dist/errors.js +150 -0
  46. package/dist/errors.js.map +1 -0
  47. package/dist/index.d.ts +11 -5
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +7 -4
  50. package/dist/index.js.map +1 -1
  51. package/dist/notices.d.ts +10 -0
  52. package/dist/notices.d.ts.map +1 -0
  53. package/dist/notices.js +11 -0
  54. package/dist/notices.js.map +1 -0
  55. package/dist/ollama.d.ts.map +1 -1
  56. package/dist/ollama.js +3 -3
  57. package/dist/ollama.js.map +1 -1
  58. package/dist/openai.d.ts +1 -1
  59. package/dist/openai.d.ts.map +1 -1
  60. package/dist/promptTokens.d.ts +4 -0
  61. package/dist/promptTokens.d.ts.map +1 -0
  62. package/dist/promptTokens.js +32 -0
  63. package/dist/promptTokens.js.map +1 -0
  64. package/dist/sdkModels.d.ts.map +1 -1
  65. package/dist/sdkModels.js +4 -3
  66. package/dist/sdkModels.js.map +1 -1
  67. package/dist/types.d.ts +43 -16
  68. package/dist/types.d.ts.map +1 -1
  69. package/dist/types.js +1 -1
  70. package/dist/types.js.map +1 -1
  71. package/dist/usage.d.ts +3 -0
  72. package/dist/usage.d.ts.map +1 -1
  73. package/dist/usage.js +26 -14
  74. package/dist/usage.js.map +1 -1
  75. package/dist/warnings.js +0 -0
  76. package/dist/warnings.js.map +1 -1
  77. package/package.json +13 -9
  78. package/src/AiSdkProvider.test.ts +480 -159
  79. package/src/AiSdkProvider.ts +320 -196
  80. package/src/Mock.test.ts +29 -14
  81. package/src/Mock.ts +33 -15
  82. package/src/Pool.test.ts +43 -6
  83. package/src/Pool.ts +56 -10
  84. package/src/ProviderRegistry.test.ts +158 -9
  85. package/src/ProviderRegistry.ts +19 -6
  86. package/src/aiSdkTransport.ts +25 -6
  87. package/src/boundaries.test.ts +8 -3
  88. package/src/catalogProvider.test.ts +17 -0
  89. package/src/catalogProvider.ts +25 -10
  90. package/src/compatibleProvider.test.ts +96 -0
  91. package/src/compatibleProvider.ts +15 -6
  92. package/src/cost.test.ts +63 -0
  93. package/src/cost.ts +83 -0
  94. package/src/defaults.test.ts +1 -0
  95. package/src/discover.test.ts +48 -7
  96. package/src/discover.ts +31 -21
  97. package/src/env.test.ts +38 -23
  98. package/src/env.ts +45 -18
  99. package/src/errors.test.ts +148 -0
  100. package/src/errors.ts +207 -0
  101. package/src/index.ts +29 -7
  102. package/src/lexicon-guard.test.ts +6 -6
  103. package/src/notices.ts +22 -0
  104. package/src/ollama.test.ts +64 -0
  105. package/src/ollama.ts +6 -3
  106. package/src/openai.ts +3 -0
  107. package/src/promptTokens.ts +41 -0
  108. package/src/sdkModels.test.ts +7 -0
  109. package/src/sdkModels.ts +4 -8
  110. package/src/types.ts +106 -64
  111. package/src/usage.test.ts +15 -4
  112. package/src/usage.ts +32 -14
  113. package/src/warnings.test.ts +10 -10
  114. package/src/warnings.ts +0 -0
  115. package/dist/OpenAICompat.d.ts +0 -76
  116. package/dist/OpenAICompat.d.ts.map +0 -1
  117. package/dist/OpenAICompat.js +0 -555
  118. package/dist/OpenAICompat.js.map +0 -1
  119. package/dist/openaiStream.d.ts +0 -47
  120. package/dist/openaiStream.d.ts.map +0 -1
  121. package/dist/openaiStream.js +0 -280
  122. package/dist/openaiStream.js.map +0 -1
  123. package/dist/standardProviders.d.ts +0 -31
  124. package/dist/standardProviders.d.ts.map +0 -1
  125. package/dist/standardProviders.js +0 -518
  126. package/dist/standardProviders.js.map +0 -1
  127. package/dist/telemetry.d.ts +0 -24
  128. package/dist/telemetry.d.ts.map +0 -1
  129. package/dist/telemetry.js +0 -85
  130. package/dist/telemetry.js.map +0 -1
  131. package/src/telemetry.test.ts +0 -69
  132. package/src/telemetry.ts +0 -116
package/src/usage.test.ts CHANGED
@@ -23,7 +23,7 @@ test("normalizeUsage: OpenAI-style — reasoning split out of completion_tokens"
23
23
  assert.equal(u.completion + u.reasoning, 100); // billable output unchanged
24
24
  });
25
25
 
26
- test("normalizeUsage: xAI/Grok-style — reasoning is ADDITIVE, not subtracted from completion (#28)", () => {
26
+ test("normalizeUsage: xAI/Grok-style — reasoning is ADDITIVE, not subtracted from completion", () => {
27
27
  // Real grok-4.3 shape: completion_tokens is visible-only; reasoning_tokens is
28
28
  // detailed but ADDITIVE — total = prompt + completion + reasoning.
29
29
  const u = normalizeUsage({
@@ -48,6 +48,17 @@ test("normalizeUsage: top-level cached_tokens still honored", () => {
48
48
  assert.equal(u.cached, 12);
49
49
  });
50
50
 
51
+ test("#157: normalizeUsage maps DeepSeek's prompt cache hit count", () => {
52
+ const u = normalizeUsage({
53
+ prompt_tokens: 50,
54
+ prompt_cache_hit_tokens: 30,
55
+ prompt_cache_miss_tokens: 20,
56
+ completion_tokens: 10,
57
+ total_tokens: 60,
58
+ });
59
+ assert.deepEqual(u, { prompt: 50, completion: 10, reasoning: 0, cached: 30, total: 60 });
60
+ });
61
+
51
62
  test("normalizeUsage: no reasoning — plain prompt+completion", () => {
52
63
  const u = normalizeUsage({ prompt_tokens: 10, completion_tokens: 20, total_tokens: 30 });
53
64
  assert.deepEqual(u, { prompt: 10, completion: 20, reasoning: 0, cached: 0, total: 30 });
@@ -63,9 +74,9 @@ test("normalizeUsage: absent usage → all zeros", () => {
63
74
  assert.deepEqual(normalizeUsage(undefined), { prompt: 0, completion: 0, reasoning: 0, cached: 0, total: 0 });
64
75
  });
65
76
 
66
- // -- Fireworks-style: reasoning shipped as TEXT, folded into completion, not itemized (#425) --
77
+ // -- Fireworks-style: reasoning shipped as TEXT, folded into completion, not itemized --
67
78
 
68
- test("normalizeUsage: fireworks folds reasoning into completion -- re-split by text proportion, sum preserved (#425)", () => {
79
+ test("normalizeUsage: fireworks folds reasoning into completion -- re-split by text proportion, sum preserved", () => {
69
80
  // total = prompt + completion (no gap), reasoning_tokens absent, but 750 vs 250
70
81
  // chars of reasoning vs content came back. Split completion 75/25; cost base held.
71
82
  const u = normalizeUsage(
@@ -78,7 +89,7 @@ test("normalizeUsage: fireworks folds reasoning into completion -- re-split by t
78
89
  assert.equal(u.prompt + u.completion + u.reasoning, u.total); // invariant
79
90
  });
80
91
 
81
- test("normalizeUsage: pure-reasoning turn (empty content) attributes all completion to reasoning (#425)", () => {
92
+ test("normalizeUsage: pure-reasoning turn (empty content) attributes all completion to reasoning", () => {
82
93
  // The run52 runaway shape: 0 visible content, the whole budget spent reasoning.
83
94
  const u = normalizeUsage(
84
95
  { prompt_tokens: 100, completion_tokens: 500, total_tokens: 600 },
package/src/usage.ts CHANGED
@@ -20,16 +20,39 @@ export type RawUsage = {
20
20
  completion_tokens?: number;
21
21
  total_tokens?: number;
22
22
  cached_tokens?: number;
23
+ prompt_cache_hit_tokens?: number;
24
+ prompt_cache_miss_tokens?: number;
23
25
  prompt_tokens_details?: { cached_tokens?: number };
24
26
  completion_tokens_details?: { reasoning_tokens?: number };
25
27
  };
26
28
 
29
+ // Some providers return distinct reasoning text while reporting one combined
30
+ // output count. Attribute that count without disturbing an upstream split.
31
+ export const attributeUnitemizedReasoning = (
32
+ usage: ProviderUsage,
33
+ reasoningText: string,
34
+ contentText: string,
35
+ ): ProviderUsage => {
36
+ if (usage.reasoning !== 0 || usage.completion === 0 || reasoningText.length === 0) return usage;
37
+ const reasoning = contentText.length === 0
38
+ ? usage.completion
39
+ : Math.round(usage.completion * reasoningText.length / (reasoningText.length + contentText.length));
40
+ return {
41
+ ...usage,
42
+ completion: usage.completion - reasoning,
43
+ reasoning,
44
+ };
45
+ };
46
+
27
47
  export const normalizeUsage = (raw: RawUsage | null | undefined, reasoningText = "", contentText = ""): ProviderUsage => {
28
48
  const prompt = raw?.prompt_tokens ?? 0;
29
49
  const completionRaw = raw?.completion_tokens ?? 0;
30
50
  const reportedTotal = raw?.total_tokens ?? 0;
31
51
  // OpenAI nests cached under prompt_tokens_details; others put it top-level.
32
- const cached = raw?.prompt_tokens_details?.cached_tokens ?? raw?.cached_tokens ?? 0;
52
+ const cached = raw?.prompt_tokens_details?.cached_tokens
53
+ ?? raw?.prompt_cache_hit_tokens
54
+ ?? raw?.cached_tokens
55
+ ?? 0;
33
56
  const reasoningDetail = raw?.completion_tokens_details?.reasoning_tokens;
34
57
 
35
58
  let completion: number;
@@ -40,7 +63,7 @@ export const normalizeUsage = (raw: RawUsage | null | undefined, reasoningText =
40
63
  // o-series folds it INTO completion_tokens (subset: total = prompt + completion,
41
64
  // so completion must have reasoning subtracted out). xAI/Grok reports it
42
65
  // ADDITIVE to a visible-only completion_tokens (total = prompt + completion +
43
- // reasoning), where subtracting wrongly zeroes the visible output (#28). Tell
66
+ // reasoning), where subtracting wrongly zeroes the visible output. Tell
44
67
  // them apart by the total identity; with no total reported, fall back on the
45
68
  // impossible-subset signal — reasoning can't exceed the completion it's a
46
69
  // subset of.
@@ -53,20 +76,15 @@ export const normalizeUsage = (raw: RawUsage | null | undefined, reasoningText =
53
76
  // reasoning. Only trust the gap when a total was actually reported.
54
77
  reasoning = reportedTotal > 0 ? Math.max(0, reportedTotal - prompt - completionRaw) : 0;
55
78
  completion = completionRaw;
56
- // Fireworks folds reasoning INTO completion_tokens and itemizes no
57
- // reasoning_tokens, so a turn that shipped only reasoning reads reasoning=0
58
- // though 300k chars of it arrived (#425). When reasoning TEXT came back but
59
- // the reported totals leave no gap, re-split the reported completion by the
60
- // emitted text proportions. Sum-preserving: billable output
61
- // (completion+reasoning) and cost are byte-identical; only the
62
- // visible/reasoning gauge is corrected (pure-reasoning turn -> completion 0).
63
- if (reasoning === 0 && reasoningText.length > 0 && reportedTotal > 0 && completionRaw > 0) {
64
- reasoning = Math.round(completionRaw * reasoningText.length / (reasoningText.length + contentText.length));
65
- completion = completionRaw - reasoning;
66
- }
67
79
  }
68
80
  const total = reportedTotal > 0 ? reportedTotal : prompt + completion + reasoning;
69
- return { prompt, completion, reasoning, cached, total };
81
+ const usage = { prompt, completion, reasoning, cached, total };
82
+ // Fireworks folds reasoning INTO completion_tokens and itemizes no
83
+ // reasoning_tokens. A reported total establishes that completion is an
84
+ // upstream quantity rather than a locally synthesized fallback.
85
+ return reasoningDetail === undefined && reportedTotal > 0
86
+ ? attributeUnitemizedReasoning(usage, reasoningText, contentText)
87
+ : usage;
70
88
  };
71
89
 
72
90
  // Conventional provider pricing: USD per million tokens, matching Models.dev.
@@ -4,24 +4,24 @@ import { emitWarningOnce, resetEmittedWarnings } from "./warnings.ts";
4
4
 
5
5
  test.afterEach(() => { mock.restoreAll(); resetEmittedWarnings(); });
6
6
 
7
- test("#40: same (code, message) fires once per process", () => {
7
+ test("same (code, message) fires once per process", () => {
8
8
  const seen: string[] = [];
9
9
  mock.method(process, "emitWarning", (msg: string | Error) => { seen.push(String(msg)); });
10
- emitWarningOnce("openai provider: heuristic", "PLURNK_TOKENIZER_HEURISTIC");
11
- emitWarningOnce("openai provider: heuristic", "PLURNK_TOKENIZER_HEURISTIC");
12
- emitWarningOnce("openai provider: heuristic", "PLURNK_TOKENIZER_HEURISTIC");
13
- assert.deepEqual(seen, ["openai provider: heuristic"]);
10
+ emitWarningOnce("openai provider: estimate", "PLURNK_PROMPT_COUNT_ESTIMATE");
11
+ emitWarningOnce("openai provider: estimate", "PLURNK_PROMPT_COUNT_ESTIMATE");
12
+ emitWarningOnce("openai provider: estimate", "PLURNK_PROMPT_COUNT_ESTIMATE");
13
+ assert.deepEqual(seen, ["openai provider: estimate"]);
14
14
  });
15
15
 
16
- test("#40: dedup is by (code, MESSAGE), not code — a second provider's surfacing is never suppressed", () => {
16
+ test("dedup is by (code, MESSAGE), not code — a second provider's surfacing is never suppressed", () => {
17
17
  const seen: string[] = [];
18
18
  mock.method(process, "emitWarning", (msg: string | Error) => { seen.push(String(msg)); });
19
- emitWarningOnce("openai provider: heuristic", "PLURNK_TOKENIZER_HEURISTIC");
20
- emitWarningOnce("groq provider: heuristic", "PLURNK_TOKENIZER_HEURISTIC"); // same code, different provider
21
- assert.deepEqual(seen, ["openai provider: heuristic", "groq provider: heuristic"]);
19
+ emitWarningOnce("openai provider: estimate", "PLURNK_PROMPT_COUNT_ESTIMATE");
20
+ emitWarningOnce("groq provider: estimate", "PLURNK_PROMPT_COUNT_ESTIMATE"); // same code, different provider
21
+ assert.deepEqual(seen, ["openai provider: estimate", "groq provider: estimate"]);
22
22
  });
23
23
 
24
- test("#40: resetEmittedWarnings clears the set (test-order independence)", () => {
24
+ test("resetEmittedWarnings clears the set (test-order independence)", () => {
25
25
  const seen: string[] = [];
26
26
  mock.method(process, "emitWarning", (msg: string | Error) => { seen.push(String(msg)); });
27
27
  emitWarningOnce("m", "C");
package/src/warnings.ts CHANGED
Binary file
@@ -1,76 +0,0 @@
1
- import type { ChatMessage, Provider, ProviderResponse, ProviderUsage } from "./types.ts";
2
- import type { Reasoning, ReserveSpec } from "./env.ts";
3
- export type ProviderFetch = typeof globalThis.fetch;
4
- export type ReasoningStyle = "none" | "think" | "include_reasoning" | "effort" | "effort_explicit" | "template" | "anthropic";
5
- export type GrammarStyle = "none" | "llamacpp";
6
- export type OpenAICompatConfig = {
7
- model: string;
8
- url: string;
9
- fetchTimeoutMs: number;
10
- streamIdleTimeoutMs?: number;
11
- headers?: Record<string, string>;
12
- fetch?: ProviderFetch;
13
- contextWindow?: number | null;
14
- reasoningStyle?: ReasoningStyle;
15
- countTokens?: (text: string) => number;
16
- calculateCost?: (usage: ProviderUsage) => number;
17
- source?: string;
18
- grammarStyle?: GrammarStyle;
19
- promptCacheKey?: boolean;
20
- serviceTier?: string;
21
- gbnfDebug?: boolean;
22
- streaming?: boolean;
23
- firstPartyMetadata?: boolean;
24
- apiKeyRejectedMessage?: string;
25
- eosText?: string;
26
- supportsSlotPinning?: boolean;
27
- slotCount?: number | null;
28
- tokenizeUrl?: string;
29
- servedModel?: string;
30
- requiresMaxTokens?: boolean;
31
- reasoning: Reasoning;
32
- temperature: number;
33
- repeatPenalty: number;
34
- frequencyPenalty?: number;
35
- dryMultiplier?: number;
36
- dryBase?: number;
37
- dryAllowedLength?: number;
38
- repeatLastN?: number;
39
- retryAttempts: number;
40
- topLogprobs?: number | null;
41
- rawBody?: boolean;
42
- reasoningReserve?: ReserveSpec;
43
- completionReserve?: ReserveSpec;
44
- tuningFloors?: boolean;
45
- };
46
- export declare const effortFromBudget: (budget: number) => "low" | "medium" | "high";
47
- export default class OpenAICompatProvider implements Provider {
48
- #private;
49
- tokenize?: (text: string) => Promise<number[]>;
50
- constructor(config: OpenAICompatConfig);
51
- get contextWindow(): number | null;
52
- get reasoningReserve(): number | null;
53
- get completionReserve(): number | null;
54
- get model(): string;
55
- get servedModel(): string | undefined;
56
- get requiresMaxTokens(): boolean | undefined;
57
- get constrainsOutput(): boolean;
58
- countTokens(text: string): number;
59
- calculateCost(usage: ProviderUsage): number;
60
- generate({ messages, workerId, primaryWorkerId, signal, grammar, maxTokens, attributions, client, strikes, workspaceId, loop, turn, sampling }: {
61
- messages: ChatMessage[];
62
- workerId: string;
63
- primaryWorkerId?: string;
64
- signal?: AbortSignal;
65
- grammar?: string;
66
- maxTokens?: number;
67
- attributions?: string[];
68
- client?: string;
69
- strikes?: number;
70
- workspaceId?: string;
71
- loop?: number;
72
- turn?: number;
73
- sampling?: Record<string, unknown>;
74
- }): Promise<ProviderResponse>;
75
- }
76
- //# sourceMappingURL=OpenAICompat.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"OpenAICompat.d.ts","sourceRoot":"","sources":["../src/OpenAICompat.ts"],"names":[],"mappings":"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"}