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 ¶
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.