Show the configuration in the shape a config file has

`settings` printed each top-level block as one Python dict repr, so nesting
was invisible, long paths wrapped mid-token and `PosixPath(...)` leaked. It
renders as YAML now, which is what `haiku.rag.yaml` is written in.
This commit is contained in:
Yiorgis Gozadinos 2026-08-26 16:18:23 +03:00
parent ab0bdff14c
commit b76c5c7db0
No known key found for this signature in database
2 changed files with 70 additions and 6 deletions

View file

@ -834,16 +834,26 @@ class HaikuRAGApp:
)
def show_settings(self):
"""Display current configuration settings."""
"""Display current configuration settings.
As YAML, which is the shape `haiku.rag.yaml` is written in, so what is
read here is what would be written there. `mode="json"` keeps paths and
enums out of their Python reprs.
"""
import yaml
self.console.print("[bold]haiku.rag configuration[/bold]")
self.console.print()
# redact_secrets walks the whole dump: masking only top-level names left
# nested api keys, tokens and source passwords printed in full.
for field_name, field_value in redact_secrets(self.config.model_dump()).items():
self.console.print(
f" [repr.attrib_name]{field_name}[/repr.attrib_name]: {field_value}"
)
dumped = redact_secrets(self.config.model_dump(mode="json"))
# Preserve YAML values and line structure through Rich rendering.
self.console.print(
yaml.safe_dump(dumped, default_flow_style=False, sort_keys=False).rstrip(),
markup=False,
soft_wrap=True,
)
def _rich_print_document(self, doc: Document, truncate: bool = False):
"""Format a document for display."""

View file

@ -11,7 +11,12 @@ from rich.console import Console
from haiku.rag.app import HaikuRAGApp
from haiku.rag.client import RebuildMode
from haiku.rag.config.models import AppConfig, LanceDBConfig
from haiku.rag.config.models import (
AppConfig,
LanceDBConfig,
PromptsConfig,
StorageConfig,
)
from haiku.rag.store.models.chunk import Chunk, SearchResult
from haiku.rag.store.models.document import Document
from tests.conftest import for_path
@ -362,6 +367,55 @@ def test_show_settings_hides_secrets(tmp_path):
assert "secret-value" not in printed
def test_show_settings_renders_the_shape_a_config_file_has(tmp_path):
"""Nesting is indented rather than flattened into one dict repr per block,
and a path is its string rather than its Python repr, so what is read here
is what would be written into `haiku.rag.yaml`."""
import yaml
config = AppConfig(
lancedb=LanceDBConfig(databases={"alpha": "/tmp/a.lancedb"}),
storage=StorageConfig(data_dir=tmp_path),
)
app = HaikuRAGApp(scope=for_path(tmp_path / "db", config), config=config)
app.console = Console(record=True, width=200)
app.show_settings()
printed = app.console.export_text()
assert "PosixPath" not in printed
# A Python dict repr parses as YAML flow style, so parsing alone does not
# distinguish a block per field from one flattened repr per field.
assert "{'" not in printed
assert "\n alpha: /tmp/a.lancedb" in printed
body = printed.split("haiku.rag configuration", 1)[1]
parsed = yaml.safe_load(body)
assert parsed["lancedb"]["databases"] == {"alpha": "/tmp/a.lancedb"}
assert parsed["storage"]["data_dir"] == str(tmp_path)
def test_show_settings_survives_a_narrow_console_and_bracketed_values(tmp_path):
"""Rich reads `[...]` as markup and wraps to the terminal, so a prompt
carrying an instruction tag rendered away or raised, and a long path was
broken across lines into something that no longer parsed."""
import yaml
long_dir = tmp_path / "Application Support" / "haiku.rag" / "collections" / "one"
config = AppConfig(
storage=StorageConfig(data_dir=long_dir),
prompts=PromptsConfig(domain_preamble="[INST] keep this [/INST]"),
)
app = HaikuRAGApp(scope=for_path(long_dir / "db", config), config=config)
app.console = Console(record=True, width=60)
app.show_settings()
body = app.console.export_text().split("haiku.rag configuration", 1)[1]
parsed = yaml.safe_load(body)
assert parsed["prompts"]["domain_preamble"] == "[INST] keep this [/INST]"
assert parsed["storage"]["data_dir"] == str(long_dir)
def test_remote_uri_is_the_display_path(tmp_path):
config = AppConfig(lancedb=LanceDBConfig(uri="s3://bucket/path"))
app = HaikuRAGApp(scope=for_path(None, config), config=config)