# AI Services Reference

## 1. AI Filtering Service

**File:** `src/server/services/ai-filtering.ts`

**Purpose:** Evaluate projects against admin-defined criteria text

### Input
- List of projects (anonymized)
- Criteria text (e.g., "Projects must be based in Mediterranean region")
- Rule configuration (PASS/REJECT/FLAG actions)

### Output
Per-project result:
- `meets_criteria` - Boolean
- `confidence` - 0-1 score
- `reasoning` - Explanation
- `quality_score` - 1-10 rating
- `spam_risk` - Boolean flag

### Configuration
- **Batch Size:** 20 projects per API call
- **Description Limit:** 500 characters
- **Token Usage:** ~1500-2500 tokens per batch

### Example Criteria
- "Filter out any project without a description"
- "Only include projects founded after 2020"
- "Reject projects with fewer than 2 team members"
- "Projects must be based in Mediterranean region"

### Usage
```typescript
import { aiFilterProjects } from '@/server/services/ai-filtering'

const results = await aiFilterProjects(
  projects,
  'Only include projects with ocean conservation focus',
  userId,
  roundId
)
```

---

## 2. AI Assignment Service

**File:** `src/server/services/ai-assignment.ts`

**Purpose:** Match jurors to projects based on expertise alignment

### Input
- List of jurors with expertise tags
- List of projects with tags/category
- Constraints:
  - Required reviews per project
  - Max assignments per juror
  - Existing assignments (to avoid duplicates)

### Output
Suggested assignments:
- `jurorId` - Juror to assign
- `projectId` - Project to assign
- `confidenceScore` - 0-1 match confidence
- `expertiseMatchScore` - 0-1 expertise overlap
- `reasoning` - Explanation

### Configuration
- **Batch Size:** 15 projects per batch (all jurors included)
- **Description Limit:** 300 characters
- **Token Usage:** ~2000-3500 tokens per batch

### Fallback Algorithm
When AI is unavailable, uses:
1. Tag overlap scoring (60% weight)
2. Load balancing (40% weight)
3. Constraint satisfaction

### Usage
```typescript
import { generateAIAssignments } from '@/server/services/ai-assignment'

const result = await generateAIAssignments(
  jurors,
  projects,
  {
    requiredReviewsPerProject: 3,
    maxAssignmentsPerJuror: 10,
    existingAssignments: [],
  },
  userId,
  roundId
)
```

---

## 3. Award Eligibility Service

**File:** `src/server/services/ai-award-eligibility.ts`

**Purpose:** Determine which projects qualify for special awards

### Input
- Award criteria text (plain language)
- List of projects (anonymized)
- Optional: Auto-tag rules (field-based matching)

### Output
Per-project:
- `eligible` - Boolean
- `confidence` - 0-1 score
- `reasoning` - Explanation
- `method` - 'AI' or 'AUTO'

### Configuration
- **Batch Size:** 20 projects per API call
- **Description Limit:** 400 characters
- **Token Usage:** ~1500-2500 tokens per batch

### Auto-Tag Rules
Deterministic rules can be combined with AI:
```typescript
const rules: AutoTagRule[] = [
  { field: 'country', operator: 'equals', value: 'Italy' },
  { field: 'competitionCategory', operator: 'equals', value: 'STARTUP' },
]
```

### Usage
```typescript
import { aiInterpretCriteria, applyAutoTagRules } from '@/server/services/ai-award-eligibility'

// Deterministic matching
const autoResults = applyAutoTagRules(rules, projects)

// AI-based criteria interpretation
const aiResults = await aiInterpretCriteria(
  'Projects focusing on marine biodiversity',
  projects,
  userId,
  awardId
)
```

---

## 4. Mentor Matching Service

**File:** `src/server/services/mentor-matching.ts`

**Purpose:** Recommend mentors for projects based on expertise

### Input
- Project details (single or batch)
- Available mentors with expertise tags and availability

### Output
Ranked list of mentor matches:
- `mentorId` - Mentor ID
- `confidenceScore` - 0-1 overall match
- `expertiseMatchScore` - 0-1 expertise overlap
- `reasoning` - Explanation

### Configuration
- **Batch Size:** 15 projects per batch
- **Description Limit:** 350 characters
- **Token Usage:** ~1500-2500 tokens per batch

### Fallback Algorithm
Keyword-based matching when AI unavailable:
1. Extract keywords from project tags/description
2. Match against mentor expertise tags
3. Factor in availability (assignments vs max)

### Usage
```typescript
import {
  getAIMentorSuggestions,
  getAIMentorSuggestionsBatch
} from '@/server/services/mentor-matching'

// Single project
const matches = await getAIMentorSuggestions(prisma, projectId, 5, userId)

// Batch processing
const batchResults = await getAIMentorSuggestionsBatch(
  prisma,
  projectIds,
  5,
  userId
)
```

---

## Common Patterns

### Token Logging
All services log usage to `AIUsageLog`:
```typescript
await logAIUsage({
  userId,
  action: 'FILTERING',
  entityType: 'Round',
  entityId: roundId,
  model,
  promptTokens: usage.promptTokens,
  completionTokens: usage.completionTokens,
  totalTokens: usage.totalTokens,
  batchSize: projects.length,
  itemsProcessed: projects.length,
  status: 'SUCCESS',
})
```

### Error Handling
All services use unified error classification:
```typescript
try {
  // AI call
} catch (error) {
  const classified = classifyAIError(error)
  logAIError('ServiceName', 'functionName', classified)

  if (classified.retryable) {
    // Retry logic
  } else {
    // Fall back to algorithm
  }
}
```

### Anonymization
All services anonymize before sending to AI:
```typescript
const { anonymized, mappings } = anonymizeProjectsForAI(projects, 'FILTERING')

if (!validateAnonymizedProjects(anonymized)) {
  throw new Error('GDPR compliance check failed')
}
```

## See Also

- [AI System Architecture](./ai-system.md)
- [AI Configuration Guide](./ai-configuration.md)
- [AI Error Handling](./ai-errors.md)
