mirror of
https://github.com/mark3labs/kit.git
synced 2026-06-14 03:30:26 +00:00
export tools and tool factories with WithWorkDir option (Plan 01)
- Add ToolOption/WithWorkDir functional options pattern to internal/core - Update all 7 tool constructors to accept ...ToolOption and resolve paths relative to the configured working directory - Create pkg/kit/tools.go with public exports: individual constructors, bundles (AllTools, CodingTools, ReadOnlyTools), and WithWorkDir - Add CoreTools field to AgentConfig/AgentCreationOptions so callers can inject custom tool sets instead of hardcoding core.AllTools() - Add Tools field to kit.Options and GetTools() to kit.Kit - Fully backward compatible: no-arg calls use os.Getwd() as before
This commit is contained in:
+11
-2
@@ -25,6 +25,11 @@ type AgentConfig struct {
|
||||
StreamingEnabled bool
|
||||
DebugLogger tools.DebugLogger
|
||||
|
||||
// CoreTools overrides the default core tool set. If empty, core.AllTools()
|
||||
// is used. This allows SDK users to provide a custom tool set (e.g.
|
||||
// CodingTools or tools with a custom WorkDir).
|
||||
CoreTools []fantasy.AgentTool
|
||||
|
||||
// ToolWrapper is an optional function that wraps the combined tool list
|
||||
// before it is passed to the Fantasy agent. Used by the extensions system
|
||||
// to intercept tool calls/results.
|
||||
@@ -93,8 +98,12 @@ func NewAgent(ctx context.Context, agentConfig *AgentConfig) (*Agent, error) {
|
||||
return nil, fmt.Errorf("failed to create model provider: %v", err)
|
||||
}
|
||||
|
||||
// Register core tools (direct fantasy implementations, no MCP overhead)
|
||||
coreTools := core.AllTools()
|
||||
// Register core tools (direct fantasy implementations, no MCP overhead).
|
||||
// Use caller-provided tools if set, otherwise default to all core tools.
|
||||
coreTools := agentConfig.CoreTools
|
||||
if len(coreTools) == 0 {
|
||||
coreTools = core.AllTools()
|
||||
}
|
||||
|
||||
// Build the combined tool list: core tools + any external MCP tools
|
||||
allTools := make([]fantasy.AgentTool, len(coreTools))
|
||||
|
||||
@@ -36,6 +36,9 @@ type AgentCreationOptions struct {
|
||||
SpinnerFunc SpinnerFunc // Function to show spinner (provided by caller)
|
||||
// DebugLogger is an optional logger for debugging MCP communications
|
||||
DebugLogger tools.DebugLogger // Optional debug logger
|
||||
// CoreTools overrides the default core tool set. If empty, core.AllTools()
|
||||
// is used.
|
||||
CoreTools []fantasy.AgentTool
|
||||
// ToolWrapper wraps the combined tool list before Fantasy agent creation.
|
||||
ToolWrapper func([]fantasy.AgentTool) []fantasy.AgentTool
|
||||
// ExtraTools are additional tools to include (e.g. from extensions).
|
||||
@@ -53,6 +56,7 @@ func CreateAgent(ctx context.Context, opts *AgentCreationOptions) (*Agent, error
|
||||
MaxSteps: opts.MaxSteps,
|
||||
StreamingEnabled: opts.StreamingEnabled,
|
||||
DebugLogger: opts.DebugLogger,
|
||||
CoreTools: opts.CoreTools,
|
||||
ToolWrapper: opts.ToolWrapper,
|
||||
ExtraTools: opts.ExtraTools,
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ type bashArgs struct {
|
||||
}
|
||||
|
||||
// NewBashTool creates the bash core tool.
|
||||
func NewBashTool() fantasy.AgentTool {
|
||||
func NewBashTool(opts ...ToolOption) fantasy.AgentTool {
|
||||
cfg := ApplyOptions(opts)
|
||||
return &coreTool{
|
||||
info: fantasy.ToolInfo{
|
||||
Name: "bash",
|
||||
@@ -52,11 +53,13 @@ func NewBashTool() fantasy.AgentTool {
|
||||
},
|
||||
Required: []string{"command"},
|
||||
},
|
||||
handler: executeBash,
|
||||
handler: func(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
return executeBash(ctx, call, cfg.WorkDir)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func executeBash(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
func executeBash(ctx context.Context, call fantasy.ToolCall, workDir string) (fantasy.ToolResponse, error) {
|
||||
var args bashArgs
|
||||
if err := parseArgs(call.Input, &args); err != nil {
|
||||
return fantasy.NewTextErrorResponse("command parameter is required"), nil
|
||||
@@ -83,6 +86,9 @@ func executeBash(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolRespon
|
||||
defer cancel()
|
||||
|
||||
cmd := exec.CommandContext(cmdCtx, "bash", "-c", args.Command)
|
||||
if workDir != "" {
|
||||
cmd.Dir = workDir
|
||||
}
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
|
||||
@@ -17,7 +17,8 @@ type editArgs struct {
|
||||
}
|
||||
|
||||
// NewEditTool creates the edit core tool.
|
||||
func NewEditTool() fantasy.AgentTool {
|
||||
func NewEditTool(opts ...ToolOption) fantasy.AgentTool {
|
||||
cfg := ApplyOptions(opts)
|
||||
return &coreTool{
|
||||
info: fantasy.ToolInfo{
|
||||
Name: "edit",
|
||||
@@ -38,11 +39,13 @@ func NewEditTool() fantasy.AgentTool {
|
||||
},
|
||||
Required: []string{"path", "old_text", "new_text"},
|
||||
},
|
||||
handler: executeEdit,
|
||||
handler: func(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
return executeEdit(ctx, call, cfg.WorkDir)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func executeEdit(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
func executeEdit(ctx context.Context, call fantasy.ToolCall, workDir string) (fantasy.ToolResponse, error) {
|
||||
var args editArgs
|
||||
if err := parseArgs(call.Input, &args); err != nil {
|
||||
return fantasy.NewTextErrorResponse("path, old_text, and new_text parameters are required"), nil
|
||||
@@ -51,7 +54,7 @@ func executeEdit(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolRespon
|
||||
return fantasy.NewTextErrorResponse("path parameter is required"), nil
|
||||
}
|
||||
|
||||
absPath, err := resolvePath(args.Path)
|
||||
absPath, err := resolvePathWithWorkDir(args.Path, workDir)
|
||||
if err != nil {
|
||||
return fantasy.NewTextErrorResponse(fmt.Sprintf("invalid path: %v", err)), nil
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@ type findArgs struct {
|
||||
}
|
||||
|
||||
// NewFindTool creates the find core tool.
|
||||
func NewFindTool() fantasy.AgentTool {
|
||||
func NewFindTool(opts ...ToolOption) fantasy.AgentTool {
|
||||
cfg := ApplyOptions(opts)
|
||||
return &coreTool{
|
||||
info: fantasy.ToolInfo{
|
||||
Name: "find",
|
||||
@@ -39,11 +40,13 @@ func NewFindTool() fantasy.AgentTool {
|
||||
},
|
||||
Required: []string{"pattern"},
|
||||
},
|
||||
handler: executeFind,
|
||||
handler: func(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
return executeFind(ctx, call, cfg.WorkDir)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func executeFind(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
func executeFind(ctx context.Context, call fantasy.ToolCall, workDir string) (fantasy.ToolResponse, error) {
|
||||
var args findArgs
|
||||
if err := parseArgs(call.Input, &args); err != nil {
|
||||
return fantasy.NewTextErrorResponse("pattern parameter is required"), nil
|
||||
@@ -59,11 +62,13 @@ func executeFind(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolRespon
|
||||
|
||||
searchPath := "."
|
||||
if args.Path != "" {
|
||||
resolved, err := resolvePath(args.Path)
|
||||
resolved, err := resolvePathWithWorkDir(args.Path, workDir)
|
||||
if err != nil {
|
||||
return fantasy.NewTextErrorResponse(fmt.Sprintf("invalid path: %v", err)), nil
|
||||
}
|
||||
searchPath = resolved
|
||||
} else if workDir != "" {
|
||||
searchPath = workDir
|
||||
}
|
||||
|
||||
// Try fd first (faster, respects .gitignore by default)
|
||||
|
||||
@@ -22,7 +22,8 @@ type grepArgs struct {
|
||||
}
|
||||
|
||||
// NewGrepTool creates the grep core tool.
|
||||
func NewGrepTool() fantasy.AgentTool {
|
||||
func NewGrepTool(opts ...ToolOption) fantasy.AgentTool {
|
||||
cfg := ApplyOptions(opts)
|
||||
return &coreTool{
|
||||
info: fantasy.ToolInfo{
|
||||
Name: "grep",
|
||||
@@ -59,11 +60,13 @@ func NewGrepTool() fantasy.AgentTool {
|
||||
},
|
||||
Required: []string{"pattern"},
|
||||
},
|
||||
handler: executeGrep,
|
||||
handler: func(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
return executeGrep(ctx, call, cfg.WorkDir)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func executeGrep(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
func executeGrep(ctx context.Context, call fantasy.ToolCall, workDir string) (fantasy.ToolResponse, error) {
|
||||
var args grepArgs
|
||||
if err := parseArgs(call.Input, &args); err != nil {
|
||||
return fantasy.NewTextErrorResponse("pattern parameter is required"), nil
|
||||
@@ -79,11 +82,13 @@ func executeGrep(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolRespon
|
||||
|
||||
searchPath := "."
|
||||
if args.Path != "" {
|
||||
resolved, err := resolvePath(args.Path)
|
||||
resolved, err := resolvePathWithWorkDir(args.Path, workDir)
|
||||
if err != nil {
|
||||
return fantasy.NewTextErrorResponse(fmt.Sprintf("invalid path: %v", err)), nil
|
||||
}
|
||||
searchPath = resolved
|
||||
} else if workDir != "" {
|
||||
searchPath = workDir
|
||||
}
|
||||
|
||||
// Build ripgrep command
|
||||
|
||||
+9
-4
@@ -16,7 +16,8 @@ type lsArgs struct {
|
||||
}
|
||||
|
||||
// NewLsTool creates the ls core tool.
|
||||
func NewLsTool() fantasy.AgentTool {
|
||||
func NewLsTool(opts ...ToolOption) fantasy.AgentTool {
|
||||
cfg := ApplyOptions(opts)
|
||||
return &coreTool{
|
||||
info: fantasy.ToolInfo{
|
||||
Name: "ls",
|
||||
@@ -33,11 +34,13 @@ func NewLsTool() fantasy.AgentTool {
|
||||
},
|
||||
Required: []string{},
|
||||
},
|
||||
handler: executeLs,
|
||||
handler: func(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
return executeLs(ctx, call, cfg.WorkDir)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func executeLs(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
func executeLs(ctx context.Context, call fantasy.ToolCall, workDir string) (fantasy.ToolResponse, error) {
|
||||
var args lsArgs
|
||||
_ = parseArgs(call.Input, &args) // optional args
|
||||
|
||||
@@ -48,11 +51,13 @@ func executeLs(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse
|
||||
|
||||
dirPath := "."
|
||||
if args.Path != "" {
|
||||
resolved, err := resolvePath(args.Path)
|
||||
resolved, err := resolvePathWithWorkDir(args.Path, workDir)
|
||||
if err != nil {
|
||||
return fantasy.NewTextErrorResponse(fmt.Sprintf("invalid path: %v", err)), nil
|
||||
}
|
||||
dirPath = resolved
|
||||
} else if workDir != "" {
|
||||
dirPath = workDir
|
||||
}
|
||||
|
||||
info, err := os.Stat(dirPath)
|
||||
|
||||
+18
-10
@@ -17,7 +17,8 @@ type readArgs struct {
|
||||
}
|
||||
|
||||
// NewReadTool creates the read core tool.
|
||||
func NewReadTool() fantasy.AgentTool {
|
||||
func NewReadTool(opts ...ToolOption) fantasy.AgentTool {
|
||||
cfg := ApplyOptions(opts)
|
||||
return &coreTool{
|
||||
info: fantasy.ToolInfo{
|
||||
Name: "read",
|
||||
@@ -38,11 +39,13 @@ func NewReadTool() fantasy.AgentTool {
|
||||
},
|
||||
Required: []string{"path"},
|
||||
},
|
||||
handler: executeRead,
|
||||
handler: func(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
return executeRead(ctx, call, cfg.WorkDir)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func executeRead(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
func executeRead(ctx context.Context, call fantasy.ToolCall, workDir string) (fantasy.ToolResponse, error) {
|
||||
var args readArgs
|
||||
if err := parseArgs(call.Input, &args); err != nil {
|
||||
return fantasy.NewTextErrorResponse("path parameter is required"), nil
|
||||
@@ -51,7 +54,7 @@ func executeRead(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolRespon
|
||||
return fantasy.NewTextErrorResponse("path parameter is required"), nil
|
||||
}
|
||||
|
||||
absPath, err := resolvePath(args.Path)
|
||||
absPath, err := resolvePathWithWorkDir(args.Path, workDir)
|
||||
if err != nil {
|
||||
return fantasy.NewTextErrorResponse(fmt.Sprintf("invalid path: %v", err)), nil
|
||||
}
|
||||
@@ -131,14 +134,19 @@ func readDirectory(absPath string) (fantasy.ToolResponse, error) {
|
||||
return fantasy.NewTextResponse(tr.Content), nil
|
||||
}
|
||||
|
||||
// resolvePath resolves a path to an absolute path relative to cwd.
|
||||
func resolvePath(path string) (string, error) {
|
||||
// resolvePathWithWorkDir resolves a path to an absolute path relative to the
|
||||
// given workDir. If workDir is empty, os.Getwd() is used.
|
||||
func resolvePathWithWorkDir(path, workDir string) (string, error) {
|
||||
if filepath.IsAbs(path) {
|
||||
return filepath.Clean(path), nil
|
||||
}
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get working directory: %w", err)
|
||||
baseDir := workDir
|
||||
if baseDir == "" {
|
||||
var err error
|
||||
baseDir, err = os.Getwd()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get working directory: %w", err)
|
||||
}
|
||||
}
|
||||
return filepath.Clean(filepath.Join(cwd, path)), nil
|
||||
return filepath.Clean(filepath.Join(baseDir, path)), nil
|
||||
}
|
||||
|
||||
+43
-18
@@ -12,6 +12,31 @@ import (
|
||||
"charm.land/fantasy"
|
||||
)
|
||||
|
||||
// ToolOption configures tool behavior.
|
||||
type ToolOption func(*ToolConfig)
|
||||
|
||||
// ToolConfig holds configuration for tool construction.
|
||||
type ToolConfig struct {
|
||||
WorkDir string
|
||||
}
|
||||
|
||||
// WithWorkDir sets the working directory for file-based tools.
|
||||
// If empty, os.Getwd() is used at execution time.
|
||||
func WithWorkDir(dir string) ToolOption {
|
||||
return func(c *ToolConfig) {
|
||||
c.WorkDir = dir
|
||||
}
|
||||
}
|
||||
|
||||
// ApplyOptions applies the given ToolOptions to a ToolConfig and returns it.
|
||||
func ApplyOptions(opts []ToolOption) ToolConfig {
|
||||
var cfg ToolConfig
|
||||
for _, o := range opts {
|
||||
o(&cfg)
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
// coreTool is the base implementation for all core tools. It implements
|
||||
// the fantasy.AgentTool interface with typed parameters and direct execution.
|
||||
type coreTool struct {
|
||||
@@ -41,35 +66,35 @@ func parseArgs(input string, target any) error {
|
||||
|
||||
// CodingTools returns the default set of core tools for a coding agent:
|
||||
// bash, read, write, edit. This matches pi's codingTools collection.
|
||||
func CodingTools() []fantasy.AgentTool {
|
||||
func CodingTools(opts ...ToolOption) []fantasy.AgentTool {
|
||||
return []fantasy.AgentTool{
|
||||
NewBashTool(),
|
||||
NewReadTool(),
|
||||
NewWriteTool(),
|
||||
NewEditTool(),
|
||||
NewBashTool(opts...),
|
||||
NewReadTool(opts...),
|
||||
NewWriteTool(opts...),
|
||||
NewEditTool(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
// ReadOnlyTools returns tools for read-only exploration:
|
||||
// read, grep, find, ls. This matches pi's readOnlyTools collection.
|
||||
func ReadOnlyTools() []fantasy.AgentTool {
|
||||
func ReadOnlyTools(opts ...ToolOption) []fantasy.AgentTool {
|
||||
return []fantasy.AgentTool{
|
||||
NewReadTool(),
|
||||
NewGrepTool(),
|
||||
NewFindTool(),
|
||||
NewLsTool(),
|
||||
NewReadTool(opts...),
|
||||
NewGrepTool(opts...),
|
||||
NewFindTool(opts...),
|
||||
NewLsTool(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
// AllTools returns all available core tools.
|
||||
func AllTools() []fantasy.AgentTool {
|
||||
func AllTools(opts ...ToolOption) []fantasy.AgentTool {
|
||||
return []fantasy.AgentTool{
|
||||
NewBashTool(),
|
||||
NewReadTool(),
|
||||
NewWriteTool(),
|
||||
NewEditTool(),
|
||||
NewGrepTool(),
|
||||
NewFindTool(),
|
||||
NewLsTool(),
|
||||
NewBashTool(opts...),
|
||||
NewReadTool(opts...),
|
||||
NewWriteTool(opts...),
|
||||
NewEditTool(opts...),
|
||||
NewGrepTool(opts...),
|
||||
NewFindTool(opts...),
|
||||
NewLsTool(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ type writeArgs struct {
|
||||
}
|
||||
|
||||
// NewWriteTool creates the write core tool.
|
||||
func NewWriteTool() fantasy.AgentTool {
|
||||
func NewWriteTool(opts ...ToolOption) fantasy.AgentTool {
|
||||
cfg := ApplyOptions(opts)
|
||||
return &coreTool{
|
||||
info: fantasy.ToolInfo{
|
||||
Name: "write",
|
||||
@@ -32,11 +33,13 @@ func NewWriteTool() fantasy.AgentTool {
|
||||
},
|
||||
Required: []string{"path", "content"},
|
||||
},
|
||||
handler: executeWrite,
|
||||
handler: func(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
return executeWrite(ctx, call, cfg.WorkDir)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func executeWrite(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
|
||||
func executeWrite(ctx context.Context, call fantasy.ToolCall, workDir string) (fantasy.ToolResponse, error) {
|
||||
var args writeArgs
|
||||
if err := parseArgs(call.Input, &args); err != nil {
|
||||
return fantasy.NewTextErrorResponse("path and content parameters are required"), nil
|
||||
@@ -45,7 +48,7 @@ func executeWrite(ctx context.Context, call fantasy.ToolCall) (fantasy.ToolRespo
|
||||
return fantasy.NewTextErrorResponse("path parameter is required"), nil
|
||||
}
|
||||
|
||||
absPath, err := resolvePath(args.Path)
|
||||
absPath, err := resolvePathWithWorkDir(args.Path, workDir)
|
||||
if err != nil {
|
||||
return fantasy.NewTextErrorResponse(fmt.Sprintf("invalid path: %v", err)), nil
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ type Options struct {
|
||||
MaxSteps int // Override max steps (0 = use default)
|
||||
Streaming bool // Enable streaming (default from config)
|
||||
Quiet bool // Suppress debug output
|
||||
Tools []Tool // Custom tool set. If empty, AllTools() is used.
|
||||
}
|
||||
|
||||
// New creates a Kit instance using the same initialization as the CLI.
|
||||
@@ -72,6 +73,7 @@ func New(ctx context.Context, opts *Options) (*Kit, error) {
|
||||
agentResult, err := SetupAgent(ctx, AgentSetupOptions{
|
||||
MCPConfig: mcpConfig,
|
||||
Quiet: opts.Quiet,
|
||||
CoreTools: opts.Tools,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -178,6 +180,11 @@ func (m *Kit) GetModelString() string {
|
||||
return m.modelString
|
||||
}
|
||||
|
||||
// GetTools returns all tools available to the agent (core + MCP + extensions).
|
||||
func (m *Kit) GetTools() []Tool {
|
||||
return m.agent.GetTools()
|
||||
}
|
||||
|
||||
// Close cleans up resources including MCP server connections and model resources.
|
||||
// Should be called when the Kit instance is no longer needed. Returns an
|
||||
// error if cleanup fails.
|
||||
|
||||
@@ -28,6 +28,9 @@ type AgentSetupOptions struct {
|
||||
UseBufferedLogger bool
|
||||
// Quiet suppresses output. Replaces the cmd package's quietFlag variable.
|
||||
Quiet bool
|
||||
// CoreTools overrides the default core tool set. If empty, core.AllTools()
|
||||
// is used. Allows SDK users to pass custom tools (e.g. with WithWorkDir).
|
||||
CoreTools []fantasy.AgentTool
|
||||
}
|
||||
|
||||
// AgentSetupResult bundles the created agent and any debug logger so the caller
|
||||
@@ -113,6 +116,7 @@ func SetupAgent(ctx context.Context, opts AgentSetupOptions) (*AgentSetupResult,
|
||||
Quiet: opts.Quiet,
|
||||
SpinnerFunc: opts.SpinnerFunc,
|
||||
DebugLogger: debugLogger,
|
||||
CoreTools: opts.CoreTools,
|
||||
ToolWrapper: extCreationOpts.toolWrapper,
|
||||
ExtraTools: extCreationOpts.extraTools,
|
||||
})
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package kit
|
||||
|
||||
import (
|
||||
"charm.land/fantasy"
|
||||
|
||||
"github.com/mark3labs/kit/internal/core"
|
||||
)
|
||||
|
||||
// Tool is the interface that all Kit tools implement.
|
||||
type Tool = fantasy.AgentTool
|
||||
|
||||
// ToolOption configures tool behavior.
|
||||
type ToolOption = core.ToolOption
|
||||
|
||||
// WithWorkDir sets the working directory for file-based tools.
|
||||
// If empty, os.Getwd() is used at execution time.
|
||||
var WithWorkDir = core.WithWorkDir
|
||||
|
||||
// --- Individual tool constructors ---
|
||||
|
||||
// NewReadTool creates a file-reading tool.
|
||||
func NewReadTool(opts ...ToolOption) Tool { return core.NewReadTool(opts...) }
|
||||
|
||||
// NewWriteTool creates a file-writing tool.
|
||||
func NewWriteTool(opts ...ToolOption) Tool { return core.NewWriteTool(opts...) }
|
||||
|
||||
// NewEditTool creates a surgical text-editing tool.
|
||||
func NewEditTool(opts ...ToolOption) Tool { return core.NewEditTool(opts...) }
|
||||
|
||||
// NewBashTool creates a bash command execution tool.
|
||||
func NewBashTool(opts ...ToolOption) Tool { return core.NewBashTool(opts...) }
|
||||
|
||||
// NewGrepTool creates a content search tool (uses ripgrep when available).
|
||||
func NewGrepTool(opts ...ToolOption) Tool { return core.NewGrepTool(opts...) }
|
||||
|
||||
// NewFindTool creates a file search tool (uses fd when available).
|
||||
func NewFindTool(opts ...ToolOption) Tool { return core.NewFindTool(opts...) }
|
||||
|
||||
// NewLsTool creates a directory listing tool.
|
||||
func NewLsTool(opts ...ToolOption) Tool { return core.NewLsTool(opts...) }
|
||||
|
||||
// --- Tool bundles ---
|
||||
|
||||
// AllTools returns all available core tools.
|
||||
func AllTools(opts ...ToolOption) []Tool { return core.AllTools(opts...) }
|
||||
|
||||
// CodingTools returns the default set of core tools for a coding agent:
|
||||
// bash, read, write, edit.
|
||||
func CodingTools(opts ...ToolOption) []Tool { return core.CodingTools(opts...) }
|
||||
|
||||
// ReadOnlyTools returns tools for read-only exploration:
|
||||
// read, grep, find, ls.
|
||||
func ReadOnlyTools(opts ...ToolOption) []Tool { return core.ReadOnlyTools(opts...) }
|
||||
Reference in New Issue
Block a user