@axlsdk/axl 0.7.6 → 0.9.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/README.md +32 -7
- package/dist/index.cjs +167 -94
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +56 -11
- package/dist/index.d.ts +56 -11
- package/dist/index.js +167 -95
- package/dist/index.js.map +1 -1
- package/package.json +3 -4
package/dist/index.js
CHANGED
|
@@ -1922,7 +1922,7 @@ var defaultRegistry = new ProviderRegistry();
|
|
|
1922
1922
|
|
|
1923
1923
|
// src/context.ts
|
|
1924
1924
|
import { AsyncLocalStorage } from "async_hooks";
|
|
1925
|
-
import { ZodError } from "zod";
|
|
1925
|
+
import { z, ZodError } from "zod";
|
|
1926
1926
|
|
|
1927
1927
|
// src/errors.ts
|
|
1928
1928
|
var AxlError = class extends Error {
|
|
@@ -1998,6 +1998,18 @@ var GuardrailError = class extends AxlError {
|
|
|
1998
1998
|
this.reason = reason;
|
|
1999
1999
|
}
|
|
2000
2000
|
};
|
|
2001
|
+
var ValidationError = class extends AxlError {
|
|
2002
|
+
lastOutput;
|
|
2003
|
+
reason;
|
|
2004
|
+
retries;
|
|
2005
|
+
constructor(lastOutput, reason, retries) {
|
|
2006
|
+
super("VALIDATION_ERROR", `Validation failed after ${retries} retries: ${reason}`);
|
|
2007
|
+
this.name = "ValidationError";
|
|
2008
|
+
this.lastOutput = lastOutput;
|
|
2009
|
+
this.reason = reason;
|
|
2010
|
+
this.retries = retries;
|
|
2011
|
+
}
|
|
2012
|
+
};
|
|
2001
2013
|
var ToolDenied = class extends AxlError {
|
|
2002
2014
|
toolName;
|
|
2003
2015
|
agentName;
|
|
@@ -2090,48 +2102,9 @@ function resolveConfig(config) {
|
|
|
2090
2102
|
// src/context.ts
|
|
2091
2103
|
var signalStorage = new AsyncLocalStorage();
|
|
2092
2104
|
function zodToJsonSchema(schema) {
|
|
2093
|
-
const
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
case "ZodString":
|
|
2097
|
-
return { type: "string" };
|
|
2098
|
-
case "ZodNumber":
|
|
2099
|
-
return { type: "number" };
|
|
2100
|
-
case "ZodBoolean":
|
|
2101
|
-
return { type: "boolean" };
|
|
2102
|
-
case "ZodArray":
|
|
2103
|
-
return { type: "array", items: zodToJsonSchema(def.type) };
|
|
2104
|
-
case "ZodObject": {
|
|
2105
|
-
const shape = def.shape?.() ?? {};
|
|
2106
|
-
const properties = {};
|
|
2107
|
-
const required = [];
|
|
2108
|
-
for (const [key, value] of Object.entries(shape)) {
|
|
2109
|
-
properties[key] = zodToJsonSchema(value);
|
|
2110
|
-
const innerDef = value._def;
|
|
2111
|
-
if (innerDef?.typeName !== "ZodOptional" && innerDef?.typeName !== "ZodDefault") {
|
|
2112
|
-
required.push(key);
|
|
2113
|
-
}
|
|
2114
|
-
}
|
|
2115
|
-
return { type: "object", properties, required: required.length > 0 ? required : void 0 };
|
|
2116
|
-
}
|
|
2117
|
-
case "ZodOptional":
|
|
2118
|
-
return zodToJsonSchema(def.innerType);
|
|
2119
|
-
case "ZodDefault":
|
|
2120
|
-
return zodToJsonSchema(def.innerType);
|
|
2121
|
-
case "ZodEnum":
|
|
2122
|
-
return { type: "string", enum: def.values };
|
|
2123
|
-
case "ZodLiteral": {
|
|
2124
|
-
const v = def.value;
|
|
2125
|
-
const t = v === null ? "null" : typeof v;
|
|
2126
|
-
return { type: t, const: v };
|
|
2127
|
-
}
|
|
2128
|
-
case "ZodUnion":
|
|
2129
|
-
return { oneOf: def.options.map((o) => zodToJsonSchema(o)) };
|
|
2130
|
-
case "ZodNullable":
|
|
2131
|
-
return { ...zodToJsonSchema(def.innerType), nullable: true };
|
|
2132
|
-
default:
|
|
2133
|
-
return {};
|
|
2134
|
-
}
|
|
2105
|
+
const result = z.toJSONSchema(schema, { unrepresentable: "any" });
|
|
2106
|
+
delete result.$schema;
|
|
2107
|
+
return result;
|
|
2135
2108
|
}
|
|
2136
2109
|
function estimateTokens(text) {
|
|
2137
2110
|
return Math.ceil(text.length / 4);
|
|
@@ -2262,9 +2235,6 @@ var WorkflowContext = class _WorkflowContext {
|
|
|
2262
2235
|
agent2,
|
|
2263
2236
|
prompt,
|
|
2264
2237
|
options,
|
|
2265
|
-
0,
|
|
2266
|
-
void 0,
|
|
2267
|
-
void 0,
|
|
2268
2238
|
void 0,
|
|
2269
2239
|
usageCapture
|
|
2270
2240
|
);
|
|
@@ -2314,7 +2284,7 @@ var WorkflowContext = class _WorkflowContext {
|
|
|
2314
2284
|
return result;
|
|
2315
2285
|
});
|
|
2316
2286
|
}
|
|
2317
|
-
async executeAgentCall(agent2, prompt, options,
|
|
2287
|
+
async executeAgentCall(agent2, prompt, options, handoffMessages, usageCapture) {
|
|
2318
2288
|
if (this.budgetContext?.exceeded) {
|
|
2319
2289
|
const { limit, totalCost: spent, policy } = this.budgetContext;
|
|
2320
2290
|
if (policy === "warn") {
|
|
@@ -2386,16 +2356,6 @@ var WorkflowContext = class _WorkflowContext {
|
|
|
2386
2356
|
|
|
2387
2357
|
Respond with valid JSON matching this schema:
|
|
2388
2358
|
${JSON.stringify(jsonSchema, null, 2)}`;
|
|
2389
|
-
}
|
|
2390
|
-
if (previousOutput && previousError) {
|
|
2391
|
-
userContent += `
|
|
2392
|
-
|
|
2393
|
-
Your previous response was invalid:
|
|
2394
|
-
${previousOutput}
|
|
2395
|
-
|
|
2396
|
-
Error: ${previousError}
|
|
2397
|
-
|
|
2398
|
-
Please fix and try again.`;
|
|
2399
2359
|
}
|
|
2400
2360
|
messages.push({ role: "user", content: userContent });
|
|
2401
2361
|
if (handoffMessages && handoffMessages.length > 0) {
|
|
@@ -2440,9 +2400,17 @@ Please fix and try again.`;
|
|
|
2440
2400
|
const maxTurns = agent2._config.maxTurns ?? 25;
|
|
2441
2401
|
const timeoutMs = parseDuration(agent2._config.timeout ?? "60s");
|
|
2442
2402
|
const startTime = Date.now();
|
|
2403
|
+
if (this.onToken && options?.validate) {
|
|
2404
|
+
throw new AxlError(
|
|
2405
|
+
"INVALID_CONFIG",
|
|
2406
|
+
"Cannot use validate with streaming. Validate requires schema (JSON output) which does not benefit from token streaming. Use a non-streaming call instead."
|
|
2407
|
+
);
|
|
2408
|
+
}
|
|
2443
2409
|
const currentMessages = [...messages];
|
|
2444
2410
|
let turns = 0;
|
|
2445
2411
|
let guardrailOutputRetries = 0;
|
|
2412
|
+
let schemaRetries = 0;
|
|
2413
|
+
let validateRetries = 0;
|
|
2446
2414
|
while (turns < maxTurns) {
|
|
2447
2415
|
if (Date.now() - startTime > timeoutMs) {
|
|
2448
2416
|
throw new TimeoutError("ctx.ask()", timeoutMs);
|
|
@@ -2570,14 +2538,17 @@ Please fix and try again.`;
|
|
|
2570
2538
|
}
|
|
2571
2539
|
}
|
|
2572
2540
|
const handoffStart = Date.now();
|
|
2573
|
-
const handoffOptions = options ? {
|
|
2541
|
+
const handoffOptions = options ? {
|
|
2542
|
+
schema: options.schema,
|
|
2543
|
+
retries: options.retries,
|
|
2544
|
+
metadata: options.metadata,
|
|
2545
|
+
validate: options.validate,
|
|
2546
|
+
validateRetries: options.validateRetries
|
|
2547
|
+
} : void 0;
|
|
2574
2548
|
const handoffFn = () => this.executeAgentCall(
|
|
2575
2549
|
descriptor.agent,
|
|
2576
2550
|
handoffPrompt,
|
|
2577
2551
|
handoffOptions,
|
|
2578
|
-
0,
|
|
2579
|
-
void 0,
|
|
2580
|
-
void 0,
|
|
2581
2552
|
currentMessages,
|
|
2582
2553
|
usageCapture
|
|
2583
2554
|
);
|
|
@@ -2911,26 +2882,26 @@ Please fix and try again.`;
|
|
|
2911
2882
|
throw new GuardrailError("output", outputResult.reason ?? "Output blocked by guardrail");
|
|
2912
2883
|
}
|
|
2913
2884
|
}
|
|
2885
|
+
let validated = void 0;
|
|
2914
2886
|
if (options?.schema) {
|
|
2915
2887
|
try {
|
|
2916
2888
|
const parsed = JSON.parse(stripMarkdownFences(content));
|
|
2917
|
-
|
|
2918
|
-
this.pushAssistantToSessionHistory(content, response.providerMetadata);
|
|
2919
|
-
return validated;
|
|
2889
|
+
validated = options.schema.parse(parsed);
|
|
2920
2890
|
} catch (err) {
|
|
2921
|
-
const
|
|
2922
|
-
if (
|
|
2891
|
+
const maxSchemaRetries = options.retries ?? 3;
|
|
2892
|
+
if (schemaRetries < maxSchemaRetries) {
|
|
2893
|
+
schemaRetries++;
|
|
2923
2894
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
prompt,
|
|
2927
|
-
options,
|
|
2928
|
-
retryCount + 1,
|
|
2895
|
+
currentMessages.push({
|
|
2896
|
+
role: "assistant",
|
|
2929
2897
|
content,
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2898
|
+
...response.providerMetadata ? { providerMetadata: response.providerMetadata } : {}
|
|
2899
|
+
});
|
|
2900
|
+
currentMessages.push({
|
|
2901
|
+
role: "system",
|
|
2902
|
+
content: `Your response was not valid JSON or did not match the required schema: ${errorMsg}. Please fix and try again.`
|
|
2903
|
+
});
|
|
2904
|
+
continue;
|
|
2934
2905
|
}
|
|
2935
2906
|
const zodErr = err instanceof ZodError ? err : new ZodError([
|
|
2936
2907
|
{
|
|
@@ -2939,11 +2910,55 @@ Please fix and try again.`;
|
|
|
2939
2910
|
message: err instanceof Error ? err.message : String(err)
|
|
2940
2911
|
}
|
|
2941
2912
|
]);
|
|
2942
|
-
throw new VerifyError(content, zodErr,
|
|
2913
|
+
throw new VerifyError(content, zodErr, maxSchemaRetries);
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
if (options?.schema && options.validate) {
|
|
2917
|
+
let validateResult;
|
|
2918
|
+
try {
|
|
2919
|
+
validateResult = await options.validate(validated, {
|
|
2920
|
+
metadata: this.metadata
|
|
2921
|
+
});
|
|
2922
|
+
} catch (err) {
|
|
2923
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
2924
|
+
validateResult = { valid: false, reason: `Validator error: ${reason}` };
|
|
2925
|
+
}
|
|
2926
|
+
this.emitTrace({
|
|
2927
|
+
type: "validate",
|
|
2928
|
+
agent: agent2._name,
|
|
2929
|
+
data: {
|
|
2930
|
+
valid: validateResult.valid,
|
|
2931
|
+
...validateResult.reason ? { reason: validateResult.reason } : {}
|
|
2932
|
+
}
|
|
2933
|
+
});
|
|
2934
|
+
this.spanManager?.addEventToActiveSpan("axl.validate.check", {
|
|
2935
|
+
"axl.validate.valid": validateResult.valid,
|
|
2936
|
+
...validateResult.reason ? { "axl.validate.reason": validateResult.reason } : {}
|
|
2937
|
+
});
|
|
2938
|
+
if (!validateResult.valid) {
|
|
2939
|
+
const maxValidateRetries = options.validateRetries ?? 2;
|
|
2940
|
+
if (validateRetries < maxValidateRetries) {
|
|
2941
|
+
validateRetries++;
|
|
2942
|
+
currentMessages.push({
|
|
2943
|
+
role: "assistant",
|
|
2944
|
+
content,
|
|
2945
|
+
...response.providerMetadata ? { providerMetadata: response.providerMetadata } : {}
|
|
2946
|
+
});
|
|
2947
|
+
currentMessages.push({
|
|
2948
|
+
role: "system",
|
|
2949
|
+
content: `Your response parsed correctly but failed validation: ${validateResult.reason ?? "Validation failed"}. Previous attempts are visible above. Please fix and try again.`
|
|
2950
|
+
});
|
|
2951
|
+
continue;
|
|
2952
|
+
}
|
|
2953
|
+
throw new ValidationError(
|
|
2954
|
+
validated,
|
|
2955
|
+
validateResult.reason ?? "Validation failed",
|
|
2956
|
+
maxValidateRetries
|
|
2957
|
+
);
|
|
2943
2958
|
}
|
|
2944
2959
|
}
|
|
2945
2960
|
this.pushAssistantToSessionHistory(content, response.providerMetadata);
|
|
2946
|
-
return content;
|
|
2961
|
+
return validated ?? content;
|
|
2947
2962
|
}
|
|
2948
2963
|
throw new MaxTurnsError("ctx.ask()", maxTurns);
|
|
2949
2964
|
}
|
|
@@ -3300,32 +3315,57 @@ ${summaryResponse.content}`
|
|
|
3300
3315
|
// ── ctx.verify() ──────────────────────────────────────────────────────
|
|
3301
3316
|
async verify(fn, schema, options) {
|
|
3302
3317
|
const maxRetries = options?.retries ?? 3;
|
|
3303
|
-
let
|
|
3304
|
-
let lastErrorMessage = void 0;
|
|
3318
|
+
let lastRetry = void 0;
|
|
3305
3319
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
3306
|
-
let
|
|
3320
|
+
let rawOutput;
|
|
3307
3321
|
try {
|
|
3308
|
-
result = await fn(
|
|
3309
|
-
|
|
3310
|
-
|
|
3322
|
+
const result = await fn(lastRetry);
|
|
3323
|
+
rawOutput = result;
|
|
3324
|
+
const parsed = schema.parse(result);
|
|
3325
|
+
if (options?.validate) {
|
|
3326
|
+
let validateResult;
|
|
3327
|
+
try {
|
|
3328
|
+
validateResult = await options.validate(parsed, { metadata: this.metadata });
|
|
3329
|
+
} catch (err) {
|
|
3330
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
3331
|
+
validateResult = { valid: false, reason: `Validator error: ${reason}` };
|
|
3332
|
+
}
|
|
3333
|
+
if (!validateResult.valid) {
|
|
3334
|
+
const errorMsg = validateResult.reason ?? "Validation failed";
|
|
3335
|
+
lastRetry = { error: errorMsg, output: rawOutput, parsed };
|
|
3336
|
+
if (attempt === maxRetries) {
|
|
3337
|
+
if (options?.fallback !== void 0) return options.fallback;
|
|
3338
|
+
throw new ValidationError(parsed, errorMsg, maxRetries);
|
|
3339
|
+
}
|
|
3340
|
+
continue;
|
|
3341
|
+
}
|
|
3342
|
+
}
|
|
3343
|
+
return parsed;
|
|
3311
3344
|
} catch (err) {
|
|
3312
|
-
if (err instanceof
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3345
|
+
if (err instanceof ValidationError) {
|
|
3346
|
+
lastRetry = {
|
|
3347
|
+
error: err.reason,
|
|
3348
|
+
output: rawOutput,
|
|
3349
|
+
parsed: err.lastOutput
|
|
3350
|
+
};
|
|
3351
|
+
if (attempt === maxRetries) {
|
|
3352
|
+
if (options?.fallback !== void 0) return options.fallback;
|
|
3353
|
+
throw err;
|
|
3354
|
+
}
|
|
3355
|
+
continue;
|
|
3318
3356
|
}
|
|
3357
|
+
const errorMsg = err instanceof ZodError ? err.message : err instanceof Error ? err.message : String(err);
|
|
3358
|
+
lastRetry = { error: errorMsg, output: rawOutput };
|
|
3319
3359
|
if (attempt === maxRetries) {
|
|
3320
3360
|
if (options?.fallback !== void 0) return options.fallback;
|
|
3321
|
-
const zodErr = err instanceof ZodError ? err : new ZodError([{ code: "custom", path: [], message:
|
|
3322
|
-
throw new VerifyError(
|
|
3361
|
+
const zodErr = err instanceof ZodError ? err : new ZodError([{ code: "custom", path: [], message: errorMsg }]);
|
|
3362
|
+
throw new VerifyError(rawOutput, zodErr, maxRetries);
|
|
3323
3363
|
}
|
|
3324
3364
|
}
|
|
3325
3365
|
}
|
|
3326
3366
|
if (options?.fallback !== void 0) return options.fallback;
|
|
3327
3367
|
throw new VerifyError(
|
|
3328
|
-
|
|
3368
|
+
lastRetry?.output,
|
|
3329
3369
|
new ZodError([{ code: "custom", path: [], message: "Verify failed" }]),
|
|
3330
3370
|
maxRetries
|
|
3331
3371
|
);
|
|
@@ -3427,7 +3467,7 @@ ${summaryResponse.content}`
|
|
|
3427
3467
|
let remaining = fns.length;
|
|
3428
3468
|
for (const fn of fns) {
|
|
3429
3469
|
const p = signalStorage.run(composedSignal, fn);
|
|
3430
|
-
p.then((value) => {
|
|
3470
|
+
p.then(async (value) => {
|
|
3431
3471
|
if (settled) return;
|
|
3432
3472
|
if (schema) {
|
|
3433
3473
|
const parsed = schema.safeParse(value);
|
|
@@ -3440,6 +3480,33 @@ ${summaryResponse.content}`
|
|
|
3440
3480
|
}
|
|
3441
3481
|
return;
|
|
3442
3482
|
}
|
|
3483
|
+
if (options?.validate) {
|
|
3484
|
+
try {
|
|
3485
|
+
const validateResult = await options.validate(parsed.data, {
|
|
3486
|
+
metadata: this.metadata
|
|
3487
|
+
});
|
|
3488
|
+
if (!validateResult.valid) {
|
|
3489
|
+
remaining--;
|
|
3490
|
+
lastError = new Error(
|
|
3491
|
+
`Validation failed: ${validateResult.reason ?? "Validation failed"}`
|
|
3492
|
+
);
|
|
3493
|
+
if (remaining === 0 && !settled) {
|
|
3494
|
+
settled = true;
|
|
3495
|
+
reject(lastError);
|
|
3496
|
+
}
|
|
3497
|
+
return;
|
|
3498
|
+
}
|
|
3499
|
+
} catch (err) {
|
|
3500
|
+
remaining--;
|
|
3501
|
+
lastError = err instanceof Error ? err : new Error(`Validator error: ${String(err)}`);
|
|
3502
|
+
if (remaining === 0 && !settled) {
|
|
3503
|
+
settled = true;
|
|
3504
|
+
reject(lastError);
|
|
3505
|
+
}
|
|
3506
|
+
return;
|
|
3507
|
+
}
|
|
3508
|
+
}
|
|
3509
|
+
if (settled) return;
|
|
3443
3510
|
settled = true;
|
|
3444
3511
|
controller.abort();
|
|
3445
3512
|
resolve(parsed.data);
|
|
@@ -3691,7 +3758,9 @@ ${summaryResponse.content}`
|
|
|
3691
3758
|
return this.ask(agents[0], prompt, {
|
|
3692
3759
|
schema: options?.schema,
|
|
3693
3760
|
retries: options?.retries,
|
|
3694
|
-
metadata: options?.metadata
|
|
3761
|
+
metadata: options?.metadata,
|
|
3762
|
+
validate: options?.validate,
|
|
3763
|
+
validateRetries: options?.validateRetries
|
|
3695
3764
|
});
|
|
3696
3765
|
}
|
|
3697
3766
|
const resolveCtx = options?.metadata ? { metadata: { ...this.metadata, ...options.metadata } } : { metadata: this.metadata };
|
|
@@ -3732,7 +3801,9 @@ ${summaryResponse.content}`
|
|
|
3732
3801
|
return this.ask(routerAgent, prompt, {
|
|
3733
3802
|
schema: options?.schema,
|
|
3734
3803
|
retries: options?.retries,
|
|
3735
|
-
metadata: options?.metadata
|
|
3804
|
+
metadata: options?.metadata,
|
|
3805
|
+
validate: options?.validate,
|
|
3806
|
+
validateRetries: options?.validateRetries
|
|
3736
3807
|
});
|
|
3737
3808
|
}
|
|
3738
3809
|
// ── Private ───────────────────────────────────────────────────────────
|
|
@@ -6012,6 +6083,7 @@ export {
|
|
|
6012
6083
|
SqliteVectorStore,
|
|
6013
6084
|
TimeoutError,
|
|
6014
6085
|
ToolDenied,
|
|
6086
|
+
ValidationError,
|
|
6015
6087
|
VerifyError,
|
|
6016
6088
|
WorkflowContext,
|
|
6017
6089
|
agent,
|