Skip to content

Better tool registry#2807

Merged
dgageot merged 27 commits into
docker:mainfrom
dgageot:better-tool-registry
May 18, 2026
Merged

Better tool registry#2807
dgageot merged 27 commits into
docker:mainfrom
dgageot:better-tool-registry

Conversation

@dgageot
Copy link
Copy Markdown
Member

@dgageot dgageot commented May 17, 2026

No description provided.

@dgageot dgageot requested a review from a team as a code owner May 17, 2026 06:48
@docker-agent

This comment was marked as outdated.

Comment thread pkg/tools/builtin/lsp/lsp.go Outdated
Comment thread pkg/teamloader/registry.go Outdated
Comment thread pkg/tools/builtin/memory/memory.go Outdated
Comment thread pkg/teamloader/registry.go
Comment thread pkg/tools/builtin/shell/shell.go
Comment thread pkg/tools/builtin/rag/rag.go
Comment thread pkg/teamloader/registry.go
dgageot added 27 commits May 18, 2026 10:23
+ Simpler interface

Signed-off-by: David Gageot <david.gageot@docker.com>
Signed-off-by: David Gageot <david.gageot@docker.com>
Signed-off-by: David Gageot <david.gageot@docker.com>
Signed-off-by: David Gageot <david.gageot@docker.com>
…tructors)

Signed-off-by: David Gageot <david@gageot.net>
Assisted-By: docker-agent
Drop resolveToolsetWorkingDir and checkDirExists helpers in favor of
workingdir.Resolve and workingdir.CheckDirExists, mirroring the MCP
toolset's approach. This ensures consistent behavior (~ and ${VAR}
expansion, error wording) across all toolsets.

Signed-off-by: David Gageot <david@gageot.net>
Assisted-By: docker-agent
Delete resolveToolsetWorkingDir and its tests (TestResolveToolsetWorkingDir,
TestResolveToolsetWorkingDir_EnvVarExpansion). The workingdir package is the
single source of truth for working directory resolution.

Signed-off-by: David Gageot <david@gageot.net>
Assisted-By: docker-agent
Create pkg/tools/toolsetpath with a Resolve helper that both memory and
tasks toolsets now call. This eliminates the duplicate resolveToolsetPath
implementations and ensures consistent path resolution behavior across
all toolsets that need to validate file/directory paths.

Signed-off-by: David Gageot <david@gageot.net>
Assisted-By: docker-agent
Change "should have been resolved from ref" to "requires either a
rag_config block or a ref" to avoid leaking internal expectations to
YAML authors who might be hand-writing configs.

Signed-off-by: David Gageot <david@gageot.net>
Assisted-By: docker-agent
Add comment explaining why os.Environ() is appended after expanding
toolset.Env: EnvProvider is used only to expand ${...} references,
while the subprocess still needs access to the full host environment.

Signed-off-by: David Gageot <david@gageot.net>
Assisted-By: docker-agent
@dgageot
Copy link
Copy Markdown
Member Author

dgageot commented May 18, 2026

/review

@dgageot dgageot force-pushed the better-tool-registry branch from a802e89 to e89c09c Compare May 18, 2026 08:55
@docker-agent
Copy link
Copy Markdown

PR Review Failed — The review agent encountered an error and could not complete the review. View logs.

Copy link
Copy Markdown
Contributor

@aheritier aheritier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Large but largely mechanical refactor — and unusually reviewable thanks to the commit-per-toolset cadence. Each step compiles and is well-scoped. CI is green; local build/test/vet/gofmt all pass. Approving.

Highlights:

  • pkg/tools/workingdir + pkg/tools/toolsetpath are exactly the right size — small, focused, with their own tests, and Resolve semantics documented up-front.
  • The end-to-end working_dir regression tests (TestCreateMCPTool_WorkingDir_ReachesSubprocess, TestCreateLSPTool_WorkingDir_ReachesSubprocess) are the kind that would have caught the original bug they defend against.
  • Moving lifecyclePolicyFromConfig into pkg/tools/lifecycle removes a layering inversion — clean win.

Findings below are non-blocking polish.

}

// TestCreateMCPTool_WorkingDir_ReachesSubprocess verifies that working_dir is
} // TestCreateMCPTool_WorkingDir_ReachesSubprocess verifies that working_dir is
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit — Stray missing newline: the closing } of TestCreateMCPTool_GatewayRefMissingBinaryStillBuilds is on the same line as the next function's leading comment (} // TestCreateMCPTool_WorkingDir_…). gofmt accepts it, but it's the only place in the file with that style.

}

// Default returns the configured agent working directory or the process cwd.
func Default(agentWorkingDir string) string {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NitDefault is exported but has zero callers. Meanwhile pkg/tools/builtin/filesystem/filesystem.go (~L130–137) still inlines the same os.Getwd() fallback. Either route filesystem through workingdir.Default or drop the exported helper.

@@ -43,29 +30,74 @@ import (
// configName identifies the agent config file (e.g. "memory_agent" from "memory_agent.yaml").
type ToolsetCreator func(ctx context.Context, toolset latest.Toolset, parentDir string, runConfig *config.RuntimeConfig, configName string) (tools.ToolSet, error)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QuestionToolsetCreator is exported, but the new ToolsetRegistry interface only exposes CreateTool — there's no public Register method anymore. External implementations (e.g. ACP) wrap NewDefaultToolsetRegistry() and forward; they never construct a ToolsetCreator. Consider unexporting it if registration is closed.

return NewWithPath(db, validatedMemoryPath), nil
}

func New(manager DB) *ToolSet {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit — After the rename, New(manager) (no path) is only used in tests; production code goes through NewWithPath. Worth folding the two into one constructor with an optional path, or marking New test-only / unexporting it.

// host environment. EnvProvider is used only to expand ${...} references
// in toolset.Env; the subprocess still needs access to the full environment.

env = append(env, os.Environ()...)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit — The new comment explaining the os.Environ() re-append is helpful — but the same logic is repeated verbatim (without the comment) in script_shell.go, lsp.go, mcp.go. Consider hoisting to a small expandedEnv(ctx, toolset.Env, runConfig) helper alongside workingdir.Resolve — same shape every time.

@dgageot dgageot merged commit 53c81f6 into docker:main May 18, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants