@@ -5,19 +5,64 @@ import logger from "../utils/logger.js";
55
66export type Dict < T > = { [ key : string ] : T } ;
77
8- export interface IAthenaArgument {
9- type : "string" | "number" | "boolean" | "object" | "array" ;
8+ type IAthenaArgumentPrimitive = {
9+ type : "string" | "number" | "boolean" ;
1010 desc : string ;
1111 required : boolean ;
12- of ?: Dict < IAthenaArgument > | IAthenaArgument ;
13- }
14-
15- export interface IAthenaTool {
12+ } ;
13+
14+ export type IAthenaArgument =
15+ | IAthenaArgumentPrimitive
16+ | {
17+ type : "object" | "array" ;
18+ desc : string ;
19+ required : boolean ;
20+ of : Dict < IAthenaArgument > | IAthenaArgument ;
21+ } ;
22+ type IAthenaArgumentInstance < T extends IAthenaArgument > =
23+ T extends IAthenaArgumentPrimitive
24+ ? T [ "type" ] extends "string"
25+ ? T [ "required" ] extends true
26+ ? string
27+ : string | undefined
28+ : T [ "type" ] extends "number"
29+ ? T [ "required" ] extends true
30+ ? number
31+ : number | undefined
32+ : T [ "type" ] extends "boolean"
33+ ? T [ "required" ] extends true
34+ ? boolean
35+ : boolean | undefined
36+ : never
37+ : T extends { of : Dict < IAthenaArgument > }
38+ ? T [ "required" ] extends true
39+ ? { [ K in keyof T [ "of" ] ] : IAthenaArgumentInstance < T [ "of" ] [ K ] > }
40+ :
41+ | { [ K in keyof T [ "of" ] ] : IAthenaArgumentInstance < T [ "of" ] [ K ] > }
42+ | undefined
43+ : T extends { of : IAthenaArgument }
44+ ? T [ "required" ] extends true
45+ ? IAthenaArgumentInstance < T [ "of" ] > [ ]
46+ : IAthenaArgumentInstance < T [ "of" ] > [ ] | undefined
47+ : never ;
48+
49+ export interface IAthenaTool <
50+ Args extends Dict < IAthenaArgument > = Dict < IAthenaArgument > ,
51+ RetArgs extends Dict < IAthenaArgument > = Dict < IAthenaArgument > ,
52+ > {
1653 name : string ;
1754 desc : string ;
18- args : Dict < IAthenaArgument > ;
19- retvals : Dict < IAthenaArgument > ;
20- fn : ( args : Dict < any > ) => Promise < Dict < any > > ;
55+ args : Args ;
56+ retvals : RetArgs ;
57+ fn : ( args : {
58+ [ K in keyof Args ] : Args [ K ] extends IAthenaArgument
59+ ? IAthenaArgumentInstance < Args [ K ] >
60+ : never ;
61+ } ) => Promise < {
62+ [ K in keyof RetArgs ] : RetArgs [ K ] extends IAthenaArgument
63+ ? IAthenaArgumentInstance < RetArgs [ K ] >
64+ : never ;
65+ } > ;
2166 explain_args ?: ( args : Dict < any > ) => IAthenaExplanation ;
2267 explain_retvals ?: ( args : Dict < any > , retvals : Dict < any > ) => IAthenaExplanation ;
2368}
@@ -38,7 +83,7 @@ export class Athena extends EventEmitter {
3883 config : Dict < any > ;
3984 states : Dict < Dict < any > > ;
4085 plugins : Dict < PluginBase > ;
41- tools : Dict < IAthenaTool > ;
86+ tools : Dict < IAthenaTool < any , any > > ;
4287 events : Dict < IAthenaEvent > ;
4388
4489 constructor ( config : Dict < any > , states : Dict < Dict < any > > ) {
@@ -103,7 +148,26 @@ export class Athena extends EventEmitter {
103148 logger . warn ( `Plugin ${ name } is unloaded` ) ;
104149 }
105150
106- registerTool ( tool : IAthenaTool ) {
151+ registerTool <
152+ Args extends Dict < IAthenaArgument > ,
153+ RetArgs extends Dict < IAthenaArgument > ,
154+ Tool extends IAthenaTool < Args , RetArgs > ,
155+ > (
156+ config : {
157+ name : string ;
158+ desc : string ;
159+ args : Args ;
160+ retvals : RetArgs ;
161+ } ,
162+ toolImpl : {
163+ fn : Tool [ "fn" ] ;
164+ explain_args ?: Tool [ "explain_args" ] ;
165+ } ,
166+ ) {
167+ const tool = {
168+ ...config ,
169+ ...toolImpl ,
170+ } ;
107171 if ( tool . name in this . tools ) {
108172 throw new Error ( `Tool ${ tool . name } already registered` ) ;
109173 }
0 commit comments