Skip to content

Commit b990506

Browse files
committed
Merged into main base
1 parent 2a13395 commit b990506

File tree

16 files changed

+1038
-27
lines changed

16 files changed

+1038
-27
lines changed

add_config_option.md

Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
# Adding a New Config Option to the Experiments System in Roo-Code
2+
3+
This guide outlines the process for adding a new config option to the experiments system in Roo-Code.
4+
5+
## Steps
6+
7+
1. Add the experiment ID to `src/shared/experiments.ts`
8+
2. Add the schema definition in `src/schemas/index.ts`
9+
3. Add default configuration in `src/shared/experiments.ts`
10+
4. Add translations in language files under `webview-ui/src/i18n/locales/`
11+
5. Use the experiment in the code
12+
13+
## Example: Adding the API Logging Experiment
14+
15+
### 1. Add Experiment ID
16+
17+
In `src/shared/experiments.ts`:
18+
19+
```typescript
20+
export const EXPERIMENT_IDS = {
21+
DIFF_STRATEGY_UNIFIED: "experimentalDiffStrategy",
22+
INSERT_BLOCK: "insert_content",
23+
SEARCH_AND_REPLACE: "search_and_replace",
24+
POWER_STEERING: "powerSteering",
25+
API_LOGGING: "apiLogging", // Added new experiment
26+
} as const satisfies Record<string, ExperimentId>
27+
28+
export const experimentConfigsMap: Record<ExperimentKey, ExperimentConfig> = {
29+
DIFF_STRATEGY_UNIFIED: { enabled: false },
30+
INSERT_BLOCK: { enabled: false },
31+
SEARCH_AND_REPLACE: { enabled: false },
32+
POWER_STEERING: { enabled: false },
33+
API_LOGGING: { enabled: false }, // Added default configuration
34+
}
35+
```
36+
37+
### 2. Add Schema Definition
38+
39+
In `src/schemas/index.ts`:
40+
41+
```typescript
42+
export const experimentIds = [
43+
"search_and_replace",
44+
"experimentalDiffStrategy",
45+
"insert_content",
46+
"powerSteering",
47+
"apiLogging", // Added new experiment ID
48+
] as const
49+
50+
const experimentsSchema = z.object({
51+
search_and_replace: z.boolean(),
52+
experimentalDiffStrategy: z.boolean(),
53+
insert_content: z.boolean(),
54+
powerSteering: z.boolean(),
55+
apiLogging: z.boolean(), // Added schema definition
56+
})
57+
```
58+
59+
### 3. Add Translations
60+
61+
Create a new file `webview-ui/src/i18n/locales/en/experimental.json`:
62+
63+
```json
64+
{
65+
"API_LOGGING": {
66+
"name": "API Logging",
67+
"description": "Enable detailed logging of API requests and responses for debugging purposes."
68+
}
69+
}
70+
```
71+
72+
### 4. Update Tests
73+
74+
In `src/shared/__tests__/experiments.test.ts`:
75+
76+
```typescript
77+
describe("isEnabled", () => {
78+
it("returns false when experiment is not enabled", () => {
79+
const experiments: Record<ExperimentId, boolean> = {
80+
powerSteering: false,
81+
experimentalDiffStrategy: false,
82+
search_and_replace: false,
83+
insert_content: false,
84+
apiLogging: false, // Added new experiment
85+
}
86+
expect(Experiments.isEnabled(experiments, EXPERIMENT_IDS.POWER_STEERING)).toBe(false)
87+
})
88+
// ... other test cases
89+
})
90+
```
91+
92+
### 5. Using the Experiment
93+
94+
In your code, you can check if the experiment is enabled:
95+
96+
```typescript
97+
const experiments = context.globalState.get<Record<ExperimentId, boolean>>("experiments") ?? experimentDefault
98+
const apiLoggingEnabled = experiments[EXPERIMENT_IDS.API_LOGGING] ?? false
99+
```
100+
101+
## Best Practices
102+
103+
1. Use consistent naming across all files (e.g., `apiLogging` instead of `api_logging`)
104+
2. Add the experiment to all test cases to ensure type safety
105+
3. Use the `experimentDefault` object as a fallback when getting experiment values
106+
4. Add descriptive translations for the experiment name and description
107+
5. Document any breaking changes or dependencies
108+
109+
## Common Issues
110+
111+
1. Type mismatches between schema and API interface
112+
2. Missing experiment in test cases
113+
3. Inconsistent naming across files
114+
4. Missing translations
115+
116+
## Testing
117+
118+
After adding a new experiment:
119+
120+
1. Run `npm run build` to check for type errors
121+
2. Run tests to ensure all test cases pass
122+
3. Test the experiment in the UI to verify it can be enabled/disabled
123+
4. Verify the experiment's functionality works as expected
124+
125+
## Overview
126+
127+
The experiments system is a type-safe feature flag system that allows for:
128+
129+
- Gradual feature rollouts
130+
- A/B testing
131+
- Feature toggling
132+
- Internationalization support
133+
- Type-safe experiment management
134+
- Default values for experiments
135+
136+
## Steps to Add a New Config Option
137+
138+
1. **Add the Experiment ID**
139+
140+
In `src/shared/experiments.ts`, add your new experiment ID to the `EXPERIMENT_IDS` object:
141+
142+
```typescript
143+
export const EXPERIMENT_IDS = {
144+
// ... existing experiments
145+
YOUR_NEW_EXPERIMENT: "your_new_experiment_id",
146+
} as const
147+
```
148+
149+
2. **Add the Schema Definition**
150+
151+
In `src/schemas/index.ts`, add your experiment ID to the `experimentIds` array:
152+
153+
```typescript
154+
export const experimentIds = [
155+
// ... existing experiment IDs
156+
"your_new_experiment_id",
157+
] as const
158+
```
159+
160+
3. **Add Default Configuration**
161+
162+
In `src/shared/experiments.ts`, add your experiment to the `experimentConfigsMap`:
163+
164+
```typescript
165+
export const experimentConfigsMap: Record<ExperimentKey, ExperimentConfig> = {
166+
// ... existing experiments
167+
YOUR_NEW_EXPERIMENT: { enabled: false },
168+
}
169+
```
170+
171+
4. **Add Translations**
172+
173+
Add translations for your experiment in all language files under `webview-ui/src/i18n/locales/`:
174+
175+
```json
176+
"experimental": {
177+
"YOUR_NEW_EXPERIMENT": {
178+
"name": "Use experimental feature name",
179+
"description": "Description of what this experimental feature does..."
180+
}
181+
}
182+
```
183+
184+
5. **Using the Experiment**
185+
186+
To check if your experiment is enabled in the code:
187+
188+
```typescript
189+
import { EXPERIMENT_IDS, experiments } from "../shared/experiments"
190+
191+
if (experiments.isEnabled(experimentsConfig, EXPERIMENT_IDS.YOUR_NEW_EXPERIMENT)) {
192+
// Your experimental feature code here
193+
}
194+
```
195+
196+
## Example
197+
198+
Here's a complete example of adding a new experiment called "Smart Code Completion":
199+
200+
1. Add to `EXPERIMENT_IDS`:
201+
202+
```typescript
203+
export const EXPERIMENT_IDS = {
204+
// ... existing experiments
205+
SMART_COMPLETION: "smart_code_completion",
206+
}
207+
```
208+
209+
2. Add to `experimentIds`:
210+
211+
```typescript
212+
export const experimentIds = [
213+
// ... existing IDs
214+
"smart_code_completion",
215+
]
216+
```
217+
218+
3. Add to `experimentConfigsMap`:
219+
220+
```typescript
221+
export const experimentConfigsMap = {
222+
// ... existing configs
223+
SMART_COMPLETION: { enabled: false },
224+
}
225+
```
226+
227+
4. Add translations (example in English):
228+
229+
```json
230+
"experimental": {
231+
"SMART_COMPLETION": {
232+
"name": "Use smart code completion",
233+
"description": "Enable AI-powered code completion that understands context and provides more relevant suggestions."
234+
}
235+
}
236+
```
237+
238+
5. Use in code:
239+
```typescript
240+
if (experiments.isEnabled(experimentsConfig, EXPERIMENT_IDS.SMART_COMPLETION)) {
241+
// Implement smart completion logic
242+
}
243+
```
244+
245+
## Best Practices
246+
247+
1. Use descriptive names for your experiment IDs
248+
2. Provide clear, user-friendly descriptions in translations
249+
3. Set appropriate default values (usually `false` for new experiments)
250+
4. Add tests for your experiment's functionality
251+
5. Document any special considerations or risks in the experiment description
252+
6. Consider adding a warning emoji (⚠️) in the UI for experimental features
253+
254+
## Testing
255+
256+
After adding a new experiment, you should:
257+
258+
1. Test the experiment toggle in the UI
259+
2. Verify the experiment state is correctly persisted
260+
3. Test the feature with both enabled and disabled states
261+
4. Verify translations appear correctly in all supported languages
262+
5. Add unit tests for the experiment's functionality
263+
264+
## Recent Example: API Logging Experiment
265+
266+
Here's a real example of adding the API Logging experiment:
267+
268+
1. Added to `EXPERIMENT_IDS` in `src/shared/experiments.ts`:
269+
270+
```typescript
271+
export const EXPERIMENT_IDS = {
272+
// ... existing experiments
273+
API_LOGGING: "api_logging",
274+
} as const
275+
```
276+
277+
2. Added to `experimentIds` in `src/schemas/index.ts`:
278+
279+
```typescript
280+
export const experimentIds = [
281+
// ... existing IDs
282+
"api_logging",
283+
] as const
284+
```
285+
286+
3. Added to `experimentConfigsMap` in `src/shared/experiments.ts`:
287+
288+
```typescript
289+
export const experimentConfigsMap: Record<ExperimentKey, ExperimentConfig> = {
290+
// ... existing experiments
291+
API_LOGGING: { enabled: false },
292+
}
293+
```
294+
295+
4. Added to `experimentsSchema` in `src/schemas/index.ts`:
296+
297+
```typescript
298+
const experimentsSchema = z.object({
299+
// ... existing experiments
300+
api_logging: z.boolean(),
301+
})
302+
```
303+
304+
5. Added translations in `webview-ui/src/i18n/locales/en/experimental.json`:
305+
306+
```json
307+
{
308+
"API_LOGGING": {
309+
"name": "API Logging",
310+
"description": "Enable detailed logging of API requests and responses for debugging purposes."
311+
}
312+
}
313+
```
314+
315+
6. Usage in code:
316+
```typescript
317+
if (experiments.isEnabled(experimentsConfig, EXPERIMENT_IDS.API_LOGGING)) {
318+
// API logging code here
319+
}
320+
```

0 commit comments

Comments
 (0)