@kindgi/adapter-model-gemini 0.1.2 → 0.1.4-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/dist/cost.d.ts +7 -3
- package/dist/cost.d.ts.map +1 -1
- package/dist/cost.js +14 -7
- package/dist/cost.js.map +1 -1
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +12 -2
- package/dist/provider.js.map +1 -1
- package/package.json +2 -2
- package/src/cost.ts +14 -7
- package/src/provider.ts +17 -5
package/dist/cost.d.ts
CHANGED
|
@@ -27,9 +27,13 @@ export interface GeminiModelInfo extends ModelInfo {
|
|
|
27
27
|
readonly cost: ModelInfo['cost'] & Omit<GeminiCostRates, keyof ModelInfo['cost']>;
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
|
-
* Gemini's usage as the framework's counters
|
|
31
|
-
*
|
|
32
|
-
*
|
|
30
|
+
* Gemini's usage as the framework's counters:
|
|
31
|
+
* - `promptTokens` includes the cached tokens and the tokens of
|
|
32
|
+
* built-in tool prompts; `cacheReadTokens` = the cached part. Gemini
|
|
33
|
+
* writes a cache in a call of its own, so there's no
|
|
34
|
+
* `cacheWriteTokens`;
|
|
35
|
+
* - thinking bills as output, so `completionTokens` includes it, and
|
|
36
|
+
* `reasoningTokens` is that part.
|
|
33
37
|
*/
|
|
34
38
|
export declare function toFrameworkUsage(usage: GenerateContentResponseUsageMetadata | undefined): UsageCounters;
|
|
35
39
|
/**
|
package/dist/cost.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oCAAoC,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErE;;;GAGG;AACH,eAAO,MAAM,gCAAgC,OAAO,CAAC;AAErD,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;IAC1C,oEAAoE;IACpE,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;QACjC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;QACtC,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;KAC3C,CAAC;CACH;AAED,mFAAmF;AACnF,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,eAAe,EAAE,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;CACnF;AAED
|
|
1
|
+
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oCAAoC,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErE;;;GAGG;AACH,eAAO,MAAM,gCAAgC,OAAO,CAAC;AAErD,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;IAC1C,oEAAoE;IACpE,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;QACjC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;QACtC,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;KAC3C,CAAC;CACH;AAED,mFAAmF;AACnF,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,eAAe,EAAE,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;CACnF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,oCAAoC,GAAG,SAAS,GACtD,aAAa,CAUf;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM,CAenF"}
|
package/dist/cost.js
CHANGED
|
@@ -6,16 +6,23 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export const DEFAULT_CACHED_PROMPT_MULTIPLIER = 0.25;
|
|
8
8
|
/**
|
|
9
|
-
* Gemini's usage as the framework's counters
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Gemini's usage as the framework's counters:
|
|
10
|
+
* - `promptTokens` includes the cached tokens and the tokens of
|
|
11
|
+
* built-in tool prompts; `cacheReadTokens` = the cached part. Gemini
|
|
12
|
+
* writes a cache in a call of its own, so there's no
|
|
13
|
+
* `cacheWriteTokens`;
|
|
14
|
+
* - thinking bills as output, so `completionTokens` includes it, and
|
|
15
|
+
* `reasoningTokens` is that part.
|
|
12
16
|
*/
|
|
13
17
|
export function toFrameworkUsage(usage) {
|
|
14
|
-
const cached = usage?.cachedContentTokenCount
|
|
18
|
+
const cached = usage?.cachedContentTokenCount;
|
|
19
|
+
const thoughts = usage?.thoughtsTokenCount;
|
|
15
20
|
return {
|
|
16
21
|
promptTokens: (usage?.promptTokenCount ?? 0) + (usage?.toolUsePromptTokenCount ?? 0),
|
|
17
|
-
completionTokens: (usage?.candidatesTokenCount ?? 0) + (
|
|
18
|
-
|
|
22
|
+
completionTokens: (usage?.candidatesTokenCount ?? 0) + (thoughts ?? 0),
|
|
23
|
+
// A part the vendor reports is kept, 0 included.
|
|
24
|
+
...(typeof cached === 'number' && { cacheReadTokens: cached }),
|
|
25
|
+
...(typeof thoughts === 'number' && { reasoningTokens: thoughts }),
|
|
19
26
|
};
|
|
20
27
|
}
|
|
21
28
|
/**
|
|
@@ -30,7 +37,7 @@ export function computeCostUsd(usage, rates) {
|
|
|
30
37
|
: undefined;
|
|
31
38
|
const promptRate = long?.promptUsdPer1kTokens ?? rates.promptUsdPer1kTokens;
|
|
32
39
|
const completionRate = long?.completionUsdPer1kTokens ?? rates.completionUsdPer1kTokens;
|
|
33
|
-
const cached = usage.
|
|
40
|
+
const cached = usage.cacheReadTokens ?? 0;
|
|
34
41
|
const multiplier = rates.cachedPromptMultiplier ?? DEFAULT_CACHED_PROMPT_MULTIPLIER;
|
|
35
42
|
return (((usage.promptTokens - cached) * promptRate +
|
|
36
43
|
cached * promptRate * multiplier +
|
package/dist/cost.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAKjC;;;GAGG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,IAAI,CAAC;AAyBrD
|
|
1
|
+
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAKjC;;;GAGG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,IAAI,CAAC;AAyBrD;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAuD;IAEvD,MAAM,MAAM,GAAG,KAAK,EAAE,uBAAuB,CAAC;IAC9C,MAAM,QAAQ,GAAG,KAAK,EAAE,kBAAkB,CAAC;IAC3C,OAAO;QACL,YAAY,EAAE,CAAC,KAAK,EAAE,gBAAgB,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,uBAAuB,IAAI,CAAC,CAAC;QACpF,gBAAgB,EAAE,CAAC,KAAK,EAAE,oBAAoB,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC;QACtE,iDAAiD;QACjD,GAAG,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC;QAC9D,GAAG,CAAC,OAAO,QAAQ,KAAK,QAAQ,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC;KACnE,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAoB,EAAE,KAAsB;IACzE,MAAM,IAAI,GACR,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,eAAe;QACvF,CAAC,CAAC,KAAK,CAAC,WAAW;QACnB,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,UAAU,GAAG,IAAI,EAAE,oBAAoB,IAAI,KAAK,CAAC,oBAAoB,CAAC;IAC5E,MAAM,cAAc,GAAG,IAAI,EAAE,wBAAwB,IAAI,KAAK,CAAC,wBAAwB,CAAC;IACxF,MAAM,MAAM,GAAG,KAAK,CAAC,eAAe,IAAI,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,KAAK,CAAC,sBAAsB,IAAI,gCAAgC,CAAC;IACpF,OAAO,CACL,CAAC,CAAC,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,GAAG,UAAU;QACzC,MAAM,GAAG,UAAU,GAAG,UAAU;QAChC,KAAK,CAAC,gBAAgB,GAAG,cAAc,CAAC;QAC1C,IAAI,CACL,CAAC;AACJ,CAAC"}
|
package/dist/provider.d.ts.map
CHANGED
|
@@ -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;
|
|
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,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACzE;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,0FAA0F;IAC1F,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;CAChC;AAID;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,aAAa,CAuFlF;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiC1E;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,EAAE,cAK/B,CAAC;AAEL,yFAAyF;AACzF,wBAAgB,YAAY,CAC1B,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GACnC,qBAAqB,CAAC,QAAQ,CAAC,CAajC"}
|
package/dist/provider.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// Copyright (C) 2026 Kindgi Inc.
|
|
3
3
|
import { GoogleGenAI, } from '@google/genai';
|
|
4
|
+
import { createAttemptCounter } from '@kindgi/capabilities/attempts';
|
|
4
5
|
import { computeCostUsd, toFrameworkUsage } from './cost.js';
|
|
5
6
|
import { fromGeminiResponse, toGeminiFunctions, toGeminiRequest } from './translate.js';
|
|
6
7
|
/** The adapter id servers register `geminiAdapterFactory` under. */
|
|
@@ -17,6 +18,8 @@ export function createGeminiProvider(options) {
|
|
|
17
18
|
// One client per credential: reused while the resolved key stays the
|
|
18
19
|
// same, rebuilt when it rotates. `''` stands for ADC.
|
|
19
20
|
let cached;
|
|
21
|
+
// Counts each call's HTTP attempts, through the `fetch` the client sends with.
|
|
22
|
+
const attempts = createAttemptCounter();
|
|
20
23
|
async function resolveClient() {
|
|
21
24
|
if (options.client !== undefined)
|
|
22
25
|
return options.client;
|
|
@@ -27,6 +30,7 @@ export function createGeminiProvider(options) {
|
|
|
27
30
|
vertexai: true,
|
|
28
31
|
project: options.vertex.project,
|
|
29
32
|
location: options.vertex.location,
|
|
33
|
+
httpOptions: { fetch: attempts.fetch },
|
|
30
34
|
...(key !== '' && {
|
|
31
35
|
googleAuthOptions: {
|
|
32
36
|
credentials: parseServiceAccountKey(key),
|
|
@@ -63,11 +67,12 @@ export function createGeminiProvider(options) {
|
|
|
63
67
|
...(input.abortSignal !== undefined && { abortSignal: input.abortSignal }),
|
|
64
68
|
};
|
|
65
69
|
const client = await resolveClient();
|
|
66
|
-
const
|
|
70
|
+
const counted = await attempts.count(() => client.models.generateContent({
|
|
67
71
|
model: input.model,
|
|
68
72
|
contents: [...contents],
|
|
69
73
|
config,
|
|
70
|
-
});
|
|
74
|
+
}));
|
|
75
|
+
const response = counted.value;
|
|
71
76
|
const { message, finishReason } = fromGeminiResponse(response);
|
|
72
77
|
const usage = toFrameworkUsage(response.usageMetadata);
|
|
73
78
|
return {
|
|
@@ -77,6 +82,11 @@ export function createGeminiProvider(options) {
|
|
|
77
82
|
costUsd: computeCostUsd(usage, model.cost),
|
|
78
83
|
durationMs: Date.now() - startedAt,
|
|
79
84
|
provider: { id: metadata.id, model: input.model },
|
|
85
|
+
...(response.modelVersion !== undefined && { servedModel: response.modelVersion }),
|
|
86
|
+
...(response.responseId !== undefined && { providerRequestId: response.responseId }),
|
|
87
|
+
// An injected client sends with its own fetch: nothing was counted.
|
|
88
|
+
...(counted.attempts > 0 && { attempts: counted.attempts }),
|
|
89
|
+
...(response.usageMetadata !== undefined && { rawUsage: { ...response.usageMetadata } }),
|
|
80
90
|
};
|
|
81
91
|
},
|
|
82
92
|
};
|
package/dist/provider.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,EAIL,WAAW,GACZ,MAAM,eAAe,CAAC;
|
|
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.
|
|
3
|
+
"version": "0.1.4-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.
|
|
31
|
+
"@kindgi/capabilities": "0.1.4-rc.0",
|
|
32
32
|
"@google/genai": "^2.24.0"
|
|
33
33
|
},
|
|
34
34
|
"engines": {
|
package/src/cost.ts
CHANGED
|
@@ -34,18 +34,25 @@ export interface GeminiModelInfo extends ModelInfo {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
|
-
* Gemini's usage as the framework's counters
|
|
38
|
-
*
|
|
39
|
-
*
|
|
37
|
+
* Gemini's usage as the framework's counters:
|
|
38
|
+
* - `promptTokens` includes the cached tokens and the tokens of
|
|
39
|
+
* built-in tool prompts; `cacheReadTokens` = the cached part. Gemini
|
|
40
|
+
* writes a cache in a call of its own, so there's no
|
|
41
|
+
* `cacheWriteTokens`;
|
|
42
|
+
* - thinking bills as output, so `completionTokens` includes it, and
|
|
43
|
+
* `reasoningTokens` is that part.
|
|
40
44
|
*/
|
|
41
45
|
export function toFrameworkUsage(
|
|
42
46
|
usage: GenerateContentResponseUsageMetadata | undefined,
|
|
43
47
|
): UsageCounters {
|
|
44
|
-
const cached = usage?.cachedContentTokenCount
|
|
48
|
+
const cached = usage?.cachedContentTokenCount;
|
|
49
|
+
const thoughts = usage?.thoughtsTokenCount;
|
|
45
50
|
return {
|
|
46
51
|
promptTokens: (usage?.promptTokenCount ?? 0) + (usage?.toolUsePromptTokenCount ?? 0),
|
|
47
|
-
completionTokens: (usage?.candidatesTokenCount ?? 0) + (
|
|
48
|
-
|
|
52
|
+
completionTokens: (usage?.candidatesTokenCount ?? 0) + (thoughts ?? 0),
|
|
53
|
+
// A part the vendor reports is kept, 0 included.
|
|
54
|
+
...(typeof cached === 'number' && { cacheReadTokens: cached }),
|
|
55
|
+
...(typeof thoughts === 'number' && { reasoningTokens: thoughts }),
|
|
49
56
|
};
|
|
50
57
|
}
|
|
51
58
|
|
|
@@ -62,7 +69,7 @@ export function computeCostUsd(usage: UsageCounters, rates: GeminiCostRates): nu
|
|
|
62
69
|
: undefined;
|
|
63
70
|
const promptRate = long?.promptUsdPer1kTokens ?? rates.promptUsdPer1kTokens;
|
|
64
71
|
const completionRate = long?.completionUsdPer1kTokens ?? rates.completionUsdPer1kTokens;
|
|
65
|
-
const cached = usage.
|
|
72
|
+
const cached = usage.cacheReadTokens ?? 0;
|
|
66
73
|
const multiplier = rates.cachedPromptMultiplier ?? DEFAULT_CACHED_PROMPT_MULTIPLIER;
|
|
67
74
|
return (
|
|
68
75
|
((usage.promptTokens - cached) * promptRate +
|
package/src/provider.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
ModelProvider,
|
|
15
15
|
ProviderMetadata,
|
|
16
16
|
} from '@kindgi/capabilities';
|
|
17
|
+
import { createAttemptCounter } from '@kindgi/capabilities/attempts';
|
|
17
18
|
|
|
18
19
|
import { type GeminiModelInfo, computeCostUsd, toFrameworkUsage } from './cost.js';
|
|
19
20
|
import { fromGeminiResponse, toGeminiFunctions, toGeminiRequest } from './translate.js';
|
|
@@ -66,6 +67,8 @@ export function createGeminiProvider(options: GeminiProviderOptions): ModelProvi
|
|
|
66
67
|
// One client per credential: reused while the resolved key stays the
|
|
67
68
|
// same, rebuilt when it rotates. `''` stands for ADC.
|
|
68
69
|
let cached: { readonly key: string; readonly client: GeminiClient } | undefined;
|
|
70
|
+
// Counts each call's HTTP attempts, through the `fetch` the client sends with.
|
|
71
|
+
const attempts = createAttemptCounter();
|
|
69
72
|
async function resolveClient(): Promise<GeminiClient> {
|
|
70
73
|
if (options.client !== undefined) return options.client;
|
|
71
74
|
const key = options.credentials !== undefined ? await options.credentials() : '';
|
|
@@ -74,6 +77,7 @@ export function createGeminiProvider(options: GeminiProviderOptions): ModelProvi
|
|
|
74
77
|
vertexai: true,
|
|
75
78
|
project: options.vertex.project,
|
|
76
79
|
location: options.vertex.location,
|
|
80
|
+
httpOptions: { fetch: attempts.fetch },
|
|
77
81
|
...(key !== '' && {
|
|
78
82
|
googleAuthOptions: {
|
|
79
83
|
credentials: parseServiceAccountKey(key),
|
|
@@ -114,11 +118,14 @@ export function createGeminiProvider(options: GeminiProviderOptions): ModelProvi
|
|
|
114
118
|
};
|
|
115
119
|
|
|
116
120
|
const client = await resolveClient();
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
const counted = await attempts.count(() =>
|
|
122
|
+
client.models.generateContent({
|
|
123
|
+
model: input.model,
|
|
124
|
+
contents: [...contents],
|
|
125
|
+
config,
|
|
126
|
+
}),
|
|
127
|
+
);
|
|
128
|
+
const response = counted.value;
|
|
122
129
|
|
|
123
130
|
const { message, finishReason } = fromGeminiResponse(response);
|
|
124
131
|
const usage = toFrameworkUsage(response.usageMetadata);
|
|
@@ -129,6 +136,11 @@ export function createGeminiProvider(options: GeminiProviderOptions): ModelProvi
|
|
|
129
136
|
costUsd: computeCostUsd(usage, model.cost),
|
|
130
137
|
durationMs: Date.now() - startedAt,
|
|
131
138
|
provider: { id: metadata.id, model: input.model },
|
|
139
|
+
...(response.modelVersion !== undefined && { servedModel: response.modelVersion }),
|
|
140
|
+
...(response.responseId !== undefined && { providerRequestId: response.responseId }),
|
|
141
|
+
// An injected client sends with its own fetch: nothing was counted.
|
|
142
|
+
...(counted.attempts > 0 && { attempts: counted.attempts }),
|
|
143
|
+
...(response.usageMetadata !== undefined && { rawUsage: { ...response.usageMetadata } }),
|
|
132
144
|
};
|
|
133
145
|
},
|
|
134
146
|
};
|