Skip to content

Overview

TendSocial uses a sophisticated AI configuration system that allows for flexible model selection, A/B testing, and cost tracking. This guide explains how to use and manage these features.

Architecture

The AI system consists of three main components:

  1. AI Gateway - Abstraction layer for different AI providers
  2. Config Service - Manages model configuration and A/B testing
  3. AI Service - High-level API for content generation

Model Configuration

Global Configuration

Each AI task (e.g., campaign_planning, social_posts, blog_writing) has a global default configuration stored in the AIModelConfig table.

Fields:

  • provider - AI provider (anthropic, google, openai)
  • model - Specific model identifier
  • maxTokens - Maximum tokens per request
  • temperature - Randomness (0.0-1.0)
  • inputCostPer1M - Cost per 1M input tokens ($)
  • outputCostPer1M - Cost per 1M output tokens ($)

Company-Specific Overrides

Companies can override global defaults for specific tasks using CompanyAIConfig. This allows:

  • Custom model selection per company
  • BYOK (Bring Your Own Key) for agencies
  • Custom cost rates for billing

Configuration Priority

The system resolves configuration in this priority order:

  1. Active A/B Test - If user is assigned to a variant
  2. Company Override - Company-specific configuration
  3. Global Default - System-wide default

A/B Testing

Creating an A/B Test

typescript
POST /api/admin/ab-tests
{
  "name": "Opus vs Sonnet for Blogs",
  "description": "Testing quality vs cost",
  "task": "blog_writing",
  "variants": [
    {
      "name": "control",
      "provider": "anthropic",
      "model": "claude-3-5-sonnet-20241022",
      "weight": 50,
      "maxTokens": 4096,
      "temperature": 0.7,
      "inputCostPer1M": 3.0,
      "outputCostPer1M": 15.0
    },
    {
      "name": "challenger",
      "provider": "anthropic",
      "model": "claude-3-opus-20240229",
      "weight": 50,
      "maxTokens": 4096,
      "temperature": 0.7,
      "inputCostPer1M": 15.0,
      "outputCostPer1M": 75.0
    }
  ],
  "targetCompanyIds": [],  // Empty = all companies
  "targetUserIds": [],      // Empty = all users
  "startsAt": "2025-12-01T00:00:00Z",
  "endsAt": "2025-12-31T23:59:59Z"
}

Variant Weights

Weights determine the distribution of users:

  • Total weight across variants should sum to 100
  • 50/50 = Equal distribution
  • 90/10 = Most users get variant 1
  • 33/33/34 = Three-way split (if using 3 variants)

Assignment Consistency

Once a user is assigned to a variant, they will always get that same variant for the duration of the test. This ensures consistent results.

Targeting

You can target specific companies or users:

typescript
{
  "targetCompanyIds": ["company-123", "company-456"],
  "targetUserIds": []  // Empty = all users in those companies
}

Or target specific users:

typescript
{
  "targetCompanyIds": [],
  "targetUserIds": ["user-789", "user-012"]
}

Activating a Test

typescript
PUT /api/admin/ab-tests/:testId
{
  "isActive": true
}

Viewing Results

typescript
GET /api/admin/ab-tests/:testId/results

Metrics Included:

  • Total generations per variant
  • Unique users per variant
  • Average cost per generation
  • Average edit ratio (how much users modify AI output)
  • User ratings (if provided)
  • Acceptance rate (posts published as-is)
  • Engagement rates (from social platforms)

Cost Tracking

All AI usage is logged in AIUsageLog with:

  • Exact token counts (input, output, total)
  • Costs calculated in cents for precision
  • Provider and model used
  • Response time (latency)
  • Success/failure status
  • Reference to generated content (if applicable)
  • A/B test metadata (if applicable)

Cost Calculation

Input Cost = (inputTokens / 1,000,000) × inputCostPer1M × 100 cents
Output Cost = (outputTokens / 1,000,000) × outputCostPer1M × 100 cents
Total Cost = Input Cost + Output Cost

Viewing Analytics

typescript
// Summary across all AI usage
GET /api/admin/ai-analytics/summary?startDate=2025-11-01&endDate=2025-11-30

// Breakdown by dimension
GET /api/admin/ai-analytics/by-dimension?dimension=task&startDate=2025-11-01&endDate=2025-11-30

// Company-specific
GET /api/admin/ai-analytics/company/:companyId?startDate=2025-11-01&endDate=2025-11-30

Gateway Management

