@axlsdk/axl 0.22.0 → 0.22.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/README.md +7 -5
- package/dist/index.cjs +14 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +14 -11
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ agent({ model: 'deepseek:deepseek-reasoner' }); // DEEPSEEK_API_KEY
|
|
|
67
67
|
agent({ model: 'ollama:llama3' }); // local — no key, $0
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
Presets: `openrouter`, `azure`, `xai`, `deepseek`, `mistral`, `groq`, `bedrock`, and self-hosted `ollama` / `vllm` / `lmstudio` / `llamacpp` / `sglang`. The unified `effort` knob and per-call cost tracking work across them. Build your own by cloning a `ProviderProfile
|
|
70
|
+
Presets: `openrouter`, `azure`, `xai`, `deepseek`, `mistral`, `groq`, `bedrock`, and self-hosted `ollama` / `vllm` / `lmstudio` / `llamacpp` / `sglang`. The unified `effort` knob and per-call cost tracking work across them. OpenRouter passes image input through to the selected model/route, but Axl does not claim every catalog model supports images, tools, or transcription. Build your own by cloning a `ProviderProfile`; see [provider details](../../docs/providers.md#openai-compatible-providers--presets) and [multimodal input](../../docs/multimodal-input.md).
|
|
71
71
|
|
|
72
72
|
Each provider also accepts an opt-in `rateLimit` (`{ maxConcurrent?, minIntervalMs?, acquireTimeoutMs? }`) for proactive client-side pacing on top of the automatic 429/503/529 backoff — useful when a large fan-out (e.g. an eval) shares one API key. It caps in-flight request concurrency (not token throughput) for that provider's chat calls. See [Providers → Rate limiting](../../docs/providers.md#rate-limiting-opt-in).
|
|
73
73
|
|
|
@@ -792,10 +792,12 @@ See [docs/providers.md](../../docs/providers.md) for the full model list includi
|
|
|
792
792
|
|
|
793
793
|
Use `ctx.transcribe()` for finite recordings, then explicitly pass
|
|
794
794
|
`Transcript.text` to an agent if analysis is needed. It is separate from chat
|
|
795
|
-
history and chat providers.
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
795
|
+
history and chat providers. OpenAI and Gemini use their documented model
|
|
796
|
+
contracts; any nonblank `openrouter-transcription:<vendor/model>` URI can
|
|
797
|
+
dispatch supported bytes/base64 to OpenRouter, where the selected model/route
|
|
798
|
+
decides endpoint compatibility. See [Multimodal input](../../docs/multimodal-input.md)
|
|
799
|
+
for the 25 MiB inline bound, source types, options, transcript redaction,
|
|
800
|
+
temporary Gemini Files cleanup, and live-verification commands.
|
|
799
801
|
|
|
800
802
|
## License
|
|
801
803
|
|
package/dist/index.cjs
CHANGED
|
@@ -1277,13 +1277,12 @@ function unsafeTransportError(surface, remediation, exposedData) {
|
|
|
1277
1277
|
}
|
|
1278
1278
|
|
|
1279
1279
|
// src/providers/openai-compatible.ts
|
|
1280
|
-
var OPENROUTER_IMAGE_MODEL = "openai/gpt-4o-mini";
|
|
1281
1280
|
function compatibleImageBase64(source) {
|
|
1282
1281
|
return source.type === "base64" ? source.data : Buffer.from(source.data.buffer, source.data.byteOffset, source.data.byteLength).toString(
|
|
1283
1282
|
"base64"
|
|
1284
1283
|
);
|
|
1285
1284
|
}
|
|
1286
|
-
function openRouterImageParts(parts) {
|
|
1285
|
+
function openRouterImageParts(parts, model) {
|
|
1287
1286
|
const content = [];
|
|
1288
1287
|
for (const part of parts) {
|
|
1289
1288
|
if (part.type === "text") {
|
|
@@ -1294,7 +1293,7 @@ function openRouterImageParts(parts) {
|
|
|
1294
1293
|
if (source.type === "provider-file") {
|
|
1295
1294
|
throw new UnsupportedModelInputError({
|
|
1296
1295
|
provider: "openrouter",
|
|
1297
|
-
model
|
|
1296
|
+
model,
|
|
1298
1297
|
modality: "image",
|
|
1299
1298
|
source: "provider-file"
|
|
1300
1299
|
});
|
|
@@ -1425,7 +1424,7 @@ function normalizeMessageContent(content) {
|
|
|
1425
1424
|
var OpenAICompatibleProvider = class {
|
|
1426
1425
|
name;
|
|
1427
1426
|
inputCapabilities(model) {
|
|
1428
|
-
return this.name === "openrouter" && model
|
|
1427
|
+
return this.name === "openrouter" && model.trim().length > 0 ? { image: { sources: ["url", "bytes", "base64"] } } : {};
|
|
1429
1428
|
}
|
|
1430
1429
|
validateInput(request) {
|
|
1431
1430
|
const effectiveModel = typeof request.providerOptions?.model === "string" ? request.providerOptions.model : request.model;
|
|
@@ -1438,13 +1437,12 @@ var OpenAICompatibleProvider = class {
|
|
|
1438
1437
|
...feature ? { feature } : {}
|
|
1439
1438
|
});
|
|
1440
1439
|
};
|
|
1441
|
-
if (this.name !== "openrouter" || effectiveModel
|
|
1440
|
+
if (this.name !== "openrouter" || effectiveModel.trim().length === 0) {
|
|
1442
1441
|
fail(void 0, "image input for this model");
|
|
1443
1442
|
}
|
|
1444
1443
|
if (request.providerOptions && "messages" in request.providerOptions) {
|
|
1445
1444
|
fail(void 0, "raw messages providerOptions");
|
|
1446
1445
|
}
|
|
1447
|
-
if (request.hasTools) fail(void 0, "tools with image input");
|
|
1448
1446
|
for (const message of request.history) {
|
|
1449
1447
|
if (!Array.isArray(message.content)) continue;
|
|
1450
1448
|
if (message.role !== "user") fail(void 0, "rich non-user history");
|
|
@@ -1632,7 +1630,7 @@ var OpenAICompatibleProvider = class {
|
|
|
1632
1630
|
formatMessage(msg, model) {
|
|
1633
1631
|
const out = {
|
|
1634
1632
|
role: this.profile.roleFor ? this.profile.roleFor(msg.role, model) : msg.role,
|
|
1635
|
-
content: Array.isArray(msg.content) && this.name === "openrouter"
|
|
1633
|
+
content: Array.isArray(msg.content) && this.name === "openrouter" ? openRouterImageParts(msg.content, model) : msg.content
|
|
1636
1634
|
};
|
|
1637
1635
|
if (msg.name && (this.profile.capabilities?.emitsMessageName ?? true)) out.name = msg.name;
|
|
1638
1636
|
if (msg.tool_calls) out.tool_calls = msg.tool_calls;
|
|
@@ -5783,7 +5781,6 @@ function normalizeTranscriptionAccounting(usageValue, pricingValue) {
|
|
|
5783
5781
|
// src/providers/transcription-utils.ts
|
|
5784
5782
|
var OPENAI_TRANSCRIPTION_MODEL = "gpt-transcribe";
|
|
5785
5783
|
var GEMINI_TRANSCRIPTION_MODEL = "gemini-3.5-transcribe";
|
|
5786
|
-
var OPENROUTER_TRANSCRIPTION_MODEL = "openai/whisper-1";
|
|
5787
5784
|
function requireExactTranscriptionModel(provider, model, expected) {
|
|
5788
5785
|
if (model !== expected) {
|
|
5789
5786
|
throw new UnsupportedTranscriptionInputError({
|
|
@@ -6434,10 +6431,16 @@ var OpenRouterTranscriptionProvider = class {
|
|
|
6434
6431
|
this.governor = options.rateLimit ? new RateLimiter(options.rateLimit) : void 0;
|
|
6435
6432
|
}
|
|
6436
6433
|
capabilities(model) {
|
|
6437
|
-
return model
|
|
6434
|
+
return model.trim().length > 0 ? { sources: ["bytes", "base64"] } : void 0;
|
|
6438
6435
|
}
|
|
6439
6436
|
async transcribe(request) {
|
|
6440
|
-
|
|
6437
|
+
if (request.model.trim().length === 0) {
|
|
6438
|
+
throw new UnsupportedTranscriptionInputError({
|
|
6439
|
+
provider: this.name,
|
|
6440
|
+
model: request.model,
|
|
6441
|
+
feature: "this transcription model"
|
|
6442
|
+
});
|
|
6443
|
+
}
|
|
6441
6444
|
requireNoProviderFile(request.audio, this.name, request.model);
|
|
6442
6445
|
if (request.audio.type === "provider-file")
|
|
6443
6446
|
throw new UnsupportedTranscriptionInputError({
|
|
@@ -6577,7 +6580,7 @@ var TranscriptionProviderRegistry = class {
|
|
|
6577
6580
|
}
|
|
6578
6581
|
resolve(uri, config = {}) {
|
|
6579
6582
|
const colon = typeof uri === "string" ? uri.indexOf(":") : -1;
|
|
6580
|
-
if (colon <= 0 || colon === uri.length - 1
|
|
6583
|
+
if (colon <= 0 || colon === uri.length - 1) {
|
|
6581
6584
|
throw new UnsupportedTranscriptionInputError({
|
|
6582
6585
|
provider: "unknown",
|
|
6583
6586
|
model: "",
|