diff --git a/docs/components/editor-demo.tsx b/docs/components/editor-demo.tsx index f952974b..24024e66 100644 --- a/docs/components/editor-demo.tsx +++ b/docs/components/editor-demo.tsx @@ -1,5 +1,5 @@ import {motion} from 'framer-motion'; -import CopilotEditor, {Theme} from 'monacopilot'; +import MonaCopilot, {Theme} from 'monacopilot'; import {useTheme} from 'next-themes'; const EDITOR_DEFAULTS = { @@ -27,7 +27,7 @@ const EditorDemo = () => { 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]"> - + + ```javascript + const express = require('express'); + const { Copilot } = require('monacopilot'); + + const app = express(); + const copilot = new Copilot(process.env.GROQ_API_KEY); + + app.use(express.json()); + + app.post('/copilot', async (req, res) => { + try { + const completion = await copilot.complete(req.body); + res.json(completion); + } catch (error) { + res.status(500).json({ error: error.message }); + } + }); + + app.listen(3000, () => console.log('Server running on port 3000')); + ``` + + + ```javascript + import { Hono } from 'hono'; + import { env } from 'hono/adapter'; + import { Copilot } from 'monacopilot'; + + const app = new Hono(); + + app.post('/copilot', async (c) => { + try { + const { GROQ_API_KEY } = env(c); + const copilot = new Copilot(GROQ_API_KEY); + const body = await c.req.json(); + const completion = await copilot.complete(body); + return c.json(completion); + } catch (error) { + return c.json({ error: error.message }, 500); + } + }); + + export default app; + ``` + + + +### Using External Endpoint + +To utilize an external endpoint with the MonaCopilot editor, use the following configuration: + +```jsx + +``` + +### Best Practices + +When implementing an external endpoint, consider the following best practices: + +1. **Security**: Ensure robust security measures are in place for your endpoint, especially when handling sensitive code or data. +2. **Performance**: Optimize the latency and throughput of your chosen endpoint solution to maintain fast and responsive code completions. + +--- + +The flexibility in endpoint configuration allows for tailored Copilot integration to meet specific needs and infrastructure requirements. diff --git a/docs/pages/docs/copilot/options.mdx b/docs/pages/docs/copilot/options.mdx new file mode 100644 index 00000000..92e456a0 --- /dev/null +++ b/docs/pages/docs/copilot/options.mdx @@ -0,0 +1,82 @@ +--- +title: Copilot Options +--- + +import { Callout } from 'nextra/components' + +# Copilot Options + +This guide outlines various configuration options available for customizing the auto completion integration in your editor. + +### External Context + +Enhance the accuracy and relevance of Copilot's completions by providing additional code context from your workspace. + +```jsx + str.split("").reverse().join("")' + } + ]} + // ... other props +/> +``` + +The `externalContext` prop accepts an array, allowing you to include content from multiple files. Each item in the array should contain: + +- `path`: The relative path from the current code in the editor +- `content`: The actual code content of the file + +#### Benefits + +By providing external context, Copilot can offer more intelligent suggestions. For example, if you start typing `const isPalindrome = `, Copilot may suggest using the `reverse` function from `utils.js` and even help with the correct import statement. + + + Note: Including more external context may slightly increase completion costs. + + +### Changing the Default Model + +You can specify a different model for completions by setting the `model` parameter in the `Copilot` constructor. + +```jsx +const copilot = new Copilot(process.env.GROQ_API_KEY, { + model: 'falcon' +}); +``` + +The default model is `llama` if not specified. + +### Filename + +Specify the name of the file being edited to receive more contextually relevant completions. + +```jsx + +``` + +Examples of filename values: +- `"index.js"` +- `"utils/objects.js"` + +### Completions for Specific Technologies + +Enable completions tailored to specific technologies by using the `technologies` prop. + +```jsx + +``` + +This configuration will provide completions relevant to React, Next.js, and Tailwind CSS. + +--- + +By leveraging these options, you can fine-tune Copilot's behavior to better suit your development environment and needs. Experiment with different configurations to find the optimal setup for your project. \ No newline at end of file diff --git a/docs/pages/docs/copilot/setup.mdx b/docs/pages/docs/copilot/setup.mdx new file mode 100644 index 00000000..5ab6c66a --- /dev/null +++ b/docs/pages/docs/copilot/setup.mdx @@ -0,0 +1,123 @@ +--- +title: Copilot Setup +--- + +import { Tabs, Callout, Card } from "nextra/components"; + +import { + Link1Icon, +} from "@radix-ui/react-icons"; + +# Copilot Setup + +This guide will walk you through the process of integrating AI auto-completion into your project using Copilot. + +### Obtaining an API Key + +To start, you'll need to obtain an API key from the [Groq console](https://console.groq.com/keys). + + + As of now, Groq has not implemented billing, allowing free usage of their API. Starting in early July, they plan to introduce a pay-as-you-go model. During this free period, you may experience some latency in completions. Once billing is implemented, you can expect instant completions without latency. + + +### Setting Up the API Key + +Once you have your API key, you need to define it as an environment variable in your project: + + + + ```bash filename=".env.local" + GROQ_API_KEY=your-api-key + ``` + + + ```bash filename=".env.development" + GROQ_API_KEY=your-api-key + ``` + + + +### API Handler + +Next, set up an API handler to manage auto-completion requests. The configuration depends on your framework: + + + + ```jsx filename="app/api/copilot/route.ts" + import { Copilot } from 'monacopilot'; + + const copilot = new Copilot(process.env.GROQ_API_KEY); + + export async function POST(req: Request) { + const body = await req.json(); + const completion = await copilot.complete(body); + + return Response.json(completion, {status: 200}) + } + ``` + + + ```jsx filename="pages/api/copilot.ts" + import { NextApiRequest, NextApiResponse } from 'next'; + import { Copilot } from 'monacopilot'; + + const copilot = new Copilot(process.env.GROQ_API_KEY); + + export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const completion = await copilot.complete(req.body); + + res.status(200).json(completion); + } + ``` + + + ```jsx filename="src/api/copilot.ts" + import { GatsbyFunctionRequest, GatsbyFunctionResponse } from "gatsby"; + import { Copilot } from 'monacopilot'; + + const copilot = new Copilot(process.env.GROQ_API_KEY); + + export default async function handler(req: GatsbyFunctionRequest, res: GatsbyFunctionResponse) { + const completion = await copilot.complete(req.body); + + res.status(200).json(completion); + } + ``` + + + +If you prefer to handle code completion requests with your own server instead of using the API handler, you can create an external completion endpoint. + +
+ +} + /> + +### Integrating Copilot with the Editor + +To utilize the MonaCopilot component with AI auto-completion, set the endpoint to the API handler: + +```jsx +import MonaCopilot from "monacopilot"; + +function App() { + return ( + + ); +} +``` + +The `language` prop is required to enable auto-completion for the specified language. + +### Additional Options + +For more advanced customization options, refer to the [Copilot Options](/docs/copilot/options) guide. + +--- + +You have now successfully configured AI auto-completion in your project. Start coding in the editor to experience the auto-completion functionality. \ No newline at end of file diff --git a/docs/pages/docs/guide/_meta.json b/docs/pages/docs/guide/_meta.json deleted file mode 100644 index 4aca51e3..00000000 --- a/docs/pages/docs/guide/_meta.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "copilot-setup": "Copilot Setup", - "copilot-options": "Copilot Options" -} diff --git a/docs/pages/docs/guide/copilot-options.mdx b/docs/pages/docs/guide/copilot-options.mdx deleted file mode 100644 index 4c718dd6..00000000 --- a/docs/pages/docs/guide/copilot-options.mdx +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Copilot Options ---- - -import { Callout } from 'nextra/components' - -# Copilot Options - -#### External Context - -Provide additional code, such as neighboring code snippets. This facilitates more accurate and workspace-specific completions by Copilot. The `externalContext` is structured as an array, allowing you to include content from multiple files. - -```jsx - str.split('').reverse().join('')' - } - ]} - ... -/> -``` - -For instance, if you begin typing `const isPalindrome = `, Copilot can intelligently suggest using the `reverse` function from the `utils.js` file. Additionally, Copilot can help you import it from the correct path. - - -Providing more external context may slightly increase completion costs. - - -#### Changing the Default Model - -Change the default model used for completions by setting the `model` parameter in the `Copilot` constructor. The default model is `llama`. - -```jsx -const copilot = new Copilot(process.env.GROQ_API_KEY, { - model: 'falcon' -}); -``` - -#### Filename - -The name of the file you are editing. This is used to provide more relevant completions based on the file's purpose. -For example, if you are editing a file named `utils.js`, the completions will be more relevant to utility functions. - -```jsx - -``` - -#### Completions for Specific Technologies - -Currently, the completions are shown based on the language specified in the editor. To enable completions for specific technologies, pass the `technologies` prop to the `CopilotEditor` component. - -```jsx - -``` - -Now, Copilot will provide completions that are relevant to React, Next.js, and Tailwind CSS. \ No newline at end of file diff --git a/docs/pages/docs/guide/copilot-setup.mdx b/docs/pages/docs/guide/copilot-setup.mdx deleted file mode 100644 index 41f1d9f9..00000000 --- a/docs/pages/docs/guide/copilot-setup.mdx +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: Copilot Setup ---- - -import { Tabs, Callout } from "nextra/components"; - -# Copilot Setup - -To integrate AI auto-completion, first obtain an API key from the [Groq console](https://console.groq.com). - - - Groq has not introduced billing yet, so you can currently use the Groq API for free. Starting the first week of July, they will implement a pay-as-you-go model. As the API is free at the moment, you may experience some latency in the completion. Once billing is introduced, you will receive instant completions without any latency. - - -#### Setting Up the API Key - -Define your API key as an environment variable in your project as shown below: - - - -```bash filename=".env.local" -GROQ_API_KEY=your-api-key -``` - - -```bash filename=".env.development" -GROQ_API_KEY=your-api-key -``` - - - -#### API Handler Configuration - -Set up an API handler to manage auto-completion requests. Configure according to your framework: - - - -```jsx filename="app/api/copilot/route.ts" -import { Copilot } from 'monacopilot'; - -const copilot = new Copilot(process.env.GROQ_API_KEY); - -export async function POST(req: Request) { - const code = await req.json(); - const completion = await copilot.complete(code); - - return Response.json(completion) -} -``` - - -```jsx filename="pages/api/copilot.ts" -import { NextApiRequest, NextApiResponse } from 'next'; -import { Copilot } from 'monacopilot'; - -const copilot = new Copilot(process.env.GROQ_API_KEY); - -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - const completion = await copilot.complete(req.body); - - res.status(200).json(completion); -} -``` - - -```jsx filename="src/api/copilot.ts" -import { GatsbyFunctionRequest, GatsbyFunctionResponse } from "gatsby"; -import { Copilot } from 'monacopilot'; - -const copilot = new Copilot(process.env.GROQ_API_KEY); - -export default async function handler(req: GatsbyFunctionRequest, res: GatsbyFunctionResponse) { - const completion = await copilot.complete(req.body); - - res.status(200).json(completion); -} -``` - - - -#### Integrating Copilot to the Editor - -Utilize the `CopilotEditor` component with the AI auto-completion by setting the `endpoint` to the API handler: - -```jsx {6} -import CopilotEditor from "monacopilot"; - -function App() { - return ( - - ); -} -``` - -Please note that the `language` prop is required to enable auto-completion for the specified language. - -More options are available to customize the auto-completion. Refer to the [Copilot Options](/docs/guide/copilot-options) guide for more information. - -🎉 You have now successfully configured AI auto-completion in your project. Start coding in the editor and watch the auto-completion magic unfold! \ No newline at end of file diff --git a/docs/pages/docs/index.mdx b/docs/pages/docs/index.mdx index deeef537..189e5300 100644 --- a/docs/pages/docs/index.mdx +++ b/docs/pages/docs/index.mdx @@ -5,74 +5,76 @@ import { # Getting Started -**Monacopilot** is a wrapper for Monaco Editor that offers AI autocompletion and new themes for React. It's similar to GitHub Copilot, but for Monaco Editor. +**Monacopilot** is a wrapper for the Monaco Editor, providing AI-powered autocompletion and an array of new themes for React. Similar to GitHub Copilot, but for Monaco Editor. -To get started with Monacopilot, you can install it first: +### Installation + +To get started with Monacopilot, install it via your preferred package manager: - + ```bash npm install monacopilot ``` - - - ```bash - pnpm install monacopilot - ``` - + + ```bash + pnpm install monacopilot + ``` + + ```bash yarn add monacopilot ``` - - + + ```bash bun add monacopilot ``` - + -Just import the `CopilotEditor` and use it in your code: +### Usage + +Import Monacopilot into your React application and use it as shown below: ```jsx -import CopilotEditor from "monacopilot"; +import MonaCopilot from "monacopilot"; function App() { - return ; + return ; } ``` -The above code is a simple example of how to use Monacopilot in your React application. +The above example demonstrates how to integrate Monacopilot into a simple React application. ### Themes -Monacopilot comes with a wide range of themes that you can use in your editor. To use a theme, you can just pass the `theme` prop to the `CopilotEditor` component: +Monacopilot offers a wide range of themes for customizing your editor. You can apply a theme by passing the `theme` prop to the MonaCopilot component: ```jsx {8} -import CopilotEditor from "monacopilot"; +import MonaCopilot from "monacopilot"; function App() { return ( - - ) + ); } ``` -The above code uses the `github-light` theme in the editor. There are many other themes available. +In this example, the `github-light` theme is applied to the editor. Numerous other themes are available for you to explore. -### More Options and Usage +### Advanced Usage -Since Monacopilot is a wrapper around `@monaco-editor/react`, you can use all the props and import statements that you would use with @monaco-editor/react. For more information, you can check out the [@monaco-editor/react documentation](https://github.com/suren-atoyan/monaco-react/blob/master/README.md). +Monacopilot, being a wrapper around `@monaco-editor/react`, supports all the properties and import statements used with `@monaco-editor/react`. For more detailed information, refer to the [@monaco-editor/react documentation](https://github.com/suren-atoyan/monaco-react/blob/master/README.md). -## Next Steps +### Next Steps -Now that you have Monacopilot installed and running, it behaves like a normal Monaco Editor but with additional themes. This setup is sufficient if you only want to use the themes. If you're interested in utilizing the AI auto-completion feature, please refer to the Copilot Setup guide. +Now that you have Monacopilot installed and running, it functions like a standard Monaco Editor with added theme capabilities. If you are interested in utilizing the AI auto-completion feature, proceed to the Copilot Setup guide.
-} -/> \ No newline at end of file +} /> diff --git a/src/classes/copilot.ts b/src/classes/copilot.ts index 72ecadad..e2a9a89c 100644 --- a/src/classes/copilot.ts +++ b/src/classes/copilot.ts @@ -83,7 +83,6 @@ class Copilot { completion: completion.choices[0].message.content, }; } catch (error) { - console.error(error); return { error: error.message, }; diff --git a/src/helpers/prompt.ts b/src/helpers/prompt.ts index ddad78d8..96abf4cd 100644 --- a/src/helpers/prompt.ts +++ b/src/helpers/prompt.ts @@ -1,5 +1,5 @@ import type {CompletionMetadata, CompletionMode} from '../types/completion'; -import type {Technologies} from '../types/copilot-editor-props'; +import type {Technologies} from '../types/monacopilot-props'; import {joinWithAnd} from '../utils/common'; const CURSOR_PLACEHOLDER = '<>'; diff --git a/src/hooks/use-start-completion.ts b/src/hooks/use-start-completion.ts index 632a0e1f..711b5fe8 100644 --- a/src/hooks/use-start-completion.ts +++ b/src/hooks/use-start-completion.ts @@ -13,7 +13,7 @@ import type { ExternalContext, Filename, Technologies, -} from '../types/copilot-editor-props'; +} from '../types/monacopilot-props'; import {getLine} from '../utils/editor'; import useDebounceFn from './use-debounce-fn'; diff --git a/src/index.ts b/src/index.ts index 13d0e8da..d71b0e7e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,11 @@ import Copilot from './classes/copilot'; -import CopilotEditor from './copilot-editor'; +import MonaCopilot from './monacopilot'; import type {CompletionRequest, CompletionResponse} from './types/completion'; -import type CopilotEditorProps from './types/copilot-editor-props'; -import type {Endpoint, Technologies, Theme} from './types/copilot-editor-props'; +import type MonaCopilotProps from './types/monacopilot-props'; +import type {Endpoint, Technologies, Theme} from './types/monacopilot-props'; // Export everything from `@monaco-editor/react` except `Editor`, `EditorProps`, and `Theme` -// We have our own `Editor` as `CopilotEditor` and `EditorProps` as `CopilotEditorProps` +// We have our own `Editor` as `MonaCopilot` and `EditorProps` as `MonaCopilotProps` // We have our own `Theme` exported. export { type BeforeMount, @@ -23,8 +23,8 @@ export { } from '@monaco-editor/react'; export { - CopilotEditor as default, - CopilotEditorProps, + MonaCopilot as default, + MonaCopilotProps, Theme, Endpoint, Technologies, diff --git a/src/copilot-editor.tsx b/src/monacopilot.tsx similarity index 90% rename from src/copilot-editor.tsx rename to src/monacopilot.tsx index 38ba39c4..544b5fa7 100644 --- a/src/copilot-editor.tsx +++ b/src/monacopilot.tsx @@ -13,17 +13,17 @@ import type { EditorOptions, StandaloneCodeEditor, } from './types/common'; -import type EditorProps from './types/copilot-editor-props'; +import type MonaCopilotProps from './types/monacopilot-props'; import {deepMerge} from './utils/common'; -const CopilotEditor = ({ +const MonaCopilot = ({ filename, endpoint, technologies, theme, externalContext, ...props -}: EditorProps) => { +}: MonaCopilotProps) => { const [monacoInstance, setMonacoInstance] = React.useState( null, ); @@ -65,4 +65,4 @@ const CopilotEditor = ({ ); }; -export default CopilotEditor; +export default MonaCopilot; diff --git a/src/types/completion.ts b/src/types/completion.ts index d6834109..6ade60c7 100644 --- a/src/types/completion.ts +++ b/src/types/completion.ts @@ -13,7 +13,7 @@ import type { ExternalContext, Filename, Technologies, -} from './copilot-editor-props'; +} from './monacopilot-props'; export type CompletionModel = 'llama'; diff --git a/src/types/copilot-editor-props.ts b/src/types/monacopilot-props.ts similarity index 93% rename from src/types/copilot-editor-props.ts rename to src/types/monacopilot-props.ts index 1992ef8f..44ae358d 100644 --- a/src/types/copilot-editor-props.ts +++ b/src/types/monacopilot-props.ts @@ -42,7 +42,7 @@ export type ExternalContext = { content: string; }[]; -export default interface CopilotEditorProps extends MonacoEditorProps { +export default interface MonaCopilotProps extends MonacoEditorProps { /** * The name of the file you are editing. This is used to provide more relevant completions based on the file's purpose. * For example, if you are editing a file named `utils.js`, the completions will be more relevant to utility functions. @@ -50,7 +50,7 @@ export default interface CopilotEditorProps extends MonacoEditorProps { filename?: Filename; /** * The API endpoint where you started the completion service. - * [Learn more](https://monacopilot.vercel.app/docs/guide/copilot-setup#integrating-copilot-to-the-editor) + * [Learn more](https://monacopilot.vercel.app/copilot/setup#integrating-copilot-to-the-editor) */ endpoint?: Endpoint; /** diff --git a/test/src/app/api/copilot/route.ts b/test/src/app/api/copilot/route.ts index 13ad9858..70697676 100644 --- a/test/src/app/api/copilot/route.ts +++ b/test/src/app/api/copilot/route.ts @@ -3,8 +3,8 @@ import {Copilot} from 'monacopilot'; const copilot = new Copilot(process.env.GROQ_API_KEY!); export async function POST(req: Request) { - const code = await req.json(); - const completion = await copilot.complete(code); + const body = await req.json(); + const completion = await copilot.complete(body); return Response.json(completion); } diff --git a/test/src/app/page.tsx b/test/src/app/page.tsx index fa404165..6e586dd8 100644 --- a/test/src/app/page.tsx +++ b/test/src/app/page.tsx @@ -1,11 +1,11 @@ 'use client'; -import CopilotEditor from 'monacopilot'; +import MonaCopilot from 'monacopilot'; export default function Home() { return (
-