cmd

package
v0.5.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AskCmd = &cli.Command{
	Name:        "ask",
	Usage:       "Ask a model a question",
	Description: "Send a question to a specific model and display the JSON response",
	MaxArgs:     cli.UnlimitedArgs,
	Arguments: []cli.Argument{
		&cli.StringArg{
			Name:     "model",
			Required: true,
			Usage:    "Model to use",
		},
	},
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:         "server",
			Usage:        "Server URL",
			DefaultValue: "http://localhost:12345",
		},
		&cli.StringFlag{
			Name:    "token",
			Aliases: []string{"t"},
			Usage:   "Bearer token for server authentication",
		},
	},
	Run: func(ctx context.Context, cmd *cli.Command) error {
		model := cmd.GetStringArg("model")
		question := strings.Join(cmd.GetArgs(), " ")
		serverURL := cmd.GetString("server")
		token := cmd.GetString("token")

		if question == "" {
			return fmt.Errorf("question is required")
		}

		payload := map[string]any{
			"model": model,
			"messages": []map[string]string{
				{"role": "user", "content": question},
			},
		}
		body, err := json.Marshal(payload)
		if err != nil {
			return fmt.Errorf("failed to marshal request: %w", err)
		}

		client := &http.Client{Timeout: 120 * time.Second}
		req, err := http.NewRequest("POST", serverURL+"/v1/chat/completions", bytes.NewReader(body))
		if err != nil {
			return fmt.Errorf("failed to create request: %w", err)
		}
		req.Header.Set("Content-Type", "application/json")
		if token != "" {
			req.Header.Set("Authorization", "Bearer "+token)
		}

		resp, err := client.Do(req)
		if err != nil {
			return fmt.Errorf("request failed: %w", err)
		}
		defer resp.Body.Close()

		respBody, err := io.ReadAll(resp.Body)
		if err != nil {
			return fmt.Errorf("failed to read response: %w", err)
		}

		var out any
		if err := json.Unmarshal(respBody, &out); err != nil {
			return fmt.Errorf("failed to parse response: %w", err)
		}

		formatted, err := json.MarshalIndent(out, "", "  ")
		if err != nil {
			return fmt.Errorf("failed to format response: %w", err)
		}
		fmt.Println(string(formatted))
		return nil
	},
}
View Source
var ModelsCmd = &cli.Command{
	Name:        "models",
	Usage:       "List available models",
	Description: "List all models available from the LLM router",
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:         "server",
			Usage:        "Server URL",
			DefaultValue: "http://localhost:12345",
		},
		&cli.StringFlag{
			Name:    "token",
			Aliases: []string{"t"},
			Usage:   "Bearer token for server authentication",
		},
	},
	Run: func(ctx context.Context, cmd *cli.Command) error {
		serverURL := cmd.GetString("server")
		token := cmd.GetString("token")

		client := &http.Client{Timeout: 30 * time.Second}
		req, err := http.NewRequest("GET", serverURL+"/v1/models", nil)
		if err != nil {
			return fmt.Errorf("failed to create request: %w", err)
		}
		if token != "" {
			req.Header.Set("Authorization", "Bearer "+token)
		}

		resp, err := client.Do(req)
		if err != nil {
			return fmt.Errorf("request failed: %w", err)
		}
		defer resp.Body.Close()

		body, err := io.ReadAll(resp.Body)
		if err != nil {
			return fmt.Errorf("failed to read response: %w", err)
		}

		var out any
		if err := json.Unmarshal(body, &out); err != nil {
			return fmt.Errorf("failed to parse response: %w", err)
		}

		formatted, err := json.MarshalIndent(out, "", "  ")
		if err != nil {
			return fmt.Errorf("failed to format response: %w", err)
		}
		fmt.Println(string(formatted))
		return nil
	},
}
View Source
var ServerCmd = &cli.Command{
	Name:        "server",
	Usage:       "Start the LLM router server",
	Description: "Start the LLM router server with MCP and OpenAI API endpoints",
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:         "host",
			Aliases:      []string{"H"},
			Usage:        "Host to bind to",
			DefaultValue: "0.0.0.0",
			ConfigPath:   []string{"server.host"},
		},
		&cli.IntFlag{
			Name:         "port",
			Aliases:      []string{"p"},
			Usage:        "Port to bind to",
			DefaultValue: 12345,
			ConfigPath:   []string{"server.port"},
		},
		&cli.StringFlag{
			Name:       "token",
			Aliases:    []string{"t"},
			Usage:      "Bearer token for API authentication",
			ConfigPath: []string{"server.token"},
		},
		&cli.StringFlag{
			Name:       "admin-password",
			Usage:      "Password for admin UI (if set, enables admin UI at /admin)",
			ConfigPath: []string{"server.admin_password"},
		},
		&cli.StringFlag{
			Name:       "storage-path",
			Usage:      "Path for persistent storage (omit for memory-only)",
			ConfigPath: []string{"server.storage_path"},
		},
		&cli.IntFlag{
			Name:         "responses-ttl",
			Usage:        "Maximum age of a response in days",
			ConfigPath:   []string{"responses.ttl_days"},
			DefaultValue: 30,
		},
		&cli.IntFlag{
			Name:         "conversations-ttl",
			Usage:        "Maximum age of a conversation in days",
			ConfigPath:   []string{"conversations.ttl_days"},
			DefaultValue: 30,
		},
		&cli.BoolFlag{
			Name:       "smart-routing",
			Usage:      "Enable smart routing",
			ConfigPath: []string{"smart_routing.enabled"},
		},
		&cli.StringFlag{
			Name:       "router-script",
			Usage:      "Path to the smart routing script",
			ConfigPath: []string{"smart_routing.script"},
		},
		&cli.StringFlag{
			Name:       "router-libdir",
			Usage:      "Directory of .py script libraries auto-loaded into every routing VM",
			ConfigPath: []string{"smart_routing.libdir"},
		},
		&cli.StringFlag{
			Name:       "router-default-model",
			Usage:      "Default model when smart routing returns nothing",
			ConfigPath: []string{"smart_routing.default_model"},
		},
		&cli.StringFlag{
			Name:       "tools-dir",
			Usage:      "Directory containing scriptling tool definitions (.toml/.py pairs)",
			ConfigPath: []string{"scripting.tools_dir"},
		},
		&cli.StringFlag{
			Name:       "resources-dir",
			Usage:      "Directory containing scriptling MCP resources (static files and {var}.py templates)",
			ConfigPath: []string{"scripting.resources_dir"},
		},
		&cli.StringFlag{
			Name:       "prompts-dir",
			Usage:      "Directory containing scriptling MCP prompts (.toml+.py dynamic, or .md/.txt static)",
			ConfigPath: []string{"scripting.prompts_dir"},
		},
		&cli.StringSliceFlag{
			Name:       "plugin-dir",
			Usage:      "Directory containing scriptling plugin executables (can be repeated)",
			ConfigPath: []string{"scripting.plugin_dirs"},
		},
		&cli.StringSliceFlag{
			Name:       "libpath",
			Usage:      "Additional directories to search for scriptling libraries (can be repeated)",
			ConfigPath: []string{"scripting.lib_paths"},
		},
		&cli.StringFlag{
			Name:       "personas-dir",
			Usage:      "Directory of chat persona .toml files (system_prompt, default_model, [params] table)",
			ConfigPath: []string{"chat.personas_dir"},
		},
		&cli.StringFlag{
			Name:       "commands-dir",
			Usage:      "Directory of slash-command .md files (use $ARGUMENTS to splice user input)",
			ConfigPath: []string{"chat.commands_dir"},
		},
	},
	Run: func(ctx context.Context, cmd *cli.Command) error {
		return server.RunServer(ctx, cmd)
	},
}
View Source
var ToolCmd = &cli.Command{
	Name:        "tool",
	Usage:       "Execute a tool via the MCP server",
	Description: "Execute a specific tool through the MCP server",
	Arguments: []cli.Argument{
		&cli.StringArg{
			Name:     "toolname",
			Required: true,
			Usage:    "Name of the tool to execute",
		},
		&cli.StringArg{
			Name:     "arguments",
			Required: false,
			Usage:    "JSON arguments for the tool (optional)",
		},
	},
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:         "server",
			Usage:        "MCP server URL",
			DefaultValue: "http://localhost:12345",
		},
		&cli.BoolFlag{
			Name:         "verbose",
			Aliases:      []string{"v"},
			Usage:        "Enable verbose output",
			DefaultValue: false,
		},
		&cli.StringFlag{
			Name:    "token",
			Aliases: []string{"t"},
			Usage:   "Bearer token for server authentication",
		},
	},
	Run: func(ctx context.Context, cmd *cli.Command) error {
		toolName := cmd.GetStringArg("toolname")
		argsStr := cmd.GetStringArg("arguments")
		serverURL := cmd.GetString("server")
		verbose := cmd.GetBool("verbose")
		token := cmd.GetString("token")

		var toolArgs map[string]interface{}
		if argsStr != "" {
			if err := json.Unmarshal([]byte(argsStr), &toolArgs); err != nil {
				return fmt.Errorf("error parsing arguments: %w\nHint: Quote your JSON string properly", err)
			}
		}

		if verbose {
			log.GetLogger().Debug("executing tool", "tool", toolName, "args", toolArgs)
		}

		var request map[string]interface{}
		if serverTools[toolName] {
			request = map[string]interface{}{
				"jsonrpc": "2.0",
				"id":      1,
				"method":  "tools/call",
				"params": map[string]interface{}{
					"name":      toolName,
					"arguments": toolArgs,
				},
			}
		} else {
			request = map[string]interface{}{
				"jsonrpc": "2.0",
				"id":      1,
				"method":  "tools/call",
				"params": map[string]interface{}{
					"name": "execute_tool",
					"arguments": map[string]interface{}{
						"name":      toolName,
						"arguments": toolArgs,
					},
				},
			}
		}

		return ExecuteMCPRequest(serverURL, request, token, verbose)
	},
}

Functions

func ExecuteMCPRequest

func ExecuteMCPRequest(serverURL string, request map[string]interface{}, token string, verbose bool) error

ExecuteMCPRequest sends an MCP request and processes the response

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL