@ax-llm/ax 11.0.67 → 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 +740 -103
- package/index.cjs.map +1 -1
- package/index.d.cts +6 -1
- package/index.d.ts +6 -1
- package/index.js +739 -103
- package/index.js.map +1 -1
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -159,6 +159,7 @@ __export(index_exports, {
|
|
|
159
159
|
axAITogetherDefaultConfig: () => axAITogetherDefaultConfig,
|
|
160
160
|
axBaseAIDefaultConfig: () => axBaseAIDefaultConfig,
|
|
161
161
|
axBaseAIDefaultCreativeConfig: () => axBaseAIDefaultCreativeConfig,
|
|
162
|
+
axGlobals: () => axGlobals,
|
|
162
163
|
axModelInfoAnthropic: () => axModelInfoAnthropic,
|
|
163
164
|
axModelInfoCohere: () => axModelInfoCohere,
|
|
164
165
|
axModelInfoDeepSeek: () => axModelInfoDeepSeek,
|
|
@@ -6727,6 +6728,11 @@ var extractValues = (sig, values, content) => {
|
|
|
6727
6728
|
const xstate = { extractedFields: [], streamedIndex: {}, s: -1 };
|
|
6728
6729
|
streamingExtractValues(sig, values, xstate, content);
|
|
6729
6730
|
streamingExtractFinalValue(sig, values, xstate, content);
|
|
6731
|
+
for (const field of sig.getOutputFields()) {
|
|
6732
|
+
if (field.isInternal) {
|
|
6733
|
+
delete values[field.name];
|
|
6734
|
+
}
|
|
6735
|
+
}
|
|
6730
6736
|
};
|
|
6731
6737
|
var checkMissingRequiredFields = (xstate, values, currentIndex) => {
|
|
6732
6738
|
const missingFields = [];
|
|
@@ -7452,93 +7458,218 @@ var AxInstanceRegistry = class {
|
|
|
7452
7458
|
// dsp/sig.ts
|
|
7453
7459
|
var import_crypto3 = require("crypto");
|
|
7454
7460
|
|
|
7461
|
+
// dsp/globals.ts
|
|
7462
|
+
var axGlobals = {
|
|
7463
|
+
signatureStrict: true
|
|
7464
|
+
// Controls reservedNames enforcement in signature parsing/validation
|
|
7465
|
+
};
|
|
7466
|
+
|
|
7455
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
|
+
};
|
|
7456
7477
|
var SignatureParser = class {
|
|
7457
7478
|
input;
|
|
7458
7479
|
position;
|
|
7459
7480
|
currentFieldName = null;
|
|
7481
|
+
currentSection = "description";
|
|
7460
7482
|
constructor(input) {
|
|
7461
|
-
this.input = input;
|
|
7483
|
+
this.input = input.trim();
|
|
7462
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
|
+
}
|
|
7463
7493
|
}
|
|
7464
7494
|
parse() {
|
|
7465
7495
|
try {
|
|
7466
7496
|
this.skipWhitespace();
|
|
7467
7497
|
const optionalDesc = this.parseParsedString();
|
|
7468
7498
|
this.skipWhitespace();
|
|
7499
|
+
this.currentSection = "inputs";
|
|
7469
7500
|
const inputs = this.parseFieldList(
|
|
7470
7501
|
this.parseInputField.bind(this),
|
|
7471
7502
|
"input"
|
|
7472
7503
|
);
|
|
7473
7504
|
this.skipWhitespace();
|
|
7474
7505
|
if (this.position >= this.input.length) {
|
|
7475
|
-
throw new
|
|
7476
|
-
|
|
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"'
|
|
7477
7511
|
);
|
|
7478
7512
|
}
|
|
7479
|
-
this.
|
|
7513
|
+
this.expectArrow();
|
|
7480
7514
|
this.skipWhitespace();
|
|
7481
7515
|
if (this.position >= this.input.length) {
|
|
7482
|
-
throw new
|
|
7483
|
-
'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"'
|
|
7484
7521
|
);
|
|
7485
7522
|
}
|
|
7523
|
+
this.currentSection = "outputs";
|
|
7486
7524
|
const outputs = this.parseFieldList(
|
|
7487
7525
|
this.parseOutputField.bind(this),
|
|
7488
7526
|
"output"
|
|
7489
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
|
+
});
|
|
7490
7543
|
return {
|
|
7491
7544
|
desc: optionalDesc?.trim(),
|
|
7492
7545
|
inputs,
|
|
7493
7546
|
outputs
|
|
7494
7547
|
};
|
|
7495
7548
|
} catch (error) {
|
|
7549
|
+
if (error instanceof SignatureValidationError) {
|
|
7550
|
+
throw error;
|
|
7551
|
+
}
|
|
7496
7552
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
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
|
+
);
|
|
7500
7610
|
}
|
|
7501
7611
|
}
|
|
7502
7612
|
getErrorContext() {
|
|
7503
|
-
const start = Math.max(0, this.position -
|
|
7504
|
-
const end = Math.min(this.input.length, this.position +
|
|
7613
|
+
const start = Math.max(0, this.position - 25);
|
|
7614
|
+
const end = Math.min(this.input.length, this.position + 25);
|
|
7505
7615
|
const before = this.input.slice(start, this.position);
|
|
7506
7616
|
const after = this.input.slice(this.position, end);
|
|
7507
7617
|
const pointer = " ".repeat(before.length) + "^";
|
|
7508
|
-
|
|
7509
|
-
${
|
|
7510
|
-
${
|
|
7618
|
+
const lines = [
|
|
7619
|
+
`Position ${this.position} in signature:`,
|
|
7620
|
+
`"${before}${after}"`,
|
|
7621
|
+
` ${pointer}`
|
|
7622
|
+
];
|
|
7623
|
+
return lines.join("\n");
|
|
7511
7624
|
}
|
|
7512
7625
|
parseFieldList(parseFieldFn, section) {
|
|
7513
7626
|
const fields = [];
|
|
7514
7627
|
this.skipWhitespace();
|
|
7515
7628
|
if (this.position >= this.input.length) {
|
|
7516
|
-
throw new
|
|
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
|
+
);
|
|
7517
7635
|
}
|
|
7518
7636
|
try {
|
|
7519
7637
|
fields.push(parseFieldFn());
|
|
7520
7638
|
} catch (error) {
|
|
7521
|
-
|
|
7522
|
-
|
|
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()
|
|
7523
7646
|
);
|
|
7524
7647
|
}
|
|
7525
7648
|
this.skipWhitespace();
|
|
7526
7649
|
while (this.position < this.input.length) {
|
|
7527
|
-
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] === ">") {
|
|
7528
7651
|
break;
|
|
7529
7652
|
}
|
|
7530
7653
|
if (this.match(",")) {
|
|
7531
7654
|
this.skipWhitespace();
|
|
7532
7655
|
if (this.position >= this.input.length) {
|
|
7533
|
-
throw new
|
|
7534
|
-
`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`
|
|
7535
7661
|
);
|
|
7536
7662
|
}
|
|
7537
7663
|
try {
|
|
7538
7664
|
fields.push(parseFieldFn());
|
|
7539
7665
|
} catch (error) {
|
|
7540
|
-
|
|
7541
|
-
|
|
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()
|
|
7542
7673
|
);
|
|
7543
7674
|
}
|
|
7544
7675
|
this.skipWhitespace();
|
|
@@ -7555,6 +7686,7 @@ ${pointer}`;
|
|
|
7555
7686
|
this.skipWhitespace();
|
|
7556
7687
|
const name = this.parseParsedIdentifier();
|
|
7557
7688
|
this.currentFieldName = name;
|
|
7689
|
+
this.validateFieldName(name, "input");
|
|
7558
7690
|
let isOptional = void 0;
|
|
7559
7691
|
while (true) {
|
|
7560
7692
|
if (this.match("?")) {
|
|
@@ -7562,8 +7694,11 @@ ${pointer}`;
|
|
|
7562
7694
|
continue;
|
|
7563
7695
|
}
|
|
7564
7696
|
if (this.match("!")) {
|
|
7565
|
-
throw new
|
|
7566
|
-
`Input field "${name}"
|
|
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"
|
|
7567
7702
|
);
|
|
7568
7703
|
}
|
|
7569
7704
|
break;
|
|
@@ -7573,17 +7708,33 @@ ${pointer}`;
|
|
|
7573
7708
|
if (this.match(":")) {
|
|
7574
7709
|
this.skipWhitespace();
|
|
7575
7710
|
if (/^class\b/.test(this.input.slice(this.position))) {
|
|
7576
|
-
throw new
|
|
7577
|
-
`Input field "${name}"
|
|
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'
|
|
7578
7716
|
);
|
|
7579
7717
|
} else {
|
|
7580
7718
|
try {
|
|
7581
7719
|
const typeName = this.parseTypeNotClass();
|
|
7582
7720
|
const isArray = this.match("[]");
|
|
7583
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
|
+
}
|
|
7584
7730
|
} catch (error) {
|
|
7585
|
-
|
|
7586
|
-
|
|
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()
|
|
7587
7738
|
);
|
|
7588
7739
|
}
|
|
7589
7740
|
}
|
|
@@ -7604,6 +7755,7 @@ ${pointer}`;
|
|
|
7604
7755
|
this.skipWhitespace();
|
|
7605
7756
|
const name = this.parseParsedIdentifier();
|
|
7606
7757
|
this.currentFieldName = name;
|
|
7758
|
+
this.validateFieldName(name, "output");
|
|
7607
7759
|
let isOptional = false;
|
|
7608
7760
|
let isInternal = false;
|
|
7609
7761
|
while (true) {
|
|
@@ -7626,25 +7778,86 @@ ${pointer}`;
|
|
|
7626
7778
|
this.skipWhitespace();
|
|
7627
7779
|
const classNamesString = this.parseParsedString();
|
|
7628
7780
|
if (!classNamesString) {
|
|
7629
|
-
throw new
|
|
7630
|
-
`Output field "${name}":
|
|
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"'
|
|
7631
7786
|
);
|
|
7632
7787
|
}
|
|
7633
7788
|
const options = classNamesString.split(/[,\s]+/).map((s2) => s2.trim()).filter((s2) => s2.length > 0);
|
|
7634
7789
|
if (options.length === 0) {
|
|
7635
|
-
throw new
|
|
7636
|
-
`Output field "${name}": Empty class list provided
|
|
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"'
|
|
7637
7795
|
);
|
|
7638
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
|
+
}
|
|
7639
7815
|
type = { name: "class", isArray, options };
|
|
7640
7816
|
} else {
|
|
7641
7817
|
try {
|
|
7642
7818
|
const typeName = this.parseTypeNotClass();
|
|
7643
7819
|
const isArray = this.match("[]");
|
|
7644
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
|
+
}
|
|
7645
7853
|
} catch (error) {
|
|
7646
|
-
|
|
7647
|
-
|
|
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()
|
|
7648
7861
|
);
|
|
7649
7862
|
}
|
|
7650
7863
|
}
|
|
@@ -7659,6 +7872,69 @@ ${pointer}`;
|
|
|
7659
7872
|
isInternal
|
|
7660
7873
|
};
|
|
7661
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
|
+
}
|
|
7662
7938
|
parseTypeNotClass() {
|
|
7663
7939
|
const types = [
|
|
7664
7940
|
"string",
|
|
@@ -7673,13 +7949,42 @@ ${pointer}`;
|
|
|
7673
7949
|
];
|
|
7674
7950
|
const foundType = types.find((type) => this.match(type));
|
|
7675
7951
|
if (!foundType) {
|
|
7676
|
-
const currentWord = this.input.slice(this.position).match(/^\w+/)?.[0] || "
|
|
7677
|
-
|
|
7678
|
-
|
|
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(", ")}`
|
|
7679
7962
|
);
|
|
7680
7963
|
}
|
|
7681
7964
|
return foundType;
|
|
7682
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
|
+
}
|
|
7683
7988
|
parseParsedIdentifier() {
|
|
7684
7989
|
this.skipWhitespace();
|
|
7685
7990
|
const match = /^[a-zA-Z_][a-zA-Z_0-9]*/.exec(
|
|
@@ -7690,9 +7995,28 @@ ${pointer}`;
|
|
|
7690
7995
|
return match[0];
|
|
7691
7996
|
}
|
|
7692
7997
|
const invalidMatch = /^\S+/.exec(this.input.slice(this.position));
|
|
7693
|
-
const invalidId = invalidMatch ? invalidMatch[0] : "
|
|
7694
|
-
|
|
7695
|
-
|
|
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"
|
|
7696
8020
|
);
|
|
7697
8021
|
}
|
|
7698
8022
|
parseParsedString() {
|
|
@@ -7701,7 +8025,7 @@ ${pointer}`;
|
|
|
7701
8025
|
if (this.match(quoteChar)) {
|
|
7702
8026
|
let content = "";
|
|
7703
8027
|
let escaped = false;
|
|
7704
|
-
|
|
8028
|
+
const startPos = this.position - 1;
|
|
7705
8029
|
while (this.position < this.input.length) {
|
|
7706
8030
|
const char = this.input[this.position];
|
|
7707
8031
|
this.position++;
|
|
@@ -7716,9 +8040,15 @@ ${pointer}`;
|
|
|
7716
8040
|
content += char;
|
|
7717
8041
|
}
|
|
7718
8042
|
}
|
|
7719
|
-
const partialString = this.input.slice(
|
|
7720
|
-
|
|
7721
|
-
|
|
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}`
|
|
7722
8052
|
);
|
|
7723
8053
|
}
|
|
7724
8054
|
}
|
|
@@ -7746,11 +8076,15 @@ ${pointer}`;
|
|
|
7746
8076
|
}
|
|
7747
8077
|
return false;
|
|
7748
8078
|
}
|
|
7749
|
-
|
|
7750
|
-
if (!this.match(
|
|
8079
|
+
expectArrow() {
|
|
8080
|
+
if (!this.match("->")) {
|
|
7751
8081
|
const found = this.input.slice(this.position, this.position + 10);
|
|
7752
|
-
|
|
7753
|
-
|
|
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
|
|
7754
8088
|
);
|
|
7755
8089
|
}
|
|
7756
8090
|
}
|
|
@@ -7761,6 +8095,14 @@ function parseSignature(input) {
|
|
|
7761
8095
|
}
|
|
7762
8096
|
|
|
7763
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
|
+
};
|
|
7764
8106
|
var AxSignature = class _AxSignature {
|
|
7765
8107
|
description;
|
|
7766
8108
|
inputFields;
|
|
@@ -7780,8 +8122,18 @@ var AxSignature = class _AxSignature {
|
|
|
7780
8122
|
try {
|
|
7781
8123
|
sig = parseSignature(signature);
|
|
7782
8124
|
} catch (e) {
|
|
7783
|
-
|
|
7784
|
-
|
|
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"'
|
|
7785
8137
|
);
|
|
7786
8138
|
}
|
|
7787
8139
|
this.description = sig.desc;
|
|
@@ -7799,12 +8151,20 @@ var AxSignature = class _AxSignature {
|
|
|
7799
8151
|
this.sigHash = signature.hash();
|
|
7800
8152
|
this.sigString = signature.toString();
|
|
7801
8153
|
} else {
|
|
7802
|
-
throw new
|
|
8154
|
+
throw new AxSignatureValidationError(
|
|
8155
|
+
"Invalid signature argument type",
|
|
8156
|
+
void 0,
|
|
8157
|
+
"Signature must be a string or another AxSignature instance"
|
|
8158
|
+
);
|
|
7803
8159
|
}
|
|
7804
8160
|
}
|
|
7805
8161
|
parseParsedField = (field) => {
|
|
7806
8162
|
if (!field.name || field.name.length === 0) {
|
|
7807
|
-
throw new
|
|
8163
|
+
throw new AxSignatureValidationError(
|
|
8164
|
+
"Field name is required",
|
|
8165
|
+
field.name,
|
|
8166
|
+
'Every field must have a descriptive name. Example: "userInput", "responseText"'
|
|
8167
|
+
);
|
|
7808
8168
|
}
|
|
7809
8169
|
const title = this.toTitle(field.name);
|
|
7810
8170
|
return {
|
|
@@ -7819,29 +8179,106 @@ var AxSignature = class _AxSignature {
|
|
|
7819
8179
|
parseField = (field) => {
|
|
7820
8180
|
const title = !field.title || field.title.length === 0 ? this.toTitle(field.name) : field.title;
|
|
7821
8181
|
if (field.type && (!field.type.name || field.type.name.length === 0)) {
|
|
7822
|
-
throw new
|
|
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
|
+
);
|
|
7823
8187
|
}
|
|
7824
8188
|
return { ...field, title };
|
|
7825
8189
|
};
|
|
7826
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
|
+
}
|
|
7827
8198
|
this.description = desc;
|
|
7828
8199
|
this.updateHash();
|
|
7829
8200
|
};
|
|
7830
8201
|
addInputField = (field) => {
|
|
7831
|
-
|
|
7832
|
-
|
|
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
|
+
}
|
|
7833
8216
|
};
|
|
7834
8217
|
addOutputField = (field) => {
|
|
7835
|
-
|
|
7836
|
-
|
|
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
|
+
}
|
|
7837
8232
|
};
|
|
7838
8233
|
setInputFields = (fields) => {
|
|
7839
|
-
|
|
7840
|
-
|
|
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
|
+
}
|
|
7841
8257
|
};
|
|
7842
8258
|
setOutputFields = (fields) => {
|
|
7843
|
-
|
|
7844
|
-
|
|
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
|
+
}
|
|
7845
8282
|
};
|
|
7846
8283
|
getInputFields = () => this.inputFields;
|
|
7847
8284
|
getOutputFields = () => this.outputFields;
|
|
@@ -7883,23 +8320,77 @@ var AxSignature = class _AxSignature {
|
|
|
7883
8320
|
return schema;
|
|
7884
8321
|
};
|
|
7885
8322
|
updateHash = () => {
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
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;
|
|
7893
8341
|
}
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
this.inputFields,
|
|
7899
|
-
this.outputFields
|
|
7900
|
-
);
|
|
7901
|
-
return [this.sigHash, this.sigString];
|
|
8342
|
+
throw new AxSignatureValidationError(
|
|
8343
|
+
`Signature validation failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
8344
|
+
);
|
|
8345
|
+
}
|
|
7902
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
|
+
}
|
|
7903
8394
|
hash = () => this.sigHash;
|
|
7904
8395
|
toString = () => this.sigString;
|
|
7905
8396
|
toJSON = () => {
|
|
@@ -7916,54 +8407,194 @@ function renderField(field) {
|
|
|
7916
8407
|
if (field.isOptional) {
|
|
7917
8408
|
result += "?";
|
|
7918
8409
|
}
|
|
8410
|
+
if (field.isInternal) {
|
|
8411
|
+
result += "!";
|
|
8412
|
+
}
|
|
7919
8413
|
if (field.type) {
|
|
7920
8414
|
result += ":" + field.type.name;
|
|
7921
8415
|
if (field.type.isArray) {
|
|
7922
8416
|
result += "[]";
|
|
7923
8417
|
}
|
|
8418
|
+
if (field.type.name === "class" && field.type.options) {
|
|
8419
|
+
result += ` "${field.type.options.join(", ")}"`;
|
|
8420
|
+
}
|
|
7924
8421
|
}
|
|
7925
|
-
if (field.description) {
|
|
8422
|
+
if (field.description && field.type?.name !== "class") {
|
|
7926
8423
|
result += ` "${field.description}"`;
|
|
7927
8424
|
}
|
|
7928
8425
|
return result;
|
|
7929
8426
|
}
|
|
7930
8427
|
function renderSignature(description, inputFields, outputFields) {
|
|
7931
|
-
const descriptionPart = description ? `"${description}"` : "";
|
|
8428
|
+
const descriptionPart = description ? `"${description}" ` : "";
|
|
7932
8429
|
const inputFieldsRendered = inputFields.map(renderField).join(", ");
|
|
7933
8430
|
const outputFieldsRendered = outputFields.map(renderField).join(", ");
|
|
7934
|
-
return `${descriptionPart}
|
|
8431
|
+
return `${descriptionPart}${inputFieldsRendered} -> ${outputFieldsRendered}`;
|
|
7935
8432
|
}
|
|
7936
8433
|
function isValidCase(inputString) {
|
|
7937
8434
|
const camelCaseRegex = /^[a-z][a-zA-Z0-9]*$/;
|
|
7938
8435
|
const snakeCaseRegex = /^[a-z]+(_[a-z0-9]+)*$/;
|
|
7939
8436
|
return camelCaseRegex.test(inputString) || snakeCaseRegex.test(inputString);
|
|
7940
8437
|
}
|
|
7941
|
-
function validateField(field) {
|
|
8438
|
+
function validateField(field, context3) {
|
|
7942
8439
|
if (!field.name || field.name.length === 0) {
|
|
7943
|
-
throw new
|
|
8440
|
+
throw new AxSignatureValidationError(
|
|
8441
|
+
"Field name cannot be blank",
|
|
8442
|
+
field.name,
|
|
8443
|
+
"Every field must have a descriptive name"
|
|
8444
|
+
);
|
|
7944
8445
|
}
|
|
7945
8446
|
if (!isValidCase(field.name)) {
|
|
7946
|
-
throw new
|
|
7947
|
-
`Invalid field name '${field.name}'
|
|
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")'
|
|
7948
8451
|
);
|
|
7949
8452
|
}
|
|
7950
|
-
if (
|
|
7951
|
-
|
|
7952
|
-
|
|
7953
|
-
|
|
7954
|
-
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
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"
|
|
7967
8598
|
);
|
|
7968
8599
|
}
|
|
7969
8600
|
}
|
|
@@ -11696,13 +12327,18 @@ var AxMockAIService = class {
|
|
|
11696
12327
|
}
|
|
11697
12328
|
};
|
|
11698
12329
|
getLastUsedChatModel() {
|
|
11699
|
-
|
|
12330
|
+
return this.config.modelInfo?.name ?? "mock-model";
|
|
11700
12331
|
}
|
|
11701
12332
|
getLastUsedEmbedModel() {
|
|
11702
|
-
|
|
12333
|
+
return this.config.embedModelInfo?.name ?? "mock-embed-model";
|
|
11703
12334
|
}
|
|
11704
12335
|
getLastUsedModelConfig() {
|
|
11705
|
-
|
|
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;
|
|
11706
12342
|
}
|
|
11707
12343
|
getName() {
|
|
11708
12344
|
return this.config.name ?? "mock-ai-service";
|
|
@@ -14106,6 +14742,7 @@ var AxRAG = class extends AxChainOfThought {
|
|
|
14106
14742
|
axAITogetherDefaultConfig,
|
|
14107
14743
|
axBaseAIDefaultConfig,
|
|
14108
14744
|
axBaseAIDefaultCreativeConfig,
|
|
14745
|
+
axGlobals,
|
|
14109
14746
|
axModelInfoAnthropic,
|
|
14110
14747
|
axModelInfoCohere,
|
|
14111
14748
|
axModelInfoDeepSeek,
|