@axlsdk/axl 0.4.0 → 0.5.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/dist/index.js CHANGED
@@ -187,6 +187,24 @@ function estimateOpenAICost(model, promptTokens, completionTokens, cachedTokens)
187
187
  function isReasoningModel(model) {
188
188
  return /^(o1|o3|o4-mini)/.test(model);
189
189
  }
190
+ function thinkingToReasoningEffort(thinking) {
191
+ if (typeof thinking === "object") {
192
+ const budget = thinking.budgetTokens;
193
+ if (budget <= 1024) return "low";
194
+ if (budget <= 8192) return "medium";
195
+ return "high";
196
+ }
197
+ switch (thinking) {
198
+ case "low":
199
+ return "low";
200
+ case "medium":
201
+ return "medium";
202
+ case "high":
203
+ return "high";
204
+ case "max":
205
+ return "xhigh";
206
+ }
207
+ }
190
208
  var OpenAIProvider = class {
191
209
  name = "openai";
192
210
  baseUrl;
@@ -289,7 +307,9 @@ var OpenAIProvider = class {
289
307
  if (options.stop) body.stop = options.stop;
290
308
  if (options.tools && options.tools.length > 0) {
291
309
  body.tools = options.tools;
292
- body.parallel_tool_calls = true;
310
+ if (!reasoning) {
311
+ body.parallel_tool_calls = true;
312
+ }
293
313
  }
294
314
  if (options.toolChoice !== void 0) {
295
315
  body.tool_choice = options.toolChoice;
@@ -297,8 +317,11 @@ var OpenAIProvider = class {
297
317
  if (options.responseFormat) {
298
318
  body.response_format = options.responseFormat;
299
319
  }
300
- if (options.reasoningEffort) {
301
- body.reasoning_effort = options.reasoningEffort;
320
+ if (reasoning) {
321
+ const effort = options.thinking ? thinkingToReasoningEffort(options.thinking) : options.reasoningEffort;
322
+ if (effort) {
323
+ body.reasoning_effort = effort;
324
+ }
302
325
  }
303
326
  if (stream) {
304
327
  body.stream_options = { include_usage: true };
@@ -489,8 +512,11 @@ var OpenAIResponsesProvider = class {
489
512
  body.tool_choice = options.toolChoice;
490
513
  }
491
514
  }
492
- if (options.reasoningEffort) {
493
- body.reasoning = { effort: options.reasoningEffort };
515
+ if (reasoning) {
516
+ const effort = options.thinking ? thinkingToReasoningEffort(options.thinking) : options.reasoningEffort;
517
+ if (effort) {
518
+ body.reasoning = { effort };
519
+ }
494
520
  }
495
521
  if (options.responseFormat) {
496
522
  body.text = { format: this.mapResponseFormat(options.responseFormat) };
@@ -724,6 +750,24 @@ function estimateAnthropicCost(model, inputTokens, outputTokens, cacheReadTokens
724
750
  const inputCost = (inputTokens - cacheRead - cacheWrite) * inputRate + cacheRead * inputRate * 0.1 + cacheWrite * inputRate * 1.25;
725
751
  return inputCost + outputTokens * outputRate;
726
752
  }
753
+ var THINKING_BUDGETS = {
754
+ low: 1024,
755
+ medium: 5e3,
756
+ high: 1e4,
757
+ // 30000 (not 32000) to stay under the 32K max_tokens limit on Opus 4/4.1.
758
+ // With auto-bump (+1024), max_tokens becomes 31024 which fits all models.
759
+ max: 3e4
760
+ };
761
+ function thinkingToBudgetTokens(thinking) {
762
+ if (typeof thinking === "string") return THINKING_BUDGETS[thinking] ?? 5e3;
763
+ return thinking.budgetTokens;
764
+ }
765
+ function supportsAdaptiveThinking(model) {
766
+ return model.startsWith("claude-opus-4-6") || model.startsWith("claude-sonnet-4-6");
767
+ }
768
+ function supportsMaxEffort(model) {
769
+ return model.startsWith("claude-opus-4-6");
770
+ }
727
771
  var AnthropicProvider = class {
728
772
  name = "anthropic";
729
773
  baseUrl;
@@ -813,7 +857,7 @@ var AnthropicProvider = class {
813
857
  if (systemText) {
814
858
  body.system = systemText;
815
859
  }
816
- if (options.temperature !== void 0) {
860
+ if (options.temperature !== void 0 && !options.thinking) {
817
861
  body.temperature = options.temperature;
818
862
  }
819
863
  if (options.stop) {
@@ -822,6 +866,23 @@ var AnthropicProvider = class {
822
866
  if (options.tools && options.tools.length > 0) {
823
867
  body.tools = options.tools.map((t) => this.mapToolDefinition(t));
824
868
  }
869
+ if (options.toolChoice !== void 0) {
870
+ body.tool_choice = this.mapToolChoice(options.toolChoice);
871
+ }
872
+ if (options.thinking) {
873
+ if (typeof options.thinking === "string" && supportsAdaptiveThinking(options.model) && // 'max' effort is only supported on Opus 4.6; Sonnet 4.6 falls back to manual mode
874
+ (options.thinking !== "max" || supportsMaxEffort(options.model))) {
875
+ body.thinking = { type: "adaptive" };
876
+ body.output_config = { effort: options.thinking };
877
+ } else {
878
+ const budgetTokens = thinkingToBudgetTokens(options.thinking);
879
+ body.thinking = { type: "enabled", budget_tokens: budgetTokens };
880
+ const currentMax = body.max_tokens;
881
+ if (currentMax < budgetTokens + 1024) {
882
+ body.max_tokens = budgetTokens + 1024;
883
+ }
884
+ }
885
+ }
825
886
  if (options.responseFormat && options.responseFormat.type !== "text") {
826
887
  const jsonInstruction = "You must respond with valid JSON only. No markdown fences, no extra text.";
827
888
  body.system = body.system ? `${body.system}
@@ -917,6 +978,22 @@ ${jsonInstruction}` : jsonInstruction;
917
978
  input_schema: tool2.function.parameters
918
979
  };
919
980
  }
981
+ /**
982
+ * Map Axl's ToolChoice to Anthropic's tool_choice format.
983
+ *
984
+ * Axl (OpenAI format) → Anthropic format
985
+ * 'auto' → { type: 'auto' }
986
+ * 'none' → { type: 'none' }
987
+ * 'required' → { type: 'any' }
988
+ * { type:'function', function: { name } } → { type: 'tool', name }
989
+ */
990
+ mapToolChoice(choice) {
991
+ if (typeof choice === "string") {
992
+ if (choice === "required") return { type: "any" };
993
+ return { type: choice };
994
+ }
995
+ return { type: "tool", name: choice.function.name };
996
+ }
920
997
  // ---------------------------------------------------------------------------
921
998
  // Internal: response parsing
922
999
  // ---------------------------------------------------------------------------
@@ -1094,6 +1171,16 @@ function estimateGeminiCost(model, inputTokens, outputTokens, cachedTokens) {
1094
1171
  const inputCost = (inputTokens - cached) * inputRate + cached * inputRate * 0.1;
1095
1172
  return inputCost + outputTokens * outputRate;
1096
1173
  }
1174
+ var THINKING_BUDGETS2 = {
1175
+ low: 1024,
1176
+ medium: 5e3,
1177
+ high: 1e4,
1178
+ max: 24576
1179
+ };
1180
+ function thinkingToBudgetTokens2(thinking) {
1181
+ if (typeof thinking === "string") return THINKING_BUDGETS2[thinking] ?? 5e3;
1182
+ return thinking.budgetTokens;
1183
+ }
1097
1184
  var GeminiProvider = class {
1098
1185
  name = "google";
1099
1186
  baseUrl;
@@ -1207,6 +1294,17 @@ var GeminiProvider = class {
1207
1294
  if (Object.keys(generationConfig).length > 0) {
1208
1295
  body.generationConfig = generationConfig;
1209
1296
  }
1297
+ if (options.thinking) {
1298
+ generationConfig.thinkingConfig = {
1299
+ thinkingBudget: thinkingToBudgetTokens2(options.thinking)
1300
+ };
1301
+ if (!body.generationConfig) {
1302
+ body.generationConfig = generationConfig;
1303
+ }
1304
+ }
1305
+ if (options.toolChoice !== void 0) {
1306
+ body.toolConfig = { functionCallingConfig: this.mapToolChoice(options.toolChoice) };
1307
+ }
1210
1308
  return body;
1211
1309
  }
1212
1310
  /**
@@ -1298,6 +1396,25 @@ var GeminiProvider = class {
1298
1396
  }
1299
1397
  return merged;
1300
1398
  }
1399
+ /**
1400
+ * Map Axl's ToolChoice to Gemini's functionCallingConfig format.
1401
+ *
1402
+ * - 'auto' → { mode: 'AUTO' }
1403
+ * - 'none' → { mode: 'NONE' }
1404
+ * - 'required' → { mode: 'ANY' }
1405
+ * - { type: 'function', function: { name } } → { mode: 'ANY', allowedFunctionNames: [name] }
1406
+ */
1407
+ mapToolChoice(choice) {
1408
+ if (typeof choice === "string") {
1409
+ const modeMap = {
1410
+ auto: "AUTO",
1411
+ none: "NONE",
1412
+ required: "ANY"
1413
+ };
1414
+ return { mode: modeMap[choice] ?? "AUTO" };
1415
+ }
1416
+ return { mode: "ANY", allowedFunctionNames: [choice.function.name] };
1417
+ }
1301
1418
  mapToolDefinition(tool2) {
1302
1419
  return {
1303
1420
  name: tool2.function.name,
@@ -1880,7 +1997,13 @@ var WorkflowContext = class {
1880
1997
  model: agent2.resolveModel(resolveCtx),
1881
1998
  cost: costAfter - costBefore,
1882
1999
  duration: Date.now() - startTime,
1883
- promptVersion: agent2._config.version
2000
+ promptVersion: agent2._config.version,
2001
+ temperature: options?.temperature ?? agent2._config.temperature,
2002
+ maxTokens: options?.maxTokens ?? agent2._config.maxTokens ?? 4096,
2003
+ thinking: options?.thinking ?? agent2._config.thinking,
2004
+ reasoningEffort: options?.reasoningEffort ?? agent2._config.reasoningEffort,
2005
+ toolChoice: options?.toolChoice ?? agent2._config.toolChoice,
2006
+ stop: options?.stop ?? agent2._config.stop
1884
2007
  });
1885
2008
  return result;
1886
2009
  });
@@ -2005,11 +2128,21 @@ Please fix and try again.`;
2005
2128
  throw new TimeoutError("ctx.ask()", timeoutMs);
2006
2129
  }
2007
2130
  turns++;
2131
+ const thinking = options?.thinking ?? agent2._config.thinking;
2132
+ if (thinking && typeof thinking === "object" && thinking.budgetTokens <= 0) {
2133
+ throw new Error(
2134
+ `thinking.budgetTokens must be a positive number, got ${thinking.budgetTokens}`
2135
+ );
2136
+ }
2008
2137
  const chatOptions = {
2009
2138
  model,
2010
- temperature: agent2._config.temperature,
2139
+ temperature: options?.temperature ?? agent2._config.temperature,
2011
2140
  tools: toolDefs.length > 0 ? toolDefs : void 0,
2012
- maxTokens: 4096,
2141
+ maxTokens: options?.maxTokens ?? agent2._config.maxTokens ?? 4096,
2142
+ thinking,
2143
+ reasoningEffort: options?.reasoningEffort ?? agent2._config.reasoningEffort,
2144
+ toolChoice: options?.toolChoice ?? agent2._config.toolChoice,
2145
+ stop: options?.stop ?? agent2._config.stop,
2013
2146
  signal: this.currentSignal
2014
2147
  };
2015
2148
  if (options?.schema && toolDefs.length === 0) {
@@ -2108,10 +2241,11 @@ Please fix and try again.`;
2108
2241
  }
2109
2242
  }
2110
2243
  const handoffStart = Date.now();
2244
+ const handoffOptions = options ? { schema: options.schema, retries: options.retries, metadata: options.metadata } : void 0;
2111
2245
  const handoffFn = () => this.executeAgentCall(
2112
2246
  descriptor.agent,
2113
2247
  handoffPrompt,
2114
- options,
2248
+ handoffOptions,
2115
2249
  0,
2116
2250
  void 0,
2117
2251
  void 0,