Files
wehub-resource-sync 1b8708893a
Security Scan / tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:12:26 +08:00

192 lines
5.2 KiB
Go

package agentpool
import (
"encoding/json"
"fmt"
"strings"
"github.com/mudler/LocalAGI/core/agent"
"github.com/mudler/LocalAGI/core/sse"
"github.com/mudler/LocalAGI/core/state"
agiServices "github.com/mudler/LocalAGI/services"
"github.com/mudler/LocalAI/core/services/agents"
)
// localAgentConfigBackend wraps the in-memory LocalAGI AgentPool for standalone mode.
type localAgentConfigBackend struct {
svc *AgentPoolService // back-reference for shared fields (pool, configMeta, outputsDir, etc.)
}
func newLocalAgentConfigBackend(svc *AgentPoolService) *localAgentConfigBackend {
return &localAgentConfigBackend{svc: svc}
}
func (b *localAgentConfigBackend) ListAgents(userID string) map[string]bool {
statuses := map[string]bool{}
agents := b.svc.localAGI.pool.List()
prefix := ""
if userID != "" {
prefix = userID + ":"
}
for _, a := range agents {
if userID != "" && !strings.HasPrefix(a, prefix) {
continue
}
ag := b.svc.localAGI.pool.GetAgent(a)
if ag == nil {
continue
}
displayName := a
if prefix != "" {
displayName = strings.TrimPrefix(a, prefix)
}
statuses[displayName] = !ag.Paused()
}
return statuses
}
func (b *localAgentConfigBackend) GetConfig(userID, name string) *state.AgentConfig {
cfg := b.svc.localAGI.pool.GetConfig(agents.AgentKey(userID, name))
if cfg == nil {
return nil
}
// Return a copy with the original name (strip userID: prefix)
result := *cfg
result.Name = name
return &result
}
func (b *localAgentConfigBackend) SaveConfig(userID string, cfg *state.AgentConfig) error {
key := agents.AgentKey(userID, cfg.Name)
cfg.Name = key
return b.svc.localAGI.pool.CreateAgent(key, cfg)
}
func (b *localAgentConfigBackend) UpdateConfig(userID, name string, cfg *state.AgentConfig) error {
key := agents.AgentKey(userID, name)
if old := b.svc.localAGI.pool.GetConfig(key); old == nil {
return fmt.Errorf("%w: %s", ErrAgentNotFound, name)
}
cfg.Name = key
return b.svc.localAGI.pool.RecreateAgent(key, cfg)
}
func (b *localAgentConfigBackend) DeleteConfig(userID, name string) error {
return b.svc.localAGI.pool.Remove(agents.AgentKey(userID, name))
}
func (b *localAgentConfigBackend) ImportConfig(userID string, cfg *state.AgentConfig) error {
key := agents.AgentKey(userID, cfg.Name)
cfg.Name = key
return b.svc.localAGI.pool.CreateAgent(key, cfg)
}
func (b *localAgentConfigBackend) ExportConfig(userID, name string) ([]byte, error) {
cfg := b.svc.localAGI.pool.GetConfig(agents.AgentKey(userID, name))
if cfg == nil {
return nil, fmt.Errorf("%w: %s", ErrAgentNotFound, name)
}
return json.MarshalIndent(cfg, "", " ")
}
func (b *localAgentConfigBackend) SetStatus(userID, name, status string) error {
ag := b.svc.localAGI.pool.GetAgent(agents.AgentKey(userID, name))
if ag == nil {
return fmt.Errorf("%w: %s", ErrAgentNotFound, name)
}
switch status {
case "paused":
ag.Pause()
case "active":
ag.Resume()
default:
return fmt.Errorf("unknown status: %s", status)
}
return nil
}
func (b *localAgentConfigBackend) GetAgent(userID, name string) *agent.Agent {
return b.svc.localAGI.pool.GetAgent(agents.AgentKey(userID, name))
}
func (b *localAgentConfigBackend) GetSSEManager(userID, name string) sse.Manager {
return b.svc.localAGI.pool.GetManager(agents.AgentKey(userID, name))
}
func (b *localAgentConfigBackend) GetStatus(userID, name string) *state.Status {
return b.svc.localAGI.pool.GetStatusHistory(agents.AgentKey(userID, name))
}
func (b *localAgentConfigBackend) GetObservables(userID, name string) ([]json.RawMessage, error) {
ag := b.svc.localAGI.pool.GetAgent(agents.AgentKey(userID, name))
if ag == nil {
return nil, fmt.Errorf("%w: %s", ErrAgentNotFound, name)
}
history := ag.Observer().History()
result := make([]json.RawMessage, 0, len(history))
for _, obs := range history {
data, err := json.Marshal(obs)
if err != nil {
continue
}
result = append(result, data)
}
return result, nil
}
func (b *localAgentConfigBackend) ClearObservables(userID, name string) error {
ag := b.svc.localAGI.pool.GetAgent(agents.AgentKey(userID, name))
if ag == nil {
return fmt.Errorf("%w: %s", ErrAgentNotFound, name)
}
ag.Observer().ClearHistory()
return nil
}
func (b *localAgentConfigBackend) ListAllGrouped() map[string][]UserAgentInfo {
result := map[string][]UserAgentInfo{}
agents := b.svc.localAGI.pool.List()
for _, a := range agents {
ag := b.svc.localAGI.pool.GetAgent(a)
if ag == nil {
continue
}
userID := ""
name := a
if u, n, ok := strings.Cut(a, ":"); ok {
userID = u
name = n
}
result[userID] = append(result[userID], UserAgentInfo{
Name: name,
Active: !ag.Paused(),
})
}
return result
}
func (b *localAgentConfigBackend) GetConfigMeta() AgentConfigMetaResult {
meta := b.svc.localAGI.configMeta
return AgentConfigMetaResult{
Fields: meta.Fields,
Actions: meta.Actions,
Connectors: meta.Connectors,
Filters: meta.Filters,
OutputsDir: b.svc.outputsDir,
}
}
func (b *localAgentConfigBackend) ListAvailableActions() []string {
return agiServices.AvailableActions
}
func (b *localAgentConfigBackend) Chat(userID, name, message string) (string, error) {
return b.svc.Chat(agents.AgentKey(userID, name), message)
}
func (b *localAgentConfigBackend) Stop() {
if b.svc.localAGI.pool != nil {
b.svc.localAGI.pool.StopAll()
}
}