Skip to content

Commit 0322139

Browse files
author
Ben Jones
committed
Enhancements to autocomplete to allow for modification of debounce delay and model timeout in configuration GUI, fix to debounce delay handling
1 parent f830ffb commit 0322139

File tree

7 files changed

+98
-35
lines changed

7 files changed

+98
-35
lines changed

core/autocomplete/filtering/streamTransforms/StreamTransformPipeline.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { streamLines } from "../../../diff/util";
2-
import { PosthogFeatureFlag, Telemetry } from "../../../util/posthog";
32
import { HelperVars } from "../../util/HelperVars";
43

54
import { stopAtStartOf, stopAtStopTokens } from "./charStream";
@@ -73,10 +72,7 @@ export class StreamTransformPipeline {
7372
fullStop,
7473
);
7574

76-
const timeoutValue = await Telemetry.getValueForFeatureFlag(
77-
PosthogFeatureFlag.AutocompleteTimeout,
78-
);
79-
75+
const timeoutValue = helper.options.modelTimeout;
8076
lineGenerator = showWhateverWeHaveAtXMs(lineGenerator, timeoutValue!);
8177

8278
const finalGenerator = streamWithNewLines(lineGenerator);
Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
11
import { v4 as uuidv4 } from "uuid";
2+
23
export class AutocompleteDebouncer {
34
private debounceTimeout: NodeJS.Timeout | undefined = undefined;
4-
private debouncing = false;
5-
private lastUUID: string | undefined = undefined;
5+
private currentRequestId: string | undefined = undefined;
66

77
async delayAndShouldDebounce(debounceDelay: number): Promise<boolean> {
8-
// Debounce
9-
const uuid = uuidv4();
10-
this.lastUUID = uuid;
11-
12-
// Debounce
13-
if (this.debouncing) {
14-
this.debounceTimeout?.refresh();
15-
const lastUUID = await new Promise((resolve) =>
16-
setTimeout(() => {
17-
resolve(this.lastUUID);
18-
}, debounceDelay),
19-
);
20-
if (uuid !== lastUUID) {
21-
return true;
22-
}
23-
} else {
24-
this.debouncing = true;
25-
this.debounceTimeout = setTimeout(async () => {
26-
this.debouncing = false;
27-
}, debounceDelay);
8+
// Generate a unique ID for this request
9+
const requestId = uuidv4();
10+
this.currentRequestId = requestId;
11+
12+
// Clear any existing timeout
13+
if (this.debounceTimeout) {
14+
clearTimeout(this.debounceTimeout);
2815
}
29-
30-
return false;
16+
17+
// Create a new promise that resolves after the debounce delay
18+
return new Promise<boolean>((resolve) => {
19+
this.debounceTimeout = setTimeout(() => {
20+
// When the timeout completes, check if this is still the most recent request
21+
const shouldDebounce = this.currentRequestId !== requestId;
22+
23+
// If this is the most recent request, it shouldn't be debounced
24+
if (!shouldDebounce) {
25+
this.currentRequestId = undefined;
26+
}
27+
28+
resolve(shouldDebounce);
29+
}, debounceDelay);
30+
});
3131
}
3232
}

core/config/sharedConfig.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ export const sharedConfigSchema = z
3131
useAutocompleteCache: z.boolean(),
3232
useAutocompleteMultilineCompletions: z.enum(["always", "never", "auto"]),
3333
disableAutocompleteInFiles: z.array(z.string()),
34+
modelTimeout: z.number(),
35+
debounceDelay: z.number(),
3436
})
3537
.partial();
3638

@@ -103,6 +105,14 @@ export function modifyAnyConfigWithSharedConfig<
103105
configCopy.tabAutocompleteOptions.disableInFiles =
104106
sharedConfig.disableAutocompleteInFiles;
105107
}
108+
if (sharedConfig.modelTimeout !== undefined) {
109+
configCopy.tabAutocompleteOptions.modelTimeout =
110+
sharedConfig.modelTimeout;
111+
}
112+
if (sharedConfig.debounceDelay !== undefined) {
113+
configCopy.tabAutocompleteOptions.debounceDelay =
114+
sharedConfig.debounceDelay;
115+
}
106116

