📦 deps(thirdparty): update snapshots
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
# ToolLoopAgent Patterns
|
||||
|
||||
Deep dive on v6 agent workflows.
|
||||
|
||||
## When to Use ToolLoopAgent
|
||||
|
||||
| Use Case | Approach |
|
||||
|----------|----------|
|
||||
| Single tool call | `streamText` with tools |
|
||||
| Multi-step reasoning | `ToolLoopAgent` |
|
||||
| Autonomous workflows | `ToolLoopAgent` with `stopWhen` |
|
||||
| Complex orchestration | `ToolLoopAgent` with custom stop conditions |
|
||||
|
||||
## Agent Configuration
|
||||
|
||||
```typescript
|
||||
import { ToolLoopAgent, stepCountIs } from 'ai';
|
||||
|
||||
const agent = new ToolLoopAgent({
|
||||
// Required
|
||||
model: 'anthropic/claude-sonnet-4.5',
|
||||
|
||||
// Optional
|
||||
instructions: 'You are a research assistant.',
|
||||
tools: { search, calculate, summarize },
|
||||
|
||||
// Stop conditions
|
||||
stopWhen: stepCountIs(10),
|
||||
// Or custom: async ({ steps }) => steps.length >= 10
|
||||
|
||||
// Tool selection
|
||||
toolChoice: 'auto', // 'auto' | 'required' | 'none'
|
||||
|
||||
// Token limits
|
||||
maxOutputTokens: 4096,
|
||||
});
|
||||
```
|
||||
|
||||
## Execution Patterns
|
||||
|
||||
### Non-Streaming (Simple)
|
||||
|
||||
```typescript
|
||||
const result = await agent.generate({
|
||||
prompt: 'Research quantum computing breakthroughs.',
|
||||
});
|
||||
|
||||
console.log(result.text);
|
||||
console.log(result.steps); // Array of all steps
|
||||
console.log(result.steps.length, 'steps executed');
|
||||
```
|
||||
|
||||
### Streaming (Real-time)
|
||||
|
||||
```typescript
|
||||
const stream = agent.stream({
|
||||
prompt: 'Analyze this data and provide insights.',
|
||||
});
|
||||
|
||||
for await (const chunk of stream.textStream) {
|
||||
process.stdout.write(chunk);
|
||||
}
|
||||
```
|
||||
|
||||
### UI Streaming (React/Next.js)
|
||||
|
||||
```typescript
|
||||
import { createAgentUIStream } from 'ai';
|
||||
|
||||
const stream = await createAgentUIStream({
|
||||
agent,
|
||||
messages: [{ role: 'user', content: 'What is the weather?' }],
|
||||
abortSignal: controller.signal,
|
||||
});
|
||||
|
||||
for await (const chunk of stream) {
|
||||
// Yield to client
|
||||
}
|
||||
```
|
||||
|
||||
## Stop Conditions
|
||||
|
||||
### Built-in: Step Count
|
||||
|
||||
```typescript
|
||||
import { stepCountIs } from 'ai';
|
||||
|
||||
stopWhen: stepCountIs(5) // Stop after 5 steps
|
||||
```
|
||||
|
||||
### Custom: Finish Reason
|
||||
|
||||
```typescript
|
||||
stopWhen: async ({ steps }) =>
|
||||
steps.at(-1)?.finishReason === 'stop'
|
||||
```
|
||||
|
||||
### Custom: Combined
|
||||
|
||||
```typescript
|
||||
stopWhen: async ({ steps }) =>
|
||||
steps.length >= 10 || steps.at(-1)?.finishReason === 'stop'
|
||||
```
|
||||
|
||||
## Tool Choice Control
|
||||
|
||||
```typescript
|
||||
const agent = new ToolLoopAgent({
|
||||
model: 'anthropic/claude-sonnet-4.5',
|
||||
tools: { search, calculate },
|
||||
|
||||
// Force tool use every step
|
||||
toolChoice: 'required',
|
||||
|
||||
// Disable tools (text only)
|
||||
toolChoice: 'none',
|
||||
|
||||
// Let model decide (default)
|
||||
toolChoice: 'auto',
|
||||
});
|
||||
```
|
||||
|
||||
## Agent with Constraints
|
||||
|
||||
```typescript
|
||||
const customerSupportAgent = new ToolLoopAgent({
|
||||
model: 'anthropic/claude-sonnet-4.5',
|
||||
instructions: `You are a customer support specialist.
|
||||
|
||||
Rules:
|
||||
- Never promise refunds without checking policy
|
||||
- Always be empathetic and professional
|
||||
- If unsure, offer to escalate
|
||||
- Keep responses concise
|
||||
- Never share internal company information`,
|
||||
tools: {
|
||||
checkOrderStatus,
|
||||
lookupPolicy,
|
||||
createTicket,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Accessing Step History
|
||||
|
||||
```typescript
|
||||
const result = await agent.generate({ prompt: '...' });
|
||||
|
||||
for (const step of result.steps) {
|
||||
if (step.type === 'tool-call') {
|
||||
console.log(`Called ${step.tool} with`, step.input);
|
||||
} else if (step.type === 'text-generation') {
|
||||
console.log('Generated:', step.output);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
```typescript
|
||||
try {
|
||||
const result = await agent.generate({ prompt: '...' });
|
||||
} catch (error) {
|
||||
if (error.name === 'AbortError') {
|
||||
console.log('Agent execution aborted');
|
||||
} else {
|
||||
console.error('Agent error:', error);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
**DO:**
|
||||
- Set reasonable `stopWhen` limits
|
||||
- Use typed tool schemas with Zod
|
||||
- Handle abort signals for long-running agents
|
||||
- Log step history for debugging
|
||||
|
||||
**DON'T:**
|
||||
- Leave agents unbounded (no stop condition)
|
||||
- Use synchronous blocking operations in tools
|
||||
- Ignore error states
|
||||
- Skip tool validation
|
||||
Reference in New Issue
Block a user