search · graph · sql are tested
as calls to Knowledge Store primitives under the owner’s
identity ACL: the right tool is chosen by intent, and permissions trim
on the KS side. The results, ranking, and fusion themselves are held
and tested by Knowledge Store — not duplicated here.
tokens_used, two locks (the owner’s switch
enabled and the sticky admin_paused) plus
the model condition (model_id IS NOT NULL; removal from
the list → SET NULL → stop), account deactivation →
enabled=false for its agents, a
skipped record on a runtime refusal (budget_exceeded /
already_running) and the scheduler’s silence when
a lock is closed, FK cascades from the agent and from the account.
Also here — that outwardly this surfaces as clean codes, not
500.
search / graph /
sql
next_run_at, the weekly
budget window
agents / agent_runs),
SAQ handler called directly — without spinning up a worker
@pytest.mark.unit / @pytest.mark.integration —
by type; @pytest.mark.p0 / p1 — by
priority, orthogonal to type
failed with reason=iteration_cap (it hit the cap, not rejected before start), not an endless model callsearch · graph · sql are dispatched by the tool-call name and call the corresponding Knowledge Store primitivesearch · graph · sql in the set, even though it’s locked; “locked” = can’t be turned off by hand, not “present in any state of the knowledge base”; the agent starts and degrades onto external tools, or plainly reports there’s no data — an empty knowledge base doesn’t enter the readiness gatequeued → running → succeeded; output written to the run rowfailed, error is filled; distinct from skippedtokens_used is set from the actual run — the basis for the weekly budget sumstarted_at / finished_at are set at start and finish; created_at / updated_at — server_default + triggerskipped) has no started_at — it was rejected before launch, not cut off mid-workUNIQUE (agent_id) WHERE state IN ('queued','running') — the race (a manual launch coinciding with a fired slot) is quashed by the database itself, not just a code checkrunning → once heartbeat_at goes stale the run is reaped to failed with reason=stale, the lock is released, and the agent starts again — a zombie doesn’t lock it outSUM(tokens_used) across all of the owner’s agents for the current week (by finished_at), not per agentskipped is written with reason=budget_exceeded, tokens_used=0platform_settings, not stored in the module — changed centrallyschedule NULL → the agent runs only manually, the scheduler leaves it alonenext_run_at from the previous runHH:MM — yields the correct next_run_atHH:MM resolves against the owner’s users.timezone (on NULL — the org default platform_settings.timezone), then is stored in UTCnext_run_at arrives, the scheduler places the run on the background queue with trigger=scheduledrunning/queued run creates no new cycle — a skipped row, reason=already_runningtrigger=manual) needs no schedule — it works even with schedule=NULL; the locks (enabled, admin_paused) are still honoredadmin_paused — only an admin can; the owner’s attempt leaves the flag unchangedenabled, not admin_paused, budget within bounds AND model_id IS NOT NULL; the axes are independentagent_models → ON DELETE SET NULL nulls agents.model_id → the agent drops out of the scan (next_run_at cleared), launch is unavailable, no skipped is written — as with a closed lock; it doesn’t fall back to a defaultenabled=false or admin_paused=true the agent is out of the scheduler’s scan (next_run_at cleared) and the manual-launch button is unavailable — no run happens and no skipped appears; the journal doesn’t accumulate durable stopsenabled on all their agents; reactivation doesn’t restore the flag — only the owner brings them back to life by handagents and behind them agent_runs go via ON DELETE CASCADEadmin_pausedenabled flagmodel_id from the allowed list is saved and applied in the run; on creation the field is set (preselect — the list default)model_id outside agent_models (or an embedding type) → 422, not 500202 + run id; an agent_run is created (trigger=manual, queued), a task in SAQPOST /agents/{id}/run while the agent’s run is already running → 409 CONFLICT (single-flight, doesn’t double the run); consistent with the domain already_running → skipped{id} → 404, not 500POST /run doesn’t start a run: 409 (or a domain skipped with reason budget_exceeded) — a fixed HTTP outcome, not 500trigger / state off the enum, an empty name → 422, not 500schedule is a tagged union by type (interval / calendar), weekday 0–6, time HH:MM; a malformed input is rejected by validation: (a) unknown type; (b) calendar without time; (c) weekday outside 0–6 → 422, not 500 → Schedule shapeoutput, tokens_used and outcome; skipped with reason is returned distinctly from failedenabled, read-only for the admin) and admin_paused — the row’s combined status is visible to the adminadmin_paused on any agent; leaves the owner’s enabled switch untouchedadmin_paused → 403403 FORBIDDEN401 UNAUTHORIZED (parameterized across all routes)401
The split is set by purpose, not folders. unit/ runs on
every PR deterministically — a fake model and fake primitives, no
network or DB. integration/ and api/ — a
separate, rarer step on a live DB: the first checks the domain (runs,
budget, control, lane), the second — the HTTP contract on the ASGI app.
The real model and provider stay out of CI, for manual debugging.
Priority (P0–P1) is orthogonal to the folders and set by markers
(pytest -m p0).
tests/agent_engine/module directory
conftest.pyfake chat-client · fake tools search/graph/sql · time-machine · agents/agent_runs factories · SAQ directlyunit/loop and tools on a fake model — every PR, deterministic
test_agent_loop.py · test_prompt_composition.pythink→tool→observe, layered prompt assemblytest_tools.pysearch/graph/sql as calls to KS primitives under the identity ACLintegration/domain on a live DB
test_run_lifecycle.pyrun states, single-active lock + stale reaping by heartbeat, token accounting, timestampstest_budget · test_scheduling · test_governance · test_isolationweekly budget, schedule, locks and cascades, background laneapi/HTTP contract of the endpoints — httpx + ASGI + DB
test_api_agents · _admin · _accessCRUD and launch, admin registry and lock, roles and authentication