Make the config file the only home for settings
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 51s

With no production instance yet, there is no reason to carry two ways
of configuring the agent. Every environment variable that duplicated a
config key is gone; the environment now supplies only the secrets the
file references by ${…}, plus NISSE_CONFIG and NISSE_ENV to find the
files.

- AgentConfig loads from a file (load, from_file) or a parsed tree
  (from_tree, for tests); a missing file is an error naming the example
- The from_env constructors on LiteLLMClient, AnthropicPassthroughClient,
  GiteaClient, MatrixConfig and RoleMap are removed, with the env
  reading for max output tokens; clients take their settings from config
- The live integration tests share a committed agent config,
  tests/integration/nisse-test.yaml, aimed at test resources, and one
  conftest that loads it and builds clients. NISSE_LIVE_PLANNER_MODEL
  becomes its planner role; NISSE_CAPABILITY_MODELS stays as a per-run
  switch
- A missing secret now fails the live tests instead of skipping them
- CI passes only the three tokens
- .env.example is secrets only; spec A5 says config comes from the file

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
dongarandClaude Opus 5.5 committed 2026-09-23 23:25:58 +00:00
1 parent df449c7e34
commit 15d69799bf
28 files changed
+571 -777

No files matched your search

+11 -6
View File
@@ -2,6 +2,7 @@
import os
import subprocess
from pathlib import Path
import pytest
@@ -16,27 +17,31 @@ def test_ops_entry_point_runs_and_greets() -> None:
assert result.stdout == "Hello from nisse-ops, the house spirit is awake.\n"
def test_dev_entry_point_refuses_to_start_unconfigured() -> None:
"""Missing configuration must fail at startup, naming everything absent.
def test_dev_entry_point_refuses_to_start_unconfigured(tmp_path: Path) -> None:
"""An incomplete config must fail at startup, naming everything absent.
Run with a deliberately empty environment and a .env path that does not
exist: the real .env in the working directory holds live credentials, and
a test must never be one cwd away from starting a real agent.
Run from an empty directory, with an empty config file and a .env path
that does not exist: the repository's .env holds live credentials, and a
test must never be one cwd away from starting a real agent.
"""
config = tmp_path / "nisse-dev.yaml"
config.write_text("")
result = subprocess.run(
["nisse-dev"],
capture_output=True,
text=True,
timeout=30,
check=False,
cwd=tmp_path,
env={
"PATH": os.environ["PATH"],
"HOME": os.environ["HOME"],
"NISSE_ENV": "/nonexistent/.env",
"NISSE_CONFIG": str(config),
},
)
assert result.returncode == 2
assert "cannot start" in result.stderr
# All of them at once, not the first one it happened to reach.
for expected in ("NISSE_STATE_DB", "NISSE_MATRIX_TOKEN", "NISSE_GITEA_REPO"):
for expected in ("state_db", "matrix.token", "gitea.repo"):
assert expected in result.stderr