Architecture
The service calls AI providers via subprocess, not SDKs:- No SDK dependencies: AI providers are called via subprocess
- Provider-agnostic: Easy to add new AI CLIs
- Auth handled externally: CLIs manage their own authentication
- Environment-driven:
AI_PROVIDERenv var selects the provider
Provider Configuration
All AI providers are configured inPROVIDER_CONFIG (analyzer.py:125-131):
analyzer.py:101-134
Adding a New Provider
Follow these steps to add a new AI CLI provider:Create command builder function
Define a function that builds the CLI command:Requirements:
- Function must accept
(binary: str, model: str, cwd: Path | None) - Must return
list[str](command arguments) - Binary receives prompt via stdin
- Binary must write response to stdout
- Binary must exit with code 0 on success
Add to PROVIDER_CONFIG
Register your provider in the ProviderConfig fields:
PROVIDER_CONFIG dictionary:binary: CLI binary name (must be in PATH)build_cmd: Your command builder functionuses_own_cwd: Set toTrueif CLI handlescwdvia its own flag (like Cursor’s--workspace)
Document authentication
Update documentation with provider-specific auth setup:
- Install the CLI
- Authenticate with the provider
- Configure environment variables for Jenkins Job Insight
- Installation instructions
- Authentication steps (API key, OAuth, or web login)
- Environment variable configuration
- Testing the CLI connection
CLI Interface Contract
Your AI CLI must implement this interface:Input
The CLI receives a prompt via stdin:analyzer.py:520-532
Output
The CLI must write the response to stdout as JSON:Exit Code
The CLI must:- Exit with 0 on success
- Exit with non-zero on error
- Write error messages to stderr
analyzer.py:539-541
Response Parsing
The service parses AI responses using multiple strategies (analyzer.py:179-223):
This tolerates:
- Markdown code blocks around JSON
- Extra text before/after JSON
- Embedded code blocks in string values
- Formatting quirks from different AI models
Working Directory Handling
Some CLIs need the repository path passed differently:Standard (Claude, Gemini)
Passcwd to subprocess:
Custom Flag (Cursor)
CLI handlescwd via its own flag:
uses_own_cwd=True if your CLI needs this pattern.
Sanity Check
Before spawning parallel analysis tasks, the service verifies the CLI works:analyzer.py:426-478
"Hi" within 60 seconds.
Example: Adding Anthropic Claude Desktop
Here’s a complete example adding Anthropic’s Claude Desktop CLI:Troubleshooting
Unknown AI provider error
Unknown AI provider error
Verify your provider is in The key in
VALID_AI_PROVIDERS:PROVIDER_CONFIG is the provider name users pass via AI_PROVIDER or ai_provider in requests.CLI not found
CLI not found
Ensure the binary is in PATH:Or use an absolute path:
Timeout errors
Timeout errors
Increase timeout for slower models:Or pass per-request:
JSON parsing failures
JSON parsing failures
The parser handles many edge cases, but if your CLI outputs unusual JSON:
- Check stderr for error messages
- Test with simple prompt:
echo "Hi" | your-cli --model model-name - Verify JSON structure matches the schema
- Look for unescaped newlines in string values
Contributing
When adding a provider, please:- Test with real Jenkins failures
- Document authentication steps
- Add example to README.md
- Update this guide
- Submit a PR with your changes