@x12i/ai-dispatcher 2.0.0 → 2.1.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.
- package/README.md +3 -3
- package/dist/index.cjs +34 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +35 -25
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.d.cts
CHANGED
|
@@ -215,6 +215,13 @@ interface AiDispatcherOptions {
|
|
|
215
215
|
cloudflare?: CloudflareRuntimeOptions;
|
|
216
216
|
/** Connected MCP servers. The dispatcher does not open transports. */
|
|
217
217
|
mcp?: DispatcherMcpOptions;
|
|
218
|
+
/**
|
|
219
|
+
* Highest priority first for the one metadata record.
|
|
220
|
+
* Listed keys are kept ahead of keys that are not in the list.
|
|
221
|
+
* The dispatcher trims on every call and adds a `METADATA_RECORD_TRIMMED` warning when it drops keys.
|
|
222
|
+
* The default keeps `agentId`, `orgId`, `stepId`, `skillId`, `recordId`, and `objectType`.
|
|
223
|
+
*/
|
|
224
|
+
metadataPriority?: readonly string[];
|
|
218
225
|
logger?: RuntimeLogger;
|
|
219
226
|
}
|
|
220
227
|
interface CompiledOpenAiRequest {
|
|
@@ -294,6 +301,8 @@ interface AiDispatcher {
|
|
|
294
301
|
readonly provider: AiProviderId;
|
|
295
302
|
}
|
|
296
303
|
|
|
304
|
+
/** Identity keys stay when a record has to be trimmed. Earlier entries are kept ahead of later ones. */
|
|
305
|
+
declare const DEFAULT_METADATA_PRIORITY: readonly ["agentId", "orgId", "stepId", "skillId", "recordId", "objectType"];
|
|
297
306
|
declare function createAiDispatcher(options?: AiDispatcherOptions): AiDispatcher;
|
|
298
307
|
|
|
299
308
|
declare class AiDispatcherError extends Error {
|
|
@@ -311,4 +320,4 @@ declare function stripReasoningHistoryFields<T>(message: T, paths: readonly stri
|
|
|
311
320
|
|
|
312
321
|
declare function resolveProvider(requestProvider: AiProviderId | undefined, defaultProvider: AiProviderId): ImplementedAiProvider;
|
|
313
322
|
|
|
314
|
-
export { type AiDispatcher, AiDispatcherError, type AiDispatcherOptions, type AiDispatcherRequest, type AiDispatcherResponse, type AiDispatcherUsage, type AiProviderAdapter, type AiProviderId, type CacheMode, type CacheOutcome, type CachePolicy, type CacheResolution, type CacheTtl, type CloudflareBackoff, type CloudflareCallContext, type CloudflareEndpoint, type CloudflareEndpointChoice, type CloudflareGatewayControls, type CloudflareRequestOptions, type CloudflareRunOptions, type CloudflareRuntimeOptions, type CloudflareWebhookFormat, type CompiledAiRequest, type CompiledCloudflareRequest, type CompiledOpenAiRequest, type DispatcherMcpOptions, type DispatcherMcpServer, type DispatcherMcpTool, IMPLEMENTED_AI_PROVIDERS, type ImplementedAiProvider, type OpenAiRuntimeOptions, type ReasoningResolution, createAiDispatcher, isImplementedAiProvider, providerNotImplemented, resolveProvider, stripReasoningHistoryFields };
|
|
323
|
+
export { type AiDispatcher, AiDispatcherError, type AiDispatcherOptions, type AiDispatcherRequest, type AiDispatcherResponse, type AiDispatcherUsage, type AiProviderAdapter, type AiProviderId, type CacheMode, type CacheOutcome, type CachePolicy, type CacheResolution, type CacheTtl, type CloudflareBackoff, type CloudflareCallContext, type CloudflareEndpoint, type CloudflareEndpointChoice, type CloudflareGatewayControls, type CloudflareRequestOptions, type CloudflareRunOptions, type CloudflareRuntimeOptions, type CloudflareWebhookFormat, type CompiledAiRequest, type CompiledCloudflareRequest, type CompiledOpenAiRequest, DEFAULT_METADATA_PRIORITY, type DispatcherMcpOptions, type DispatcherMcpServer, type DispatcherMcpTool, IMPLEMENTED_AI_PROVIDERS, type ImplementedAiProvider, type OpenAiRuntimeOptions, type ReasoningResolution, createAiDispatcher, isImplementedAiProvider, providerNotImplemented, resolveProvider, stripReasoningHistoryFields };
|
package/dist/index.d.ts
CHANGED
|
@@ -215,6 +215,13 @@ interface AiDispatcherOptions {
|
|
|
215
215
|
cloudflare?: CloudflareRuntimeOptions;
|
|
216
216
|
/** Connected MCP servers. The dispatcher does not open transports. */
|
|
217
217
|
mcp?: DispatcherMcpOptions;
|
|
218
|
+
/**
|
|
219
|
+
* Highest priority first for the one metadata record.
|
|
220
|
+
* Listed keys are kept ahead of keys that are not in the list.
|
|
221
|
+
* The dispatcher trims on every call and adds a `METADATA_RECORD_TRIMMED` warning when it drops keys.
|
|
222
|
+
* The default keeps `agentId`, `orgId`, `stepId`, `skillId`, `recordId`, and `objectType`.
|
|
223
|
+
*/
|
|
224
|
+
metadataPriority?: readonly string[];
|
|
218
225
|
logger?: RuntimeLogger;
|
|
219
226
|
}
|
|
220
227
|
interface CompiledOpenAiRequest {
|
|
@@ -294,6 +301,8 @@ interface AiDispatcher {
|
|
|
294
301
|
readonly provider: AiProviderId;
|
|
295
302
|
}
|
|
296
303
|
|
|
304
|
+
/** Identity keys stay when a record has to be trimmed. Earlier entries are kept ahead of later ones. */
|
|
305
|
+
declare const DEFAULT_METADATA_PRIORITY: readonly ["agentId", "orgId", "stepId", "skillId", "recordId", "objectType"];
|
|
297
306
|
declare function createAiDispatcher(options?: AiDispatcherOptions): AiDispatcher;
|
|
298
307
|
|
|
299
308
|
declare class AiDispatcherError extends Error {
|
|
@@ -311,4 +320,4 @@ declare function stripReasoningHistoryFields<T>(message: T, paths: readonly stri
|
|
|
311
320
|
|
|
312
321
|
declare function resolveProvider(requestProvider: AiProviderId | undefined, defaultProvider: AiProviderId): ImplementedAiProvider;
|
|
313
322
|
|
|
314
|
-
export { type AiDispatcher, AiDispatcherError, type AiDispatcherOptions, type AiDispatcherRequest, type AiDispatcherResponse, type AiDispatcherUsage, type AiProviderAdapter, type AiProviderId, type CacheMode, type CacheOutcome, type CachePolicy, type CacheResolution, type CacheTtl, type CloudflareBackoff, type CloudflareCallContext, type CloudflareEndpoint, type CloudflareEndpointChoice, type CloudflareGatewayControls, type CloudflareRequestOptions, type CloudflareRunOptions, type CloudflareRuntimeOptions, type CloudflareWebhookFormat, type CompiledAiRequest, type CompiledCloudflareRequest, type CompiledOpenAiRequest, type DispatcherMcpOptions, type DispatcherMcpServer, type DispatcherMcpTool, IMPLEMENTED_AI_PROVIDERS, type ImplementedAiProvider, type OpenAiRuntimeOptions, type ReasoningResolution, createAiDispatcher, isImplementedAiProvider, providerNotImplemented, resolveProvider, stripReasoningHistoryFields };
|
|
323
|
+
export { type AiDispatcher, AiDispatcherError, type AiDispatcherOptions, type AiDispatcherRequest, type AiDispatcherResponse, type AiDispatcherUsage, type AiProviderAdapter, type AiProviderId, type CacheMode, type CacheOutcome, type CachePolicy, type CacheResolution, type CacheTtl, type CloudflareBackoff, type CloudflareCallContext, type CloudflareEndpoint, type CloudflareEndpointChoice, type CloudflareGatewayControls, type CloudflareRequestOptions, type CloudflareRunOptions, type CloudflareRuntimeOptions, type CloudflareWebhookFormat, type CompiledAiRequest, type CompiledCloudflareRequest, type CompiledOpenAiRequest, DEFAULT_METADATA_PRIORITY, type DispatcherMcpOptions, type DispatcherMcpServer, type DispatcherMcpTool, IMPLEMENTED_AI_PROVIDERS, type ImplementedAiProvider, type OpenAiRuntimeOptions, type ReasoningResolution, createAiDispatcher, isImplementedAiProvider, providerNotImplemented, resolveProvider, stripReasoningHistoryFields };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { decodeProviderMetadata } from "@x12i/openrouter-runtime";
|
|
3
3
|
|
|
4
|
+
// src/create-dispatcher.ts
|
|
5
|
+
import { createMetadataPacker } from "@x12i/provider-metadata";
|
|
6
|
+
|
|
4
7
|
// src/cache-usage.ts
|
|
5
8
|
function readCacheTokens(source) {
|
|
6
9
|
const cached = [];
|
|
@@ -1125,8 +1128,7 @@ function isRouterImplicit(id) {
|
|
|
1125
1128
|
|
|
1126
1129
|
// src/providers/cloudflare.ts
|
|
1127
1130
|
import {
|
|
1128
|
-
|
|
1129
|
-
toProviderMetadata
|
|
1131
|
+
packProviderRecord
|
|
1130
1132
|
} from "@x12i/openrouter-runtime";
|
|
1131
1133
|
var DEFAULT_BASE_URL = "https://api.cloudflare.com/client/v4";
|
|
1132
1134
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
@@ -1154,8 +1156,8 @@ function restoreCloudflareModel(model, prefix) {
|
|
|
1154
1156
|
if (!prefix || model.includes("/")) return model;
|
|
1155
1157
|
return `${prefix}${model}`;
|
|
1156
1158
|
}
|
|
1157
|
-
function createCloudflareProviderAdapter(options = {}) {
|
|
1158
|
-
const resolved = resolveCloudflareOptions(options);
|
|
1159
|
+
function createCloudflareProviderAdapter(options = {}, packer) {
|
|
1160
|
+
const resolved = resolveCloudflareOptions(options, packer);
|
|
1159
1161
|
return {
|
|
1160
1162
|
compile(request, call) {
|
|
1161
1163
|
return compileCloudflareRequest(request, resolved, call, false);
|
|
@@ -1208,12 +1210,13 @@ function compileCloudflareRequest(request, options, call, streaming) {
|
|
|
1208
1210
|
if (endpoint !== "run") body = { ...body, stream: streaming };
|
|
1209
1211
|
const gateway = mergeGateway(options.gateway, call?.cloudflare?.gateway);
|
|
1210
1212
|
const fromBody = isRecord5(body.metadata) ? body.metadata : void 0;
|
|
1211
|
-
const
|
|
1213
|
+
const packed = packProviderRecord(
|
|
1212
1214
|
request.metadata,
|
|
1213
1215
|
request.agentId,
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
+
overlayMetadata(gateway?.metadata, fromBody),
|
|
1217
|
+
options.metadataPacker
|
|
1216
1218
|
);
|
|
1219
|
+
const record2 = packed.wire;
|
|
1217
1220
|
body = applyProviderRecord(body, record2);
|
|
1218
1221
|
if (endpoint === "run") body = wrapRun(body, run);
|
|
1219
1222
|
return {
|
|
@@ -1221,7 +1224,7 @@ function compileCloudflareRequest(request, options, call, streaming) {
|
|
|
1221
1224
|
url: endpointUrl(options, endpoint),
|
|
1222
1225
|
headers: buildHeaders(options, call?.cloudflare, model, record2),
|
|
1223
1226
|
body,
|
|
1224
|
-
warnings: []
|
|
1227
|
+
warnings: packed.warning ? [packed.warning] : []
|
|
1225
1228
|
};
|
|
1226
1229
|
}
|
|
1227
1230
|
function compileResponsesBody(request, model) {
|
|
@@ -2270,7 +2273,7 @@ function parseSsePart(part) {
|
|
|
2270
2273
|
return void 0;
|
|
2271
2274
|
}
|
|
2272
2275
|
}
|
|
2273
|
-
function resolveCloudflareOptions(options) {
|
|
2276
|
+
function resolveCloudflareOptions(options, packer) {
|
|
2274
2277
|
const {
|
|
2275
2278
|
apiToken,
|
|
2276
2279
|
accountId,
|
|
@@ -2299,7 +2302,8 @@ function resolveCloudflareOptions(options) {
|
|
|
2299
2302
|
maxAttempts: maxAttempts ?? 2,
|
|
2300
2303
|
fetch: fetch ?? globalThis.fetch,
|
|
2301
2304
|
...tools ? { tools } : {},
|
|
2302
|
-
...logger ? { logger } : {}
|
|
2305
|
+
...logger ? { logger } : {},
|
|
2306
|
+
...packer ? { metadataPacker: packer } : {}
|
|
2303
2307
|
};
|
|
2304
2308
|
}
|
|
2305
2309
|
function hasGateway(gateway) {
|
|
@@ -2814,13 +2818,12 @@ function isBedrockToolChoice(toolChoice) {
|
|
|
2814
2818
|
|
|
2815
2819
|
// src/providers/openai.ts
|
|
2816
2820
|
import {
|
|
2817
|
-
|
|
2818
|
-
toProviderMetadata as toProviderMetadata2
|
|
2821
|
+
packProviderRecord as packProviderRecord2
|
|
2819
2822
|
} from "@x12i/openrouter-runtime";
|
|
2820
2823
|
var DEFAULT_BASE_URL2 = "https://api.openai.com/v1";
|
|
2821
2824
|
var DEFAULT_TIMEOUT_MS2 = 12e4;
|
|
2822
|
-
function createOpenAiProviderAdapter(options = {}) {
|
|
2823
|
-
const resolved = resolveOpenAiOptions(options);
|
|
2825
|
+
function createOpenAiProviderAdapter(options = {}, packer) {
|
|
2826
|
+
const resolved = resolveOpenAiOptions(options, packer);
|
|
2824
2827
|
return {
|
|
2825
2828
|
compile(request, call) {
|
|
2826
2829
|
return compileOpenAiRequest(request, resolved, call, false);
|
|
@@ -2873,12 +2876,13 @@ function compileOpenAiRequest(request, options, call, streaming) {
|
|
|
2873
2876
|
if (call?.finalizeBody) body = call.finalizeBody(body);
|
|
2874
2877
|
if (streaming) body = { ...body, stream: true };
|
|
2875
2878
|
else body = { ...body, stream: false };
|
|
2876
|
-
|
|
2879
|
+
const packed = attachProviderMetadata(body, request, options.metadataPacker);
|
|
2880
|
+
body = packed.body;
|
|
2877
2881
|
return {
|
|
2878
2882
|
url: `${options.baseUrl}/responses`,
|
|
2879
2883
|
headers: buildHeaders2(options),
|
|
2880
2884
|
body,
|
|
2881
|
-
warnings: []
|
|
2885
|
+
warnings: packed.warning ? [packed.warning] : []
|
|
2882
2886
|
};
|
|
2883
2887
|
}
|
|
2884
2888
|
function assertSupported2(request) {
|
|
@@ -3378,14 +3382,14 @@ function messageFrom2(body) {
|
|
|
3378
3382
|
function numberValue2(value) {
|
|
3379
3383
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
3380
3384
|
}
|
|
3381
|
-
function attachProviderMetadata(body, request) {
|
|
3385
|
+
function attachProviderMetadata(body, request, packer) {
|
|
3382
3386
|
const fromBody = isRecord7(body.metadata) ? body.metadata : void 0;
|
|
3383
|
-
const
|
|
3384
|
-
if (
|
|
3385
|
-
if (body.metadata === void 0) return body;
|
|
3387
|
+
const packed = packProviderRecord2(request.metadata, request.agentId, fromBody, packer);
|
|
3388
|
+
if (packed.wire) return { body: { ...body, metadata: packed.wire }, ...packed.warning ? { warning: packed.warning } : {} };
|
|
3389
|
+
if (body.metadata === void 0) return { body, ...packed.warning ? { warning: packed.warning } : {} };
|
|
3386
3390
|
const rest = { ...body };
|
|
3387
3391
|
delete rest.metadata;
|
|
3388
|
-
return rest;
|
|
3392
|
+
return { body: rest, ...packed.warning ? { warning: packed.warning } : {} };
|
|
3389
3393
|
}
|
|
3390
3394
|
function clean2(body) {
|
|
3391
3395
|
return Object.fromEntries(Object.entries(body).filter(([, value]) => value !== void 0));
|
|
@@ -3433,7 +3437,7 @@ function parseSsePart2(part) {
|
|
|
3433
3437
|
return void 0;
|
|
3434
3438
|
}
|
|
3435
3439
|
}
|
|
3436
|
-
function resolveOpenAiOptions(options) {
|
|
3440
|
+
function resolveOpenAiOptions(options, packer) {
|
|
3437
3441
|
const baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL2).replace(/\/+$/, "");
|
|
3438
3442
|
return {
|
|
3439
3443
|
apiKey: options.apiKey ?? readEnv3("OPENAI_API_KEY") ?? "",
|
|
@@ -3445,7 +3449,8 @@ function resolveOpenAiOptions(options) {
|
|
|
3445
3449
|
maxAttempts: options.maxAttempts ?? 3,
|
|
3446
3450
|
fetch: options.fetch ?? globalThis.fetch,
|
|
3447
3451
|
...options.tools ? { tools: options.tools } : {},
|
|
3448
|
-
...options.logger ? { logger: options.logger } : {}
|
|
3452
|
+
...options.logger ? { logger: options.logger } : {},
|
|
3453
|
+
...packer ? { metadataPacker: packer } : {}
|
|
3449
3454
|
};
|
|
3450
3455
|
}
|
|
3451
3456
|
function readEnv3(name) {
|
|
@@ -3500,7 +3505,9 @@ function resolveProvider(requestProvider, defaultProvider) {
|
|
|
3500
3505
|
|
|
3501
3506
|
// src/create-dispatcher.ts
|
|
3502
3507
|
var SECRET_HEADERS = /* @__PURE__ */ new Set(["authorization", "x-api-key", "api-key"]);
|
|
3508
|
+
var DEFAULT_METADATA_PRIORITY = ["agentId", "orgId", "stepId", "skillId", "recordId", "objectType"];
|
|
3503
3509
|
function createAiDispatcher(options = {}) {
|
|
3510
|
+
const packer = createMetadataPacker({ priority: options.metadataPriority ?? DEFAULT_METADATA_PRIORITY });
|
|
3504
3511
|
const defaultProvider = resolveProvider(options.provider, "openrouter");
|
|
3505
3512
|
const catalog = createMcpCatalog(options.mcp);
|
|
3506
3513
|
let refreshChain = Promise.resolve();
|
|
@@ -3509,6 +3516,7 @@ function createAiDispatcher(options = {}) {
|
|
|
3509
3516
|
if (provider === "openrouter") {
|
|
3510
3517
|
const openrouterOptions = {
|
|
3511
3518
|
...options.openrouter,
|
|
3519
|
+
metadataPacker: packer,
|
|
3512
3520
|
...options.logger && !options.openrouter?.logger ? { logger: options.logger } : {}
|
|
3513
3521
|
};
|
|
3514
3522
|
return createOpenRouterProviderAdapter(openrouterOptions);
|
|
@@ -3516,6 +3524,7 @@ function createAiDispatcher(options = {}) {
|
|
|
3516
3524
|
if (provider === "bedrock") {
|
|
3517
3525
|
const bedrockOptions = {
|
|
3518
3526
|
...options.bedrock,
|
|
3527
|
+
metadataPacker: packer,
|
|
3519
3528
|
...options.logger && !options.bedrock?.logger ? { logger: options.logger } : {}
|
|
3520
3529
|
};
|
|
3521
3530
|
return createBedrockProviderAdapter(bedrockOptions);
|
|
@@ -3525,14 +3534,14 @@ function createAiDispatcher(options = {}) {
|
|
|
3525
3534
|
...options.openai,
|
|
3526
3535
|
...options.logger && !options.openai?.logger ? { logger: options.logger } : {}
|
|
3527
3536
|
};
|
|
3528
|
-
return createOpenAiProviderAdapter(openaiOptions);
|
|
3537
|
+
return createOpenAiProviderAdapter(openaiOptions, packer);
|
|
3529
3538
|
}
|
|
3530
3539
|
if (provider === "cloudflare") {
|
|
3531
3540
|
const cloudflareOptions = {
|
|
3532
3541
|
...options.cloudflare,
|
|
3533
3542
|
...options.logger && !options.cloudflare?.logger ? { logger: options.logger } : {}
|
|
3534
3543
|
};
|
|
3535
|
-
return createCloudflareProviderAdapter(cloudflareOptions);
|
|
3544
|
+
return createCloudflareProviderAdapter(cloudflareOptions, packer);
|
|
3536
3545
|
}
|
|
3537
3546
|
throw new AiDispatcherError(
|
|
3538
3547
|
"PROVIDER_ADAPTER_MISSING",
|
|
@@ -3652,6 +3661,7 @@ function stripReasoningHistoryFields(message, paths) {
|
|
|
3652
3661
|
}
|
|
3653
3662
|
export {
|
|
3654
3663
|
AiDispatcherError,
|
|
3664
|
+
DEFAULT_METADATA_PRIORITY,
|
|
3655
3665
|
IMPLEMENTED_AI_PROVIDERS,
|
|
3656
3666
|
createAiDispatcher,
|
|
3657
3667
|
decodeProviderMetadata,
|