Problem
Every kbagent invocation spends ~0.4 s just importing Python modules before any command logic runs (measured on macOS, warm cache: kbagent --help ~0.7 s wall-clock, python -X importtime -c "import keboola_agent_cli.cli" ~0.38-0.47 s cumulative).
AI agents call kbagent tens to hundreds of times per session, so this fixed cost adds up to minutes and is paid even by trivial reads like job list or project list.
Root cause
cli.py eagerly imports every command group and every service at module load (from .commands.agent import agent_app, ... ~37 command modules, plus all services.*). Examples of cost paid by unrelated commands:
commands.auth -> _auth_picker -> _checkbox_select -> prompt_toolkit (~50-75 ms), loaded even for kbagent job list.
keboola_agent_cli/__init__.py imports the SDK facade (lib -> client -> httpx) at package import (~170 ms for the package alone).
constants.py pulls in importlib.metadata (~30 ms).
Proposal
- Register command groups lazily: import a group's module only when that group is actually invoked (Typer/Click lazy-group pattern), keep
--help listing all groups.
- Defer heavy optional imports (
prompt_toolkit, service modules) to the functions that need them.
- Avoid eager SDK imports in
__init__.py (e.g. module-level __getattr__ for the public names) without changing the public __all__ API.
Guardrail (the important part)
Add a CI test that fails when startup regresses, using a deterministic metric rather than wall-clock time:
- Run
python -c "import keboola_agent_cli.cli; import sys; print(len(sys.modules))" (or check that specific heavy modules such as prompt_toolkit are NOT in sys.modules after resolving e.g. job list), and assert against a committed budget.
- The budget only ratchets down: when an optimization lands, lower the number in the same PR.
Wall-clock timings are too noisy for CI (especially on Windows runners); module count / forbidden-module checks are stable.
Acceptance criteria
kbagent job list --help does not import prompt_toolkit or unrelated command/service modules.
- Import time of
keboola_agent_cli.cli for a single-group invocation drops substantially (target: well under 150 ms on a dev machine; report before/after -X importtime numbers in the PR).
- CI guardrail test as described above is in place.
- No change to CLI surface,
--help output, or the public SDK __all__.
Inspired by the "measure first, then ratchet in CI" approach from https://claude.dev/blog/how-we-made-claude-ai-faster/
Problem
Every
kbagentinvocation spends ~0.4 s just importing Python modules before any command logic runs (measured on macOS, warm cache:kbagent --help~0.7 s wall-clock,python -X importtime -c "import keboola_agent_cli.cli"~0.38-0.47 s cumulative).AI agents call
kbagenttens to hundreds of times per session, so this fixed cost adds up to minutes and is paid even by trivial reads likejob listorproject list.Root cause
cli.pyeagerly imports every command group and every service at module load (from .commands.agent import agent_app, ... ~37 command modules, plus allservices.*). Examples of cost paid by unrelated commands:commands.auth->_auth_picker->_checkbox_select->prompt_toolkit(~50-75 ms), loaded even forkbagent job list.keboola_agent_cli/__init__.pyimports the SDK facade (lib->client->httpx) at package import (~170 ms for the package alone).constants.pypulls inimportlib.metadata(~30 ms).Proposal
--helplisting all groups.prompt_toolkit, service modules) to the functions that need them.__init__.py(e.g. module-level__getattr__for the public names) without changing the public__all__API.Guardrail (the important part)
Add a CI test that fails when startup regresses, using a deterministic metric rather than wall-clock time:
python -c "import keboola_agent_cli.cli; import sys; print(len(sys.modules))"(or check that specific heavy modules such asprompt_toolkitare NOT insys.modulesafter resolving e.g.job list), and assert against a committed budget.Wall-clock timings are too noisy for CI (especially on Windows runners); module count / forbidden-module checks are stable.
Acceptance criteria
kbagent job list --helpdoes not importprompt_toolkitor unrelated command/service modules.keboola_agent_cli.clifor a single-group invocation drops substantially (target: well under 150 ms on a dev machine; report before/after-X importtimenumbers in the PR).--helpoutput, or the public SDK__all__.Inspired by the "measure first, then ratchet in CI" approach from https://claude.dev/blog/how-we-made-claude-ai-faster/