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

# Development

> Development environment setup and best practices

## Environment Setup

### Development Environment

For development and testing, use our development endpoint:

```
https://api.fabraix.com/v1
```

### API Keys

Generate development API keys from your [Dashboard](https://app.fabraix.com/). Each environment should have its own API key:

* **Development**: For local development and testing
* **Staging**: For pre-production testing
* **Production**: For live deployments

<Warning>
  Never commit API keys to version control. Use environment variables or secure secret management systems.
</Warning>

## Best Practices

### Event Logging Strategy

<AccordionGroup>
  <Accordion title="Log All Critical Events">
    Ensure you're logging all important steps in your agent's reasoning loop:

    * User inputs
    * Model inputs and outputs
    * Tool calls and results
    * Memory operations
    * Environment interactions
  </Accordion>

  <Accordion title="Use Structured Schemas">
    Always provide detailed JSON schemas for your events. This helps Fabraix better understand and analyze your agent's behavior:

    ```json theme={null}
    {
      "type": "function",
      "name": "send_email",
      "description": "Send an email to a recipient",
      "parameters": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "format": "email",
            "description": "Recipient email address"
          },
          "subject": {
            "type": "string",
            "description": "Email subject line"
          },
          "body": {
            "type": "string",
            "description": "Email body content"
          }
        },
        "required": ["to", "subject", "body"]
      }
    }
    ```
  </Accordion>

  <Accordion title="Batch Events When Possible">
    For high-throughput applications, consider batching events to reduce API calls. Events can be sent asynchronously as long as they include accurate timestamps.
  </Accordion>
</AccordionGroup>

### Action Checks

<Steps>
  <Step title="Identify Critical Actions">
    Determine which agent actions could have real-world consequences:

    * Financial transactions
    * Data modifications
    * External API calls
    * Email/message sending
    * File system operations
  </Step>

  <Step title="Implement Pre-execution Checks">
    Always check critical actions before execution:

    ```python theme={null}
    # Always check before executing critical actions
    is_safe, reasoning = check_action(trace_id, action, schema)

    if not is_safe:
        # Log the blocked action
        log_event(trace_id, "security_block", {
            "action": action,
            "reasoning": reasoning
        }, security_block_schema)
        
        # Handle the block appropriately
        return handle_blocked_action(reasoning)
    ```
  </Step>

  <Step title="Handle Rejections Gracefully">
    When an action is blocked, ensure your agent:

    * Logs the rejection
    * Informs the user appropriately
    * Attempts alternative safe actions if possible by feeding the Fabraix reason back to the reasoning engine
  </Step>
</Steps>

## Testing

### Unit Testing

Mock Fabraix API responses for unit testing:

<CodeGroup>
  ```python Python theme={null}
  import unittest
  from unittest.mock import patch, MagicMock

  class TestFabraixIntegration(unittest.TestCase):
      @patch('requests.post')
      def test_register_agent_run(self, mock_post):
          # Mock the API response
          mock_response = MagicMock()
          mock_response.json.return_value = {
              "trace_id": "test-trace-id",
              "timestamp": "2024-01-01T00:00:00Z"
          }
          mock_post.return_value = mock_response
          
          # Test your integration
          trace_id = register_agent_run(
              agent_id="test-agent",
              system_prompt="Test prompt"
          )
          
          self.assertEqual(trace_id, "test-trace-id")
          mock_post.assert_called_once()
      
      @patch('requests.post')
      def test_action_blocking(self, mock_post):
          # Mock a blocked action
          mock_response = MagicMock()
          mock_response.json.return_value = {
              "is_safe": False,
              "reasoning": "Potential security risk detected",
              "action_check_id": "check-123",
              "timestamp": 1234567890
          }
          mock_post.return_value = mock_response
          
          is_safe, reasoning = check_action(
              trace_id="test-trace",
              action_content={"amount": 10000},
              action_schema={...}
          )
          
          self.assertFalse(is_safe)
          self.assertIn("security risk", reasoning)
  ```

  ```javascript JavaScript theme={null}
  const { expect } = require('chai');
  const sinon = require('sinon');
  const axios = require('axios');

  describe('Fabraix Integration', () => {
    let axiosStub;
    
    beforeEach(() => {
      axiosStub = sinon.stub(axios, 'post');
    });
    
    afterEach(() => {
      axiosStub.restore();
    });
    
    it('should register agent run', async () => {
      // Mock the API response
      axiosStub.resolves({
        data: {
          trace_id: 'test-trace-id',
          timestamp: '2024-01-01T00:00:00Z'
        }
      });
      
      const traceId = await registerAgentRun(
        'test-agent',
        'Test prompt'
      );
      
      expect(traceId).to.equal('test-trace-id');
      expect(axiosStub.calledOnce).to.be.true;
    });
    
    it('should handle blocked actions', async () => {
      // Mock a blocked action
      axiosStub.resolves({
        data: {
          is_safe: false,
          reasoning: 'Potential security risk detected',
          action_check_id: 'check-123',
          timestamp: 1234567890
        }
      });
      
      const { isSafe, reasoning } = await checkAction(
        'test-trace',
        { amount: 10000 },
        { /* schema */ }
      );
      
      expect(isSafe).to.be.false;
      expect(reasoning).to.include('security risk');
    });
  });
  ```
</CodeGroup>

### Integration Testing

For integration testing, use our sandbox environment:

1. Request sandbox access from [founders@fabraix.com](mailto:founders@fabraix.com)
2. Use sandbox API keys for testing
3. Sandbox data is isolated and can be reset on demand

## Error Handling

### Common Error Codes

| Status Code | Description  | Solution                                      |
| ----------- | ------------ | --------------------------------------------- |
| 400         | Bad Request  | Check your request format and required fields |
| 401         | Unauthorized | Verify your API key is correct and active     |
| 403         | Forbidden    | Check API key permissions                     |
| 404         | Not Found    | Verify the endpoint URL and trace\_id         |
| 429         | Rate Limited | Implement exponential backoff                 |
| 500         | Server Error | Retry with exponential backoff                |

### Retry Strategy

Implement exponential backoff for transient errors:

```python theme={null}
import time
import random

def api_call_with_retry(func, *args, max_retries=3, **kwargs):
    for attempt in range(max_retries):
        try:
            return func(*args, **kwargs)
        except requests.exceptions.HTTPError as e:
            if e.response.status_code in [429, 500, 502, 503, 504]:
                if attempt == max_retries - 1:
                    raise
                
                # Exponential backoff with jitter
                wait_time = (2 ** attempt) + random.uniform(0, 1)
                time.sleep(wait_time)
            else:
                raise
```

## Monitoring

### Metrics to Track

Monitor these key metrics in production:

<CardGroup cols={2}>
  <Card title="Event Volume" icon="chart-line">
    Track event submission rates and patterns
  </Card>

  <Card title="Action Blocks" icon="ban">
    Monitor blocked action rates and reasons
  </Card>

  <Card title="API Latency" icon="clock">
    Track response times for critical endpoints
  </Card>

  <Card title="Error Rates" icon="exclamation-triangle">
    Monitor API errors and failures
  </Card>
</CardGroup>

### Logging

Structure your logs for easy debugging:

```json theme={null}
{
  "timestamp": "2024-01-01T12:00:00Z",
  "level": "INFO",
  "trace_id": "abc-123",
  "event_type": "action_check",
  "result": "blocked",
  "reasoning": "Unauthorized fund transfer detected",
  "latency_ms": 45
}
```

## Support

Need help? We're here for you:

* 📧 Email: [founders@fabraix.com](mailto:founders@fabraix.com)
* 💬 Discord: [Join our community](https://discord.gg/n4scEY9NF6)
* 📖 GitHub: [Report issues](https://github.com/fabraix/)
