> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Rules Quickstart

> Create intelligent, context-aware behaviors for your AI agents with powerful rule-based automation

## Introduction

Agent Rules are the decision-making engine of your StateSet agents. They enable sophisticated, context-aware behaviors that adapt to customer needs, business policies, and real-time conditions. This guide will show you how to create rules that make your agents truly intelligent.

## What are Agent Rules?

Rules define how your agents respond to specific situations. They work on an "if-then" basis but can incorporate complex logic, multiple conditions, and sophisticated actions. Think of rules as your agent's decision tree—guiding every interaction toward the best possible outcome.

### How Rules Work

<Frame caption="Rule Execution Flow">
  ```mermaid theme={null}
  graph TD
    A[Customer Message] --> B{Evaluate Rules}
    B --> C{Condition 1?}
    C -->|Yes| D[Execute Action 1]
    C -->|No| E{Condition 2?}
    E -->|Yes| F[Execute Action 2]
    E -->|No| G{Condition 3?}
    G -->|Yes| H[Execute Action 3]
    G -->|No| I[Default Response]
    D --> J[Continue Conversation]
    F --> J
    H --> J
    I --> J
  ```
</Frame>

## Why Rules Matter

<CardGroup cols={3}>
  <Card title="Consistent Responses" icon="equals">
    Ensure every customer gets the right answer, every time
  </Card>

  <Card title="Business Logic" icon="briefcase">
    Embed your policies and procedures directly into agent behavior
  </Card>

  <Card title="Dynamic Adaptation" icon="shuffle">
    Adjust responses based on context, customer history, and real-time data
  </Card>
</CardGroup>

## Getting Started

### Prerequisites

1. StateSet account with API access
2. At least one agent created
3. Understanding of your business rules and policies

<Note>
  Code examples focus on core API calls. For production-ready patterns (structured logging, retries, and error handling), see [Error Handling Best Practices](/guides/error-handling-best-practices).
</Note>

### Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install StateSet-node
  ```

  ```bash yarn theme={null}
  yarn add StateSet-node
  ```

  ```bash pip theme={null}
  pip install StateSet
  ```
</CodeGroup>

## Creating Rules

### Basic Rule Structure

Every rule consists of:

* **Name**: Unique identifier
* **Conditions**: When the rule should trigger
* **Actions**: What should happen
* **Priority**: Order of execution
* **Scope**: Where the rule applies

### Simple Rule Example

Let's start with a basic rule for handling refund inquiries:

```javascript theme={null}
import { StateSetClient } from 'StateSet-node';

const client = new StateSetClient({
  apiKey: process.env.STATESET_API_KEY
});

