Refactor, add consts
Change-Id: Iabb1738e90d06ec9830a3d9efcf35cfecc2d86ce
diff --git a/server/agent/agent.go b/server/agent/agent.go
index eca7b62..1b27831 100644
--- a/server/agent/agent.go
+++ b/server/agent/agent.go
@@ -135,6 +135,17 @@
return nil
}
+const (
+ // Agent polling intervals
+ TaskPollingInterval = 60 * time.Second
+ ErrorRetryInterval = 30 * time.Second
+ DefaultGitTimeout = 30 * time.Second
+ DefaultContextTimeout = 5 * time.Minute
+ DefaultMaxTaskRetries = 3
+ DefaultLLMMaxTokens = 4000
+ DefaultLLMTemperature = 0.7
+)
+
// Run starts the agent's main loop
func (a *Agent) Run() error {
a.logger.Info("Starting agent", slog.String("name", a.Config.Name), slog.String("role", a.Config.Role))
@@ -153,8 +164,7 @@
default:
if err := a.processNextTask(); err != nil {
a.logger.Error("Error processing task", slog.String("error", err.Error()))
- // Continue running even if there's an error
- time.Sleep(30 * time.Second)
+ time.Sleep(ErrorRetryInterval)
}
}
}
@@ -173,91 +183,122 @@
func (a *Agent) initializeGit() error {
ctx := context.Background()
- // Check if repository exists
+ if err := a.ensureRepository(ctx); err != nil {
+ return err
+ }
+
+ if err := a.ensureRemoteOrigin(ctx); err != nil {
+ return err
+ }
+
+ if err := a.ensureTargetBranch(ctx); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// ensureRepository ensures the git repository is initialized
+func (a *Agent) ensureRepository(ctx context.Context) error {
isRepo, err := a.gitInterface.IsRepository(ctx, a.Config.GitRepoPath)
if err != nil {
return fmt.Errorf("failed to check repository: %w", err)
}
if !isRepo {
- // Initialize new repository
if err := a.gitInterface.Init(ctx, a.Config.GitRepoPath); err != nil {
return fmt.Errorf("failed to initialize repository: %w", err)
}
}
- // Check if remote origin exists, if not add it
+ return nil
+}
+
+// ensureRemoteOrigin ensures the remote origin is configured
+func (a *Agent) ensureRemoteOrigin(ctx context.Context) error {
remotes, err := a.gitInterface.ListRemotes(ctx)
if err != nil {
return fmt.Errorf("failed to list remotes: %w", err)
}
- originExists := false
+ // Check if origin already exists
for _, remote := range remotes {
if remote.Name == "origin" {
- originExists = true
- break
+ return nil
}
}
- if !originExists {
- // Add remote origin - use Gerrit URL if enabled, otherwise use the configured remote
- remoteURL := a.Config.GitRemote
- if a.Config.GerritEnabled {
- // For Gerrit, the remote URL should be the Gerrit SSH or HTTP URL
- // Format: ssh://username@gerrit-host:29418/project-name.git
- // or: https://gerrit-host/project-name.git
- if strings.HasPrefix(a.Config.GerritConfig.BaseURL, "https://") {
- remoteURL = fmt.Sprintf("%s/%s.git", a.Config.GerritConfig.BaseURL, a.Config.GerritConfig.Project)
- } else {
- // Assume SSH format
- remoteURL = fmt.Sprintf("ssh://%s@%s:29418/%s.git",
- a.Config.GerritConfig.Username,
- strings.TrimPrefix(a.Config.GerritConfig.BaseURL, "https://"),
- a.Config.GerritConfig.Project)
- }
- }
-
- if err := a.gitInterface.AddRemote(ctx, "origin", remoteURL); err != nil {
- return fmt.Errorf("failed to add remote origin: %w", err)
- }
- }
-
- // Checkout to the specified branch
- if a.Config.GitBranch != "" {
- // First, check if we're already on the target branch
- currentBranch, err := a.gitInterface.GetCurrentBranch(ctx)
- if err != nil {
- return fmt.Errorf("failed to get current branch: %w", err)
- }
-
- // Only checkout if we're not already on the target branch
- if currentBranch != a.Config.GitBranch {
- if err := a.gitInterface.Checkout(ctx, a.Config.GitBranch); err != nil {
- errMsg := err.Error()
-
- // Only create the branch if the error indicates it doesn't exist
- if strings.Contains(errMsg, "did not match any file(s) known to git") ||
- strings.Contains(errMsg, "not found") ||
- strings.Contains(errMsg, "unknown revision") ||
- strings.Contains(errMsg, "reference is not a tree") ||
- strings.Contains(errMsg, "pathspec") ||
- strings.Contains(errMsg, "fatal: invalid reference") {
- if err := a.gitInterface.CreateBranch(ctx, a.Config.GitBranch, ""); err != nil {
- return fmt.Errorf("failed to create branch %s: %w", a.Config.GitBranch, err)
- }
- } else {
- return fmt.Errorf("failed to checkout branch %s: %w", a.Config.GitBranch, err)
- }
- }
- } else {
- a.logger.Info("Already on target branch", slog.String("branch", a.Config.GitBranch))
- }
+ // Add remote origin
+ remoteURL := a.buildRemoteURL()
+ if err := a.gitInterface.AddRemote(ctx, "origin", remoteURL); err != nil {
+ return fmt.Errorf("failed to add remote origin: %w", err)
}
return nil
}
+// buildRemoteURL builds the appropriate remote URL based on configuration
+func (a *Agent) buildRemoteURL() string {
+ if !a.Config.GerritEnabled {
+ return a.Config.GitRemote
+ }
+
+ // Build Gerrit URL
+ if strings.HasPrefix(a.Config.GerritConfig.BaseURL, "https://") {
+ return fmt.Sprintf("%s/%s.git", a.Config.GerritConfig.BaseURL, a.Config.GerritConfig.Project)
+ }
+
+ // SSH format
+ return fmt.Sprintf("ssh://%s@%s:29418/%s.git",
+ a.Config.GerritConfig.Username,
+ strings.TrimPrefix(a.Config.GerritConfig.BaseURL, "https://"),
+ a.Config.GerritConfig.Project)
+}
+
+// ensureTargetBranch ensures the agent is on the target branch
+func (a *Agent) ensureTargetBranch(ctx context.Context) error {
+ if a.Config.GitBranch == "" {
+ return nil
+ }
+
+ currentBranch, err := a.gitInterface.GetCurrentBranch(ctx)
+ if err != nil {
+ return fmt.Errorf("failed to get current branch: %w", err)
+ }
+
+ if currentBranch == a.Config.GitBranch {
+ a.logger.Info("Already on target branch", slog.String("branch", a.Config.GitBranch))
+ return nil
+ }
+
+ return a.checkoutOrCreateBranch(ctx, a.Config.GitBranch)
+}
+
+// checkoutOrCreateBranch attempts to checkout a branch, creating it if it doesn't exist
+func (a *Agent) checkoutOrCreateBranch(ctx context.Context, branchName string) error {
+ if err := a.gitInterface.Checkout(ctx, branchName); err != nil {
+ if a.isBranchNotFoundError(err) {
+ if createErr := a.gitInterface.CreateBranch(ctx, branchName, ""); createErr != nil {
+ return fmt.Errorf("failed to create branch %s: %w", branchName, createErr)
+ }
+ return nil
+ }
+ return fmt.Errorf("failed to checkout branch %s: %w", branchName, err)
+ }
+ return nil
+}
+
+// isBranchNotFoundError checks if the error indicates a branch doesn't exist
+func (a *Agent) isBranchNotFoundError(err error) bool {
+ errMsg := err.Error()
+ return strings.Contains(errMsg, "did not match any file(s) known to git") ||
+ strings.Contains(errMsg, "not found") ||
+ strings.Contains(errMsg, "unknown revision") ||
+ strings.Contains(errMsg, "reference is not a tree") ||
+ strings.Contains(errMsg, "pathspec") ||
+ strings.Contains(errMsg, "fatal: invalid reference")
+}
+
// processNextTask processes the next available task
func (a *Agent) processNextTask() error {
ctx := context.Background()
@@ -282,7 +323,7 @@
if taskToProcess == nil {
// No tasks to process, wait a bit
- time.Sleep(60 * time.Second)
+ time.Sleep(TaskPollingInterval)
return nil
}
@@ -336,8 +377,8 @@
Content: prompt,
},
},
- MaxTokens: intPtr(4000),
- Temperature: float64Ptr(0.7),
+ MaxTokens: intPtr(DefaultLLMMaxTokens),
+ Temperature: float64Ptr(DefaultLLMTemperature),
}
// Get response from LLM