ak-gemini 1.0.13 → 1.0.14
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 +5 -4
- package/index.cjs +39 -7
- package/index.js +55 -6
- package/package.json +1 -1
- package/types.d.ts +5 -3
package/README.md
CHANGED
|
@@ -205,14 +205,15 @@ Clears conversation history while preserving seeded examples. Useful for startin
|
|
|
205
205
|
|
|
206
206
|
#### `transformer.getLastUsage()`
|
|
207
207
|
|
|
208
|
-
Returns structured usage data
|
|
208
|
+
Returns structured usage data for billing verification. Token counts are **cumulative across all retry attempts** - if validation failed and a retry was needed, you see the total tokens consumed, not just the final successful call. Returns `null` if no API call has been made yet.
|
|
209
209
|
|
|
210
210
|
```js
|
|
211
211
|
const usage = transformer.getLastUsage();
|
|
212
212
|
// {
|
|
213
|
-
// promptTokens:
|
|
214
|
-
// responseTokens:
|
|
215
|
-
// totalTokens:
|
|
213
|
+
// promptTokens: 300, // CUMULATIVE input tokens across all attempts
|
|
214
|
+
// responseTokens: 84, // CUMULATIVE output tokens across all attempts
|
|
215
|
+
// totalTokens: 384, // CUMULATIVE total tokens
|
|
216
|
+
// attempts: 2, // Number of attempts (1 = first try success, 2+ = retries needed)
|
|
216
217
|
// modelVersion: 'gemini-2.5-flash-001', // Actual model that responded
|
|
217
218
|
// requestedModel: 'gemini-2.5-flash', // Model you requested
|
|
218
219
|
// timestamp: 1703... // When response was received
|
package/index.cjs
CHANGED
|
@@ -122,6 +122,12 @@ var AITransformer = class {
|
|
|
122
122
|
this.logLevel = "info";
|
|
123
123
|
this.lastResponseMetadata = null;
|
|
124
124
|
this.exampleCount = 0;
|
|
125
|
+
this._cumulativeUsage = {
|
|
126
|
+
promptTokens: 0,
|
|
127
|
+
responseTokens: 0,
|
|
128
|
+
totalTokens: 0,
|
|
129
|
+
attempts: 0
|
|
130
|
+
};
|
|
125
131
|
AITransformFactory.call(this, options);
|
|
126
132
|
this.init = initChat.bind(this);
|
|
127
133
|
this.seed = seedWithExamples.bind(this);
|
|
@@ -469,9 +475,21 @@ async function prepareAndValidateMessage(sourcePayload, options = {}, validatorF
|
|
|
469
475
|
if (options.labels) {
|
|
470
476
|
messageOptions.labels = options.labels;
|
|
471
477
|
}
|
|
478
|
+
this._cumulativeUsage = {
|
|
479
|
+
promptTokens: 0,
|
|
480
|
+
responseTokens: 0,
|
|
481
|
+
totalTokens: 0,
|
|
482
|
+
attempts: 0
|
|
483
|
+
};
|
|
472
484
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
473
485
|
try {
|
|
474
486
|
const transformedPayload = attempt === 0 ? await this.rawMessage(lastPayload, messageOptions) : await this.rebuild(lastPayload, lastError.message);
|
|
487
|
+
if (this.lastResponseMetadata) {
|
|
488
|
+
this._cumulativeUsage.promptTokens += this.lastResponseMetadata.promptTokens || 0;
|
|
489
|
+
this._cumulativeUsage.responseTokens += this.lastResponseMetadata.responseTokens || 0;
|
|
490
|
+
this._cumulativeUsage.totalTokens += this.lastResponseMetadata.totalTokens || 0;
|
|
491
|
+
this._cumulativeUsage.attempts = attempt + 1;
|
|
492
|
+
}
|
|
475
493
|
lastPayload = transformedPayload;
|
|
476
494
|
if (validatorFn) {
|
|
477
495
|
await validatorFn(transformedPayload);
|
|
@@ -631,6 +649,13 @@ async function clearConversation() {
|
|
|
631
649
|
},
|
|
632
650
|
history: exampleHistory
|
|
633
651
|
});
|
|
652
|
+
this.lastResponseMetadata = null;
|
|
653
|
+
this._cumulativeUsage = {
|
|
654
|
+
promptTokens: 0,
|
|
655
|
+
responseTokens: 0,
|
|
656
|
+
totalTokens: 0,
|
|
657
|
+
attempts: 0
|
|
658
|
+
};
|
|
634
659
|
logger_default.debug(`Conversation cleared. Preserved ${exampleHistory.length} example items.`);
|
|
635
660
|
}
|
|
636
661
|
function getLastUsage() {
|
|
@@ -638,14 +663,15 @@ function getLastUsage() {
|
|
|
638
663
|
return null;
|
|
639
664
|
}
|
|
640
665
|
const meta = this.lastResponseMetadata;
|
|
666
|
+
const cumulative = this._cumulativeUsage || { promptTokens: 0, responseTokens: 0, totalTokens: 0, attempts: 1 };
|
|
667
|
+
const useCumulative = cumulative.attempts > 0;
|
|
641
668
|
return {
|
|
642
|
-
// Token breakdown for billing
|
|
643
|
-
promptTokens: meta.promptTokens,
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
//
|
|
647
|
-
|
|
648
|
-
// promptTokens + responseTokens
|
|
669
|
+
// Token breakdown for billing - CUMULATIVE across all retry attempts
|
|
670
|
+
promptTokens: useCumulative ? cumulative.promptTokens : meta.promptTokens,
|
|
671
|
+
responseTokens: useCumulative ? cumulative.responseTokens : meta.responseTokens,
|
|
672
|
+
totalTokens: useCumulative ? cumulative.totalTokens : meta.totalTokens,
|
|
673
|
+
// Number of attempts (1 = success on first try, 2+ = retries were needed)
|
|
674
|
+
attempts: useCumulative ? cumulative.attempts : 1,
|
|
649
675
|
// Model verification for billing cross-check
|
|
650
676
|
modelVersion: meta.modelVersion,
|
|
651
677
|
// Actual model that responded (e.g., 'gemini-2.5-flash-001')
|
|
@@ -684,6 +710,12 @@ async function statelessMessage(sourcePayload, options = {}, validatorFn = null)
|
|
|
684
710
|
totalTokens: result.usageMetadata?.totalTokenCount || 0,
|
|
685
711
|
timestamp: Date.now()
|
|
686
712
|
};
|
|
713
|
+
this._cumulativeUsage = {
|
|
714
|
+
promptTokens: this.lastResponseMetadata.promptTokens,
|
|
715
|
+
responseTokens: this.lastResponseMetadata.responseTokens,
|
|
716
|
+
totalTokens: this.lastResponseMetadata.totalTokens,
|
|
717
|
+
attempts: 1
|
|
718
|
+
};
|
|
687
719
|
if (result.usageMetadata && logger_default.level !== "silent") {
|
|
688
720
|
logger_default.debug(`Stateless message metadata:`, {
|
|
689
721
|
modelVersion: result.modelVersion || "not-provided",
|
package/index.js
CHANGED
|
@@ -114,6 +114,13 @@ class AITransformer {
|
|
|
114
114
|
this.logLevel = 'info'; // default log level
|
|
115
115
|
this.lastResponseMetadata = null; // stores metadata from last API response
|
|
116
116
|
this.exampleCount = 0; // tracks number of example history items from seed()
|
|
117
|
+
// Cumulative usage tracking across retry attempts
|
|
118
|
+
this._cumulativeUsage = {
|
|
119
|
+
promptTokens: 0,
|
|
120
|
+
responseTokens: 0,
|
|
121
|
+
totalTokens: 0,
|
|
122
|
+
attempts: 0
|
|
123
|
+
};
|
|
117
124
|
AITransformFactory.call(this, options);
|
|
118
125
|
|
|
119
126
|
//external API
|
|
@@ -640,6 +647,14 @@ async function prepareAndValidateMessage(sourcePayload, options = {}, validatorF
|
|
|
640
647
|
messageOptions.labels = options.labels;
|
|
641
648
|
}
|
|
642
649
|
|
|
650
|
+
// Reset cumulative usage tracking for this message call
|
|
651
|
+
this._cumulativeUsage = {
|
|
652
|
+
promptTokens: 0,
|
|
653
|
+
responseTokens: 0,
|
|
654
|
+
totalTokens: 0,
|
|
655
|
+
attempts: 0
|
|
656
|
+
};
|
|
657
|
+
|
|
643
658
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
644
659
|
try {
|
|
645
660
|
// Step 1: Get the transformed payload
|
|
@@ -647,6 +662,14 @@ async function prepareAndValidateMessage(sourcePayload, options = {}, validatorF
|
|
|
647
662
|
? await this.rawMessage(lastPayload, messageOptions) // Use the new raw method with per-message options
|
|
648
663
|
: await this.rebuild(lastPayload, lastError.message);
|
|
649
664
|
|
|
665
|
+
// Accumulate token usage from this attempt
|
|
666
|
+
if (this.lastResponseMetadata) {
|
|
667
|
+
this._cumulativeUsage.promptTokens += this.lastResponseMetadata.promptTokens || 0;
|
|
668
|
+
this._cumulativeUsage.responseTokens += this.lastResponseMetadata.responseTokens || 0;
|
|
669
|
+
this._cumulativeUsage.totalTokens += this.lastResponseMetadata.totalTokens || 0;
|
|
670
|
+
this._cumulativeUsage.attempts = attempt + 1;
|
|
671
|
+
}
|
|
672
|
+
|
|
650
673
|
lastPayload = transformedPayload; // Always update lastPayload *before* validation
|
|
651
674
|
|
|
652
675
|
// Step 2: Validate if a validator is provided
|
|
@@ -915,15 +938,25 @@ async function clearConversation() {
|
|
|
915
938
|
history: exampleHistory,
|
|
916
939
|
});
|
|
917
940
|
|
|
941
|
+
// Reset usage tracking for the new conversation
|
|
942
|
+
this.lastResponseMetadata = null;
|
|
943
|
+
this._cumulativeUsage = {
|
|
944
|
+
promptTokens: 0,
|
|
945
|
+
responseTokens: 0,
|
|
946
|
+
totalTokens: 0,
|
|
947
|
+
attempts: 0
|
|
948
|
+
};
|
|
949
|
+
|
|
918
950
|
log.debug(`Conversation cleared. Preserved ${exampleHistory.length} example items.`);
|
|
919
951
|
}
|
|
920
952
|
|
|
921
953
|
/**
|
|
922
|
-
* Returns structured usage data from the last
|
|
954
|
+
* Returns structured usage data from the last message call for billing verification.
|
|
955
|
+
* Includes CUMULATIVE token counts across all retry attempts.
|
|
923
956
|
* Call this after message() or statelessMessage() to get actual token consumption.
|
|
924
957
|
*
|
|
925
958
|
* @this {ExportedAPI}
|
|
926
|
-
* @returns {Object|null} Usage data with promptTokens, responseTokens, totalTokens,
|
|
959
|
+
* @returns {Object|null} Usage data with promptTokens, responseTokens, totalTokens, attempts, etc.
|
|
927
960
|
* Returns null if no API call has been made yet.
|
|
928
961
|
*/
|
|
929
962
|
function getLastUsage() {
|
|
@@ -932,11 +965,19 @@ function getLastUsage() {
|
|
|
932
965
|
}
|
|
933
966
|
|
|
934
967
|
const meta = this.lastResponseMetadata;
|
|
968
|
+
const cumulative = this._cumulativeUsage || { promptTokens: 0, responseTokens: 0, totalTokens: 0, attempts: 1 };
|
|
969
|
+
|
|
970
|
+
// Use cumulative tokens if tracking was active (attempts > 0), otherwise fall back to last response
|
|
971
|
+
const useCumulative = cumulative.attempts > 0;
|
|
972
|
+
|
|
935
973
|
return {
|
|
936
|
-
// Token breakdown for billing
|
|
937
|
-
promptTokens: meta.promptTokens,
|
|
938
|
-
responseTokens: meta.responseTokens,
|
|
939
|
-
totalTokens: meta.totalTokens,
|
|
974
|
+
// Token breakdown for billing - CUMULATIVE across all retry attempts
|
|
975
|
+
promptTokens: useCumulative ? cumulative.promptTokens : meta.promptTokens,
|
|
976
|
+
responseTokens: useCumulative ? cumulative.responseTokens : meta.responseTokens,
|
|
977
|
+
totalTokens: useCumulative ? cumulative.totalTokens : meta.totalTokens,
|
|
978
|
+
|
|
979
|
+
// Number of attempts (1 = success on first try, 2+ = retries were needed)
|
|
980
|
+
attempts: useCumulative ? cumulative.attempts : 1,
|
|
940
981
|
|
|
941
982
|
// Model verification for billing cross-check
|
|
942
983
|
modelVersion: meta.modelVersion, // Actual model that responded (e.g., 'gemini-2.5-flash-001')
|
|
@@ -1001,6 +1042,14 @@ async function statelessMessage(sourcePayload, options = {}, validatorFn = null)
|
|
|
1001
1042
|
timestamp: Date.now()
|
|
1002
1043
|
};
|
|
1003
1044
|
|
|
1045
|
+
// Set cumulative usage for stateless message (single attempt, no retries)
|
|
1046
|
+
this._cumulativeUsage = {
|
|
1047
|
+
promptTokens: this.lastResponseMetadata.promptTokens,
|
|
1048
|
+
responseTokens: this.lastResponseMetadata.responseTokens,
|
|
1049
|
+
totalTokens: this.lastResponseMetadata.totalTokens,
|
|
1050
|
+
attempts: 1
|
|
1051
|
+
};
|
|
1052
|
+
|
|
1004
1053
|
if (result.usageMetadata && log.level !== 'silent') {
|
|
1005
1054
|
log.debug(`Stateless message metadata:`, {
|
|
1006
1055
|
modelVersion: result.modelVersion || 'not-provided',
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -43,9 +43,10 @@ export interface ResponseMetadata {
|
|
|
43
43
|
|
|
44
44
|
/** Structured usage data returned by getLastUsage() for billing verification */
|
|
45
45
|
export interface UsageData {
|
|
46
|
-
promptTokens: number; //
|
|
47
|
-
responseTokens: number; //
|
|
48
|
-
totalTokens: number; //
|
|
46
|
+
promptTokens: number; // CUMULATIVE input tokens across all retry attempts
|
|
47
|
+
responseTokens: number; // CUMULATIVE output tokens across all retry attempts
|
|
48
|
+
totalTokens: number; // CUMULATIVE total tokens across all retry attempts
|
|
49
|
+
attempts: number; // Number of attempts (1 = first try success, 2+ = retries needed)
|
|
49
50
|
modelVersion: string | null; // Actual model that responded (e.g., 'gemini-2.5-flash-001')
|
|
50
51
|
requestedModel: string; // Model you requested (e.g., 'gemini-2.5-flash')
|
|
51
52
|
timestamp: number; // When response was received
|
|
@@ -91,6 +92,7 @@ export interface AITransformerContext {
|
|
|
91
92
|
lastResponseMetadata?: ResponseMetadata | null; // Metadata from the last API response
|
|
92
93
|
exampleCount?: number; // Number of example history items from seed()
|
|
93
94
|
clearConversation?: () => Promise<void>; // Clears conversation history while preserving examples
|
|
95
|
+
_cumulativeUsage?: { promptTokens: number; responseTokens: number; totalTokens: number; attempts: number }; // Internal cumulative tracking
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
export interface TransformationExample {
|