@@ -11,6 +11,7 @@ import (
11
11
"strings"
12
12
13
13
"github.com/spf13/cobra"
14
+ "github.com/spf13/viper"
14
15
"golang.org/x/xerrors"
15
16
16
17
"github.com/coder/agentapi/lib/httpapi"
@@ -19,15 +20,6 @@ import (
19
20
"github.com/coder/agentapi/lib/termexec"
20
21
)
21
22
22
- var (
23
- agentTypeVar string
24
- port int
25
- printOpenAPI bool
26
- chatBasePath string
27
- termWidth uint16
28
- termHeight uint16
29
- )
30
-
31
23
type AgentType = msgfmt.AgentType
32
24
33
25
const (
@@ -70,11 +62,15 @@ func parseAgentType(firstArg string, agentTypeVar string) (AgentType, error) {
70
62
71
63
func runServer (ctx context.Context , logger * slog.Logger , argsToPass []string ) error {
72
64
agent := argsToPass [0 ]
73
- agentType , err := parseAgentType (agent , agentTypeVar )
65
+ agentTypeValue := viper .GetString (FlagType )
66
+ agentType , err := parseAgentType (agent , agentTypeValue )
74
67
if err != nil {
75
68
return xerrors .Errorf ("failed to parse agent type: %w" , err )
76
69
}
77
70
71
+ termWidth := viper .GetUint16 (FlagTermWidth )
72
+ termHeight := viper .GetUint16 (FlagTermHeight )
73
+
78
74
if termWidth < 10 {
79
75
return xerrors .Errorf ("term width must be at least 10" )
80
76
}
@@ -85,6 +81,7 @@ func runServer(ctx context.Context, logger *slog.Logger, argsToPass []string) er
85
81
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
86
82
}
87
83
84
+ printOpenAPI := viper .GetBool (FlagPrintOpenAPI )
88
85
var process * termexec.Process
89
86
if printOpenAPI {
90
87
process = nil
@@ -99,7 +96,13 @@ func runServer(ctx context.Context, logger *slog.Logger, argsToPass []string) er
99
96
return xerrors .Errorf ("failed to setup process: %w" , err )
100
97
}
101
98
}
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
+ })
103
106
if printOpenAPI {
104
107
fmt .Println (srv .GetOpenAPI ())
105
108
return nil
@@ -140,26 +143,69 @@ var agentNames = (func() []string {
140
143
return names
141
144
})()
142
145
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
156
152
}
157
153
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
165
211
}
0 commit comments