@ax-llm/ax 12.0.0 → 12.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +138 -40
- package/index.cjs.map +1 -1
- package/index.d.cts +38 -33
- package/index.d.ts +38 -33
- package/index.js +138 -40
- package/index.js.map +1 -1
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -1270,6 +1270,7 @@ var AxBaseAI = class {
|
|
|
1270
1270
|
if (chatReq.functions && chatReq.functions.length > 0) {
|
|
1271
1271
|
functions = chatReq.functions.map((fn2) => this.cleanupFunctionSchema(fn2));
|
|
1272
1272
|
}
|
|
1273
|
+
validateChatPrompt(chatReq.chatPrompt);
|
|
1273
1274
|
const req = {
|
|
1274
1275
|
...chatReq,
|
|
1275
1276
|
model,
|
|
@@ -1611,6 +1612,31 @@ function setChatResponseEvents(res, span, excludeContentFromTrace) {
|
|
|
1611
1612
|
});
|
|
1612
1613
|
}
|
|
1613
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
|
+
}
|
|
1614
1640
|
function validateModels(models) {
|
|
1615
1641
|
const keys = /* @__PURE__ */ new Set();
|
|
1616
1642
|
for (const model of models) {
|
|
@@ -3387,7 +3413,9 @@ var AxAIGoogleGeminiImpl = class {
|
|
|
3387
3413
|
const contents = req.chatPrompt.filter((p) => p.role !== "system").map((msg, i) => {
|
|
3388
3414
|
switch (msg.role) {
|
|
3389
3415
|
case "user": {
|
|
3390
|
-
const parts = Array.isArray(
|
|
3416
|
+
const parts = Array.isArray(
|
|
3417
|
+
msg.content
|
|
3418
|
+
) ? msg.content.map((c, i2) => {
|
|
3391
3419
|
switch (c.type) {
|
|
3392
3420
|
case "text":
|
|
3393
3421
|
return { text: c.text };
|
|
@@ -3448,12 +3476,14 @@ var AxAIGoogleGeminiImpl = class {
|
|
|
3448
3476
|
}
|
|
3449
3477
|
];
|
|
3450
3478
|
return {
|
|
3451
|
-
role: "
|
|
3479
|
+
role: "model",
|
|
3452
3480
|
parts
|
|
3453
3481
|
};
|
|
3454
3482
|
}
|
|
3455
3483
|
default:
|
|
3456
|
-
throw new Error(
|
|
3484
|
+
throw new Error(
|
|
3485
|
+
`Invalid role: ${JSON.stringify(msg)} (index: ${i})`
|
|
3486
|
+
);
|
|
3457
3487
|
}
|
|
3458
3488
|
});
|
|
3459
3489
|
let tools = [];
|
|
@@ -5629,10 +5659,15 @@ var MemoryImpl = class {
|
|
|
5629
5659
|
name,
|
|
5630
5660
|
functionCalls
|
|
5631
5661
|
}) {
|
|
5632
|
-
|
|
5662
|
+
const isContentEmpty = typeof content === "string" && content.trim() === "";
|
|
5663
|
+
if (isContentEmpty && (!functionCalls || functionCalls.length === 0)) {
|
|
5633
5664
|
return;
|
|
5634
5665
|
}
|
|
5635
|
-
|
|
5666
|
+
if (isContentEmpty) {
|
|
5667
|
+
this.addMemory({ name, role: "assistant", functionCalls });
|
|
5668
|
+
} else {
|
|
5669
|
+
this.addMemory({ content, name, role: "assistant", functionCalls });
|
|
5670
|
+
}
|
|
5636
5671
|
}
|
|
5637
5672
|
addResult({
|
|
5638
5673
|
content,
|
|
@@ -5654,7 +5689,7 @@ var MemoryImpl = class {
|
|
|
5654
5689
|
if (!lastItem || lastItem.chat.role !== "assistant") {
|
|
5655
5690
|
this.addResultMessage({ content, name, functionCalls });
|
|
5656
5691
|
} else {
|
|
5657
|
-
if ("content" in lastItem.chat && content) {
|
|
5692
|
+
if ("content" in lastItem.chat && typeof content === "string" && content.trim() !== "") {
|
|
5658
5693
|
lastItem.chat.content = content;
|
|
5659
5694
|
}
|
|
5660
5695
|
if ("name" in lastItem.chat && name) {
|
|
@@ -7785,7 +7820,7 @@ var SignatureParser = class {
|
|
|
7785
7820
|
'Add class names in quotes. Example: class "positive, negative, neutral"'
|
|
7786
7821
|
);
|
|
7787
7822
|
}
|
|
7788
|
-
const options = classNamesString.split(/[
|
|
7823
|
+
const options = classNamesString.split(/[,|]/).map((s2) => s2.trim()).filter((s2) => s2.length > 0);
|
|
7789
7824
|
if (options.length === 0) {
|
|
7790
7825
|
throw new SignatureValidationError(
|
|
7791
7826
|
`Output field "${name}": Empty class list provided`,
|
|
@@ -7794,24 +7829,6 @@ var SignatureParser = class {
|
|
|
7794
7829
|
'Provide at least one class option. Example: "positive, negative"'
|
|
7795
7830
|
);
|
|
7796
7831
|
}
|
|
7797
|
-
if (options.length === 1) {
|
|
7798
|
-
throw new SignatureValidationError(
|
|
7799
|
-
`Output field "${name}": Class type needs at least 2 options`,
|
|
7800
|
-
this.position,
|
|
7801
|
-
this.getErrorContext(),
|
|
7802
|
-
'Add more class options or use "string" type instead. Example: "positive, negative, neutral"'
|
|
7803
|
-
);
|
|
7804
|
-
}
|
|
7805
|
-
for (const option of options) {
|
|
7806
|
-
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(option)) {
|
|
7807
|
-
throw new SignatureValidationError(
|
|
7808
|
-
`Output field "${name}": Invalid class option "${option}"`,
|
|
7809
|
-
this.position,
|
|
7810
|
-
this.getErrorContext(),
|
|
7811
|
-
"Class options must start with a letter and contain only letters, numbers, underscores, or hyphens"
|
|
7812
|
-
);
|
|
7813
|
-
}
|
|
7814
|
-
}
|
|
7815
7832
|
type = { name: "class", isArray, options };
|
|
7816
7833
|
} else {
|
|
7817
7834
|
try {
|
|
@@ -8109,6 +8126,8 @@ var AxSignature = class _AxSignature {
|
|
|
8109
8126
|
outputFields;
|
|
8110
8127
|
sigHash;
|
|
8111
8128
|
sigString;
|
|
8129
|
+
// Validation caching - stores hash when validation last passed
|
|
8130
|
+
validatedAtHash;
|
|
8112
8131
|
constructor(signature) {
|
|
8113
8132
|
if (!signature) {
|
|
8114
8133
|
this.inputFields = [];
|
|
@@ -8150,6 +8169,9 @@ var AxSignature = class _AxSignature {
|
|
|
8150
8169
|
);
|
|
8151
8170
|
this.sigHash = signature.hash();
|
|
8152
8171
|
this.sigString = signature.toString();
|
|
8172
|
+
if (signature.validatedAtHash === this.sigHash) {
|
|
8173
|
+
this.validatedAtHash = this.sigHash;
|
|
8174
|
+
}
|
|
8153
8175
|
} else {
|
|
8154
8176
|
throw new AxSignatureValidationError(
|
|
8155
8177
|
"Invalid signature argument type",
|
|
@@ -8196,14 +8218,34 @@ var AxSignature = class _AxSignature {
|
|
|
8196
8218
|
);
|
|
8197
8219
|
}
|
|
8198
8220
|
this.description = desc;
|
|
8221
|
+
this.invalidateValidationCache();
|
|
8199
8222
|
this.updateHash();
|
|
8200
8223
|
};
|
|
8201
8224
|
addInputField = (field) => {
|
|
8202
8225
|
try {
|
|
8203
8226
|
const parsedField = this.parseField(field);
|
|
8204
8227
|
validateField(parsedField, "input");
|
|
8228
|
+
for (const existingField of this.inputFields) {
|
|
8229
|
+
if (existingField.name === parsedField.name) {
|
|
8230
|
+
throw new AxSignatureValidationError(
|
|
8231
|
+
`Duplicate input field name: "${parsedField.name}"`,
|
|
8232
|
+
parsedField.name,
|
|
8233
|
+
"Each field name must be unique within the signature"
|
|
8234
|
+
);
|
|
8235
|
+
}
|
|
8236
|
+
}
|
|
8237
|
+
for (const outputField of this.outputFields) {
|
|
8238
|
+
if (outputField.name === parsedField.name) {
|
|
8239
|
+
throw new AxSignatureValidationError(
|
|
8240
|
+
`Field name "${parsedField.name}" appears in both inputs and outputs`,
|
|
8241
|
+
parsedField.name,
|
|
8242
|
+
"Use different names for input and output fields to avoid confusion"
|
|
8243
|
+
);
|
|
8244
|
+
}
|
|
8245
|
+
}
|
|
8205
8246
|
this.inputFields.push(parsedField);
|
|
8206
|
-
this.
|
|
8247
|
+
this.invalidateValidationCache();
|
|
8248
|
+
this.updateHashLight();
|
|
8207
8249
|
} catch (error) {
|
|
8208
8250
|
if (error instanceof AxSignatureValidationError) {
|
|
8209
8251
|
throw error;
|
|
@@ -8218,8 +8260,27 @@ var AxSignature = class _AxSignature {
|
|
|
8218
8260
|
try {
|
|
8219
8261
|
const parsedField = this.parseField(field);
|
|
8220
8262
|
validateField(parsedField, "output");
|
|
8263
|
+
for (const existingField of this.outputFields) {
|
|
8264
|
+
if (existingField.name === parsedField.name) {
|
|
8265
|
+
throw new AxSignatureValidationError(
|
|
8266
|
+
`Duplicate output field name: "${parsedField.name}"`,
|
|
8267
|
+
parsedField.name,
|
|
8268
|
+
"Each field name must be unique within the signature"
|
|
8269
|
+
);
|
|
8270
|
+
}
|
|
8271
|
+
}
|
|
8272
|
+
for (const inputField of this.inputFields) {
|
|
8273
|
+
if (inputField.name === parsedField.name) {
|
|
8274
|
+
throw new AxSignatureValidationError(
|
|
8275
|
+
`Field name "${parsedField.name}" appears in both inputs and outputs`,
|
|
8276
|
+
parsedField.name,
|
|
8277
|
+
"Use different names for input and output fields to avoid confusion"
|
|
8278
|
+
);
|
|
8279
|
+
}
|
|
8280
|
+
}
|
|
8221
8281
|
this.outputFields.push(parsedField);
|
|
8222
|
-
this.
|
|
8282
|
+
this.invalidateValidationCache();
|
|
8283
|
+
this.updateHashLight();
|
|
8223
8284
|
} catch (error) {
|
|
8224
8285
|
if (error instanceof AxSignatureValidationError) {
|
|
8225
8286
|
throw error;
|
|
@@ -8245,6 +8306,7 @@ var AxSignature = class _AxSignature {
|
|
|
8245
8306
|
return parsed;
|
|
8246
8307
|
});
|
|
8247
8308
|
this.inputFields = parsedFields;
|
|
8309
|
+
this.invalidateValidationCache();
|
|
8248
8310
|
this.updateHash();
|
|
8249
8311
|
} catch (error) {
|
|
8250
8312
|
if (error instanceof AxSignatureValidationError) {
|
|
@@ -8270,6 +8332,7 @@ var AxSignature = class _AxSignature {
|
|
|
8270
8332
|
return parsed;
|
|
8271
8333
|
});
|
|
8272
8334
|
this.outputFields = parsedFields;
|
|
8335
|
+
this.invalidateValidationCache();
|
|
8273
8336
|
this.updateHash();
|
|
8274
8337
|
} catch (error) {
|
|
8275
8338
|
if (error instanceof AxSignatureValidationError) {
|
|
@@ -8283,6 +8346,9 @@ var AxSignature = class _AxSignature {
|
|
|
8283
8346
|
getInputFields = () => this.inputFields;
|
|
8284
8347
|
getOutputFields = () => this.outputFields;
|
|
8285
8348
|
getDescription = () => this.description;
|
|
8349
|
+
invalidateValidationCache = () => {
|
|
8350
|
+
this.validatedAtHash = void 0;
|
|
8351
|
+
};
|
|
8286
8352
|
toTitle = (name) => {
|
|
8287
8353
|
let result = name.replace(/_/g, " ");
|
|
8288
8354
|
result = result.replace(/([A-Z]|[0-9]+)/g, " $1").trim();
|
|
@@ -8319,6 +8385,30 @@ var AxSignature = class _AxSignature {
|
|
|
8319
8385
|
};
|
|
8320
8386
|
return schema;
|
|
8321
8387
|
};
|
|
8388
|
+
updateHashLight = () => {
|
|
8389
|
+
try {
|
|
8390
|
+
this.getInputFields().forEach((field) => {
|
|
8391
|
+
validateField(field, "input");
|
|
8392
|
+
});
|
|
8393
|
+
this.getOutputFields().forEach((field) => {
|
|
8394
|
+
validateField(field, "output");
|
|
8395
|
+
});
|
|
8396
|
+
this.sigHash = (0, import_crypto3.createHash)("sha256").update(this.description ?? "").update(JSON.stringify(this.inputFields)).update(JSON.stringify(this.outputFields)).digest("hex");
|
|
8397
|
+
this.sigString = renderSignature(
|
|
8398
|
+
this.description,
|
|
8399
|
+
this.inputFields,
|
|
8400
|
+
this.outputFields
|
|
8401
|
+
);
|
|
8402
|
+
return [this.sigHash, this.sigString];
|
|
8403
|
+
} catch (error) {
|
|
8404
|
+
if (error instanceof AxSignatureValidationError) {
|
|
8405
|
+
throw error;
|
|
8406
|
+
}
|
|
8407
|
+
throw new AxSignatureValidationError(
|
|
8408
|
+
`Signature validation failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
8409
|
+
);
|
|
8410
|
+
}
|
|
8411
|
+
};
|
|
8322
8412
|
updateHash = () => {
|
|
8323
8413
|
try {
|
|
8324
8414
|
this.getInputFields().forEach((field) => {
|
|
@@ -8391,6 +8481,19 @@ var AxSignature = class _AxSignature {
|
|
|
8391
8481
|
);
|
|
8392
8482
|
}
|
|
8393
8483
|
}
|
|
8484
|
+
validate = () => {
|
|
8485
|
+
if (this.validatedAtHash === this.sigHash) {
|
|
8486
|
+
return true;
|
|
8487
|
+
}
|
|
8488
|
+
try {
|
|
8489
|
+
this.updateHash();
|
|
8490
|
+
this.validatedAtHash = this.sigHash;
|
|
8491
|
+
return true;
|
|
8492
|
+
} catch (error) {
|
|
8493
|
+
this.validatedAtHash = void 0;
|
|
8494
|
+
throw error;
|
|
8495
|
+
}
|
|
8496
|
+
};
|
|
8394
8497
|
hash = () => this.sigHash;
|
|
8395
8498
|
toString = () => this.sigString;
|
|
8396
8499
|
toJSON = () => {
|
|
@@ -8416,7 +8519,7 @@ function renderField(field) {
|
|
|
8416
8519
|
result += "[]";
|
|
8417
8520
|
}
|
|
8418
8521
|
if (field.type.name === "class" && field.type.options) {
|
|
8419
|
-
result += ` "${field.type.options.join("
|
|
8522
|
+
result += ` "${field.type.options.join(" | ")}"`;
|
|
8420
8523
|
}
|
|
8421
8524
|
}
|
|
8422
8525
|
if (field.description && field.type?.name !== "class") {
|
|
@@ -8548,13 +8651,6 @@ function validateFieldType(field, context3) {
|
|
|
8548
8651
|
'Provide class options. Example: class "positive, negative, neutral"'
|
|
8549
8652
|
);
|
|
8550
8653
|
}
|
|
8551
|
-
if (type.options.length === 1) {
|
|
8552
|
-
throw new AxSignatureValidationError(
|
|
8553
|
-
"Class type needs at least 2 options",
|
|
8554
|
-
field.name,
|
|
8555
|
-
'Add more class options or use "string" type instead'
|
|
8556
|
-
);
|
|
8557
|
-
}
|
|
8558
8654
|
for (const option of type.options) {
|
|
8559
8655
|
if (!option || option.trim().length === 0) {
|
|
8560
8656
|
throw new AxSignatureValidationError(
|
|
@@ -8564,11 +8660,11 @@ function validateFieldType(field, context3) {
|
|
|
8564
8660
|
);
|
|
8565
8661
|
}
|
|
8566
8662
|
const trimmedOption = option.trim();
|
|
8567
|
-
if (
|
|
8663
|
+
if (trimmedOption.includes(",") || trimmedOption.includes("|")) {
|
|
8568
8664
|
throw new AxSignatureValidationError(
|
|
8569
8665
|
`Invalid class option "${trimmedOption}"`,
|
|
8570
8666
|
field.name,
|
|
8571
|
-
"Class options
|
|
8667
|
+
"Class options cannot contain commas (,) or pipes (|) as they are used to separate options"
|
|
8572
8668
|
);
|
|
8573
8669
|
}
|
|
8574
8670
|
}
|
|
@@ -8612,12 +8708,13 @@ var AxProgramWithSignature = class {
|
|
|
8612
8708
|
children;
|
|
8613
8709
|
constructor(signature, options) {
|
|
8614
8710
|
this.signature = new AxSignature(signature);
|
|
8615
|
-
this.sigHash = this.signature?.hash();
|
|
8616
|
-
this.children = new AxInstanceRegistry();
|
|
8617
|
-
this.key = { id: this.constructor.name };
|
|
8618
8711
|
if (options?.description) {
|
|
8619
8712
|
this.signature.setDescription(options.description);
|
|
8620
8713
|
}
|
|
8714
|
+
this.signature.validate();
|
|
8715
|
+
this.sigHash = this.signature?.hash();
|
|
8716
|
+
this.children = new AxInstanceRegistry();
|
|
8717
|
+
this.key = { id: this.constructor.name };
|
|
8621
8718
|
}
|
|
8622
8719
|
getSignature() {
|
|
8623
8720
|
return this.signature;
|
|
@@ -9185,6 +9282,7 @@ Content: ${result.content}`
|
|
|
9185
9282
|
}
|
|
9186
9283
|
let prompt;
|
|
9187
9284
|
if (Array.isArray(values)) {
|
|
9285
|
+
validateAxMessageArray(values);
|
|
9188
9286
|
prompt = this.promptTemplate.render(values, {
|
|
9189
9287
|
examples: this.examples,
|
|
9190
9288
|
demos: this.demos
|