@@ -11,6 +11,7 @@ import (
1111 "strings"
1212
1313 "github.com/spf13/cobra"
14+ "github.com/spf13/viper"
1415 "golang.org/x/xerrors"
1516
1617 "github.com/coder/agentapi/lib/httpapi"
@@ -19,15 +20,6 @@ import (
1920 "github.com/coder/agentapi/lib/termexec"
2021)
2122
22- var (
23- agentTypeVar string
24- port int
25- printOpenAPI bool
26- chatBasePath string
27- termWidth uint16
28- termHeight uint16
29- )
30-
3123type AgentType = msgfmt.AgentType
3224
3325const (
@@ -70,11 +62,15 @@ func parseAgentType(firstArg string, agentTypeVar string) (AgentType, error) {
7062
7163func runServer (ctx context.Context , logger * slog.Logger , argsToPass []string ) error {
7264 agent := argsToPass [0 ]
73- agentType , err := parseAgentType (agent , agentTypeVar )
65+ agentTypeValue := viper .GetString (FlagType )
66+ agentType , err := parseAgentType (agent , agentTypeValue )
7467 if err != nil {
7568 return xerrors .Errorf ("failed to parse agent type: %w" , err )
7669 }
7770
71+ termWidth := viper .GetUint16 (FlagTermWidth )
72+ termHeight := viper .GetUint16 (FlagTermHeight )
73+
7874 if termWidth < 10 {
7975 return xerrors .Errorf ("term width must be at least 10" )
8076 }
@@ -85,6 +81,7 @@ func runServer(ctx context.Context, logger *slog.Logger, argsToPass []string) er
8581 termHeight = 930 // codex has a bug where the TUI distorts the screen if the height is too large, see: https://github.com/openai/codex/issues/1608
8682 }
8783
84+ printOpenAPI := viper .GetBool (FlagPrintOpenAPI )
8885 var process * termexec.Process
8986 if printOpenAPI {
9087 process = nil
@@ -99,7 +96,13 @@ func runServer(ctx context.Context, logger *slog.Logger, argsToPass []string) er
9996 return xerrors .Errorf ("failed to setup process: %w" , err )
10097 }
10198 }
102- srv := httpapi .NewServer (ctx , agentType , process , port , chatBasePath )
99+ port := viper .GetInt (FlagPort )
100+ srv := httpapi .NewServer (ctx , httpapi.ServerConfig {
101+ AgentType : agentType ,
102+ Process : process ,
103+ Port : port ,
104+ ChatBasePath : viper .GetString (FlagChatBasePath ),
105+ })
103106 if printOpenAPI {
104107 fmt .Println (srv .GetOpenAPI ())
105108 return nil
@@ -140,26 +143,69 @@ var agentNames = (func() []string {
140143 return names
141144})()
142145
143- var ServerCmd = & cobra.Command {
144- Use : "server [agent]" ,
145- Short : "Run the server" ,
146- Long : fmt .Sprintf ("Run the server with the specified agent (one of: %s)" , strings .Join (agentNames , ", " )),
147- Args : cobra .MinimumNArgs (1 ),
148- Run : func (cmd * cobra.Command , args []string ) {
149- logger := slog .New (slog .NewTextHandler (os .Stdout , nil ))
150- ctx := logctx .WithLogger (context .Background (), logger )
151- if err := runServer (ctx , logger , cmd .Flags ().Args ()); err != nil {
152- fmt .Fprintf (os .Stderr , "%+v\n " , err )
153- os .Exit (1 )
154- }
155- },
146+ type flagSpec struct {
147+ name string
148+ shorthand string
149+ defaultValue any
150+ usage string
151+ flagType string
156152}
157153
158- func init () {
159- ServerCmd .Flags ().StringVarP (& agentTypeVar , "type" , "t" , "" , fmt .Sprintf ("Override the agent type (one of: %s, custom)" , strings .Join (agentNames , ", " )))
160- ServerCmd .Flags ().IntVarP (& port , "port" , "p" , 3284 , "Port to run the server on" )
161- ServerCmd .Flags ().BoolVarP (& printOpenAPI , "print-openapi" , "P" , false , "Print the OpenAPI schema to stdout and exit" )
162- ServerCmd .Flags ().StringVarP (& chatBasePath , "chat-base-path" , "c" , "/chat" , "Base path for assets and routes used in the static files of the chat interface" )
163- ServerCmd .Flags ().Uint16VarP (& termWidth , "term-width" , "W" , 80 , "Width of the emulated terminal" )
164- ServerCmd .Flags ().Uint16VarP (& termHeight , "term-height" , "H" , 1000 , "Height of the emulated terminal" )
154+ const (
155+ FlagType = "type"
156+ FlagPort = "port"
157+ FlagPrintOpenAPI = "print-openapi"
158+ FlagChatBasePath = "chat-base-path"
159+ FlagTermWidth = "term-width"
160+ FlagTermHeight = "term-height"
161+ )
162+
163+ func CreateServerCmd () * cobra.Command {
164+ serverCmd := & cobra.Command {
165+ Use : "server [agent]" ,
166+ Short : "Run the server" ,
167+ Long : fmt .Sprintf ("Run the server with the specified agent (one of: %s)" , strings .Join (agentNames , ", " )),
168+ Args : cobra .MinimumNArgs (1 ),
169+ Run : func (cmd * cobra.Command , args []string ) {
170+ logger := slog .New (slog .NewTextHandler (os .Stdout , nil ))
171+ ctx := logctx .WithLogger (context .Background (), logger )
172+ if err := runServer (ctx , logger , cmd .Flags ().Args ()); err != nil {
173+ fmt .Fprintf (os .Stderr , "%+v\n " , err )
174+ os .Exit (1 )
175+ }
176+ },
177+ }
178+
179+ flagSpecs := []flagSpec {
180+ {FlagType , "t" , "" , fmt .Sprintf ("Override the agent type (one of: %s, custom)" , strings .Join (agentNames , ", " )), "string" },
181+ {FlagPort , "p" , 3284 , "Port to run the server on" , "int" },
182+ {FlagPrintOpenAPI , "P" , false , "Print the OpenAPI schema to stdout and exit" , "bool" },
183+ {FlagChatBasePath , "c" , "/chat" , "Base path for assets and routes used in the static files of the chat interface" , "string" },
184+ {FlagTermWidth , "W" , uint16 (80 ), "Width of the emulated terminal" , "uint16" },
185+ {FlagTermHeight , "H" , uint16 (1000 ), "Height of the emulated terminal" , "uint16" },
186+ }
187+
188+ for _ , spec := range flagSpecs {
189+ switch spec .flagType {
190+ case "string" :
191+ serverCmd .Flags ().StringP (spec .name , spec .shorthand , spec .defaultValue .(string ), spec .usage )
192+ case "int" :
193+ serverCmd .Flags ().IntP (spec .name , spec .shorthand , spec .defaultValue .(int ), spec .usage )
194+ case "bool" :
195+ serverCmd .Flags ().BoolP (spec .name , spec .shorthand , spec .defaultValue .(bool ), spec .usage )
196+ case "uint16" :
197+ serverCmd .Flags ().Uint16P (spec .name , spec .shorthand , spec .defaultValue .(uint16 ), spec .usage )
198+ default :
199+ panic (fmt .Sprintf ("unknown flag type: %s" , spec .flagType ))
200+ }
201+ if err := viper .BindPFlag (spec .name , serverCmd .Flags ().Lookup (spec .name )); err != nil {
202+ panic (fmt .Sprintf ("failed to bind flag %s: %v" , spec .name , err ))
203+ }
204+ }
205+
206+ viper .SetEnvPrefix ("AGENTAPI" )
207+ viper .AutomaticEnv ()
208+ viper .SetEnvKeyReplacer (strings .NewReplacer ("-" , "_" ))
209+
210+ return serverCmd
165211}
0 commit comments