Namespace: googleAdkAgentsWorkflow
Workflow-safe API for the Google ADK Temporal plugin — importable from Workflow code running in the V8 sandbox.
The Google ADK plugin is an experimental feature; APIs may change without notice.
Classes
Interfaces
- ActivityAsToolOptions
- ActivityNodeOptions
- HitlConfirmation
- LoadMcpResourceToolOptions
- MCPResourceContents
- TemporalMCPToolsetOptions
- TemporalModelOptions
References
MCPToolsetFactory
Re-exports MCPToolsetFactory
Type Aliases
ActivityRequireConfirmation
Ƭ ActivityRequireConfirmation: RequireConfirmation<Record<string, unknown>>
Whether an Activity tool call needs human approval before it runs: a flag, or
a predicate over the model's arguments. Spelled apart from ADK's own
RequireConfirmation, which an agent module imports from @google/adk in the
same breath as this one.
HitlConfirmationRequest
Ƭ HitlConfirmationRequest: Omit<UserInputRequest, "kind"> & { kind: "confirmation" }
A pause awaiting approval of a tool call gated with requireConfirmation:
ADK's own UserInputRequest narrowed to kind: 'confirmation'.
Answer it with hitlConfirmationResponse.
HitlInputRequest
Ƭ HitlInputRequest: Omit<UserInputRequest, "kind"> & { kind: "input" }
A pause awaiting free-form or structured data: ADK's own
UserInputRequest narrowed to kind: 'input'. Answer it with
hitlInputResponse.
HitlRequest
Ƭ HitlRequest: HitlInputRequest | HitlConfirmationRequest
A pause awaiting a human answer, plain JSON so a Workflow Query can return it
as-is. A discriminated union on kind, so narrowing on it picks the builder:
ADK's third kind, 'credential', is absent because pendingHitlRequests
never reports one and neither builder accepts one (see the module doc).
MCPRequireConfirmation
Ƭ MCPRequireConfirmation: boolean | (toolName: string, args: Record<string, unknown>, toolContext?: Context) => boolean | Promise<boolean>
Whether an MCP tool call needs human approval before it runs: a flag for
every tool of the toolset, or a predicate over the model's arguments and the
tool name as advertised to the model, which carries the toolset's prefix
when it sets one. A predicate MUST be a pure function of its inputs — ADK
re-evaluates it when binding the human's approval to the pinned call and
refuses the approval if it then answers false.
Variables
ADK_RUNTIME_FAILURE_TYPES
• Const ADK_RUNTIME_FAILURE_TYPES: Readonly<Record<string, string>>
The ADK runtime errors the plugin converts into non-retryable
ApplicationFailures, keyed by the error's name (ADK's own type guards
match by name too; not every class is exported). Any other error that
escapes a Workflow is left alone and follows the SDK's convention for
unexpected errors: it fails the Workflow Task, which retries. Use
WorkerOptions.workflowFailureErrorTypes to fail the execution on more.
DYNAMIC_NODE_FAIL_FAILURE_TYPE
• Const DYNAMIC_NODE_FAIL_FAILURE_TYPE: "GoogleAdkDynamicNodeFailError"
Error type for a dynamic node (ctx.runNode) whose child failed
(DynamicNodeFailError). ADK wraps the child's error in it; when that error
was a Temporal failure — a failed or cancelled Activity — the plugin raises
the original instead, so a cancelled execution still ends CANCELLED and the
cause chain matches a static node's.
HITL_RESPONSE_FAILURE_TYPE
• Const HITL_RESPONSE_FAILURE_TYPE: "GoogleAdkHitlResponseError"
Error type for an answer the HITL wire-format helpers refuse: a request of the
wrong kind, or a string ADK would silently retype on the way into the node.
Non-retryable, and raised where the helper is called.
It is an ApplicationFailure rather than a TypeError so that building the
response inside an Update handler rejects the Update: the SDK rejects an update
only for a TemporalFailure (packages/workflow/src/internals.ts), and any
other error fails the Workflow Task instead, which then retries forever against
an answer the caller can no longer take back.
INTENT_MISMATCH_FAILURE_TYPE
• Const INTENT_MISMATCH_FAILURE_TYPE: "GoogleAdkIntentMismatchError"
Error type for a human-in-the-loop approval ADK refused to bind to its gate
(IntentMismatchError) — for example an approval naming a tool that does not
require confirmation, or arguments that no longer match the pinned call.
INVOCATION_ABORTED_FAILURE_TYPE
• Const INVOCATION_ABORTED_FAILURE_TYPE: "GoogleAdkInvocationAbortedError"
Error type for an ADK invocation aborted through its abortSignal (InvocationAbortedError).
MCP_ERROR_FAILURE_TYPE
• Const MCP_ERROR_FAILURE_TYPE: "GoogleAdkMCPError"
Error type for a failed MCP listTools or callTool call. Raised inside an
Activity, so wherever you catch it, it arrives wrapped in an ActivityFailure:
match it through the .cause chain, never against the caught error's own .type.
An HTTP status, when present, is appended and classified exactly as for
MODEL_ERROR_FAILURE_TYPE — but an MCP failure rarely carries one, so a
rejected token or an unreachable server classifies as retryable rather than
failing fast, and the plugin sets no retry policy: the call retries indefinitely
until the caller bounds it with
TemporalMCPToolsetOptions.activity.retry.maximumAttempts.
MCP_RESOURCES_UNSUPPORTED_FAILURE_TYPE
• Const MCP_RESOURCES_UNSUPPORTED_FAILURE_TYPE: "GoogleAdkMCPResourcesUnsupported"
Error type when a <name>-listResources / <name>-readResource Activity finds
that the toolset its factory returned cannot serve MCP resources — it is a
BaseToolset without ADK 2.0's listResources / readResource methods.
Non-retryable, and raised inside the Activity, so it arrives wrapped in an
ActivityFailure: match it through the .cause chain. A factory returning
MCPConnectionParams never raises it: the plugin reads resources over a
session it opens itself.
MCP_TOOL_NOT_FOUND_FAILURE_TYPE
• Const MCP_TOOL_NOT_FOUND_FAILURE_TYPE: "GoogleAdkMCPToolNotFound"
Error type when the <name>-callTool Activity finds no tool by the requested name
in the BaseToolset its factory returned. Non-retryable, and raised inside that
Activity, so it arrives wrapped in an ActivityFailure: match it through the
.cause chain, never against the caught error's own .type. It reaches code that
calls the tool's runAsync itself.
A factory returning MCPConnectionParams never raises it: the plugin calls the tool
without resolving the name first, so the caller gets whatever the server answers.
MODEL_ERROR_FAILURE_TYPE
• Const MODEL_ERROR_FAILURE_TYPE: "GoogleAdkModelError"
Error type for a failed model call. Raised inside an Activity, so it arrives
wrapped in an ActivityFailure: match it through the .cause chain. A request
carrying an adk_agent_name label, as an ADK agent run's requests do, has its
failure recorded: it fails the Workflow — or rejects the Update whose handler ran
the turn — unless an onModelErrorCallback recovers and calls
markModelFailureHandled(error). A hand-built request ordinarily carries none, and
then only throws at the call site.
A failure that carries an HTTP status has it appended as .<status>, for example
GoogleAdkModelError.429, so match with startsWith, not ===; such a failure is
retryable for 408, 409, 429 and 5xx and non-retryable otherwise. One carrying no
status is the bare type and retryable. An x-should-retry response header overrides
either verdict.
NODE_REPORTED_FAILURE_TYPE
• Const NODE_REPORTED_FAILURE_TYPE: "GoogleAdkNodeReportedError"
Error type for a graph node that finished without output because the agent
it ran absorbed an error (ADK's NodeReportedError). When the absorbed
error was a TemporalModel call, the plugin raises that call's
ActivityFailure instead, so the model failure's HTTP status and cause
chain survive.
NODE_SCHEMA_VALIDATION_FAILURE_TYPE
• Const NODE_SCHEMA_VALIDATION_FAILURE_TYPE: "GoogleAdkNodeSchemaValidationError"
Error type for a node input/output/state that failed its ADK schema (NodeSchemaValidationError).
NODE_TIMEOUT_FAILURE_TYPE
• Const NODE_TIMEOUT_FAILURE_TYPE: "GoogleAdkNodeTimeoutError"
Error type for an ADK workflow-runtime node that exceeded its timeout.
ADK raises a plain NodeTimeoutError; the plugin converts it to a
non-retryable ApplicationFailure of this type as it leaves the Workflow
(or the Signal/Update handler) that ran the graph, so the execution fails
instead of retrying the Workflow Task forever. The original error is the
cause. The same conversion, under the types below, applies to every ADK
runtime error listed in ADK_RUNTIME_FAILURE_TYPES.
STATE_SCHEMA_FAILURE_TYPE
• Const STATE_SCHEMA_FAILURE_TYPE: "GoogleAdkStateSchemaError"
Error type for a session-state write that failed its ADK stateSchema (StateSchemaError).
STREAMING_TOPIC_REQUIRED_FAILURE_TYPE
• Const STREAMING_TOPIC_REQUIRED_FAILURE_TYPE: "GoogleAdkStreamingTopicRequired"
Error type when streaming is requested but TemporalModelOptions.streamingTopic
is unset. Non-retryable, and thrown in the Workflow, so code calling
TemporalModel directly catches it unwrapped.
UNSUPPORTED_FAILURE_TYPE
• Const UNSUPPORTED_FAILURE_TYPE: "GoogleAdkUnsupported"
Error type when BaseLlm.connect (BIDI live streaming) is called inside a
Workflow. Non-retryable, and thrown in the Workflow to whoever called connect,
so it arrives unwrapped.
Functions
activityAsTool
▸ activityAsTool(options): BaseTool
Wraps an existing Temporal Activity (by registered name) as an ADK
BaseTool. Add the returned tool to an agent's tools[].
Parameters
| Name | Type |
|---|---|
options | ActivityAsToolOptions |
Returns
BaseTool
activityNode
▸ activityNode<TInput, TOutput>(options): BaseNode<TInput, TOutput>
Wraps a registered Temporal Activity as an ADK workflow graph node. Put the
returned node on a Workflow's edges, run it from a dynamicEntry with
ctx.runNode(node, input), or give it to an LlmAgent's tools (ADK 2.0
wraps a node in a NodeTool; that needs an inputSchema).
Inside a Workflow the node's input (or the arguments args derives from it)
is sent to the Activity, and the Activity's result, whatever its shape, is the
node's output: it flows to the successors, and it is what ADK records to
fast-forward the node rather than run it again when a paused graph resumes.
The node's event carries the result as output only, the way ADK's
JoinNode does, because ADK's FunctionNode would take an object with a
parts array for genai Content and record no output for it. An Activity
returning nothing (undefined or null) completes the node with a null
output, so its successors receive null (and an outputSchema has to accept
it). The node can only run inside a Workflow.
Two of ADK's node flags are deliberately not exposed. waitForOutput is not
a fan-in gate: it parks a node in WAITING when the node ended with neither
an output nor a route (Workflow.handleCompletion), which for an Activity
node is a no-op when the Activity returns a value and a hang when it returns
undefined. Fan in with a JoinNode, the node type that does wait for every
predecessor (BaseNode.requiresAllPredecessors), and whose input is the map
from predecessor name to output. rerunOnResume only decides what happens to
a node that paused for input last turn (Workflow.scheduleNode); a node that
completed is always fast-forwarded, and an Activity node never raises an
interrupt, so neither value could change anything.
Type parameters
| Name | Type |
|---|---|
TInput | unknown |
TOutput | unknown |
Parameters
| Name | Type |
|---|---|
options | ActivityNodeOptions<TInput> |
Returns
BaseNode<TInput, TOutput>
hitlConfirmationResponse
▸ hitlConfirmationResponse(request, decision): Part
Builds the Part answering a tool-confirmation request
(adk_request_confirmation). ADK reads approvals from the latest
user-authored event only, so answer every pending confirmation in one
newMessage, and rebuild the agent for the resumed turn with the same tool
names — an approval naming a tool the agent no longer has is refused.
decision is checked before it is read, since an Update handler hands it over
unchecked: it must be an object whose confirmed is a boolean and whose hint,
when present, is a string (payload may be anything). ADK approves only on
confirmed === true, so a 'yes' is refused rather than guessed as either
answer. Every refusal is a non-retryable ApplicationFailure of type
HITL_RESPONSE_FAILURE_TYPE.
Parameters
| Name | Type |
|---|---|
request | HitlConfirmationRequest |
decision | HitlConfirmation |
Returns
Part
hitlInputResponse
▸ hitlInputResponse(request, value): Part
Builds the Part answering an input request (adk_request_input). Put it
in the next turn's newMessage as { role: 'user', parts: [part] }.
A plain object value is sent as-is, so it can satisfy the request's
responseSchema; anything else is wrapped in the { result: value }
envelope ADK unwraps. The unwrap is by shape, not by who wrote it: ADK
delivers the bare value of any response whose single key is result, so a
value of { result: x } reaches the node as x.
ADK also parses a string it unwraps as JSON, unless the request declared
a schema that accepts strings (type: 'string'), so '42' reaches the node
as a number and '"foo"' as foo with the quotes gone. Rather than let
that happen silently, this throws for any string that parses: declare a
string responseSchema on the RequestInput, or pass the parsed value
yourself.
A structured answer is also held to the request's responseSchema, with the
same check ADK runs when the graph resumes: an object or array that the schema
rejects is refused here, with ADK's own message, instead of failing the Workflow
Task later (a bare scalar is exempt, as it is in ADK).
value must be a JSON value (null included). undefined is refused because
ADK reads it as no answer at all: a waiting node resumes only once its answer
is !== undefined (workflow/workflow.ts), so the node would ask again while
pendingHitlRequests already counts the request as answered. A
function, symbol or bigint is refused as not JSON, which is also why a Client
could never send one over an Update.
Every refusal is a non-retryable ApplicationFailure of type
HITL_RESPONSE_FAILURE_TYPE, so calling this from a Signal or Update
handler on an unchecked value is safe.
Parameters
| Name | Type |
|---|---|
request | HitlInputRequest |
value | unknown |
Returns
Part
loadMcpResourceTool
▸ loadMcpResourceTool(toolset, options?): BaseTool
ADK 2.0's LoadMcpResourceTool for a TemporalMCPToolset: lets the
model list and load the MCP server's resources, reading them through the
toolset's <name>-listResources / <name>-readResource Activities. Add the
returned tool to the agent's tools[] alongside the toolset.
Parameters
| Name | Type |
|---|---|
toolset | TemporalMCPToolset |
options? | LoadMcpResourceToolOptions |
Returns
BaseTool
markModelFailureHandled
▸ markModelFailureHandled(error): void
Declares that the caller handled error from a failed TemporalModel call, so it must
not fail the Workflow or reject the Update it happened in. Other failures absorbed by the
same Workflow invocation — the main function, or the Signal or Update handler that ran
the turn — still surface. Does nothing outside a Workflow.
Call it from an ADK onModelErrorCallback, passing the error that callback received,
and return the substitute response from that callback — built with ADK's createEvent,
because ADK yields the callback's return value untouched and isFinalResponse then
dereferences the actions a bare LlmResponse does not carry. ADK finishes the run on
the substitute, and without this call the Workflow fails anyway and the recovery is
discarded. A cancellation cannot be handled this way: an execution whose cancel a model
call absorbed still ends CANCELLED.
Parameters
| Name | Type |
|---|---|
error | unknown |
Returns
void
pendingHitlRequests
▸ pendingHitlRequests(events): HitlRequest[]
The pauses in events that still await an answer, excluding credential
requests (see the module doc). Pass the session's events, collected from the
runAsync iteration or read from runner.sessionService.getSession(...).
This wraps ADK's getPendingUserInputRequests, whose bookkeeping is coarser
than it looks: a request counts as answered as soon as any functionResponse
anywhere in events carries its id, whoever authored it and whether or not
ADK went on to accept it (a reply its responseSchema refuses leaves the run
paused but drops it from this list). The converse also holds: an answer that
is not a function response never clears it, so a plain-text gate approval
(runConfig.plainTextToolConfirmation) and a text reply to an agent's own
requestInputTool both keep being listed. A driver loop that uses those has
to remember what it already answered.
Parameters
| Name | Type |
|---|---|
events | readonly Event[] |