Skip to content

Commit c355da0

Browse files
committed
feat: Feature flags
1 parent ee86a41 commit c355da0

File tree

3 files changed

+495
-0
lines changed

3 files changed

+495
-0
lines changed

internal/features/flags.go

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
package features
2+
3+
import "sync"
4+
5+
// FeatureFlags manages runtime feature flags for tools and capabilities.
6+
// This structure is NOT persisted to disk - it's in-memory only.
7+
// Each tool has its own boolean flag with a default value of true (enabled).
8+
type FeatureFlags struct {
9+
mu sync.RWMutex
10+
11+
// Planning mode
12+
PlanningEnabled bool
13+
14+
// Tool flags - all default to true (enabled)
15+
ReadFile bool
16+
ReadFileSummarized bool
17+
CreateFile bool
18+
WriteFileDiff bool
19+
WriteFileReplace bool
20+
WriteFileJSON bool
21+
Shell bool
22+
StatusProgram bool
23+
WaitProgram bool
24+
StopProgram bool
25+
Parallel bool
26+
GoSandbox bool
27+
WebSearch bool
28+
ToolSummarize bool
29+
Todo bool
30+
SearchFiles bool
31+
SearchFileContent bool
32+
CodebaseInvestigator bool
33+
SearchContextFiles bool
34+
GrepContextFiles bool
35+
ReadContextFile bool
36+
}
37+
38+
// NewFeatureFlags creates a new FeatureFlags instance with default values (all enabled)
39+
func NewFeatureFlags() *FeatureFlags {
40+
return &FeatureFlags{
41+
PlanningEnabled: true,
42+
ReadFile: true,
43+
ReadFileSummarized: true,
44+
CreateFile: true,
45+
WriteFileDiff: true,
46+
WriteFileReplace: true,
47+
WriteFileJSON: true,
48+
Shell: true,
49+
StatusProgram: true,
50+
WaitProgram: true,
51+
StopProgram: true,
52+
Parallel: true,
53+
GoSandbox: true,
54+
WebSearch: true,
55+
ToolSummarize: true,
56+
Todo: true,
57+
SearchFiles: true,
58+
SearchFileContent: true,
59+
CodebaseInvestigator: true,
60+
SearchContextFiles: true,
61+
GrepContextFiles: true,
62+
ReadContextFile: true,
63+
}
64+
}
65+
66+
// IsToolEnabled checks if a tool is enabled
67+
func (f *FeatureFlags) IsToolEnabled(toolName string) bool {
68+
f.mu.RLock()
69+
defer f.mu.RUnlock()
70+
71+
switch toolName {
72+
case "read_file":
73+
return f.ReadFile
74+
case "read_file_summarized":
75+
return f.ReadFileSummarized
76+
case "create_file":
77+
return f.CreateFile
78+
case "write_file_diff":
79+
return f.WriteFileDiff
80+
case "write_file_replace":
81+
return f.WriteFileReplace
82+
case "write_file_json":
83+
return f.WriteFileJSON
84+
case "shell":
85+
return f.Shell
86+
case "status_program":
87+
return f.StatusProgram
88+
case "wait_program":
89+
return f.WaitProgram
90+
case "stop_program":
91+
return f.StopProgram
92+
case "parallel_tool_execution":
93+
return f.Parallel
94+
case "go_sandbox":
95+
return f.GoSandbox
96+
case "web_search":
97+
return f.WebSearch
98+
case "tool_summarize":
99+
return f.ToolSummarize
100+
case "todo":
101+
return f.Todo
102+
case "search_files":
103+
return f.SearchFiles
104+
case "search_file_content":
105+
return f.SearchFileContent
106+
case "codebase_investigator":
107+
return f.CodebaseInvestigator
108+
case "search_context_files":
109+
return f.SearchContextFiles
110+
case "grep_context_files":
111+
return f.GrepContextFiles
112+
case "read_context_file":
113+
return f.ReadContextFile
114+
default:
115+
// Unknown tools default to enabled
116+
return true
117+
}
118+
}
119+
120+
// EnableTool enables a specific tool
121+
func (f *FeatureFlags) EnableTool(toolName string) {
122+
f.mu.Lock()
123+
defer f.mu.Unlock()
124+
f.setToolFlag(toolName, true)
125+
}
126+
127+
// DisableTool disables a specific tool
128+
func (f *FeatureFlags) DisableTool(toolName string) {
129+
f.mu.Lock()
130+
defer f.mu.Unlock()
131+
f.setToolFlag(toolName, false)
132+
}
133+
134+
// IsPlanningEnabled checks if planning mode is enabled
135+
func (f *FeatureFlags) IsPlanningEnabled() bool {
136+
f.mu.RLock()
137+
defer f.mu.RUnlock()
138+
return f.PlanningEnabled
139+
}
140+
141+
// SetPlanningEnabled enables or disables planning mode
142+
func (f *FeatureFlags) SetPlanningEnabled(enabled bool) {
143+
f.mu.Lock()
144+
defer f.mu.Unlock()
145+
f.PlanningEnabled = enabled
146+
}
147+
148+
// EnableAllTools sets all tools to enabled
149+
func (f *FeatureFlags) EnableAllTools() {
150+
f.mu.Lock()
151+
defer f.mu.Unlock()
152+
153+
f.ReadFile = true
154+
f.ReadFileSummarized = true
155+
f.CreateFile = true
156+
f.WriteFileDiff = true
157+
f.WriteFileReplace = true
158+
f.WriteFileJSON = true
159+
f.Shell = true
160+
f.StatusProgram = true
161+
f.WaitProgram = true
162+
f.StopProgram = true
163+
f.Parallel = true
164+
f.GoSandbox = true
165+
f.WebSearch = true
166+
f.ToolSummarize = true
167+
f.Todo = true
168+
f.SearchFiles = true
169+
f.SearchFileContent = true
170+
f.CodebaseInvestigator = true
171+
f.SearchContextFiles = true
172+
f.GrepContextFiles = true
173+
f.ReadContextFile = true
174+
}
175+
176+
// setToolFlag sets the tool's flag (must be called with lock held)
177+
func (f *FeatureFlags) setToolFlag(toolName string, enabled bool) {
178+
switch toolName {
179+
case "read_file":
180+
f.ReadFile = enabled
181+
case "read_file_summarized":
182+
f.ReadFileSummarized = enabled
183+
case "create_file":
184+
f.CreateFile = enabled
185+
case "write_file_diff":
186+
f.WriteFileDiff = enabled
187+
case "write_file_replace":
188+
f.WriteFileReplace = enabled
189+
case "write_file_json":
190+
f.WriteFileJSON = enabled
191+
case "shell":
192+
f.Shell = enabled
193+
case "status_program":
194+
f.StatusProgram = enabled
195+
case "wait_program":
196+
f.WaitProgram = enabled
197+
case "stop_program":
198+
f.StopProgram = enabled
199+
case "parallel_tool_execution":
200+
f.Parallel = enabled
201+
case "go_sandbox":
202+
f.GoSandbox = enabled
203+
case "web_search":
204+
f.WebSearch = enabled
205+
case "tool_summarize":
206+
f.ToolSummarize = enabled
207+
case "todo":
208+
f.Todo = enabled
209+
case "search_files":
210+
f.SearchFiles = enabled
211+
case "search_file_content":
212+
f.SearchFileContent = enabled
213+
case "codebase_investigator":
214+
f.CodebaseInvestigator = enabled
215+
case "search_context_files":
216+
f.SearchContextFiles = enabled
217+
case "grep_context_files":
218+
f.GrepContextFiles = enabled
219+
case "read_context_file":
220+
f.ReadContextFile = enabled
221+
}
222+
// Unknown tools are ignored
223+
}

0 commit comments

Comments
 (0)