107117
configCopy.ui = {
108118
...configCopy.ui,

core/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,7 @@ export interface TabAutocompleteOptions {
983983
disable: boolean;
984984
maxPromptTokens: number;
985985
debounceDelay: number;
986+
modelTimeout: number;
986987
maxSuffixPercentage: number;
987988
prefixPercentage: number;
988989
transform?: boolean;

core/util/parameters.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const DEFAULT_AUTOCOMPLETE_OPTS: TabAutocompleteOptions = {
66
prefixPercentage: 0.3,
77
maxSuffixPercentage: 0.2,
88
debounceDelay: 350,
9+
modelTimeout: 150,
910
multilineCompletions: "auto",
1011
// @deprecated TO BE REMOVED
1112
slidingWindowPrefixPercentage: 0.75,

gui/src/components/gui/NumberInput.tsx

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { useState } from "react";
22

33
interface NumberInputProps {
44
value: number;
@@ -13,24 +13,50 @@ const NumberInput: React.FC<NumberInputProps> = ({
1313
max,
1414
min,
1515
}) => {
16+
const [inputValue, setInputValue] = useState(value.toString());
17+
1618
const handleIncrement = () => {
1719
if (value < max) {
18-
onChange(value + 1);
20+
const newValue = value + 1;
21+
onChange(newValue);
22+
setInputValue(newValue.toString());
1923
}
2024
};
2125

2226
const handleDecrement = () => {
2327
if (value > min) {
24-
onChange(value - 1);
28+
const newValue = value - 1;
29+
onChange(newValue);
30+
setInputValue(newValue.toString());
31+
}
32+
};
33+
34+
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
35+
const newInputValue = e.target.value;
36+
setInputValue(newInputValue);
37+
38+
// Only update the actual value if it's a valid number
39+
const numValue = parseInt(newInputValue, 10);
40+
if (!isNaN(numValue)) {
41+
// Apply min/max constraints
42+
const constrainedValue = Math.min(Math.max(numValue, min), max);
43+
onChange(constrainedValue);
2544
}
2645
};
2746

47+
const handleBlur = () => {
48+
// When input loses focus, ensure the displayed value matches the actual value
49+
// This handles cases where the user entered an invalid value
50+
setInputValue(value.toString());
51+
};
52+
2853
return (
2954
<div className="border-vsc-input-border bg-vsc-input-background flex flex-row overflow-hidden rounded-md border border-solid">
3055
<input
3156
type="text"
32-
value={value}
33-
readOnly
57+
value={inputValue}
58+
onChange={handleInputChange}
59+
onBlur={handleBlur}
3460
className="text-vsc-foreground max-w-7 border-none bg-inherit pr-1.5 text-right outline-none ring-0 focus:border-none focus:outline-none focus:ring-0"
3561
style={{
3662
appearance: "none",

gui/src/pages/config/index.tsx

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ function ConfigPage() {
130130
const codeBlockToolbarPosition = config.ui?.codeBlockToolbarPosition ?? "top";
131131
const useAutocompleteMultilineCompletions =
132132
config.tabAutocompleteOptions?.multilineCompletions ?? "auto";
133+
const modelTimeout =
134+
config.tabAutocompleteOptions?.modelTimeout ?? 150;
135+
const debounceDelay =
136+
config.tabAutocompleteOptions?.debounceDelay ?? 250;
133137
const fontSize = getFontSize();
134138

135139
// Disable autocomplete
@@ -513,7 +517,32 @@ function ConfigPage() {
513517
<option value="never">Never</option>
514518
</Select>
515519
</label>
516-
520+
<label className="flex items-center justify-between gap-3">
521+
<span className="text-left">Model Timeout (ms)</span>
522+
<NumberInput
523+
value={modelTimeout}
524+
onChange={(val) =>
525+
handleUpdate({
526+
modelTimeout: val,
527+
})
528+
}
529+
min={100}
530+
max={5000}
531+
/>
532+
</label>
533+
<label className="flex items-center justify-between gap-3">
534+
<span className="text-left">Model Debounce (ms)</span>
535+
<NumberInput
536+
value={debounceDelay}
537+
onChange={(val) =>
538+
handleUpdate({
539+
debounceDelay: val,
540+
})
541+
}
542+
min={0}
543+
max={2500}
544+
/>
545+
</label>
517546
<label className="flex items-center justify-between gap-3">
518547
<span className="text-left">Font Size</span>
519548
<NumberInput

0 commit comments

Comments
 (0)