From 9ee0d89a6b1edc8130c86c89e79986942a01da1c Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Wed, 12 Mar 2025 22:50:45 +0100 Subject: [PATCH] Add github actions to upload and get files, update github dep Signed-off-by: Ettore Di Giacinto --- go.mod | 1 + go.sum | 2 + services/actions.go | 31 +++-- services/actions/githubissuecloser.go | 2 +- services/actions/githubissuelabeler.go | 2 +- services/actions/githubissueopener.go | 2 +- services/actions/githubissuesearch.go | 2 +- .../githubrepositorycreateupdatecontent.go | 107 ++++++++++++++++++ .../actions/githubrepositorygetcontent.go | 106 +++++++++++++++++ services/connectors/githubissue.go | 2 +- services/connectors/githubpr.go | 2 +- 11 files changed, 241 insertions(+), 18 deletions(-) create mode 100644 services/actions/githubrepositorycreateupdatecontent.go create mode 100644 services/actions/githubrepositorygetcontent.go diff --git a/go.mod b/go.mod index d46811f..92a0e4c 100644 --- a/go.mod +++ b/go.mod @@ -44,6 +44,7 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-github/v69 v69.2.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/google/uuid v1.6.0 // indirect diff --git a/go.sum b/go.sum index 9be66a4..9b900ef 100644 --- a/go.sum +++ b/go.sum @@ -85,6 +85,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v61 v61.0.0 h1:VwQCBwhyE9JclCI+22/7mLB1PuU9eowCXKY5pNlu1go= github.com/google/go-github/v61 v61.0.0/go.mod h1:0WR+KmsWX75G2EbpyGsGmradjo3IiciuI4BmdVCobQY= +github.com/google/go-github/v69 v69.2.0 h1:wR+Wi/fN2zdUx9YxSmYE0ktiX9IAR/BeePzeaUUbEHE= +github.com/google/go-github/v69 v69.2.0/go.mod h1:xne4jymxLR6Uj9b7J7PyTpkMYstEMMwGZa0Aehh1azM= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= diff --git a/services/actions.go b/services/actions.go index 3fb3f23..c97d9e5 100644 --- a/services/actions.go +++ b/services/actions.go @@ -14,18 +14,20 @@ import ( const ( // Actions - ActionSearch = "search" - ActionCustom = "custom" - ActionGithubIssueLabeler = "github-issue-labeler" - ActionGithubIssueOpener = "github-issue-opener" - ActionGithubIssueCloser = "github-issue-closer" - ActionGithubIssueSearcher = "github-issue-searcher" - ActionScraper = "scraper" - ActionWikipedia = "wikipedia" - ActionBrowse = "browse" - ActionSendMail = "send_mail" - ActionGenerateImage = "generate_image" - ActionCounter = "counter" + ActionSearch = "search" + ActionCustom = "custom" + ActionGithubIssueLabeler = "github-issue-labeler" + ActionGithubIssueOpener = "github-issue-opener" + ActionGithubIssueCloser = "github-issue-closer" + ActionGithubIssueSearcher = "github-issue-searcher" + ActionGithubRepositoryGet = "github-repository-get-content" + ActionGithubRepositoryCreateOrUpdate = "github-repository-create-or-update-content" + ActionScraper = "scraper" + ActionWikipedia = "wikipedia" + ActionBrowse = "browse" + ActionSendMail = "send_mail" + ActionGenerateImage = "generate_image" + ActionCounter = "counter" ) var AvailableActions = []string{ @@ -35,6 +37,7 @@ var AvailableActions = []string{ ActionGithubIssueOpener, ActionGithubIssueCloser, ActionGithubIssueSearcher, + ActionGithubRepositoryGet, ActionScraper, ActionBrowse, ActionWikipedia, @@ -74,6 +77,10 @@ func Actions(a *state.AgentConfig) func(ctx context.Context) []agent.Action { allActions = append(allActions, actions.NewGithubIssueCloser(ctx, config)) case ActionGithubIssueSearcher: allActions = append(allActions, actions.NewGithubIssueSearch(ctx, config)) + case ActionGithubRepositoryGet: + allActions = append(allActions, actions.NewGithubRepositoryGetContent(ctx, config)) + case ActionGithubRepositoryCreateOrUpdate: + allActions = append(allActions, actions.NewGithubRepositoryCreateOrUpdateContent(ctx, config)) case ActionScraper: allActions = append(allActions, actions.NewScraper(config)) case ActionWikipedia: diff --git a/services/actions/githubissuecloser.go b/services/actions/githubissuecloser.go index babd67f..195d30c 100644 --- a/services/actions/githubissuecloser.go +++ b/services/actions/githubissuecloser.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v69/github" "github.com/mudler/LocalAgent/core/action" "github.com/sashabaranov/go-openai/jsonschema" ) diff --git a/services/actions/githubissuelabeler.go b/services/actions/githubissuelabeler.go index 7cf4365..386ee9e 100644 --- a/services/actions/githubissuelabeler.go +++ b/services/actions/githubissuelabeler.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v69/github" "github.com/mudler/LocalAgent/core/action" "github.com/mudler/LocalAgent/pkg/xlog" "github.com/sashabaranov/go-openai/jsonschema" diff --git a/services/actions/githubissueopener.go b/services/actions/githubissueopener.go index eabb8dd..53752a5 100644 --- a/services/actions/githubissueopener.go +++ b/services/actions/githubissueopener.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v69/github" "github.com/mudler/LocalAgent/core/action" "github.com/sashabaranov/go-openai/jsonschema" ) diff --git a/services/actions/githubissuesearch.go b/services/actions/githubissuesearch.go index 0004bca..d93619b 100644 --- a/services/actions/githubissuesearch.go +++ b/services/actions/githubissuesearch.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v69/github" "github.com/mudler/LocalAgent/core/action" "github.com/mudler/LocalAgent/pkg/xlog" "github.com/sashabaranov/go-openai/jsonschema" diff --git a/services/actions/githubrepositorycreateupdatecontent.go b/services/actions/githubrepositorycreateupdatecontent.go new file mode 100644 index 0000000..2360dcf --- /dev/null +++ b/services/actions/githubrepositorycreateupdatecontent.go @@ -0,0 +1,107 @@ +package actions + +import ( + "context" + "fmt" + + "github.com/google/go-github/v69/github" + "github.com/mudler/LocalAgent/core/action" + "github.com/sashabaranov/go-openai/jsonschema" +) + +type GithubRepositoryCreateOrUpdateContent struct { + token, repository, owner, customActionName string + context context.Context + client *github.Client +} + +func NewGithubRepositoryCreateOrUpdateContent(ctx context.Context, config map[string]string) *GithubRepositoryCreateOrUpdateContent { + client := github.NewClient(nil).WithAuthToken(config["token"]) + + return &GithubRepositoryCreateOrUpdateContent{ + client: client, + token: config["token"], + repository: config["repository"], + owner: config["owner"], + customActionName: config["customActionName"], + context: ctx, + } +} + +func (g *GithubRepositoryCreateOrUpdateContent) Run(ctx context.Context, params action.ActionParams) (action.ActionResult, error) { + result := struct { + Path string `json:"path"` + Repository string `json:"repository"` + Owner string `json:"owner"` + Content string `json:"content"` + }{} + err := params.Unmarshal(&result) + if err != nil { + fmt.Printf("error: %v", err) + + return action.ActionResult{}, err + } + + if g.repository != "" && g.owner != "" { + result.Repository = g.repository + result.Owner = g.owner + } + + fileContent, _, err := g.client.Repositories.CreateFile(g.context, result.Owner, result.Repository, result.Path, &github.RepositoryContentFileOptions{ + Content: []byte(result.Content), + }) + if err != nil { + resultString := fmt.Sprintf("Error creating content : %v", err) + return action.ActionResult{Result: resultString}, err + } + + return action.ActionResult{Result: fmt.Sprintf("File created/updated: %s\n", fileContent.GetURL())}, err +} + +func (g *GithubRepositoryCreateOrUpdateContent) Definition() action.ActionDefinition { + actionName := "github_repository_create_or_update_content" + actionDescription := "Create or update a file in a GitHub repository" + if g.customActionName != "" { + actionName = g.customActionName + } + if g.repository != "" && g.owner != "" { + return action.ActionDefinition{ + Name: action.ActionDefinitionName(actionName), + Description: actionDescription, + Properties: map[string]jsonschema.Definition{ + "path": { + Type: jsonschema.String, + Description: "The path to the file or directory", + }, + "content": { + Type: jsonschema.String, + Description: "The content to create/update", + }, + }, + Required: []string{"path", "content"}, + } + } + return action.ActionDefinition{ + Name: action.ActionDefinitionName(actionName), + Description: actionDescription, + Properties: map[string]jsonschema.Definition{ + "path": { + Type: jsonschema.String, + Description: "The path to the file or directory", + }, + "repository": { + Type: jsonschema.String, + Description: "The repository to search in", + }, + "owner": { + Type: jsonschema.String, + Description: "The owner of the repository", + }, + "content": { + Type: jsonschema.String, + Description: "The content to create/update", + }, + }, + Required: []string{"path", "repository", "owner", "content"}, + } +} diff --git a/services/actions/githubrepositorygetcontent.go b/services/actions/githubrepositorygetcontent.go new file mode 100644 index 0000000..4a34b46 --- /dev/null +++ b/services/actions/githubrepositorygetcontent.go @@ -0,0 +1,106 @@ +package actions + +import ( + "context" + "fmt" + + "github.com/google/go-github/v69/github" + "github.com/mudler/LocalAgent/core/action" + "github.com/sashabaranov/go-openai/jsonschema" +) + +type GithubRepositoryGetContent struct { + token, repository, owner, customActionName string + context context.Context + client *github.Client +} + +func NewGithubRepositoryGetContent(ctx context.Context, config map[string]string) *GithubRepositoryGetContent { + client := github.NewClient(nil).WithAuthToken(config["token"]) + + return &GithubRepositoryGetContent{ + client: client, + token: config["token"], + repository: config["repository"], + owner: config["owner"], + customActionName: config["customActionName"], + context: ctx, + } +} + +func (g *GithubRepositoryGetContent) Run(ctx context.Context, params action.ActionParams) (action.ActionResult, error) { + result := struct { + Path string `json:"path"` + Repository string `json:"repository"` + Owner string `json:"owner"` + }{} + err := params.Unmarshal(&result) + if err != nil { + fmt.Printf("error: %v", err) + + return action.ActionResult{}, err + } + + if g.repository != "" && g.owner != "" { + result.Repository = g.repository + result.Owner = g.owner + } + + fileContent, directoryContent, _, err := g.client.Repositories.GetContents(g.context, result.Owner, result.Repository, result.Path, nil) + if err != nil { + resultString := fmt.Sprintf("Error getting content : %v", err) + return action.ActionResult{Result: resultString}, err + } + + if len(directoryContent) > 0 { + resultString := fmt.Sprintf("Directory found: %s\n", result.Path) + for _, f := range directoryContent { + resultString += fmt.Sprintf("File: %s\n", f.GetName()) + } + return action.ActionResult{Result: resultString}, err + } + + content := fileContent.Content + + return action.ActionResult{Result: fmt.Sprintf("File %s\nContent:%s\n", result.Path, content)}, err +} + +func (g *GithubRepositoryGetContent) Definition() action.ActionDefinition { + actionName := "get_github_repository_content" + actionDescription := "Get content of a file or directory in a github repository" + if g.customActionName != "" { + actionName = g.customActionName + } + if g.repository != "" && g.owner != "" { + return action.ActionDefinition{ + Name: action.ActionDefinitionName(actionName), + Description: actionDescription, + Properties: map[string]jsonschema.Definition{ + "path": { + Type: jsonschema.String, + Description: "The path to the file or directory", + }, + }, + Required: []string{"path"}, + } + } + return action.ActionDefinition{ + Name: action.ActionDefinitionName(actionName), + Description: actionDescription, + Properties: map[string]jsonschema.Definition{ + "path": { + Type: jsonschema.String, + Description: "The path to the file or directory", + }, + "repository": { + Type: jsonschema.String, + Description: "The repository to search in", + }, + "owner": { + Type: jsonschema.String, + Description: "The owner of the repository", + }, + }, + Required: []string{"path", "repository", "owner"}, + } +} diff --git a/services/connectors/githubissue.go b/services/connectors/githubissue.go index 017cf8d..bd6506e 100644 --- a/services/connectors/githubissue.go +++ b/services/connectors/githubissue.go @@ -5,7 +5,7 @@ import ( "strings" "time" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v69/github" "github.com/mudler/LocalAgent/core/agent" "github.com/mudler/LocalAgent/pkg/xlog" diff --git a/services/connectors/githubpr.go b/services/connectors/githubpr.go index 1c151e1..3114e01 100644 --- a/services/connectors/githubpr.go +++ b/services/connectors/githubpr.go @@ -5,7 +5,7 @@ import ( "strings" "time" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v69/github" "github.com/mudler/LocalAgent/core/agent" "github.com/mudler/LocalAgent/pkg/xlog"