Skip to content

Commit cece1aa

Browse files
author
Serge H.
committed
context mgt
1 parent 4798d21 commit cece1aa

File tree

6 files changed

+194
-3
lines changed

6 files changed

+194
-3
lines changed

docs/roo-code-plus/configuration.md

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,47 @@ The following settings have been added to support the LiteLLM provider. They are
3333

3434
* The `apiProvider` setting should be set to `"litellm"` to activate this provider.
3535
* LiteLLM settings follow the same pattern as other providers, ensuring consistency.
36-
* Existing configurations without LiteLLM settings remain valid and functional.
36+
* Existing configurations without LiteLLM settings remain valid and functional.
37+
38+
## OpenAI Compatible Provider Settings
39+
40+
The following settings are relevant when `apiProvider` is set to `"openai"`.
41+
42+
* **`rooCode.apiConfiguration.openAiBaseUrl`** (`string`, optional):
43+
* The base URL of the OpenAI-compatible API endpoint.
44+
* Required. Example: `"https://api.mistral.ai/v1"`
45+
46+
* **`rooCode.apiConfiguration.openAiApiKey`** (`string`, optional):
47+
* The API key for the endpoint.
48+
* Stored securely in VS Code's SecretStorage.
49+
50+
* **`rooCode.apiConfiguration.openAiModelId`** (`string`, optional):
51+
* The specific model ID to use with the endpoint.
52+
* Example: `"mistral-large-latest"`, `"gpt-4o"`
53+
54+
* **`rooCode.apiConfiguration.openAiContextWindowOverride`** (`number`, optional):
55+
* Allows overriding the default context window size (128k tokens) assumed for compatible endpoints.
56+
* Set via a slider in the UI (Default, 8k, 32k, 128k, 512k, 1M, 2M tokens).
57+
* If set, this value is used for determining when to truncate conversation history. If unset (`undefined`), the default 128k is used.
58+
59+
* **`rooCode.apiConfiguration.openAiCustomModelInfo`** (`object`, optional):
60+
* Allows overriding other `ModelInfo` properties like `maxTokens`, `supportsImages`, pricing, etc., for the specified `openAiModelId`.
61+
* The `openAiContextWindowOverride` takes precedence over the `contextWindow` value within `openAiCustomModelInfo` if both are set.
62+
63+
* **`rooCode.apiConfiguration.openAiUseAzure`** (`boolean`, optional):
64+
* Set to `true` if connecting to an Azure OpenAI endpoint.
65+
66+
* **`rooCode.apiConfiguration.azureApiVersion`** (`string`, optional):
67+
* Specifies the API version for Azure OpenAI endpoints.
68+
69+
* **`rooCode.apiConfiguration.openAiHostHeader`** (`string`, optional):
70+
* Allows setting a custom `Host` HTTP header, sometimes required by proxy services.
71+
72+
* **`rooCode.apiConfiguration.openAiLegacyFormat`** (`boolean`, optional):
73+
* Set to `true` if the endpoint requires the older OpenAI message format (less common).
74+
75+
* **`rooCode.apiConfiguration.openAiR1FormatEnabled`** (`boolean`, optional):
76+
* Set to `true` for models requiring specific R1 formatting (e.g., DeepSeek Reasoner).
77+
78+
* **`rooCode.apiConfiguration.openAiStreamingEnabled`** (`boolean`, optional):
79+
* Defaults to `true`. Set to `false` if the endpoint does not support streaming responses.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# OpenAI Compatible Context Window Override Plan
2+
3+
## Objective
4+
5+
Allow users to configure the context window size for the "OpenAI Compatible" LLM provider type via the settings UI, overriding the default 128k limit.
6+
7+
## Implementation Strategy
8+
9+
Use a fixed-step slider UI element in the provider settings.
10+
11+
## Plan Steps
12+
13+
1. **Schema Modification (`src/schemas/index.ts`):**
14+
* Add an optional property `openAiContextWindowOverride?: number;` to the relevant settings interface (likely `ProviderSettings` or a derived type). This field will store the user-selected token value (e.g., 8192, 32768) or `undefined` if the default is chosen.
15+
16+
2. **Backend Provider Logic Update (`src/api/providers/openai.ts`):**
17+
* Modify the `OpenAiHandler.getModel()` method.
18+
* Retrieve the base `ModelInfo` (from `openAiCustomModelInfo` or `openAiModelInfoSaneDefaults`).
19+
* If `this.options.openAiContextWindowOverride` is defined and valid, create a new `ModelInfo` object by copying the base info and setting `contextWindow` to the override value.
20+
* Return the potentially modified `ModelInfo`.
21+
22+
3. **UI Settings Update (Likely `webview-ui/src/components/Settings/ProviderSettings/OpenAISettings.tsx`):**
23+
* Add a `Slider` component with 7 discrete steps (0 to 6).
24+
* Map slider steps to token override values:
25+
* `0`: Default (sets override to `undefined`, effectively 128k)
26+
* `1`: 8k (sets override to `8192`)
27+
* `2`: 32k (sets override to `32768`)
28+
* `3`: 128k (sets override to `131072`)
29+
* `4`: 512k (sets override to `524288`)
30+
* `5`: 1M (sets override to `1048576`)
31+
* `6`: 2M (sets override to `2097152`)
32+
* Bind the slider's value to the `openAiContextWindowOverride` setting (mapping back and forth between the 0-6 scale and the token/undefined values).
33+
* Add a "Context Window Override" label.
34+
* Add a dynamic text display showing the selected token value (e.g., "Selected: 32k tokens", "Selected: Default (128k)").
35+
* Position this control after the model selection element.
36+
37+
4. **UI Chat Display Verification (Likely `webview-ui/src/components/Chat/ContextWindowProgress.tsx`):**
38+
* Ensure the component displaying the context size during chat correctly uses the `contextWindow` property from the `ModelInfo` object provided by the backend. No changes are expected if it already does this.
39+
40+
5. **Core Logic Verification (e.g., `src/core/sliding-window/index.ts`):**
41+
* Confirm that components like the sliding window manager consume the `contextWindow` value from the provider's `getModel().info` result. The override should propagate automatically.
42+
43+
6. **Internationalization (i18n):**
44+
* Add new keys to `webview-ui/src/i18n/locales/en/settings.json` for the label ("Context Window Override") and the dynamic display text.
45+
* Add placeholders or translations to other locale files as needed.
46+
47+
## Context Limit Usage
48+
49+
* **Verification Result:** Analysis of `src/core/sliding-window/index.ts` confirmed that the `contextWindow` value (including the override) is actively used by the `truncateConversationIfNeeded` function to determine when conversation history should be truncated before sending it to the API. It does not block requests but shortens the history based on the limit and buffer settings.
50+
51+
## Target Files
52+
53+
* `src/schemas/index.ts`
54+
* `src/api/providers/openai.ts`
55+
* `webview-ui/src/components/Settings/ProviderSettings/OpenAISettings.tsx` (or similar)
56+
* `webview-ui/src/components/Chat/ContextWindowProgress.tsx` (for verification)
57+
* `webview-ui/src/i18n/locales/en/settings.json`
58+
* `webview-ui/src/i18n/locales/*/settings.json` (as needed)

