diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-25 18:13:39 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-25 18:13:39 +0200 |
| commit | 88ac15f496cde6104709ec6925212df0eb3cddc2 (patch) | |
| tree | 8566472b03631edb58017f939923452a22c73bbe | |
| parent | ea63943b0e9f755d00cf3e69b5ae5cebb41eb959 (diff) | |
| download | llamachat-88ac15f496cde6104709ec6925212df0eb3cddc2.tar.gz llamachat-88ac15f496cde6104709ec6925212df0eb3cddc2.zip | |
feat: skills config keys, on by default
| -rw-r--r-- | llamachat/config.py | 20 | ||||
| -rwxr-xr-x | test_llamachat.py | 30 |
2 files changed, 50 insertions, 0 deletions
diff --git a/llamachat/config.py b/llamachat/config.py index 0c119ad..f3a2fbb 100644 --- a/llamachat/config.py +++ b/llamachat/config.py @@ -53,6 +53,12 @@ DEFAULTS = { # (llama-server's cache-type-k/v) makes that failure far more likely, so # lower this to 1 if the server runs one. "max_searches": 2, + # Skills: instruction files read from a directory, one SKILL.md per + # skill, loaded into the model's context on demand. On by default + # because the directory already exists; a flag whose directory is + # missing resolves to off. + "skills_enabled": True, + "skills_dir": "~/.agents/skills", } # The global prompt lives here; every other .md beside it is a named preset. @@ -89,6 +95,8 @@ class Config: search_snippet_chars: int search_timeout: int max_searches: int + skills_enabled: bool + skills_dir: Path providers: dict[str, providers_mod.Provider] models_path: Path provider_warnings: list[str] @@ -124,6 +132,9 @@ def load(path: Path = CONFIG_PATH) -> Config: search_url = str(values["search_url"]).rstrip("/") search_enabled = bool(values["search_enabled"]) and bool(search_url) + skills_dir = Path(str(values["skills_dir"])).expanduser() + skills_enabled = bool(values["skills_enabled"]) and skills_dir.is_dir() + # Providers are built from the raw values so a bare base_url still # synthesizes the local entry. DEFAULTS supplies base_url when the file # names neither, which keeps a config with no network settings working. @@ -157,6 +168,8 @@ def load(path: Path = CONFIG_PATH) -> Config: search_snippet_chars=int(values["search_snippet_chars"]), search_timeout=int(values["search_timeout"]), max_searches=int(values["max_searches"]), + skills_enabled=skills_enabled, + skills_dir=skills_dir, providers=provider_table, # Cloud model metadata, cached beside state.ini for the same reason: # it is machine-written, not user-editable config. @@ -224,6 +237,13 @@ def write_default(path: Path = CONFIG_PATH) -> Path: f'search_timeout = {DEFAULTS["search_timeout"]}\n' f'max_searches = {DEFAULTS["max_searches"]}\n' '\n' + '# Skills: instruction files read from a directory, one SKILL.md per\n' + '# skill, loaded into the model\'s context on demand (by the model\n' + '# itself, by /skill-name, or by mentioning a skill name). On by\n' + '# default; a directory that does not exist resolves to off.\n' + f'skills_enabled = {str(DEFAULTS["skills_enabled"]).lower()}\n' + f'skills_dir = "{DEFAULTS["skills_dir"]}"\n' + '\n' '# External providers. The local router is a provider named "local",\n' '# synthesized from base_url above when no [providers.local] exists.\n' '# Any OpenAI-compatible endpoint works.\n' diff --git a/test_llamachat.py b/test_llamachat.py index ef73fe3..ed990af 100755 --- a/test_llamachat.py +++ b/test_llamachat.py @@ -1137,6 +1137,35 @@ def test_config_defaults(): print("ok config defaults") +def test_skills_config(): + with tempfile.TemporaryDirectory() as tmp: + skills_dir = Path(tmp) / "skills" + (skills_dir / "firefly-cli").mkdir(parents=True) + (skills_dir / "firefly-cli" / "SKILL.md").write_text( + "---\nname: firefly-cli\ndescription: d\n---\n\nbody\n" + ) + path = Path(tmp) / "config.toml" + path.write_text(f'skills_enabled = true\nskills_dir = "{skills_dir}"\n') + cfg = config.load(path) + assert cfg.skills_enabled is True + assert cfg.skills_dir == skills_dir + + # A flag whose directory does not exist resolves to off, mirroring + # the search rule that a flag with no URL stays off. + path.write_text('skills_enabled = true\nskills_dir = "/nonexistent"\n') + assert config.load(path).skills_enabled is False + + assert config.DEFAULTS["skills_enabled"] is True + assert config.DEFAULTS["skills_dir"] == "~/.agents/skills" + + with tempfile.TemporaryDirectory() as tmp: + written = config.write_default(Path(tmp) / "config.toml") + text = written.read_text() + assert "skills_enabled" in text + assert "skills_dir" in text + print("ok skills config") + + def test_provider_parsing(): """Providers come from [providers.*]; a bare base_url synthesizes local.""" from llamachat import providers @@ -3482,6 +3511,7 @@ if __name__ == "__main__": test_version_matches_changelog() test_venv_discovery() test_config_defaults() + test_skills_config() test_provider_parsing() test_provider_malformed_shapes() test_unusable_config_exits() |
