UNPKG

workflow

Version:

Workflow SDK - Build durable, resilient, and observable workflows

87 lines (66 loc) • 3.05 kB
--- title: Patterns for Defining Tools description: Common patterns for defining tools in durable AI agents using Workflow SDK. type: guide summary: Define step-level and workflow-level tools for durable AI agents with stream writing and context access. prerequisites: - /docs/ai related: - /docs/ai/streaming-updates-from-tools - /docs/ai/sleep-and-delays - /docs/foundations/workflows-and-steps - /docs/api-reference/workflow/get-writable --- This page covers the details for some common patterns when defining tools for AI agents using Workflow SDK. Using WorkflowAgent, we model most tools as steps. These can range from a single function call to an entire multi-day workflow. ## Accessing message context in tools As with regular AI SDK tool definitions, tools in WorkflowAgent receive the tool's input parameters as the first argument and the tool call context as the second. When your tool needs access to the full message history, you can access it via the `messages` property of the tool call context: ```typescript title="tools.ts" lineNumbers import type { ModelMessage } from "ai"; async function getWeather( { city }: { city: string }, { messages, toolCallId }: { messages: ModelMessage[], toolCallId: string }) { // [!code highlight] "use step"; return `Weather in ${city} is sunny`; } ``` ## Writing to streams As discussed in [Streaming Updates from Tools](/docs/ai/streaming-updates-from-tools), it's common to use a step only to call `getWritable()` for writing custom data parts to the stream. This can be made generic, by creating a helper step function to write arbitrary data to the stream: ```typescript title="tools.ts" lineNumbers import { getWritable } from "workflow"; async function writeToStream(data: any) { "use step"; const writable = getWritable(); const writer = writable.getWriter(); await writer.write(data); writer.releaseLock(); } ``` ## Step-level vs workflow-level tools Tools can be implemented either at the step level or the workflow level, with different capabilities and constraints. | Capability | Step-Level (`"use step"`) | Workflow-Level (`"use workflow"`) | |------------|---------------------------|----------------| | `getWritable()` | ✅ | ❌ | | Automatic retries | ✅ | ❌ | | Side-effects (e.g. API calls) allowed | ✅ | ❌ | | `sleep()` | ❌ | ✅ | | `createWebhook()` | ❌ | ✅ | Tools can also combine both by starting out on the workflow level, and calling into steps for I/O operations, like so: ```typescript title="tools.ts" lineNumbers import { sleep } from "workflow"; import type { LanguageModel, ModelMessage } from "ai"; // Step: handles I/O with retries async function performFetch(url: string) { "use step"; const response = await fetch(url); return response.json(); } // Workflow-level: orchestrates steps and can use sleep() async function executeFetchWithDelay({ url }: { url: string }) { const result = await performFetch(url); await sleep("5s"); // Only available at workflow level return result; } ```