mirror of
https://github.com/lordmathis/llamactl.git
synced 2025-11-05 16:44:22 +00:00
Refactor command parsing
This commit is contained in:
@@ -18,6 +18,17 @@ type ParseCommandRequest struct {
|
|||||||
Command string `json:"command"`
|
Command string `json:"command"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type errorResponse struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
Details string `json:"details,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeError(w http.ResponseWriter, status int, code, details string) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(status)
|
||||||
|
_ = json.NewEncoder(w).Encode(errorResponse{Error: code, Details: details})
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handler) LlamaCppProxy(onDemandStart bool) http.HandlerFunc {
|
func (h *Handler) LlamaCppProxy(onDemandStart bool) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
@@ -98,6 +109,31 @@ func (h *Handler) LlamaCppProxy(onDemandStart bool) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseHelper parses a backend command and returns the parsed options
|
||||||
|
func parseHelper(w http.ResponseWriter, r *http.Request, backend interface {
|
||||||
|
ParseCommand(string) (any, error)
|
||||||
|
}) (any, bool) {
|
||||||
|
var req ParseCommandRequest
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
|
writeError(w, http.StatusBadRequest, "invalid_request", "Invalid JSON body")
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.TrimSpace(req.Command) == "" {
|
||||||
|
writeError(w, http.StatusBadRequest, "invalid_command", "Command cannot be empty")
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse command using the backend's ParseCommand method
|
||||||
|
parsedOptions, err := backend.ParseCommand(req.Command)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, http.StatusBadRequest, "parse_error", err.Error())
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedOptions, true
|
||||||
|
}
|
||||||
|
|
||||||
// ParseLlamaCommand godoc
|
// ParseLlamaCommand godoc
|
||||||
// @Summary Parse llama-server command
|
// @Summary Parse llama-server command
|
||||||
// @Description Parses a llama-server command string into instance options
|
// @Description Parses a llama-server command string into instance options
|
||||||
@@ -111,36 +147,19 @@ func (h *Handler) LlamaCppProxy(onDemandStart bool) http.HandlerFunc {
|
|||||||
// @Failure 500 {object} map[string]string "Internal Server Error"
|
// @Failure 500 {object} map[string]string "Internal Server Error"
|
||||||
// @Router /backends/llama-cpp/parse-command [post]
|
// @Router /backends/llama-cpp/parse-command [post]
|
||||||
func (h *Handler) ParseLlamaCommand() http.HandlerFunc {
|
func (h *Handler) ParseLlamaCommand() http.HandlerFunc {
|
||||||
type errorResponse struct {
|
|
||||||
Error string `json:"error"`
|
|
||||||
Details string `json:"details,omitempty"`
|
|
||||||
}
|
|
||||||
writeError := func(w http.ResponseWriter, status int, code, details string) {
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.WriteHeader(status)
|
|
||||||
_ = json.NewEncoder(w).Encode(errorResponse{Error: code, Details: details})
|
|
||||||
}
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var req ParseCommandRequest
|
parsedOptions, ok := parseHelper(w, r, &backends.LlamaServerOptions{})
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if !ok {
|
||||||
writeError(w, http.StatusBadRequest, "invalid_request", "Invalid JSON body")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if strings.TrimSpace(req.Command) == "" {
|
|
||||||
writeError(w, http.StatusBadRequest, "invalid_command", "Command cannot be empty")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
llamaOptions, err := backends.ParseLlamaCommand(req.Command)
|
|
||||||
if err != nil {
|
|
||||||
writeError(w, http.StatusBadRequest, "parse_error", err.Error())
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
options := &instance.Options{
|
options := &instance.Options{
|
||||||
BackendOptions: backends.Options{
|
BackendOptions: backends.Options{
|
||||||
BackendType: backends.BackendTypeLlamaCpp,
|
BackendType: backends.BackendTypeLlamaCpp,
|
||||||
LlamaServerOptions: llamaOptions,
|
LlamaServerOptions: parsedOptions.(*backends.LlamaServerOptions),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
if err := json.NewEncoder(w).Encode(options); err != nil {
|
if err := json.NewEncoder(w).Encode(options); err != nil {
|
||||||
writeError(w, http.StatusInternalServerError, "encode_error", err.Error())
|
writeError(w, http.StatusInternalServerError, "encode_error", err.Error())
|
||||||
@@ -160,40 +179,16 @@ func (h *Handler) ParseLlamaCommand() http.HandlerFunc {
|
|||||||
// @Failure 400 {object} map[string]string "Invalid request or command"
|
// @Failure 400 {object} map[string]string "Invalid request or command"
|
||||||
// @Router /backends/mlx/parse-command [post]
|
// @Router /backends/mlx/parse-command [post]
|
||||||
func (h *Handler) ParseMlxCommand() http.HandlerFunc {
|
func (h *Handler) ParseMlxCommand() http.HandlerFunc {
|
||||||
type errorResponse struct {
|
|
||||||
Error string `json:"error"`
|
|
||||||
Details string `json:"details,omitempty"`
|
|
||||||
}
|
|
||||||
writeError := func(w http.ResponseWriter, status int, code, details string) {
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.WriteHeader(status)
|
|
||||||
_ = json.NewEncoder(w).Encode(errorResponse{Error: code, Details: details})
|
|
||||||
}
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var req ParseCommandRequest
|
parsedOptions, ok := parseHelper(w, r, &backends.MlxServerOptions{})
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if !ok {
|
||||||
writeError(w, http.StatusBadRequest, "invalid_request", "Invalid JSON body")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(req.Command) == "" {
|
|
||||||
writeError(w, http.StatusBadRequest, "invalid_command", "Command cannot be empty")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
mlxOptions, err := backends.ParseMlxCommand(req.Command)
|
|
||||||
if err != nil {
|
|
||||||
writeError(w, http.StatusBadRequest, "parse_error", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Currently only support mlx_lm backend type
|
|
||||||
backendType := backends.BackendTypeMlxLm
|
|
||||||
|
|
||||||
options := &instance.Options{
|
options := &instance.Options{
|
||||||
BackendOptions: backends.Options{
|
BackendOptions: backends.Options{
|
||||||
BackendType: backendType,
|
BackendType: backends.BackendTypeMlxLm,
|
||||||
MlxServerOptions: mlxOptions,
|
MlxServerOptions: parsedOptions.(*backends.MlxServerOptions),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,39 +211,16 @@ func (h *Handler) ParseMlxCommand() http.HandlerFunc {
|
|||||||
// @Failure 400 {object} map[string]string "Invalid request or command"
|
// @Failure 400 {object} map[string]string "Invalid request or command"
|
||||||
// @Router /backends/vllm/parse-command [post]
|
// @Router /backends/vllm/parse-command [post]
|
||||||
func (h *Handler) ParseVllmCommand() http.HandlerFunc {
|
func (h *Handler) ParseVllmCommand() http.HandlerFunc {
|
||||||
type errorResponse struct {
|
|
||||||
Error string `json:"error"`
|
|
||||||
Details string `json:"details,omitempty"`
|
|
||||||
}
|
|
||||||
writeError := func(w http.ResponseWriter, status int, code, details string) {
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.WriteHeader(status)
|
|
||||||
_ = json.NewEncoder(w).Encode(errorResponse{Error: code, Details: details})
|
|
||||||
}
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var req ParseCommandRequest
|
parsedOptions, ok := parseHelper(w, r, &backends.VllmServerOptions{})
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if !ok {
|
||||||
writeError(w, http.StatusBadRequest, "invalid_request", "Invalid JSON body")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(req.Command) == "" {
|
|
||||||
writeError(w, http.StatusBadRequest, "invalid_command", "Command cannot be empty")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
vllmOptions, err := backends.ParseVllmCommand(req.Command)
|
|
||||||
if err != nil {
|
|
||||||
writeError(w, http.StatusBadRequest, "parse_error", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
backendType := backends.BackendTypeVllm
|
|
||||||
|
|
||||||
options := &instance.Options{
|
options := &instance.Options{
|
||||||
BackendOptions: backends.Options{
|
BackendOptions: backends.Options{
|
||||||
BackendType: backendType,
|
BackendType: backends.BackendTypeVllm,
|
||||||
VllmServerOptions: vllmOptions,
|
VllmServerOptions: parsedOptions.(*backends.VllmServerOptions),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user