Skip to content

Commit f297a1a

Browse files
chore: refactor export context behavior
1 parent f02d11e commit f297a1a

File tree

5 files changed

+149
-121
lines changed

5 files changed

+149
-121
lines changed

pkg/parser/parser.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,13 @@ func isParam(line string, tool *types.Tool) (_ bool, err error) {
100100
return false, err
101101
}
102102
tool.Parameters.Chat = v
103-
case "export":
103+
case "export", "exporttool", "exports", "exporttools":
104104
tool.Parameters.Export = append(tool.Parameters.Export, csv(value)...)
105105
case "tool", "tools":
106106
tool.Parameters.Tools = append(tool.Parameters.Tools, csv(value)...)
107107
case "globaltool", "globaltools":
108108
tool.Parameters.GlobalTools = append(tool.Parameters.GlobalTools, csv(value)...)
109-
case "exportcontext":
109+
case "exportcontext", "exportcontexts":
110110
tool.Parameters.ExportContext = append(tool.Parameters.ExportContext, csv(value)...)
111111
case "context":
112112
tool.Parameters.Context = append(tool.Parameters.Context, csv(value)...)

pkg/tests/testdata/TestExportContext/call1.golden

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"Tools": [
55
{
66
"function": {
7-
"toolID": "testdata/TestExportContext/test.gpt:21",
7+
"toolID": "testdata/TestExportContext/test.gpt:22",
88
"name": "subtool",
99
"parameters": {
1010
"properties": {
@@ -22,7 +22,7 @@
2222
},
2323
{
2424
"function": {
25-
"toolID": "testdata/TestExportContext/test.gpt:14",
25+
"toolID": "testdata/TestExportContext/test.gpt:15",
2626
"name": "sampletool",
2727
"description": "sample",
2828
"parameters": {

pkg/tests/testdata/TestExportContext/test.gpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ This is from tool
66
---
77
name: fromcontext
88
export: sampletool
9+
export context: fromexportcontext
910

1011
#!/bin/bash
1112
echo this is from context
@@ -19,7 +20,6 @@ Dummy body
1920

2021
---
2122
name: subtool
22-
export context: fromexportcontext
2323

2424
Dummy body
2525

pkg/types/set.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package types
2+
3+
type toolRefKey struct {
4+
name string
5+
toolID string
6+
arg string
7+
}
8+
9+
type toolRefSet struct {
10+
set map[toolRefKey]ToolReference
11+
order []toolRefKey
12+
err error
13+
}
14+
15+
func (t *toolRefSet) List() (result []ToolReference, err error) {
16+
for _, k := range t.order {
17+
result = append(result, t.set[k])
18+
}
19+
return result, t.err
20+
}
21+
22+
func (t *toolRefSet) AddAll(values []ToolReference, err error) {
23+
if t.err != nil {
24+
t.err = err
25+
}
26+
for _, v := range values {
27+
t.Add(v)
28+
}
29+
}
30+
31+
func (t *toolRefSet) Add(value ToolReference) {
32+
key := toolRefKey{
33+
name: value.Named,
34+
toolID: value.ToolID,
35+
arg: value.Arg,
36+
}
37+
38+
if _, ok := t.set[key]; !ok {
39+
if t.set == nil {
40+
t.set = map[toolRefKey]ToolReference{}
41+
}
42+
t.set[key] = value
43+
t.order = append(t.order, key)
44+
}
45+
}

pkg/types/tool.go

Lines changed: 99 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -63,59 +63,8 @@ type ToolReference struct {
6363
ToolID string
6464
}
6565

66-
func (p Program) GetContextToolRefs(toolID string) (result []ToolReference, _ error) {
67-
seen := map[struct {
68-
toolID string
69-
arg string
70-
}]struct{}{}
71-
tool := p.ToolSet[toolID]
72-
73-
subToolRefs, err := tool.GetToolRefsFromNames(tool.Tools)
74-
if err != nil {
75-
return nil, err
76-
}
77-
78-
for _, subToolRef := range subToolRefs {
79-
subTool := p.ToolSet[subToolRef.ToolID]
80-
exportContextToolRefs, err := subTool.GetToolRefsFromNames(subTool.ExportContext)
81-
if err != nil {
82-
return nil, err
83-
}
84-
for _, exportContextToolRef := range exportContextToolRefs {
85-
key := struct {
86-
toolID string
87-
arg string
88-
}{
89-
toolID: exportContextToolRef.ToolID,
90-
arg: exportContextToolRef.Arg,
91-
}
92-
if _, ok := seen[key]; !ok {
93-
seen[key] = struct{}{}
94-
result = append(result, exportContextToolRef)
95-
}
96-
}
97-
}
98-
99-
contextToolRefs, err := p.ToolSet[toolID].GetToolRefsFromNames(p.ToolSet[toolID].Context)
100-
if err != nil {
101-
return nil, err
102-
}
103-
104-
for _, contextToolRef := range contextToolRefs {
105-
key := struct {
106-
toolID string
107-
arg string
108-
}{
109-
toolID: contextToolRef.ToolID,
110-
arg: contextToolRef.Arg,
111-
}
112-
if _, ok := seen[key]; !ok {
113-
seen[key] = struct{}{}
114-
result = append(result, contextToolRef)
115-
}
116-
}
117-
118-
return
66+
func (p Program) GetContextToolRefs(toolID string) ([]ToolReference, error) {
67+
return p.ToolSet[toolID].GetContextTools(p)
11968
}
12069

12170
func (p Program) GetCompletionTools() (result []CompletionTool, err error) {
@@ -295,105 +244,139 @@ func (t Tool) String() string {
295244
return buf.String()
296245
}
297246

298-
func (t Tool) GetCompletionTools(prg Program) (result []CompletionTool, err error) {
299-
toolNames := map[string]struct{}{}
247+
func (t Tool) GetExportedContext(prg Program) ([]ToolReference, error) {
248+
result := &toolRefSet{}
300249

301-
subToolRefs, err := t.GetToolRefsFromNames(t.Parameters.Tools)
250+
exportRefs, err := t.GetToolRefsFromNames(t.ExportContext)
302251
if err != nil {
303252
return nil, err
304253
}
305254

306-
for _, subToolRef := range subToolRefs {
307-
result, err = appendTool(result, prg, t, subToolRef.Reference, toolNames, subToolRef.Named)
308-
if err != nil {
309-
return nil, err
310-
}
255+
for _, exportRef := range exportRefs {
256+
result.Add(exportRef)
257+
258+
tool := prg.ToolSet[exportRef.ToolID]
259+
result.AddAll(tool.GetExportedContext(prg))
311260
}
312261

313-
for _, subToolName := range t.Parameters.Context {
314-
result, err = appendExports(result, prg, t, subToolName, toolNames)
315-
if err != nil {
316-
return nil, err
317-
}
262+
return result.List()
263+
}
264+
265+
func (t Tool) GetExportedTools(prg Program) ([]ToolReference, error) {
266+
result := &toolRefSet{}
267+
268+
exportRefs, err := t.GetToolRefsFromNames(t.Export)
269+
if err != nil {
270+
return nil, err
271+
}
272+
273+
for _, exportRef := range exportRefs {
274+
result.Add(exportRef)
275+
result.AddAll(prg.ToolSet[exportRef.ToolID].GetExportedTools(prg))
318276
}
319277

320-
return result, nil
278+
return result.List()
321279
}
322280

323-
func getTool(prg Program, parent Tool, name string) (Tool, error) {
324-
toolID, ok := parent.ToolMapping[name]
325-
if !ok {
326-
return Tool{}, &ErrToolNotFound{
327-
ToolName: name,
328-
}
281+
func (t Tool) GetContextTools(prg Program) ([]ToolReference, error) {
282+
result := &toolRefSet{}
283+
284+
contextRefs, err := t.GetToolRefsFromNames(t.Context)
285+
if err != nil {
286+
return nil, err
329287
}
330-
tool, ok := prg.ToolSet[toolID]
331-
if !ok {
332-
return Tool{}, &ErrToolNotFound{
333-
ToolName: name,
334-
}
288+
289+
for _, contextRef := range contextRefs {
290+
result.AddAll(prg.ToolSet[contextRef.ToolID].GetExportedContext(prg))
291+
result.Add(contextRef)
335292
}
336-
return tool, nil
293+
294+
return result.List()
337295
}
338296

339-
func appendExports(completionTools []CompletionTool, prg Program, parentTool Tool, subToolName string, toolNames map[string]struct{}) ([]CompletionTool, error) {
340-
subTool, err := getTool(prg, parentTool, subToolName)
297+
func (t Tool) GetCompletionTools(prg Program) (result []CompletionTool, err error) {
298+
refs, err := t.getCompletionToolRefs(prg)
341299
if err != nil {
342300
return nil, err
343301
}
302+
return toolRefsToCompletionTools(refs, prg), nil
303+
}
304+
305+
func (t Tool) addReferencedTools(prg Program, result *toolRefSet) error {
306+
subToolRefs, err := t.GetToolRefsFromNames(t.Parameters.Tools)
307+
if err != nil {
308+
return err
309+
}
344310

345-
for _, export := range subTool.Export {
346-
completionTools, err = appendTool(completionTools, prg, subTool, export, toolNames, "")
347-
if err != nil {
348-
return nil, err
349-
}
311+
for _, subToolRef := range subToolRefs {
312+
// Add the tool
313+
result.Add(subToolRef)
314+
315+
// Get all tools exports
316+
result.AddAll(prg.ToolSet[subToolRef.ToolID].GetExportedTools(prg))
350317
}
351318

352-
return completionTools, nil
319+
return nil
353320
}
354321

355-
func appendTool(completionTools []CompletionTool, prg Program, parentTool Tool, subToolName string, toolNames map[string]struct{}, asName string) ([]CompletionTool, error) {
356-
subTool, err := getTool(prg, parentTool, subToolName)
322+
func (t Tool) addContextExportedTools(prg Program, result *toolRefSet) error {
323+
contextTools, err := t.GetContextTools(prg)
357324
if err != nil {
325+
return err
326+
}
327+
328+
for _, contextTool := range contextTools {
329+
result.AddAll(prg.ToolSet[contextTool.ToolID].GetExportedTools(prg))
330+
}
331+
332+
return nil
333+
}
334+
335+
func (t Tool) getCompletionToolRefs(prg Program) ([]ToolReference, error) {
336+
result := toolRefSet{}
337+
338+
if err := t.addReferencedTools(prg, &result); err != nil {
358339
return nil, err
359340
}
360341

361-
args := subTool.Parameters.Arguments
362-
if args == nil && !subTool.IsCommand() && !subTool.Chat {
363-
args = &system.DefaultToolSchema
342+
if err := t.addContextExportedTools(prg, &result); err != nil {
343+
return nil, err
364344
}
365345

366-
for _, existingTool := range completionTools {
367-
if existingTool.Function.ToolID == subTool.ID {
368-
return completionTools, nil
346+
return result.List()
347+
}
348+
349+
func toolRefsToCompletionTools(completionTools []ToolReference, prg Program) (result []CompletionTool) {
350+
toolNames := map[string]struct{}{}
351+
352+
for _, subToolRef := range completionTools {
353+
subTool := prg.ToolSet[subToolRef.ToolID]
354+
355+
subToolName := subToolRef.Reference
356+
if subToolRef.Named != "" {
357+
subToolName = subToolRef.Named
369358
}
370-
}
371359

372-
if subTool.Instructions == "" {
373-
log.Debugf("Skipping zero instruction tool %s (%s)", subToolName, subTool.ID)
374-
} else {
375-
name := subToolName
376-
if asName != "" {
377-
name = asName
360+
args := subTool.Parameters.Arguments
361+
if args == nil && !subTool.IsCommand() && !subTool.Chat {
362+
args = &system.DefaultToolSchema
378363
}
379-
completionTools = append(completionTools, CompletionTool{
380-
Function: CompletionFunctionDefinition{
381-
ToolID: subTool.ID,
382-
Name: PickToolName(name, toolNames),
383-
Description: subTool.Parameters.Description,
384-
Parameters: args,
385-
},
386-
})
387-
}
388364

389-
for _, export := range subTool.Export {
390-
completionTools, err = appendTool(completionTools, prg, subTool, export, toolNames, "")
391-
if err != nil {
392-
return nil, err
365+
if subTool.Instructions == "" {
366+
log.Debugf("Skipping zero instruction tool %s (%s)", subToolName, subTool.ID)
367+
} else {
368+
result = append(result, CompletionTool{
369+
Function: CompletionFunctionDefinition{
370+
ToolID: subTool.ID,
371+
Name: PickToolName(subToolName, toolNames),
372+
Description: subTool.Parameters.Description,
373+
Parameters: args,
374+
},
375+
})
393376
}
394377
}
395378

396-
return completionTools, nil
379+
return
397380
}
398381

399382
type Repo struct {

0 commit comments

Comments
 (0)