Repository: GoogleCloudPlatform/kubectl-ai
File: pkg/tools/custom_tool.go (Go)

Code before:
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package tools

import (
	"context"
	"fmt"
	"os"
	"os/exec"

	"github.com/GoogleCloudPlatform/kubectl-ai/gollm"
)

// CustomToolConfig defines the structure for configuring a custom tool.
type CustomToolConfig struct {
	Name    string                    `yaml:"name"`
	FnDef   *gollm.FunctionDefinition `yaml:"fndef"`
	Command []string                  `yaml:"command"` // Command and args to execute
}

// CustomTool implements the Tool interface for external commands.
type CustomTool struct {
	config CustomToolConfig
}

// NewCustomTool creates a new CustomTool instance.
func NewCustomTool(config CustomToolConfig) (*CustomTool, error) {
	if config.Name == "" {
		return nil, fmt.Errorf("custom tool name cannot be empty")
	}
	if config.FnDef == nil {
		return nil, fmt.Errorf("custom tool function definition cannot be nil for tool %q", config.Name)
	}
	if len(config.Command) == 0 {
		return nil, fmt.Errorf("custom tool command cannot be empty for tool %q", config.Name)
	}
	config.FnDef.Name = config.Name

	return &CustomTool{config: config}, nil
}

// Name returns the tool's name.
func (t *CustomTool) Name() string {
	return t.config.Name
}


Review comment (suggestion):
would be great if you can share an example of what a real config look like say for `nomos` or `helm`

Better will be a quick screencast showing this in action to get a feel for the UX.

Code after:
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package tools

import (
	"context"
	"fmt"
	"os"
	"os/exec"
	"strings"

	"github.com/GoogleCloudPlatform/kubectl-ai/gollm"
)

// CustomToolConfig defines the structure for configuring a custom tool.
type CustomToolConfig struct {
	Name        string `yaml:"name"`
	Description string `yaml:"description"`
	Command     string `yaml:"command"`
	CommandDesc string `yaml:"command_desc"`
}

// CustomTool implements the Tool interface for external commands.
type CustomTool struct {
	config CustomToolConfig
}

// NewCustomTool creates a new CustomTool instance.
func NewCustomTool(config CustomToolConfig) (*CustomTool, error) {
	if config.Name == "" {
		return nil, fmt.Errorf("custom tool name cannot be empty")
	}
	if len(config.Command) == 0 {
		return nil, fmt.Errorf("custom tool command cannot be empty for tool %q", config.Name)
	}

	return &CustomTool{config: config}, nil
}

// Name returns the tool's name.
func (t *CustomTool) Name() string {
	return t.config.Name
}

// Description returns the tool's description from its function definition.
func (t *CustomTool) Description() string {