Test end to end: laptop, container, live URL
The done-when checks from The AI Agent Factory applied at each stage of the basic agent: the harness on your laptop, the same harness inside the container, the deployed URL on Vercel, then the eval set and the harness gates against the live endpoint.
- Status
- stable
- Trust
- human-reviewedHuman: Raza Rizwan ·
- Owner
- Human: Raza Rizwan
- Approved
- Human: Raza Rizwan ·
The book closes every deployment step with a done when list: conditions a command can prove, not a feeling that it works. 1 This page runs those conditions in order, at each of the three places the agent now lives, and then adds the two checks that matter for behaviour rather than plumbing. Do not skip a stage; each one proves something the next one assumes.
Stage 1: the harness on your laptop
Boot it, then ask it two questions from another shell. The companion ships a
smoke test that POSTs one message to a running harness; it is the whole
end-to-end check in twenty lines, and it needs OPENAI_API_KEY in your
.env so the agent can actually answer. 2
uv run uvicorn chat_agent.main:app --reload --port 8000# scripts/smoke.py, the companion's smoke test: POST one message to a running harness
from __future__ import annotations
import json
import sys
import urllib.request
URL = "http://localhost:8000/runs"
BODY = {"message": "Hi, I cannot log in to account acct_1001.", "session_id": "smoke"}
def main() -> int:
req = urllib.request.Request(
URL,
data=json.dumps(BODY).encode("utf-8"),
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(req, timeout=60) as resp:
print(resp.read().decode("utf-8"))
return 0
except Exception as exc: # noqa: BLE001
print(f"smoke failed: {exc}", file=sys.stderr)
return 1
if __name__ == "__main__":
raise SystemExit(main())Change BODY to one of your own proven inputs from
from plan to worker, then:
curl http://localhost:8000/health
uv run python scripts/smoke.pyDone when: the harness starts with no errors; /health returns
{"status": "ok", ...}; /docs shows the two endpoints; the smoke test
prints a reply and exits 0. 1 If /runs answers 503, the key is not
in .env; that is the harness working as designed, not a bug.
2
Stage 2: the same harness inside the container
Build the image and run it with your .env handed in at run time, then
repeat exactly the two checks from stage 1 against the container. 1
docker build -t chat-agent .
docker run --rm -p 8000:8000 --env-file .env chat-agentDone when: the image builds with no errors; /health returns ok from
inside the container; the smoke test passes against it; and after you change
one source line and rebuild, the build is fast because the dependency layer
stays cached. 1
Stage 3: the deployed URL
Deploy as on the previous page. With the CLI, standard output is always the deployment URL, so capture it: 3
vercel > deployment-url.txtPoint the smoke test at that URL (URL = "https://<your-deployment>/runs")
and run it again. The book's done-when for the cloud step is written to be
run from somewhere that is not your laptop: opening https://<that-url>/health
from your phone returns {"status": "ok", ...}. 1
Then wait. Functions not receiving any traffic for 5 minutes in production,
and 30 seconds in preview, automatically scale down, and the container gets
a SIGTERM with a 30 seconds grace period. 4 The
book's third condition is that after a quiet spell the app scales to zero
and the next request wakes a copy within a few seconds, a scale-to-zero cold
start. 1 So the check is: leave it alone past the window, call
/health once more, and expect a slower first answer followed by ok. A
session started before the scale-down is gone afterwards, which is the
laptop-versus-production difference the previous page's note warned about;
it is expected here, not a failure.
Done when: /health answers ok over HTTPS from a device that is not your
laptop; the smoke test passes against the live URL; and one cold start has
been observed and recovered from. 1
Stage 4: behaviour, against the live endpoint
Plumbing passing is not the agent passing. Run the golden set from
evals before shipping against the deployed
/runs, not the laptop; the book's reason for FastAPI's generated schema is
precisely that the eval suite can hit the harness's endpoints with checked
requests. 1 Grade at least the final output and the tool calls with
their arguments, as a pass rate across several runs, per difficulty tag; a
change ships only when the failing case passes and nothing else regressed.
5
Stage 5: the gates, on purpose
Prove the harness stops when it should, before anyone else can reach the URL:
- Send an input the input guardrail must block, and confirm the turn stops and no tool runs. That is the tripwire from the build page firing in production.
- Send an input that reaches the approval-gated tool, and confirm the run pauses with an interruption instead of acting.
- Send an input the agent cannot finish, and confirm
max_turnsends the run instead of the loop running on.
Each of those is a condition from loop and harness made real: a limit, a deny, an ask.
The checklist
| Stage | Done when |
|---|---|
| Laptop | Boots clean; /health ok; /docs lists both endpoints; smoke test exits 0 |
| Container | Image builds; /health ok from inside; smoke passes; rebuild after one edit is fast |
| Live URL | /health ok over HTTPS from your phone; smoke passes against the URL; one cold start recovered |
| Behaviour | Golden set passes its thresholds against the live /runs, across several runs |
| Gates | Guardrail blocks; approval pauses; max_turns ends a run |
Everything above the last two rows is the book's own done-when list; the last two are the same discipline applied to behaviour. Keep this table in the project's progress file so the next run of your coding agent starts from what is already proven.
When the table is full, you have a basic worker behind a URL. If you want a second pair of eyes on it, the 15-minute call on the audit page is the place; bring the deployment URL and your step table.
Continue to give it a record, which is where the book continues past this room, or to the worked example to see the whole room on one small agent.
Footnotes
-
Deploy Your Agent Harness to the Cloud: A Crash Course, Decisions 1, 2 and 3 ("Done when" lists) and Concept 4. The AI Agent Factory, Panaversity, 2026. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
deploying-agents-base companion:
scripts/smoke.py,Makefile,README.md. Panaversity, 2026. ↩ ↩2 -
vercel deploy, section Standard output usage. Vercel CLI documentation, last updated 2026-08-11. ↩
-
Container Images, section Scale in behavior. Vercel documentation, last updated 2026-07-07. ↩
-
Eval-Driven Development for AI Employees: A Multi-Track Crash Course, Concepts 2, 3 and 12. The AI Agent Factory, Panaversity, 2026. ↩
Sources
- [^af-50]Deploy Your Agent Harness to the Cloud: A Crash Course. The AI Agent Factory, Panaversity, 2026
- [^af-50-companion]deploying-agents-base, the companion code for the deployment crash course (scripts/smoke.py, Makefile). Panaversity, 2026
- [^af-49]Eval-Driven Development for AI Employees: A Multi-Track Crash Course. The AI Agent Factory, Panaversity, 2026
- [^vercel-container-images]Container Images. Vercel documentation, last updated 2026-07-07
- [^vercel-cli-deploy]vercel deploy. Vercel CLI documentation, last updated 2026-08-11
FastAPI, Docker, Vercel: put the agent behind a URL
Wrap the text agent in a FastAPI harness, build the container image the book uses, and deploy it to Vercel from the official Vercel docs: Dockerfile.vercel, the PORT variable, project environment variables, vercel deploy, and the scale-in rules.
Give it a record: the tables a worker runs against, the audit trail, and the MCP wire
Where the book continues after this room's basic worker, from The AI Agent Factory: every worker runs against a system of record; four tables every worker keeps; Postgres with pgvector over a separate vector store; the embedding pipeline; the audit trail written in the same transaction as the action; what MCP is and is not; a development plane that never reaches runtime; when a custom MCP server earns its keep over a plain function tool; reads run free, writes are gated, schema changes never reach production through the agent.