feat(google-adk-agents): add @temporalio/google-adk-agents package#2120
feat(google-adk-agents): add @temporalio/google-adk-agents package#2120xumaple wants to merge 12 commits into
Conversation
76ffc67 to
adb04ef
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new contrib package, @temporalio/google-adk-agents, that enables running Google ADK (@google/adk) agents inside Temporal Workflows deterministically by routing non-deterministic boundaries (model + MCP calls) through Activities, with bundler compatibility shims to make ADK load in the Workflow sandbox.
Changes:
- Introduces the new
contrib/google-adk-agentspackage (plugin, workflow-safe API surface, worker Activities, polyfills, and tests). - Wires the package into the monorepo (workspace config, lint scoping, CODEOWNERS, top-level README listing).
- Adds extensive E2E/unit test coverage for model routing, streaming, MCP, replay determinism, and published-artifact consumption.
Reviewed changes
Copilot reviewed 28 out of 29 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Adds the new contrib package to the monorepo package list. |
| pnpm-workspace.yaml | Includes contrib/google-adk-agents in the pnpm workspace. |
| eslint.config.mjs | Adds lint scoping/rules for the new contrib package sources. |
| contrib/google-adk-agents/tsconfig.json | Adds TS build config and project references for the new package. |
| contrib/google-adk-agents/src/workflow.ts | Defines the workflow-safe entry point and re-exports workflow-safe APIs. |
| contrib/google-adk-agents/src/tools.ts | Implements activityAsTool to expose Temporal Activities as ADK tools. |
| contrib/google-adk-agents/src/testing.ts | Adds test doubles/helpers for model + MCP routing. |
| contrib/google-adk-agents/src/plugin.ts | Implements the worker-side plugin plus webpack shims/hooks for Workflow sandbox compatibility. |
| contrib/google-adk-agents/src/model.ts | Implements TemporalModel workflow-side boundary for durable model calls via Activities. |
| contrib/google-adk-agents/src/mcp.ts | Implements TemporalMCPToolset workflow-side boundary for durable MCP tool discovery/execution. |
| contrib/google-adk-agents/src/load-polyfills.ts | Installs workflow-context-only polyfills required by ADK/genai in the sandbox. |
| contrib/google-adk-agents/src/index.ts | Defines the worker-side main entry point exporting GoogleAdkPlugin. |
| contrib/google-adk-agents/src/activities.ts | Implements worker-side Activities for model inference, streaming, MCP list/call, retries, and heartbeats. |
| contrib/google-adk-agents/src/tests/workflows.ts | Workflow fixtures used by E2E tests to exercise in-sandbox ADK behavior. |
| contrib/google-adk-agents/src/tests/workflows-published.ts | Fixture proving the published artifact bundles/executes via by-name imports. |
| contrib/google-adk-agents/src/tests/tools.test.ts | E2E tests for activityAsTool. |
| contrib/google-adk-agents/src/tests/streaming.test.ts | E2E + unit tests for SSE streaming and stream disposal behavior. |
| contrib/google-adk-agents/src/tests/replay.test.ts | Replay determinism test with plugin registered during replay. |
| contrib/google-adk-agents/src/tests/published-artifact.test.ts | Tests CommonJS requires and Workflow bundling against the compiled lib outputs. |
| contrib/google-adk-agents/src/tests/model.test.ts | E2E tests for TemporalModel routing, summaries, timeouts, and error typing. |
| contrib/google-adk-agents/src/tests/mcp.test.ts | E2E tests for MCP tool discovery/calls and filtering/prefixing behavior. |
| contrib/google-adk-agents/src/tests/hitl.test.ts | E2E test for human-in-the-loop via Signals/Updates within ADK long-running tools. |
| contrib/google-adk-agents/src/tests/helpers.ts | Shared E2E test scaffolding and doubles (providers, tool defs, history helpers). |
| contrib/google-adk-agents/src/tests/errors.test.ts | Unit tests for error classification and retry-after parsing. |
| contrib/google-adk-agents/src/tests/agent.test.ts | E2E test proving a native ADK agent/runner runs durably with a one-line model swap. |
| contrib/google-adk-agents/README.md | Adds package documentation, usage examples, and design explanation. |
| contrib/google-adk-agents/package.json | Defines package metadata, exports map, dependencies/peers, and test/build scripts. |
| .github/CODEOWNERS | Adds code ownership for the new contrib package. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Initial preliminary draft of the Google ADK agent integration: plugin, model/MCP/tool workflow-side proxies, worker-side activities, test doubles, and E2E tests. Builds, typechecks, and passes the test suite; cleanup (lint, ava migration, packaging metadata, docs) to follow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ng, code fixes Convert tests vitest→ava, add eslint override, extend tsconfig base + references, fill package.json metadata, fix README/comment inaccuracies, warn on streaming without streamingTopic + adaptive-heartbeat the streaming activity, and register in CODEOWNERS + root README.
…ions Rename TemporalLlm->TemporalModel and TemporalMcpToolset->TemporalMcpToolSet (with their *Options) to match the Python contrib, and trim the public barrel to the constructs users actually touch -- demoting the activity-boundary wire types and the internal tool classes (TemporalMcpTool, ActivityTool) to internal. Replace the bespoke TemporalActivityOptions with the SDK's ActivityOptions, nested as `activity?:` consistently across the model, MCP, and activity-tool options. Reduce @experimental to the public entry points and conform the package to the repo prettier config.
… contrib Raise a non-retryable GoogleAdkStreamingTopicRequired error when streaming is requested without a streamingTopic, instead of silently falling back to a non-streaming call. Default the model and tool Activity start-to-close timeout to 1 minute, and derive the default Activity summary from the ADK `adk_agent_name` label. Adds E2E coverage for the streaming-without-topic failure and the agent-name summary default.
… tool-not-found - readStatus now also reads err.response?.status, so wrapped HTTP errors are classified by their real status instead of defaulting to retryable. - Nest the streaming Activity's finally block so stopHeartbeat() always runs even if the stream's async-dispose throws (was leaking the heartbeat timer). - MCP tool-not-found is now non-retryable; a tool absent from the server won't appear on a retry.
Condense plugin.ts's webpack-sandbox shim documentation down to the non-obvious WHY (why a data: URI shim rather than alias->false, the node: scheme strip, the determinism guarantee), cutting restatement and enumeration. Remove two code-restating one-line comments. No code changes.
…ehavior Rename TemporalLlm->TemporalModel and TemporalMcpToolset->TemporalMcpToolSet in the docs, note that streamingTopic is required for SSE streaming (requesting it without a topic throws GoogleAdkStreamingTopicRequired), and reflect the nested activity options shape.
…ct is consumable
Drop "type": "module" and add require/default export conditions (mirroring the
openai-agents sibling) so the package is require()-able from CommonJS and its
compiled lib bundles into a Workflow without the strict-ESM errors — a
require() threw `No "exports" main defined`, and the lib failed to bundle on
`import { builtinModules } from 'node:module'`. The CJS emit root-fixes both.
Also: export an inert builtinModules=[] from the node:module shim and alias
ADK's dist/cjs Postgres subtree (@mikro-orm/postgresql, pg) to silence the
remaining webpack warnings. Adds a regression test that consumes the built lib
by package name (CJS require + a Workflow bundling the barrel) so these can't
regress — the existing suite bundled source and hid them.
- README: import TemporalModel/activityAsTool from the /workflow subpath - README: fix TemporalMCPToolset / mockMCPToolset casing - README: note tools run in-workflow, activityAsTool opts into an Activity - README: drop the under-the-hood bundling section; retriable -> retryable - CODEOWNERS: align the contrib owner column
5d3386d to
b9c733a
Compare
| - **Streaming (SSE).** Streaming requires `streamingTopic` on `TemporalModel`: | ||
| set it to publish incremental `LlmResponse` chunks via | ||
| `@temporalio/workflow-streams` while the Workflow still receives the full | ||
| transcript. Requesting streaming without a `streamingTopic` throws a | ||
| non-retryable `GoogleAdkStreamingTopicRequired` error. |
There was a problem hiding this comment.
Could this have its own section with a code snippet?
| human's result — no special shim required. | ||
| - **Deterministic replay.** ADK's event IDs and timestamps funnel through | ||
| `Math.random()` / `Date.now()`, which the Temporal Workflow sandbox makes | ||
| deterministic — so the agent loop replays without a custom determinism hook. |
There was a problem hiding this comment.
What would a custom determinism hook entail? Since we don't have one, maybe we can just leave that part out so we don't confuse anyone.
| new Client({ | ||
| plugins: [ | ||
| new OpenTelemetryPlugin(), // 1. observability (outermost) | ||
| new GovernancePlugin(), // 2. governance |
There was a problem hiding this comment.
Do we have an example plugin for this? If not, rename OpenTelemetryPlugin() to ObservabilityPlugin() so users aren't looking for this.
Adds
@temporalio/google-adk-agents, a contrib plugin that runs Google Agent Development Kit (@google/adk) agents as durable Temporal Workflows. The agent graph runs inside the Workflow and replays deterministically; the non-deterministic boundaries — every model call and every MCP tool call — are routed out to Activities, so the whole run gets Temporal's retries, timeouts, heartbeating, and crash-safe replay. For users it's a one-line change: wrap the agent's model inTemporalLlmand register the plugin.