# Phase B: AI-Powered Action Suggestions — Implementation Plan

## 1. Codebase Research Summary

### What Exists Today

#### Agent API (`app/routes/agent_api.py`)
- **All routes under `/api/v2/` prefix** — v2 sites, actions, submissions, analytics, campaigns, templates
- **No `/api/agent/build` endpoint exists** — it's documented in the spec but not implemented
- Auth: `X-API-Key` header via `_authenticate_api_key()` helper
- Site creation uses `add_site()` from models
- Action CRUD via `create_action()`, `update_action()`, `delete_action()`

#### LLM Integration
- **No dedicated LLM client module exists** — spec documents raw `requests.post()` to `{LLM_HOST}/v1/chat/completions`
- Model: Qwen3.5-4B via llama.cpp on port 8086 (configured via `BUILDER_LLM_HOST` env var)
- OpenAI-compatible API format with system/user message pattern
- No prompt templates, response parsing, or streaming logic implemented yet

#### Action Types (6 types)
| Type | Purpose | Config Schema |
|---|---|---|
| `webhook` | POST to URL | url, method, headers, body_template |
| `email` | Send email | recipients, subject, body_template |
| `log` | Audit logging | message_template |
| `redirect` | Redirect user | url, delay |
| `document` | Generate doc | template_id, output_format |
| `chain` | Multi-step workflow | name, steps[] |

#### Chain Step Types (12 types)
`webhook`, `email`, `document`, `wait`, `condition`, `webhook_batch`, `log`, `redirect`, `llm`, `variable_set`, `variable_merge`, `http_call`

#### Chain Templates (11 pre-built)
- `notification_chain` — email + webhook + log
- `crm_sync_chain` — webhook (create) + webhook (update)
- `support_workflow_chain` — email + webhook + wait + email
- `approval_workflow_chain` — email → condition → email/webhook
- `multi_vendor_chain` — webhook_batch + wait + webhook
- `document_workflow_chain` — document + email + webhook
- `lead_routing_chain` — webhook → wait → email
- `data_pipeline_chain` — http_call + webhook + condition + log
- `notification_escalation_chain` — email → wait → condition → webhook → log
- `onboarding_sequence_chain` — email → wait → email → wait → webhook → log
- `marketing_automation_chain` — webhook → email → wait → email

#### Chain Templates Categories
`notification`, `crm_sync`, `support`, `approval`, `multi_vendor`, `document_workflow`, `lead_routing`, `data_pipeline`, `escalation`, `onboarding`, `marketing`

#### Chain Engine (`app/services/chain_engine.py`)
- `validate_chain(config)` — validates chain before saving
- `execute_chain(action_id, submission_data)` — full chain execution with variable scope, conditions, LLM steps
- `evaluate_condition(step, scope)` — condition evaluation
- `execute_chain_step(step, scope)` — step dispatch
- `_execute_llm_step(step, scope)` — LLM step execution (uses `LLM_HOST` for variable enrichment)
- `execute_chain_sync(action_id, submission_data)` — sync execution
- Steps stored as JSON in `config["steps"]` array

#### Action Pipeline (`app/services/action_pipeline.py`)
- `execute_action(action, submission_data)` — dispatches action by type
- `_execute_webhook()` — POST with Jinja2 templating, retry logic
- `_execute_email()` — via Resend API
- `_execute_document()` — template rendering
- `_execute_chain(action_id, submission_data)` — delegates to chain_engine

#### DB Schema (SQLite)
```sql
CREATE TABLE actions (
    id INTEGER PRIMARY KEY,
    site_id INTEGER REFERENCES sites(id),
    type TEXT,          -- webhook/email/log/redirect/document/chain
    config TEXT,        -- JSON object
    trigger_event TEXT DEFAULT 'submission',
    enabled BOOLEAN DEFAULT 1,
    execution_order INTEGER DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE form_versions (
    id INTEGER PRIMARY KEY,
    site_id INTEGER REFERENCES sites(id),
    field_config TEXT,  -- JSON snapshot
    version_number INTEGER,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

#### What's Missing for Phase B
1. `/api/agent/build` endpoint (documented, not built)
2. LLM client module (no reusable client exists)
3. Chain suggestion engine (LLM-based action/chain recommendations)
4. Suggested chains storage (temporary or draft table)
5. One-click deploy for suggested chains
6. Edit-before-deploy workflow


## 2. Phase B Implementation Plan

### 2.1. New Files to Create

| File | Purpose |
|---|---|
| `app/services/llm_client.py` | Reusable LLM client with prompt templates, response parsing, retry logic |
| `app/services/chain_suggester.py` | LLM-based chain suggestion engine — takes user prompt + field context, returns suggested action chains |
| `app/routes/agent_build.py` | `/api/agent/build` endpoint + `/api/agent/suggest-chains` + `/api/agent/deploy-chain` endpoints |
| `app/models_suggested_chains.py` | DB operations for suggested chains (temporary storage) |

### 2.2. Files to Modify

| File | Changes |
|---|---|
| `app/__init__.py` | Register new `agent_build` blueprint |
| `app/migrations.py` | Add `migrate_suggested_chains()` for new table |
| `docs/agent-infrastructure-spec.md` | Update Phase B status, add new endpoints |

### 2.3. DB Changes

#### New Table: `suggested_chains`
```sql
CREATE TABLE suggested_chains (
    id INTEGER PRIMARY KEY,
    site_id INTEGER REFERENCES sites(id),
    prompt TEXT,                     -- Original user prompt
    suggested_actions TEXT,          -- JSON array of suggested actions
    status TEXT DEFAULT 'pending',   -- pending | deployed | discarded
    user_edits TEXT,                 -- JSON of user modifications
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    expires_at TIMESTAMP             -- Auto-expire after 24h
);

