Skip to content

Commit

Permalink
🎨 Use ToJsonSchema from glalzed now and the new command layers
Browse files Browse the repository at this point in the history
  • Loading branch information
wesen committed Feb 16, 2025
1 parent 10e51ca commit 294b4da
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 194 deletions.
18 changes: 17 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -1047,4 +1047,20 @@ Added server-side tool management commands for direct interaction with tool prov

- Added `server tools list` command to list available tools directly from tool provider
- Added `server tools call` command to call tools directly without starting the server
- Reused server layer for configuration consistency
- Reused server layer for configuration consistency

## Add Minimal Glazed Command Layer

Added a minimal version of the Glazed command layer (NewGlazedMinimalCommandLayer) that contains just the most commonly used parameters: print-yaml, print-parsed-parameters, load-parameters-from-file, and print-schema. This provides a simpler interface for basic command configuration.

- Added GlazedMinimalCommandSlug constant
- Added NewGlazedMinimalCommandLayer function

## Enhanced Glazed Command Layer Handling

Updated cobra command handling to support both full and minimal Glazed command layers:

- Added support for GlazedMinimalCommandLayer in cobra command processing
- Unified handling of common flags (print-yaml, print-parsed-parameters, etc.) between both layers
- Maintained backward compatibility with full GlazedCommandLayer features
- Added placeholder for schema printing functionality
2 changes: 1 addition & 1 deletion cmd/go-go-mcp/cmds/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (c *SchemaCommand) RunIntoWriter(
}

