@genesislcap/foundation-ai 15.22.2 → 15.23.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.
@@ -1,6 +1,36 @@
1
1
  import { type AITransport, type CostReportingTransport, type GeminiModelId, type StructuredPromptOptions } from '../types';
2
2
  import type { ChatTransport } from '../types/chat-transport.types';
3
3
  import type { ChatMessage, ChatRequestOptions } from '../types/chat.types';
4
+ /**
5
+ * Gemini's `thinkingLevel` enum, weakest to strongest. The ORDER is load-bearing:
6
+ * {@link clampThinkingLevel} measures distance along it.
7
+ */
8
+ type GeminiThinkingLevel = 'minimal' | 'low' | 'medium' | 'high';
9
+ /**
10
+ * Clamp `level` onto the nearest level in `supported`, measured along {@link GEMINI_LEVEL_LADDER}.
11
+ * Returns `level` untouched when it is already supported, or when `supported` is empty/absent.
12
+ *
13
+ * Takes the SET, not a model id, so it is a pure function of its arguments. A helper that read
14
+ * {@link GEMINI_THINKING_LEVELS} internally could only ever be tested through whichever rows
15
+ * happen to be in it — and the tie-break below is precisely the rule no current row exercises.
16
+ *
17
+ * Ties resolve UPWARD. **Not for continuity** — the shipped rows changed deliberately when they
18
+ * were widened to the measured sets, so `medium` on `gemini-3.5-flash` no longer folds to `high`.
19
+ * The reason is cost visibility: a clamp that reasons a little harder than asked shows up in the
20
+ * bill, where one that quietly reasons less shows up only as a worse answer nobody attributes to
21
+ * this function.
22
+ *
23
+ * **No current row can produce a tie**, and that is a property of their shape rather than luck. A
24
+ * tie needs two supported levels equidistant from an unsupported target, which needs a GAP inside
25
+ * the set; every row today is a contiguous suffix of the ladder, so the only clamp any of them
26
+ * produces is `minimal` → `low`, at distances 1/2/3. The old coarse `['low','high']` pair WAS the
27
+ * gapped shape — `medium` sat equidistant between them, which is why that table folded it up —
28
+ * and widening the rows removed it. The rule is kept, and pinned in the tests against a synthesised
29
+ * gapped set, so whoever adds such a row next finds the behaviour decided rather than discovers it.
30
+ *
31
+ * @internal
32
+ */
33
+ export declare function clampThinkingLevel(supported: readonly GeminiThinkingLevel[] | undefined, level: GeminiThinkingLevel): GeminiThinkingLevel;
4
34
  export interface GeminiTransportConfig {
5
35
  /**
6
36
  * Defaults to `gemini-2.5-flash-lite`. Only {@link SUPPORTED_GEMINI_MODEL_IDS} are accepted.
@@ -73,7 +103,7 @@ export declare class GeminiTransport implements AITransport, ChatTransport, Cost
73
103
  /**
74
104
  * Warn once when a requested policy cannot be honoured on this model — a *cost* decision the
75
105
  * caller made that the wire silently reversed, so they hear about it, but only once, not per
76
- * turn. Two shapes reach here (the Anthropic twin warns on the same two):
106
+ * turn. Three shapes reach here (the Anthropic twin warns on the first two):
77
107
  *
78
108
  * - `'off'` on a tier that can't disable thinking — only the flash tiers accept a zero thinking
79
109
  * budget; everything else keeps paying for reasoning it was told to stop. (`'auto'` is NOT this
@@ -83,6 +113,12 @@ export declare class GeminiTransport implements AITransport, ChatTransport, Cost
83
113
  * not the Gemini 3 `thinkingLevel` enum, so the level is dropped and the turn runs at the
84
114
  * default posture. Without this, a caller asking for `high` on `gemini-2.5-pro` and quietly
85
115
  * getting the default is left to wonder why.
116
+ * - A graded depth whose DIALECT a Gemini 3 tier speaks but whose particular value it does not
117
+ * accept — `minimal` on `gemini-3.8-flash` or `gemini-3.1-pro-preview`, the two tiers that
118
+ * reject it outright. Nothing is dropped here; `clampThinkingLevel` MOVES the level onto the
119
+ * nearest one the tier takes, and since ties resolve upward the move is usually to something
120
+ * DEARER than the caller chose. A cost decision reversed on the wire in the expensive
121
+ * direction is exactly what this warning exists for — without it the only trace is the bill.
86
122
  */
87
123
  private warnIfThinkingUnclampable;
88
124
  constructor(config?: GeminiTransportConfig);
@@ -165,4 +201,5 @@ export declare class GeminiTransport implements AITransport, ChatTransport, Cost
165
201
  private post;
166
202
  private toDirectPayload;
167
203
  }