CREATE INDEX idx_suggested_chains_site ON suggested_chains(site_id);
CREATE INDEX idx_suggested_chains_status ON suggested_chains(status);
```

This table acts as a temporary staging area for AI suggestions before deployment.

### 2.4. API Endpoint Design

#### `POST /api/agent/build`
The main entry point — accepts a natural language prompt and returns a complete form + suggested action chains.

**Request:**
```json
{
    "prompt": "Create a client intake form for our consulting business: client name, company, email, phone, project description, budget range, timeline",
    "form_type": "form",
    "theme": { "primary": "#2563eb" },
    "suggest_chains": true  // Phase B addition
}
```

**Response:**
```json
{
    "success": true,
    "site_id": 42,
    "token": "abc123xyz",
    "fields": [...],
    "actions_suggested": [
        {
            "id": "suggest_1",
            "type": "chain",
            "name": "Lead Management Workflow",
            "description": "Notify your team, sync to CRM, then send a follow-up after 24h",
            "confidence": 0.92,
            "category": "lead_routing",
            "steps": [
                {
                    "id": "step_1",
                    "type": "email",
                    "name": "Notify Sales Team",
                    "config": {
                        "recipients": ["{{owner_email}}"],
                        "subject": "New lead: {{client_name}}",
                        "body_template": "..."
                    }
                },
                {
                    "id": "step_2",
                    "type": "webhook",
                    "name": "Sync to CRM",
                    "config": {
                        "url": "",
                        "method": "POST",
                        "body_template": "{{ submission_data }}"
                    },
                    "requires_config": ["url"]
                },
                {
                    "id": "step_3",
                    "type": "wait",
                    "name": "Wait 24 hours",
                    "config": { "duration": "24h" }
                },
                {
                    "id": "step_4",
                    "type": "email",
                    "name": "Follow-up Email",
                    "config": { ... }
                }
            ],
            "suggestion_id": "sc_abc123"  // References suggested_chains DB record
        }
    ],
    "embed_url": "https://agentforms.io/embed/abc123xyz"
}
```

Key design decisions:
- `confidence` score (0.0–1.0) tells UI how strongly the LLM recommends this
- `requires_config` flags which step fields the user must fill before deploying
- `suggestion_id` ties back to the `suggested_chains` DB record for edit/deploy

#### `POST /api/agent/suggest-chains`
Standalone endpoint to get chain suggestions for an existing site (without rebuilding the form).

**Request:**
```json
{
    "site_id": 42,
    "prompt": "I want to set up automated follow-up emails after form submission"
}
```

**Response:**
```json
{
    "success": true,
    "suggestions": [ ... same format as actions_suggested above ... ]
}
```

#### `POST /api/agent/deploy-chain`
One-click deploy — takes a suggestion (with optional edits) and creates the real action.

**Request:**
```json
{
    "site_id": 42,
    "suggestion_id": "sc_abc123",
    "steps": [
        {
            "id": "step_2",
            "type": "webhook",
            "name": "Sync to CRM",
            "config": {
                "url": "https://my-crm.com/api/leads",  // User filled this in
                "method": "POST",
                "body_template": "{{ submission_data }}"
            }
        }
    ]  // Only steps that were edited/added; omitted steps use original suggestion
}
```

**Response:**
```json
{
    "success": true,
    "action_id": 156,
    "chain_steps": 4
}
```

#### `PUT /api/agent/suggestions/:suggestion_id`
Edit a suggested chain before deploying.

**Request:**
```json
{
    "steps": [
        // Modified steps — full replacement of the suggestion's steps
        { "id": "step_1", "type": "email", "name": "Notify Team", "config": {...} },
        // ... all steps with user modifications
    ],
    // Or partial edits:
    "edits": {
        "step_2.config.url": "https://my-crm.com/api/leads",
        "step_3.config.duration": "12h"
    }
}
```

#### `DELETE /api/agent/suggestions/:suggestion_id`
Discard a suggestion.

### 2.5. LLM Prompt Structure

#### System Prompt for Chain Suggestions
```
You are an automated workflow suggestion engine for AgentForms, a form automation platform.

