Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions src/tau_coding/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,13 @@ def main(
"(text, json, or transcript).",
),
] = None,
auto_name_session: Annotated[
bool,
typer.Option(
"--auto-name-session/--no-auto-name-session",
help="Enable/disable automatic session naming in print mode.",
),
] = False,
output: Annotated[
PrintOutputMode | None,
typer.Option(
Expand Down Expand Up @@ -391,15 +398,16 @@ def main(
try:
ok = anyio.run(
run_openai_print_mode,
prompt,
model,
cwd or Path.cwd(),
effective_output,
provider,
None,
extension_paths,
not no_extensions,
project_extensions,
prompt=prompt,
model=model,
cwd=cwd or Path.cwd(),
output=effective_output,
provider_name=provider,
session_manager=None,
extension_paths=extension_paths,
extensions_enabled=not no_extensions,
project_extensions_enabled=project_extensions,
auto_name_session=auto_name_session,
)
except (RuntimeError, ValueError) as exc:
raise typer.BadParameter(str(exc)) from exc
Expand Down Expand Up @@ -436,6 +444,7 @@ async def run_openai_tui(
extension_paths=extension_paths,
extensions_enabled=extensions_enabled,
project_extensions_enabled=project_extensions_enabled,
tui_settings=None, # Will load defaults in run_tui_app
)


Expand Down Expand Up @@ -655,6 +664,7 @@ async def run_openai_print_mode(
extension_paths: tuple[Path, ...] = (),
extensions_enabled: bool = True,
project_extensions_enabled: bool = False,
auto_name_session: bool = False,
) -> bool:
"""Run print mode with the OpenAI-compatible provider configured from the environment."""
settings = load_provider_settings()
Expand Down Expand Up @@ -684,6 +694,7 @@ async def run_openai_print_mode(
extension_paths=extension_paths,
extensions_enabled=extensions_enabled,
project_extensions_enabled=project_extensions_enabled,
auto_name_session=auto_name_session,
)
finally:
await provider.aclose()
Expand All @@ -707,6 +718,7 @@ async def run_print_mode(
extension_paths: tuple[Path, ...] = (),
extensions_enabled: bool = True,
project_extensions_enabled: bool = False,
auto_name_session: bool = False,
) -> bool:
"""Run one non-interactive prompt and print streamed events.

Expand All @@ -729,6 +741,7 @@ async def run_print_mode(
extension_paths=extension_paths,
extensions_enabled=extensions_enabled,
project_extensions_enabled=project_extensions_enabled,
auto_name_session=auto_name_session,
)
)
session.extension_runtime.set_ui_bridge(StderrUiBridge())
Expand Down
9 changes: 9 additions & 0 deletions src/tau_coding/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ class CodingSessionConfig:
extensions_enabled: bool = True
project_extensions_enabled: bool = False
extension_runtime: ExtensionRuntime | None = None
auto_name_session: bool = True


class CodingSession:
Expand Down Expand Up @@ -278,6 +279,7 @@ def __init__(
self._resource_paths = resource_paths_with_cwd(config.resource_paths, config.cwd)
self._auto_compact_token_threshold = config.auto_compact_token_threshold
self._auto_compact_enabled = config.auto_compact_enabled
self._auto_name_session = config.auto_name_session
self._thinking_level = _state_thinking_level(
state,
default=_default_thinking_level_for_active_model(self),
Expand Down Expand Up @@ -1300,6 +1302,7 @@ async def resume(self, session_id: str) -> str:
runtime_provider_config=runtime_provider_config,
auto_compact_token_threshold=self._auto_compact_token_threshold,
auto_compact_enabled=self._auto_compact_enabled,
auto_name_session=self._auto_name_session,
thinking_level=self._thinking_level,
shell_command_prefix=self._config.shell_command_prefix,
skills_enabled=self._config.skills_enabled,
Expand Down Expand Up @@ -1882,6 +1885,10 @@ async def _try_auto_name_session(
context: AgentCallDiagnosticContext,
) -> None:
if not self._should_auto_name_session():
# When auto-naming is disabled, use first 4 words of the user message
title = _fallback_session_name(first_message)
if title:
self._set_auto_session_title(title)
return
try:
title = await self._generate_session_name(first_message)
Expand All @@ -1899,6 +1906,8 @@ async def _try_auto_name_session(
self._set_auto_session_title(title)

def _should_auto_name_session(self) -> bool:
if not self._auto_name_session:
return False
if self._config.session_id is None or self._config.session_manager is None:
return False
record = self._config.session_manager.get_session(self._config.session_id)
Expand Down
4 changes: 4 additions & 0 deletions src/tau_coding/tui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4479,6 +4479,7 @@ def _replace_tui_settings(self, *, theme: TuiThemeName) -> None:
keybindings=self.tui_settings.keybindings,
theme=theme,
auto_copy_selection=self.tui_settings.auto_copy_selection,
auto_name_session=self.tui_settings.auto_name_session,
sidebar_position=self.tui_settings.sidebar_position,
turn_notification=self.tui_settings.turn_notification,
)
Expand Down Expand Up @@ -6604,6 +6605,7 @@ async def run_tui_app(
extension_paths: tuple[Path, ...] = (),
extensions_enabled: bool = True,
project_extensions_enabled: bool = False,
tui_settings: TuiSettings | None = None,
) -> str | None:
"""Run the Textual app and return the active id when its session is persisted."""
if new_session and session_id is not None:
Expand All @@ -6612,6 +6614,7 @@ async def run_tui_app(
provider_settings = load_provider_settings()
shell_settings = load_shell_settings()
manager = session_manager or SessionManager()
effective_tui_settings = tui_settings or load_tui_settings()
record = _explicit_resume_record(
manager,
session_id=session_id,
Expand Down Expand Up @@ -6677,6 +6680,7 @@ async def run_tui_app(
extension_paths=extension_paths,
extensions_enabled=extensions_enabled,
project_extensions_enabled=project_extensions_enabled,
auto_name_session=effective_tui_settings.auto_name_session,
)
)
custom_themes, theme_diagnostics = load_custom_tui_themes(
Expand Down
6 changes: 6 additions & 0 deletions src/tau_coding/tui/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,13 @@ class TuiSettings:
auto_copy_selection: bool = False
sidebar_position: Literal["left", "right", "off"] = "right"
turn_notification: TurnNotificationMode = "desktop"
auto_name_session: bool = True

def to_json(self) -> dict[str, Any]:
"""Serialize these settings to JSON-compatible data."""
return {
"auto_copy_selection": self.auto_copy_selection,
"auto_name_session": self.auto_name_session,
"keybindings": self.keybindings.to_json(),
"sidebar_position": self.sidebar_position,
"theme": self.theme,
Expand Down Expand Up @@ -161,6 +163,10 @@ def tui_settings_from_json(data: dict[str, Any]) -> TuiSettings:
data.get("auto_copy_selection", False),
"auto_copy_selection",
),
auto_name_session=_bool_setting(
data.get("auto_name_session", True),
"auto_name_session",
),
sidebar_position=cast(Literal["left", "right", "off"], raw_sidebar),
turn_notification=cast(TurnNotificationMode, raw_notification),
)
Expand Down