@@ -391,7 +391,8 @@ def use_provider(
391391 existing_key = get_existing_api_key(provider)
392392
393393 if not existing_key:
394- console.print(f" [yellow]![/yellow] {t('ai.no_api_key_configured', var=env_var_name)}")
394+ warning = t("ai.no_api_key_configured", var=env_var_name)
395+ console.print(f" [yellow]![/yellow] {warning}")
395396 console.print()
396397 console.print(f"[yellow]{t('ai.consider_running')}[/yellow]")
397398 console.print(
@@ -526,8 +527,8 @@ def chat(
526527 typer.echo("\nChat interrupted", err=True)
527528 raise typer.Exit(1)
528529 except Exception as e:
529- error_str = str(e)
530530{% if ai_rag %}
531+ error_str = str(e)
531532 # Provide helpful guidance for RAG collection errors
532533 if "No RAG collection specified" in error_str:
533534 console.print()
@@ -649,7 +650,9 @@ def voice(
649650 # Validate file exists
650651 audio_path = Path(audio_file)
651652 if not audio_path.exists():
652- console.print(f"[red]{t('shared.error')}[/red] {t('ai.file_not_found', path=audio_file)}")
653+ err_label = t("shared.error")
654+ detail = t("ai.file_not_found", path=audio_file)
655+ console.print(f"[red]{err_label}[/red] {detail}")
653656 raise typer.Exit(1)
654657
655658 # Determine audio format
@@ -658,7 +661,9 @@ def voice(
658661 audio_format = AudioFormat(ext)
659662 except ValueError:
660663 supported = ", ".join(f.value for f in AudioFormat)
661- console.print(f"[red]{t('shared.error')}[/red] {t('ai.unsupported_format', ext=ext)}")
664+ err_label = t("shared.error")
665+ detail = t("ai.unsupported_format", ext=ext)
666+ console.print(f"[red]{err_label}[/red] {detail}")
662667 console.print(f"[dim]{t('ai.supported_formats', formats=supported)}[/dim]")
663668 raise typer.Exit(1)
664669
@@ -704,11 +709,19 @@ def voice(
704709 console.print(f" {result.transcription.text}")
705710
706711 if result.transcription.language:
707- console.print(f" [dim]{t('ai.language_label', lang=result.transcription.language)}[/dim]")
712+ lang_label = t(
713+ "ai.language_label",
714+ lang=result.transcription.language,
715+ )
716+ console.print(f" [dim]{lang_label}[/dim]")
708717 if result.transcription.duration_seconds:
709- console.print(
710- f" [dim]{t('ai.speech_duration', duration=f'{result.transcription.duration_seconds:.1f}')}[/dim]"
718+ duration_str = (
719+ f"{result.transcription.duration_seconds:.1f}"
720+ )
721+ duration_label = t(
722+ "ai.speech_duration", duration=duration_str
711723 )
724+ console.print(f" [dim]{duration_label}[/dim]")
712725
713726 console.print()
714727 console.print(f"[bold green]{t('ai.response_label')}[/bold green]")
@@ -725,9 +738,11 @@ def voice(
725738
726739 if result.conversation_id:
727740 console.print()
728- console.print(
729- f"[dim]{t('ai.conversation_id_label', id=result.conversation_id[:8])}...[/dim]"
741+ conv_label = t(
742+ "ai.conversation_id_label",
743+ id=result.conversation_id[:8],
730744 )
745+ console.print(f"[dim]{conv_label}...[/dim]")
731746
732747 except KeyboardInterrupt:
733748 typer.echo(f"\n{t('ai.cancelled')}", err=True)
@@ -794,7 +809,12 @@ def record(
794809 sample_rate = int(device_info['default_samplerate'])
795810 channels = 1 # Mono
796811
797- console.print(f"[dim]{t('ai.using_mic', name=device_info['name'], rate=sample_rate)}[/dim]")
812+ mic_label = t(
813+ "ai.using_mic",
814+ name=device_info["name"],
815+ rate=sample_rate,
816+ )
817+ console.print(f"[dim]{mic_label}[/dim]")
798818
799819 # Determine output path
800820 if output:
@@ -850,8 +870,11 @@ def record(
850870 minutes = int(elapsed // 60)
851871 seconds = int(elapsed % 60)
852872 # Use regular print with \r for proper carriage return
873+ timer_str = (
874+ f"{minutes:02d}:{seconds:02d}"
875+ )
853876 print(
854- f"\r \033[91m●\033[0m Recording: {minutes:02d}:{seconds:02d }",
877+ f"\r \033[91m●\033[0m Recording: {timer_str }",
855878 end="",
856879 flush=True,
857880 )
@@ -880,7 +903,13 @@ def record(
880903 # Save to WAV file
881904 sf.write(str(audio_path), audio_data, sample_rate)
882905
883- console.print(f"[dim]{t('ai.audio_saved', path=str(audio_path), size=f'{audio_path.stat().st_size:,}')}[/dim]")
906+ size_str = f"{audio_path.stat().st_size:,}"
907+ saved_label = t(
908+ "ai.audio_saved",
909+ path=str(audio_path),
910+ size=size_str,
911+ )
912+ console.print(f"[dim]{saved_label}[/dim]")
884913
885914 # Read audio file
886915 with open(audio_path, "rb") as f:
@@ -949,9 +978,11 @@ def record(
949978
950979 if chat_result.metadata.get("conversation_id"):
951980 console.print()
952- console.print(
953- f"[dim]{t('ai.conversation_id_label', id=chat_result.metadata['conversation_id'][:8])}...[/dim]"
981+ conv_label = t(
982+ "ai.conversation_id_label",
983+ id=chat_result.metadata["conversation_id"][:8],
954984 )
985+ console.print(f"[dim]{conv_label}...[/dim]")
955986
956987 # Play TTS response if requested
957988 if voice_response:
@@ -1047,7 +1078,9 @@ def transcribe(
10471078 # Validate file exists
10481079 audio_path = Path(audio_file)
10491080 if not audio_path.exists():
1050- console.print(f"[red]{t('shared.error')}[/red] {t('ai.file_not_found', path=audio_file)}")
1081+ err_label = t("shared.error")
1082+ detail = t("ai.file_not_found", path=audio_file)
1083+ console.print(f"[red]{err_label}[/red] {detail}")
10511084 raise typer.Exit(1)
10521085
10531086 # Determine audio format
@@ -1056,7 +1089,9 @@ def transcribe(
10561089 audio_format = AudioFormat(ext)
10571090 except ValueError:
10581091 supported = ", ".join(f.value for f in AudioFormat)
1059- console.print(f"[red]{t('shared.error')}[/red] {t('ai.unsupported_format', ext=ext)}")
1092+ err_label = t("shared.error")
1093+ detail = t("ai.unsupported_format", ext=ext)
1094+ console.print(f"[red]{err_label}[/red] {detail}")
10601095 console.print(f"[dim]{t('ai.supported_formats', formats=supported)}[/dim]")
10611096 raise typer.Exit(1)
10621097
@@ -1208,7 +1243,11 @@ def speak(
12081243 console.print(f" [dim]{t('ai.speech_size', size=f'{len(result.audio):,}')}[/dim]")
12091244
12101245 if result.duration_seconds:
1211- console.print(f" [dim]{t('ai.speech_duration', duration=f'{result.duration_seconds:.1f}')}[/dim]")
1246+ duration_str = f"{result.duration_seconds:.1f}"
1247+ duration_label = t(
1248+ "ai.speech_duration", duration=duration_str
1249+ )
1250+ console.print(f" [dim]{duration_label}[/dim]")
12121251
12131252 except KeyboardInterrupt:
12141253 typer.echo(f"\n{t('ai.cancelled')}", err=True)
@@ -1362,12 +1401,20 @@ def usage(
13621401 # Display functions
13631402 def display_summary_panel(stats: UsageStatsResponse) -> None:
13641403 success_color = get_success_color(stats.success_rate)
1404+ tokens_label = t("ai.usage_total_tokens")
1405+ cost_label = t("ai.usage_total_cost")
1406+ requests_label = t("ai.usage_total_requests")
1407+ rate_label = t("ai.usage_success_rate")
1408+ tokens_str = format_number(stats.total_tokens)
1409+ cost_str = format_cost(stats.total_cost)
1410+ requests_str = format_number(stats.total_requests)
1411+ rate_str = format_percentage(stats.success_rate)
13651412 summary_lines = [
1366- f"[bold cyan]{t('ai.usage_total_tokens') }[/bold cyan] {format_number(stats.total_tokens) }",
1367- f"[bold cyan]{t('ai.usage_total_cost') }[/bold cyan] {format_cost(stats.total_cost) }",
1368- f"[bold cyan]{t('ai.usage_total_requests') }[/bold cyan] {format_number(stats.total_requests) }",
1369- f"[bold cyan]{t('ai.usage_success_rate') }[/bold cyan] "
1370- f"[{success_color}]{format_percentage(stats.success_rate) }[/{success_color}]",
1413+ f"[bold cyan]{tokens_label }[/bold cyan] {tokens_str }",
1414+ f"[bold cyan]{cost_label }[/bold cyan] {cost_str }",
1415+ f"[bold cyan]{requests_label }[/bold cyan] {requests_str }",
1416+ f"[bold cyan]{rate_label }[/bold cyan] "
1417+ f"[{success_color}]{rate_str }[/{success_color}]",
13711418 ]
13721419 console.print(
13731420 Panel(
@@ -1388,8 +1435,14 @@ def usage(
13881435 console.print(f"\n[bold blue]{t('ai.token_breakdown')}[/bold blue]")
13891436 input_str = format_number(stats.input_tokens)
13901437 output_str = format_number(stats.output_tokens)
1391- console.print(f" [cyan]{t('ai.input_tokens')}[/cyan] {input_str:>12} ({input_pct:.0f}%)")
1392- console.print(f" [cyan]{t('ai.output_tokens')}[/cyan] {output_str:>12} ({output_pct:.0f}%)")
1438+ in_label = t("ai.input_tokens")
1439+ out_label = t("ai.output_tokens")
1440+ console.print(
1441+ f" [cyan]{in_label}[/cyan] {input_str:>12} ({input_pct:.0f}%)"
1442+ )
1443+ console.print(
1444+ f" [cyan]{out_label}[/cyan] {output_str:>12} ({output_pct:.0f}%)"
1445+ )
13931446 bar_width = 40
13941447 input_bars = int((input_pct / 100) * bar_width)
13951448 output_bars = bar_width - input_bars
@@ -1646,15 +1699,24 @@ async def _interactive_chat_session(
16461699 ai_config = get_ai_config(settings)
16471700
16481701 console.print()
1649- console.print(f"[bold bright_magenta]Illiana[/bold bright_magenta] [dim]v{__aegis_version__}[/dim]")
1702+ banner = (
1703+ f"[bold bright_magenta]Illiana[/bold bright_magenta] "
1704+ f"[dim]v{__aegis_version__}[/dim]"
1705+ )
1706+ console.print(banner)
16501707 console.print()
16511708
16521709 # Boot steps with brief delays for effect
16531710 console.print(f" [dim]>[/dim] {t('ai.initializing')}", end="")
16541711 await asyncio.sleep(0.15)
16551712 console.print(f" [green]{t('ai.ok')}[/green]")
16561713
1657- console.print(f" [dim]>[/dim] {t('ai.connecting_to', provider=get_provider_display_name(ai_config.provider))}", end="")
1714+ provider_name = get_provider_display_name(ai_config.provider)
1715+ connecting_label = t("ai.connecting_to", provider=provider_name)
1716+ console.print(
1717+ f" [dim]>[/dim] {connecting_label}",
1718+ end="",
1719+ )
16581720 # Warm up the agent (lazy imports, model initialization)
16591721 from app.services.ai.providers import get_agent
16601722 _ = get_agent(ai_config, settings)
@@ -1694,7 +1756,12 @@ async def _interactive_chat_session(
16941756 console.print(f"[green]{t('ai.health_ok', pct=health_pct)}[/green]")
16951757 else:
16961758 unhealthy_count = len(status.unhealthy_components)
1697- console.print(f"[yellow]{t('ai.health_degraded', pct=health_pct, count=unhealthy_count)}[/yellow]")
1759+ degraded_label = t(
1760+ "ai.health_degraded",
1761+ pct=health_pct,
1762+ count=unhealthy_count,
1763+ )
1764+ console.print(f"[yellow]{degraded_label}[/yellow]")
16981765 except Exception:
16991766 console.print(f"[dim]{t('ai.health_na')}[/dim]")
17001767
@@ -1948,9 +2015,15 @@ async def _interactive_chat_session(
19482015 except ProviderNotInstalledError as e:
19492016 # Clean display for missing provider
19502017 console.print()
1951- console.print(f"[yellow]{t('ai.provider_not_installed', provider=e.provider)}[/yellow]")
2018+ missing_label = t(
2019+ "ai.provider_not_installed", provider=e.provider
2020+ )
2021+ console.print(f"[yellow]{missing_label}[/yellow]")
19522022 console.print()
1953- console.print(f"[green]{t('ai.run_to_install', command=e.cli_command)}[/green]")
2023+ install_label = t(
2024+ "ai.run_to_install", command=e.cli_command
2025+ )
2026+ console.print(f"[green]{install_label}[/green]")
19542027 console.print()
19552028 except Exception as stream_error:
19562029 console.print(f"[red]{t('shared.error')} {stream_error}[/red]")
@@ -2156,9 +2229,13 @@ async def _stream_chat_response(
21562229 except ProviderNotInstalledError as e:
21572230 # Clean display for missing provider - no need to re-raise
21582231 console.print()
2159- console.print(f"[yellow]{t('ai.provider_not_installed', provider=e.provider)}[/yellow]")
2232+ missing_label = t(
2233+ "ai.provider_not_installed", provider=e.provider
2234+ )
2235+ console.print(f"[yellow]{missing_label}[/yellow]")
21602236 console.print()
2161- console.print(f"[green]{t('ai.run_to_install', command=e.cli_command)}[/green]")
2237+ install_label = t("ai.run_to_install", command=e.cli_command)
2238+ console.print(f"[green]{install_label}[/green]")
21622239 console.print()
21632240 return None
21642241
0 commit comments