# AriaFlow Config Guide

A comprehensive guide to creating and managing AriaFlow agent configurations.

## Overview

The AriaFlow Config package (`@ariaflowagents/config`) provides:
- Configuration loading from `ariaflow.jsonc` files
- Agent and flow definition parsing
- Tool registration and loading
- Runtime creation from config
- **HTTP Callbacks** for real-time event streaming

## Installation

```bash
npm install @ariaflowagents/config
```

## Quick Links

- [HTTP Callbacks Guide](./CALLBACKS.md) - Real-time event streaming to webhooks
- [Agent Architect](#agent-architect) - AI-powered agent generation from use cases

## Agent Architect

The Agent Architect is an AI-powered CLI tool that analyzes your use case and generates production-ready agent configurations, prompts, and implementation guides.

### Overview

Instead of manually crafting prompts and deciding which tools your agent needs, you describe your use case and the architect:
- Analyzes the domain and entities
- Recommends required tools
- Generates a 6-layer system prompt (inspired by OpenAI's data agent architecture)
- Creates implementation RFC with checklist
- Generates flow definitions (for flow/hybrid modes)

### Usage

```bash
# Basic usage - analyzes use case and generates artifacts
ariaflow agent architect --use-case "bakery that answers questions about products and store hours" --llm-driven

# With options
ariaflow agent architect \
  --use-case "cake shop order taking" \
  --mode hybrid \
  --detail-level simple \
  --name "cake-shop" \
  --emit-rfc
```

### Options

| Flag | Description |
|------|-------------|
| `--use-case <text>` | Use-case description (required) |
| `--name <id>` | Output id override |
| `--mode <value>` | `llm`, `flow`, or `hybrid` (default: hybrid) |
| `--detail-level` | `simple` or `detailed` - simple shows only required tools |
| `--llm-driven` | Use LLM-powered analysis (recommended) |
| `--emit-rfc` | Generate implementation RFC |
| `--out-dir <path>` | Output directory (default: ./.ariaflow/generated) |

### Generated Artifacts

The architect creates:

1. **System Prompt** (`.ariaflow/generated/prompts/<name>.system.md`)
   - 6-layer prompt: Identity, Safety, Tool Contract, Reasoning, Execution, Output

2. **RFC** (`.ariaflow/generated/rfcs/RFC_<name>.md`)
   - Domain analysis
   - Recommended tools with priorities
   - Tool policies
   - Implementation checklist
   - User journey

3. **Blueprint** (`.ariaflow/generated/blueprints/<name>.blueprint.json`)
   - Complete agent specification

4. **Flow** (for flow/hybrid modes)
   - `.ariaflow/generated/flow/<name>.json`
   - `.ariaflow/generated/code/flows/<name>.flow.ts`

### 6-Layer Prompt Model

Generated prompts use this structure (inspired by OpenAI's in-house data agent):

1. **Identity and Role** - Who the agent is
2. **Safety and Guardrails** - What to never do
3. **Tool Contract** - When/how to use tools
4. **Reasoning Workflow** - How to think through conversations
5. **Execution Policy** - Mode-specific behavior
6. **Output Constraints** - Formatting and verification

### Example: Bakery Inquiry Agent

```bash
ariaflow agent architect \
  --use-case "bakery that answers customer questions about products, prices, availability, store hours, and dietary info - NO orders" \
  --llm-driven \
  --mode llm \
  --detail-level simple \
  --name "bakery-inquiry"
```

This generates:
- System prompt with 6 layers
- Tools: get_product_info, check_inventory_availability, get_store_hours_and_contact, etc.
- RFC with implementation checklist
- All artifacts in `.ariaflow/generated/`

### Detail Levels

- **simple**: Only shows required tools, truncated prompt layers
- **detailed**: Shows all tools with full specs, complete prompts

## Configuration File

### Basic Structure

```jsonc
{
  "$schema": "https://mithushancj.com/config.json",
  "name": "my-agent",
  "version": "1.0.0",
  "runtime": {
    "defaultAgent": "chat",
    "defaultModel": "default"
  },
  "models": {
    "default": "openai:gpt-4o-mini"
  },
  "agents": { /* ... */ },
  "tools": { /* ... */ },
  "providers": { /* ... */ }
}
```

## Runtime Configuration

### Default Agent & Model

```jsonc
{
  "runtime": {
    "defaultAgent": "chat",
    "defaultModel": "default"
  }
}
```

### Model Registry

Define available models with providers:

```jsonc
{
  "models": {
    "default": "openai:gpt-4o-mini",
    "gpt-4": "openai:gpt-4",
    "claude-3": "anthropic:claude-3-5-sonnet-20241022"
  }
}
```

## Agents

Agents are the core components that handle user interactions.

### LLM Agent

```jsonc
{
  "agents": {
    "chat": {
      "type": "llm",
      "description": "A helpful assistant",
      "prompt": {
        "inline": "You are a helpful assistant. Be concise."
      },
      "tools": ["search", "calculator"]
    }
  }
}
```

### Triage Agent

Routes users to specialized agents:

```jsonc
{
  "agents": {
    "triage": {
      "type": "triage",
      "description": "Routes customers to the right department",
      "prompt": { "file": "./prompts/triage.md" },
      "routes": [
        {
          "agentId": "sales",
          "description": "Handles sales inquiries"
        },
        {
          "agentId": "support",
          "description": "Handles support issues"
        }
      ],
      "defaultAgent": "sales"
    }
  }
}
```

### Flow Agent

Guided workflow agents:

```jsonc
{
  "agents": {
    "booking": {
      "type": "flow",
      "description": "Hotel booking flow",
      "prompt": { "file": "./prompts/booking.md" },
      "flowRef": "booking-flow",
      "mode": "hybrid"
    }
  }
}
```

### Inline Prompt

For simple agents, use inline prompts:

```jsonc
{
  "agents": {
    "chat": {
      "type": "llm",
      "description": "A helpful assistant",
      "prompt": {
        "inline": "You are a helpful assistant. Be concise and friendly."
      }
    }
  }
}
```

### File-based Prompt

For complex prompts, use external files:

```jsonc
{
  "agents": {
    "support": {
      "type": "llm",
      "description": "Customer support",
      "prompt": { "file": "./prompts/support.md" }
    }
  }
}
```

Create the prompt file:

```markdown
# System Prompt

You are a customer support agent for our company.

## Guidelines
- Be empathetic and patient
- Always verify customer identity before sharing sensitive info
- Escalate complex issues to human agents

## Tools Available
- create_ticket: Create support tickets
```

## Tools

### External Tools

Define tools that agents can use:

```jsonc
{
  "tools": {
    "search": {
      "type": "module",
      "entry": "./tools/search/index.ts"
    },
    "calculator": {
      "type": "module",
      "entry": "./tools/calculator/index.ts"
    }
  }
}
```

Tool implementation (`tools/search/index.ts`):

```typescript
import type { ToolDefinition } from '@ariaflowagents/core';

export const tool: ToolDefinition = {
  description: 'Search for information',
  inputSchema: {
    type: 'object',
    properties: {
      query: { type: 'string', description: 'Search query' }
    },
    required: ['query']
  },
  execute: async (input: unknown) => {
    const { query } = input as { query: string };
    // Implementation
    return { results: [...] };
  }
};

export default tool;
```

### Skill Loader

Load skills from a directory:

```jsonc
{
  "tools": {
    "skill": {
      "type": "skill-loader",
      "paths": ["./skill"]
    }
  }
}
```

## Flows

Define reusable workflow patterns:

```jsonc
{
  "flows": {
    "booking-flow": {
      "steps": [
        {
          "id": "collect-info",
          "tool": "collect_info"
        },
        {
          "id": "confirm",
          "tool": "confirm_booking"
        }
      ]
    }
  }
}
```

## Providers

Configure API providers:

```jsonc
{
  "providers": {
    "openai": {
      "apiKey": "OPENAI_API_KEY",
      "baseUrl": "https://api.openai.com/v1"
    },
    "anthropic": {
      "apiKey": "ANTHROPIC_API_KEY"
    }
  }
}
```

## Loading Configuration

### Basic Loading

```typescript
import { loadAriaflowConfig } from '@ariaflowagents/config';

const config = await loadAriaflowConfig({
  configPath: './ariaflow.jsonc'
});
```

### With Model Registry

```typescript
import { loadAriaflowConfigWithResult } from '@ariaflowagents/config';
import { openai } from '@ai-sdk/openai';

const model = openai('gpt-4o-mini') as any;

const { config, summary, warnings } = await loadAriaflowConfigWithResult({
  configPath: './ariaflow.jsonc',
  modelRegistry: {
    default: model,
    'openai:gpt-4o-mini': model
  }
});

console.log(`Loaded ${summary.agents} agents`);
```

### Create Runtime

```typescript
import { createRuntimeFromConfig } from '@ariaflowagents/config';

const { config } = await loadAriaflowConfigWithResult({
  configPath: './ariaflow.jsonc'
});

const runtime = createRuntimeFromConfig(config);
```

## Directory Structure

```
my-agent/
├── ariaflow.jsonc              # Main configuration
├── .ariaflow/
│   ├── prompts/
│   │   ├── system.md           # System prompts
│   │   ├── chat.md             # Agent prompts
│   │   └── triage.md           # Triage prompts
│   ├── tools/
│   │   ├── search/
│   │   │   ├── index.ts        # Tool implementation
│   │   │   └── tool.json       # Tool metadata
│   │   └── calculator/
│   │       ├── index.ts
│   │       └── tool.json
│   ├── skill/
│   │   └── my-skill/
│   │       └── SKILL.md
│   └── flow/
│       └── booking-flow.json   # Flow definitions
└── package.json                # Optional: Tool dependencies
```

## Example: Complete Configuration

```jsonc
{
  "$schema": "https://mithushancj.com/config.json",
  "name": "support-agent",
  "version": "1.0.0",
  "runtime": {
    "defaultAgent": "triage",
    "defaultModel": "gpt-4o-mini"
  },
  "models": {
    "default": "openai:gpt-4o-mini",
    "gpt-4": "openai:gpt-4"
  },
  "agents": {
    "triage": {
      "type": "triage",
      "description": "Routes support requests",
      "prompt": { "file": "./prompts/triage.md" },
      "routes": [
        { "agentId": "billing", "description": "Billing inquiries" },
        { "agentId": "technical", "description": "Technical support" }
      ],
      "defaultAgent": "billing"
    },
    "billing": {
      "type": "llm",
      "description": "Handles billing questions",
      "prompt": { "file": "./prompts/billing.md" },
      "tools": ["create_ticket"]
    },
    "technical": {
      "type": "llm",
      "description": "Technical support",
      "prompt": { "file": "./prompts/technical.md" },
      "tools": ["diagnose", "create_ticket"]
    }
  },
  "tools": {
    "create_ticket": {
      "type": "module",
      "entry": "./tools/create_ticket/index.ts"
    },
    "diagnose": {
      "type": "module",
      "entry": "./tools/diagnose/index.ts"
    }
  },
  "providers": {
    "openai": {
      "apiKey": "OPENAI_API_KEY"
    }
  }
}
```

## Configuration Reference

### Root Properties

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `$schema` | string | No | JSON schema URI |
| `name` | string | Yes | Agent name |
| `version` | string | No | Version number |
| `runtime` | object | Yes | Runtime configuration |
| `models` | object | Yes | Model registry |
| `agents` | object | Yes | Agent definitions |
| `tools` | object | No | Tool definitions |
| `providers` | object | No | Provider configurations |
| `permissions` | object | No | Permission settings |
| `callback` | object | No | HTTP callback configuration |

### Runtime Properties

| Property | Type | Description |
|----------|------|-------------|
| `defaultAgent` | string | Default agent ID |
| `defaultModel` | string | Default model key |

### Agent Properties

| Property | Type | Description |
|----------|------|-------------|
| `type` | string | Agent type: `llm`, `triage`, `flow` |
| `description` | string | Agent description |
| `prompt` | object | Prompt configuration |
| `tools` | array | List of tool names |
| `routes` | array | Triage routes (triage only) |
| `defaultAgent` | string | Default route (triage only) |
| `flowRef` | string | Flow reference (flow only) |
| `mode` | string | Flow mode: `guided`, `hybrid` (flow only) |

### Prompt Properties

| Property | Type | Description |
|----------|------|-------------|
| `inline` | string | Inline prompt text |
| `file` | string | Path to prompt file |

### Callback Properties

See the [HTTP Callbacks Guide](./CALLBACKS.md) for complete documentation.

| Property | Type | Description |
|----------|------|-------------|
| `url` | string | Webhook endpoint URL (required) |
| `method` | string | HTTP method (`POST` or `PUT`) |
| `headers` | object | Custom headers |
| `allowList` | array | Event types to send |
| `denyList` | array | Event types to block |
| `includeFullText` | boolean | Include accumulated text |

## Best Practices

1. **Use file-based prompts** for complex prompts (>100 lines)
2. **Organize tools** in separate directories with `tool.json` metadata
3. **Use triage agents** for multi-agent routing
4. **Version your config** using semantic versioning
5. **Test locally** using the Hono server before deployment
6. **Use environment variables** for API keys

## Integration with Hono Server

```typescript
import { loadAriaflowConfigWithResult, createRuntimeFromConfig } from '@ariaflowagents/config';
import { createAriaChatRouter } from '@ariaflowagents/hono-server';

const { config, summary } = await loadAriaflowConfigWithResult({
  configPath: './ariaflow.jsonc',
  modelRegistry: { default: model }
});

const runtime = createRuntimeFromConfig(config);

const app = new Hono();
app.route('/', createAriaChatRouter({ runtime }));
```

## HTTP Callbacks

The HTTP callback feature allows you to stream agent events (text deltas, tool calls, etc.) to external webhooks in real-time. This is useful for:
- Analytics and monitoring
- Real-time UI updates
- Audit logging
- Integration with external systems

### Basic Configuration

Add a `callback` block to your `ariaflow.jsonc`:

```jsonc
{
  "name": "my-agent",
  "runtime": {
    "defaultAgent": "support",
    "defaultModel": "default"
  },
  "callback": {
    "url": "https://your-webhook.com/events",
    "method": "POST"
  }
}
```

### Complete Callback Configuration

```jsonc
{
  "callback": {
    "url": "https://your-webhook.com/events",
    "method": "POST",
    "headers": {
      "Authorization": "Bearer $ENV.API_KEY",
      "X-Source": "ariaflow",
      "Content-Type": "application/json"
    },
    "allowList": ["text-delta", "tool-call", "tool-result", "handoff", "error"],
    "denyList": ["step-start", "step-end"],
    "includeFullText": true
  }
}
```

### Configuration Options

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `url` | string | - | Webhook endpoint URL (required) |
| `method` | string | `"POST"` | HTTP method (`POST` or `PUT`) |
| `headers` | object | - | Custom headers for the request |
| `allowList` | array | `[]` (all events) | Only send these event types |
| `denyList` | array | `[]` (none) | Never send these event types |
| `includeFullText` | boolean | `false` | Include accumulated full text |

### Event Filtering

Use `allowList` to send only specific events:

```jsonc
{
  "callback": {
    "url": "https://analytics.example.com/events",
    "allowList": ["text-delta", "tool-call"]
  }
}
```

Use `denyList` to exclude specific events:

```jsonc
{
  "callback": {
    "url": "https://analytics.example.com/events",
    "denyList": ["step-start", "step-end", "agent-start", "agent-end"]
  }
}
```

**Filtering Rules:**
1. `denyList` takes precedence over `allowList`
2. If `allowList` is empty, all non-denied events are sent
3. Event types: `text-delta`, `tool-call`, `tool-result`, `tool-error`, `tool-start`, `tool-done`, `handoff`, `agent-start`, `agent-end`, `step-start`, `step-end`, `node-enter`, `node-exit`, `flow-transition`, `flow-end`, `error`, `done`

### Environment Variables

Use `$ENV.VAR_NAME` or `${ENV.VAR_NAME}` syntax for environment variables:

```jsonc
{
  "callback": {
    "url": "https://$ENV.WEBHOOK_HOST/events",
    "headers": {
      "Authorization": "Bearer $ENV.API_KEY",
      "X-Custom-Header": "${ENV.CUSTOM_VALUE}"
    }
  }
}
```

### Full Text Accumulation

When `includeFullText: true`, each event payload includes the accumulated text from all `text-delta` events:

```jsonc
{
  "callback": {
    "url": "https://your-webhook.com/events",
    "includeFullText": true
  }
}
```

**Payload Structure:**
```json
{
  "sessionId": "uuid",
  "agentId": "support",
  "timestamp": "2026-02-01T17:00:00.000Z",
  "part": {
    "type": "text-delta",
    "text": "Hello"
  },
  "fullText": "Hello! How can I assist you today?"
}
```

### Performance Considerations

The HTTP callback uses a **fire-and-forget** pattern to avoid blocking the agent's main stream. HTTP requests are sent without awaiting the response.

**Best Practices:**
1. Ensure your webhook endpoint is fast and reliable
2. Consider adding rate limiting on the receiving end
3. For high-volume applications, consider batching events on the receiver side
4. Use HTTPS for production deployments

### Example: Complete Configuration with Callbacks

```jsonc
{
  "$schema": "https://mithushancj.com/config.json",
  "name": "support-agent",
  "version": "1.0.0",
  "runtime": {
    "defaultAgent": "support",
    "defaultModel": "default"
  },
  "models": {
    "default": "openai:gpt-4o-mini"
  },
  "callback": {
    "url": "https://analytics.example.com/ariaflow-events",
    "method": "POST",
    "headers": {
      "Authorization": "Bearer $ENV.ANALYTICS_API_KEY",
      "X-Source": "production-agent"
    },
    "allowList": ["text-delta", "tool-call", "tool-result", "handoff", "error"],
    "includeFullText": true
  },
  "agents": {
    "support": {
      "type": "llm",
      "description": "Customer support agent",
      "prompt": "You are a helpful support agent.",
      "tools": ["search", "create_ticket"]
    }
  },
  "tools": {
    "search": { "type": "module", "entry": "./tools/search/index.ts" },
    "create_ticket": { "type": "module", "entry": "./tools/create_ticket/index.ts" }
  }
}
```

### Code-First Usage

You can also configure HTTP callbacks programmatically:

```typescript
import { Runtime, createHttpCallback } from '@ariaflowagents/core';

const runtime = new Runtime({
  agents: [agent],
  defaultAgentId: 'support',
  callback: {
    url: 'https://webhook.com/events',
    method: 'POST',
    headers: {
      'Authorization': 'Bearer $ENV.API_KEY'
    },
    allowList: ['text-delta', 'tool-call'],
    includeFullText: true
  }
});
```
