Agent interrupts from Activity tool with ApplicationFailure
An activityAsTool-wrapped Activity can interrupt the agent by throwing ApplicationFailure with type STRANDS_INTERRUPT_TYPE and nonRetryable: true. The plugin's Failure Converter preserves the interrupt payload, so AgentResult.interrupts is populated. Import STRANDS_INTERRUPT_TYPE from @temporalio/strands-agents.
Agent interrupts from hook with event.interrupt()
A hook on interruptible event like BeforeToolCallEvent can pause the agent by calling event.interrupt({ name: '...', reason: '...' }). The hook runs in Workflow context (must be deterministic). Agent.invoke() returns AgentResult with stopReason: 'interrupt' and interrupts array. Resume by calling agent.invoke() with interrupt responses.
MCP connection idle timeout
MCP Activities share one Worker-process connection per server. The connection disconnects after idle for mcpConnectionIdleTimeout (default 5 minutes). The timer resets on every reuse. Accept millisecond number or duration string like '30 seconds'.
TemporalMCPClient configuration
TemporalMCPClient accepts server (name matching registered MCP client), cacheTools (boolean, default false for re-listing tools each turn), and activityOptions (startToCloseTimeout, retry policy). Set cacheTools: true to list tools once and reuse schema for Workflow lifetime.
MCP server configuration in StrandsPlugin
StrandsPlugin accepts mcpClients mapping of name to McpClient factory. Each factory returns a fully configured McpClient. The plugin registers per-server {name}-listTools and {name}-callTool Activities. Reference MCP servers in Workflows via TemporalMCPClient with server name and activityOptions.
Hook callbacks must be deterministic
Hook callbacks run in Workflow context and must be deterministic. Do not use Date.now(), randomUUID(), or I/O inside hook callbacks. Use workflow.activityAsHook for anything requiring I/O.
workflow.activityAsHook for I/O in hook callbacks
For hook callbacks requiring I/O, use workflow.activityAsHook('activityName', { activityInput: (event) => ..., activityOptions: {...} }). The activityInput function extracts serializable values from the event to pass as the Activity's input.
Hook system for agent lifecycle events
Use agent.addHook(EventClass, callback) to subscribe to agent lifecycle events such as AfterToolCallEvent, BeforeToolCallEvent, invocation start/end, model call before/after, and message added. Hook callbacks run in Workflow context and must be deterministic. Use workflow.activityAsHook for I/O-safe callbacks.
workflow.activityAsTool parameters
workflow.activityAsTool takes: activityName (string matching Activity registration), description (string), inputSchema (JSON Schema or Zod schema), and activityOptions (startToCloseTimeout, retry policy, etc.). The tool name passed to agent.invoke hooks must match the Activity name registered on the Worker.
Register tools as Activities for I/O operations
Strands tools that perform I/O, access external services, or produce non-deterministic results must run as Temporal Activities. Register the tool Activity on the Worker, then pass it to TemporalAgent using workflow.activityAsTool with inputSchema, description, and activityOptions. Deterministic tools can run inline in the Workflow.
Model selection in StrandsPlugin
StrandsPlugin accepts a models mapping of name to factory function. Each factory is called lazily on first use on the Worker outside the Workflow sandbox. If models is omitted, a single BedrockModel factory is registered under name 'bedrock'. TemporalAgent selects which model to use via the model option by name.
TemporalAgent.invoke() accepts prompts or interrupt responses
TemporalAgent.invoke() can be called with a string prompt to start or continue an agent session, or with an array of InterruptResponseContent to respond to interrupts. Returns an AgentResult with stopReason, structuredOutput, and interrupts properties.
TemporalAgent configuration and options
TemporalAgent accepts activityOptions (including startToCloseTimeout and retry policy), model selection, tools array, structuredOutputSchema for typed responses, streamingTopic for output streaming, and messages for multi-turn conversations. It does not accept retryStrategy directly.
Workflow registration with StrandsPlugin
Create a Worker with Worker.create(), passing workflowsPath pointing to Workflow files, activities object for Activity implementations, and plugins array containing new StrandsPlugin(). The plugin automatically registers Activities for model calls. Omit models option to use default BedrockModel under name 'bedrock'.
Agent snapshots not supported in Temporal
TemporalAgent.takeSnapshot() and TemporalAgent.loadSnapshot() throw. Temporal's Event History persists Workflow state durably at finer granularity than Strands snapshots, making snapshots redundant inside a Workflow.
OpenAI hosted traces for agents
Enable the upstream hosted exporter before constructing the plugin, in the Worker process (not inside Workflow code). Use addTraceProcessor with BatchTraceProcessor and OpenAITracingExporter. Do not call setDefaultOpenAITracingExporter as it overwrites internal state on any OpenAIAgentsPlugin instances already constructed.
Streaming OpenAI agent runs
The run method supports streaming with { stream: true }. The streaming model Activity publishes each model event to a Workflow Stream topic as the model produces it, so an external client can observe a run live while it stays durable. Streaming is experimental. Set the topic name in modelParams.streamingTopic on the Client's OpenAIAgentsPlugin, not the Worker's; run fails with a StreamingTopicNotConfigured error if no topic is configured. Streaming requires the @temporalio/workflow-streams package.
Human-in-the-loop approvals with RunState
TemporalOpenAIRunner.run accepts a RunState as its second argument, matching the upstream runner. This supports human-approval flows that pause, wait for a Signal or Update, then Continue-As-New. Use RunState.fromString to deserialize a previous run state, and call state.approve(interruption) for each interruption to resume execution.
Carry conversation history across Continue-As-New
To carry session history across a Continue-As-New boundary in OpenAI agent Workflows: (1) Before continuing, capture the current history with const items = await session.getItems(); then call continueAsNew with those items. (2) The continued run declares a Workflow parameter to receive those items and re-seeds the session with: const session = new WorkflowSafeMemorySession({ initialItems: items });
WorkflowSafeMemorySession for conversation history
Use WorkflowSafeMemorySession for conversation history in Temporal-backed agents. It replaces the upstream MemorySession, which is not replay safe because it depends on host process state. Session history lives on the Workflow heap and is rebuilt by replay within a single run. It does not automatically survive continueAsNew—a continued run starts with an empty session.
Stateful MCP servers for agents
Use stateful MCP servers when a persistent connection or session is required. Register the provider with a NativeConnection; the plugin starts a dedicated in-process Worker pinned to a per-run Task Queue and routes MCP operations to it. In the Workflow, call connect() before use and cleanup() in a finally block. Dedicated Worker startup and heartbeat failures surface as an ApplicationFailure whose type is exported as DEDICATED_WORKER_FAILURE_TYPE.
Temporal orchestration spans for agents
Set addTemporalSpans: true in plugin interceptorOptions to emit temporal:* agent-SDK spans for orchestration operations such as Workflow starts, Signals, Queries, Updates, Activities, child Workflows, Nexus Operations, and Continue-As-New. These are agent-SDK spans, so they reach the hosted OpenAI dashboard, custom TracingProcessors, and OpenTelemetry when enabled.
Stateless MCP servers for agents
Use stateless Model Context Protocol servers when each tool call is independent. Register a StatelessMCPServerProvider on the Worker. Reference the same provider name from Workflow code with statelessMcpServer(). Each tool call creates a new server instance.
Nested agent tools with agentAsTool
Use agentAsTool to expose another Agent as a tool while keeping nested model calls durable. Nested approval interruptions are not supported; if a nested run pauses for approval, the tool invocation fails with an ApplicationFailure of type NestedAgentInterruption.
Nexus operation tools with nexusOperationAsTool
Use nexusOperationAsTool to expose a Nexus Operation as an agent tool. The Workflow starts the Operation through a Nexus client and feeds the stringified result back to the agent.
Inline and hosted tools for agents
For deterministic computation in agents, use tool() from @openai/agents-core directly. Inline tools run in the Workflow sandbox and must not perform non-deterministic activities like I/O or reading wall-clock time beyond Temporal's replacements. Hosted tools from @openai/agents-openai, such as webSearchTool(), run server-side through the model provider during the model Activity.
Activity-backed tools with activityAsTool
Use activityAsTool for HTTP calls, database access, file system work, or other I/O. The tool name must match a registered Activity. Example:
const weatherTool = activityAsTool<typeof activities.getWeather>(
{
name: 'getWeather',
description: 'Get the weather for a city',
parameters: {
type: 'object',
properties: { location: { type: 'string' } },
required: ['location'],
additionalProperties: false,
},
},
{
startToCloseTimeout: '10s',
retryPolicy: { maximumAttempts: 3 },
}
);
The type parameter is only used at compile time. At runtime, the Activity is invoked by name through proxyActivities.
Hello World workflow with OpenAI Agents example
Example of a basic Temporal-backed OpenAI agent:
import { Agent } from '@openai/agents-core';
import { TemporalOpenAIRunner } from '@temporalio/openai-agents/workflow';
export async function haikuAgentWorkflow(prompt: string): Promise<string> {
const agent = new Agent({
name: 'Assistant',
instructions: 'You only respond in haikus.',
model: 'gpt-4o-mini',
});
const runner = new TemporalOpenAIRunner();
const result = await runner.run(agent, prompt);
return result.finalOutput ?? '';
}
This shows a Workflow that creates an agent, instantiates a TemporalOpenAIRunner, runs the agent with a prompt, and returns the final output.
Configure Client for OpenAI Agents
Register the same OpenAIAgentsPlugin type on the Client so model parameters and tracing options propagate to new Workflows. Attach one OpenAIAgentsPlugin instance per Client or Connection configuration.
Configure Worker for OpenAI Agents
Register OpenAIAgentsPlugin on the Worker. The plugin registers the model Activity, adds trace-propagation interceptors, installs Workflow-bundle polyfills the OpenAI Agents SDK needs, and registers any configured MCP server providers. The modelParams option controls scheduling for the model Activity, including startToCloseTimeout, retry, and useLocalActivity. See ModelActivityOptions for the complete field list. The Worker process must have access to your model-provider credentials, typically from environment variables.
TemporalOpenAIRunner for Workflow agent loop
Use TemporalOpenAIRunner instead of the upstream Runner from the OpenAI Agents SDK. The runner runs the agent loop inside the Workflow and dispatches each model call to an Activity. TemporalOpenAIRunner mirrors the OpenAI Agents SDK Runner with familiar options such as maxTurns, context, and session. The runConfig.model must be a model name string (the Worker's modelProvider resolves it inside the model Activity). The signal option is not supported; use Temporal cancellation APIs such as CancellationScope to cancel Workflow work.
OpenAI Agents import paths
Import paths for the OpenAI Agents integration: @temporalio/openai-agents is used in Worker or Client code for plugin setup, MCP providers, and model option types; @temporalio/openai-agents/workflow is used in Workflow code for Runner, Workflow-safe tools, sessions, and MCP handles; @temporalio/openai-agents/otel is used in Worker or Client code for replay-safe OpenTelemetry setup; @temporalio/openai-agents/workflow-interceptor is used for Worker bundling and manual workflowInterceptorModules wiring without a plugin.
Install OpenAI Agents integration
Install with: npm install @temporalio/openai-agents @openai/agents-core @openai/agents-openai openai. The @openai/agents-core, @openai/agents-openai, and openai packages are peer dependencies.
OpenAI Agents SDK integration overview
Temporal's integration with the OpenAI Agents SDK for JavaScript/TypeScript lets you run agents as Temporal Workflows. Agent orchestration—the agent loop, tool selection, and handoffs—runs inside the Workflow, while model calls run as Activities. This allows LLM calls to retry durably and not repeat during Workflow replay. Agents survive Worker restarts and can run for extended periods without losing state.
OpenTelemetry integration for OpenAI agents
To emit agent spans through an OpenTelemetry pipeline: install @opentelemetry/sdk-trace-base as a peer dependency, register the tracer provider, and enable OpenTelemetry instrumentation in plugin options. Use createTracerProvider from @temporalio/openai-agents/otel and call trace.setGlobalTracerProvider before creating the plugin. Set interceptorOptions: { useOtelInstrumentation: true } on the plugin. Model calls, tools, and orchestration then land in the same backend as the rest of the application's traces.
Google ADK multi-agent systems with SubAgents
Build a coordinator agent with specialist SubAgents; ADK wires the parent/child relationship and exposes the built-in transfer_to_agent tool automatically. The entire tree—including the transfer hop—runs in the Workflow; only the model calls and any Activity-backed tools leave it.
Google ADK integration overview
Temporal's integration with Google ADK gives agents durable execution: the agent's orchestration loop runs inside a Temporal Workflow, each LLM call becomes a durable Temporal Activity, and any tool that does I/O runs as an Activity. Every step is retried, timed out, recorded in Workflow history, and replayable after crashes or restarts.
Google ADK integration setup: two changes required
To use the Google ADK integration: (1) Use googleadk.NewModel("<model-name>") as the agent's Model instead of the native ADK model. It is a model.LLM whose calls dispatch to the InvokeModel Activity; the real model is reconstructed worker-side, never in the Workflow. (2) Pass googleadk.NewContext(workflowCtx) to r.Run, which installs Temporal-deterministic time, UUID, and task-fan-out providers so the agent loop replays deterministically.
Google ADK tool execution model
Tools run in-workflow by default (the idiomatic Temporal model: the Workflow is deterministic, and anything touching the network, clock, or disk goes through an Activity). Opt a tool into an Activity with googleadk.ActivityAsTool, or use googleadk.NewMCPToolset for MCP tools.
Install Google ADK contrib module
Install the googleadk contrib module with: go get go.temporal.io/sdk/contrib/googleadk@latest
Google ADK plugin setup in worker
Configure the Worker with the integration's plugin, which registers the model and MCP Activities at Worker start and closes any cached MCP toolsets at Worker stop. The plugin accepts a googleadk.Config with a Models map of model names to ModelFactory functions. The real model credentials (like GEMINI_API_KEY) are read worker-side and never cross into the workflow. Disable the model SDK's own retries so Temporal's RetryPolicy is the single source of truth.
Google ADK model credentials placement
Model credentials must be provided worker-side. For Gemini, set GEMINI_API_KEY (or GOOGLE_API_KEY) in the worker's environment. Credentials are captured in the worker's ModelFactory and never cross the Activity boundary into the Workflow.
ActivityAsTool exposes Activity to agent
Use googleadk.ActivityAsTool(myActivity, options) to expose an existing func(context.Context, TArgs) (TResults, error) Temporal Activity to the agent as a tool. Its call dispatches the Activity, so it is retried, timed out, and visible in the UI. The parameter schema is inferred from the argument type.
Google ADK human-in-the-loop confirmation flow
A sensitive tool calls ADK's ctx.RequestConfirmation(hint, payload), which ends the turn with an adk_request_confirmation function call. The Workflow detects pending confirmations with googleadk.PendingConfirmations, durably waits for the human's decision delivered as a Temporal signal, and resumes the agent with googleadk.ConfirmationResponse. Because the wait is durable, the Workflow can sit idle for days and survive worker restarts.
Google ADK continue-as-new for long conversations
To keep a Workflow's history bounded during long conversations, snapshot the session with googleadk.ExportSession and continue-as-new, then rebuild it on the next run with googleadk.ImportSession. SessionSnapshot is JSON-serializable (session-scoped state plus the full event history), so every value in session state and every tool result must be JSON-encodable.
Google ADK streaming mode setup
Use googleadk.NewModel(name, googleadk.WithStreaming(topic, 0)) to drive the model in streaming mode. The InvokeModel Activity calls the model with stream=true, heartbeats, and publishes each chunk to a per-run workflowstreams topic for external consumers, then returns the aggregated final response into the Workflow so replay stays deterministic. Call googleadk.StreamServer(ctx) once near the top of the Workflow that drives r.Run, and set agent.RunConfig{StreamingMode: agent.StreamingModeSSE}.
Google ADK streaming mode limitations
The bidirectional RunLive path (hard-coded goroutines/channels) is not supported when using streaming mode.
Google ADK error handling and error classification
Model, tool, and MCP failures surface as Temporal ApplicationErrors tagged googleadk.ModelError, .ToolError, and .McpError. Classify them with googleadk.IsNonRetryable(err) rather than string-matching. For model calls, the upstream HTTP status drives retryability: 408/409/429/5xx are retryable; other 4xx are not.
Google ADK retry policy best practice
Disable your model client's own retries in the ModelFactory. InvokeModel already runs under Temporal's RetryPolicy; leaving the model SDK's retries on retries a transient failure twice over. Let Temporal own retries.
Google ADK plugin composition with other plugins
The integration's plugin only registers its Activities and closes cached MCP toolsets. It uses the default JSON data converter and ships no client/worker interceptor, so it composes with interceptor- or converter-based plugins (for example sdk-go/contrib/opentelemetry) without conflict. ADK emits its own OpenTelemetry spans; register your tracing interceptor on the worker as usual.
Google ADK testing without live LLM
The plugin ships test helpers so you can unit-test agent Workflows with no network: FakeModel (with TextResponse/FunctionCallResponse builders) and FakeMCPServer. Register them through the same googleadk.Config your production worker uses—via googleadk.NewActivities and Register rather than the plugin, since test environments construct no real Worker and therefore run no plugins.
Google ADK MCP toolset execution
googleadk.NewMCPToolset(...) is a workflow-side proxy that lists remote tools via the ListMcpTools Activity and executes calls via CallMcpTool. The live, stateful mcptoolset.New(...) runs worker-side (registered in Config.MCPToolsets), never in the Workflow.
Google ADK function tools run in-workflow by default
Ordinary functiontool.New(...) tools run on Temporal's deterministic dispatcher inside the Workflow—no Activity overhead—and their session-state mutations propagate normally. Their code must be deterministic and replay-safe: no direct network, clock, randomness, or goroutines.
Google ADK supported features
Supported: single- and multi-agent (SubAgents) trees, in-workflow function tools, ActivityAsTool, stateless MCP, Gemini built-in tools (executed server-side inside InvokeModel), human-in-the-loop tool confirmation, continue-as-new session-state carry, the in-memory session service, and SSE streaming.
Google ADK not-yet-supported features
Not yet supported: RunLive (bidirectional streaming), sub-agent-as-child-workflow, live memory/artifact tools that require in-workflow network I/O, and database/Vertex session services. These raise or are documented rather than silently degrading.
Google ADK multi-agent workflow example
Example multi-agent workflow with a coordinator that routes to specialist agents:
func MultiAgentWorkflow(ctx workflow.Context, question string) (string, error) {
weatherTool, err := googleadk.ActivityAsTool(GetWeather, googleadk.ActivityToolOptions{
Name: WeatherToolName,
Description: "Get the current weather for a city.",
})
if err != nil {
return "", err
}
weather, err := llmagent.New(llmagent.Config{
Name: "weather",
Description: "answers questions about the current weather in a city",
Model: googleadk.NewModel(WeatherModelName),
Instruction: "You are a weather specialist. Use the get_weather tool to answer weather questions.",
Tools: []tool.Tool{weatherTool},
})
if err != nil {
return "", err
}
jokes, err := llmagent.New(llmagent.Config{
Name: "jokes",
Description: "tells a light-hearted joke",
Model: googleadk.NewModel(JokesModelName),
Instruction: "You are a comedian. Respond with a short, friendly joke.",
})
if err != nil {
return "", err
}
coordinator, err := llmagent.New(llmagent.Config{
Name: "coordinator",
Description: "routes the user's request to the right specialist",
Model: googleadk.NewModel(CoordinatorModelName),
Instruction: "You are a router. Delegate weather questions to the weather agent and requests for a joke to the jokes agent. Do not answer directly.",
SubAgents: []agent.Agent{weather, jokes},
})
if err != nil {
return "", err
}
r, err := runner.New(runner.Config{
AppName: "multiagent",
Agent: coordinator,
SessionService: session.InMemoryService(),
AutoCreateSession: true,
})
if err != nil {
return "", err
}
adkCtx := googleadk.NewContext(ctx)
msg := genai.NewContentFromText(question, genai.RoleUser)
var answer string
for ev, err := range r.Run(adkCtx, "user-1", "session-1", msg, agent.RunConfig{}) {
if err != nil {
return "", err
}
if ev == nil || ev.Content == nil {
continue
}
for _, p := range ev.Content.Parts {
if p != nil && p.Text != "" {
answer = p.Text
}
}
}
return answer, nil
}
Google ADK human-in-the-loop workflow example
Example workflow with human-in-the-loop tool confirmation:
func ApprovalWorkflow(ctx workflow.Context, request string) (Result, error) {
delTool, err := functiontool.New[DeleteArgs, map[string]any](
functiontool.Config{
Name: DeleteToolName,
Description: "Delete a named resource. Requires human confirmation before it runs.",
},
deleteResource,
)
if err != nil {
return Result{}, err
}
root, err := llmagent.New(llmagent.Config{
Name: "assistant",
Description: "an assistant that can delete resources with human approval",
Model: googleadk.NewModel(ModelName),
Instruction: "Use the delete_resource tool when the user asks to delete something.",
Tools: []tool.Tool{delTool},
})
if err != nil {
return Result{}, err
}
r, err := runner.New(runner.Config{
AppName: "hitl",
Agent: root,
SessionService: session.InMemoryService(),
AutoCreateSession: true,
})
if err != nil {
return Result{}, err
}
adkCtx := googleadk.NewContext(ctx)
msg := genai.NewContentFromText(request, genai.RoleUser)
var res Result
for {
var events []*session.Event
for ev, err := range r.Run(adkCtx, "user-1", "session-1", msg, agent.RunConfig{}) {
if err != nil {
return Result{}, err
}
if ev == nil {
continue
}
events = append(events, ev)
if ev.Content != nil {
for _, p := range ev.Content.Parts {
if p != nil && p.Text != "" {
res.Answer = p.Text
}
}
}
}
pending := googleadk.PendingConfirmations(events)
if len(pending) == 0 {
return res, nil
}
var decision googleadk.ConfirmationDecision
workflow.GetSignalChannel(ctx, googleadk.ConfirmationSignalName).Receive(ctx, &decision)
res.Approved = decision.Confirmed
if decision.FunctionCallID == "" {
decision.FunctionCallID = pending[0].FunctionCallID
}
msg = googleadk.ConfirmationResponse(decision)
}
}
Google ADK continue-as-new chat workflow example
Example workflow with continue-as-new for long conversations:
func ChatWorkflow(ctx workflow.Context, in ChatInput) error {
svc := session.InMemoryService()
adkCtx := googleadk.NewContext(ctx)
if in.Snapshot != nil {
if _, err := googleadk.ImportSession(adkCtx, svc, in.Snapshot); err != nil {
return err
}
}
root, err := llmagent.New(llmagent.Config{
Name: "assistant",
Description: "a friendly conversational assistant",
Model: googleadk.NewModel(ModelName),
Instruction: "You are a helpful assistant. Answer the user, using the conversation history for context.",
})
if err != nil {
return err
}
r, err := runner.New(runner.Config{
AppName: AppName,
Agent: root,
SessionService: svc,
AutoCreateSession: true,
})
if err != nil {
return err
}
turns := 0
busy := false
err = workflow.SetUpdateHandlerWithOptions(
ctx,
SendMessageUpdateName,
func(ctx workflow.Context, text string) (string, error) {
if err := workflow.Await(ctx, func() bool { return !busy }); err != nil {
return "", err
}
busy = true
defer func() { busy = false }()
turnCtx := googleadk.NewContext(ctx)
var answer string
msg := genai.NewContentFromText(text, genai.RoleUser)
for ev, err := range r.Run(turnCtx, UserID, SessionID, msg, agent.RunConfig{}) {
if err != nil {
return "", err
}
if ev == nil || ev.Content == nil {
continue
}
for _, p := range ev.Content.Parts {
if p != nil && p.Text != "" {
answer = p.Text
}
}
}
turns++
return answer, nil
},
workflow.UpdateHandlerOptions{
Validator: func(ctx workflow.Context, text string) error {
if text == "" {
return fmt.Errorf("message must not be empty")
}
return nil
},
},
)
if err != nil {
return err
}
if err := workflow.Await(ctx, func() bool {
return workflow.GetInfo(ctx).GetContinueAsNewSuggested() || (in.MaxTurns > 0 && turns >= in.MaxTurns)
}); err != nil {
return err
}
if err := workflow.Await(ctx, func() bool { return workflow.AllHandlersFinished(ctx) }); err != nil {
return err
}
snap, err := googleadk.ExportSession(adkCtx, svc, AppName, UserID, SessionID)
if err != nil {
return err
}
return workflow.NewContinueAsNewError(ctx, ChatWorkflow, ChatInput{
Snapshot: snap,
MaxTurns: in.MaxTurns,
})
}
Google ADK streaming model setup example
Example of setting up a streaming model:
func StreamingAgentWorkflow(ctx workflow.Context, q string) (string, error) {
if err := googleadk.StreamServer(ctx); err != nil {
return "", err
}
topic := "run-" + workflow.GetInfo(ctx).WorkflowExecution.ID
root, _ := llmagent.New(llmagent.Config{
Model: googleadk.NewModel("gemini-2.0-flash", googleadk.WithStreaming(topic, 0)),
})
}
External consumers read chunks with workflowstreams.NewClient(c, workflowID, ...).Subscribe(...).
Google ADK worker plugin registration example
Example of registering the Google ADK plugin in a worker:
adkPlugin, err := googleadk.NewPlugin(googleadk.Config{
Models: map[string]googleadk.ModelFactory{
adk.ModelName: func(ctx context.Context, name string) (model.LLM, error) {
return gemini.NewModel(ctx, name, nil)
},
},
})
if err != nil {
log.Fatalln("Unable to build googleadk plugin", err)
}
w := worker.New(c, adk.TaskQueue, worker.Options{
Plugins: []worker.Plugin{adkPlugin},
})
w.RegisterWorkflow(adk.AgentWorkflow)
w.RegisterActivityWithOptions(adk.GetWeather, activity.RegisterOptions{Name: adk.WeatherToolName})
if err := w.Run(worker.InterruptCh()); err != nil {
log.Fatalln("Unable to start worker", err)
}