@axlsdk/axl 0.22.1 → 0.22.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/dist/index.js CHANGED
@@ -1205,7 +1205,8 @@ var OpenAICompatibleProvider = class {
1205
1205
  return this.name === "openrouter" && model.trim().length > 0 ? { image: { sources: ["url", "bytes", "base64"] } } : {};
1206
1206
  }
1207
1207
  validateInput(request) {
1208
- const effectiveModel = typeof request.providerOptions?.model === "string" ? request.providerOptions.model : request.model;
1208
+ const modelOverride = request.providerOptions?.model;
1209
+ const effectiveModel = typeof modelOverride === "string" ? modelOverride : request.model;
1209
1210
  const fail = (source, feature) => {
1210
1211
  throw new UnsupportedModelInputError({
1211
1212
  provider: this.name,
@@ -1215,6 +1216,9 @@ var OpenAICompatibleProvider = class {
1215
1216
  ...feature ? { feature } : {}
1216
1217
  });
1217
1218
  };
1219
+ if (request.providerOptions && "model" in request.providerOptions && (typeof modelOverride !== "string" || modelOverride.trim().length === 0)) {
1220
+ fail(void 0, "invalid model providerOptions");
1221
+ }
1218
1222
  if (this.name !== "openrouter" || effectiveModel.trim().length === 0) {
1219
1223
  fail(void 0, "image input for this model");
1220
1224
  }
@@ -2155,13 +2159,6 @@ var OpenAIProvider = class extends OpenAICompatibleProvider {
2155
2159
  };
2156
2160
 
2157
2161
  // src/providers/openai-responses.ts
2158
- var OPENAI_RESPONSES_IMAGE_MODELS = /* @__PURE__ */ new Set([
2159
- "gpt-4o",
2160
- "gpt-4o-2024-08-06",
2161
- "gpt-4o-2024-11-20",
2162
- "gpt-4o-mini",
2163
- "gpt-4o-mini-2024-07-18"
2164
- ]);
2165
2162
  function base64FromSource(source) {
2166
2163
  return source.type === "base64" ? source.data : Buffer.from(source.data.buffer, source.data.byteOffset, source.data.byteLength).toString(
2167
2164
  "base64"
@@ -2200,10 +2197,11 @@ function responseImageParts(parts) {
2200
2197
  var OpenAIResponsesProvider = class {
2201
2198
  name = "openai-responses";
2202
2199
  inputCapabilities(model) {
2203
- return OPENAI_RESPONSES_IMAGE_MODELS.has(model) ? { image: { sources: ["url", "bytes", "base64", "provider-file"] } } : {};
2200
+ return model.trim().length > 0 ? { image: { sources: ["url", "bytes", "base64", "provider-file"] } } : {};
2204
2201
  }
2205
2202
  validateInput(request) {
2206
- const effectiveModel = typeof request.providerOptions?.model === "string" ? request.providerOptions.model : request.model;
2203
+ const modelOverride = request.providerOptions?.model;
2204
+ const effectiveModel = typeof modelOverride === "string" ? modelOverride : request.model;
2207
2205
  const fail = (source, feature) => {
2208
2206
  throw new UnsupportedModelInputError({
2209
2207
  provider: this.name,
@@ -2213,7 +2211,10 @@ var OpenAIResponsesProvider = class {
2213
2211
  ...feature ? { feature } : {}
2214
2212
  });
2215
2213
  };
2216
- if (!OPENAI_RESPONSES_IMAGE_MODELS.has(effectiveModel)) {
2214
+ if (request.providerOptions && "model" in request.providerOptions && (typeof modelOverride !== "string" || modelOverride.trim().length === 0)) {
2215
+ fail(void 0, "invalid model providerOptions");
2216
+ }
2217
+ if (effectiveModel.trim().length === 0) {
2217
2218
  fail(void 0, "image input for this model");
2218
2219
  }
2219
2220
  if (request.providerOptions && "input" in request.providerOptions) {
@@ -2341,7 +2342,7 @@ var OpenAIResponsesProvider = class {
2341
2342
  const resolved = resolveThinkingOptions(options);
2342
2343
  const { includeThoughts } = resolved;
2343
2344
  const wireEffort = resolveOpenAIReasoningEffort(effectiveModel, resolved);
2344
- const stripTemp = oSeries || reasoningCapable && wireEffort !== void 0;
2345
+ const stripTemp = oSeries || supportsMaxReasoningEffort(effectiveModel) || reasoningCapable && wireEffort !== void 0;
2345
2346
  const systemMessages = messages.filter((m) => m.role === "system");
2346
2347
  const nonSystemMessages = messages.filter((m) => m.role !== "system");
2347
2348
  const body = {
@@ -2689,7 +2690,6 @@ function anthropicImageBlocks(parts) {
2689
2690
  }
2690
2691
  var ANTHROPIC_API_VERSION = "2023-06-01";
2691
2692
  var ANTHROPIC_FILES_BETA = "files-api-2025-04-14";
2692
- var ANTHROPIC_IMAGE_MODELS = /* @__PURE__ */ new Set(["claude-sonnet-4-5", "claude-opus-4-8"]);
2693
2693
  function hasAnthropicProviderFileImage(messages) {
2694
2694
  return messages.some(
2695
2695
  (message) => Array.isArray(message.content) && message.content.some(
@@ -2808,6 +2808,28 @@ var ANTHROPIC_RATES = {
2808
2808
  function isValidTokenCount(value) {
2809
2809
  return value !== void 0 && Number.isSafeInteger(value) && value >= 0;
2810
2810
  }
2811
+ function anthropicStreamErrorStatus(type) {
2812
+ switch (type) {
2813
+ case "invalid_request_error":
2814
+ return 400;
2815
+ case "authentication_error":
2816
+ return 401;
2817
+ case "permission_error":
2818
+ return 403;
2819
+ case "not_found_error":
2820
+ return 404;
2821
+ case "request_too_large":
2822
+ return 413;
2823
+ case "rate_limit_error":
2824
+ return 429;
2825
+ case "api_error":
2826
+ return 500;
2827
+ case "overloaded_error":
2828
+ return 529;
2829
+ default:
2830
+ return 0;
2831
+ }
2832
+ }
2811
2833
  function estimateAnthropicCost(model, usage, now = /* @__PURE__ */ new Date()) {
2812
2834
  if (!model || !isValidTokenCount(usage.inputTokens) || !isValidTokenCount(usage.outputTokens)) {
2813
2835
  return void 0;
@@ -3057,10 +3079,11 @@ function mergeAnthropicUsage(initial, update) {
3057
3079
  var AnthropicProvider = class {
3058
3080
  name = "anthropic";
3059
3081
  inputCapabilities(model) {
3060
- return ANTHROPIC_IMAGE_MODELS.has(model) ? { image: { sources: ["url", "bytes", "base64", "provider-file"] } } : {};
3082
+ return model.trim().length > 0 ? { image: { sources: ["url", "bytes", "base64", "provider-file"] } } : {};
3061
3083
  }
3062
3084
  validateInput(request) {
3063
- const effectiveModel = typeof request.providerOptions?.model === "string" ? request.providerOptions.model : request.model;
3085
+ const modelOverride = request.providerOptions?.model;
3086
+ const effectiveModel = typeof modelOverride === "string" ? modelOverride : request.model;
3064
3087
  const fail = (source, feature) => {
3065
3088
  throw new UnsupportedModelInputError({
3066
3089
  provider: this.name,
@@ -3070,7 +3093,10 @@ var AnthropicProvider = class {
3070
3093
  ...feature ? { feature } : {}
3071
3094
  });
3072
3095
  };
3073
- if (!ANTHROPIC_IMAGE_MODELS.has(effectiveModel)) {
3096
+ if (request.providerOptions && "model" in request.providerOptions && (typeof modelOverride !== "string" || modelOverride.trim().length === 0)) {
3097
+ fail(void 0, "invalid model providerOptions");
3098
+ }
3099
+ if (effectiveModel.trim().length === 0) {
3074
3100
  fail(void 0, "image input for this model");
3075
3101
  }
3076
3102
  if (request.providerOptions && "messages" in request.providerOptions) {
@@ -3195,7 +3221,7 @@ var AnthropicProvider = class {
3195
3221
  if (!res.body) {
3196
3222
  throw new Error("Anthropic stream response has no body");
3197
3223
  }
3198
- yield* this.parseSSEStream(res.body, pricingContext);
3224
+ yield* this.parseSSEStream(res.body, pricingContext, res.headers);
3199
3225
  }
3200
3226
  // ---------------------------------------------------------------------------
3201
3227
  // Internal: request building
@@ -3438,7 +3464,7 @@ ${jsonInstruction}` : jsonInstruction;
3438
3464
  // ---------------------------------------------------------------------------
3439
3465
  // Internal: SSE stream parsing
3440
3466
  // ---------------------------------------------------------------------------
3441
- async *parseSSEStream(body, pricingContext) {
3467
+ async *parseSSEStream(body, pricingContext, responseHeaders) {
3442
3468
  const reader = body.getReader();
3443
3469
  const decoder = new TextDecoder();
3444
3470
  let buffer = "";
@@ -3484,6 +3510,15 @@ ${jsonInstruction}` : jsonInstruction;
3484
3510
  continue;
3485
3511
  }
3486
3512
  switch (event.type) {
3513
+ case "error": {
3514
+ const status = anthropicStreamErrorStatus(event.error?.type);
3515
+ throw buildProviderError({
3516
+ provider: this.name,
3517
+ status,
3518
+ headers: responseHeaders,
3519
+ message: event.error?.message ?? "Anthropic stream failed"
3520
+ });
3521
+ }
3487
3522
  case "content_block_start": {
3488
3523
  const block = event.content_block;
3489
3524
  if (block?.type === "tool_use") {
@@ -3735,7 +3770,6 @@ var GEMINI_PRICING = {
3735
3770
  "gemini-3.5-flash-lite": { input: 3e-7, cached: 3e-8, output: 25e-7 },
3736
3771
  "gemini-3.6-flash": { input: 15e-7, cached: 15e-8, output: 75e-7 }
3737
3772
  };
3738
- var GEMINI_INTERACTIONS_IMAGE_MODELS = /* @__PURE__ */ new Set(["gemini-3.7-flash"]);
3739
3773
  function isValidTokenCount2(value) {
3740
3774
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
3741
3775
  }
@@ -3745,6 +3779,55 @@ function isStandardGeminiRequestTier(value) {
3745
3779
  function isDefinitiveStandardGeminiResponseTier(value) {
3746
3780
  return value === "SERVICE_TIER_UNSPECIFIED" || value === "SERVICE_TIER_STANDARD" || value === "standard";
3747
3781
  }
3782
+ function geminiInteractionErrorStatus(code) {
3783
+ if (typeof code === "number" && Number.isInteger(code) && code >= 100 && code <= 599) {
3784
+ return code;
3785
+ }
3786
+ switch (code) {
3787
+ case "invalid_request":
3788
+ case "invalid_argument":
3789
+ case "parameter_unknown":
3790
+ case "failed_precondition":
3791
+ return 400;
3792
+ case "authentication":
3793
+ case "unauthenticated":
3794
+ return 401;
3795
+ case "permission_denied":
3796
+ return 403;
3797
+ case "not_found":
3798
+ case "model_not_found":
3799
+ return 404;
3800
+ case "request_timeout":
3801
+ return 408;
3802
+ case "conflict":
3803
+ case "already_exists":
3804
+ return 409;
3805
+ case "request_too_large":
3806
+ return 413;
3807
+ case "out_of_range":
3808
+ return 416;
3809
+ case "quota_exceeded":
3810
+ case "resource_exhausted":
3811
+ case "rate_limit_exceeded":
3812
+ return 429;
3813
+ case "cancelled":
3814
+ return 499;
3815
+ case "api_error":
3816
+ case "internal":
3817
+ case "internal_server_error":
3818
+ return 500;
3819
+ case "bad_gateway":
3820
+ return 502;
3821
+ case "unavailable":
3822
+ case "service_unavailable":
3823
+ return 503;
3824
+ case "deadline_exceeded":
3825
+ case "gateway_timeout":
3826
+ return 504;
3827
+ default:
3828
+ return void 0;
3829
+ }
3830
+ }
3748
3831
  function isEligibleGeminiPricing(context, hasDefinitiveStandardResponseTier, hasInvalidResponseTier) {
3749
3832
  return context.eligibleRequest && isStandardGeminiRequestTier(context.serviceTier) && hasDefinitiveStandardResponseTier && !hasInvalidResponseTier;
3750
3833
  }
@@ -3826,7 +3909,9 @@ var GEMINI_3X_MIN_THINKING_LEVEL = /* @__PURE__ */ new Map([
3826
3909
  ["gemini-3.6-flash", "minimal"],
3827
3910
  // L4 live evidence: Interactions gemini-3.7-flash accepts low/medium/high,
3828
3911
  // but rejects minimal. Keep this exact entry isolated from legacy aliases.
3829
- ["gemini-3.7-flash", "low"]
3912
+ ["gemini-3.7-flash", "low"],
3913
+ // Current-model live evidence: gemini-3.8-flash has the same low floor.
3914
+ ["gemini-3.8-flash", "low"]
3830
3915
  ]);
3831
3916
  var GEMINI_MODELS_WITHOUT_PORTABLE_TEMPERATURE = /* @__PURE__ */ new Set([
3832
3917
  "gemini-3.5-flash-lite",
@@ -3854,10 +3939,11 @@ function warnGemini3xEffortNone(model) {
3854
3939
  var GeminiProvider = class {
3855
3940
  name = "google";
3856
3941
  inputCapabilities(model) {
3857
- return GEMINI_INTERACTIONS_IMAGE_MODELS.has(model) ? { image: { sources: ["bytes", "base64", "provider-file"] } } : {};
3942
+ return model.trim().length > 0 ? { image: { sources: ["bytes", "base64", "provider-file"] } } : {};
3858
3943
  }
3859
3944
  validateInput(request) {
3860
- const effectiveModel = typeof request.providerOptions?.model === "string" ? request.providerOptions.model : request.model;
3945
+ const modelOverride = request.providerOptions?.model;
3946
+ const effectiveModel = typeof modelOverride === "string" ? modelOverride : request.model;
3861
3947
  const fail = (source, feature) => {
3862
3948
  throw new UnsupportedModelInputError({
3863
3949
  provider: this.name,
@@ -3867,7 +3953,10 @@ var GeminiProvider = class {
3867
3953
  ...feature ? { feature } : {}
3868
3954
  });
3869
3955
  };
3870
- if (!GEMINI_INTERACTIONS_IMAGE_MODELS.has(effectiveModel)) {
3956
+ if (request.providerOptions && "model" in request.providerOptions && (typeof modelOverride !== "string" || modelOverride.trim().length === 0)) {
3957
+ fail(void 0, "invalid model providerOptions");
3958
+ }
3959
+ if (effectiveModel.trim().length === 0) {
3871
3960
  fail(void 0, "image input for this model");
3872
3961
  }
3873
3962
  if (request.providerOptions) {
@@ -4059,7 +4148,7 @@ var GeminiProvider = class {
4059
4148
  });
4060
4149
  }
4061
4150
  if (!res.body) throw new Error("Gemini Interactions stream has no body");
4062
- yield* this.parseInteractionSSEStream(res.body);
4151
+ yield* this.parseInteractionSSEStream(res.body, res.headers);
4063
4152
  }
4064
4153
  buildInteractionRequestBody(messages, options, stream) {
4065
4154
  const model = this.requestModel(options);
@@ -4129,6 +4218,7 @@ var GeminiProvider = class {
4129
4218
  return body;
4130
4219
  }
4131
4220
  assertSafeInteractionOptions(options) {
4221
+ const modelOverride = options.providerOptions?.model;
4132
4222
  const model = this.requestModel(options);
4133
4223
  const fail = (feature) => {
4134
4224
  throw new UnsupportedModelInputError({
@@ -4138,7 +4228,10 @@ var GeminiProvider = class {
4138
4228
  feature
4139
4229
  });
4140
4230
  };
4141
- if (!GEMINI_INTERACTIONS_IMAGE_MODELS.has(model)) fail("image input for this model");
4231
+ if (options.providerOptions && "model" in options.providerOptions && (typeof modelOverride !== "string" || modelOverride.trim().length === 0)) {
4232
+ fail("invalid model providerOptions");
4233
+ }
4234
+ if (model.trim().length === 0) fail("image input for this model");
4142
4235
  const forbidden = [
4143
4236
  "input",
4144
4237
  "contents",
@@ -4214,7 +4307,7 @@ var GeminiProvider = class {
4214
4307
  providerMetadata: json.steps?.length ? { geminiInteractionSteps: json.steps.filter(isGeminiInteractionStep) } : void 0
4215
4308
  };
4216
4309
  }
4217
- async *parseInteractionSSEStream(body) {
4310
+ async *parseInteractionSSEStream(body, responseHeaders) {
4218
4311
  const reader = body.getReader();
4219
4312
  const decoder = new TextDecoder();
4220
4313
  let buffer = "";
@@ -4240,7 +4333,22 @@ var GeminiProvider = class {
4240
4333
  continue;
4241
4334
  }
4242
4335
  if (event.event_type === "error") {
4243
- throw new Error(event.error?.message ?? "Gemini Interactions stream failed");
4336
+ const status = geminiInteractionErrorStatus(event.error?.code);
4337
+ const message = event.error?.message ?? "Gemini Interactions stream failed";
4338
+ if (status !== void 0) {
4339
+ throw buildProviderError({
4340
+ provider: this.name,
4341
+ status,
4342
+ headers: responseHeaders,
4343
+ message
4344
+ });
4345
+ }
4346
+ throw new ProviderError({
4347
+ provider: this.name,
4348
+ status: 0,
4349
+ retryable: false,
4350
+ message
4351
+ });
4244
4352
  }
4245
4353
  if (event.event_type === "step.start" && event.step) {
4246
4354
  const index = event.index;