@x12i/ai-gateway 10.3.0 → 10.4.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.
Files changed (68) hide show
  1. package/README.md +92 -1
  2. package/dist/activity-manager.js +33 -0
  3. package/dist/gateway-config.js +15 -0
  4. package/dist/gateway-utils.d.ts +8 -1
  5. package/dist/gateway-utils.js +73 -1
  6. package/dist/gateway.js +18 -3
  7. package/dist/index.d.ts +4 -3
  8. package/dist/index.js +3 -2
  9. package/dist/instruction-errors.d.ts +21 -0
  10. package/dist/instruction-errors.js +36 -0
  11. package/dist/logger-factory.js +0 -2
  12. package/dist/openrouter-runtime-adapter/create-openrouter-runtime-adapter.d.ts +23 -0
  13. package/dist/openrouter-runtime-adapter/create-openrouter-runtime-adapter.js +31 -0
  14. package/dist/openrouter-runtime-adapter/create-openrouter-runtime-provider.d.ts +9 -0
  15. package/dist/openrouter-runtime-adapter/create-openrouter-runtime-provider.js +41 -0
  16. package/dist/openrouter-runtime-adapter/index.d.ts +8 -0
  17. package/dist/openrouter-runtime-adapter/index.js +8 -0
  18. package/dist/openrouter-runtime-adapter/map-gateway-request.d.ts +26 -0
  19. package/dist/openrouter-runtime-adapter/map-gateway-request.js +62 -0
  20. package/dist/openrouter-runtime-adapter/map-runtime-errors.d.ts +5 -0
  21. package/dist/openrouter-runtime-adapter/map-runtime-errors.js +60 -0
  22. package/dist/openrouter-runtime-adapter/map-runtime-response.d.ts +31 -0
  23. package/dist/openrouter-runtime-adapter/map-runtime-response.js +153 -0
  24. package/dist/openrouter-runtime-adapter/map-server-tools.d.ts +3 -0
  25. package/dist/openrouter-runtime-adapter/map-server-tools.js +143 -0
  26. package/dist/openrouter-runtime-adapter/map-trace.d.ts +5 -0
  27. package/dist/openrouter-runtime-adapter/map-trace.js +45 -0
  28. package/dist/openrouter-runtime-adapter/register-openrouter-runtime.d.ts +10 -0
  29. package/dist/openrouter-runtime-adapter/register-openrouter-runtime.js +14 -0
  30. package/dist/openrouter-runtime-adapter/should-use-openrouter-runtime.d.ts +14 -0
  31. package/dist/openrouter-runtime-adapter/should-use-openrouter-runtime.js +29 -0
  32. package/dist/openrouter-runtime-adapter/validate-server-tools.d.ts +30 -0
  33. package/dist/openrouter-runtime-adapter/validate-server-tools.js +151 -0
  34. package/dist/types.d.ts +234 -0
  35. package/dist-cjs/activity-manager.cjs +33 -0
  36. package/dist-cjs/gateway-config.cjs +15 -0
  37. package/dist-cjs/gateway-utils.cjs +73 -1
  38. package/dist-cjs/gateway-utils.d.ts +8 -1
  39. package/dist-cjs/gateway.cjs +18 -3
  40. package/dist-cjs/index.cjs +3 -2
  41. package/dist-cjs/index.d.ts +4 -3
  42. package/dist-cjs/instruction-errors.cjs +36 -0
  43. package/dist-cjs/instruction-errors.d.ts +21 -0
  44. package/dist-cjs/logger-factory.cjs +0 -2
  45. package/dist-cjs/openrouter-runtime-adapter/create-openrouter-runtime-adapter.cjs +31 -0
  46. package/dist-cjs/openrouter-runtime-adapter/create-openrouter-runtime-adapter.d.ts +23 -0
  47. package/dist-cjs/openrouter-runtime-adapter/create-openrouter-runtime-provider.cjs +41 -0
  48. package/dist-cjs/openrouter-runtime-adapter/create-openrouter-runtime-provider.d.ts +9 -0
  49. package/dist-cjs/openrouter-runtime-adapter/index.cjs +8 -0
  50. package/dist-cjs/openrouter-runtime-adapter/index.d.ts +8 -0
  51. package/dist-cjs/openrouter-runtime-adapter/map-gateway-request.cjs +62 -0
  52. package/dist-cjs/openrouter-runtime-adapter/map-gateway-request.d.ts +26 -0
  53. package/dist-cjs/openrouter-runtime-adapter/map-runtime-errors.cjs +60 -0
  54. package/dist-cjs/openrouter-runtime-adapter/map-runtime-errors.d.ts +5 -0
  55. package/dist-cjs/openrouter-runtime-adapter/map-runtime-response.cjs +153 -0
  56. package/dist-cjs/openrouter-runtime-adapter/map-runtime-response.d.ts +31 -0
  57. package/dist-cjs/openrouter-runtime-adapter/map-server-tools.cjs +143 -0
  58. package/dist-cjs/openrouter-runtime-adapter/map-server-tools.d.ts +3 -0
  59. package/dist-cjs/openrouter-runtime-adapter/map-trace.cjs +45 -0
  60. package/dist-cjs/openrouter-runtime-adapter/map-trace.d.ts +5 -0
  61. package/dist-cjs/openrouter-runtime-adapter/register-openrouter-runtime.cjs +14 -0
  62. package/dist-cjs/openrouter-runtime-adapter/register-openrouter-runtime.d.ts +10 -0
  63. package/dist-cjs/openrouter-runtime-adapter/should-use-openrouter-runtime.cjs +29 -0
  64. package/dist-cjs/openrouter-runtime-adapter/should-use-openrouter-runtime.d.ts +14 -0
  65. package/dist-cjs/openrouter-runtime-adapter/validate-server-tools.cjs +151 -0
  66. package/dist-cjs/openrouter-runtime-adapter/validate-server-tools.d.ts +30 -0
  67. package/dist-cjs/types.d.ts +234 -0
  68. package/package.json +7 -5
