65 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			65 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package llmapi
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"encoding/json"
 | |
| 	"fmt"
 | |
| 	"log/slog"
 | |
| 	"net/http"
 | |
| 	"time"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	ormodelsLink = "https://openrouter.ai/api/v1/models"
 | |
| 	ORFreeModels = []string{
 | |
| 		"google/gemini-2.0-flash-exp:free",
 | |
| 		"deepseek/deepseek-chat-v3-0324:free",
 | |
| 		"mistralai/mistral-small-3.2-24b-instruct:free",
 | |
| 		"qwen/qwen3-14b:free",
 | |
| 		"google/gemma-3-27b-it:free",
 | |
| 		"meta-llama/llama-3.3-70b-instruct:free",
 | |
| 	}
 | |
| )
 | |
| 
 | |
| func ListORModels() ([]string, error) {
 | |
| 	resp, err := http.Get(ormodelsLink)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	defer resp.Body.Close()
 | |
| 	if resp.StatusCode != 200 {
 | |
| 		err := fmt.Errorf("failed to fetch or models; status: %s", resp.Status)
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	data := &ORModels{}
 | |
| 	if err := json.NewDecoder(resp.Body).Decode(data); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	freeModels := data.ListFree()
 | |
| 	return freeModels, nil
 | |
| }
 | |
| 
 | |
| func ORModelListUpdateTicker(ctx context.Context) {
 | |
| 	ticker := time.NewTicker(time.Hour * 2)
 | |
| 	freeModels, err := ListORModels()
 | |
| 	slog.Info("updated free models list", "list", freeModels)
 | |
| 	if err != nil {
 | |
| 		slog.Error("failed to update free models list", "list", freeModels)
 | |
| 	}
 | |
| 	for {
 | |
| 		select {
 | |
| 		case <-ctx.Done():
 | |
| 			return
 | |
| 		case <-ticker.C:
 | |
| 			freeModels, err := ListORModels()
 | |
| 			slog.Info("updated free models list", "list", freeModels)
 | |
| 			if err != nil {
 | |
| 				slog.Error("failed to update free models list", "list", freeModels)
 | |
| 				// log
 | |
| 				continue
 | |
| 			}
 | |
| 			ORFreeModels = freeModels
 | |
| 		}
 | |
| 	}
 | |
| }
 | 