Given a user's form description and form fields, suggest optimal post-submission action chains.

Available action step types:
- webhook: POST to any URL with submission data
- email: Send formatted email
- log: Store in audit log
- redirect: Redirect user to URL
- document: Generate PDF/DOCX from template
- wait: Pause for a duration (e.g., "24h", "1d", "2w")
- condition: Branch based on submission field values
- webhook_batch: Send to multiple endpoints simultaneously
- llm: Enrich data using AI (adds variables to submission)
- variable_set: Set a variable from field value
- variable_merge: Merge multiple fields into one variable
- http_call: Generic HTTP request (GET/PUT/DELETE)

Available pre-built chain templates by category:
- notification: email + webhook + log
- crm_sync: webhook (create) + webhook (update)
- support: email + webhook + wait + email
- approval: email → condition → email/webhook
- multi_vendor: webhook_batch + wait + webhook
- document_workflow: document + email + webhook
- lead_routing: webhook → wait → email
- data_pipeline: http_call + webhook + condition + log
- escalation: email → wait → condition → webhook → log
- onboarding: email → wait → email → wait → webhook → log
- marketing: webhook → email → wait → email

Rules:
1. Always suggest the MOST relevant chain based on the form purpose
2. Fill in realistic defaults for config fields when possible
3. Mark fields that require user configuration with "requires_config"
4. Use {{field_key}} template syntax for referencing form fields
5. Keep chains practical (2-6 steps, not excessive)
6. If multiple chains make sense, suggest the primary one and mention alternatives
7. Use pre-built templates as starting points when they fit
8. Confidence: high (0.8+) when form purpose clearly matches a template, low (<0.5) when uncertain

Response format — return ONLY valid JSON:
{
    "suggested_chains": [
        {
            "name": "string",
            "description": "string",
            "confidence": 0.0-1.0,
            "category": "string (one of the template categories)",
            "steps": [
                {
                    "type": "string",
                    "name": "string",
                    "config": {},
                    "requires_config": ["field_names_if_any"]
                }
            ]
        }
    ]
}
```

#### User Prompt Template
```
Form purpose: {prompt}
Form type: {form_type}

Form fields:
{field_list_json}