The AI gateway supports multiple adapters:

  1. Vercel AI SDK (default) - Unified interface
  2. Direct API - Direct provider calls
  3. LiteLLM (optional) - Proxy for cost tracking

Switching Adapters

typescript
POST /api/admin/gateway/switch
{
  "adapter": "direct-api"
}

Clearing Cache

typescript
POST /api/admin/gateway/clear-cache

This clears both gateway response cache and configuration cache.

Environment Variables

bash
# AI Gateway
AI_GATEWAY_ADAPTER=vercel-ai-sdk  # or direct-api, litellm
AI_CONFIG_CACHE_TTL=60            # seconds
AI_GATEWAY_CACHE_TTL=300          # seconds

# Provider API Keys
ANTHROPIC_API_KEY=sk-ant-...
GOOGLE_AI_API_KEY=...
OPEN AI_API_KEY=sk-...

# Optional: LiteLLM
LITELLM_PROXY_URL=http://localhost:4000

Best Practices

1. Start with Quality

Use the best model (e.g., Claude Opus) initially, then A/B test against cheaper models. Don't compromise quality for cost savings.

2. Test One Variable

When A/B testing, change only one thing:

  • Same model, different prompts
  • Same prompt, different models
  • Same everything, different temperatures

3. Statistical Significance

Run tests with at least 100 users per variant for meaningful results.

4. Monitor Edit Ratios

If edit ratio is consistently high (>50%), the AI output needs improvement. Consider:

  • Better prompts
  • More context (brand profile, examples)
  • Different model
  • Higher temperature for creativity

5. Cache Appropriately

  • Config cache: 60 seconds (frequent updates to A/B tests)
  • Gateway cache: 300 seconds (responses shouldn't change often for same input)

6. Budget Controls

Set budgetPerCall in AIModelConfig to prevent runaway costs:

typescript
{
  "budgetPerCall": 10  // Max 10 cents per call
}

Troubleshooting

Issue: Config changes not taking effect

Solution: Clear the cache

typescript
POST /api/admin/gateway/clear-cache

Issue: Users not being assigned to A/B test

Check:

  1. Is the test isActive: true?
  2. Does the user/company match targeting rules?
  3. Is the date within startsAt and endsAt?
  4. Has the cache been cleared after creating the test?

Issue: Costs higher than expected

Debug:

  1. Check AIUsageLog for actual token counts
  2. Verify inputCostPer1M and outputCostPer1M are correct
  3. Look for failed requests that retry multiple times
  4. Check if prompt is unnecessarily long (trim context)

Issue: Slow performance

Optimize:

  1. Enable gateway caching for identical requests
  2. Use faster models (Haiku vs Sonnet)
  3. Reduce maxTokens if output is too long
  4. Check database indexes on AIUsageLog

AI Refinement Entitlements

The AI Refinement system provides granular usage controls tied to subscription packages.

Action Types

ActionDescriptionToken Cost
WEBSITE_ANALYSISExtract brand identity from websiteHigh (~5,000-15,000)
FIELD_ANALYSISRead-only insights for existing contentMedium (~500-1,000)
ONE_SHOT_REFINEMENTQuick, single-turn field improvementsLow (~200-500)
CHAT_SESSION_STARTStart a multi-turn chat sessionN/A (session tracking)
CHAT_MESSAGEMessage within a chat sessionMedium (~500-2,000)

Usage Limits by Tier

FeatureFreeStarterProfessionalEnterprise
Website Analysis1/period5/period20/periodUnlimited
Field Analysis10/period50/period200/periodUnlimited
One-Shot Refinement25/period100/period500/periodUnlimited
Chat Sessions3/period10/period50/periodUnlimited
Messages/Session10152550

Pre-flight Checks

Before performing an AI action, check entitlements:

typescript
// Frontend
const { checkAction } = useAIEntitlements();
const result = await checkAction('CHAT_SESSION_START');
if (!result.allowed) {
  // Show upgrade modal
}

// Backend
const check = await entitlementsService.checkAIAction(companyId, 'WEBSITE_ANALYSIS');
if (!check.allowed) {
  reply.code(403).send({ error: 'ENTITLEMENT_EXCEEDED' });
}

Rate Limiting

In addition to entitlements, rate limits apply:

TierLimit
Free10 requests/min
Starter30 requests/min
Professional100 requests/min
Enterprise200 requests/min

Rate limit headers are included in responses:

X-RateLimit-Limit: 30
X-RateLimit-Remaining: 25
X-RateLimit-Reset: 1702400000

API Reference

See full API documentation at /api/docs for complete endpoint details.

TendSocial Documentation