@@ -13,6 +13,7 @@ import (
13 "github.com/charmbracelet/catwalk/pkg/catwalk"
13 "github.com/charmbracelet/catwalk/pkg/catwalk"
14 "github.com/charmbracelet/crush/internal/csync"
14 "github.com/charmbracelet/crush/internal/csync"
15 "github.com/charmbracelet/crush/internal/env"
15 "github.com/charmbracelet/crush/internal/env"
16+ "github.com/invopop/jsonschema"
16 "github.com/tidwall/sjson"
17 "github.com/tidwall/sjson"
@@ -45,51 +46,61 @@ const (
45 SelectedModelTypeSmall SelectedModelType = "small"
46 SelectedModelTypeSmall SelectedModelType = "small"
49+// JSONSchema returns the JSON schema for SelectedModelType
50+func (SelectedModelType) JSONSchema() *jsonschema.Schema {
51+ return &jsonschema.Schema{
53+ Description: "Model type selection for different use cases",
54+ Enum: []any{"large", "small"},
48type SelectedModel struct {
59type SelectedModel struct {
49 // The model id as used by the provider API.
60 // The model id as used by the provider API.
50 // Required.
61 // Required.
51− Model string `json:"model"`
62+ Model string `json:"model" jsonschema:"required,description=The model ID as used by the provider API,example=gpt-4o"`
52 // The model provider, same as the key/id used in the providers config.
63 // The model provider, same as the key/id used in the providers config.
53 // Required.
64 // Required.
54− Provider string `json:"provider"`
65+ Provider string `json:"provider" jsonschema:"required,description=The model provider ID that matches a key in the providers config,example=openai"`
56 // Only used by models that use the openai provider and need this set.
67 // Only used by models that use the openai provider and need this set.
57− ReasoningEffort string `json:"reasoning_effort,omitempty"`
68+ ReasoningEffort string `json:"reasoning_effort,omitempty" jsonschema:"description=Reasoning effort level for OpenAI models that support it,enum=low,enum=medium,enum=high"`
59 // Overrides the default model configuration.
70 // Overrides the default model configuration.
60− MaxTokens int64 `json:"max_tokens,omitempty"`
71+ MaxTokens int64 `json:"max_tokens,omitempty" jsonschema:"description=Maximum number of tokens for model responses,minimum=1,maximum=200000,example=4096"`
62 // Used by anthropic models that can reason to indicate if the model should think.
73 // Used by anthropic models that can reason to indicate if the model should think.
63− Think bool `json:"think,omitempty"`
74+ Think bool `json:"think,omitempty" jsonschema:"description=Enable thinking mode for Anthropic models that support reasoning"`
66type ProviderConfig struct {
77type ProviderConfig struct {
67 // The provider's id.
78 // The provider's id.
68− ID string `json:"id,omitempty"`
79+ ID string `json:"id,omitempty" jsonschema:"description=Unique identifier for the provider,example=openai"`
69 // The provider's name, used for display purposes.
80 // The provider's name, used for display purposes.
70− Name string `json:"name,omitempty"`
81+ Name string `json:"name,omitempty" jsonschema:"description=Human-readable name for the provider,example=OpenAI"`
71 // The provider's API endpoint.
82 // The provider's API endpoint.
72− BaseURL string `json:"base_url,omitempty"`
83+ BaseURL string `json:"base_url,omitempty" jsonschema:"description=Base URL for the provider's API,format=uri,example=https://api.openai.com/v1"`
73 // The provider type, e.g. "openai", "anthropic", etc. if empty it defaults to openai.
84 // The provider type, e.g. "openai", "anthropic", etc. if empty it defaults to openai.
74− Type catwalk.Type `json:"type,omitempty"`
85+ Type catwalk.Type `json:"type,omitempty" jsonschema:"description=Provider type that determines the API format,enum=openai,enum=anthropic,enum=gemini,enum=azure,enum=vertexai,default=openai"`
75 // The provider's API key.
86 // The provider's API key.
76− APIKey string `json:"api_key,omitempty"`
87+ APIKey string `json:"api_key,omitempty" jsonschema:"description=API key for authentication with the provider,example=$OPENAI_API_KEY"`
77 // Marks the provider as disabled.
88 // Marks the provider as disabled.
78− Disable bool `json:"disable,omitempty"`
89+ Disable bool `json:"disable,omitempty" jsonschema:"description=Whether this provider is disabled,default=false"`
80 // Custom system prompt prefix.
91 // Custom system prompt prefix.
81− SystemPromptPrefix string `json:"system_prompt_prefix,omitempty"`
92+ SystemPromptPrefix string `json:"system_prompt_prefix,omitempty" jsonschema:"description=Custom prefix to add to system prompts for this provider"`
83 // Extra headers to send with each request to the provider.
94 // Extra headers to send with each request to the provider.
84− ExtraHeaders map[string]string `json:"extra_headers,omitempty"`
95+ ExtraHeaders map[string]string `json:"extra_headers,omitempty" jsonschema:"description=Additional HTTP headers to send with requests"`
85 // Extra body
96 // Extra body
86− ExtraBody map[string]any `json:"extra_body,omitempty"`
97+ ExtraBody map[string]any `json:"extra_body,omitempty" jsonschema:"description=Additional fields to include in request bodies"`
88 // Used to pass extra parameters to the provider.
99 // Used to pass extra parameters to the provider.
89 ExtraParams map[string]string `json:"-"`
100 ExtraParams map[string]string `json:"-"`
91 // The provider models
102 // The provider models
92− Models []catwalk.Model `json:"models,omitempty"`
103+ Models []catwalk.Model `json:"models,omitempty" jsonschema:"description=List of models available from this provider"`
95type MCPType string
106type MCPType string
@@ -100,42 +111,52 @@ const (
100 MCPHttp MCPType = "http"
111 MCPHttp MCPType = "http"
114+// JSONSchema returns the JSON schema for MCPType
115+func (MCPType) JSONSchema() *jsonschema.Schema {
116+ return &jsonschema.Schema{
118+ Description: "Type of MCP connection protocol",
119+ Enum: []any{"stdio", "sse", "http"},
103type MCPConfig struct {
124type MCPConfig struct {
104− Command string `json:"command,omitempty" `
125+ Command string `json:"command,omitempty" jsonschema:"description=Command to execute for stdio MCP servers,example=npx"`
105− Env map[string]string `json:"env,omitempty"`
126+ Env map[string]string `json:"env,omitempty" jsonschema:"description=Environment variables to set for the MCP server"`
106− Args []string `json:"args,omitempty"`
127+ Args []string `json:"args,omitempty" jsonschema:"description=Arguments to pass to the MCP server command"`
107− Type MCPType `json:"type"`
128+ Type MCPType `json:"type" jsonschema:"required,description=Type of MCP connection,enum=stdio,enum=sse,enum=http,default=stdio"`
108− URL string `json:"url,omitempty"`
129+ URL string `json:"url,omitempty" jsonschema:"description=URL for HTTP or SSE MCP servers,format=uri,example=http://localhost:3000/mcp"`
109− Disabled bool `json:"disabled,omitempty"`
130+ Disabled bool `json:"disabled,omitempty" jsonschema:"description=Whether this MCP server is disabled,default=false"`
111 // TODO: maybe make it possible to get the value from the env
132 // TODO: maybe make it possible to get the value from the env
112− Headers map[string]string `json:"headers,omitempty"`
133+ Headers map[string]string `json:"headers,omitempty" jsonschema:"description=HTTP headers for HTTP/SSE MCP servers"`
115type LSPConfig struct {
136type LSPConfig struct {
116− Disabled bool `json:"enabled,omitempty"`
137+ Disabled bool `json:"enabled,omitempty" jsonschema:"description=Whether this LSP server is disabled,default=false"`
117− Command string `json:"command"`
138+ Command string `json:"command" jsonschema:"required,description=Command to execute for the LSP server,example=gopls"`
118− Args []string `json:"args,omitempty"`
139+ Args []string `json:"args,omitempty" jsonschema:"description=Arguments to pass to the LSP server command"`
119− Options any `json:"options,omitempty"`
140+ Options any `json:"options,omitempty" jsonschema:"description=LSP server-specific configuration options"`
122type TUIOptions struct {
143type TUIOptions struct {
123− CompactMode bool `json:"compact_mode,omitempty"`
144+ CompactMode bool `json:"compact_mode,omitempty" jsonschema:"description=Enable compact mode for the TUI interface,default=false"`
124 // Here we can add themes later or any TUI related options
145 // Here we can add themes later or any TUI related options
127type Permissions struct {
148type Permissions struct {
128− AllowedTools []string `json:"allowed_tools,omitempty"` // Tools that don't require permission prompts
149+ AllowedTools []string `json:"allowed_tools,omitempty" jsonschema:"description=List of tools that don't require permission prompts,example=bash,example=view"` // Tools that don't require permission prompts
129− SkipRequests bool `json:"-"` // Automatically accept all permissions (YOLO mode)
150+ SkipRequests bool `json:"-"` // Automatically accept all permissions (YOLO mode)
132type Options struct {
153type Options struct {
133− ContextPaths []string `json:"context_paths,omitempty"`
154+ ContextPaths []string `json:"context_paths,omitempty" jsonschema:"description=Paths to files containing context information for the AI,example=.cursorrules,example=CRUSH.md"`
134− TUI *TUIOptions `json:"tui,omitempty"`
155+ TUI *TUIOptions `json:"tui,omitempty" jsonschema:"description=Terminal user interface options"`
135− Debug bool `json:"debug,omitempty"`
156+ Debug bool `json:"debug,omitempty" jsonschema:"description=Enable debug logging,default=false"`
136− DebugLSP bool `json:"debug_lsp,omitempty"`
157+ DebugLSP bool `json:"debug_lsp,omitempty" jsonschema:"description=Enable debug logging for LSP servers,default=false"`
137− DisableAutoSummarize bool `json:"disable_auto_summarize,omitempty"`
158+ DisableAutoSummarize bool `json:"disable_auto_summarize,omitempty" jsonschema:"description=Disable automatic conversation summarization,default=false"`
138− DataDirectory string `json:"data_directory,omitempty"` // Relative to the cwd
159+ DataDirectory string `json:"data_directory,omitempty" jsonschema:"description=Directory for storing application data (relative to working directory),default=.crush,example=.crush"` // Relative to the cwd
141type MCPs map[string]MCPConfig
162type MCPs map[string]MCPConfig
@@ -241,18 +262,18 @@ type Agent struct {
241// Config holds the configuration for crush.
262// Config holds the configuration for crush.
242type Config struct {
263type Config struct {
243 // We currently only support large/small as values here.
264 // We currently only support large/small as values here.
244− Models map[SelectedModelType]SelectedModel `json:"models,omitempty"`
265+ Models map[SelectedModelType]SelectedModel `json:"models,omitempty" jsonschema:"description=Model configurations for different model types,example={\"large\":{\"model\":\"gpt-4o\",\"provider\":\"openai\"}}"`
246 // The providers that are configured
267 // The providers that are configured
247− Providers *csync.Map[string, ProviderConfig] `json:"providers,omitempty"`
268+ Providers *csync.Map[string, ProviderConfig] `json:"providers,omitempty" jsonschema:"description=AI provider configurations"`
249− MCP MCPs `json:"mcp,omitempty"`
270+ MCP MCPs `json:"mcp,omitempty" jsonschema:"description=Model Context Protocol server configurations"`
251− LSP LSPs `json:"lsp,omitempty"`
272+ LSP LSPs `json:"lsp,omitempty" jsonschema:"description=Language Server Protocol configurations"`
253− Options *Options `json:"options,omitempty"`
274+ Options *Options `json:"options,omitempty" jsonschema:"description=General application options"`
255− Permissions *Permissions `json:"permissions,omitempty"`
276+ Permissions *Permissions `json:"permissions,omitempty" jsonschema:"description=Permission settings for tool usage"`
257 // Internal
278 // Internal
258 workingDir string `json:"-"`
279 workingDir string `json:"-"`