@kindgi/adapter-model-gemini 0.1.4-rc.5 → 0.1.5-rc.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/README.md CHANGED
@@ -23,6 +23,7 @@ One non-streaming `models.generateContent` call per `invoke`:
23
23
  - **Thinking parts** (`thought: true`) are left out of the message text. Thinking tokens count as completion tokens, since they bill as output.
24
24
  - **Structured output.** `structuredOutput` becomes `responseMimeType: 'application/json'` plus `responseJsonSchema`.
25
25
  - `temperature`, `maxOutputTokens` (the call's, else the model's `ModelInfo.maxOutputTokens`) and `abortSignal` are passed through.
26
+ - **Retries.** A call that fails with a transient status (408, 429, 500, 502, 503, 504) is retried: three attempts in all, backing off from a second, with jitter. The `@google/genai` client retries only when it's told to, and the adapter tells it. A failed connection isn't retried. The result's `attempts` counts every attempt; a call that still fails throws the last error, and `attemptsOf(error)` (`@kindgi/capabilities/attempts`) counts them. An injected `client` keeps its own settings.
26
27
  - **`finishReason`:**
27
28
  - a response with function calls → `tool-use`;
28
29
  - `STOP` or unspecified → `stop`;
@@ -37,7 +38,7 @@ One non-streaming `models.generateContent` call per `invoke`:
37
38
  - uncached prompt tokens at `promptUsdPer1kTokens`;
38
39
  - cached prompt tokens at `promptUsdPer1kTokens × cachedPromptMultiplier` (default `0.25`, Gemini 2.5's implicit-cache discount);
39
40
  - completion tokens, thinking included, at `completionUsdPer1kTokens`;
40
- - `longContext: { thresholdTokens, promptUsdPer1kTokens, completionUsdPer1kTokens }`: a call whose prompt exceeds the threshold bills entirely at those rates (Gemini 2.5 Pro doubles past 200K prompt tokens).
41
+ - `longContext: { thresholdTokens, promptUsdPer1kTokens, completionUsdPer1kTokens }`: a call whose prompt exceeds the threshold bills entirely at those rates, for a model whose price rises past a prompt size.
41
42
 
42
43
  `usage.promptTokens` includes cached tokens and built-in tool prompts; `usage.cachedTokens` reports the cached ones when there are any.
43
44
 
@@ -54,6 +55,7 @@ One non-streaming `models.generateContent` call per `invoke`:
54
55
  - `metadata.region` as the location (`unspecified` means `global`);
55
56
  - an optional `secret_ref` holding a service-account key.
56
57
  - **`vertexTarget(input)`**: the project and location a registration names, as the factory reads them.
58
+ - **`geminiAdapterEntry`**: the `AdapterFactoryEntry` a runtime registers, `geminiAdapterFactory` plus **`geminiCheckConfig(input)`**. The check reports what the factory would throw on (`adapter_config.api`, `secret_ref` on the Developer API, `adapter_config.project`, `metadata.region`) with the factory's own messages, without building anything.
57
59
  - **Cost helpers**: `computeCostUsd(usage, rates)`, `toFrameworkUsage(usageMetadata)`, `GeminiCostRates`, `GeminiModelInfo`, `DEFAULT_CACHED_PROMPT_MULTIPLIER`.
58
60
  - **Translation helpers**: `toGeminiRequest(messages)`, `toGeminiFunctions(tools)`, `fromGeminiResponse(response)`, `mapFinishReason(reason)`, `checkFunctionName(name)`.
59
61
 
@@ -69,27 +71,19 @@ const gemini = createGeminiProvider({
69
71
  region: 'global',
70
72
  models: [
71
73
  {
72
- name: 'gemini-2.5-pro',
74
+ name: 'gemini-3.8-flash',
73
75
  contextWindow: 1_048_576,
74
- features: ['tool-use'],
76
+ features: ['tool-use', 'structured-output', 'long-context'],
75
77
  maxOutputTokens: 8_192,
76
78
  // Rates from Google's published pricing.
77
- cost: {
78
- promptUsdPer1kTokens: 0.00125,
79
- completionUsdPer1kTokens: 0.01,
80
- longContext: {
81
- thresholdTokens: 200_000,
82
- promptUsdPer1kTokens: 0.0025,
83
- completionUsdPer1kTokens: 0.015,
84
- },
85
- },
79
+ cost: { promptUsdPer1kTokens: 0.00075, completionUsdPer1kTokens: 0.00375 },
86
80
  },
87
81
  ],
88
82
  },
89
83
  });
90
84
 