204
+ export {};
168
205
  //# sourceMappingURL=gemini-transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gemini-transport.d.ts","sourceRoot":"","sources":["../../../src/transports/gemini-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC7B,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAEV,WAAW,EACX,kBAAkB,EAMnB,MAAM,qBAAqB,CAAC;AA8K7B,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AA6ED;;;;;;GAMG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;IACvC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM;gBAAtB,aAAa,CAAC,EAAE,MAAM;CAI5C;AAED;;;;;;;;GAQG;AACH,qBAAa,eAAgB,YAAW,WAAW,EAAE,aAAa,EAAE,sBAAsB;IACxF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD;;;;;OAKG;IACH,OAAO,CAAC,eAAe,CAAK;IAC5B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB,CAAK;IAC/B;;;OAGG;IACH,OAAO,CAAC,qBAAqB,CAAS;IAEtC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,yBAAyB;gBAmBrB,MAAM,GAAE,qBAA0B;IAe9C,SAAS,IAAI;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,aAAa,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE;IAQ/E,iGAAiG;IACjG,eAAe,IAAI,MAAM;IAIzB,mGAAmG;IACnG,kBAAkB,IAAI,MAAM;IAI5B,+FAA+F;IAC/F,iBAAiB,IAAI,IAAI;IAOnB,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBvE,eAAe,CACnB,OAAO,EAAE,WAAW,EAAE,EACtB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,WAAW,CAAC;IA+HvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAa;IACvD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAK;IAEhD;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAqCrB,OAAO,CAAC,gBAAgB;IAwGxB;;;;;;;;;OASG;IACH,OAAO,CAAC,eAAe;IAyCvB,OAAO,CAAC,kBAAkB;IAsI1B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,wBAAwB;IAoBhC;;;;;;;;OAQG;IACH,OAAO,CAAC,mBAAmB;IAkC3B,OAAO,CAAC,aAAa;IA8BrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAO;IAChD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAAO;IACzD;;;;;;;;;;OAUG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAO;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAIxC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAQ;YAEjC,IAAI;IAgBlB,OAAO,CAAC,eAAe;CAexB"}
