Provider Implementation Guide #
Overview #
This guide explains how to add new provider support to Starmap or enhance existing provider integrations.
Quick Start #
Adding a New Provider #
-
Add Provider Definition
1# internal/embedded/catalog/providers.yaml 2- id: "new-provider" 3 name: "New Provider" 4 website: "https://newprovider.com" 5 description: "Provider description" -
Create Provider Client
1// internal/sources/providers/newprovider/client.go 2package newprovider 3 4type Client struct { 5 apiKey string 6 baseURL string 7} -
Register Provider
1// internal/sources/providers/providers.go 2case "new-provider": 3 return newprovider.NewClient(apiKey) -
Test Implementation
1# Update testdata 2starmap testdata --provider new-provider --update 3 4# Test fetching 5starmap fetch models --provider new-provider
Provider Client Interface #
Each provider client must implement the Provider interface:
1type Provider interface {
2 ID() string
3 Name() string
4 FetchModels(ctx context.Context) ([]*Model, error)
5}
Required Methods #
ID()- Returns the provider’s unique identifierName()- Returns the provider’s display nameFetchModels()- Fetches available models from the provider’s API
Authentication #
Provider clients should support API key authentication via environment variables:
1export NEWPROVIDER_API_KEY="your-api-key"
Rate Limiting #
Implement rate limiting to respect provider API limits:
1func (c *Client) FetchModels(ctx context.Context) ([]*Model, error) {
2 // Add delay between requests
3 time.Sleep(100 * time.Millisecond)
4 // ...
5}
Error Handling #
Use typed errors from pkg/errors:
1if resp.StatusCode == 404 {
2 return nil, &errors.NotFoundError{
3 Resource: "models",
4 ID: providerID,
5 }
6}
Testing #
Unit Tests #
Create unit tests for your provider client:
1// internal/sources/providers/newprovider/client_test.go
2func TestFetchModels(t *testing.T) {
3 // Test implementation
4}
Integration Tests #
Test with real API (requires API key):
1go test ./internal/sources/providers/newprovider -integration
Testdata #
Generate testdata for offline testing:
1starmap testdata --provider new-provider --update
Common Patterns #
Pagination #
Handle paginated responses:
1var allModels []*Model
2nextPage := ""
3
4for {
5 models, next, err := c.fetchPage(ctx, nextPage)
6 if err != nil {
7 return nil, err
8 }
9
10 allModels = append(allModels, models...)
11
12 if next == "" {
13 break
14 }
15 nextPage = next
16}
Model Mapping #
Map provider-specific model format to Starmap format:
1func mapToStarmapModel(providerModel *APIModel) *catalogs.Model {
2 return &catalogs.Model{
3 ID: catalogs.ModelID(providerModel.Name),
4 Name: providerModel.DisplayName,
5 // Map other fields...
6 }
7}
Best Practices #
- Use Constants - Define API endpoints and other values as constants
- Handle Timeouts - Set reasonable timeouts for API requests
- Log Errors - Use structured logging for debugging
- Validate Input - Check API keys and parameters before making requests
- Cache Results - Consider caching responses to reduce API calls
Example Implementation #
See the OpenAI provider implementation as a reference:
- Client:
internal/sources/providers/openai/client.go - Tests:
internal/sources/providers/openai/client_test.go - Testdata:
internal/sources/providers/openai/testdata/
Troubleshooting #
API Key Issues #
1# Check if API key is set
2echo $NEWPROVIDER_API_KEY
3
4# Test with explicit key
5NEWPROVIDER_API_KEY="key" starmap fetch models --provider new-provider
Rate Limiting #
If you encounter rate limit errors:
- Add delays between requests
- Implement exponential backoff
- Respect
Retry-Afterheaders
Debugging #
Enable verbose logging:
1starmap fetch models --provider new-provider --verbose
Contributing #
When submitting a new provider:
- Include unit tests
- Generate testdata
- Update documentation
- Add provider to README
See our contribution guidelines for more details.