@future-explorer/lib 1.0.11 → 1.0.12
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 +58 -1
- package/dist/clients/ai/index.d.ts +1 -0
- package/dist/clients/ai/index.d.ts.map +1 -1
- package/dist/clients/ai/index.js +1 -0
- package/dist/clients/ai/unified/ai-usage-tracker.d.ts +34 -0
- package/dist/clients/ai/unified/ai-usage-tracker.d.ts.map +1 -0
- package/dist/clients/ai/unified/ai-usage-tracker.js +94 -0
- package/dist/clients/ai/unified/index.d.ts +1 -0
- package/dist/clients/ai/unified/index.d.ts.map +1 -1
- package/dist/clients/ai/unified/index.js +1 -0
- package/dist/clients/ai/unified/unified-ai-client.d.ts +3 -1
- package/dist/clients/ai/unified/unified-ai-client.d.ts.map +1 -1
- package/dist/clients/ai/unified/unified-ai-client.js +23 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -107,9 +107,52 @@ console.log(result.summary); // '...'
|
|
|
107
107
|
|
|
108
108
|
### Methods
|
|
109
109
|
|
|
110
|
-
- `generateStructuredResponse<T>(schema
|
|
110
|
+
- `generateStructuredResponse<T>(schema, params, usageTracker?)`: Generates a structured response matching the Zod schema. Accepts `prompt`, `system`, plus any additional options. Optionally pass an `AiUsageTracker` to record usage.
|
|
111
111
|
- `getModel()`: Returns the underlying LanguageModel instance
|
|
112
112
|
|
|
113
|
+
## AiUsageTracker
|
|
114
|
+
|
|
115
|
+
Tracks and accumulates AI usage costs across multiple `generateStructuredResponse()` calls. Useful for calculating the total cost of processing a single input that requires multiple AI calls.
|
|
116
|
+
|
|
117
|
+
### Basic Usage
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import { UnifiedAiClient, AiUsageTracker, Provider } from '@future-explorer/lib';
|
|
121
|
+
import { z } from 'zod';
|
|
122
|
+
|
|
123
|
+
const client = new UnifiedAiClient(Provider.XAI);
|
|
124
|
+
const tracker = new AiUsageTracker();
|
|
125
|
+
|
|
126
|
+
const Schema = z.object({ summary: z.string() });
|
|
127
|
+
|
|
128
|
+
// Each call automatically records usage in the tracker
|
|
129
|
+
await client.generateStructuredResponse(Schema, { prompt: 'First call...' }, tracker);
|
|
130
|
+
await client.generateStructuredResponse(Schema, { prompt: 'Second call...' }, tracker);
|
|
131
|
+
|
|
132
|
+
// Get accumulated results
|
|
133
|
+
console.log(tracker.getSummary());
|
|
134
|
+
// AI Usage: 2 call(s), $0.001234 estimated
|
|
135
|
+
// Tokens - input: 500, output: 200, reasoning: 0, total: 700
|
|
136
|
+
// [xai/grok-4-1-fast-reasoning] in=250 out=100 $0.000617 3200ms
|
|
137
|
+
// [xai/grok-4-1-fast-reasoning] in=250 out=100 $0.000617 2800ms
|
|
138
|
+
|
|
139
|
+
console.log(tracker.getTotalCost()); // 0.001234
|
|
140
|
+
console.log(tracker.getTotalTokens()); // { input: 500, output: 200, reasoning: 0, total: 700 }
|
|
141
|
+
console.log(tracker.getCalls()); // AiCallUsage[]
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Supported Models
|
|
145
|
+
|
|
146
|
+
Built-in pricing for cost estimation (easily extensible):
|
|
147
|
+
|
|
148
|
+
| Provider | Models |
|
|
149
|
+
| -------- | ------ |
|
|
150
|
+
| xAI | grok-4-1-fast, grok-4-fast, grok-4, grok-3, grok-3-mini, grok-2 |
|
|
151
|
+
| OpenAI | gpt-4.1, gpt-4.1-mini, gpt-4.1-nano, gpt-4o, gpt-4o-mini, o3, o3-mini, o4-mini |
|
|
152
|
+
| Gemini | gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite, gemini-2.0-flash |
|
|
153
|
+
|
|
154
|
+
Model IDs are matched by substring, so `grok-4-1-fast-reasoning` matches the `grok-4-1-fast` pricing entry.
|
|
155
|
+
|
|
113
156
|
## Development
|
|
114
157
|
|
|
115
158
|
### Build
|
|
@@ -162,6 +205,20 @@ npm publish
|
|
|
162
205
|
|
|
163
206
|
## Changelog
|
|
164
207
|
|
|
208
|
+
### 1.0.12
|
|
209
|
+
|
|
210
|
+
- Added `AiUsageTracker` for tracking AI usage costs across multiple calls
|
|
211
|
+
- `generateStructuredResponse()` now accepts optional `usageTracker` parameter
|
|
212
|
+
|
|
213
|
+
### 1.0.11
|
|
214
|
+
|
|
215
|
+
- Moved `schema` out of `GenerateObjectParams` into a separate parameter
|
|
216
|
+
- Renamed `userPrompt`/`systemMessage` to `prompt`/`system`
|
|
217
|
+
|
|
218
|
+
### 1.0.10
|
|
219
|
+
|
|
220
|
+
- Refactored `generateStructuredResponse()` to accept a single `GenerateObjectParams<T>` object
|
|
221
|
+
|
|
165
222
|
### 1.0.7
|
|
166
223
|
|
|
167
224
|
- Updated peer dependency to zod 4.2.x
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/clients/ai/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/clients/ai/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC"}
|
package/dist/clients/ai/index.js
CHANGED
|
@@ -16,5 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./grok"), exports);
|
|
18
18
|
__exportStar(require("./shared"), exports);
|
|
19
|
+
__exportStar(require("./unified/ai-usage-tracker"), exports);
|
|
19
20
|
__exportStar(require("./unified/unified-ai-client"), exports);
|
|
20
21
|
__exportStar(require("./unified/unified-ai-client.model"), exports);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { LanguageModelUsage } from 'ai';
|
|
2
|
+
export interface AiCallUsage {
|
|
3
|
+
provider: string;
|
|
4
|
+
model: string;
|
|
5
|
+
inputTokens: number;
|
|
6
|
+
outputTokens: number;
|
|
7
|
+
totalTokens: number;
|
|
8
|
+
reasoningTokens?: number;
|
|
9
|
+
cachedInputTokens?: number;
|
|
10
|
+
estimatedCost: number;
|
|
11
|
+
durationMs: number;
|
|
12
|
+
}
|
|
13
|
+
export interface ModelPricing {
|
|
14
|
+
inputPer1MTokens: number;
|
|
15
|
+
outputPer1MTokens: number;
|
|
16
|
+
reasoningPer1MTokens?: number;
|
|
17
|
+
cachedInputPer1MTokens?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class AiUsageTracker {
|
|
20
|
+
private calls;
|
|
21
|
+
addCall(call: AiCallUsage): void;
|
|
22
|
+
getCalls(): AiCallUsage[];
|
|
23
|
+
getTotalCost(): number;
|
|
24
|
+
getTotalTokens(): {
|
|
25
|
+
input: number;
|
|
26
|
+
output: number;
|
|
27
|
+
reasoning: number;
|
|
28
|
+
total: number;
|
|
29
|
+
};
|
|
30
|
+
getSummary(): string;
|
|
31
|
+
static findPricing(model: string): ModelPricing | undefined;
|
|
32
|
+
static estimateCost(model: string, usage: LanguageModelUsage): number;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=ai-usage-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-usage-tracker.d.ts","sourceRoot":"","sources":["../../../../src/clients/ai/unified/ai-usage-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,IAAI,CAAC;AAExC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AA0BD,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAqB;IAElC,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAIhC,QAAQ,IAAI,WAAW,EAAE;IAIzB,YAAY,IAAI,MAAM;IAItB,cAAc,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAYrF,UAAU,IAAI,MAAM;IAepB,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAe3D,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,MAAM;CAsBtE"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AiUsageTracker = void 0;
|
|
4
|
+
const MODEL_PRICING = {
|
|
5
|
+
// xAI / Grok
|
|
6
|
+
'grok-4-1-fast': { inputPer1MTokens: 0.2, outputPer1MTokens: 0.5, reasoningPer1MTokens: 0.5, cachedInputPer1MTokens: 0.05 },
|
|
7
|
+
'grok-4-fast': { inputPer1MTokens: 0.2, outputPer1MTokens: 0.5, reasoningPer1MTokens: 0.5, cachedInputPer1MTokens: 0.05 },
|
|
8
|
+
'grok-4': { inputPer1MTokens: 3, outputPer1MTokens: 15, cachedInputPer1MTokens: 0.75 },
|
|
9
|
+
'grok-3-mini': { inputPer1MTokens: 0.3, outputPer1MTokens: 0.5, reasoningPer1MTokens: 0.5, cachedInputPer1MTokens: 0.075 },
|
|
10
|
+
'grok-3': { inputPer1MTokens: 3, outputPer1MTokens: 15, cachedInputPer1MTokens: 0.75 },
|
|
11
|
+
'grok-2': { inputPer1MTokens: 2, outputPer1MTokens: 10 },
|
|
12
|
+
// OpenAI
|
|
13
|
+
'gpt-4.1': { inputPer1MTokens: 2, outputPer1MTokens: 8, cachedInputPer1MTokens: 0.5 },
|
|
14
|
+
'gpt-4.1-mini': { inputPer1MTokens: 0.4, outputPer1MTokens: 1.6, cachedInputPer1MTokens: 0.1 },
|
|
15
|
+
'gpt-4.1-nano': { inputPer1MTokens: 0.1, outputPer1MTokens: 0.4, cachedInputPer1MTokens: 0.025 },
|
|
16
|
+
'gpt-4o': { inputPer1MTokens: 2.5, outputPer1MTokens: 10, cachedInputPer1MTokens: 1.25 },
|
|
17
|
+
'gpt-4o-mini': { inputPer1MTokens: 0.15, outputPer1MTokens: 0.6, cachedInputPer1MTokens: 0.075 },
|
|
18
|
+
'o3': { inputPer1MTokens: 2, outputPer1MTokens: 8, reasoningPer1MTokens: 8, cachedInputPer1MTokens: 0.5 },
|
|
19
|
+
'o3-mini': { inputPer1MTokens: 1.1, outputPer1MTokens: 4.4, reasoningPer1MTokens: 4.4, cachedInputPer1MTokens: 0.275 },
|
|
20
|
+
'o4-mini': { inputPer1MTokens: 1.1, outputPer1MTokens: 4.4, reasoningPer1MTokens: 4.4, cachedInputPer1MTokens: 0.275 },
|
|
21
|
+
// Google Gemini
|
|
22
|
+
'gemini-2.5-pro': { inputPer1MTokens: 1.25, outputPer1MTokens: 10, reasoningPer1MTokens: 10 },
|
|
23
|
+
'gemini-2.5-flash': { inputPer1MTokens: 0.15, outputPer1MTokens: 0.6, reasoningPer1MTokens: 0.6 },
|
|
24
|
+
'gemini-2.5-flash-lite': { inputPer1MTokens: 0.1, outputPer1MTokens: 0.4 },
|
|
25
|
+
'gemini-2.0-flash': { inputPer1MTokens: 0.1, outputPer1MTokens: 0.4 },
|
|
26
|
+
};
|
|
27
|
+
class AiUsageTracker {
|
|
28
|
+
calls = [];
|
|
29
|
+
addCall(call) {
|
|
30
|
+
this.calls.push(call);
|
|
31
|
+
}
|
|
32
|
+
getCalls() {
|
|
33
|
+
return this.calls;
|
|
34
|
+
}
|
|
35
|
+
getTotalCost() {
|
|
36
|
+
return this.calls.reduce((sum, c) => sum + c.estimatedCost, 0);
|
|
37
|
+
}
|
|
38
|
+
getTotalTokens() {
|
|
39
|
+
return this.calls.reduce((acc, c) => ({
|
|
40
|
+
input: acc.input + c.inputTokens,
|
|
41
|
+
output: acc.output + c.outputTokens,
|
|
42
|
+
reasoning: acc.reasoning + (c.reasoningTokens ?? 0),
|
|
43
|
+
total: acc.total + c.totalTokens,
|
|
44
|
+
}), { input: 0, output: 0, reasoning: 0, total: 0 });
|
|
45
|
+
}
|
|
46
|
+
getSummary() {
|
|
47
|
+
const tokens = this.getTotalTokens();
|
|
48
|
+
const cost = this.getTotalCost();
|
|
49
|
+
const lines = [
|
|
50
|
+
`AI Usage: ${this.calls.length} call(s), $${cost.toFixed(6)} estimated`,
|
|
51
|
+
` Tokens — input: ${tokens.input}, output: ${tokens.output}, reasoning: ${tokens.reasoning}, total: ${tokens.total}`,
|
|
52
|
+
];
|
|
53
|
+
for (const c of this.calls) {
|
|
54
|
+
lines.push(` [${c.provider}/${c.model}] in=${c.inputTokens} out=${c.outputTokens}${c.reasoningTokens ? ` reasoning=${c.reasoningTokens}` : ''} $${c.estimatedCost.toFixed(6)} ${c.durationMs}ms`);
|
|
55
|
+
}
|
|
56
|
+
return lines.join('\n');
|
|
57
|
+
}
|
|
58
|
+
static findPricing(model) {
|
|
59
|
+
// Exact match first
|
|
60
|
+
if (MODEL_PRICING[model])
|
|
61
|
+
return MODEL_PRICING[model];
|
|
62
|
+
// Substring match — find the longest key that matches
|
|
63
|
+
let bestMatch;
|
|
64
|
+
for (const key of Object.keys(MODEL_PRICING)) {
|
|
65
|
+
if (model.includes(key)) {
|
|
66
|
+
if (!bestMatch || key.length > bestMatch.length) {
|
|
67
|
+
bestMatch = key;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return bestMatch ? MODEL_PRICING[bestMatch] : undefined;
|
|
72
|
+
}
|
|
73
|
+
static estimateCost(model, usage) {
|
|
74
|
+
const pricing = AiUsageTracker.findPricing(model);
|
|
75
|
+
if (!pricing)
|
|
76
|
+
return 0;
|
|
77
|
+
const inputTokens = usage.inputTokens ?? 0;
|
|
78
|
+
const outputTokens = usage.outputTokens ?? 0;
|
|
79
|
+
const reasoningTokens = usage.reasoningTokens ?? 0;
|
|
80
|
+
const cachedInputTokens = usage.cachedInputTokens ?? 0;
|
|
81
|
+
const billableInputTokens = inputTokens - cachedInputTokens;
|
|
82
|
+
let cost = 0;
|
|
83
|
+
cost += (billableInputTokens / 1_000_000) * pricing.inputPer1MTokens;
|
|
84
|
+
cost += (outputTokens / 1_000_000) * pricing.outputPer1MTokens;
|
|
85
|
+
if (pricing.cachedInputPer1MTokens) {
|
|
86
|
+
cost += (cachedInputTokens / 1_000_000) * pricing.cachedInputPer1MTokens;
|
|
87
|
+
}
|
|
88
|
+
if (pricing.reasoningPer1MTokens) {
|
|
89
|
+
cost += (reasoningTokens / 1_000_000) * pricing.reasoningPer1MTokens;
|
|
90
|
+
}
|
|
91
|
+
return cost;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.AiUsageTracker = AiUsageTracker;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/clients/ai/unified/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/clients/ai/unified/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"}
|
|
@@ -14,5 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./ai-usage-tracker"), exports);
|
|
17
18
|
__exportStar(require("./unified-ai-client"), exports);
|
|
18
19
|
__exportStar(require("./unified-ai-client.model"), exports);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LanguageModel } from 'ai';
|
|
2
2
|
import { ZodSchema } from 'zod';
|
|
3
|
+
import { AiUsageTracker } from './ai-usage-tracker';
|
|
3
4
|
import { GenerateObjectParams, Provider } from './unified-ai-client.model';
|
|
4
5
|
/**
|
|
5
6
|
* Unified AI Client that supports multiple AI providers (OpenAI, XAI, Gemini)
|
|
@@ -7,6 +8,7 @@ import { GenerateObjectParams, Provider } from './unified-ai-client.model';
|
|
|
7
8
|
*/
|
|
8
9
|
export declare class UnifiedAiClient {
|
|
9
10
|
private model;
|
|
11
|
+
private provider;
|
|
10
12
|
constructor(provider: Provider);
|
|
11
13
|
/**
|
|
12
14
|
* Generates a structured response from the AI model based on a Zod schema.
|
|
@@ -40,7 +42,7 @@ export declare class UnifiedAiClient {
|
|
|
40
42
|
* console.log(result.sentiment); // 'positive'
|
|
41
43
|
* console.log(result.confidence); // 0.95
|
|
42
44
|
*/
|
|
43
|
-
generateStructuredResponse<T>(schema: ZodSchema<T>, params: GenerateObjectParams<T
|
|
45
|
+
generateStructuredResponse<T>(schema: ZodSchema<T>, params: GenerateObjectParams<T>, usageTracker?: AiUsageTracker): Promise<T>;
|
|
44
46
|
/**
|
|
45
47
|
* Retrieves the underlying LanguageModel instance.
|
|
46
48
|
* @returns The LanguageModel instance used by the UnifiedAiClient.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unified-ai-client.d.ts","sourceRoot":"","sources":["../../../../src/clients/ai/unified/unified-ai-client.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,aAAa,EAAE,MAAM,IAAI,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE3E;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAgB;
|
|
1
|
+
{"version":3,"file":"unified-ai-client.d.ts","sourceRoot":"","sources":["../../../../src/clients/ai/unified/unified-ai-client.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,aAAa,EAAE,MAAM,IAAI,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAe,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE3E;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAgB;IAE7B,OAAO,CAAC,QAAQ,CAAW;gBAEf,QAAQ,EAAE,QAAQ;IAK9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACG,0BAA0B,CAAC,CAAC,EAChC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EACpB,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC,EAC/B,YAAY,CAAC,EAAE,cAAc,GAC5B,OAAO,CAAC,CAAC,CAAC;IAuCb;;;OAGG;IACH,QAAQ,IAAI,aAAa;IAIzB,OAAO,CAAC,WAAW;CAYpB"}
|
|
@@ -5,6 +5,7 @@ const google_1 = require("@ai-sdk/google");
|
|
|
5
5
|
const openai_1 = require("@ai-sdk/openai");
|
|
6
6
|
const xai_1 = require("@ai-sdk/xai");
|
|
7
7
|
const ai_1 = require("ai");
|
|
8
|
+
const ai_usage_tracker_1 = require("./ai-usage-tracker");
|
|
8
9
|
const unified_ai_client_model_1 = require("./unified-ai-client.model");
|
|
9
10
|
/**
|
|
10
11
|
* Unified AI Client that supports multiple AI providers (OpenAI, XAI, Gemini)
|
|
@@ -12,7 +13,9 @@ const unified_ai_client_model_1 = require("./unified-ai-client.model");
|
|
|
12
13
|
*/
|
|
13
14
|
class UnifiedAiClient {
|
|
14
15
|
model;
|
|
16
|
+
provider;
|
|
15
17
|
constructor(provider) {
|
|
18
|
+
this.provider = provider;
|
|
16
19
|
this.model = this.createModel(provider);
|
|
17
20
|
}
|
|
18
21
|
/**
|
|
@@ -47,8 +50,9 @@ class UnifiedAiClient {
|
|
|
47
50
|
* console.log(result.sentiment); // 'positive'
|
|
48
51
|
* console.log(result.confidence); // 0.95
|
|
49
52
|
*/
|
|
50
|
-
async generateStructuredResponse(schema, params) {
|
|
53
|
+
async generateStructuredResponse(schema, params, usageTracker) {
|
|
51
54
|
const { prompt, system, ...rest } = params;
|
|
55
|
+
const startTime = Date.now();
|
|
52
56
|
const result = await (0, ai_1.generateObject)({
|
|
53
57
|
...rest,
|
|
54
58
|
model: this.model,
|
|
@@ -56,6 +60,24 @@ class UnifiedAiClient {
|
|
|
56
60
|
prompt: prompt,
|
|
57
61
|
system: system,
|
|
58
62
|
});
|
|
63
|
+
const durationMs = Date.now() - startTime;
|
|
64
|
+
const usage = result.usage;
|
|
65
|
+
const model = result.response.modelId;
|
|
66
|
+
const aiCallUsage = {
|
|
67
|
+
provider: this.provider,
|
|
68
|
+
model,
|
|
69
|
+
inputTokens: usage.inputTokens ?? 0,
|
|
70
|
+
outputTokens: usage.outputTokens ?? 0,
|
|
71
|
+
totalTokens: usage.totalTokens ?? 0,
|
|
72
|
+
reasoningTokens: usage.reasoningTokens ?? undefined,
|
|
73
|
+
cachedInputTokens: usage.cachedInputTokens ?? undefined,
|
|
74
|
+
estimatedCost: ai_usage_tracker_1.AiUsageTracker.estimateCost(model, usage),
|
|
75
|
+
durationMs,
|
|
76
|
+
};
|
|
77
|
+
console.log(`[AI Call Usage] ${aiCallUsage.provider}/${aiCallUsage.model} in=${aiCallUsage.inputTokens} out=${aiCallUsage.outputTokens}${aiCallUsage.reasoningTokens ? ` reasoning=${aiCallUsage.reasoningTokens}` : ''} $${aiCallUsage.estimatedCost.toFixed(6)} ${aiCallUsage.durationMs}ms`);
|
|
78
|
+
if (usageTracker) {
|
|
79
|
+
usageTracker.addCall(aiCallUsage);
|
|
80
|
+
}
|
|
59
81
|
return result.object;
|
|
60
82
|
}
|
|
61
83
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@future-explorer/lib",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "Shared utilities and clients for Future Explorer projects",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -63,6 +63,6 @@
|
|
|
63
63
|
"rimraf": "^6.0.1",
|
|
64
64
|
"ts-node": "^10.9.2",
|
|
65
65
|
"typescript": "^5.6.3",
|
|
66
|
-
"zod": "4.
|
|
66
|
+
"zod": "^4.3.6"
|
|
67
67
|
}
|
|
68
68
|
}
|