4747 noStream bool
4848 noSummary bool
4949 summaryAgent string
50+ jsonOutput bool
5051)
5152
5253var runCmd = & cobra.Command {
@@ -80,6 +81,7 @@ func init() {
8081 runCmd .Flags ().BoolVar (& noStream , "no-stream" , false , "Disable streaming to AgentPipe Web for this run (overrides config)" )
8182 runCmd .Flags ().BoolVar (& noSummary , "no-summary" , false , "Disable conversation summary generation (overrides config)" )
8283 runCmd .Flags ().StringVar (& summaryAgent , "summary-agent" , "" , "Agent to use for summary generation (default: gemini, overrides config)" )
84+ runCmd .Flags ().BoolVar (& jsonOutput , "json" , false , "Output events in JSON format (JSONL)" )
8385}
8486
8587func runConversation (cobraCmd * cobra.Command , args []string ) {
@@ -243,7 +245,9 @@ func startConversation(cmd *cobra.Command, cfg *config.Config) error {
243245
244246 verbose := viper .GetBool ("verbose" )
245247
246- fmt .Println ("🔍 Initializing agents..." )
248+ if ! jsonOutput {
249+ fmt .Println ("🔍 Initializing agents..." )
250+ }
247251
248252 for _ , agentCfg := range cfg .Agents {
249253 if verbose {
@@ -319,7 +323,9 @@ func startConversation(cmd *cobra.Command, cfg *config.Config) error {
319323 return fmt .Errorf ("no agents configured" )
320324 }
321325
322- fmt .Printf ("✅ All %d agents initialized successfully\n \n " , len (agentsList ))
326+ if ! jsonOutput {
327+ fmt .Printf ("✅ All %d agents initialized successfully\n \n " , len (agentsList ))
328+ }
323329
324330 orchConfig := orchestrator.OrchestratorConfig {
325331 Mode : orchestrator .ConversationMode (cfg .Orchestrator .Mode ),
@@ -334,7 +340,12 @@ func startConversation(cmd *cobra.Command, cfg *config.Config) error {
334340 var chatLogger * logger.ChatLogger
335341 if cfg .Logging .Enabled {
336342 var err error
337- chatLogger , err = logger .NewChatLogger (cfg .Logging .ChatLogDir , cfg .Logging .LogFormat , os .Stdout , cfg .Logging .ShowMetrics )
343+ // Suppress console output when --json is set
344+ var consoleWriter io.Writer = os .Stdout
345+ if jsonOutput {
346+ consoleWriter = nil
347+ }
348+ chatLogger , err = logger .NewChatLogger (cfg .Logging .ChatLogDir , cfg .Logging .LogFormat , consoleWriter , cfg .Logging .ShowMetrics )
338349 if err != nil {
339350 fmt .Fprintf (os .Stderr , "Warning: Failed to create chat logger: %v\n " , err )
340351 // Continue without logging
@@ -345,8 +356,8 @@ func startConversation(cmd *cobra.Command, cfg *config.Config) error {
345356
346357 // Create orchestrator with appropriate writer
347358 var writer io.Writer = os .Stdout
348- if chatLogger != nil {
349- writer = nil // Logger will handle console output
359+ if chatLogger != nil || jsonOutput {
360+ writer = nil // Logger will handle console output, or suppress for JSON mode
350361 }
351362
352363 orch := orchestrator .NewOrchestrator (orchConfig , writer )
@@ -358,31 +369,40 @@ func startConversation(cmd *cobra.Command, cfg *config.Config) error {
358369 commandInfo := buildCommandInfo (cmd , cfg )
359370 orch .SetCommandInfo (commandInfo )
360371
361- // Set up streaming bridge if enabled
362- shouldStream := determineShouldStream (streamEnabled , noStream )
363- if shouldStream {
364- bridgeConfig := bridge .LoadConfig ()
365- if bridgeConfig .Enabled || streamEnabled {
366- // Override config enabled setting if --stream was specified
367- if streamEnabled {
368- bridgeConfig .Enabled = true
369- }
372+ // Set up JSON stdout emitter if --json flag is set
373+ if jsonOutput {
374+ stdoutEmitter := bridge .NewStdoutEmitter (version .GetShortVersion ())
375+ orch .SetBridgeEmitter (stdoutEmitter )
376+ } else {
377+ // Set up streaming bridge if enabled (only when not in JSON mode)
378+ shouldStream := determineShouldStream (streamEnabled , noStream )
379+ if shouldStream {
380+ bridgeConfig := bridge .LoadConfig ()
381+ if bridgeConfig .Enabled || streamEnabled {
382+ // Override config enabled setting if --stream was specified
383+ if streamEnabled {
384+ bridgeConfig .Enabled = true
385+ }
370386
371- emitter := bridge .NewEmitter (bridgeConfig , version .GetShortVersion ())
372- orch .SetBridgeEmitter (emitter )
387+ emitter := bridge .NewEmitter (bridgeConfig , version .GetShortVersion ())
388+ orch .SetBridgeEmitter (emitter )
373389
374- if verbose {
375- fmt .Printf ("🌐 Streaming enabled (conversation ID: %s)\n " , emitter .GetConversationID ())
390+ if verbose {
391+ fmt .Printf ("🌐 Streaming enabled (conversation ID: %s)\n " , emitter .GetConversationID ())
392+ }
376393 }
377394 }
378395 }
379396
380- fmt .Println ("🚀 Starting AgentPipe conversation..." )
381- fmt .Printf ("Mode: %s | Max turns: %d | Agents: %d\n " , cfg .Orchestrator .Mode , cfg .Orchestrator .MaxTurns , len (agentsList ))
382- if ! cfg .Logging .Enabled {
383- fmt .Println ("📝 Chat logging disabled (use --log-dir to enable)" )
397+ // Only show UI elements when not in JSON output mode
398+ if ! jsonOutput {
399+ fmt .Println ("🚀 Starting AgentPipe conversation..." )
400+ fmt .Printf ("Mode: %s | Max turns: %d | Agents: %d\n " , cfg .Orchestrator .Mode , cfg .Orchestrator .MaxTurns , len (agentsList ))
401+ if ! cfg .Logging .Enabled {
402+ fmt .Println ("📝 Chat logging disabled (use --log-dir to enable)" )
403+ }
404+ fmt .Println (strings .Repeat ("=" , 60 ))
384405 }
385- fmt .Println (strings .Repeat ("=" , 60 ))
386406
387407 log .WithFields (map [string ]interface {}{
388408 "mode" : cfg .Orchestrator .Mode ,
@@ -404,8 +424,10 @@ func startConversation(cmd *cobra.Command, cfg *config.Config) error {
404424 log .Info ("conversation completed successfully" )
405425 }
406426
407- // Print summary
408- fmt .Println ("\n " + strings .Repeat ("=" , 60 ))
427+ // Only print UI summary when not in JSON mode
428+ if ! jsonOutput {
429+ fmt .Println ("\n " + strings .Repeat ("=" , 60 ))
430+ }
409431
410432 // Save conversation state if requested
411433 if saveState || stateFile != "" {
@@ -415,16 +437,19 @@ func startConversation(cmd *cobra.Command, cfg *config.Config) error {
415437 }
416438 }
417439
418- // Always print session summary (whether interrupted or completed normally)
419- if gracefulShutdown {
420- fmt .Println ("📊 Session Summary (Interrupted)" )
421- } else if err != nil {
422- fmt .Println ("📊 Session Summary (Ended with Error)" )
423- } else {
424- fmt .Println ("📊 Session Summary (Completed)" )
440+ // Only print session summary when not in JSON output mode
441+ if ! jsonOutput {
442+ // Always print session summary (whether interrupted or completed normally)
443+ if gracefulShutdown {
444+ fmt .Println ("📊 Session Summary (Interrupted)" )
445+ } else if err != nil {
446+ fmt .Println ("📊 Session Summary (Ended with Error)" )
447+ } else {
448+ fmt .Println ("📊 Session Summary (Completed)" )
449+ }
450+ fmt .Println (strings .Repeat ("=" , 60 ))
451+ printSessionSummary (orch , cfg )
425452 }
426- fmt .Println (strings .Repeat ("=" , 60 ))
427- printSessionSummary (orch , cfg )
428453
429454 if err != nil {
430455 return fmt .Errorf ("orchestrator error: %w" , err )
0 commit comments