-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathConfiguration.cs
More file actions
132 lines (101 loc) · 4.78 KB
/
Configuration.cs
File metadata and controls
132 lines (101 loc) · 4.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using RalphController.Models;
namespace RalphController;
/// <summary>
/// Configuration for the Ralph Controller
/// </summary>
public record RalphConfig
{
/// <summary>Target directory where the AI will work</summary>
public required string TargetDirectory { get; init; }
/// <summary>AI provider to use (Claude, Codex, etc.)</summary>
public AIProvider Provider { get; init; } = AIProvider.Claude;
/// <summary>Provider-specific configuration</summary>
public AIProviderConfig ProviderConfig { get; init; } = AIProviderConfig.ForClaude();
/// <summary>Multi-model configuration (rotation, verification)</summary>
public MultiModelConfig? MultiModel { get; init; }
/// <summary>Teams mode configuration</summary>
public TeamConfig? Teams { get; init; }
/// <summary>Path to AI CLI executable (overrides provider default)</summary>
public string? ExecutablePath { get; init; }
/// <summary>Name of the prompt file</summary>
public string PromptFile { get; init; } = "prompt.md";
/// <summary>Name of the implementation plan file</summary>
public string PlanFile { get; init; } = "implementation_plan.md";
/// <summary>Name of the agents file (self-improvement notes)</summary>
public string AgentsFile { get; init; } = "agents.md";
/// <summary>Name of the specs directory</summary>
public string SpecsDirectory { get; init; } = "specs";
/// <summary>Optional folder for Ralph project files (relative to TargetDirectory, or absolute path)</summary>
public string? RalphFolder { get; init; }
/// <summary>Directory where project files (prompt.md, plan, agents, specs) are stored</summary>
public string ProjectFilesDirectory => RalphFolder switch
{
null or "" => TargetDirectory,
_ when Path.IsPathRooted(RalphFolder) => RalphFolder,
_ => Path.Combine(TargetDirectory, RalphFolder)
};
/// <summary>Optional maximum number of iterations (null = unlimited)</summary>
public int? MaxIterations { get; init; }
/// <summary>Cost per hour estimate for tracking</summary>
public double CostPerHour { get; init; } = 10.50;
/// <summary>Delay between iterations in milliseconds</summary>
public int IterationDelayMs { get; init; } = 1000;
/// <summary>Maximum API calls per hour (rate limiting)</summary>
public int MaxCallsPerHour { get; init; } = 100;
/// <summary>Enable circuit breaker to detect stagnation</summary>
public bool EnableCircuitBreaker { get; init; } = true;
/// <summary>Enable response analyzer for completion detection</summary>
public bool EnableResponseAnalyzer { get; init; } = true;
/// <summary>Auto-exit when completion signals detected</summary>
public bool AutoExitOnCompletion { get; init; } = true;
/// <summary>Enable final verification step before completing</summary>
public bool EnableFinalVerification { get; init; } = true;
/// <summary>Maximum time for a single iteration in minutes (default: 30, 0 = no timeout)</summary>
public int IterationTimeoutMinutes { get; init; } = 30;
/// <summary>Full path to prompt file</summary>
public string PromptFilePath => Path.Combine(ProjectFilesDirectory, PromptFile);
/// <summary>Full path to plan file</summary>
public string PlanFilePath => Path.Combine(ProjectFilesDirectory, PlanFile);
/// <summary>Full path to agents file</summary>
public string AgentsFilePath => Path.Combine(ProjectFilesDirectory, AgentsFile);
/// <summary>Full path to specs directory</summary>
public string SpecsDirectoryPath => Path.Combine(ProjectFilesDirectory, SpecsDirectory);
}
/// <summary>
/// Validates and checks project structure
/// </summary>
public static class ProjectValidator
{
/// <summary>
/// Checks the target directory for required Ralph project files
/// </summary>
public static ProjectStructure ValidateProject(RalphConfig config)
{
return new ProjectStructure
{
TargetDirectory = config.TargetDirectory,
HasAgentsMd = File.Exists(config.AgentsFilePath),
HasSpecsDirectory = Directory.Exists(config.SpecsDirectoryPath),
HasPromptMd = File.Exists(config.PromptFilePath),
HasImplementationPlan = File.Exists(config.PlanFilePath)
};
}
/// <summary>
/// Validates the target directory exists
/// </summary>
public static bool ValidateTargetDirectory(string path, out string? error)
{
error = null;
if (string.IsNullOrWhiteSpace(path))
{
error = "Target directory path cannot be empty";
return false;
}
if (!Directory.Exists(path))
{
error = $"Target directory does not exist: {path}";
return false;
}
return true;
}
}