@x12i/ai-gateway 9.1.0 → 9.1.1
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 +15 -1
- package/dist/gateway-utils.js +43 -0
- package/dist/gateway.js +11 -22
- package/dist/types.d.ts +10 -2
- package/dist-cjs/gateway-utils.cjs +45 -0
- package/dist-cjs/gateway-utils.d.ts +15 -1
- package/dist-cjs/gateway.cjs +10 -21
- package/dist-cjs/types.d.ts +10 -2
- package/package.json +1 -1
package/dist/gateway-utils.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Gateway Utilities Module
|
|
3
3
|
* Handles utility functions
|
|
4
4
|
*/
|
|
5
|
-
import type { ChatRequest, GatewayConfig } from './types.js';
|
|
5
|
+
import type { ChatRequest, GatewayConfig, ModelConfig } from './types.js';
|
|
6
6
|
import type { Logxer } from '@x12i/logxer';
|
|
7
7
|
/**
|
|
8
8
|
* Generates MD5 hash of a string
|
|
@@ -43,6 +43,20 @@ export declare function extractTokenUsageFromRouterResponse(routerResponse: unkn
|
|
|
43
43
|
* Does not compute cost from tokens — adapters must populate normalized fields or raw usage.cost-style keys.
|
|
44
44
|
*/
|
|
45
45
|
export declare function extractCostUsdFromRouterResponse(routerResponse: unknown): number | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Stable routing facts for gateway response metadata (router metadata + merged config fallbacks).
|
|
48
|
+
* Matches trace-mode resolution; intended for every successful invoke(), not only diagnostics.trace.
|
|
49
|
+
*/
|
|
50
|
+
export declare function pickInvokeRoutingMetadataSlice(routerResponse: unknown, mergedConfig: unknown): Partial<{
|
|
51
|
+
provider: string;
|
|
52
|
+
modelUsed: string;
|
|
53
|
+
maxTokensRequested: number;
|
|
54
|
+
region: string;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Allowlisted generation profile from merged config for client introspection (no secrets, no arbitrary extras).
|
|
58
|
+
*/
|
|
59
|
+
export declare function pickEffectiveModelConfigForMetadata(mergedConfig: unknown): Partial<Pick<ModelConfig, 'model' | 'modelId' | 'provider' | 'temperature' | 'maxTokens' | 'topP'>> | undefined;
|
|
46
60
|
/** Default JSON string length cap for Activix `content.fullResponse` when diagnostics allow storing it. */
|
|
47
61
|
export declare const DEFAULT_ACTIVITY_FULL_RESPONSE_MAX_CHARS = 512000;
|
|
48
62
|
/**
|
package/dist/gateway-utils.js
CHANGED
|
@@ -315,6 +315,49 @@ export function extractCostUsdFromRouterResponse(routerResponse) {
|
|
|
315
315
|
}
|
|
316
316
|
return undefined;
|
|
317
317
|
}
|
|
318
|
+
/**
|
|
319
|
+
* Stable routing facts for gateway response metadata (router metadata + merged config fallbacks).
|
|
320
|
+
* Matches trace-mode resolution; intended for every successful invoke(), not only diagnostics.trace.
|
|
321
|
+
*/
|
|
322
|
+
export function pickInvokeRoutingMetadataSlice(routerResponse, mergedConfig) {
|
|
323
|
+
const rr = routerResponse != null && typeof routerResponse === 'object' ? routerResponse : {};
|
|
324
|
+
const meta = rr.metadata != null && typeof rr.metadata === 'object' ? rr.metadata : {};
|
|
325
|
+
const cfg = mergedConfig != null && typeof mergedConfig === 'object' ? mergedConfig : {};
|
|
326
|
+
const provider = meta.provider || rr.provider || cfg.provider;
|
|
327
|
+
const modelUsed = meta.modelUsed || meta.model || rr.model || cfg.model;
|
|
328
|
+
const maxTokensRequested = typeof meta.maxTokensRequested === 'number'
|
|
329
|
+
? meta.maxTokensRequested
|
|
330
|
+
: typeof cfg.maxTokens === 'number'
|
|
331
|
+
? cfg.maxTokens
|
|
332
|
+
: undefined;
|
|
333
|
+
const region = typeof meta.region === 'string' ? meta.region : undefined;
|
|
334
|
+
const out = {};
|
|
335
|
+
if (provider !== undefined && provider !== null)
|
|
336
|
+
out.provider = provider;
|
|
337
|
+
if (modelUsed !== undefined && modelUsed !== null)
|
|
338
|
+
out.modelUsed = modelUsed;
|
|
339
|
+
if (maxTokensRequested !== undefined)
|
|
340
|
+
out.maxTokensRequested = maxTokensRequested;
|
|
341
|
+
if (region !== undefined)
|
|
342
|
+
out.region = region;
|
|
343
|
+
return out;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Allowlisted generation profile from merged config for client introspection (no secrets, no arbitrary extras).
|
|
347
|
+
*/
|
|
348
|
+
export function pickEffectiveModelConfigForMetadata(mergedConfig) {
|
|
349
|
+
if (mergedConfig == null || typeof mergedConfig !== 'object')
|
|
350
|
+
return undefined;
|
|
351
|
+
const c = mergedConfig;
|
|
352
|
+
const keys = ['model', 'modelId', 'provider', 'temperature', 'maxTokens', 'topP'];
|
|
353
|
+
const out = {};
|
|
354
|
+
for (const k of keys) {
|
|
355
|
+
const v = c[k];
|
|
356
|
+
if (v !== undefined)
|
|
357
|
+
out[k] = v;
|
|
358
|
+
}
|
|
359
|
+
return Object.keys(out).length ? out : undefined;
|
|
360
|
+
}
|
|
318
361
|
/** Default JSON string length cap for Activix `content.fullResponse` when diagnostics allow storing it. */
|
|
319
362
|
export const DEFAULT_ACTIVITY_FULL_RESPONSE_MAX_CHARS = 512_000;
|
|
320
363
|
/**
|
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 { capActivityFullResponsePayload, DEFAULT_ACTIVITY_FULL_RESPONSE_MAX_CHARS, extractCostUsdFromRouterResponse, extractTokenUsageFromRouterResponse, mergeConfig } from './gateway-utils.js';
|
|
11
|
+
import { capActivityFullResponsePayload, DEFAULT_ACTIVITY_FULL_RESPONSE_MAX_CHARS, extractCostUsdFromRouterResponse, extractTokenUsageFromRouterResponse, mergeConfig, pickEffectiveModelConfigForMetadata, pickInvokeRoutingMetadataSlice } 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';
|
|
@@ -524,6 +524,8 @@ export class AIGateway {
|
|
|
524
524
|
}
|
|
525
525
|
const resolvedCostUsd = extractCostUsdFromRouterResponse(routerResponse);
|
|
526
526
|
const routerMetaForCost = routerResponse?.metadata || {};
|
|
527
|
+
const routingMetadataSlice = pickInvokeRoutingMetadataSlice(routerResponse, mergedConfig);
|
|
528
|
+
const effectiveModelConfig = pickEffectiveModelConfigForMetadata(mergedConfig);
|
|
527
529
|
const enhancedResponse = {
|
|
528
530
|
content: content,
|
|
529
531
|
parsedContent: parsedContent,
|
|
@@ -536,6 +538,8 @@ export class AIGateway {
|
|
|
536
538
|
agentType: 'ai',
|
|
537
539
|
contentType,
|
|
538
540
|
parsingMethod,
|
|
541
|
+
...routingMetadataSlice,
|
|
542
|
+
...(effectiveModelConfig !== undefined ? { effectiveModelConfig } : {}),
|
|
539
543
|
...(typeof resolvedCostUsd === 'number'
|
|
540
544
|
? {
|
|
541
545
|
costUsd: resolvedCostUsd,
|
|
@@ -545,27 +549,12 @@ export class AIGateway {
|
|
|
545
549
|
}
|
|
546
550
|
: {}),
|
|
547
551
|
...(traceEnabled
|
|
548
|
-
?
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
? meta.maxTokensRequested
|
|
555
|
-
: typeof mergedConfig?.maxTokens === 'number'
|
|
556
|
-
? mergedConfig.maxTokens
|
|
557
|
-
: undefined;
|
|
558
|
-
return {
|
|
559
|
-
provider,
|
|
560
|
-
region,
|
|
561
|
-
modelUsed,
|
|
562
|
-
maxTokensRequested,
|
|
563
|
-
requestIds: traceRequestIds,
|
|
564
|
-
retryCount: traceRetryCount,
|
|
565
|
-
fallbackCount: traceFallbackCount,
|
|
566
|
-
attempts: traceAttempts
|
|
567
|
-
};
|
|
568
|
-
})()
|
|
552
|
+
? {
|
|
553
|
+
requestIds: traceRequestIds,
|
|
554
|
+
retryCount: traceRetryCount,
|
|
555
|
+
fallbackCount: traceFallbackCount,
|
|
556
|
+
attempts: traceAttempts
|
|
557
|
+
}
|
|
569
558
|
: {})
|
|
570
559
|
}
|
|
571
560
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -876,7 +876,8 @@ export interface EnhancedLLMResponse<TContent = unknown> extends Omit<AIResponse
|
|
|
876
876
|
*/
|
|
877
877
|
model?: string;
|
|
878
878
|
/**
|
|
879
|
-
* Provider used (e.g., 'openai', 'anthropic')
|
|
879
|
+
* Provider used (e.g., 'openai', 'anthropic').
|
|
880
|
+
* Populated on every successful invoke when router or merged config supplies it.
|
|
880
881
|
*/
|
|
881
882
|
provider?: string;
|
|
882
883
|
/**
|
|
@@ -884,23 +885,30 @@ export interface EnhancedLLMResponse<TContent = unknown> extends Omit<AIResponse
|
|
|
884
885
|
*/
|
|
885
886
|
cost?: number;
|
|
886
887
|
/**
|
|
887
|
-
* Cost in USD (preferred
|
|
888
|
+
* Cost in USD (preferred stable key when the router exposes it).
|
|
888
889
|
* When both are present, costUsd should mirror cost.
|
|
889
890
|
*/
|
|
890
891
|
costUsd?: number;
|
|
891
892
|
/**
|
|
892
893
|
* Final effective max token cap applied (after merges/normalization), if known.
|
|
894
|
+
* Populated on every successful invoke when router or merged config supplies it.
|
|
893
895
|
*/
|
|
894
896
|
maxTokensRequested?: number;
|
|
895
897
|
/**
|
|
896
898
|
* Model that actually served the response (after routing/fallback), if known.
|
|
897
899
|
* This is distinct from requested model.
|
|
900
|
+
* Populated on every successful invoke when router or merged config supplies it.
|
|
898
901
|
*/
|
|
899
902
|
modelUsed?: string;
|
|
900
903
|
/**
|
|
901
904
|
* Optional region identifier when applicable (provider-specific).
|
|
902
905
|
*/
|
|
903
906
|
region?: string;
|
|
907
|
+
/**
|
|
908
|
+
* Sanitized merged generation profile (allowlisted fields only; no secrets).
|
|
909
|
+
* Reflects gateway merge order: modelConfig / request.config / defaults.
|
|
910
|
+
*/
|
|
911
|
+
effectiveModelConfig?: Partial<Pick<ModelConfig, 'model' | 'modelId' | 'provider' | 'temperature' | 'maxTokens' | 'topP'>>;
|
|
904
912
|
/**
|
|
905
913
|
* Stable request/correlation identifiers across gateway/router/provider layers.
|
|
906
914
|
* Only populated when diagnostics trace mode is enabled.
|
|
@@ -44,6 +44,8 @@ exports.mergeConfig = mergeConfig;
|
|
|
44
44
|
exports.normalizeRouterUsageTokens = normalizeRouterUsageTokens;
|
|
45
45
|
exports.extractTokenUsageFromRouterResponse = extractTokenUsageFromRouterResponse;
|
|
46
46
|
exports.extractCostUsdFromRouterResponse = extractCostUsdFromRouterResponse;
|
|
47
|
+
exports.pickInvokeRoutingMetadataSlice = pickInvokeRoutingMetadataSlice;
|
|
48
|
+
exports.pickEffectiveModelConfigForMetadata = pickEffectiveModelConfigForMetadata;
|
|
47
49
|
exports.capActivityFullResponsePayload = capActivityFullResponsePayload;
|
|
48
50
|
const crypto = __importStar(require("crypto"));
|
|
49
51
|
const gateway_instructions_js_1 = require("./gateway-instructions.cjs");
|
|
@@ -358,6 +360,49 @@ function extractCostUsdFromRouterResponse(routerResponse) {
|
|
|
358
360
|
}
|
|
359
361
|
return undefined;
|
|
360
362
|
}
|
|
363
|
+
/**
|
|
364
|
+
* Stable routing facts for gateway response metadata (router metadata + merged config fallbacks).
|
|
365
|
+
* Matches trace-mode resolution; intended for every successful invoke(), not only diagnostics.trace.
|
|
366
|
+
*/
|
|
367
|
+
function pickInvokeRoutingMetadataSlice(routerResponse, mergedConfig) {
|
|
368
|
+
const rr = routerResponse != null && typeof routerResponse === 'object' ? routerResponse : {};
|
|
369
|
+
const meta = rr.metadata != null && typeof rr.metadata === 'object' ? rr.metadata : {};
|
|
370
|
+
const cfg = mergedConfig != null && typeof mergedConfig === 'object' ? mergedConfig : {};
|
|
371
|
+
const provider = meta.provider || rr.provider || cfg.provider;
|
|
372
|
+
const modelUsed = meta.modelUsed || meta.model || rr.model || cfg.model;
|
|
373
|
+
const maxTokensRequested = typeof meta.maxTokensRequested === 'number'
|
|
374
|
+
? meta.maxTokensRequested
|
|
375
|
+
: typeof cfg.maxTokens === 'number'
|
|
376
|
+
? cfg.maxTokens
|
|
377
|
+
: undefined;
|
|
378
|
+
const region = typeof meta.region === 'string' ? meta.region : undefined;
|
|
379
|
+
const out = {};
|
|
380
|
+
if (provider !== undefined && provider !== null)
|
|
381
|
+
out.provider = provider;
|
|
382
|
+
if (modelUsed !== undefined && modelUsed !== null)
|
|
383
|
+
out.modelUsed = modelUsed;
|
|
384
|
+
if (maxTokensRequested !== undefined)
|
|
385
|
+
out.maxTokensRequested = maxTokensRequested;
|
|
386
|
+
if (region !== undefined)
|
|
387
|
+
out.region = region;
|
|
388
|
+
return out;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Allowlisted generation profile from merged config for client introspection (no secrets, no arbitrary extras).
|
|
392
|
+
*/
|
|
393
|
+
function pickEffectiveModelConfigForMetadata(mergedConfig) {
|
|
394
|
+
if (mergedConfig == null || typeof mergedConfig !== 'object')
|
|
395
|
+
return undefined;
|
|
396
|
+
const c = mergedConfig;
|
|
397
|
+
const keys = ['model', 'modelId', 'provider', 'temperature', 'maxTokens', 'topP'];
|
|
398
|
+
const out = {};
|
|
399
|
+
for (const k of keys) {
|
|
400
|
+
const v = c[k];
|
|
401
|
+
if (v !== undefined)
|
|
402
|
+
out[k] = v;
|
|
403
|
+
}
|
|
404
|
+
return Object.keys(out).length ? out : undefined;
|
|
405
|
+
}
|
|
361
406
|
/** Default JSON string length cap for Activix `content.fullResponse` when diagnostics allow storing it. */
|
|
362
407
|
exports.DEFAULT_ACTIVITY_FULL_RESPONSE_MAX_CHARS = 512_000;
|
|
363
408
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Gateway Utilities Module
|
|
3
3
|
* Handles utility functions
|
|
4
4
|
*/
|
|
5
|
-
import type { ChatRequest, GatewayConfig } from './types.js';
|
|
5
|
+
import type { ChatRequest, GatewayConfig, ModelConfig } from './types.js';
|
|
6
6
|
import type { Logxer } from '@x12i/logxer';
|
|
7
7
|
/**
|
|
8
8
|
* Generates MD5 hash of a string
|
|
@@ -43,6 +43,20 @@ export declare function extractTokenUsageFromRouterResponse(routerResponse: unkn
|
|
|
43
43
|
* Does not compute cost from tokens — adapters must populate normalized fields or raw usage.cost-style keys.
|
|
44
44
|
*/
|
|
45
45
|
export declare function extractCostUsdFromRouterResponse(routerResponse: unknown): number | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Stable routing facts for gateway response metadata (router metadata + merged config fallbacks).
|
|
48
|
+
* Matches trace-mode resolution; intended for every successful invoke(), not only diagnostics.trace.
|
|
49
|
+
*/
|
|
50
|
+
export declare function pickInvokeRoutingMetadataSlice(routerResponse: unknown, mergedConfig: unknown): Partial<{
|
|
51
|
+
provider: string;
|
|
52
|
+
modelUsed: string;
|
|
53
|
+
maxTokensRequested: number;
|
|
54
|
+
region: string;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Allowlisted generation profile from merged config for client introspection (no secrets, no arbitrary extras).
|
|
58
|
+
*/
|
|
59
|
+
export declare function pickEffectiveModelConfigForMetadata(mergedConfig: unknown): Partial<Pick<ModelConfig, 'model' | 'modelId' | 'provider' | 'temperature' | 'maxTokens' | 'topP'>> | undefined;
|
|
46
60
|
/** Default JSON string length cap for Activix `content.fullResponse` when diagnostics allow storing it. */
|
|
47
61
|
export declare const DEFAULT_ACTIVITY_FULL_RESPONSE_MAX_CHARS = 512000;
|
|
48
62
|
/**
|
package/dist-cjs/gateway.cjs
CHANGED
|
@@ -527,6 +527,8 @@ class AIGateway {
|
|
|
527
527
|
}
|
|
528
528
|
const resolvedCostUsd = (0, gateway_utils_js_1.extractCostUsdFromRouterResponse)(routerResponse);
|
|
529
529
|
const routerMetaForCost = routerResponse?.metadata || {};
|
|
530
|
+
const routingMetadataSlice = (0, gateway_utils_js_1.pickInvokeRoutingMetadataSlice)(routerResponse, mergedConfig);
|
|
531
|
+
const effectiveModelConfig = (0, gateway_utils_js_1.pickEffectiveModelConfigForMetadata)(mergedConfig);
|
|
530
532
|
const enhancedResponse = {
|
|
531
533
|
content: content,
|
|
532
534
|
parsedContent: parsedContent,
|
|
@@ -539,6 +541,8 @@ class AIGateway {
|
|
|
539
541
|
agentType: 'ai',
|
|
540
542
|
contentType,
|
|
541
543
|
parsingMethod,
|
|
544
|
+
...routingMetadataSlice,
|
|
545
|
+
...(effectiveModelConfig !== undefined ? { effectiveModelConfig } : {}),
|
|
542
546
|
...(typeof resolvedCostUsd === 'number'
|
|
543
547
|
? {
|
|
544
548
|
costUsd: resolvedCostUsd,
|
|
@@ -548,27 +552,12 @@ class AIGateway {
|
|
|
548
552
|
}
|
|
549
553
|
: {}),
|
|
550
554
|
...(traceEnabled
|
|
551
|
-
?
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
? meta.maxTokensRequested
|
|
558
|
-
: typeof mergedConfig?.maxTokens === 'number'
|
|
559
|
-
? mergedConfig.maxTokens
|
|
560
|
-
: undefined;
|
|
561
|
-
return {
|
|
562
|
-
provider,
|
|
563
|
-
region,
|
|
564
|
-
modelUsed,
|
|
565
|
-
maxTokensRequested,
|
|
566
|
-
requestIds: traceRequestIds,
|
|
567
|
-
retryCount: traceRetryCount,
|
|
568
|
-
fallbackCount: traceFallbackCount,
|
|
569
|
-
attempts: traceAttempts
|
|
570
|
-
};
|
|
571
|
-
})()
|
|
555
|
+
? {
|
|
556
|
+
requestIds: traceRequestIds,
|
|
557
|
+
retryCount: traceRetryCount,
|
|
558
|
+
fallbackCount: traceFallbackCount,
|
|
559
|
+
attempts: traceAttempts
|
|
560
|
+
}
|
|
572
561
|
: {})
|
|
573
562
|
}
|
|
574
563
|
};
|
package/dist-cjs/types.d.ts
CHANGED
|
@@ -876,7 +876,8 @@ export interface EnhancedLLMResponse<TContent = unknown> extends Omit<AIResponse
|
|
|
876
876
|
*/
|
|
877
877
|
model?: string;
|
|
878
878
|
/**
|
|
879
|
-
* Provider used (e.g., 'openai', 'anthropic')
|
|
879
|
+
* Provider used (e.g., 'openai', 'anthropic').
|
|
880
|
+
* Populated on every successful invoke when router or merged config supplies it.
|
|
880
881
|
*/
|
|
881
882
|
provider?: string;
|
|
882
883
|
/**
|
|
@@ -884,23 +885,30 @@ export interface EnhancedLLMResponse<TContent = unknown> extends Omit<AIResponse
|
|
|
884
885
|
*/
|
|
885
886
|
cost?: number;
|
|
886
887
|
/**
|
|
887
|
-
* Cost in USD (preferred
|
|
888
|
+
* Cost in USD (preferred stable key when the router exposes it).
|
|
888
889
|
* When both are present, costUsd should mirror cost.
|
|
889
890
|
*/
|
|
890
891
|
costUsd?: number;
|
|
891
892
|
/**
|
|
892
893
|
* Final effective max token cap applied (after merges/normalization), if known.
|
|
894
|
+
* Populated on every successful invoke when router or merged config supplies it.
|
|
893
895
|
*/
|
|
894
896
|
maxTokensRequested?: number;
|
|
895
897
|
/**
|
|
896
898
|
* Model that actually served the response (after routing/fallback), if known.
|
|
897
899
|
* This is distinct from requested model.
|
|
900
|
+
* Populated on every successful invoke when router or merged config supplies it.
|
|
898
901
|
*/
|
|
899
902
|
modelUsed?: string;
|
|
900
903
|
/**
|
|
901
904
|
* Optional region identifier when applicable (provider-specific).
|
|
902
905
|
*/
|
|
903
906
|
region?: string;
|
|
907
|
+
/**
|
|
908
|
+
* Sanitized merged generation profile (allowlisted fields only; no secrets).
|
|
909
|
+
* Reflects gateway merge order: modelConfig / request.config / defaults.
|
|
910
|
+
*/
|
|
911
|
+
effectiveModelConfig?: Partial<Pick<ModelConfig, 'model' | 'modelId' | 'provider' | 'temperature' | 'maxTokens' | 'topP'>>;
|
|
904
912
|
/**
|
|
905
913
|
* Stable request/correlation identifiers across gateway/router/provider layers.
|
|
906
914
|
* Only populated when diagnostics trace mode is enabled.
|