@@ -11,7 +11,8 @@ import { resolveRetryConfig } from './gateway-defaults.js';
11
11
  import { buildMessages } from './message-builder.js';
12
12
  import { extractJsonFromFlexMd } from './flex-md-loader.js';
13
13
  import { enrichParsedContentForOutputContract, resolveOutputContractFieldKeys } from './output-contract-normalizer.js';
14
- import { attachGatewayInvokeRejectionMetadata, buildGatewayFallbackAttemptsFromTrace, buildInvokeRejectionMetadata, capActivityFullResponsePayload, formatFallbackExhaustionMessage, logResolvedModelRouting, mapGatewayFallbackAttemptsToRouter, DEFAULT_ACTIVITY_FULL_RESPONSE_MAX_CHARS, extractCostUsdFromRouterResponse, extractTokenUsageFromRouterResponse, mergeConfig, pickEffectiveModelConfigForMetadata, pickInvokeRoutingMetadataSlice, pickTraceMergedRouterConfig, resolveCostCompletionWithAiTools, buildTraceUsageSummary, enrichTraceAttemptsWithBilling, tryExtractRouterLikePayloadFromErrorChain } from './gateway-utils.js';
14
+ import { attachGatewayInvokeRejectionMetadata, buildGatewayFallbackAttemptsFromTrace, buildInvokeRejectionMetadata, capActivityFullResponsePayload, formatFallbackExhaustionMessage, logResolvedModelRouting, mapGatewayFallbackAttemptsToRouter, DEFAULT_ACTIVITY_FULL_RESPONSE_MAX_CHARS, extractCostUsdFromRouterResponse, extractTokenUsageFromRouterResponse, mergeConfig, pickEffectiveModelConfigForMetadata, pickInvokeRoutingMetadataSlice, pickTraceMergedRouterConfig, pickEnhancedOpenRouterMetadata, resolveCostCompletionWithAiTools, buildTraceUsageSummary, enrichTraceAttemptsWithBilling, tryExtractRouterLikePayloadFromErrorChain } from './gateway-utils.js';
15
+ import { buildTraceAttemptOpenRouterRuntimeSlice } from './openrouter-runtime-adapter/index.js';
15
16
  import { getAiToolsClient } from './ai-tools-client.js';
16
17
  import { autoRegisterProviders } from './gateway-provider-auto-register.js';
17
18
  import { setGatewayLastJobId, setGatewayRuntimeClients } from './runtime-objects.js';
@@ -140,9 +141,12 @@ export class AIGateway {
140
141
  calculator: aiTools?.calculator ?? null,
141
142
  calculateCost: this.config.aiTools?.calculateCost
142
143
  });
144
+ const routingMetadataSliceChat = pickInvokeRoutingMetadataSlice(response, mergedConfig);
145
+ const effectiveModelConfigChat = pickEffectiveModelConfigForMetadata(mergedConfig);
146
+ const openrouterMetadataChat = pickEnhancedOpenRouterMetadata(response, false);
143
147
  // Create enhanced response