async function createRefundRule(agentId) {
  const rule = await client.rules.create({
    agent_id: agentId,
    name: 'refund_inquiry_handler',
    description: 'Handles customer refund inquiries with appropriate care',
    priority: 100, // Higher priority executes first
    conditions: {
      any: [
        { field: 'message.text', operator: 'contains', value: 'refund' },
        { field: 'message.text', operator: 'contains', value: 'money back' },
        { field: 'message.text', operator: 'matches', value: '/return.*money/i' }
      ]
    },
    actions: [
      {
        type: 'set_attribute',
        attribute: 'conversation_tone',
        value: 'empathetic_professional'
      },
      {
        type: 'add_context',
        context: {
          topic: 'refund',
          sensitivity: 'high',
          require_order_lookup: true
        }
      },
      {
        type: 'send_message',
        message: 'I understand you have questions about a refund. I\'d be happy to help you with that. Could you please provide your order number?'
      }
    ],
    metadata: {
      category: 'customer_service',
      compliance: 'required',
      last_reviewed: new Date().toISOString()
    }
  });
  
  return rule;
}
```

### Complex Rule with Multiple Conditions

Here's a more sophisticated rule that considers customer history and order value:

```javascript theme={null}
async function createVIPCustomerRule(agentId) {
  const vipRule = await client.rules.create({
    agent_id: agentId,
    name: 'vip_customer_treatment',
    description: 'Provides premium service to VIP customers',
    priority: 200, // Executes before standard rules
    conditions: {
      all: [
        {
          any: [
            { field: 'customer.lifetime_value', operator: 'greater_than', value: 5000 },
            { field: 'customer.tier', operator: 'equals', value: 'platinum' },
            { field: 'customer.orders_count', operator: 'greater_than', value: 50 }
          ]
        },
        {
          field: 'conversation.sentiment',
          operator: 'in',
          value: ['negative', 'very_negative']
        }
      ]
    },
    actions: [
      {
        type: 'escalate',
        target: 'vip_support_team',
        priority: 'immediate'
      },
      {
        type: 'set_attribute',
        attribute: 'service_level',
        value: 'white_glove'
      },
      {
        type: 'apply_discount',
        discount_type: 'percentage',
        value: 10,
        code: 'VIP_CARE'
      },
      {
        type: 'send_message',
        message: 'I sincerely apologize for any inconvenience. As one of our valued customers, I\'m immediately escalating this to our VIP support team who will assist you right away.'
      },
      {
        type: 'log_event',
        event: 'vip_escalation',
        data: {
          customer_id: '{{customer.id}}',
          reason: 'negative_sentiment',
          automated: true
        }
      }
    ]
  });
  
  return vipRule;
}
```

## Advanced Rule Patterns

### Time-Based Rules

Create rules that adapt based on time of day, business hours, or dates:

```javascript theme={null}
const afterHoursRule = await client.rules.create({
  agent_id: agentId,
  name: 'after_hours_support',
  conditions: {
    any: [
      {
        field: 'current_time',
        operator: 'outside_range',
        value: { start: '09:00', end: '17:00', timezone: 'America/New_York' }
      },
      {
        field: 'current_day',
        operator: 'in',
        value: ['Saturday', 'Sunday']
      },
      {
        field: 'current_date',
        operator: 'in',
        value: ['2024-12-25', '2024-01-01'] // Holidays
      }
    ]
  },
  actions: [
    {
      type: 'set_expectation',
      message: 'Thanks for reaching out! Our team is currently offline, but I can still help with many requests.'
    },
    {
      type: 'limit_functions',
      allowed: ['order_status', 'track_package', 'faq_lookup'],
      message_on_restricted: 'For this request, our human team will need to assist you. They\'ll respond within one business day.'
    }
  ]
});
```

### Dynamic Routing Rules

Route conversations based on content and context:

```javascript theme={null}
const routingRule = await client.rules.create({
  agent_id: agentId,
  name: 'intelligent_routing',
  priority: 300,
  conditions: {
    evaluate: 'routing_logic'
  },
  routing_logic: `
    // Technical issues go to tech support
    if (message.text.match(/error|bug|crash|not working/i)) {
      return 'technical_support';
    }
    
    // Billing issues to finance team
    if (message.text.match(/charge|bill|payment|invoice/i)) {
      return 'billing_team';
    }
    
    // Sales inquiries to sales team
    if (message.text.match(/pricing|discount|upgrade|plan/i) && !customer.is_existing) {
      return 'sales_team';
    }
    
    // VIP customers always get premium support
    if (customer.tier === 'vip' || customer.lifetime_value > 10000) {
      return 'vip_support';
    }
    
    // Default to general support
    return 'general_support';
  `,
  actions: [
    {
      type: 'route_to_team',
      team: '{{routing_result}}',
      transfer_context: true,
      message: 'I\'m connecting you with our {{routing_result.friendly_name}} team who can best assist with your request.'
    }
  ]
});
```

### Compliance and Security Rules

Ensure sensitive data is handled appropriately:

```javascript theme={null}
const complianceRule = await client.rules.create({
  agent_id: agentId,
  name: 'pii_protection',
  priority: 500, // Highest priority
  conditions: {
    any: [
      {
        field: 'message.text',
        operator: 'matches',
        value: '/\\b\\d{3}-\\d{2}-\\d{4}\\b/' // SSN pattern
      },
      {
        field: 'message.text',
        operator: 'matches',
        value: '/\\b(?:\\d{4}[\\s-]?){3}\\d{4}\\b/' // Credit card pattern
      }
    ]
  },
  actions: [
    {
      type: 'mask_sensitive_data',
      patterns: ['ssn', 'credit_card'],
      replacement: '[REDACTED]'
    },
    {
      type: 'send_message',
      message: 'For your security, please don\'t share sensitive information like SSN or credit card numbers in chat. I can help you without this information.'
    },
    {
      type: 'log_security_event',
      event_type: 'pii_attempted',
      severity: 'medium'
    }
  ]
});
```

## Rule Conditions

### Condition Operators

StateSet supports a comprehensive set of operators:

```javascript theme={null}
// Comparison operators
{ field: 'order.total', operator: 'greater_than', value: 100 }
{ field: 'customer.age', operator: 'between', value: { min: 18, max: 65 } }

// String operators
{ field: 'message.text', operator: 'contains', value: 'urgent' }
{ field: 'customer.email', operator: 'ends_with', value: '@company.com' }
{ field: 'product.sku', operator: 'matches', value: '/^PROD-\\d{6}$/' }

// Array operators
{ field: 'customer.tags', operator: 'includes', value: 'vip' }
{ field: 'order.items', operator: 'includes_any', value: ['electronics', 'computers'] }

// Date operators
{ field: 'customer.created_at', operator: 'before', value: '2024-01-01' }
{ field: 'order.date', operator: 'within_last', value: { amount: 30, unit: 'days' } }

