# Tools Guide

AriaFlow tools use the Vercel AI SDK `tool(...)` API. Tools are how agents read data, write state, and trigger flow transitions.

## Tool Basics

```ts
import { tool } from 'ai';
import { z } from 'zod';

const lookup = tool({
  description: 'Lookup an account by email',
  inputSchema: z.object({ email: z.string().email() }),
  execute: async ({ email }) => ({ id: 'ACC-123', email }),
});
```

## Tool Helpers

AriaFlow exposes:
- `createTool(...)`
- `createToolWithFiller(...)` for user-friendly filler text

```ts
import { createToolWithFiller } from '@ariaflowagents/core';

const lookup = createToolWithFiller({
  description: 'Lookup an account',
  filler: 'Let me check that...',
  inputSchema: z.object({ email: z.string().email() }),
  execute: async ({ email }) => ({ id: 'ACC-123', email }),
});
```

## Agent-to-Agent Consultation

Use `runtime.runAgent()` to have one agent consult another directly, without CTA routing or wrapper functions.

### Why This Matters

- **Team Model**: Lead agent orchestrates, specialists provide domain expertise
- **Single Response**: Customer sees ONE unified answer from lead agent
- **Type-Safe**: No `as any` casts needed - uses proper types
- **Automatic Context**: Session ID injected via `experimental_context`

### Basic Example

```ts
// Define specialist agents
const weatherAgent = {
  id: 'weather',
  name: 'Weather Specialist',
  type: 'llm' as const,
  systemPrompt: 'You are a weather expert.',
  model,
};

const newsAgent = {
  id: 'news',
  name: 'News Specialist',
  type: 'llm' as const,
  systemPrompt: 'You are a news expert.',
  model,
};

// Create lead agent with consultation tools
const leadAgent = {
  id: 'lead',
  name: 'Lead Agent',
  type: 'llm' as const,
  systemPrompt: 'You have access to weather and news specialists.',
  model,
  tools: {
    consult_weather: createTool({
      description: 'Consult Weather Specialist',
      inputSchema: z.object({ query: z.string() }),
      execute: async (input, options?: ToolExecutionOptions) => {
        const { runtime } = options.experimental_context;
        if (!runtime) throw new Error('Runtime required in tool context');
        
        let result = '';
        for await (const part of runtime.runAgent('weather', input, options.sessionId)) {
          if (part.type === 'text-delta') result += part.text;
        }
        
        return result;
      },
    }),
  },
};

// Runtime handles orchestration
const runtime = new Runtime({
  agents: [leadAgent, weatherAgent, newsAgent],
  defaultModel: model,
  ctaConfig: { enabled: false },
});

// Usage: Lead agent consults specialists
const response = await runtime.stream({ input: 'What is the weather today?' });
// Internally: consult_weather tool calls runtime.runAgent('weather', query)
// Weather agent responds, result returned to lead
// Lead combines into: "The weather is sunny, 72°F."
```

### How It Works

1. **User asks**: Lead agent
2. **Tool executes**: `consult_weather` tool
3. **Runtime available**: Tool receives `runtime` via `experimental_context.runtime`
4. **Direct consultation**: Tool calls `runtime.runAgent('weather', input, sessionId)`
5. **Session preserved**: Same session ID flows through consultation
6. **Specialist responds**: Weather agent processes request
7. **Result returned**: Tool result passed back to lead agent
8. **Unified answer**: Lead agent synthesizes and delivers ONE response

### Key Features

- ✅ **No wrapper functions** - Tools get runtime directly from context
- ✅ **Type-safe** - Uses `ToolExecutionOptions` and `ToolExecutionContext`
- ✅ **Session sharing** - Automatic sessionId injection
- ✅ **Clean consultation** - Direct agent-to-agent execution path
- ✅ **Team collaboration** - Multiple agents can work together

### When to Use

- When you need **one agent to consult another** (specialist pattern)
- When you want **team collaboration** (lead agent + specialists)
- When you need **direct agent control** (skip CTA entirely)

### When NOT to Use

- Simple tool-to-API calls (use `createTool()` directly)
- Handoffs/CTA (use handoffs for routing instead)
- Wrapper functions around tools

See [Agent Consultation Example](../../examples/agents/agent-consultation.ts) for a full working demo.

