@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.js CHANGED
@@ -2451,48 +2451,59 @@ function createMessages2(req) {
2451
2451
  case "system":
2452
2452
  return { role: "system", content: msg.content };
2453
2453
  case "user":
2454
- if (Array.isArray(msg.content)) {
2454
+ const content = Array.isArray(msg.content) ? msg.content.map((c) => {
2455
+ switch (c.type) {
2456
+ case "text":
2457
+ return { type: "text", text: c.text };
2458
+ case "image": {
2459
+ const url = `data:${c.mimeType};base64,` + c.image;
2460
+ return {
2461
+ type: "image_url",
2462
+ image_url: { url, details: c.details ?? "auto" }
2463
+ };
2464
+ }
2465
+ case "audio": {
2466
+ const data = c.data;
2467
+ return {
2468
+ type: "input_audio",
2469
+ input_audio: { data, format: c.format ?? "wav" }
2470
+ };
2471
+ }
2472
+ default:
2473
+ throw new Error("Invalid content type");
2474
+ }
2475
+ }) : msg.content;
2476
+ return {
2477
+ role: "user",
2478
+ ...msg.name ? { name: msg.name } : {},
2479
+ content
2480
+ };
2481
+ case "assistant":
2482
+ const toolCalls = msg.functionCalls?.map((v) => ({
2483
+ id: v.id,
2484
+ type: "function",
2485
+ function: {
2486
+ name: v.function.name,
2487
+ arguments: typeof v.function.params === "object" ? JSON.stringify(v.function.params) : v.function.params
2488
+ }
2489
+ }));
2490
+ if (toolCalls && toolCalls.length > 0) {
2455
2491
  return {
2456
- role: "user",
2492
+ role: "assistant",
2493
+ ...msg.content ? { content: msg.content } : {},
2457
2494
  name: msg.name,
2458
- content: msg.content.map((c) => {
2459
- switch (c.type) {
2460
- case "text":
2461
- return { type: "text", text: c.text };
2462
- case "image": {
2463
- const url = `data:${c.mimeType};base64,` + c.image;
2464
- return {
2465
- type: "image_url",
2466
- image_url: { url, details: c.details ?? "auto" }
2467
- };
2468
- }
2469
- case "audio": {
2470
- const data = c.data;
2471
- return {
2472
- type: "input_audio",
2473
- input_audio: { data, format: c.format ?? "wav" }
2474
- };
2475
- }
2476
- default:
2477
- throw new Error("Invalid content type");
2478
- }
2479
- })
2495
+ tool_calls: toolCalls
2480
2496
  };
2481
2497
  }
2482
- return { role: "user", content: msg.content, name: msg.name };
2483
- case "assistant":
2498
+ if (!msg.content) {
2499
+ throw new Error(
2500
+ "Assistant content is required when no tool calls are provided"
2501
+ );
2502
+ }
2484
2503
  return {
2485
2504
  role: "assistant",
2486
2505
  content: msg.content,
2487
- name: msg.name,
2488
- tool_calls: msg.functionCalls?.map((v) => ({
2489
- id: v.id,
2490
- type: "function",
2491
- function: {
2492
- name: v.function.name,
2493
- arguments: typeof v.function.params === "object" ? JSON.stringify(v.function.params) : v.function.params
2494
- }
2495
- }))
2506
+ ...msg.name ? { name: msg.name } : {}
2496
2507
  };
2497
2508
  case "function":
2498
2509
  return {
@@ -3328,7 +3339,7 @@ var AxAIGoogleGeminiImpl = class {
3328
3339
  }
3329
3340
  ];
3330
3341
  return {
3331
- role: "model",
3342
+ role: "user",
3332
3343
  parts
3333
3344
  };
3334
3345
  }
@@ -4051,8 +4062,11 @@ var AxAIMistral = class extends AxAIOpenAIBase {
4051
4062
  for (const message of messages) {
4052
4063
  if (message.role === "user" && Array.isArray(message.content)) {
4053
4064
  const contentUpdated = message.content.map((item) => {
4054
- if (typeof item === "object" && item !== null && item.type === "image_url") {
4055
- return { type: "image_url", image_url: item.image_url?.url };
4065
+ if (typeof item === "object" && item !== null && "image_url" in item) {
4066
+ return {
4067
+ type: "image_url",
4068
+ image_url: { url: item.image_url?.url }
4069
+ };
4056
4070
  }
4057
4071
  return item;
4058
4072
  });
@@ -4725,8 +4739,6 @@ var AxAIOpenAIResponsesImpl = class {
4725
4739
  baseResult.content = event.delta;
4726
4740
  break;
4727
4741
  case "response.output_text.done":
4728
- baseResult.id = event.item_id;
4729
- baseResult.content = event.text;
4730
4742
  break;
4731
4743
  case "response.function_call_arguments.delta":
4732
4744
  baseResult.id = event.item_id;
@@ -5549,9 +5561,6 @@ var MemoryImpl = class {
5549
5561
  functionCalls
5550
5562
  }) {
5551
5563
  const isContentEmpty = typeof content === "string" && content.trim() === "";
5552
- if (isContentEmpty && (!functionCalls || functionCalls.length === 0)) {
5553
- return;
5554
- }
5555
5564
  if (isContentEmpty) {
5556
5565
  this.addMemory({ name, role: "assistant", functionCalls });
5557
5566
  } else {
@@ -5576,17 +5585,16 @@ var MemoryImpl = class {
5576
5585
  }) {
5577
5586
  const lastItem = this.data.at(-1);
5578
5587
  if (!lastItem || lastItem.chat.role !== "assistant") {
5579
- this.addResultMessage({ content, name, functionCalls });
5580
- } else {
5581
- if ("content" in lastItem.chat && typeof content === "string" && content.trim() !== "") {
5582
- lastItem.chat.content = content;
5583
- }
5584
- if ("name" in lastItem.chat && name) {
5585
- lastItem.chat.name = name;
5586
- }
5587
- if ("functionCalls" in lastItem.chat && functionCalls) {
5588
- lastItem.chat.functionCalls = functionCalls;
5589
- }
5588
+ throw new Error("No assistant message to update");
5589
+ }
5590
+ if (typeof content === "string" && content.trim() !== "") {
5591
+ lastItem.chat.content = content;
5592
+ }
5593
+ if (name && name.trim() !== "") {
5594
+ lastItem.chat.name = name;
5595
+ }
5596
+ if (functionCalls && functionCalls.length > 0) {
5597
+ lastItem.chat.functionCalls = functionCalls;
5590
5598
  }
5591
5599
  if (this.options?.debug) {
5592
5600
  if (delta && typeof delta === "string") {
@@ -6116,6 +6124,12 @@ ${outputFields}`);
6116
6124
  text: task.join("\n\n")
6117
6125
  };
6118
6126
  }
6127
+ renderSingleValueUserContent = (values, renderedExamples, renderedDemos, examplesInSystemPrompt) => {
6128
+ const completion = this.renderInputFields(values);
6129
+ const promptList = examplesInSystemPrompt ? completion : [...renderedExamples, ...renderedDemos, ...completion];
6130
+ const prompt = promptList.filter((v) => v !== void 0);
6131
+ return prompt.every((v) => v.type === "text") ? prompt.map((v) => v.text).join("\n") : prompt.reduce(combineConsecutiveStrings("\n"), []);
6132
+ };
6119
6133
  render = (values, {
6120
6134
  examples,
6121
6135
  demos
@@ -6144,60 +6158,49 @@ ${outputFields}`);
6144
6158
  role: "system",
6145
6159
  content: systemContent
6146
6160
  };
6147
- let userMessages = [];
6148
6161
  if (Array.isArray(values)) {
6162
+ let userMessages = [];
6149
6163
  const history = values;
6150
- let lastRole = void 0;
6151
- for (const message of history) {
6152
- let messageContent = "";
6153
- if (message.role === "user") {
6154
- const userMsgParts = this.renderInputFields(
6155
- message.values
6156
- // Cast message.values (AxGenIn) to T (which extends AxGenIn)
6164
+ for (const [index, message] of history.entries()) {
6165
+ let content;
6166
+ if (index === 0) {
6167
+ content = this.renderSingleValueUserContent(
6168
+ message.values,
6169
+ renderedExamples,
6170
+ renderedDemos,
6171
+ examplesInSystemPrompt
6157
6172
  );
6158
- messageContent = userMsgParts.map((part) => part.type === "text" ? part.text : "").join("").trim();
6159
- } else if (message.role === "assistant") {
6160
- const assistantMsgParts = this.renderInputFields(
6161
- message.values
6162
- // Cast message.values (AxGenIn) to T (which extends AxGenIn)
6173
+ } else {
6174
+ content = this.renderSingleValueUserContent(
6175
+ message.values,
6176
+ [],
6177
+ [],
6178
+ false
6163
6179
  );
6164
- messageContent = assistantMsgParts.map((part) => part.type === "text" ? part.text : "").join("").trim();
6165
6180
  }
6166
- if (messageContent) {
6167
- if (lastRole === message.role && userMessages.length > 0) {
6168
- const lastMessage = userMessages[userMessages.length - 1];
6169
- if (lastMessage) {
6170
- lastMessage.content += "\n" + messageContent;
6171
- }
6172
- } else {
6173
- if (message.role === "user") {
6174
- userMessages.push({ role: "user", content: messageContent });
6175
- } else if (message.role === "assistant") {
6176
- userMessages.push({ role: "assistant", content: messageContent });
6177
- }
6178
- }
6179
- lastRole = message.role;
6181
+ if (message.role === "user") {
6182
+ userMessages.push({ role: "user", content });
6183
+ continue;
6180
6184
  }
6185
+ if (message.role !== "assistant") {
6186
+ throw new Error("Invalid message role");
6187
+ }
6188
+ if (typeof content !== "string") {
6189
+ throw new Error(
6190
+ "Assistant message cannot contain non-text content like images, files,etc"
6191
+ );
6192
+ }
6193
+ userMessages.push({ role: "assistant", content });
6181
6194
  }
6182
- } else {
6183
- const currentValues = values;
6184
- const completion = this.renderInputFields(currentValues);
6185
- const promptList = examplesInSystemPrompt ? completion : [...renderedExamples, ...renderedDemos, ...completion];
6186
- const promptFilter = promptList.filter((v) => v !== void 0);
6187
- let userContent;
6188
- if (promptFilter.every((v) => v.type === "text")) {
6189
- userContent = promptFilter.map((v) => v.text).join("\n");
6190
- } else {
6191
- userContent = promptFilter.map((part) => {
6192
- if (part.type === "text") return part.text;
6193
- if (part.type === "image") return "[IMAGE]";
6194
- if (part.type === "audio") return "[AUDIO]";
6195
- return "";
6196
- }).join("\n").trim();
6197
- }
6198
- userMessages.push({ role: "user", content: userContent });
6195
+ return [systemPrompt, ...userMessages];
6199
6196
  }
6200
- return [systemPrompt, ...userMessages];
6197
+ const userContent = this.renderSingleValueUserContent(
6198
+ values,
6199
+ renderedExamples,
6200
+ renderedDemos,
6201
+ examplesInSystemPrompt
6202
+ );
6203
+ return [systemPrompt, { role: "user", content: userContent }];
6201
6204
  };
6202
6205
  renderExtraFields = (extraFields) => {
6203
6206
  const prompt = [];
@@ -6264,9 +6267,6 @@ ${outputFields}`);
6264
6267
  if ("text" in v) {
6265
6268
  v.text = v.text + "\n";
6266
6269
  }
6267
- if ("image" in v) {
6268
- v.image = v.image;
6269
- }
6270
6270
  list.push(v);
6271
6271
  });
6272
6272
  }
@@ -6297,9 +6297,6 @@ ${outputFields}`);
6297
6297
  if ("text" in v) {
6298
6298
  v.text = v.text + "\n";
6299
6299
  }
6300
- if ("image" in v) {
6301
- v.image = v.image;
6302
- }
6303
6300
  list.push(v);
6304
6301
  });
6305
6302
  }
@@ -8061,11 +8058,41 @@ var AxSignature = class _AxSignature {
8061
8058
  if (signature.validatedAtHash === this.sigHash) {
8062
8059
  this.validatedAtHash = this.sigHash;
8063
8060
  }
8061
+ } else if (typeof signature === "object" && signature !== null) {
8062
+ if (!("inputs" in signature) || !("outputs" in signature)) {
8063
+ throw new AxSignatureValidationError(
8064
+ "Invalid signature object: missing inputs or outputs",
8065
+ void 0,
8066
+ 'Signature object must have "inputs" and "outputs" arrays. Example: { inputs: [...], outputs: [...] }'
8067
+ );
8068
+ }
8069
+ if (!Array.isArray(signature.inputs) || !Array.isArray(signature.outputs)) {
8070
+ throw new AxSignatureValidationError(
8071
+ "Invalid signature object: inputs and outputs must be arrays",
8072
+ void 0,
8073
+ 'Both "inputs" and "outputs" must be arrays of AxField objects'
8074
+ );
8075
+ }
8076
+ try {
8077
+ this.description = signature.description;
8078
+ this.inputFields = signature.inputs.map((v) => this.parseField(v));
8079
+ this.outputFields = signature.outputs.map((v) => this.parseField(v));
8080
+ [this.sigHash, this.sigString] = this.updateHash();
8081
+ } catch (error) {
8082
+ if (error instanceof AxSignatureValidationError) {
8083
+ throw error;
8084
+ }
8085
+ throw new AxSignatureValidationError(
8086
+ `Failed to create signature from object: ${error instanceof Error ? error.message : "Unknown error"}`,
8087
+ void 0,
8088
+ "Check that all fields in inputs and outputs arrays are valid AxField objects"
8089
+ );
8090
+ }
8064
8091
  } else {
8065
8092
  throw new AxSignatureValidationError(
8066
8093
  "Invalid signature argument type",
8067
8094
  void 0,
8068
- "Signature must be a string or another AxSignature instance"
8095
+ "Signature must be a string, another AxSignature instance, or an object with inputs and outputs arrays"
8069
8096
  );
8070
8097
  }
8071
8098
  }
@@ -8108,7 +8135,7 @@ var AxSignature = class _AxSignature {
8108
8135
  }
8109
8136
  this.description = desc;
8110
8137
  this.invalidateValidationCache();
8111
- this.updateHash();
8138
+ this.updateHashLight();
8112
8139
  };
8113
8140
  addInputField = (field) => {
8114
8141
  try {
@@ -8784,11 +8811,9 @@ var AxGen = class extends AxProgramWithSignature {
8784
8811
  values = {};
8785
8812
  excludeContentFromTrace = false;
8786
8813
  thoughtFieldName;
8787
- logger;
8788
8814
  constructor(signature, options) {
8789
8815
  super(signature, { description: options?.description });
8790
8816
  this.options = options;
8791
- this.logger = options?.logger;
8792
8817
  this.thoughtFieldName = options?.thoughtFieldName ?? "thought";
8793
8818
  const promptTemplateOptions = {
8794
8819
  functions: options?.functions,
@@ -8878,6 +8903,7 @@ var AxGen = class extends AxProgramWithSignature {
8878
8903
  rateLimiter,
8879
8904
  stream,
8880
8905
  debug: false,
8906
+ // we do our own debug logging
8881
8907
  thinkingTokenBudget,
8882
8908
  showThoughts,
8883
8909
  traceContext,
@@ -8917,6 +8943,7 @@ var AxGen = class extends AxProgramWithSignature {
8917
8943
  fastFail,
8918
8944
  span
8919
8945
  });
8946
+ this.getLogger(ai, options)?.("", { tags: ["responseEnd"] });
8920
8947
  } else {
8921
8948
  yield await this.processResponse({
8922
8949
  ai,
@@ -8950,6 +8977,13 @@ var AxGen = class extends AxProgramWithSignature {
8950
8977
  s: -1
8951
8978
  };
8952
8979
  let content = "";
8980
+ mem.addResult(
8981
+ {
8982
+ content: "",
8983
+ functionCalls: []
8984
+ },
8985
+ sessionId
8986
+ );
8953
8987
  for await (const v of res) {
8954
8988
  const result = v.results[0];
8955
8989
  if (!result) {
@@ -9078,10 +9112,6 @@ Content: ${content}`
9078
9112
  xstate
9079
9113
  );
9080
9114
  }
9081
- if (ai.getOptions().debug) {
9082
- const logger = ai.getLogger();
9083
- logger("", { tags: ["responseEnd"] });
9084
- }
9085
9115
  }
9086
9116
  async processResponse({
9087
9117
  ai,
@@ -9153,9 +9183,11 @@ Content: ${result.content}`
9153
9183
  const stopFunction = (options?.stopFunction ?? this.options?.stopFunction)?.toLowerCase();
9154
9184
  const maxRetries = options.maxRetries ?? this.options?.maxRetries ?? 10;
9155
9185
  const maxSteps = options.maxSteps ?? this.options?.maxSteps ?? 10;
9156
- const debug = options.debug ?? ai.getOptions().debug;
9157
9186
  const debugHideSystemPrompt = options.debugHideSystemPrompt;
9158
- const memOptions = { debug, debugHideSystemPrompt };
9187
+ const memOptions = {
9188
+ debug: this.isDebug(ai, options),
9189
+ debugHideSystemPrompt
9190
+ };
9159
9191
  const mem = options.mem ?? this.options?.mem ?? new AxMemory(1e4, memOptions);
9160
9192
  let err;
9161
9193
  if (options?.functions && options.functions.length > 0) {
@@ -9209,10 +9241,7 @@ Content: ${result.content}`
9209
9241
  if (shouldContinue) {
9210
9242
  continue multiStepLoop;
9211
9243
  }
9212
- if (debug) {
9213
- const logger = options.logger ?? this.logger ?? ai.getLogger();
9214
- logger("", { tags: ["responseEnd"] });
9215
- }
9244
+ this.getLogger(ai, options)?.("", { tags: ["responseEnd"] });
9216
9245
  return;
9217
9246
  } catch (e) {
9218
9247
  let errorFields;
@@ -9354,6 +9383,12 @@ Content: ${result.content}`
9354
9383
  setExamples(examples, options) {
9355
9384
  super.setExamples(examples, options);
9356
9385
  }
9386
+ isDebug(ai, options) {
9387
+ return options?.debug ?? this.options?.debug ?? ai.getOptions().debug ?? false;
9388
+ }
9389
+ getLogger(ai, options) {
9390
+ return options?.logger ?? this.options?.logger ?? ai.getLogger();
9391
+ }
9357
9392
  };
9358
9393
  var AxGenerateError = class extends Error {
9359
9394
  details;