// Null checks
{ field: 'customer.phone', operator: 'is_null', value: true }
{ field: 'order.discount_code', operator: 'is_not_null', value: true }
```

### Complex Condition Logic

Combine conditions with AND/OR logic:

```javascript theme={null}
const complexRule = await client.rules.create({
  conditions: {
    all: [ // AND logic
      {
        any: [ // OR logic
          { field: 'customer.status', operator: 'equals', value: 'gold' },
          { field: 'customer.lifetime_value', operator: 'greater_than', value: 1000 }
        ]
      },
      {
        field: 'current_promotion.active',
        operator: 'equals',
        value: true
      },
      {
        not: { // NOT logic
          field: 'customer.flags',
          operator: 'includes',
          value: 'promotional_opt_out'
        }
      }
    ]
  }
});
```

## Rule Actions

### Available Action Types

```javascript theme={null}
// Conversation Control
{ type: 'set_attribute', attribute: 'tone', value: 'formal' }
{ type: 'add_tag', tag: 'urgent_issue' }
{ type: 'set_priority', level: 'high' }

// Message Actions
{ type: 'send_message', message: 'Your custom message here' }
{ type: 'send_template', template_id: 'welcome_back_vip' }
{ type: 'suggest_responses', options: ['Yes', 'No', 'Tell me more'] }

// Function Execution
{ type: 'execute_function', function: 'check_inventory', params: { sku: '{{product.sku}}' } }
{ type: 'disable_function', function: 'process_payment', reason: 'after_hours' }

// Routing and Escalation
{ type: 'route_to_team', team: 'technical_support' }
{ type: 'escalate_to_human', priority: 'immediate', reason: '{{escalation_reason}}' }

// Data Operations
{ type: 'update_customer', fields: { last_contact: '{{current_timestamp}}' } }
{ type: 'create_ticket', priority: 'medium', category: 'billing' }
{ type: 'log_event', event: 'rule_triggered', data: { rule_id: '{{rule.id}}' } }
```

### Action Sequencing

Control the flow of actions:

```javascript theme={null}
const sequencedRule = await client.rules.create({
  actions: [
    {
      type: 'execute_function',
      function: 'check_order_status',
      store_result: 'order_status'
    },
    {
      type: 'conditional_action',
      condition: 'order_status.status === "shipped"',
      then: {
        type: 'send_message',
        message: 'Great news! Your order has shipped and is on its way.'
      },
      else: {
        type: 'send_message',
        message: 'Your order is being prepared and will ship soon.'
      }
    }
  ]
});
```

## Testing Rules

### Rule Testing Framework

```javascript theme={null}
async function testRule(ruleId, testCases) {
  const results = await client.rules.test({
    rule_id: ruleId,
    test_cases: testCases
  });
  
  results.forEach(result => {
    logger.info(`Test Case: ${result.name}`);
    logger.info(`Expected: ${result.expected}`);
    logger.info(`Actual: ${result.actual}`);
    logger.info(`Passed: ${result.passed}`);
  });
  
  return results;
}

// Define test cases
const testCases = [
  {
    name: 'VIP customer with complaint',
    input: {
      message: { text: 'This service is terrible!' },
      customer: { tier: 'vip', lifetime_value: 15000 },
      conversation: { sentiment: 'very_negative' }
    },
    expected_actions: ['escalate', 'apply_discount']
  },
  {
    name: 'Regular customer inquiry',
    input: {
      message: { text: 'What are your business hours?' },
      customer: { tier: 'standard' },
      conversation: { sentiment: 'neutral' }
    },
    expected_actions: ['send_message']
  }
];

await testRule(vipRule.id, testCases);
```

## Rule Management

### Rule Versioning

Keep track of rule changes:

```javascript theme={null}
const ruleWithVersion = await client.rules.create({
  agent_id: agentId,
  name: 'return_policy_v2',
  version: '2.0.0',
  changelog: 'Updated return window from 30 to 60 days',
  replaces: 'rule_abc123', // ID of previous version
  effective_date: '2024-02-01',
  actions: [
    {
      type: 'send_message',
      message: 'Our return policy allows returns within 60 days of purchase.'
    }
  ]
});
```

### Bulk Rule Operations

Manage multiple rules efficiently:

```javascript theme={null}
// Import rules from configuration
async function importRules(agentId, rulesConfig) {
  const imported = await client.rules.bulkCreate({
    agent_id: agentId,
    rules: rulesConfig,
    conflict_resolution: 'skip', // or 'overwrite'
    validate_before_import: true
  });
  
  logger.info(`Imported ${imported.success.length} rules`);
  if (imported.failures.length > 0) {
    logger.error('Failed imports:', imported.failures);
  }
}

