@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.js
CHANGED
|
@@ -6560,6 +6560,11 @@ var extractValues = (sig, values, content) => {
|
|
|
6560
6560
|
const xstate = { extractedFields: [], streamedIndex: {}, s: -1 };
|
|
6561
6561
|
streamingExtractValues(sig, values, xstate, content);
|
|
6562
6562
|
streamingExtractFinalValue(sig, values, xstate, content);
|
|
6563
|
+
for (const field of sig.getOutputFields()) {
|
|
6564
|
+
if (field.isInternal) {
|
|
6565
|
+
delete values[field.name];
|
|
6566
|
+
}
|
|
6567
|
+
}
|
|
6563
6568
|
};
|
|
6564
6569
|
var checkMissingRequiredFields = (xstate, values, currentIndex) => {
|
|
6565
6570
|
const missingFields = [];
|
|
@@ -7285,93 +7290,218 @@ var AxInstanceRegistry = class {
|
|
|
7285
7290
|
// dsp/sig.ts
|
|
7286
7291
|
import { createHash } from "crypto";
|
|
7287
7292
|
|
|
7293
|
+
// dsp/globals.ts
|
|
7294
|
+
var axGlobals = {
|
|
7295
|
+
signatureStrict: true
|
|
7296
|
+
// Controls reservedNames enforcement in signature parsing/validation
|
|
7297
|
+
};
|
|
7298
|
+
|
|
7288
7299
|
// dsp/parser.ts
|
|
7300
|
+
var SignatureValidationError = class extends Error {
|
|
7301
|
+
constructor(message, position, context3, suggestion) {
|
|
7302
|
+
super(message);
|
|
7303
|
+
this.position = position;
|
|
7304
|
+
this.context = context3;
|
|
7305
|
+
this.suggestion = suggestion;
|
|
7306
|
+
this.name = "SignatureValidationError";
|
|
7307
|
+
}
|
|
7308
|
+
};
|
|
7289
7309
|
var SignatureParser = class {
|
|
7290
7310
|
input;
|
|
7291
7311
|
position;
|
|
7292
7312
|
currentFieldName = null;
|
|
7313
|
+
currentSection = "description";
|
|
7293
7314
|
constructor(input) {
|
|
7294
|
-
this.input = input;
|
|
7315
|
+
this.input = input.trim();
|
|
7295
7316
|
this.position = 0;
|
|
7317
|
+
if (!this.input) {
|
|
7318
|
+
throw new SignatureValidationError(
|
|
7319
|
+
"Empty signature provided",
|
|
7320
|
+
0,
|
|
7321
|
+
"",
|
|
7322
|
+
'A signature must contain at least input and output fields separated by "->". Example: "userQuery:string -> aiResponse:string"'
|
|
7323
|
+
);
|
|
7324
|
+
}
|
|
7296
7325
|
}
|
|
7297
7326
|
parse() {
|
|
7298
7327
|
try {
|
|
7299
7328
|
this.skipWhitespace();
|
|
7300
7329
|
const optionalDesc = this.parseParsedString();
|
|
7301
7330
|
this.skipWhitespace();
|
|
7331
|
+
this.currentSection = "inputs";
|
|
7302
7332
|
const inputs = this.parseFieldList(
|
|
7303
7333
|
this.parseInputField.bind(this),
|
|
7304
7334
|
"input"
|
|
7305
7335
|
);
|
|
7306
7336
|
this.skipWhitespace();
|
|
7307
7337
|
if (this.position >= this.input.length) {
|
|
7308
|
-
throw new
|
|
7309
|
-
|
|
7338
|
+
throw new SignatureValidationError(
|
|
7339
|
+
"Incomplete signature: Missing output section",
|
|
7340
|
+
this.position,
|
|
7341
|
+
this.getErrorContext(),
|
|
7342
|
+
'Add "->" followed by output fields. Example: "-> responseText:string"'
|
|
7310
7343
|
);
|
|
7311
7344
|
}
|
|
7312
|
-
this.
|
|
7345
|
+
this.expectArrow();
|
|
7313
7346
|
this.skipWhitespace();
|
|
7314
7347
|
if (this.position >= this.input.length) {
|
|
7315
|
-
throw new
|
|
7316
|
-
'Incomplete signature: No output fields specified after "->"'
|
|
7348
|
+
throw new SignatureValidationError(
|
|
7349
|
+
'Incomplete signature: No output fields specified after "->"',
|
|
7350
|
+
this.position,
|
|
7351
|
+
this.getErrorContext(),
|
|
7352
|
+
'Add at least one output field. Example: "-> responseText:string"'
|
|
7317
7353
|
);
|
|
7318
7354
|
}
|
|
7355
|
+
this.currentSection = "outputs";
|
|
7319
7356
|
const outputs = this.parseFieldList(
|
|
7320
7357
|
this.parseOutputField.bind(this),
|
|
7321
7358
|
"output"
|
|
7322
7359
|
);
|
|
7360
|
+
this.skipWhitespace();
|
|
7361
|
+
if (this.position < this.input.length) {
|
|
7362
|
+
const remaining = this.input.slice(this.position);
|
|
7363
|
+
throw new SignatureValidationError(
|
|
7364
|
+
`Unexpected content after signature: "${remaining}"`,
|
|
7365
|
+
this.position,
|
|
7366
|
+
this.getErrorContext(),
|
|
7367
|
+
"Remove any extra content after the output fields"
|
|
7368
|
+
);
|
|
7369
|
+
}
|
|
7370
|
+
this.validateParsedSignature({
|
|
7371
|
+
desc: optionalDesc?.trim(),
|
|
7372
|
+
inputs,
|
|
7373
|
+
outputs
|
|
7374
|
+
});
|
|
7323
7375
|
return {
|
|
7324
7376
|
desc: optionalDesc?.trim(),
|
|
7325
7377
|
inputs,
|
|
7326
7378
|
outputs
|
|
7327
7379
|
};
|
|
7328
7380
|
} catch (error) {
|
|
7381
|
+
if (error instanceof SignatureValidationError) {
|
|
7382
|
+
throw error;
|
|
7383
|
+
}
|
|
7329
7384
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7385
|
+
throw new SignatureValidationError(
|
|
7386
|
+
errorMessage,
|
|
7387
|
+
this.position,
|
|
7388
|
+
this.getErrorContext()
|
|
7389
|
+
);
|
|
7390
|
+
}
|
|
7391
|
+
}
|
|
7392
|
+
validateParsedSignature(signature) {
|
|
7393
|
+
const inputNames = /* @__PURE__ */ new Set();
|
|
7394
|
+
for (const field of signature.inputs) {
|
|
7395
|
+
if (inputNames.has(field.name)) {
|
|
7396
|
+
throw new SignatureValidationError(
|
|
7397
|
+
`Duplicate input field name: "${field.name}"`,
|
|
7398
|
+
0,
|
|
7399
|
+
"",
|
|
7400
|
+
"Each field name must be unique within the signature"
|
|
7401
|
+
);
|
|
7402
|
+
}
|
|
7403
|
+
inputNames.add(field.name);
|
|
7404
|
+
}
|
|
7405
|
+
const outputNames = /* @__PURE__ */ new Set();
|
|
7406
|
+
for (const field of signature.outputs) {
|
|
7407
|
+
if (outputNames.has(field.name)) {
|
|
7408
|
+
throw new SignatureValidationError(
|
|
7409
|
+
`Duplicate output field name: "${field.name}"`,
|
|
7410
|
+
0,
|
|
7411
|
+
"",
|
|
7412
|
+
"Each field name must be unique within the signature"
|
|
7413
|
+
);
|
|
7414
|
+
}
|
|
7415
|
+
outputNames.add(field.name);
|
|
7416
|
+
}
|
|
7417
|
+
for (const outputField of signature.outputs) {
|
|
7418
|
+
if (inputNames.has(outputField.name)) {
|
|
7419
|
+
throw new SignatureValidationError(
|
|
7420
|
+
`Field name "${outputField.name}" appears in both inputs and outputs`,
|
|
7421
|
+
0,
|
|
7422
|
+
"",
|
|
7423
|
+
"Use different names for input and output fields to avoid confusion"
|
|
7424
|
+
);
|
|
7425
|
+
}
|
|
7426
|
+
}
|
|
7427
|
+
if (signature.inputs.length === 0) {
|
|
7428
|
+
throw new SignatureValidationError(
|
|
7429
|
+
"Signature must have at least one input field",
|
|
7430
|
+
0,
|
|
7431
|
+
"",
|
|
7432
|
+
'Add an input field before "->". Example: "userInput:string -> ..."'
|
|
7433
|
+
);
|
|
7434
|
+
}
|
|
7435
|
+
if (signature.outputs.length === 0) {
|
|
7436
|
+
throw new SignatureValidationError(
|
|
7437
|
+
"Signature must have at least one output field",
|
|
7438
|
+
0,
|
|
7439
|
+
"",
|
|
7440
|
+
'Add an output field after "->". Example: "... -> responseText:string"'
|
|
7441
|
+
);
|
|
7333
7442
|
}
|
|
7334
7443
|
}
|
|
7335
7444
|
getErrorContext() {
|
|
7336
|
-
const start = Math.max(0, this.position -
|
|
7337
|
-
const end = Math.min(this.input.length, this.position +
|
|
7445
|
+
const start = Math.max(0, this.position - 25);
|
|
7446
|
+
const end = Math.min(this.input.length, this.position + 25);
|
|
7338
7447
|
const before = this.input.slice(start, this.position);
|
|
7339
7448
|
const after = this.input.slice(this.position, end);
|
|
7340
7449
|
const pointer = " ".repeat(before.length) + "^";
|
|
7341
|
-
|
|
7342
|
-
${
|
|
7343
|
-
${
|
|
7450
|
+
const lines = [
|
|
7451
|
+
`Position ${this.position} in signature:`,
|
|
7452
|
+
`"${before}${after}"`,
|
|
7453
|
+
` ${pointer}`
|
|
7454
|
+
];
|
|
7455
|
+
return lines.join("\n");
|
|
7344
7456
|
}
|
|
7345
7457
|
parseFieldList(parseFieldFn, section) {
|
|
7346
7458
|
const fields = [];
|
|
7347
7459
|
this.skipWhitespace();
|
|
7348
7460
|
if (this.position >= this.input.length) {
|
|
7349
|
-
throw new
|
|
7461
|
+
throw new SignatureValidationError(
|
|
7462
|
+
`Empty ${section} section: Expected at least one field`,
|
|
7463
|
+
this.position,
|
|
7464
|
+
this.getErrorContext(),
|
|
7465
|
+
`Add a ${section} field. Example: ${section === "input" ? "userInput:string" : "responseText:string"}`
|
|
7466
|
+
);
|
|
7350
7467
|
}
|
|
7351
7468
|
try {
|
|
7352
7469
|
fields.push(parseFieldFn());
|
|
7353
7470
|
} catch (error) {
|
|
7354
|
-
|
|
7355
|
-
|
|
7471
|
+
if (error instanceof SignatureValidationError) {
|
|
7472
|
+
throw error;
|
|
7473
|
+
}
|
|
7474
|
+
throw new SignatureValidationError(
|
|
7475
|
+
`Invalid first ${section} field: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
7476
|
+
this.position,
|
|
7477
|
+
this.getErrorContext()
|
|
7356
7478
|
);
|
|
7357
7479
|
}
|
|
7358
7480
|
this.skipWhitespace();
|
|
7359
7481
|
while (this.position < this.input.length) {
|
|
7360
|
-
if (this.input[this.position] === "-" && this.input[this.position + 1] === ">") {
|
|
7482
|
+
if (this.input[this.position] === "-" && this.position + 1 < this.input.length && this.input[this.position + 1] === ">") {
|
|
7361
7483
|
break;
|
|
7362
7484
|
}
|
|
7363
7485
|
if (this.match(",")) {
|
|
7364
7486
|
this.skipWhitespace();
|
|
7365
7487
|
if (this.position >= this.input.length) {
|
|
7366
|
-
throw new
|
|
7367
|
-
`Unexpected end of input after comma in ${section} section
|
|
7488
|
+
throw new SignatureValidationError(
|
|
7489
|
+
`Unexpected end of input after comma in ${section} section`,
|
|
7490
|
+
this.position,
|
|
7491
|
+
this.getErrorContext(),
|
|
7492
|
+
`Add another ${section} field after the comma`
|
|
7368
7493
|
);
|
|
7369
7494
|
}
|
|
7370
7495
|
try {
|
|
7371
7496
|
fields.push(parseFieldFn());
|
|
7372
7497
|
} catch (error) {
|
|
7373
|
-
|
|
7374
|
-
|
|
7498
|
+
if (error instanceof SignatureValidationError) {
|
|
7499
|
+
throw error;
|
|
7500
|
+
}
|
|
7501
|
+
throw new SignatureValidationError(
|
|
7502
|
+
`Invalid ${section} field after comma: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
7503
|
+
this.position,
|
|
7504
|
+
this.getErrorContext()
|
|
7375
7505
|
);
|
|
7376
7506
|
}
|
|
7377
7507
|
this.skipWhitespace();
|
|
@@ -7388,6 +7518,7 @@ ${pointer}`;
|
|
|
7388
7518
|
this.skipWhitespace();
|
|
7389
7519
|
const name = this.parseParsedIdentifier();
|
|
7390
7520
|
this.currentFieldName = name;
|
|
7521
|
+
this.validateFieldName(name, "input");
|
|
7391
7522
|
let isOptional = void 0;
|
|
7392
7523
|
while (true) {
|
|
7393
7524
|
if (this.match("?")) {
|
|
@@ -7395,8 +7526,11 @@ ${pointer}`;
|
|
|
7395
7526
|
continue;
|
|
7396
7527
|
}
|
|
7397
7528
|
if (this.match("!")) {
|
|
7398
|
-
throw new
|
|
7399
|
-
`Input field "${name}"
|
|
7529
|
+
throw new SignatureValidationError(
|
|
7530
|
+
`Input field "${name}" cannot use the internal marker "!"`,
|
|
7531
|
+
this.position - 1,
|
|
7532
|
+
this.getErrorContext(),
|
|
7533
|
+
"Internal markers (!) are only allowed on output fields"
|
|
7400
7534
|
);
|
|
7401
7535
|
}
|
|
7402
7536
|
break;
|
|
@@ -7406,17 +7540,33 @@ ${pointer}`;
|
|
|
7406
7540
|
if (this.match(":")) {
|
|
7407
7541
|
this.skipWhitespace();
|
|
7408
7542
|
if (/^class\b/.test(this.input.slice(this.position))) {
|
|
7409
|
-
throw new
|
|
7410
|
-
`Input field "${name}"
|
|
7543
|
+
throw new SignatureValidationError(
|
|
7544
|
+
`Input field "${name}" cannot use the "class" type`,
|
|
7545
|
+
this.position,
|
|
7546
|
+
this.getErrorContext(),
|
|
7547
|
+
'Class types are only allowed on output fields. Use "string" type for input classifications'
|
|
7411
7548
|
);
|
|
7412
7549
|
} else {
|
|
7413
7550
|
try {
|
|
7414
7551
|
const typeName = this.parseTypeNotClass();
|
|
7415
7552
|
const isArray = this.match("[]");
|
|
7416
7553
|
type = { name: typeName, isArray };
|
|
7554
|
+
if ((typeName === "image" || typeName === "audio") && isArray) {
|
|
7555
|
+
throw new SignatureValidationError(
|
|
7556
|
+
`Input field "${name}": Arrays of ${typeName} are not supported`,
|
|
7557
|
+
this.position,
|
|
7558
|
+
this.getErrorContext(),
|
|
7559
|
+
`Use a single ${typeName} type instead: "${typeName}"`
|
|
7560
|
+
);
|
|
7561
|
+
}
|
|
7417
7562
|
} catch (error) {
|
|
7418
|
-
|
|
7419
|
-
|
|
7563
|
+
if (error instanceof SignatureValidationError) {
|
|
7564
|
+
throw error;
|
|
7565
|
+
}
|
|
7566
|
+
throw new SignatureValidationError(
|
|
7567
|
+
`Input field "${name}": ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
7568
|
+
this.position,
|
|
7569
|
+
this.getErrorContext()
|
|
7420
7570
|
);
|
|
7421
7571
|
}
|
|
7422
7572
|
}
|
|
@@ -7437,6 +7587,7 @@ ${pointer}`;
|
|
|
7437
7587
|
this.skipWhitespace();
|
|
7438
7588
|
const name = this.parseParsedIdentifier();
|
|
7439
7589
|
this.currentFieldName = name;
|
|
7590
|
+
this.validateFieldName(name, "output");
|
|
7440
7591
|
let isOptional = false;
|
|
7441
7592
|
let isInternal = false;
|
|
7442
7593
|
while (true) {
|
|
@@ -7459,25 +7610,86 @@ ${pointer}`;
|
|
|
7459
7610
|
this.skipWhitespace();
|
|
7460
7611
|
const classNamesString = this.parseParsedString();
|
|
7461
7612
|
if (!classNamesString) {
|
|
7462
|
-
throw new
|
|
7463
|
-
`Output field "${name}":
|
|
7613
|
+
throw new SignatureValidationError(
|
|
7614
|
+
`Output field "${name}": Missing class options after "class" type`,
|
|
7615
|
+
this.position,
|
|
7616
|
+
this.getErrorContext(),
|
|
7617
|
+
'Add class names in quotes. Example: class "positive, negative, neutral"'
|
|
7464
7618
|
);
|
|
7465
7619
|
}
|
|
7466
7620
|
const options = classNamesString.split(/[,\s]+/).map((s2) => s2.trim()).filter((s2) => s2.length > 0);
|
|
7467
7621
|
if (options.length === 0) {
|
|
7468
|
-
throw new
|
|
7469
|
-
`Output field "${name}": Empty class list provided
|
|
7622
|
+
throw new SignatureValidationError(
|
|
7623
|
+
`Output field "${name}": Empty class list provided`,
|
|
7624
|
+
this.position,
|
|
7625
|
+
this.getErrorContext(),
|
|
7626
|
+
'Provide at least one class option. Example: "positive, negative"'
|
|
7470
7627
|
);
|
|
7471
7628
|
}
|
|
7629
|
+
if (options.length === 1) {
|
|
7630
|
+
throw new SignatureValidationError(
|
|
7631
|
+
`Output field "${name}": Class type needs at least 2 options`,
|
|
7632
|
+
this.position,
|
|
7633
|
+
this.getErrorContext(),
|
|
7634
|
+
'Add more class options or use "string" type instead. Example: "positive, negative, neutral"'
|
|
7635
|
+
);
|
|
7636
|
+
}
|
|
7637
|
+
for (const option of options) {
|
|
7638
|
+
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(option)) {
|
|
7639
|
+
throw new SignatureValidationError(
|
|
7640
|
+
`Output field "${name}": Invalid class option "${option}"`,
|
|
7641
|
+
this.position,
|
|
7642
|
+
this.getErrorContext(),
|
|
7643
|
+
"Class options must start with a letter and contain only letters, numbers, underscores, or hyphens"
|
|
7644
|
+
);
|
|
7645
|
+
}
|
|
7646
|
+
}
|
|
7472
7647
|
type = { name: "class", isArray, options };
|
|
7473
7648
|
} else {
|
|
7474
7649
|
try {
|
|
7475
7650
|
const typeName = this.parseTypeNotClass();
|
|
7476
7651
|
const isArray = this.match("[]");
|
|
7477
7652
|
type = { name: typeName, isArray };
|
|
7653
|
+
if (typeName === "image" && isArray) {
|
|
7654
|
+
throw new SignatureValidationError(
|
|
7655
|
+
`Output field "${name}": Arrays of images are not supported`,
|
|
7656
|
+
this.position,
|
|
7657
|
+
this.getErrorContext(),
|
|
7658
|
+
'Use a single image type instead: "image"'
|
|
7659
|
+
);
|
|
7660
|
+
}
|
|
7661
|
+
if (typeName === "audio" && isArray) {
|
|
7662
|
+
throw new SignatureValidationError(
|
|
7663
|
+
`Output field "${name}": Arrays of audio are not supported`,
|
|
7664
|
+
this.position,
|
|
7665
|
+
this.getErrorContext(),
|
|
7666
|
+
'Use a single audio type instead: "audio"'
|
|
7667
|
+
);
|
|
7668
|
+
}
|
|
7669
|
+
if (typeName === "image") {
|
|
7670
|
+
throw new SignatureValidationError(
|
|
7671
|
+
`Output field "${name}": Image type is not supported in output fields`,
|
|
7672
|
+
this.position,
|
|
7673
|
+
this.getErrorContext(),
|
|
7674
|
+
"Image types can only be used in input fields"
|
|
7675
|
+
);
|
|
7676
|
+
}
|
|
7677
|
+
if (typeName === "audio") {
|
|
7678
|
+
throw new SignatureValidationError(
|
|
7679
|
+
`Output field "${name}": Audio type is not supported in output fields`,
|
|
7680
|
+
this.position,
|
|
7681
|
+
this.getErrorContext(),
|
|
7682
|
+
"Audio types can only be used in input fields"
|
|
7683
|
+
);
|
|
7684
|
+
}
|
|
7478
7685
|
} catch (error) {
|
|
7479
|
-
|
|
7480
|
-
|
|
7686
|
+
if (error instanceof SignatureValidationError) {
|
|
7687
|
+
throw error;
|
|
7688
|
+
}
|
|
7689
|
+
throw new SignatureValidationError(
|
|
7690
|
+
`Output field "${name}": ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
7691
|
+
this.position,
|
|
7692
|
+
this.getErrorContext()
|
|
7481
7693
|
);
|
|
7482
7694
|
}
|
|
7483
7695
|
}
|
|
@@ -7492,6 +7704,69 @@ ${pointer}`;
|
|
|
7492
7704
|
isInternal
|
|
7493
7705
|
};
|
|
7494
7706
|
}
|
|
7707
|
+
validateFieldName(name, fieldType) {
|
|
7708
|
+
if (axGlobals.signatureStrict) {
|
|
7709
|
+
const reservedNames = [
|
|
7710
|
+
"text",
|
|
7711
|
+
"object",
|
|
7712
|
+
"image",
|
|
7713
|
+
"string",
|
|
7714
|
+
"number",
|
|
7715
|
+
"boolean",
|
|
7716
|
+
"json",
|
|
7717
|
+
"array",
|
|
7718
|
+
"datetime",
|
|
7719
|
+
"date",
|
|
7720
|
+
"time",
|
|
7721
|
+
"type",
|
|
7722
|
+
"class",
|
|
7723
|
+
"input",
|
|
7724
|
+
"output",
|
|
7725
|
+
"data",
|
|
7726
|
+
"value",
|
|
7727
|
+
"result",
|
|
7728
|
+
"response",
|
|
7729
|
+
"request",
|
|
7730
|
+
"item",
|
|
7731
|
+
"element"
|
|
7732
|
+
];
|
|
7733
|
+
if (reservedNames.includes(name.toLowerCase())) {
|
|
7734
|
+
const suggestions = fieldType === "input" ? ["userInput", "questionText", "documentContent", "messageText"] : ["responseText", "analysisResult", "categoryType", "summaryText"];
|
|
7735
|
+
throw new SignatureValidationError(
|
|
7736
|
+
`Field name "${name}" is too generic`,
|
|
7737
|
+
this.position,
|
|
7738
|
+
this.getErrorContext(),
|
|
7739
|
+
`Use a more descriptive name. Examples: ${suggestions.join(", ")}`
|
|
7740
|
+
);
|
|
7741
|
+
}
|
|
7742
|
+
}
|
|
7743
|
+
const camelCaseRegex = /^[a-z][a-zA-Z0-9]*$/;
|
|
7744
|
+
const snakeCaseRegex = /^[a-z]+(_[a-z0-9]+)*$/;
|
|
7745
|
+
if (!camelCaseRegex.test(name) && !snakeCaseRegex.test(name)) {
|
|
7746
|
+
throw new SignatureValidationError(
|
|
7747
|
+
`Invalid field name "${name}"`,
|
|
7748
|
+
this.position,
|
|
7749
|
+
this.getErrorContext(),
|
|
7750
|
+
'Field names must be in camelCase (e.g., "userInput") or snake_case (e.g., "user_input")'
|
|
7751
|
+
);
|
|
7752
|
+
}
|
|
7753
|
+
if (name.length < 2) {
|
|
7754
|
+
throw new SignatureValidationError(
|
|
7755
|
+
`Field name "${name}" is too short`,
|
|
7756
|
+
this.position,
|
|
7757
|
+
this.getErrorContext(),
|
|
7758
|
+
"Field names must be at least 2 characters long"
|
|
7759
|
+
);
|
|
7760
|
+
}
|
|
7761
|
+
if (name.length > 50) {
|
|
7762
|
+
throw new SignatureValidationError(
|
|
7763
|
+
`Field name "${name}" is too long (${name.length} characters)`,
|
|
7764
|
+
this.position,
|
|
7765
|
+
this.getErrorContext(),
|
|
7766
|
+
"Field names should be 50 characters or less"
|
|
7767
|
+
);
|
|
7768
|
+
}
|
|
7769
|
+
}
|
|
7495
7770
|
parseTypeNotClass() {
|
|
7496
7771
|
const types = [
|
|
7497
7772
|
"string",
|
|
@@ -7506,13 +7781,42 @@ ${pointer}`;
|
|
|
7506
7781
|
];
|
|
7507
7782
|
const foundType = types.find((type) => this.match(type));
|
|
7508
7783
|
if (!foundType) {
|
|
7509
|
-
const currentWord = this.input.slice(this.position).match(/^\w+/)?.[0] || "
|
|
7510
|
-
|
|
7511
|
-
|
|
7784
|
+
const currentWord = this.input.slice(this.position).match(/^\w+/)?.[0] || "";
|
|
7785
|
+
const suggestion = this.suggestType(currentWord);
|
|
7786
|
+
const baseMessage = `Invalid type "${currentWord || "empty"}"`;
|
|
7787
|
+
const suggestionPart = suggestion ? `. Did you mean "${suggestion}"?` : "";
|
|
7788
|
+
const fullMessage = `${baseMessage}${suggestionPart}`;
|
|
7789
|
+
throw new SignatureValidationError(
|
|
7790
|
+
fullMessage,
|
|
7791
|
+
this.position,
|
|
7792
|
+
this.getErrorContext(),
|
|
7793
|
+
`Expected one of: ${types.join(", ")}`
|
|
7512
7794
|
);
|
|
7513
7795
|
}
|
|
7514
7796
|
return foundType;
|
|
7515
7797
|
}
|
|
7798
|
+
suggestType(input) {
|
|
7799
|
+
const suggestions = {
|
|
7800
|
+
str: "string",
|
|
7801
|
+
text: "string",
|
|
7802
|
+
int: "number",
|
|
7803
|
+
integer: "number",
|
|
7804
|
+
float: "number",
|
|
7805
|
+
double: "number",
|
|
7806
|
+
bool: "boolean",
|
|
7807
|
+
object: "json",
|
|
7808
|
+
dict: "json",
|
|
7809
|
+
timestamp: "datetime",
|
|
7810
|
+
time: "datetime",
|
|
7811
|
+
img: "image",
|
|
7812
|
+
picture: "image",
|
|
7813
|
+
sound: "audio",
|
|
7814
|
+
voice: "audio",
|
|
7815
|
+
classification: "class",
|
|
7816
|
+
category: "class"
|
|
7817
|
+
};
|
|
7818
|
+
return suggestions[input.toLowerCase()] || null;
|
|
7819
|
+
}
|
|
7516
7820
|
parseParsedIdentifier() {
|
|
7517
7821
|
this.skipWhitespace();
|
|
7518
7822
|
const match = /^[a-zA-Z_][a-zA-Z_0-9]*/.exec(
|
|
@@ -7523,9 +7827,28 @@ ${pointer}`;
|
|
|
7523
7827
|
return match[0];
|
|
7524
7828
|
}
|
|
7525
7829
|
const invalidMatch = /^\S+/.exec(this.input.slice(this.position));
|
|
7526
|
-
const invalidId = invalidMatch ? invalidMatch[0] : "
|
|
7527
|
-
|
|
7528
|
-
|
|
7830
|
+
const invalidId = invalidMatch ? invalidMatch[0] : "";
|
|
7831
|
+
if (invalidId === "") {
|
|
7832
|
+
throw new SignatureValidationError(
|
|
7833
|
+
"Expected field name but found end of input",
|
|
7834
|
+
this.position,
|
|
7835
|
+
this.getErrorContext(),
|
|
7836
|
+
"Add a field name. Field names must start with a letter or underscore"
|
|
7837
|
+
);
|
|
7838
|
+
}
|
|
7839
|
+
if (/^\d/.test(invalidId)) {
|
|
7840
|
+
throw new SignatureValidationError(
|
|
7841
|
+
`Invalid field name "${invalidId}" - cannot start with a number`,
|
|
7842
|
+
this.position,
|
|
7843
|
+
this.getErrorContext(),
|
|
7844
|
+
'Field names must start with a letter or underscore. Example: "userInput" or "_internal"'
|
|
7845
|
+
);
|
|
7846
|
+
}
|
|
7847
|
+
throw new SignatureValidationError(
|
|
7848
|
+
`Invalid field name "${invalidId}"`,
|
|
7849
|
+
this.position,
|
|
7850
|
+
this.getErrorContext(),
|
|
7851
|
+
"Field names must start with a letter or underscore and contain only letters, numbers, or underscores"
|
|
7529
7852
|
);
|
|
7530
7853
|
}
|
|
7531
7854
|
parseParsedString() {
|
|
@@ -7534,7 +7857,7 @@ ${pointer}`;
|
|
|
7534
7857
|
if (this.match(quoteChar)) {
|
|
7535
7858
|
let content = "";
|
|
7536
7859
|
let escaped = false;
|
|
7537
|
-
|
|
7860
|
+
const startPos = this.position - 1;
|
|
7538
7861
|
while (this.position < this.input.length) {
|
|
7539
7862
|
const char = this.input[this.position];
|
|
7540
7863
|
this.position++;
|
|
@@ -7549,9 +7872,15 @@ ${pointer}`;
|
|
|
7549
7872
|
content += char;
|
|
7550
7873
|
}
|
|
7551
7874
|
}
|
|
7552
|
-
const partialString = this.input.slice(
|
|
7553
|
-
|
|
7554
|
-
|
|
7875
|
+
const partialString = this.input.slice(
|
|
7876
|
+
startPos,
|
|
7877
|
+
Math.min(this.position, startPos + 20)
|
|
7878
|
+
);
|
|
7879
|
+
throw new SignatureValidationError(
|
|
7880
|
+
`Unterminated string starting at position ${startPos}`,
|
|
7881
|
+
startPos,
|
|
7882
|
+
this.getErrorContext(),
|
|
7883
|
+
`Add closing ${quoteChar} to complete the string: ${partialString}${quoteChar}`
|
|
7555
7884
|
);
|
|
7556
7885
|
}
|
|
7557
7886
|
}
|
|
@@ -7579,11 +7908,15 @@ ${pointer}`;
|
|
|
7579
7908
|
}
|
|
7580
7909
|
return false;
|
|
7581
7910
|
}
|
|
7582
|
-
|
|
7583
|
-
if (!this.match(
|
|
7911
|
+
expectArrow() {
|
|
7912
|
+
if (!this.match("->")) {
|
|
7584
7913
|
const found = this.input.slice(this.position, this.position + 10);
|
|
7585
|
-
|
|
7586
|
-
|
|
7914
|
+
const suggestion = found.includes(">") ? 'Use "->" (dash followed by greater-than)' : found.includes("-") ? 'Add ">" after the dash' : 'Add "->" to separate input and output fields';
|
|
7915
|
+
throw new SignatureValidationError(
|
|
7916
|
+
`Expected "->" but found "${found}..."`,
|
|
7917
|
+
this.position,
|
|
7918
|
+
this.getErrorContext(),
|
|
7919
|
+
suggestion
|
|
7587
7920
|
);
|
|
7588
7921
|
}
|
|
7589
7922
|
}
|
|
@@ -7594,6 +7927,14 @@ function parseSignature(input) {
|
|
|
7594
7927
|
}
|
|
7595
7928
|
|
|
7596
7929
|
// dsp/sig.ts
|
|
7930
|
+
var AxSignatureValidationError = class extends Error {
|
|
7931
|
+
constructor(message, fieldName, suggestion) {
|
|
7932
|
+
super(message);
|
|
7933
|
+
this.fieldName = fieldName;
|
|
7934
|
+
this.suggestion = suggestion;
|
|
7935
|
+
this.name = "AxSignatureValidationError";
|
|
7936
|
+
}
|
|
7937
|
+
};
|
|
7597
7938
|
var AxSignature = class _AxSignature {
|
|
7598
7939
|
description;
|
|
7599
7940
|
inputFields;
|
|
@@ -7613,8 +7954,18 @@ var AxSignature = class _AxSignature {
|
|
|
7613
7954
|
try {
|
|
7614
7955
|
sig = parseSignature(signature);
|
|
7615
7956
|
} catch (e) {
|
|
7616
|
-
|
|
7617
|
-
|
|
7957
|
+
if (e instanceof Error) {
|
|
7958
|
+
const suggestion = "suggestion" in e && typeof e.suggestion === "string" ? e.suggestion : 'Please check the signature format. Example: "userInput:string -> responseText:string"';
|
|
7959
|
+
throw new AxSignatureValidationError(
|
|
7960
|
+
`Invalid Signature: ${e.message}`,
|
|
7961
|
+
void 0,
|
|
7962
|
+
suggestion
|
|
7963
|
+
);
|
|
7964
|
+
}
|
|
7965
|
+
throw new AxSignatureValidationError(
|
|
7966
|
+
`Invalid Signature: ${signature}`,
|
|
7967
|
+
void 0,
|
|
7968
|
+
'Please check the signature format. Example: "userInput:string -> responseText:string"'
|
|
7618
7969
|
);
|
|
7619
7970
|
}
|
|
7620
7971
|
this.description = sig.desc;
|
|
@@ -7632,12 +7983,20 @@ var AxSignature = class _AxSignature {
|
|
|
7632
7983
|
this.sigHash = signature.hash();
|
|
7633
7984
|
this.sigString = signature.toString();
|
|
7634
7985
|
} else {
|
|
7635
|
-
throw new
|
|
7986
|
+
throw new AxSignatureValidationError(
|
|
7987
|
+
"Invalid signature argument type",
|
|
7988
|
+
void 0,
|
|
7989
|
+
"Signature must be a string or another AxSignature instance"
|
|
7990
|
+
);
|
|
7636
7991
|
}
|
|
7637
7992
|
}
|
|
7638
7993
|
parseParsedField = (field) => {
|
|
7639
7994
|
if (!field.name || field.name.length === 0) {
|
|
7640
|
-
throw new
|
|
7995
|
+
throw new AxSignatureValidationError(
|
|
7996
|
+
"Field name is required",
|
|
7997
|
+
field.name,
|
|
7998
|
+
'Every field must have a descriptive name. Example: "userInput", "responseText"'
|
|
7999
|
+
);
|
|
7641
8000
|
}
|
|
7642
8001
|
const title = this.toTitle(field.name);
|
|
7643
8002
|
return {
|
|
@@ -7652,29 +8011,106 @@ var AxSignature = class _AxSignature {
|
|
|
7652
8011
|
parseField = (field) => {
|
|
7653
8012
|
const title = !field.title || field.title.length === 0 ? this.toTitle(field.name) : field.title;
|
|
7654
8013
|
if (field.type && (!field.type.name || field.type.name.length === 0)) {
|
|
7655
|
-
throw new
|
|
8014
|
+
throw new AxSignatureValidationError(
|
|
8015
|
+
"Field type name is required",
|
|
8016
|
+
field.name,
|
|
8017
|
+
"Specify a valid type. Available types: string, number, boolean, json, image, audio, date, datetime, class, code"
|
|
8018
|
+
);
|
|
7656
8019
|
}
|
|
7657
8020
|
return { ...field, title };
|
|
7658
8021
|
};
|
|
7659
8022
|
setDescription = (desc) => {
|
|
8023
|
+
if (typeof desc !== "string") {
|
|
8024
|
+
throw new AxSignatureValidationError(
|
|
8025
|
+
"Description must be a string",
|
|
8026
|
+
void 0,
|
|
8027
|
+
"Provide a string description for the signature"
|
|
8028
|
+
);
|
|
8029
|
+
}
|
|
7660
8030
|
this.description = desc;
|
|
7661
8031
|
this.updateHash();
|
|
7662
8032
|
};
|
|
7663
8033
|
addInputField = (field) => {
|
|
7664
|
-
|
|
7665
|
-
|
|
8034
|
+
try {
|
|
8035
|
+
const parsedField = this.parseField(field);
|
|
8036
|
+
validateField(parsedField, "input");
|
|
8037
|
+
this.inputFields.push(parsedField);
|
|
8038
|
+
this.updateHash();
|
|
8039
|
+
} catch (error) {
|
|
8040
|
+
if (error instanceof AxSignatureValidationError) {
|
|
8041
|
+
throw error;
|
|
8042
|
+
}
|
|
8043
|
+
throw new AxSignatureValidationError(
|
|
8044
|
+
`Failed to add input field "${field.name}": ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
8045
|
+
field.name
|
|
8046
|
+
);
|
|
8047
|
+
}
|
|
7666
8048
|
};
|
|
7667
8049
|
addOutputField = (field) => {
|
|
7668
|
-
|
|
7669
|
-
|
|
8050
|
+
try {
|
|
8051
|
+
const parsedField = this.parseField(field);
|
|
8052
|
+
validateField(parsedField, "output");
|
|
8053
|
+
this.outputFields.push(parsedField);
|
|
8054
|
+
this.updateHash();
|
|
8055
|
+
} catch (error) {
|
|
8056
|
+
if (error instanceof AxSignatureValidationError) {
|
|
8057
|
+
throw error;
|
|
8058
|
+
}
|
|
8059
|
+
throw new AxSignatureValidationError(
|
|
8060
|
+
`Failed to add output field "${field.name}": ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
8061
|
+
field.name
|
|
8062
|
+
);
|
|
8063
|
+
}
|
|
7670
8064
|
};
|
|
7671
8065
|
setInputFields = (fields) => {
|
|
7672
|
-
|
|
7673
|
-
|
|
8066
|
+
if (!Array.isArray(fields)) {
|
|
8067
|
+
throw new AxSignatureValidationError(
|
|
8068
|
+
"Input fields must be an array",
|
|
8069
|
+
void 0,
|
|
8070
|
+
"Provide an array of field objects"
|
|
8071
|
+
);
|
|
8072
|
+
}
|
|
8073
|
+
try {
|
|
8074
|
+
const parsedFields = fields.map((v) => {
|
|
8075
|
+
const parsed = this.parseField(v);
|
|
8076
|
+
validateField(parsed, "input");
|
|
8077
|
+
return parsed;
|
|
8078
|
+
});
|
|
8079
|
+
this.inputFields = parsedFields;
|
|
8080
|
+
this.updateHash();
|
|
8081
|
+
} catch (error) {
|
|
8082
|
+
if (error instanceof AxSignatureValidationError) {
|
|
8083
|
+
throw error;
|
|
8084
|
+
}
|
|
8085
|
+
throw new AxSignatureValidationError(
|
|
8086
|
+
`Failed to set input fields: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
8087
|
+
);
|
|
8088
|
+
}
|
|
7674
8089
|
};
|
|
7675
8090
|
setOutputFields = (fields) => {
|
|
7676
|
-
|
|
7677
|
-
|
|
8091
|
+
if (!Array.isArray(fields)) {
|
|
8092
|
+
throw new AxSignatureValidationError(
|
|
8093
|
+
"Output fields must be an array",
|
|
8094
|
+
void 0,
|
|
8095
|
+
"Provide an array of field objects"
|
|
8096
|
+
);
|
|
8097
|
+
}
|
|
8098
|
+
try {
|
|
8099
|
+
const parsedFields = fields.map((v) => {
|
|
8100
|
+
const parsed = this.parseField(v);
|
|
8101
|
+
validateField(parsed, "output");
|
|
8102
|
+
return parsed;
|
|
8103
|
+
});
|
|
8104
|
+
this.outputFields = parsedFields;
|
|
8105
|
+
this.updateHash();
|
|
8106
|
+
} catch (error) {
|
|
8107
|
+
if (error instanceof AxSignatureValidationError) {
|
|
8108
|
+
throw error;
|
|
8109
|
+
}
|
|
8110
|
+
throw new AxSignatureValidationError(
|
|
8111
|
+
`Failed to set output fields: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
8112
|
+
);
|
|
8113
|
+
}
|
|
7678
8114
|
};
|
|
7679
8115
|
getInputFields = () => this.inputFields;
|
|
7680
8116
|
getOutputFields = () => this.outputFields;
|
|
@@ -7716,23 +8152,77 @@ var AxSignature = class _AxSignature {
|
|
|
7716
8152
|
return schema;
|
|
7717
8153
|
};
|
|
7718
8154
|
updateHash = () => {
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
8155
|
+
try {
|
|
8156
|
+
this.getInputFields().forEach((field) => {
|
|
8157
|
+
validateField(field, "input");
|
|
8158
|
+
});
|
|
8159
|
+
this.getOutputFields().forEach((field) => {
|
|
8160
|
+
validateField(field, "output");
|
|
8161
|
+
});
|
|
8162
|
+
this.validateSignatureConsistency();
|
|
8163
|
+
this.sigHash = createHash("sha256").update(this.description ?? "").update(JSON.stringify(this.inputFields)).update(JSON.stringify(this.outputFields)).digest("hex");
|
|
8164
|
+
this.sigString = renderSignature(
|
|
8165
|
+
this.description,
|
|
8166
|
+
this.inputFields,
|
|
8167
|
+
this.outputFields
|
|
8168
|
+
);
|
|
8169
|
+
return [this.sigHash, this.sigString];
|
|
8170
|
+
} catch (error) {
|
|
8171
|
+
if (error instanceof AxSignatureValidationError) {
|
|
8172
|
+
throw error;
|
|
7726
8173
|
}
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
this.inputFields,
|
|
7732
|
-
this.outputFields
|
|
7733
|
-
);
|
|
7734
|
-
return [this.sigHash, this.sigString];
|
|
8174
|
+
throw new AxSignatureValidationError(
|
|
8175
|
+
`Signature validation failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
8176
|
+
);
|
|
8177
|
+
}
|
|
7735
8178
|
};
|
|
8179
|
+
validateSignatureConsistency() {
|
|
8180
|
+
const inputNames = /* @__PURE__ */ new Set();
|
|
8181
|
+
for (const field of this.inputFields) {
|
|
8182
|
+
if (inputNames.has(field.name)) {
|
|
8183
|
+
throw new AxSignatureValidationError(
|
|
8184
|
+
`Duplicate input field name: "${field.name}"`,
|
|
8185
|
+
field.name,
|
|
8186
|
+
"Each field name must be unique within the signature"
|
|
8187
|
+
);
|
|
8188
|
+
}
|
|
8189
|
+
inputNames.add(field.name);
|
|
8190
|
+
}
|
|
8191
|
+
const outputNames = /* @__PURE__ */ new Set();
|
|
8192
|
+
for (const field of this.outputFields) {
|
|
8193
|
+
if (outputNames.has(field.name)) {
|
|
8194
|
+
throw new AxSignatureValidationError(
|
|
8195
|
+
`Duplicate output field name: "${field.name}"`,
|
|
8196
|
+
field.name,
|
|
8197
|
+
"Each field name must be unique within the signature"
|
|
8198
|
+
);
|
|
8199
|
+
}
|
|
8200
|
+
outputNames.add(field.name);
|
|
8201
|
+
}
|
|
8202
|
+
for (const outputField of this.outputFields) {
|
|
8203
|
+
if (inputNames.has(outputField.name)) {
|
|
8204
|
+
throw new AxSignatureValidationError(
|
|
8205
|
+
`Field name "${outputField.name}" appears in both inputs and outputs`,
|
|
8206
|
+
outputField.name,
|
|
8207
|
+
"Use different names for input and output fields to avoid confusion"
|
|
8208
|
+
);
|
|
8209
|
+
}
|
|
8210
|
+
}
|
|
8211
|
+
if (this.inputFields.length === 0) {
|
|
8212
|
+
throw new AxSignatureValidationError(
|
|
8213
|
+
"Signature must have at least one input field",
|
|
8214
|
+
void 0,
|
|
8215
|
+
'Add an input field. Example: "userInput:string -> ..."'
|
|
8216
|
+
);
|
|
8217
|
+
}
|
|
8218
|
+
if (this.outputFields.length === 0) {
|
|
8219
|
+
throw new AxSignatureValidationError(
|
|
8220
|
+
"Signature must have at least one output field",
|
|
8221
|
+
void 0,
|
|
8222
|
+
'Add an output field. Example: "... -> responseText:string"'
|
|
8223
|
+
);
|
|
8224
|
+
}
|
|
8225
|
+
}
|
|
7736
8226
|
hash = () => this.sigHash;
|
|
7737
8227
|
toString = () => this.sigString;
|
|
7738
8228
|
toJSON = () => {
|
|
@@ -7749,54 +8239,194 @@ function renderField(field) {
|
|
|
7749
8239
|
if (field.isOptional) {
|
|
7750
8240
|
result += "?";
|
|
7751
8241
|
}
|
|
8242
|
+
if (field.isInternal) {
|
|
8243
|
+
result += "!";
|
|
8244
|
+
}
|
|
7752
8245
|
if (field.type) {
|
|
7753
8246
|
result += ":" + field.type.name;
|
|
7754
8247
|
if (field.type.isArray) {
|
|
7755
8248
|
result += "[]";
|
|
7756
8249
|
}
|
|
8250
|
+
if (field.type.name === "class" && field.type.options) {
|
|
8251
|
+
result += ` "${field.type.options.join(", ")}"`;
|
|
8252
|
+
}
|
|
7757
8253
|
}
|
|
7758
|
-
if (field.description) {
|
|
8254
|
+
if (field.description && field.type?.name !== "class") {
|
|
7759
8255
|
result += ` "${field.description}"`;
|
|
7760
8256
|
}
|
|
7761
8257
|
return result;
|
|
7762
8258
|
}
|
|
7763
8259
|
function renderSignature(description, inputFields, outputFields) {
|
|
7764
|
-
const descriptionPart = description ? `"${description}"` : "";
|
|
8260
|
+
const descriptionPart = description ? `"${description}" ` : "";
|
|
7765
8261
|
const inputFieldsRendered = inputFields.map(renderField).join(", ");
|
|
7766
8262
|
const outputFieldsRendered = outputFields.map(renderField).join(", ");
|
|
7767
|
-
return `${descriptionPart}
|
|
8263
|
+
return `${descriptionPart}${inputFieldsRendered} -> ${outputFieldsRendered}`;
|
|
7768
8264
|
}
|
|
7769
8265
|
function isValidCase(inputString) {
|
|
7770
8266
|
const camelCaseRegex = /^[a-z][a-zA-Z0-9]*$/;
|
|
7771
8267
|
const snakeCaseRegex = /^[a-z]+(_[a-z0-9]+)*$/;
|
|
7772
8268
|
return camelCaseRegex.test(inputString) || snakeCaseRegex.test(inputString);
|
|
7773
8269
|
}
|
|
7774
|
-
function validateField(field) {
|
|
8270
|
+
function validateField(field, context3) {
|
|
7775
8271
|
if (!field.name || field.name.length === 0) {
|
|
7776
|
-
throw new
|
|
8272
|
+
throw new AxSignatureValidationError(
|
|
8273
|
+
"Field name cannot be blank",
|
|
8274
|
+
field.name,
|
|
8275
|
+
"Every field must have a descriptive name"
|
|
8276
|
+
);
|
|
7777
8277
|
}
|
|
7778
8278
|
if (!isValidCase(field.name)) {
|
|
7779
|
-
throw new
|
|
7780
|
-
`Invalid field name '${field.name}'
|
|
8279
|
+
throw new AxSignatureValidationError(
|
|
8280
|
+
`Invalid field name '${field.name}' - must be camelCase or snake_case`,
|
|
8281
|
+
field.name,
|
|
8282
|
+
'Use camelCase (e.g., "userInput") or snake_case (e.g., "user_input")'
|
|
7781
8283
|
);
|
|
7782
8284
|
}
|
|
7783
|
-
if (
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
|
|
7788
|
-
|
|
7789
|
-
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
8285
|
+
if (axGlobals.signatureStrict) {
|
|
8286
|
+
const reservedNames = [
|
|
8287
|
+
"text",
|
|
8288
|
+
"object",
|
|
8289
|
+
"image",
|
|
8290
|
+
"string",
|
|
8291
|
+
"number",
|
|
8292
|
+
"boolean",
|
|
8293
|
+
"json",
|
|
8294
|
+
"array",
|
|
8295
|
+
"datetime",
|
|
8296
|
+
"date",
|
|
8297
|
+
"time",
|
|
8298
|
+
"type",
|
|
8299
|
+
"class",
|
|
8300
|
+
"input",
|
|
8301
|
+
"output",
|
|
8302
|
+
"data",
|
|
8303
|
+
"value",
|
|
8304
|
+
"result",
|
|
8305
|
+
"response",
|
|
8306
|
+
"request",
|
|
8307
|
+
"item",
|
|
8308
|
+
"element"
|
|
8309
|
+
];
|
|
8310
|
+
if (reservedNames.includes(field.name.toLowerCase())) {
|
|
8311
|
+
const suggestions = context3 === "input" ? [
|
|
8312
|
+
"userInput",
|
|
8313
|
+
"questionText",
|
|
8314
|
+
"documentContent",
|
|
8315
|
+
"messageText",
|
|
8316
|
+
"queryString"
|
|
8317
|
+
] : [
|
|
8318
|
+
"responseText",
|
|
8319
|
+
"analysisResult",
|
|
8320
|
+
"categoryType",
|
|
8321
|
+
"summaryText",
|
|
8322
|
+
"outputData"
|
|
8323
|
+
];
|
|
8324
|
+
throw new AxSignatureValidationError(
|
|
8325
|
+
`Field name '${field.name}' is too generic`,
|
|
8326
|
+
field.name,
|
|
8327
|
+
`Use a more descriptive name. Examples for ${context3} fields: ${suggestions.join(", ")}`
|
|
8328
|
+
);
|
|
8329
|
+
}
|
|
8330
|
+
}
|
|
8331
|
+
if (field.name.length < 2) {
|
|
8332
|
+
throw new AxSignatureValidationError(
|
|
8333
|
+
`Field name '${field.name}' is too short`,
|
|
8334
|
+
field.name,
|
|
8335
|
+
"Field names must be at least 2 characters long"
|
|
8336
|
+
);
|
|
8337
|
+
}
|
|
8338
|
+
if (field.name.length > 50) {
|
|
8339
|
+
throw new AxSignatureValidationError(
|
|
8340
|
+
`Field name '${field.name}' is too long (${field.name.length} characters)`,
|
|
8341
|
+
field.name,
|
|
8342
|
+
"Field names should be 50 characters or less"
|
|
8343
|
+
);
|
|
8344
|
+
}
|
|
8345
|
+
if (field.type) {
|
|
8346
|
+
validateFieldType(field, context3);
|
|
8347
|
+
}
|
|
8348
|
+
}
|
|
8349
|
+
function validateFieldType(field, context3) {
|
|
8350
|
+
if (!field.type) return;
|
|
8351
|
+
const { type } = field;
|
|
8352
|
+
if (type.name === "image" || type.name === "audio") {
|
|
8353
|
+
if (context3 === "output") {
|
|
8354
|
+
throw new AxSignatureValidationError(
|
|
8355
|
+
`${type.name} type is not supported in output fields`,
|
|
8356
|
+
field.name,
|
|
8357
|
+
`${type.name} types can only be used in input fields`
|
|
8358
|
+
);
|
|
8359
|
+
}
|
|
8360
|
+
if (type.isArray) {
|
|
8361
|
+
throw new AxSignatureValidationError(
|
|
8362
|
+
`Arrays of ${type.name} are not supported`,
|
|
8363
|
+
field.name,
|
|
8364
|
+
`Use a single ${type.name} type instead`
|
|
8365
|
+
);
|
|
8366
|
+
}
|
|
8367
|
+
}
|
|
8368
|
+
if (type.name === "class") {
|
|
8369
|
+
if (context3 === "input") {
|
|
8370
|
+
throw new AxSignatureValidationError(
|
|
8371
|
+
"Class type is not supported in input fields",
|
|
8372
|
+
field.name,
|
|
8373
|
+
'Class types are only allowed on output fields. Use "string" type for input classifications'
|
|
8374
|
+
);
|
|
8375
|
+
}
|
|
8376
|
+
if (!type.options || type.options.length === 0) {
|
|
8377
|
+
throw new AxSignatureValidationError(
|
|
8378
|
+
"Class type requires options",
|
|
8379
|
+
field.name,
|
|
8380
|
+
'Provide class options. Example: class "positive, negative, neutral"'
|
|
8381
|
+
);
|
|
8382
|
+
}
|
|
8383
|
+
if (type.options.length === 1) {
|
|
8384
|
+
throw new AxSignatureValidationError(
|
|
8385
|
+
"Class type needs at least 2 options",
|
|
8386
|
+
field.name,
|
|
8387
|
+
'Add more class options or use "string" type instead'
|
|
8388
|
+
);
|
|
8389
|
+
}
|
|
8390
|
+
for (const option of type.options) {
|
|
8391
|
+
if (!option || option.trim().length === 0) {
|
|
8392
|
+
throw new AxSignatureValidationError(
|
|
8393
|
+
"Empty class option found",
|
|
8394
|
+
field.name,
|
|
8395
|
+
"All class options must be non-empty strings"
|
|
8396
|
+
);
|
|
8397
|
+
}
|
|
8398
|
+
const trimmedOption = option.trim();
|
|
8399
|
+
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(trimmedOption)) {
|
|
8400
|
+
throw new AxSignatureValidationError(
|
|
8401
|
+
`Invalid class option "${trimmedOption}"`,
|
|
8402
|
+
field.name,
|
|
8403
|
+
"Class options must start with a letter and contain only letters, numbers, underscores, or hyphens"
|
|
8404
|
+
);
|
|
8405
|
+
}
|
|
8406
|
+
}
|
|
8407
|
+
const uniqueOptions = new Set(
|
|
8408
|
+
type.options.map((opt) => opt.trim().toLowerCase())
|
|
8409
|
+
);
|
|
8410
|
+
if (uniqueOptions.size !== type.options.length) {
|
|
8411
|
+
throw new AxSignatureValidationError(
|
|
8412
|
+
"Duplicate class options found",
|
|
8413
|
+
field.name,
|
|
8414
|
+
"Each class option must be unique (case-insensitive)"
|
|
8415
|
+
);
|
|
8416
|
+
}
|
|
8417
|
+
}
|
|
8418
|
+
if (type.name === "code" && type.isArray) {
|
|
8419
|
+
throw new AxSignatureValidationError(
|
|
8420
|
+
"Arrays of code are not commonly supported",
|
|
8421
|
+
field.name,
|
|
8422
|
+
"Consider using a single code field or an array of strings instead"
|
|
8423
|
+
);
|
|
8424
|
+
}
|
|
8425
|
+
if (field.isInternal && context3 === "input") {
|
|
8426
|
+
throw new AxSignatureValidationError(
|
|
8427
|
+
"Internal marker (!) is not allowed on input fields",
|
|
8428
|
+
field.name,
|
|
8429
|
+
"Internal markers are only allowed on output fields"
|
|
7800
8430
|
);
|
|
7801
8431
|
}
|
|
7802
8432
|
}
|
|
@@ -11529,13 +12159,18 @@ var AxMockAIService = class {
|
|
|
11529
12159
|
}
|
|
11530
12160
|
};
|
|
11531
12161
|
getLastUsedChatModel() {
|
|
11532
|
-
|
|
12162
|
+
return this.config.modelInfo?.name ?? "mock-model";
|
|
11533
12163
|
}
|
|
11534
12164
|
getLastUsedEmbedModel() {
|
|
11535
|
-
|
|
12165
|
+
return this.config.embedModelInfo?.name ?? "mock-embed-model";
|
|
11536
12166
|
}
|
|
11537
12167
|
getLastUsedModelConfig() {
|
|
11538
|
-
|
|
12168
|
+
return this.config.modelInfo ? {
|
|
12169
|
+
maxTokens: this.config.modelInfo.maxTokens,
|
|
12170
|
+
temperature: 0.7,
|
|
12171
|
+
// Default temperature
|
|
12172
|
+
stream: this.config.features?.streaming ?? false
|
|
12173
|
+
} : void 0;
|
|
11539
12174
|
}
|
|
11540
12175
|
getName() {
|
|
11541
12176
|
return this.config.name ?? "mock-ai-service";
|
|
@@ -13938,6 +14573,7 @@ export {
|
|
|
13938
14573
|
axAITogetherDefaultConfig,
|
|
13939
14574
|
axBaseAIDefaultConfig,
|
|
13940
14575
|
axBaseAIDefaultCreativeConfig,
|
|
14576
|
+
axGlobals,
|
|
13941
14577
|
axModelInfoAnthropic,
|
|
13942
14578
|
axModelInfoCohere,
|
|
13943
14579
|
axModelInfoDeepSeek,
|