cmd

package
v0.9.2 Latest Latest
Warning

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

Go to latest
Published: Aug 15, 2026 License: MIT Imports: 16 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 RootCmd = &cli.Command{
	Name:        "llmrouter",
	Version:     build.Version,
	Usage:       "LLM Routing Service",
	Description: "Routes requests to different LLM providers based on configuration",
	ConfigFile: cli_toml.NewConfigFile(&configFile, func() []string {
		paths := []string{"."}
		if home, err := os.UserHomeDir(); err == nil {
			paths = append(paths, filepath.Join(home, ".llmrouter"))
			paths = append(paths, filepath.Join(home, ".config", "llmrouter"))
			paths = append(paths, filepath.Join(home, ".config"))
		}
		return paths
	}),
	Flags: append([]cli.Flag{
		&cli.StringFlag{
			Name:     "config",
			Aliases:  []string{"c"},
			Usage:    "Configuration file path",
			AssignTo: &configFile,
			Global:   true,
		},
		&cli.StringFlag{
			Name:         "log-level",
			Usage:        "Log level (trace|debug|info|warn|error)",
			DefaultValue: "info",
			ConfigPath:   []string{"logging.level"},
			Global:       true,
		},
		&cli.StringFlag{
			Name:         "log-format",
			Usage:        "Log format (console|json)",
			DefaultValue: "console",
			ConfigPath:   []string{"logging.format"},
			Global:       true,
		},
	}, ServerFlags()...),
	PreRun: func(ctx context.Context, cmd *cli.Command) (context.Context, error) {
		log.Configure(cmd.GetString("log-level"), cmd.GetString("log-format"))
		return ctx, nil
	},
	Commands: []*cli.Command{
		ServerCmd,
		ToolCmd,
		ModelsCmd,
		AskCmd,
	},
}

RootCmd is the top-level command. With no subcommand:

  • desktop builds (default) open the GUI window via RootCmd.Run (set by init() in root_desktop.go)
  • server builds (-tags server) show help (Run stays nil — the original behaviour before desktop support was added)

In both builds, `llmrouter server` explicitly starts the headless server.

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:       ServerFlags(),
	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

func ServerFlags added in v0.9.0

func ServerFlags() []cli.Flag

ServerFlags returns the flag set for the server. Shared between the `server` subcommand and the root command so that `llmrouter -p 8080` (desktop mode) and `llmrouter server -p 8080` (headless) accept the same options.

Types

This section is empty.

Jump to

Keyboard shortcuts

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