// Export rules for backup
async function exportRules(agentId) {
  const rules = await client.rules.export({
    agent_id: agentId,
    format: 'json',
    include_disabled: false
  });
  
  // Save to file or version control
  fs.writeFileSync('rules-backup.json', JSON.stringify(rules, null, 2));
}
```

## Monitoring & Analytics

### Rule Performance Tracking

```javascript theme={null}
// Get rule analytics
const analytics = await client.rules.getAnalytics({
  rule_id: ruleId,
  timeframe: '30d',
  metrics: ['trigger_count', 'success_rate', 'avg_execution_time']
});

logger.info(`Rule Performance:
  Triggered: ${analytics.trigger_count} times
  Success Rate: ${analytics.success_rate}%
  Avg Execution: ${analytics.avg_execution_time}ms
  Most Common Trigger: ${analytics.top_trigger_condition}
`);

// Set up alerts
await client.rules.createAlert({
  rule_id: ruleId,
  alert_conditions: [
    {
      metric: 'error_rate',
      threshold: 5,
      window: '1h',
      notification: 'email'
    }
  ]
});
```

## Best Practices

### 1. Rule Priority and Order

```javascript theme={null}
// Good: Clear priority hierarchy
const rules = [
  { name: 'security_check', priority: 1000 },      // Always first
  { name: 'compliance_filter', priority: 900 },    // Before business logic
  { name: 'vip_treatment', priority: 500 },        // Special handling
  { name: 'standard_routing', priority: 100 },     // Normal flow
  { name: 'fallback_handler', priority: 1 }        // Catch-all
];
```

### 2. Performance Optimization

```javascript theme={null}
// Optimize condition checking
const efficientRule = await client.rules.create({
  conditions: {
    // Check simple conditions first
    all: [
      { field: 'message.length', operator: 'less_than', value: 10 }, // Fast
      { field: 'customer.tier', operator: 'equals', value: 'vip' },  // Fast
      { field: 'message.text', operator: 'matches', value: '/complex.*regex/i' } // Slower
    ]
  },
  // Cache results for repeated checks
  cache_ttl: 300 // 5 minutes
});
```

### 3. Error Handling

```javascript theme={null}
const robustRule = await client.rules.create({
  error_handling: {
    on_condition_error: 'skip_rule',
    on_action_error: 'continue_next_action',
    fallback_message: 'I encountered an issue, but I\'m still here to help!',
    log_errors: true
  }
});
```

## Common Patterns

### Customer Segmentation Rules

```javascript theme={null}
const segmentationRules = [
  {
    name: 'new_customer_welcome',
    conditions: { field: 'customer.orders_count', operator: 'equals', value: 0 },
    actions: [{ type: 'send_template', template: 'first_time_buyer_welcome' }]
  },
  {
    name: 'loyal_customer_perks',
    conditions: { field: 'customer.orders_count', operator: 'greater_than', value: 10 },
    actions: [{ type: 'apply_loyalty_discount', percentage: 15 }]
  },
  {
    name: 'win_back_inactive',
    conditions: { field: 'customer.last_order_date', operator: 'before', value: '90_days_ago' },
    actions: [{ type: 'send_template', template: 'we_miss_you_offer' }]
  }
];
```

### Contextual Help Rules

```javascript theme={null}
const contextualHelpRule = await client.rules.create({
  name: 'smart_help_suggestions',
  conditions: {
    evaluate: `
      const keywords = message.text.toLowerCase();
      const page = context.current_page;
      
      if (page === 'checkout' && keywords.includes('coupon')) {
        return 'show_coupon_help';
      } else if (page === 'product' && keywords.includes('size')) {
        return 'show_size_guide';
      } else if (keywords.includes('ship')) {
        return 'show_shipping_info';
      }
      return null;
    `
  },
  actions: [
    {
      type: 'dynamic_action',
      action: '{{evaluation_result}}'
    }
  ]
});
```

## Troubleshooting

### Common Issues

1. **Rules Not Triggering**
   * Check rule priority and order
   * Verify conditions are correctly formatted
   * Ensure rule is enabled and not expired

2. **Conflicting Rules**
   * Use priority levels to control execution order
   * Implement exclusive rule groups
   * Add conflict detection in conditions

3. **Performance Issues**
   * Optimize complex regex patterns
   * Use caching for expensive operations
   * Limit the number of active rules

## Next Steps

<CardGroup cols={2}>
  <Card title="Rule Templates" icon="copy" href="/guides/rule-templates">
    Pre-built rules for common scenarios
  </Card>

  <Card title="Advanced Conditions" icon="code-branch" href="/guides/advanced-rule-conditions">
    Master complex rule logic
  </Card>
</CardGroup>

***

<Note>
  **Pro Tip**: Start with simple rules and gradually add complexity. Use the testing framework to validate rules before deploying to production.
</Note>

For support and examples, visit our [GitHub repository](https://github.com/StateSet/rule-examples) or contact [support@StateSet.com](mailto:support@StateSet.com).
