core/project_config_files.py
Rama main · réplica de lectura del repositorio original.
# SPDX-License-Identifier: BUSL-1.1
# Copyright (c) 2024-2026 Ali Sadeghi Aghili
"""The files a deployment's ``project_config/`` must contain.
One list, importable without reading any of them. ``import knowledge`` loads
five of the files the moment it is imported, so anything that wants to say
*which* file is missing (the setup wizard, ``scripts/verify_deployment.py``)
cannot ask the loaders: it would die on the first absent file with a
traceback instead of naming all of them.
Public API
----------
REQUIRED_PROJECT_CONFIG_FILES
The ten required file names.
missing_project_config_files(directory) -> list[str]
Which of them a directory lacks.
"""
from __future__ import annotations
from pathlib import Path
__all__ = ["REQUIRED_PROJECT_CONFIG_FILES", "missing_project_config_files"]
#: Every file the application cannot start or answer without: the nine
#: ``*.yaml`` files ``knowledge.config_loader`` and ``schema_data.registry``
#: raise ``ConfigNotFoundError`` for (the same nine ``appdb.config_versions``
#: versions as one bundle), and ``system_prompt.md``. Optional files
#: (``relationships.yaml``, ``datasources.yaml``, ``api_keys.json``) are not
#: listed. ``tests/test_project_config_files.py`` pins this list to the
#: loaders, so a file added to one and not here fails a test.
REQUIRED_PROJECT_CONFIG_FILES: tuple[str, ...] = (
"aliases.yaml",
"entities.yaml",
"business_rules.yaml",
"examples.yaml",
"metrics.yaml",
"schema.yaml",
"retrieval_hints.yaml",
"session_policy.yaml",
"memory_policy.yaml",
"system_prompt.md",
)
def missing_project_config_files(directory: Path) -> list[str]:
"""Return the required files that *directory* does not contain.
Args:
directory: A ``project_config``-style directory. It need not exist.
Returns:
The names from :data:`REQUIRED_PROJECT_CONFIG_FILES` that are not
regular files in *directory*, in that tuple's order. Empty when the
directory is complete.
Raises:
Nothing. This function never raises.
Examples:
>>> import tempfile
>>> with tempfile.TemporaryDirectory() as tmp:
... Path(tmp, "aliases.yaml").write_text("{}")
... missing = missing_project_config_files(Path(tmp))
2
>>> "aliases.yaml" in missing, "metrics.yaml" in missing
(False, True)
>>> len(missing_project_config_files(Path("/no/such/directory")))
10
"""
return [name for name in REQUIRED_PROJECT_CONFIG_FILES if not (directory / name).is_file()]