@agentforge/core 0.16.36 → 0.16.37
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 +79 -226
- package/dist/index.d.cts +7 -198
- package/dist/index.d.ts +7 -198
- package/dist/index.js +79 -226
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -493,7 +493,54 @@ function validateTool(tool) {
|
|
|
493
493
|
};
|
|
494
494
|
}
|
|
495
495
|
|
|
496
|
-
// src/tools/builder.ts
|
|
496
|
+
// src/tools/builder-finalize.ts
|
|
497
|
+
function assertBuildable(metadata, schema, invoke) {
|
|
498
|
+
if (!metadata.name) {
|
|
499
|
+
throw new Error("Tool name is required. Use .name() to set it.");
|
|
500
|
+
}
|
|
501
|
+
if (!metadata.description) {
|
|
502
|
+
throw new Error("Tool description is required. Use .description() to set it.");
|
|
503
|
+
}
|
|
504
|
+
if (!metadata.category) {
|
|
505
|
+
throw new Error("Tool category is required. Use .category() to set it.");
|
|
506
|
+
}
|
|
507
|
+
if (!schema) {
|
|
508
|
+
throw new Error("Tool schema is required. Use .schema() to set it.");
|
|
509
|
+
}
|
|
510
|
+
if (!invoke) {
|
|
511
|
+
throw new Error("Tool implementation is required. Use .implement() to set it.");
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
function buildTool(metadata, schema, invoke) {
|
|
515
|
+
assertBuildable(metadata, schema, invoke);
|
|
516
|
+
const finalSchema = schema;
|
|
517
|
+
const finalInvoke = invoke;
|
|
518
|
+
return createTool(metadata, finalSchema, async function(input) {
|
|
519
|
+
return finalInvoke.call(this, input);
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// src/tools/builder-implementation.ts
|
|
524
|
+
function wrapInvoke(invoke) {
|
|
525
|
+
return async function(input) {
|
|
526
|
+
return invoke.call(this, input);
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
function wrapSafeInvoke(invoke) {
|
|
530
|
+
return wrapInvoke(async function(input) {
|
|
531
|
+
try {
|
|
532
|
+
const data = await invoke.call(this, input);
|
|
533
|
+
return { success: true, data };
|
|
534
|
+
} catch (error) {
|
|
535
|
+
return {
|
|
536
|
+
success: false,
|
|
537
|
+
error: error instanceof Error ? error.message : String(error)
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// src/tools/builder-metadata.ts
|
|
497
544
|
function cloneRelations(relations) {
|
|
498
545
|
if (!relations) {
|
|
499
546
|
return void 0;
|
|
@@ -532,309 +579,115 @@ function cloneMetadata(metadata) {
|
|
|
532
579
|
relations: cloneRelations(metadata.relations)
|
|
533
580
|
};
|
|
534
581
|
}
|
|
582
|
+
function appendMetadataList(metadata, key, value) {
|
|
583
|
+
if (!metadata[key]) {
|
|
584
|
+
metadata[key] = [];
|
|
585
|
+
}
|
|
586
|
+
metadata[key].push(value);
|
|
587
|
+
}
|
|
588
|
+
function appendExample(metadata, example) {
|
|
589
|
+
if (!metadata.examples) {
|
|
590
|
+
metadata.examples = [];
|
|
591
|
+
}
|
|
592
|
+
metadata.examples.push(example);
|
|
593
|
+
}
|
|
594
|
+
function setRelation(metadata, relation, tools) {
|
|
595
|
+
metadata.relations = {
|
|
596
|
+
...metadata.relations ?? {},
|
|
597
|
+
[relation]: tools
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// src/tools/builder.ts
|
|
535
602
|
var ToolBuilder = class _ToolBuilder {
|
|
536
603
|
constructor(metadata = {}, _schema, _invoke) {
|
|
537
604
|
this.metadata = metadata;
|
|
538
605
|
this._schema = _schema;
|
|
539
606
|
this._invoke = _invoke;
|
|
540
607
|
}
|
|
541
|
-
/**
|
|
542
|
-
* Set the tool name (required)
|
|
543
|
-
*
|
|
544
|
-
* @param name - Tool name in kebab-case (e.g., 'read-file')
|
|
545
|
-
*/
|
|
546
608
|
name(name) {
|
|
547
609
|
this.metadata.name = name;
|
|
548
610
|
return this;
|
|
549
611
|
}
|
|
550
|
-
/**
|
|
551
|
-
* Set the tool description (required)
|
|
552
|
-
*
|
|
553
|
-
* @param description - Clear description of what the tool does
|
|
554
|
-
*/
|
|
555
612
|
description(description) {
|
|
556
613
|
this.metadata.description = description;
|
|
557
614
|
return this;
|
|
558
615
|
}
|
|
559
|
-
/**
|
|
560
|
-
* Set the tool category (required)
|
|
561
|
-
*
|
|
562
|
-
* @param category - Tool category for organization
|
|
563
|
-
*/
|
|
564
616
|
category(category) {
|
|
565
617
|
this.metadata.category = category;
|
|
566
618
|
return this;
|
|
567
619
|
}
|
|
568
|
-
/**
|
|
569
|
-
* Set the display name (optional)
|
|
570
|
-
*
|
|
571
|
-
* @param displayName - Human-friendly name for UI display
|
|
572
|
-
*/
|
|
573
620
|
displayName(displayName) {
|
|
574
621
|
this.metadata.displayName = displayName;
|
|
575
622
|
return this;
|
|
576
623
|
}
|
|
577
|
-
/**
|
|
578
|
-
* Set tags for searchability (optional)
|
|
579
|
-
*
|
|
580
|
-
* @param tags - Array of tags for categorization and search
|
|
581
|
-
*/
|
|
582
624
|
tags(tags) {
|
|
583
625
|
this.metadata.tags = tags;
|
|
584
626
|
return this;
|
|
585
627
|
}
|
|
586
|
-
/**
|
|
587
|
-
* Add a single tag (optional)
|
|
588
|
-
*
|
|
589
|
-
* @param tag - Tag to add
|
|
590
|
-
*/
|
|
591
628
|
tag(tag) {
|
|
592
|
-
|
|
593
|
-
this.metadata.tags = [];
|
|
594
|
-
}
|
|
595
|
-
this.metadata.tags.push(tag);
|
|
629
|
+
appendMetadataList(this.metadata, "tags", tag);
|
|
596
630
|
return this;
|
|
597
631
|
}
|
|
598
|
-
/**
|
|
599
|
-
* Add an example (optional)
|
|
600
|
-
*
|
|
601
|
-
* @param example - Usage example for the tool
|
|
602
|
-
*/
|
|
603
632
|
example(example) {
|
|
604
|
-
|
|
605
|
-
this.metadata.examples = [];
|
|
606
|
-
}
|
|
607
|
-
this.metadata.examples.push(example);
|
|
633
|
+
appendExample(this.metadata, example);
|
|
608
634
|
return this;
|
|
609
635
|
}
|
|
610
|
-
/**
|
|
611
|
-
* Set usage notes (optional)
|
|
612
|
-
*
|
|
613
|
-
* @param notes - Important usage information
|
|
614
|
-
*/
|
|
615
636
|
usageNotes(notes) {
|
|
616
637
|
this.metadata.usageNotes = notes;
|
|
617
638
|
return this;
|
|
618
639
|
}
|
|
619
|
-
/**
|
|
620
|
-
* Set limitations (optional)
|
|
621
|
-
*
|
|
622
|
-
* @param limitations - Array of known limitations
|
|
623
|
-
*/
|
|
624
640
|
limitations(limitations) {
|
|
625
641
|
this.metadata.limitations = limitations;
|
|
626
642
|
return this;
|
|
627
643
|
}
|
|
628
|
-
/**
|
|
629
|
-
* Add a single limitation (optional)
|
|
630
|
-
*
|
|
631
|
-
* @param limitation - Limitation to add
|
|
632
|
-
*/
|
|
633
644
|
limitation(limitation) {
|
|
634
|
-
|
|
635
|
-
this.metadata.limitations = [];
|
|
636
|
-
}
|
|
637
|
-
this.metadata.limitations.push(limitation);
|
|
645
|
+
appendMetadataList(this.metadata, "limitations", limitation);
|
|
638
646
|
return this;
|
|
639
647
|
}
|
|
640
|
-
/**
|
|
641
|
-
* Set version (optional)
|
|
642
|
-
*
|
|
643
|
-
* @param version - Semantic version string
|
|
644
|
-
*/
|
|
645
648
|
version(version) {
|
|
646
649
|
this.metadata.version = version;
|
|
647
650
|
return this;
|
|
648
651
|
}
|
|
649
|
-
/**
|
|
650
|
-
* Set author (optional)
|
|
651
|
-
*
|
|
652
|
-
* @param author - Tool author name
|
|
653
|
-
*/
|
|
654
652
|
author(author) {
|
|
655
653
|
this.metadata.author = author;
|
|
656
654
|
return this;
|
|
657
655
|
}
|
|
658
|
-
/**
|
|
659
|
-
* Set tools that must be called before this tool (optional)
|
|
660
|
-
*
|
|
661
|
-
* @param tools - Array of tool names that are required
|
|
662
|
-
* @example
|
|
663
|
-
* ```ts
|
|
664
|
-
* .requires(['view-file', 'search-codebase'])
|
|
665
|
-
* ```
|
|
666
|
-
*/
|
|
667
656
|
requires(tools) {
|
|
668
|
-
|
|
669
|
-
this.metadata.relations = {};
|
|
670
|
-
}
|
|
671
|
-
this.metadata.relations.requires = tools;
|
|
657
|
+
setRelation(this.metadata, "requires", tools);
|
|
672
658
|
return this;
|
|
673
659
|
}
|
|
674
|
-
/**
|
|
675
|
-
* Set tools that work well with this tool (optional)
|
|
676
|
-
*
|
|
677
|
-
* @param tools - Array of tool names that are suggested
|
|
678
|
-
* @example
|
|
679
|
-
* ```ts
|
|
680
|
-
* .suggests(['run-tests', 'format-code'])
|
|
681
|
-
* ```
|
|
682
|
-
*/
|
|
683
660
|
suggests(tools) {
|
|
684
|
-
|
|
685
|
-
this.metadata.relations = {};
|
|
686
|
-
}
|
|
687
|
-
this.metadata.relations.suggests = tools;
|
|
661
|
+
setRelation(this.metadata, "suggests", tools);
|
|
688
662
|
return this;
|
|
689
663
|
}
|
|
690
|
-
/**
|
|
691
|
-
* Set tools that conflict with this tool (optional)
|
|
692
|
-
*
|
|
693
|
-
* @param tools - Array of tool names that conflict
|
|
694
|
-
* @example
|
|
695
|
-
* ```ts
|
|
696
|
-
* .conflicts(['delete-file'])
|
|
697
|
-
* ```
|
|
698
|
-
*/
|
|
699
664
|
conflicts(tools) {
|
|
700
|
-
|
|
701
|
-
this.metadata.relations = {};
|
|
702
|
-
}
|
|
703
|
-
this.metadata.relations.conflicts = tools;
|
|
665
|
+
setRelation(this.metadata, "conflicts", tools);
|
|
704
666
|
return this;
|
|
705
667
|
}
|
|
706
|
-
/**
|
|
707
|
-
* Set tools this typically follows in a workflow (optional)
|
|
708
|
-
*
|
|
709
|
-
* @param tools - Array of tool names this follows
|
|
710
|
-
* @example
|
|
711
|
-
* ```ts
|
|
712
|
-
* .follows(['search-codebase', 'view-file'])
|
|
713
|
-
* ```
|
|
714
|
-
*/
|
|
715
668
|
follows(tools) {
|
|
716
|
-
|
|
717
|
-
this.metadata.relations = {};
|
|
718
|
-
}
|
|
719
|
-
this.metadata.relations.follows = tools;
|
|
669
|
+
setRelation(this.metadata, "follows", tools);
|
|
720
670
|
return this;
|
|
721
671
|
}
|
|
722
|
-
/**
|
|
723
|
-
* Set tools this typically precedes in a workflow (optional)
|
|
724
|
-
*
|
|
725
|
-
* @param tools - Array of tool names this precedes
|
|
726
|
-
* @example
|
|
727
|
-
* ```ts
|
|
728
|
-
* .precedes(['run-tests'])
|
|
729
|
-
* ```
|
|
730
|
-
*/
|
|
731
672
|
precedes(tools) {
|
|
732
|
-
|
|
733
|
-
this.metadata.relations = {};
|
|
734
|
-
}
|
|
735
|
-
this.metadata.relations.precedes = tools;
|
|
673
|
+
setRelation(this.metadata, "precedes", tools);
|
|
736
674
|
return this;
|
|
737
675
|
}
|
|
738
|
-
/**
|
|
739
|
-
* Set the input schema (required)
|
|
740
|
-
*
|
|
741
|
-
* All fields MUST have .describe() for LLM understanding!
|
|
742
|
-
*
|
|
743
|
-
* @param schema - Zod schema for input validation
|
|
744
|
-
*/
|
|
745
676
|
schema(schema) {
|
|
746
677
|
return new _ToolBuilder(cloneMetadata(this.metadata), schema, this._invoke);
|
|
747
678
|
}
|
|
748
|
-
/**
|
|
749
|
-
* Set the implementation function (required)
|
|
750
|
-
*
|
|
751
|
-
* @param invoke - Async function that implements the tool
|
|
752
|
-
*/
|
|
753
679
|
implement(invoke) {
|
|
754
|
-
|
|
755
|
-
return invoke.call(this, input);
|
|
756
|
-
};
|
|
757
|
-
return new _ToolBuilder(cloneMetadata(this.metadata), this._schema, wrappedInvoke);
|
|
680
|
+
return new _ToolBuilder(cloneMetadata(this.metadata), this._schema, wrapInvoke(invoke));
|
|
758
681
|
}
|
|
759
|
-
/**
|
|
760
|
-
* Set the implementation function with automatic error handling
|
|
761
|
-
*
|
|
762
|
-
* Wraps the implementation in a try-catch block and returns a standardized
|
|
763
|
-
* result object with success/error information.
|
|
764
|
-
*
|
|
765
|
-
* @param invoke - Async function that implements the tool
|
|
766
|
-
* @returns ToolBuilder with safe result type { success: boolean; data?: T; error?: string }
|
|
767
|
-
*
|
|
768
|
-
* @example
|
|
769
|
-
* ```ts
|
|
770
|
-
* const tool = toolBuilder()
|
|
771
|
-
* .name('read-file')
|
|
772
|
-
* .schema(z.object({ path: z.string() }))
|
|
773
|
-
* .implementSafe(async ({ path }) => {
|
|
774
|
-
* return await fs.readFile(path, 'utf-8');
|
|
775
|
-
* })
|
|
776
|
-
* .build();
|
|
777
|
-
*
|
|
778
|
-
* // Result will be: { success: true, data: "file content" }
|
|
779
|
-
* // Or on error: { success: false, error: "ENOENT: no such file..." }
|
|
780
|
-
* ```
|
|
781
|
-
*/
|
|
782
682
|
implementSafe(invoke) {
|
|
783
|
-
const safeInvoke = async function(input) {
|
|
784
|
-
try {
|
|
785
|
-
const data = await invoke.call(this, input);
|
|
786
|
-
return { success: true, data };
|
|
787
|
-
} catch (error) {
|
|
788
|
-
return {
|
|
789
|
-
success: false,
|
|
790
|
-
error: error instanceof Error ? error.message : String(error)
|
|
791
|
-
};
|
|
792
|
-
}
|
|
793
|
-
};
|
|
794
|
-
const wrappedInvoke = async function(input) {
|
|
795
|
-
return safeInvoke.call(this, input);
|
|
796
|
-
};
|
|
797
683
|
return new _ToolBuilder(
|
|
798
684
|
cloneMetadata(this.metadata),
|
|
799
685
|
this._schema,
|
|
800
|
-
|
|
686
|
+
wrapSafeInvoke(invoke)
|
|
801
687
|
);
|
|
802
688
|
}
|
|
803
|
-
/**
|
|
804
|
-
* Build the tool with validation
|
|
805
|
-
*
|
|
806
|
-
* Validates:
|
|
807
|
-
* - All required fields are present
|
|
808
|
-
* - Metadata is valid
|
|
809
|
-
* - Schema has descriptions on all fields
|
|
810
|
-
*
|
|
811
|
-
* @returns The validated tool
|
|
812
|
-
* @throws {Error} If validation fails
|
|
813
|
-
*/
|
|
814
689
|
build() {
|
|
815
|
-
|
|
816
|
-
throw new Error("Tool name is required. Use .name() to set it.");
|
|
817
|
-
}
|
|
818
|
-
if (!this.metadata.description) {
|
|
819
|
-
throw new Error("Tool description is required. Use .description() to set it.");
|
|
820
|
-
}
|
|
821
|
-
if (!this.metadata.category) {
|
|
822
|
-
throw new Error("Tool category is required. Use .category() to set it.");
|
|
823
|
-
}
|
|
824
|
-
if (!this._schema) {
|
|
825
|
-
throw new Error("Tool schema is required. Use .schema() to set it.");
|
|
826
|
-
}
|
|
827
|
-
if (!this._invoke) {
|
|
828
|
-
throw new Error("Tool implementation is required. Use .implement() to set it.");
|
|
829
|
-
}
|
|
830
|
-
const invoke = this._invoke;
|
|
831
|
-
return createTool(
|
|
832
|
-
this.metadata,
|
|
833
|
-
this._schema,
|
|
834
|
-
async function(input) {
|
|
835
|
-
return invoke.call(this, input);
|
|
836
|
-
}
|
|
837
|
-
);
|
|
690
|
+
return buildTool(this.metadata, this._schema, this._invoke);
|
|
838
691
|
}
|
|
839
692
|
};
|
|
840
693
|
function toolBuilder() {
|
package/dist/index.d.cts
CHANGED
|
@@ -920,231 +920,40 @@ declare function validateTool(tool: Tool): {
|
|
|
920
920
|
errors: string[];
|
|
921
921
|
};
|
|
922
922
|
|
|
923
|
-
/**
|
|
924
|
-
* Tool Builder API
|
|
925
|
-
*
|
|
926
|
-
* Fluent interface for creating tools with automatic validation.
|
|
927
|
-
*
|
|
928
|
-
* @example
|
|
929
|
-
* ```ts
|
|
930
|
-
* const tool = createToolBuilder()
|
|
931
|
-
* .name('read-file')
|
|
932
|
-
* .description('Read a file from the file system')
|
|
933
|
-
* .category(ToolCategory.FILE_SYSTEM)
|
|
934
|
-
* .tags(['file', 'read', 'io'])
|
|
935
|
-
* .schema(z.object({
|
|
936
|
-
* path: z.string().describe('Path to the file')
|
|
937
|
-
* }))
|
|
938
|
-
* .implement(async ({ path }) => {
|
|
939
|
-
* // Implementation
|
|
940
|
-
* })
|
|
941
|
-
* .build();
|
|
942
|
-
* ```
|
|
943
|
-
*/
|
|
944
|
-
|
|
945
923
|
type ToolInvoke<TOutput> = (this: unknown, input: unknown) => Promise<TOutput>;
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
924
|
+
type SafeToolResult<T> = {
|
|
925
|
+
success: boolean;
|
|
926
|
+
data?: T;
|
|
927
|
+
error?: string;
|
|
928
|
+
};
|
|
929
|
+
|
|
952
930
|
declare class ToolBuilder<TInput = unknown, TOutput = unknown> {
|
|
953
931
|
private metadata;
|
|
954
932
|
private _schema?;
|
|
955
933
|
private _invoke?;
|
|
956
934
|
constructor(metadata?: Partial<ToolMetadata>, _schema?: z.ZodSchema<TInput> | undefined, _invoke?: ToolInvoke<TOutput> | undefined);
|
|
957
|
-
/**
|
|
958
|
-
* Set the tool name (required)
|
|
959
|
-
*
|
|
960
|
-
* @param name - Tool name in kebab-case (e.g., 'read-file')
|
|
961
|
-
*/
|
|
962
935
|
name(name: string): this;
|
|
963
|
-
/**
|
|
964
|
-
* Set the tool description (required)
|
|
965
|
-
*
|
|
966
|
-
* @param description - Clear description of what the tool does
|
|
967
|
-
*/
|
|
968
936
|
description(description: string): this;
|
|
969
|
-
/**
|
|
970
|
-
* Set the tool category (required)
|
|
971
|
-
*
|
|
972
|
-
* @param category - Tool category for organization
|
|
973
|
-
*/
|
|
974
937
|
category(category: ToolCategory): this;
|
|
975
|
-
/**
|
|
976
|
-
* Set the display name (optional)
|
|
977
|
-
*
|
|
978
|
-
* @param displayName - Human-friendly name for UI display
|
|
979
|
-
*/
|
|
980
938
|
displayName(displayName: string): this;
|
|
981
|
-
/**
|
|
982
|
-
* Set tags for searchability (optional)
|
|
983
|
-
*
|
|
984
|
-
* @param tags - Array of tags for categorization and search
|
|
985
|
-
*/
|
|
986
939
|
tags(tags: string[]): this;
|
|
987
|
-
/**
|
|
988
|
-
* Add a single tag (optional)
|
|
989
|
-
*
|
|
990
|
-
* @param tag - Tag to add
|
|
991
|
-
*/
|
|
992
940
|
tag(tag: string): this;
|
|
993
|
-
/**
|
|
994
|
-
* Add an example (optional)
|
|
995
|
-
*
|
|
996
|
-
* @param example - Usage example for the tool
|
|
997
|
-
*/
|
|
998
941
|
example(example: ToolExample): this;
|
|
999
|
-
/**
|
|
1000
|
-
* Set usage notes (optional)
|
|
1001
|
-
*
|
|
1002
|
-
* @param notes - Important usage information
|
|
1003
|
-
*/
|
|
1004
942
|
usageNotes(notes: string): this;
|
|
1005
|
-
/**
|
|
1006
|
-
* Set limitations (optional)
|
|
1007
|
-
*
|
|
1008
|
-
* @param limitations - Array of known limitations
|
|
1009
|
-
*/
|
|
1010
943
|
limitations(limitations: string[]): this;
|
|
1011
|
-
/**
|
|
1012
|
-
* Add a single limitation (optional)
|
|
1013
|
-
*
|
|
1014
|
-
* @param limitation - Limitation to add
|
|
1015
|
-
*/
|
|
1016
944
|
limitation(limitation: string): this;
|
|
1017
|
-
/**
|
|
1018
|
-
* Set version (optional)
|
|
1019
|
-
*
|
|
1020
|
-
* @param version - Semantic version string
|
|
1021
|
-
*/
|
|
1022
945
|
version(version: string): this;
|
|
1023
|
-
/**
|
|
1024
|
-
* Set author (optional)
|
|
1025
|
-
*
|
|
1026
|
-
* @param author - Tool author name
|
|
1027
|
-
*/
|
|
1028
946
|
author(author: string): this;
|
|
1029
|
-
/**
|
|
1030
|
-
* Set tools that must be called before this tool (optional)
|
|
1031
|
-
*
|
|
1032
|
-
* @param tools - Array of tool names that are required
|
|
1033
|
-
* @example
|
|
1034
|
-
* ```ts
|
|
1035
|
-
* .requires(['view-file', 'search-codebase'])
|
|
1036
|
-
* ```
|
|
1037
|
-
*/
|
|
1038
947
|
requires(tools: string[]): this;
|
|
1039
|
-
/**
|
|
1040
|
-
* Set tools that work well with this tool (optional)
|
|
1041
|
-
*
|
|
1042
|
-
* @param tools - Array of tool names that are suggested
|
|
1043
|
-
* @example
|
|
1044
|
-
* ```ts
|
|
1045
|
-
* .suggests(['run-tests', 'format-code'])
|
|
1046
|
-
* ```
|
|
1047
|
-
*/
|
|
1048
948
|
suggests(tools: string[]): this;
|
|
1049
|
-
/**
|
|
1050
|
-
* Set tools that conflict with this tool (optional)
|
|
1051
|
-
*
|
|
1052
|
-
* @param tools - Array of tool names that conflict
|
|
1053
|
-
* @example
|
|
1054
|
-
* ```ts
|
|
1055
|
-
* .conflicts(['delete-file'])
|
|
1056
|
-
* ```
|
|
1057
|
-
*/
|
|
1058
949
|
conflicts(tools: string[]): this;
|
|
1059
|
-
/**
|
|
1060
|
-
* Set tools this typically follows in a workflow (optional)
|
|
1061
|
-
*
|
|
1062
|
-
* @param tools - Array of tool names this follows
|
|
1063
|
-
* @example
|
|
1064
|
-
* ```ts
|
|
1065
|
-
* .follows(['search-codebase', 'view-file'])
|
|
1066
|
-
* ```
|
|
1067
|
-
*/
|
|
1068
950
|
follows(tools: string[]): this;
|
|
1069
|
-
/**
|
|
1070
|
-
* Set tools this typically precedes in a workflow (optional)
|
|
1071
|
-
*
|
|
1072
|
-
* @param tools - Array of tool names this precedes
|
|
1073
|
-
* @example
|
|
1074
|
-
* ```ts
|
|
1075
|
-
* .precedes(['run-tests'])
|
|
1076
|
-
* ```
|
|
1077
|
-
*/
|
|
1078
951
|
precedes(tools: string[]): this;
|
|
1079
|
-
/**
|
|
1080
|
-
* Set the input schema (required)
|
|
1081
|
-
*
|
|
1082
|
-
* All fields MUST have .describe() for LLM understanding!
|
|
1083
|
-
*
|
|
1084
|
-
* @param schema - Zod schema for input validation
|
|
1085
|
-
*/
|
|
1086
952
|
schema<T>(schema: z.ZodSchema<T>): ToolBuilder<T, TOutput>;
|
|
1087
|
-
/**
|
|
1088
|
-
* Set the implementation function (required)
|
|
1089
|
-
*
|
|
1090
|
-
* @param invoke - Async function that implements the tool
|
|
1091
|
-
*/
|
|
1092
953
|
implement<T>(invoke: (input: TInput) => Promise<T>): ToolBuilder<TInput, T>;
|
|
1093
|
-
|
|
1094
|
-
* Set the implementation function with automatic error handling
|
|
1095
|
-
*
|
|
1096
|
-
* Wraps the implementation in a try-catch block and returns a standardized
|
|
1097
|
-
* result object with success/error information.
|
|
1098
|
-
*
|
|
1099
|
-
* @param invoke - Async function that implements the tool
|
|
1100
|
-
* @returns ToolBuilder with safe result type { success: boolean; data?: T; error?: string }
|
|
1101
|
-
*
|
|
1102
|
-
* @example
|
|
1103
|
-
* ```ts
|
|
1104
|
-
* const tool = toolBuilder()
|
|
1105
|
-
* .name('read-file')
|
|
1106
|
-
* .schema(z.object({ path: z.string() }))
|
|
1107
|
-
* .implementSafe(async ({ path }) => {
|
|
1108
|
-
* return await fs.readFile(path, 'utf-8');
|
|
1109
|
-
* })
|
|
1110
|
-
* .build();
|
|
1111
|
-
*
|
|
1112
|
-
* // Result will be: { success: true, data: "file content" }
|
|
1113
|
-
* // Or on error: { success: false, error: "ENOENT: no such file..." }
|
|
1114
|
-
* ```
|
|
1115
|
-
*/
|
|
1116
|
-
implementSafe<T>(invoke: (input: TInput) => Promise<T>): ToolBuilder<TInput, {
|
|
1117
|
-
success: boolean;
|
|
1118
|
-
data?: T;
|
|
1119
|
-
error?: string;
|
|
1120
|
-
}>;
|
|
1121
|
-
/**
|
|
1122
|
-
* Build the tool with validation
|
|
1123
|
-
*
|
|
1124
|
-
* Validates:
|
|
1125
|
-
* - All required fields are present
|
|
1126
|
-
* - Metadata is valid
|
|
1127
|
-
* - Schema has descriptions on all fields
|
|
1128
|
-
*
|
|
1129
|
-
* @returns The validated tool
|
|
1130
|
-
* @throws {Error} If validation fails
|
|
1131
|
-
*/
|
|
954
|
+
implementSafe<T>(invoke: (input: TInput) => Promise<T>): ToolBuilder<TInput, SafeToolResult<T>>;
|
|
1132
955
|
build(): Tool<TInput, TOutput>;
|
|
1133
956
|
}
|
|
1134
|
-
/**
|
|
1135
|
-
* Create a new tool builder
|
|
1136
|
-
*
|
|
1137
|
-
* @example
|
|
1138
|
-
* ```ts
|
|
1139
|
-
* const tool = toolBuilder()
|
|
1140
|
-
* .name('my-tool')
|
|
1141
|
-
* .description('Does something useful')
|
|
1142
|
-
* .category(ToolCategory.UTILITY)
|
|
1143
|
-
* .schema(z.object({ input: z.string().describe('Input') }))
|
|
1144
|
-
* .implement(async ({ input }) => input)
|
|
1145
|
-
* .build();
|
|
1146
|
-
* ```
|
|
1147
|
-
*/
|
|
1148
957
|
declare function toolBuilder(): ToolBuilder;
|
|
1149
958
|
|
|
1150
959
|
type RegistryTool = Tool<unknown, unknown>;
|
package/dist/index.d.ts
CHANGED
|
@@ -920,231 +920,40 @@ declare function validateTool(tool: Tool): {
|
|
|
920
920
|
errors: string[];
|
|
921
921
|
};
|
|
922
922
|
|
|
923
|
-
/**
|
|
924
|
-
* Tool Builder API
|
|
925
|
-
*
|
|
926
|
-
* Fluent interface for creating tools with automatic validation.
|
|
927
|
-
*
|
|
928
|
-
* @example
|
|
929
|
-
* ```ts
|
|
930
|
-
* const tool = createToolBuilder()
|
|
931
|
-
* .name('read-file')
|
|
932
|
-
* .description('Read a file from the file system')
|
|
933
|
-
* .category(ToolCategory.FILE_SYSTEM)
|
|
934
|
-
* .tags(['file', 'read', 'io'])
|
|
935
|
-
* .schema(z.object({
|
|
936
|
-
* path: z.string().describe('Path to the file')
|
|
937
|
-
* }))
|
|
938
|
-
* .implement(async ({ path }) => {
|
|
939
|
-
* // Implementation
|
|
940
|
-
* })
|
|
941
|
-
* .build();
|
|
942
|
-
* ```
|
|
943
|
-
*/
|
|
944
|
-
|
|
945
923
|
type ToolInvoke<TOutput> = (this: unknown, input: unknown) => Promise<TOutput>;
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
924
|
+
type SafeToolResult<T> = {
|
|
925
|
+
success: boolean;
|
|
926
|
+
data?: T;
|
|
927
|
+
error?: string;
|
|
928
|
+
};
|
|
929
|
+
|
|
952
930
|
declare class ToolBuilder<TInput = unknown, TOutput = unknown> {
|
|
953
931
|
private metadata;
|
|
954
932
|
private _schema?;
|
|
955
933
|
private _invoke?;
|
|
956
934
|
constructor(metadata?: Partial<ToolMetadata>, _schema?: z.ZodSchema<TInput> | undefined, _invoke?: ToolInvoke<TOutput> | undefined);
|
|
957
|
-
/**
|
|
958
|
-
* Set the tool name (required)
|
|
959
|
-
*
|
|
960
|
-
* @param name - Tool name in kebab-case (e.g., 'read-file')
|
|
961
|
-
*/
|
|
962
935
|
name(name: string): this;
|
|
963
|
-
/**
|
|
964
|
-
* Set the tool description (required)
|
|
965
|
-
*
|
|
966
|
-
* @param description - Clear description of what the tool does
|
|
967
|
-
*/
|
|
968
936
|
description(description: string): this;
|
|
969
|
-
/**
|
|
970
|
-
* Set the tool category (required)
|
|
971
|
-
*
|
|
972
|
-
* @param category - Tool category for organization
|
|
973
|
-
*/
|
|
974
937
|
category(category: ToolCategory): this;
|
|
975
|
-
/**
|
|
976
|
-
* Set the display name (optional)
|
|
977
|
-
*
|
|
978
|
-
* @param displayName - Human-friendly name for UI display
|
|
979
|
-
*/
|
|
980
938
|
displayName(displayName: string): this;
|
|
981
|
-
/**
|
|
982
|
-
* Set tags for searchability (optional)
|
|
983
|
-
*
|
|
984
|
-
* @param tags - Array of tags for categorization and search
|
|
985
|
-
*/
|
|
986
939
|
tags(tags: string[]): this;
|
|
987
|
-
/**
|
|
988
|
-
* Add a single tag (optional)
|
|
989
|
-
*
|
|
990
|
-
* @param tag - Tag to add
|
|
991
|
-
*/
|
|
992
940
|
tag(tag: string): this;
|
|
993
|
-
/**
|
|
994
|
-
* Add an example (optional)
|
|
995
|
-
*
|
|
996
|
-
* @param example - Usage example for the tool
|
|
997
|
-
*/
|
|
998
941
|
example(example: ToolExample): this;
|
|
999
|
-
/**
|
|
1000
|
-
* Set usage notes (optional)
|
|
1001
|
-
*
|
|
1002
|
-
* @param notes - Important usage information
|
|
1003
|
-
*/
|
|
1004
942
|
usageNotes(notes: string): this;
|
|
1005
|
-
/**
|
|
1006
|
-
* Set limitations (optional)
|
|
1007
|
-
*
|
|
1008
|
-
* @param limitations - Array of known limitations
|
|
1009
|
-
*/
|
|
1010
943
|
limitations(limitations: string[]): this;
|
|
1011
|
-
/**
|
|
1012
|
-
* Add a single limitation (optional)
|
|
1013
|
-
*
|
|
1014
|
-
* @param limitation - Limitation to add
|
|
1015
|
-
*/
|
|
1016
944
|
limitation(limitation: string): this;
|
|
1017
|
-
/**
|
|
1018
|
-
* Set version (optional)
|
|
1019
|
-
*
|
|
1020
|
-
* @param version - Semantic version string
|
|
1021
|
-
*/
|
|
1022
945
|
version(version: string): this;
|
|
1023
|
-
/**
|
|
1024
|
-
* Set author (optional)
|
|
1025
|
-
*
|
|
1026
|
-
* @param author - Tool author name
|
|
1027
|
-
*/
|
|
1028
946
|
author(author: string): this;
|
|
1029
|
-
/**
|
|
1030
|
-
* Set tools that must be called before this tool (optional)
|
|
1031
|
-
*
|
|
1032
|
-
* @param tools - Array of tool names that are required
|
|
1033
|
-
* @example
|
|
1034
|
-
* ```ts
|
|
1035
|
-
* .requires(['view-file', 'search-codebase'])
|
|
1036
|
-
* ```
|
|
1037
|
-
*/
|
|
1038
947
|
requires(tools: string[]): this;
|
|
1039
|
-
/**
|
|
1040
|
-
* Set tools that work well with this tool (optional)
|
|
1041
|
-
*
|
|
1042
|
-
* @param tools - Array of tool names that are suggested
|
|
1043
|
-
* @example
|
|
1044
|
-
* ```ts
|
|
1045
|
-
* .suggests(['run-tests', 'format-code'])
|
|
1046
|
-
* ```
|
|
1047
|
-
*/
|
|
1048
948
|
suggests(tools: string[]): this;
|
|
1049
|
-
/**
|
|
1050
|
-
* Set tools that conflict with this tool (optional)
|
|
1051
|
-
*
|
|
1052
|
-
* @param tools - Array of tool names that conflict
|
|
1053
|
-
* @example
|
|
1054
|
-
* ```ts
|
|
1055
|
-
* .conflicts(['delete-file'])
|
|
1056
|
-
* ```
|
|
1057
|
-
*/
|
|
1058
949
|
conflicts(tools: string[]): this;
|
|
1059
|
-
/**
|
|
1060
|
-
* Set tools this typically follows in a workflow (optional)
|
|
1061
|
-
*
|
|
1062
|
-
* @param tools - Array of tool names this follows
|
|
1063
|
-
* @example
|
|
1064
|
-
* ```ts
|
|
1065
|
-
* .follows(['search-codebase', 'view-file'])
|
|
1066
|
-
* ```
|
|
1067
|
-
*/
|
|
1068
950
|
follows(tools: string[]): this;
|
|
1069
|
-
/**
|
|
1070
|
-
* Set tools this typically precedes in a workflow (optional)
|
|
1071
|
-
*
|
|
1072
|
-
* @param tools - Array of tool names this precedes
|
|
1073
|
-
* @example
|
|
1074
|
-
* ```ts
|
|
1075
|
-
* .precedes(['run-tests'])
|
|
1076
|
-
* ```
|
|
1077
|
-
*/
|
|
1078
951
|
precedes(tools: string[]): this;
|
|
1079
|
-
/**
|
|
1080
|
-
* Set the input schema (required)
|
|
1081
|
-
*
|
|
1082
|
-
* All fields MUST have .describe() for LLM understanding!
|
|
1083
|
-
*
|
|
1084
|
-
* @param schema - Zod schema for input validation
|
|
1085
|
-
*/
|
|
1086
952
|
schema<T>(schema: z.ZodSchema<T>): ToolBuilder<T, TOutput>;
|
|
1087
|
-
/**
|
|
1088
|
-
* Set the implementation function (required)
|
|
1089
|
-
*
|
|
1090
|
-
* @param invoke - Async function that implements the tool
|
|
1091
|
-
*/
|
|
1092
953
|
implement<T>(invoke: (input: TInput) => Promise<T>): ToolBuilder<TInput, T>;
|
|
1093
|
-
|
|
1094
|
-
* Set the implementation function with automatic error handling
|
|
1095
|
-
*
|
|
1096
|
-
* Wraps the implementation in a try-catch block and returns a standardized
|
|
1097
|
-
* result object with success/error information.
|
|
1098
|
-
*
|
|
1099
|
-
* @param invoke - Async function that implements the tool
|
|
1100
|
-
* @returns ToolBuilder with safe result type { success: boolean; data?: T; error?: string }
|
|
1101
|
-
*
|
|
1102
|
-
* @example
|
|
1103
|
-
* ```ts
|
|
1104
|
-
* const tool = toolBuilder()
|
|
1105
|
-
* .name('read-file')
|
|
1106
|
-
* .schema(z.object({ path: z.string() }))
|
|
1107
|
-
* .implementSafe(async ({ path }) => {
|
|
1108
|
-
* return await fs.readFile(path, 'utf-8');
|
|
1109
|
-
* })
|
|
1110
|
-
* .build();
|
|
1111
|
-
*
|
|
1112
|
-
* // Result will be: { success: true, data: "file content" }
|
|
1113
|
-
* // Or on error: { success: false, error: "ENOENT: no such file..." }
|
|
1114
|
-
* ```
|
|
1115
|
-
*/
|
|
1116
|
-
implementSafe<T>(invoke: (input: TInput) => Promise<T>): ToolBuilder<TInput, {
|
|
1117
|
-
success: boolean;
|
|
1118
|
-
data?: T;
|
|
1119
|
-
error?: string;
|
|
1120
|
-
}>;
|
|
1121
|
-
/**
|
|
1122
|
-
* Build the tool with validation
|
|
1123
|
-
*
|
|
1124
|
-
* Validates:
|
|
1125
|
-
* - All required fields are present
|
|
1126
|
-
* - Metadata is valid
|
|
1127
|
-
* - Schema has descriptions on all fields
|
|
1128
|
-
*
|
|
1129
|
-
* @returns The validated tool
|
|
1130
|
-
* @throws {Error} If validation fails
|
|
1131
|
-
*/
|
|
954
|
+
implementSafe<T>(invoke: (input: TInput) => Promise<T>): ToolBuilder<TInput, SafeToolResult<T>>;
|
|
1132
955
|
build(): Tool<TInput, TOutput>;
|
|
1133
956
|
}
|
|
1134
|
-
/**
|
|
1135
|
-
* Create a new tool builder
|
|
1136
|
-
*
|
|
1137
|
-
* @example
|
|
1138
|
-
* ```ts
|
|
1139
|
-
* const tool = toolBuilder()
|
|
1140
|
-
* .name('my-tool')
|
|
1141
|
-
* .description('Does something useful')
|
|
1142
|
-
* .category(ToolCategory.UTILITY)
|
|
1143
|
-
* .schema(z.object({ input: z.string().describe('Input') }))
|
|
1144
|
-
* .implement(async ({ input }) => input)
|
|
1145
|
-
* .build();
|
|
1146
|
-
* ```
|
|
1147
|
-
*/
|
|
1148
957
|
declare function toolBuilder(): ToolBuilder;
|
|
1149
958
|
|
|
1150
959
|
type RegistryTool = Tool<unknown, unknown>;
|
package/dist/index.js
CHANGED
|
@@ -318,7 +318,54 @@ function validateTool(tool) {
|
|
|
318
318
|
};
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
// src/tools/builder.ts
|
|
321
|
+
// src/tools/builder-finalize.ts
|
|
322
|
+
function assertBuildable(metadata, schema, invoke) {
|
|
323
|
+
if (!metadata.name) {
|
|
324
|
+
throw new Error("Tool name is required. Use .name() to set it.");
|
|
325
|
+
}
|
|
326
|
+
if (!metadata.description) {
|
|
327
|
+
throw new Error("Tool description is required. Use .description() to set it.");
|
|
328
|
+
}
|
|
329
|
+
if (!metadata.category) {
|
|
330
|
+
throw new Error("Tool category is required. Use .category() to set it.");
|
|
331
|
+
}
|
|
332
|
+
if (!schema) {
|
|
333
|
+
throw new Error("Tool schema is required. Use .schema() to set it.");
|
|
334
|
+
}
|
|
335
|
+
if (!invoke) {
|
|
336
|
+
throw new Error("Tool implementation is required. Use .implement() to set it.");
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
function buildTool(metadata, schema, invoke) {
|
|
340
|
+
assertBuildable(metadata, schema, invoke);
|
|
341
|
+
const finalSchema = schema;
|
|
342
|
+
const finalInvoke = invoke;
|
|
343
|
+
return createTool(metadata, finalSchema, async function(input) {
|
|
344
|
+
return finalInvoke.call(this, input);
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// src/tools/builder-implementation.ts
|
|
349
|
+
function wrapInvoke(invoke) {
|
|
350
|
+
return async function(input) {
|
|
351
|
+
return invoke.call(this, input);
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
function wrapSafeInvoke(invoke) {
|
|
355
|
+
return wrapInvoke(async function(input) {
|
|
356
|
+
try {
|
|
357
|
+
const data = await invoke.call(this, input);
|
|
358
|
+
return { success: true, data };
|
|
359
|
+
} catch (error) {
|
|
360
|
+
return {
|
|
361
|
+
success: false,
|
|
362
|
+
error: error instanceof Error ? error.message : String(error)
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// src/tools/builder-metadata.ts
|
|
322
369
|
function cloneRelations(relations) {
|
|
323
370
|
if (!relations) {
|
|
324
371
|
return void 0;
|
|
@@ -357,309 +404,115 @@ function cloneMetadata(metadata) {
|
|
|
357
404
|
relations: cloneRelations(metadata.relations)
|
|
358
405
|
};
|
|
359
406
|
}
|
|
407
|
+
function appendMetadataList(metadata, key, value) {
|
|
408
|
+
if (!metadata[key]) {
|
|
409
|
+
metadata[key] = [];
|
|
410
|
+
}
|
|
411
|
+
metadata[key].push(value);
|
|
412
|
+
}
|
|
413
|
+
function appendExample(metadata, example) {
|
|
414
|
+
if (!metadata.examples) {
|
|
415
|
+
metadata.examples = [];
|
|
416
|
+
}
|
|
417
|
+
metadata.examples.push(example);
|
|
418
|
+
}
|
|
419
|
+
function setRelation(metadata, relation, tools) {
|
|
420
|
+
metadata.relations = {
|
|
421
|
+
...metadata.relations ?? {},
|
|
422
|
+
[relation]: tools
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// src/tools/builder.ts
|
|
360
427
|
var ToolBuilder = class _ToolBuilder {
|
|
361
428
|
constructor(metadata = {}, _schema, _invoke) {
|
|
362
429
|
this.metadata = metadata;
|
|
363
430
|
this._schema = _schema;
|
|
364
431
|
this._invoke = _invoke;
|
|
365
432
|
}
|
|
366
|
-
/**
|
|
367
|
-
* Set the tool name (required)
|
|
368
|
-
*
|
|
369
|
-
* @param name - Tool name in kebab-case (e.g., 'read-file')
|
|
370
|
-
*/
|
|
371
433
|
name(name) {
|
|
372
434
|
this.metadata.name = name;
|
|
373
435
|
return this;
|
|
374
436
|
}
|
|
375
|
-
/**
|
|
376
|
-
* Set the tool description (required)
|
|
377
|
-
*
|
|
378
|
-
* @param description - Clear description of what the tool does
|
|
379
|
-
*/
|
|
380
437
|
description(description) {
|
|
381
438
|
this.metadata.description = description;
|
|
382
439
|
return this;
|
|
383
440
|
}
|
|
384
|
-
/**
|
|
385
|
-
* Set the tool category (required)
|
|
386
|
-
*
|
|
387
|
-
* @param category - Tool category for organization
|
|
388
|
-
*/
|
|
389
441
|
category(category) {
|
|
390
442
|
this.metadata.category = category;
|
|
391
443
|
return this;
|
|
392
444
|
}
|
|
393
|
-
/**
|
|
394
|
-
* Set the display name (optional)
|
|
395
|
-
*
|
|
396
|
-
* @param displayName - Human-friendly name for UI display
|
|
397
|
-
*/
|
|
398
445
|
displayName(displayName) {
|
|
399
446
|
this.metadata.displayName = displayName;
|
|
400
447
|
return this;
|
|
401
448
|
}
|
|
402
|
-
/**
|
|
403
|
-
* Set tags for searchability (optional)
|
|
404
|
-
*
|
|
405
|
-
* @param tags - Array of tags for categorization and search
|
|
406
|
-
*/
|
|
407
449
|
tags(tags) {
|
|
408
450
|
this.metadata.tags = tags;
|
|
409
451
|
return this;
|
|
410
452
|
}
|
|
411
|
-
/**
|
|
412
|
-
* Add a single tag (optional)
|
|
413
|
-
*
|
|
414
|
-
* @param tag - Tag to add
|
|
415
|
-
*/
|
|
416
453
|
tag(tag) {
|
|
417
|
-
|
|
418
|
-
this.metadata.tags = [];
|
|
419
|
-
}
|
|
420
|
-
this.metadata.tags.push(tag);
|
|
454
|
+
appendMetadataList(this.metadata, "tags", tag);
|
|
421
455
|
return this;
|
|
422
456
|
}
|
|
423
|
-
/**
|
|
424
|
-
* Add an example (optional)
|
|
425
|
-
*
|
|
426
|
-
* @param example - Usage example for the tool
|
|
427
|
-
*/
|
|
428
457
|
example(example) {
|
|
429
|
-
|
|
430
|
-
this.metadata.examples = [];
|
|
431
|
-
}
|
|
432
|
-
this.metadata.examples.push(example);
|
|
458
|
+
appendExample(this.metadata, example);
|
|
433
459
|
return this;
|
|
434
460
|
}
|
|
435
|
-
/**
|
|
436
|
-
* Set usage notes (optional)
|
|
437
|
-
*
|
|
438
|
-
* @param notes - Important usage information
|
|
439
|
-
*/
|
|
440
461
|
usageNotes(notes) {
|
|
441
462
|
this.metadata.usageNotes = notes;
|
|
442
463
|
return this;
|
|
443
464
|
}
|
|
444
|
-
/**
|
|
445
|
-
* Set limitations (optional)
|
|
446
|
-
*
|
|
447
|
-
* @param limitations - Array of known limitations
|
|
448
|
-
*/
|
|
449
465
|
limitations(limitations) {
|
|
450
466
|
this.metadata.limitations = limitations;
|
|
451
467
|
return this;
|
|
452
468
|
}
|
|
453
|
-
/**
|
|
454
|
-
* Add a single limitation (optional)
|
|
455
|
-
*
|
|
456
|
-
* @param limitation - Limitation to add
|
|
457
|
-
*/
|
|
458
469
|
limitation(limitation) {
|
|
459
|
-
|
|
460
|
-
this.metadata.limitations = [];
|
|
461
|
-
}
|
|
462
|
-
this.metadata.limitations.push(limitation);
|
|
470
|
+
appendMetadataList(this.metadata, "limitations", limitation);
|
|
463
471
|
return this;
|
|
464
472
|
}
|
|
465
|
-
/**
|
|
466
|
-
* Set version (optional)
|
|
467
|
-
*
|
|
468
|
-
* @param version - Semantic version string
|
|
469
|
-
*/
|
|
470
473
|
version(version) {
|
|
471
474
|
this.metadata.version = version;
|
|
472
475
|
return this;
|
|
473
476
|
}
|
|
474
|
-
/**
|
|
475
|
-
* Set author (optional)
|
|
476
|
-
*
|
|
477
|
-
* @param author - Tool author name
|
|
478
|
-
*/
|
|
479
477
|
author(author) {
|
|
480
478
|
this.metadata.author = author;
|
|
481
479
|
return this;
|
|
482
480
|
}
|
|
483
|
-
/**
|
|
484
|
-
* Set tools that must be called before this tool (optional)
|
|
485
|
-
*
|
|
486
|
-
* @param tools - Array of tool names that are required
|
|
487
|
-
* @example
|
|
488
|
-
* ```ts
|
|
489
|
-
* .requires(['view-file', 'search-codebase'])
|
|
490
|
-
* ```
|
|
491
|
-
*/
|
|
492
481
|
requires(tools) {
|
|
493
|
-
|
|
494
|
-
this.metadata.relations = {};
|
|
495
|
-
}
|
|
496
|
-
this.metadata.relations.requires = tools;
|
|
482
|
+
setRelation(this.metadata, "requires", tools);
|
|
497
483
|
return this;
|
|
498
484
|
}
|
|
499
|
-
/**
|
|
500
|
-
* Set tools that work well with this tool (optional)
|
|
501
|
-
*
|
|
502
|
-
* @param tools - Array of tool names that are suggested
|
|
503
|
-
* @example
|
|
504
|
-
* ```ts
|
|
505
|
-
* .suggests(['run-tests', 'format-code'])
|
|
506
|
-
* ```
|
|
507
|
-
*/
|
|
508
485
|
suggests(tools) {
|
|
509
|
-
|
|
510
|
-
this.metadata.relations = {};
|
|
511
|
-
}
|
|
512
|
-
this.metadata.relations.suggests = tools;
|
|
486
|
+
setRelation(this.metadata, "suggests", tools);
|
|
513
487
|
return this;
|
|
514
488
|
}
|
|
515
|
-
/**
|
|
516
|
-
* Set tools that conflict with this tool (optional)
|
|
517
|
-
*
|
|
518
|
-
* @param tools - Array of tool names that conflict
|
|
519
|
-
* @example
|
|
520
|
-
* ```ts
|
|
521
|
-
* .conflicts(['delete-file'])
|
|
522
|
-
* ```
|
|
523
|
-
*/
|
|
524
489
|
conflicts(tools) {
|
|
525
|
-
|
|
526
|
-
this.metadata.relations = {};
|
|
527
|
-
}
|
|
528
|
-
this.metadata.relations.conflicts = tools;
|
|
490
|
+
setRelation(this.metadata, "conflicts", tools);
|
|
529
491
|
return this;
|
|
530
492
|
}
|
|
531
|
-
/**
|
|
532
|
-
* Set tools this typically follows in a workflow (optional)
|
|
533
|
-
*
|
|
534
|
-
* @param tools - Array of tool names this follows
|
|
535
|
-
* @example
|
|
536
|
-
* ```ts
|
|
537
|
-
* .follows(['search-codebase', 'view-file'])
|
|
538
|
-
* ```
|
|
539
|
-
*/
|
|
540
493
|
follows(tools) {
|
|
541
|
-
|
|
542
|
-
this.metadata.relations = {};
|
|
543
|
-
}
|
|
544
|
-
this.metadata.relations.follows = tools;
|
|
494
|
+
setRelation(this.metadata, "follows", tools);
|
|
545
495
|
return this;
|
|
546
496
|
}
|
|
547
|
-
/**
|
|
548
|
-
* Set tools this typically precedes in a workflow (optional)
|
|
549
|
-
*
|
|
550
|
-
* @param tools - Array of tool names this precedes
|
|
551
|
-
* @example
|
|
552
|
-
* ```ts
|
|
553
|
-
* .precedes(['run-tests'])
|
|
554
|
-
* ```
|
|
555
|
-
*/
|
|
556
497
|
precedes(tools) {
|
|
557
|
-
|
|
558
|
-
this.metadata.relations = {};
|
|
559
|
-
}
|
|
560
|
-
this.metadata.relations.precedes = tools;
|
|
498
|
+
setRelation(this.metadata, "precedes", tools);
|
|
561
499
|
return this;
|
|
562
500
|
}
|
|
563
|
-
/**
|
|
564
|
-
* Set the input schema (required)
|
|
565
|
-
*
|
|
566
|
-
* All fields MUST have .describe() for LLM understanding!
|
|
567
|
-
*
|
|
568
|
-
* @param schema - Zod schema for input validation
|
|
569
|
-
*/
|
|
570
501
|
schema(schema) {
|
|
571
502
|
return new _ToolBuilder(cloneMetadata(this.metadata), schema, this._invoke);
|
|
572
503
|
}
|
|
573
|
-
/**
|
|
574
|
-
* Set the implementation function (required)
|
|
575
|
-
*
|
|
576
|
-
* @param invoke - Async function that implements the tool
|
|
577
|
-
*/
|
|
578
504
|
implement(invoke) {
|
|
579
|
-
|
|
580
|
-
return invoke.call(this, input);
|
|
581
|
-
};
|
|
582
|
-
return new _ToolBuilder(cloneMetadata(this.metadata), this._schema, wrappedInvoke);
|
|
505
|
+
return new _ToolBuilder(cloneMetadata(this.metadata), this._schema, wrapInvoke(invoke));
|
|
583
506
|
}
|
|
584
|
-
/**
|
|
585
|
-
* Set the implementation function with automatic error handling
|
|
586
|
-
*
|
|
587
|
-
* Wraps the implementation in a try-catch block and returns a standardized
|
|
588
|
-
* result object with success/error information.
|
|
589
|
-
*
|
|
590
|
-
* @param invoke - Async function that implements the tool
|
|
591
|
-
* @returns ToolBuilder with safe result type { success: boolean; data?: T; error?: string }
|
|
592
|
-
*
|
|
593
|
-
* @example
|
|
594
|
-
* ```ts
|
|
595
|
-
* const tool = toolBuilder()
|
|
596
|
-
* .name('read-file')
|
|
597
|
-
* .schema(z.object({ path: z.string() }))
|
|
598
|
-
* .implementSafe(async ({ path }) => {
|
|
599
|
-
* return await fs.readFile(path, 'utf-8');
|
|
600
|
-
* })
|
|
601
|
-
* .build();
|
|
602
|
-
*
|
|
603
|
-
* // Result will be: { success: true, data: "file content" }
|
|
604
|
-
* // Or on error: { success: false, error: "ENOENT: no such file..." }
|
|
605
|
-
* ```
|
|
606
|
-
*/
|
|
607
507
|
implementSafe(invoke) {
|
|
608
|
-
const safeInvoke = async function(input) {
|
|
609
|
-
try {
|
|
610
|
-
const data = await invoke.call(this, input);
|
|
611
|
-
return { success: true, data };
|
|
612
|
-
} catch (error) {
|
|
613
|
-
return {
|
|
614
|
-
success: false,
|
|
615
|
-
error: error instanceof Error ? error.message : String(error)
|
|
616
|
-
};
|
|
617
|
-
}
|
|
618
|
-
};
|
|
619
|
-
const wrappedInvoke = async function(input) {
|
|
620
|
-
return safeInvoke.call(this, input);
|
|
621
|
-
};
|
|
622
508
|
return new _ToolBuilder(
|
|
623
509
|
cloneMetadata(this.metadata),
|
|
624
510
|
this._schema,
|
|
625
|
-
|
|
511
|
+
wrapSafeInvoke(invoke)
|
|
626
512
|
);
|
|
627
513
|
}
|
|
628
|
-
/**
|
|
629
|
-
* Build the tool with validation
|
|
630
|
-
*
|
|
631
|
-
* Validates:
|
|
632
|
-
* - All required fields are present
|
|
633
|
-
* - Metadata is valid
|
|
634
|
-
* - Schema has descriptions on all fields
|
|
635
|
-
*
|
|
636
|
-
* @returns The validated tool
|
|
637
|
-
* @throws {Error} If validation fails
|
|
638
|
-
*/
|
|
639
514
|
build() {
|
|
640
|
-
|
|
641
|
-
throw new Error("Tool name is required. Use .name() to set it.");
|
|
642
|
-
}
|
|
643
|
-
if (!this.metadata.description) {
|
|
644
|
-
throw new Error("Tool description is required. Use .description() to set it.");
|
|
645
|
-
}
|
|
646
|
-
if (!this.metadata.category) {
|
|
647
|
-
throw new Error("Tool category is required. Use .category() to set it.");
|
|
648
|
-
}
|
|
649
|
-
if (!this._schema) {
|
|
650
|
-
throw new Error("Tool schema is required. Use .schema() to set it.");
|
|
651
|
-
}
|
|
652
|
-
if (!this._invoke) {
|
|
653
|
-
throw new Error("Tool implementation is required. Use .implement() to set it.");
|
|
654
|
-
}
|
|
655
|
-
const invoke = this._invoke;
|
|
656
|
-
return createTool(
|
|
657
|
-
this.metadata,
|
|
658
|
-
this._schema,
|
|
659
|
-
async function(input) {
|
|
660
|
-
return invoke.call(this, input);
|
|
661
|
-
}
|
|
662
|
-
);
|
|
515
|
+
return buildTool(this.metadata, this._schema, this._invoke);
|
|
663
516
|
}
|
|
664
517
|
};
|
|
665
518
|
function toolBuilder() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentforge/core",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.37",
|
|
4
4
|
"description": "Production-ready TypeScript agent framework built on LangGraph with orchestration, middleware, and typed abstractions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|