@@ -45,21 +45,23 @@ type Return struct {
4545}
4646
4747type Call struct {
48- ToolName string `json:"toolName ,omitempty"`
49- Input string `json:"input,omitempty"`
48+ ToolID string `json:"toolID ,omitempty"`
49+ Input string `json:"input,omitempty"`
5050}
5151
5252type CallResult struct {
53- ID string `json:"id,omitempty"`
53+ ToolID string `json:"toolID,omitempty"`
54+ CallID string `json:"callID,omitempty"`
5455 Result string `json:"result,omitempty"`
5556}
5657
5758type Context struct {
58- ID string
59- Ctx context.Context
60- Parent * Context
61- Program * types.Program
62- Tool types.Tool
59+ ID string
60+ Ctx context.Context
61+ Parent * Context
62+ Program * types.Program
63+ Tool types.Tool
64+ toolNames map [string ]struct {}
6365}
6466
6567func (c * Context ) ParentID () string {
@@ -97,10 +99,10 @@ func NewContext(ctx context.Context, prg *types.Program) Context {
9799 return callCtx
98100}
99101
100- func (c * Context ) SubCall (ctx context.Context , toolName , callID string ) (Context , error ) {
101- tool , err := c .getTool ( toolName )
102- if err != nil {
103- return Context {}, err
102+ func (c * Context ) SubCall (ctx context.Context , toolID , callID string ) (Context , error ) {
103+ tool , ok := c .Program . ToolSet [ toolID ]
104+ if ! ok {
105+ return Context {}, fmt . Errorf ( "failed to file tool for id [%s]" , toolID )
104106 }
105107 return Context {
106108 ID : callID ,
@@ -111,8 +113,8 @@ func (c *Context) SubCall(ctx context.Context, toolName, callID string) (Context
111113 }, nil
112114}
113115
114- func (c * Context ) getTool (name string ) (types.Tool , error ) {
115- toolID , ok := c . Tool .ToolMapping [name ]
116+ func (c * Context ) getTool (parent types. Tool , name string ) (types.Tool , error ) {
117+ toolID , ok := parent .ToolMapping [name ]
116118 if ! ok {
117119 return types.Tool {}, & ErrToolNotFound {
118120 ToolName : name ,
@@ -127,6 +129,45 @@ func (c *Context) getTool(name string) (types.Tool, error) {
127129 return tool , nil
128130}
129131
132+ func (c * Context ) appendTool (completion * types.CompletionRequest , parentTool types.Tool , subToolName string ) error {
133+ subTool , err := c .getTool (parentTool , subToolName )
134+ if err != nil {
135+ return err
136+ }
137+
138+ args := subTool .Parameters .Arguments
139+ if args == nil && ! subTool .IsCommand () {
140+ args = & system .DefaultToolSchema
141+ }
142+
143+ for _ , existingTool := range completion .Tools {
144+ if existingTool .Function .ToolID == subTool .ID {
145+ return nil
146+ }
147+ }
148+
149+ if c .toolNames == nil {
150+ c .toolNames = map [string ]struct {}{}
151+ }
152+
153+ completion .Tools = append (completion .Tools , types.CompletionTool {
154+ Function : types.CompletionFunctionDefinition {
155+ ToolID : subTool .ID ,
156+ Name : PickToolName (subToolName , c .toolNames ),
157+ Description : subTool .Parameters .Description ,
158+ Parameters : args ,
159+ },
160+ })
161+
162+ for _ , export := range subTool .Export {
163+ if err := c .appendTool (completion , subTool , export ); err != nil {
164+ return err
165+ }
166+ }
167+
168+ return nil
169+ }
170+
130171func (e * Engine ) Start (ctx Context , input string ) (* Return , error ) {
131172 tool := ctx .Tool
132173
@@ -155,21 +196,9 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) {
155196 }
156197
157198 for _ , subToolName := range tool .Parameters .Tools {
158- subTool , err := ctx .getTool (subToolName )
159- if err != nil {
199+ if err := ctx .appendTool (& completion , ctx .Tool , subToolName ); err != nil {
160200 return nil , err
161201 }
162- args := subTool .Parameters .Arguments
163- if args == nil && ! subTool .IsCommand () {
164- args = & system .DefaultToolSchema
165- }
166- completion .Tools = append (completion .Tools , types.CompletionTool {
167- Function : types.CompletionFunctionDefinition {
168- Name : subToolName ,
169- Description : subTool .Parameters .Description ,
170- Parameters : args ,
171- },
172- })
173202 }
174203
175204 if tool .Instructions != "" {
@@ -225,10 +254,19 @@ func (e *Engine) complete(ctx context.Context, state *State) (*Return, error) {
225254 state .Pending = map [string ]types.CompletionToolCall {}
226255 for _ , content := range resp .Content {
227256 if content .ToolCall != nil {
257+ var toolID string
258+ for _ , tool := range state .Completion .Tools {
259+ if tool .Function .Name == content .ToolCall .Function .Name {
260+ toolID = tool .Function .ToolID
261+ }
262+ }
263+ if toolID == "" {
264+ return nil , fmt .Errorf ("failed to find tool id for tool %s in tool_call result" , content .ToolCall .Function .Name )
265+ }
228266 state .Pending [content .ToolCall .ID ] = * content .ToolCall
229267 ret .Calls [content .ToolCall .ID ] = Call {
230- ToolName : content . ToolCall . Function . Name ,
231- Input : content .ToolCall .Function .Arguments ,
268+ ToolID : toolID ,
269+ Input : content .ToolCall .Function .Arguments ,
232270 }
233271 } else {
234272 cp := content .Text
@@ -247,7 +285,7 @@ func (e *Engine) Continue(ctx context.Context, state *State, results ...CallResu
247285 }
248286
249287 for _ , result := range results {
250- state .Results [result .ID ] = result
288+ state .Results [result .CallID ] = result
251289 }
252290
253291 ret := Return {
@@ -262,8 +300,8 @@ func (e *Engine) Continue(ctx context.Context, state *State, results ...CallResu
262300 for id , pending := range state .Pending {
263301 if _ , ok := state .Results [id ]; ! ok {
264302 ret .Calls [id ] = Call {
265- ToolName : pending .Function .Name ,
266- Input : pending .Function .Arguments ,
303+ ToolID : state . Completion . Tools [ * pending .Index ]. Function .ToolID ,
304+ Input : pending .Function .Arguments ,
267305 }
268306 }
269307 }
0 commit comments