Skip to content

Commit c09defe

Browse files
committed
fix: move drujensen to generic
1 parent c2df0f5 commit c09defe

File tree

9 files changed

+191
-137
lines changed

9 files changed

+191
-137
lines changed

internal/domain/entities/provider.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ const (
1616
ProviderTogether ProviderType = "together"
1717
ProviderGroq ProviderType = "groq"
1818
ProviderMistral ProviderType = "mistral"
19-
ProviderOllama ProviderType = "ollama"
20-
ProviderDrujensen ProviderType = "drujensen"
2119
ProviderGeneric ProviderType = "generic"
2220
)
2321

internal/domain/services/model_refresh_service.go

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,64 @@ func (s *modelRefreshService) RefreshProvider(ctx context.Context, providerID st
186186
}
187187

188188
func (s *modelRefreshService) refreshProvider(ctx context.Context, provider *entities.Provider) error {
189+
// Check if this provider is defined in global config (custom provider)
190+
// For custom providers, we need to find the config entry by matching names
191+
var customConfig *config.CustomProviderConfig
192+
var configKey string
193+
for key, cfg := range s.globalConfig.Providers {
194+
if cfg.Name == provider.Name && cfg.Type == "generic" {
195+
customConfig = &cfg
196+
configKey = key
197+
break
198+
}
199+
}
200+
201+
if customConfig != nil {
202+
s.logger.Debug("Using custom provider config",
203+
zap.String("provider_id", provider.ID),
204+
zap.String("provider_name", provider.Name),
205+
zap.String("config_key", configKey))
206+
207+
// Update provider with config data
208+
providerToUpdate := &entities.Provider{
209+
ID: provider.ID,
210+
Name: customConfig.Name,
211+
Type: entities.ProviderType(customConfig.Type),
212+
BaseURL: customConfig.BaseURL,
213+
APIKeyName: customConfig.APIKeyName,
214+
Models: make([]entities.ModelPricing, 0),
215+
}
216+
217+
// Add models from config
218+
for modelName, modelConfig := range customConfig.Models {
219+
pricing := entities.ModelPricing{
220+
Name: modelName,
221+
InputPricePerMille: modelConfig.InputPricePerMille,
222+
OutputPricePerMille: modelConfig.OutputPricePerMille,
223+
ContextWindow: modelConfig.ContextWindow,
224+
MaxOutputTokens: modelConfig.MaxOutputTokens,
225+
}
226+
providerToUpdate.Models = append(providerToUpdate.Models, pricing)
227+
}
228+
229+
providerToUpdate.UpdatedAt = time.Now()
230+
if err := s.providerRepo.UpdateProvider(ctx, providerToUpdate); err != nil {
231+
return err
232+
}
233+
234+
s.logger.Info("Updated custom provider from config",
235+
zap.String("provider_id", provider.ID),
236+
zap.String("provider_name", provider.Name),
237+
zap.String("config_key", configKey),
238+
zap.Int("models_count", len(providerToUpdate.Models)))
239+
return nil
240+
}
241+
242+
// Original logic for built-in providers
189243
if provider.Type == entities.ProviderGeneric {
190-
s.logger.Debug("Skipping generic provider refresh",
244+
s.logger.Debug("Skipping generic provider refresh (no config found)",
191245
zap.String("provider_id", provider.ID),
192-
zap.String("name", provider.Name))
246+
zap.String("provider_name", provider.Name))
193247
return nil
194248
}
195249

@@ -218,34 +272,22 @@ func (s *modelRefreshService) refreshProvider(ctx context.Context, provider *ent
218272
Models: make([]entities.ModelPricing, 0),
219273
}
220274

221-
// Handle drujensen provider specially - it doesn't exist in models.dev
222-
if provider.Type == entities.ProviderDrujensen {
275+
// Handle provider key mapping for models.dev
276+
providerKey := string(provider.Type)
277+
if provider.Type == entities.ProviderTogether {
278+
providerKey = "togetherai" // models.dev uses "togetherai" not "together"
279+
}
280+
281+
for _, modelData := range (*fetched)[providerKey].Models {
223282
pricing := entities.ModelPricing{
224-
Name: "qwen3-coder:latest",
225-
InputPricePerMille: 0, // 0 pricing as requested
226-
OutputPricePerMille: 0, // 0 pricing as requested
227-
ContextWindow: 64000,
228-
MaxOutputTokens: 0, // Will use ratio fallback
229-
}
230-
providerToUpdate.Models = append(providerToUpdate.Models, pricing)
231-
} else {
232-
// Handle provider key mapping for models.dev
233-
providerKey := string(provider.Type)
234-
if provider.Type == entities.ProviderTogether {
235-
providerKey = "togetherai" // models.dev uses "togetherai" not "together"
283+
Name: modelData.ID,
284+
InputPricePerMille: modelData.Cost.Input, // Keep as per million tokens
285+
OutputPricePerMille: modelData.Cost.Output, // Keep as per million tokens
286+
ContextWindow: modelData.Limit.Context,
287+
MaxOutputTokens: modelData.Limit.Output,
236288
}
237289

238-
for _, modelData := range (*fetched)[providerKey].Models {
239-
pricing := entities.ModelPricing{
240-
Name: modelData.ID,
241-
InputPricePerMille: modelData.Cost.Input, // Keep as per million tokens
242-
OutputPricePerMille: modelData.Cost.Output, // Keep as per million tokens
243-
ContextWindow: modelData.Limit.Context,
244-
MaxOutputTokens: modelData.Limit.Output,
245-
}
246-
247-
providerToUpdate.Models = append(providerToUpdate.Models, pricing)
248-
}
290+
providerToUpdate.Models = append(providerToUpdate.Models, pricing)
249291
}
250292

251293
providerToUpdate.UpdatedAt = time.Now()

internal/domain/services/provider_service.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@ package services
22

33
import (
44
"context"
5+
"fmt"
56

67
"github.com/drujensen/aiagent/internal/domain/entities"
78
"github.com/drujensen/aiagent/internal/domain/errs"
89
"github.com/drujensen/aiagent/internal/domain/interfaces"
10+
"github.com/drujensen/aiagent/internal/impl/config"
911

1012
"go.uber.org/zap"
1113
)
1214

1315
type ProviderService interface {
1416
ListProviders(ctx context.Context) ([]*entities.Provider, error)
1517
GetProvider(ctx context.Context, id string) (*entities.Provider, error)
18+
EnsureCustomProviders(ctx context.Context, globalConfig *config.GlobalConfig) error
1619
}
1720

1821
type providerService struct {
@@ -42,3 +45,52 @@ func (s *providerService) GetProvider(ctx context.Context, id string) (*entities
4245
}
4346
return provider, nil
4447
}
48+
49+
func (s *providerService) EnsureCustomProviders(ctx context.Context, globalConfig *config.GlobalConfig) error {
50+
// Get existing providers to check for duplicates
51+
existingProviders, err := s.providerRepo.ListProviders(ctx)
52+
if err != nil {
53+
return fmt.Errorf("failed to list existing providers: %w", err)
54+
}
55+
56+
// Create a map of existing provider names for quick lookup
57+
existingNames := make(map[string]bool)
58+
for _, provider := range existingProviders {
59+
existingNames[provider.Name] = true
60+
}
61+
62+
for providerKey, customConfig := range globalConfig.Providers {
63+
// Check if provider name already exists
64+
if existingNames[customConfig.Name] {
65+
s.logger.Debug("Custom provider name already exists, skipping",
66+
zap.String("provider_key", providerKey),
67+
zap.String("name", customConfig.Name))
68+
continue
69+
}
70+
71+
// Provider doesn't exist, create it
72+
s.logger.Info("Creating custom provider from config",
73+
zap.String("provider_key", providerKey),
74+
zap.String("name", customConfig.Name))
75+
76+
provider := &entities.Provider{
77+
ID: "", // Let repository generate UUID
78+
Name: customConfig.Name,
79+
Type: entities.ProviderType(customConfig.Type),
80+
BaseURL: customConfig.BaseURL,
81+
APIKeyName: customConfig.APIKeyName,
82+
Models: []entities.ModelPricing{}, // Will be populated during refresh
83+
}
84+
85+
if err := s.providerRepo.CreateProvider(ctx, provider); err != nil {
86+
return fmt.Errorf("failed to create custom provider %s: %w", providerKey, err)
87+
}
88+
89+
s.logger.Info("Created custom provider",
90+
zap.String("provider_key", providerKey),
91+
zap.String("provider_id", provider.ID),
92+
zap.String("name", provider.Name))
93+
}
94+
95+
return nil
96+
}

internal/impl/config/global.go

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,29 @@ import (
1111

1212
// GlobalConfig represents the global configuration settings
1313
type GlobalConfig struct {
14-
DefaultTemperature float64 `json:"default_temperature"`
15-
DefaultMaxTokensRatio float64 `json:"default_max_tokens_ratio"`
16-
LastUsedAgent string `json:"last_used_agent"`
17-
LastUsedModel string `json:"last_used_model"`
14+
DefaultTemperature float64 `json:"default_temperature"`
15+
DefaultMaxTokensRatio float64 `json:"default_max_tokens_ratio"`
16+
LastUsedAgent string `json:"last_used_agent"`
17+
LastUsedModel string `json:"last_used_model"`
18+
Providers map[string]CustomProviderConfig `json:"providers,omitempty"`
19+
}
20+
21+
// CustomProviderConfig represents a custom provider configuration
22+
type CustomProviderConfig struct {
23+
Name string `json:"name"`
24+
Type string `json:"type"`
25+
BaseURL string `json:"base_url"`
26+
APIKeyName string `json:"api_key_name"`
27+
Models map[string]CustomModelConfig `json:"models"`
28+
}
29+
30+
// CustomModelConfig represents a custom model configuration
31+
type CustomModelConfig struct {
32+
Name string `json:"name"`
33+
ContextWindow int `json:"context_window"`
34+
InputPricePerMille float64 `json:"input_price_per_mille"`
35+
OutputPricePerMille float64 `json:"output_price_per_mille"`
36+
MaxOutputTokens int `json:"max_output_tokens,omitempty"`
1837
}
1938

2039
// DefaultGlobalConfig returns the default global configuration
@@ -24,6 +43,36 @@ func DefaultGlobalConfig() *GlobalConfig {
2443
DefaultMaxTokensRatio: 0.25,
2544
LastUsedAgent: "",
2645
LastUsedModel: "",
46+
Providers: map[string]CustomProviderConfig{
47+
"drujensen": {
48+
Name: "Drujensen",
49+
Type: "generic",
50+
BaseURL: "https://ai.drujensen.com",
51+
APIKeyName: "DRUJENSEN_API_KEY",
52+
Models: map[string]CustomModelConfig{
53+
"qwen3-coder:latest": {
54+
Name: "Qwen3 Coder",
55+
ContextWindow: 64000,
56+
InputPricePerMille: 0,
57+
OutputPricePerMille: 0,
58+
},
59+
},
60+
},
61+
"ollama": {
62+
Name: "Ollama",
63+
Type: "generic",
64+
BaseURL: "http://localhost:11434",
65+
APIKeyName: "",
66+
Models: map[string]CustomModelConfig{
67+
"llama2:7b": {
68+
Name: "Llama 2 7B",
69+
ContextWindow: 4096,
70+
InputPricePerMille: 0,
71+
OutputPricePerMille: 0,
72+
},
73+
},
74+
},
75+
},
2776
}
2877
}
2978

internal/impl/defaults/defaults.go

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,7 @@ func DefaultProviders() []*entities.Provider {
1717
APIKeyName: "ANTHROPIC_API_KEY",
1818
Models: []entities.ModelPricing{},
1919
},
20-
{
21-
ID: "41A83584-ABEB-4490-921A-D778A296862D",
22-
Name: "Custom Provider",
23-
Type: "generic",
24-
BaseURL: "",
25-
APIKeyName: "CUSTOM_API_KEY",
26-
Models: []entities.ModelPricing{},
27-
},
20+
2821
{
2922
ID: "ADEAC984-EBB4-491F-B041-38966A15DE83",
3023
Name: "DeepSeek",
@@ -33,14 +26,6 @@ func DefaultProviders() []*entities.Provider {
3326
APIKeyName: "DEEPSEEK_API_KEY",
3427
Models: []entities.ModelPricing{},
3528
},
36-
{
37-
ID: "511D9293-347A-495E-8C56-1A7B7D2185BB",
38-
Name: "Drujensen",
39-
Type: "drujensen",
40-
BaseURL: "https://ai.drujensen.com",
41-
APIKeyName: "DRUJENSEN_API_KEY",
42-
Models: []entities.ModelPricing{},
43-
},
4429
{
4530
ID: "E384327C-337D-4EA5-88D5-B1FC4147CD6D",
4631
Name: "Google",

internal/impl/integrations/aimodel_factory.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package integrations
22

33
import (
4-
"fmt"
5-
64
"github.com/drujensen/aiagent/internal/domain/entities"
75
"github.com/drujensen/aiagent/internal/domain/interfaces"
86

@@ -46,14 +44,11 @@ func (f *AIModelFactory) CreateModelIntegration(model *entities.Model, provider
4644
return NewGroqIntegration(endpoint, apiKey, model.ModelName, f.toolRepo, f.logger)
4745
case entities.ProviderMistral:
4846
return NewMistralIntegration(endpoint, apiKey, model.ModelName, f.toolRepo, f.logger)
49-
case entities.ProviderOllama:
50-
return NewOllamaIntegration(endpoint, apiKey, model.ModelName, f.toolRepo, f.logger)
51-
case entities.ProviderDrujensen:
52-
return NewDrujensenIntegration(endpoint, apiKey, model.ModelName, f.toolRepo, f.logger)
5347
case entities.ProviderGeneric:
5448
// For generic providers, use the OpenAI-compatible API
5549
return NewGenericIntegration(endpoint, apiKey, model.ModelName, f.toolRepo, f.logger)
5650
default:
57-
return nil, fmt.Errorf("unsupported provider type: %s", provider.Type)
51+
// Treat any unknown provider type as generic (OpenAI-compatible)
52+
return NewGenericIntegration(endpoint, apiKey, model.ModelName, f.toolRepo, f.logger)
5853
}
5954
}

internal/impl/integrations/drujensen.go

Lines changed: 0 additions & 34 deletions
This file was deleted.

internal/impl/integrations/ollama.go

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)