mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-09-23 10:28:00 +00:00
feat(templates): source templates for multi-key balancing
A template stores every source field except name and api_key, so operators spin up N key-bearing sources from one shared skeleton instead of duplicating the whole source block N times. - config: SourceTemplate type + RuntimeConfig.SourceTemplates stored in runtime.json alongside runtime sources - store: UpsertTemplate / ListTemplates / RemoveTemplate - core: Templates / SaveTemplate / RemoveTemplate - gateway: GET/POST/DELETE /api/source_templates - webui: source list gains a Templates button opening a manager with per-template edit/delete; the add-source dialog gains 'from template' (event-delegated picker) and 'as template' (card modal) buttons in its header; z-index fixed so the template editor layers above the manager
This commit is contained in:
@ -675,6 +675,33 @@ func (c *Core) Sources() []config.Source {
|
||||
return c.mergedSources()
|
||||
}
|
||||
|
||||
// Templates returns the saved source templates.
|
||||
func (c *Core) Templates() []config.SourceTemplate {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
return c.store.ListTemplates()
|
||||
}
|
||||
|
||||
// SaveTemplate upserts a source template.
|
||||
func (c *Core) SaveTemplate(t config.SourceTemplate) error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if t.Name == "" {
|
||||
return fmt.Errorf("template requires a name")
|
||||
}
|
||||
return c.store.UpsertTemplate(t)
|
||||
}
|
||||
|
||||
// RemoveTemplate deletes a source template by name.
|
||||
func (c *Core) RemoveTemplate(name string) error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if _, err := c.store.RemoveTemplate(name); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func normalizeSource(s *config.Source) error {
|
||||
if s.Name == "" || s.BaseURL == "" {
|
||||
return fmt.Errorf("source requires name and base_url")
|
||||
|
||||
Reference in New Issue
Block a user