Lesson 2 · Agentic generation for the Teaching Assistant

Three platforms, one seam

ADK 2.0, Claude Managed Agents and Gemini's Antigravity agent compared against your constraints, and how each would plug into the generation engine seam. About 15 minutes.

Warm-up: answer from memory before opening

(1) State the three parts of the climbing test. (2) Where does a Thread's state live when an agent writes its messages, and why?

(1) The model must decide what to fetch mid-task; the job can wait; the gain is worth the extra tokens. (2) In Postgres, with one agent session per job (session-per-job), because generators never write memory and there should be one source of truth. Lesson 1.

The three, side by side

Facts as of September 2026. All three are moving fast, so check the linked docs again before you build.

Google ADK 2.0 (TypeScript)Claude Managed AgentsGemini Managed Agents (Antigravity)
What it isA framework: you host the loop and the graph[1]A hosted API: versioned Agent → Session per run → event stream, with a container per session[2]A hosted API: interactions.create with agent: "antigravity-preview-05-2026", running in a Linux sandbox[3]
StatusGA (TS 2.0.0, 2026-08-21)BetaPublic preview
Runs onNode, deployed to Cloud Run (not Deno or Supabase Edge)[4]Anthropic's infrastructureGoogle's infrastructure
ModelsGemini built in. OpenRouter needs a custom BaseLlm (your research)Claude only, through the Anthropic APIGemini 3.5–3.8 Flash only, through the Gemini API[5]
Fixed-shape outputTyped node outputSchema (zod)[6]Validate the final message yourself"Does not support structured outputs", so you validate the text
Your own toolsOrdinary functions or nodes, in your own processThe agent emits agent.custom_tool_use, the session goes idle, and you send back user.custom_tool_resultThe interaction returns requires_action, and you call create again with a function_result
Long runsYour Cloud Run requestStream events, or state-change webhooks[7]background: true, then poll interactions.get
StateIn-memory, Postgres (DatabaseSessionService) or Agent Platform sessions; Memory Bank service (in the 2.1.0 package, although the docs lag)[8]Sessions persist, and memory stores persist across sessionsprevious_interaction_id; environments kept for 7 days
SecretsYour own environmentVault credentials, substituted when requests leave the sandboxNetwork allowlist with header transform
Cost beyond tokensCloud Run, probably within the free tierRuntime at $0.08 per active hour; a hard dollar budget per session is availableSandbox compute is not billed during the preview

The conflict to decide. Your map says all LLM calls go to OpenRouter directly. Of the three, only ADK can keep that rule. Both managed services run their own vendor's models on their own API. Using either one for the bot means relaxing that preference, at least for the jobs you move to it. That decision is yours to make, and it belongs in the map.

How each plugs into the seam

The worker is a Supabase Edge Function with a 150 s wall clock (ticket 01). An agent run can take longer than that. So an agent-ready seam needs two outcomes: done now or pending, collect later.

generate(kind, jobId, bundle) → { done, result } | { pending, runRef }
collect(runRef)               → { done, result } | { pending } | { failed }
// The bot always validates `result` against the fixed shape, then records it.

Why mount the bundle instead of exposing tools? Each custom-tool call pauses a managed session until your code answers, so every answer would be another Edge Function invocation. A bundle given up front plus read-only GitHub access avoids those round trips. Keep custom tools for the ADK graph, where tools run in the same process.

Where each one fits best in this project

UseBest fitWhy
Classify, Exercise, Answer feedback, Topic recapPlain callsAll inputs are known and the latency targets are tight
Project-grounded Lesson; Follow-ups that need codeADK 2.0 graph with one agent nodeKeeps OpenRouter, typed outputs and fixed order, and adds exploration only where it pays
Project digest refresh (clone, read, list Candidate improvements)Managed agent (either)Sandbox with git and files, slow is fine, runs outside the Thread; Claude Managed Agents can also run it on a schedule
A trial against the ADK graphManaged agent, session-per-jobCheap to try behind the same seam, and the result shows whether a hosted harness writes better Lessons

Practice

1. Which platform can keep the "all LLM calls go to OpenRouter" rule?

2. Whose docs say the agent "does not support structured outputs"?

3. The worker has a 150 s wall clock and a managed run may take minutes. What should the seam do?

4. A Claude Managed Agents run calls your custom tool readLessonLines. What happens?

5. Which is the best first job for a managed agent in this project?

Take back to your tickets. (1) Ticket 13: add a pending → collect result to the seam, and list which generations may go agentic (Lesson, code-aware Follow-up). (2) Map: decide whether the OpenRouter-only rule holds after the MVP, because that decides whether managed agents are allowed in the bot at all. (3) A possible new ticket: a managed-agent Project digest refresh.

Read next (primary source): "Why we built ADK 2.0" (Google Developers Blog), then ADK graph workflows for the node() and edges syntax.

Questions, or a platform fact that looks out of date? Ask me, your teacher. To test these ideas with practitioners, try the Google AI Developers Forum or adk-js Discussions.