Add more actions, small fixups in the UI, add stop action
This commit is contained in:
65
example/webui/actions.go
Normal file
65
example/webui/actions.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
|
||||
. "github.com/mudler/local-agent-framework/agent"
|
||||
"github.com/mudler/local-agent-framework/external"
|
||||
)
|
||||
|
||||
const (
|
||||
// Actions
|
||||
ActionSearch = "search"
|
||||
ActionGithubIssueLabeler = "github-issue-labeler"
|
||||
ActionGithubIssueOpener = "github-issue-opener"
|
||||
ActionGithubIssueCloser = "github-issue-closer"
|
||||
ActionGithubIssueSearcher = "github-issue-searcher"
|
||||
ActionScraper = "scraper"
|
||||
ActionWikipedia = "wikipedia"
|
||||
)
|
||||
|
||||
var AvailableActions = []string{
|
||||
ActionSearch,
|
||||
ActionGithubIssueLabeler,
|
||||
ActionGithubIssueOpener,
|
||||
ActionGithubIssueCloser,
|
||||
ActionGithubIssueSearcher,
|
||||
ActionScraper,
|
||||
ActionWikipedia,
|
||||
}
|
||||
|
||||
func (a *AgentConfig) availableActions(ctx context.Context) []Action {
|
||||
actions := []Action{}
|
||||
|
||||
for _, action := range a.Actions {
|
||||
slog.Info("Set Action", action)
|
||||
|
||||
var config map[string]string
|
||||
if err := json.Unmarshal([]byte(action.Config), &config); err != nil {
|
||||
slog.Info("Error unmarshalling action config", err)
|
||||
continue
|
||||
}
|
||||
slog.Info("Config", config)
|
||||
|
||||
switch action.Name {
|
||||
case ActionSearch:
|
||||
actions = append(actions, external.NewSearch(config))
|
||||
case ActionGithubIssueLabeler:
|
||||
actions = append(actions, external.NewGithubIssueLabeler(ctx, config))
|
||||
case ActionGithubIssueOpener:
|
||||
actions = append(actions, external.NewGithubIssueOpener(ctx, config))
|
||||
case ActionGithubIssueCloser:
|
||||
actions = append(actions, external.NewGithubIssueCloser(ctx, config))
|
||||
case ActionGithubIssueSearcher:
|
||||
actions = append(actions, external.NewGithubIssueSearch(ctx, config))
|
||||
case ActionScraper:
|
||||
actions = append(actions, external.NewScraper(config))
|
||||
case ActionWikipedia:
|
||||
actions = append(actions, external.NewWikipedia(config))
|
||||
}
|
||||
}
|
||||
|
||||
return actions
|
||||
}
|
||||
30
example/webui/agentconfig.go
Normal file
30
example/webui/agentconfig.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
type ConnectorConfig struct {
|
||||
Type string `json:"type"` // e.g. Slack
|
||||
Config string `json:"config"`
|
||||
}
|
||||
|
||||
type ActionsConfig struct {
|
||||
Name string `json:"name"` // e.g. search
|
||||
Config string `json:"config"`
|
||||
}
|
||||
|
||||
type AgentConfig struct {
|
||||
Connector []ConnectorConfig `json:"connectors" form:"connectors" `
|
||||
Actions []ActionsConfig `json:"actions" form:"actions"`
|
||||
// This is what needs to be part of ActionsConfig
|
||||
Model string `json:"model" form:"model"`
|
||||
Name string `json:"name" form:"name"`
|
||||
HUD bool `json:"hud" form:"hud"`
|
||||
StandaloneJob bool `json:"standalone_job" form:"standalone_job"`
|
||||
RandomIdentity bool `json:"random_identity" form:"random_identity"`
|
||||
InitiateConversations bool `json:"initiate_conversations" form:"initiate_conversations"`
|
||||
IdentityGuidance string `json:"identity_guidance" form:"identity_guidance"`
|
||||
PeriodicRuns string `json:"periodic_runs" form:"periodic_runs"`
|
||||
PermanentGoal string `json:"permanent_goal" form:"permanent_goal"`
|
||||
EnableKnowledgeBase bool `json:"enable_kb" form:"enable_kb"`
|
||||
KnowledgeBaseResults int `json:"kb_results" form:"kb_results"`
|
||||
CanStopItself bool `json:"can_stop_itself" form:"can_stop_itself"`
|
||||
SystemPrompt string `json:"system_prompt" form:"system_prompt"`
|
||||
}
|
||||
@@ -10,41 +10,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/mudler/local-agent-framework/example/webui/connector"
|
||||
|
||||
. "github.com/mudler/local-agent-framework/agent"
|
||||
"github.com/mudler/local-agent-framework/external"
|
||||
)
|
||||
|
||||
type ConnectorConfig struct {
|
||||
Type string `json:"type"` // e.g. Slack
|
||||
Config string `json:"config"`
|
||||
}
|
||||
|
||||
type ActionsConfig struct {
|
||||
Name string `json:"name"` // e.g. search
|
||||
Config string `json:"config"`
|
||||
}
|
||||
|
||||
type AgentConfig struct {
|
||||
Connector []ConnectorConfig `json:"connectors" form:"connectors" `
|
||||
Actions []ActionsConfig `json:"actions" form:"actions"`
|
||||
// This is what needs to be part of ActionsConfig
|
||||
Model string `json:"model" form:"model"`
|
||||
Name string `json:"name" form:"name"`
|
||||
HUD bool `json:"hud" form:"hud"`
|
||||
StandaloneJob bool `json:"standalone_job" form:"standalone_job"`
|
||||
RandomIdentity bool `json:"random_identity" form:"random_identity"`
|
||||
InitiateConversations bool `json:"initiate_conversations" form:"initiate_conversations"`
|
||||
IdentityGuidance string `json:"identity_guidance" form:"identity_guidance"`
|
||||
PeriodicRuns string `json:"periodic_runs" form:"periodic_runs"`
|
||||
PermanentGoal string `json:"permanent_goal" form:"permanent_goal"`
|
||||
EnableKnowledgeBase bool `json:"enable_kb" form:"enable_kb"`
|
||||
KnowledgeBaseResults int `json:"kb_results" form:"kb_results"`
|
||||
CanStopItself bool `json:"can_stop_itself" form:"can_stop_itself"`
|
||||
SystemPrompt string `json:"system_prompt" form:"system_prompt"`
|
||||
}
|
||||
|
||||
type AgentPool struct {
|
||||
sync.Mutex
|
||||
file string
|
||||
@@ -148,105 +116,6 @@ func (a *AgentPool) List() []string {
|
||||
return agents
|
||||
}
|
||||
|
||||
const (
|
||||
// Connectors
|
||||
ConnectorTelegram = "telegram"
|
||||
ConnectorSlack = "slack"
|
||||
ConnectorDiscord = "discord"
|
||||
ConnectorGithubIssues = "github-issues"
|
||||
|
||||
// Actions
|
||||
ActionSearch = "search"
|
||||
ActionGithubIssueLabeler = "github-issue-labeler"
|
||||
ActionGithubIssueOpener = "github-issue-opener"
|
||||
ActionGithubIssueCloser = "github-issue-closer"
|
||||
ActionGithubIssueSearcher = "github-issue-searcher"
|
||||
)
|
||||
|
||||
var AvailableActions = []string{
|
||||
ActionSearch,
|
||||
ActionGithubIssueLabeler,
|
||||
ActionGithubIssueOpener,
|
||||
ActionGithubIssueCloser,
|
||||
ActionGithubIssueSearcher,
|
||||
}
|
||||
|
||||
func (a *AgentConfig) availableActions(ctx context.Context) []Action {
|
||||
actions := []Action{}
|
||||
|
||||
for _, action := range a.Actions {
|
||||
slog.Info("Set Action", action)
|
||||
|
||||
var config map[string]string
|
||||
if err := json.Unmarshal([]byte(action.Config), &config); err != nil {
|
||||
slog.Info("Error unmarshalling action config", err)
|
||||
continue
|
||||
}
|
||||
slog.Info("Config", config)
|
||||
|
||||
switch action.Name {
|
||||
case ActionSearch:
|
||||
actions = append(actions, external.NewSearch(config))
|
||||
case ActionGithubIssueLabeler:
|
||||
actions = append(actions, external.NewGithubIssueLabeler(ctx, config))
|
||||
case ActionGithubIssueOpener:
|
||||
actions = append(actions, external.NewGithubIssueOpener(ctx, config))
|
||||
case ActionGithubIssueCloser:
|
||||
actions = append(actions, external.NewGithubIssueCloser(ctx, config))
|
||||
case ActionGithubIssueSearcher:
|
||||
actions = append(actions, external.NewGithubIssueSearch(ctx, config))
|
||||
}
|
||||
}
|
||||
|
||||
return actions
|
||||
}
|
||||
|
||||
type Connector interface {
|
||||
AgentResultCallback() func(state ActionState)
|
||||
AgentReasoningCallback() func(state ActionCurrentState) bool
|
||||
Start(a *Agent)
|
||||
}
|
||||
|
||||
var AvailableConnectors = []string{
|
||||
ConnectorTelegram,
|
||||
ConnectorSlack,
|
||||
ConnectorDiscord,
|
||||
ConnectorGithubIssues,
|
||||
}
|
||||
|
||||
func (a *AgentConfig) availableConnectors() []Connector {
|
||||
connectors := []Connector{}
|
||||
|
||||
for _, c := range a.Connector {
|
||||
slog.Info("Set Connector", c)
|
||||
|
||||
var config map[string]string
|
||||
if err := json.Unmarshal([]byte(c.Config), &config); err != nil {
|
||||
slog.Info("Error unmarshalling connector config", err)
|
||||
continue
|
||||
}
|
||||
slog.Info("Config", config)
|
||||
|
||||
switch c.Type {
|
||||
case ConnectorTelegram:
|
||||
cc, err := connector.NewTelegramConnector(config)
|
||||
if err != nil {
|
||||
slog.Info("Error creating telegram connector", err)
|
||||
continue
|
||||
}
|
||||
|
||||
connectors = append(connectors, cc)
|
||||
case ConnectorSlack:
|
||||
connectors = append(connectors, connector.NewSlack(config))
|
||||
case ConnectorDiscord:
|
||||
connectors = append(connectors, connector.NewDiscord(config))
|
||||
case ConnectorGithubIssues:
|
||||
connectors = append(connectors, connector.NewGithubIssueWatcher(config))
|
||||
}
|
||||
}
|
||||
return connectors
|
||||
}
|
||||
|
||||
func (a *AgentPool) GetStatusHistory(name string) *Status {
|
||||
a.Lock()
|
||||
defer a.Unlock()
|
||||
|
||||
@@ -264,7 +264,11 @@ func (a *App) Chat(pool *AgentPool) func(c *fiber.Ctx) error {
|
||||
res := agent.Ask(
|
||||
WithText(query),
|
||||
)
|
||||
slog.Info("response is", res.Response)
|
||||
if res.Error != nil {
|
||||
slog.Error("Error asking agent", "agent", agentName, "error", res.Error)
|
||||
} else {
|
||||
slog.Info("we got a response from the agent", "agent", agentName, "response", res.Response)
|
||||
}
|
||||
manager.Send(
|
||||
NewMessage(
|
||||
chatDiv(res.Response, "blue"),
|
||||
|
||||
64
example/webui/connectors.go
Normal file
64
example/webui/connectors.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
|
||||
. "github.com/mudler/local-agent-framework/agent"
|
||||
|
||||
"github.com/mudler/local-agent-framework/example/webui/connector"
|
||||
)
|
||||
|
||||
const (
|
||||
// Connectors
|
||||
ConnectorTelegram = "telegram"
|
||||
ConnectorSlack = "slack"
|
||||
ConnectorDiscord = "discord"
|
||||
ConnectorGithubIssues = "github-issues"
|
||||
)
|
||||
|
||||
type Connector interface {
|
||||
AgentResultCallback() func(state ActionState)
|
||||
AgentReasoningCallback() func(state ActionCurrentState) bool
|
||||
Start(a *Agent)
|
||||
}
|
||||
|
||||
var AvailableConnectors = []string{
|
||||
ConnectorTelegram,
|
||||
ConnectorSlack,
|
||||
ConnectorDiscord,
|
||||
ConnectorGithubIssues,
|
||||
}
|
||||
|
||||
func (a *AgentConfig) availableConnectors() []Connector {
|
||||
connectors := []Connector{}
|
||||
|
||||
for _, c := range a.Connector {
|
||||
slog.Info("Set Connector", c)
|
||||
|
||||
var config map[string]string
|
||||
if err := json.Unmarshal([]byte(c.Config), &config); err != nil {
|
||||
slog.Info("Error unmarshalling connector config", err)
|
||||
continue
|
||||
}
|
||||
slog.Info("Config", config)
|
||||
|
||||
switch c.Type {
|
||||
case ConnectorTelegram:
|
||||
cc, err := connector.NewTelegramConnector(config)
|
||||
if err != nil {
|
||||
slog.Info("Error creating telegram connector", err)
|
||||
continue
|
||||
}
|
||||
|
||||
connectors = append(connectors, cc)
|
||||
case ConnectorSlack:
|
||||
connectors = append(connectors, connector.NewSlack(config))
|
||||
case ConnectorDiscord:
|
||||
connectors = append(connectors, connector.NewDiscord(config))
|
||||
case ConnectorGithubIssues:
|
||||
connectors = append(connectors, connector.NewGithubIssueWatcher(config))
|
||||
}
|
||||
}
|
||||
return connectors
|
||||
}
|
||||
@@ -105,7 +105,7 @@
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="identity_guidance" class="block text-lg font-medium text-gray-400">Identity Guidance</label>
|
||||
<input type="text" name="identity_guidance" id="identity_guidance" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder="Identity Guidance">
|
||||
<textarea name="identity_guidance" id="identity_guidance" class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-lg border-gray-300 rounded-md bg-gray-700 text-white" placeholder="Identity Guidance"></textarea>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="periodic_runs" class="block text-lg font-medium text-gray-400">Periodic Runs</label>
|
||||
@@ -113,13 +113,13 @@
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="permanent_goal" class="block text-lg font-medium text-gray-400">Permanent goal</label>
|
||||
<input type="text" name="permanent_goal" id="permanent_goal" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder="Permanent goal">
|
||||
<textarea name="permanent_goal" id="permanent_goal" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder="Permanent goal"></textarea>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="system_prompt" class="block text-lg font-medium text-gray-400">System prompt</label>
|
||||
<input type="text" name="system_prompt" id="system_prompt" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder="System prompt">
|
||||
<textarea name="system_prompt" id="system_prompt" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder="System prompt"></textarea>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-500 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
||||
Create Agent
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
<div class="section-box">
|
||||
<h2>Danger section</h2>
|
||||
<a href="/delete/{{.}}" class="text-red-500 hover:text-red-400">
|
||||
<a href="/delete/{{.Name}}" class="text-red-500 hover:text-red-400">
|
||||
<i class="fas fa-trash-alt"></i> Delete
|
||||
</a>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user