@x12i/ai-gateway 9.0.7 → 9.0.8
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/gateway-utils.d.ts +17 -0
- package/dist/gateway-utils.js +52 -0
- package/dist/gateway.js +5 -24
- package/dist/usage-tracker.js +2 -5
- package/dist-cjs/gateway-utils.cjs +54 -0
- package/dist-cjs/gateway-utils.d.ts +17 -0
- package/dist-cjs/gateway.cjs +4 -23
- package/dist-cjs/usage-tracker.cjs +2 -5
- package/package.json +1 -1
package/dist/gateway-utils.d.ts
CHANGED
|
@@ -19,3 +19,20 @@ export declare function ensureTaskTypeId(request: ChatRequest, logger: Logxer):
|
|
|
19
19
|
export declare function mergeConfig(request: ChatRequest & {
|
|
20
20
|
useInternalDefaults?: 'skill' | 'audit';
|
|
21
21
|
}, config: GatewayConfig, logger: Logxer): Promise<ChatRequest['config']>;
|
|
22
|
+
/**
|
|
23
|
+
* Maps provider/router usage objects to gateway token counts (`metadata.tokens`, Activix, trace attempts).
|
|
24
|
+
* Handles promptTokens/inputTokens, OpenAI-style snake_case, and missing total (sum prompt+completion).
|
|
25
|
+
*/
|
|
26
|
+
export declare function normalizeRouterUsageTokens(usage: unknown): {
|
|
27
|
+
prompt: number;
|
|
28
|
+
completion: number;
|
|
29
|
+
total: number;
|
|
30
|
+
} | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Reads token usage from every stable location the router may populate (see docs/PROVIDERS_ROUTER_DIAGNOSTICS_TRACE_REQUIREMENTS.md).
|
|
33
|
+
*/
|
|
34
|
+
export declare function extractTokenUsageFromRouterResponse(routerResponse: unknown): {
|
|
35
|
+
prompt: number;
|
|
36
|
+
completion: number;
|
|
37
|
+
total: number;
|
|
38
|
+
};
|
package/dist/gateway-utils.js
CHANGED
|
@@ -179,3 +179,55 @@ export async function mergeConfig(request, config, logger) {
|
|
|
179
179
|
});
|
|
180
180
|
return merged;
|
|
181
181
|
}
|
|
182
|
+
function firstFiniteNumber(...vals) {
|
|
183
|
+
for (const v of vals) {
|
|
184
|
+
if (typeof v === 'number' && Number.isFinite(v))
|
|
185
|
+
return v;
|
|
186
|
+
}
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Maps provider/router usage objects to gateway token counts (`metadata.tokens`, Activix, trace attempts).
|
|
191
|
+
* Handles promptTokens/inputTokens, OpenAI-style snake_case, and missing total (sum prompt+completion).
|
|
192
|
+
*/
|
|
193
|
+
export function normalizeRouterUsageTokens(usage) {
|
|
194
|
+
if (usage == null || typeof usage !== 'object')
|
|
195
|
+
return undefined;
|
|
196
|
+
const u = usage;
|
|
197
|
+
const prompt = firstFiniteNumber(u.promptTokens, u.inputTokens, u.prompt, u.prompt_tokens) ?? 0;
|
|
198
|
+
const completion = firstFiniteNumber(u.completionTokens, u.outputTokens, u.completion, u.completion_tokens) ?? 0;
|
|
199
|
+
let total = firstFiniteNumber(u.totalTokens, u.total_tokens) ?? 0;
|
|
200
|
+
if (!total && (prompt || completion))
|
|
201
|
+
total = prompt + completion;
|
|
202
|
+
return { prompt, completion, total };
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Reads token usage from every stable location the router may populate (see docs/PROVIDERS_ROUTER_DIAGNOSTICS_TRACE_REQUIREMENTS.md).
|
|
206
|
+
*/
|
|
207
|
+
export function extractTokenUsageFromRouterResponse(routerResponse) {
|
|
208
|
+
if (routerResponse == null || typeof routerResponse !== 'object') {
|
|
209
|
+
return { prompt: 0, completion: 0, total: 0 };
|
|
210
|
+
}
|
|
211
|
+
const r = routerResponse;
|
|
212
|
+
const meta = r.metadata != null && typeof r.metadata === 'object'
|
|
213
|
+
? r.metadata
|
|
214
|
+
: undefined;
|
|
215
|
+
const buckets = [r.usage];
|
|
216
|
+
if (meta) {
|
|
217
|
+
buckets.push(meta.usage);
|
|
218
|
+
const nested = meta['ai-activities-response'];
|
|
219
|
+
if (nested != null && typeof nested === 'object') {
|
|
220
|
+
buckets.push(nested.usage);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const raw = r.rawResponse ?? r.raw;
|
|
224
|
+
if (raw != null && typeof raw === 'object') {
|
|
225
|
+
buckets.push(raw.usage);
|
|
226
|
+
}
|
|
227
|
+
for (const b of buckets) {
|
|
228
|
+
const n = normalizeRouterUsageTokens(b);
|
|
229
|
+
if (n && (n.prompt || n.completion || n.total))
|
|
230
|
+
return n;
|
|
231
|
+
}
|
|
232
|
+
return { prompt: 0, completion: 0, total: 0 };
|
|
233
|
+
}
|
package/dist/gateway.js
CHANGED
|
@@ -8,7 +8,7 @@ import { ensureGatewayRequestIdentity } from './activity-manager.js';
|
|
|
8
8
|
import { initializeGatewayComponents } from './gateway-config.js';
|
|
9
9
|
import { buildMessages } from './message-builder.js';
|
|
10
10
|
import { extractJsonFromFlexMd } from './flex-md-loader.js';
|
|
11
|
-
import { mergeConfig } from './gateway-utils.js';
|
|
11
|
+
import { extractTokenUsageFromRouterResponse, mergeConfig } from './gateway-utils.js';
|
|
12
12
|
import { autoRegisterProviders } from './gateway-provider-auto-register.js';
|
|
13
13
|
import { setGatewayLastJobId, setGatewayRuntimeClients } from './runtime-objects.js';
|
|
14
14
|
import { gatewayLogDebug, withActivityIdentity } from './gateway-log-meta.js';
|
|
@@ -94,7 +94,7 @@ export class AIGateway {
|
|
|
94
94
|
aiRequestId: request.aiRequestId,
|
|
95
95
|
identity: request.identity,
|
|
96
96
|
latencyMs: Date.now() - startTime,
|
|
97
|
-
tokens: response
|
|
97
|
+
tokens: extractTokenUsageFromRouterResponse(response),
|
|
98
98
|
taskTypeId,
|
|
99
99
|
agentType: 'chat'
|
|
100
100
|
}
|
|
@@ -340,12 +340,9 @@ export class AIGateway {
|
|
|
340
340
|
const respAny = tryResp;
|
|
341
341
|
if (ok && respAny) {
|
|
342
342
|
const meta = respAny.metadata || {};
|
|
343
|
-
const
|
|
344
|
-
const prompt = usage?.promptTokens ?? usage?.inputTokens ?? 0;
|
|
345
|
-
const completion = usage?.completionTokens ?? usage?.outputTokens ?? 0;
|
|
346
|
-
const total = usage?.totalTokens ?? 0;
|
|
343
|
+
const tokenCounts = extractTokenUsageFromRouterResponse(respAny);
|
|
347
344
|
a.usage = {
|
|
348
|
-
tokens:
|
|
345
|
+
tokens: tokenCounts,
|
|
349
346
|
maxTokensRequested: typeof meta?.maxTokensRequested === 'number'
|
|
350
347
|
? meta.maxTokensRequested
|
|
351
348
|
: typeof mergedConfig?.maxTokens === 'number'
|
|
@@ -491,23 +488,7 @@ export class AIGateway {
|
|
|
491
488
|
}
|
|
492
489
|
contentType = 'structured';
|
|
493
490
|
parsingMethod = 'flex-md';
|
|
494
|
-
|
|
495
|
-
let tokens = { prompt: 0, completion: 0, total: 0 };
|
|
496
|
-
if (routerResponse.usage) {
|
|
497
|
-
tokens = {
|
|
498
|
-
prompt: routerResponse.usage.promptTokens || routerResponse.usage.inputTokens || 0,
|
|
499
|
-
completion: routerResponse.usage.completionTokens || routerResponse.usage.outputTokens || 0,
|
|
500
|
-
total: routerResponse.usage.totalTokens || 0
|
|
501
|
-
};
|
|
502
|
-
}
|
|
503
|
-
else if (routerResponse.metadata?.['ai-activities-response']?.usage) {
|
|
504
|
-
const usage = routerResponse.metadata['ai-activities-response'].usage;
|
|
505
|
-
tokens = {
|
|
506
|
-
prompt: usage.promptTokens || usage.inputTokens || 0,
|
|
507
|
-
completion: usage.completionTokens || usage.outputTokens || 0,
|
|
508
|
-
total: usage.totalTokens || 0
|
|
509
|
-
};
|
|
510
|
-
}
|
|
491
|
+
const tokens = extractTokenUsageFromRouterResponse(routerResponse);
|
|
511
492
|
const enhancedResponse = {
|
|
512
493
|
content: content,
|
|
513
494
|
parsedContent: parsedContent,
|
package/dist/usage-tracker.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Note: x-models dependency removed - usage tracking functions are permanently disabled
|
|
10
10
|
*/
|
|
11
|
+
import { extractTokenUsageFromRouterResponse } from './gateway-utils.js';
|
|
11
12
|
/**
|
|
12
13
|
* Manages usage tracking for LLM requests
|
|
13
14
|
*/
|
|
@@ -26,11 +27,7 @@ export class UsageTracker {
|
|
|
26
27
|
* @returns Token usage breakdown
|
|
27
28
|
*/
|
|
28
29
|
extractTokens(response) {
|
|
29
|
-
return
|
|
30
|
-
prompt: response.usage?.promptTokens || 0,
|
|
31
|
-
completion: response.usage?.completionTokens || 0,
|
|
32
|
-
total: response.usage?.totalTokens || 0
|
|
33
|
-
};
|
|
30
|
+
return extractTokenUsageFromRouterResponse(response);
|
|
34
31
|
}
|
|
35
32
|
/**
|
|
36
33
|
* Records usage for a request
|
|
@@ -40,6 +40,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
40
40
|
exports.generateMD5Hash = generateMD5Hash;
|
|
41
41
|
exports.ensureTaskTypeId = ensureTaskTypeId;
|
|
42
42
|
exports.mergeConfig = mergeConfig;
|
|
43
|
+
exports.normalizeRouterUsageTokens = normalizeRouterUsageTokens;
|
|
44
|
+
exports.extractTokenUsageFromRouterResponse = extractTokenUsageFromRouterResponse;
|
|
43
45
|
const crypto = __importStar(require("crypto"));
|
|
44
46
|
const gateway_instructions_js_1 = require("./gateway-instructions.cjs");
|
|
45
47
|
const flex_md_loader_js_1 = require("./flex-md-loader.cjs");
|
|
@@ -217,3 +219,55 @@ async function mergeConfig(request, config, logger) {
|
|
|
217
219
|
});
|
|
218
220
|
return merged;
|
|
219
221
|
}
|
|
222
|
+
function firstFiniteNumber(...vals) {
|
|
223
|
+
for (const v of vals) {
|
|
224
|
+
if (typeof v === 'number' && Number.isFinite(v))
|
|
225
|
+
return v;
|
|
226
|
+
}
|
|
227
|
+
return undefined;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Maps provider/router usage objects to gateway token counts (`metadata.tokens`, Activix, trace attempts).
|
|
231
|
+
* Handles promptTokens/inputTokens, OpenAI-style snake_case, and missing total (sum prompt+completion).
|
|
232
|
+
*/
|
|
233
|
+
function normalizeRouterUsageTokens(usage) {
|
|
234
|
+
if (usage == null || typeof usage !== 'object')
|
|
235
|
+
return undefined;
|
|
236
|
+
const u = usage;
|
|
237
|
+
const prompt = firstFiniteNumber(u.promptTokens, u.inputTokens, u.prompt, u.prompt_tokens) ?? 0;
|
|
238
|
+
const completion = firstFiniteNumber(u.completionTokens, u.outputTokens, u.completion, u.completion_tokens) ?? 0;
|
|
239
|
+
let total = firstFiniteNumber(u.totalTokens, u.total_tokens) ?? 0;
|
|
240
|
+
if (!total && (prompt || completion))
|
|
241
|
+
total = prompt + completion;
|
|
242
|
+
return { prompt, completion, total };
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Reads token usage from every stable location the router may populate (see docs/PROVIDERS_ROUTER_DIAGNOSTICS_TRACE_REQUIREMENTS.md).
|
|
246
|
+
*/
|
|
247
|
+
function extractTokenUsageFromRouterResponse(routerResponse) {
|
|
248
|
+
if (routerResponse == null || typeof routerResponse !== 'object') {
|
|
249
|
+
return { prompt: 0, completion: 0, total: 0 };
|
|
250
|
+
}
|
|
251
|
+
const r = routerResponse;
|
|
252
|
+
const meta = r.metadata != null && typeof r.metadata === 'object'
|
|
253
|
+
? r.metadata
|
|
254
|
+
: undefined;
|
|
255
|
+
const buckets = [r.usage];
|
|
256
|
+
if (meta) {
|
|
257
|
+
buckets.push(meta.usage);
|
|
258
|
+
const nested = meta['ai-activities-response'];
|
|
259
|
+
if (nested != null && typeof nested === 'object') {
|
|
260
|
+
buckets.push(nested.usage);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
const raw = r.rawResponse ?? r.raw;
|
|
264
|
+
if (raw != null && typeof raw === 'object') {
|
|
265
|
+
buckets.push(raw.usage);
|
|
266
|
+
}
|
|
267
|
+
for (const b of buckets) {
|
|
268
|
+
const n = normalizeRouterUsageTokens(b);
|
|
269
|
+
if (n && (n.prompt || n.completion || n.total))
|
|
270
|
+
return n;
|
|
271
|
+
}
|
|
272
|
+
return { prompt: 0, completion: 0, total: 0 };
|
|
273
|
+
}
|
|
@@ -19,3 +19,20 @@ export declare function ensureTaskTypeId(request: ChatRequest, logger: Logxer):
|
|
|
19
19
|
export declare function mergeConfig(request: ChatRequest & {
|
|
20
20
|
useInternalDefaults?: 'skill' | 'audit';
|
|
21
21
|
}, config: GatewayConfig, logger: Logxer): Promise<ChatRequest['config']>;
|
|
22
|
+
/**
|
|
23
|
+
* Maps provider/router usage objects to gateway token counts (`metadata.tokens`, Activix, trace attempts).
|
|
24
|
+
* Handles promptTokens/inputTokens, OpenAI-style snake_case, and missing total (sum prompt+completion).
|
|
25
|
+
*/
|
|
26
|
+
export declare function normalizeRouterUsageTokens(usage: unknown): {
|
|
27
|
+
prompt: number;
|
|
28
|
+
completion: number;
|
|
29
|
+
total: number;
|
|
30
|
+
} | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Reads token usage from every stable location the router may populate (see docs/PROVIDERS_ROUTER_DIAGNOSTICS_TRACE_REQUIREMENTS.md).
|
|
33
|
+
*/
|
|
34
|
+
export declare function extractTokenUsageFromRouterResponse(routerResponse: unknown): {
|
|
35
|
+
prompt: number;
|
|
36
|
+
completion: number;
|
|
37
|
+
total: number;
|
|
38
|
+
};
|
package/dist-cjs/gateway.cjs
CHANGED
|
@@ -97,7 +97,7 @@ class AIGateway {
|
|
|
97
97
|
aiRequestId: request.aiRequestId,
|
|
98
98
|
identity: request.identity,
|
|
99
99
|
latencyMs: Date.now() - startTime,
|
|
100
|
-
tokens:
|
|
100
|
+
tokens: (0, gateway_utils_js_1.extractTokenUsageFromRouterResponse)(response),
|
|
101
101
|
taskTypeId,
|
|
102
102
|
agentType: 'chat'
|
|
103
103
|
}
|
|
@@ -343,12 +343,9 @@ class AIGateway {
|
|
|
343
343
|
const respAny = tryResp;
|
|
344
344
|
if (ok && respAny) {
|
|
345
345
|
const meta = respAny.metadata || {};
|
|
346
|
-
const
|
|
347
|
-
const prompt = usage?.promptTokens ?? usage?.inputTokens ?? 0;
|
|
348
|
-
const completion = usage?.completionTokens ?? usage?.outputTokens ?? 0;
|
|
349
|
-
const total = usage?.totalTokens ?? 0;
|
|
346
|
+
const tokenCounts = (0, gateway_utils_js_1.extractTokenUsageFromRouterResponse)(respAny);
|
|
350
347
|
a.usage = {
|
|
351
|
-
tokens:
|
|
348
|
+
tokens: tokenCounts,
|
|
352
349
|
maxTokensRequested: typeof meta?.maxTokensRequested === 'number'
|
|
353
350
|
? meta.maxTokensRequested
|
|
354
351
|
: typeof mergedConfig?.maxTokens === 'number'
|
|
@@ -494,23 +491,7 @@ class AIGateway {
|
|
|
494
491
|
}
|
|
495
492
|
contentType = 'structured';
|
|
496
493
|
parsingMethod = 'flex-md';
|
|
497
|
-
|
|
498
|
-
let tokens = { prompt: 0, completion: 0, total: 0 };
|
|
499
|
-
if (routerResponse.usage) {
|
|
500
|
-
tokens = {
|
|
501
|
-
prompt: routerResponse.usage.promptTokens || routerResponse.usage.inputTokens || 0,
|
|
502
|
-
completion: routerResponse.usage.completionTokens || routerResponse.usage.outputTokens || 0,
|
|
503
|
-
total: routerResponse.usage.totalTokens || 0
|
|
504
|
-
};
|
|
505
|
-
}
|
|
506
|
-
else if (routerResponse.metadata?.['ai-activities-response']?.usage) {
|
|
507
|
-
const usage = routerResponse.metadata['ai-activities-response'].usage;
|
|
508
|
-
tokens = {
|
|
509
|
-
prompt: usage.promptTokens || usage.inputTokens || 0,
|
|
510
|
-
completion: usage.completionTokens || usage.outputTokens || 0,
|
|
511
|
-
total: usage.totalTokens || 0
|
|
512
|
-
};
|
|
513
|
-
}
|
|
494
|
+
const tokens = (0, gateway_utils_js_1.extractTokenUsageFromRouterResponse)(routerResponse);
|
|
514
495
|
const enhancedResponse = {
|
|
515
496
|
content: content,
|
|
516
497
|
parsedContent: parsedContent,
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.UsageTracker = void 0;
|
|
14
|
+
const gateway_utils_js_1 = require("./gateway-utils.cjs");
|
|
14
15
|
/**
|
|
15
16
|
* Manages usage tracking for LLM requests
|
|
16
17
|
*/
|
|
@@ -29,11 +30,7 @@ class UsageTracker {
|
|
|
29
30
|
* @returns Token usage breakdown
|
|
30
31
|
*/
|
|
31
32
|
extractTokens(response) {
|
|
32
|
-
return
|
|
33
|
-
prompt: response.usage?.promptTokens || 0,
|
|
34
|
-
completion: response.usage?.completionTokens || 0,
|
|
35
|
-
total: response.usage?.totalTokens || 0
|
|
36
|
-
};
|
|
33
|
+
return (0, gateway_utils_js_1.extractTokenUsageFromRouterResponse)(response);
|
|
37
34
|
}
|
|
38
35
|
/**
|
|
39
36
|
* Records usage for a request
|