// Convert to JSON schema
schema, err := mcp_cmds.ToJsonSchema(shellCmd.Description())
schema, err := shellCmd.Description().ToJsonSchema()
if err != nil {
return fmt.Errorf("could not convert to JSON schema: %w", err)
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/go-go-mcp/cmds/server/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,13 @@ func init() {
listCmd, err := NewListToolsCommand()
cobra.CheckErr(err)

cobraListCmd, err := cli.BuildCobraCommandFromGlazeCommand(listCmd, cli.WithSkipGlazedCommandLayer())
cobraListCmd, err := cli.BuildCobraCommandFromGlazeCommand(listCmd)
cobra.CheckErr(err)

callCmd, err := NewCallToolCommand()
cobra.CheckErr(err)

cobraCallCmd, err := cli.BuildCobraCommandFromWriterCommand(callCmd, cli.WithSkipGlazedCommandLayer())
cobraCallCmd, err := cli.BuildCobraCommandFromWriterCommand(callCmd)
cobra.CheckErr(err)

ToolsCmd.AddCommand(cobraListCmd)
Expand Down
4 changes: 2 additions & 2 deletions cmd/go-go-mcp/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,14 @@ func initRootCmd() (*help.HelpSystem, error) {
// Create and add start command
startCmd, err := mcp_cmds.NewStartCommand()
cobra.CheckErr(err)
cobraStartCmd, err := cli.BuildCobraCommandFromBareCommand(startCmd, cli.WithSkipGlazedCommandLayer())
cobraStartCmd, err := cli.BuildCobraCommandFromBareCommand(startCmd)
cobra.CheckErr(err)
rootCmd.AddCommand(cobraStartCmd)

// Create and add schema command
schemaCmd, err := mcp_cmds.NewSchemaCommand()
cobra.CheckErr(err)
cobraSchemaCmd, err := cli.BuildCobraCommandFromWriterCommand(schemaCmd, cli.WithSkipGlazedCommandLayer())
cobraSchemaCmd, err := cli.BuildCobraCommandFromWriterCommand(schemaCmd)
cobra.CheckErr(err)
rootCmd.AddCommand(cobraSchemaCmd)

Expand Down
186 changes: 0 additions & 186 deletions pkg/cmds/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,189 +246,3 @@ func LoadShellCommandFromYAML(data []byte) (*ShellCommand, error) {
WithCaptureStderr(desc.CaptureStderr),
)
}

// JsonSchemaProperty represents a property in the JSON Schema
type JsonSchemaProperty struct {
Type string `json:"type"`
Description string `json:"description,omitempty"`
Enum []string `json:"enum,omitempty"`
Default interface{} `json:"default,omitempty"`
Items *JsonSchemaProperty `json:"items,omitempty"`
Required bool `json:"-"`
Properties map[string]*JsonSchemaProperty `json:"properties,omitempty"`
AdditionalProperties *JsonSchemaProperty `json:"additionalProperties,omitempty"`
}

// CommandJsonSchema represents the root JSON Schema for a command
type CommandJsonSchema struct {
Type string `json:"type"`
Description string `json:"description,omitempty"`
Properties map[string]*JsonSchemaProperty `json:"properties"`
Required []string `json:"required,omitempty"`
}

// parameterTypeToJsonSchema converts a parameter definition to a JSON schema property
func parameterTypeToJsonSchema(param *parameters.ParameterDefinition) (*JsonSchemaProperty, error) {
prop := &JsonSchemaProperty{
Description: param.Help,
Required: param.Required,
}

if param.Default != nil {
prop.Default = *param.Default
}

switch param.Type {
// Basic types
case parameters.ParameterTypeString:
prop.Type = "string"

case parameters.ParameterTypeInteger:
prop.Type = "integer"

case parameters.ParameterTypeFloat:
prop.Type = "number"

case parameters.ParameterTypeBool:
prop.Type = "boolean"

case parameters.ParameterTypeDate:
prop.Type = "string"
// Add format for date strings
prop.Properties = map[string]*JsonSchemaProperty{
"format": {Type: "string", Default: "date"},
}

// List types
case parameters.ParameterTypeStringList:
prop.Type = "array"
prop.Items = &JsonSchemaProperty{Type: "string"}

case parameters.ParameterTypeIntegerList:
prop.Type = "array"
prop.Items = &JsonSchemaProperty{Type: "integer"}

case parameters.ParameterTypeFloatList:
prop.Type = "array"
prop.Items = &JsonSchemaProperty{Type: "number"}

// Choice types
case parameters.ParameterTypeChoice:
prop.Type = "string"
prop.Enum = param.Choices

case parameters.ParameterTypeChoiceList:
prop.Type = "array"
prop.Items = &JsonSchemaProperty{Type: "string"}
prop.Items.Enum = param.Choices

// File types
case parameters.ParameterTypeFile:
prop.Type = "object"
prop.Properties = map[string]*JsonSchemaProperty{
"path": {Type: "string", Description: "Path to the file"},
"content": {Type: "string", Description: "File content"},
}

case parameters.ParameterTypeFileList:
prop.Type = "array"
prop.Items = &JsonSchemaProperty{
Type: "object",
Properties: map[string]*JsonSchemaProperty{
"path": {Type: "string", Description: "Path to the file"},
"content": {Type: "string", Description: "File content"},
},
}

// Key-value type
case parameters.ParameterTypeKeyValue:
prop.Type = "object"
prop.Properties = map[string]*JsonSchemaProperty{
"key": {Type: "string"},
"value": {Type: "string"},
}

// File-based parameter types
case parameters.ParameterTypeStringFromFile:
prop.Type = "string"

case parameters.ParameterTypeStringFromFiles:
prop.Type = "array"
prop.Items = &JsonSchemaProperty{Type: "string"}

case parameters.ParameterTypeObjectFromFile:
prop.Type = "object"
prop.AdditionalProperties = &JsonSchemaProperty{Type: "string"}

case parameters.ParameterTypeObjectListFromFile:
prop.Type = "array"
prop.Items = &JsonSchemaProperty{
Type: "object",
AdditionalProperties: &JsonSchemaProperty{Type: "string"},
}

case parameters.ParameterTypeObjectListFromFiles:
prop.Type = "array"
prop.Items = &JsonSchemaProperty{
Type: "object",
AdditionalProperties: &JsonSchemaProperty{Type: "string"},
}

case parameters.ParameterTypeStringListFromFile:
prop.Type = "array"
prop.Items = &JsonSchemaProperty{Type: "string"}

case parameters.ParameterTypeStringListFromFiles:
prop.Type = "array"
prop.Items = &JsonSchemaProperty{Type: "string"}

default:
return nil, fmt.Errorf("unsupported parameter type: %s", param.Type)
}

return prop, nil
}

// ToJsonSchema converts a ShellCommand to a JSON Schema representation
func ToJsonSchema(desc *cmds.CommandDescription) (*CommandJsonSchema, error) {
schema := &CommandJsonSchema{
Type: "object",
Description: fmt.Sprintf("%s\n\n%s", desc.Short, desc.Long),
Properties: make(map[string]*JsonSchemaProperty),
Required: []string{},
}

// Process flags
err := desc.GetDefaultFlags().ForEachE(func(flag *parameters.ParameterDefinition) error {
prop, err := parameterTypeToJsonSchema(flag)
if err != nil {
return fmt.Errorf("error processing flag %s: %w", flag.Name, err)
}
schema.Properties[flag.Name] = prop
if flag.Required {
schema.Required = append(schema.Required, flag.Name)
}
return nil
})
if err != nil {
return nil, err
}

// Process arguments
err = desc.GetDefaultArguments().ForEachE(func(arg *parameters.ParameterDefinition) error {
prop, err := parameterTypeToJsonSchema(arg)
if err != nil {
return fmt.Errorf("error processing argument %s: %w", arg.Name, err)
}
schema.Properties[arg.Name] = prop
if arg.Required {
schema.Required = append(schema.Required, arg.Name)
}
return nil
})
if err != nil {
return nil, err
}

return schema, nil
}
2 changes: 1 addition & 1 deletion pkg/cmds/shell-tool-provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (p *ShellToolProvider) ListTools(cursor string) ([]protocol.Tool, string, e

for _, cmd := range p.commands {
desc := cmd.Description()
schema, err := ToJsonSchema(desc)
schema, err := desc.ToJsonSchema()
if err != nil {
return nil, "", errors.Wrap(err, "failed to generate JSON schema")
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/tools/providers/config-provider/tool-provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func NewConfigToolProvider(options ...ConfigToolProviderOption) (*ConfigToolProv
}

func ConvertCommandToTool(desc *cmds.CommandDescription) (protocol.Tool, error) {
schema_, err := mcp_cmds.ToJsonSchema(desc)
schema_, err := desc.ToJsonSchema()
if err != nil {
return protocol.Tool{}, errors.Wrapf(err, "failed to convert command to schema")
}
Expand Down

0 comments on commit 294b4da

Please sign in to comment.