monacopilot 0.9.35 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -18
- package/build/index.d.mts +11 -1
- package/build/index.d.ts +11 -1
- package/build/index.js +21 -20
- package/build/index.mjs +21 -20
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
## Table of Contents
|
|
8
8
|
|
|
9
9
|
- [Examples](#examples)
|
|
10
|
-
- [Installation](#installation)
|
|
11
10
|
- [Inline Completions](#inline-completions)
|
|
11
|
+
- [Installation](#installation)
|
|
12
12
|
- [Usage](#usage)
|
|
13
13
|
- [API Handler](#api-handler)
|
|
14
14
|
- [Register Completion with the Monaco Editor](#register-completion-with-the-monaco-editor)
|
|
@@ -35,7 +35,11 @@ Here are some examples of how to integrate Monacopilot into your project:
|
|
|
35
35
|
- [Pages Router](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/nextjs/pages)
|
|
36
36
|
- [Remix](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/remix)
|
|
37
37
|
|
|
38
|
-
##
|
|
38
|
+
## Inline Completions
|
|
39
|
+
|
|
40
|
+
[Inline Completions Demo Video](https://github.com/user-attachments/assets/f2ec4ae1-f658-4002-af9c-c6b1bbad70d9)
|
|
41
|
+
|
|
42
|
+
### Installation
|
|
39
43
|
|
|
40
44
|
To install Monacopilot, run:
|
|
41
45
|
|
|
@@ -43,12 +47,6 @@ To install Monacopilot, run:
|
|
|
43
47
|
npm install monacopilot
|
|
44
48
|
```
|
|
45
49
|
|
|
46
|
-
## Inline Completions
|
|
47
|
-
|
|
48
|
-
AI-generated suggestions that appear directly within your code as you type.
|
|
49
|
-
|
|
50
|
-
[Inline Completions Demo Video](https://github.com/user-attachments/assets/f2ec4ae1-f658-4002-af9c-c6b1bbad70d9)
|
|
51
|
-
|
|
52
50
|
### Usage
|
|
53
51
|
|
|
54
52
|
#### API Handler
|
|
@@ -223,7 +221,7 @@ const copilot = new Copilot(process.env.HUGGINGFACE_API_KEY, {
|
|
|
223
221
|
},
|
|
224
222
|
},
|
|
225
223
|
}),
|
|
226
|
-
transformResponse: response => response[0].generated_text,
|
|
224
|
+
transformResponse: response => ({text: response[0].generated_text}),
|
|
227
225
|
},
|
|
228
226
|
});
|
|
229
227
|
```
|
|
@@ -232,10 +230,10 @@ const copilot = new Copilot(process.env.HUGGINGFACE_API_KEY, {
|
|
|
232
230
|
|
|
233
231
|
The `model` option accepts an object with two functions:
|
|
234
232
|
|
|
235
|
-
| Function | Description
|
|
236
|
-
| ------------------- |
|
|
237
|
-
| `config` | A function that receives the API key and prompt data, and returns the configuration for the custom model API request.
|
|
238
|
-
| `transformResponse` | A function that takes the raw/parsed response from the custom model API and returns
|
|
233
|
+
| Function | Description | Type |
|
|
234
|
+
| ------------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
235
|
+
| `config` | A function that receives the API key and prompt data, and returns the configuration for the custom model API request. | `(apiKey: string, prompt: { system: string; user: string }) => { endpoint: string; body?: object; headers?: object }` |
|
|
236
|
+
| `transformResponse` | A function that takes the raw/parsed response from the custom model API and returns an object with the `text` property. | `(response: unknown) => { text: string \| null; }` |
|
|
239
237
|
|
|
240
238
|
The `config` function must return an object with the following properties:
|
|
241
239
|
|
|
@@ -245,7 +243,7 @@ The `config` function must return an object with the following properties:
|
|
|
245
243
|
| `body` | `object` or `undefined` | The body of the custom model API request. |
|
|
246
244
|
| `headers` | `object` or `undefined` | The headers of the custom model API request. |
|
|
247
245
|
|
|
248
|
-
The `transformResponse` function must return the
|
|
246
|
+
The `transformResponse` function must return an object with the `text` property. This `text` property should contain the text generated by the custom model. If no valid text can be extracted, the function should return `null` for the `text` property.
|
|
249
247
|
|
|
250
248
|
## Completion Request Options
|
|
251
249
|
|
|
@@ -351,11 +349,9 @@ By using a custom prompt, you can guide the model to generate completions that b
|
|
|
351
349
|
|
|
352
350
|
## Select and Edit
|
|
353
351
|
|
|
354
|
-
Select and Edit is a feature that allows you to select code from the editor and edit it inline with AI assistance
|
|
355
|
-
|
|
356
|
-
<img width="871" alt="select-and-edit-example" src="https://github.com/user-attachments/assets/87c6245a-7827-47f3-8b59-1f59eec9d2ef">
|
|
352
|
+
Select and Edit is a feature that allows you to select code from the editor and edit it inline with AI assistance.
|
|
357
353
|
|
|
358
|
-
This feature is coming soon
|
|
354
|
+
This feature is coming soon™️.
|
|
359
355
|
|
|
360
356
|
## Contributing
|
|
361
357
|
|
package/build/index.d.mts
CHANGED
|
@@ -72,7 +72,17 @@ type CustomCopilotModelConfig = (apiKey: string, prompt: {
|
|
|
72
72
|
*/
|
|
73
73
|
body?: Record<string, unknown>;
|
|
74
74
|
};
|
|
75
|
-
type CustomCopilotModelTransformResponse = (response: unknown) =>
|
|
75
|
+
type CustomCopilotModelTransformResponse = (response: unknown) => {
|
|
76
|
+
/**
|
|
77
|
+
* The text generated by the custom model.
|
|
78
|
+
*/
|
|
79
|
+
text: string | null;
|
|
80
|
+
/**
|
|
81
|
+
* The text generated by the custom model.
|
|
82
|
+
* @deprecated Use `text` instead. This property will be removed in a future version.
|
|
83
|
+
*/
|
|
84
|
+
completion: string | null;
|
|
85
|
+
};
|
|
76
86
|
|
|
77
87
|
type Monaco = typeof monaco;
|
|
78
88
|
type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
package/build/index.d.ts
CHANGED
|
@@ -72,7 +72,17 @@ type CustomCopilotModelConfig = (apiKey: string, prompt: {
|
|
|
72
72
|
*/
|
|
73
73
|
body?: Record<string, unknown>;
|
|
74
74
|
};
|
|
75
|
-
type CustomCopilotModelTransformResponse = (response: unknown) =>
|
|
75
|
+
type CustomCopilotModelTransformResponse = (response: unknown) => {
|
|
76
|
+
/**
|
|
77
|
+
* The text generated by the custom model.
|
|
78
|
+
*/
|
|
79
|
+
text: string | null;
|
|
80
|
+
/**
|
|
81
|
+
* The text generated by the custom model.
|
|
82
|
+
* @deprecated Use `text` instead. This property will be removed in a future version.
|
|
83
|
+
*/
|
|
84
|
+
completion: string | null;
|
|
85
|
+
};
|
|
76
86
|
|
|
77
87
|
type Monaco = typeof monaco;
|
|
78
88
|
type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
package/build/index.js
CHANGED
|
@@ -1,32 +1,33 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`);return o[o.length-1].length+1};var k=(e,o)=>o.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:e.lineNumber,endColumn:e.column}),H=(e,o)=>o.getValueInRange({startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:o.getLineCount(),endColumn:o.getLineMaxColumn(o.getLineCount())});var Q=async(e,o,t={})=>{let
|
|
1
|
+
"use strict";var w=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var Ce=Object.getOwnPropertyNames;var ge=Object.prototype.hasOwnProperty;var he=(e,o)=>{for(var t in o)w(e,t,{get:o[t],enumerable:!0})},fe=(e,o,t,n)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of Ce(o))!ge.call(e,r)&&r!==t&&w(e,r,{get:()=>o[r],enumerable:!(n=ue(o,r))||n.enumerable});return e};var Pe=e=>fe(w({},"__esModule",{value:!0}),e);var Be={};he(Be,{Copilot:()=>I,registerCompletion:()=>j,registerCopilot:()=>me});module.exports=Pe(Be);var N=["groq","openai","anthropic"],G={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini","claude-3.5-sonnet":"claude-3.5-sonnet-20240620","claude-3-opus":"claude-3-opus-20240229","claude-3-sonnet":"claude-3-sonnet-20240229","claude-3-haiku":"claude-3-haiku-20240307","o1-preview":"o1-preview","o1-mini":"o1-mini"},D={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini","o1-preview","o1-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},K="llama-3-70b",Y="groq",X={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},y=.3;var z=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var P=class P{constructor(){}static getInstance(){return P.instance}handleError(o,t){let n=this.getErrorDetails(o),r=`\x1B[31m[${t}]\x1B[0m \x1B[1m${n.message}\x1B[0m`;return console.error(r),n}getErrorDetails(o){return o instanceof Error?{message:o.message,name:o.name,stack:o.stack,context:o.context}:{message:String(o),name:"UnknownError"}}};P.instance=new P;var S=P;var C=(e,o)=>S.getInstance().handleError(e,o);var B=(e,o)=>{let t=null,n=null,r=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),n&&n("Cancelled")),n=s,t=setTimeout(()=>{a(e(...i)),n=null},o)});return r.cancel=()=>{t&&(clearTimeout(t),n&&n("Cancelled"),t=null,n=null)},r},E=e=>!e||e.length===0?"":e.length===1?e[0]:`${e.slice(0,-1).join(", ")} and ${e.slice(-1)}`;var R=(e,o)=>o.getLineContent(e.lineNumber)[e.column-1],J=(e,o)=>o.getLineContent(e.lineNumber).slice(e.column-1),h=(e,o)=>o.getLineContent(e.lineNumber).slice(0,e.column-1),Z=e=>{let o=e.split(`
|
|
2
|
+
`);return o[o.length-1].length+1};var k=(e,o)=>o.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:e.lineNumber,endColumn:e.column}),H=(e,o)=>o.getValueInRange({startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:o.getLineCount(),endColumn:o.getLineMaxColumn(o.getLineCount())});var Q=async(e,o,t={})=>{let n={"Content-Type":"application/json",...t.headers},r=o==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(e,{method:o,headers:n,body:r,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},Ee=(e,o)=>Q(e,"GET",o),Te=(e,o,t)=>Q(e,"POST",{...t,body:o}),M={GET:Ee,POST:Te};var ee=(e,o)=>{let t=R(e,o);return!!t&&!z.has(t)},oe=(e,o)=>{let t=J(e,o).trim(),n=h(e,o).trim();return e.column<=3&&(t!==""||n!=="")};var O="<<CURSOR>>",te=e=>e==="javascript"?"latest JavaScript":e,ne=e=>{switch(e){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},xe=e=>{let o=te(e.language),t=ne(e.editorState.completionMode);return`You are an AI coding assistant with expertise in${o?` ${o}`:""} programming, specializing in ${t}. Your goal is to provide accurate, efficient, and context-aware code completions that align with the existing code and the developer's intent. Provide code that is syntactically correct, follows best practices, and integrates seamlessly with the provided code snippet.`},ye=(e,o)=>{if(!e?.length&&!o)return"";let t=e?` using ${E(e)}`:"",n=te(o);return`The code is written${n?` in ${n}`:""}${t}.`},Re=e=>{let{filename:o,language:t,technologies:n,editorState:{completionMode:r},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=e,p=ne(r),d=o?`the file named "${o}"`:"a larger project",l=`Please assist with ${p} for the following code snippet, which is part of ${d}.
|
|
3
3
|
|
|
4
|
-
`;return l+=ye(
|
|
4
|
+
`;return l+=ye(n,t),l+=`
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
Please follow these guidelines when generating the completion:
|
|
7
|
+
- The cursor position is indicated by '${O}' in the code snippet.
|
|
8
|
+
- Begin your completion exactly at the cursor position.
|
|
9
|
+
- Do not duplicate any code that appears before or after the cursor in the provided snippet.
|
|
10
|
+
- Ensure that the completed code is syntactically correct and logically consistent with the surrounding code.
|
|
11
|
+
- Maintain the coding style and conventions used in the existing code.
|
|
12
|
+
- Optimize the code for readability and performance where applicable.
|
|
13
|
+
- Do not include any additional explanations or comments in your output.
|
|
14
|
+
- Output only the code completion, without wrapping it in markdown code syntax (e.g., no triple backticks).`,r==="fill-in-the-middle"?l+=`
|
|
15
|
+
- Since you are filling in the middle, replace '${O}' entirely with your completion.`:r==="completion"&&(l+=`
|
|
16
|
+
- Since you are completing the code, provide a logical continuation starting from '${O}'.`),l+=`
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
Here's the code snippet for completion:
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
${i}${M}${a}
|
|
21
|
-
</code>`,s&&s.length>0&&(l+=`
|
|
20
|
+
<code>
|
|
21
|
+
${i}${O}${a}
|
|
22
|
+
</code>`,s&&s.length>0&&(l+=`
|
|
22
23
|
|
|
23
24
|
Additional context from related files:
|
|
24
25
|
|
|
25
26
|
`,l+=s.map(c=>`// Path: ${c.path}
|
|
26
27
|
${c.content}
|
|
27
28
|
`).join(`
|
|
28
|
-
`)),l.endsWith(".")?l:`${l}.`};function q(e){return{system:xe(e),user:Re(e)}}var
|
|
29
|
+
`)),l.endsWith(".")?l:`${l}.`};function q(e){return{system:xe(e),user:Re(e)}}var re={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var Me={createRequestBody:(e,o)=>{let n=e==="o1-preview"||e==="o1-mini"?[{role:"user",content:o.user}]:[{role:"system",content:o.system},{role:"user",content:o.user}];return{model:F(e),temperature:y,messages:n}},createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Oe={createRequestBody:(e,o)=>({model:F(e),temperature:y,messages:[{role:"system",content:o.system},{role:"user",content:o.user}]}),createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Ie={createRequestBody:(e,o)=>({model:F(e),temperature:y,system:o.system,messages:[{role:"user",content:o.user}],max_tokens:ve(e)}),createHeaders:e=>({"Content-Type":"application/json","x-api-key":e,"anthropic-version":"2023-06-01"}),parseCompletion:e=>!e.content||typeof e.content!="string"?null:e.content},$={openai:Me,groq:Oe,anthropic:Ie},ie=(e,o,t)=>$[o].createRequestBody(e,t),se=(e,o)=>$[o].createHeaders(e),le=(e,o)=>$[o].parseCompletion(e),F=e=>G[e],ae=e=>X[e],ve=e=>re[e]||4096;var I=class{constructor(o,t={}){if(!o)throw new Error("Please provide an API key.");this.apiKey=o,this.provider=t.provider??Y,this.model=t.model??K,this.validateInputs()}validateInputs(){if(!N.includes(this.provider))throw new Error(`The provider "${this.provider}" is not supported. Please choose a supported provider: ${E(N)}. If you're using a custom model, you don't need to specify a provider.`);if(typeof this.model=="string"&&!D[this.provider].includes(this.model)){let o=E(D[this.provider]);throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${o}`)}}async complete(o){let{body:t,options:n}=o,{completionMetadata:r}=t,{headers:i={},customPrompt:a}=n??{},s=q(r),p=a?{...s,...a(r)}:s,d=ae(this.provider),l,c=se(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let m=this.model.config(this.apiKey,p);d=m.endpoint??d,l=m.body??{},c={...c,...m.headers}}else l=ie(this.model,this.provider,p);c={...c,...i};try{let m=await M.POST(d,l,{headers:c}),u;if(typeof this.model=="object"&&"transformResponse"in this.model){let f=this.model.transformResponse(m);u={completion:f.text??f.completion}}else u={completion:le(m,this.provider)};return u}catch(m){return{error:C(m,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}};var v=class e{constructor(o){this.formattedCompletion="";this.formattedCompletion=o}static create(o){return new e(o)}setCompletion(o){return this.formattedCompletion=o,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(o){let t=/```[\s\S]*?```/g,n=o,r;for(;(r=t.exec(o))!==null;){let i=r[0],a=i.split(`
|
|
29
30
|
`).slice(1,-1).join(`
|
|
30
|
-
`);
|
|
31
|
+
`);n=n.replace(i,a)}return n.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
31
32
|
|
|
32
|
-
`),this}build(){return this.formattedCompletion}};var
|
|
33
|
+
`),this}build(){return this.formattedCompletion}};var b=class{constructor(o,t){this.cursorPosition=o,this.model=t}shouldProvideCompletions(){return!ee(this.cursorPosition,this.model)&&!oe(this.cursorPosition,this.model)}};var A=class A{constructor(){this.cache=[]}getCompletionCache(o,t){return this.cache.filter(n=>this.isCacheItemValid(n,o,t))}addCompletionCache(o){this.cache=[...this.cache.slice(-(A.MAX_CACHE_SIZE-1)),o]}clearCompletionCache(){this.cache=[]}isCacheItemValid(o,t,n){let r=n.getValueInRange(o.range);return h(t,n).startsWith(o.textBeforeCursorInLine)&&this.isPositionValid(o,t,r)}isPositionValid(o,t,n){return o.range.startLineNumber===t.lineNumber&&t.column===o.range.startColumn||o.completion.startsWith(n)&&o.range.startLineNumber===t.lineNumber&&t.column>=o.range.startColumn-n.length&&t.column<=o.range.endColumn}};A.MAX_CACHE_SIZE=10;var L=A;var be="application/json",V=async({filename:e,endpoint:o,language:t,technologies:n,externalContext:r,model:i,position:a})=>{try{let{completion:s}=await M.POST(o,{completionMetadata:Le({filename:e,position:a,model:i,language:t,technologies:n,externalContext:r})},{headers:{"Content-Type":be},error:"Error while fetching completion item"});return s}catch(s){return C(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},Le=({filename:e,position:o,model:t,language:n,technologies:r,externalContext:i})=>{let a=Ae(o,t),s=k(o,t),p=H(o,t);return{filename:e,language:n,technologies:r,externalContext:i,textBeforeCursor:s,textAfterCursor:p,cursorPosition:o,editorState:{completionMode:a}}},Ae=(e,o)=>{let t=k(e,o),n=H(e,o);return t&&n?"fill-in-the-middle":"completion"};var pe=(e,o,t,n)=>{let r=(e.match(/\n/g)||[]).length,i=Z(e),a=R(t,n);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+r,endColumn:e.includes(a)?t.lineNumber===o.startLineNumber&&r===0?t.column+(i-1):i:t.column}};function ce(e){return v.create(e).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var g=e=>({items:e,enableForwardStability:!0});var _e=300,we=600,Ne={onTyping:B(V,_e),onIdle:B(V,we)},_=new L,De=async({monaco:e,model:o,position:t,token:n,isCompletionAccepted:r,onShowCompletion:i,options:a})=>{let{trigger:s="onIdle",...p}=a;if(!new b(t,o).shouldProvideCompletions())return g([]);let d=_.getCompletionCache(t,o).map(l=>({insertText:l.completion,range:l.range}));if(d.length>0)return i(),g(d);if(n.isCancellationRequested||r)return g([]);try{let l=s==="onTyping"?"onTyping":"onIdle",c=Ne[l];n.onCancellationRequested(()=>{c.cancel()});let m=await c({...p,text:o.getValue(),model:o,position:t});if(m){let u=ce(m),f=new e.Range(t.lineNumber,t.column,t.lineNumber,t.column),W=pe(u,f,t,o);return _.addCompletionCache({completion:u,range:W,textBeforeCursorInLine:h(t,o)}),i(),g([{insertText:u,range:W}])}}catch(l){if(Se(l))return g([]);C(l,"FETCH_COMPLETION_ITEM_ERROR")}return g([])},Se=e=>typeof e=="string"&&(e==="Cancelled"||e==="AbortError")||e instanceof Error&&(e.message==="Cancelled"||e.name==="AbortError"),de=De;var T=new WeakMap,x=null,j=(e,o,t)=>{x&&x.deregister();let n=[];T.set(o,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let r=e.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,p,d,l)=>{let c=T.get(o);if(c)return de({monaco:e,model:s,position:p,token:l,isCompletionAccepted:c.isCompletionAccepted,onShowCompletion:()=>{c.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});n.push(r);let i=o.onKeyDown(s=>{let p=T.get(o);if(!p)return;let d=s.keyCode===e.KeyCode.Tab||s.keyCode===e.KeyCode.RightArrow&&s.metaKey;p.isCompletionVisible&&d?(p.isCompletionAccepted=!0,p.isCompletionVisible=!1):p.isCompletionAccepted=!1});n.push(i);let a={deregister:()=>{n.forEach(s=>s.dispose()),_.clearCompletionCache(),T.delete(o),x=null}};return x=a,a}catch(r){return C(r,"REGISTER_COMPLETION_ERROR"),{deregister:()=>{n.forEach(i=>i.dispose()),T.delete(o),x=null}}}},me=j;0&&(module.exports={Copilot,registerCompletion,registerCopilot});
|
package/build/index.mjs
CHANGED
|
@@ -1,32 +1,33 @@
|
|
|
1
|
-
var _=["groq","openai","anthropic"],j={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini","claude-3.5-sonnet":"claude-3.5-sonnet-20240620","claude-3-opus":"claude-3-opus-20240229","claude-3-sonnet":"claude-3-sonnet-20240229","claude-3-haiku":"claude-3-haiku-20240307","o1-preview":"o1-preview","o1-mini":"o1-mini"},
|
|
2
|
-
`);return o[o.length-1].length+1};var S=(e,o)=>o.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:e.lineNumber,endColumn:e.column}),B=(e,o)=>o.getValueInRange({startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:o.getLineCount(),endColumn:o.getLineMaxColumn(o.getLineCount())});var
|
|
1
|
+
var _=["groq","openai","anthropic"],j={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini","claude-3.5-sonnet":"claude-3.5-sonnet-20240620","claude-3-opus":"claude-3-opus-20240229","claude-3-sonnet":"claude-3-sonnet-20240229","claude-3-haiku":"claude-3-haiku-20240307","o1-preview":"o1-preview","o1-mini":"o1-mini"},w={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini","o1-preview","o1-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},W="llama-3-70b",G="groq",K={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},y=.3;var Y=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var P=class P{constructor(){}static getInstance(){return P.instance}handleError(o,t){let n=this.getErrorDetails(o),r=`\x1B[31m[${t}]\x1B[0m \x1B[1m${n.message}\x1B[0m`;return console.error(r),n}getErrorDetails(o){return o instanceof Error?{message:o.message,name:o.name,stack:o.stack,context:o.context}:{message:String(o),name:"UnknownError"}}};P.instance=new P;var N=P;var C=(e,o)=>N.getInstance().handleError(e,o);var D=(e,o)=>{let t=null,n=null,r=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),n&&n("Cancelled")),n=s,t=setTimeout(()=>{a(e(...i)),n=null},o)});return r.cancel=()=>{t&&(clearTimeout(t),n&&n("Cancelled"),t=null,n=null)},r},E=e=>!e||e.length===0?"":e.length===1?e[0]:`${e.slice(0,-1).join(", ")} and ${e.slice(-1)}`;var R=(e,o)=>o.getLineContent(e.lineNumber)[e.column-1],X=(e,o)=>o.getLineContent(e.lineNumber).slice(e.column-1),h=(e,o)=>o.getLineContent(e.lineNumber).slice(0,e.column-1),z=e=>{let o=e.split(`
|
|
2
|
+
`);return o[o.length-1].length+1};var S=(e,o)=>o.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:e.lineNumber,endColumn:e.column}),B=(e,o)=>o.getValueInRange({startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:o.getLineCount(),endColumn:o.getLineMaxColumn(o.getLineCount())});var J=async(e,o,t={})=>{let n={"Content-Type":"application/json",...t.headers},r=o==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(e,{method:o,headers:n,body:r,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},de=(e,o)=>J(e,"GET",o),me=(e,o,t)=>J(e,"POST",{...t,body:o}),M={GET:de,POST:me};var Z=(e,o)=>{let t=R(e,o);return!!t&&!Y.has(t)},Q=(e,o)=>{let t=X(e,o).trim(),n=h(e,o).trim();return e.column<=3&&(t!==""||n!=="")};var O="<<CURSOR>>",ee=e=>e==="javascript"?"latest JavaScript":e,oe=e=>{switch(e){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},ue=e=>{let o=ee(e.language),t=oe(e.editorState.completionMode);return`You are an AI coding assistant with expertise in${o?` ${o}`:""} programming, specializing in ${t}. Your goal is to provide accurate, efficient, and context-aware code completions that align with the existing code and the developer's intent. Provide code that is syntactically correct, follows best practices, and integrates seamlessly with the provided code snippet.`},Ce=(e,o)=>{if(!e?.length&&!o)return"";let t=e?` using ${E(e)}`:"",n=ee(o);return`The code is written${n?` in ${n}`:""}${t}.`},ge=e=>{let{filename:o,language:t,technologies:n,editorState:{completionMode:r},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=e,p=oe(r),d=o?`the file named "${o}"`:"a larger project",l=`Please assist with ${p} for the following code snippet, which is part of ${d}.
|
|
3
3
|
|
|
4
|
-
`;return l+=Ce(
|
|
4
|
+
`;return l+=Ce(n,t),l+=`
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
Please follow these guidelines when generating the completion:
|
|
7
|
+
- The cursor position is indicated by '${O}' in the code snippet.
|
|
8
|
+
- Begin your completion exactly at the cursor position.
|
|
9
|
+
- Do not duplicate any code that appears before or after the cursor in the provided snippet.
|
|
10
|
+
- Ensure that the completed code is syntactically correct and logically consistent with the surrounding code.
|
|
11
|
+
- Maintain the coding style and conventions used in the existing code.
|
|
12
|
+
- Optimize the code for readability and performance where applicable.
|
|
13
|
+
- Do not include any additional explanations or comments in your output.
|
|
14
|
+
- Output only the code completion, without wrapping it in markdown code syntax (e.g., no triple backticks).`,r==="fill-in-the-middle"?l+=`
|
|
15
|
+
- Since you are filling in the middle, replace '${O}' entirely with your completion.`:r==="completion"&&(l+=`
|
|
16
|
+
- Since you are completing the code, provide a logical continuation starting from '${O}'.`),l+=`
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
Here's the code snippet for completion:
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
${i}${M}${a}
|
|
21
|
-
</code>`,s&&s.length>0&&(l+=`
|
|
20
|
+
<code>
|
|
21
|
+
${i}${O}${a}
|
|
22
|
+
</code>`,s&&s.length>0&&(l+=`
|
|
22
23
|
|
|
23
24
|
Additional context from related files:
|
|
24
25
|
|
|
25
26
|
`,l+=s.map(c=>`// Path: ${c.path}
|
|
26
27
|
${c.content}
|
|
27
28
|
`).join(`
|
|
28
|
-
`)),l.endsWith(".")?l:`${l}.`};function k(e){return{system:ue(e),user:ge(e)}}var te={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var he={createRequestBody:(e,o)=>{let
|
|
29
|
+
`)),l.endsWith(".")?l:`${l}.`};function k(e){return{system:ue(e),user:ge(e)}}var te={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var he={createRequestBody:(e,o)=>{let n=e==="o1-preview"||e==="o1-mini"?[{role:"user",content:o.user}]:[{role:"system",content:o.system},{role:"user",content:o.user}];return{model:q(e),temperature:y,messages:n}},createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},fe={createRequestBody:(e,o)=>({model:q(e),temperature:y,messages:[{role:"system",content:o.system},{role:"user",content:o.user}]}),createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Pe={createRequestBody:(e,o)=>({model:q(e),temperature:y,system:o.system,messages:[{role:"user",content:o.user}],max_tokens:Ee(e)}),createHeaders:e=>({"Content-Type":"application/json","x-api-key":e,"anthropic-version":"2023-06-01"}),parseCompletion:e=>!e.content||typeof e.content!="string"?null:e.content},H={openai:he,groq:fe,anthropic:Pe},ne=(e,o,t)=>H[o].createRequestBody(e,t),re=(e,o)=>H[o].createHeaders(e),ie=(e,o)=>H[o].parseCompletion(e),q=e=>j[e],se=e=>K[e],Ee=e=>te[e]||4096;var $=class{constructor(o,t={}){if(!o)throw new Error("Please provide an API key.");this.apiKey=o,this.provider=t.provider??G,this.model=t.model??W,this.validateInputs()}validateInputs(){if(!_.includes(this.provider))throw new Error(`The provider "${this.provider}" is not supported. Please choose a supported provider: ${E(_)}. If you're using a custom model, you don't need to specify a provider.`);if(typeof this.model=="string"&&!w[this.provider].includes(this.model)){let o=E(w[this.provider]);throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${o}`)}}async complete(o){let{body:t,options:n}=o,{completionMetadata:r}=t,{headers:i={},customPrompt:a}=n??{},s=k(r),p=a?{...s,...a(r)}:s,d=se(this.provider),l,c=re(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let m=this.model.config(this.apiKey,p);d=m.endpoint??d,l=m.body??{},c={...c,...m.headers}}else l=ne(this.model,this.provider,p);c={...c,...i};try{let m=await M.POST(d,l,{headers:c}),u;if(typeof this.model=="object"&&"transformResponse"in this.model){let f=this.model.transformResponse(m);u={completion:f.text??f.completion}}else u={completion:ie(m,this.provider)};return u}catch(m){return{error:C(m,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}};var I=class e{constructor(o){this.formattedCompletion="";this.formattedCompletion=o}static create(o){return new e(o)}setCompletion(o){return this.formattedCompletion=o,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(o){let t=/```[\s\S]*?```/g,n=o,r;for(;(r=t.exec(o))!==null;){let i=r[0],a=i.split(`
|
|
29
30
|
`).slice(1,-1).join(`
|
|
30
|
-
`);
|
|
31
|
+
`);n=n.replace(i,a)}return n.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
31
32
|
|
|
32
|
-
`),this}build(){return this.formattedCompletion}};var
|
|
33
|
+
`),this}build(){return this.formattedCompletion}};var v=class{constructor(o,t){this.cursorPosition=o,this.model=t}shouldProvideCompletions(){return!Z(this.cursorPosition,this.model)&&!Q(this.cursorPosition,this.model)}};var L=class L{constructor(){this.cache=[]}getCompletionCache(o,t){return this.cache.filter(n=>this.isCacheItemValid(n,o,t))}addCompletionCache(o){this.cache=[...this.cache.slice(-(L.MAX_CACHE_SIZE-1)),o]}clearCompletionCache(){this.cache=[]}isCacheItemValid(o,t,n){let r=n.getValueInRange(o.range);return h(t,n).startsWith(o.textBeforeCursorInLine)&&this.isPositionValid(o,t,r)}isPositionValid(o,t,n){return o.range.startLineNumber===t.lineNumber&&t.column===o.range.startColumn||o.completion.startsWith(n)&&o.range.startLineNumber===t.lineNumber&&t.column>=o.range.startColumn-n.length&&t.column<=o.range.endColumn}};L.MAX_CACHE_SIZE=10;var b=L;var Te="application/json",U=async({filename:e,endpoint:o,language:t,technologies:n,externalContext:r,model:i,position:a})=>{try{let{completion:s}=await M.POST(o,{completionMetadata:xe({filename:e,position:a,model:i,language:t,technologies:n,externalContext:r})},{headers:{"Content-Type":Te},error:"Error while fetching completion item"});return s}catch(s){return C(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},xe=({filename:e,position:o,model:t,language:n,technologies:r,externalContext:i})=>{let a=ye(o,t),s=S(o,t),p=B(o,t);return{filename:e,language:n,technologies:r,externalContext:i,textBeforeCursor:s,textAfterCursor:p,cursorPosition:o,editorState:{completionMode:a}}},ye=(e,o)=>{let t=S(e,o),n=B(e,o);return t&&n?"fill-in-the-middle":"completion"};var le=(e,o,t,n)=>{let r=(e.match(/\n/g)||[]).length,i=z(e),a=R(t,n);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+r,endColumn:e.includes(a)?t.lineNumber===o.startLineNumber&&r===0?t.column+(i-1):i:t.column}};function ae(e){return I.create(e).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var g=e=>({items:e,enableForwardStability:!0});var Re=300,Me=600,Oe={onTyping:D(U,Re),onIdle:D(U,Me)},A=new b,Ie=async({monaco:e,model:o,position:t,token:n,isCompletionAccepted:r,onShowCompletion:i,options:a})=>{let{trigger:s="onIdle",...p}=a;if(!new v(t,o).shouldProvideCompletions())return g([]);let d=A.getCompletionCache(t,o).map(l=>({insertText:l.completion,range:l.range}));if(d.length>0)return i(),g(d);if(n.isCancellationRequested||r)return g([]);try{let l=s==="onTyping"?"onTyping":"onIdle",c=Oe[l];n.onCancellationRequested(()=>{c.cancel()});let m=await c({...p,text:o.getValue(),model:o,position:t});if(m){let u=ae(m),f=new e.Range(t.lineNumber,t.column,t.lineNumber,t.column),V=le(u,f,t,o);return A.addCompletionCache({completion:u,range:V,textBeforeCursorInLine:h(t,o)}),i(),g([{insertText:u,range:V}])}}catch(l){if(ve(l))return g([]);C(l,"FETCH_COMPLETION_ITEM_ERROR")}return g([])},ve=e=>typeof e=="string"&&(e==="Cancelled"||e==="AbortError")||e instanceof Error&&(e.message==="Cancelled"||e.name==="AbortError"),pe=Ie;var T=new WeakMap,x=null,ce=(e,o,t)=>{x&&x.deregister();let n=[];T.set(o,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let r=e.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,p,d,l)=>{let c=T.get(o);if(c)return pe({monaco:e,model:s,position:p,token:l,isCompletionAccepted:c.isCompletionAccepted,onShowCompletion:()=>{c.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});n.push(r);let i=o.onKeyDown(s=>{let p=T.get(o);if(!p)return;let d=s.keyCode===e.KeyCode.Tab||s.keyCode===e.KeyCode.RightArrow&&s.metaKey;p.isCompletionVisible&&d?(p.isCompletionAccepted=!0,p.isCompletionVisible=!1):p.isCompletionAccepted=!1});n.push(i);let a={deregister:()=>{n.forEach(s=>s.dispose()),A.clearCompletionCache(),T.delete(o),x=null}};return x=a,a}catch(r){return C(r,"REGISTER_COMPLETION_ERROR"),{deregister:()=>{n.forEach(i=>i.dispose()),T.delete(o),x=null}}}},be=ce;export{$ as Copilot,ce as registerCompletion,be as registerCopilot};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monacopilot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "AI auto-completion plugin for Monaco Editor",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"module": "./build/index.mjs",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
],
|
|
44
44
|
"repository": {
|
|
45
45
|
"type": "git",
|
|
46
|
-
"url": "https://github.com/arshad-yaseen/monacopilot"
|
|
46
|
+
"url": "git+https://github.com/arshad-yaseen/monacopilot.git"
|
|
47
47
|
},
|
|
48
48
|
"maintainers": [
|
|
49
49
|
{
|