-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathservice.go
More file actions
144 lines (122 loc) · 3.51 KB
/
service.go
File metadata and controls
144 lines (122 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package ai
import (
"context"
"fmt"
"sync"
"github.com/GoCodeAlone/workflow/config"
)
// Service coordinates multiple AI generator backends with provider selection,
// caching, and rate limiting.
type Service struct {
generators map[Provider]WorkflowGenerator
preferred Provider
mu sync.RWMutex
// Simple in-memory suggestion cache
cache map[string][]WorkflowSuggestion
cacheMu sync.RWMutex
}
// NewService creates a new AI service.
func NewService() *Service {
return &Service{
generators: make(map[Provider]WorkflowGenerator),
preferred: ProviderAuto,
cache: make(map[string][]WorkflowSuggestion),
}
}
// RegisterGenerator registers an AI generator for a provider.
func (s *Service) RegisterGenerator(provider Provider, gen WorkflowGenerator) {
s.mu.Lock()
defer s.mu.Unlock()
s.generators[provider] = gen
}
// SetPreferred sets the preferred provider. Use ProviderAuto to auto-select.
func (s *Service) SetPreferred(provider Provider) {
s.mu.Lock()
defer s.mu.Unlock()
s.preferred = provider
}
// Providers returns the list of registered provider names.
func (s *Service) Providers() []Provider {
s.mu.RLock()
defer s.mu.RUnlock()
providers := make([]Provider, 0, len(s.generators))
for p := range s.generators {
providers = append(providers, p)
}
return providers
}
func (s *Service) generator() (WorkflowGenerator, error) {
s.mu.RLock()
defer s.mu.RUnlock()
if s.preferred != ProviderAuto {
gen, ok := s.generators[s.preferred]
if !ok {
return nil, fmt.Errorf("provider %q not registered", s.preferred)
}
return gen, nil
}
// Auto-select: prefer anthropic, then copilot, then any
for _, p := range []Provider{ProviderAnthropic, ProviderCopilot} {
if gen, ok := s.generators[p]; ok {
return gen, nil
}
}
// Fall back to any registered generator
for _, gen := range s.generators {
return gen, nil
}
return nil, fmt.Errorf("no AI generators registered")
}
// GenerateWorkflow creates a workflow config from a natural language request.
func (s *Service) GenerateWorkflow(ctx context.Context, req GenerateRequest) (*GenerateResponse, error) {
gen, err := s.generator()
if err != nil {
return nil, err
}
return gen.GenerateWorkflow(ctx, req)
}
// GenerateComponent generates Go source code for a component.
func (s *Service) GenerateComponent(ctx context.Context, spec ComponentSpec) (string, error) {
gen, err := s.generator()
if err != nil {
return "", err
}
return gen.GenerateComponent(ctx, spec)
}
// SuggestWorkflow returns cached or fresh suggestions for a use case.
func (s *Service) SuggestWorkflow(ctx context.Context, useCase string) ([]WorkflowSuggestion, error) {
// Check cache first
s.cacheMu.RLock()
if cached, ok := s.cache[useCase]; ok {
s.cacheMu.RUnlock()
return cached, nil
}
s.cacheMu.RUnlock()
gen, err := s.generator()
if err != nil {
return nil, err
}
suggestions, err := gen.SuggestWorkflow(ctx, useCase)
if err != nil {
return nil, err
}
// Cache the result
s.cacheMu.Lock()
s.cache[useCase] = suggestions
s.cacheMu.Unlock()
return suggestions, nil
}
// IdentifyMissingComponents analyzes a config for non-built-in module types.
func (s *Service) IdentifyMissingComponents(ctx context.Context, cfg *config.WorkflowConfig) ([]ComponentSpec, error) {
gen, err := s.generator()
if err != nil {
return nil, err
}
return gen.IdentifyMissingComponents(ctx, cfg)
}
// ClearCache clears the suggestion cache.
func (s *Service) ClearCache() {
s.cacheMu.Lock()
s.cache = make(map[string][]WorkflowSuggestion)
s.cacheMu.Unlock()
}