@ax-llm/ax 12.0.1 → 12.0.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/index.cjs CHANGED
@@ -5659,10 +5659,15 @@ var MemoryImpl = class {
5659
5659
  name,
5660
5660
  functionCalls
5661
5661
  }) {
5662
- if (!content && (!functionCalls || functionCalls.length === 0)) {
5662
+ const isContentEmpty = typeof content === "string" && content.trim() === "";
5663
+ if (isContentEmpty && (!functionCalls || functionCalls.length === 0)) {
5663
5664
  return;
5664
5665
  }
5665
- this.addMemory({ content, name, role: "assistant", functionCalls });
5666
+ if (isContentEmpty) {
5667
+ this.addMemory({ name, role: "assistant", functionCalls });
5668
+ } else {
5669
+ this.addMemory({ content, name, role: "assistant", functionCalls });
5670
+ }
5666
5671
  }
5667
5672
  addResult({
5668
5673
  content,
@@ -5684,7 +5689,7 @@ var MemoryImpl = class {
5684
5689
  if (!lastItem || lastItem.chat.role !== "assistant") {
5685
5690
  this.addResultMessage({ content, name, functionCalls });
5686
5691
  } else {
5687
- if ("content" in lastItem.chat && content) {
5692
+ if ("content" in lastItem.chat && typeof content === "string" && content.trim() !== "") {
5688
5693
  lastItem.chat.content = content;
5689
5694
  }
5690
5695
  if ("name" in lastItem.chat && name) {
@@ -7815,7 +7820,7 @@ var SignatureParser = class {
7815
7820
  'Add class names in quotes. Example: class "positive, negative, neutral"'
7816
7821
  );
7817
7822
  }
7818
- const options = classNamesString.split(/[,\s]+/).map((s2) => s2.trim()).filter((s2) => s2.length > 0);
7823
+ const options = classNamesString.split(/[,|]/).map((s2) => s2.trim()).filter((s2) => s2.length > 0);
7819
7824
  if (options.length === 0) {
7820
7825
  throw new SignatureValidationError(
7821
7826
  `Output field "${name}": Empty class list provided`,
@@ -7824,24 +7829,6 @@ var SignatureParser = class {
7824
7829
  'Provide at least one class option. Example: "positive, negative"'
7825
7830
  );
7826
7831
  }
7827
- if (options.length === 1) {
7828
- throw new SignatureValidationError(
7829
- `Output field "${name}": Class type needs at least 2 options`,
7830
- this.position,
7831
- this.getErrorContext(),
7832
- 'Add more class options or use "string" type instead. Example: "positive, negative, neutral"'
7833
- );
7834
- }
7835
- for (const option of options) {
7836
- if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(option)) {
7837
- throw new SignatureValidationError(
7838
- `Output field "${name}": Invalid class option "${option}"`,
7839
- this.position,
7840
- this.getErrorContext(),
7841
- "Class options must start with a letter and contain only letters, numbers, underscores, or hyphens"
7842
- );
7843
- }
7844
- }
7845
7832
  type = { name: "class", isArray, options };
7846
7833
  } else {
7847
7834
  try {
@@ -8139,6 +8126,8 @@ var AxSignature = class _AxSignature {
8139
8126
  outputFields;
8140
8127
  sigHash;
8141
8128
  sigString;
8129
+ // Validation caching - stores hash when validation last passed
8130
+ validatedAtHash;
8142
8131
  constructor(signature) {
8143
8132
  if (!signature) {
8144
8133
  this.inputFields = [];
@@ -8180,6 +8169,9 @@ var AxSignature = class _AxSignature {
8180
8169
  );
8181
8170
  this.sigHash = signature.hash();
8182
8171
  this.sigString = signature.toString();
8172
+ if (signature.validatedAtHash === this.sigHash) {
8173
+ this.validatedAtHash = this.sigHash;
8174
+ }
8183
8175
  } else {
8184
8176
  throw new AxSignatureValidationError(
8185
8177
  "Invalid signature argument type",
@@ -8226,14 +8218,34 @@ var AxSignature = class _AxSignature {
8226
8218
  );
8227
8219
  }
8228
8220
  this.description = desc;
8221
+ this.invalidateValidationCache();
8229
8222
  this.updateHash();
8230
8223
  };
8231
8224
  addInputField = (field) => {
8232
8225
  try {
8233
8226
  const parsedField = this.parseField(field);
8234
8227
  validateField(parsedField, "input");
8228
+ for (const existingField of this.inputFields) {
8229
+ if (existingField.name === parsedField.name) {
8230
+ throw new AxSignatureValidationError(
8231
+ `Duplicate input field name: "${parsedField.name}"`,
8232
+ parsedField.name,
8233
+ "Each field name must be unique within the signature"
8234
+ );
8235
+ }
8236
+ }
8237
+ for (const outputField of this.outputFields) {
8238
+ if (outputField.name === parsedField.name) {
8239
+ throw new AxSignatureValidationError(
8240
+ `Field name "${parsedField.name}" appears in both inputs and outputs`,
8241
+ parsedField.name,
8242
+ "Use different names for input and output fields to avoid confusion"
8243
+ );
8244
+ }
8245
+ }
8235
8246
  this.inputFields.push(parsedField);
8236
- this.updateHash();
8247
+ this.invalidateValidationCache();
8248
+ this.updateHashLight();
8237
8249
  } catch (error) {
8238
8250
  if (error instanceof AxSignatureValidationError) {
8239
8251
  throw error;
@@ -8248,8 +8260,27 @@ var AxSignature = class _AxSignature {
8248
8260
  try {
8249
8261
  const parsedField = this.parseField(field);
8250
8262
  validateField(parsedField, "output");
8263
+ for (const existingField of this.outputFields) {
8264
+ if (existingField.name === parsedField.name) {
8265
+ throw new AxSignatureValidationError(
8266
+ `Duplicate output field name: "${parsedField.name}"`,
8267
+ parsedField.name,
8268
+ "Each field name must be unique within the signature"
8269
+ );
8270
+ }
8271
+ }
8272
+ for (const inputField of this.inputFields) {
8273
+ if (inputField.name === parsedField.name) {
8274
+ throw new AxSignatureValidationError(
8275
+ `Field name "${parsedField.name}" appears in both inputs and outputs`,
8276
+ parsedField.name,
8277
+ "Use different names for input and output fields to avoid confusion"
8278
+ );
8279
+ }
8280
+ }
8251
8281
  this.outputFields.push(parsedField);
8252
- this.updateHash();
8282
+ this.invalidateValidationCache();
8283
+ this.updateHashLight();
8253
8284
  } catch (error) {
8254
8285
  if (error instanceof AxSignatureValidationError) {
8255
8286
  throw error;
@@ -8275,6 +8306,7 @@ var AxSignature = class _AxSignature {
8275
8306
  return parsed;
8276
8307
  });
8277
8308
  this.inputFields = parsedFields;
8309
+ this.invalidateValidationCache();
8278
8310
  this.updateHash();
8279
8311
  } catch (error) {
8280
8312
  if (error instanceof AxSignatureValidationError) {
@@ -8300,6 +8332,7 @@ var AxSignature = class _AxSignature {
8300
8332
  return parsed;
8301
8333
  });
8302
8334
  this.outputFields = parsedFields;
8335
+ this.invalidateValidationCache();
8303
8336
  this.updateHash();
8304
8337
  } catch (error) {
8305
8338
  if (error instanceof AxSignatureValidationError) {
@@ -8313,6 +8346,9 @@ var AxSignature = class _AxSignature {
8313
8346
  getInputFields = () => this.inputFields;
8314
8347
  getOutputFields = () => this.outputFields;
8315
8348
  getDescription = () => this.description;
8349
+ invalidateValidationCache = () => {
8350
+ this.validatedAtHash = void 0;
8351
+ };
8316
8352
  toTitle = (name) => {
8317
8353
  let result = name.replace(/_/g, " ");
8318
8354
  result = result.replace(/([A-Z]|[0-9]+)/g, " $1").trim();
@@ -8349,6 +8385,30 @@ var AxSignature = class _AxSignature {
8349
8385
  };
8350
8386
  return schema;
8351
8387
  };
8388
+ updateHashLight = () => {
8389
+ try {
8390
+ this.getInputFields().forEach((field) => {
8391
+ validateField(field, "input");
8392
+ });
8393
+ this.getOutputFields().forEach((field) => {
8394
+ validateField(field, "output");
8395
+ });
8396
+ this.sigHash = (0, import_crypto3.createHash)("sha256").update(this.description ?? "").update(JSON.stringify(this.inputFields)).update(JSON.stringify(this.outputFields)).digest("hex");
8397
+ this.sigString = renderSignature(
8398
+ this.description,
8399
+ this.inputFields,
8400
+ this.outputFields
8401
+ );
8402
+ return [this.sigHash, this.sigString];
8403
+ } catch (error) {
8404
+ if (error instanceof AxSignatureValidationError) {
8405
+ throw error;
8406
+ }
8407
+ throw new AxSignatureValidationError(
8408
+ `Signature validation failed: ${error instanceof Error ? error.message : "Unknown error"}`
8409
+ );
8410
+ }
8411
+ };
8352
8412
  updateHash = () => {
8353
8413
  try {
8354
8414
  this.getInputFields().forEach((field) => {
@@ -8421,6 +8481,19 @@ var AxSignature = class _AxSignature {
8421
8481
  );
8422
8482
  }
8423
8483
  }
8484
+ validate = () => {
8485
+ if (this.validatedAtHash === this.sigHash) {
8486
+ return true;
8487
+ }
8488
+ try {
8489
+ this.updateHash();
8490
+ this.validatedAtHash = this.sigHash;
8491
+ return true;
8492
+ } catch (error) {
8493
+ this.validatedAtHash = void 0;
8494
+ throw error;
8495
+ }
8496
+ };
8424
8497
  hash = () => this.sigHash;
8425
8498
  toString = () => this.sigString;
8426
8499
  toJSON = () => {
@@ -8446,7 +8519,7 @@ function renderField(field) {
8446
8519
  result += "[]";
8447
8520
  }
8448
8521
  if (field.type.name === "class" && field.type.options) {
8449
- result += ` "${field.type.options.join(", ")}"`;
8522
+ result += ` "${field.type.options.join(" | ")}"`;
8450
8523
  }
8451
8524
  }
8452
8525
  if (field.description && field.type?.name !== "class") {
@@ -8578,13 +8651,6 @@ function validateFieldType(field, context3) {
8578
8651
  'Provide class options. Example: class "positive, negative, neutral"'
8579
8652
  );
8580
8653
  }
8581
- if (type.options.length === 1) {
8582
- throw new AxSignatureValidationError(
8583
- "Class type needs at least 2 options",
8584
- field.name,
8585
- 'Add more class options or use "string" type instead'
8586
- );
8587
- }
8588
8654
  for (const option of type.options) {
8589
8655
  if (!option || option.trim().length === 0) {
8590
8656
  throw new AxSignatureValidationError(
@@ -8594,11 +8660,11 @@ function validateFieldType(field, context3) {
8594
8660
  );
8595
8661
  }
8596
8662
  const trimmedOption = option.trim();
8597
- if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(trimmedOption)) {
8663
+ if (trimmedOption.includes(",") || trimmedOption.includes("|")) {
8598
8664
  throw new AxSignatureValidationError(
8599
8665
  `Invalid class option "${trimmedOption}"`,
8600
8666
  field.name,
8601
- "Class options must start with a letter and contain only letters, numbers, underscores, or hyphens"
8667
+ "Class options cannot contain commas (,) or pipes (|) as they are used to separate options"
8602
8668
  );
8603
8669
  }
8604
8670
  }
@@ -8642,12 +8708,13 @@ var AxProgramWithSignature = class {
8642
8708
  children;
8643
8709
  constructor(signature, options) {
8644
8710
  this.signature = new AxSignature(signature);
8645
- this.sigHash = this.signature?.hash();
8646
- this.children = new AxInstanceRegistry();
8647
- this.key = { id: this.constructor.name };
8648
8711
  if (options?.description) {
8649
8712
  this.signature.setDescription(options.description);
8650
8713
  }
8714
+ this.signature.validate();
8715
+ this.sigHash = this.signature?.hash();
8716
+ this.children = new AxInstanceRegistry();
8717
+ this.key = { id: this.constructor.name };
8651
8718
  }
8652
8719
  getSignature() {
8653
8720
  return this.signature;