Add agent-adk: a Google ADK conversational agent template#246
Open
andrew-fleischer-databricks wants to merge 1 commit into
Open
Add agent-adk: a Google ADK conversational agent template#246andrew-fleischer-databricks wants to merge 1 commit into
andrew-fleischer-databricks wants to merge 1 commit into
Conversation
New Python agent template built on Google's Agent Development Kit (ADK v2.x), mirroring the agent-langgraph / agent-openai-agents-sdk conventions: MLflow Responses API via @invoke()/@stream() handlers, the shared chat UI, MLflow tracing, and DAB deployment to Databricks Apps. Design: - Model access via LiteLLM (openai/<endpoint> against {host}/serving-endpoints), so any Databricks / Foundation Model API endpoint works by name; per-request bearer token from the SDK credential chain. Default endpoint: databricks-claude-sonnet-4-5. - Stateless base: client-carried history is replayed into a per-request InMemorySessionService (seed_session_history); ADK Events are adapted to Responses stream events (process_adk_events). - Tracing via mlflow.litellm.autolog() (ADK routes model calls through LiteLLM), nested under the @invoke()/@stream() request trace. - MCP tools (UC functions, Genie, Vector Search, code interpreter) via ADK MCPToolset, commented out by default (needs google-adk[extensions]). - Pinned google-adk>=2.0.0,<3 (targets the 2.x API surface). process_adk_events unwraps ADK's {"result": <value>} tool-response wrapping so tool outputs are a bare string, matching the other templates and the shared e2e validate_time contract. Repo wiring: - Register agent-adk (sdk="adk") in .scripts/templates.py; add e2e entry in template_config.py; new source skills add-tools-adk and modify-adk-agent; .gitignore skill allowlist; README and .claude/AGENTS.md conventions (autolog, MCP, session/memory, app.yaml). - Synced shared scripts and skills via sync-scripts.py / sync-skills.py. Co-authored-by: Isaac
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
agent-adk, a new Python starter template built on Google's Agent Development Kit (ADK v2.x). It mirrors the functionality of the existingagent-langgraph/agent-openai-agents-sdktemplates — a conversational agent implementing the MLflow Responses API with the shared chat UI, MLflow tracing, and Databricks Asset Bundle deployment — while conforming to the repo's Python template conventions (realmlflow.genai.agent_server@invoke()/@stream()handlers, not a hand-rolled server).Why add an ADK agent template?
Databricks Apps intentionally ships agent starter templates across several frameworks — LangGraph, the OpenAI Agents SDK, and a TypeScript LangChain variant — so developers can start from the framework they already know rather than being forced onto one. Google's Agent Development Kit (ADK) is a notable gap: it has real developer and customer traction, and its absence meant ADK users had no on-ramp to building agents on Databricks Apps.
agent-adkcloses that gap while conforming to the exact same contract as the other templates — the MLflow Responses API via@invoke()/@stream()handlers, the shared chat UI, MLflow tracing, and DAB deployment — so framework choice never changes the deployment story.LiteLlm(model="openai/<endpoint>", api_base="{host}/serving-endpoints")), so the agent can target any Databricks or Foundation Model API endpoint by name; the default isdatabricks-claude-sonnet-4-5.LlmAgent,Runner, and session services directly. The base template is stateless — it replays client-carried history into anInMemorySessionServiceper request — with a documented path to a LakebaseDatabaseSessionServiceor managed memory.MCPToolset, matching the tool story of the other templates.mlflow.litellm.autolog()captures every model call as a span, giving the same end-to-end observability as the LangGraph and OpenAI variants.What an engineer needs to know
build_model()builds aLiteLlmper request with a bearer token pulled from the SDK credential chain (WorkspaceClient.config.authenticate()). Resolved per request, so it refreshes naturally and works for local CLI profiles and the deployed App service principal alike. This is more explicit than the LangChain/OpenAI clients only because LiteLLM needs a concreteapi_key.InMemorySessionService;seed_session_history()replays prior user/assistant text turns (system + tool turns intentionally dropped) and hands ADK the latest user turn. Durable memory is a documented add-on (LakebaseDatabaseSessionServicevia lakebase-setup, or managed-memory), not shipped in the base.langchain, OpenAI→openai, ADK→mlflow.litellm.autolog(), because ADK routes all model calls through LiteLLM. Documented in.claude/AGENTS.md.{"result": <value>}.process_adk_eventsunwraps the single-key form so outputs are bare strings, matching the other templates (and the shared e2evalidate_timeassertion).google-adk>=2.0.0,<3— the code targets the 2.x API (RunConfig/StreamingMode.SSE, currentLiteLlm/MCPToolsetimport paths).serving-endpointresource grant indatabricks.yml(relies on Foundation Model API default access, matchingagent-langgraph). Pointing the template at a custom/provisioned endpoint requires adding a grant — see the add-tools skill /examples/serving-endpoint.yaml.uv add "google-adk[extensions]"(themcpextra is not a base dependency).add-tools/modify-agent(from new source skillsadd-tools-adk/modify-adk-agent), plusapp.yaml+manifest.yamlso it's UI-creatable like the other base templates.lakebase-setupandmanaged-memoryare synced; there is no ADK-specific memory template (base is stateless by design).Testing
Ran the repo e2e suite against a live workspace:
uv run pytest test_e2e.py --template agent-adk(full local and deploy)./responsesand/invocations, each JSON + SSE streaming, plus OpenAI-SDK non-streaming and streaming.get_current_timetool call validated (validate_time).deploy→run→ app reached RUNNING →/agent/info200 → all six endpoint checks green on the real deployed Databricks App →bundle destroy. The tool-output-shape fix is confirmed on the deployed app, not just locally.agent-evaluate— not validated in this run. It failed on a Databricks CLI U2M OAuth token-cache concurrency race (exit status 45), triggered by MLflow'sConversationSimulatordoing concurrent SDK token force-refreshes. This is environmental and reproduces independent of the template (it will affect any template's evaluate step under a U2M profile); it should pass under CI / a PAT or service-principal profile. Flagging for the e2e-suite maintainers as non-adk-specific.build_templates()registry cross-check passes;uv syncresolves cleanly.Notes / follow-ups
lakebase-setup's shared body still frames agent memory only for the LangGraph/OpenAI advanced templates, and the MCP error-handling snippet inadd-tools-adkshows atimeoutexample rather than the try/except it describes.This pull request and its description were written by Isaac.