77 "strings"
88
99 "github.com/getkin/kin-openapi/openapi3"
10+ "github.com/gptscript-ai/gptscript/pkg/system"
1011 "golang.org/x/exp/maps"
1112)
1213
@@ -16,6 +17,14 @@ const (
1617 CommandPrefix = "#!"
1718)
1819
20+ type ErrToolNotFound struct {
21+ ToolName string
22+ }
23+
24+ func (e * ErrToolNotFound ) Error () string {
25+ return fmt .Sprintf ("tool not found: %s" , e .ToolName )
26+ }
27+
1928type ToolSet map [string ]Tool
2029
2130type Program struct {
@@ -24,6 +33,17 @@ type Program struct {
2433 ToolSet ToolSet `json:"toolSet,omitempty"`
2534}
2635
36+ func (p Program ) GetCompletionTools () (result []CompletionTool , err error ) {
37+ return Tool {
38+ Parameters : Parameters {
39+ Tools : []string {"main" },
40+ },
41+ ToolMapping : map [string ]string {
42+ "main" : p .EntryToolID ,
43+ },
44+ }.GetCompletionTools (p )
45+ }
46+
2747func (p Program ) TopLevelTools () (result []Tool ) {
2848 for _ , tool := range p .ToolSet [p .EntryToolID ].LocalTools {
2949 result = append (result , p .ToolSet [tool ])
@@ -124,6 +144,75 @@ func (t Tool) String() string {
124144 return buf .String ()
125145}
126146
147+ func (t Tool ) GetCompletionTools (prg Program ) (result []CompletionTool , err error ) {
148+ toolNames := map [string ]struct {}{}
149+
150+ for _ , subToolName := range t .Parameters .Tools {
151+ result , err = appendTool (result , prg , t , subToolName , toolNames )
152+ if err != nil {
153+ return nil , err
154+ }
155+ }
156+
157+ return result , nil
158+ }
159+
160+ func getTool (prg Program , parent Tool , name string ) (Tool , error ) {
161+ toolID , ok := parent .ToolMapping [name ]
162+ if ! ok {
163+ return Tool {}, & ErrToolNotFound {
164+ ToolName : name ,
165+ }
166+ }
167+ tool , ok := prg .ToolSet [toolID ]
168+ if ! ok {
169+ return Tool {}, & ErrToolNotFound {
170+ ToolName : name ,
171+ }
172+ }
173+ return tool , nil
174+ }
175+
176+ func appendTool (completionTools []CompletionTool , prg Program , parentTool Tool , subToolName string , toolNames map [string ]struct {}) ([]CompletionTool , error ) {
177+ subTool , err := getTool (prg , parentTool , subToolName )
178+ if err != nil {
179+ return nil , err
180+ }
181+
182+ args := subTool .Parameters .Arguments
183+ if args == nil && ! subTool .IsCommand () {
184+ args = & system .DefaultToolSchema
185+ }
186+
187+ for _ , existingTool := range completionTools {
188+ if existingTool .Function .ToolID == subTool .ID {
189+ return completionTools , nil
190+ }
191+ }
192+
193+ if subTool .Instructions == "" {
194+ log .Debugf ("Skipping zero instruction tool %s (%s)" , subToolName , subTool .ID )
195+ } else {
196+ completionTools = append (completionTools , CompletionTool {
197+ Function : CompletionFunctionDefinition {
198+ ToolID : subTool .ID ,
199+ Name : PickToolName (subToolName , toolNames ),
200+ Description : subTool .Parameters .Description ,
201+ Parameters : args ,
202+ },
203+ })
204+ }
205+
206+ for _ , export := range subTool .Export {
207+ completionTools , err = appendTool (completionTools , prg , subTool , export , toolNames )
208+ if err != nil {
209+ return nil , err
210+ }
211+ }
212+
213+ return completionTools , nil
214+ }
215+
127216type Repo struct {
128217 // VCS The VCS type, such as "git"
129218 VCS string
0 commit comments