| 134 | } |
| 135 | |
| 136 | func (d *ToolSet) handleAddTool(ctx context.Context, args AddToolArgs) (*tools.ToolCallResult, error) { |
| 137 | d.mu.Lock() |
| 138 | defer d.mu.Unlock() |
| 139 | |
| 140 | span := trace.SpanFromContext(ctx) |
| 141 | annotate := func(outcome string) { |
| 142 | if !span.IsRecording() { |
| 143 | return |
| 144 | } |
| 145 | span.SetAttributes( |
| 146 | attribute.String("cagent.tool.deferred.op", "add_tool"), |
| 147 | attribute.String("cagent.tool.deferred.tool_name", args.Name), |
| 148 | attribute.String("cagent.tool.deferred.outcome", outcome), |
| 149 | attribute.Int("cagent.tool.deferred.activated_count", len(d.activatedTools)), |
| 150 | ) |
| 151 | } |
| 152 | |
| 153 | if _, exists := d.activatedTools[args.Name]; exists { |
| 154 | annotate("already_active") |
| 155 | return tools.ResultSuccess(fmt.Sprintf("Tool '%s' is already active", args.Name)), nil |
| 156 | } |
| 157 | |
| 158 | entry, exists := d.deferredTools[args.Name] |
| 159 | if !exists { |
| 160 | annotate("not_found") |
| 161 | return tools.ResultError(fmt.Sprintf("Tool '%s' not found.", args.Name)), nil |
| 162 | } |
| 163 | |
| 164 | delete(d.deferredTools, args.Name) |
| 165 | d.activatedTools[args.Name] = entry.tool |
| 166 | annotate("activated") |
| 167 | |
| 168 | return tools.ResultSuccess(fmt.Sprintf("Tool '%s' has been activated and is now available for use.\n\nDescription: %s", args.Name, entry.tool.Description)), nil |
| 169 | } |
| 170 | |
| 171 | func (d *ToolSet) Tools(context.Context) ([]tools.Tool, error) { |
| 172 | d.mu.RLock() |