MCPcopy
hub / github.com/docker/docker-agent / getToolsForAgent

Function getToolsForAgent

pkg/teamloader/teamloader.go:669–749  ·  view source on GitHub ↗

getToolsForAgent returns the tool definitions for an agent based on its configuration. Toolset instructions support ${...} JavaScript placeholders (e.g. ${env.X}); they are expanded here using the runtime env provider.

(ctx context.Context, a *latest.AgentConfig, parentDir string, runConfig *config.RuntimeConfig, registry ToolsetRegistry, configName string, expander *js.Expander)

Source from the content-addressed store, hash-verified

667// configuration. Toolset instructions support ${...} JavaScript placeholders
668// (e.g. ${env.X}); they are expanded here using the runtime env provider.
669func getToolsForAgent(ctx context.Context, a *latest.AgentConfig, parentDir string, runConfig *config.RuntimeConfig, registry ToolsetRegistry, configName string, expander *js.Expander) ([]tools.ToolSet, []string) {
670 var (
671 toolSets []tools.ToolSet
672 warnings []string
673 lspBackends []lsp.Backend
674 )
675
676 deferredToolset := deferred.New()
677
678 for i := range a.Toolsets {
679 toolset := a.Toolsets[i]
680
681 tool, err := registry.CreateTool(ctx, toolset, parentDir, runConfig, configName)
682 if err != nil {
683 // Collect error but continue loading other toolsets
684 slog.WarnContext(ctx, "Toolset configuration failed; skipping", "type", toolset.Type, "ref", toolset.Ref, "command", toolset.Command, "error", err)
685 warnings = append(warnings, fmt.Sprintf("toolset %s failed: %v", toolset.Type, err))
686 continue
687 }
688
689 wrapped := WithToolsFilter(tool, toolset.Tools...)
690 wrapped = WithReadOnlyFilter(wrapped, toolset.ReadOnly || a.ReadOnly)
691 wrapped = WithInstructions(wrapped, expander.Expand(ctx, toolset.Instruction, nil))
692 wrapped = WithToon(wrapped, toolset.Toon)
693 wrapped = WithModelOverride(wrapped, toolset.Model)
694
695 // Handle deferred tools
696 if !toolset.Defer.IsEmpty() {
697 deferredToolset.AddSource(wrapped, toolset.Defer.DeferAll, toolset.Defer.Tools)
698 if toolset.Defer.DeferAll {
699 // Don't add the wrapped toolset to toolSets - all its tools are deferred
700 // TODO: maybe we _do_ want to add this toolset since it has instructions?
701 continue
702 } else {
703 wrapped = WithToolsExcludeFilter(wrapped, toolset.Defer.Tools...)
704 }
705 }
706
707 // Collect LSP backends for multiplexing when there are multiple.
708 // Instead of adding them individually (which causes duplicate tool names),
709 // they are combined into a single Multiplexer after the loop.
710 if toolset.Type == "lsp" {
711 if lspTool, ok := tool.(*lsp.ToolSet); ok {
712 lspBackends = append(lspBackends, lsp.Backend{LSP: lspTool, Toolset: wrapped})
713 continue
714 }
715 slog.WarnContext(ctx, "Toolset configured as type 'lsp' but registry returned unexpected type; treating as regular toolset",
716 "type", fmt.Sprintf("%T", tool), "command", toolset.Command)
717 }
718
719 toolSets = append(toolSets, wrapped)
720 }
721
722 // Merge LSP backends: if there are multiple, combine them into a single
723 // multiplexer so the LLM sees one set of lsp_* tools instead of duplicates.
724 if len(lspBackends) > 1 {
725 toolSets = append(toolSets, lsp.NewLSPMultiplexer(lspBackends))
726 } else if len(lspBackends) == 1 {

Calls 15

NewFunction · 0.92
NewLSPMultiplexerFunction · 0.92
NewFunction · 0.92
NewFunction · 0.92
WrapFunction · 0.92
WithToolsFilterFunction · 0.85
WithReadOnlyFilterFunction · 0.85
WithInstructionsFunction · 0.85
WithToonFunction · 0.85
WithModelOverrideFunction · 0.85
WithToolsExcludeFilterFunction · 0.85
ExpandMethod · 0.80