@x12i/ai-dispatcher 2.3.0 → 2.3.2
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 +14 -3
- package/dist/index.cjs +3 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ One request shape for OpenRouter, AWS Bedrock, the OpenAI Responses API, and Clo
|
|
|
4
4
|
|
|
5
5
|
**Implemented providers:** `openrouter`, `bedrock`, `openai`, `cloudflare`. Any other provider throws `PROVIDER_NOT_IMPLEMENTED`.
|
|
6
6
|
|
|
7
|
-
The package is `@x12i/ai-dispatcher` 2.3.
|
|
7
|
+
The package is `@x12i/ai-dispatcher` 2.3.1. It runs on Node 20 or newer and publishes ESM and CommonJS from the same entry.
|
|
8
8
|
|
|
9
9
|
Connected MCP servers can be passed to `createAiDispatcher`. `run()` and `compile()` expose those tools to the model. `executeStreamingChat` does not. Details are in [MCP tools](#mcp-tools).
|
|
10
10
|
|
|
@@ -177,7 +177,7 @@ const record = decodeProviderMetadata(logMetadata);
|
|
|
177
177
|
|
|
178
178
|
`metadata` is the one record. When `rawOpenRouterOverrides` only repeats `metadata`, the dispatcher folds it in. `metadata` wins when the same key is in both places. String, number, and boolean values are stored, including a JSON string. Objects and arrays stay on the normalized response and the tool context.
|
|
179
179
|
|
|
180
|
-
Every provider writes that record as `m.0`, `m.1`, and so on: one base64 string, 256 characters per piece, at most 16 pieces. The base64 is the UTF-8 JSON object of the string map, with keys sorted. `decodeProviderMetadata` reads those pieces from OpenRouter body `metadata`, OpenAI Responses `metadata`, Bedrock `requestMetadata`, or Cloudflare body `metadata
|
|
180
|
+
Every provider writes that record as `m.0`, `m.1`, and so on: one base64 string, 256 characters per piece, at most 16 pieces. The base64 is the UTF-8 JSON object of the string map, with keys sorted. `decodeProviderMetadata` reads those pieces from OpenRouter body `metadata`, OpenAI Responses `metadata`, Bedrock `requestMetadata`, or Cloudflare body `metadata`. Pass the Cloudflare `cf-aig-metadata` header as that same object or as the raw JSON string. The pieces are the same on every provider. The dispatcher trims on every call. Pass `metadataPriority` (highest priority first) to choose what stays. The default keeps `agentId`, `orgId`, `stepId`, `skillId`, `role`, `roleLayer`, `roleDigest`, `profileChoice`, `recordId`, and `objectType`. A trimmed call adds a `METADATA_RECORD_TRIMMED` warning.
|
|
181
181
|
|
|
182
182
|
Repeating vendor fields normalize to one key. Prefer `metadata.api_key_name` over `metadata.openrouter.api_key_name`. `normalizeMetadata` and `decodeProviderMetadata` promote known aliases and keep the vendor key. Grow `METADATA_NORMALIZATION_MAP` as more shared fields appear.
|
|
183
183
|
|
|
@@ -446,6 +446,17 @@ await dispatcher.run({
|
|
|
446
446
|
|
|
447
447
|
Cloudflare supports the same `run`, `compile`, and `executeStreamingChat` entrypoints. `executeStreamingChat` rejects `/ai/run`. `reasoningEffort` uses the OpenAI or OpenRouter catalog, as described above. `cache` sets AI Gateway headers and, for GPT on Responses and Claude on Messages, the native breakpoint. Local function tools and MCP tools follow the OpenAI loop. OpenRouter server tools are rejected. `rawOpenRouterOverrides` is rejected except for a `metadata` object, which is folded into `metadata`. `responseFormat` is `text` on Responses, `response_format` on chat, and rejected on messages and run.
|
|
448
448
|
|
|
449
|
+
## Credentials
|
|
450
|
+
|
|
451
|
+
A provider is available when the dispatcher can resolve the credential it sends. `compile` and `run` throw when a required value is missing.
|
|
452
|
+
|
|
453
|
+
| Provider | Option | Environment |
|
|
454
|
+
| --- | --- | --- |
|
|
455
|
+
| OpenRouter | `openrouter.apiKey` | `OPENROUTER_API_KEY`, then `OPEN_ROUTER_KEY` |
|
|
456
|
+
| Bedrock | `bedrock.region` and optional `bedrock.credentials` | `AWS_REGION` or `AWS_DEFAULT_REGION`. When `credentials` is omitted, the AWS SDK default chain is used. An explicit credential is `accessKeyId`, `secretAccessKey`, and optional `sessionToken`. |
|
|
457
|
+
| OpenAI | `openai.apiKey` | `OPENAI_API_KEY` |
|
|
458
|
+
| Cloudflare | `cloudflare.apiToken` and `cloudflare.accountId` | `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID` |
|
|
459
|
+
|
|
449
460
|
## Errors
|
|
450
461
|
|
|
451
462
|
Catalog failures throw `AiDispatcherError` with `code`, `message`, and the catalog `details`. Dispatcher codes include:
|
|
@@ -466,7 +477,7 @@ Catalog failures throw `AiDispatcherError` with `code`, `message`, and the catal
|
|
|
466
477
|
| `PROVIDER_AUTH_FAILED` | OpenAI or Cloudflare HTTP `401` or `403` |
|
|
467
478
|
| `PROVIDER_MODEL_NOT_FOUND` | OpenAI or Cloudflare HTTP `404` |
|
|
468
479
|
| `PROVIDER_REQUEST_FAILED` | Other OpenAI or Cloudflare HTTP failures |
|
|
469
|
-
| `PROVIDER_RATE_LIMITED` | Cloudflare HTTP `429` after retries |
|
|
480
|
+
| `PROVIDER_RATE_LIMITED` | OpenAI or Cloudflare HTTP `429` after retries |
|
|
470
481
|
| `PROVIDER_RETRYABLE` / `PROVIDER_GATEWAY_UNREACHABLE` | OpenAI or Cloudflare transport failures after retries, including timeout |
|
|
471
482
|
| `FUNCTION_TOOL_LIMIT` | Function-tool calls exceed `maxFunctionToolCalls` |
|
|
472
483
|
| `UNSUPPORTED_CONTENT` | Bedrock received an image URL or content part it cannot send |
|
package/dist/index.cjs
CHANGED
|
@@ -3280,8 +3280,7 @@ async function readFailure2(response) {
|
|
|
3280
3280
|
function classifyStatus2(status) {
|
|
3281
3281
|
if (status === 401 || status === 403) return "PROVIDER_AUTH_FAILED";
|
|
3282
3282
|
if (status === 404) return "PROVIDER_MODEL_NOT_FOUND";
|
|
3283
|
-
if (status === 429) return "
|
|
3284
|
-
if (status === 408 || status >= 500) return "PROVIDER_RETRYABLE";
|
|
3283
|
+
if (status === 429 || status === 408 || status >= 500) return "PROVIDER_RETRYABLE";
|
|
3285
3284
|
return "PROVIDER_REQUEST_FAILED";
|
|
3286
3285
|
}
|
|
3287
3286
|
function isConfigError2(code) {
|
|
@@ -3289,6 +3288,8 @@ function isConfigError2(code) {
|
|
|
3289
3288
|
}
|
|
3290
3289
|
function asTerminalError2(error) {
|
|
3291
3290
|
if (error instanceof AiDispatcherError && error.code === "PROVIDER_RETRYABLE") {
|
|
3291
|
+
const status = isRecord7(error.details) ? error.details.status : void 0;
|
|
3292
|
+
if (status === 429) return new AiDispatcherError("PROVIDER_RATE_LIMITED", error.message, error.details);
|
|
3292
3293
|
return new AiDispatcherError("PROVIDER_GATEWAY_UNREACHABLE", error.message, error.details);
|
|
3293
3294
|
}
|
|
3294
3295
|
if (error instanceof AiDispatcherError) return error;
|