@genesislcap/foundation-ai 15.33.1 → 15.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dts/index.d.ts +4 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/tiers/ai-tiers.d.ts +154 -0
- package/dist/dts/tiers/ai-tiers.d.ts.map +1 -0
- package/dist/dts/tiers/build-tier-providers.d.ts +67 -0
- package/dist/dts/tiers/build-tier-providers.d.ts.map +1 -0
- package/dist/dts/utils/token-cost.d.ts +14 -0
- package/dist/dts/utils/token-cost.d.ts.map +1 -1
- package/dist/esm/index.js +7 -0
- package/dist/esm/tiers/ai-tiers.js +173 -0
- package/dist/esm/tiers/build-tier-providers.js +72 -0
- package/dist/esm/utils/token-cost.js +14 -0
- package/dist/foundation-ai.api.json +1128 -263
- package/dist/foundation-ai.d.ts +191 -0
- package/package.json +10 -10
package/dist/foundation-ai.d.ts
CHANGED
|
@@ -64,6 +64,26 @@ export declare interface AggregateUsage {
|
|
|
64
64
|
/** Feature flag name for AI functionality (beta). Enable via ?feature.ai in URL or GENX_ENABLE_AI env var. */
|
|
65
65
|
export declare const AI_FEATURE_FLAG = "ai";
|
|
66
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Every tier id, in ascending capability order.
|
|
69
|
+
*
|
|
70
|
+
* This array is the source of truth and {@link AITierId} is derived from it, so the two cannot
|
|
71
|
+
* drift: a tier exists exactly when it is listed here. That matters because the provider
|
|
72
|
+
* builders and the table's tests all loop over this array — a tier missing from it would get
|
|
73
|
+
* no provider and no test, with nothing to say so.
|
|
74
|
+
*
|
|
75
|
+
* @beta
|
|
76
|
+
*/
|
|
77
|
+
export declare const AI_TIER_IDS: readonly ["low", "high", "reasoning"];
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Every vendor in the table — the two the platform's proxy meters. The source of truth for
|
|
81
|
+
* {@link AITierVendor}, for the same reason as {@link AI_TIER_IDS}.
|
|
82
|
+
*
|
|
83
|
+
* @beta
|
|
84
|
+
*/
|
|
85
|
+
export declare const AI_TIER_VENDORS: readonly ["anthropic", "gemini"];
|
|
86
|
+
|
|
67
87
|
/**
|
|
68
88
|
* Union type for provider-specific configs.
|
|
69
89
|
* Extend when adding new providers.
|
|
@@ -229,6 +249,47 @@ export declare interface AIStatus {
|
|
|
229
249
|
contextLimit?: number;
|
|
230
250
|
}
|
|
231
251
|
|
|
252
|
+
/**
|
|
253
|
+
* The tier a caller asks for, rather than a model id.
|
|
254
|
+
*
|
|
255
|
+
* Tier-shaped names are what let an app swap vendor (or re-bench a tier onto a
|
|
256
|
+
* newer model) without touching a single agent config — agents resolve `'high'`,
|
|
257
|
+
* not `claude-sonnet-5`. Derived from {@link AI_TIER_IDS}.
|
|
258
|
+
*
|
|
259
|
+
* @beta
|
|
260
|
+
*/
|
|
261
|
+
export declare type AITierId = (typeof AI_TIER_IDS)[number];
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Per-tier overrides, shallow-merged field by field over the defaults.
|
|
265
|
+
*
|
|
266
|
+
* @beta
|
|
267
|
+
*/
|
|
268
|
+
export declare interface AITierOverrides {
|
|
269
|
+
anthropic?: Partial<Record<AITierId, Partial<AnthropicTierConfig>>>;
|
|
270
|
+
gemini?: Partial<Record<AITierId, Partial<GeminiTierConfig>>>;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* The whole table: every tier, for every vendor.
|
|
275
|
+
*
|
|
276
|
+
* Total records, not partials — a tier a vendor cannot serve is not a tier, it is a
|
|
277
|
+
* gap that only shows up when an agent resolves it at runtime.
|
|
278
|
+
*
|
|
279
|
+
* @beta
|
|
280
|
+
*/
|
|
281
|
+
export declare interface AITiers {
|
|
282
|
+
anthropic: Record<AITierId, AnthropicTierConfig>;
|
|
283
|
+
gemini: Record<AITierId, GeminiTierConfig>;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* The cloud vendors the tier table covers. Derived from {@link AI_TIER_VENDORS}.
|
|
288
|
+
*
|
|
289
|
+
* @beta
|
|
290
|
+
*/
|
|
291
|
+
export declare type AITierVendor = (typeof AI_TIER_VENDORS)[number];
|
|
292
|
+
|
|
232
293
|
/**
|
|
233
294
|
* Transport interface for AI providers.
|
|
234
295
|
* Each provider (OpenAI, Chrome, Anthropic) implements this to handle API-specific details.
|
|
@@ -325,6 +386,27 @@ declare interface AnthropicProviderConfig {
|
|
|
325
386
|
*/
|
|
326
387
|
export declare function anthropicRatesFor(model: AnthropicModelId): TokenRates;
|
|
327
388
|
|
|
389
|
+
/**
|
|
390
|
+
* What one tier is worth on Anthropic: the model, its output ceiling, and the two clocks.
|
|
391
|
+
*
|
|
392
|
+
* @beta
|
|
393
|
+
*/
|
|
394
|
+
export declare interface AnthropicTierConfig {
|
|
395
|
+
model: AnthropicModelId;
|
|
396
|
+
/**
|
|
397
|
+
* `max_tokens` for every request on this tier. Part of the tier, not an optional
|
|
398
|
+
* extra: Anthropic requires the field and the transport defaults it to 4096, which
|
|
399
|
+
* truncates a large single-call file write mid-stream (`stop_reason: max_tokens`)
|
|
400
|
+
* and leaves the tool input unparseable. Values sit inside each model's documented
|
|
401
|
+
* output ceiling.
|
|
402
|
+
*/
|
|
403
|
+
maxTokens: number;
|
|
404
|
+
/** Inactivity window on a stream that has started. */
|
|
405
|
+
stallTimeoutMs: number;
|
|
406
|
+
/** Ceiling on the wait for the FIRST byte — a different clock from the stall one. */
|
|
407
|
+
timeoutMs: number;
|
|
408
|
+
}
|
|
409
|
+
|
|
328
410
|
/**
|
|
329
411
|
* Cost one Anthropic request.
|
|
330
412
|
*
|
|
@@ -687,6 +769,48 @@ export declare class BudgetExhaustedError extends Error {
|
|
|
687
769
|
});
|
|
688
770
|
}
|
|
689
771
|
|
|
772
|
+
/**
|
|
773
|
+
* Builds one {@link AIProvider} per tier for a vendor, ready to register under the tier
|
|
774
|
+
* names agents resolve (`low` / `high` / `reasoning`).
|
|
775
|
+
*
|
|
776
|
+
* @remarks
|
|
777
|
+
* Each provider carries its tier's model, output ceiling (Anthropic) and both clocks, so no
|
|
778
|
+
* tier can silently fall back to the transport defaults — which is how a large tool write
|
|
779
|
+
* ends up truncated at 4096 tokens.
|
|
780
|
+
*
|
|
781
|
+
* @example
|
|
782
|
+
* ```ts
|
|
783
|
+
* registerAIProviders(
|
|
784
|
+
* container,
|
|
785
|
+
* buildTierProviders({ vendor: 'gemini', serverEndpoint: (v) => `/gwf/ai-service/${v}/chat` }),
|
|
786
|
+
* { default: 'high' },
|
|
787
|
+
* );
|
|
788
|
+
* ```
|
|
789
|
+
*
|
|
790
|
+
* @beta
|
|
791
|
+
*/
|
|
792
|
+
export declare function buildTierProviders(options: BuildTierProvidersOptions): Record<AITierId, AIProvider>;
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Options for {@link buildTierProviders}.
|
|
796
|
+
*
|
|
797
|
+
* @beta
|
|
798
|
+
*/
|
|
799
|
+
export declare interface BuildTierProvidersOptions {
|
|
800
|
+
/** Which vendor's models to build. */
|
|
801
|
+
vendor: AITierVendor;
|
|
802
|
+
/**
|
|
803
|
+
* The proxy endpoint every tier posts to — a string, or a function of the vendor for a
|
|
804
|
+
* caller that builds more than one vendor from one rule (see the example below).
|
|
805
|
+
*
|
|
806
|
+
* Always a server endpoint, never an API key: these providers are meant for an app whose
|
|
807
|
+
* keys stay on its server. An empty endpoint throws here rather than at the first turn.
|
|
808
|
+
*/
|
|
809
|
+
serverEndpoint: string | ((vendor: AITierVendor) => string);
|
|
810
|
+
/** The table to build from. Defaults to {@link DEFAULT_AI_TIERS}. */
|
|
811
|
+
tiers?: AITiers;
|
|
812
|
+
}
|
|
813
|
+
|
|
690
814
|
/**
|
|
691
815
|
* Prompt-cache policy for a chat request, resolved per turn. **Provider-neutral intent,
|
|
692
816
|
* provider-specific effect** — read this carefully, the two providers differ sharply:
|
|
@@ -2419,6 +2543,30 @@ export declare interface CriteriaInterpretContext {
|
|
|
2419
2543
|
fields?: FieldLike[];
|
|
2420
2544
|
}
|
|
2421
2545
|
|
|
2546
|
+
/**
|
|
2547
|
+
* The platform's default tier table.
|
|
2548
|
+
*
|
|
2549
|
+
* @remarks
|
|
2550
|
+
* Frozen, because it is shared by every app in the process: {@link resolveAITiers} returns
|
|
2551
|
+
* a fresh object for callers that override, and hands this back untouched for callers that
|
|
2552
|
+
* do not.
|
|
2553
|
+
*
|
|
2554
|
+
* The models are the ones Genesis Create has been running these tiers on in production — except
|
|
2555
|
+
* Anthropic's `reasoning`, moved to `claude-opus-4-8` (see its entry) — and they are a
|
|
2556
|
+
* **benchmark result, not a preference**: re-bench before moving one. Two of the Gemini
|
|
2557
|
+
* defaults carry a caveat recorded beside them, a preview model and an introductory rate. Two dates
|
|
2558
|
+
* are already on the calendar for that: `gemini-3.8-flash` sits on an introductory rate that
|
|
2559
|
+
* doubles on 2027-01-01 (at which point it is dearer on input than the model it replaced),
|
|
2560
|
+
* and `token-cost.test.ts` fails the build that day; `ai-tiers.test.ts` fails alongside it
|
|
2561
|
+
* saying the High tier is the thing to re-bench.
|
|
2562
|
+
*
|
|
2563
|
+
* Every model here must be in `SUPPORTED_*_MODEL_IDS` with a context limit and a price —
|
|
2564
|
+
* pinned by tests, because an unpriced model silently bills at nothing.
|
|
2565
|
+
*
|
|
2566
|
+
* @beta
|
|
2567
|
+
*/
|
|
2568
|
+
export declare const DEFAULT_AI_TIERS: AITiers;
|
|
2569
|
+
|
|
2422
2570
|
/**
|
|
2423
2571
|
* The single copy shown to a user whose AI budget is gone — the transcript bubble
|
|
2424
2572
|
* the chat driver appends, and the default text of the assistant's blocked banner.
|
|
@@ -2573,6 +2721,22 @@ declare interface GeminiProviderConfig {
|
|
|
2573
2721
|
*/
|
|
2574
2722
|
export declare function geminiRatesFor(model: GeminiModelId, promptTokens: number): TokenRates;
|
|
2575
2723
|
|
|
2724
|
+
/**
|
|
2725
|
+
* What one tier is worth on Gemini.
|
|
2726
|
+
*
|
|
2727
|
+
* No `maxTokens`: `GeminiAIConfig` has no such field and the provider's own (much
|
|
2728
|
+
* larger) default applies, so Gemini writes never hit the Anthropic wall above.
|
|
2729
|
+
*
|
|
2730
|
+
* @beta
|
|
2731
|
+
*/
|
|
2732
|
+
export declare interface GeminiTierConfig {
|
|
2733
|
+
model: GeminiModelId;
|
|
2734
|
+
/** Inactivity window on a stream that has started. */
|
|
2735
|
+
stallTimeoutMs: number;
|
|
2736
|
+
/** Ceiling on the wait for the FIRST byte — a different clock from the stall one. */
|
|
2737
|
+
timeoutMs: number;
|
|
2738
|
+
}
|
|
2739
|
+
|
|
2576
2740
|
/**
|
|
2577
2741
|
* Cost one Gemini request.
|
|
2578
2742
|
*
|
|
@@ -3234,6 +3398,33 @@ export declare interface ResolveAIConfigOptions {
|
|
|
3234
3398
|
preferChrome?: boolean;
|
|
3235
3399
|
}
|
|
3236
3400
|
|
|
3401
|
+
/**
|
|
3402
|
+
* The table an app should actually use: {@link DEFAULT_AI_TIERS} with `overrides` applied
|
|
3403
|
+
* per field, so an app that wants one model moved says only that and keeps the platform's
|
|
3404
|
+
* clocks and ceilings.
|
|
3405
|
+
*
|
|
3406
|
+
* @remarks
|
|
3407
|
+
* An override field set to `undefined` is skipped, exactly as if it had been left out. The
|
|
3408
|
+
* common caller passes an optional config value straight through
|
|
3409
|
+
* (`{ high: { model: appConfig.model } }`), and copying `undefined` over the default would
|
|
3410
|
+
* hand the transport no model at all — it then quietly falls back to its own default, with
|
|
3411
|
+
* nothing logged.
|
|
3412
|
+
*
|
|
3413
|
+
* The result is frozen whether or not anything was overridden, so whether mutating it throws
|
|
3414
|
+
* does not depend on what the caller passed. The default itself is returned untouched when
|
|
3415
|
+
* there is nothing to override, and is never mutated, which matters because it is shared
|
|
3416
|
+
* across every app in the process.
|
|
3417
|
+
*
|
|
3418
|
+
* @example
|
|
3419
|
+
* ```ts
|
|
3420
|
+
* // Keep everything, but run the reasoning tier on Fable.
|
|
3421
|
+
* const tiers = resolveAITiers({ anthropic: { reasoning: { model: 'claude-fable-5' } } });
|
|
3422
|
+
* ```
|
|
3423
|
+
*
|
|
3424
|
+
* @beta
|
|
3425
|
+
*/
|
|
3426
|
+
export declare function resolveAITiers(overrides?: AITierOverrides): AITiers;
|
|
3427
|
+
|
|
3237
3428
|
/**
|
|
3238
3429
|
* Thrown when a response was cut off at the output-token limit (Anthropic
|
|
3239
3430
|
* `stop_reason: 'max_tokens'`, Gemini `finishReason: 'MAX_TOKENS'`) in a way
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genesislcap/foundation-ai",
|
|
3
3
|
"description": "Genesis Foundation AI - Provider-agnostic AI configuration and shared utilities",
|
|
4
|
-
"version": "15.
|
|
4
|
+
"version": "15.34.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "SEE LICENSE IN license.txt",
|
|
7
7
|
"main": "dist/esm/index.js",
|
|
@@ -52,17 +52,17 @@
|
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@genesislcap/foundation-testing": "15.
|
|
56
|
-
"@genesislcap/genx": "15.
|
|
57
|
-
"@genesislcap/rollup-builder": "15.
|
|
58
|
-
"@genesislcap/ts-builder": "15.
|
|
59
|
-
"@genesislcap/uvu-playwright-builder": "15.
|
|
60
|
-
"@genesislcap/vite-builder": "15.
|
|
61
|
-
"@genesislcap/webpack-builder": "15.
|
|
55
|
+
"@genesislcap/foundation-testing": "15.34.0",
|
|
56
|
+
"@genesislcap/genx": "15.34.0",
|
|
57
|
+
"@genesislcap/rollup-builder": "15.34.0",
|
|
58
|
+
"@genesislcap/ts-builder": "15.34.0",
|
|
59
|
+
"@genesislcap/uvu-playwright-builder": "15.34.0",
|
|
60
|
+
"@genesislcap/vite-builder": "15.34.0",
|
|
61
|
+
"@genesislcap/webpack-builder": "15.34.0"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@genesislcap/foundation-logger": "15.
|
|
65
|
-
"@genesislcap/foundation-utils": "15.
|
|
64
|
+
"@genesislcap/foundation-logger": "15.34.0",
|
|
65
|
+
"@genesislcap/foundation-utils": "15.34.0",
|
|
66
66
|
"@microsoft/fast-foundation": "2.50.0"
|
|
67
67
|
},
|
|
68
68
|
"repository": {
|