@ax-llm/ax 11.0.67 → 12.0.1
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 +774 -106
- package/index.cjs.map +1 -1
- package/index.d.cts +39 -33
- package/index.d.ts +39 -33
- package/index.js +773 -106
- 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,
|
|
@@ -1269,6 +1270,7 @@ var AxBaseAI = class {
|
|
|
1269
1270
|
if (chatReq.functions && chatReq.functions.length > 0) {
|
|
1270
1271
|
functions = chatReq.functions.map((fn2) => this.cleanupFunctionSchema(fn2));
|
|
1271
1272
|
}
|
|
1273
|
+
validateChatPrompt(chatReq.chatPrompt);
|
|
1272
1274
|
const req = {
|
|
1273
1275
|
...chatReq,
|
|
1274
1276
|
model,
|
|
@@ -1610,6 +1612,31 @@ function setChatResponseEvents(res, span, excludeContentFromTrace) {
|
|
|
1610
1612
|
});
|
|
1611
1613
|
}
|
|
1612
1614
|
}
|
|
1615
|
+
function validateAxMessageArray(values) {
|
|
1616
|
+
for (let i = 0; i < values.length; i++) {
|
|
1617
|
+
const message = values[i];
|
|
1618
|
+
if (!message || typeof message !== "object") {
|
|
1619
|
+
throw new Error(
|
|
1620
|
+
`AxMessage array validation failed: Item at index ${i} is not a valid message object`
|
|
1621
|
+
);
|
|
1622
|
+
}
|
|
1623
|
+
if ("content" in message && typeof message.content === "string" && message.content.trim() === "") {
|
|
1624
|
+
throw new Error(
|
|
1625
|
+
`AxMessage array validation failed: Item at index ${i} has empty content`
|
|
1626
|
+
);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
function validateChatPrompt(chatPrompt) {
|
|
1631
|
+
for (let i = 0; i < chatPrompt.length; i++) {
|
|
1632
|
+
const message = chatPrompt[i];
|
|
1633
|
+
if (message && "content" in message && typeof message.content === "string" && message.content.trim() === "") {
|
|
1634
|
+
throw new Error(
|
|
1635
|
+
`Chat prompt validation failed: Message at index ${i} has empty content`
|
|
1636
|
+
);
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1613
1640
|
function validateModels(models) {
|
|
1614
1641
|
const keys = /* @__PURE__ */ new Set();
|
|
1615
1642
|
for (const model of models) {
|
|
@@ -3386,7 +3413,9 @@ var AxAIGoogleGeminiImpl = class {
|
|
|
3386
3413
|
const contents = req.chatPrompt.filter((p) => p.role !== "system").map((msg, i) => {
|
|
3387
3414
|
switch (msg.role) {
|
|
3388
3415
|
case "user": {
|
|
3389
|
-
const parts = Array.isArray(
|
|
3416
|
+
const parts = Array.isArray(
|
|
3417
|
+
msg.content
|
|
3418
|
+
) ? msg.content.map((c, i2) => {
|
|
3390
3419
|
switch (c.type) {
|
|
3391
3420
|
case "text":
|
|
3392
3421
|
return { text: c.text };
|
|
@@ -3447,12 +3476,14 @@ var AxAIGoogleGeminiImpl = class {
|
|
|
3447
3476
|
}
|
|
3448
3477
|
];
|
|
3449
3478
|
return {
|
|
3450
|
-
role: "
|
|
3479
|
+
role: "model",
|
|
3451
3480
|
parts
|
|
3452
3481
|
};
|
|
3453
3482
|
}
|
|
3454
3483
|
default:
|
|
3455
|
-
throw new Error(
|
|
3484
|
+
throw new Error(
|
|
3485
|
+
`Invalid role: ${JSON.stringify(msg)} (index: ${i})`
|
|
3486
|
+
);
|
|
3456
3487
|
}
|
|
3457
3488
|
});
|
|
3458
3489
|
let tools = [];
|
|
@@ -6727,6 +6758,11 @@ var extractValues = (sig, values, content) => {
|
|
|
6727
6758
|
const xstate = { extractedFields: [], streamedIndex: {}, s: -1 };
|
|
6728
6759
|
streamingExtractValues(sig, values, xstate, content);
|
|
6729
6760
|
streamingExtractFinalValue(sig, values, xstate, content);
|
|
6761
|
+
for (const field of sig.getOutputFields()) {
|
|
6762
|
+
if (field.isInternal) {
|
|
6763
|
+
delete values[field.name];
|
|
6764
|
+
}
|
|
6765
|
+
}
|
|
6730
6766
|
};
|
|
6731
6767
|
var checkMissingRequiredFields = (xstate, values, currentIndex) => {
|
|
6732
6768
|
const missingFields = [];
|
|
@@ -7452,93 +7488,218 @@ var AxInstanceRegistry = class {
|
|
|
7452
7488
|
// dsp/sig.ts
|
|
7453
7489
|
var import_crypto3 = require("crypto");
|
|
7454
7490
|
|
|
7491
|
+
// dsp/globals.ts
|
|
7492
|
+
var axGlobals = {
|
|
7493
|
+
signatureStrict: true
|
|
7494
|
+
// Controls reservedNames enforcement in signature parsing/validation
|
|
7495
|
+
};
|
|
7496
|
+
|
|
7455
7497
|
// dsp/parser.ts
|
|
7498
|
+
var SignatureValidationError = class extends Error {
|
|
7499
|
+
constructor(message, position, context3, suggestion) {
|
|
7500
|
+
super(message);
|
|
7501
|
+
this.position = position;
|
|
7502
|
+
this.context = context3;
|
|
7503
|
+
this.suggestion = suggestion;
|
|
7504
|
+
this.name = "SignatureValidationError";
|
|
7505
|
+
}
|
|
7506
|
+
};
|
|
7456
7507
|
var SignatureParser = class {
|
|
7457
7508
|
input;
|
|
7458
7509
|
position;
|
|
7459
7510
|
currentFieldName = null;
|
|
7511
|
+
currentSection = "description";
|
|
7460
7512
|
constructor(input) {
|
|
7461
|
-
this.input = input;
|
|
7513
|
+
this.input = input.trim();
|
|
7462
7514
|
this.position = 0;
|
|
7515
|
+
if (!this.input) {
|
|
7516
|
+
throw new SignatureValidationError(
|
|
7517
|
+
"Empty signature provided",
|
|
7518
|
+
0,
|
|
7519
|
+
"",
|
|
7520
|
+
'A signature must contain at least input and output fields separated by "->". Example: "userQuery:string -> aiResponse:string"'
|
|
7521
|
+
);
|
|
7522
|
+
}
|
|
7463
7523
|
}
|
|
7464
7524
|
parse() {
|
|
7465
7525
|
try {
|
|
7466
7526
|
this.skipWhitespace();
|
|
7467
7527
|
const optionalDesc = this.parseParsedString();
|
|
7468
7528
|
this.skipWhitespace();
|
|
7529
|
+
this.currentSection = "inputs";
|
|
7469
7530
|
const inputs = this.parseFieldList(
|
|
7470
7531
|
this.parseInputField.bind(this),
|
|
7471
7532
|
"input"
|
|
7472
7533
|
);
|
|
7473
7534
|
this.skipWhitespace();
|
|
7474
7535
|
if (this.position >= this.input.length) {
|
|
7475
|
-
throw new
|
|
7476
|
-
|
|
7536
|
+
throw new SignatureValidationError(
|
|
7537
|
+
"Incomplete signature: Missing output section",
|
|
7538
|
+
this.position,
|
|
7539
|
+
this.getErrorContext(),
|
|
7540
|
+
'Add "->" followed by output fields. Example: "-> responseText:string"'
|
|
7477
7541
|
);
|
|
7478
7542
|
}
|
|
7479
|
-
this.
|
|
7543
|
+
this.expectArrow();
|
|
7480
7544
|
this.skipWhitespace();
|
|
7481
7545
|
if (this.position >= this.input.length) {
|
|
7482
|
-
throw new
|
|
7483
|
-
'Incomplete signature: No output fields specified after "->"'
|
|
7546
|
+
throw new SignatureValidationError(
|
|
7547
|
+
'Incomplete signature: No output fields specified after "->"',
|
|
7548
|
+
this.position,
|
|
7549
|
+
this.getErrorContext(),
|
|
7550
|
+
'Add at least one output field. Example: "-> responseText:string"'
|
|
7484
7551
|
);
|
|
7485
7552
|
}
|
|
7553
|
+
this.currentSection = "outputs";
|
|
7486
7554
|
const outputs = this.parseFieldList(
|
|
7487
7555
|
this.parseOutputField.bind(this),
|
|
7488
7556
|
"output"
|
|
7489
7557
|
);
|
|
7558
|
+
this.skipWhitespace();
|
|
7559
|
+
if (this.position < this.input.length) {
|
|
7560
|
+
const remaining = this.input.slice(this.position);
|
|
7561
|
+
throw new SignatureValidationError(
|
|
7562
|
+
`Unexpected content after signature: "${remaining}"`,
|
|
7563
|
+
this.position,
|
|
7564
|
+
this.getErrorContext(),
|
|
7565
|
+
"Remove any extra content after the output fields"
|
|
7566
|
+
);
|
|
7567
|
+
}
|
|
7568
|
+
this.validateParsedSignature({
|
|
7569
|
+
desc: optionalDesc?.trim(),
|
|
7570
|
+
inputs,
|
|
7571
|
+
outputs
|
|
7572
|
+
});
|
|
7490
7573
|
return {
|
|
7491
7574
|
desc: optionalDesc?.trim(),
|
|
7492
7575
|
inputs,
|
|
7493
7576
|
outputs
|
|
7494
7577
|
};
|
|
7495
7578
|
} catch (error) {
|
|
7579
|
+
if (error instanceof SignatureValidationError) {
|
|
7580
|
+
throw error;
|
|
7581
|
+
}
|
|
7496
7582
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7583
|
+
throw new SignatureValidationError(
|
|
7584
|
+
errorMessage,
|
|
7585
|
+
this.position,
|
|
7586
|
+
this.getErrorContext()
|
|
7587
|
+
);
|
|
7588
|
+
}
|
|
7589
|
+
}
|
|
7590
|
+
validateParsedSignature(signature) {
|
|
7591
|
+
const inputNames = /* @__PURE__ */ new Set();
|
|
7592
|
+
for (const field of signature.inputs) {
|
|
7593
|
+
if (inputNames.has(field.name)) {
|
|
7594
|
+
throw new SignatureValidationError(
|
|
7595
|
+
`Duplicate input field name: "${field.name}"`,
|
|
7596
|
+
0,
|
|
7597
|
+
"",
|
|
7598
|
+
"Each field name must be unique within the signature"
|
|
7599
|
+
);
|
|
7600
|
+
}
|
|
7601
|
+
inputNames.add(field.name);
|
|
7602
|
+
}
|
|
7603
|
+
const outputNames = /* @__PURE__ */ new Set();
|
|
7604
|
+
for (const field of signature.outputs) {
|
|
7605
|
+
if (outputNames.has(field.name)) {
|
|
7606
|
+
throw new SignatureValidationError(
|
|
7607
|
+
`Duplicate output field name: "${field.name}"`,
|
|
7608
|
+
0,
|
|
7609
|
+
"",
|
|
7610
|
+
"Each field name must be unique within the signature"
|
|
7611
|
+
);
|
|
7612
|
+
}
|
|
7613
|
+
outputNames.add(field.name);
|
|
7614
|
+
}
|
|
7615
|
+
for (const outputField of signature.outputs) {
|
|
7616
|
+
if (inputNames.has(outputField.name)) {
|
|
7617
|
+
throw new SignatureValidationError(
|
|
7618
|
+
`Field name "${outputField.name}" appears in both inputs and outputs`,
|
|
7619
|
+
0,
|
|
7620
|
+
"",
|
|
7621
|
+
"Use different names for input and output fields to avoid confusion"
|
|
7622
|
+
);
|
|
7623
|
+
}
|
|
7624
|
+
}
|
|
7625
|
+
if (signature.inputs.length === 0) {
|
|
7626
|
+
throw new SignatureValidationError(
|
|
7627
|
+
"Signature must have at least one input field",
|
|
7628
|
+
0,
|
|
7629
|
+
"",
|
|
7630
|
+
'Add an input field before "->". Example: "userInput:string -> ..."'
|
|
7631
|
+
);
|
|
7632
|
+
}
|
|
7633
|
+
if (signature.outputs.length === 0) {
|
|
7634
|
+
throw new SignatureValidationError(
|
|
7635
|
+
"Signature must have at least one output field",
|
|
7636
|
+
0,
|
|
7637
|
+
"",
|
|
7638
|
+
'Add an output field after "->". Example: "... -> responseText:string"'
|
|
7639
|
+
);
|
|
7500
7640
|
}
|
|
7501
7641
|
}
|
|
7502
7642
|
getErrorContext() {
|
|
7503
|
-
const start = Math.max(0, this.position -
|
|
7504
|
-
const end = Math.min(this.input.length, this.position +
|
|
7643
|
+
const start = Math.max(0, this.position - 25);
|
|
7644
|
+
const end = Math.min(this.input.length, this.position + 25);
|
|
7505
7645
|
const before = this.input.slice(start, this.position);
|
|
7506
7646
|
const after = this.input.slice(this.position, end);
|
|
7507
7647
|
const pointer = " ".repeat(before.length) + "^";
|
|
7508
|
-
|
|
7509
|
-
${
|
|
7510
|
-
${
|
|
7648
|
+
const lines = [
|
|
7649
|
+
`Position ${this.position} in signature:`,
|
|
7650
|
+
`"${before}${after}"`,
|
|
7651
|
+
` ${pointer}`
|
|
7652
|
+
];
|
|
7653
|
+
return lines.join("\n");
|
|
7511
7654
|
}
|
|
7512
7655
|
parseFieldList(parseFieldFn, section) {
|
|
7513
7656
|
const fields = [];
|
|
7514
7657
|
this.skipWhitespace();
|
|
7515
7658
|
if (this.position >= this.input.length) {
|
|
7516
|
-
throw new
|
|
7659
|
+
throw new SignatureValidationError(
|
|
7660
|
+
`Empty ${section} section: Expected at least one field`,
|
|
7661
|
+
this.position,
|
|
7662
|
+
this.getErrorContext(),
|
|
7663
|
+
`Add a ${section} field. Example: ${section === "input" ? "userInput:string" : "responseText:string"}`
|
|
7664
|
+
);
|
|
7517
7665
|
}
|
|
7518
7666
|
try {
|
|
7519
7667
|
fields.push(parseFieldFn());
|
|
7520
7668
|
} catch (error) {
|
|
7521
|
-
|
|
7522
|
-
|
|
7669
|
+
if (error instanceof SignatureValidationError) {
|
|
7670
|
+
throw error;
|
|
7671
|
+
}
|
|
7672
|
+
throw new SignatureValidationError(
|
|
7673
|
+
`Invalid first ${section} field: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
7674
|
+
this.position,
|
|
7675
|
+
this.getErrorContext()
|
|
7523
7676
|
);
|
|
7524
7677
|
}
|
|
7525
7678
|
this.skipWhitespace();
|
|
7526
7679
|
while (this.position < this.input.length) {
|
|
7527
|
-
if (this.input[this.position] === "-" && this.input[this.position + 1] === ">") {
|
|
7680
|
+
if (this.input[this.position] === "-" && this.position + 1 < this.input.length && this.input[this.position + 1] === ">") {
|
|
7528
7681
|
break;
|
|
7529
7682
|
}
|
|
7530
7683
|
if (this.match(",")) {
|
|
7531
7684
|
this.skipWhitespace();
|
|
7532
7685
|
if (this.position >= this.input.length) {
|
|
7533
|
-
throw new
|
|
7534
|
-
`Unexpected end of input after comma in ${section} section
|
|
7686
|
+
throw new SignatureValidationError(
|
|
7687
|
+
`Unexpected end of input after comma in ${section} section`,
|
|
7688
|
+
this.position,
|
|
7689
|
+
this.getErrorContext(),
|
|
7690
|
+
`Add another ${section} field after the comma`
|
|
7535
7691
|
);
|
|
7536
7692
|
}
|
|
7537
7693
|
try {
|
|
7538
7694
|
fields.push(parseFieldFn());
|
|
7539
7695
|
} catch (error) {
|
|
7540
|
-
|
|
7541
|
-
|
|
7696
|
+
if (error instanceof SignatureValidationError) {
|
|
7697
|
+
throw error;
|
|
7698
|
+
}
|
|
7699
|
+
throw new SignatureValidationError(
|
|
7700
|
+
`Invalid ${section} field after comma: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
7701
|
+
this.position,
|
|
7702
|
+
this.getErrorContext()
|
|
7542
7703
|
);
|
|
7543
7704
|
}
|
|
7544
7705
|
this.skipWhitespace();
|
|
@@ -7555,6 +7716,7 @@ ${pointer}`;
|
|
|
7555
7716
|
this.skipWhitespace();
|
|
7556
7717
|
const name = this.parseParsedIdentifier();
|
|
7557
7718
|
this.currentFieldName = name;
|
|
7719
|
+
this.validateFieldName(name, "input");
|
|
7558
7720
|
let isOptional = void 0;
|
|
7559
7721
|
while (true) {
|
|
7560
7722
|
if (this.match("?")) {
|
|
@@ -7562,8 +7724,11 @@ ${pointer}`;
|
|
|
7562
7724
|
continue;
|
|
7563
7725
|
}
|
|
7564
7726
|
if (this.match("!")) {
|
|
7565
|
-
throw new
|
|
7566
|
-
`Input field "${name}"
|
|
7727
|
+
throw new SignatureValidationError(
|
|
7728
|
+
`Input field "${name}" cannot use the internal marker "!"`,
|
|
7729
|
+
this.position - 1,
|
|
7730
|
+
this.getErrorContext(),
|
|
7731
|
+
"Internal markers (!) are only allowed on output fields"
|
|
7567
7732
|
);
|
|
7568
7733
|
}
|
|
7569
7734
|
break;
|
|
@@ -7573,17 +7738,33 @@ ${pointer}`;
|
|
|
7573
7738
|
if (this.match(":")) {
|
|
7574
7739
|
this.skipWhitespace();
|
|
7575
7740
|
if (/^class\b/.test(this.input.slice(this.position))) {
|
|
7576
|
-
throw new
|
|
7577
|
-
`Input field "${name}"
|
|
7741
|
+
throw new SignatureValidationError(
|
|
7742
|
+
`Input field "${name}" cannot use the "class" type`,
|
|
7743
|
+
this.position,
|
|
7744
|
+
this.getErrorContext(),
|
|
7745
|
+
'Class types are only allowed on output fields. Use "string" type for input classifications'
|
|
7578
7746
|
);
|
|
7579
7747
|
} else {
|
|
7580
7748
|
try {
|
|
7581
7749
|
const typeName = this.parseTypeNotClass();
|
|
7582
7750
|
const isArray = this.match("[]");
|
|
7583
7751
|
type = { name: typeName, isArray };
|
|
7752
|
+
if ((typeName === "image" || typeName === "audio") && isArray) {
|
|
7753
|
+
throw new SignatureValidationError(
|
|
7754
|
+
`Input field "${name}": Arrays of ${typeName} are not supported`,
|
|
7755
|
+
this.position,
|
|
7756
|
+
this.getErrorContext(),
|
|
7757
|
+
`Use a single ${typeName} type instead: "${typeName}"`
|
|
7758
|
+
);
|
|
7759
|
+
}
|
|
7584
7760
|
} catch (error) {
|
|
7585
|
-
|
|
7586
|
-
|
|
7761
|
+
if (error instanceof SignatureValidationError) {
|
|
7762
|
+
throw error;
|
|
7763
|
+
}
|
|
7764
|
+
throw new SignatureValidationError(
|
|
7765
|
+
`Input field "${name}": ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
7766
|
+
this.position,
|
|
7767
|
+
this.getErrorContext()
|
|
7587
7768
|
);
|
|
7588
7769
|
}
|
|
7589
7770
|
}
|
|
@@ -7604,6 +7785,7 @@ ${pointer}`;
|
|
|
7604
7785
|
this.skipWhitespace();
|
|
7605
7786
|
const name = this.parseParsedIdentifier();
|
|
7606
7787
|
this.currentFieldName = name;
|
|
7788
|
+
this.validateFieldName(name, "output");
|
|
7607
7789
|
let isOptional = false;
|
|
7608
7790
|
let isInternal = false;
|
|
7609
7791
|
while (true) {
|
|
@@ -7626,25 +7808,86 @@ ${pointer}`;
|
|
|
7626
7808
|
this.skipWhitespace();
|
|
7627
7809
|
const classNamesString = this.parseParsedString();
|
|
7628
7810
|
if (!classNamesString) {
|
|
7629
|
-
throw new
|
|
7630
|
-
`Output field "${name}":
|
|
7811
|
+
throw new SignatureValidationError(
|
|
7812
|
+
`Output field "${name}": Missing class options after "class" type`,
|
|
7813
|
+
this.position,
|
|
7814
|
+
this.getErrorContext(),
|
|
7815
|
+
'Add class names in quotes. Example: class "positive, negative, neutral"'
|
|
7631
7816
|
);
|
|
7632
7817
|
}
|
|
7633
7818
|
const options = classNamesString.split(/[,\s]+/).map((s2) => s2.trim()).filter((s2) => s2.length > 0);
|
|
7634
7819
|
if (options.length === 0) {
|
|
7635
|
-
throw new
|
|
7636
|
-
`Output field "${name}": Empty class list provided
|
|
7820
|
+
throw new SignatureValidationError(
|
|
7821
|
+
`Output field "${name}": Empty class list provided`,
|
|
7822
|
+
this.position,
|
|
7823
|
+
this.getErrorContext(),
|
|
7824
|
+
'Provide at least one class option. Example: "positive, negative"'
|
|
7637
7825
|
);
|
|
7638
7826
|
}
|
|
7827
|
+
if (options.length === 1) {
|
|
7828
|
+
throw new SignatureValidationError(
|
|
7829
|
+
`Output field "${name}": Class type needs at least 2 options`,
|
|
7830
|
+
this.position,
|
|
7831
|
+
this.getErrorContext(),
|
|
7832
|
+
'Add more class options or use "string" type instead. Example: "positive, negative, neutral"'
|
|
7833
|
+
);
|
|
7834
|
+
}
|
|
7835
|
+
for (const option of options) {
|
|
7836
|
+
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(option)) {
|
|
7837
|
+
throw new SignatureValidationError(
|
|
7838
|
+
`Output field "${name}": Invalid class option "${option}"`,
|
|
7839
|
+
this.position,
|
|
7840
|
+
this.getErrorContext(),
|
|
7841
|
+
"Class options must start with a letter and contain only letters, numbers, underscores, or hyphens"
|
|
7842
|
+
);
|
|
7843
|
+
}
|
|
7844
|
+
}
|
|
7639
7845
|
type = { name: "class", isArray, options };
|
|
7640
7846
|
} else {
|
|
7641
7847
|
try {
|
|
7642
7848
|
const typeName = this.parseTypeNotClass();
|
|
7643
7849
|
const isArray = this.match("[]");
|
|
7644
7850
|
type = { name: typeName, isArray };
|
|
7851
|
+
if (typeName === "image" && isArray) {
|
|
7852
|
+
throw new SignatureValidationError(
|
|
7853
|
+
`Output field "${name}": Arrays of images are not supported`,
|
|
7854
|
+
this.position,
|
|
7855
|
+
this.getErrorContext(),
|
|
7856
|
+
'Use a single image type instead: "image"'
|
|
7857
|
+
);
|
|
7858
|
+
}
|
|
7859
|
+
if (typeName === "audio" && isArray) {
|
|
7860
|
+
throw new SignatureValidationError(
|
|
7861
|
+
`Output field "${name}": Arrays of audio are not supported`,
|
|
7862
|
+
this.position,
|
|
7863
|
+
this.getErrorContext(),
|
|
7864
|
+
'Use a single audio type instead: "audio"'
|
|
7865
|
+
);
|
|
7866
|
+
}
|
|
7867
|
+
if (typeName === "image") {
|
|
7868
|
+
throw new SignatureValidationError(
|
|
7869
|
+
`Output field "${name}": Image type is not supported in output fields`,
|
|
7870
|
+
this.position,
|
|
7871
|
+
this.getErrorContext(),
|
|
7872
|
+
"Image types can only be used in input fields"
|
|
7873
|
+
);
|
|
7874
|
+
}
|
|
7875
|
+
if (typeName === "audio") {
|
|
7876
|
+
throw new SignatureValidationError(
|
|
7877
|
+
`Output field "${name}": Audio type is not supported in output fields`,
|
|
7878
|
+
this.position,
|
|
7879
|
+
this.getErrorContext(),
|
|
7880
|
+
"Audio types can only be used in input fields"
|
|
7881
|
+
);
|
|
7882
|
+
}
|
|
7645
7883
|
} catch (error) {
|
|
7646
|
-
|
|
7647
|
-
|
|
7884
|
+
if (error instanceof SignatureValidationError) {
|
|
7885
|
+
throw error;
|
|
7886
|
+
}
|
|
7887
|
+
throw new SignatureValidationError(
|
|
7888
|
+
`Output field "${name}": ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
7889
|
+
this.position,
|
|
7890
|
+
this.getErrorContext()
|
|
7648
7891
|
);
|
|
7649
7892
|
}
|
|
7650
7893
|
}
|
|
@@ -7659,6 +7902,69 @@ ${pointer}`;
|
|
|
7659
7902
|
isInternal
|
|
7660
7903
|
};
|
|
7661
7904
|
}
|
|
7905
|
+
validateFieldName(name, fieldType) {
|
|
7906
|
+
if (axGlobals.signatureStrict) {
|
|
7907
|
+
const reservedNames = [
|
|
7908
|
+
"text",
|
|
7909
|
+
"object",
|
|
7910
|
+
"image",
|
|
7911
|
+
"string",
|
|
7912
|
+
"number",
|
|
7913
|
+
"boolean",
|
|
7914
|
+
"json",
|
|
7915
|
+
"array",
|
|
7916
|
+
"datetime",
|
|
7917
|
+
"date",
|
|
7918
|
+
"time",
|
|
7919
|
+
"type",
|
|
7920
|
+
"class",
|
|
7921
|
+
"input",
|
|
7922
|
+
"output",
|
|
7923
|
+
"data",
|
|
7924
|
+
"value",
|
|
7925
|
+
"result",
|
|
7926
|
+
"response",
|
|
7927
|
+
"request",
|
|
7928
|
+
"item",
|
|
7929
|
+
"element"
|
|
7930
|
+
];
|
|
7931
|
+
if (reservedNames.includes(name.toLowerCase())) {
|
|
7932
|
+
const suggestions = fieldType === "input" ? ["userInput", "questionText", "documentContent", "messageText"] : ["responseText", "analysisResult", "categoryType", "summaryText"];
|
|
7933
|
+
throw new SignatureValidationError(
|
|
7934
|
+
`Field name "${name}" is too generic`,
|
|
7935
|
+
this.position,
|
|
7936
|
+
this.getErrorContext(),
|
|
7937
|
+
`Use a more descriptive name. Examples: ${suggestions.join(", ")}`
|
|
7938
|
+
);
|
|
7939
|
+
}
|
|
7940
|
+
}
|
|
7941
|
+
const camelCaseRegex = /^[a-z][a-zA-Z0-9]*$/;
|
|
7942
|
+
const snakeCaseRegex = /^[a-z]+(_[a-z0-9]+)*$/;
|
|
7943
|
+
if (!camelCaseRegex.test(name) && !snakeCaseRegex.test(name)) {
|
|
7944
|
+
throw new SignatureValidationError(
|
|
7945
|
+
`Invalid field name "${name}"`,
|
|
7946
|
+
this.position,
|
|
7947
|
+
this.getErrorContext(),
|
|
7948
|
+
'Field names must be in camelCase (e.g., "userInput") or snake_case (e.g., "user_input")'
|
|
7949
|
+
);
|
|
7950
|
+
}
|
|
7951
|
+
if (name.length < 2) {
|
|
7952
|
+
throw new SignatureValidationError(
|
|
7953
|
+
`Field name "${name}" is too short`,
|
|
7954
|
+
this.position,
|
|
7955
|
+
this.getErrorContext(),
|
|
7956
|
+
"Field names must be at least 2 characters long"
|
|
7957
|
+
);
|
|
7958
|
+
}
|
|
7959
|
+
if (name.length > 50) {
|
|
7960
|
+
throw new SignatureValidationError(
|
|
7961
|
+
`Field name "${name}" is too long (${name.length} characters)`,
|
|
7962
|
+
this.position,
|
|
7963
|
+
this.getErrorContext(),
|
|
7964
|
+
"Field names should be 50 characters or less"
|
|
7965
|
+
);
|
|
7966
|
+
}
|
|
7967
|
+
}
|
|
7662
7968
|
parseTypeNotClass() {
|
|
7663
7969
|
const types = [
|
|
7664
7970
|
"string",
|
|
@@ -7673,13 +7979,42 @@ ${pointer}`;
|
|
|
7673
7979
|
];
|
|
7674
7980
|
const foundType = types.find((type) => this.match(type));
|
|
7675
7981
|
if (!foundType) {
|
|
7676
|
-
const currentWord = this.input.slice(this.position).match(/^\w+/)?.[0] || "
|
|
7677
|
-
|
|
7678
|
-
|
|
7982
|
+
const currentWord = this.input.slice(this.position).match(/^\w+/)?.[0] || "";
|
|
7983
|
+
const suggestion = this.suggestType(currentWord);
|
|
7984
|
+
const baseMessage = `Invalid type "${currentWord || "empty"}"`;
|
|
7985
|
+
const suggestionPart = suggestion ? `. Did you mean "${suggestion}"?` : "";
|
|
7986
|
+
const fullMessage = `${baseMessage}${suggestionPart}`;
|
|
7987
|
+
throw new SignatureValidationError(
|
|
7988
|
+
fullMessage,
|
|
7989
|
+
this.position,
|
|
7990
|
+
this.getErrorContext(),
|
|
7991
|
+
`Expected one of: ${types.join(", ")}`
|
|
7679
7992
|
);
|
|
7680
7993
|
}
|
|
7681
7994
|
return foundType;
|
|
7682
7995
|
}
|
|
7996
|
+
suggestType(input) {
|
|
7997
|
+
const suggestions = {
|
|
7998
|
+
str: "string",
|
|
7999
|
+
text: "string",
|
|
8000
|
+
int: "number",
|
|
8001
|
+
integer: "number",
|
|
8002
|
+
float: "number",
|
|
8003
|
+
double: "number",
|
|
8004
|
+
bool: "boolean",
|
|
8005
|
+
object: "json",
|
|
8006
|
+
dict: "json",
|
|
8007
|
+
timestamp: "datetime",
|
|
8008
|
+
time: "datetime",
|
|
8009
|
+
img: "image",
|
|
8010
|
+
picture: "image",
|
|
8011
|
+
sound: "audio",
|
|
8012
|
+
voice: "audio",
|
|
8013
|
+
classification: "class",
|
|
8014
|
+
category: "class"
|
|
8015
|
+
};
|
|
8016
|
+
return suggestions[input.toLowerCase()] || null;
|
|
8017
|
+
}
|
|
7683
8018
|
parseParsedIdentifier() {
|
|
7684
8019
|
this.skipWhitespace();
|
|
7685
8020
|
const match = /^[a-zA-Z_][a-zA-Z_0-9]*/.exec(
|
|
@@ -7690,9 +8025,28 @@ ${pointer}`;
|
|
|
7690
8025
|
return match[0];
|
|
7691
8026
|
}
|
|
7692
8027
|
const invalidMatch = /^\S+/.exec(this.input.slice(this.position));
|
|
7693
|
-
const invalidId = invalidMatch ? invalidMatch[0] : "
|
|
7694
|
-
|
|
7695
|
-
|
|
8028
|
+
const invalidId = invalidMatch ? invalidMatch[0] : "";
|
|
8029
|
+
if (invalidId === "") {
|
|
8030
|
+
throw new SignatureValidationError(
|
|
8031
|
+
"Expected field name but found end of input",
|
|
8032
|
+
this.position,
|
|
8033
|
+
this.getErrorContext(),
|
|
8034
|
+
"Add a field name. Field names must start with a letter or underscore"
|
|
8035
|
+
);
|
|
8036
|
+
}
|
|
8037
|
+
if (/^\d/.test(invalidId)) {
|
|
8038
|
+
throw new SignatureValidationError(
|
|
8039
|
+
`Invalid field name "${invalidId}" - cannot start with a number`,
|
|
8040
|
+
this.position,
|
|
8041
|
+
this.getErrorContext(),
|
|
8042
|
+
'Field names must start with a letter or underscore. Example: "userInput" or "_internal"'
|
|
8043
|
+
);
|
|
8044
|
+
}
|
|
8045
|
+
throw new SignatureValidationError(
|
|
8046
|
+
`Invalid field name "${invalidId}"`,
|
|
8047
|
+
this.position,
|
|
8048
|
+
this.getErrorContext(),
|
|
8049
|
+
"Field names must start with a letter or underscore and contain only letters, numbers, or underscores"
|
|
7696
8050
|
);
|
|
7697
8051
|
}
|
|
7698
8052
|
parseParsedString() {
|
|
@@ -7701,7 +8055,7 @@ ${pointer}`;
|
|
|
7701
8055
|
if (this.match(quoteChar)) {
|
|
7702
8056
|
let content = "";
|
|
7703
8057
|
let escaped = false;
|
|
7704
|
-
|
|
8058
|
+
const startPos = this.position - 1;
|
|
7705
8059
|
while (this.position < this.input.length) {
|
|
7706
8060
|
const char = this.input[this.position];
|
|
7707
8061
|
this.position++;
|
|
@@ -7716,9 +8070,15 @@ ${pointer}`;
|
|
|
7716
8070
|
content += char;
|
|
7717
8071
|
}
|
|
7718
8072
|
}
|
|
7719
|
-
const partialString = this.input.slice(
|
|
7720
|
-
|
|
7721
|
-
|
|
8073
|
+
const partialString = this.input.slice(
|
|
8074
|
+
startPos,
|
|
8075
|
+
Math.min(this.position, startPos + 20)
|
|
8076
|
+
);
|
|
8077
|
+
throw new SignatureValidationError(
|
|
8078
|
+
`Unterminated string starting at position ${startPos}`,
|
|
8079
|
+
startPos,
|
|
8080
|
+
this.getErrorContext(),
|
|
8081
|
+
`Add closing ${quoteChar} to complete the string: ${partialString}${quoteChar}`
|
|
7722
8082
|
);
|
|
7723
8083
|
}
|
|
7724
8084
|
}
|
|
@@ -7746,11 +8106,15 @@ ${pointer}`;
|
|
|
7746
8106
|
}
|
|
7747
8107
|
return false;
|
|
7748
8108
|
}
|
|
7749
|
-
|
|
7750
|
-
if (!this.match(
|
|
8109
|
+
expectArrow() {
|
|
8110
|
+
if (!this.match("->")) {
|
|
7751
8111
|
const found = this.input.slice(this.position, this.position + 10);
|
|
7752
|
-
|
|
7753
|
-
|
|
8112
|
+
const suggestion = found.includes(">") ? 'Use "->" (dash followed by greater-than)' : found.includes("-") ? 'Add ">" after the dash' : 'Add "->" to separate input and output fields';
|
|
8113
|
+
throw new SignatureValidationError(
|
|
8114
|
+
`Expected "->" but found "${found}..."`,
|
|
8115
|
+
this.position,
|
|
8116
|
+
this.getErrorContext(),
|
|
8117
|
+
suggestion
|
|
7754
8118
|
);
|
|
7755
8119
|
}
|
|
7756
8120
|
}
|
|
@@ -7761,6 +8125,14 @@ function parseSignature(input) {
|
|
|
7761
8125
|
}
|
|
7762
8126
|
|
|
7763
8127
|
// dsp/sig.ts
|
|
8128
|
+
var AxSignatureValidationError = class extends Error {
|
|
8129
|
+
constructor(message, fieldName, suggestion) {
|
|
8130
|
+
super(message);
|
|
8131
|
+
this.fieldName = fieldName;
|
|
8132
|
+
this.suggestion = suggestion;
|
|
8133
|
+
this.name = "AxSignatureValidationError";
|
|
8134
|
+
}
|
|
8135
|
+
};
|
|
7764
8136
|
var AxSignature = class _AxSignature {
|
|
7765
8137
|
description;
|
|
7766
8138
|
inputFields;
|
|
@@ -7780,8 +8152,18 @@ var AxSignature = class _AxSignature {
|
|
|
7780
8152
|
try {
|
|
7781
8153
|
sig = parseSignature(signature);
|
|
7782
8154
|
} catch (e) {
|
|
7783
|
-
|
|
7784
|
-
|
|
8155
|
+
if (e instanceof Error) {
|
|
8156
|
+
const suggestion = "suggestion" in e && typeof e.suggestion === "string" ? e.suggestion : 'Please check the signature format. Example: "userInput:string -> responseText:string"';
|
|
8157
|
+
throw new AxSignatureValidationError(
|
|
8158
|
+
`Invalid Signature: ${e.message}`,
|
|
8159
|
+
void 0,
|
|
8160
|
+
suggestion
|
|
8161
|
+
);
|
|
8162
|
+
}
|
|
8163
|
+
throw new AxSignatureValidationError(
|
|
8164
|
+
`Invalid Signature: ${signature}`,
|
|
8165
|
+
void 0,
|
|
8166
|
+
'Please check the signature format. Example: "userInput:string -> responseText:string"'
|
|
7785
8167
|
);
|
|
7786
8168
|
}
|
|
7787
8169
|
this.description = sig.desc;
|
|
@@ -7799,12 +8181,20 @@ var AxSignature = class _AxSignature {
|
|
|
7799
8181
|
this.sigHash = signature.hash();
|
|
7800
8182
|
this.sigString = signature.toString();
|
|
7801
8183
|
} else {
|
|
7802
|
-
throw new
|
|
8184
|
+
throw new AxSignatureValidationError(
|
|
8185
|
+
"Invalid signature argument type",
|
|
8186
|
+
void 0,
|
|
8187
|
+
"Signature must be a string or another AxSignature instance"
|
|
8188
|
+
);
|
|
7803
8189
|
}
|
|
7804
8190
|
}
|
|
7805
8191
|
parseParsedField = (field) => {
|
|
7806
8192
|
if (!field.name || field.name.length === 0) {
|
|
7807
|
-
throw new
|
|
8193
|
+
throw new AxSignatureValidationError(
|
|
8194
|
+
"Field name is required",
|
|
8195
|
+
field.name,
|
|
8196
|
+
'Every field must have a descriptive name. Example: "userInput", "responseText"'
|
|
8197
|
+
);
|
|
7808
8198
|
}
|
|
7809
8199
|
const title = this.toTitle(field.name);
|
|
7810
8200
|
return {
|
|
@@ -7819,29 +8209,106 @@ var AxSignature = class _AxSignature {
|
|
|
7819
8209
|
parseField = (field) => {
|
|
7820
8210
|
const title = !field.title || field.title.length === 0 ? this.toTitle(field.name) : field.title;
|
|
7821
8211
|
if (field.type && (!field.type.name || field.type.name.length === 0)) {
|
|
7822
|
-
throw new
|
|
8212
|
+
throw new AxSignatureValidationError(
|
|
8213
|
+
"Field type name is required",
|
|
8214
|
+
field.name,
|
|
8215
|
+
"Specify a valid type. Available types: string, number, boolean, json, image, audio, date, datetime, class, code"
|
|
8216
|
+
);
|
|
7823
8217
|
}
|
|
7824
8218
|
return { ...field, title };
|
|
7825
8219
|
};
|
|
7826
8220
|
setDescription = (desc) => {
|
|
8221
|
+
if (typeof desc !== "string") {
|
|
8222
|
+
throw new AxSignatureValidationError(
|
|
8223
|
+
"Description must be a string",
|
|
8224
|
+
void 0,
|
|
8225
|
+
"Provide a string description for the signature"
|
|
8226
|
+
);
|
|
8227
|
+
}
|
|
7827
8228
|
this.description = desc;
|
|
7828
8229
|
this.updateHash();
|
|
7829
8230
|
};
|
|
7830
8231
|
addInputField = (field) => {
|
|
7831
|
-
|
|
7832
|
-
|
|
8232
|
+
try {
|
|
8233
|
+
const parsedField = this.parseField(field);
|
|
8234
|
+
validateField(parsedField, "input");
|
|
8235
|
+
this.inputFields.push(parsedField);
|
|
8236
|
+
this.updateHash();
|
|
8237
|
+
} catch (error) {
|
|
8238
|
+
if (error instanceof AxSignatureValidationError) {
|
|
8239
|
+
throw error;
|
|
8240
|
+
}
|
|
8241
|
+
throw new AxSignatureValidationError(
|
|
8242
|
+
`Failed to add input field "${field.name}": ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
8243
|
+
field.name
|
|
8244
|
+
);
|
|
8245
|
+
}
|
|
7833
8246
|
};
|
|
7834
8247
|
addOutputField = (field) => {
|
|
7835
|
-
|
|
7836
|
-
|
|
8248
|
+
try {
|
|
8249
|
+
const parsedField = this.parseField(field);
|
|
8250
|
+
validateField(parsedField, "output");
|
|
8251
|
+
this.outputFields.push(parsedField);
|
|
8252
|
+
this.updateHash();
|
|
8253
|
+
} catch (error) {
|
|
8254
|
+
if (error instanceof AxSignatureValidationError) {
|
|
8255
|
+
throw error;
|
|
8256
|
+
}
|
|
8257
|
+
throw new AxSignatureValidationError(
|
|
8258
|
+
`Failed to add output field "${field.name}": ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
8259
|
+
field.name
|
|
8260
|
+
);
|
|
8261
|
+
}
|
|
7837
8262
|
};
|
|
7838
8263
|
setInputFields = (fields) => {
|
|
7839
|
-
|
|
7840
|
-
|
|
8264
|
+
if (!Array.isArray(fields)) {
|
|
8265
|
+
throw new AxSignatureValidationError(
|
|
8266
|
+
"Input fields must be an array",
|
|
8267
|
+
void 0,
|
|
8268
|
+
"Provide an array of field objects"
|
|
8269
|
+
);
|
|
8270
|
+
}
|
|
8271
|
+
try {
|
|
8272
|
+
const parsedFields = fields.map((v) => {
|
|
8273
|
+
const parsed = this.parseField(v);
|
|
8274
|
+
validateField(parsed, "input");
|
|
8275
|
+
return parsed;
|
|
8276
|
+
});
|
|
8277
|
+
this.inputFields = parsedFields;
|
|
8278
|
+
this.updateHash();
|
|
8279
|
+
} catch (error) {
|
|
8280
|
+
if (error instanceof AxSignatureValidationError) {
|
|
8281
|
+
throw error;
|
|
8282
|
+
}
|
|
8283
|
+
throw new AxSignatureValidationError(
|
|
8284
|
+
`Failed to set input fields: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
8285
|
+
);
|
|
8286
|
+
}
|
|
7841
8287
|
};
|
|
7842
8288
|
setOutputFields = (fields) => {
|
|
7843
|
-
|
|
7844
|
-
|
|
8289
|
+
if (!Array.isArray(fields)) {
|
|
8290
|
+
throw new AxSignatureValidationError(
|
|
8291
|
+
"Output fields must be an array",
|
|
8292
|
+
void 0,
|
|
8293
|
+
"Provide an array of field objects"
|
|
8294
|
+
);
|
|
8295
|
+
}
|
|
8296
|
+
try {
|
|
8297
|
+
const parsedFields = fields.map((v) => {
|
|
8298
|
+
const parsed = this.parseField(v);
|
|
8299
|
+
validateField(parsed, "output");
|
|
8300
|
+
return parsed;
|
|
8301
|
+
});
|
|
8302
|
+
this.outputFields = parsedFields;
|
|
8303
|
+
this.updateHash();
|
|
8304
|
+
} catch (error) {
|
|
8305
|
+
if (error instanceof AxSignatureValidationError) {
|
|
8306
|
+
throw error;
|
|
8307
|
+
}
|
|
8308
|
+
throw new AxSignatureValidationError(
|
|
8309
|
+
`Failed to set output fields: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
8310
|
+
);
|
|
8311
|
+
}
|
|
7845
8312
|
};
|
|
7846
8313
|
getInputFields = () => this.inputFields;
|
|
7847
8314
|
getOutputFields = () => this.outputFields;
|
|
@@ -7883,23 +8350,77 @@ var AxSignature = class _AxSignature {
|
|
|
7883
8350
|
return schema;
|
|
7884
8351
|
};
|
|
7885
8352
|
updateHash = () => {
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
8353
|
+
try {
|
|
8354
|
+
this.getInputFields().forEach((field) => {
|
|
8355
|
+
validateField(field, "input");
|
|
8356
|
+
});
|
|
8357
|
+
this.getOutputFields().forEach((field) => {
|
|
8358
|
+
validateField(field, "output");
|
|
8359
|
+
});
|
|
8360
|
+
this.validateSignatureConsistency();
|
|
8361
|
+
this.sigHash = (0, import_crypto3.createHash)("sha256").update(this.description ?? "").update(JSON.stringify(this.inputFields)).update(JSON.stringify(this.outputFields)).digest("hex");
|
|
8362
|
+
this.sigString = renderSignature(
|
|
8363
|
+
this.description,
|
|
8364
|
+
this.inputFields,
|
|
8365
|
+
this.outputFields
|
|
8366
|
+
);
|
|
8367
|
+
return [this.sigHash, this.sigString];
|
|
8368
|
+
} catch (error) {
|
|
8369
|
+
if (error instanceof AxSignatureValidationError) {
|
|
8370
|
+
throw error;
|
|
7893
8371
|
}
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
this.inputFields,
|
|
7899
|
-
this.outputFields
|
|
7900
|
-
);
|
|
7901
|
-
return [this.sigHash, this.sigString];
|
|
8372
|
+
throw new AxSignatureValidationError(
|
|
8373
|
+
`Signature validation failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
8374
|
+
);
|
|
8375
|
+
}
|
|
7902
8376
|
};
|
|
8377
|
+
validateSignatureConsistency() {
|
|
8378
|
+
const inputNames = /* @__PURE__ */ new Set();
|
|
8379
|
+
for (const field of this.inputFields) {
|
|
8380
|
+
if (inputNames.has(field.name)) {
|
|
8381
|
+
throw new AxSignatureValidationError(
|
|
8382
|
+
`Duplicate input field name: "${field.name}"`,
|
|
8383
|
+
field.name,
|
|
8384
|
+
"Each field name must be unique within the signature"
|
|
8385
|
+
);
|
|
8386
|
+
}
|
|
8387
|
+
inputNames.add(field.name);
|
|
8388
|
+
}
|
|
8389
|
+
const outputNames = /* @__PURE__ */ new Set();
|
|
8390
|
+
for (const field of this.outputFields) {
|
|
8391
|
+
if (outputNames.has(field.name)) {
|
|
8392
|
+
throw new AxSignatureValidationError(
|
|
8393
|
+
`Duplicate output field name: "${field.name}"`,
|
|
8394
|
+
field.name,
|
|
8395
|
+
"Each field name must be unique within the signature"
|
|
8396
|
+
);
|
|
8397
|
+
}
|
|
8398
|
+
outputNames.add(field.name);
|
|
8399
|
+
}
|
|
8400
|
+
for (const outputField of this.outputFields) {
|
|
8401
|
+
if (inputNames.has(outputField.name)) {
|
|
8402
|
+
throw new AxSignatureValidationError(
|
|
8403
|
+
`Field name "${outputField.name}" appears in both inputs and outputs`,
|
|
8404
|
+
outputField.name,
|
|
8405
|
+
"Use different names for input and output fields to avoid confusion"
|
|
8406
|
+
);
|
|
8407
|
+
}
|
|
8408
|
+
}
|
|
8409
|
+
if (this.inputFields.length === 0) {
|
|
8410
|
+
throw new AxSignatureValidationError(
|
|
8411
|
+
"Signature must have at least one input field",
|
|
8412
|
+
void 0,
|
|
8413
|
+
'Add an input field. Example: "userInput:string -> ..."'
|
|
8414
|
+
);
|
|
8415
|
+
}
|
|
8416
|
+
if (this.outputFields.length === 0) {
|
|
8417
|
+
throw new AxSignatureValidationError(
|
|
8418
|
+
"Signature must have at least one output field",
|
|
8419
|
+
void 0,
|
|
8420
|
+
'Add an output field. Example: "... -> responseText:string"'
|
|
8421
|
+
);
|
|
8422
|
+
}
|
|
8423
|
+
}
|
|
7903
8424
|
hash = () => this.sigHash;
|
|
7904
8425
|
toString = () => this.sigString;
|
|
7905
8426
|
toJSON = () => {
|
|
@@ -7916,54 +8437,194 @@ function renderField(field) {
|
|
|
7916
8437
|
if (field.isOptional) {
|
|
7917
8438
|
result += "?";
|
|
7918
8439
|
}
|
|
8440
|
+
if (field.isInternal) {
|
|
8441
|
+
result += "!";
|
|
8442
|
+
}
|
|
7919
8443
|
if (field.type) {
|
|
7920
8444
|
result += ":" + field.type.name;
|
|
7921
8445
|
if (field.type.isArray) {
|
|
7922
8446
|
result += "[]";
|
|
7923
8447
|
}
|
|
8448
|
+
if (field.type.name === "class" && field.type.options) {
|
|
8449
|
+
result += ` "${field.type.options.join(", ")}"`;
|
|
8450
|
+
}
|
|
7924
8451
|
}
|
|
7925
|
-
if (field.description) {
|
|
8452
|
+
if (field.description && field.type?.name !== "class") {
|
|
7926
8453
|
result += ` "${field.description}"`;
|
|
7927
8454
|
}
|
|
7928
8455
|
return result;
|
|
7929
8456
|
}
|
|
7930
8457
|
function renderSignature(description, inputFields, outputFields) {
|
|
7931
|
-
const descriptionPart = description ? `"${description}"` : "";
|
|
8458
|
+
const descriptionPart = description ? `"${description}" ` : "";
|
|
7932
8459
|
const inputFieldsRendered = inputFields.map(renderField).join(", ");
|
|
7933
8460
|
const outputFieldsRendered = outputFields.map(renderField).join(", ");
|
|
7934
|
-
return `${descriptionPart}
|
|
8461
|
+
return `${descriptionPart}${inputFieldsRendered} -> ${outputFieldsRendered}`;
|
|
7935
8462
|
}
|
|
7936
8463
|
function isValidCase(inputString) {
|
|
7937
8464
|
const camelCaseRegex = /^[a-z][a-zA-Z0-9]*$/;
|
|
7938
8465
|
const snakeCaseRegex = /^[a-z]+(_[a-z0-9]+)*$/;
|
|
7939
8466
|
return camelCaseRegex.test(inputString) || snakeCaseRegex.test(inputString);
|
|
7940
8467
|
}
|
|
7941
|
-
function validateField(field) {
|
|
8468
|
+
function validateField(field, context3) {
|
|
7942
8469
|
if (!field.name || field.name.length === 0) {
|
|
7943
|
-
throw new
|
|
8470
|
+
throw new AxSignatureValidationError(
|
|
8471
|
+
"Field name cannot be blank",
|
|
8472
|
+
field.name,
|
|
8473
|
+
"Every field must have a descriptive name"
|
|
8474
|
+
);
|
|
7944
8475
|
}
|
|
7945
8476
|
if (!isValidCase(field.name)) {
|
|
7946
|
-
throw new
|
|
7947
|
-
`Invalid field name '${field.name}'
|
|
8477
|
+
throw new AxSignatureValidationError(
|
|
8478
|
+
`Invalid field name '${field.name}' - must be camelCase or snake_case`,
|
|
8479
|
+
field.name,
|
|
8480
|
+
'Use camelCase (e.g., "userInput") or snake_case (e.g., "user_input")'
|
|
7948
8481
|
);
|
|
7949
8482
|
}
|
|
7950
|
-
if (
|
|
7951
|
-
|
|
7952
|
-
|
|
7953
|
-
|
|
7954
|
-
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
8483
|
+
if (axGlobals.signatureStrict) {
|
|
8484
|
+
const reservedNames = [
|
|
8485
|
+
"text",
|
|
8486
|
+
"object",
|
|
8487
|
+
"image",
|
|
8488
|
+
"string",
|
|
8489
|
+
"number",
|
|
8490
|
+
"boolean",
|
|
8491
|
+
"json",
|
|
8492
|
+
"array",
|
|
8493
|
+
"datetime",
|
|
8494
|
+
"date",
|
|
8495
|
+
"time",
|
|
8496
|
+
"type",
|
|
8497
|
+
"class",
|
|
8498
|
+
"input",
|
|
8499
|
+
"output",
|
|
8500
|
+
"data",
|
|
8501
|
+
"value",
|
|
8502
|
+
"result",
|
|
8503
|
+
"response",
|
|
8504
|
+
"request",
|
|
8505
|
+
"item",
|
|
8506
|
+
"element"
|
|
8507
|
+
];
|
|
8508
|
+
if (reservedNames.includes(field.name.toLowerCase())) {
|
|
8509
|
+
const suggestions = context3 === "input" ? [
|
|
8510
|
+
"userInput",
|
|
8511
|
+
"questionText",
|
|
8512
|
+
"documentContent",
|
|
8513
|
+
"messageText",
|
|
8514
|
+
"queryString"
|
|
8515
|
+
] : [
|
|
8516
|
+
"responseText",
|
|
8517
|
+
"analysisResult",
|
|
8518
|
+
"categoryType",
|
|
8519
|
+
"summaryText",
|
|
8520
|
+
"outputData"
|
|
8521
|
+
];
|
|
8522
|
+
throw new AxSignatureValidationError(
|
|
8523
|
+
`Field name '${field.name}' is too generic`,
|
|
8524
|
+
field.name,
|
|
8525
|
+
`Use a more descriptive name. Examples for ${context3} fields: ${suggestions.join(", ")}`
|
|
8526
|
+
);
|
|
8527
|
+
}
|
|
8528
|
+
}
|
|
8529
|
+
if (field.name.length < 2) {
|
|
8530
|
+
throw new AxSignatureValidationError(
|
|
8531
|
+
`Field name '${field.name}' is too short`,
|
|
8532
|
+
field.name,
|
|
8533
|
+
"Field names must be at least 2 characters long"
|
|
8534
|
+
);
|
|
8535
|
+
}
|
|
8536
|
+
if (field.name.length > 50) {
|
|
8537
|
+
throw new AxSignatureValidationError(
|
|
8538
|
+
`Field name '${field.name}' is too long (${field.name.length} characters)`,
|
|
8539
|
+
field.name,
|
|
8540
|
+
"Field names should be 50 characters or less"
|
|
8541
|
+
);
|
|
8542
|
+
}
|
|
8543
|
+
if (field.type) {
|
|
8544
|
+
validateFieldType(field, context3);
|
|
8545
|
+
}
|
|
8546
|
+
}
|
|
8547
|
+
function validateFieldType(field, context3) {
|
|
8548
|
+
if (!field.type) return;
|
|
8549
|
+
const { type } = field;
|
|
8550
|
+
if (type.name === "image" || type.name === "audio") {
|
|
8551
|
+
if (context3 === "output") {
|
|
8552
|
+
throw new AxSignatureValidationError(
|
|
8553
|
+
`${type.name} type is not supported in output fields`,
|
|
8554
|
+
field.name,
|
|
8555
|
+
`${type.name} types can only be used in input fields`
|
|
8556
|
+
);
|
|
8557
|
+
}
|
|
8558
|
+
if (type.isArray) {
|
|
8559
|
+
throw new AxSignatureValidationError(
|
|
8560
|
+
`Arrays of ${type.name} are not supported`,
|
|
8561
|
+
field.name,
|
|
8562
|
+
`Use a single ${type.name} type instead`
|
|
8563
|
+
);
|
|
8564
|
+
}
|
|
8565
|
+
}
|
|
8566
|
+
if (type.name === "class") {
|
|
8567
|
+
if (context3 === "input") {
|
|
8568
|
+
throw new AxSignatureValidationError(
|
|
8569
|
+
"Class type is not supported in input fields",
|
|
8570
|
+
field.name,
|
|
8571
|
+
'Class types are only allowed on output fields. Use "string" type for input classifications'
|
|
8572
|
+
);
|
|
8573
|
+
}
|
|
8574
|
+
if (!type.options || type.options.length === 0) {
|
|
8575
|
+
throw new AxSignatureValidationError(
|
|
8576
|
+
"Class type requires options",
|
|
8577
|
+
field.name,
|
|
8578
|
+
'Provide class options. Example: class "positive, negative, neutral"'
|
|
8579
|
+
);
|
|
8580
|
+
}
|
|
8581
|
+
if (type.options.length === 1) {
|
|
8582
|
+
throw new AxSignatureValidationError(
|
|
8583
|
+
"Class type needs at least 2 options",
|
|
8584
|
+
field.name,
|
|
8585
|
+
'Add more class options or use "string" type instead'
|
|
8586
|
+
);
|
|
8587
|
+
}
|
|
8588
|
+
for (const option of type.options) {
|
|
8589
|
+
if (!option || option.trim().length === 0) {
|
|
8590
|
+
throw new AxSignatureValidationError(
|
|
8591
|
+
"Empty class option found",
|
|
8592
|
+
field.name,
|
|
8593
|
+
"All class options must be non-empty strings"
|
|
8594
|
+
);
|
|
8595
|
+
}
|
|
8596
|
+
const trimmedOption = option.trim();
|
|
8597
|
+
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(trimmedOption)) {
|
|
8598
|
+
throw new AxSignatureValidationError(
|
|
8599
|
+
`Invalid class option "${trimmedOption}"`,
|
|
8600
|
+
field.name,
|
|
8601
|
+
"Class options must start with a letter and contain only letters, numbers, underscores, or hyphens"
|
|
8602
|
+
);
|
|
8603
|
+
}
|
|
8604
|
+
}
|
|
8605
|
+
const uniqueOptions = new Set(
|
|
8606
|
+
type.options.map((opt) => opt.trim().toLowerCase())
|
|
8607
|
+
);
|
|
8608
|
+
if (uniqueOptions.size !== type.options.length) {
|
|
8609
|
+
throw new AxSignatureValidationError(
|
|
8610
|
+
"Duplicate class options found",
|
|
8611
|
+
field.name,
|
|
8612
|
+
"Each class option must be unique (case-insensitive)"
|
|
8613
|
+
);
|
|
8614
|
+
}
|
|
8615
|
+
}
|
|
8616
|
+
if (type.name === "code" && type.isArray) {
|
|
8617
|
+
throw new AxSignatureValidationError(
|
|
8618
|
+
"Arrays of code are not commonly supported",
|
|
8619
|
+
field.name,
|
|
8620
|
+
"Consider using a single code field or an array of strings instead"
|
|
8621
|
+
);
|
|
8622
|
+
}
|
|
8623
|
+
if (field.isInternal && context3 === "input") {
|
|
8624
|
+
throw new AxSignatureValidationError(
|
|
8625
|
+
"Internal marker (!) is not allowed on input fields",
|
|
8626
|
+
field.name,
|
|
8627
|
+
"Internal markers are only allowed on output fields"
|
|
7967
8628
|
);
|
|
7968
8629
|
}
|
|
7969
8630
|
}
|
|
@@ -8554,6 +9215,7 @@ Content: ${result.content}`
|
|
|
8554
9215
|
}
|
|
8555
9216
|
let prompt;
|
|
8556
9217
|
if (Array.isArray(values)) {
|
|
9218
|
+
validateAxMessageArray(values);
|
|
8557
9219
|
prompt = this.promptTemplate.render(values, {
|
|
8558
9220
|
examples: this.examples,
|
|
8559
9221
|
demos: this.demos
|
|
@@ -11696,13 +12358,18 @@ var AxMockAIService = class {
|
|
|
11696
12358
|
}
|
|
11697
12359
|
};
|
|
11698
12360
|
getLastUsedChatModel() {
|
|
11699
|
-
|
|
12361
|
+
return this.config.modelInfo?.name ?? "mock-model";
|
|
11700
12362
|
}
|
|
11701
12363
|
getLastUsedEmbedModel() {
|
|
11702
|
-
|
|
12364
|
+
return this.config.embedModelInfo?.name ?? "mock-embed-model";
|
|
11703
12365
|
}
|
|
11704
12366
|
getLastUsedModelConfig() {
|
|
11705
|
-
|
|
12367
|
+
return this.config.modelInfo ? {
|
|
12368
|
+
maxTokens: this.config.modelInfo.maxTokens,
|
|
12369
|
+
temperature: 0.7,
|
|
12370
|
+
// Default temperature
|
|
12371
|
+
stream: this.config.features?.streaming ?? false
|
|
12372
|
+
} : void 0;
|
|
11706
12373
|
}
|
|
11707
12374
|
getName() {
|
|
11708
12375
|
return this.config.name ?? "mock-ai-service";
|
|
@@ -14106,6 +14773,7 @@ var AxRAG = class extends AxChainOfThought {
|
|
|
14106
14773
|
axAITogetherDefaultConfig,
|
|
14107
14774
|
axBaseAIDefaultConfig,
|
|
14108
14775
|
axBaseAIDefaultCreativeConfig,
|
|
14776
|
+
axGlobals,
|
|
14109
14777
|
axModelInfoAnthropic,
|
|
14110
14778
|
axModelInfoCohere,
|
|
14111
14779
|
axModelInfoDeepSeek,
|