Fix vllm command parsing

This commit is contained in:
2025-09-22 21:25:50 +02:00
parent 313666ea17
commit 184d6df1bc
2 changed files with 34 additions and 12 deletions

View File

@@ -17,8 +17,8 @@ func ParseCommand(command string, executableNames []string, subcommandNames []st
return fmt.Errorf("command cannot be empty")
}
// Extract arguments
args, err := extractArgs(command, executableNames, subcommandNames)
// Extract arguments and positional model
args, modelFromPositional, err := extractArgs(command, executableNames, subcommandNames)
if err != nil {
return err
}
@@ -29,6 +29,13 @@ func ParseCommand(command string, executableNames []string, subcommandNames []st
return err
}
// If we found a positional model and no --model flag was provided, set the model
if modelFromPositional != "" {
if _, hasModelFlag := options["model"]; !hasModelFlag {
options["model"] = modelFromPositional
}
}
// Convert to target struct via JSON
jsonData, err := json.Marshal(options)
if err != nil {
@@ -51,15 +58,16 @@ func normalizeCommand(command string) string {
}
// extractArgs extracts arguments from command, removing executable and subcommands
func extractArgs(command string, executableNames []string, subcommandNames []string) ([]string, error) {
// Returns: args, modelFromPositional, error
func extractArgs(command string, executableNames []string, subcommandNames []string) ([]string, string, error) {
// Check for unterminated quotes
if strings.Count(command, `"`)%2 != 0 || strings.Count(command, `'`)%2 != 0 {
return nil, fmt.Errorf("unterminated quoted string")
return nil, "", fmt.Errorf("unterminated quoted string")
}
tokens := strings.Fields(command)
if len(tokens) == 0 {
return nil, fmt.Errorf("no tokens found")
return nil, "", fmt.Errorf("no tokens found")
}
// Skip executable
@@ -104,7 +112,16 @@ func extractArgs(command string, executableNames []string, subcommandNames []str
}
}
return tokens[start:], nil
args := tokens[start:]
// Extract first positional argument (model) if present and not a flag
var modelFromPositional string
if len(args) > 0 && !strings.HasPrefix(args[0], "-") {
modelFromPositional = args[0]
args = args[1:] // Remove the model from args to process remaining flags
}
return args, modelFromPositional, nil
}
// parseFlags parses command line flags into a map

View File

@@ -14,17 +14,22 @@ func TestParseVllmCommand(t *testing.T) {
}{
{
name: "basic vllm serve command",
command: "vllm serve --model microsoft/DialoGPT-medium",
command: "vllm serve microsoft/DialoGPT-medium",
expectErr: false,
},
{
name: "serve only command",
command: "serve --model microsoft/DialoGPT-medium",
command: "serve microsoft/DialoGPT-medium",
expectErr: false,
},
{
name: "args only",
command: "--model microsoft/DialoGPT-medium --tensor-parallel-size 2",
name: "positional model with flags",
command: "vllm serve microsoft/DialoGPT-medium --tensor-parallel-size 2",
expectErr: false,
},
{
name: "model with path",
command: "vllm serve /path/to/model --gpu-memory-utilization 0.8",
expectErr: false,
},
{
@@ -34,7 +39,7 @@ func TestParseVllmCommand(t *testing.T) {
},
{
name: "unterminated quote",
command: `vllm serve --model "unterminated`,
command: `vllm serve "unterminated`,
expectErr: true,
},
}
@@ -63,7 +68,7 @@ func TestParseVllmCommand(t *testing.T) {
}
func TestParseVllmCommandValues(t *testing.T) {
command := "vllm serve --model test-model --tensor-parallel-size 4 --gpu-memory-utilization 0.8 --enable-log-outputs"
command := "vllm serve test-model --tensor-parallel-size 4 --gpu-memory-utilization 0.8 --enable-log-outputs"
result, err := vllm.ParseVllmCommand(command)
if err != nil {