Suggest the best post-submission action chain(s) for this form.
Consider: What typically happens after someone submits this kind of form?
Who needs to be notified? Where does the data need to go? What follow-up actions make sense?
```

#### Field List Format for LLM
```json
[
    {"key": "client_name", "type": "text", "label": "Client Name"},
    {"key": "company", "type": "text", "label": "Company"},
    {"key": "email", "type": "email", "label": "Email"},
    {"key": "budget", "type": "select", "label": "Budget Range", "options": ["Under $5K", "$5K-$15K", "$15K-$50K", "$50K+"]},
    {"key": "project_description", "type": "textarea", "label": "Project Description"}
]
```

### 2.6. Response Format — Detailed

The `/api/agent/build` response needs to support both the existing spec contract AND Phase B additions:

```json
{
    "success": true,
    "site_id": 42,
    "token": "abc123",
    "fields": [...],  // Existing: generated field config
    "actions_suggested": [...],  // Phase B: suggested action chains
    "embed_url": "https://agentforms.io/embed/abc123",
    "meta": {
        "llm_model": "qwen3.5-4b",
        "llm_tokens_used": 1247,
        "suggestions_generated": true,
        "suggestion_ids": ["sc_abc123"]
    }
}
```

Each `actions_suggested` item:
```json
{
    "id": "suggest_1",  // UI identifier
    "type": "chain",
    "name": "Lead Management Workflow",
    "description": "Notify your team, sync to CRM, then send a follow-up after 24h",
    "confidence": 0.92,
    "category": "lead_routing",
    "steps": [
        {
            "id": "step_1",
            "type": "email",
            "name": "Notify Sales Team",
            "config": {
                "recipients": ["{{owner_email}}"],
                "subject": "New lead: {{client_name}}",
                "body_template": "A new lead has submitted..."
            },
            "requires_config": []
        },
        {
            "id": "step_2",
            "type": "webhook",
            "name": "Sync to CRM",
            "config": {
                "url": "",
                "method": "POST",
                "body_template": "{{ submission_data }}"
            },
            "requires_config": ["url"]  // User must fill this
        }
    ],
    "suggestion_id": "sc_abc123",  // DB reference
    "can_deploy": false  // false if requires_config fields are empty
}
```

### 2.7. Implementation Order (Recommended)

#### Step 1: LLM Client Module (`app/services/llm_client.py`)
- Create reusable client with `generate(prompt, system_prompt, temperature, max_tokens)`
- JSON response parsing with retry on parse failure
- Config from `BUILDER_LLM_HOST` env var
- This centralizes LLM access for both the existing (future) `/agent/build` form generation AND the new chain suggestions

#### Step 2: Suggested Chains Table + Models
- Migration for `suggested_chains` table
- `app/models_suggested_chains.py` with `create_suggestion()`, `get_suggestion()`, `update_suggestion()`, `deploy_suggestion()`, `delete_suggestion()`, `cleanup_expired()`

#### Step 3: Chain Suggester Service (`app/services/chain_suggester.py`)
- `suggest_chains(prompt, fields, form_type)` → list of suggested chain objects
- Uses llm_client with the system prompt defined above
- Validates LLM output against expected schema
- Falls back to template-based matching if LLM fails

#### Step 4: Agent Build Endpoint (`app/routes/agent_build.py`)
- `POST /api/agent/build` — main endpoint
- `POST /api/agent/suggest-chains` — standalone suggestions
- `POST /api/agent/deploy-chain` — one-click deploy
- `PUT /api/agent/suggestions/:id` — edit suggestion
- `DELETE /api/agent/suggestions/:id` — discard suggestion

#### Step 5: Wire Up + Register
- Register `agent_build_bp` in `app/__init__.py`
- Run migration
- Test end-to-end

### 2.8. Fallback Strategy

If the LLM is unavailable or returns invalid output:
1. Match form type/prompt keywords to pre-built chain templates from `chain_templates.py`
2. Return template-based suggestions with `confidence: 0.5` and `"llm_fallback": true` flag
3. This ensures the feature is always available even if the LLM is down

### 2.9. Edge Cases & Considerations

- **Rate limiting**: LLM calls are expensive — add per-user rate limiting on `/api/agent/build` and `/api/agent/suggest-chains`
- **Expiry**: `suggested_chains` records expire after 24h — add a background cleanup (can run in the existing rate limiter cleanup thread)
- **Security**: Validate all user edits against the action schema before deploying
- **Template variables**: In suggested chains, use `{{owner_email}}` for the site owner (resolved at deploy time) and `{{field_key}}` for form fields
- **Chain validation**: Run `validate_chain()` before deploying — reject invalid chains
- **One-click deploy creates a `type=chain` action**: The deployed action follows the exact same format as manually created chains

### 2.10. File Structure After Phase B

```
app/
├── __init__.py              # Modified: register agent_build_bp
├── migrations.py            # Modified: add suggested_chains table
├── models.py                # (no changes needed)
├── models_suggested_chains.py  # NEW
├── routes/
│   ├── agent_api.py         # (no changes — v2 routes)
│   ├── agent_build.py       # NEW: /api/agent/* endpoints
│   └── ...
├── services/
│   ├── llm_client.py        # NEW: reusable LLM client
│   ├── chain_suggester.py   # NEW: chain suggestion engine
│   ├── chain_engine.py      # (no changes)
│   ├── chain_templates.py   # (no changes)
│   ├── action_pipeline.py   # (no changes)
│   └── ...
└── ...
```

## 3. Summary

| Area | Status | Action |
|---|---|---|
| `/api/agent/build` endpoint | Not implemented | Create `app/routes/agent_build.py` |
| LLM client | No module exists | Create `app/services/llm_client.py` |
| Chain suggestion engine | Does not exist | Create `app/services/chain_suggester.py` |
| Suggested chains storage | No table | Add `suggested_chains` table + models |
| One-click deploy | Does not exist | `POST /api/agent/deploy-chain` endpoint |
| Edit before deploy | Does not exist | `PUT /api/agent/suggestions/:id` endpoint |
| Delete suggestion | Does not exist | `DELETE /api/agent/suggestions/:id` endpoint |
| Chain validation | Exists | Reuse existing `validate_chain()` |
| Chain templates | 11 templates exist | Use as LLM context + fallback |
| Chain engine execution | Fully working | Deployed chains use existing engine |
