@@ -47,8 +47,8 @@ type SpawnCmd struct {
4747 WriteStats string `kong:"help='Write stats to file on exit'"`
4848 PrintStats bool `kong:"help='Print stats on exit'"`
4949
50- // Display mode
51- Pretty bool `kong:"help='Display hands in pretty format instead of logs'"`
50+ // Output format
51+ Output string `kong:"default='logs',enum='logs,bot-cmd,hand-history', help='Output format: logs (all logs), bot-cmd (only custom bot logs), hand-history (pretty hand visualization) '"`
5252
5353 // Logging
5454 LogLevel string `kong:"help='Log level (debug|info|warn|error)'"`
@@ -68,8 +68,8 @@ func (c *SpawnCmd) Run() error {
6868 level = zerolog .ErrorLevel
6969 }
7070
71- // In pretty mode, suppress most logs unless explicitly set
72- if c .Pretty && c .LogLevel == "" {
71+ // In hand-history mode, suppress most logs unless explicitly set
72+ if c .Output == "hand-history" && c .LogLevel == "" {
7373 level = zerolog .WarnLevel
7474 }
7575
@@ -96,7 +96,7 @@ func (c *SpawnCmd) Run() error {
9696 wsURL := fmt .Sprintf ("ws://%s/ws" , listener .Addr ())
9797
9898 // Now parse bot specifications with the WebSocket URL
99- specs , err := parseSpecString (c .Spec , wsURL )
99+ specs , err := parseSpecString (c .Spec , wsURL , c . Output )
100100 if err != nil {
101101 return fmt .Errorf ("failed to parse spec: %w" , err )
102102 }
@@ -109,10 +109,12 @@ func (c *SpawnCmd) Run() error {
109109 if len (parts ) == 0 {
110110 continue
111111 }
112+ // Custom bot logs are suppressed only in hand-history mode
112113 specs = append (specs , spawner.BotSpec {
113- Command : parts [0 ],
114- Args : parts [1 :], // Don't append wsURL - bot should use POKERFORBOTS_SERVER
115- Count : c .Count ,
114+ Command : parts [0 ],
115+ Args : parts [1 :], // Don't append wsURL - bot should use POKERFORBOTS_SERVER
116+ Count : c .Count ,
117+ QuietLogs : c .Output == "hand-history" ,
116118 })
117119 }
118120
@@ -130,7 +132,7 @@ func (c *SpawnCmd) Run() error {
130132 minPlayers := c .MinPlayers
131133 if minPlayers == 0 {
132134 minPlayers = max (2 , min (totalBots , c .MaxPlayers ))
133- if ! c . Pretty {
135+ if c . Output != "hand-history" {
134136 logger .Info ().Int ("min_players" , minPlayers ).Int ("total_bots" , totalBots ).Msg ("Auto-setting min-players to match bot count" )
135137 }
136138 }
@@ -168,8 +170,8 @@ func (c *SpawnCmd) Run() error {
168170 return fmt .Errorf ("server failed to start: %w" , err )
169171 }
170172
171- // Set up pretty printer if requested
172- if c .Pretty {
173+ // Set up hand-history monitor if requested
174+ if c .Output == "hand-history" {
173175 monitor := server .NewPrettyPrintMonitor (os .Stdout )
174176 srv .SetHandMonitor (monitor )
175177 } else {
@@ -179,16 +181,13 @@ func (c *SpawnCmd) Run() error {
179181 }
180182 }
181183
182- if ! c . Pretty {
184+ if c . Output != "hand-history" {
183185 logger .Info ().Str ("spec" , c .Spec ).Int ("additional" , len (c .BotCmd )).Int ("total_bots" , totalBots ).Msg ("Spawning bots" )
184186 }
185187
186188 // Create spawner and spawn bots
189+ // Note: Per-bot quiet logs are handled by BotSpec.QuietLogs, not here
187190 spawnerLogger := logger
188- if c .Pretty {
189- // Create a quiet logger for bot processes in pretty mode
190- spawnerLogger = zerolog .New (io .Discard ).Level (zerolog .Disabled )
191- }
192191
193192 botSpawner := spawner .NewWithSeed (wsURL , spawnerLogger , seed )
194193 defer botSpawner .StopAll ()
@@ -197,7 +196,7 @@ func (c *SpawnCmd) Run() error {
197196 return fmt .Errorf ("failed to spawn bots: %w" , err )
198197 }
199198
200- if ! c . Pretty {
199+ if c . Output != "hand-history" {
201200 logger .Info ().Int ("count" , botSpawner .ActiveCount ()).Msg ("Bots spawned" )
202201 }
203202
@@ -233,7 +232,7 @@ func (c *SpawnCmd) Run() error {
233232 case <- ctx .Done ():
234233 logger .Info ().Msg ("Shutting down..." )
235234 case <- srv .DefaultGameDone ():
236- if ! c . Pretty {
235+ if c . Output != "hand-history" {
237236 logger .Info ().Msg ("Hand limit reached" )
238237 }
239238 case err := <- serverErr :
@@ -271,15 +270,15 @@ func (c *SpawnCmd) Run() error {
271270 time .Sleep (100 * time .Millisecond )
272271
273272 // Stop bots (will be done by defer)
274- if ! c . Pretty {
273+ if c . Output != "hand-history" {
275274 logger .Info ().Msg ("Stopping bots..." )
276275 }
277276
278277 return nil
279278}
280279
281280// parseSpecString parses a specification string like "calling-station:2,random:1,aggressive:3"
282- func parseSpecString (spec string , wsURL string ) ([]spawner.BotSpec , error ) {
281+ func parseSpecString (spec string , wsURL string , outputMode string ) ([]spawner.BotSpec , error ) {
283282 if spec == "" {
284283 return nil , nil
285284 }
@@ -314,6 +313,7 @@ func parseSpecString(spec string, wsURL string) ([]spawner.BotSpec, error) {
314313 // Check if it's a built-in bot or a custom command
315314 var command string
316315 var args []string
316+ var isBuiltIn bool
317317
318318 if strings .Contains (strategy , "/" ) || strings .Contains (strategy , "." ) {
319319 // Custom command (e.g., "./my-bot")
@@ -324,16 +324,29 @@ func parseSpecString(spec string, wsURL string) ([]spawner.BotSpec, error) {
324324 command = fields [0 ]
325325 args = fields [1 :]
326326 args = append (args , wsURL )
327+ isBuiltIn = false
327328 } else {
328329 // Built-in bot - use pokerforbots bot subcommand
329330 command = pokerforbotsBin
330331 args = []string {"bot" , strategy , "--server" , wsURL }
332+ isBuiltIn = true
333+ }
334+
335+ // Determine if logs should be suppressed for this bot
336+ quietLogs := false
337+ if isBuiltIn {
338+ // Suppress built-in bot logs in bot-cmd and hand-history modes
339+ quietLogs = (outputMode == "bot-cmd" || outputMode == "hand-history" )
340+ } else {
341+ // Suppress custom bot logs only in hand-history mode
342+ quietLogs = (outputMode == "hand-history" )
331343 }
332344
333345 specs = append (specs , spawner.BotSpec {
334- Command : command ,
335- Args : args ,
336- Count : count ,
346+ Command : command ,
347+ Args : args ,
348+ Count : count ,
349+ QuietLogs : quietLogs ,
337350 })
338351 }
339352
0 commit comments