-
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1dffd96
commit bc547d8
Showing
10 changed files
with
103 additions
and
182 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,130 +1,42 @@ | ||
import {useState} from 'react'; | ||
|
||
import {Tabs, TabsList, TabsTrigger} from '@/components/ui/tabs'; | ||
import {TabsContent} from '@radix-ui/react-tabs'; | ||
import {motion} from 'framer-motion'; | ||
import {Editor, EditorProps, Theme} from 'monacopilot'; | ||
import {Editor, Theme} from 'monacopilot'; | ||
import {useTheme} from 'next-themes'; | ||
|
||
interface File { | ||
filename: string; | ||
language: string; | ||
path: string; | ||
content: string; | ||
} | ||
|
||
const COPILOT_ENDPOINT = '/api/copilot'; | ||
|
||
const EDITOR_OPTIONS: EditorProps['options'] = { | ||
padding: {top: 60, bottom: 16}, | ||
overviewRulerBorder: false, | ||
overviewRulerLanes: 0, | ||
scrollBeyondLastLine: false, | ||
fontFamily: 'var(--font-mono)', | ||
fontSize: 15, | ||
renderLineHighlightOnlyWhenFocus: true, | ||
lineDecorationsWidth: 0, | ||
const EDITOR_DEFAULTS = { | ||
value: `// Start coding here to see the autocompletions in action!`, | ||
language: 'javascript', | ||
options: { | ||
padding: {top: 16, bottom: 16}, | ||
overviewRulerBorder: false, | ||
overviewRulerLanes: 0, | ||
scrollBeyondLastLine: false, | ||
fontFamily: 'var(--font-mono)', | ||
fontSize: 15, | ||
scrollbar: {alwaysConsumeMouseWheel: false}, | ||
}, | ||
}; | ||
|
||
const EditorDemo = () => { | ||
const [files, setFiles] = useState<Array<File>>([ | ||
{ | ||
filename: 'index.js', | ||
language: 'javascript', | ||
path: './index.js', | ||
content: `import { add } from './utils';\n\nconst result = add(1, 2);`, | ||
}, | ||
{ | ||
filename: 'utils.js', | ||
language: 'javascript', | ||
path: './utils.js', | ||
content: | ||
'export function add(a, b) { return a + b; }\nexport function subtract(a, b) { return a - b; }', | ||
}, | ||
{ | ||
filename: 'constants.js', | ||
language: 'javascript', | ||
path: './constants.js', | ||
content: 'export const PI = 3.14159;', | ||
}, | ||
]); | ||
const {resolvedTheme} = useTheme(); | ||
const theme: Theme = | ||
resolvedTheme === 'dark' ? 'codesandbox-dark' : 'github-light'; | ||
|
||
return ( | ||
<motion.div | ||
initial={{opacity: 0, y: 6}} | ||
animate={{opacity: 1, y: 0}} | ||
transition={{duration: 0.4, delay: 0.6}} | ||
className="rounded-xl my-8 overflow-hidden bg-background border shadow-md shadow-neutral-50 dark:shadow-neutral-900 md:w-[700px] w-full h-[400px] relative"> | ||
<Tabs defaultValue="index.js" className="w-full h-full"> | ||
<TabsList className="absolute top-0 border-b left-0 rounded-b-none z-50 w-full justify-start px-3 h-12 gap-2 bg-neutral-50 dark:bg-neutral-950"> | ||
{files.map(file => ( | ||
<TabsTrigger | ||
key={file.filename} | ||
value={file.filename} | ||
className="rounded-md border font-mono"> | ||
{file.filename} | ||
</TabsTrigger> | ||
))} | ||
</TabsList> | ||
{files.map(file => ( | ||
<TabsContent | ||
key={file.filename} | ||
value={file.filename} | ||
className="w-full h-full"> | ||
<RenderEditor | ||
filename={file.filename} | ||
value={file.content} | ||
language={file.language} | ||
externalContext={files | ||
.filter(f => f.filename !== file.filename) | ||
.map(f => ({path: f.path, content: f.content}))} | ||
setValue={(filename, value) => | ||
setFiles(prevFiles => | ||
prevFiles.map(f => | ||
f.filename === filename ? {...f, content: value} : f, | ||
), | ||
) | ||
} | ||
/> | ||
</TabsContent> | ||
))} | ||
</Tabs> | ||
className="rounded-xl my-8 overflow-hidden bg-background border shadow-md shadow-neutral-50 dark:shadow-neutral-900 md:w-[700px] w-full h-[400px]"> | ||
<Editor | ||
endpoint="/api/copilot" | ||
language={EDITOR_DEFAULTS.language} | ||
theme={theme} | ||
className="w-full" | ||
defaultValue={EDITOR_DEFAULTS.value} | ||
options={EDITOR_DEFAULTS.options} | ||
/> | ||
</motion.div> | ||
); | ||
}; | ||
|
||
interface RenderEditorProps extends EditorProps { | ||
setValue: (filename: string, value: string) => void; | ||
} | ||
|
||
const RenderEditor = ({ | ||
setValue, | ||
filename, | ||
value, | ||
language, | ||
externalContext, | ||
}: RenderEditorProps) => { | ||
const {resolvedTheme} = useTheme(); | ||
const theme: Theme = | ||
resolvedTheme === 'dark' ? 'codesandbox-dark' : 'github-light'; | ||
|
||
return ( | ||
<Editor | ||
endpoint={COPILOT_ENDPOINT} | ||
theme={theme} | ||
options={EDITOR_OPTIONS} | ||
onChange={newValue => { | ||
if (filename && newValue) { | ||
setValue(filename, newValue); | ||
} | ||
}} | ||
value={value} | ||
language={language} | ||
className="w-full z-10" | ||
loading="" | ||
externalContext={externalContext} | ||
/> | ||
); | ||
}; | ||
|
||
export default EditorDemo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,71 @@ | ||
import {CompletionMetadata, CompletionMode} from '../types/completion'; | ||
|
||
const CURSOR_PLACEHOLDER = '<|cursor|>'; | ||
const CURSOR_PLACEHOLDER = '<<CURSOR>>'; | ||
|
||
const getProperLanguageName = (language?: string): string | undefined => { | ||
return language === 'javascript' ? 'latest JavaScript' : language; | ||
}; | ||
|
||
const getDescriptionForMode = (mode: CompletionMode): string => { | ||
switch (mode) { | ||
case 'fill-in-the-middle': | ||
return 'filling in the middle of code'; | ||
case 'continuation': | ||
return 'continuing the code'; | ||
default: | ||
return 'unknown mode'; | ||
return 'filling in the middle of the code'; | ||
case 'completion': | ||
return 'completing the code'; | ||
} | ||
}; | ||
|
||
export const generateSystemPrompt = (metadata: CompletionMetadata): string => { | ||
const language = getProperLanguageName(metadata.language); | ||
const description = getDescriptionForMode( | ||
metadata.editorState.completionMode, | ||
); | ||
const langText = language || ''; | ||
return `You are an expert ${langText} code completion assistant known for exceptional skill in ${description}.`; | ||
}; | ||
|
||
export const generateUserPrompt = (metadata: CompletionMetadata): string => { | ||
const { | ||
language = 'the language', | ||
filename, | ||
framework, | ||
editorState, | ||
codeBeforeCursor, | ||
codeAfterCursor, | ||
externalContext, | ||
} = metadata; | ||
|
||
let prompt = `As an expert ${language} code completion assistant known for high accuracy in ${getDescriptionForMode(editorState.completionMode)}, could you assist with the code at the cursor location marked '${CURSOR_PLACEHOLDER}'? This code is part of ${filename ? `the ${filename} file` : 'a larger project'}. Please `; | ||
const language = getProperLanguageName(metadata.language); | ||
const modeDescription = getDescriptionForMode(editorState.completionMode); | ||
const fileNameText = filename | ||
? `the file named ${filename}` | ||
: 'a larger project'; | ||
|
||
const frameworkText = framework | ||
? ` The code utilizes the ${framework} framework in ${language}.` | ||
: ` The code is implemented in ${language}.`; | ||
|
||
let prompt = `You will be presented with a code snippet where the cursor location is marked with '${CURSOR_PLACEHOLDER}'. Your task is to assist with ${modeDescription}. This code is part of ${fileNameText}. Please `; | ||
|
||
switch (editorState.completionMode) { | ||
case 'fill-in-the-middle': | ||
prompt += `generate a completion to fill the middle of the code surrounding '${CURSOR_PLACEHOLDER}'. Ensure the completion precisely replaces '${CURSOR_PLACEHOLDER}', maintaining consistency, semantic accuracy, and relevance to the context.`; | ||
prompt += `generate a completion to fill the middle of the code around '${CURSOR_PLACEHOLDER}'. Ensure the completion replaces '${CURSOR_PLACEHOLDER}' precisely, maintaining consistency, semantic accuracy, and relevance to the context. The completion must start exactly from the cursor position without any preceding or following characters, and it should not introduce any syntactical or semantic errors to the existing code.`; | ||
break; | ||
case 'continuation': | ||
prompt += `provide a continuation from '${CURSOR_PLACEHOLDER}'. The completion should fluidly extend the existing code, precisely replacing '${CURSOR_PLACEHOLDER}' while adhering to ${language} standards and ensuring semantic correctness and contextual appropriateness.`; | ||
case 'completion': | ||
prompt += `provide the necessary completion for '${CURSOR_PLACEHOLDER}' while ensuring consistency, semantic accuracy, and relevance to the context. The completion must start exactly from the cursor position without any preceding or following characters, and it should not introduce any syntactical or semantic errors to the existing code.`; | ||
break; | ||
} | ||
|
||
prompt += ` Output only the necessary completion code, without additional explanations or content.`; | ||
prompt += ` Output only the necessary completion code, without additional explanations or content.${frameworkText}`; | ||
|
||
if (framework) { | ||
prompt += ` The code utilizes the ${framework} framework in ${language}.`; | ||
} else { | ||
prompt += ` The code is implemented in ${language}.`; | ||
} | ||
|
||
return prompt.endsWith('.') ? prompt : prompt + '.'; | ||
}; | ||
let codeForCompletion = `${codeBeforeCursor}${CURSOR_PLACEHOLDER}${codeAfterCursor}\n\n`; | ||
|
||
export const generateUserPrompt = (metadata: CompletionMetadata): string => { | ||
const {codeBeforeCursor, codeAfterCursor, externalContext} = metadata; | ||
|
||
let prompt = `${codeBeforeCursor}${CURSOR_PLACEHOLDER}${codeAfterCursor}\n\n`; | ||
|
||
// Append external context information if available | ||
if (externalContext && externalContext.length > 0) { | ||
prompt += externalContext | ||
codeForCompletion += externalContext | ||
.map(context => `// Path: ${context.path}\n${context.content}\n`) | ||
.join('\n'); | ||
} | ||
|
||
return prompt; | ||
prompt += `\n\n<code>\n${codeForCompletion}\n</code>`; | ||
|
||
return prompt.endsWith('.') ? prompt : `${prompt}.`; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.