feat(cloud-agent): prompt autocomplete (ghost text)#2119
feat(cloud-agent): prompt autocomplete (ghost text)#2119kilo-code-bot[bot] wants to merge 1 commit intomainfrom
Conversation
Implements ghost-text prompt autocomplete for the Cloud Agent chat input (based on original PR #5 by @markijbema, rebased on monorepo main). - Adds `cloudAgent.getFimAutocomplete` tRPC mutation using Mistral Codestral FIM - Adds `useChatGhostText` hook with debounced completion requests - Adds ghost text overlay rendering in `cloud-agent-next` ChatInput - Accept suggestion: Tab (all), ArrowRight (next word), Escape clears - Improves error handling in `sendProxiedChatCompletion`
| const newCursorPos = selectionStart + text.length; | ||
| textarea.setSelectionRange(newCursorPos, newCursorPos); | ||
| // Trigger input event so React sees the change | ||
| textarea.dispatchEvent(new Event('input', { bubbles: true })); |
There was a problem hiding this comment.
WARNING: Accepting a suggestion does not reliably sync the controlled textarea state
This helper mutates textarea.value directly and then relies on a synthetic input event to drive onChange, but the textarea is controlled by React via value={value}. React's value tracker usually treats programmatic element.value = ... writes as already observed, so onChange may never fire here. When that happens the accepted text can disappear on the next render or leave derived UI like the send-button disabled state out of sync.
| } catch (error) { | ||
| debugCloudAgentAutocomplete('error', error); | ||
| // Silently ignore errors - just don't show ghost text | ||
| setGhostText(''); |
There was a problem hiding this comment.
WARNING: Stale failed requests can erase a newer completion
The success path only updates ghostText when requestId === completionRequestIdRef.current, but this catch block always calls setGhostText(''). If request A fails after request B has already started or populated a suggestion, A will clear B's result even though it is stale. The error path needs the same request-id guard as the success path.
| // Ignore keyboard events during IME composition (Chinese, Japanese, Korean input) | ||
| if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return; | ||
|
|
||
| if (handleGhostTextKeyDown(e)) { |
There was a problem hiding this comment.
WARNING: Ghost-text shortcuts now take precedence over slash-command shortcuts
handleGhostTextKeyDown runs before the existing slash-command autocomplete logic. When the input starts with / and a ghost suggestion is present, pressing Tab will accept ghost text instead of selecting the highlighted slash command, which regresses the current slash-command keyboard flow. Slash-command handling should keep precedence while that popover is open.
Code Review SummaryStatus: 3 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Other Observations (not in diff)No additional issues found outside the diff. Files Reviewed (7 files)
Reviewed by gpt-5.4-20260305 · 489,292 tokens |
|
Closing to recreate as a new PR |
Summary
Recreates PR #5 by @markijbema on the monorepo main, as requested by @jeanduplessis.
cloudAgent.getFimAutocompletetRPC mutation backed by Mistral Codestral FIM endpointuseChatGhostTexthook incloud-agent-nextwith debounced completion requests and stale-request guardcloud-agent-next/ChatInput; accept with Tab (full), ArrowRight (next word), or dismiss with EscapesendProxiedChatCompletionerror handling to catch network failures and JSON parse errors gracefullyVerification
tsgo --noEmit -p apps/web/tsconfig.json)Visual Changes
N/A (ghost text overlay is invisible until a suggestion is returned)
Reviewer Notes
getFimAutocompleteendpoint usesgenerateApiTokenwithinternalApiUse: trueto bypass abuse heuristics, consistent with the original PR's intenttrpc.cloudAgent.getFimAutocomplete(notcloudAgentNext) since the FIM endpoint is user-scoped, not session-scopedsrc/components/cloud-agent/→apps/web/src/components/cloud-agent-next/andsrc/routers/→apps/web/src/routers/per monorepo structureCloses #5