@@ -838,7 +838,14 @@ def parse_args(self):
838838 parser .add_argument ("--no-acp" , action = "store_true" , help = "Disable ACP tools (agentic file operations with plan/approve/apply)" )
839839 parser .add_argument ("--no-lsp" , action = "store_true" , help = "Disable LSP tools (code intelligence: symbols, definitions, references)" )
840840 parser .add_argument ("--save" , "-s" , action = "store_true" , help = "Save research output to file (output/research/)" )
841- parser .add_argument ("--verbose" , "-v" , action = "store_true" , help = "Enable verbose output for research" )
841+ parser .add_argument ("-v" , "--verbose" , action = "count" , default = 0 ,
842+ help = "Increase verbosity (-v=verbose, -vv=debug)" )
843+ parser .add_argument ("-q" , "--quiet" , action = "count" , default = 0 ,
844+ help = "Decrease verbosity (-q=quiet, -qq=silent)" )
845+ parser .add_argument ("--output" , type = str , choices = ["json" , "jsonl" ], dest = "output_format" ,
846+ help = "Machine-readable output format (json or jsonl)" )
847+ parser .add_argument ("--flow" , action = "store_true" ,
848+ help = "Show visual agent→tool flow chart" )
842849 parser .add_argument ("--web" , "--web-search" , action = "store_true" , help = "Enable native web search (OpenAI, Gemini, Anthropic, xAI, Perplexity)" )
843850 parser .add_argument ("--web-fetch" , action = "store_true" , help = "Enable web fetch to retrieve URL content (Anthropic only)" )
844851 parser .add_argument ("--prompt-caching" , action = "store_true" , help = "Enable prompt caching to reduce costs (OpenAI, Anthropic, Bedrock, Deepseek)" )
@@ -954,9 +961,6 @@ def parse_args(self):
954961 parser .add_argument ("--lsp" , action = "store_true" ,
955962 help = "Enable LSP tools in autonomy mode (slower but provides code intelligence)" )
956963
957- # P3/G5: Display mode - control output verbosity
958- parser .add_argument ("--display" , type = str , choices = ["minimal" , "status" , "verbose" , "debug" , "jsonl" , "json" , "flow" ],
959- default = "status" , help = "Display mode: minimal|status|verbose|debug|jsonl|json|flow" )
960964
961965 # P8/G11: Tool timeout - prevent slow tools from blocking
962966 parser .add_argument ("--tool-timeout" , type = int , default = 60 ,
@@ -3888,9 +3892,12 @@ def handle_direct_prompt(self, prompt):
38883892 if autonomy_mode and autonomy_mode not in ('disable' , None ):
38893893 agent_config ["autonomy" ] = {"level" : autonomy_mode , "enabled" : True }
38903894
3891- # Set output mode based on --verbose flag
3892- # Uses consolidated 'output' param instead of deprecated 'verbose'
3893- if hasattr (self , 'args' ) and getattr (self .args , 'verbose' , False ):
3895+ # Set SDK output preset based on verbosity flags
3896+ # The display dispatcher handles CLI rendering; this controls SDK-level behavior
3897+ v = getattr (self .args , 'verbose' , 0 ) if hasattr (self , 'args' ) else 0
3898+ if v >= 2 :
3899+ agent_config ["output" ] = "verbose" # SDK debug-level detail
3900+ elif v >= 1 :
38943901 agent_config ["output" ] = "verbose"
38953902 else :
38963903 agent_config ["output" ] = "minimal"
@@ -4264,42 +4271,29 @@ def level_based_approve(function_name, arguments, risk_level):
42644271 else :
42654272 result = auto_rag .chat (prompt )
42664273 else :
4267- # Unified display mode dispatcher
4268- display_mode = getattr ( self .args , 'display' , 'status' )
4274+ # Resolve display mode from CLI flags
4275+ display_mode = self ._resolve_display_mode ( )
42694276
4270- # Also check Typer global state (for -o json, --quiet, etc.)
4271- try :
4272- from .app import state as typer_state
4273- if typer_state .quiet :
4274- display_mode = 'minimal'
4275- elif typer_state .output_format .value == 'json' :
4276- display_mode = 'json'
4277- elif typer_state .output_format .value == 'stream-json' :
4278- display_mode = 'jsonl'
4279- elif typer_state .screen_reader :
4280- display_mode = 'debug' # trace-like, no spinners
4281- except (ImportError , AttributeError ):
4282- pass
4283-
4284- # Check legacy verbose flag
4285- is_verbose = agent_config .get ("verbose" , False )
4286- if is_verbose and display_mode == 'status' :
4287- display_mode = 'verbose'
4277+ if display_mode == 'silent' :
4278+ # -qq: No output at all, exit code only
4279+ if hasattr (agent , 'start' ):
4280+ result = agent .start (prompt )
4281+ else :
4282+ result = agent .chat (prompt )
42884283
4289- if display_mode == 'minimal ' :
4290- # Quiet: result only, no spinners
4284+ elif display_mode == 'quiet ' :
4285+ # -q: Result only, no spinners or status
42914286 if hasattr (agent , 'start' ):
42924287 result = agent .start (prompt )
42934288 else :
42944289 result = agent .chat (prompt )
4295- # Still print the result
42964290 if result is not None :
42974291 output = getattr (result , 'output' , None ) or (str (result ) if result else None )
42984292 if output :
42994293 print (output )
43004294
43014295 elif display_mode == 'verbose' :
4302- # SDK StatusOutput with timestamps and metrics
4296+ # -v: SDK StatusOutput with timestamps and metrics
43034297 try :
43044298 from praisonaiagents .output .status import enable_status_output , disable_status_output
43054299 enable_status_output (show_timestamps = True , show_metrics = True )
@@ -4315,7 +4309,7 @@ def level_based_approve(function_name, arguments, risk_level):
43154309 result = agent .chat (prompt )
43164310
43174311 elif display_mode == 'debug' :
4318- # SDK TraceOutput with markdown
4312+ # -vv: SDK TraceOutput with markdown rendering
43194313 try :
43204314 from praisonaiagents .output .trace import enable_trace_output , disable_trace_output
43214315 enable_trace_output (use_markdown = True )
@@ -4331,7 +4325,7 @@ def level_based_approve(function_name, arguments, risk_level):
43314325 result = agent .chat (prompt )
43324326
43334327 elif display_mode == 'jsonl' :
4334- # JSONL structured output for CI/CD
4328+ # --output jsonl: JSONL structured output for CI/CD
43354329 from .features .display_jsonl import JsonlDisplay
43364330 from praisonaiagents .main import register_display_callback as _reg_cb
43374331
@@ -4367,7 +4361,7 @@ def level_based_approve(function_name, arguments, risk_level):
43674361 print (result )
43684362
43694363 elif display_mode == 'json' :
4370- # JSON envelope output
4364+ # --output json: JSON envelope output
43714365 import json as json_mod
43724366 start_time = time .time ()
43734367 if hasattr (agent , 'start' ):
@@ -4388,7 +4382,7 @@ def level_based_approve(function_name, arguments, risk_level):
43884382 print (json_mod .dumps (envelope , indent = 2 ))
43894383
43904384 elif display_mode == 'flow' :
4391- # SDK FlowDisplay - visual agent→tool chart
4385+ # --flow: SDK FlowDisplay - visual agent→tool chart
43924386 try :
43934387 from praisonaiagents .flow_display import track_workflow
43944388 flow = track_workflow ()
@@ -4405,8 +4399,21 @@ def level_based_approve(function_name, arguments, risk_level):
44054399 result = agent .chat (prompt )
44064400
44074401 else :
4408- # Default "status" mode - enhanced interactive display
4409- result = self ._run_with_status_display (agent , prompt )
4402+ # Default: SDK status output — clean inline progress
4403+ # Shows: spinner + tool calls, no panels, no timestamps
4404+ try :
4405+ from praisonaiagents .output .status import enable_status_output , disable_status_output
4406+ enable_status_output (show_timestamps = False , show_metrics = False )
4407+ if hasattr (agent , 'start' ):
4408+ result = agent .start (prompt )
4409+ else :
4410+ result = agent .chat (prompt )
4411+ disable_status_output ()
4412+ except ImportError :
4413+ if hasattr (agent , 'start' ):
4414+ result = agent .start (prompt )
4415+ else :
4416+ result = agent .chat (prompt )
44104417
44114418 # ===== POST-PROCESSING WITH NEW FEATURES =====
44124419
@@ -4590,14 +4597,60 @@ def _handle_profiled_prompt(self, prompt):
45904597 # Return the actual result for any downstream processing
45914598 return result .output
45924599
4600+ def _resolve_display_mode (self ):
4601+ """Map CLI flags to a display mode string.
4602+
4603+ Priority: --output > --flow > --display (deprecated) > -v/-q > default.
4604+ Returns one of: 'silent', 'quiet', 'verbose', 'debug', 'json', 'jsonl', 'flow', 'status'.
4605+ """
4606+ # Machine formats take highest priority
4607+ output_fmt = getattr (self .args , 'output_format' , None )
4608+ if output_fmt :
4609+ return output_fmt # "json" or "jsonl"
4610+
4611+ # --flow is an independent feature flag
4612+ if getattr (self .args , 'flow' , False ) or getattr (self .args , 'flow_display' , False ):
4613+ return 'flow'
4614+
4615+ # Check Typer global state (for Typer subcommands)
4616+ try :
4617+ from .app import state as typer_state
4618+ if typer_state .quiet :
4619+ return 'quiet'
4620+ if hasattr (typer_state , 'output_format' ):
4621+ if typer_state .output_format .value == 'json' :
4622+ return 'json'
4623+ elif typer_state .output_format .value == 'stream-json' :
4624+ return 'jsonl'
4625+ if typer_state .screen_reader :
4626+ return 'verbose' # Accessible: timestamps but no spinners
4627+ except (ImportError , AttributeError ):
4628+ pass
4629+
4630+ # Verbosity ladder: -v/-vv/-q/-qq
4631+ v = getattr (self .args , 'verbose' , 0 )
4632+ q = getattr (self .args , 'quiet' , 0 )
4633+ if q >= 2 :
4634+ return 'silent'
4635+ if q >= 1 :
4636+ return 'quiet'
4637+ if v >= 2 :
4638+ return 'debug'
4639+ if v >= 1 :
4640+ return 'verbose'
4641+
4642+ return 'status' # Default: Rich Live TUI
4643+
45934644 def _run_with_status_display (self , agent , prompt ):
45944645 """
4595- Run agent with minimal status display (spinner + tool/handoff updates ).
4646+ Run agent with Rich Live TUI display (default CLI experience ).
45964647
45974648 Shows:
4598- - "Generating..." with spinner while processing
4649+ - Spinner with emoji (🤖 thinking, ⏳ tools)
45994650 - Real-time tool call notifications via registered callback
4651+ - Autonomy iteration badges
46004652 - Agent handoff notifications
4653+ - Elapsed time with pause tracking during approval
46014654 """
46024655 import threading
46034656 import time
@@ -4660,7 +4713,7 @@ def _run_with_status_display(self, agent, prompt):
46604713 }
46614714
46624715 # P7/G3: Get display mode for tool args/results visibility
4663- display_mode = getattr ( self .args , 'display' , 'status' )
4716+ display_mode = self ._resolve_display_mode ( )
46644717
46654718 # Phase 0: Smart action verb mapping for tool names
46664719 _TOOL_VERBS = {
0 commit comments