@@ -108,16 +108,19 @@ def _handle_slash(self, line: str) -> bool:
108108 self .console .print ("[yellow]Conversation history cleared.[/yellow]" )
109109 elif cmd == "/model" :
110110 self ._run_model_command (arg )
111+ elif cmd == "/agent" :
112+ self ._run_agent_command (arg )
111113 elif cmd == "/help" :
112114 self .console .print (
113115 "/plan /build /init /review /explain /compact "
114- "/save /summary /sessions /restore /clear /model /exit\n "
116+ "/save /summary /sessions /restore /clear /model /agent / exit\n "
115117 "/init [project] [--extra TEXT] create/update AGENTS.md\n "
116118 "/review [project] [commit|branch|PR] review code changes\n "
117119 "/explain [project] [target] explain code\n "
118120 "/sessions list saved sessions\n "
119121 "/restore [path | title | --latest | latest] restore a saved session\n "
120122 "/model [name] switch LLM model profile\n "
123+ "/agent [name] switch agent system prompt\n "
121124 "Ctrl-C cancels the current execution (app stays open); "
122125 "Ctrl-D or /exit quits." ,
123126 markup = False ,
@@ -487,6 +490,81 @@ def worker() -> None:
487490 else :
488491 self .console .print (msg )
489492
493+ def _refresh_agent_profiles (self ) -> None :
494+ """Re-discover agent prompt files from the agents/ directory.
495+
496+ Agent files may be added/removed while the TUI is running;
497+ this re-scans so new agents show up on the next /agent call.
498+ """
499+ from ..agents import discover_agents
500+
501+ self ._discovered_agents = discover_agents ()
502+
503+ def _agent_list_names (self ) -> list [str ]:
504+ """Names shown by /agent: ``default`` followed by every
505+ discovered agent from the agents/ directory."""
506+ return ["default" , * sorted (self ._discovered_agents .keys ())]
507+
508+ def _agent_switch_by_name (self , name : str ) -> None :
509+ """Switch to a named agent (or ``default``) and report."""
510+ success , msg = self .session .switch_agent (name )
511+ if success :
512+ self .console .print (f"[green]{ msg } [/green]" )
513+ self ._data_event .set ()
514+ else :
515+ self .console .print (f"[red]{ msg } [/red]" )
516+
517+ def _run_agent_command (self , arg : str ) -> None :
518+ """Handle /agent command for switching agent system prompts."""
519+ self ._refresh_agent_profiles ()
520+ if not arg :
521+ all_names = self ._agent_list_names ()
522+ self .console .print ("\n [bold cyan]Available agent profiles:[/bold cyan]" )
523+ if not self ._discovered_agents :
524+ self .console .print (
525+ "[yellow] (none found — add .md files to the agents/ directory to use /agent)[/yellow]"
526+ )
527+ for idx , name in enumerate (all_names , 1 ):
528+ if name == "default" :
529+ self .console .print (f" [cyan]{ idx } )[/cyan] default — agent.md" )
530+ else :
531+ prompt_file = self ._discovered_agents [name ]
532+ self .console .print (f" [cyan]{ idx } )[/cyan] { name } — { prompt_file } " )
533+ total_count = len (all_names )
534+ self .console .print (
535+ f"\n [dim]Type a number (1-{ total_count } ) to switch, or enter an agent name directly[/dim]\n "
536+ )
537+ try :
538+ selection = input ("Select agent: " ).strip ()
539+ if not selection :
540+ return
541+ if selection .isdigit ():
542+ idx = int (selection ) - 1
543+ if 0 <= idx < len (all_names ):
544+ self ._agent_switch_by_name (all_names [idx ])
545+ else :
546+ self .console .print (
547+ f"[red]Invalid selection: { selection } . Choose 1-{ len (all_names )} [/red]"
548+ )
549+ else :
550+ self ._agent_switch_by_name (selection )
551+ except EOFError :
552+ pass
553+ except KeyboardInterrupt :
554+ self .console .print ("\n [dim]cancelled[/dim]" )
555+ return
556+ if arg .strip ().isdigit ():
557+ all_names = self ._agent_list_names ()
558+ idx = int (arg .strip ()) - 1
559+ if 0 <= idx < len (all_names ):
560+ self ._agent_switch_by_name (all_names [idx ])
561+ else :
562+ self .console .print (
563+ f"[red]Invalid selection: { arg } . Choose 1-{ len (all_names )} [/red]"
564+ )
565+ return
566+ self ._agent_switch_by_name (arg )
567+
490568 def _run_sessions (self ) -> None :
491569 """List saved sessions with metadata."""
492570 files = SessionPersistence .list_sessions ()
0 commit comments