src/api/providers/openai.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,24 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
232232
}
233233

234234
override getModel(): { id: string; info: ModelInfo } {
235+
// Get the base model info (custom or default)
236+
const baseInfo = this.options.openAiCustomModelInfo ?? openAiModelInfoSaneDefaults
237+
238+
// Check for a valid override value
239+
const overrideValue = this.options.openAiContextWindowOverride
240+
let effectiveInfo = baseInfo
241+
242+
if (typeof overrideValue === "number" && overrideValue > 0) {
243+
// Apply the override by creating a new object
244+
effectiveInfo = {
245+
...baseInfo,
246+
contextWindow: overrideValue,
247+
}
248+
}
249+
235250
return {
236251
id: this.options.openAiModelId ?? "",
237-
info: this.options.openAiCustomModelInfo ?? openAiModelInfoSaneDefaults,
252+
info: effectiveInfo, // Return the potentially overridden info
238253
}
239254
}
240255

src/schemas/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ export const providerSettingsSchema = z.object({
347347
openAiUseAzure: z.boolean().optional(),
348348
azureApiVersion: z.string().optional(),
349349
openAiStreamingEnabled: z.boolean().optional(),
350+
openAiContextWindowOverride: z.number().optional(),
350351
// Ollama
351352
ollamaModelId: z.string().optional(),
352353
ollamaBaseUrl: z.string().optional(),

webview-ui/src/components/settings/ApiOptions.tsx

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,17 @@ import {
4646
useOpenRouterModelProviders,
4747
OPENROUTER_DEFAULT_PROVIDER_NAME,
4848
} from "@/components/ui/hooks/useOpenRouterModelProviders"
49-
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SelectSeparator, Button } from "@/components/ui"
49+
import {
50+
Select,
51+
SelectContent,
52+
SelectItem,
53+
SelectTrigger,
54+
SelectValue,
55+
SelectSeparator,
56+
Button,
57+
Slider,
58+
Label,
59+
} from "@/components/ui"
5060
import { MODELS_BY_PROVIDER, PROVIDERS, VERTEX_REGIONS } from "./constants"
5161
import { AWS_REGIONS } from "../../../../src/shared/aws_regions"
5262
import { VSCodeButtonLink } from "../common/VSCodeButtonLink"
@@ -282,6 +292,37 @@ const ApiOptions = ({
282292
}
283293
}
284294

295+
// --- START: Helper functions and data for Context Window Slider ---
296+
const contextWindowSteps = [
297+
{ sliderValue: 0, overrideValue: undefined, label: t("settings:providers.contextWindow.default", { value: "128k" }) },
298+
{ sliderValue: 1, overrideValue: 8192, label: "8k" },
299+
{ sliderValue: 2, overrideValue: 32768, label: "32k" },
300+
{ sliderValue: 3, overrideValue: 131072, label: "128k" },
301+
{ sliderValue: 4, overrideValue: 524288, label: "512k" },
302+
{ sliderValue: 5, overrideValue: 1048576, label: "1M" },
303+
{ sliderValue: 6, overrideValue: 2097152, label: "2M" },
304+
]
305+
306+
const mapOverrideToSliderValue = (override?: number): number => {
307+
const step = contextWindowSteps.find((s) => s.overrideValue === override)
308+
return step ? step.sliderValue : 0 // Default to step 0 if override is undefined or not found
309+
}
310+
311+
const mapSliderValueToOverride = (sliderValue: number): number | undefined => {
312+
const step = contextWindowSteps.find((s) => s.sliderValue === sliderValue)
313+
return step ? step.overrideValue : undefined
314+
}
315+
316+
const mapSliderValueToLabel = (sliderValue: number): string => {
317+
const step = contextWindowSteps.find((s) => s.sliderValue === sliderValue)
318+
return step ? step.label : "Unknown"
319+
}
320+
321+
const currentSliderValue = mapOverrideToSliderValue(apiConfiguration?.openAiContextWindowOverride)
322+
const currentSliderLabel = mapSliderValueToLabel(currentSliderValue)
323+
// --- END: Helper functions and data for Context Window Slider ---
324+
325+
285326
return (
286327
<div className="flex flex-col gap-3">
287328
<div className="flex flex-col gap-1 relative">
@@ -782,6 +823,33 @@ const ApiOptions = ({
782823
serviceName="OpenAI"
783824
serviceUrl="https://platform.openai.com"
784825
/>
826+
{/* START: OpenAI Context Window Override Slider */}
827+
<div className="space-y-2">
828+
<Label htmlFor="context-window-slider">
829+
{t("settings:providers.contextWindow.overrideLabel")}
830+
</Label>
831+
<div className="flex items-center gap-3">
832+
<Slider
833+
id="context-window-slider"
834+
min={0}
835+
max={6}
836+
step={1}
837+
value={[currentSliderValue]}
838+
onValueChange={(value) => {
839+
const newOverride = mapSliderValueToOverride(value[0])
840+
setApiConfigurationField("openAiContextWindowOverride", newOverride)
841+
}}
842+
className="flex-grow"
843+
/>
844+
<span className="text-sm text-vscode-descriptionForeground min-w-[100px] text-right">
845+
{t("settings:providers.contextWindow.selectedValue", { value: currentSliderLabel })}
846+
</span>
847+
</div>
848+
<div className="text-sm text-vscode-descriptionForeground">
849+
{t("settings:providers.contextWindow.description")}
850+
</div>
851+
</div>
852+
{/* END: OpenAI Context Window Override Slider */}
785853
<R1FormatSetting
786854
onChange={handleInputChange("openAiR1FormatEnabled", noTransform)}
787855
openAiR1FormatEnabled={apiConfiguration?.openAiR1FormatEnabled ?? false}

webview-ui/src/i18n/locales/en/settings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@
150150
"googleCloudKeyFile": "Google Cloud Key File Path",
151151
"googleCloudProjectId": "Google Cloud Project ID",
152152
"googleCloudRegion": "Google Cloud Region",
153+
"contextWindow": {
154+
"overrideLabel": "Context Window Override",
155+
"selectedValue": "Selected: {{value}}",
156+
"default": "Default ({{value}})",
157+
"description": "Override the default context window size for this OpenAI compatible endpoint. 'Default' uses 128k tokens."
158+
},
153159
"lmStudio": {
154160
"baseUrl": "Base URL (optional)",
155161
"modelId": "Model ID",

0 commit comments

Comments
 (0)