Move monitor config in its own section
This commit is contained in:
parent
e6e3273cae
commit
ad1ee52a27
8 changed files with 64 additions and 60 deletions
|
|
@ -55,14 +55,16 @@ environment: production
|
||||||
|
|
||||||
storage:
|
storage:
|
||||||
data_dir: "" # Empty = use default platform location
|
data_dir: "" # Empty = use default platform location
|
||||||
monitor_directories:
|
|
||||||
- /path/to/documents
|
|
||||||
- /another/path
|
|
||||||
monitor_ignore_patterns: [] # Gitignore-style patterns to exclude
|
|
||||||
monitor_include_patterns: [] # Gitignore-style patterns to include
|
|
||||||
disable_autocreate: false
|
disable_autocreate: false
|
||||||
vacuum_retention_seconds: 60
|
vacuum_retention_seconds: 60
|
||||||
|
|
||||||
|
monitor:
|
||||||
|
directories:
|
||||||
|
- /path/to/documents
|
||||||
|
- /another/path
|
||||||
|
ignore_patterns: [] # Gitignore-style patterns to exclude
|
||||||
|
include_patterns: [] # Gitignore-style patterns to include
|
||||||
|
|
||||||
lancedb:
|
lancedb:
|
||||||
uri: "" # Empty for local, or db://, s3://, az://, gs://
|
uri: "" # Empty for local, or db://, s3://, az://, gs://
|
||||||
api_key: ""
|
api_key: ""
|
||||||
|
|
@ -163,8 +165,8 @@ export OLLAMA_BASE_URL=http://localhost:11434
|
||||||
Set directories to monitor for automatic indexing:
|
Set directories to monitor for automatic indexing:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
storage:
|
monitor:
|
||||||
monitor_directories:
|
directories:
|
||||||
- /path/to/documents
|
- /path/to/documents
|
||||||
- /another_path/to/documents
|
- /another_path/to/documents
|
||||||
```
|
```
|
||||||
|
|
@ -174,19 +176,19 @@ storage:
|
||||||
Use gitignore-style patterns to control which files are monitored:
|
Use gitignore-style patterns to control which files are monitored:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
storage:
|
monitor:
|
||||||
monitor_directories:
|
directories:
|
||||||
- /path/to/documents
|
- /path/to/documents
|
||||||
|
|
||||||
# Exclude specific files or directories
|
# Exclude specific files or directories
|
||||||
monitor_ignore_patterns:
|
ignore_patterns:
|
||||||
- "*draft*" # Ignore files with "draft" in the name
|
- "*draft*" # Ignore files with "draft" in the name
|
||||||
- "temp/" # Ignore temp directory
|
- "temp/" # Ignore temp directory
|
||||||
- "**/archive/**" # Ignore all archive directories
|
- "**/archive/**" # Ignore all archive directories
|
||||||
- "*.backup" # Ignore backup files
|
- "*.backup" # Ignore backup files
|
||||||
|
|
||||||
# Only include specific files (whitelist mode)
|
# Only include specific files (whitelist mode)
|
||||||
monitor_include_patterns:
|
include_patterns:
|
||||||
- "*.md" # Only markdown files
|
- "*.md" # Only markdown files
|
||||||
- "*.pdf" # Only PDF files
|
- "*.pdf" # Only PDF files
|
||||||
- "**/docs/**" # Only files in docs directories
|
- "**/docs/**" # Only files in docs directories
|
||||||
|
|
@ -203,18 +205,20 @@ storage:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# Only monitor markdown documentation, but ignore drafts
|
# Only monitor markdown documentation, but ignore drafts
|
||||||
monitor_include_patterns:
|
monitor:
|
||||||
- "*.md"
|
include_patterns:
|
||||||
monitor_ignore_patterns:
|
- "*.md"
|
||||||
- "*draft*"
|
ignore_patterns:
|
||||||
- "*WIP*"
|
- "*draft*"
|
||||||
|
- "*WIP*"
|
||||||
|
|
||||||
# Monitor all supported files except in specific directories
|
# Monitor all supported files except in specific directories
|
||||||
monitor_ignore_patterns:
|
monitor:
|
||||||
- "node_modules/"
|
ignore_patterns:
|
||||||
- ".git/"
|
- "node_modules/"
|
||||||
- "**/test/**"
|
- ".git/"
|
||||||
- "**/temp/**"
|
- "**/test/**"
|
||||||
|
- "**/temp/**"
|
||||||
```
|
```
|
||||||
|
|
||||||
Patterns follow [gitignore syntax](https://git-scm.com/docs/gitignore#_pattern_format):
|
Patterns follow [gitignore syntax](https://git-scm.com/docs/gitignore#_pattern_format):
|
||||||
|
|
@ -589,8 +593,8 @@ This will read your current environment variables and generate a `haiku.rag.yaml
|
||||||
When migrating from environment variables, list values like `MONITOR_DIRECTORIES` that were comma-separated (`/path1,/path2`) will be converted to proper YAML lists. In YAML, always use list syntax:
|
When migrating from environment variables, list values like `MONITOR_DIRECTORIES` that were comma-separated (`/path1,/path2`) will be converted to proper YAML lists. In YAML, always use list syntax:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
storage:
|
monitor:
|
||||||
monitor_directories:
|
directories:
|
||||||
- /path/to/dir1
|
- /path/to/dir1
|
||||||
- /path/to/dir2
|
- /path/to/dir2
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,8 @@ This will start file monitoring, MCP server on port 8001, and A2A server on port
|
||||||
Configure directories to monitor in your `haiku.rag.yaml`:
|
Configure directories to monitor in your `haiku.rag.yaml`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
storage:
|
monitor:
|
||||||
monitor_directories:
|
directories:
|
||||||
- /path/to/documents
|
- /path/to/documents
|
||||||
- /another/path
|
- /another/path
|
||||||
```
|
```
|
||||||
|
|
@ -71,18 +71,18 @@ haiku-rag serve --monitor
|
||||||
You can filter which files to monitor using gitignore-style patterns:
|
You can filter which files to monitor using gitignore-style patterns:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
storage:
|
monitor:
|
||||||
monitor_directories:
|
directories:
|
||||||
- /path/to/documents
|
- /path/to/documents
|
||||||
|
|
||||||
# Ignore patterns (exclude files)
|
# Ignore patterns (exclude files)
|
||||||
monitor_ignore_patterns:
|
ignore_patterns:
|
||||||
- "*draft*" # Ignore draft files
|
- "*draft*" # Ignore draft files
|
||||||
- "temp/" # Ignore temp directory
|
- "temp/" # Ignore temp directory
|
||||||
- "**/archive/**" # Ignore archive directories
|
- "**/archive/**" # Ignore archive directories
|
||||||
|
|
||||||
# Include patterns (whitelist files)
|
# Include patterns (whitelist files)
|
||||||
monitor_include_patterns:
|
include_patterns:
|
||||||
- "*.md" # Only markdown files
|
- "*.md" # Only markdown files
|
||||||
- "**/docs/**" # Files in docs directories
|
- "**/docs/**" # Files in docs directories
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ from haiku.rag.config.models import (
|
||||||
AppConfig,
|
AppConfig,
|
||||||
EmbeddingsConfig,
|
EmbeddingsConfig,
|
||||||
LanceDBConfig,
|
LanceDBConfig,
|
||||||
|
MonitorConfig,
|
||||||
OllamaConfig,
|
OllamaConfig,
|
||||||
ProcessingConfig,
|
ProcessingConfig,
|
||||||
ProvidersConfig,
|
ProvidersConfig,
|
||||||
|
|
@ -25,6 +26,7 @@ __all__ = [
|
||||||
"Config",
|
"Config",
|
||||||
"AppConfig",
|
"AppConfig",
|
||||||
"StorageConfig",
|
"StorageConfig",
|
||||||
|
"MonitorConfig",
|
||||||
"LanceDBConfig",
|
"LanceDBConfig",
|
||||||
"EmbeddingsConfig",
|
"EmbeddingsConfig",
|
||||||
"RerankingConfig",
|
"RerankingConfig",
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,14 @@ def generate_default_config() -> dict:
|
||||||
"environment": "production",
|
"environment": "production",
|
||||||
"storage": {
|
"storage": {
|
||||||
"data_dir": "",
|
"data_dir": "",
|
||||||
"monitor_directories": [],
|
|
||||||
"disable_autocreate": False,
|
"disable_autocreate": False,
|
||||||
"vacuum_retention_seconds": 60,
|
"vacuum_retention_seconds": 60,
|
||||||
},
|
},
|
||||||
|
"monitor": {
|
||||||
|
"directories": [],
|
||||||
|
"ignore_patterns": [],
|
||||||
|
"include_patterns": [],
|
||||||
|
},
|
||||||
"lancedb": {"uri": "", "api_key": "", "region": ""},
|
"lancedb": {"uri": "", "api_key": "", "region": ""},
|
||||||
"embeddings": {
|
"embeddings": {
|
||||||
"provider": "ollama",
|
"provider": "ollama",
|
||||||
|
|
@ -88,7 +92,7 @@ def load_config_from_env() -> dict:
|
||||||
env_mappings = {
|
env_mappings = {
|
||||||
"ENV": "environment",
|
"ENV": "environment",
|
||||||
"DEFAULT_DATA_DIR": ("storage", "data_dir"),
|
"DEFAULT_DATA_DIR": ("storage", "data_dir"),
|
||||||
"MONITOR_DIRECTORIES": ("storage", "monitor_directories"),
|
"MONITOR_DIRECTORIES": ("monitor", "directories"),
|
||||||
"DISABLE_DB_AUTOCREATE": ("storage", "disable_autocreate"),
|
"DISABLE_DB_AUTOCREATE": ("storage", "disable_autocreate"),
|
||||||
"VACUUM_RETENTION_SECONDS": ("storage", "vacuum_retention_seconds"),
|
"VACUUM_RETENTION_SECONDS": ("storage", "vacuum_retention_seconds"),
|
||||||
"LANCEDB_URI": ("lancedb", "uri"),
|
"LANCEDB_URI": ("lancedb", "uri"),
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,16 @@ from haiku.rag.utils import get_default_data_dir
|
||||||
|
|
||||||
class StorageConfig(BaseModel):
|
class StorageConfig(BaseModel):
|
||||||
data_dir: Path = Field(default_factory=get_default_data_dir)
|
data_dir: Path = Field(default_factory=get_default_data_dir)
|
||||||
monitor_directories: list[Path] = []
|
|
||||||
monitor_ignore_patterns: list[str] = []
|
|
||||||
monitor_include_patterns: list[str] = []
|
|
||||||
disable_autocreate: bool = False
|
disable_autocreate: bool = False
|
||||||
vacuum_retention_seconds: int = 60
|
vacuum_retention_seconds: int = 60
|
||||||
|
|
||||||
|
|
||||||
|
class MonitorConfig(BaseModel):
|
||||||
|
directories: list[Path] = []
|
||||||
|
ignore_patterns: list[str] = []
|
||||||
|
include_patterns: list[str] = []
|
||||||
|
|
||||||
|
|
||||||
class LanceDBConfig(BaseModel):
|
class LanceDBConfig(BaseModel):
|
||||||
uri: str = ""
|
uri: str = ""
|
||||||
api_key: str = ""
|
api_key: str = ""
|
||||||
|
|
@ -74,6 +77,7 @@ class A2AConfig(BaseModel):
|
||||||
class AppConfig(BaseModel):
|
class AppConfig(BaseModel):
|
||||||
environment: str = "production"
|
environment: str = "production"
|
||||||
storage: StorageConfig = Field(default_factory=StorageConfig)
|
storage: StorageConfig = Field(default_factory=StorageConfig)
|
||||||
|
monitor: MonitorConfig = Field(default_factory=MonitorConfig)
|
||||||
lancedb: LanceDBConfig = Field(default_factory=LanceDBConfig)
|
lancedb: LanceDBConfig = Field(default_factory=LanceDBConfig)
|
||||||
embeddings: EmbeddingsConfig = Field(default_factory=EmbeddingsConfig)
|
embeddings: EmbeddingsConfig = Field(default_factory=EmbeddingsConfig)
|
||||||
reranking: RerankingConfig = Field(default_factory=RerankingConfig)
|
reranking: RerankingConfig = Field(default_factory=RerankingConfig)
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,10 @@ class FileWatcher:
|
||||||
client: HaikuRAG,
|
client: HaikuRAG,
|
||||||
config: AppConfig = Config,
|
config: AppConfig = Config,
|
||||||
):
|
):
|
||||||
self.paths = config.storage.monitor_directories
|
self.paths = config.monitor.directories
|
||||||
self.client = client
|
self.client = client
|
||||||
self.ignore_patterns = config.storage.monitor_ignore_patterns or None
|
self.ignore_patterns = config.monitor.ignore_patterns or None
|
||||||
self.include_patterns = config.storage.monitor_include_patterns or None
|
self.include_patterns = config.monitor.include_patterns or None
|
||||||
|
|
||||||
async def observe(self):
|
async def observe(self):
|
||||||
logger.info(f"Watching files in {self.paths}")
|
logger.info(f"Watching files in {self.paths}")
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from unittest.mock import AsyncMock
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from haiku.rag.client import HaikuRAG
|
from haiku.rag.client import HaikuRAG
|
||||||
from haiku.rag.config import AppConfig, StorageConfig
|
from haiku.rag.config import AppConfig, MonitorConfig
|
||||||
from haiku.rag.monitor import FileWatcher
|
from haiku.rag.monitor import FileWatcher
|
||||||
from haiku.rag.store.models.document import Document
|
from haiku.rag.store.models.document import Document
|
||||||
|
|
||||||
|
|
@ -23,9 +23,7 @@ async def test_file_watcher_upsert_document():
|
||||||
mock_client.create_document_from_source.return_value = mock_doc
|
mock_client.create_document_from_source.return_value = mock_doc
|
||||||
mock_client.get_document_by_uri.return_value = None # No existing document
|
mock_client.get_document_by_uri.return_value = None # No existing document
|
||||||
|
|
||||||
test_config = AppConfig(
|
test_config = AppConfig(monitor=MonitorConfig(directories=[temp_path.parent]))
|
||||||
storage=StorageConfig(monitor_directories=[temp_path.parent])
|
|
||||||
)
|
|
||||||
watcher = FileWatcher(client=mock_client, config=test_config)
|
watcher = FileWatcher(client=mock_client, config=test_config)
|
||||||
|
|
||||||
result = await watcher._upsert_document(temp_path)
|
result = await watcher._upsert_document(temp_path)
|
||||||
|
|
@ -53,9 +51,7 @@ async def test_file_watcher_upsert_existing_document():
|
||||||
mock_client.get_document_by_uri.return_value = existing_doc
|
mock_client.get_document_by_uri.return_value = existing_doc
|
||||||
mock_client.create_document_from_source.return_value = updated_doc
|
mock_client.create_document_from_source.return_value = updated_doc
|
||||||
|
|
||||||
test_config = AppConfig(
|
test_config = AppConfig(monitor=MonitorConfig(directories=[temp_path.parent]))
|
||||||
storage=StorageConfig(monitor_directories=[temp_path.parent])
|
|
||||||
)
|
|
||||||
watcher = FileWatcher(client=mock_client, config=test_config)
|
watcher = FileWatcher(client=mock_client, config=test_config)
|
||||||
|
|
||||||
result = await watcher._upsert_document(temp_path)
|
result = await watcher._upsert_document(temp_path)
|
||||||
|
|
@ -76,9 +72,7 @@ async def test_file_watcher_delete_document():
|
||||||
mock_client.get_document_by_uri.return_value = existing_doc
|
mock_client.get_document_by_uri.return_value = existing_doc
|
||||||
mock_client.delete_document.return_value = True
|
mock_client.delete_document.return_value = True
|
||||||
|
|
||||||
test_config = AppConfig(
|
test_config = AppConfig(monitor=MonitorConfig(directories=[temp_path.parent]))
|
||||||
storage=StorageConfig(monitor_directories=[temp_path.parent])
|
|
||||||
)
|
|
||||||
watcher = FileWatcher(client=mock_client, config=test_config)
|
watcher = FileWatcher(client=mock_client, config=test_config)
|
||||||
|
|
||||||
await watcher._delete_document(temp_path)
|
await watcher._delete_document(temp_path)
|
||||||
|
|
@ -95,9 +89,7 @@ async def test_file_watcher_delete_nonexistent_document():
|
||||||
mock_client = AsyncMock(spec=HaikuRAG)
|
mock_client = AsyncMock(spec=HaikuRAG)
|
||||||
mock_client.get_document_by_uri.return_value = None
|
mock_client.get_document_by_uri.return_value = None
|
||||||
|
|
||||||
test_config = AppConfig(
|
test_config = AppConfig(monitor=MonitorConfig(directories=[temp_path.parent]))
|
||||||
storage=StorageConfig(monitor_directories=[temp_path.parent])
|
|
||||||
)
|
|
||||||
watcher = FileWatcher(client=mock_client, config=test_config)
|
watcher = FileWatcher(client=mock_client, config=test_config)
|
||||||
|
|
||||||
await watcher._delete_document(temp_path)
|
await watcher._delete_document(temp_path)
|
||||||
|
|
@ -210,9 +202,7 @@ async def test_file_watcher_with_ignore_patterns():
|
||||||
mock_client.get_document_by_uri.return_value = None
|
mock_client.get_document_by_uri.return_value = None
|
||||||
|
|
||||||
test_config = AppConfig(
|
test_config = AppConfig(
|
||||||
storage=StorageConfig(
|
monitor=MonitorConfig(directories=[temp_path], ignore_patterns=["draft*"])
|
||||||
monitor_directories=[temp_path], monitor_ignore_patterns=["draft*"]
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
watcher = FileWatcher(client=mock_client, config=test_config)
|
watcher = FileWatcher(client=mock_client, config=test_config)
|
||||||
|
|
||||||
|
|
@ -243,9 +233,7 @@ async def test_file_watcher_with_include_patterns():
|
||||||
mock_client.get_document_by_uri.return_value = None
|
mock_client.get_document_by_uri.return_value = None
|
||||||
|
|
||||||
test_config = AppConfig(
|
test_config = AppConfig(
|
||||||
storage=StorageConfig(
|
monitor=MonitorConfig(directories=[temp_path], include_patterns=["*.md"])
|
||||||
monitor_directories=[temp_path], monitor_include_patterns=["*.md"]
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
watcher = FileWatcher(client=mock_client, config=test_config)
|
watcher = FileWatcher(client=mock_client, config=test_config)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,9 @@ async def test_config_validation_on_db_load(temp_db_path):
|
||||||
|
|
||||||
def test_monitor_filter_patterns_config():
|
def test_monitor_filter_patterns_config():
|
||||||
"""Test that monitor filter patterns are available in config."""
|
"""Test that monitor filter patterns are available in config."""
|
||||||
assert hasattr(Config.storage, "monitor_ignore_patterns")
|
assert hasattr(Config.monitor, "ignore_patterns")
|
||||||
assert hasattr(Config.storage, "monitor_include_patterns")
|
assert hasattr(Config.monitor, "include_patterns")
|
||||||
assert isinstance(Config.storage.monitor_ignore_patterns, list)
|
assert hasattr(Config.monitor, "directories")
|
||||||
assert isinstance(Config.storage.monitor_include_patterns, list)
|
assert isinstance(Config.monitor.ignore_patterns, list)
|
||||||
|
assert isinstance(Config.monitor.include_patterns, list)
|
||||||
|
assert isinstance(Config.monitor.directories, list)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue