Repo-Analyzer ↔ AI Service Integration
Overview
This document describes the integration layer that connects packages/repo-analyzer output to packages/ai-service to generate AI-powered test suggestions.
When a repository is analysed, the structured result (file list, language stats, framework detections, existing test coverage) is forwarded to the AI service. The AI returns prioritised test recommendations with rationale and optional code snippets.
Architecture
┌─────────────────────┐ tRPC mutation ┌──────────────────────┐
│ Frontend / API │ ─── analysis.suggestTests ──▶ │ @izri/trpc │
└─────────────────────┘ └──────────┬───────────┘
│ HTTP POST /suggest-tests
▼
┌──────────────────────┐
│ packages/ai-service │
│ (FastAPI + Python) │
│ │
│ RepoAnalyzerIntegra- │
│ tion → AI provider │
│ (OpenAI/Anthropic/ │
│ mock) │
└──────────────────────┘
Components
| Component | Location | Language | Purpose |
|---|---|---|---|
RepoAnalyzerIntegration |
packages/ai-service/repo_analyzer_integration.py |
Python | Builds prompts from analysis data, calls AI, parses response |
AIServiceClient |
packages/trpc/src/services/aiServiceClient.ts |
TypeScript | HTTP client from tRPC layer to AI service |
analysis.suggestTests |
packages/trpc/src/routers/analysis.ts |
TypeScript | tRPC mutation that orchestrates the full flow |
POST /suggest-tests |
packages/ai-service/main.py |
Python | FastAPI endpoint exposed by the AI service |
tRPC Procedure: analysis.suggestTests
Input
{
projectId: string // ULID — must belong to the authenticated user
userEmail: string // Used to resolve the user record
maxSuggestions?: number // 1–50, default 10
analysisOverride?: Record<string, unknown> // Optional: bypass DB lookup
}
Output
{
success: true
commitSha: string
summary: string
suggestions: Array<{
file_path: string
test_type: 'unit' | 'integration' | 'e2e'
description: string
rationale: string
example_code: string
}>
suggestionCount: number
}
Example (tRPC client)
const result = await trpc.analysis.suggestTests.mutate({
projectId: '01HVXXXXXXXXXXXXXXXXXXXXXXXX',
userEmail: 'alice@example.com',
maxSuggestions: 8,
})
console.log(result.summary)
for (const s of result.suggestions) {
console.log(`[${s.test_type}] ${s.file_path}: ${s.description}`)
}
REST Endpoint: POST /suggest-tests
Called internally by AIServiceClient. Can also be called directly.
Request
{
"analysis": {
"commitSha": "abc123",
"summary": {
"totalFiles": 20,
"languages": { "TypeScript": 15 },
"frameworks": [{ "name": "React", "confidence": 0.9 }],
"hasTests": false,
"testFrameworks": []
},
"files": [
{ "path": "src/utils/helpers.ts", "size": 1024, "extension": ".ts", "language": "TypeScript" }
],
"directories": [],
"packageInfo": { "name": "my-app" }
},
"max_suggestions": 10
}
Response
{
"commit_sha": "abc123",
"summary": "The project lacks tests for its utility layer. Recommend starting with unit tests for pure functions.",
"suggestions": [
{
"file_path": "src/utils/helpers.ts",
"test_type": "unit",
"description": "Test the formatDate helper function",
"rationale": "Pure function, easy to unit-test, widely used across the codebase.",
"example_code": "expect(formatDate(new Date('2024-01-15'))).toBe('2024-01-15');"
}
],
"suggestion_count": 1
}
Python Integration Class
from repo_analyzer_integration import RepoAnalyzerIntegration, AnalysisResultInput
# Auto-detects AI provider from environment
integration = RepoAnalyzerIntegration()
# From a dict (e.g. deserialized from JSON / tRPC payload)
result = integration.generate_test_suggestions_from_dict(analysis_dict)
print(result.summary)
for s in result.suggestions:
print(f"[{s.test_type}] {s.file_path}: {s.description}")
AI Provider Configuration
The integration uses the same provider selection as the rest of the AI service:
| Environment Variable | Behaviour |
|---|---|
AI_PROVIDER=openai + OPENAI_API_KEY |
Calls OpenAI GPT-4o |
AI_PROVIDER=anthropic + ANTHROPIC_API_KEY |
Calls Anthropic Claude |
| Neither key set | Returns mock suggestions (safe for CI/dev) |
Running Tests
Python (integration layer)
cd packages/ai-service
python3 -m unittest tests/test_repo_analyzer_integration.py -v
TypeScript (AIServiceClient)
cd packages/trpc
pnpm test
# or specifically:
pnpm vitest run src/routers/__tests__/aiServiceClient.test.ts
Typical Workflow
- Call
analysis.analyzeRepository— storesAnalysisResultinprojectAnalysestable. - Call
analysis.suggestTests— retrieves the latest stored analysis for the project, sends it to the AI service, returns prioritised recommendations. - Optionally pass
analysisOverrideto bypass the DB and supply analysis data directly (useful for testing or one-off calls).