144
148
  const enhancedResponse = {
145
- content: response.content || '',
149
+ content: response.content || response.outputText || '',
146
150
  metadata: {
147
151
  aiRequestId: request.aiRequestId,
148
152
  identity: request.identity,
@@ -150,6 +154,9 @@ export class AIGateway {
150
154
  tokens: tokensChat,
151
155
  taskTypeId,
152
156
  agentType: 'chat',
157
+ ...routingMetadataSliceChat,
158
+ ...(effectiveModelConfigChat !== undefined ? { effectiveModelConfig: effectiveModelConfigChat } : {}),
159
+ ...openrouterMetadataChat,
153
160
  ...(costCompletionChat.costStatus === 'priced'
154
161
  ? {
155
162
  costUsd: costCompletionChat.cost,
@@ -466,6 +473,9 @@ export class AIGateway {
466
473
  const rawStr = typeof raw === 'string' ? raw : safeJsonStringify(raw);
467
474
  a.rawProviderPayload = capString(rawStr, 4000);
468
475
  }
476
+ const runtimeSlice = buildTraceAttemptOpenRouterRuntimeSlice(pickEnhancedOpenRouterMetadata(respAny, true));
477
+ if (runtimeSlice)
478
+ a.openrouterRuntime = runtimeSlice;
469
479
  }
470
480
  else if (tryErr) {
471
481
  a.error = { name: tryErr.name || 'Error', message: capErrorMessage(tryErr.message || String(tryErr)) };
@@ -617,6 +627,7 @@ export class AIGateway {
617
627
  const routerMetaForCost = routerResponse?.metadata || {};
618
628
  const routingMetadataSlice = pickInvokeRoutingMetadataSlice(routerResponse, mergedConfig);
619
629
  const effectiveModelConfig = pickEffectiveModelConfigForMetadata(mergedConfig);
630
+ const openrouterMetadata = pickEnhancedOpenRouterMetadata(routerResponse, traceEnabled);
620
631
  const traceMergedRouterSnapshot = traceEnabled ? pickTraceMergedRouterConfig(mergedConfig) : undefined;
621
632
  if (traceEnabled && traceAttempts) {
622
633
  await enrichTraceAttemptsWithBilling(traceAttempts, costCompletion, {
@@ -626,7 +637,10 @@ export class AIGateway {
626
637
  });
627
638
  }
628
639
  const traceUsageSummary = traceEnabled
629
- ? buildTraceUsageSummary(tokens, costCompletion, routingMetadataSlice.maxTokensRequested)
640
+ ? buildTraceUsageSummary(tokens, costCompletion, routingMetadataSlice.maxTokensRequested, {
641
+ serverTools: openrouterMetadata.serverTools,
642
+ citations: openrouterMetadata.citations,
643
+ })
630
644
  : undefined;
631
645
  const enhancedResponse = {
632
646
  content: content,
@@ -642,6 +656,7 @@ export class AIGateway {
642
656
  parsingMethod,
643
657
  ...routingMetadataSlice,
644
658
  ...(effectiveModelConfig !== undefined ? { effectiveModelConfig } : {}),
659
+ ...openrouterMetadata,
645
660
  ...(costCompletion.costStatus === 'priced'
646
661
  ? {
647
662
  costUsd: costCompletion.cost,
@@ -15,10 +15,11 @@ export { ProviderNotFoundError, FallbackExhaustedError } from '@x12i/ai-provider
15
15
  export * from '@x12i/ai-providers-router';
16
16
  // Export enhanced gateway
17
17
  export { AIGateway } from './gateway.js';
18
- export { InstructionNotFoundError, InstructionBackendError, ModelRequiredError, MaxTokensRequiredError, GatewayAliasModelRejectedError, } from './instruction-errors.js';
18
+ export { InstructionNotFoundError, InstructionBackendError, ModelRequiredError, MaxTokensRequiredError, GatewayAliasModelRejectedError, GatewayValidationError, ProviderConfigError, ProviderInvokeError, GatewayPolicyViolationError, } from './instruction-errors.js';
19
19
  export { normalizeInvokeModelAtIngress } from './invoke-model-ingress.js';
20
20
  export { autoRegisterProviders } from './gateway-provider-auto-register.js';
21
- export { attachGatewayInvokeRejectionMetadata, buildInvokeRejectionMetadata, tryExtractRouterLikePayloadFromErrorChain, tryExtractFallbackAttemptsFromErrorChain, pickRequestIdsFromRouterLike, resolveActivityCostCompletion, resolveCostCompletionForActivity, resolveCostCompletionWithAiTools, buildGatewayPricingRecord, mapAiCostResultToResolvedActivityCost, catalogPricingSucceeded, extractUsageExtrasFromRouterResponse, buildTraceUsageSummary, enrichTraceAttemptsWithBilling, hasNonZeroTokenUsage, MODEL_PROFILE_UNROUTABLE, ModelProfileUnroutableError, ModelProfileInputRejectedError, buildGatewayFallbackAttemptsFromTrace, formatFallbackExhaustionMessage, logResolvedModelRouting, mapGatewayFallbackAttemptsToRouter } from './gateway-utils.js';
21
+ export { registerOpenRouterRuntime, shouldUseOpenRouterRuntime, mapGatewayServerTools, } from './openrouter-runtime-adapter/index.js';
22
+ export { attachGatewayInvokeRejectionMetadata, buildInvokeRejectionMetadata, tryExtractRouterLikePayloadFromErrorChain, tryExtractFallbackAttemptsFromErrorChain, pickRequestIdsFromRouterLike, resolveActivityCostCompletion, resolveCostCompletionForActivity, resolveCostCompletionWithAiTools, buildGatewayPricingRecord, mapAiCostResultToResolvedActivityCost, catalogPricingSucceeded, extractUsageExtrasFromRouterResponse, buildTraceUsageSummary, enrichTraceAttemptsWithBilling, pickEnhancedOpenRouterMetadata, hasNonZeroTokenUsage, MODEL_PROFILE_UNROUTABLE, ModelProfileUnroutableError, ModelProfileInputRejectedError, buildGatewayFallbackAttemptsFromTrace, formatFallbackExhaustionMessage, logResolvedModelRouting, mapGatewayFallbackAttemptsToRouter } from './gateway-utils.js';
22
23
  export { getGatewayOperationalMode, isProdGatewayMode, parseModelProviderSpec } from './gateway-mode.js';
23
24
  export { DEFAULT_ACTIVITY_FULL_RESPONSE_MAX_CHARS, GATEWAY_DEFAULT_FREQUENCY_PENALTY, GATEWAY_DEFAULT_PRESENCE_PENALTY, GATEWAY_DEFAULT_RETRY, GATEWAY_DEFAULT_TEMPERATURE, GATEWAY_DEFAULT_TOP_P, resolveRetryConfig } from './gateway-defaults.js';
24
25
  export { contractSpecToFieldKeys, enrichParsedContentForOutputContract, resolveOutputContractFieldKeys } from './output-contract-normalizer.js';
@@ -14,11 +14,12 @@ export type { RequestInterceptor, ResponseInterceptor } from '@x12i/ai-providers
14
14
  export type { UsageTracker } from '@x12i/ai-providers-router';
15
15
  export * from '@x12i/ai-providers-router';
16
16
  export { AIGateway } from './gateway.js';
17
- export { InstructionNotFoundError, InstructionBackendError, ModelRequiredError, MaxTokensRequiredError, GatewayAliasModelRejectedError, } from './instruction-errors.js';
17
+ export { InstructionNotFoundError, InstructionBackendError, ModelRequiredError, MaxTokensRequiredError, GatewayAliasModelRejectedError, GatewayValidationError, ProviderConfigError, ProviderInvokeError, GatewayPolicyViolationError, } from './instruction-errors.js';
18
18
  export { normalizeInvokeModelAtIngress } from './invoke-model-ingress.js';
19
19
  export { autoRegisterProviders } from './gateway-provider-auto-register.js';
20
- export type { GatewayConfig, ProviderModelRef, ModelConfig, RetryConfig, ChatRequest, AIInvokeRequest, AIRequest, GatewayActionType, GatewayInvokeRejectionMetadata, GatewayFallbackAttempt, GatewayTraceRequestIds, GatewayTraceAttempt, GatewayTraceUsageSummary, GatewayTraceMergedConfig, EnhancedLLMResponse, InstructionMetadata, ValidationRule, TemplateRenderOptions, SmartInputConfig, SmartInputRenderOptions } from './types.js';
21
- export { attachGatewayInvokeRejectionMetadata, buildInvokeRejectionMetadata, tryExtractRouterLikePayloadFromErrorChain, tryExtractFallbackAttemptsFromErrorChain, pickRequestIdsFromRouterLike, resolveActivityCostCompletion, resolveCostCompletionForActivity, resolveCostCompletionWithAiTools, buildGatewayPricingRecord, mapAiCostResultToResolvedActivityCost, catalogPricingSucceeded, extractUsageExtrasFromRouterResponse, buildTraceUsageSummary, enrichTraceAttemptsWithBilling, hasNonZeroTokenUsage, MODEL_PROFILE_UNROUTABLE, ModelProfileUnroutableError, ModelProfileInputRejectedError, buildGatewayFallbackAttemptsFromTrace, formatFallbackExhaustionMessage, logResolvedModelRouting, mapGatewayFallbackAttemptsToRouter } from './gateway-utils.js';
20
+ export { registerOpenRouterRuntime, shouldUseOpenRouterRuntime, mapGatewayServerTools, } from './openrouter-runtime-adapter/index.js';
21
+ export type { GatewayConfig, ProviderModelRef, ModelConfig, GatewayModelConfig, GatewayServerToolsConfig, GatewayOpenRouterConfig, GatewayOpenRouterRuntimeConfig, GatewayServerToolUsageMap, GatewayCitation, GatewayGeneratedImage, GatewayPatchProposal, GatewayOpenRouterRuntimeMetadata, RetryConfig, ChatRequest, AIInvokeRequest, AIRequest, GatewayActionType, GatewayInvokeRejectionMetadata, GatewayFallbackAttempt, GatewayTraceRequestIds, GatewayTraceAttempt, GatewayTraceUsageSummary, GatewayTraceMergedConfig, EnhancedLLMResponse, InstructionMetadata, ValidationRule, TemplateRenderOptions, SmartInputConfig, SmartInputRenderOptions } from './types.js';
22
+ export { attachGatewayInvokeRejectionMetadata, buildInvokeRejectionMetadata, tryExtractRouterLikePayloadFromErrorChain, tryExtractFallbackAttemptsFromErrorChain, pickRequestIdsFromRouterLike, resolveActivityCostCompletion, resolveCostCompletionForActivity, resolveCostCompletionWithAiTools, buildGatewayPricingRecord, mapAiCostResultToResolvedActivityCost, catalogPricingSucceeded, extractUsageExtrasFromRouterResponse, buildTraceUsageSummary, enrichTraceAttemptsWithBilling, pickEnhancedOpenRouterMetadata, hasNonZeroTokenUsage, MODEL_PROFILE_UNROUTABLE, ModelProfileUnroutableError, ModelProfileInputRejectedError, buildGatewayFallbackAttemptsFromTrace, formatFallbackExhaustionMessage, logResolvedModelRouting, mapGatewayFallbackAttemptsToRouter } from './gateway-utils.js';
22
23
  export { getGatewayOperationalMode, isProdGatewayMode, parseModelProviderSpec } from './gateway-mode.js';
23
24
  export type { GatewayOperationalMode } from './gateway-mode.js';
24
25
  export { DEFAULT_ACTIVITY_FULL_RESPONSE_MAX_CHARS, GATEWAY_DEFAULT_FREQUENCY_PENALTY, GATEWAY_DEFAULT_PRESENCE_PENALTY, GATEWAY_DEFAULT_RETRY, GATEWAY_DEFAULT_TEMPERATURE, GATEWAY_DEFAULT_TOP_P, resolveRetryConfig } from './gateway-defaults.js';
@@ -25,6 +25,42 @@ export class GatewayAliasModelRejectedError extends Error {
25
25
  this.name = 'GatewayAliasModelRejectedError';
26
26
  }
27
27
  }
28
+ export class GatewayValidationError extends Error {
29
+ code;
30
+ constructor(code, message) {
31
+ super(message);
32
+ this.name = 'GatewayValidationError';
33
+ this.code = code;
34
+ }
35
+ }
36
+ export class ProviderConfigError extends Error {
37
+ code;
38
+ constructor(code, message) {
39
+ super(message);
40
+ this.name = 'ProviderConfigError';
41
+ this.code = code;
42
+ }
43
+ }
44
+ export class ProviderInvokeError extends Error {
45
+ code;
46
+ status;
47
+ retryable;
48
+ constructor(code, message, options) {
49
+ super(message);
50
+ this.name = 'ProviderInvokeError';
51
+ this.code = code;
52
+ this.status = options?.status;
53
+ this.retryable = options?.retryable;
54
+ }
55
+ }
56
+ export class GatewayPolicyViolationError extends Error {
57
+ code;
58
+ constructor(code, message) {
59
+ super(message);
60
+ this.name = 'GatewayPolicyViolationError';
61
+ this.code = code;
62
+ }
63
+ }
28
64
  export class InstructionNotFoundError extends Error {
29
65
  key;
30
66
  backend;
@@ -14,6 +14,27 @@ export declare class GatewayAliasModelRejectedError extends Error {
14
14
  readonly code = "GATEWAY_ALIAS_MODEL_REJECTED";
15
15
  constructor(aliasModel: string, message?: string);
16
16
  }
17
+ export declare class GatewayValidationError extends Error {
18
+ readonly code: string;
19
+ constructor(code: string, message: string);
20
+ }
21
+ export declare class ProviderConfigError extends Error {
22
+ readonly code: string;
23
+ constructor(code: string, message: string);
24
+ }
25
+ export declare class ProviderInvokeError extends Error {
26
+ readonly code: string;
27
+ readonly status?: number;
28
+ readonly retryable?: boolean;
29
+ constructor(code: string, message: string, options?: {
30
+ status?: number;
31
+ retryable?: boolean;
32
+ });
33
+ }
34
+ export declare class GatewayPolicyViolationError extends Error {
35
+ readonly code: string;
36
+ constructor(code: string, message: string);
37
+ }
17
38
  export declare class InstructionNotFoundError extends Error {
18
39
  key: string;
19
40
  backend: string;
@@ -59,8 +59,6 @@ function inheritLoggingConfigFromHost(hostLogger) {
59
59
  pick('logFilePath');
60
60
  pick('logFormat');
61
61
  pick('showFullTimestamp');
62
- pick('enableUnifiedLogger');
63
- pick('unifiedLogger');
64
62
  pick('consolePackagesShow');
65
63
  pick('consolePackagesHide');
66
64
  pick('transports');
@@ -0,0 +1,31 @@
1
+ import { mapGatewayRequestToRuntimeRequestFromRouter, OPENROUTER_RUNTIME_OPERATION, } from './map-gateway-request.js';
2
+ import { parseRuntimeResponseToAIResponse } from './map-runtime-response.js';
3
+ export function createOpenRouterRuntimeAdapter() {
4
+ return {
5
+ provider: 'openrouter',
6
+ buildCallSpec(input) {
7
+ const runtimeRequest = mapGatewayRequestToRuntimeRequestFromRouter({
8
+ request: input.request,
9
+ exec: input.exec,
10
+ });
11
+ return {
12
+ requestId: input.requestId,
13
+ provider: 'openrouter',
14
+ mode: input.mode === 'stream' ? 'sync' : input.mode,
15
+ operation: OPENROUTER_RUNTIME_OPERATION,
16
+ args: runtimeRequest,
17
+ exec: input.exec
18
+ ? {
19
+ timeoutMs: input.exec.timeoutMs,
20
+ retries: input.exec.retries,
21
+ idempotencyKey: input.exec.idempotencyKey,
22
+ signal: input.exec.signal,
23
+ }
24
+ : undefined,
25
+ };
26
+ },
27
+ parseResponse(input) {
28
+ return parseRuntimeResponseToAIResponse(input);
29
+ },
30
+ };
31
+ }
@@ -0,0 +1,23 @@
1
+ import type { ProviderSDKCallSpec } from '@x12i/ai-provider-interface';
2
+ import type { AIResponse } from '@x12i/ai-providers-router';
3
+ export declare function createOpenRouterRuntimeAdapter(): {
4
+ provider: string;
5
+ buildCallSpec(input: {
6
+ requestId: string;
7
+ mode: "sync" | "stream";
8
+ request: Record<string, unknown>;
9
+ exec?: {
10
+ timeoutMs?: number;
11
+ retries?: number;
12
+ idempotencyKey?: string;
13
+ signal?: AbortSignal;
14
+ };
15
+ }): ProviderSDKCallSpec;
16
+ parseResponse(input: {
17
+ requestId: string;
18
+ request: unknown;
19
+ execResult: {
20
+ rawResponse: unknown;
21
+ };
22
+ }): AIResponse;
23
+ };
@@ -0,0 +1,41 @@
1
+ import { createOpenRouterRuntime, RuntimeConfigError, OpenRouterHttpError, } from '@x12i/openrouter-runtime';
2
+ import { OPENROUTER_RUNTIME_OPERATION } from './map-gateway-request.js';
3
+ import { throwMappedOpenRouterHttpError, throwMappedRuntimeConfigError, throwMappedRuntimeResponseErrors, } from './map-runtime-errors.js';
4
+ export function createOpenRouterRuntimeProvider(options) {
5
+ const runtime = options.runtime ??
6
+ createOpenRouterRuntime({
7
+ apiKey: options.apiKey,
8
+ defaults: {
9
+ retry: { enabled: false },
10
+ onPolicyViolation: 'return_error',
11
+ },
12
+ });
13
+ return {
14
+ name: 'openrouter',
15
+ capabilities: {
16
+ modes: { sync: true, stream: false, batch: false },
17
+ operations: [OPENROUTER_RUNTIME_OPERATION],
18
+ maxConcurrency: 10,
19
+ },
20
+ async execute(spec) {
21
+ if (spec.operation !== OPENROUTER_RUNTIME_OPERATION) {
22
+ throw new Error(`Unsupported OpenRouter runtime operation: ${spec.operation}`);
23
+ }
24
+ const runtimeRequest = spec.args;
25
+ try {
26
+ const response = await runtime.run(runtimeRequest);
27
+ if (response.status !== 'completed') {
28
+ throwMappedRuntimeResponseErrors(response);
29
+ }
30
+ return { rawResponse: response };
31
+ }
32
+ catch (err) {
33
+ if (err instanceof RuntimeConfigError)
34
+ throwMappedRuntimeConfigError(err);
35
+ if (err instanceof OpenRouterHttpError)
36
+ throwMappedOpenRouterHttpError(err);
37
+ throw err;
38
+ }
39
+ },
40
+ };
41
+ }
@@ -0,0 +1,9 @@
1
+ import { type OpenRouterRuntime } from '@x12i/openrouter-runtime';
2
+ import type { ProviderModule } from '@x12i/ai-provider-interface';
3
+ import type { Logxer } from '@x12i/logxer';
4
+ export type OpenRouterRuntimeProviderOptions = {
5
+ apiKey: string;
6
+ logger?: Logxer;
7
+ runtime?: OpenRouterRuntime;
8
+ };
9
+ export declare function createOpenRouterRuntimeProvider(options: OpenRouterRuntimeProviderOptions): ProviderModule;
@@ -0,0 +1,8 @@
1
+ export { registerOpenRouterRuntime, shouldUseOpenRouterRuntime, resolveOpenRouterRuntimeDefaults, } from './register-openrouter-runtime.js';
2
+ export { createOpenRouterRuntimeProvider } from './create-openrouter-runtime-provider.js';
3
+ export { createOpenRouterRuntimeAdapter } from './create-openrouter-runtime-adapter.js';
4
+ export { mapGatewayServerTools } from './map-server-tools.js';
5
+ export { mapGatewayRequestToRuntimeRequest } from './map-gateway-request.js';
6
+ export { pickOpenRouterRuntimeMetadataSlice, extractOpenRouterRuntimeRouterMetadata, parseRuntimeResponseToAIResponse, } from './map-runtime-response.js';
7
+ export { applyOnlineVariantMigration, applyPostRoutingServerToolsPolicy, mergeOpenRouterConfig, mergeServerToolsConfig, normalizeApplyPatchDefaults, validateApplyPatchConfig, hasAnyActiveServerTool, hasRequiredServerTool, } from './validate-server-tools.js';
8
+ export { buildTraceAttemptOpenRouterRuntimeSlice, enrichTraceOpenRouterRuntimeMetadata, redactRawOpenRouterPayload, } from './map-trace.js';
@@ -0,0 +1,8 @@
1
+ export { registerOpenRouterRuntime, shouldUseOpenRouterRuntime, resolveOpenRouterRuntimeDefaults, } from './register-openrouter-runtime.js';
2
+ export { createOpenRouterRuntimeProvider } from './create-openrouter-runtime-provider.js';
3
+ export { createOpenRouterRuntimeAdapter } from './create-openrouter-runtime-adapter.js';
4
+ export { mapGatewayServerTools } from './map-server-tools.js';
5
+ export { mapGatewayRequestToRuntimeRequest } from './map-gateway-request.js';
6
+ export { pickOpenRouterRuntimeMetadataSlice, extractOpenRouterRuntimeRouterMetadata, parseRuntimeResponseToAIResponse, } from './map-runtime-response.js';
7
+ export { applyOnlineVariantMigration, applyPostRoutingServerToolsPolicy, mergeOpenRouterConfig, mergeServerToolsConfig, normalizeApplyPatchDefaults, validateApplyPatchConfig, hasAnyActiveServerTool, hasRequiredServerTool, } from './validate-server-tools.js';
8
+ export { buildTraceAttemptOpenRouterRuntimeSlice, enrichTraceOpenRouterRuntimeMetadata, redactRawOpenRouterPayload, } from './map-trace.js';
@@ -0,0 +1,62 @@
1
+ import { mapGatewayServerTools } from './map-server-tools.js';
2
+ export const OPENROUTER_RUNTIME_OPERATION = 'openrouter-runtime.run';
3
+ function mapMessages(messages) {
4
+ if (!messages?.length)
5
+ return [];
6
+ return messages.map((m) => ({
7
+ role: m.role,
8
+ content: m.content,
9
+ ...(m.name ? { name: m.name } : {}),
10
+ ...(m.toolCallId ? { toolCallId: m.toolCallId } : {}),
11
+ }));
12
+ }
13
+ function buildGenerationOverrides(config) {
14
+ const overrides = {};
15
+ if (config.topP !== undefined)
16
+ overrides.top_p = config.topP;
17
+ if (config.frequencyPenalty !== undefined)
18
+ overrides.frequency_penalty = config.frequencyPenalty;
19
+ if (config.presencePenalty !== undefined)
20
+ overrides.presence_penalty = config.presencePenalty;
21
+ if (Array.isArray(config.stop) && config.stop.length)
22
+ overrides.stop = config.stop;
23
+ return overrides;
24
+ }
25
+ export function mapGatewayRequestToRuntimeRequest(request, exec) {
26
+ const config = request.config ?? {};
27
+ const openrouter = config.openrouter;
28
+ const generationOverrides = buildGenerationOverrides(config);
29
+ const trustedRaw = openrouter?.rawOverrides ?? {};
30
+ const rawOpenRouterOverrides = Object.keys(generationOverrides).length || Object.keys(trustedRaw).length
31
+ ? { ...generationOverrides, ...trustedRaw }
32
+ : undefined;
33
+ const aiRequestId = (typeof request.aiRequestId === 'string' && request.aiRequestId) ||
34
+ (typeof request.identity?.aiRequestId === 'string' ? request.identity.aiRequestId : undefined);
35
+ return {
36
+ id: aiRequestId,
37
+ model: typeof config.model === 'string' ? config.model : undefined,
38
+ apiMode: openrouter?.apiMode ?? 'auto',
39
+ messages: mapMessages(request.messages),
40
+ temperature: typeof config.temperature === 'number' ? config.temperature : undefined,
41
+ maxTokens: typeof config.maxTokens === 'number' ? config.maxTokens : undefined,
42
+ reasoning: config.reasoning != null && typeof config.reasoning === 'object'
43
+ ? config.reasoning
44
+ : undefined,
45
+ serverTools: mapGatewayServerTools(config.serverTools),
46
+ execution: exec?.timeoutMs ? { timeoutMs: exec.timeoutMs } : undefined,
47
+ rawOpenRouterOverrides,
48
+ metadata: {
49
+ source: 'ai-gateway',
50
+ sourcePackage: '@x12i/ai-gateway',
51
+ provider: 'openrouter',
52
+ identity: request.identity,
53
+ actionType: request.actionType,
54
+ actionRef: request.actionRef,
55
+ aiRequestId,
56
+ agentId: request.agentId,
57
+ },
58
+ };
59
+ }
60
+ export function mapGatewayRequestToRuntimeRequestFromRouter(input) {
61
+ return mapGatewayRequestToRuntimeRequest(input.request, { timeoutMs: input.exec?.timeoutMs });
62
+ }
@@ -0,0 +1,26 @@
1
+ import type { RuntimeRequest } from '@x12i/openrouter-runtime';
2
+ export declare const OPENROUTER_RUNTIME_OPERATION = "openrouter-runtime.run";
3
+ export type GatewayRouterInvokeRequest = {
4
+ messages?: Array<{
5
+ role: string;
6
+ content: string | unknown[];
7
+ name?: string;
8
+ toolCallId?: string;
9
+ }>;
10
+ config?: Record<string, unknown>;
11
+ identity?: Record<string, unknown>;
12
+ aiRequestId?: string;
13
+ agentId?: string;
14
+ actionType?: string;
15
+ actionRef?: string;
16
+ };
17
+ export declare function mapGatewayRequestToRuntimeRequest(request: GatewayRouterInvokeRequest, exec?: {
18
+ timeoutMs?: number;
19
+ }): RuntimeRequest;
20
+ export declare function mapGatewayRequestToRuntimeRequestFromRouter(input: {
21
+ request: GatewayRouterInvokeRequest;
22
+ exec?: {
23
+ timeoutMs?: number;
24
+ signal?: AbortSignal;
25
+ };
26
+ }): RuntimeRequest;
@@ -0,0 +1,60 @@
1
+ import { OpenRouterHttpError, RuntimeConfigError, } from '@x12i/openrouter-runtime';
2
+ import { GatewayPolicyViolationError, GatewayValidationError, ProviderConfigError, ProviderInvokeError, } from '../instruction-errors.js';
3
+ export function throwMappedRuntimeConfigError(err) {
4
+ const code = err.code;
5
+ if (code === 'OPENROUTER_API_KEY_MISSING') {
6
+ throw new ProviderConfigError(code, err.message);
7
+ }
8
+ if (code === 'MODEL_MISSING') {
9
+ throw new GatewayValidationError(code, err.message);
10
+ }
11
+ if (code === 'INPUT_MISSING') {
12
+ throw new GatewayValidationError(code, err.message);
13
+ }
14
+ if (code === 'APPLY_PATCH_REQUIRES_RESPONSES_API') {
15
+ throw new GatewayValidationError(code, err.message);
16
+ }
17
+ throw new GatewayValidationError(code, err.message);
18
+ }
19
+ export function throwMappedOpenRouterHttpError(err) {
20
+ throw new ProviderInvokeError(err.code, err.message, {
21
+ status: err.status,
22
+ retryable: err.retryable,
23
+ });
24
+ }
25
+ export function throwMappedRuntimeResponseErrors(response) {
26
+ if (response.status === 'completed')
27
+ return;
28
+ const primary = response.errors[0];
29
+ if (!primary) {
30
+ throw new ProviderInvokeError('OPENROUTER_REQUEST_FAILED', 'OpenRouter runtime request failed');
31
+ }
32
+ if (primary.source === 'policy' || response.status === 'policy_violation') {
33
+ throw new GatewayPolicyViolationError(primary.code, primary.message);
34
+ }
35
+ if (primary.retryable) {
36
+ throw new ProviderInvokeError(primary.code, primary.message, { retryable: true });
37
+ }
38
+ throw new ProviderInvokeError(primary.code, primary.message);
39
+ }
40
+ export function mapRuntimeErrorToGatewayError(err) {
41
+ if (err instanceof RuntimeConfigError) {
42
+ try {
43
+ throwMappedRuntimeConfigError(err);
44
+ }
45
+ catch (mapped) {
46
+ return mapped;
47
+ }
48
+ }
49
+ if (err instanceof OpenRouterHttpError) {
50
+ try {
51
+ throwMappedOpenRouterHttpError(err);
52
+ }
53
+ catch (mapped) {
54
+ return mapped;
55
+ }
56
+ }
57
+ if (err instanceof Error)
58
+ return err;
59
+ return new Error(String(err));
60
+ }
@@ -0,0 +1,5 @@
1
+ import { OpenRouterHttpError, RuntimeConfigError, type RuntimeResponse } from '@x12i/openrouter-runtime';
2
+ export declare function throwMappedRuntimeConfigError(err: RuntimeConfigError): never;
3
+ export declare function throwMappedOpenRouterHttpError(err: OpenRouterHttpError): never;
4
+ export declare function throwMappedRuntimeResponseErrors(response: RuntimeResponse): void;
5
+ export declare function mapRuntimeErrorToGatewayError(err: unknown): Error;
@@ -0,0 +1,153 @@
1
+ const EMPTY_REASONING = {
2
+ requested: { effort: 'none', visibility: 'none' },
3
+ applied: { effort: 'none', visibility: 'none' },
4
+ artifacts: {},
5
+ availability: {
6
+ supportsEffort: false,
7
+ supportsSummary: false,
8
+ supportsTrace: false,
9
+ supportsEncrypted: false,
10
+ },
11
+ };
12
+ export function mapRuntimeToolUsage(toolUsage) {
13
+ const st = toolUsage.serverTools;
14
+ return {
15
+ webSearch: st.webSearch,
16
+ webFetch: st.webFetch,
17
+ datetime: st.datetime,
18
+ imageGeneration: st.imageGeneration,
19
+ applyPatch: st.applyPatch,
20
+ fusion: st.fusion,
21
+ advisor: st.advisor,
22
+ subagent: st.subagent,
23
+ };
24
+ }
25
+ export function mapRuntimeCitations(citations) {
26
+ return citations.map((c) => ({
27
+ type: 'url',
28
+ url: c.url,
29
+ title: c.title,
30
+ excerpt: c.excerpt,
31
+ startIndex: c.startIndex,
32
+ endIndex: c.endIndex,
33
+ sourceProvider: 'openrouter',
34
+ }));
35
+ }
36
+ export function mapRuntimeImages(images) {
37
+ return images.map((img) => ({
38
+ imageUrl: img.imageUrl,
39
+ status: img.status,
40
+ error: img.error,
41
+ raw: img.raw,
42
+ }));
43
+ }
44
+ export function mapRuntimePatches(patches) {
45
+ return patches.map((p) => ({
46
+ callId: p.callId,
47
+ status: p.status,
48
+ operation: p.operation,
49
+ raw: p.raw,
50
+ }));
51
+ }
52
+ export function buildOpenRouterRuntimeMetadata(response) {
53
+ const policyViolations = response.errors
54
+ .filter((e) => e.source === 'policy')
55
+ .map((e) => ({ code: e.code, message: e.message, details: e.details }));
56
+ return {
57
+ apiMode: response.apiMode,
58
+ warnings: response.warnings.map((w) => ({
59
+ code: w.code,
60
+ message: w.message,
61
+ details: w.details,
62
+ })),
63
+ policyViolations,
64
+ requestIds: response.id ? [response.id] : undefined,
65
+ };
66
+ }
67
+ export function extractOpenRouterRuntimeRouterMetadata(routerResponse) {
68
+ if (routerResponse == null || typeof routerResponse !== 'object')
69
+ return {};
70
+ const r = routerResponse;
71
+ const meta = r.metadata != null && typeof r.metadata === 'object'
72
+ ? r.metadata
73
+ : {};
74
+ const out = {};
75
+ if (meta.serverTools != null)
76
+ out.serverTools = meta.serverTools;
77
+ if (meta.citations != null)
78
+ out.citations = meta.citations;
79
+ if (meta.generatedImages != null)
80
+ out.generatedImages = meta.generatedImages;
81
+ if (meta.patchProposals != null)
82
+ out.patchProposals = meta.patchProposals;
83
+ if (meta.openrouterRuntime != null) {
84
+ out.openrouterRuntime = meta.openrouterRuntime;
85
+ }
86
+ if (typeof meta.costUsd === 'number')
87
+ out.costUsd = meta.costUsd;
88
+ if (meta.costStatus === 'priced' || meta.costStatus === 'unpriced') {
89
+ out.costStatus = meta.costStatus;
90
+ }
91
+ return out;
92
+ }
93
+ export function parseRuntimeResponseToAIResponse(input) {
94
+ const response = input.execResult.rawResponse;
95
+ const usage = response.usage;
96
+ const promptTokens = usage?.inputTokens ?? 0;
97
+ const completionTokens = usage?.outputTokens ?? 0;
98
+ const totalTokens = usage?.totalTokens ?? promptTokens + completionTokens;
99
+ const serverTools = mapRuntimeToolUsage(response.toolUsage);
100
+ const citations = mapRuntimeCitations(response.citations);
101
+ const generatedImages = mapRuntimeImages(response.images);
102
+ const patchProposals = mapRuntimePatches(response.patches);
103
+ const openrouterRuntime = buildOpenRouterRuntimeMetadata(response);
104
+ const costUsd = usage?.costUsd;
105
+ const metadata = {
106
+ provider: 'openrouter',
107
+ modelUsed: response.model,
108
+ serverTools,
109
+ citations,
110
+ generatedImages,
111
+ patchProposals,
112
+ openrouterRuntime,
113
+ requestIds: {
114
+ openrouterRequestId: response.id,
115
+ },
116
+ };
117
+ if (typeof costUsd === 'number' && Number.isFinite(costUsd)) {
118
+ metadata.costUsd = costUsd;
119
+ metadata.cost = costUsd;
120
+ metadata.costStatus = 'priced';
121
+ }
122
+ else if (usage && (promptTokens || completionTokens || totalTokens)) {
123
+ metadata.costStatus = 'unpriced';
124
+ }
125
+ return {
126
+ requestId: input.requestId,
127
+ provider: 'openrouter',
128
+ rawResponse: response,
129
+ outputText: response.text,
130
+ usage: {
131
+ promptTokens,
132
+ completionTokens,
133
+ totalTokens,
134
+ },
135
+ reasoning: EMPTY_REASONING,
136
+ metadata,
137
+ };
138
+ }
139
+ export function pickOpenRouterRuntimeMetadataSlice(routerResponse) {
140
+ const extracted = extractOpenRouterRuntimeRouterMetadata(routerResponse);
141
+ const out = {};
142
+ if (extracted.serverTools)
143
+ out.serverTools = extracted.serverTools;
144
+ if (extracted.citations?.length)
145
+ out.citations = extracted.citations;
146
+ if (extracted.generatedImages?.length)
147
+ out.generatedImages = extracted.generatedImages;
148
+ if (extracted.patchProposals?.length)
149
+ out.patchProposals = extracted.patchProposals;
150
+ if (extracted.openrouterRuntime)
151
+ out.openrouterRuntime = extracted.openrouterRuntime;
152
+ return out;
153
+ }