@genesislcap/foundation-ai 15.11.0 → 15.12.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.
@@ -243,7 +243,7 @@
243
243
  {
244
244
  "kind": "PropertySignature",
245
245
  "canonicalReference": "@genesislcap/foundation-ai!AggregateUsage#cacheWriteTokens:member",
246
- "docComment": "/**\n * Prompt tokens written to the provider's cache.\n */\n",
246
+ "docComment": "/**\n * Prompt tokens written to the provider's cache.\n *\n * **Volume only — this aggregate can never be priced.** Two reasons, either of which is sufficient: Anthropic's per-TTL write split is already collapsed on each contributing message, and a run may span models (and providers) at different rates, so no single rate applies to the total. Report it, chart it, do not multiply it.\n */\n",
247
247
  "excerptTokens": [
248
248
  {
249
249
  "kind": "Content",
@@ -270,7 +270,7 @@
270
270
  {
271
271
  "kind": "PropertySignature",
272
272
  "canonicalReference": "@genesislcap/foundation-ai!AggregateUsage#costUsd:member",
273
- "docComment": "/**\n * USD cost, provider-reported per request and summed — cache discounts applied.\n */\n",
273
+ "docComment": "/**\n * USD cost, provider-reported per request and summed — cache discounts applied.\n *\n * The authoritative total. It is a **sum of per-request costs**, each computed where the full provider usage was in hand; it is never re-derived from the token buckets below, and should not be.\n */\n",
274
274
  "excerptTokens": [
275
275
  {
276
276
  "kind": "Content",
@@ -1415,6 +1415,87 @@
1415
1415
  ],
1416
1416
  "extendsTokenRanges": []
1417
1417
  },
1418
+ {
1419
+ "kind": "Variable",
1420
+ "canonicalReference": "@genesislcap/foundation-ai!ANTHROPIC_CACHE_READ_MULTIPLIER:var",
1421
+ "docComment": "/**\n * Prompt-cache pricing multipliers, applied to the model's base input rate (`promptPerMillion`) — https://docs.claude.com/en/docs/build-with-claude/prompt-caching Reads bill at ~0.1× base input; writes bill by TTL — 5-minute at ~1.25× and 1-hour at 2×. Both write TTLs are reachable (`CachePolicy.ttl` is `'5m' | '1h'`), so each TTL bucket is costed from the response's per-TTL `cache_creation` breakdown rather than assuming one rate.\n *\n * @beta\n */\n",
1422
+ "excerptTokens": [
1423
+ {
1424
+ "kind": "Content",
1425
+ "text": "ANTHROPIC_CACHE_READ_MULTIPLIER = "
1426
+ },
1427
+ {
1428
+ "kind": "Content",
1429
+ "text": "0.1"
1430
+ }
1431
+ ],
1432
+ "fileUrlPath": "src/utils/token-cost.ts",
1433
+ "initializerTokenRange": {
1434
+ "startIndex": 1,
1435
+ "endIndex": 2
1436
+ },
1437
+ "isReadonly": true,
1438
+ "releaseTag": "Beta",
1439
+ "name": "ANTHROPIC_CACHE_READ_MULTIPLIER",
1440
+ "variableTypeTokenRange": {
1441
+ "startIndex": 0,
1442
+ "endIndex": 0
1443
+ }
1444
+ },
1445
+ {
1446
+ "kind": "Variable",
1447
+ "canonicalReference": "@genesislcap/foundation-ai!ANTHROPIC_CACHE_WRITE_1H_MULTIPLIER:var",
1448
+ "docComment": "/**\n * @beta\n */\n",
1449
+ "excerptTokens": [
1450
+ {
1451
+ "kind": "Content",
1452
+ "text": "ANTHROPIC_CACHE_WRITE_1H_MULTIPLIER = "
1453
+ },
1454
+ {
1455
+ "kind": "Content",
1456
+ "text": "2"
1457
+ }
1458
+ ],
1459
+ "fileUrlPath": "src/utils/token-cost.ts",
1460
+ "initializerTokenRange": {
1461
+ "startIndex": 1,
1462
+ "endIndex": 2
1463
+ },
1464
+ "isReadonly": true,
1465
+ "releaseTag": "Beta",
1466
+ "name": "ANTHROPIC_CACHE_WRITE_1H_MULTIPLIER",
1467
+ "variableTypeTokenRange": {
1468
+ "startIndex": 0,
1469
+ "endIndex": 0
1470
+ }
1471
+ },
1472
+ {
1473
+ "kind": "Variable",
1474
+ "canonicalReference": "@genesislcap/foundation-ai!ANTHROPIC_CACHE_WRITE_5M_MULTIPLIER:var",
1475
+ "docComment": "/**\n * @beta\n */\n",
1476
+ "excerptTokens": [
1477
+ {
1478
+ "kind": "Content",
1479
+ "text": "ANTHROPIC_CACHE_WRITE_5M_MULTIPLIER = "
1480
+ },
1481
+ {
1482
+ "kind": "Content",
1483
+ "text": "1.25"
1484
+ }
1485
+ ],
1486
+ "fileUrlPath": "src/utils/token-cost.ts",
1487
+ "initializerTokenRange": {
1488
+ "startIndex": 1,
1489
+ "endIndex": 2
1490
+ },
1491
+ "isReadonly": true,
1492
+ "releaseTag": "Beta",
1493
+ "name": "ANTHROPIC_CACHE_WRITE_5M_MULTIPLIER",
1494
+ "variableTypeTokenRange": {
1495
+ "startIndex": 0,
1496
+ "endIndex": 0
1497
+ }
1498
+ },
1418
1499
  {
1419
1500
  "kind": "Interface",
1420
1501
  "canonicalReference": "@genesislcap/foundation-ai!AnthropicAIConfig:interface",
@@ -2086,6 +2167,117 @@
2086
2167
  }
2087
2168
  ]
2088
2169
  },
2170
+ {
2171
+ "kind": "Function",
2172
+ "canonicalReference": "@genesislcap/foundation-ai!anthropicRatesFor:function(1)",
2173
+ "docComment": "/**\n * Standard tier pricing per million tokens — https://docs.claude.com/en/docs/about-claude/pricing\n *\n * @remarks\n *\n * Backed by a total {@link https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type | Record} over `AnthropicModelId` rather than a chain of checks with a default. That is the whole point: adding a model to `SUPPORTED_ANTHROPIC_MODEL_IDS` without pricing it becomes a COMPILE error instead of a silent charge at whatever the fall-through happened to be — the exact failure this module's header warns about, and one a consumer has already been bitten by. The Gemini half of this file has always had the guarantee; this half now matches.\n *\n * @beta\n */\n",
2174
+ "excerptTokens": [
2175
+ {
2176
+ "kind": "Content",
2177
+ "text": "export declare function anthropicRatesFor(model: "
2178
+ },
2179
+ {
2180
+ "kind": "Reference",
2181
+ "text": "AnthropicModelId",
2182
+ "canonicalReference": "@genesislcap/foundation-ai!AnthropicModelId:type"
2183
+ },
2184
+ {
2185
+ "kind": "Content",
2186
+ "text": "): "
2187
+ },
2188
+ {
2189
+ "kind": "Reference",
2190
+ "text": "TokenRates",
2191
+ "canonicalReference": "@genesislcap/foundation-ai!TokenRates:interface"
2192
+ },
2193
+ {
2194
+ "kind": "Content",
2195
+ "text": ";"
2196
+ }
2197
+ ],
2198
+ "fileUrlPath": "src/utils/token-cost.ts",
2199
+ "returnTypeTokenRange": {
2200
+ "startIndex": 3,
2201
+ "endIndex": 4
2202
+ },
2203
+ "releaseTag": "Beta",
2204
+ "overloadIndex": 1,
2205
+ "parameters": [
2206
+ {
2207
+ "parameterName": "model",
2208
+ "parameterTypeTokenRange": {
2209
+ "startIndex": 1,
2210
+ "endIndex": 2
2211
+ },
2212
+ "isOptional": false
2213
+ }
2214
+ ],
2215
+ "name": "anthropicRatesFor"
2216
+ },
2217
+ {
2218
+ "kind": "Function",
2219
+ "canonicalReference": "@genesislcap/foundation-ai!anthropicTokenCost:function(1)",
2220
+ "docComment": "/**\n * Cost one Anthropic request.\n *\n * @beta\n */\n",
2221
+ "excerptTokens": [
2222
+ {
2223
+ "kind": "Content",
2224
+ "text": "export declare function anthropicTokenCost(model: "
2225
+ },
2226
+ {
2227
+ "kind": "Reference",
2228
+ "text": "AnthropicModelId",
2229
+ "canonicalReference": "@genesislcap/foundation-ai!AnthropicModelId:type"
2230
+ },
2231
+ {
2232
+ "kind": "Content",
2233
+ "text": ", usage: "
2234
+ },
2235
+ {
2236
+ "kind": "Reference",
2237
+ "text": "AnthropicUsageRecord",
2238
+ "canonicalReference": "@genesislcap/foundation-ai!AnthropicUsageRecord:interface"
2239
+ },
2240
+ {
2241
+ "kind": "Content",
2242
+ "text": "): "
2243
+ },
2244
+ {
2245
+ "kind": "Reference",
2246
+ "text": "TokenCost",
2247
+ "canonicalReference": "@genesislcap/foundation-ai!TokenCost:interface"
2248
+ },
2249
+ {
2250
+ "kind": "Content",
2251
+ "text": ";"
2252
+ }
2253
+ ],
2254
+ "fileUrlPath": "src/utils/token-cost.ts",
2255
+ "returnTypeTokenRange": {
2256
+ "startIndex": 5,
2257
+ "endIndex": 6
2258
+ },
2259
+ "releaseTag": "Beta",
2260
+ "overloadIndex": 1,
2261
+ "parameters": [
2262
+ {
2263
+ "parameterName": "model",
2264
+ "parameterTypeTokenRange": {
2265
+ "startIndex": 1,
2266
+ "endIndex": 2
2267
+ },
2268
+ "isOptional": false
2269
+ },
2270
+ {
2271
+ "parameterName": "usage",
2272
+ "parameterTypeTokenRange": {
2273
+ "startIndex": 3,
2274
+ "endIndex": 4
2275
+ },
2276
+ "isOptional": false
2277
+ }
2278
+ ],
2279
+ "name": "anthropicTokenCost"
2280
+ },
2089
2281
  {
2090
2282
  "kind": "Class",
2091
2283
  "canonicalReference": "@genesislcap/foundation-ai!AnthropicTransport:class",
@@ -2466,86 +2658,55 @@
2466
2658
  ]
2467
2659
  },
2468
2660
  {
2469
- "kind": "Variable",
2470
- "canonicalReference": "@genesislcap/foundation-ai!BUDGETED_VENDORS:var",
2471
- "docComment": "/**\n * The vendors whose spend the ai-service proxy meters — i.e. the only vendors that can raise a {@link BudgetExhaustedError}, and therefore the only ones a 402's `otherVendorAvailable: false` is a statement about.\n *\n * Deliberately narrower than the keys of {@link VENDOR_LABELS}, and it must stay exactly the proxy's own list — `VENDORS` in ai-service's `utils/aiVendor.js`. A vendor listed here that the proxy does not meter gets walled by the `otherVendorAvailable: false` sweep on a verdict that says nothing about it, and if it is reachable, `blocked` then derives true and locks a composer with headroom left.\n *\n * Two vendors are excluded for that reason: - `chrome` runs on-device — no pot to exhaust, and free. - `openai` is **not budgeted by the proxy**. ai-service rejects it up front with `400 UNSUPPORTED_PROVIDER` (`SUPPORTED_PROVIDERS` in `aiVendor.js`), no `MODEL_PRICING` row names it, and `otherVendorAvailable` is computed over Anthropic and Gemini alone. So it can never raise a 402, and a 402 is never a statement about it.\n *\n * @beta\n */\n",
2472
- "excerptTokens": [
2473
- {
2474
- "kind": "Content",
2475
- "text": "BUDGETED_VENDORS: "
2476
- },
2477
- {
2478
- "kind": "Content",
2479
- "text": "readonly "
2480
- },
2481
- {
2482
- "kind": "Reference",
2483
- "text": "AIProviderType",
2484
- "canonicalReference": "@genesislcap/foundation-ai!AIProviderType:type"
2485
- },
2486
- {
2487
- "kind": "Content",
2488
- "text": "[]"
2489
- }
2490
- ],
2491
- "fileUrlPath": "src/transports/budget-exhausted-error.ts",
2492
- "isReadonly": true,
2493
- "releaseTag": "Beta",
2494
- "name": "BUDGETED_VENDORS",
2495
- "variableTypeTokenRange": {
2496
- "startIndex": 1,
2497
- "endIndex": 4
2498
- }
2499
- },
2500
- {
2501
- "kind": "Class",
2502
- "canonicalReference": "@genesislcap/foundation-ai!BudgetExhaustedError:class",
2503
- "docComment": "/**\n * Thrown when the AI-spend budget for the caller (user, tenant, or project) is exhausted and the ai-service proxy refuses the request outright — HTTP `402` with `code: 'BUDGET_EXCEEDED'`, in either the legacy JSON or the NDJSON framed mode.\n *\n * This is a **terminal, non-transient** condition, in the same family as `ResponseTruncatedError`: no amount of retrying clears it, because nothing about the request is wrong. The budget has to be raised out-of-band before any further call can succeed, so both the transport retry ladder and the driver's transient-retry catch step aside for it and the failure surfaces immediately as the `'budget-exhausted'` `TurnFailureReason`.\n *\n * `budgetUsd`/`spentUsd` are populated from the rejection body when the proxy supplies them (the workstream-C contract does); they are optional because a plain-text or truncated 402 from an older proxy still has to classify.\n *\n * @beta\n */\n",
2661
+ "kind": "Interface",
2662
+ "canonicalReference": "@genesislcap/foundation-ai!AnthropicUsageRecord:interface",
2663
+ "docComment": "/**\n * Token counts from an Anthropic `usage` block.\n *\n * @remarks\n *\n * Note the input semantics, which are the opposite of Gemini's: `input_tokens` on this provider is the **uncached remainder**, so the three input buckets ADD to the prompt total rather than breaking it down.\n *\n * @beta\n */\n",
2504
2664
  "excerptTokens": [
2505
2665
  {
2506
2666
  "kind": "Content",
2507
- "text": "export declare class BudgetExhaustedError extends "
2508
- },
2509
- {
2510
- "kind": "Reference",
2511
- "text": "Error",
2512
- "canonicalReference": "!Error:interface"
2513
- },
2514
- {
2515
- "kind": "Content",
2516
- "text": " "
2667
+ "text": "export interface AnthropicUsageRecord "
2517
2668
  }
2518
2669
  ],
2519
- "fileUrlPath": "src/transports/budget-exhausted-error.ts",
2670
+ "fileUrlPath": "src/utils/token-cost.ts",
2520
2671
  "releaseTag": "Beta",
2521
- "isAbstract": false,
2522
- "name": "BudgetExhaustedError",
2672
+ "name": "AnthropicUsageRecord",
2523
2673
  "preserveMemberOrder": false,
2524
2674
  "members": [
2525
2675
  {
2526
- "kind": "Constructor",
2527
- "canonicalReference": "@genesislcap/foundation-ai!BudgetExhaustedError:constructor(1)",
2528
- "docComment": "/**\n * Constructs a new instance of the `BudgetExhaustedError` class\n */\n",
2676
+ "kind": "PropertySignature",
2677
+ "canonicalReference": "@genesislcap/foundation-ai!AnthropicUsageRecord#cacheReadTokens:member",
2678
+ "docComment": "/**\n * `usage.cache_read_input_tokens`.\n */\n",
2529
2679
  "excerptTokens": [
2530
2680
  {
2531
2681
  "kind": "Content",
2532
- "text": "constructor(\n vendorLabel: "
2533
- },
2534
- {
2535
- "kind": "Content",
2536
- "text": "string"
2682
+ "text": "cacheReadTokens: "
2537
2683
  },
2538
2684
  {
2539
2685
  "kind": "Content",
2540
- "text": ", \n budgetUsd?: "
2686
+ "text": "number"
2541
2687
  },
2542
2688
  {
2543
2689
  "kind": "Content",
2544
- "text": "number"
2545
- },
2690
+ "text": ";"
2691
+ }
2692
+ ],
2693
+ "isReadonly": false,
2694
+ "isOptional": false,
2695
+ "releaseTag": "Beta",
2696
+ "name": "cacheReadTokens",
2697
+ "propertyTypeTokenRange": {
2698
+ "startIndex": 1,
2699
+ "endIndex": 2
2700
+ }
2701
+ },
2702
+ {
2703
+ "kind": "PropertySignature",
2704
+ "canonicalReference": "@genesislcap/foundation-ai!AnthropicUsageRecord#cacheWrite1hTokens:member",
2705
+ "docComment": "/**\n * `usage.cache_creation.ephemeral_1h_input_tokens` — the 1-hour portion of {@link AnthropicUsageRecord.cacheWriteTokens}. The remainder is treated as 5-minute, which is also the correct fallback when a response omits the per-TTL breakdown entirely.\n *\n * Pass `0` if unknown. Doing so under-bills a request that really did write to the 1-hour cache — by the difference between the two multipliers — so prefer reading the breakdown when the provider sends one.\n */\n",
2706
+ "excerptTokens": [
2546
2707
  {
2547
2708
  "kind": "Content",
2548
- "text": ", \n spentUsd?: "
2709
+ "text": "cacheWrite1hTokens: "
2549
2710
  },
2550
2711
  {
2551
2712
  "kind": "Content",
@@ -2553,19 +2714,203 @@
2553
2714
  },
2554
2715
  {
2555
2716
  "kind": "Content",
2556
- "text": ", \n detail?: "
2557
- },
2717
+ "text": ";"
2718
+ }
2719
+ ],
2720
+ "isReadonly": false,
2721
+ "isOptional": false,
2722
+ "releaseTag": "Beta",
2723
+ "name": "cacheWrite1hTokens",
2724
+ "propertyTypeTokenRange": {
2725
+ "startIndex": 1,
2726
+ "endIndex": 2
2727
+ }
2728
+ },
2729
+ {
2730
+ "kind": "PropertySignature",
2731
+ "canonicalReference": "@genesislcap/foundation-ai!AnthropicUsageRecord#cacheWriteTokens:member",
2732
+ "docComment": "/**\n * `usage.cache_creation_input_tokens` — the total across BOTH TTLs.\n */\n",
2733
+ "excerptTokens": [
2558
2734
  {
2559
2735
  "kind": "Content",
2560
- "text": "string"
2736
+ "text": "cacheWriteTokens: "
2561
2737
  },
2562
2738
  {
2563
2739
  "kind": "Content",
2564
- "text": ", \n extra?: "
2740
+ "text": "number"
2565
2741
  },
2566
2742
  {
2567
2743
  "kind": "Content",
2568
- "text": "{\n otherVendorAvailable?: boolean;\n serverVendor?: string;\n }"
2744
+ "text": ";"
2745
+ }
2746
+ ],
2747
+ "isReadonly": false,
2748
+ "isOptional": false,
2749
+ "releaseTag": "Beta",
2750
+ "name": "cacheWriteTokens",
2751
+ "propertyTypeTokenRange": {
2752
+ "startIndex": 1,
2753
+ "endIndex": 2
2754
+ }
2755
+ },
2756
+ {
2757
+ "kind": "PropertySignature",
2758
+ "canonicalReference": "@genesislcap/foundation-ai!AnthropicUsageRecord#outputTokens:member",
2759
+ "docComment": "/**\n * `usage.output_tokens`. Includes thinking tokens, which this provider bills as output.\n */\n",
2760
+ "excerptTokens": [
2761
+ {
2762
+ "kind": "Content",
2763
+ "text": "outputTokens: "
2764
+ },
2765
+ {
2766
+ "kind": "Content",
2767
+ "text": "number"
2768
+ },
2769
+ {
2770
+ "kind": "Content",
2771
+ "text": ";"
2772
+ }
2773
+ ],
2774
+ "isReadonly": false,
2775
+ "isOptional": false,
2776
+ "releaseTag": "Beta",
2777
+ "name": "outputTokens",
2778
+ "propertyTypeTokenRange": {
2779
+ "startIndex": 1,
2780
+ "endIndex": 2
2781
+ }
2782
+ },
2783
+ {
2784
+ "kind": "PropertySignature",
2785
+ "canonicalReference": "@genesislcap/foundation-ai!AnthropicUsageRecord#uncachedInputTokens:member",
2786
+ "docComment": "/**\n * `usage.input_tokens` — the uncached remainder of the prompt, billed at full rate.\n */\n",
2787
+ "excerptTokens": [
2788
+ {
2789
+ "kind": "Content",
2790
+ "text": "uncachedInputTokens: "
2791
+ },
2792
+ {
2793
+ "kind": "Content",
2794
+ "text": "number"
2795
+ },
2796
+ {
2797
+ "kind": "Content",
2798
+ "text": ";"
2799
+ }
2800
+ ],
2801
+ "isReadonly": false,
2802
+ "isOptional": false,
2803
+ "releaseTag": "Beta",
2804
+ "name": "uncachedInputTokens",
2805
+ "propertyTypeTokenRange": {
2806
+ "startIndex": 1,
2807
+ "endIndex": 2
2808
+ }
2809
+ }
2810
+ ],
2811
+ "extendsTokenRanges": []
2812
+ },
2813
+ {
2814
+ "kind": "Variable",
2815
+ "canonicalReference": "@genesislcap/foundation-ai!BUDGETED_VENDORS:var",
2816
+ "docComment": "/**\n * The vendors whose spend the ai-service proxy meters — i.e. the only vendors that can raise a {@link BudgetExhaustedError}, and therefore the only ones a 402's `otherVendorAvailable: false` is a statement about.\n *\n * Deliberately narrower than the keys of {@link VENDOR_LABELS}, and it must stay exactly the proxy's own list — `VENDORS` in ai-service's `utils/aiVendor.js`. A vendor listed here that the proxy does not meter gets walled by the `otherVendorAvailable: false` sweep on a verdict that says nothing about it, and if it is reachable, `blocked` then derives true and locks a composer with headroom left.\n *\n * Two vendors are excluded for that reason: - `chrome` runs on-device — no pot to exhaust, and free. - `openai` is **not budgeted by the proxy**. ai-service rejects it up front with `400 UNSUPPORTED_PROVIDER` (`SUPPORTED_PROVIDERS` in `aiVendor.js`), no `MODEL_PRICING` row names it, and `otherVendorAvailable` is computed over Anthropic and Gemini alone. So it can never raise a 402, and a 402 is never a statement about it.\n *\n * @beta\n */\n",
2817
+ "excerptTokens": [
2818
+ {
2819
+ "kind": "Content",
2820
+ "text": "BUDGETED_VENDORS: "
2821
+ },
2822
+ {
2823
+ "kind": "Content",
2824
+ "text": "readonly "
2825
+ },
2826
+ {
2827
+ "kind": "Reference",
2828
+ "text": "AIProviderType",
2829
+ "canonicalReference": "@genesislcap/foundation-ai!AIProviderType:type"
2830
+ },
2831
+ {
2832
+ "kind": "Content",
2833
+ "text": "[]"
2834
+ }
2835
+ ],
2836
+ "fileUrlPath": "src/transports/budget-exhausted-error.ts",
2837
+ "isReadonly": true,
2838
+ "releaseTag": "Beta",
2839
+ "name": "BUDGETED_VENDORS",
2840
+ "variableTypeTokenRange": {
2841
+ "startIndex": 1,
2842
+ "endIndex": 4
2843
+ }
2844
+ },
2845
+ {
2846
+ "kind": "Class",
2847
+ "canonicalReference": "@genesislcap/foundation-ai!BudgetExhaustedError:class",
2848
+ "docComment": "/**\n * Thrown when the AI-spend budget for the caller (user, tenant, or project) is exhausted and the ai-service proxy refuses the request outright — HTTP `402` with `code: 'BUDGET_EXCEEDED'`, in either the legacy JSON or the NDJSON framed mode.\n *\n * This is a **terminal, non-transient** condition, in the same family as `ResponseTruncatedError`: no amount of retrying clears it, because nothing about the request is wrong. The budget has to be raised out-of-band before any further call can succeed, so both the transport retry ladder and the driver's transient-retry catch step aside for it and the failure surfaces immediately as the `'budget-exhausted'` `TurnFailureReason`.\n *\n * `budgetUsd`/`spentUsd` are populated from the rejection body when the proxy supplies them (the workstream-C contract does); they are optional because a plain-text or truncated 402 from an older proxy still has to classify.\n *\n * @beta\n */\n",
2849
+ "excerptTokens": [
2850
+ {
2851
+ "kind": "Content",
2852
+ "text": "export declare class BudgetExhaustedError extends "
2853
+ },
2854
+ {
2855
+ "kind": "Reference",
2856
+ "text": "Error",
2857
+ "canonicalReference": "!Error:interface"
2858
+ },
2859
+ {
2860
+ "kind": "Content",
2861
+ "text": " "
2862
+ }
2863
+ ],
2864
+ "fileUrlPath": "src/transports/budget-exhausted-error.ts",
2865
+ "releaseTag": "Beta",
2866
+ "isAbstract": false,
2867
+ "name": "BudgetExhaustedError",
2868
+ "preserveMemberOrder": false,
2869
+ "members": [
2870
+ {
2871
+ "kind": "Constructor",
2872
+ "canonicalReference": "@genesislcap/foundation-ai!BudgetExhaustedError:constructor(1)",
2873
+ "docComment": "/**\n * Constructs a new instance of the `BudgetExhaustedError` class\n */\n",
2874
+ "excerptTokens": [
2875
+ {
2876
+ "kind": "Content",
2877
+ "text": "constructor(\n vendorLabel: "
2878
+ },
2879
+ {
2880
+ "kind": "Content",
2881
+ "text": "string"
2882
+ },
2883
+ {
2884
+ "kind": "Content",
2885
+ "text": ", \n budgetUsd?: "
2886
+ },
2887
+ {
2888
+ "kind": "Content",
2889
+ "text": "number"
2890
+ },
2891
+ {
2892
+ "kind": "Content",
2893
+ "text": ", \n spentUsd?: "
2894
+ },
2895
+ {
2896
+ "kind": "Content",
2897
+ "text": "number"
2898
+ },
2899
+ {
2900
+ "kind": "Content",
2901
+ "text": ", \n detail?: "
2902
+ },
2903
+ {
2904
+ "kind": "Content",
2905
+ "text": "string"
2906
+ },
2907
+ {
2908
+ "kind": "Content",
2909
+ "text": ", \n extra?: "
2910
+ },
2911
+ {
2912
+ "kind": "Content",
2913
+ "text": "{\n otherVendorAvailable?: boolean;\n serverVendor?: string;\n }"
2569
2914
  },
2570
2915
  {
2571
2916
  "kind": "Content",
@@ -4079,7 +4424,7 @@
4079
4424
  {
4080
4425
  "kind": "PropertySignature",
4081
4426
  "canonicalReference": "@genesislcap/foundation-ai!ChatMessage#cacheWriteTokens:member",
4082
- "docComment": "/**\n * Prompt tokens written to the provider's cache for the request that produced this message — billed at a premium over the uncached rate.\n *\n * Like {@link ChatMessage.cacheReadTokens}, a breakdown of {@link ChatMessage.inputTokens} rather than an addition to it. `undefined` where the provider reports no distinct write bucket (e.g. Gemini's implicit caching) — read it with `?? 0`.\n */\n",
4427
+ "docComment": "/**\n * Prompt tokens written to the provider's cache for the request that produced this message — billed at a premium over the uncached rate.\n *\n * Like {@link ChatMessage.cacheReadTokens}, a breakdown of {@link ChatMessage.inputTokens} rather than an addition to it. `undefined` where the provider reports no distinct write bucket (e.g. Gemini's implicit caching) — read it with `?? 0`.\n *\n * **A volume figure, not a pricing input — do not re-price it.** Anthropic bills cache writes by TTL (5-minute and 1-hour at different multiples of the input rate) and this field is the combined total, so the split needed to cost it is not recoverable from a stored message. Pricing this bucket therefore under-bills a 1-hour write, silently and in the cheap direction. {@link ChatMessage.cost} is the authoritative figure: the transport computed it from the per-TTL breakdown before that breakdown was collapsed to this total.\n *\n * A host that genuinely must compute a cost itself — a proxy holding a raw provider usage block, where nothing stamped one — should price from that raw block instead, which carries the split.\n */\n",
4083
4428
  "excerptTokens": [
4084
4429
  {
4085
4430
  "kind": "Content",
@@ -4188,7 +4533,7 @@
4188
4533
  {
4189
4534
  "kind": "PropertySignature",
4190
4535
  "canonicalReference": "@genesislcap/foundation-ai!ChatMessage#cost:member",
4191
- "docComment": "/**\n * Estimated USD cost for the single request that produced this message, derived from the active model's input/output rates. Set by transports. Hosts can sum this across the message list to display a running session cost without re-deriving rates.\n */\n",
4536
+ "docComment": "/**\n * Estimated USD cost for the single request that produced this message, derived from the active model's input/output rates. Set by transports. Hosts can sum this across the message list to display a running session cost without re-deriving rates.\n *\n * @remarks\n *\n * **The authoritative cost for this request.** Computed at the transport, at the one point where the full provider usage is in hand — including Anthropic's per-TTL cache-write breakdown, which the token fields on this message do not preserve. Prefer it over any figure re-derived from those fields, which cannot be exact and is wrong in the direction that under-reports spend.\n *\n * Already carries every cache discount and premium, so a cache-heavy request shows a small `cost` against a large token count — that is the discount working, not a missing charge.\n *\n * **When a server-side fallback chain ran, this and the token fields have different scopes.** `cost` sums every *billed* attempt, possibly across models at different rates, while `inputTokens` / `outputTokens` / the cache buckets describe only the attempt that produced the content. So such a turn can carry cost with no volume behind it to explain the difference — a $/token column or a \"cost without tokens\" audit will see an outlier that is correct. Read `cost` as the bill and the token fields as the size of the answer, not as two views of one thing.\n */\n",
4192
4537
  "excerptTokens": [
4193
4538
  {
4194
4539
  "kind": "Content",
@@ -4846,6 +5191,34 @@
4846
5191
  "endIndex": 2
4847
5192
  }
4848
5193
  },
5194
+ {
5195
+ "kind": "PropertySignature",
5196
+ "canonicalReference": "@genesislcap/foundation-ai!ChatRequestOptions#thinkingPolicy:member",
5197
+ "docComment": "/**\n * Extended-thinking posture for this turn. **Omit** to keep each model's own default — that is the third state, and it is not the same as either value. See {@link ChatThinkingPolicy}.\n *\n * @beta\n */\n",
5198
+ "excerptTokens": [
5199
+ {
5200
+ "kind": "Content",
5201
+ "text": "thinkingPolicy?: "
5202
+ },
5203
+ {
5204
+ "kind": "Reference",
5205
+ "text": "ChatThinkingPolicy",
5206
+ "canonicalReference": "@genesislcap/foundation-ai!ChatThinkingPolicy:type"
5207
+ },
5208
+ {
5209
+ "kind": "Content",
5210
+ "text": ";"
5211
+ }
5212
+ ],
5213
+ "isReadonly": false,
5214
+ "isOptional": true,
5215
+ "releaseTag": "Beta",
5216
+ "name": "thinkingPolicy",
5217
+ "propertyTypeTokenRange": {
5218
+ "startIndex": 1,
5219
+ "endIndex": 2
5220
+ }
5221
+ },
4849
5222
  {
4850
5223
  "kind": "PropertySignature",
4851
5224
  "canonicalReference": "@genesislcap/foundation-ai!ChatRequestOptions#toolChoice:member",
@@ -5214,6 +5587,32 @@
5214
5587
  "endIndex": 2
5215
5588
  }
5216
5589
  },
5590
+ {
5591
+ "kind": "TypeAlias",
5592
+ "canonicalReference": "@genesislcap/foundation-ai!ChatThinkingPolicy:type",
5593
+ "docComment": "/**\n * Whether the model should reason before answering, resolved per turn. **Provider-neutral intent, provider-specific effect**, and — like `tool_choice` — a *request*, not a guarantee: a model that cannot honour it keeps its default.\n *\n * - `'auto'` — the model decides how much to think (Anthropic `thinking: {type:'adaptive'}`, Gemini `thinkingConfig.thinkingBudget: -1`). On a model whose default is thinking-*off* this turns it **on**, which is the point: it is the opt-in for models where adaptive thinking is available but not default. - `'off'` — no reasoning tokens (Anthropic `thinking: {type:'disabled'}`, Gemini `thinkingBudget: 0`). The lever for turns that only step a known sequence, where reasoning is billed as output at the full candidate rate to decide something already determined.\n *\n * **Choose it per turn, not per model call.** A tool-use loop is one assistant turn, and Anthropic requires a single thinking mode for its duration; toggling part-way through does not error but silently disables thinking for that request, strips blocks that would leave the turn structure invalid, and invalidates the prompt cache. The driver pins whatever it resolves on a turn's first model call for the rest of that turn.\n *\n * Deliberately has **no token-budget member**. Gemini accepts a numeric `thinkingBudget`, but Anthropic *removed* `budget_tokens` and returns a 400 for it on Sonnet 5 and every Opus 5-era model — so a budget field would be unimplementable on half the supported fleet and would exist only to be ignored. `'low' | 'high'` can be added later if wanted: Anthropic `effort` and Gemini `thinkingLevel` do line up.\n *\n * **Omitting this is a distinct third state** — each model keeps its own default posture (see `anthropicThinking`), which is *not* uniformly `'auto'` or `'off'`. So a resolver returning `undefined` on some turns leaves those turns exactly as they were before this option existed, rather than silently re-pricing them.\n *\n * Not every model can honour every value, and the two providers hit the same wall at the top of their ranges: Anthropic Fable 5 and Gemini 2.5 Pro both think unconditionally and reject (or ignore) a request to stop. Transports **clamp** rather than forward a request that would 400 — the turn runs at the model's default and a one-time warning is logged. Never assume `'off'` means zero reasoning tokens were billed; read the usage back.\n *\n * @beta\n */\n",
5594
+ "excerptTokens": [
5595
+ {
5596
+ "kind": "Content",
5597
+ "text": "export type ChatThinkingPolicy = "
5598
+ },
5599
+ {
5600
+ "kind": "Content",
5601
+ "text": "'auto' | 'off'"
5602
+ },
5603
+ {
5604
+ "kind": "Content",
5605
+ "text": ";"
5606
+ }
5607
+ ],
5608
+ "fileUrlPath": "src/types/chat.types.ts",
5609
+ "releaseTag": "Beta",
5610
+ "name": "ChatThinkingPolicy",
5611
+ "typeTokenRange": {
5612
+ "startIndex": 1,
5613
+ "endIndex": 2
5614
+ }
5615
+ },
5217
5616
  {
5218
5617
  "kind": "TypeAlias",
5219
5618
  "canonicalReference": "@genesislcap/foundation-ai!ChatToolCall:type",
@@ -7120,6 +7519,60 @@
7120
7519
  "endIndex": 2
7121
7520
  }
7122
7521
  },
7522
+ {
7523
+ "kind": "Variable",
7524
+ "canonicalReference": "@genesislcap/foundation-ai!GEMINI_CACHED_INPUT_MULTIPLIER:var",
7525
+ "docComment": "/**\n * Cached / context-cache input tokens bill at a flat ~10% of the model's normal input rate — consistent across models (flash $0.30→$0.03, flash-lite $0.10→$0.01, pro $1.25→$0.125). Source: https://ai.google.dev/gemini-api/docs/pricing. (Explicit context caching also has an hourly storage fee; implicit caching — what the transport relies on — has none, so only this read discount applies. There is no write premium on this provider, which is why its savings figure is never negative.)\n *\n * @beta\n */\n",
7526
+ "excerptTokens": [
7527
+ {
7528
+ "kind": "Content",
7529
+ "text": "GEMINI_CACHED_INPUT_MULTIPLIER = "
7530
+ },
7531
+ {
7532
+ "kind": "Content",
7533
+ "text": "0.1"
7534
+ }
7535
+ ],
7536
+ "fileUrlPath": "src/utils/token-cost.ts",
7537
+ "initializerTokenRange": {
7538
+ "startIndex": 1,
7539
+ "endIndex": 2
7540
+ },
7541
+ "isReadonly": true,
7542
+ "releaseTag": "Beta",
7543
+ "name": "GEMINI_CACHED_INPUT_MULTIPLIER",
7544
+ "variableTypeTokenRange": {
7545
+ "startIndex": 0,
7546
+ "endIndex": 0
7547
+ }
7548
+ },
7549
+ {
7550
+ "kind": "Variable",
7551
+ "canonicalReference": "@genesislcap/foundation-ai!GEMINI_LONG_CONTEXT_THRESHOLD:var",
7552
+ "docComment": "/**\n * Prompt size (tokens) at or below which the standard pricing tier applies. Above it, Gemini's long-context tier kicks in. Google applies a single tier to the whole request based on prompt size — it is not a marginal/blended rate.\n *\n * @beta\n */\n",
7553
+ "excerptTokens": [
7554
+ {
7555
+ "kind": "Content",
7556
+ "text": "GEMINI_LONG_CONTEXT_THRESHOLD = "
7557
+ },
7558
+ {
7559
+ "kind": "Content",
7560
+ "text": "200000"
7561
+ }
7562
+ ],
7563
+ "fileUrlPath": "src/utils/token-cost.ts",
7564
+ "initializerTokenRange": {
7565
+ "startIndex": 1,
7566
+ "endIndex": 2
7567
+ },
7568
+ "isReadonly": true,
7569
+ "releaseTag": "Beta",
7570
+ "name": "GEMINI_LONG_CONTEXT_THRESHOLD",
7571
+ "variableTypeTokenRange": {
7572
+ "startIndex": 0,
7573
+ "endIndex": 0
7574
+ }
7575
+ },
7123
7576
  {
7124
7577
  "kind": "Interface",
7125
7578
  "canonicalReference": "@genesislcap/foundation-ai!GeminiAIConfig:interface",
@@ -7765,13 +8218,140 @@
7765
8218
  ]
7766
8219
  },
7767
8220
  {
7768
- "kind": "Class",
7769
- "canonicalReference": "@genesislcap/foundation-ai!GeminiTransport:class",
7770
- "docComment": "/**\n * Transport for Gemini. Calls the Gemini REST API directly when `apiKey` is provided, otherwise falls back to a server-proxy endpoint (if `serverEndpoint` is configured).\n *\n * Implements `AITransport` (structured prompt) and `ChatTransport` (multi-turn chat).\n *\n * @beta\n */\n",
8221
+ "kind": "Function",
8222
+ "canonicalReference": "@genesislcap/foundation-ai!geminiRatesFor:function(1)",
8223
+ "docComment": "/**\n * Resolve the per-million-token rates for a model given the request's prompt size, selecting the long-context tier for tiered models when the prompt exceeds {@link GEMINI_LONG_CONTEXT_THRESHOLD}.\n *\n * @remarks\n *\n * `promptTokens` must be the **full** prompt size, cached slice included — the tier is chosen on what was sent, not on what was billed at full rate. A mostly-cached long prompt is still a long prompt.\n *\n * Unlike Anthropic's, this accessor is not a pure function of the model, which is why there is no single `ratesFor(model)` across both providers.\n *\n * @beta\n */\n",
7771
8224
  "excerptTokens": [
7772
8225
  {
7773
8226
  "kind": "Content",
7774
- "text": "export declare class GeminiTransport implements "
8227
+ "text": "export declare function geminiRatesFor(model: "
8228
+ },
8229
+ {
8230
+ "kind": "Reference",
8231
+ "text": "GeminiModelId",
8232
+ "canonicalReference": "@genesislcap/foundation-ai!GeminiModelId:type"
8233
+ },
8234
+ {
8235
+ "kind": "Content",
8236
+ "text": ", promptTokens: "
8237
+ },
8238
+ {
8239
+ "kind": "Content",
8240
+ "text": "number"
8241
+ },
8242
+ {
8243
+ "kind": "Content",
8244
+ "text": "): "
8245
+ },
8246
+ {
8247
+ "kind": "Reference",
8248
+ "text": "TokenRates",
8249
+ "canonicalReference": "@genesislcap/foundation-ai!TokenRates:interface"
8250
+ },
8251
+ {
8252
+ "kind": "Content",
8253
+ "text": ";"
8254
+ }
8255
+ ],
8256
+ "fileUrlPath": "src/utils/token-cost.ts",
8257
+ "returnTypeTokenRange": {
8258
+ "startIndex": 5,
8259
+ "endIndex": 6
8260
+ },
8261
+ "releaseTag": "Beta",
8262
+ "overloadIndex": 1,
8263
+ "parameters": [
8264
+ {
8265
+ "parameterName": "model",
8266
+ "parameterTypeTokenRange": {
8267
+ "startIndex": 1,
8268
+ "endIndex": 2
8269
+ },
8270
+ "isOptional": false
8271
+ },
8272
+ {
8273
+ "parameterName": "promptTokens",
8274
+ "parameterTypeTokenRange": {
8275
+ "startIndex": 3,
8276
+ "endIndex": 4
8277
+ },
8278
+ "isOptional": false
8279
+ }
8280
+ ],
8281
+ "name": "geminiRatesFor"
8282
+ },
8283
+ {
8284
+ "kind": "Function",
8285
+ "canonicalReference": "@genesislcap/foundation-ai!geminiTokenCost:function(1)",
8286
+ "docComment": "/**\n * Cost one Gemini request.\n *\n * @beta\n */\n",
8287
+ "excerptTokens": [
8288
+ {
8289
+ "kind": "Content",
8290
+ "text": "export declare function geminiTokenCost(model: "
8291
+ },
8292
+ {
8293
+ "kind": "Reference",
8294
+ "text": "GeminiModelId",
8295
+ "canonicalReference": "@genesislcap/foundation-ai!GeminiModelId:type"
8296
+ },
8297
+ {
8298
+ "kind": "Content",
8299
+ "text": ", usage: "
8300
+ },
8301
+ {
8302
+ "kind": "Reference",
8303
+ "text": "GeminiUsageRecord",
8304
+ "canonicalReference": "@genesislcap/foundation-ai!GeminiUsageRecord:interface"
8305
+ },
8306
+ {
8307
+ "kind": "Content",
8308
+ "text": "): "
8309
+ },
8310
+ {
8311
+ "kind": "Reference",
8312
+ "text": "TokenCost",
8313
+ "canonicalReference": "@genesislcap/foundation-ai!TokenCost:interface"
8314
+ },
8315
+ {
8316
+ "kind": "Content",
8317
+ "text": ";"
8318
+ }
8319
+ ],
8320
+ "fileUrlPath": "src/utils/token-cost.ts",
8321
+ "returnTypeTokenRange": {
8322
+ "startIndex": 5,
8323
+ "endIndex": 6
8324
+ },
8325
+ "releaseTag": "Beta",
8326
+ "overloadIndex": 1,
8327
+ "parameters": [
8328
+ {
8329
+ "parameterName": "model",
8330
+ "parameterTypeTokenRange": {
8331
+ "startIndex": 1,
8332
+ "endIndex": 2
8333
+ },
8334
+ "isOptional": false
8335
+ },
8336
+ {
8337
+ "parameterName": "usage",
8338
+ "parameterTypeTokenRange": {
8339
+ "startIndex": 3,
8340
+ "endIndex": 4
8341
+ },
8342
+ "isOptional": false
8343
+ }
8344
+ ],
8345
+ "name": "geminiTokenCost"
8346
+ },
8347
+ {
8348
+ "kind": "Class",
8349
+ "canonicalReference": "@genesislcap/foundation-ai!GeminiTransport:class",
8350
+ "docComment": "/**\n * Transport for Gemini. Calls the Gemini REST API directly when `apiKey` is provided, otherwise falls back to a server-proxy endpoint (if `serverEndpoint` is configured).\n *\n * Implements `AITransport` (structured prompt) and `ChatTransport` (multi-turn chat).\n *\n * @beta\n */\n",
8351
+ "excerptTokens": [
8352
+ {
8353
+ "kind": "Content",
8354
+ "text": "export declare class GeminiTransport implements "
7775
8355
  },
7776
8356
  {
7777
8357
  "kind": "Reference",
@@ -8143,6 +8723,132 @@
8143
8723
  }
8144
8724
  ]
8145
8725
  },
8726
+ {
8727
+ "kind": "Interface",
8728
+ "canonicalReference": "@genesislcap/foundation-ai!GeminiUsageRecord:interface",
8729
+ "docComment": "/**\n * Token counts from a Gemini `usageMetadata` block.\n *\n * @remarks\n *\n * Note the input semantics, which are the opposite of Anthropic's: `promptTokenCount` is the **whole** prompt and already includes `cachedContentTokenCount`, so uncached input is a subtraction. Adding the buckets instead double-charges the cached portion.\n *\n * @beta\n */\n",
8730
+ "excerptTokens": [
8731
+ {
8732
+ "kind": "Content",
8733
+ "text": "export interface GeminiUsageRecord "
8734
+ }
8735
+ ],
8736
+ "fileUrlPath": "src/utils/token-cost.ts",
8737
+ "releaseTag": "Beta",
8738
+ "name": "GeminiUsageRecord",
8739
+ "preserveMemberOrder": false,
8740
+ "members": [
8741
+ {
8742
+ "kind": "PropertySignature",
8743
+ "canonicalReference": "@genesislcap/foundation-ai!GeminiUsageRecord#cachedTokens:member",
8744
+ "docComment": "/**\n * `usageMetadata.cachedContentTokenCount` — 0 when caching was not active.\n */\n",
8745
+ "excerptTokens": [
8746
+ {
8747
+ "kind": "Content",
8748
+ "text": "cachedTokens: "
8749
+ },
8750
+ {
8751
+ "kind": "Content",
8752
+ "text": "number"
8753
+ },
8754
+ {
8755
+ "kind": "Content",
8756
+ "text": ";"
8757
+ }
8758
+ ],
8759
+ "isReadonly": false,
8760
+ "isOptional": false,
8761
+ "releaseTag": "Beta",
8762
+ "name": "cachedTokens",
8763
+ "propertyTypeTokenRange": {
8764
+ "startIndex": 1,
8765
+ "endIndex": 2
8766
+ }
8767
+ },
8768
+ {
8769
+ "kind": "PropertySignature",
8770
+ "canonicalReference": "@genesislcap/foundation-ai!GeminiUsageRecord#candidateTokens:member",
8771
+ "docComment": "/**\n * `usageMetadata.candidatesTokenCount`.\n */\n",
8772
+ "excerptTokens": [
8773
+ {
8774
+ "kind": "Content",
8775
+ "text": "candidateTokens: "
8776
+ },
8777
+ {
8778
+ "kind": "Content",
8779
+ "text": "number"
8780
+ },
8781
+ {
8782
+ "kind": "Content",
8783
+ "text": ";"
8784
+ }
8785
+ ],
8786
+ "isReadonly": false,
8787
+ "isOptional": false,
8788
+ "releaseTag": "Beta",
8789
+ "name": "candidateTokens",
8790
+ "propertyTypeTokenRange": {
8791
+ "startIndex": 1,
8792
+ "endIndex": 2
8793
+ }
8794
+ },
8795
+ {
8796
+ "kind": "PropertySignature",
8797
+ "canonicalReference": "@genesislcap/foundation-ai!GeminiUsageRecord#promptTokens:member",
8798
+ "docComment": "/**\n * `usageMetadata.promptTokenCount` — the whole prompt, cached slice INCLUDED.\n */\n",
8799
+ "excerptTokens": [
8800
+ {
8801
+ "kind": "Content",
8802
+ "text": "promptTokens: "
8803
+ },
8804
+ {
8805
+ "kind": "Content",
8806
+ "text": "number"
8807
+ },
8808
+ {
8809
+ "kind": "Content",
8810
+ "text": ";"
8811
+ }
8812
+ ],
8813
+ "isReadonly": false,
8814
+ "isOptional": false,
8815
+ "releaseTag": "Beta",
8816
+ "name": "promptTokens",
8817
+ "propertyTypeTokenRange": {
8818
+ "startIndex": 1,
8819
+ "endIndex": 2
8820
+ }
8821
+ },
8822
+ {
8823
+ "kind": "PropertySignature",
8824
+ "canonicalReference": "@genesislcap/foundation-ai!GeminiUsageRecord#thoughtTokens:member",
8825
+ "docComment": "/**\n * `usageMetadata.thoughtsTokenCount`. Reported separately from candidates but billed at the candidate rate, so omitting it undercounts the bill.\n */\n",
8826
+ "excerptTokens": [
8827
+ {
8828
+ "kind": "Content",
8829
+ "text": "thoughtTokens: "
8830
+ },
8831
+ {
8832
+ "kind": "Content",
8833
+ "text": "number"
8834
+ },
8835
+ {
8836
+ "kind": "Content",
8837
+ "text": ";"
8838
+ }
8839
+ ],
8840
+ "isReadonly": false,
8841
+ "isOptional": false,
8842
+ "releaseTag": "Beta",
8843
+ "name": "thoughtTokens",
8844
+ "propertyTypeTokenRange": {
8845
+ "startIndex": 1,
8846
+ "endIndex": 2
8847
+ }
8848
+ }
8849
+ ],
8850
+ "extendsTokenRanges": []
8851
+ },
8146
8852
  {
8147
8853
  "kind": "TypeAlias",
8148
8854
  "canonicalReference": "@genesislcap/foundation-ai!InteractionPresentation:type",
@@ -10476,6 +11182,304 @@
10476
11182
  "endIndex": 4
10477
11183
  }
10478
11184
  },
11185
+ {
11186
+ "kind": "Interface",
11187
+ "canonicalReference": "@genesislcap/foundation-ai!TokenCost:interface",
11188
+ "docComment": "/**\n * What one request cost, and what prompt caching saved on it.\n *\n * @beta\n */\n",
11189
+ "excerptTokens": [
11190
+ {
11191
+ "kind": "Content",
11192
+ "text": "export interface TokenCost "
11193
+ }
11194
+ ],
11195
+ "fileUrlPath": "src/utils/token-cost.ts",
11196
+ "releaseTag": "Beta",
11197
+ "name": "TokenCost",
11198
+ "preserveMemberOrder": false,
11199
+ "members": [
11200
+ {
11201
+ "kind": "PropertySignature",
11202
+ "canonicalReference": "@genesislcap/foundation-ai!TokenCost#breakdown:member",
11203
+ "docComment": "/**\n * The four cost buckets, summing to {@link TokenCost.costUsd}.\n *\n * Reported because a single total cannot show *why* a request was cheap: a cache-heavy call moves a large number of tokens for very little money, and only the split says so. Also what a per-call usage row needs, rather than the one number a dashboard would have to explain.\n */\n",
11204
+ "excerptTokens": [
11205
+ {
11206
+ "kind": "Content",
11207
+ "text": "breakdown: "
11208
+ },
11209
+ {
11210
+ "kind": "Reference",
11211
+ "text": "TokenCostBreakdown",
11212
+ "canonicalReference": "@genesislcap/foundation-ai!TokenCostBreakdown:interface"
11213
+ },
11214
+ {
11215
+ "kind": "Content",
11216
+ "text": ";"
11217
+ }
11218
+ ],
11219
+ "isReadonly": false,
11220
+ "isOptional": false,
11221
+ "releaseTag": "Beta",
11222
+ "name": "breakdown",
11223
+ "propertyTypeTokenRange": {
11224
+ "startIndex": 1,
11225
+ "endIndex": 2
11226
+ }
11227
+ },
11228
+ {
11229
+ "kind": "PropertySignature",
11230
+ "canonicalReference": "@genesislcap/foundation-ai!TokenCost#costUsd:member",
11231
+ "docComment": "/**\n * Total USD for the request, with every cache discount and premium applied.\n */\n",
11232
+ "excerptTokens": [
11233
+ {
11234
+ "kind": "Content",
11235
+ "text": "costUsd: "
11236
+ },
11237
+ {
11238
+ "kind": "Content",
11239
+ "text": "number"
11240
+ },
11241
+ {
11242
+ "kind": "Content",
11243
+ "text": ";"
11244
+ }
11245
+ ],
11246
+ "isReadonly": false,
11247
+ "isOptional": false,
11248
+ "releaseTag": "Beta",
11249
+ "name": "costUsd",
11250
+ "propertyTypeTokenRange": {
11251
+ "startIndex": 1,
11252
+ "endIndex": 2
11253
+ }
11254
+ },
11255
+ {
11256
+ "kind": "PropertySignature",
11257
+ "canonicalReference": "@genesislcap/foundation-ai!TokenCost#savedUsd:member",
11258
+ "docComment": "/**\n * USD saved versus paying the full input rate for every cached token, net of any cache-write premium.\n *\n * **Can be negative**, and that is not an error: a write premium is an upfront cost that later reads pay back, so a cold write-heavy request legitimately reports a loss. Clamping it at zero destroys the signal that a cache is being written more often than it is read.\n */\n",
11259
+ "excerptTokens": [
11260
+ {
11261
+ "kind": "Content",
11262
+ "text": "savedUsd: "
11263
+ },
11264
+ {
11265
+ "kind": "Content",
11266
+ "text": "number"
11267
+ },
11268
+ {
11269
+ "kind": "Content",
11270
+ "text": ";"
11271
+ }
11272
+ ],
11273
+ "isReadonly": false,
11274
+ "isOptional": false,
11275
+ "releaseTag": "Beta",
11276
+ "name": "savedUsd",
11277
+ "propertyTypeTokenRange": {
11278
+ "startIndex": 1,
11279
+ "endIndex": 2
11280
+ }
11281
+ }
11282
+ ],
11283
+ "extendsTokenRanges": []
11284
+ },
11285
+ {
11286
+ "kind": "Interface",
11287
+ "canonicalReference": "@genesislcap/foundation-ai!TokenCostBreakdown:interface",
11288
+ "docComment": "/**\n * Per-bucket cost split for one request. Each field is already in USD.\n *\n * @beta\n */\n",
11289
+ "excerptTokens": [
11290
+ {
11291
+ "kind": "Content",
11292
+ "text": "export interface TokenCostBreakdown "
11293
+ }
11294
+ ],
11295
+ "fileUrlPath": "src/utils/token-cost.ts",
11296
+ "releaseTag": "Beta",
11297
+ "name": "TokenCostBreakdown",
11298
+ "preserveMemberOrder": false,
11299
+ "members": [
11300
+ {
11301
+ "kind": "PropertySignature",
11302
+ "canonicalReference": "@genesislcap/foundation-ai!TokenCostBreakdown#cacheReadUsd:member",
11303
+ "docComment": "/**\n * Prompt tokens served from the provider's cache.\n */\n",
11304
+ "excerptTokens": [
11305
+ {
11306
+ "kind": "Content",
11307
+ "text": "cacheReadUsd: "
11308
+ },
11309
+ {
11310
+ "kind": "Content",
11311
+ "text": "number"
11312
+ },
11313
+ {
11314
+ "kind": "Content",
11315
+ "text": ";"
11316
+ }
11317
+ ],
11318
+ "isReadonly": false,
11319
+ "isOptional": false,
11320
+ "releaseTag": "Beta",
11321
+ "name": "cacheReadUsd",
11322
+ "propertyTypeTokenRange": {
11323
+ "startIndex": 1,
11324
+ "endIndex": 2
11325
+ }
11326
+ },
11327
+ {
11328
+ "kind": "PropertySignature",
11329
+ "canonicalReference": "@genesislcap/foundation-ai!TokenCostBreakdown#cacheWriteUsd:member",
11330
+ "docComment": "/**\n * Prompt tokens written to the provider's cache. Always `0` on Gemini, whose implicit caching has no write charge.\n *\n * A per-request charge for *populating* a cache. Not a home for a cache's ongoing storage cost, which is not per-request — see the module header.\n */\n",
11331
+ "excerptTokens": [
11332
+ {
11333
+ "kind": "Content",
11334
+ "text": "cacheWriteUsd: "
11335
+ },
11336
+ {
11337
+ "kind": "Content",
11338
+ "text": "number"
11339
+ },
11340
+ {
11341
+ "kind": "Content",
11342
+ "text": ";"
11343
+ }
11344
+ ],
11345
+ "isReadonly": false,
11346
+ "isOptional": false,
11347
+ "releaseTag": "Beta",
11348
+ "name": "cacheWriteUsd",
11349
+ "propertyTypeTokenRange": {
11350
+ "startIndex": 1,
11351
+ "endIndex": 2
11352
+ }
11353
+ },
11354
+ {
11355
+ "kind": "PropertySignature",
11356
+ "canonicalReference": "@genesislcap/foundation-ai!TokenCostBreakdown#candidateUsd:member",
11357
+ "docComment": "/**\n * Generated output, including any reasoning tokens billed as output.\n */\n",
11358
+ "excerptTokens": [
11359
+ {
11360
+ "kind": "Content",
11361
+ "text": "candidateUsd: "
11362
+ },
11363
+ {
11364
+ "kind": "Content",
11365
+ "text": "number"
11366
+ },
11367
+ {
11368
+ "kind": "Content",
11369
+ "text": ";"
11370
+ }
11371
+ ],
11372
+ "isReadonly": false,
11373
+ "isOptional": false,
11374
+ "releaseTag": "Beta",
11375
+ "name": "candidateUsd",
11376
+ "propertyTypeTokenRange": {
11377
+ "startIndex": 1,
11378
+ "endIndex": 2
11379
+ }
11380
+ },
11381
+ {
11382
+ "kind": "PropertySignature",
11383
+ "canonicalReference": "@genesislcap/foundation-ai!TokenCostBreakdown#promptUsd:member",
11384
+ "docComment": "/**\n * Prompt tokens billed at the full uncached input rate.\n */\n",
11385
+ "excerptTokens": [
11386
+ {
11387
+ "kind": "Content",
11388
+ "text": "promptUsd: "
11389
+ },
11390
+ {
11391
+ "kind": "Content",
11392
+ "text": "number"
11393
+ },
11394
+ {
11395
+ "kind": "Content",
11396
+ "text": ";"
11397
+ }
11398
+ ],
11399
+ "isReadonly": false,
11400
+ "isOptional": false,
11401
+ "releaseTag": "Beta",
11402
+ "name": "promptUsd",
11403
+ "propertyTypeTokenRange": {
11404
+ "startIndex": 1,
11405
+ "endIndex": 2
11406
+ }
11407
+ }
11408
+ ],
11409
+ "extendsTokenRanges": []
11410
+ },
11411
+ {
11412
+ "kind": "Interface",
11413
+ "canonicalReference": "@genesislcap/foundation-ai!TokenRates:interface",
11414
+ "docComment": "/**\n * USD per million tokens, split by direction. `prompt` covers input/prompt tokens, `candidate` covers generated output (including any reasoning tokens the provider bills as output).\n *\n * @beta\n */\n",
11415
+ "excerptTokens": [
11416
+ {
11417
+ "kind": "Content",
11418
+ "text": "export interface TokenRates "
11419
+ }
11420
+ ],
11421
+ "fileUrlPath": "src/utils/token-cost.ts",
11422
+ "releaseTag": "Beta",
11423
+ "name": "TokenRates",
11424
+ "preserveMemberOrder": false,
11425
+ "members": [
11426
+ {
11427
+ "kind": "PropertySignature",
11428
+ "canonicalReference": "@genesislcap/foundation-ai!TokenRates#candidatePerMillion:member",
11429
+ "docComment": "",
11430
+ "excerptTokens": [
11431
+ {
11432
+ "kind": "Content",
11433
+ "text": "candidatePerMillion: "
11434
+ },
11435
+ {
11436
+ "kind": "Content",
11437
+ "text": "number"
11438
+ },
11439
+ {
11440
+ "kind": "Content",
11441
+ "text": ";"
11442
+ }
11443
+ ],
11444
+ "isReadonly": false,
11445
+ "isOptional": false,
11446
+ "releaseTag": "Beta",
11447
+ "name": "candidatePerMillion",
11448
+ "propertyTypeTokenRange": {
11449
+ "startIndex": 1,
11450
+ "endIndex": 2
11451
+ }
11452
+ },
11453
+ {
11454
+ "kind": "PropertySignature",
11455
+ "canonicalReference": "@genesislcap/foundation-ai!TokenRates#promptPerMillion:member",
11456
+ "docComment": "",
11457
+ "excerptTokens": [
11458
+ {
11459
+ "kind": "Content",
11460
+ "text": "promptPerMillion: "
11461
+ },
11462
+ {
11463
+ "kind": "Content",
11464
+ "text": "number"
11465
+ },
11466
+ {
11467
+ "kind": "Content",
11468
+ "text": ";"
11469
+ }
11470
+ ],
11471
+ "isReadonly": false,
11472
+ "isOptional": false,
11473
+ "releaseTag": "Beta",
11474
+ "name": "promptPerMillion",
11475
+ "propertyTypeTokenRange": {
11476
+ "startIndex": 1,
11477
+ "endIndex": 2
11478
+ }
11479
+ }
11480
+ ],
11481
+ "extendsTokenRanges": []
11482
+ },
10479
11483
  {
10480
11484
  "kind": "TypeAlias",
10481
11485
  "canonicalReference": "@genesislcap/foundation-ai!TurnFailureReason:type",
@@ -10557,6 +11561,56 @@
10557
11561
  "endIndex": 9
10558
11562
  }
10559
11563
  },
11564
+ {
11565
+ "kind": "Function",
11566
+ "canonicalReference": "@genesislcap/foundation-ai!vendorOfModel:function(1)",
11567
+ "docComment": "/**\n * Which vendor a model id belongs to, or `undefined` when no supported provider claims it.\n *\n * @remarks\n *\n * Derived from {@link SUPPORTED_ANTHROPIC_MODEL_IDS} and {@link SUPPORTED_GEMINI_MODEL_IDS}, so it cannot drift from them the way a hand-maintained map does — adding a model to an allowlist is enough to teach this too.\n *\n * Exists because callers hold a **model id**, not a vendor. A usage ledger reads a message's `model` and then has to pick the matching pricing function — `anthropicTokenCost` vs `geminiTokenCost` — whose usage records are deliberately not interchangeable, because the two providers disagree about whether the prompt figure includes the cached part. Without this, every such caller writes its own model→vendor map, which is the same duplication that exporting the pricing removes.\n *\n * Returns `undefined` rather than falling back to a default vendor so an unrecognised model is a decision the caller has to make out loud. Silently defaulting is precisely how an unlisted model gets priced at some other tier's rates — a consumer has already had Haiku billed at Sonnet rates that way.\n *\n * Takes a plain `string`, not a union: the interesting callers are reading a model id back off a stored message or a config file, where it is untrusted text.\n *\n * @beta\n */\n",
11568
+ "excerptTokens": [
11569
+ {
11570
+ "kind": "Content",
11571
+ "text": "export declare function vendorOfModel(modelId: "
11572
+ },
11573
+ {
11574
+ "kind": "Content",
11575
+ "text": "string"
11576
+ },
11577
+ {
11578
+ "kind": "Content",
11579
+ "text": "): "
11580
+ },
11581
+ {
11582
+ "kind": "Reference",
11583
+ "text": "AIProviderType",
11584
+ "canonicalReference": "@genesislcap/foundation-ai!AIProviderType:type"
11585
+ },
11586
+ {
11587
+ "kind": "Content",
11588
+ "text": " | undefined"
11589
+ },
11590
+ {
11591
+ "kind": "Content",
11592
+ "text": ";"
11593
+ }
11594
+ ],
11595
+ "fileUrlPath": "src/types/config.types.ts",
11596
+ "returnTypeTokenRange": {
11597
+ "startIndex": 3,
11598
+ "endIndex": 5
11599
+ },
11600
+ "releaseTag": "Beta",
11601
+ "overloadIndex": 1,
11602
+ "parameters": [
11603
+ {
11604
+ "parameterName": "modelId",
11605
+ "parameterTypeTokenRange": {
11606
+ "startIndex": 1,
11607
+ "endIndex": 2
11608
+ },
11609
+ "isOptional": false
11610
+ }
11611
+ ],
11612
+ "name": "vendorOfModel"
11613
+ },
10560
11614
  {
10561
11615
  "kind": "Function",
10562
11616
  "canonicalReference": "@genesislcap/foundation-ai!vendorTypeOfLabel:function(1)",