@ax-llm/ax 12.0.5 → 12.0.7

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/index.cjs CHANGED
@@ -2623,48 +2623,59 @@ function createMessages2(req) {
2623
2623
  case "system":
2624
2624
  return { role: "system", content: msg.content };
2625
2625
  case "user":
2626
- if (Array.isArray(msg.content)) {
2626
+ const content = Array.isArray(msg.content) ? msg.content.map((c) => {
2627
+ switch (c.type) {
2628
+ case "text":
2629
+ return { type: "text", text: c.text };
2630
+ case "image": {
2631
+ const url = `data:${c.mimeType};base64,` + c.image;
2632
+ return {
2633
+ type: "image_url",
2634
+ image_url: { url, details: c.details ?? "auto" }
2635
+ };
2636
+ }
2637
+ case "audio": {
2638
+ const data = c.data;
2639
+ return {
2640
+ type: "input_audio",
2641
+ input_audio: { data, format: c.format ?? "wav" }
2642
+ };
2643
+ }
2644
+ default:
2645
+ throw new Error("Invalid content type");
2646
+ }
2647
+ }) : msg.content;
2648
+ return {
2649
+ role: "user",
2650
+ ...msg.name ? { name: msg.name } : {},
2651
+ content
2652
+ };
2653
+ case "assistant":
2654
+ const toolCalls = msg.functionCalls?.map((v) => ({
2655
+ id: v.id,
2656
+ type: "function",
2657
+ function: {
2658
+ name: v.function.name,
2659
+ arguments: typeof v.function.params === "object" ? JSON.stringify(v.function.params) : v.function.params
2660
+ }
2661
+ }));
2662
+ if (toolCalls && toolCalls.length > 0) {
2627
2663
  return {
2628
- role: "user",
2664
+ role: "assistant",
2665
+ ...msg.content ? { content: msg.content } : {},
2629
2666
  name: msg.name,
2630
- content: msg.content.map((c) => {
2631
- switch (c.type) {
2632
- case "text":
2633
- return { type: "text", text: c.text };
2634
- case "image": {
2635
- const url = `data:${c.mimeType};base64,` + c.image;
2636
- return {
2637
- type: "image_url",
2638
- image_url: { url, details: c.details ?? "auto" }
2639
- };
2640
- }
2641
- case "audio": {
2642
- const data = c.data;
2643
- return {
2644
- type: "input_audio",
2645
- input_audio: { data, format: c.format ?? "wav" }
2646
- };
2647
- }
2648
- default:
2649
- throw new Error("Invalid content type");
2650
- }
2651
- })
2667
+ tool_calls: toolCalls
2652
2668
  };
2653
2669
  }
2654
- return { role: "user", content: msg.content, name: msg.name };
2655
- case "assistant":
2670
+ if (!msg.content) {
2671
+ throw new Error(
2672
+ "Assistant content is required when no tool calls are provided"
2673
+ );
2674
+ }
2656
2675
  return {
2657
2676
  role: "assistant",
2658
2677
  content: msg.content,
2659
- name: msg.name,
2660
- tool_calls: msg.functionCalls?.map((v) => ({
2661
- id: v.id,
2662
- type: "function",
2663
- function: {
2664
- name: v.function.name,
2665
- arguments: typeof v.function.params === "object" ? JSON.stringify(v.function.params) : v.function.params
2666
- }
2667
- }))
2678
+ ...msg.name ? { name: msg.name } : {}
2668
2679
  };
2669
2680
  case "function":
2670
2681
  return {
@@ -3500,7 +3511,7 @@ var AxAIGoogleGeminiImpl = class {
3500
3511
  }
3501
3512
  ];
3502
3513
  return {
3503
- role: "model",
3514
+ role: "user",
3504
3515
  parts
3505
3516
  };
3506
3517
  }
@@ -4223,8 +4234,11 @@ var AxAIMistral = class extends AxAIOpenAIBase {
4223
4234
  for (const message of messages) {
4224
4235
  if (message.role === "user" && Array.isArray(message.content)) {
4225
4236
  const contentUpdated = message.content.map((item) => {
4226
- if (typeof item === "object" && item !== null && item.type === "image_url") {
4227
- return { type: "image_url", image_url: item.image_url?.url };
4237
+ if (typeof item === "object" && item !== null && "image_url" in item) {
4238
+ return {
4239
+ type: "image_url",
4240
+ image_url: { url: item.image_url?.url }
4241
+ };
4228
4242
  }
4229
4243
  return item;
4230
4244
  });
@@ -4897,8 +4911,6 @@ var AxAIOpenAIResponsesImpl = class {
4897
4911
  baseResult.content = event.delta;
4898
4912
  break;
4899
4913
  case "response.output_text.done":
4900
- baseResult.id = event.item_id;
4901
- baseResult.content = event.text;
4902
4914
  break;
4903
4915
  case "response.function_call_arguments.delta":
4904
4916
  baseResult.id = event.item_id;
@@ -5717,9 +5729,6 @@ var MemoryImpl = class {
5717
5729
  functionCalls
5718
5730
  }) {
5719
5731
  const isContentEmpty = typeof content === "string" && content.trim() === "";
5720
- if (isContentEmpty && (!functionCalls || functionCalls.length === 0)) {
5721
- return;
5722
- }
5723
5732
  if (isContentEmpty) {
5724
5733
  this.addMemory({ name, role: "assistant", functionCalls });
5725
5734
  } else {
@@ -5744,17 +5753,16 @@ var MemoryImpl = class {
5744
5753
  }) {
5745
5754
  const lastItem = this.data.at(-1);
5746
5755
  if (!lastItem || lastItem.chat.role !== "assistant") {
5747
- this.addResultMessage({ content, name, functionCalls });
5748
- } else {
5749
- if ("content" in lastItem.chat && typeof content === "string" && content.trim() !== "") {
5750
- lastItem.chat.content = content;
5751
- }
5752
- if ("name" in lastItem.chat && name) {
5753
- lastItem.chat.name = name;
5754
- }
5755
- if ("functionCalls" in lastItem.chat && functionCalls) {
5756
- lastItem.chat.functionCalls = functionCalls;
5757
- }
5756
+ throw new Error("No assistant message to update");
5757
+ }
5758
+ if (typeof content === "string" && content.trim() !== "") {
5759
+ lastItem.chat.content = content;
5760
+ }
5761
+ if (name && name.trim() !== "") {
5762
+ lastItem.chat.name = name;
5763
+ }
5764
+ if (functionCalls && functionCalls.length > 0) {
5765
+ lastItem.chat.functionCalls = functionCalls;
5758
5766
  }
5759
5767
  if (this.options?.debug) {
5760
5768
  if (delta && typeof delta === "string") {
@@ -6284,6 +6292,12 @@ ${outputFields}`);
6284
6292
  text: task.join("\n\n")
6285
6293
  };
6286
6294
  }
6295
+ renderSingleValueUserContent = (values, renderedExamples, renderedDemos, examplesInSystemPrompt) => {
6296
+ const completion = this.renderInputFields(values);
6297
+ const promptList = examplesInSystemPrompt ? completion : [...renderedExamples, ...renderedDemos, ...completion];
6298
+ const prompt = promptList.filter((v) => v !== void 0);
6299
+ return prompt.every((v) => v.type === "text") ? prompt.map((v) => v.text).join("\n") : prompt.reduce(combineConsecutiveStrings("\n"), []);
6300
+ };
6287
6301
  render = (values, {
6288
6302
  examples,
6289
6303
  demos
@@ -6312,60 +6326,49 @@ ${outputFields}`);
6312
6326
  role: "system",
6313
6327
  content: systemContent
6314
6328
  };
6315
- let userMessages = [];
6316
6329
  if (Array.isArray(values)) {
6330
+ let userMessages = [];
6317
6331
  const history = values;
6318
- let lastRole = void 0;
6319
- for (const message of history) {
6320
- let messageContent = "";
6321
- if (message.role === "user") {
6322
- const userMsgParts = this.renderInputFields(
6323
- message.values
6324
- // Cast message.values (AxGenIn) to T (which extends AxGenIn)
6332
+ for (const [index, message] of history.entries()) {
6333
+ let content;
6334
+ if (index === 0) {
6335
+ content = this.renderSingleValueUserContent(
6336
+ message.values,
6337
+ renderedExamples,
6338
+ renderedDemos,
6339
+ examplesInSystemPrompt
6325
6340
  );
6326
- messageContent = userMsgParts.map((part) => part.type === "text" ? part.text : "").join("").trim();
6327
- } else if (message.role === "assistant") {
6328
- const assistantMsgParts = this.renderInputFields(
6329
- message.values
6330
- // Cast message.values (AxGenIn) to T (which extends AxGenIn)
6341
+ } else {
6342
+ content = this.renderSingleValueUserContent(
6343
+ message.values,
6344
+ [],
6345
+ [],
6346
+ false
6331
6347
  );
6332
- messageContent = assistantMsgParts.map((part) => part.type === "text" ? part.text : "").join("").trim();
6333
6348
  }
6334
- if (messageContent) {
6335
- if (lastRole === message.role && userMessages.length > 0) {
6336
- const lastMessage = userMessages[userMessages.length - 1];
6337
- if (lastMessage) {
6338
- lastMessage.content += "\n" + messageContent;
6339
- }
6340
- } else {
6341
- if (message.role === "user") {
6342
- userMessages.push({ role: "user", content: messageContent });
6343
- } else if (message.role === "assistant") {
6344
- userMessages.push({ role: "assistant", content: messageContent });
6345
- }
6346
- }
6347
- lastRole = message.role;
6349
+ if (message.role === "user") {
6350
+ userMessages.push({ role: "user", content });
6351
+ continue;
6348
6352
  }
6353
+ if (message.role !== "assistant") {
6354
+ throw new Error("Invalid message role");
6355
+ }
6356
+ if (typeof content !== "string") {
6357
+ throw new Error(
6358
+ "Assistant message cannot contain non-text content like images, files,etc"
6359
+ );
6360
+ }
6361
+ userMessages.push({ role: "assistant", content });
6349
6362
  }
6350
- } else {
6351
- const currentValues = values;
6352
- const completion = this.renderInputFields(currentValues);
6353
- const promptList = examplesInSystemPrompt ? completion : [...renderedExamples, ...renderedDemos, ...completion];
6354
- const promptFilter = promptList.filter((v) => v !== void 0);
6355
- let userContent;
6356
- if (promptFilter.every((v) => v.type === "text")) {
6357
- userContent = promptFilter.map((v) => v.text).join("\n");
6358
- } else {
6359
- userContent = promptFilter.map((part) => {
6360
- if (part.type === "text") return part.text;
6361
- if (part.type === "image") return "[IMAGE]";
6362
- if (part.type === "audio") return "[AUDIO]";
6363
- return "";
6364
- }).join("\n").trim();
6365
- }
6366
- userMessages.push({ role: "user", content: userContent });
6363
+ return [systemPrompt, ...userMessages];
6367
6364
  }
6368
- return [systemPrompt, ...userMessages];
6365
+ const userContent = this.renderSingleValueUserContent(
6366
+ values,
6367
+ renderedExamples,
6368
+ renderedDemos,
6369
+ examplesInSystemPrompt
6370
+ );
6371
+ return [systemPrompt, { role: "user", content: userContent }];
6369
6372
  };
6370
6373
  renderExtraFields = (extraFields) => {
6371
6374
  const prompt = [];
@@ -6432,9 +6435,6 @@ ${outputFields}`);
6432
6435
  if ("text" in v) {
6433
6436
  v.text = v.text + "\n";
6434
6437
  }
6435
- if ("image" in v) {
6436
- v.image = v.image;
6437
- }
6438
6438
  list.push(v);
6439
6439
  });
6440
6440
  }
@@ -6465,9 +6465,6 @@ ${outputFields}`);
6465
6465
  if ("text" in v) {
6466
6466
  v.text = v.text + "\n";
6467
6467
  }
6468
- if ("image" in v) {
6469
- v.image = v.image;
6470
- }
6471
6468
  list.push(v);
6472
6469
  });
6473
6470
  }
@@ -8229,11 +8226,41 @@ var AxSignature = class _AxSignature {
8229
8226
  if (signature.validatedAtHash === this.sigHash) {
8230
8227
  this.validatedAtHash = this.sigHash;
8231
8228
  }
8229
+ } else if (typeof signature === "object" && signature !== null) {
8230
+ if (!("inputs" in signature) || !("outputs" in signature)) {
8231
+ throw new AxSignatureValidationError(
8232
+ "Invalid signature object: missing inputs or outputs",
8233
+ void 0,
8234
+ 'Signature object must have "inputs" and "outputs" arrays. Example: { inputs: [...], outputs: [...] }'
8235
+ );
8236
+ }
8237
+ if (!Array.isArray(signature.inputs) || !Array.isArray(signature.outputs)) {
8238
+ throw new AxSignatureValidationError(
8239
+ "Invalid signature object: inputs and outputs must be arrays",
8240
+ void 0,
8241
+ 'Both "inputs" and "outputs" must be arrays of AxField objects'
8242
+ );
8243
+ }
8244
+ try {
8245
+ this.description = signature.description;
8246
+ this.inputFields = signature.inputs.map((v) => this.parseField(v));
8247
+ this.outputFields = signature.outputs.map((v) => this.parseField(v));
8248
+ [this.sigHash, this.sigString] = this.updateHash();
8249
+ } catch (error) {
8250
+ if (error instanceof AxSignatureValidationError) {
8251
+ throw error;
8252
+ }
8253
+ throw new AxSignatureValidationError(
8254
+ `Failed to create signature from object: ${error instanceof Error ? error.message : "Unknown error"}`,
8255
+ void 0,
8256
+ "Check that all fields in inputs and outputs arrays are valid AxField objects"
8257
+ );
8258
+ }
8232
8259
  } else {
8233
8260
  throw new AxSignatureValidationError(
8234
8261
  "Invalid signature argument type",
8235
8262
  void 0,
8236
- "Signature must be a string or another AxSignature instance"
8263
+ "Signature must be a string, another AxSignature instance, or an object with inputs and outputs arrays"
8237
8264
  );
8238
8265
  }
8239
8266
  }
@@ -8276,7 +8303,7 @@ var AxSignature = class _AxSignature {
8276
8303
  }
8277
8304
  this.description = desc;
8278
8305
  this.invalidateValidationCache();
8279
- this.updateHash();
8306
+ this.updateHashLight();
8280
8307
  };
8281
8308
  addInputField = (field) => {
8282
8309
  try {
@@ -8952,11 +8979,9 @@ var AxGen = class extends AxProgramWithSignature {
8952
8979
  values = {};
8953
8980
  excludeContentFromTrace = false;
8954
8981
  thoughtFieldName;
8955
- logger;
8956
8982
  constructor(signature, options) {
8957
8983
  super(signature, { description: options?.description });
8958
8984
  this.options = options;
8959
- this.logger = options?.logger;
8960
8985
  this.thoughtFieldName = options?.thoughtFieldName ?? "thought";
8961
8986
  const promptTemplateOptions = {
8962
8987
  functions: options?.functions,
@@ -9046,6 +9071,7 @@ var AxGen = class extends AxProgramWithSignature {
9046
9071
  rateLimiter,
9047
9072
  stream,
9048
9073
  debug: false,
9074
+ // we do our own debug logging
9049
9075
  thinkingTokenBudget,
9050
9076
  showThoughts,
9051
9077
  traceContext,
@@ -9085,6 +9111,7 @@ var AxGen = class extends AxProgramWithSignature {
9085
9111
  fastFail,
9086
9112
  span
9087
9113
  });
9114
+ this.getLogger(ai, options)?.("", { tags: ["responseEnd"] });
9088
9115
  } else {
9089
9116
  yield await this.processResponse({
9090
9117
  ai,
@@ -9118,6 +9145,13 @@ var AxGen = class extends AxProgramWithSignature {
9118
9145
  s: -1
9119
9146
  };
9120
9147
  let content = "";
9148
+ mem.addResult(
9149
+ {
9150
+ content: "",
9151
+ functionCalls: []
9152
+ },
9153
+ sessionId
9154
+ );
9121
9155
  for await (const v of res) {
9122
9156
  const result = v.results[0];
9123
9157
  if (!result) {
@@ -9246,10 +9280,6 @@ Content: ${content}`
9246
9280
  xstate
9247
9281
  );
9248
9282
  }
9249
- if (ai.getOptions().debug) {
9250
- const logger = ai.getLogger();
9251
- logger("", { tags: ["responseEnd"] });
9252
- }
9253
9283
  }
9254
9284
  async processResponse({
9255
9285
  ai,
@@ -9321,9 +9351,11 @@ Content: ${result.content}`
9321
9351
  const stopFunction = (options?.stopFunction ?? this.options?.stopFunction)?.toLowerCase();
9322
9352
  const maxRetries = options.maxRetries ?? this.options?.maxRetries ?? 10;
9323
9353
  const maxSteps = options.maxSteps ?? this.options?.maxSteps ?? 10;
9324
- const debug = options.debug ?? ai.getOptions().debug;
9325
9354
  const debugHideSystemPrompt = options.debugHideSystemPrompt;
9326
- const memOptions = { debug, debugHideSystemPrompt };
9355
+ const memOptions = {
9356
+ debug: this.isDebug(ai, options),
9357
+ debugHideSystemPrompt
9358
+ };
9327
9359
  const mem = options.mem ?? this.options?.mem ?? new AxMemory(1e4, memOptions);
9328
9360
  let err;
9329
9361
  if (options?.functions && options.functions.length > 0) {
@@ -9377,10 +9409,7 @@ Content: ${result.content}`
9377
9409
  if (shouldContinue) {
9378
9410
  continue multiStepLoop;
9379
9411
  }
9380
- if (debug) {
9381
- const logger = options.logger ?? this.logger ?? ai.getLogger();
9382
- logger("", { tags: ["responseEnd"] });
9383
- }
9412
+ this.getLogger(ai, options)?.("", { tags: ["responseEnd"] });
9384
9413
  return;
9385
9414
  } catch (e) {
9386
9415
  let errorFields;
@@ -9522,6 +9551,12 @@ Content: ${result.content}`
9522
9551
  setExamples(examples, options) {
9523
9552
  super.setExamples(examples, options);
9524
9553
  }
9554
+ isDebug(ai, options) {
9555
+ return options?.debug ?? this.options?.debug ?? ai.getOptions().debug ?? false;
9556
+ }
9557
+ getLogger(ai, options) {
9558
+ return options?.logger ?? this.options?.logger ?? ai.getLogger();
9559
+ }
9525
9560
  };
9526
9561
  var AxGenerateError = class extends Error {
9527
9562
  details;