Provider Guide

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 #

  1. 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"
    
  2. Create Provider Client

    1// internal/sources/providers/newprovider/client.go
    2package newprovider
    3
    4type Client struct {
    5    apiKey string
    6    baseURL string
    7}
    
  3. Register Provider

    1// internal/sources/providers/providers.go
    2case "new-provider":
    3    return newprovider.NewClient(apiKey)
    
  4. 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 identifier
  • Name() - Returns the provider’s display name
  • FetchModels() - 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 #

  1. Use Constants - Define API endpoints and other values as constants
  2. Handle Timeouts - Set reasonable timeouts for API requests
  3. Log Errors - Use structured logging for debugging
  4. Validate Input - Check API keys and parameters before making requests
  5. 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:

  1. Add delays between requests
  2. Implement exponential backoff
  3. Respect Retry-After headers

Debugging #

Enable verbose logging:

1starmap fetch models --provider new-provider --verbose

Contributing #

When submitting a new provider:

  1. Include unit tests
  2. Generate testdata
  3. Update documentation
  4. Add provider to README

See our contribution guidelines for more details.