1
+ {"version":3,"file":"gemini-transport.d.ts","sourceRoot":"","sources":["../../../src/transports/gemini-transport.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@ export type AIProviderType = 'openai' | 'chrome' | 'gemini' | 'anthropic' | 'non
9
9
  *
10
10
  * @beta
11
11
  */
12
- export type GeminiModelId = 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-lite' | 'gemini-3.5-flash' | 'gemini-3.1-flash-lite' | 'gemini-3.1-pro-preview';
12
+ export type GeminiModelId = 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-lite' | 'gemini-3.8-flash' | 'gemini-3.5-flash' | 'gemini-3.1-flash-lite' | 'gemini-3.1-pro-preview';
13
13
  /** @beta */
14
14
  export declare const SUPPORTED_GEMINI_MODEL_IDS: readonly GeminiModelId[];
15
15
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.types.d.ts","sourceRoot":"","sources":["../../../src/types/config.types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,CAAC;AAEnF;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACrB,gBAAgB,GAChB,kBAAkB,GAClB,uBAAuB,GACvB,kBAAkB,GAClB,uBAAuB,GAEvB,wBAAwB,CAAC;AAE7B,YAAY;AACZ,eAAO,MAAM,0BAA0B,EAAE,SAAS,aAAa,EAOrD,CAAC;AAEX;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GACxB,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,mBAAmB,GACnB,2BAA2B,CAAC;AAEhC,YAAY;AACZ,eAAO,MAAM,6BAA6B,EAAE,SAAS,gBAAgB,EAO3D,CAAC;AAEX;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAIzE;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,6DAA6D;AAC7D,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;AAErE;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,QAAQ,EAAE,oBAAoB,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,YAAY,CAAC,EAAE,QAAQ,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,YAAY,EAAE,QAAQ,CAAC;IACvB,4GAA4G;IAC5G,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,YAAY,EAAE,WAAW,CAAC;IAC1B,mHAAmH;IACnH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,cAAc,GAAG,cAAc,GAAG,iBAAiB,CAAC"}
1
+ {"version":3,"file":"config.types.d.ts","sourceRoot":"","sources":["../../../src/types/config.types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,CAAC;AAEnF;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACrB,gBAAgB,GAChB,kBAAkB,GAClB,uBAAuB,GACvB,kBAAkB,GAClB,kBAAkB,GAClB,uBAAuB,GAEvB,wBAAwB,CAAC;AAE7B,YAAY;AACZ,eAAO,MAAM,0BAA0B,EAAE,SAAS,aAAa,EAQrD,CAAC;AAEX;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GACxB,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,mBAAmB,GACnB,2BAA2B,CAAC;AAEhC,YAAY;AACZ,eAAO,MAAM,6BAA6B,EAAE,SAAS,gBAAgB,EAO3D,CAAC;AAEX;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAIzE;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,6DAA6D;AAC7D,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;AAErE;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,QAAQ,EAAE,oBAAoB,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,YAAY,CAAC,EAAE,QAAQ,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,YAAY,EAAE,QAAQ,CAAC;IACvB,4GAA4G;IAC5G,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,YAAY,EAAE,WAAW,CAAC;IAC1B,mHAAmH;IACnH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,cAAc,GAAG,cAAc,GAAG,iBAAiB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"token-cost.d.ts","sourceRoot":"","sources":["../../../src/utils/token-cost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAkDhE;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;;OAQG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,SAAS,EAAE,kBAAkB,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;CACtB;AAiCD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,UAAU,CAErE;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B,MAAM,CAAC;AACnD,YAAY;AACZ,eAAO,MAAM,mCAAmC,OAAO,CAAC;AACxD,YAAY;AACZ,eAAO,MAAM,mCAAmC,IAAI,CAAC;AAErD;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,wFAAwF;IACxF,mBAAmB,EAAE,MAAM,CAAC;IAC5B,4FAA4F;IAC5F,YAAY,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,eAAe,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;;;;;OASG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,oBAAoB,GAC1B,SAAS,CAiCX;AAMD;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,SAAU,CAAC;AAErD;;;;;;;;;GASG;AACH,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAsClD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,GAAG,UAAU,CAMrF;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB;IAChC,kFAAkF;IAClF,YAAY,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,eAAe,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,iBAAiB,GAAG,SAAS,CAuBzF"}
1
+ {"version":3,"file":"token-cost.d.ts","sourceRoot":"","sources":["../../../src/utils/token-cost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAkDhE;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;;OAQG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,SAAS,EAAE,kBAAkB,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;CACtB;AAiCD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,UAAU,CAErE;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B,MAAM,CAAC;AACnD,YAAY;AACZ,eAAO,MAAM,mCAAmC,OAAO,CAAC;AACxD,YAAY;AACZ,eAAO,MAAM,mCAAmC,IAAI,CAAC;AAErD;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,wFAAwF;IACxF,mBAAmB,EAAE,MAAM,CAAC;IAC5B,4FAA4F;IAC5F,YAAY,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,eAAe,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;;;;;OASG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,oBAAoB,GAC1B,SAAS,CAiCX;AAMD;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,SAAU,CAAC;AAErD;;;;;;;;;GASG;AACH,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAsDlD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,GAAG,UAAU,CAMrF;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB;IAChC,kFAAkF;IAClF,YAAY,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,eAAe,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,iBAAiB,GAAG,SAAS,CAuBzF"}
@@ -21,6 +21,7 @@ const GEMINI_CONTEXT_LIMITS = {
21
21
  'gemini-2.5-pro': 1048576,
22
22
  'gemini-2.5-flash': 1048576,
23
23
  'gemini-2.5-flash-lite': 1048576,
24
+ 'gemini-3.8-flash': 1048576,
24
25
  'gemini-3.5-flash': 1048576,
25
26
  'gemini-3.1-flash-lite': 1048576,
26
27
  'gemini-3.1-pro-preview': 1048576,
@@ -55,6 +56,10 @@ const GEMINI_MODEL_WARNINGS = {
55
56
  'gemini-2.5-flash': 'GeminiTransport: using gemini-2.5-flash — higher cost than flash-lite; use for harder reasoning or agent tasks.',
56
57
  'gemini-2.5-pro': 'GeminiTransport: using gemini-2.5-pro — significantly higher, prompt-size-tiered cost; reserve for tasks where flash reliability is insufficient.',
57
58
  'gemini-3.5-flash': 'GeminiTransport: using gemini-3.5-flash — frontier model, materially higher cost than flash-lite; use for harder reasoning or agent tasks.',
59
+ // Warns despite currently costing LESS than gemini-3.5-flash, because that is temporary: the
60
+ // rate doubles on 2027-01-01 (see GEMINI_PRICING). A caller that picks this tier on today's
61
+ // price and never revisits the choice gets twice the bill in January without changing a line.
62
+ 'gemini-3.8-flash': 'GeminiTransport: using gemini-3.8-flash — frontier model, materially higher cost than flash-lite. Its $0.75/$3.75 per-MTok rate is introductory and DOUBLES to $1.50/$7.50 on 2027-01-01; re-check this tier choice before then.',
58
63
  'gemini-3.1-pro-preview': 'GeminiTransport: using gemini-3.1-pro-preview — PREVIEW model (no stability guarantee, may be withdrawn) with significantly higher, prompt-size-tiered cost; reserve for tasks where flash reliability is insufficient.',
59
64
  };
60
65
  /**
@@ -84,21 +89,100 @@ const GEMINI_THINKING_DISABLEABLE = [
84
89
  ];
85
90
  /** Tiers that accept `generationConfig.mediaResolution`. Gemini 3 only, like `thinkingLevel`. */
86
91
  const GEMINI_MEDIA_RESOLUTION_TIERS = [
92
+ 'gemini-3.8-flash',
87
93
  'gemini-3.5-flash',
88
94
  'gemini-3.1-flash-lite',
89
95
  'gemini-3.1-pro-preview',
90
96
  ];
91
- /** The tiers that take `thinkingConfig.thinkingLevel` rather than a numeric `thinkingBudget`. */
92
- const GEMINI_THINKING_LEVEL_TIERS = [
93
- 'gemini-3.5-flash',
94
- 'gemini-3.1-flash-lite',
95
- 'gemini-3.1-pro-preview',
96
- ];
97
+ const GEMINI_LEVEL_LADDER = ['minimal', 'low', 'medium', 'high'];
98
+ /**
99
+ * The `thinkingLevel` values each Gemini 3 tier accepts, weakest first — and, by carrying an entry
100
+ * at all, WHICH tiers speak the `thinkingLevel` dialect rather than the 2.5 numeric
101
+ * `thinkingBudget`. One table where there were two parallel lists, so a tier can no longer be
102
+ * added to the dialect list and forgotten in the level list.
103
+ *
104
+ * Replaces a boolean "full four-level enum, or only the coarse `low`/`high` pair", a shape
105
+ * `gemini-3.8-flash` does not fit: it takes `low`, `medium` and `high` but NOT `minimal`. The
106
+ * boolean could only round that to a wrong answer in one direction or the other — coarsening it
107
+ * sends every `medium` request as `high` and pays for reasoning nobody asked for, while leaving it
108
+ * uncoarsened forwards `minimal` to a tier that rejects it. Google now publishes the accepted set
109
+ * per model, so that table is what is encoded here.
110
+ * https://ai.google.dev/gemini-api/docs/thinking
111
+ *
112
+ * **Every row here is OBSERVED, not documented** — the bar this file has always set for forwarding
113
+ * an enum value ("a clamp costs money, but a guess costs a 400 on a turn the user is waiting for"),
114
+ * and the reason the previous version pinned all three shipped tiers to the coarse `low`/`high`
115
+ * pair rather than trusting a docs table. Measured 2026-09-04 by POSTing each level at each tier
116
+ * directly, bypassing this clamp (which can never observe a rejection, since it prevents one):
117
+ *
118
+ * | tier | minimal | low | medium | high |
119
+ * |---|---|---|---|---|
120
+ * | `gemini-3.8-flash` | **400** | ok | ok | ok |
121
+ * | `gemini-3.5-flash` | ok | ok | ok | ok |
122
+ * | `gemini-3.1-flash-lite` | ok | ok | ok | ok |
123
+ * | `gemini-3.1-pro-preview` | **400** | ok | ok | ok |
124
+ *
125
+ * So the two `minimal` clamps are load-bearing — unclamped they are a hard
126
+ * `Thinking level MINIMAL is not supported for this model` on a turn the user is waiting for —
127
+ * and the coarse pair was over-clamping the other three tiers, quietly buying `high` reasoning for
128
+ * every caller who asked for `medium` and billing it at the candidate rate.
129
+ *
130
+ * Worth noting against future doc-reading: Google's own thinking-level table disagrees with this
131
+ * measurement on `gemini-3.1-flash-lite` (it lists minimal/high only, where the API accepts all
132
+ * four). Re-measure with the probe rather than re-reading the docs when a tier is added.
133
+ */
134
+ const GEMINI_THINKING_LEVELS = {
135
+ 'gemini-3.8-flash': ['low', 'medium', 'high'],
136
+ 'gemini-3.5-flash': ['minimal', 'low', 'medium', 'high'],
137
+ 'gemini-3.1-flash-lite': ['minimal', 'low', 'medium', 'high'],
138
+ 'gemini-3.1-pro-preview': ['low', 'medium', 'high'],
139
+ };
140
+ /**
141
+ * Clamp `level` onto the nearest level in `supported`, measured along {@link GEMINI_LEVEL_LADDER}.
142
+ * Returns `level` untouched when it is already supported, or when `supported` is empty/absent.
143
+ *
144
+ * Takes the SET, not a model id, so it is a pure function of its arguments. A helper that read
145
+ * {@link GEMINI_THINKING_LEVELS} internally could only ever be tested through whichever rows
146
+ * happen to be in it — and the tie-break below is precisely the rule no current row exercises.
147
+ *
148
+ * Ties resolve UPWARD. **Not for continuity** — the shipped rows changed deliberately when they
149
+ * were widened to the measured sets, so `medium` on `gemini-3.5-flash` no longer folds to `high`.
150
+ * The reason is cost visibility: a clamp that reasons a little harder than asked shows up in the
151
+ * bill, where one that quietly reasons less shows up only as a worse answer nobody attributes to
152
+ * this function.
153
+ *
154
+ * **No current row can produce a tie**, and that is a property of their shape rather than luck. A
155
+ * tie needs two supported levels equidistant from an unsupported target, which needs a GAP inside
156
+ * the set; every row today is a contiguous suffix of the ladder, so the only clamp any of them
157
+ * produces is `minimal` → `low`, at distances 1/2/3. The old coarse `['low','high']` pair WAS the
158
+ * gapped shape — `medium` sat equidistant between them, which is why that table folded it up —
159
+ * and widening the rows removed it. The rule is kept, and pinned in the tests against a synthesised
160
+ * gapped set, so whoever adds such a row next finds the behaviour decided rather than discovers it.
161
+ *
162
+ * @internal
163
+ */
164
+ export function clampThinkingLevel(supported, level) {
165
+ if (!(supported === null || supported === void 0 ? void 0 : supported.length) || supported.includes(level)) {
166
+ return level;
167
+ }
168
+ const target = GEMINI_LEVEL_LADDER.indexOf(level);
169
+ const distance = (candidate) => Math.abs(GEMINI_LEVEL_LADDER.indexOf(candidate) - target);
170
+ // `supported` is weakest-first, and `<=` lets a later (stronger) candidate win an equal
171
+ // distance — that is the upward tie-break.
172
+ let best = supported[0];
173
+ for (const candidate of supported) {
174
+ if (distance(candidate) <= distance(best)) {
175
+ best = candidate;
176
+ }
177
+ }
178
+ return best;
179
+ }
97
180
  /**
98
181
  * Graded policy → Gemini `thinkingLevel`. Exhaustive `Record` for the same reason as the
99
182
  * Anthropic table: a new level must be mapped here or the build fails.
100
183
  *
101
184
  * `'max'` clamps DOWN to `high` — Gemini's ladder stops there. See {@link ChatThinkingPolicy}.
185
+ * The result is then clamped again, per tier, by {@link clampThinkingLevel}.
102
186
  */
103
187
  const GEMINI_THINKING_LEVEL = {
104
188
  minimal: 'minimal',
@@ -107,36 +191,18 @@ const GEMINI_THINKING_LEVEL = {
107
191
  high: 'high',
108
192
  max: 'high',
109
193
  };
110
- /**
111
- * Tiers that accept only the coarse `low` / `high` pair rather than the full four-level enum.
112
- *
113
- * Currently EVERY `thinkingLevel` tier. The Gemini 3 line did not ship `minimal` and `medium`
114
- * across every tier at once, and this file's own doctrine is that an unverified enum value is
115
- * worse than a coarser one — "a clamp costs money, but a guess costs a 400 on a turn the user is
116
- * waiting for". `low`/`high` are the pair confirmed across the line, so the fine levels fold onto
117
- * their nearer neighbour here rather than being forwarded on faith to a tier that may 400 on
118
- * them. Remove a tier from this list once its support for the full enum has been OBSERVED, not
119
- * assumed — `GEMINI_THINKING_LEVEL`'s finer mapping then takes effect for it immediately.
120
- */
121
- const GEMINI_COARSE_LEVEL_TIERS = [
122
- 'gemini-3.5-flash',
123
- 'gemini-3.1-flash-lite',
124
- 'gemini-3.1-pro-preview',
125
- ];
126
- const GEMINI_COARSE_LEVEL = {
127
- minimal: 'low',
128
- low: 'low',
129
- medium: 'high',
130
- high: 'high',
131
- };
132
194
  const isGradedLevel = (p) => p !== undefined && p !== 'auto' && p !== 'off';
133
195
  function geminiThinkingConfig(model, policy) {
134
- if (isGradedLevel(policy) && GEMINI_THINKING_LEVEL_TIERS.includes(model)) {
135
- const level = GEMINI_THINKING_LEVEL[policy];
136
- return {
137
- includeThoughts: true,
138
- thinkingLevel: GEMINI_COARSE_LEVEL_TIERS.includes(model) ? GEMINI_COARSE_LEVEL[level] : level,
139
- };
196
+ if (isGradedLevel(policy)) {
197
+ // Presence in the table IS the "speaks the thinkingLevel dialect" test, so one lookup answers
198
+ // both questions and there is no separate predicate to keep in step with it.
199
+ const accepted = GEMINI_THINKING_LEVELS[model];
200
+ if (accepted) {
201
+ return {
202
+ includeThoughts: true,
203
+ thinkingLevel: clampThinkingLevel(accepted, GEMINI_THINKING_LEVEL[policy]),
204
+ };
205
+ }
140
206
  }
141
207
  if (policy === 'off' && GEMINI_THINKING_DISABLEABLE.includes(model)) {
142
208
  // No reasoning to return once there is none to bill for.
@@ -215,7 +281,7 @@ export class GeminiTransport {
215
281
  /**
216
282
  * Warn once when a requested policy cannot be honoured on this model — a *cost* decision the
217
283
  * caller made that the wire silently reversed, so they hear about it, but only once, not per
218
- * turn. Two shapes reach here (the Anthropic twin warns on the same two):
284
+ * turn. Three shapes reach here (the Anthropic twin warns on the first two):
219
285
  *
220
286
  * - `'off'` on a tier that can't disable thinking — only the flash tiers accept a zero thinking
221
287
  * budget; everything else keeps paying for reasoning it was told to stop. (`'auto'` is NOT this
@@ -225,6 +291,12 @@ export class GeminiTransport {
225
291
  * not the Gemini 3 `thinkingLevel` enum, so the level is dropped and the turn runs at the
226
292
  * default posture. Without this, a caller asking for `high` on `gemini-2.5-pro` and quietly
227
293
  * getting the default is left to wonder why.
294
+ * - A graded depth whose DIALECT a Gemini 3 tier speaks but whose particular value it does not
295
+ * accept — `minimal` on `gemini-3.8-flash` or `gemini-3.1-pro-preview`, the two tiers that
296
+ * reject it outright. Nothing is dropped here; `clampThinkingLevel` MOVES the level onto the
297
+ * nearest one the tier takes, and since ties resolve upward the move is usually to something
298
+ * DEARER than the caller chose. A cost decision reversed on the wire in the expensive
299
+ * direction is exactly what this warning exists for — without it the only trace is the bill.
228
300
  */
229
301
  warnIfThinkingUnclampable(policy) {
230
302
  if (this.warnedThinkingClamped) {
@@ -235,9 +307,24 @@ export class GeminiTransport {
235
307
  logger.warn(`GeminiTransport: thinkingPolicy 'off' ignored — ${this.model} runs its default thinking posture and takes no budget we can safely set. Reasoning tokens are still billed at the candidate rate; use a flash tier if you need them gone.`);
236
308
  return;
237
309
  }
238
- if (isGradedLevel(policy) && !GEMINI_THINKING_LEVEL_TIERS.includes(this.model)) {
239
- this.warnedThinkingClamped = true;
240
- logger.warn(`GeminiTransport: thinkingPolicy '${policy}' ignored ${this.model} takes a numeric thinking budget, not the graded 'thinkingLevel' the Gemini 3 tiers use, so this turn runs at its default reasoning posture. Use a Gemini 3 tier to set reasoning depth.`);
310
+ if (isGradedLevel(policy)) {
311
+ // ONE lookup, and both graded cases hang off whether it found anything. Written this way
312
+ // rather than as two separate membership tests so the non-null below is established by the
313
+ // early return rather than asserted — no fallback guarding a state the control flow already
314
+ // rules out, and it still compiles if `strictNullChecks` is ever turned on (indexing a
315
+ // `Partial<Record>` yields `T | undefined` under it).
316
+ const accepted = GEMINI_THINKING_LEVELS[this.model];
317
+ if (!accepted) {
318
+ this.warnedThinkingClamped = true;
319
+ logger.warn(`GeminiTransport: thinkingPolicy '${policy}' ignored — ${this.model} takes a numeric thinking budget, not the graded 'thinkingLevel' the Gemini 3 tiers use, so this turn runs at its default reasoning posture. Use a Gemini 3 tier to set reasoning depth.`);
320
+ return;
321
+ }
322
+ const requested = GEMINI_THINKING_LEVEL[policy];
323
+ const sent = clampThinkingLevel(accepted, requested);
324
+ if (sent !== requested) {
325
+ this.warnedThinkingClamped = true;
326
+ logger.warn(`GeminiTransport: thinkingPolicy '${policy}' sent as thinkingLevel '${sent}' — ${this.model} does not accept '${requested}' (it takes ${accepted.join('/')}). Reasoning bills at the candidate rate, so an upward clamp costs more than you asked for.`);
327
+ }
241
328
  }
242
329
  }
243
330
  constructor(config = {}) {
@@ -3,6 +3,7 @@ export const SUPPORTED_GEMINI_MODEL_IDS = [
3
3
  'gemini-2.5-pro',
4
4
  'gemini-2.5-flash',
5
5
  'gemini-2.5-flash-lite',
6
+ 'gemini-3.8-flash',
6
7
  'gemini-3.5-flash',
7
8
  'gemini-3.1-flash-lite',
8
9
  'gemini-3.1-pro-preview',
@@ -181,6 +181,22 @@ const GEMINI_PRICING = {
181
181
  rate: { promptPerMillion: 0.25, candidatePerMillion: 1.5 },
182
182
  },
183
183
  'gemini-3.5-flash': { kind: 'flat', rate: { promptPerMillion: 1.5, candidatePerMillion: 9.0 } },
184
+ // INTRODUCTORY RATE, and the only dated entry in this file. Google publishes
185
+ // $0.75 / $3.75 per MTok **through 2026-12-31**, rising to $1.50 / $7.50 on 2027-01-01 —
186
+ // so today this model is CHEAPER than gemini-3.5-flash above and in January it is not.
187
+ //
188
+ // The listed figure is the one in force, not the one coming. That is the lesson the
189
+ // `claude-sonnet-5` entry records from the other direction: charging a scheduled future
190
+ // rate early over-billed every request by 50% for as long as nobody noticed. A rate that
191
+ // has not taken effect is not a price, and `GeminiPricing` deliberately has no time
192
+ // dimension to express one — flip these two numbers on 2027-01-01 instead.
193
+ //
194
+ // That flip is ENFORCED, not remembered: `token-cost.test.ts` carries a dated assertion that
195
+ // turns the build red on 2027-01-01 and names the three-line edit (these two rates, plus the
196
+ // now-false `< gemini-3.5-flash` comparison in that same test — both models are $1.50 input
197
+ // from that date). There is no ticket to lose.
198
+ // https://ai.google.dev/gemini-api/docs/pricing
199
+ 'gemini-3.8-flash': { kind: 'flat', rate: { promptPerMillion: 0.75, candidatePerMillion: 3.75 } },
184
200
  'gemini-3.1-pro-preview': {
185
201
  kind: 'tiered',
186
202
  standard: { promptPerMillion: 2.0, candidatePerMillion: 12.0 },
@@ -8608,7 +8608,7 @@
8608
8608
  },
8609
8609
  {
8610
8610
  "kind": "Content",
8611
- "text": "'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-lite' | 'gemini-3.5-flash' | 'gemini-3.1-flash-lite' | 'gemini-3.1-pro-preview'"
8611
+ "text": "'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-lite' | 'gemini-3.8-flash' | 'gemini-3.5-flash' | 'gemini-3.1-flash-lite' | 'gemini-3.1-pro-preview'"
8612
8612
  },
8613
8613
  {
8614
8614
  "kind": "Content",
@@ -2405,7 +2405,7 @@ export declare interface GeminiAIConfig extends AIProviderConfig {
2405
2405
  *
2406
2406
  * @beta
2407
2407
  */
2408
- export declare type GeminiModelId = 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-lite' | 'gemini-3.5-flash' | 'gemini-3.1-flash-lite' | 'gemini-3.1-pro-preview';
2408
+ export declare type GeminiModelId = 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-lite' | 'gemini-3.8-flash' | 'gemini-3.5-flash' | 'gemini-3.1-flash-lite' | 'gemini-3.1-pro-preview';
2409
2409
 
2410
2410
  /**
2411
2411
  * Gemini AI provider. Uses {@link GeminiTransport} to handle requests.
@@ -2488,7 +2488,7 @@ export declare class GeminiTransport implements AITransport, ChatTransport, Cost
2488
2488
  /**
2489
2489
  * Warn once when a requested policy cannot be honoured on this model — a *cost* decision the
2490
2490
  * caller made that the wire silently reversed, so they hear about it, but only once, not per
2491
- * turn. Two shapes reach here (the Anthropic twin warns on the same two):
2491
+ * turn. Three shapes reach here (the Anthropic twin warns on the first two):
2492
2492
  *
2493
2493
  * - `'off'` on a tier that can't disable thinking — only the flash tiers accept a zero thinking
2494
2494
  * budget; everything else keeps paying for reasoning it was told to stop. (`'auto'` is NOT this
@@ -2498,6 +2498,12 @@ export declare class GeminiTransport implements AITransport, ChatTransport, Cost
2498
2498
  * not the Gemini 3 `thinkingLevel` enum, so the level is dropped and the turn runs at the
2499
2499
  * default posture. Without this, a caller asking for `high` on `gemini-2.5-pro` and quietly
2500
2500
  * getting the default is left to wonder why.
2501
+ * - A graded depth whose DIALECT a Gemini 3 tier speaks but whose particular value it does not
2502
+ * accept — `minimal` on `gemini-3.8-flash` or `gemini-3.1-pro-preview`, the two tiers that
2503
+ * reject it outright. Nothing is dropped here; `clampThinkingLevel` MOVES the level onto the
2504
+ * nearest one the tier takes, and since ties resolve upward the move is usually to something
2505
+ * DEARER than the caller chose. A cost decision reversed on the wire in the expensive
2506
+ * direction is exactly what this warning exists for — without it the only trace is the bill.
2501
2507
  */
2502
2508
  private warnIfThinkingUnclampable;
2503
2509
  constructor(config?: GeminiTransportConfig);
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.22.2",
4
+ "version": "15.23.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.22.2",
56
- "@genesislcap/genx": "15.22.2",
57
- "@genesislcap/rollup-builder": "15.22.2",
58
- "@genesislcap/ts-builder": "15.22.2",
59
- "@genesislcap/uvu-playwright-builder": "15.22.2",
60
- "@genesislcap/vite-builder": "15.22.2",
61
- "@genesislcap/webpack-builder": "15.22.2"
55
+ "@genesislcap/foundation-testing": "15.23.0",
56
+ "@genesislcap/genx": "15.23.0",
57
+ "@genesislcap/rollup-builder": "15.23.0",
58
+ "@genesislcap/ts-builder": "15.23.0",
59
+ "@genesislcap/uvu-playwright-builder": "15.23.0",
60
+ "@genesislcap/vite-builder": "15.23.0",
61
+ "@genesislcap/webpack-builder": "15.23.0"
62
62
  },
63
63
  "dependencies": {
64
- "@genesislcap/foundation-logger": "15.22.2",
65
- "@genesislcap/foundation-utils": "15.22.2",
64
+ "@genesislcap/foundation-logger": "15.23.0",
65
+ "@genesislcap/foundation-utils": "15.23.0",
66
66
  "@microsoft/fast-foundation": "2.50.0"
67
67
  },
68
68
  "repository": {