91
85
  const result = await gemini.invoke({
92
- model: 'gemini-2.5-pro',
86
+ model: 'gemini-3.8-flash',
93
87
  messages: [{ role: 'user', content: 'Summarise the grievance in one sentence.' }],
94
88
  });
95
89
  ```
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { GEMINI_ADAPTER_ID, createGeminiProvider, geminiAdapterFactory, vertexTarget, } from './provider.js';
1
+ export { GEMINI_ADAPTER_ID, createGeminiProvider, geminiAdapterEntry, geminiAdapterFactory, geminiCheckConfig, vertexTarget, } from './provider.js';
2
2
  export type { GeminiClient, GeminiProviderOptions } from './provider.js';
3
3
  export { DEFAULT_CACHED_PROMPT_MULTIPLIER, computeCostUsd, toFrameworkUsage } from './cost.js';
4
4
  export type { GeminiCostRates, GeminiModelInfo } from './cost.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC/F,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC/F,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
- export { GEMINI_ADAPTER_ID, createGeminiProvider, geminiAdapterFactory, vertexTarget, } from './provider.js';
3
+ export { GEMINI_ADAPTER_ID, createGeminiProvider, geminiAdapterEntry, geminiAdapterFactory, geminiCheckConfig, vertexTarget, } from './provider.js';
4
4
  export { DEFAULT_CACHED_PROMPT_MULTIPLIER, computeCostUsd, toFrameworkUsage } from './cost.js';
5
5
  export { checkFunctionName, fromGeminiResponse, mapFinishReason, toGeminiFunctions, toGeminiRequest, } from './translate.js';
6
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,GACb,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE/F,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,eAAe,GAChB,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,GACb,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE/F,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,eAAe,GAChB,MAAM,gBAAgB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { type GenerateContentParameters, type GenerateContentResponse } from '@google/genai';
2
- import type { AdapterFactory, ModelProvider, ProviderMetadata } from '@kindgi/capabilities';
2
+ import type { AdapterConfigCheckInput, AdapterConfigProblem, AdapterFactory, AdapterFactoryEntry, ModelProvider, ProviderMetadata } from '@kindgi/capabilities';
3
3
  import { type GeminiModelInfo } from './cost.js';
4
4
  /** The adapter id servers register `geminiAdapterFactory` under. */
5
5
  export declare const GEMINI_ADAPTER_ID = "@kindgi/adapter-model-gemini";
@@ -73,6 +73,16 @@ export declare function parseServiceAccountKey(key: string): Record<string, stri
73
73
  * - `secret_ref` (required) — a Gemini API key from Google AI Studio.
74
74
  */
75
75
  export declare const geminiAdapterFactory: AdapterFactory;
76
+ /**
77
+ * What's wrong with a registration for this adapter, read without building
78
+ * it (`AdapterFactoryEntry.checkConfig`): its API, its Gemini API key on
79
+ * the Developer API, its Vertex project and location. Each problem's
80
+ * message is the error the factory throws for it: both read the
81
+ * registration through the same functions.
82
+ */
83
+ export declare function geminiCheckConfig(input: AdapterConfigCheckInput): readonly AdapterConfigProblem[];
84
+ /** The entry a runtime registers: the factory, and its static check. */
85
+ export declare const geminiAdapterEntry: AdapterFactoryEntry;
76
86
  /** The Vertex project and location a registration names (see `geminiAdapterFactory`). */
77
87
  export declare function vertexTarget(input: Parameters<AdapterFactory>[0]): NonNullable<GeminiProviderOptions['vertex']>;
78
88
  //# sourceMappingURL=provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAE7B,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,cAAc,EAGd,aAAa,EACb,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,KAAK,eAAe,EAAoC,MAAM,WAAW,CAAC;AAGnF,oEAAoE;AACpE,eAAO,MAAM,iBAAiB,iCAAiC,CAAC;AAEhE,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE;QACf,eAAe,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;KACtF,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,GAAG;QACpD,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;KAC7C,CAAC;IACF;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,oGAAoG;IACpG,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;CAChC;AAID;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,aAAa,CAoGlF;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiC1E;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,oBAAoB,EAAE,cAqBlC,CAAC;AAEF,yFAAyF;AACzF,wBAAgB,YAAY,CAC1B,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GACnC,WAAW,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAa9C"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAG7B,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,uBAAuB,EACvB,oBAAoB,EACpB,cAAc,EACd,mBAAmB,EAInB,aAAa,EACb,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAE,KAAK,eAAe,EAAoC,MAAM,WAAW,CAAC;AAGnF,oEAAoE;AACpE,eAAO,MAAM,iBAAiB,iCAAiC,CAAC;AAEhE,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE;QACf,eAAe,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;KACtF,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,GAAG;QACpD,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;KAC7C,CAAC;IACF;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,oGAAoG;IACpG,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;CAChC;AAaD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,aAAa,CAmHlF;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiC1E;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,oBAAoB,EAAE,cAYlC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,uBAAuB,GAAG,SAAS,oBAAoB,EAAE,CAQjG;AAED,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,EAAE,mBAKhC,CAAC;AAkCF,yFAAyF;AACzF,wBAAgB,YAAY,CAC1B,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GACnC,WAAW,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAM9C"}
package/dist/provider.js CHANGED
@@ -1,12 +1,21 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
3
  import { GoogleGenAI, } from '@google/genai';
4
+ import { adapterConfigError, samplingFor } from '@kindgi/capabilities';
4
5
  import { createAttemptCounter } from '@kindgi/capabilities/attempts';
5
6
  import { computeCostUsd, toFrameworkUsage } from './cost.js';
6
7
  import { fromGeminiResponse, toGeminiFunctions, toGeminiRequest } from './translate.js';
7
8
  /** The adapter id servers register `geminiAdapterFactory` under. */
8
9
  export const GEMINI_ADAPTER_ID = '@kindgi/adapter-model-gemini';
9
10
  const CLOUD_PLATFORM_SCOPE = 'https://www.googleapis.com/auth/cloud-platform';
11
+ /**
12
+ * The SDK retries a call only when it's given `retryOptions`: three
13
+ * attempts on a transient status (408, 429, 500, 502, 503, 504), backing
14
+ * off from a second, with jitter, the OpenAI and Anthropic SDKs' default
15
+ * count. Unlike theirs, it doesn't retry a failed connection (Node's
16
+ * `fetch failed`).
17
+ */
18
+ const RETRY_ATTEMPTS = 3;
10
19
  /**
11
20
  * A Gemini `ModelProvider`, on Vertex AI (`vertex`) or the Gemini
12
21
  * Developer API (`apiKey`). Non-streaming, tool-use enabled: one
@@ -32,7 +41,10 @@ export function createGeminiProvider(options) {
32
41
  }
33
42
  if (cached?.key === key)
34
43
  return cached.client;
35
- const client = new GoogleGenAI({ apiKey: key, httpOptions: { fetch: attempts.fetch } });
44
+ const client = new GoogleGenAI({
45
+ apiKey: key,
46
+ httpOptions: { fetch: attempts.fetch, retryOptions: { attempts: RETRY_ATTEMPTS } },
47
+ });
36
48
  cached = { key, client };
37
49
  return client;
38
50
  }
@@ -44,7 +56,7 @@ export function createGeminiProvider(options) {
44
56
  vertexai: true,
45
57
  project: vertex.project,
46
58
  location: vertex.location,
47
- httpOptions: { fetch: attempts.fetch },
59
+ httpOptions: { fetch: attempts.fetch, retryOptions: { attempts: RETRY_ATTEMPTS } },
48
60
  ...(key !== '' && {
49
61
  googleAuthOptions: {
50
62
  credentials: parseServiceAccountKey(key),
@@ -66,6 +78,7 @@ export function createGeminiProvider(options) {
66
78
  const startedAt = Date.now();
67
79
  const { systemInstruction, contents } = toGeminiRequest(input.messages);
68
80
  const maxOutputTokens = input.maxOutputTokens ?? model.maxOutputTokens;
81
+ const sampling = samplingFor(model, input);
69
82
  const config = {
70
83
  ...(systemInstruction !== undefined && { systemInstruction }),
71
84
  ...(input.tools !== undefined &&
@@ -76,9 +89,19 @@ export function createGeminiProvider(options) {
76
89
  responseMimeType: 'application/json',
77
90
  responseJsonSchema: input.structuredOutput.schema,
78
91
  }),
79
- ...(input.temperature !== undefined && { temperature: input.temperature }),
92
+ ...(sampling.temperature !== undefined && { temperature: sampling.temperature }),
93
+ ...(input.thinking === 'lowest' &&
94
+ model.thinking !== undefined && {
95
+ // Gemini's thinking levels: `low`, `minimal` (3.8 Flash refuses `minimal`).
96
+ thinkingConfig: { thinkingLevel: model.thinking.lowest.toUpperCase() },
97
+ }),
80
98
  ...(maxOutputTokens !== undefined && { maxOutputTokens }),
81
99
  ...(input.abortSignal !== undefined && { abortSignal: input.abortSignal }),
100
+ // A header on this request only, when the caller sets it (the
101
+ // provider's registration opted in); merged into the client's.
102
+ ...(input.traceparent !== undefined && {
103
+ httpOptions: { headers: { traceparent: input.traceparent } },
104
+ }),
82
105
  };
83
106
  const client = await resolveClient();
84
107
  const counted = await attempts.count(() => client.models.generateContent({
@@ -101,6 +124,7 @@ export function createGeminiProvider(options) {
101
124
  // An injected client sends with its own fetch: nothing was counted.
102
125
  ...(counted.attempts > 0 && { attempts: counted.attempts }),
103
126
  ...(response.usageMetadata !== undefined && { rawUsage: { ...response.usageMetadata } }),
127
+ ...(sampling.warnings.length > 0 && { warnings: sampling.warnings }),
104
128
  };
105
129
  },
106
130
  };
@@ -160,34 +184,87 @@ export function parseServiceAccountKey(key) {
160
184
  */
161
185
  export const geminiAdapterFactory = (input) => {
162
186
  const metadata = input.metadata;
163
- const api = input.config?.api ?? 'vertex';
164
- if (api === 'developer') {
165
- if (input.resolveApiKey === undefined) {
166
- throw new Error(`${GEMINI_ADAPTER_ID}: provider "${input.metadata.id}" uses the Gemini Developer API (adapter_config.api "developer") and needs secret_ref: its Gemini API key.`);
167
- }
187
+ const hasSecretRef = input.resolveApiKey !== undefined;
188
+ throwIf(input.metadata.id, apiProblem(input) ?? developerKeyProblem(input, hasSecretRef));
189
+ if (apiOf(input) === 'developer') {
168
190
  return createGeminiProvider({ metadata, apiKey: input.resolveApiKey });
169
191
  }
170
- if (api !== 'vertex') {
171
- throw new Error(`${GEMINI_ADAPTER_ID}: provider "${input.metadata.id}" adapter_config.api must be "vertex" or "developer", got ${JSON.stringify(api)}.`);
172
- }
173
192
  return createGeminiProvider({
174
193
  metadata,
175
194
  vertex: vertexTarget(input),
176
195
  ...(input.resolveApiKey !== undefined && { credentials: input.resolveApiKey }),
177
196
  });
178
197
  };
198
+ /**
199
+ * What's wrong with a registration for this adapter, read without building
200
+ * it (`AdapterFactoryEntry.checkConfig`): its API, its Gemini API key on
201
+ * the Developer API, its Vertex project and location. Each problem's
202
+ * message is the error the factory throws for it: both read the
203
+ * registration through the same functions.
204
+ */
205
+ export function geminiCheckConfig(input) {
206
+ const api = apiProblem(input);
207
+ if (api !== undefined)
208
+ return [api];
209
+ if (apiOf(input) === 'developer') {
210
+ const key = developerKeyProblem(input, input.hasSecretRef);
211
+ return key !== undefined ? [key] : [];
212
+ }
213
+ return vertexTargetProblems(input);
214
+ }
215
+ /** The entry a runtime registers: the factory, and its static check. */
216
+ export const geminiAdapterEntry = {
217
+ adapterId: GEMINI_ADAPTER_ID,
218
+ capabilityKind: 'llm-inference',
219
+ factory: geminiAdapterFactory,
220
+ checkConfig: geminiCheckConfig,
221
+ };
222
+ function throwIf(providerId, problem) {
223
+ if (problem !== undefined)
224
+ throw adapterConfigError(GEMINI_ADAPTER_ID, providerId, problem);
225
+ }
226
+ function apiOf(input) {
227
+ return input.config?.api ?? 'vertex';
228
+ }
229
+ function apiProblem(input) {
230
+ const api = apiOf(input);
231
+ if (api === 'vertex' || api === 'developer')
232
+ return undefined;
233
+ return {
234
+ path: '/adapter_config/api',
235
+ message: `adapter_config.api must be "vertex" or "developer", got ${JSON.stringify(api)}.`,
236
+ };
237
+ }
238
+ function developerKeyProblem(input, hasSecretRef) {
239
+ if (apiOf(input) !== 'developer' || hasSecretRef)
240
+ return undefined;
241
+ return {
242
+ path: '/secret_ref',
243
+ message: 'uses the Gemini Developer API (adapter_config.api "developer") and needs secret_ref: its Gemini API key.',
244
+ };
245
+ }
179
246
  /** The Vertex project and location a registration names (see `geminiAdapterFactory`). */
180
247
  export function vertexTarget(input) {
248
+ throwIf(input.metadata.id, vertexTargetProblems(input)[0]);
249
+ return {
250
+ project: input.config?.project,
251
+ location: locationOf(input),
252
+ };
253
+ }
254
+ function locationOf(input) {
255
+ return input.metadata.region === 'unspecified' ? 'global' : input.metadata.region;
256
+ }
257
+ function vertexTargetProblems(input) {
181
258
  const project = input.config?.project;
182
259
  if (typeof project !== 'string' || project.length === 0) {
183
- throw new Error(`${GEMINI_ADAPTER_ID}: provider "${input.metadata.id}" needs adapter_config.project (the Vertex AI project).`);
260
+ return [
261
+ {
262
+ path: '/adapter_config/project',
263
+ message: 'needs adapter_config.project (the Vertex AI project).',
264
+ },
265
+ ];
184
266
  }
185
- const target = {
186
- project,
187
- location: input.metadata.region === 'unspecified' ? 'global' : input.metadata.region,
188
- };
189
- checkVertexTarget(input.metadata.id, target);
190
- return target;
267
+ return vertexTargetProblemsOf({ project, location: locationOf(input) });
191
268
  }
192
269
  /** A provider names exactly one target: Vertex AI, or a Gemini API key. */
193
270
  function checkTarget(providerId, options) {
@@ -195,7 +272,7 @@ function checkTarget(providerId, options) {
195
272
  throw new Error(`${GEMINI_ADAPTER_ID}: provider "${providerId}" needs exactly one of vertex (a Vertex AI project) or apiKey (a Gemini Developer API key).`);
196
273
  }
197
274
  if (options.vertex !== undefined)
198
- checkVertexTarget(providerId, options.vertex);
275
+ throwIf(providerId, vertexTargetProblemsOf(options.vertex)[0]);
199
276
  }
200
277
  /**
201
278
  * The SDK puts the project in the request path and builds the hostname
@@ -203,13 +280,21 @@ function checkTarget(providerId, options) {
203
280
  * anything but a project id and one DNS label could move the request,
204
281
  * with the server's credentials, to another host.
205
282
  */
206
- function checkVertexTarget(providerId, vertex) {
283
+ function vertexTargetProblemsOf(vertex) {
284
+ const problems = [];
207
285
  if (!VERTEX_PROJECT.test(vertex.project)) {
208
- throw new Error(`${GEMINI_ADAPTER_ID}: provider "${providerId}" adapter_config.project must be a Google Cloud project id or number.`);
286
+ problems.push({
287
+ path: '/adapter_config/project',
288
+ message: 'adapter_config.project must be a Google Cloud project id or number.',
289
+ });
209
290
  }
210
291
  if (!VERTEX_LOCATION.test(vertex.location)) {
211
- throw new Error(`${GEMINI_ADAPTER_ID}: provider "${providerId}" metadata.region must be a Vertex AI location (one DNS label, e.g. us-central1).`);
292
+ problems.push({
293
+ path: '/metadata/region',
294
+ message: 'metadata.region must be a Vertex AI location (one DNS label, e.g. us-central1).',
295
+ });
212
296
  }
297
+ return problems;
213
298
  }
214
299
  /** A Google Cloud project id (6–30: lowercase, digits, hyphens) or project number. */
215
300
  const VERTEX_PROJECT = /^(?:[a-z][a-z0-9-]{4,28}[a-z0-9]|[0-9]{1,20})$/;
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kindgi/adapter-model-gemini",
3
- "version": "0.1.4-rc.5",
3
+ "version": "0.1.5-rc.0",
4
4
  "description": "Gemini ModelProvider for @kindgi/capabilities, on Vertex AI. Wraps @google/genai with the framework's provider-neutral interface: message-trail ↔ generateContent translation, function calling with thought signatures, token and cost accounting including thinking tokens, and Google Application Default Credentials (or a service-account key from the secret store). Non-streaming, tool-use enabled.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -28,7 +28,7 @@
28
28
  "README.md"
29
29
  ],
30
30
  "dependencies": {
31
- "@kindgi/capabilities": "0.1.4-rc.5",
31
+ "@kindgi/capabilities": "0.1.5-rc.0",
32
32
  "@google/genai": "^2.24.0"
33
33
  },
34
34
  "engines": {
package/src/index.ts CHANGED
@@ -4,7 +4,9 @@
4
4
  export {
5
5
  GEMINI_ADAPTER_ID,
6
6
  createGeminiProvider,
7
+ geminiAdapterEntry,
7
8
  geminiAdapterFactory,
9
+ geminiCheckConfig,
8
10
  vertexTarget,
9
11
  } from './provider.js';
10
12
  export type { GeminiClient, GeminiProviderOptions } from './provider.js';
package/src/provider.ts CHANGED
@@ -6,14 +6,20 @@ import {
6
6
  type GenerateContentParameters,
7
7
  type GenerateContentResponse,
8
8
  GoogleGenAI,
9
+ type ThinkingLevel,
9
10
  } from '@google/genai';
10
11
  import type {
12
+ AdapterConfigCheckInput,
13
+ AdapterConfigProblem,
11
14
  AdapterFactory,
15
+ AdapterFactoryEntry,
16
+ AdapterFactoryInput,
12
17
  ModelCallInput,
13
18
  ModelCallResult,
14
19
  ModelProvider,
15
20
  ProviderMetadata,
16
21
  } from '@kindgi/capabilities';
22
+ import { adapterConfigError, samplingFor } from '@kindgi/capabilities';
17
23
  import { createAttemptCounter } from '@kindgi/capabilities/attempts';
18
24
 
19
25
  import { type GeminiModelInfo, computeCostUsd, toFrameworkUsage } from './cost.js';
@@ -62,6 +68,15 @@ export interface GeminiProviderOptions {
62
68
 
63
69
  const CLOUD_PLATFORM_SCOPE = 'https://www.googleapis.com/auth/cloud-platform';
64
70
 
71
+ /**
72
+ * The SDK retries a call only when it's given `retryOptions`: three
73
+ * attempts on a transient status (408, 429, 500, 502, 503, 504), backing
74
+ * off from a second, with jitter, the OpenAI and Anthropic SDKs' default
75
+ * count. Unlike theirs, it doesn't retry a failed connection (Node's
76
+ * `fetch failed`).
77
+ */
78
+ const RETRY_ATTEMPTS = 3;
79
+
65
80
  /**
66
81
  * A Gemini `ModelProvider`, on Vertex AI (`vertex`) or the Gemini
67
82
  * Developer API (`apiKey`). Non-streaming, tool-use enabled: one
@@ -89,7 +104,10 @@ export function createGeminiProvider(options: GeminiProviderOptions): ModelProvi
89
104
  );
90
105
  }
91
106
  if (cached?.key === key) return cached.client;
92
- const client = new GoogleGenAI({ apiKey: key, httpOptions: { fetch: attempts.fetch } });
107
+ const client = new GoogleGenAI({
108
+ apiKey: key,
109
+ httpOptions: { fetch: attempts.fetch, retryOptions: { attempts: RETRY_ATTEMPTS } },
110
+ });
93
111
  cached = { key, client };
94
112
  return client;
95
113
  }
@@ -100,7 +118,7 @@ export function createGeminiProvider(options: GeminiProviderOptions): ModelProvi
100
118
  vertexai: true,
101
119
  project: vertex.project,
102
120
  location: vertex.location,
103
- httpOptions: { fetch: attempts.fetch },
121
+ httpOptions: { fetch: attempts.fetch, retryOptions: { attempts: RETRY_ATTEMPTS } },
104
122
  ...(key !== '' && {
105
123
  googleAuthOptions: {
106
124
  credentials: parseServiceAccountKey(key),
@@ -125,6 +143,7 @@ export function createGeminiProvider(options: GeminiProviderOptions): ModelProvi
125
143
  const startedAt = Date.now();
126
144
  const { systemInstruction, contents } = toGeminiRequest(input.messages);
127
145
  const maxOutputTokens = input.maxOutputTokens ?? model.maxOutputTokens;
146
+ const sampling = samplingFor(model, input);
128
147
  const config: GenerateContentConfig = {
129
148
  ...(systemInstruction !== undefined && { systemInstruction }),
130
149
  ...(input.tools !== undefined &&
@@ -135,9 +154,19 @@ export function createGeminiProvider(options: GeminiProviderOptions): ModelProvi
135
154
  responseMimeType: 'application/json',
136
155
  responseJsonSchema: input.structuredOutput.schema,
137
156
  }),
138
- ...(input.temperature !== undefined && { temperature: input.temperature }),
157
+ ...(sampling.temperature !== undefined && { temperature: sampling.temperature }),
158
+ ...(input.thinking === 'lowest' &&
159
+ model.thinking !== undefined && {
160
+ // Gemini's thinking levels: `low`, `minimal` (3.8 Flash refuses `minimal`).
161
+ thinkingConfig: { thinkingLevel: model.thinking.lowest.toUpperCase() as ThinkingLevel },
162
+ }),
139
163
  ...(maxOutputTokens !== undefined && { maxOutputTokens }),
140
164
  ...(input.abortSignal !== undefined && { abortSignal: input.abortSignal }),
165
+ // A header on this request only, when the caller sets it (the
166
+ // provider's registration opted in); merged into the client's.
167
+ ...(input.traceparent !== undefined && {
168
+ httpOptions: { headers: { traceparent: input.traceparent } },
169
+ }),
141
170
  };
142
171
 
143
172
  const client = await resolveClient();
@@ -164,6 +193,7 @@ export function createGeminiProvider(options: GeminiProviderOptions): ModelProvi
164
193
  // An injected client sends with its own fetch: nothing was counted.
165
194
  ...(counted.attempts > 0 && { attempts: counted.attempts }),
166
195
  ...(response.usageMetadata !== undefined && { rawUsage: { ...response.usageMetadata } }),
196
+ ...(sampling.warnings.length > 0 && { warnings: sampling.warnings }),
167
197
  };
168
198
  },
169
199
  };
@@ -229,19 +259,10 @@ export function parseServiceAccountKey(key: string): Record<string, string> {
229
259
  */
230
260
  export const geminiAdapterFactory: AdapterFactory = (input) => {
231
261
  const metadata = input.metadata as GeminiProviderOptions['metadata'];
232
- const api = input.config?.api ?? 'vertex';
233
- if (api === 'developer') {
234
- if (input.resolveApiKey === undefined) {
235
- throw new Error(
236
- `${GEMINI_ADAPTER_ID}: provider "${input.metadata.id}" uses the Gemini Developer API (adapter_config.api "developer") and needs secret_ref: its Gemini API key.`,
237
- );
238
- }
239
- return createGeminiProvider({ metadata, apiKey: input.resolveApiKey });
240
- }
241
- if (api !== 'vertex') {
242
- throw new Error(
243
- `${GEMINI_ADAPTER_ID}: provider "${input.metadata.id}" adapter_config.api must be "vertex" or "developer", got ${JSON.stringify(api)}.`,
244
- );
262
+ const hasSecretRef = input.resolveApiKey !== undefined;
263
+ throwIf(input.metadata.id, apiProblem(input) ?? developerKeyProblem(input, hasSecretRef));
264
+ if (apiOf(input) === 'developer') {
265
+ return createGeminiProvider({ metadata, apiKey: input.resolveApiKey as () => Promise<string> });
245
266
  }
246
267
  return createGeminiProvider({
247
268
  metadata,
@@ -250,22 +271,89 @@ export const geminiAdapterFactory: AdapterFactory = (input) => {
250
271
  });
251
272
  };
252
273
 
274
+ /**
275
+ * What's wrong with a registration for this adapter, read without building
276
+ * it (`AdapterFactoryEntry.checkConfig`): its API, its Gemini API key on
277
+ * the Developer API, its Vertex project and location. Each problem's
278
+ * message is the error the factory throws for it: both read the
279
+ * registration through the same functions.
280
+ */
281
+ export function geminiCheckConfig(input: AdapterConfigCheckInput): readonly AdapterConfigProblem[] {
282
+ const api = apiProblem(input);
283
+ if (api !== undefined) return [api];
284
+ if (apiOf(input) === 'developer') {
285
+ const key = developerKeyProblem(input, input.hasSecretRef);
286
+ return key !== undefined ? [key] : [];
287
+ }
288
+ return vertexTargetProblems(input);
289
+ }
290
+
291
+ /** The entry a runtime registers: the factory, and its static check. */
292
+ export const geminiAdapterEntry: AdapterFactoryEntry = {
293
+ adapterId: GEMINI_ADAPTER_ID,
294
+ capabilityKind: 'llm-inference',
295
+ factory: geminiAdapterFactory,
296
+ checkConfig: geminiCheckConfig,
297
+ };
298
+
299
+ /** What the checks read of a registration. */
300
+ type Registration = Pick<AdapterFactoryInput, 'metadata' | 'config'>;
301
+
302
+ function throwIf(providerId: string, problem: AdapterConfigProblem | undefined): void {
303
+ if (problem !== undefined) throw adapterConfigError(GEMINI_ADAPTER_ID, providerId, problem);
304
+ }
305
+
306
+ function apiOf(input: Registration): unknown {
307
+ return input.config?.api ?? 'vertex';
308
+ }
309
+
310
+ function apiProblem(input: Registration): AdapterConfigProblem | undefined {
311
+ const api = apiOf(input);
312
+ if (api === 'vertex' || api === 'developer') return undefined;
313
+ return {
314
+ path: '/adapter_config/api',
315
+ message: `adapter_config.api must be "vertex" or "developer", got ${JSON.stringify(api)}.`,
316
+ };
317
+ }
318
+
319
+ function developerKeyProblem(
320
+ input: Registration,
321
+ hasSecretRef: boolean,
322
+ ): AdapterConfigProblem | undefined {
323
+ if (apiOf(input) !== 'developer' || hasSecretRef) return undefined;
324
+ return {
325
+ path: '/secret_ref',
326
+ message:
327
+ 'uses the Gemini Developer API (adapter_config.api "developer") and needs secret_ref: its Gemini API key.',
328
+ };
329
+ }
330
+
253
331
  /** The Vertex project and location a registration names (see `geminiAdapterFactory`). */
254
332
  export function vertexTarget(
255
333
  input: Parameters<AdapterFactory>[0],
256
334
  ): NonNullable<GeminiProviderOptions['vertex']> {
335
+ throwIf(input.metadata.id, vertexTargetProblems(input)[0]);
336
+ return {
337
+ project: input.config?.project as string,
338
+ location: locationOf(input),
339
+ };
340
+ }
341
+
342
+ function locationOf(input: Registration): string {
343
+ return input.metadata.region === 'unspecified' ? 'global' : input.metadata.region;
344
+ }
345
+
346
+ function vertexTargetProblems(input: Registration): AdapterConfigProblem[] {
257
347
  const project = input.config?.project;
258
348
  if (typeof project !== 'string' || project.length === 0) {
259
- throw new Error(
260
- `${GEMINI_ADAPTER_ID}: provider "${input.metadata.id}" needs adapter_config.project (the Vertex AI project).`,
261
- );
349
+ return [
350
+ {
351
+ path: '/adapter_config/project',
352
+ message: 'needs adapter_config.project (the Vertex AI project).',
353
+ },
354
+ ];
262
355
  }
263
- const target = {
264
- project,
265
- location: input.metadata.region === 'unspecified' ? 'global' : input.metadata.region,
266
- };
267
- checkVertexTarget(input.metadata.id, target);
268
- return target;
356
+ return vertexTargetProblemsOf({ project, location: locationOf(input) });
269
357
  }
270
358
 
271
359
  /** A provider names exactly one target: Vertex AI, or a Gemini API key. */
@@ -275,7 +363,7 @@ function checkTarget(providerId: string, options: GeminiProviderOptions): void {
275
363
  `${GEMINI_ADAPTER_ID}: provider "${providerId}" needs exactly one of vertex (a Vertex AI project) or apiKey (a Gemini Developer API key).`,
276
364
  );
277
365
  }
278
- if (options.vertex !== undefined) checkVertexTarget(providerId, options.vertex);
366
+ if (options.vertex !== undefined) throwIf(providerId, vertexTargetProblemsOf(options.vertex)[0]);
279
367
  }
280
368
 
281
369
  /**
@@ -284,20 +372,23 @@ function checkTarget(providerId: string, options: GeminiProviderOptions): void {
284
372
  * anything but a project id and one DNS label could move the request,
285
373
  * with the server's credentials, to another host.
286
374
  */
287
- function checkVertexTarget(
288
- providerId: string,
375
+ function vertexTargetProblemsOf(
289
376
  vertex: NonNullable<GeminiProviderOptions['vertex']>,
290
- ): void {
377
+ ): AdapterConfigProblem[] {
378
+ const problems: AdapterConfigProblem[] = [];
291
379
  if (!VERTEX_PROJECT.test(vertex.project)) {
292
- throw new Error(
293
- `${GEMINI_ADAPTER_ID}: provider "${providerId}" adapter_config.project must be a Google Cloud project id or number.`,
294
- );
380
+ problems.push({
381
+ path: '/adapter_config/project',
382
+ message: 'adapter_config.project must be a Google Cloud project id or number.',
383
+ });
295
384
  }
296
385
  if (!VERTEX_LOCATION.test(vertex.location)) {
297
- throw new Error(
298
- `${GEMINI_ADAPTER_ID}: provider "${providerId}" metadata.region must be a Vertex AI location (one DNS label, e.g. us-central1).`,
299
- );
386
+ problems.push({
387
+ path: '/metadata/region',
388
+ message: 'metadata.region must be a Vertex AI location (one DNS label, e.g. us-central1).',
389
+ });
300
390
  }
391
+ return problems;
301
392
  }
302
393
 
303
394
  /** A Google Cloud project id (6–30: lowercase, digits, hyphens) or project number. */