# Flows Guide

Flows provide structured, multi-step conversations using nodes and tool-driven transitions.

Legacy note: `AgentFlowManager` has been renamed to `FlowManager`. New flows should generally use `FlowAgent` orchestrated by the `Runtime`.

## Flow Agents

A `FlowAgent` wraps a `FlowConfig` and is orchestrated by the `Runtime`.

Key features:
- Node-based steps (`id`, `prompt`, `tools`)
- Tool-driven transitions via `createFlowTransition()`
- Implicit transition tools for `transitions[].on` edges (explicit tools override on name collisions)
- Contract-aware transitions (`contract.toolOnly`, `contract.requiresUserTurn`)
- Context strategies (`append`, `reset`, `reset_with_summary`)
- Hybrid mode to answer off-topic questions

## Minimal Flow Example

```ts
import { tool } from 'ai';
import { z } from 'zod';
import { createFlowTransition } from '@ariaflowagents/core';

const bookingFlow = {
  nodes: [
    {
      id: 'greeting',
      prompt: 'Welcome. What date would you like to book?',
      tools: {
        submit_date: tool({
          description: 'Capture booking date',
          inputSchema: z.object({ date: z.string() }),
          execute: async ({ date }) =>
            createFlowTransition('collect_time', { date }),
        }),
      },
    },
    {
      id: 'collect_time',
      prompt: 'What time works for you?',
      tools: {
        submit_time: tool({
          description: 'Capture booking time',
          inputSchema: z.object({ time: z.string() }),
          execute: async ({ time }) =>
            createFlowTransition('confirm', { time }),
        }),
      },
    },
    {
      id: 'confirm',
      prompt: 'Thanks. Confirm the booking?',
    },
  ],
  transitions: [
    {
      from: 'greeting',
      to: 'collect_time',
      on: 'to_collect_time',
      contract: {
        label: 'Move after date capture',
        conditionText: 'User has provided a valid date.',
        toolOnly: true,
        requiresUserTurn: true,
      },
    },
  ],
};
```

## Flow Agent Config

```ts
const bookingAgent: FlowAgentConfig = {
  id: 'booking',
  name: 'Booking',
  type: 'flow',
  systemPrompt: 'You are a booking assistant.',
  model,
  flow: bookingFlow,
  initialNode: 'greeting',
  mode: 'hybrid',
  canHandoffTo: [],
};
```

## Transition Tips

- Always return `createFlowTransition(targetId, data)` from tools that move the flow.
- If a transition has `on: 'to_next'`, `FlowManager` auto-exposes a `to_next` tool for that node.
- Use explicit tools when you need custom transition payload logic; explicit tool names override implicit transition tools.
- Use `createFlowUpdate(data, text, keys)` when you want to stay on the same node.
- Flow actions support `deferUntil: 'turn-end'` for deterministic post-response side effects.
- Use `contract.toolOnly: true` when a transition must come from a tool/event signal (not condition-only auto-transition).
- Use `contract.requiresUserTurn: true` to prevent autonomous chain transitions without a user turn.

## Prompt Composition

- Flow-level/global prompt is combined with node prompt by default.
- Set `addGlobalPrompt: false` on a node to suppress global prompt injection for that node (useful for short closing nodes).
- Optional `nodeType` (`start`, `agent`, `end`, `global`) improves validation/tooling consistency.

## Context Strategies

Use `contextStrategy: 'reset'` to keep each node clean, or `reset_with_summary` for long flows.
For `reset_with_summary`, you can set `summaryTimeoutMs` at flow or node level to prevent stalled turns.
