AgentBoot
April 24, 2026 · View on GitHub
Layout
src/agentboot/
├── __init__.py # package version
├── _errors.py # base AgentBootError
├── cli.py # argparse subcommands + dispatch
├── config.py # JSON config loader
├── errors.py # public error re-exports
├── logging_setup.py # setup_logging() helper
├── hardware_detector.py # local + SSH detection
├── os_compatibility.py # OS catalog + scorer
├── iso/ # catalogue + verifying downloader
├── flasher/ # enumeration + dd-style flasher
├── autoinstall/ # cloud-init / preseed / kickstart / unattend
├── serial_link/ # JSON-over-serial protocol + transports
├── agent/ # InstallSession + Orchestrator
└── llm/ # LocalLLM, cloud backends, router
scripts/
└── agentboot_collector.py # stdlib-only, runs on the target
tests/ # pytest; every module has tests
docs/ # USAGE / OPERATOR / DEVELOPER / COLLECTOR
Design principles
- No stubs, no TODOs in main code. Every exported symbol has a real implementation and at least one test.
- Failure is explicit. Functions raise
AgentBootError(or a subclass) rather than returning sentinels. Callers catch the base class when they want to be generic. - Side-effects behind safety rails. Any function that wipes a disk, overwrites a file, or sends a destructive command requires an explicit, matching confirm token.
- Idempotency by persistence.
InstallSessionrecords each decision atomically. Re-runningorchestrator.detect()recomputes detection but does not re-download or re-flash. - Stdlib first. Cloud LLMs are optional extras; llama-cpp is an
optional extra; PyYAML is never a dependency. The core pipeline
works with a plain
pip install agentboot-ai.
Testing
pytest # everything
pytest tests/test_flasher.py # one module
pytest -k "session" # by keyword
The slow/flaky tests are isolated:
test_local_llm.pyrequires a real GGUF model. Skipped in CI by default;pytest --ignore=tests/test_local_llm.py.- Network-dependent tests use an in-process
http.serverfixture — no external network.
Adding a new OS to the catalog
- Edit
src/agentboot/os_compatibility.py→ append toOS_CATALOGwith min RAM / disk / architecture tags. Add a scoring tiebreak if needed. - Edit
src/agentboot/iso/catalog.py→ append anIsoEntryper architecture. Prefer vendor URLs that include aSHA256SUMSfile next to the ISO. - Add a generator entry in
src/agentboot/autoinstall/generators.py_DISPATCHmap if this OS uses an autoinstall format not already covered (cloud-init / preseed / kickstart / unattend). - Add a smoke test under
tests/.
Adding a new LLM backend
Implement the LLMBackend protocol in agentboot.llm.base:
class MyBackend:
name = "mybackend"
def generate(self, prompt: str, **kw) -> str: ...
def chat(self, messages, **kw) -> str: ...
def chat_stream(self, messages, **kw): ...
Then register it with a Router in priority order. LLMUnavailable
means "skip me"; LLMError means "fail hard".
Cutting a release
- Bump
src/agentboot/__init__.py__version__and the[project] versionkey inpyproject.toml. pytest --ignore=tests/test_local_llm.pymust be green.git tag vX.Y.Z && git push --tags.python -m build && python -m twine upload dist/*.