diff --git a/packages/kilo-vscode/tests/unit/review-comments.test.ts b/packages/kilo-vscode/tests/unit/review-comments.test.ts
index ca9b9353cfe..f1e75a3bc94 100644
--- a/packages/kilo-vscode/tests/unit/review-comments.test.ts
+++ b/packages/kilo-vscode/tests/unit/review-comments.test.ts
@@ -245,9 +245,7 @@ describe("markdownCommentBlocks", () => {
describe("review annotation speech keys", () => {
it("keeps draft keys scoped to the selected review location", () => {
- expect(reviewDraftSpeechKey({ file: "src/a.ts", side: "additions", line: 4 })).toBe(
- "draft:src/a.ts:additions:4:4",
- )
+ expect(reviewDraftSpeechKey({ file: "src/a.ts", side: "additions", line: 4 })).toBe("draft:src/a.ts:additions:4:4")
expect(reviewDraftSpeechKey({ file: "src/a.ts", side: "deletions", line: 4, endLine: 8 })).toBe(
"draft:src/a.ts:deletions:4:8",
)
diff --git a/packages/kilo-vscode/webview-ui/agent-manager/review-annotation-speech.tsx b/packages/kilo-vscode/webview-ui/agent-manager/review-annotation-speech.tsx
index ae8314e1b52..48c67f73d28 100644
--- a/packages/kilo-vscode/webview-ui/agent-manager/review-annotation-speech.tsx
+++ b/packages/kilo-vscode/webview-ui/agent-manager/review-annotation-speech.tsx
@@ -1,4 +1,4 @@
-import { createEffect, createSignal, onCleanup, Show, type Accessor } from "solid-js"
+import { createEffect, createRoot, createSignal, onCleanup, Show, type Accessor } from "solid-js"
import { render as renderSolid } from "solid-js/web"
import { SpeechToTextButton } from "../src/components/speech-to-text/SpeechToTextButton"
import { insertSpacedText } from "../src/components/chat/prompt-input-utils"
@@ -19,7 +19,7 @@ type Node = {
setTextarea: (textarea: HTMLTextAreaElement) => void
}
-export function insertReviewSpeechText(textarea: HTMLTextAreaElement, value: string): void {
+function insertReviewSpeechText(textarea: HTMLTextAreaElement, value: string): void {
const text = textarea.value
const start = textarea.selectionStart ?? text.length
const end = textarea.selectionEnd ?? start
@@ -42,11 +42,18 @@ export function createReviewAnnotationSpeechRenderer(props: Props) {
let field = textarea
const mine = () => owner() === key
const state = (): SpeechState => (mine() ? props.speech.state() : "idle")
+ const start = (model: string) => {
+ setOwner(key)
+ props.speech.start({
+ model,
+ insert: (value) => insertReviewSpeechText(field, value),
+ })
+ }
const speech: SpeechToText = {
state,
error: () => (mine() ? props.speech.error() : undefined),
active: () => mine() && props.speech.active(),
- start: props.speech.start,
+ start: (opts) => start(opts.model),
stop: () => {
if (!mine()) return
props.speech.stop()
@@ -63,22 +70,24 @@ export function createReviewAnnotationSpeechRenderer(props: Props) {
},
}
const blocked = () => props.speech.active() && !mine()
- const start = () => {
- setOwner(key)
- props.speech.start({
- model: props.model(),
- insert: (value) => insertReviewSpeechText(field, value),
- })
- }
- const dispose = renderSolid(
- () => (
-
-
-
- ),
- host,
- )
+ const dispose = createRoot((root) => {
+ const view = renderSolid(
+ () => (
+
+ start(props.model())}
+ label={props.label}
+ />
+
+ ),
+ host,
+ )
+ onCleanup(view)
+ return root
+ })
const node = {
host,