@axlsdk/axl 0.21.0 → 0.21.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/dist/index.cjs +266 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +266 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -380,6 +380,221 @@ var ValidationError = class extends AxlError {
|
|
|
380
380
|
|
|
381
381
|
// src/tool.ts
|
|
382
382
|
var DEFAULT_MAX_STRING_LENGTH = 1e4;
|
|
383
|
+
var MAX_MODEL_ARGUMENT_ISSUES = 8;
|
|
384
|
+
var MAX_MODEL_ARGUMENT_MESSAGE_LENGTH = 2e3;
|
|
385
|
+
var MAX_MODEL_ARGUMENT_LINE_LENGTH = 220;
|
|
386
|
+
var MAX_MODEL_ARGUMENT_PATH_LENGTH = 160;
|
|
387
|
+
var MAX_UNION_DEPTH = 3;
|
|
388
|
+
var MAX_UNION_BRANCHES = 4;
|
|
389
|
+
var MAX_LITERAL_ALTERNATIVES = 10;
|
|
390
|
+
var SAFE_SCHEMA_TYPES = /* @__PURE__ */ new Set([
|
|
391
|
+
"string",
|
|
392
|
+
"number",
|
|
393
|
+
"boolean",
|
|
394
|
+
"null",
|
|
395
|
+
"array",
|
|
396
|
+
"object",
|
|
397
|
+
"integer"
|
|
398
|
+
]);
|
|
399
|
+
var SAFE_STRING_FORMATS = /* @__PURE__ */ new Set([
|
|
400
|
+
"email",
|
|
401
|
+
"url",
|
|
402
|
+
"emoji",
|
|
403
|
+
"uuid",
|
|
404
|
+
"guid",
|
|
405
|
+
"nanoid",
|
|
406
|
+
"cuid",
|
|
407
|
+
"cuid2",
|
|
408
|
+
"ulid",
|
|
409
|
+
"xid",
|
|
410
|
+
"ksuid",
|
|
411
|
+
"datetime",
|
|
412
|
+
"date",
|
|
413
|
+
"time",
|
|
414
|
+
"duration",
|
|
415
|
+
"ipv4",
|
|
416
|
+
"ipv6",
|
|
417
|
+
"cidrv4",
|
|
418
|
+
"cidrv6",
|
|
419
|
+
"base64",
|
|
420
|
+
"base64url",
|
|
421
|
+
"json_string",
|
|
422
|
+
"e164",
|
|
423
|
+
"lowercase",
|
|
424
|
+
"uppercase",
|
|
425
|
+
"jwt"
|
|
426
|
+
]);
|
|
427
|
+
function truncateModelFeedback(value, maximum) {
|
|
428
|
+
return value.length <= maximum ? value : `${value.slice(0, Math.max(0, maximum - 1))}\u2026`;
|
|
429
|
+
}
|
|
430
|
+
var DISPLAY_CONTROL_CHARACTERS = /[\u061C\u200B-\u200F\u202A-\u202E\u2066-\u2069\u2028\u2029]/g;
|
|
431
|
+
function isJsonSchema(value) {
|
|
432
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
433
|
+
}
|
|
434
|
+
function escapeDisplayControls(value) {
|
|
435
|
+
return value.replace(
|
|
436
|
+
DISPLAY_CONTROL_CHARACTERS,
|
|
437
|
+
(character) => `\\u${character.codePointAt(0).toString(16).padStart(4, "0")}`
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
function quoteModelText(value) {
|
|
441
|
+
return escapeDisplayControls(JSON.stringify(value));
|
|
442
|
+
}
|
|
443
|
+
function schemaNumber(value) {
|
|
444
|
+
return typeof value === "number" && Number.isFinite(value) ? String(value) : void 0;
|
|
445
|
+
}
|
|
446
|
+
function schemaLiteral(value) {
|
|
447
|
+
if (typeof value === "string") {
|
|
448
|
+
const rendered = quoteModelText(value);
|
|
449
|
+
return rendered.length <= 120 ? rendered : '"<literal omitted>"';
|
|
450
|
+
}
|
|
451
|
+
if (typeof value === "number") return Number.isFinite(value) ? String(value) : void 0;
|
|
452
|
+
if (typeof value === "boolean") return String(value);
|
|
453
|
+
if (value === null) return "null";
|
|
454
|
+
return void 0;
|
|
455
|
+
}
|
|
456
|
+
function schemaType(schema) {
|
|
457
|
+
const type = schema.type;
|
|
458
|
+
return typeof type === "string" && SAFE_SCHEMA_TYPES.has(type) ? type : void 0;
|
|
459
|
+
}
|
|
460
|
+
function compositionBranches(schema) {
|
|
461
|
+
const branches = [];
|
|
462
|
+
for (const key of ["anyOf", "oneOf", "allOf"]) {
|
|
463
|
+
const value = schema[key];
|
|
464
|
+
if (!Array.isArray(value)) continue;
|
|
465
|
+
for (const branch of value.slice(0, MAX_UNION_BRANCHES)) {
|
|
466
|
+
if (isJsonSchema(branch)) branches.push(branch);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return branches;
|
|
470
|
+
}
|
|
471
|
+
function unionBranches(schema) {
|
|
472
|
+
const branches = [];
|
|
473
|
+
for (const key of ["anyOf", "oneOf"]) {
|
|
474
|
+
const value = schema[key];
|
|
475
|
+
if (!Array.isArray(value)) continue;
|
|
476
|
+
for (const branch of value.slice(0, MAX_UNION_BRANCHES)) {
|
|
477
|
+
if (isJsonSchema(branch)) branches.push(branch);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return branches;
|
|
481
|
+
}
|
|
482
|
+
function resolvePathSegment(schema, segment, depth = 0) {
|
|
483
|
+
if (depth >= MAX_UNION_DEPTH) return void 0;
|
|
484
|
+
if (typeof segment === "string") {
|
|
485
|
+
const properties = schema.properties;
|
|
486
|
+
if (isJsonSchema(properties) && Object.hasOwn(properties, segment)) {
|
|
487
|
+
const child = properties[segment];
|
|
488
|
+
if (isJsonSchema(child)) return { node: child, renderedSegment: segment };
|
|
489
|
+
}
|
|
490
|
+
if (isJsonSchema(schema.additionalProperties)) {
|
|
491
|
+
return { node: schema.additionalProperties, renderedSegment: "<key>" };
|
|
492
|
+
}
|
|
493
|
+
} else if (typeof segment === "number" && Number.isSafeInteger(segment) && segment >= 0) {
|
|
494
|
+
const prefixItems = schema.prefixItems;
|
|
495
|
+
if (Array.isArray(prefixItems) && isJsonSchema(prefixItems[segment])) {
|
|
496
|
+
return { node: prefixItems[segment], renderedSegment: String(segment) };
|
|
497
|
+
}
|
|
498
|
+
if (isJsonSchema(schema.items)) {
|
|
499
|
+
return { node: schema.items, renderedSegment: "<index>" };
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
for (const branch of compositionBranches(schema)) {
|
|
503
|
+
const resolved = resolvePathSegment(branch, segment, depth + 1);
|
|
504
|
+
if (resolved !== void 0) return resolved;
|
|
505
|
+
}
|
|
506
|
+
return void 0;
|
|
507
|
+
}
|
|
508
|
+
function resolveSchemaPath(providerVisibleSchema, issuePath) {
|
|
509
|
+
if (!isJsonSchema(providerVisibleSchema)) return void 0;
|
|
510
|
+
let node = providerVisibleSchema;
|
|
511
|
+
const segments = [];
|
|
512
|
+
for (const segment of issuePath) {
|
|
513
|
+
const resolved = resolvePathSegment(node, segment);
|
|
514
|
+
if (resolved === void 0) {
|
|
515
|
+
segments.push("<path omitted>");
|
|
516
|
+
return { node, segments };
|
|
517
|
+
}
|
|
518
|
+
node = resolved.node;
|
|
519
|
+
segments.push(resolved.renderedSegment);
|
|
520
|
+
}
|
|
521
|
+
return { node, segments };
|
|
522
|
+
}
|
|
523
|
+
function jsonPointerPath(segments) {
|
|
524
|
+
if (segments.length === 0) return "<root>";
|
|
525
|
+
const pointer = `/${segments.map((segment) => segment.replaceAll("~", "~0").replaceAll("/", "~1")).join("/")}`;
|
|
526
|
+
const rendered = quoteModelText(pointer);
|
|
527
|
+
return rendered.length <= MAX_MODEL_ARGUMENT_PATH_LENGTH ? rendered : '"<path omitted>"';
|
|
528
|
+
}
|
|
529
|
+
function schemaAlternatives(schema, depth = 0) {
|
|
530
|
+
if (depth >= MAX_UNION_DEPTH) return [];
|
|
531
|
+
const constant = "const" in schema ? schemaLiteral(schema.const) : void 0;
|
|
532
|
+
if (constant !== void 0) return [constant];
|
|
533
|
+
if (Array.isArray(schema.enum)) {
|
|
534
|
+
const values = schema.enum.slice(0, MAX_LITERAL_ALTERNATIVES).map(schemaLiteral);
|
|
535
|
+
if (values.every((value) => value !== void 0)) return values;
|
|
536
|
+
}
|
|
537
|
+
const type = schemaType(schema);
|
|
538
|
+
if (type !== void 0) return [type];
|
|
539
|
+
const alternatives = unionBranches(schema).flatMap(
|
|
540
|
+
(branch) => schemaAlternatives(branch, depth + 1)
|
|
541
|
+
);
|
|
542
|
+
return alternatives.slice(0, MAX_LITERAL_ALTERNATIVES);
|
|
543
|
+
}
|
|
544
|
+
function schemaEnumExpectation(schema) {
|
|
545
|
+
if ("const" in schema) {
|
|
546
|
+
const constant = schemaLiteral(schema.const);
|
|
547
|
+
return constant === void 0 ? void 0 : `expected ${constant}`;
|
|
548
|
+
}
|
|
549
|
+
if (!Array.isArray(schema.enum)) return void 0;
|
|
550
|
+
const values = schema.enum.slice(0, MAX_LITERAL_ALTERNATIVES).map(schemaLiteral);
|
|
551
|
+
if (values.some((value) => value === void 0)) return void 0;
|
|
552
|
+
const rendered = values;
|
|
553
|
+
if (rendered.length === 0) return void 0;
|
|
554
|
+
const omission = schema.enum.length > rendered.length ? ", \u2026" : "";
|
|
555
|
+
return `expected ${rendered.length === 1 ? rendered[0] : `one of ${rendered.join(", ")}`}${omission}`;
|
|
556
|
+
}
|
|
557
|
+
function schemaTypeExpectation(schema) {
|
|
558
|
+
const type = schemaType(schema);
|
|
559
|
+
if (type !== void 0) return `expected ${type}`;
|
|
560
|
+
const alternatives = schemaAlternatives(schema);
|
|
561
|
+
return alternatives.length === 0 ? void 0 : `expected one of: ${alternatives.join(", ")}`;
|
|
562
|
+
}
|
|
563
|
+
function schemaSizeExpectation(schema, direction) {
|
|
564
|
+
const type = schemaType(schema);
|
|
565
|
+
const keyword = direction === "small" ? type === "string" ? "minLength" : type === "array" ? "minItems" : "minimum" : type === "string" ? "maxLength" : type === "array" ? "maxItems" : "maximum";
|
|
566
|
+
const value = schemaNumber(schema[keyword]);
|
|
567
|
+
if (value === void 0) return void 0;
|
|
568
|
+
const label = type === "string" ? "string length" : type === "array" ? "array length" : type;
|
|
569
|
+
if (label === void 0) return void 0;
|
|
570
|
+
return `expected ${label} ${direction === "small" ? "at least" : "at most"} ${value}`;
|
|
571
|
+
}
|
|
572
|
+
function schemaExpectation(schema, issueCode) {
|
|
573
|
+
switch (issueCode) {
|
|
574
|
+
case "invalid_type":
|
|
575
|
+
return schemaTypeExpectation(schema) ?? "failed structural validation";
|
|
576
|
+
case "invalid_value":
|
|
577
|
+
return schemaEnumExpectation(schema) ?? schemaTypeExpectation(schema) ?? "failed structural validation";
|
|
578
|
+
case "too_small":
|
|
579
|
+
return schemaSizeExpectation(schema, "small") ?? schemaTypeExpectation(schema) ?? "failed structural validation";
|
|
580
|
+
case "too_big":
|
|
581
|
+
return schemaSizeExpectation(schema, "big") ?? schemaTypeExpectation(schema) ?? "failed structural validation";
|
|
582
|
+
case "not_multiple_of": {
|
|
583
|
+
const multipleOf = schemaNumber(schema.multipleOf);
|
|
584
|
+
return multipleOf === void 0 ? schemaTypeExpectation(schema) ?? "failed structural validation" : `expected a multiple of ${multipleOf}`;
|
|
585
|
+
}
|
|
586
|
+
case "invalid_format": {
|
|
587
|
+
const format = schema.format;
|
|
588
|
+
return typeof format === "string" && SAFE_STRING_FORMATS.has(format) ? `expected valid ${format} format` : schemaTypeExpectation(schema) ?? "failed structural validation";
|
|
589
|
+
}
|
|
590
|
+
case "invalid_union":
|
|
591
|
+
return schemaTypeExpectation(schema) ?? "failed structural validation";
|
|
592
|
+
default: {
|
|
593
|
+
const typeExpectation = schemaTypeExpectation(schema);
|
|
594
|
+
return typeExpectation === void 0 ? "failed structural validation" : `failed structural validation; ${typeExpectation}`;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
383
598
|
var ToolStringLengthError = class extends Error {
|
|
384
599
|
constructor(path, actual, maximum) {
|
|
385
600
|
const renderedPath = path.reduce(
|
|
@@ -395,6 +610,42 @@ var ToolStringLengthError = class extends Error {
|
|
|
395
610
|
this.name = "ToolStringLengthError";
|
|
396
611
|
}
|
|
397
612
|
};
|
|
613
|
+
function toolArgumentModelMessage(error, providerVisibleSchema) {
|
|
614
|
+
try {
|
|
615
|
+
let lines;
|
|
616
|
+
let omitted = false;
|
|
617
|
+
if (error instanceof import_zod.ZodError) {
|
|
618
|
+
if (error.issues.length === 0) return void 0;
|
|
619
|
+
lines = [];
|
|
620
|
+
for (const issue of error.issues.slice(0, MAX_MODEL_ARGUMENT_ISSUES)) {
|
|
621
|
+
const resolved = resolveSchemaPath(providerVisibleSchema, issue.path);
|
|
622
|
+
if (resolved === void 0) return void 0;
|
|
623
|
+
const path = jsonPointerPath(resolved.segments);
|
|
624
|
+
const expectation = schemaExpectation(resolved.node, issue.code);
|
|
625
|
+
lines.push(
|
|
626
|
+
truncateModelFeedback(`- ${path}: ${expectation}`, MAX_MODEL_ARGUMENT_LINE_LENGTH)
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
omitted = error.issues.length > lines.length;
|
|
630
|
+
} else if (error instanceof ToolStringLengthError) {
|
|
631
|
+
const resolved = resolveSchemaPath(providerVisibleSchema, error.path);
|
|
632
|
+
const maximum = schemaNumber(error.maximum);
|
|
633
|
+
if (resolved === void 0 || maximum === void 0) return void 0;
|
|
634
|
+
const path = jsonPointerPath(resolved.segments);
|
|
635
|
+
lines = [`- ${path}: maximum string length is ${maximum}`];
|
|
636
|
+
} else {
|
|
637
|
+
return void 0;
|
|
638
|
+
}
|
|
639
|
+
const header = "Error: Invalid tool arguments:";
|
|
640
|
+
const footer = "Correct the arguments and try again.";
|
|
641
|
+
const omission = omitted ? "Additional validation issues were omitted." : void 0;
|
|
642
|
+
const parts = [header, ...lines, ...omission ? [omission] : [], footer];
|
|
643
|
+
const message = parts.join("\n");
|
|
644
|
+
return message.length <= MAX_MODEL_ARGUMENT_MESSAGE_LENGTH ? message : void 0;
|
|
645
|
+
} catch {
|
|
646
|
+
return void 0;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
398
649
|
function validateStringLengths(value, maxLen, path = []) {
|
|
399
650
|
if (typeof value === "string") {
|
|
400
651
|
if (value.length > maxLen) {
|
|
@@ -6539,7 +6790,15 @@ function cloneToolArguments(value) {
|
|
|
6539
6790
|
}
|
|
6540
6791
|
}
|
|
6541
6792
|
function parseToolInvocation(options) {
|
|
6542
|
-
const {
|
|
6793
|
+
const {
|
|
6794
|
+
toolCall,
|
|
6795
|
+
configuredTool,
|
|
6796
|
+
override,
|
|
6797
|
+
mcpCall,
|
|
6798
|
+
mcpTraceName,
|
|
6799
|
+
availableTools,
|
|
6800
|
+
providerVisibleSchema
|
|
6801
|
+
} = options;
|
|
6543
6802
|
const requestedTool = toolCall.function.name;
|
|
6544
6803
|
if (!override && !configuredTool && !mcpCall) {
|
|
6545
6804
|
return {
|
|
@@ -6599,7 +6858,7 @@ function parseToolInvocation(options) {
|
|
|
6599
6858
|
args: parsedArguments,
|
|
6600
6859
|
issues: toolArgumentIssues(error)
|
|
6601
6860
|
},
|
|
6602
|
-
modelMessage: INVALID_ARGUMENTS_MODEL_MESSAGE
|
|
6861
|
+
modelMessage: toolArgumentModelMessage(error, providerVisibleSchema) ?? INVALID_ARGUMENTS_MODEL_MESSAGE
|
|
6603
6862
|
};
|
|
6604
6863
|
}
|
|
6605
6864
|
}
|
|
@@ -7502,7 +7761,7 @@ var WorkflowContext = class _WorkflowContext {
|
|
|
7502
7761
|
/** Resolve, execute, and observe one non-handoff tool request. Rejections
|
|
7503
7762
|
* never start. Every accepted request emits one terminal event before a
|
|
7504
7763
|
* continuation message or abort escapes this coordinator. */
|
|
7505
|
-
async observeToolInvocation(agent2, toolCall, currentMessages,
|
|
7764
|
+
async observeToolInvocation(agent2, toolCall, currentMessages, toolDefs) {
|
|
7506
7765
|
const signal = this.currentSignal;
|
|
7507
7766
|
signal?.throwIfAborted();
|
|
7508
7767
|
const requestedTool = toolCall.function.name;
|
|
@@ -7512,6 +7771,7 @@ var WorkflowContext = class _WorkflowContext {
|
|
|
7512
7771
|
const override = this.toolOverrides?.get(requestedTool);
|
|
7513
7772
|
const mcpManager = this.mcpManager;
|
|
7514
7773
|
const mcpMatch = !configuredTool ? mcpManager?.getToolsForAgent(agent2._config.mcp, agent2._config.mcpTools).find(({ tool: tool2 }) => tool2.name === requestedTool) : void 0;
|
|
7774
|
+
const providerVisibleSchema = toolDefs.find((tool2) => tool2.function.name === requestedTool)?.function.parameters;
|
|
7515
7775
|
const parsed = parseToolInvocation({
|
|
7516
7776
|
toolCall,
|
|
7517
7777
|
configuredTool,
|
|
@@ -7520,7 +7780,8 @@ var WorkflowContext = class _WorkflowContext {
|
|
|
7520
7780
|
mcpCall: (args) => mcpManager.callTool(requestedTool, args, mcpMatch.server),
|
|
7521
7781
|
mcpTraceName: `${mcpMatch.server}:${requestedTool}`
|
|
7522
7782
|
} : {},
|
|
7523
|
-
availableTools
|
|
7783
|
+
availableTools: toolDefs.map((tool2) => tool2.function.name),
|
|
7784
|
+
...configuredTool ? { providerVisibleSchema } : {}
|
|
7524
7785
|
});
|
|
7525
7786
|
signal?.throwIfAborted();
|
|
7526
7787
|
if ("kind" in parsed) {
|
|
@@ -8331,12 +8592,7 @@ ${appendedSchemaText}`;
|
|
|
8331
8592
|
return await handoffFn();
|
|
8332
8593
|
}
|
|
8333
8594
|
}
|
|
8334
|
-
await this.observeToolInvocation(
|
|
8335
|
-
agent2,
|
|
8336
|
-
toolCall,
|
|
8337
|
-
currentMessages,
|
|
8338
|
-
toolDefs.map((tool2) => tool2.function.name)
|
|
8339
|
-
);
|
|
8595
|
+
await this.observeToolInvocation(agent2, toolCall, currentMessages, toolDefs);
|
|
8340
8596
|
}
|
|
8341
8597
|
continue;
|
|
8342
8598
|
}
|