@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.d.cts CHANGED
@@ -2065,6 +2065,7 @@ declare class AxSignature {
2065
2065
  private outputFields;
2066
2066
  private sigHash;
2067
2067
  private sigString;
2068
+ private validatedAtHash?;
2068
2069
  constructor(signature?: Readonly<AxSignature | string>);
2069
2070
  private parseParsedField;
2070
2071
  private parseField;
@@ -2076,10 +2077,13 @@ declare class AxSignature {
2076
2077
  getInputFields: () => Readonly<AxIField[]>;
2077
2078
  getOutputFields: () => Readonly<AxIField[]>;
2078
2079
  getDescription: () => string | undefined;
2080
+ private invalidateValidationCache;
2079
2081
  private toTitle;
2080
2082
  toJSONSchema: () => AxFunctionJSONSchema;
2083
+ private updateHashLight;
2081
2084
  private updateHash;
2082
2085
  private validateSignatureConsistency;
2086
+ validate: () => boolean;
2083
2087
  hash: () => string;
2084
2088
  toString: () => string;
2085
2089
  toJSON: () => {
package/index.d.ts CHANGED
@@ -2065,6 +2065,7 @@ declare class AxSignature {
2065
2065
  private outputFields;
2066
2066
  private sigHash;
2067
2067
  private sigString;
2068
+ private validatedAtHash?;
2068
2069
  constructor(signature?: Readonly<AxSignature | string>);
2069
2070
  private parseParsedField;
2070
2071
  private parseField;
@@ -2076,10 +2077,13 @@ declare class AxSignature {
2076
2077
  getInputFields: () => Readonly<AxIField[]>;
2077
2078
  getOutputFields: () => Readonly<AxIField[]>;
2078
2079
  getDescription: () => string | undefined;
2080
+ private invalidateValidationCache;
2079
2081
  private toTitle;
2080
2082
  toJSONSchema: () => AxFunctionJSONSchema;
2083
+ private updateHashLight;
2081
2084
  private updateHash;
2082
2085
  private validateSignatureConsistency;
2086
+ validate: () => boolean;
2083
2087
  hash: () => string;
2084
2088
  toString: () => string;
2085
2089
  toJSON: () => {
package/index.js CHANGED
@@ -5491,10 +5491,15 @@ var MemoryImpl = class {
5491
5491
  name,
5492
5492
  functionCalls
5493
5493
  }) {
5494
- if (!content && (!functionCalls || functionCalls.length === 0)) {
5494
+ const isContentEmpty = typeof content === "string" && content.trim() === "";
5495
+ if (isContentEmpty && (!functionCalls || functionCalls.length === 0)) {
5495
5496
  return;
5496
5497
  }
5497
- this.addMemory({ content, name, role: "assistant", functionCalls });
5498
+ if (isContentEmpty) {
5499
+ this.addMemory({ name, role: "assistant", functionCalls });
5500
+ } else {
5501
+ this.addMemory({ content, name, role: "assistant", functionCalls });
5502
+ }
5498
5503
  }
5499
5504
  addResult({
5500
5505
  content,
@@ -5516,7 +5521,7 @@ var MemoryImpl = class {
5516
5521
  if (!lastItem || lastItem.chat.role !== "assistant") {
5517
5522
  this.addResultMessage({ content, name, functionCalls });
5518
5523
  } else {
5519
- if ("content" in lastItem.chat && content) {
5524
+ if ("content" in lastItem.chat && typeof content === "string" && content.trim() !== "") {
5520
5525
  lastItem.chat.content = content;
5521
5526
  }
5522
5527
  if ("name" in lastItem.chat && name) {
@@ -7647,7 +7652,7 @@ var SignatureParser = class {
7647
7652
  'Add class names in quotes. Example: class "positive, negative, neutral"'
7648
7653
  );
7649
7654
  }
7650
- const options = classNamesString.split(/[,\s]+/).map((s2) => s2.trim()).filter((s2) => s2.length > 0);
7655
+ const options = classNamesString.split(/[,|]/).map((s2) => s2.trim()).filter((s2) => s2.length > 0);
7651
7656
  if (options.length === 0) {
7652
7657
  throw new SignatureValidationError(
7653
7658
  `Output field "${name}": Empty class list provided`,
@@ -7656,24 +7661,6 @@ var SignatureParser = class {
7656
7661
  'Provide at least one class option. Example: "positive, negative"'
7657
7662
  );
7658
7663
  }
7659
- if (options.length === 1) {
7660
- throw new SignatureValidationError(
7661
- `Output field "${name}": Class type needs at least 2 options`,
7662
- this.position,
7663
- this.getErrorContext(),
7664
- 'Add more class options or use "string" type instead. Example: "positive, negative, neutral"'
7665
- );
7666
- }
7667
- for (const option of options) {
7668
- if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(option)) {
7669
- throw new SignatureValidationError(
7670
- `Output field "${name}": Invalid class option "${option}"`,
7671
- this.position,
7672
- this.getErrorContext(),
7673
- "Class options must start with a letter and contain only letters, numbers, underscores, or hyphens"
7674
- );
7675
- }
7676
- }
7677
7664
  type = { name: "class", isArray, options };
7678
7665
  } else {
7679
7666
  try {
@@ -7971,6 +7958,8 @@ var AxSignature = class _AxSignature {
7971
7958
  outputFields;
7972
7959
  sigHash;
7973
7960
  sigString;
7961
+ // Validation caching - stores hash when validation last passed
7962
+ validatedAtHash;
7974
7963
  constructor(signature) {
7975
7964
  if (!signature) {
7976
7965
  this.inputFields = [];
@@ -8012,6 +8001,9 @@ var AxSignature = class _AxSignature {
8012
8001
  );
8013
8002
  this.sigHash = signature.hash();
8014
8003
  this.sigString = signature.toString();
8004
+ if (signature.validatedAtHash === this.sigHash) {
8005
+ this.validatedAtHash = this.sigHash;
8006
+ }
8015
8007
  } else {
8016
8008
  throw new AxSignatureValidationError(
8017
8009
  "Invalid signature argument type",
@@ -8058,14 +8050,34 @@ var AxSignature = class _AxSignature {
8058
8050
  );
8059
8051
  }
8060
8052
  this.description = desc;
8053
+ this.invalidateValidationCache();
8061
8054
  this.updateHash();
8062
8055
  };
8063
8056
  addInputField = (field) => {
8064
8057
  try {
8065
8058
  const parsedField = this.parseField(field);
8066
8059
  validateField(parsedField, "input");
8060
+ for (const existingField of this.inputFields) {
8061
+ if (existingField.name === parsedField.name) {
8062
+ throw new AxSignatureValidationError(
8063
+ `Duplicate input field name: "${parsedField.name}"`,
8064
+ parsedField.name,
8065
+ "Each field name must be unique within the signature"
8066
+ );
8067
+ }
8068
+ }
8069
+ for (const outputField of this.outputFields) {
8070
+ if (outputField.name === parsedField.name) {
8071
+ throw new AxSignatureValidationError(
8072
+ `Field name "${parsedField.name}" appears in both inputs and outputs`,
8073
+ parsedField.name,
8074
+ "Use different names for input and output fields to avoid confusion"
8075
+ );
8076
+ }
8077
+ }
8067
8078
  this.inputFields.push(parsedField);
8068
- this.updateHash();
8079
+ this.invalidateValidationCache();
8080
+ this.updateHashLight();
8069
8081
  } catch (error) {
8070
8082
  if (error instanceof AxSignatureValidationError) {
8071
8083
  throw error;
@@ -8080,8 +8092,27 @@ var AxSignature = class _AxSignature {
8080
8092
  try {
8081
8093
  const parsedField = this.parseField(field);
8082
8094
  validateField(parsedField, "output");
8095
+ for (const existingField of this.outputFields) {
8096
+ if (existingField.name === parsedField.name) {
8097
+ throw new AxSignatureValidationError(
8098
+ `Duplicate output field name: "${parsedField.name}"`,
8099
+ parsedField.name,
8100
+ "Each field name must be unique within the signature"
8101
+ );
8102
+ }
8103
+ }
8104
+ for (const inputField of this.inputFields) {
8105
+ if (inputField.name === parsedField.name) {
8106
+ throw new AxSignatureValidationError(
8107
+ `Field name "${parsedField.name}" appears in both inputs and outputs`,
8108
+ parsedField.name,
8109
+ "Use different names for input and output fields to avoid confusion"
8110
+ );
8111
+ }
8112
+ }
8083
8113
  this.outputFields.push(parsedField);
8084
- this.updateHash();
8114
+ this.invalidateValidationCache();
8115
+ this.updateHashLight();
8085
8116
  } catch (error) {
8086
8117
  if (error instanceof AxSignatureValidationError) {
8087
8118
  throw error;
@@ -8107,6 +8138,7 @@ var AxSignature = class _AxSignature {
8107
8138
  return parsed;
8108
8139
  });
8109
8140
  this.inputFields = parsedFields;
8141
+ this.invalidateValidationCache();
8110
8142
  this.updateHash();
8111
8143
  } catch (error) {
8112
8144
  if (error instanceof AxSignatureValidationError) {
@@ -8132,6 +8164,7 @@ var AxSignature = class _AxSignature {
8132
8164
  return parsed;
8133
8165
  });
8134
8166
  this.outputFields = parsedFields;
8167
+ this.invalidateValidationCache();
8135
8168
  this.updateHash();
8136
8169
  } catch (error) {
8137
8170
  if (error instanceof AxSignatureValidationError) {
@@ -8145,6 +8178,9 @@ var AxSignature = class _AxSignature {
8145
8178
  getInputFields = () => this.inputFields;
8146
8179
  getOutputFields = () => this.outputFields;
8147
8180
  getDescription = () => this.description;
8181
+ invalidateValidationCache = () => {
8182
+ this.validatedAtHash = void 0;
8183
+ };
8148
8184
  toTitle = (name) => {
8149
8185
  let result = name.replace(/_/g, " ");
8150
8186
  result = result.replace(/([A-Z]|[0-9]+)/g, " $1").trim();
@@ -8181,6 +8217,30 @@ var AxSignature = class _AxSignature {
8181
8217
  };
8182
8218
  return schema;
8183
8219
  };
8220
+ updateHashLight = () => {
8221
+ try {
8222
+ this.getInputFields().forEach((field) => {
8223
+ validateField(field, "input");
8224
+ });
8225
+ this.getOutputFields().forEach((field) => {
8226
+ validateField(field, "output");
8227
+ });
8228
+ this.sigHash = createHash("sha256").update(this.description ?? "").update(JSON.stringify(this.inputFields)).update(JSON.stringify(this.outputFields)).digest("hex");
8229
+ this.sigString = renderSignature(
8230
+ this.description,
8231
+ this.inputFields,
8232
+ this.outputFields
8233
+ );
8234
+ return [this.sigHash, this.sigString];
8235
+ } catch (error) {
8236
+ if (error instanceof AxSignatureValidationError) {
8237
+ throw error;
8238
+ }
8239
+ throw new AxSignatureValidationError(
8240
+ `Signature validation failed: ${error instanceof Error ? error.message : "Unknown error"}`
8241
+ );
8242
+ }
8243
+ };
8184
8244
  updateHash = () => {
8185
8245
  try {
8186
8246
  this.getInputFields().forEach((field) => {
@@ -8253,6 +8313,19 @@ var AxSignature = class _AxSignature {
8253
8313
  );
8254
8314
  }
8255
8315
  }
8316
+ validate = () => {
8317
+ if (this.validatedAtHash === this.sigHash) {
8318
+ return true;
8319
+ }
8320
+ try {
8321
+ this.updateHash();
8322
+ this.validatedAtHash = this.sigHash;
8323
+ return true;
8324
+ } catch (error) {
8325
+ this.validatedAtHash = void 0;
8326
+ throw error;
8327
+ }
8328
+ };
8256
8329
  hash = () => this.sigHash;
8257
8330
  toString = () => this.sigString;
8258
8331
  toJSON = () => {
@@ -8278,7 +8351,7 @@ function renderField(field) {
8278
8351
  result += "[]";
8279
8352
  }
8280
8353
  if (field.type.name === "class" && field.type.options) {
8281
- result += ` "${field.type.options.join(", ")}"`;
8354
+ result += ` "${field.type.options.join(" | ")}"`;
8282
8355
  }
8283
8356
  }
8284
8357
  if (field.description && field.type?.name !== "class") {
@@ -8410,13 +8483,6 @@ function validateFieldType(field, context3) {
8410
8483
  'Provide class options. Example: class "positive, negative, neutral"'
8411
8484
  );
8412
8485
  }
8413
- if (type.options.length === 1) {
8414
- throw new AxSignatureValidationError(
8415
- "Class type needs at least 2 options",
8416
- field.name,
8417
- 'Add more class options or use "string" type instead'
8418
- );
8419
- }
8420
8486
  for (const option of type.options) {
8421
8487
  if (!option || option.trim().length === 0) {
8422
8488
  throw new AxSignatureValidationError(
@@ -8426,11 +8492,11 @@ function validateFieldType(field, context3) {
8426
8492
  );
8427
8493
  }
8428
8494
  const trimmedOption = option.trim();
8429
- if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(trimmedOption)) {
8495
+ if (trimmedOption.includes(",") || trimmedOption.includes("|")) {
8430
8496
  throw new AxSignatureValidationError(
8431
8497
  `Invalid class option "${trimmedOption}"`,
8432
8498
  field.name,
8433
- "Class options must start with a letter and contain only letters, numbers, underscores, or hyphens"
8499
+ "Class options cannot contain commas (,) or pipes (|) as they are used to separate options"
8434
8500
  );
8435
8501
  }
8436
8502
  }
@@ -8474,12 +8540,13 @@ var AxProgramWithSignature = class {
8474
8540
  children;
8475
8541
  constructor(signature, options) {
8476
8542
  this.signature = new AxSignature(signature);
8477
- this.sigHash = this.signature?.hash();
8478
- this.children = new AxInstanceRegistry();
8479
- this.key = { id: this.constructor.name };
8480
8543
  if (options?.description) {
8481
8544
  this.signature.setDescription(options.description);
8482
8545
  }
8546
+ this.signature.validate();
8547
+ this.sigHash = this.signature?.hash();
8548
+ this.children = new AxInstanceRegistry();
8549
+ this.key = { id: this.constructor.name };
8483
8550
  }
8484
8551
  getSignature() {
8485
8552
  return this.signature;