@ax-llm/ax 11.0.66 → 12.0.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/index.cjs CHANGED
@@ -159,7 +159,7 @@ __export(index_exports, {
159
159
  axAITogetherDefaultConfig: () => axAITogetherDefaultConfig,
160
160
  axBaseAIDefaultConfig: () => axBaseAIDefaultConfig,
161
161
  axBaseAIDefaultCreativeConfig: () => axBaseAIDefaultCreativeConfig,
162
- axField: () => axField,
162
+ axGlobals: () => axGlobals,
163
163
  axModelInfoAnthropic: () => axModelInfoAnthropic,
164
164
  axModelInfoCohere: () => axModelInfoCohere,
165
165
  axModelInfoDeepSeek: () => axModelInfoDeepSeek,
@@ -172,7 +172,9 @@ __export(index_exports, {
172
172
  axModelInfoReka: () => axModelInfoReka,
173
173
  axModelInfoTogether: () => axModelInfoTogether,
174
174
  axSpanAttributes: () => axSpanAttributes,
175
- axSpanEvents: () => axSpanEvents
175
+ axSpanEvents: () => axSpanEvents,
176
+ f: () => f,
177
+ s: () => s
176
178
  });
177
179
  module.exports = __toCommonJS(index_exports);
178
180
 
@@ -953,14 +955,14 @@ var logResponseResult = (r, logger = defaultLogger) => {
953
955
  logger(r.content, { tags: ["responseContent"] });
954
956
  }
955
957
  if (r.functionCalls && r.functionCalls.length > 0) {
956
- for (const [i, f] of r.functionCalls.entries()) {
957
- if (f.function.name) {
958
- logger(`[${i + 1}] ${f.function.name}`, {
958
+ for (const [i, f2] of r.functionCalls.entries()) {
959
+ if (f2.function.name) {
960
+ logger(`[${i + 1}] ${f2.function.name}`, {
959
961
  tags: ["functionName"]
960
962
  });
961
963
  }
962
- if (f.function.params) {
963
- const params = typeof f.function.params === "string" ? f.function.params : JSON.stringify(f.function.params, null, 2);
964
+ if (f2.function.params) {
965
+ const params = typeof f2.function.params === "string" ? f2.function.params : JSON.stringify(f2.function.params, null, 2);
964
966
  logger(params, { tags: ["functionArg"] });
965
967
  }
966
968
  }
@@ -3087,7 +3089,7 @@ function createHistory(chatPrompt) {
3087
3089
  case "function": {
3088
3090
  const functionCalls = chatPrompt.map((v) => {
3089
3091
  if (v.role === "assistant") {
3090
- return v.functionCalls?.find((f) => f.id === chat.functionId);
3092
+ return v.functionCalls?.find((f2) => f2.id === chat.functionId);
3091
3093
  }
3092
3094
  return void 0;
3093
3095
  }).filter((v) => v !== void 0);
@@ -3407,11 +3409,11 @@ var AxAIGoogleGeminiImpl = class {
3407
3409
  case "assistant": {
3408
3410
  let parts = [];
3409
3411
  if (msg.functionCalls) {
3410
- parts = msg.functionCalls.map((f) => {
3411
- const args = typeof f.function.params === "string" ? JSON.parse(f.function.params) : f.function.params;
3412
+ parts = msg.functionCalls.map((f2) => {
3413
+ const args = typeof f2.function.params === "string" ? JSON.parse(f2.function.params) : f2.function.params;
3412
3414
  return {
3413
3415
  functionCall: {
3414
- name: f.function.name,
3416
+ name: f2.function.name,
3415
3417
  args
3416
3418
  }
3417
3419
  };
@@ -4468,7 +4470,7 @@ var AxAIOpenAIResponsesImpl = class {
4468
4470
  currentResult.thought = item.encrypted_content;
4469
4471
  } else {
4470
4472
  currentResult.thought = item.summary.map(
4471
- (s) => typeof s === "object" ? JSON.stringify(s) : s
4473
+ (s2) => typeof s2 === "object" ? JSON.stringify(s2) : s2
4472
4474
  ).join("\n");
4473
4475
  }
4474
4476
  break;
@@ -4792,7 +4794,7 @@ var AxAIOpenAIResponsesImpl = class {
4792
4794
  baseResult.thought = reasoningItem.encrypted_content;
4793
4795
  } else if (reasoningItem.summary) {
4794
4796
  baseResult.thought = reasoningItem.summary.map(
4795
- (s) => typeof s === "object" ? JSON.stringify(s) : s
4797
+ (s2) => typeof s2 === "object" ? JSON.stringify(s2) : s2
4796
4798
  ).join("\n");
4797
4799
  }
4798
4800
  }
@@ -6164,7 +6166,7 @@ var AxPromptTemplate = class {
6164
6166
  task.push(
6165
6167
  `You will be provided with the following fields: ${inArgs}. Your task is to generate new fields: ${outArgs}.`
6166
6168
  );
6167
- const funcs = this.functions?.map((f) => "toFunction" in f ? f.toFunction() : f)?.flat();
6169
+ const funcs = this.functions?.map((f2) => "toFunction" in f2 ? f2.toFunction() : f2)?.flat();
6168
6170
  const funcList = funcs?.map((fn) => `- \`${fn.name}\`: ${formatDescription(fn.description)}`).join("\n");
6169
6171
  if (funcList && funcList.length > 0) {
6170
6172
  task.push(`## Available Functions
@@ -6726,6 +6728,11 @@ var extractValues = (sig, values, content) => {
6726
6728
  const xstate = { extractedFields: [], streamedIndex: {}, s: -1 };
6727
6729
  streamingExtractValues(sig, values, xstate, content);
6728
6730
  streamingExtractFinalValue(sig, values, xstate, content);
6731
+ for (const field of sig.getOutputFields()) {
6732
+ if (field.isInternal) {
6733
+ delete values[field.name];
6734
+ }
6735
+ }
6729
6736
  };
6730
6737
  var checkMissingRequiredFields = (xstate, values, currentIndex) => {
6731
6738
  const missingFields = [];
@@ -6858,7 +6865,7 @@ var convertValueToType = (field, val, required = false) => {
6858
6865
  return val;
6859
6866
  }
6860
6867
  };
6861
- function* yieldDelta(content, field, s, e, xstate) {
6868
+ function* yieldDelta(content, field, s2, e, xstate) {
6862
6869
  const { name: fieldName, isInternal } = field;
6863
6870
  const { isArray: fieldIsArray, name: fieldTypeName } = field.type ?? {};
6864
6871
  if (isInternal || fieldIsArray || fieldTypeName && fieldTypeName !== "string" && fieldTypeName !== "code") {
@@ -6866,7 +6873,7 @@ function* yieldDelta(content, field, s, e, xstate) {
6866
6873
  }
6867
6874
  const pos = xstate.streamedIndex[fieldName] ?? 0;
6868
6875
  const isFirstChunk = pos === 0;
6869
- const d1 = content.substring(s + pos, e);
6876
+ const d1 = content.substring(s2 + pos, e);
6870
6877
  if (d1.length === 0) {
6871
6878
  return;
6872
6879
  }
@@ -6885,8 +6892,8 @@ function* yieldDelta(content, field, s, e, xstate) {
6885
6892
  }
6886
6893
  function* streamValues(sig, content, values, xstate) {
6887
6894
  for (const prevField of xstate.prevFields ?? []) {
6888
- const { field, s, e } = prevField;
6889
- yield* yieldDelta(content, field, s, e, xstate);
6895
+ const { field, s: s2, e } = prevField;
6896
+ yield* yieldDelta(content, field, s2, e, xstate);
6890
6897
  }
6891
6898
  xstate.prevFields = void 0;
6892
6899
  if (!xstate.currField || xstate.currField.isInternal) {
@@ -6901,17 +6908,17 @@ function* streamValues(sig, content, values, xstate) {
6901
6908
  );
6902
6909
  const outputFields = sig.getOutputFields();
6903
6910
  for (const key of Object.keys(values)) {
6904
- const field = outputFields.find((f) => f.name === key);
6911
+ const field = outputFields.find((f2) => f2.name === key);
6905
6912
  if (!field || field.isInternal) {
6906
6913
  continue;
6907
6914
  }
6908
6915
  const value = values[key];
6909
6916
  if (Array.isArray(value)) {
6910
- const s = xstate.streamedIndex?.[key] ?? 0;
6911
- const v = value.slice(s);
6917
+ const s2 = xstate.streamedIndex?.[key] ?? 0;
6918
+ const v = value.slice(s2);
6912
6919
  if (v && v.length > 0) {
6913
6920
  yield { [key]: v };
6914
- xstate.streamedIndex[key] = s + v.length;
6921
+ xstate.streamedIndex[key] = s2 + v.length;
6915
6922
  }
6916
6923
  continue;
6917
6924
  }
@@ -7334,11 +7341,11 @@ var parseFunctions = (newFuncs, existingFuncs) => {
7334
7341
  if (newFuncs.length === 0) {
7335
7342
  return [...existingFuncs ?? []];
7336
7343
  }
7337
- const functions = newFuncs.map((f) => {
7338
- if ("toFunction" in f) {
7339
- return f.toFunction();
7344
+ const functions = newFuncs.map((f2) => {
7345
+ if ("toFunction" in f2) {
7346
+ return f2.toFunction();
7340
7347
  }
7341
- return f;
7348
+ return f2;
7342
7349
  }).flat();
7343
7350
  for (const fn of functions.filter((v) => v.parameters)) {
7344
7351
  if (fn.parameters) {
@@ -7423,10 +7430,10 @@ function parseFunctionCalls(ai, functionCalls, values, model) {
7423
7430
  if (!ai.getFeatures(model).functions) {
7424
7431
  throw new Error("Functions are not supported by the AI service");
7425
7432
  }
7426
- const funcs = functionCalls.map((f) => ({
7427
- id: f.id,
7428
- name: f.function.name,
7429
- args: f.function.params
7433
+ const funcs = functionCalls.map((f2) => ({
7434
+ id: f2.id,
7435
+ name: f2.function.name,
7436
+ args: f2.function.params
7430
7437
  }));
7431
7438
  return funcs;
7432
7439
  }
@@ -7451,93 +7458,218 @@ var AxInstanceRegistry = class {
7451
7458
  // dsp/sig.ts
7452
7459
  var import_crypto3 = require("crypto");
7453
7460
 
7461
+ // dsp/globals.ts
7462
+ var axGlobals = {
7463
+ signatureStrict: true
7464
+ // Controls reservedNames enforcement in signature parsing/validation
7465
+ };
7466
+
7454
7467
  // dsp/parser.ts
7468
+ var SignatureValidationError = class extends Error {
7469
+ constructor(message, position, context3, suggestion) {
7470
+ super(message);
7471
+ this.position = position;
7472
+ this.context = context3;
7473
+ this.suggestion = suggestion;
7474
+ this.name = "SignatureValidationError";
7475
+ }
7476
+ };
7455
7477
  var SignatureParser = class {
7456
7478
  input;
7457
7479
  position;
7458
7480
  currentFieldName = null;
7481
+ currentSection = "description";
7459
7482
  constructor(input) {
7460
- this.input = input;
7483
+ this.input = input.trim();
7461
7484
  this.position = 0;
7485
+ if (!this.input) {
7486
+ throw new SignatureValidationError(
7487
+ "Empty signature provided",
7488
+ 0,
7489
+ "",
7490
+ 'A signature must contain at least input and output fields separated by "->". Example: "userQuery:string -> aiResponse:string"'
7491
+ );
7492
+ }
7462
7493
  }
7463
7494
  parse() {
7464
7495
  try {
7465
7496
  this.skipWhitespace();
7466
7497
  const optionalDesc = this.parseParsedString();
7467
7498
  this.skipWhitespace();
7499
+ this.currentSection = "inputs";
7468
7500
  const inputs = this.parseFieldList(
7469
7501
  this.parseInputField.bind(this),
7470
7502
  "input"
7471
7503
  );
7472
7504
  this.skipWhitespace();
7473
7505
  if (this.position >= this.input.length) {
7474
- throw new Error(
7475
- 'Incomplete signature: Missing output section. Expected "->" followed by output fields'
7506
+ throw new SignatureValidationError(
7507
+ "Incomplete signature: Missing output section",
7508
+ this.position,
7509
+ this.getErrorContext(),
7510
+ 'Add "->" followed by output fields. Example: "-> responseText:string"'
7476
7511
  );
7477
7512
  }
7478
- this.expect("->");
7513
+ this.expectArrow();
7479
7514
  this.skipWhitespace();
7480
7515
  if (this.position >= this.input.length) {
7481
- throw new Error(
7482
- 'Incomplete signature: No output fields specified after "->"'
7516
+ throw new SignatureValidationError(
7517
+ 'Incomplete signature: No output fields specified after "->"',
7518
+ this.position,
7519
+ this.getErrorContext(),
7520
+ 'Add at least one output field. Example: "-> responseText:string"'
7483
7521
  );
7484
7522
  }
7523
+ this.currentSection = "outputs";
7485
7524
  const outputs = this.parseFieldList(
7486
7525
  this.parseOutputField.bind(this),
7487
7526
  "output"
7488
7527
  );
7528
+ this.skipWhitespace();
7529
+ if (this.position < this.input.length) {
7530
+ const remaining = this.input.slice(this.position);
7531
+ throw new SignatureValidationError(
7532
+ `Unexpected content after signature: "${remaining}"`,
7533
+ this.position,
7534
+ this.getErrorContext(),
7535
+ "Remove any extra content after the output fields"
7536
+ );
7537
+ }
7538
+ this.validateParsedSignature({
7539
+ desc: optionalDesc?.trim(),
7540
+ inputs,
7541
+ outputs
7542
+ });
7489
7543
  return {
7490
7544
  desc: optionalDesc?.trim(),
7491
7545
  inputs,
7492
7546
  outputs
7493
7547
  };
7494
7548
  } catch (error) {
7549
+ if (error instanceof SignatureValidationError) {
7550
+ throw error;
7551
+ }
7495
7552
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
7496
- const context3 = this.getErrorContext();
7497
- throw new Error(`${errorMessage}
7498
- ${context3}`);
7553
+ throw new SignatureValidationError(
7554
+ errorMessage,
7555
+ this.position,
7556
+ this.getErrorContext()
7557
+ );
7558
+ }
7559
+ }
7560
+ validateParsedSignature(signature) {
7561
+ const inputNames = /* @__PURE__ */ new Set();
7562
+ for (const field of signature.inputs) {
7563
+ if (inputNames.has(field.name)) {
7564
+ throw new SignatureValidationError(
7565
+ `Duplicate input field name: "${field.name}"`,
7566
+ 0,
7567
+ "",
7568
+ "Each field name must be unique within the signature"
7569
+ );
7570
+ }
7571
+ inputNames.add(field.name);
7572
+ }
7573
+ const outputNames = /* @__PURE__ */ new Set();
7574
+ for (const field of signature.outputs) {
7575
+ if (outputNames.has(field.name)) {
7576
+ throw new SignatureValidationError(
7577
+ `Duplicate output field name: "${field.name}"`,
7578
+ 0,
7579
+ "",
7580
+ "Each field name must be unique within the signature"
7581
+ );
7582
+ }
7583
+ outputNames.add(field.name);
7584
+ }
7585
+ for (const outputField of signature.outputs) {
7586
+ if (inputNames.has(outputField.name)) {
7587
+ throw new SignatureValidationError(
7588
+ `Field name "${outputField.name}" appears in both inputs and outputs`,
7589
+ 0,
7590
+ "",
7591
+ "Use different names for input and output fields to avoid confusion"
7592
+ );
7593
+ }
7594
+ }
7595
+ if (signature.inputs.length === 0) {
7596
+ throw new SignatureValidationError(
7597
+ "Signature must have at least one input field",
7598
+ 0,
7599
+ "",
7600
+ 'Add an input field before "->". Example: "userInput:string -> ..."'
7601
+ );
7602
+ }
7603
+ if (signature.outputs.length === 0) {
7604
+ throw new SignatureValidationError(
7605
+ "Signature must have at least one output field",
7606
+ 0,
7607
+ "",
7608
+ 'Add an output field after "->". Example: "... -> responseText:string"'
7609
+ );
7499
7610
  }
7500
7611
  }
7501
7612
  getErrorContext() {
7502
- const start = Math.max(0, this.position - 20);
7503
- const end = Math.min(this.input.length, this.position + 20);
7613
+ const start = Math.max(0, this.position - 25);
7614
+ const end = Math.min(this.input.length, this.position + 25);
7504
7615
  const before = this.input.slice(start, this.position);
7505
7616
  const after = this.input.slice(this.position, end);
7506
7617
  const pointer = " ".repeat(before.length) + "^";
7507
- return `Near position ${this.position}:
7508
- ${before}${after}
7509
- ${pointer}`;
7618
+ const lines = [
7619
+ `Position ${this.position} in signature:`,
7620
+ `"${before}${after}"`,
7621
+ ` ${pointer}`
7622
+ ];
7623
+ return lines.join("\n");
7510
7624
  }
7511
7625
  parseFieldList(parseFieldFn, section) {
7512
7626
  const fields = [];
7513
7627
  this.skipWhitespace();
7514
7628
  if (this.position >= this.input.length) {
7515
- throw new Error(`Empty ${section} section: Expected at least one field`);
7629
+ throw new SignatureValidationError(
7630
+ `Empty ${section} section: Expected at least one field`,
7631
+ this.position,
7632
+ this.getErrorContext(),
7633
+ `Add a ${section} field. Example: ${section === "input" ? "userInput:string" : "responseText:string"}`
7634
+ );
7516
7635
  }
7517
7636
  try {
7518
7637
  fields.push(parseFieldFn());
7519
7638
  } catch (error) {
7520
- throw new Error(
7521
- `Invalid first ${section} field: ${error instanceof Error ? error.message : "Unknown error"}`
7639
+ if (error instanceof SignatureValidationError) {
7640
+ throw error;
7641
+ }
7642
+ throw new SignatureValidationError(
7643
+ `Invalid first ${section} field: ${error instanceof Error ? error.message : "Unknown error"}`,
7644
+ this.position,
7645
+ this.getErrorContext()
7522
7646
  );
7523
7647
  }
7524
7648
  this.skipWhitespace();
7525
7649
  while (this.position < this.input.length) {
7526
- if (this.input[this.position] === "-" && this.input[this.position + 1] === ">") {
7650
+ if (this.input[this.position] === "-" && this.position + 1 < this.input.length && this.input[this.position + 1] === ">") {
7527
7651
  break;
7528
7652
  }
7529
7653
  if (this.match(",")) {
7530
7654
  this.skipWhitespace();
7531
7655
  if (this.position >= this.input.length) {
7532
- throw new Error(
7533
- `Unexpected end of input after comma in ${section} section`
7656
+ throw new SignatureValidationError(
7657
+ `Unexpected end of input after comma in ${section} section`,
7658
+ this.position,
7659
+ this.getErrorContext(),
7660
+ `Add another ${section} field after the comma`
7534
7661
  );
7535
7662
  }
7536
7663
  try {
7537
7664
  fields.push(parseFieldFn());
7538
7665
  } catch (error) {
7539
- throw new Error(
7540
- `Invalid ${section} field after comma: ${error instanceof Error ? error.message : "Unknown error"}`
7666
+ if (error instanceof SignatureValidationError) {
7667
+ throw error;
7668
+ }
7669
+ throw new SignatureValidationError(
7670
+ `Invalid ${section} field after comma: ${error instanceof Error ? error.message : "Unknown error"}`,
7671
+ this.position,
7672
+ this.getErrorContext()
7541
7673
  );
7542
7674
  }
7543
7675
  this.skipWhitespace();
@@ -7554,6 +7686,7 @@ ${pointer}`;
7554
7686
  this.skipWhitespace();
7555
7687
  const name = this.parseParsedIdentifier();
7556
7688
  this.currentFieldName = name;
7689
+ this.validateFieldName(name, "input");
7557
7690
  let isOptional = void 0;
7558
7691
  while (true) {
7559
7692
  if (this.match("?")) {
@@ -7561,8 +7694,11 @@ ${pointer}`;
7561
7694
  continue;
7562
7695
  }
7563
7696
  if (this.match("!")) {
7564
- throw new Error(
7565
- `Input field "${name}" does not support the internal marker "!"`
7697
+ throw new SignatureValidationError(
7698
+ `Input field "${name}" cannot use the internal marker "!"`,
7699
+ this.position - 1,
7700
+ this.getErrorContext(),
7701
+ "Internal markers (!) are only allowed on output fields"
7566
7702
  );
7567
7703
  }
7568
7704
  break;
@@ -7572,17 +7708,33 @@ ${pointer}`;
7572
7708
  if (this.match(":")) {
7573
7709
  this.skipWhitespace();
7574
7710
  if (/^class\b/.test(this.input.slice(this.position))) {
7575
- throw new Error(
7576
- `Input field "${name}" does not support the "class" type`
7711
+ throw new SignatureValidationError(
7712
+ `Input field "${name}" cannot use the "class" type`,
7713
+ this.position,
7714
+ this.getErrorContext(),
7715
+ 'Class types are only allowed on output fields. Use "string" type for input classifications'
7577
7716
  );
7578
7717
  } else {
7579
7718
  try {
7580
7719
  const typeName = this.parseTypeNotClass();
7581
7720
  const isArray = this.match("[]");
7582
7721
  type = { name: typeName, isArray };
7722
+ if ((typeName === "image" || typeName === "audio") && isArray) {
7723
+ throw new SignatureValidationError(
7724
+ `Input field "${name}": Arrays of ${typeName} are not supported`,
7725
+ this.position,
7726
+ this.getErrorContext(),
7727
+ `Use a single ${typeName} type instead: "${typeName}"`
7728
+ );
7729
+ }
7583
7730
  } catch (error) {
7584
- throw new Error(
7585
- `Input field "${name}": ${error instanceof Error ? error.message : "Unknown error"}`
7731
+ if (error instanceof SignatureValidationError) {
7732
+ throw error;
7733
+ }
7734
+ throw new SignatureValidationError(
7735
+ `Input field "${name}": ${error instanceof Error ? error.message : "Unknown error"}`,
7736
+ this.position,
7737
+ this.getErrorContext()
7586
7738
  );
7587
7739
  }
7588
7740
  }
@@ -7603,6 +7755,7 @@ ${pointer}`;
7603
7755
  this.skipWhitespace();
7604
7756
  const name = this.parseParsedIdentifier();
7605
7757
  this.currentFieldName = name;
7758
+ this.validateFieldName(name, "output");
7606
7759
  let isOptional = false;
7607
7760
  let isInternal = false;
7608
7761
  while (true) {
@@ -7625,25 +7778,86 @@ ${pointer}`;
7625
7778
  this.skipWhitespace();
7626
7779
  const classNamesString = this.parseParsedString();
7627
7780
  if (!classNamesString) {
7628
- throw new Error(
7629
- `Output field "${name}": Expected class names in quotes after "class" type. Example: class "MyClass1, MyClass2"`
7781
+ throw new SignatureValidationError(
7782
+ `Output field "${name}": Missing class options after "class" type`,
7783
+ this.position,
7784
+ this.getErrorContext(),
7785
+ 'Add class names in quotes. Example: class "positive, negative, neutral"'
7630
7786
  );
7631
7787
  }
7632
- const options = classNamesString.split(/[,\s]+/).map((s) => s.trim()).filter((s) => s.length > 0);
7788
+ const options = classNamesString.split(/[,\s]+/).map((s2) => s2.trim()).filter((s2) => s2.length > 0);
7633
7789
  if (options.length === 0) {
7634
- throw new Error(
7635
- `Output field "${name}": Empty class list provided. At least one class name is required`
7790
+ throw new SignatureValidationError(
7791
+ `Output field "${name}": Empty class list provided`,
7792
+ this.position,
7793
+ this.getErrorContext(),
7794
+ 'Provide at least one class option. Example: "positive, negative"'
7636
7795
  );
7637
7796
  }
7797
+ if (options.length === 1) {
7798
+ throw new SignatureValidationError(
7799
+ `Output field "${name}": Class type needs at least 2 options`,
7800
+ this.position,
7801
+ this.getErrorContext(),
7802
+ 'Add more class options or use "string" type instead. Example: "positive, negative, neutral"'
7803
+ );
7804
+ }
7805
+ for (const option of options) {
7806
+ if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(option)) {
7807
+ throw new SignatureValidationError(
7808
+ `Output field "${name}": Invalid class option "${option}"`,
7809
+ this.position,
7810
+ this.getErrorContext(),
7811
+ "Class options must start with a letter and contain only letters, numbers, underscores, or hyphens"
7812
+ );
7813
+ }
7814
+ }
7638
7815
  type = { name: "class", isArray, options };
7639
7816
  } else {
7640
7817
  try {
7641
7818
  const typeName = this.parseTypeNotClass();
7642
7819
  const isArray = this.match("[]");
7643
7820
  type = { name: typeName, isArray };
7821
+ if (typeName === "image" && isArray) {
7822
+ throw new SignatureValidationError(
7823
+ `Output field "${name}": Arrays of images are not supported`,
7824
+ this.position,
7825
+ this.getErrorContext(),
7826
+ 'Use a single image type instead: "image"'
7827
+ );
7828
+ }
7829
+ if (typeName === "audio" && isArray) {
7830
+ throw new SignatureValidationError(
7831
+ `Output field "${name}": Arrays of audio are not supported`,
7832
+ this.position,
7833
+ this.getErrorContext(),
7834
+ 'Use a single audio type instead: "audio"'
7835
+ );
7836
+ }
7837
+ if (typeName === "image") {
7838
+ throw new SignatureValidationError(
7839
+ `Output field "${name}": Image type is not supported in output fields`,
7840
+ this.position,
7841
+ this.getErrorContext(),
7842
+ "Image types can only be used in input fields"
7843
+ );
7844
+ }
7845
+ if (typeName === "audio") {
7846
+ throw new SignatureValidationError(
7847
+ `Output field "${name}": Audio type is not supported in output fields`,
7848
+ this.position,
7849
+ this.getErrorContext(),
7850
+ "Audio types can only be used in input fields"
7851
+ );
7852
+ }
7644
7853
  } catch (error) {
7645
- throw new Error(
7646
- `Output field "${name}": ${error instanceof Error ? error.message : "Unknown error"}`
7854
+ if (error instanceof SignatureValidationError) {
7855
+ throw error;
7856
+ }
7857
+ throw new SignatureValidationError(
7858
+ `Output field "${name}": ${error instanceof Error ? error.message : "Unknown error"}`,
7859
+ this.position,
7860
+ this.getErrorContext()
7647
7861
  );
7648
7862
  }
7649
7863
  }
@@ -7658,6 +7872,69 @@ ${pointer}`;
7658
7872
  isInternal
7659
7873
  };
7660
7874
  }
7875
+ validateFieldName(name, fieldType) {
7876
+ if (axGlobals.signatureStrict) {
7877
+ const reservedNames = [
7878
+ "text",
7879
+ "object",
7880
+ "image",
7881
+ "string",
7882
+ "number",
7883
+ "boolean",
7884
+ "json",
7885
+ "array",
7886
+ "datetime",
7887
+ "date",
7888
+ "time",
7889
+ "type",
7890
+ "class",
7891
+ "input",
7892
+ "output",
7893
+ "data",
7894
+ "value",
7895
+ "result",
7896
+ "response",
7897
+ "request",
7898
+ "item",
7899
+ "element"
7900
+ ];
7901
+ if (reservedNames.includes(name.toLowerCase())) {
7902
+ const suggestions = fieldType === "input" ? ["userInput", "questionText", "documentContent", "messageText"] : ["responseText", "analysisResult", "categoryType", "summaryText"];
7903
+ throw new SignatureValidationError(
7904
+ `Field name "${name}" is too generic`,
7905
+ this.position,
7906
+ this.getErrorContext(),
7907
+ `Use a more descriptive name. Examples: ${suggestions.join(", ")}`
7908
+ );
7909
+ }
7910
+ }
7911
+ const camelCaseRegex = /^[a-z][a-zA-Z0-9]*$/;
7912
+ const snakeCaseRegex = /^[a-z]+(_[a-z0-9]+)*$/;
7913
+ if (!camelCaseRegex.test(name) && !snakeCaseRegex.test(name)) {
7914
+ throw new SignatureValidationError(
7915
+ `Invalid field name "${name}"`,
7916
+ this.position,
7917
+ this.getErrorContext(),
7918
+ 'Field names must be in camelCase (e.g., "userInput") or snake_case (e.g., "user_input")'
7919
+ );
7920
+ }
7921
+ if (name.length < 2) {
7922
+ throw new SignatureValidationError(
7923
+ `Field name "${name}" is too short`,
7924
+ this.position,
7925
+ this.getErrorContext(),
7926
+ "Field names must be at least 2 characters long"
7927
+ );
7928
+ }
7929
+ if (name.length > 50) {
7930
+ throw new SignatureValidationError(
7931
+ `Field name "${name}" is too long (${name.length} characters)`,
7932
+ this.position,
7933
+ this.getErrorContext(),
7934
+ "Field names should be 50 characters or less"
7935
+ );
7936
+ }
7937
+ }
7661
7938
  parseTypeNotClass() {
7662
7939
  const types = [
7663
7940
  "string",
@@ -7672,13 +7949,42 @@ ${pointer}`;
7672
7949
  ];
7673
7950
  const foundType = types.find((type) => this.match(type));
7674
7951
  if (!foundType) {
7675
- const currentWord = this.input.slice(this.position).match(/^\w+/)?.[0] || "empty";
7676
- throw new Error(
7677
- `Invalid type "${currentWord}". Expected one of: ${types.join(", ")}`
7952
+ const currentWord = this.input.slice(this.position).match(/^\w+/)?.[0] || "";
7953
+ const suggestion = this.suggestType(currentWord);
7954
+ const baseMessage = `Invalid type "${currentWord || "empty"}"`;
7955
+ const suggestionPart = suggestion ? `. Did you mean "${suggestion}"?` : "";
7956
+ const fullMessage = `${baseMessage}${suggestionPart}`;
7957
+ throw new SignatureValidationError(
7958
+ fullMessage,
7959
+ this.position,
7960
+ this.getErrorContext(),
7961
+ `Expected one of: ${types.join(", ")}`
7678
7962
  );
7679
7963
  }
7680
7964
  return foundType;
7681
7965
  }
7966
+ suggestType(input) {
7967
+ const suggestions = {
7968
+ str: "string",
7969
+ text: "string",
7970
+ int: "number",
7971
+ integer: "number",
7972
+ float: "number",
7973
+ double: "number",
7974
+ bool: "boolean",
7975
+ object: "json",
7976
+ dict: "json",
7977
+ timestamp: "datetime",
7978
+ time: "datetime",
7979
+ img: "image",
7980
+ picture: "image",
7981
+ sound: "audio",
7982
+ voice: "audio",
7983
+ classification: "class",
7984
+ category: "class"
7985
+ };
7986
+ return suggestions[input.toLowerCase()] || null;
7987
+ }
7682
7988
  parseParsedIdentifier() {
7683
7989
  this.skipWhitespace();
7684
7990
  const match = /^[a-zA-Z_][a-zA-Z_0-9]*/.exec(
@@ -7689,9 +7995,28 @@ ${pointer}`;
7689
7995
  return match[0];
7690
7996
  }
7691
7997
  const invalidMatch = /^\S+/.exec(this.input.slice(this.position));
7692
- const invalidId = invalidMatch ? invalidMatch[0] : "empty";
7693
- throw new Error(
7694
- `Invalid identifier "${invalidId}". Identifiers must start with a letter or underscore and contain only letters, numbers, or underscores`
7998
+ const invalidId = invalidMatch ? invalidMatch[0] : "";
7999
+ if (invalidId === "") {
8000
+ throw new SignatureValidationError(
8001
+ "Expected field name but found end of input",
8002
+ this.position,
8003
+ this.getErrorContext(),
8004
+ "Add a field name. Field names must start with a letter or underscore"
8005
+ );
8006
+ }
8007
+ if (/^\d/.test(invalidId)) {
8008
+ throw new SignatureValidationError(
8009
+ `Invalid field name "${invalidId}" - cannot start with a number`,
8010
+ this.position,
8011
+ this.getErrorContext(),
8012
+ 'Field names must start with a letter or underscore. Example: "userInput" or "_internal"'
8013
+ );
8014
+ }
8015
+ throw new SignatureValidationError(
8016
+ `Invalid field name "${invalidId}"`,
8017
+ this.position,
8018
+ this.getErrorContext(),
8019
+ "Field names must start with a letter or underscore and contain only letters, numbers, or underscores"
7695
8020
  );
7696
8021
  }
7697
8022
  parseParsedString() {
@@ -7700,7 +8025,7 @@ ${pointer}`;
7700
8025
  if (this.match(quoteChar)) {
7701
8026
  let content = "";
7702
8027
  let escaped = false;
7703
- let startPos = this.position;
8028
+ const startPos = this.position - 1;
7704
8029
  while (this.position < this.input.length) {
7705
8030
  const char = this.input[this.position];
7706
8031
  this.position++;
@@ -7715,9 +8040,15 @@ ${pointer}`;
7715
8040
  content += char;
7716
8041
  }
7717
8042
  }
7718
- const partialString = this.input.slice(startPos, this.position);
7719
- throw new Error(
7720
- `Unterminated string starting at position ${startPos}: "${partialString}..."`
8043
+ const partialString = this.input.slice(
8044
+ startPos,
8045
+ Math.min(this.position, startPos + 20)
8046
+ );
8047
+ throw new SignatureValidationError(
8048
+ `Unterminated string starting at position ${startPos}`,
8049
+ startPos,
8050
+ this.getErrorContext(),
8051
+ `Add closing ${quoteChar} to complete the string: ${partialString}${quoteChar}`
7721
8052
  );
7722
8053
  }
7723
8054
  }
@@ -7745,11 +8076,15 @@ ${pointer}`;
7745
8076
  }
7746
8077
  return false;
7747
8078
  }
7748
- expect(str) {
7749
- if (!this.match(str)) {
8079
+ expectArrow() {
8080
+ if (!this.match("->")) {
7750
8081
  const found = this.input.slice(this.position, this.position + 10);
7751
- throw new Error(
7752
- `Expected "${str}" but found "${found}..." at position ${this.position}`
8082
+ const suggestion = found.includes(">") ? 'Use "->" (dash followed by greater-than)' : found.includes("-") ? 'Add ">" after the dash' : 'Add "->" to separate input and output fields';
8083
+ throw new SignatureValidationError(
8084
+ `Expected "->" but found "${found}..."`,
8085
+ this.position,
8086
+ this.getErrorContext(),
8087
+ suggestion
7753
8088
  );
7754
8089
  }
7755
8090
  }
@@ -7760,6 +8095,14 @@ function parseSignature(input) {
7760
8095
  }
7761
8096
 
7762
8097
  // dsp/sig.ts
8098
+ var AxSignatureValidationError = class extends Error {
8099
+ constructor(message, fieldName, suggestion) {
8100
+ super(message);
8101
+ this.fieldName = fieldName;
8102
+ this.suggestion = suggestion;
8103
+ this.name = "AxSignatureValidationError";
8104
+ }
8105
+ };
7763
8106
  var AxSignature = class _AxSignature {
7764
8107
  description;
7765
8108
  inputFields;
@@ -7779,8 +8122,18 @@ var AxSignature = class _AxSignature {
7779
8122
  try {
7780
8123
  sig = parseSignature(signature);
7781
8124
  } catch (e) {
7782
- throw new Error(
7783
- `Invalid Signature: ${e.message} (${signature})`
8125
+ if (e instanceof Error) {
8126
+ const suggestion = "suggestion" in e && typeof e.suggestion === "string" ? e.suggestion : 'Please check the signature format. Example: "userInput:string -> responseText:string"';
8127
+ throw new AxSignatureValidationError(
8128
+ `Invalid Signature: ${e.message}`,
8129
+ void 0,
8130
+ suggestion
8131
+ );
8132
+ }
8133
+ throw new AxSignatureValidationError(
8134
+ `Invalid Signature: ${signature}`,
8135
+ void 0,
8136
+ 'Please check the signature format. Example: "userInput:string -> responseText:string"'
7784
8137
  );
7785
8138
  }
7786
8139
  this.description = sig.desc;
@@ -7798,12 +8151,20 @@ var AxSignature = class _AxSignature {
7798
8151
  this.sigHash = signature.hash();
7799
8152
  this.sigString = signature.toString();
7800
8153
  } else {
7801
- throw new Error("invalid signature argument: " + signature);
8154
+ throw new AxSignatureValidationError(
8155
+ "Invalid signature argument type",
8156
+ void 0,
8157
+ "Signature must be a string or another AxSignature instance"
8158
+ );
7802
8159
  }
7803
8160
  }
7804
8161
  parseParsedField = (field) => {
7805
8162
  if (!field.name || field.name.length === 0) {
7806
- throw new Error("Field name is required.");
8163
+ throw new AxSignatureValidationError(
8164
+ "Field name is required",
8165
+ field.name,
8166
+ 'Every field must have a descriptive name. Example: "userInput", "responseText"'
8167
+ );
7807
8168
  }
7808
8169
  const title = this.toTitle(field.name);
7809
8170
  return {
@@ -7818,29 +8179,106 @@ var AxSignature = class _AxSignature {
7818
8179
  parseField = (field) => {
7819
8180
  const title = !field.title || field.title.length === 0 ? this.toTitle(field.name) : field.title;
7820
8181
  if (field.type && (!field.type.name || field.type.name.length === 0)) {
7821
- throw new Error("Field type name is required: " + field.name);
8182
+ throw new AxSignatureValidationError(
8183
+ "Field type name is required",
8184
+ field.name,
8185
+ "Specify a valid type. Available types: string, number, boolean, json, image, audio, date, datetime, class, code"
8186
+ );
7822
8187
  }
7823
8188
  return { ...field, title };
7824
8189
  };
7825
8190
  setDescription = (desc) => {
8191
+ if (typeof desc !== "string") {
8192
+ throw new AxSignatureValidationError(
8193
+ "Description must be a string",
8194
+ void 0,
8195
+ "Provide a string description for the signature"
8196
+ );
8197
+ }
7826
8198
  this.description = desc;
7827
8199
  this.updateHash();
7828
8200
  };
7829
8201
  addInputField = (field) => {
7830
- this.inputFields.push(this.parseField(field));
7831
- this.updateHash();
8202
+ try {
8203
+ const parsedField = this.parseField(field);
8204
+ validateField(parsedField, "input");
8205
+ this.inputFields.push(parsedField);
8206
+ this.updateHash();
8207
+ } catch (error) {
8208
+ if (error instanceof AxSignatureValidationError) {
8209
+ throw error;
8210
+ }
8211
+ throw new AxSignatureValidationError(
8212
+ `Failed to add input field "${field.name}": ${error instanceof Error ? error.message : "Unknown error"}`,
8213
+ field.name
8214
+ );
8215
+ }
7832
8216
  };
7833
8217
  addOutputField = (field) => {
7834
- this.outputFields.push(this.parseField(field));
7835
- this.updateHash();
8218
+ try {
8219
+ const parsedField = this.parseField(field);
8220
+ validateField(parsedField, "output");
8221
+ this.outputFields.push(parsedField);
8222
+ this.updateHash();
8223
+ } catch (error) {
8224
+ if (error instanceof AxSignatureValidationError) {
8225
+ throw error;
8226
+ }
8227
+ throw new AxSignatureValidationError(
8228
+ `Failed to add output field "${field.name}": ${error instanceof Error ? error.message : "Unknown error"}`,
8229
+ field.name
8230
+ );
8231
+ }
7836
8232
  };
7837
8233
  setInputFields = (fields) => {
7838
- this.inputFields = fields.map((v) => this.parseField(v));
7839
- this.updateHash();
8234
+ if (!Array.isArray(fields)) {
8235
+ throw new AxSignatureValidationError(
8236
+ "Input fields must be an array",
8237
+ void 0,
8238
+ "Provide an array of field objects"
8239
+ );
8240
+ }
8241
+ try {
8242
+ const parsedFields = fields.map((v) => {
8243
+ const parsed = this.parseField(v);
8244
+ validateField(parsed, "input");
8245
+ return parsed;
8246
+ });
8247
+ this.inputFields = parsedFields;
8248
+ this.updateHash();
8249
+ } catch (error) {
8250
+ if (error instanceof AxSignatureValidationError) {
8251
+ throw error;
8252
+ }
8253
+ throw new AxSignatureValidationError(
8254
+ `Failed to set input fields: ${error instanceof Error ? error.message : "Unknown error"}`
8255
+ );
8256
+ }
7840
8257
  };
7841
8258
  setOutputFields = (fields) => {
7842
- this.outputFields = fields.map((v) => this.parseField(v));
7843
- this.updateHash();
8259
+ if (!Array.isArray(fields)) {
8260
+ throw new AxSignatureValidationError(
8261
+ "Output fields must be an array",
8262
+ void 0,
8263
+ "Provide an array of field objects"
8264
+ );
8265
+ }
8266
+ try {
8267
+ const parsedFields = fields.map((v) => {
8268
+ const parsed = this.parseField(v);
8269
+ validateField(parsed, "output");
8270
+ return parsed;
8271
+ });
8272
+ this.outputFields = parsedFields;
8273
+ this.updateHash();
8274
+ } catch (error) {
8275
+ if (error instanceof AxSignatureValidationError) {
8276
+ throw error;
8277
+ }
8278
+ throw new AxSignatureValidationError(
8279
+ `Failed to set output fields: ${error instanceof Error ? error.message : "Unknown error"}`
8280
+ );
8281
+ }
7844
8282
  };
7845
8283
  getInputFields = () => this.inputFields;
7846
8284
  getOutputFields = () => this.outputFields;
@@ -7853,25 +8291,25 @@ var AxSignature = class _AxSignature {
7853
8291
  toJSONSchema = () => {
7854
8292
  const properties = {};
7855
8293
  const required = [];
7856
- for (const f of this.inputFields) {
7857
- const type = f.type ? f.type.name : "string";
7858
- if (f.type?.isArray) {
7859
- properties[f.name] = {
7860
- description: f.description,
8294
+ for (const f2 of this.inputFields) {
8295
+ const type = f2.type ? f2.type.name : "string";
8296
+ if (f2.type?.isArray) {
8297
+ properties[f2.name] = {
8298
+ description: f2.description,
7861
8299
  type: "array",
7862
8300
  items: {
7863
8301
  type,
7864
- description: f.description
8302
+ description: f2.description
7865
8303
  }
7866
8304
  };
7867
8305
  } else {
7868
- properties[f.name] = {
7869
- description: f.description,
8306
+ properties[f2.name] = {
8307
+ description: f2.description,
7870
8308
  type
7871
8309
  };
7872
8310
  }
7873
- if (!f.isOptional) {
7874
- required.push(f.name);
8311
+ if (!f2.isOptional) {
8312
+ required.push(f2.name);
7875
8313
  }
7876
8314
  }
7877
8315
  const schema = {
@@ -7882,23 +8320,77 @@ var AxSignature = class _AxSignature {
7882
8320
  return schema;
7883
8321
  };
7884
8322
  updateHash = () => {
7885
- this.getInputFields().forEach((field) => {
7886
- validateField(field);
7887
- });
7888
- this.getOutputFields().forEach((field) => {
7889
- validateField(field);
7890
- if (field.type?.name === "image") {
7891
- throw new Error("Image type is not supported in output fields.");
8323
+ try {
8324
+ this.getInputFields().forEach((field) => {
8325
+ validateField(field, "input");
8326
+ });
8327
+ this.getOutputFields().forEach((field) => {
8328
+ validateField(field, "output");
8329
+ });
8330
+ this.validateSignatureConsistency();
8331
+ this.sigHash = (0, import_crypto3.createHash)("sha256").update(this.description ?? "").update(JSON.stringify(this.inputFields)).update(JSON.stringify(this.outputFields)).digest("hex");
8332
+ this.sigString = renderSignature(
8333
+ this.description,
8334
+ this.inputFields,
8335
+ this.outputFields
8336
+ );
8337
+ return [this.sigHash, this.sigString];
8338
+ } catch (error) {
8339
+ if (error instanceof AxSignatureValidationError) {
8340
+ throw error;
7892
8341
  }
7893
- });
7894
- this.sigHash = (0, import_crypto3.createHash)("sha256").update(this.description ?? "").update(JSON.stringify(this.inputFields)).update(JSON.stringify(this.outputFields)).digest("hex");
7895
- this.sigString = renderSignature(
7896
- this.description,
7897
- this.inputFields,
7898
- this.outputFields
7899
- );
7900
- return [this.sigHash, this.sigString];
8342
+ throw new AxSignatureValidationError(
8343
+ `Signature validation failed: ${error instanceof Error ? error.message : "Unknown error"}`
8344
+ );
8345
+ }
7901
8346
  };
8347
+ validateSignatureConsistency() {
8348
+ const inputNames = /* @__PURE__ */ new Set();
8349
+ for (const field of this.inputFields) {
8350
+ if (inputNames.has(field.name)) {
8351
+ throw new AxSignatureValidationError(
8352
+ `Duplicate input field name: "${field.name}"`,
8353
+ field.name,
8354
+ "Each field name must be unique within the signature"
8355
+ );
8356
+ }
8357
+ inputNames.add(field.name);
8358
+ }
8359
+ const outputNames = /* @__PURE__ */ new Set();
8360
+ for (const field of this.outputFields) {
8361
+ if (outputNames.has(field.name)) {
8362
+ throw new AxSignatureValidationError(
8363
+ `Duplicate output field name: "${field.name}"`,
8364
+ field.name,
8365
+ "Each field name must be unique within the signature"
8366
+ );
8367
+ }
8368
+ outputNames.add(field.name);
8369
+ }
8370
+ for (const outputField of this.outputFields) {
8371
+ if (inputNames.has(outputField.name)) {
8372
+ throw new AxSignatureValidationError(
8373
+ `Field name "${outputField.name}" appears in both inputs and outputs`,
8374
+ outputField.name,
8375
+ "Use different names for input and output fields to avoid confusion"
8376
+ );
8377
+ }
8378
+ }
8379
+ if (this.inputFields.length === 0) {
8380
+ throw new AxSignatureValidationError(
8381
+ "Signature must have at least one input field",
8382
+ void 0,
8383
+ 'Add an input field. Example: "userInput:string -> ..."'
8384
+ );
8385
+ }
8386
+ if (this.outputFields.length === 0) {
8387
+ throw new AxSignatureValidationError(
8388
+ "Signature must have at least one output field",
8389
+ void 0,
8390
+ 'Add an output field. Example: "... -> responseText:string"'
8391
+ );
8392
+ }
8393
+ }
7902
8394
  hash = () => this.sigHash;
7903
8395
  toString = () => this.sigString;
7904
8396
  toJSON = () => {
@@ -7915,54 +8407,194 @@ function renderField(field) {
7915
8407
  if (field.isOptional) {
7916
8408
  result += "?";
7917
8409
  }
8410
+ if (field.isInternal) {
8411
+ result += "!";
8412
+ }
7918
8413
  if (field.type) {
7919
8414
  result += ":" + field.type.name;
7920
8415
  if (field.type.isArray) {
7921
8416
  result += "[]";
7922
8417
  }
8418
+ if (field.type.name === "class" && field.type.options) {
8419
+ result += ` "${field.type.options.join(", ")}"`;
8420
+ }
7923
8421
  }
7924
- if (field.description) {
8422
+ if (field.description && field.type?.name !== "class") {
7925
8423
  result += ` "${field.description}"`;
7926
8424
  }
7927
8425
  return result;
7928
8426
  }
7929
8427
  function renderSignature(description, inputFields, outputFields) {
7930
- const descriptionPart = description ? `"${description}"` : "";
8428
+ const descriptionPart = description ? `"${description}" ` : "";
7931
8429
  const inputFieldsRendered = inputFields.map(renderField).join(", ");
7932
8430
  const outputFieldsRendered = outputFields.map(renderField).join(", ");
7933
- return `${descriptionPart} ${inputFieldsRendered} -> ${outputFieldsRendered}`;
8431
+ return `${descriptionPart}${inputFieldsRendered} -> ${outputFieldsRendered}`;
7934
8432
  }
7935
8433
  function isValidCase(inputString) {
7936
8434
  const camelCaseRegex = /^[a-z][a-zA-Z0-9]*$/;
7937
8435
  const snakeCaseRegex = /^[a-z]+(_[a-z0-9]+)*$/;
7938
8436
  return camelCaseRegex.test(inputString) || snakeCaseRegex.test(inputString);
7939
8437
  }
7940
- function validateField(field) {
8438
+ function validateField(field, context3) {
7941
8439
  if (!field.name || field.name.length === 0) {
7942
- throw new Error("Field name cannot be blank");
8440
+ throw new AxSignatureValidationError(
8441
+ "Field name cannot be blank",
8442
+ field.name,
8443
+ "Every field must have a descriptive name"
8444
+ );
7943
8445
  }
7944
8446
  if (!isValidCase(field.name)) {
7945
- throw new Error(
7946
- `Invalid field name '${field.name}', it must be camel case or snake case: `
8447
+ throw new AxSignatureValidationError(
8448
+ `Invalid field name '${field.name}' - must be camelCase or snake_case`,
8449
+ field.name,
8450
+ 'Use camelCase (e.g., "userInput") or snake_case (e.g., "user_input")'
7947
8451
  );
7948
8452
  }
7949
- if ([
7950
- "text",
7951
- "object",
7952
- "image",
7953
- "string",
7954
- "number",
7955
- "boolean",
7956
- "json",
7957
- "array",
7958
- "datetime",
7959
- "date",
7960
- "time",
7961
- "type",
7962
- "class"
7963
- ].includes(field.name)) {
7964
- throw new Error(
7965
- `Invalid field name '${field.name}', please make it more descriptive (eg. companyDescription)`
8453
+ if (axGlobals.signatureStrict) {
8454
+ const reservedNames = [
8455
+ "text",
8456
+ "object",
8457
+ "image",
8458
+ "string",
8459
+ "number",
8460
+ "boolean",
8461
+ "json",
8462
+ "array",
8463
+ "datetime",
8464
+ "date",
8465
+ "time",
8466
+ "type",
8467
+ "class",
8468
+ "input",
8469
+ "output",
8470
+ "data",
8471
+ "value",
8472
+ "result",
8473
+ "response",
8474
+ "request",
8475
+ "item",
8476
+ "element"
8477
+ ];
8478
+ if (reservedNames.includes(field.name.toLowerCase())) {
8479
+ const suggestions = context3 === "input" ? [
8480
+ "userInput",
8481
+ "questionText",
8482
+ "documentContent",
8483
+ "messageText",
8484
+ "queryString"
8485
+ ] : [
8486
+ "responseText",
8487
+ "analysisResult",
8488
+ "categoryType",
8489
+ "summaryText",
8490
+ "outputData"
8491
+ ];
8492
+ throw new AxSignatureValidationError(
8493
+ `Field name '${field.name}' is too generic`,
8494
+ field.name,
8495
+ `Use a more descriptive name. Examples for ${context3} fields: ${suggestions.join(", ")}`
8496
+ );
8497
+ }
8498
+ }
8499
+ if (field.name.length < 2) {
8500
+ throw new AxSignatureValidationError(
8501
+ `Field name '${field.name}' is too short`,
8502
+ field.name,
8503
+ "Field names must be at least 2 characters long"
8504
+ );
8505
+ }
8506
+ if (field.name.length > 50) {
8507
+ throw new AxSignatureValidationError(
8508
+ `Field name '${field.name}' is too long (${field.name.length} characters)`,
8509
+ field.name,
8510
+ "Field names should be 50 characters or less"
8511
+ );
8512
+ }
8513
+ if (field.type) {
8514
+ validateFieldType(field, context3);
8515
+ }
8516
+ }
8517
+ function validateFieldType(field, context3) {
8518
+ if (!field.type) return;
8519
+ const { type } = field;
8520
+ if (type.name === "image" || type.name === "audio") {
8521
+ if (context3 === "output") {
8522
+ throw new AxSignatureValidationError(
8523
+ `${type.name} type is not supported in output fields`,
8524
+ field.name,
8525
+ `${type.name} types can only be used in input fields`
8526
+ );
8527
+ }
8528
+ if (type.isArray) {
8529
+ throw new AxSignatureValidationError(
8530
+ `Arrays of ${type.name} are not supported`,
8531
+ field.name,
8532
+ `Use a single ${type.name} type instead`
8533
+ );
8534
+ }
8535
+ }
8536
+ if (type.name === "class") {
8537
+ if (context3 === "input") {
8538
+ throw new AxSignatureValidationError(
8539
+ "Class type is not supported in input fields",
8540
+ field.name,
8541
+ 'Class types are only allowed on output fields. Use "string" type for input classifications'
8542
+ );
8543
+ }
8544
+ if (!type.options || type.options.length === 0) {
8545
+ throw new AxSignatureValidationError(
8546
+ "Class type requires options",
8547
+ field.name,
8548
+ 'Provide class options. Example: class "positive, negative, neutral"'
8549
+ );
8550
+ }
8551
+ if (type.options.length === 1) {
8552
+ throw new AxSignatureValidationError(
8553
+ "Class type needs at least 2 options",
8554
+ field.name,
8555
+ 'Add more class options or use "string" type instead'
8556
+ );
8557
+ }
8558
+ for (const option of type.options) {
8559
+ if (!option || option.trim().length === 0) {
8560
+ throw new AxSignatureValidationError(
8561
+ "Empty class option found",
8562
+ field.name,
8563
+ "All class options must be non-empty strings"
8564
+ );
8565
+ }
8566
+ const trimmedOption = option.trim();
8567
+ if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(trimmedOption)) {
8568
+ throw new AxSignatureValidationError(
8569
+ `Invalid class option "${trimmedOption}"`,
8570
+ field.name,
8571
+ "Class options must start with a letter and contain only letters, numbers, underscores, or hyphens"
8572
+ );
8573
+ }
8574
+ }
8575
+ const uniqueOptions = new Set(
8576
+ type.options.map((opt) => opt.trim().toLowerCase())
8577
+ );
8578
+ if (uniqueOptions.size !== type.options.length) {
8579
+ throw new AxSignatureValidationError(
8580
+ "Duplicate class options found",
8581
+ field.name,
8582
+ "Each class option must be unique (case-insensitive)"
8583
+ );
8584
+ }
8585
+ }
8586
+ if (type.name === "code" && type.isArray) {
8587
+ throw new AxSignatureValidationError(
8588
+ "Arrays of code are not commonly supported",
8589
+ field.name,
8590
+ "Consider using a single code field or an array of strings instead"
8591
+ );
8592
+ }
8593
+ if (field.isInternal && context3 === "input") {
8594
+ throw new AxSignatureValidationError(
8595
+ "Internal marker (!) is not allowed on input fields",
8596
+ field.name,
8597
+ "Internal markers are only allowed on output fields"
7966
8598
  );
7967
8599
  }
7968
8600
  }
@@ -8037,11 +8669,11 @@ var AxProgramWithSignature = class {
8037
8669
  const fields = [...sig.getInputFields(), ...sig.getOutputFields()];
8038
8670
  this.examples = traces.map((e) => {
8039
8671
  const res = {};
8040
- for (const f of fields) {
8041
- const value = e[f.name];
8672
+ for (const f2 of fields) {
8673
+ const value = e[f2.name];
8042
8674
  if (value !== void 0) {
8043
- validateValue(f, value);
8044
- res[f.name] = value;
8675
+ validateValue(f2, value);
8676
+ res[f2.name] = value;
8045
8677
  }
8046
8678
  }
8047
8679
  return res;
@@ -8195,7 +8827,7 @@ var AxGen = class extends AxProgramWithSignature {
8195
8827
  this.streamingAsserts.push({ fieldName, fn, message });
8196
8828
  };
8197
8829
  addFieldProcessorInternal = (fieldName, fn, streaming = false) => {
8198
- const field = this.signature.getOutputFields().find((f) => f.name === fieldName);
8830
+ const field = this.signature.getOutputFields().find((f2) => f2.name === fieldName);
8199
8831
  if (!field) {
8200
8832
  throw new Error(`addFieldProcessor: field ${fieldName} not found`);
8201
8833
  }
@@ -8241,7 +8873,7 @@ var AxGen = class extends AxProgramWithSignature {
8241
8873
  if (chatPrompt.length === 0) {
8242
8874
  throw new Error("No chat prompt found");
8243
8875
  }
8244
- const functions = _functions?.map((f) => "toFunction" in f ? f.toFunction() : f)?.flat();
8876
+ const functions = _functions?.map((f2) => "toFunction" in f2 ? f2.toFunction() : f2)?.flat();
8245
8877
  let functionCall = _functionCall ?? this.options?.functionCall;
8246
8878
  if (!firstStep && (functionCall === "required" || typeof functionCall === "function")) {
8247
8879
  functionCall = void 0;
@@ -8279,7 +8911,7 @@ var AxGen = class extends AxProgramWithSignature {
8279
8911
  const { sessionId, traceId, functions: _functions } = options ?? {};
8280
8912
  const fastFail = options?.fastFail ?? this.options?.fastFail;
8281
8913
  const model = options.model;
8282
- const functions = _functions?.map((f) => "toFunction" in f ? f.toFunction() : f)?.flat();
8914
+ const functions = _functions?.map((f2) => "toFunction" in f2 ? f2.toFunction() : f2)?.flat();
8283
8915
  const res = await this.forwardSendRequest({
8284
8916
  ai,
8285
8917
  mem,
@@ -8604,7 +9236,7 @@ Content: ${result.content}`
8604
9236
  if (span) {
8605
9237
  span.addEvent("validation.error", {
8606
9238
  message: e.toString(),
8607
- fixing_instructions: errorFields?.map((f) => f.title).join(", ") ?? ""
9239
+ fixing_instructions: errorFields?.map((f2) => f2.title).join(", ") ?? ""
8608
9240
  });
8609
9241
  }
8610
9242
  } else if (e instanceof AxAssertionError) {
@@ -8614,7 +9246,7 @@ Content: ${result.content}`
8614
9246
  if (span) {
8615
9247
  span.addEvent("assertion.error", {
8616
9248
  message: e1.toString(),
8617
- fixing_instructions: errorFields?.map((f) => f.title).join(", ") ?? ""
9249
+ fixing_instructions: errorFields?.map((f2) => f2.title).join(", ") ?? ""
8618
9250
  });
8619
9251
  }
8620
9252
  } else if (e instanceof AxAIServiceStreamTerminatedError) {
@@ -8669,7 +9301,7 @@ Content: ${result.content}`
8669
9301
  });
8670
9302
  return;
8671
9303
  }
8672
- const funcNames = functions?.map((f) => f.name).join(",");
9304
+ const funcNames = functions?.map((f2) => f2.name).join(",");
8673
9305
  const attributes = {
8674
9306
  signature: JSON.stringify(this.signature.toJSON(), null, 2),
8675
9307
  ...this.examples ? { examples: JSON.stringify(this.examples, null, 2) } : {},
@@ -8928,7 +9560,7 @@ var AxAgent = class {
8928
9560
  const sig = this.program.getSignature();
8929
9561
  const outFields = sig.getOutputFields();
8930
9562
  const result = Object.keys(ret).map((k) => {
8931
- const field = outFields.find((f) => f.name === k);
9563
+ const field = outFields.find((f2) => f2.name === k);
8932
9564
  if (field) {
8933
9565
  return `${field.title}: ${ret[k]}`;
8934
9566
  }
@@ -8957,12 +9589,12 @@ var AxAgent = class {
8957
9589
  const parentKeys = parentSchema.map((p) => p.name);
8958
9590
  const debug = this.getDebug(ai, options);
8959
9591
  const agentFuncs = this.agents?.map((agent) => {
8960
- const f = agent.getFeatures();
9592
+ const f2 = agent.getFeatures();
8961
9593
  const processOptions = {
8962
9594
  debug,
8963
9595
  disableSmartModelRouting: !!this.disableSmartModelRouting,
8964
- excludeFieldsFromPassthrough: f.excludeFieldsFromPassthrough,
8965
- canConfigureSmartModelRouting: f.canConfigureSmartModelRouting
9596
+ excludeFieldsFromPassthrough: f2.excludeFieldsFromPassthrough,
9597
+ canConfigureSmartModelRouting: f2.canConfigureSmartModelRouting
8966
9598
  };
8967
9599
  return processChildAgentFunction(
8968
9600
  agent.getFunction(),
@@ -11695,13 +12327,18 @@ var AxMockAIService = class {
11695
12327
  }
11696
12328
  };
11697
12329
  getLastUsedChatModel() {
11698
- throw new Error("Method not implemented.");
12330
+ return this.config.modelInfo?.name ?? "mock-model";
11699
12331
  }
11700
12332
  getLastUsedEmbedModel() {
11701
- throw new Error("Method not implemented.");
12333
+ return this.config.embedModelInfo?.name ?? "mock-embed-model";
11702
12334
  }
11703
12335
  getLastUsedModelConfig() {
11704
- throw new Error("Method not implemented.");
12336
+ return this.config.modelInfo ? {
12337
+ maxTokens: this.config.modelInfo.maxTokens,
12338
+ temperature: 0.7,
12339
+ // Default temperature
12340
+ stream: this.config.features?.streaming ?? false
12341
+ } : void 0;
11705
12342
  }
11706
12343
  getName() {
11707
12344
  return this.config.name ?? "mock-ai-service";
@@ -11934,7 +12571,7 @@ var AxTestPrompt = class {
11934
12571
  };
11935
12572
 
11936
12573
  // dsp/template.ts
11937
- function ax(strings, ...values) {
12574
+ function s(strings, ...values) {
11938
12575
  let result = "";
11939
12576
  for (let i = 0; i < strings.length; i++) {
11940
12577
  result += strings[i] ?? "";
@@ -11962,6 +12599,34 @@ function ax(strings, ...values) {
11962
12599
  }
11963
12600
  return new AxSignature(result);
11964
12601
  }
12602
+ function ax(strings, ...values) {
12603
+ let result = "";
12604
+ for (let i = 0; i < strings.length; i++) {
12605
+ result += strings[i] ?? "";
12606
+ if (i < values.length) {
12607
+ const val = values[i];
12608
+ if (isAxFieldType(val)) {
12609
+ const fieldNameMatch = result.match(/(\w+)\s*:\s*$/);
12610
+ if (fieldNameMatch && (val.isOptional || val.isInternal)) {
12611
+ const fieldName = fieldNameMatch[1];
12612
+ let modifiedFieldName = fieldName;
12613
+ if (val.isOptional) modifiedFieldName += "?";
12614
+ if (val.isInternal) modifiedFieldName += "!";
12615
+ result = result.replace(/(\w+)(\s*:\s*)$/, `${modifiedFieldName}$2`);
12616
+ }
12617
+ const { isOptional: _o, isInternal: _i, ...typeNoFlags } = val;
12618
+ result += convertFieldTypeToString(typeNoFlags);
12619
+ } else if (isAxFieldDescriptor(val)) {
12620
+ result += convertFieldDescriptorToString(val);
12621
+ } else if (typeof val === "string" || val instanceof AxSignature) {
12622
+ result += convertValueToSignatureString(val);
12623
+ } else {
12624
+ throw new Error("Unsupported template interpolation value");
12625
+ }
12626
+ }
12627
+ }
12628
+ return new AxGen(result);
12629
+ }
11965
12630
  function convertValueToSignatureString(value) {
11966
12631
  if (typeof value === "string") {
11967
12632
  return value;
@@ -12017,7 +12682,7 @@ function isAxFieldType(value) {
12017
12682
  function isAxFieldDescriptor(value) {
12018
12683
  return value !== null && typeof value === "object" && value !== void 0 && "name" in value && typeof value.name === "string";
12019
12684
  }
12020
- var axField = {
12685
+ var f = {
12021
12686
  string: (desc) => ({
12022
12687
  type: "string",
12023
12688
  description: desc
@@ -13398,12 +14063,12 @@ function countTokens(tokens) {
13398
14063
  }
13399
14064
  return counter;
13400
14065
  }
13401
- function normalizeText(s) {
13402
- s = s.normalize("NFD");
13403
- s = s.replace(/\b(a|an|the)\b/g, " ");
13404
- s = s.split(/\s+/).join(" ");
13405
- s = s.replace(/[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]/g, "");
13406
- return s.toLowerCase();
14066
+ function normalizeText(s2) {
14067
+ s2 = s2.normalize("NFD");
14068
+ s2 = s2.replace(/\b(a|an|the)\b/g, " ");
14069
+ s2 = s2.split(/\s+/).join(" ");
14070
+ s2 = s2.replace(/[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]/g, "");
14071
+ return s2.toLowerCase();
13407
14072
  }
13408
14073
  function emScore(prediction, groundTruth) {
13409
14074
  return normalizeText(prediction) === normalizeText(groundTruth) ? 1 : 0;
@@ -13817,7 +14482,7 @@ var AxMultiServiceRouter = class {
13817
14482
  * Returns a composite ID built from the IDs of the underlying services.
13818
14483
  */
13819
14484
  getId() {
13820
- return "MultiServiceRouter:" + Array.from(this.services.values()).map((s) => s.service.getId()).join(",");
14485
+ return "MultiServiceRouter:" + Array.from(this.services.values()).map((s2) => s2.service.getId()).join(",");
13821
14486
  }
13822
14487
  /**
13823
14488
  * Returns the name of this router.
@@ -14077,7 +14742,7 @@ var AxRAG = class extends AxChainOfThought {
14077
14742
  axAITogetherDefaultConfig,
14078
14743
  axBaseAIDefaultConfig,
14079
14744
  axBaseAIDefaultCreativeConfig,
14080
- axField,
14745
+ axGlobals,
14081
14746
  axModelInfoAnthropic,
14082
14747
  axModelInfoCohere,
14083
14748
  axModelInfoDeepSeek,
@@ -14090,6 +14755,8 @@ var AxRAG = class extends AxChainOfThought {
14090
14755
  axModelInfoReka,
14091
14756
  axModelInfoTogether,
14092
14757
  axSpanAttributes,
14093
- axSpanEvents
14758
+ axSpanEvents,
14759
+ f,
14760
+ s
14094
14761
  });
14095
14762
  //# sourceMappingURL=index.cjs.map