Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix React refreshSync error #5967

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 60 additions & 10 deletions lib/prompt-editor/src/PromptEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { $insertFirst } from '@lexical/utils'
import {
type ContextItem,
type SerializedContextItem,
type SerializedPromptEditorState,
type SerializedPromptEditorValue,
getMentionOperations,
Expand All @@ -8,6 +10,7 @@ import {
} from '@sourcegraph/cody-shared'
import { clsx } from 'clsx'
import {
$createParagraphNode,
$createTextNode,
$getRoot,
$getSelection,
Expand Down Expand Up @@ -53,7 +56,8 @@ export interface PromptEditorRefAPI {
getSerializedValue(): SerializedPromptEditorValue
setFocus(focus: boolean, options?: { moveCursorToEnd?: boolean }, cb?: () => void): void
appendText(text: string, cb?: () => void): void
addMentions(items: ContextItem[], cb?: () => void): void
addMentions(items: ContextItem[], cb?: () => void, position?: 'before' | 'after', sep?: string): void
removeMentions(filter: (item: SerializedContextItem) => boolean, cb?: () => void): void
setInitialContextMentions(items: ContextItem[], cb?: () => void): void
setEditorState(state: SerializedPromptEditorState, cb?: () => void): void
}
Expand Down Expand Up @@ -146,7 +150,23 @@ export const PromptEditor: FunctionComponent<Props> = ({
{ onUpdate: cb }
)
},
addMentions(items: ContextItem[], cb?: () => void): void {
removeMentions(filter: (item: SerializedContextItem) => boolean, cb?: () => void): void {
if (!editorRef.current) {
cb?.()
return
}
visitContextItemsForEditor(editorRef.current, node => {
if (!filter(node.contextItem)) {
node.remove()
}
})
},
addMentions(
items: ContextItem[],
cb?: () => void,
position: 'before' | 'after' = 'after',
sep = ' '
): void {
const editor = editorRef.current
if (!editor) {
cb?.()
Expand Down Expand Up @@ -176,13 +196,40 @@ export const PromptEditor: FunctionComponent<Props> = ({

editorRef.current?.update(
() => {
const nodesToInsert = lexicalNodesForContextItems(ops.create, {
isFromInitialContext: false,
})
$insertNodes([$createTextNode(getWhitespace($getRoot())), ...nodesToInsert])
const lastNode = nodesToInsert.at(-1)
if (lastNode) {
$selectAfter(lastNode)
switch (position) {
case 'before': {
const nodesToInsert = lexicalNodesForContextItems(
ops.create,
{
isFromInitialContext: false,
},
sep
)
const pNode = $createParagraphNode()
pNode.append(...nodesToInsert)
$insertFirst($getRoot(), pNode)
$selectEnd()
break
}
case 'after': {
const nodesToInsert = lexicalNodesForContextItems(
ops.create,
{
isFromInitialContext: false,
},
sep
)
$insertNodes([
$createTextNode(getWhitespace($getRoot())),
$createTextNode('\n'),
...nodesToInsert,
])
const lastNode = nodesToInsert.at(-1)
if (lastNode) {
$selectAfter(lastNode)
}
break
}
}
},
{ onUpdate: cb }
Expand All @@ -206,6 +253,7 @@ export const PromptEditor: FunctionComponent<Props> = ({
const nodesToInsert = lexicalNodesForContextItems(items, {
isFromInitialContext: true,
})
nodesToInsert.push($createTextNode(' '))
$setSelection($getRoot().selectStart()) // insert at start
$insertNodes(nodesToInsert)
$selectEnd()
Expand Down Expand Up @@ -237,7 +285,9 @@ export const PromptEditor: FunctionComponent<Props> = ({
const currentEditorState = normalizeEditorStateJSON(editor.getEditorState().toJSON())
const newEditorState = initialEditorState.lexicalEditorState
if (!isEqual(currentEditorState, newEditorState)) {
editor.setEditorState(editor.parseEditorState(newEditorState))
queueMicrotask(() => {
editor.setEditorState(editor.parseEditorState(newEditorState))
})
}
}
}
Expand Down
14 changes: 9 additions & 5 deletions lib/prompt-editor/src/initialContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ export function lexicalNodesForContextItems(
isFromInitialContext,
}: {
isFromInitialContext: boolean
}
},
sep = ' '
): (TextNode | ContextItemMentionNode)[] {
const nodes = items.flatMap(item => [
$createContextItemMentionNode(item, { isFromInitialContext }),
$createTextNode(' '),
])
const nodes: (ContextItemMentionNode | TextNode)[] = []
for (let i = 0; i < items.length; i++) {
nodes.push($createContextItemMentionNode(items[i], { isFromInitialContext }))
if (i < items.length - 1) {
nodes.push($createTextNode(sep))
}
}
return nodes
}

Expand Down
13 changes: 6 additions & 7 deletions vscode/src/chat/chat-view/ChatBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,6 @@ export class ChatBuilder {
}

private changeNotifications = new Subject<void>()

/** An observable that emits whenever the {@link ChatBuilder}'s chat changes. */
public changes: Observable<ChatBuilder> = this.changeNotifications.pipe(
startWith(undefined),
map(() => this)
)

constructor(
/**
* The model ID to use for the next assistant response if the user has explicitly chosen
Expand All @@ -103,6 +96,12 @@ export class ChatBuilder {
private customChatTitle?: string
) {}

/** An observable that emits whenever the {@link ChatBuilder}'s chat changes. */
public changes: Observable<ChatBuilder> = this.changeNotifications.pipe(
startWith(undefined),
map(() => this)
)

/**
* Set the selected model to use for the next assistant response, or `undefined` to use the
* default chat model.
Expand Down
11 changes: 11 additions & 0 deletions vscode/webviews/chat/Transcript.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,16 @@ const TranscriptInteraction: FC<TranscriptInteractionProps> = memo(props => {

const resetIntent = useCallback(() => setIntentResults(undefined), [setIntentResults])

const manuallyEditContext = useCallback(() => {
const contextFiles = humanMessage.contextFiles
const editor = humanEditorRef.current
if (!contextFiles || !editor) {
return
}
editor.removeMentions(item => item.type !== 'repository')
editor.addMentions(contextFiles, undefined, 'before', '\n')
}, [humanMessage.contextFiles])

return (
<>
<HumanMessageCell
Expand Down Expand Up @@ -428,6 +438,7 @@ const TranscriptInteraction: FC<TranscriptInteractionProps> = memo(props => {
reSubmitWithChatIntent={reSubmitWithChatIntent}
isContextLoading={isContextLoading}
onAddToFollowupChat={onAddToFollowupChat}
onManuallyEditContext={manuallyEditContext}
/>
)}
{(!experimentalOneBoxEnabled || humanMessage.intent !== 'search') &&
Expand Down
13 changes: 13 additions & 0 deletions vscode/webviews/chat/cells/contextCell/ContextCell.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,16 @@
padding-left: 0.1rem;
text-wrap: nowrap;
}

.context-item-edit-button {
display: flex;
align-items: center;

flex-wrap: nowrap;

}

.context-item-edit-button-icon {
height: 20%;
margin-right: 0.5rem;
}
15 changes: 14 additions & 1 deletion vscode/webviews/chat/cells/contextCell/ContextCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ContextItem, Model } from '@sourcegraph/cody-shared'
import { pluralize } from '@sourcegraph/cody-shared'
import type { RankedContext } from '@sourcegraph/cody-shared/src/chat/transcript/messages'
import { clsx } from 'clsx'
import { BrainIcon, MessagesSquareIcon } from 'lucide-react'
import { BrainIcon, MessagesSquareIcon, Pencil } from 'lucide-react'
import { type FunctionComponent, memo, useCallback, useState } from 'react'
import { FileContextItem } from '../../../components/FileContextItem'
import {
Expand Down Expand Up @@ -41,6 +41,7 @@ export const ContextCell: FunctionComponent<{
filePath: string
fileURL: string
}) => void
onManuallyEditContext: () => void

/** For use in storybooks only. */
__storybook__initialOpen?: boolean
Expand All @@ -57,6 +58,7 @@ export const ContextCell: FunctionComponent<{
showSnippets = false,
isContextLoading,
onAddToFollowupChat,
onManuallyEditContext,
}) => {
const [selectedAlternative, setSelectedAlternative] = useState<number | undefined>(undefined)
const incrementSelectedAlternative = useCallback(
Expand Down Expand Up @@ -167,6 +169,17 @@ export const ContextCell: FunctionComponent<{
) : (
<>
<AccordionContent overflow={showSnippets}>
<button
type="button"
className={styles.contextItemEditButton}
onClick={onManuallyEditContext}
>
<div className={styles.contextItemEditButtonIcon}>
<Pencil size={'1rem'} />
</div>
<div>Edit context manually</div>
</button>

{internalDebugContext && contextAlternatives && (
<div>
<button
Expand Down
Loading