mirror of
https://github.com/mudler/LocalAGI.git
synced 2026-07-23 10:45:41 -04:00
chore: drop LocalOperator actions, we will use MCP for this (#407)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
committed by
GitHub
parent
1d574069f2
commit
cea3b7b111
@@ -25,7 +25,6 @@ var withLogs = os.Getenv("LOCALAGI_ENABLE_CONVERSATIONS_LOGGING") == "true"
|
||||
var apiKeysEnv = os.Getenv("LOCALAGI_API_KEYS")
|
||||
var imageModel = os.Getenv("LOCALAGI_IMAGE_MODEL")
|
||||
var conversationDuration = os.Getenv("LOCALAGI_CONVERSATION_DURATION")
|
||||
var localOperatorBaseURL = os.Getenv("LOCALOPERATOR_BASE_URL")
|
||||
var customActionsDir = os.Getenv("LOCALAGI_CUSTOM_ACTIONS_DIR")
|
||||
var sshBoxURL = os.Getenv("LOCALAGI_SSHBOX_URL")
|
||||
|
||||
@@ -71,11 +70,9 @@ func main() {
|
||||
stateDir,
|
||||
localRAG,
|
||||
services.Actions(map[string]string{
|
||||
services.ActionConfigBrowserAgentRunner: localOperatorBaseURL,
|
||||
services.ActionConfigDeepResearchRunner: localOperatorBaseURL,
|
||||
services.ActionConfigSSHBoxURL: sshBoxURL,
|
||||
services.ConfigStateDir: stateDir,
|
||||
services.CustomActionsDir: customActionsDir,
|
||||
services.ActionConfigSSHBoxURL: sshBoxURL,
|
||||
services.ConfigStateDir: stateDir,
|
||||
services.CustomActionsDir: customActionsDir,
|
||||
}),
|
||||
services.Connectors,
|
||||
services.DynamicPrompts(map[string]string{
|
||||
|
||||
+3
-23
@@ -22,8 +22,6 @@ const (
|
||||
// Actions
|
||||
ActionSearch = "search"
|
||||
ActionCustom = "custom"
|
||||
ActionBrowserAgentRunner = "browser-agent-runner"
|
||||
ActionDeepResearchRunner = "deep-research-runner"
|
||||
ActionGithubIssueLabeler = "github-issue-labeler"
|
||||
ActionGithubIssueOpener = "github-issue-opener"
|
||||
ActionGithubIssueEditor = "github-issue-editor"
|
||||
@@ -81,8 +79,6 @@ var AvailableActions = []string{
|
||||
ActionGithubGetAllContent,
|
||||
ActionGithubRepositorySearchFiles,
|
||||
ActionGithubRepositoryListFiles,
|
||||
ActionBrowserAgentRunner,
|
||||
ActionDeepResearchRunner,
|
||||
ActionGithubRepositoryCreateOrUpdate,
|
||||
ActionGithubIssueReader,
|
||||
ActionGithubIssueCommenter,
|
||||
@@ -119,16 +115,6 @@ var DefaultActions = []config.FieldGroup{
|
||||
Label: "Search",
|
||||
Fields: actions.SearchConfigMeta(),
|
||||
},
|
||||
{
|
||||
Name: "browser-agent-runner",
|
||||
Label: "Browser Agent Runner",
|
||||
Fields: actions.BrowserAgentRunnerConfigMeta(),
|
||||
},
|
||||
{
|
||||
Name: "deep-research-runner",
|
||||
Label: "Deep Research Runner",
|
||||
Fields: actions.DeepResearchRunnerConfigMeta(),
|
||||
},
|
||||
{
|
||||
Name: "generate_image",
|
||||
Label: "Generate Image",
|
||||
@@ -322,11 +308,9 @@ var DefaultActions = []config.FieldGroup{
|
||||
}
|
||||
|
||||
const (
|
||||
ActionConfigBrowserAgentRunner = "browser-agent-runner-base-url"
|
||||
ActionConfigDeepResearchRunner = "deep-research-runner-base-url"
|
||||
ActionConfigSSHBoxURL = "sshbox-url"
|
||||
ConfigStateDir = "state-dir"
|
||||
CustomActionsDir = "custom-actions-dir"
|
||||
ActionConfigSSHBoxURL = "sshbox-url"
|
||||
ConfigStateDir = "state-dir"
|
||||
CustomActionsDir = "custom-actions-dir"
|
||||
)
|
||||
|
||||
func customActions(customActionsDir string, existingActionConfigs map[string]map[string]string) (allActions []types.Action) {
|
||||
@@ -435,10 +419,6 @@ func Action(name, agentName string, config map[string]string, pool *state.AgentP
|
||||
a = actions.NewGithubIssueCloser(config)
|
||||
case ActionGithubIssueSearcher:
|
||||
a = actions.NewGithubIssueSearch(config)
|
||||
case ActionBrowserAgentRunner:
|
||||
a = actions.NewBrowserAgentRunner(config, actionsConfigs[ActionConfigBrowserAgentRunner])
|
||||
case ActionDeepResearchRunner:
|
||||
a = actions.NewDeepResearchRunner(config, actionsConfigs[ActionConfigDeepResearchRunner])
|
||||
case ActionGithubIssueReader:
|
||||
a = actions.NewGithubIssueReader(config)
|
||||
case ActionGithubPRReader:
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
package actions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/mudler/LocalAGI/core/types"
|
||||
"github.com/mudler/LocalAGI/pkg/config"
|
||||
api "github.com/mudler/LocalAGI/pkg/localoperator"
|
||||
"github.com/sashabaranov/go-openai/jsonschema"
|
||||
)
|
||||
|
||||
const (
|
||||
MetadataBrowserAgentHistory = "browser_agent_history"
|
||||
)
|
||||
|
||||
type BrowserAgentRunner struct {
|
||||
baseURL, customActionName string
|
||||
client *api.Client
|
||||
}
|
||||
|
||||
func NewBrowserAgentRunner(config map[string]string, defaultURL string) *BrowserAgentRunner {
|
||||
if config["baseURL"] == "" {
|
||||
config["baseURL"] = defaultURL
|
||||
}
|
||||
|
||||
timeout := "15m"
|
||||
if config["timeout"] != "" {
|
||||
timeout = config["timeout"]
|
||||
}
|
||||
|
||||
duration, err := time.ParseDuration(timeout)
|
||||
if err != nil {
|
||||
// If parsing fails, use default 15 minutes
|
||||
duration = 15 * time.Minute
|
||||
}
|
||||
|
||||
client := api.NewClient(config["baseURL"], duration)
|
||||
|
||||
return &BrowserAgentRunner{
|
||||
client: client,
|
||||
baseURL: config["baseURL"],
|
||||
customActionName: config["customActionName"],
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BrowserAgentRunner) Run(ctx context.Context, sharedState *types.AgentSharedState, params types.ActionParams) (types.ActionResult, error) {
|
||||
result := api.AgentRequest{}
|
||||
err := params.Unmarshal(&result)
|
||||
if err != nil {
|
||||
return types.ActionResult{}, fmt.Errorf("failed to unmarshal params: %w", err)
|
||||
}
|
||||
|
||||
req := api.AgentRequest{
|
||||
Goal: result.Goal,
|
||||
MaxAttempts: result.MaxAttempts,
|
||||
MaxNoActionAttempts: result.MaxNoActionAttempts,
|
||||
}
|
||||
|
||||
stateHistory, err := b.client.RunBrowserAgent(req)
|
||||
if err != nil {
|
||||
return types.ActionResult{}, fmt.Errorf("failed to run browser agent: %w", err)
|
||||
}
|
||||
|
||||
// Format the state history into a readable string
|
||||
var historyStr string
|
||||
// for i, state := range stateHistory.States {
|
||||
// historyStr += fmt.Sprintf("State %d:\n", i+1)
|
||||
// historyStr += fmt.Sprintf(" URL: %s\n", state.CurrentURL)
|
||||
// historyStr += fmt.Sprintf(" Title: %s\n", state.PageTitle)
|
||||
// historyStr += fmt.Sprintf(" Description: %s\n\n", state.PageContentDescription)
|
||||
// }
|
||||
|
||||
historyStr += fmt.Sprintf(" URL: %s\n", stateHistory.States[len(stateHistory.States)-1].CurrentURL)
|
||||
historyStr += fmt.Sprintf(" Title: %s\n", stateHistory.States[len(stateHistory.States)-1].PageTitle)
|
||||
historyStr += fmt.Sprintf(" Description: %s\n\n", stateHistory.States[len(stateHistory.States)-1].PageContentDescription)
|
||||
|
||||
return types.ActionResult{
|
||||
Result: fmt.Sprintf("Browser agent completed successfully. History:\n%s", historyStr),
|
||||
Metadata: map[string]interface{}{MetadataBrowserAgentHistory: stateHistory},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *BrowserAgentRunner) Definition() types.ActionDefinition {
|
||||
actionName := "run_browser_agent"
|
||||
if b.customActionName != "" {
|
||||
actionName = b.customActionName
|
||||
}
|
||||
description := "Run a browser agent to achieve a specific goal, for example: 'Go to https://www.google.com and search for 'LocalAI', and tell me what's on the first page'"
|
||||
return types.ActionDefinition{
|
||||
Name: types.ActionDefinitionName(actionName),
|
||||
Description: description,
|
||||
Properties: map[string]jsonschema.Definition{
|
||||
"goal": {
|
||||
Type: jsonschema.String,
|
||||
Description: "The goal for the browser agent to achieve",
|
||||
},
|
||||
"max_attempts": {
|
||||
Type: jsonschema.Number,
|
||||
Description: "Maximum number of attempts the agent can make (optional)",
|
||||
},
|
||||
"max_no_action_attempts": {
|
||||
Type: jsonschema.Number,
|
||||
Description: "Maximum number of attempts without taking an action (optional)",
|
||||
},
|
||||
},
|
||||
Required: []string{"goal"},
|
||||
}
|
||||
}
|
||||
|
||||
func (a *BrowserAgentRunner) Plannable() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// BrowserAgentRunnerConfigMeta returns the metadata for Browser Agent Runner action configuration fields
|
||||
func BrowserAgentRunnerConfigMeta() []config.Field {
|
||||
return []config.Field{
|
||||
{
|
||||
Name: "baseURL",
|
||||
Label: "Base URL",
|
||||
Type: config.FieldTypeText,
|
||||
Required: false,
|
||||
HelpText: "Base URL of the LocalOperator API",
|
||||
},
|
||||
{
|
||||
Name: "customActionName",
|
||||
Label: "Custom Action Name",
|
||||
Type: config.FieldTypeText,
|
||||
HelpText: "Custom name for this action",
|
||||
},
|
||||
{
|
||||
Name: "timeout",
|
||||
Label: "Client Timeout",
|
||||
Type: config.FieldTypeText,
|
||||
Required: false,
|
||||
HelpText: "Client timeout duration (e.g. '15m', '1h'). Defaults to '15m' if not specified.",
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
package actions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/mudler/LocalAGI/core/types"
|
||||
"github.com/mudler/LocalAGI/pkg/config"
|
||||
api "github.com/mudler/LocalAGI/pkg/localoperator"
|
||||
"github.com/sashabaranov/go-openai/jsonschema"
|
||||
)
|
||||
|
||||
const (
|
||||
MetadataDeepResearchResult = "deep_research_result"
|
||||
)
|
||||
|
||||
type DeepResearchRunner struct {
|
||||
baseURL, customActionName string
|
||||
client *api.Client
|
||||
}
|
||||
|
||||
func NewDeepResearchRunner(config map[string]string, defaultURL string) *DeepResearchRunner {
|
||||
if config["baseURL"] == "" {
|
||||
config["baseURL"] = defaultURL
|
||||
}
|
||||
|
||||
timeout := "15m"
|
||||
if config["timeout"] != "" {
|
||||
timeout = config["timeout"]
|
||||
}
|
||||
|
||||
duration, err := time.ParseDuration(timeout)
|
||||
if err != nil {
|
||||
// If parsing fails, use default 15 minutes
|
||||
duration = 15 * time.Minute
|
||||
}
|
||||
|
||||
client := api.NewClient(config["baseURL"], duration)
|
||||
|
||||
return &DeepResearchRunner{
|
||||
client: client,
|
||||
baseURL: config["baseURL"],
|
||||
customActionName: config["customActionName"],
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DeepResearchRunner) Run(ctx context.Context, sharedState *types.AgentSharedState, params types.ActionParams) (types.ActionResult, error) {
|
||||
result := api.DeepResearchRequest{}
|
||||
err := params.Unmarshal(&result)
|
||||
if err != nil {
|
||||
return types.ActionResult{}, fmt.Errorf("failed to unmarshal params: %w", err)
|
||||
}
|
||||
|
||||
req := api.DeepResearchRequest{
|
||||
Topic: result.Topic,
|
||||
MaxCycles: result.MaxCycles,
|
||||
MaxNoActionAttempts: result.MaxNoActionAttempts,
|
||||
MaxResults: result.MaxResults,
|
||||
}
|
||||
|
||||
researchResult, err := d.client.RunDeepResearch(req)
|
||||
if err != nil {
|
||||
return types.ActionResult{}, fmt.Errorf("failed to run deep research: %w", err)
|
||||
}
|
||||
|
||||
// Format the research result into a readable string
|
||||
var resultStr string
|
||||
|
||||
resultStr += "Deep research result\n"
|
||||
resultStr += fmt.Sprintf("Topic: %s\n", researchResult.Topic)
|
||||
resultStr += fmt.Sprintf("Summary: %s\n", researchResult.Summary)
|
||||
resultStr += fmt.Sprintf("Research Cycles: %d\n", researchResult.ResearchCycles)
|
||||
resultStr += fmt.Sprintf("Completion Time: %s\n\n", researchResult.CompletionTime)
|
||||
|
||||
if len(researchResult.Sources) > 0 {
|
||||
resultStr += "Sources:\n"
|
||||
for _, source := range researchResult.Sources {
|
||||
resultStr += fmt.Sprintf("- %s (%s)\n %s\n", source.Title, source.URL, source.Description)
|
||||
}
|
||||
}
|
||||
|
||||
return types.ActionResult{
|
||||
Result: fmt.Sprintf("Deep research completed successfully.\n%s", resultStr),
|
||||
Metadata: map[string]interface{}{MetadataDeepResearchResult: researchResult},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *DeepResearchRunner) Definition() types.ActionDefinition {
|
||||
actionName := "run_deep_research"
|
||||
if d.customActionName != "" {
|
||||
actionName = d.customActionName
|
||||
}
|
||||
description := "Run a deep research on a specific topic, gathering information from multiple sources and providing a comprehensive summary"
|
||||
return types.ActionDefinition{
|
||||
Name: types.ActionDefinitionName(actionName),
|
||||
Description: description,
|
||||
Properties: map[string]jsonschema.Definition{
|
||||
"topic": {
|
||||
Type: jsonschema.String,
|
||||
Description: "The topic to research",
|
||||
},
|
||||
"max_cycles": {
|
||||
Type: jsonschema.Number,
|
||||
Description: "Maximum number of research cycles to perform (optional)",
|
||||
},
|
||||
"max_no_action_attempts": {
|
||||
Type: jsonschema.Number,
|
||||
Description: "Maximum number of attempts without taking an action (optional)",
|
||||
},
|
||||
"max_results": {
|
||||
Type: jsonschema.Number,
|
||||
Description: "Maximum number of results to collect (optional)",
|
||||
},
|
||||
},
|
||||
Required: []string{"topic"},
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DeepResearchRunner) Plannable() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// DeepResearchRunnerConfigMeta returns the metadata for Deep Research Runner action configuration fields
|
||||
func DeepResearchRunnerConfigMeta() []config.Field {
|
||||
return []config.Field{
|
||||
{
|
||||
Name: "baseURL",
|
||||
Label: "Base URL",
|
||||
Type: config.FieldTypeText,
|
||||
Required: false,
|
||||
HelpText: "Base URL of the LocalOperator API",
|
||||
},
|
||||
{
|
||||
Name: "customActionName",
|
||||
Label: "Custom Action Name",
|
||||
Type: config.FieldTypeText,
|
||||
HelpText: "Custom name for this action",
|
||||
},
|
||||
{
|
||||
Name: "timeout",
|
||||
Label: "Client Timeout",
|
||||
Type: config.FieldTypeText,
|
||||
Required: false,
|
||||
HelpText: "Client timeout duration (e.g. '15m', '1h'). Defaults to '15m' if not specified.",
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user