Merge pull request #166 from ggozad/fix/init-config
Fix `init-config` command generating invalid configuration files
This commit is contained in:
commit
7876830eca
17 changed files with 87 additions and 77 deletions
|
|
@ -1,6 +1,12 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **Configuration**: Fixed `init-config` command generating invalid configuration files (#165)
|
||||||
|
- Refactored `generate_default_config()` to use Pydantic model serialization instead of manual dict construction
|
||||||
|
- Updated `qa`, `research`, and `reranking` sections to use new `ModelConfig` structure
|
||||||
|
|
||||||
## [0.19.0] - 2025-11-25
|
## [0.19.0] - 2025-11-25
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ haiku-rag rebuild
|
||||||
haiku-rag serve --monitor
|
haiku-rag serve --monitor
|
||||||
```
|
```
|
||||||
|
|
||||||
To customize settings, create a `haiku.rag.yaml` config file (see [Configuration](https://ggozad.github.io/haiku.rag/config-index/)).
|
To customize settings, create a `haiku.rag.yaml` config file (see [Configuration](https://ggozad.github.io/haiku.rag/configuration/)).
|
||||||
|
|
||||||
## Python Usage
|
## Python Usage
|
||||||
|
|
||||||
|
|
@ -162,7 +162,7 @@ See the [examples directory](examples/) for working examples:
|
||||||
Full documentation at: https://ggozad.github.io/haiku.rag/
|
Full documentation at: https://ggozad.github.io/haiku.rag/
|
||||||
|
|
||||||
- [Installation](https://ggozad.github.io/haiku.rag/installation/) - Provider setup
|
- [Installation](https://ggozad.github.io/haiku.rag/installation/) - Provider setup
|
||||||
- [Configuration](https://ggozad.github.io/haiku.rag/config-index/) - YAML configuration
|
- [Configuration](https://ggozad.github.io/haiku.rag/configuration/) - YAML configuration
|
||||||
- [CLI](https://ggozad.github.io/haiku.rag/cli/) - Command reference
|
- [CLI](https://ggozad.github.io/haiku.rag/cli/) - Command reference
|
||||||
- [Python API](https://ggozad.github.io/haiku.rag/python/) - Complete API docs
|
- [Python API](https://ggozad.github.io/haiku.rag/python/) - Complete API docs
|
||||||
- [Agents](https://ggozad.github.io/haiku.rag/agents/) - QA agent and multi-agent research
|
- [Agents](https://ggozad.github.io/haiku.rag/agents/) - QA agent and multi-agent research
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ haiku-rag add-src /path/to/documents/
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
When adding a directory, the same content filters configured for [file monitoring](processing.md#filtering-monitored-files) are applied. This means `ignore_patterns` and `include_patterns` from your configuration will be used to filter which files are added.
|
When adding a directory, the same content filters configured for [file monitoring](configuration/processing.md#filtering-monitored-files) are applied. This means `ignore_patterns` and `include_patterns` from your configuration will be used to filter which files are added.
|
||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
As you add documents to `haiku.rag` the database keeps growing. By default, LanceDB supports versioning
|
As you add documents to `haiku.rag` the database keeps growing. By default, LanceDB supports versioning
|
||||||
|
|
@ -158,7 +158,7 @@ haiku-rag research "How does haiku.rag organize and query documents?" --verbose
|
||||||
Flags:
|
Flags:
|
||||||
- `--verbose`: Show planning, searching previews, evaluation summary, and stop reason
|
- `--verbose`: Show planning, searching previews, evaluation summary, and stop reason
|
||||||
|
|
||||||
Research parameters like `max_iterations`, `confidence_threshold`, and `max_concurrency` are configured in your [configuration file](config-index.md) under the `research` section.
|
Research parameters like `max_iterations`, `confidence_threshold`, and `max_concurrency` are configured in your [configuration file](configuration/index.md) under the `research` section.
|
||||||
|
|
||||||
When `--verbose` is set, the CLI consumes the research graph's AG-UI event stream, displaying step events and activity snapshots as agents progress through planning, search, evaluation, and synthesis. Without `--verbose`, only the final research report is displayed.
|
When `--verbose` is set, the CLI consumes the research graph's AG-UI event stream, displaying step events and activity snapshots as agents progress through planning, search, evaluation, and synthesis. Without `--verbose`, only the final research report is displayed.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
Configuration is done through YAML configuration files.
|
Configuration is done through YAML configuration files.
|
||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
If you create a db with certain settings and later change them, `haiku.rag` will detect incompatibilities (for example, if you change embedding provider) and will exit. You can **rebuild** the database to apply the new settings, see [Rebuild Database](./cli.md#rebuild-database).
|
If you create a db with certain settings and later change them, `haiku.rag` will detect incompatibilities (for example, if you change embedding provider) and will exit. You can **rebuild** the database to apply the new settings, see [Rebuild Database](../cli.md#rebuild-database).
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
|
|
@ -92,7 +92,7 @@ conversion_options:
|
||||||
|
|
||||||
- Offloads processing to docling-serve API
|
- Offloads processing to docling-serve API
|
||||||
- Better for heavy workloads and production
|
- Better for heavy workloads and production
|
||||||
- Requires docling-serve instance (see [Remote processing setup](remote-processing.md))
|
- Requires docling-serve instance (see [Remote processing setup](../remote-processing.md))
|
||||||
|
|
||||||
To use remote processing:
|
To use remote processing:
|
||||||
|
|
||||||
|
|
@ -68,4 +68,4 @@ The server exposes:
|
||||||
- `GET /health` - Health check endpoint
|
- `GET /health` - Health check endpoint
|
||||||
- `POST /v1/agent/stream` - Research graph streaming endpoint (Server-Sent Events)
|
- `POST /v1/agent/stream` - Research graph streaming endpoint (Server-Sent Events)
|
||||||
|
|
||||||
See [Server Mode](server.md) for more details.
|
See [Server Mode](../server.md) for more details.
|
||||||
|
|
@ -55,7 +55,7 @@ haiku-rag ask "Who is the author of haiku.rag?"
|
||||||
|
|
||||||
- [Getting started](tutorial.md) - Tutorial
|
- [Getting started](tutorial.md) - Tutorial
|
||||||
- [Installation](installation.md) - Install haiku.rag with different providers
|
- [Installation](installation.md) - Install haiku.rag with different providers
|
||||||
- [Configuration](config-index.md) - Environment variables and settings
|
- [Configuration](configuration/index.md) - Environment variables and settings
|
||||||
- [CLI](cli.md) - Command line interface usage
|
- [CLI](cli.md) - Command line interface usage
|
||||||
- [Server](server.md) - File monitoring and server mode
|
- [Server](server.md) - File monitoring and server mode
|
||||||
- [MCP](mcp.md) - Model Context Protocol integration
|
- [MCP](mcp.md) - Model Context Protocol integration
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ The slim package has minimal dependencies and lets you install only what you nee
|
||||||
- **OpenAI** (GPT models for QA and embeddings)
|
- **OpenAI** (GPT models for QA and embeddings)
|
||||||
- **Anthropic** (Claude models for QA)
|
- **Anthropic** (Claude models for QA)
|
||||||
|
|
||||||
See [Configuration](config-index.md) for configuring providers including advanced options like vLLM.
|
See [Configuration](configuration/index.md) for configuring providers including advanced options like vLLM.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
|
|
@ -71,7 +71,7 @@ When using `haiku.rag-slim`, you can skip installing the `docling` extra and ins
|
||||||
- Offloading heavy document processing to a dedicated service
|
- Offloading heavy document processing to a dedicated service
|
||||||
- Production deployments with separate processing infrastructure
|
- Production deployments with separate processing infrastructure
|
||||||
|
|
||||||
See [Remote processing](remote-processing.md) for setup instructions and [Document Processing](processing.md) for configuration options.
|
See [Remote processing](remote-processing.md) for setup instructions and [Document Processing](configuration/processing.md) for configuration options.
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -321,6 +321,6 @@ answer = await client.ask(
|
||||||
|
|
||||||
The QA agent will search your documents for relevant information and use the configured LLM to generate a comprehensive answer. With `cite=True`, responses include citations showing which documents were used as sources. Citations prefer the document title when present, otherwise they use the URI.
|
The QA agent will search your documents for relevant information and use the configured LLM to generate a comprehensive answer. With `cite=True`, responses include citations showing which documents were used as sources. Citations prefer the document title when present, otherwise they use the URI.
|
||||||
|
|
||||||
The QA provider and model are configured in `haiku.rag.yaml` or can be passed directly to the client (see [Configuration](config-index.md)).
|
The QA provider and model are configured in `haiku.rag.yaml` or can be passed directly to the client (see [Configuration](configuration/index.md)).
|
||||||
|
|
||||||
See also: [Agents](agents.md) for details on the QA agent and the multi‑agent research workflow.
|
See also: [Agents](agents.md) for details on the QA agent and the multi‑agent research workflow.
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ docker run -p 5001:5001 -e DOCLING_SERVE_ENABLE_UI=1 quay.io/docling-project/doc
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
Configure haiku.rag to use docling-serve. See the [Document Processing](processing.md) guide for all available options.
|
Configure haiku.rag to use docling-serve. See the [Document Processing](configuration/processing.md) guide for all available options.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# haiku.rag.yaml
|
# haiku.rag.yaml
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ agui:
|
||||||
cors_credentials: true
|
cors_credentials: true
|
||||||
```
|
```
|
||||||
|
|
||||||
See [Configuration](qa-research.md#ag-ui-server-configuration) for all available options.
|
See [Configuration](configuration/qa-research.md#ag-ui-server-configuration) for all available options.
|
||||||
|
|
||||||
### Using the Streaming Endpoints
|
### Using the Streaming Endpoints
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ export OPENAI_API_KEY="<your OpenAI API key>"
|
||||||
|
|
||||||
For the list of available OpenAI models and their vector dimensions, see the [OpenAI documentation](https://platform.openai.com/docs/guides/embeddings).
|
For the list of available OpenAI models and their vector dimensions, see the [OpenAI documentation](https://platform.openai.com/docs/guides/embeddings).
|
||||||
|
|
||||||
See [Configuration](config-index.md) for all available options.
|
See [Configuration](configuration/index.md) for all available options.
|
||||||
|
|
||||||
## Adding the first documents
|
## Adding the first documents
|
||||||
|
|
||||||
|
|
@ -216,4 +216,4 @@ The following people are presenting talks at PyCon Finland 2025:
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
See [Configuration page](./config-index.md) for complete documentation on YAML configuration and all available options.
|
See [Configuration page](./configuration/index.md) for complete documentation on YAML configuration and all available options.
|
||||||
|
|
|
||||||
|
|
@ -48,47 +48,8 @@ def load_yaml_config(path: Path) -> dict:
|
||||||
|
|
||||||
|
|
||||||
def generate_default_config() -> dict:
|
def generate_default_config() -> dict:
|
||||||
"""Generate a default YAML config structure with documentation."""
|
"""Generate a default YAML config structure from AppConfig defaults."""
|
||||||
return {
|
from haiku.rag.config.models import AppConfig
|
||||||
"environment": "production",
|
|
||||||
"storage": {
|
default_config = AppConfig()
|
||||||
"data_dir": "",
|
return default_config.model_dump(mode="json", exclude_none=False)
|
||||||
"vacuum_retention_seconds": 86400,
|
|
||||||
},
|
|
||||||
"monitor": {
|
|
||||||
"directories": [],
|
|
||||||
"ignore_patterns": [],
|
|
||||||
"include_patterns": [],
|
|
||||||
},
|
|
||||||
"lancedb": {"uri": "", "api_key": "", "region": ""},
|
|
||||||
"embeddings": {
|
|
||||||
"provider": "ollama",
|
|
||||||
"model": "qwen3-embedding:4b",
|
|
||||||
"vector_dim": 2560,
|
|
||||||
},
|
|
||||||
"reranking": {"provider": "", "model": ""},
|
|
||||||
"qa": {"provider": "ollama", "model": "gpt-oss"},
|
|
||||||
"research": {"provider": "", "model": ""},
|
|
||||||
"processing": {
|
|
||||||
"chunk_size": 256,
|
|
||||||
"context_chunk_radius": 0,
|
|
||||||
"markdown_preprocessor": "",
|
|
||||||
},
|
|
||||||
"providers": {
|
|
||||||
"ollama": {"base_url": "http://localhost:11434"},
|
|
||||||
"vllm": {
|
|
||||||
"embeddings_base_url": "",
|
|
||||||
"rerank_base_url": "",
|
|
||||||
"qa_base_url": "",
|
|
||||||
"research_base_url": "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"agui": {
|
|
||||||
"host": "0.0.0.0",
|
|
||||||
"port": 8000,
|
|
||||||
"cors_origins": ["*"],
|
|
||||||
"cors_credentials": True,
|
|
||||||
"cors_methods": ["GET", "POST", "OPTIONS"],
|
|
||||||
"cors_headers": ["*"],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
|
||||||
10
mkdocs.yml
10
mkdocs.yml
|
|
@ -60,11 +60,11 @@ nav:
|
||||||
- Getting started: tutorial.md
|
- Getting started: tutorial.md
|
||||||
- Installation: installation.md
|
- Installation: installation.md
|
||||||
- Configuration:
|
- Configuration:
|
||||||
- config-index.md
|
- configuration/index.md
|
||||||
- Providers: providers.md
|
- Providers: configuration/providers.md
|
||||||
- QA and Research: qa-research.md
|
- QA and Research: configuration/qa-research.md
|
||||||
- Document Processing: processing.md
|
- Document Processing: configuration/processing.md
|
||||||
- Storage: storage.md
|
- Storage: configuration/storage.md
|
||||||
- CLI: cli.md
|
- CLI: cli.md
|
||||||
- Python: python.md
|
- Python: python.md
|
||||||
- Agents: agents.md
|
- Agents: agents.md
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
from haiku.rag.config import AppConfig
|
||||||
from haiku.rag.config.loader import (
|
from haiku.rag.config.loader import (
|
||||||
find_config_file,
|
find_config_file,
|
||||||
generate_default_config,
|
generate_default_config,
|
||||||
|
|
@ -98,19 +100,6 @@ def test_find_config_file_cli_path_not_exists(tmp_path):
|
||||||
find_config_file(config_file)
|
find_config_file(config_file)
|
||||||
|
|
||||||
|
|
||||||
def test_generate_default_config():
|
|
||||||
"""Test generating default config structure."""
|
|
||||||
config = generate_default_config()
|
|
||||||
|
|
||||||
assert config["environment"] == "production"
|
|
||||||
assert "storage" in config
|
|
||||||
assert "embeddings" in config
|
|
||||||
assert "qa" in config
|
|
||||||
assert "providers" in config
|
|
||||||
assert config["embeddings"]["provider"] == "ollama"
|
|
||||||
assert config["embeddings"]["vector_dim"] == 2560
|
|
||||||
|
|
||||||
|
|
||||||
def test_config_precedence_cwd_over_user(tmp_path, monkeypatch):
|
def test_config_precedence_cwd_over_user(tmp_path, monkeypatch):
|
||||||
"""Test that cwd config takes precedence over user config."""
|
"""Test that cwd config takes precedence over user config."""
|
||||||
# Create separate directories for cwd and user config
|
# Create separate directories for cwd and user config
|
||||||
|
|
@ -163,3 +152,57 @@ def test_config_precedence_env_var_over_cwd(tmp_path, monkeypatch):
|
||||||
|
|
||||||
config = load_yaml_config(found)
|
config = load_yaml_config(found)
|
||||||
assert config["environment"] == "from-env-var"
|
assert config["environment"] == "from-env-var"
|
||||||
|
|
||||||
|
|
||||||
|
def test_generate_default_config_completeness():
|
||||||
|
"""Test that generated config has all fields from AppConfig and validates."""
|
||||||
|
config_data = generate_default_config()
|
||||||
|
|
||||||
|
# Validate against AppConfig model
|
||||||
|
config = AppConfig.model_validate(config_data)
|
||||||
|
|
||||||
|
# Get all fields from AppConfig
|
||||||
|
expected_fields = set(AppConfig.model_fields.keys())
|
||||||
|
actual_fields = set(config_data.keys())
|
||||||
|
|
||||||
|
# Verify all expected fields are present
|
||||||
|
assert expected_fields == actual_fields, (
|
||||||
|
f"Missing fields: {expected_fields - actual_fields}, "
|
||||||
|
f"Extra fields: {actual_fields - expected_fields}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify nested structures are dicts/lists, not model instances
|
||||||
|
for field_name, field_value in config_data.items():
|
||||||
|
assert not hasattr(field_value, "model_dump"), (
|
||||||
|
f"Field {field_name} should be dict/primitive, not Pydantic model"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify config validates successfully
|
||||||
|
assert config.environment == "production"
|
||||||
|
assert config.embeddings.provider == "ollama"
|
||||||
|
assert config.qa.model.provider == "ollama"
|
||||||
|
assert config.research.model.provider == "ollama"
|
||||||
|
assert config.reranking.model is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_config_creates_valid_yaml(tmp_path):
|
||||||
|
"""Test that generated config can be written to YAML and loaded back."""
|
||||||
|
config_file = tmp_path / "test-config.yaml"
|
||||||
|
|
||||||
|
# Generate and write config
|
||||||
|
config_data = generate_default_config()
|
||||||
|
|
||||||
|
with open(config_file, "w") as f:
|
||||||
|
f.write("# haiku.rag configuration file\n")
|
||||||
|
f.write(
|
||||||
|
"# See https://ggozad.github.io/haiku.rag/configuration/ for details\n\n"
|
||||||
|
)
|
||||||
|
yaml.dump(config_data, f, default_flow_style=False, sort_keys=False)
|
||||||
|
|
||||||
|
# Load it back
|
||||||
|
with open(config_file) as f:
|
||||||
|
loaded_data = yaml.safe_load(f)
|
||||||
|
|
||||||
|
# Validate it
|
||||||
|
config = AppConfig.model_validate(loaded_data)
|
||||||
|
assert config.environment == "production"
|
||||||
Loading…
Reference in a new issue