monacopilot 0.9.19 → 0.9.21

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 CHANGED
@@ -9,9 +9,12 @@
9
9
  - [Examples](#examples)
10
10
  - [Installation](#installation)
11
11
  - [Usage](#usage)
12
+ - [Copilot Options](#copilot-options)
13
+ - [Changing the Provider and Model](#changing-the-provider-and-model)
14
+ - [Copilot Completion Request Options](#copilot-completion-request-options)
15
+ - [Custom Headers](#custom-headers)
12
16
  - [Configuration Options](#configuration-options)
13
17
  - [External Context](#external-context)
14
- - [Changing the Provider and Model](#changing-the-provider-and-model)
15
18
  - [Filename](#filename)
16
19
  - [Completions for Specific Technologies](#completions-for-specific-technologies)
17
20
  - [Cost Overview](#cost-overview)
@@ -27,6 +30,7 @@ https://github.com/user-attachments/assets/4af4e24a-1b05-4bee-84aa-1521ad7098cd
27
30
  Here are some examples of how to use Monacopilot in different project setups:
28
31
 
29
32
  - Next.js ([app](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/nextjs/app) | [pages](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/nextjs/pages))
33
+ - [Remix](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/remix)
30
34
 
31
35
  ## Installation
32
36
 
@@ -40,6 +44,8 @@ npm install monacopilot
40
44
 
41
45
  #### Setting Up the API Key
42
46
 
47
+ In this example, we'll use Groq as our provider.
48
+
43
49
  Start by obtaining an API key from the [Groq console](https://console.groq.com/keys). Once you have your API key, define it as an environment variable in your project:
44
50
 
45
51
  ```bash
@@ -62,16 +68,22 @@ const copilot = new Copilot(process.env.GROQ_API_KEY);
62
68
  app.use(express.json());
63
69
 
64
70
  app.post('/copilot', async (req, res) => {
65
- const completion = await copilot.complete(req.body);
71
+ const completion = await copilot.complete({
72
+ body: req.body,
73
+ });
66
74
  res.status(200).json(completion);
67
75
  });
68
76
 
69
77
  app.listen(port);
70
78
  ```
71
79
 
80
+ Great! Now Monacopilot is all set up to send completion requests to the `/copilot` endpoint and get those completions back. It's like a high-five between your code and the AI!
81
+
82
+ The `copilot.complete` method processes the request body sent by Monacopilot and returns the corresponding completion.
83
+
72
84
  #### Register Copilot with the Monaco Editor
73
85
 
74
- Next, register Copilot with the Monaco editor.
86
+ Now, let's integrate Copilot with the Monaco editor. Here's how you can do it:
75
87
 
76
88
  ```javascript
77
89
  import * as monaco from 'monaco-editor';
@@ -87,6 +99,52 @@ registerCopilot(monaco, editor, {
87
99
  });
88
100
  ```
89
101
 
102
+ - `endpoint`: The URL of the API endpoint that we created in the previous step.
103
+ - `language`: The language of the editor.
104
+
105
+ ## Copilot Options
106
+
107
+ ### Changing the Provider and Model
108
+
109
+ You can specify a different provider and model for completions by setting the `provider` and `model` parameters in the `Copilot` instance.
110
+
111
+ ```javascript
112
+ const copilot = new Copilot(process.env.OPENAI_API_KEY, {
113
+ provider: 'openai',
114
+ model: 'gpt-4o',
115
+ });
116
+ ```
117
+
118
+ The default provider is `groq` and the default model is `llama-3-70b`.
119
+
120
+ | Provider | Model | Description |
121
+ | --------- | ----------------- | ------------------------------------------------------------------------------------------------------------- |
122
+ | Groq | llama-3-70b | Ultra-fast inference (<0.5s response time), balancing speed and quality for a wide range of coding tasks |
123
+ | OpenAI | gpt-4o-mini | Compact version of gpt-4o, offering cost-effective completions with good performance |
124
+ | OpenAI | gpt-4o | State-of-the-art model, excelling in complex reasoning and generating high-quality, context-aware completions |
125
+ | Anthropic | Claude-3.5-Sonnet | Advanced AI with broad knowledge, ideal for diverse coding scenarios and natural language understanding |
126
+ | Anthropic | Claude-3-Opus | Top-tier AI model, exceptional at handling intricate tasks and providing detailed, nuanced completions |
127
+ | Anthropic | Claude-3-Sonnet | Versatile and powerful, offering a great balance between performance and efficiency for various coding needs |
128
+ | Anthropic | Claude-3-Haiku | Streamlined model optimized for speed, perfect for quick completions and real-time coding assistance |
129
+
130
+ ## Copilot Completion Request Options
131
+
132
+ ### Custom Headers
133
+
134
+ You can add custom headers to the provider's completion requests. For example, if you select `OpenAI` as your provider, you can add a custom header to the OpenAI completion requests made by Monacopilot.
135
+
136
+ ```javascript
137
+ copilot.complete({
138
+ body,
139
+ options: {
140
+ // ...other options
141
+ headers: {
142
+ 'X-Custom-Header': 'custom-value',
143
+ },
144
+ },
145
+ });
146
+ ```
147
+
90
148
  ## Configuration Options
91
149
 
92
150
  ### External Context
@@ -108,25 +166,6 @@ registerCopilot(monaco, editor, {
108
166
 
109
167
  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`.
110
168
 
111
- ### Changing the Provider and Model
112
-
113
- You can specify a different provider and model for completions by setting the `provider` and `model` parameters in the `Copilot` instance.
114
-
115
- ```javascript
116
- const copilot = new Copilot(process.env.OPENAI_API_KEY, {
117
- provider: 'openai',
118
- model: 'gpt-4o',
119
- });
120
- ```
121
-
122
- The default provider is `groq` and the default model is `llama-3-70b`.
123
-
124
- | Provider | Model | Description | Avg. Response Time |
125
- | -------- | ----------- | ------------------------------------------------- | ------------------ |
126
- | Groq | llama-3-70b | Fast and efficient, suitable for most tasks | <0.5s |
127
- | OpenAI | gpt-4o-mini | Mini version of gpt-4o, cheaper | 1.5-3s |
128
- | OpenAI | gpt-4o | Highly intelligent, ideal for complex completions | 1-2s |
129
-
130
169
  ### Filename
131
170
 
132
171
  Specify the name of the file being edited to receive more contextually relevant completions.
@@ -153,24 +192,6 @@ registerCopilot(monaco, editor, {
153
192
 
154
193
  This configuration will provide completions relevant to React, Next.js, and Tailwind CSS.
155
194
 
156
- ## Cost Overview
157
-
158
- The cost of completions is very affordable. See the table below for an estimate of the costs you will need to pay for completions.
159
-
160
- | Provider | Model | Avg. Cost per 1000 Code Completions |
161
- | -------- | ----------- | ----------------------------------- |
162
- | Groq | llama-3-70b | $0.939 |
163
- | OpenAI | gpt-4o-mini | $0.821 |
164
- | OpenAI | gpt-4o | $3.46 |
165
-
166
- > **Note:** Currently, Groq does not implement billing, allowing free usage of their API. During this free period, you will experience minimal rate limiting and some latency in completions. You can opt for Groq's enterprise plan to benefit from increased rate limits and get quick completions without visible latency.
167
-
168
- ## FAQ
169
-
170
- ### Is AI Auto Completion Free?
171
-
172
- You use your own Groq or OpenAI API key for AI auto-completion. The cost of completions is very affordable, and we implement various methods to minimize these costs as much as possible. Costs vary depending on the model you use; see this [cost overview](#cost-overview) for an idea of the cost.
173
-
174
195
  ## Contributing
175
196
 
176
197
  For guidelines on contributing, Please read the [contributing guide](https://github.com/arshad-yaseen/monacopilot/blob/main/CONTRIBUTING.md).
package/build/index.d.mts CHANGED
@@ -3,8 +3,20 @@ import * as monaco from 'monaco-editor';
3
3
  type Monaco = typeof monaco;
4
4
  type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
5
5
 
6
+ /**
7
+ * Options for configuring the Copilot instance.
8
+ */
6
9
  interface CopilotOptions {
10
+ /**
11
+ * The completion provider to use (e.g., 'openai', 'anthropic', 'groq').
12
+ * If not specified, a default provider will be used.
13
+ */
7
14
  provider?: CompletionProvider;
15
+ /**
16
+ * The specific model to use for completions.
17
+ * Must be compatible with the chosen provider.
18
+ * If not specified, a default model will be used.
19
+ */
8
20
  model?: CompletionModel;
9
21
  }
10
22
  type Endpoint = string;
@@ -64,11 +76,33 @@ interface CopilotRegistration {
64
76
  deregister: () => void;
65
77
  }
66
78
 
67
- type CompletionModel = 'llama-3-70b' | 'gpt-4o' | 'gpt-4o-mini';
68
- type CompletionProvider = 'openai' | 'groq';
79
+ type OpenAIModel = 'gpt-4o' | 'gpt-4o-mini';
80
+ type GroqModel = 'llama-3-70b';
81
+ type AnthropicModel = 'claude-3.5-sonnet' | 'claude-3-opus' | 'claude-3-haiku' | 'claude-3-sonnet';
82
+ type CompletionModel = OpenAIModel | GroqModel | AnthropicModel;
83
+ type CompletionProvider = 'openai' | 'groq' | 'anthropic';
69
84
  interface CompletionRequest {
85
+ /**
86
+ * The body of the completion request.
87
+ */
88
+ body: CompletionRequestBody;
89
+ /**
90
+ * Additional options to include in the completion request.
91
+ */
92
+ options?: CompletionRequestOptions;
93
+ }
94
+ interface CompletionRequestBody {
95
+ /**
96
+ * The metadata required to generate the completion.
97
+ */
70
98
  completionMetadata: CompletionMetadata;
71
99
  }
100
+ interface CompletionRequestOptions {
101
+ /**
102
+ * Additional headers to include in the provider's completion requests.
103
+ */
104
+ headers?: Record<string, string>;
105
+ }
72
106
  interface CompletionResponse {
73
107
  completion: string | null;
74
108
  error?: string;
@@ -87,29 +121,25 @@ interface CompletionMetadata {
87
121
  }
88
122
 
89
123
  /**
90
- * Copilot class for handling completions using the API.
124
+ * Copilot class for handling completions using various AI providers.
91
125
  */
92
126
  declare class Copilot {
93
127
  private readonly apiKey;
94
- private readonly model;
95
128
  private readonly provider;
129
+ private readonly model;
96
130
  /**
97
131
  * Initializes the Copilot with an API key and optional configuration.
98
- * @param {string} apiKey - The API key.
99
- * @param {CopilotOptions<CompletionProvider>} [options] - Optional parameters to configure the completion model.
100
- * @throws {Error} If the API key is not provided.
132
+ * @param apiKey - The API key for the chosen provider.
133
+ * @param options - Options for configuring the Copilot instance.
101
134
  */
102
135
  constructor(apiKey: string, options?: CopilotOptions);
103
136
  /**
104
- * Sends a completion request to API and returns the completion.
105
- * @param {CompletionRequest} params - The metadata required to generate the completion.
106
- * @returns {Promise<CompletionResponse>} The completed text snippet or an error.
137
+ * Sends a completion request to the API and returns the completion.
138
+ * @param params - The metadata required to generate the completion.
139
+ * @returns A promise resolving to the completed text snippet or an error.
107
140
  */
108
- complete({ completionMetadata, }: CompletionRequest): Promise<CompletionResponse>;
109
- private getEndpoint;
110
- private getModelId;
111
- private createRequestBody;
112
- private createHeaders;
141
+ complete({ body, options, }: CompletionRequest): Promise<CompletionResponse>;
142
+ private validateInputs;
113
143
  }
114
144
 
115
145
  /**
package/build/index.d.ts CHANGED
@@ -3,8 +3,20 @@ import * as monaco from 'monaco-editor';
3
3
  type Monaco = typeof monaco;
4
4
  type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
5
5
 
6
+ /**
7
+ * Options for configuring the Copilot instance.
8
+ */
6
9
  interface CopilotOptions {
10
+ /**
11
+ * The completion provider to use (e.g., 'openai', 'anthropic', 'groq').
12
+ * If not specified, a default provider will be used.
13
+ */
7
14
  provider?: CompletionProvider;
15
+ /**
16
+ * The specific model to use for completions.
17
+ * Must be compatible with the chosen provider.
18
+ * If not specified, a default model will be used.
19
+ */
8
20
  model?: CompletionModel;
9
21
  }
10
22
  type Endpoint = string;
@@ -64,11 +76,33 @@ interface CopilotRegistration {
64
76
  deregister: () => void;
65
77
  }
66
78
 
67
- type CompletionModel = 'llama-3-70b' | 'gpt-4o' | 'gpt-4o-mini';
68
- type CompletionProvider = 'openai' | 'groq';
79
+ type OpenAIModel = 'gpt-4o' | 'gpt-4o-mini';
80
+ type GroqModel = 'llama-3-70b';
81
+ type AnthropicModel = 'claude-3.5-sonnet' | 'claude-3-opus' | 'claude-3-haiku' | 'claude-3-sonnet';
82
+ type CompletionModel = OpenAIModel | GroqModel | AnthropicModel;
83
+ type CompletionProvider = 'openai' | 'groq' | 'anthropic';
69
84
  interface CompletionRequest {
85
+ /**
86
+ * The body of the completion request.
87
+ */
88
+ body: CompletionRequestBody;
89
+ /**
90
+ * Additional options to include in the completion request.
91
+ */
92
+ options?: CompletionRequestOptions;
93
+ }
94
+ interface CompletionRequestBody {
95
+ /**
96
+ * The metadata required to generate the completion.
97
+ */
70
98
  completionMetadata: CompletionMetadata;
71
99
  }
100
+ interface CompletionRequestOptions {
101
+ /**
102
+ * Additional headers to include in the provider's completion requests.
103
+ */
104
+ headers?: Record<string, string>;
105
+ }
72
106
  interface CompletionResponse {
73
107
  completion: string | null;
74
108
  error?: string;
@@ -87,29 +121,25 @@ interface CompletionMetadata {
87
121
  }
88
122
 
89
123
  /**
90
- * Copilot class for handling completions using the API.
124
+ * Copilot class for handling completions using various AI providers.
91
125
  */
92
126
  declare class Copilot {
93
127
  private readonly apiKey;
94
- private readonly model;
95
128
  private readonly provider;
129
+ private readonly model;
96
130
  /**
97
131
  * Initializes the Copilot with an API key and optional configuration.
98
- * @param {string} apiKey - The API key.
99
- * @param {CopilotOptions<CompletionProvider>} [options] - Optional parameters to configure the completion model.
100
- * @throws {Error} If the API key is not provided.
132
+ * @param apiKey - The API key for the chosen provider.
133
+ * @param options - Options for configuring the Copilot instance.
101
134
  */
102
135
  constructor(apiKey: string, options?: CopilotOptions);
103
136
  /**
104
- * Sends a completion request to API and returns the completion.
105
- * @param {CompletionRequest} params - The metadata required to generate the completion.
106
- * @returns {Promise<CompletionResponse>} The completed text snippet or an error.
137
+ * Sends a completion request to the API and returns the completion.
138
+ * @param params - The metadata required to generate the completion.
139
+ * @returns A promise resolving to the completed text snippet or an error.
107
140
  */
108
- complete({ completionMetadata, }: CompletionRequest): Promise<CompletionResponse>;
109
- private getEndpoint;
110
- private getModelId;
111
- private createRequestBody;
112
- private createHeaders;
141
+ complete({ body, options, }: CompletionRequest): Promise<CompletionResponse>;
142
+ private validateInputs;
113
143
  }
114
144
 
115
145
  /**
package/build/index.js CHANGED
@@ -1,36 +1,38 @@
1
- "use strict";var N=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var me=Object.getOwnPropertyNames;var pe=Object.prototype.hasOwnProperty;var ce=(o,e)=>{for(var t in e)N(o,t,{get:e[t],enumerable:!0})},de=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of me(e))!pe.call(o,n)&&n!==t&&N(o,n,{get:()=>e[n],enumerable:!(r=ae(e,n))||r.enumerable});return o};var ue=o=>de(N({},"__esModule",{value:!0}),o);var Me={};ce(Me,{Copilot:()=>I,registerCopilot:()=>ie});module.exports=ue(Me);var k={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini"},w={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini"]},F="llama-3-70b",H="groq",U={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions"},q={temperature:.3};var V=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var f=class f{static getInstance(){return f.instance}handleError(e,t){let r=this.getErrorDetails(e);return this.logError(t,r),r}getErrorDetails(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack,context:e.context}:{message:String(e),name:"UnknownError"}}styleMessage(e,t){let r=this.getTimestamp(),n="Please create an issue on GitHub if the issue persists.",i=80,a="\u2500".repeat(i-2),s=`\u250C${a}\u2510`,l=`\u2514${a}\u2518`,m=((C,se)=>{let le=C.split(" "),A=[],g="";return le.forEach(B=>{(g+B).length>se&&(A.push(g.trim()),g=""),g+=B+" "}),g.trim()&&A.push(g.trim()),A})(e,i-4),p=[s,...m.map(C=>`\u2502 ${C.padEnd(i-4)} \u2502`),l].join(`
1
+ "use strict";var S=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var he=Object.getOwnPropertyNames;var fe=Object.prototype.hasOwnProperty;var Ee=(o,e)=>{for(var t in e)S(o,t,{get:e[t],enumerable:!0})},Te=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of he(e))!fe.call(o,n)&&n!==t&&S(o,n,{get:()=>e[n],enumerable:!(r=ge(e,n))||r.enumerable});return o};var Pe=o=>Te(S({},"__esModule",{value:!0}),o);var Se={};Ee(Se,{Copilot:()=>b,registerCopilot:()=>de});module.exports=Pe(Se);var U={"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"},D={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},k="llama-3-70b",P="groq",V={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},j=.3;var W=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var x=class o{constructor(){}static getInstance(){return o.instance||(o.instance=new o),o.instance}error(e,t){console.error(this.styleMessage(t.message,e,"error")),t.stack&&console.error(this.styleStackTrace(t.stack))}warn(e,t){console.warn(this.styleMessage(t,e,"warning"))}styleMessage(e,t,r){let n=this.getTimestamp(),i="Please create an issue on GitHub if the issue persists.",l=100,s="\u2500".repeat(l-2),a=`\u250C${s}\u2510`,c=`\u2514${s}\u2518`,m=((w,ue)=>{let Ce=w.split(" "),_=[],C="";return Ce.forEach(F=>{(C+F).length>ue&&(_.push(C.trim()),C=""),C+=F+" "}),C.trim()&&_.push(C.trim()),_})(e,l-4),T=[a,...m.map(w=>`\u2502 ${w.padEnd(l-4)} \u2502`),c].join(`
2
2
  `);return`
3
- \x1B[1m\x1B[37m[${r}]\x1B[0m \x1B[31m[${t}]\x1B[0m \x1B[2m${n}\x1B[0m
4
- ${p}
5
- `}logError(e,t){console.error(this.styleMessage(t.message,e))}getTimestamp(){return new Date().toISOString()}};f.instance=new f;var _=f;var d=(o,e)=>_.getInstance().handleError(o,e);var j=(o,e)=>{let t=null,r=null,n=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),r&&r("Cancelled")),r=s,t=setTimeout(()=>{a(o(...i)),r=null},e)});return n.cancel=()=>{t&&(clearTimeout(t),r&&r("Cancelled"),t=null,r=null)},n},P=o=>!o||o.length===0?"":o.length===1?o[0]:`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`;var x=(o,e)=>e.getLineContent(o.lineNumber)[o.column-1],W=(o,e)=>e.getLineContent(o.lineNumber).slice(o.column-1),h=(o,e)=>e.getLineContent(o.lineNumber).slice(0,o.column-1),G=o=>{let e=o.split(`
6
- `);return e[e.length-1].length+1};var S=(o,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:o.lineNumber,endColumn:o.column}),D=(o,e)=>e.getValueInRange({startLineNumber:o.lineNumber,startColumn:o.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())});var Y=async(o,e,t={})=>{let r={"Content-Type":"application/json",...t.headers},n=e==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(o,{method:e,headers:r,body:n,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},Ce=(o,e)=>Y(o,"GET",e),ge=(o,e,t)=>Y(o,"POST",{...t,body:e}),M={GET:Ce,POST:ge};var K=(o,e)=>{let t=x(o,e);return!!t&&!V.has(t)},J=(o,e)=>{let t=W(o,e).trim(),r=h(o,e).trim();return o.column<=3&&(t!==""||r!=="")};var y="<<CURSOR>>",X=o=>o==="javascript"?"latest JavaScript":o,z=o=>{switch(o){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},Z=o=>{let e=X(o.language),t=z(o.editorState.completionMode),r=e?` ${e}`:"";return`You are an advanced AI coding assistant with expertise in ${t} for${r} programming. Your goal is to provide accurate, efficient, and context-aware code completions. Remember, your role is to act as an extension of the developer's thought process, providing intelligent and contextually appropriate code completions.`},he=(o,e)=>{if(!o?.length&&!e)return"";let t=o?` using ${P(o)}`:"",r=X(e);return`The code is written${r?` in ${r}`:""}${t}.`},Q=o=>{let{filename:e,language:t,technologies:r,editorState:{completionMode:n},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=o,l=z(n),c=e?`the file named "${e}"`:"a larger project",m=`You are tasked with ${l} for a code snippet. The code is part of ${c}.
3
+ \x1B[1m\x1B[37m[${n}]\x1B[0m${r==="error"?"\x1B[31m":"\x1B[33m"} [${t}]\x1B[0m \x1B[2m${i}\x1B[0m
4
+ ${T}
5
+ `}styleStackTrace(e){return e.split(`
6
+ `).map((n,i)=>i===0?`\x1B[31m${n}\x1B[0m`:`\x1B[2m${n}\x1B[0m`).join(`
7
+ `)}getTimestamp(){return new Date().toISOString()}};var h=class h{constructor(){this.logger=x.getInstance()}static getInstance(){return h.instance}handleError(e,t){let r=this.getErrorDetails(e);return this.logger.error(t,r),r}getErrorDetails(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack,context:e.context}:{message:String(e),name:"UnknownError"}}};h.instance=new h;var B=h;var d=(o,e)=>B.getInstance().handleError(o,e);var G={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var Y=(o,e)=>{let t=null,r=null,n=(...i)=>new Promise((l,s)=>{t&&(clearTimeout(t),r&&r("Cancelled")),r=s,t=setTimeout(()=>{l(o(...i)),r=null},e)});return n.cancel=()=>{t&&(clearTimeout(t),r&&r("Cancelled"),t=null,r=null)},n},M=o=>!o||o.length===0?"":o.length===1?o[0]:`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`;var y=(o,e)=>e.getLineContent(o.lineNumber)[o.column-1],K=(o,e)=>e.getLineContent(o.lineNumber).slice(o.column-1),g=(o,e)=>e.getLineContent(o.lineNumber).slice(0,o.column-1),X=o=>{let e=o.split(`
8
+ `);return e[e.length-1].length+1};var $=(o,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:o.lineNumber,endColumn:o.column}),H=(o,e)=>e.getValueInRange({startLineNumber:o.lineNumber,startColumn:o.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())});var z=async(o,e,t={})=>{let r={"Content-Type":"application/json",...t.headers},n=e==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(o,{method:e,headers:r,body:n,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},xe=(o,e)=>z(o,"GET",e),Me=(o,e,t)=>z(o,"POST",{...t,body:e}),R={GET:xe,POST:Me};var J=(o,e)=>{let t=y(o,e);return!!t&&!W.has(t)},Z=(o,e)=>{let t=K(o,e).trim(),r=g(o,e).trim();return o.column<=3&&(t!==""||r!=="")};var I="<<CURSOR>>",Q=o=>o==="javascript"?"latest JavaScript":o,ee=o=>{switch(o){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},oe=o=>{let e=Q(o.language),t=ee(o.editorState.completionMode),r=e?` ${e}`:"";return`You are an advanced AI coding assistant with expertise in ${t} for${r} programming. Your goal is to provide accurate, efficient, and context-aware code completions. Remember, your role is to act as an extension of the developer's thought process, providing intelligent and contextually appropriate code completions.`},ye=(o,e)=>{if(!o?.length&&!e)return"";let t=o?` using ${M(o)}`:"",r=Q(e);return`The code is written${r?` in ${r}`:""}${t}.`},te=o=>{let{filename:e,language:t,technologies:r,editorState:{completionMode:n},textBeforeCursor:i,textAfterCursor:l,externalContext:s}=o,a=ee(n),c=e?`the file named "${e}"`:"a larger project",p=`You are tasked with ${a} for a code snippet. The code is part of ${c}.
7
9
 
8
- `;return m+=he(r,t),m+=`
10
+ `;return p+=ye(r,t),p+=`
9
11
 
10
12
  Here are the details about how the completion should be generated:
11
- - The cursor position is marked with '${y}'.
13
+ - The cursor position is marked with '${I}'.
12
14
  - Your completion must start exactly at the cursor position.
13
15
  - Do not repeat any code that appears before or after the cursor.
14
16
  - Ensure your completion does not introduce any syntactical or logical errors.
15
- `,n==="fill-in-the-middle"?m+=` - If filling in the middle, replace '${y}' entirely with your completion.
16
- `:n==="completion"&&(m+=` - If completing the code, start from '${y}' and provide a logical continuation.
17
- `),m+=` - Optimize for readability and performance where possible.
17
+ `,n==="fill-in-the-middle"?p+=` - If filling in the middle, replace '${I}' entirely with your completion.
18
+ `:n==="completion"&&(p+=` - If completing the code, start from '${I}' and provide a logical continuation.
19
+ `),p+=` - Optimize for readability and performance where possible.
18
20
 
19
21
  Remember to output only the completion code without any additional explanation, and do not wrap it in markdown code syntax, such as three backticks (\`\`\`).
20
22
 
21
23
  Here's the code snippet for completion:
22
24
 
23
25
  <code>
24
- ${i}${y}${a}
25
- </code>`,s&&s.length>0&&(m+=`
26
+ ${i}${I}${l}
27
+ </code>`,s&&s.length>0&&(p+=`
26
28
 
27
29
  Additional context from related files:
28
30
 
29
- `,m+=s.map(p=>`// Path: ${p.path}
30
- ${p.content}
31
+ `,p+=s.map(m=>`// Path: ${m.path}
32
+ ${m.content}
31
33
  `).join(`
32
- `)),m.endsWith(".")?m:`${m}.`};var fe="application/json",ee=async({filename:o,endpoint:e,language:t,technologies:r,externalContext:n,model:i,position:a})=>{try{let{completion:s}=await M.POST(e,{completionMetadata:Ee({filename:o,position:a,model:i,language:t,technologies:r,externalContext:n})},{headers:{"Content-Type":fe},error:"Error while fetching completion item"});return s}catch(s){return s instanceof Error&&(s.message==="Cancelled"||s.name==="AbortError")||d(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},Ee=({filename:o,position:e,model:t,language:r,technologies:n,externalContext:i})=>{let a=Te(e,t),s=S(e,t),l=D(e,t);return{filename:o,language:r,technologies:n,externalContext:i,textBeforeCursor:s,textAfterCursor:l,editorState:{completionMode:a}}},Te=(o,e)=>{let t=S(o,e),r=D(o,e);return t&&r?"fill-in-the-middle":"completion"};var I=class{constructor(e,t){let{provider:r,model:n}=t||{};if(r&&!n)throw new Error("You must provide a model when setting a provider");if(n&&!r)throw new Error("You must provide a provider when setting a model");if(this.model=n||F,this.provider=r||H,!w[this.provider].includes(this.model))throw new Error(`Model ${this.model} is not supported by ${this.provider} provider. Supported models: ${P(w[this.provider])}`);if(!e)throw new Error(`Please provide ${this.provider} API key.`);this.apiKey=e}async complete({completionMetadata:e}){try{let t=this.createRequestBody(e),r=this.createHeaders(),n=this.getEndpoint(),i=await M.POST(n,t,{headers:r});if(!i.choices?.length)throw new Error("No completion choices received from API");return{completion:i.choices[0].message.content}}catch(t){return{error:d(t,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}getEndpoint(){return U[this.provider]}getModelId(){return k[this.model]}createRequestBody(e){return{...q,model:this.getModelId(),messages:[{role:"system",content:Z(e)},{role:"user",content:Q(e)}]}}createHeaders(){return{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"}}};var R=class o{constructor(e){this.formattedCompletion="";this.formattedCompletion=e}static create(e){return new o(e)}setCompletion(e){return this.formattedCompletion=e,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(e){let t=/```[\s\S]*?```/g,r=e,n;for(;(n=t.exec(e))!==null;){let i=n[0],a=i.split(`
34
+ `)),p.endsWith(".")?p:`${p}.`};var re=(o,e,t)=>{let r=oe(o),n=te(o),l={model:Oe(e),temperature:j},s={openai:{messages:[{role:"system",content:r},{role:"user",content:n}]},groq:{messages:[{role:"system",content:r},{role:"user",content:n}]},anthropic:{system:r,messages:[{role:"user",content:n}],max_tokens:ve(e)}};return{...l,...s[t]}},ne=(o,e)=>{let t={"Content-Type":"application/json"},r={openai:{Authorization:`Bearer ${o}`},groq:{Authorization:`Bearer ${o}`},anthropic:{"x-api-key":o,"anthropic-version":"2023-06-01"}};return{...t,...r[e]}},ie=(o,e)=>{let r={openai:Re,groq:Ie,anthropic:be}[e];if(!r)throw new Error(`Unsupported provider: ${e}`);return r(o)},Re=o=>o.choices?.length?{completion:o.choices[0].message.content}:{completion:null,error:"No completion found in the openai response"},Ie=o=>o.choices?.length?{completion:o.choices[0].message.content}:{completion:null,error:"No completion found in the groq response"},be=o=>o.content?typeof o.content!="string"?{completion:null,error:"Completion content is not a string"}:{completion:o.content}:{completion:null,error:"No completion found in the anthropic response"},Oe=o=>U[o],se=o=>V[o],ve=o=>G[o]||4096;var b=class{constructor(e,t={}){this.validateInputs(e,t),this.apiKey=e,this.provider=t.provider??P,this.model=t.model??k}async complete({body:e,options:t}){let{completionMetadata:r}=e,{headers:n={}}=t??{};try{let i=re(r,this.model,this.provider),l=se(this.provider),s=ne(this.apiKey,this.provider),a={...n,...s},c=await R.POST(l,i,{headers:a});return ie(c,this.provider)}catch(i){return{error:d(i,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}validateInputs(e,t){if(!e)throw new Error(`Please provide ${this.provider??P} API key.`);let{provider:r,model:n}=t;if(r&&!n||!r&&n)throw new Error("Both provider and model must be specified together");let i=r??P,l=n??k;if(!D[i].includes(l)){let s=M(D[i]);throw new Error(`Model ${l} is not supported by ${i} provider. Supported models: ${s}`)}}};var O=class o{constructor(e){this.formattedCompletion="";this.formattedCompletion=e}static create(e){return new o(e)}setCompletion(e){return this.formattedCompletion=e,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(e){let t=/```[\s\S]*?```/g,r=e,n;for(;(n=t.exec(e))!==null;){let i=n[0],l=i.split(`
33
35
  `).slice(1,-1).join(`
34
- `);r=r.replace(i,a)}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
36
+ `);r=r.replace(i,l)}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
35
37
 
36
- `),this}build(){return this.formattedCompletion}};var b=class{constructor(e,t){this.cursorPosition=e,this.model=t}shouldProvideCompletions(){return!K(this.cursorPosition,this.model)&&!J(this.cursorPosition,this.model)}};var L=class L{constructor(){this.cache=[]}getCompletionCache(e,t){return this.cache.filter(r=>this.isCacheItemValid(r,e,t))}addCompletionCache(e){this.cache=[...this.cache.slice(-(L.MAX_CACHE_SIZE-1)),e]}clearCompletionCache(){this.cache=[]}isCacheItemValid(e,t,r){let n=r.getValueInRange(e.range);return h(t,r).startsWith(e.textBeforeCursorInLine)&&this.isPositionValid(e,t,n)}isPositionValid(e,t,r){return e.range.startLineNumber===t.lineNumber&&t.column===e.range.startColumn||e.completion.startsWith(r)&&e.range.startLineNumber===t.lineNumber&&t.column>=e.range.startColumn-r.length&&t.column<=e.range.endColumn}};L.MAX_CACHE_SIZE=10;var O=L;var te=(o,e,t,r)=>{let n=(o.match(/\n/g)||[]).length,i=G(o),a=x(t,r);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+n,endColumn:o.includes(a)?t.lineNumber===e.startLineNumber&&n===0?t.column+(i-1):i:t.column}};function oe(o){return R.create(o).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var u=o=>({items:o,enableForwardStability:!0});var Pe=300,re=j(ee,Pe),v=new O,xe=async({monaco:o,model:e,position:t,token:r,isCompletionAccepted:n,onShowCompletion:i,options:a})=>{if(!new b(t,e).shouldProvideCompletions())return u([]);let s=v.getCompletionCache(t,e).map(l=>({insertText:l.completion,range:l.range}));if(s.length)return i(),u(s);if(r.isCancellationRequested||n)return u([]);try{let l=re({...a,text:e.getValue(),model:e,position:t});r.onCancellationRequested(()=>{re.cancel()});let c=await l;if(c){let m=oe(c),p=new o.Range(t.lineNumber,t.column,t.lineNumber,t.column),C=te(m,p,t,e);return v.addCompletionCache({completion:m,range:C,textBeforeCursorInLine:h(t,e)}),i(),u([{insertText:m,range:C}])}}catch(l){if(l instanceof Error&&(l.message==="Cancelled"||l.name==="AbortError"))return u([]);d(l,"FETCH_COMPLETION_ITEM_ERROR")}return u([])},ne=xe;var E=new WeakMap,T=null,ie=(o,e,t)=>{T&&T.deregister();let r=[];E.set(e,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let n=o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,l,c,m)=>{let p=E.get(e);if(p)return ne({monaco:o,model:s,position:l,token:m,isCompletionAccepted:p.isCompletionAccepted,onShowCompletion:()=>{p.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});r.push(n);let i=e.onKeyDown(s=>{let l=E.get(e);if(!l)return;let c=s.keyCode===o.KeyCode.Tab||s.keyCode===o.KeyCode.RightArrow&&s.metaKey;l.isCompletionVisible&&c?(l.isCompletionAccepted=!0,l.isCompletionVisible=!1):l.isCompletionAccepted=!1});r.push(i);let a={deregister:()=>{r.forEach(s=>s.dispose()),v.clearCompletionCache(),E.delete(e),T=null}};return T=a,a}catch(n){return d(n,"REGISTER_COPILOT_ERROR"),{deregister:()=>{r.forEach(i=>i.dispose()),E.delete(e),T=null}}}};0&&(module.exports={Copilot,registerCopilot});
38
+ `),this}build(){return this.formattedCompletion}};var v=class{constructor(e,t){this.cursorPosition=e,this.model=t}shouldProvideCompletions(){return!J(this.cursorPosition,this.model)&&!Z(this.cursorPosition,this.model)}};var A=class A{constructor(){this.cache=[]}getCompletionCache(e,t){return this.cache.filter(r=>this.isCacheItemValid(r,e,t))}addCompletionCache(e){this.cache=[...this.cache.slice(-(A.MAX_CACHE_SIZE-1)),e]}clearCompletionCache(){this.cache=[]}isCacheItemValid(e,t,r){let n=r.getValueInRange(e.range);return g(t,r).startsWith(e.textBeforeCursorInLine)&&this.isPositionValid(e,t,n)}isPositionValid(e,t,r){return e.range.startLineNumber===t.lineNumber&&t.column===e.range.startColumn||e.completion.startsWith(r)&&e.range.startLineNumber===t.lineNumber&&t.column>=e.range.startColumn-r.length&&t.column<=e.range.endColumn}};A.MAX_CACHE_SIZE=10;var L=A;var Le="application/json",le=async({filename:o,endpoint:e,language:t,technologies:r,externalContext:n,model:i,position:l})=>{try{let{completion:s}=await R.POST(e,{body:{completionMetadata:Ae({filename:o,position:l,model:i,language:t,technologies:r,externalContext:n})}},{headers:{"Content-Type":Le},error:"Error while fetching completion item"});return s}catch(s){return d(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},Ae=({filename:o,position:e,model:t,language:r,technologies:n,externalContext:i})=>{let l=Ne(e,t),s=$(e,t),a=H(e,t);return{filename:o,language:r,technologies:n,externalContext:i,textBeforeCursor:s,textAfterCursor:a,editorState:{completionMode:l}}},Ne=(o,e)=>{let t=$(o,e),r=H(o,e);return t&&r?"fill-in-the-middle":"completion"};var ae=(o,e,t,r)=>{let n=(o.match(/\n/g)||[]).length,i=X(o),l=y(t,r);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+n,endColumn:o.includes(l)?t.lineNumber===e.startLineNumber&&n===0?t.column+(i-1):i:t.column}};function pe(o){return O.create(o).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var u=o=>({items:o,enableForwardStability:!0});var we=300,ce=Y(le,we),N=new L,_e=async({monaco:o,model:e,position:t,token:r,isCompletionAccepted:n,onShowCompletion:i,options:l})=>{if(!new v(t,e).shouldProvideCompletions())return u([]);let s=N.getCompletionCache(t,e).map(a=>({insertText:a.completion,range:a.range}));if(s.length)return i(),u(s);if(r.isCancellationRequested||n)return u([]);try{let a=ce({...l,text:e.getValue(),model:e,position:t});r.onCancellationRequested(()=>{ce.cancel()});let c=await a;if(c){let p=pe(c),m=new o.Range(t.lineNumber,t.column,t.lineNumber,t.column),T=ae(p,m,t,e);return N.addCompletionCache({completion:p,range:T,textBeforeCursorInLine:g(t,e)}),i(),u([{insertText:p,range:T}])}}catch(a){if(typeof a=="string"&&(a==="Cancelled"||a==="AbortError")||a instanceof Error&&(a.message==="Cancelled"||a.name==="AbortError"))return u([]);d(a,"FETCH_COMPLETION_ITEM_ERROR")}return u([])},me=_e;var f=new WeakMap,E=null,de=(o,e,t)=>{E&&E.deregister();let r=[];f.set(e,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let n=o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,a,c,p)=>{let m=f.get(e);if(m)return me({monaco:o,model:s,position:a,token:p,isCompletionAccepted:m.isCompletionAccepted,onShowCompletion:()=>{m.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});r.push(n);let i=e.onKeyDown(s=>{let a=f.get(e);if(!a)return;let c=s.keyCode===o.KeyCode.Tab||s.keyCode===o.KeyCode.RightArrow&&s.metaKey;a.isCompletionVisible&&c?(a.isCompletionAccepted=!0,a.isCompletionVisible=!1):a.isCompletionAccepted=!1});r.push(i);let l={deregister:()=>{r.forEach(s=>s.dispose()),N.clearCompletionCache(),f.delete(e),E=null}};return E=l,l}catch(n){return d(n,"REGISTER_COPILOT_ERROR"),{deregister:()=>{r.forEach(i=>i.dispose()),f.delete(e),E=null}}}};0&&(module.exports={Copilot,registerCopilot});
package/build/index.mjs CHANGED
@@ -1,36 +1,38 @@
1
- var B={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini"},A={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini"]},k="llama-3-70b",F="groq",H={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions"},U={temperature:.3};var q=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var f=class f{static getInstance(){return f.instance}handleError(e,t){let r=this.getErrorDetails(e);return this.logError(t,r),r}getErrorDetails(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack,context:e.context}:{message:String(e),name:"UnknownError"}}styleMessage(e,t){let r=this.getTimestamp(),n="Please create an issue on GitHub if the issue persists.",i=80,a="\u2500".repeat(i-2),s=`\u250C${a}\u2510`,l=`\u2514${a}\u2518`,m=((C,ne)=>{let ie=C.split(" "),v=[],g="";return ie.forEach($=>{(g+$).length>ne&&(v.push(g.trim()),g=""),g+=$+" "}),g.trim()&&v.push(g.trim()),v})(e,i-4),p=[s,...m.map(C=>`\u2502 ${C.padEnd(i-4)} \u2502`),l].join(`
1
+ var F={"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"},_={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},S="llama-3-70b",P="groq",U={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},V=.3;var j=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var x=class o{constructor(){}static getInstance(){return o.instance||(o.instance=new o),o.instance}error(e,t){console.error(this.styleMessage(t.message,e,"error")),t.stack&&console.error(this.styleStackTrace(t.stack))}warn(e,t){console.warn(this.styleMessage(t,e,"warning"))}styleMessage(e,t,r){let n=this.getTimestamp(),i="Please create an issue on GitHub if the issue persists.",l=100,s="\u2500".repeat(l-2),a=`\u250C${s}\u2510`,c=`\u2514${s}\u2518`,m=((N,me)=>{let de=N.split(" "),w=[],C="";return de.forEach(q=>{(C+q).length>me&&(w.push(C.trim()),C=""),C+=q+" "}),C.trim()&&w.push(C.trim()),w})(e,l-4),T=[a,...m.map(N=>`\u2502 ${N.padEnd(l-4)} \u2502`),c].join(`
2
2
  `);return`
3
- \x1B[1m\x1B[37m[${r}]\x1B[0m \x1B[31m[${t}]\x1B[0m \x1B[2m${n}\x1B[0m
4
- ${p}
5
- `}logError(e,t){console.error(this.styleMessage(t.message,e))}getTimestamp(){return new Date().toISOString()}};f.instance=new f;var N=f;var d=(o,e)=>N.getInstance().handleError(o,e);var V=(o,e)=>{let t=null,r=null,n=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),r&&r("Cancelled")),r=s,t=setTimeout(()=>{a(o(...i)),r=null},e)});return n.cancel=()=>{t&&(clearTimeout(t),r&&r("Cancelled"),t=null,r=null)},n},P=o=>!o||o.length===0?"":o.length===1?o[0]:`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`;var x=(o,e)=>e.getLineContent(o.lineNumber)[o.column-1],j=(o,e)=>e.getLineContent(o.lineNumber).slice(o.column-1),h=(o,e)=>e.getLineContent(o.lineNumber).slice(0,o.column-1),W=o=>{let e=o.split(`
6
- `);return e[e.length-1].length+1};var w=(o,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:o.lineNumber,endColumn:o.column}),_=(o,e)=>e.getValueInRange({startLineNumber:o.lineNumber,startColumn:o.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())});var G=async(o,e,t={})=>{let r={"Content-Type":"application/json",...t.headers},n=e==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(o,{method:e,headers:r,body:n,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},se=(o,e)=>G(o,"GET",e),le=(o,e,t)=>G(o,"POST",{...t,body:e}),M={GET:se,POST:le};var Y=(o,e)=>{let t=x(o,e);return!!t&&!q.has(t)},K=(o,e)=>{let t=j(o,e).trim(),r=h(o,e).trim();return o.column<=3&&(t!==""||r!=="")};var y="<<CURSOR>>",J=o=>o==="javascript"?"latest JavaScript":o,X=o=>{switch(o){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},z=o=>{let e=J(o.language),t=X(o.editorState.completionMode),r=e?` ${e}`:"";return`You are an advanced AI coding assistant with expertise in ${t} for${r} programming. Your goal is to provide accurate, efficient, and context-aware code completions. Remember, your role is to act as an extension of the developer's thought process, providing intelligent and contextually appropriate code completions.`},ae=(o,e)=>{if(!o?.length&&!e)return"";let t=o?` using ${P(o)}`:"",r=J(e);return`The code is written${r?` in ${r}`:""}${t}.`},Z=o=>{let{filename:e,language:t,technologies:r,editorState:{completionMode:n},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=o,l=X(n),c=e?`the file named "${e}"`:"a larger project",m=`You are tasked with ${l} for a code snippet. The code is part of ${c}.
3
+ \x1B[1m\x1B[37m[${n}]\x1B[0m${r==="error"?"\x1B[31m":"\x1B[33m"} [${t}]\x1B[0m \x1B[2m${i}\x1B[0m
4
+ ${T}
5
+ `}styleStackTrace(e){return e.split(`
6
+ `).map((n,i)=>i===0?`\x1B[31m${n}\x1B[0m`:`\x1B[2m${n}\x1B[0m`).join(`
7
+ `)}getTimestamp(){return new Date().toISOString()}};var h=class h{constructor(){this.logger=x.getInstance()}static getInstance(){return h.instance}handleError(e,t){let r=this.getErrorDetails(e);return this.logger.error(t,r),r}getErrorDetails(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack,context:e.context}:{message:String(e),name:"UnknownError"}}};h.instance=new h;var D=h;var d=(o,e)=>D.getInstance().handleError(o,e);var W={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var G=(o,e)=>{let t=null,r=null,n=(...i)=>new Promise((l,s)=>{t&&(clearTimeout(t),r&&r("Cancelled")),r=s,t=setTimeout(()=>{l(o(...i)),r=null},e)});return n.cancel=()=>{t&&(clearTimeout(t),r&&r("Cancelled"),t=null,r=null)},n},M=o=>!o||o.length===0?"":o.length===1?o[0]:`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`;var y=(o,e)=>e.getLineContent(o.lineNumber)[o.column-1],Y=(o,e)=>e.getLineContent(o.lineNumber).slice(o.column-1),g=(o,e)=>e.getLineContent(o.lineNumber).slice(0,o.column-1),K=o=>{let e=o.split(`
8
+ `);return e[e.length-1].length+1};var k=(o,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:o.lineNumber,endColumn:o.column}),B=(o,e)=>e.getValueInRange({startLineNumber:o.lineNumber,startColumn:o.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())});var X=async(o,e,t={})=>{let r={"Content-Type":"application/json",...t.headers},n=e==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(o,{method:e,headers:r,body:n,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},ue=(o,e)=>X(o,"GET",e),Ce=(o,e,t)=>X(o,"POST",{...t,body:e}),R={GET:ue,POST:Ce};var z=(o,e)=>{let t=y(o,e);return!!t&&!j.has(t)},J=(o,e)=>{let t=Y(o,e).trim(),r=g(o,e).trim();return o.column<=3&&(t!==""||r!=="")};var I="<<CURSOR>>",Z=o=>o==="javascript"?"latest JavaScript":o,Q=o=>{switch(o){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},ee=o=>{let e=Z(o.language),t=Q(o.editorState.completionMode),r=e?` ${e}`:"";return`You are an advanced AI coding assistant with expertise in ${t} for${r} programming. Your goal is to provide accurate, efficient, and context-aware code completions. Remember, your role is to act as an extension of the developer's thought process, providing intelligent and contextually appropriate code completions.`},ge=(o,e)=>{if(!o?.length&&!e)return"";let t=o?` using ${M(o)}`:"",r=Z(e);return`The code is written${r?` in ${r}`:""}${t}.`},oe=o=>{let{filename:e,language:t,technologies:r,editorState:{completionMode:n},textBeforeCursor:i,textAfterCursor:l,externalContext:s}=o,a=Q(n),c=e?`the file named "${e}"`:"a larger project",p=`You are tasked with ${a} for a code snippet. The code is part of ${c}.
7
9
 
8
- `;return m+=ae(r,t),m+=`
10
+ `;return p+=ge(r,t),p+=`
9
11
 
10
12
  Here are the details about how the completion should be generated:
11
- - The cursor position is marked with '${y}'.
13
+ - The cursor position is marked with '${I}'.
12
14
  - Your completion must start exactly at the cursor position.
13
15
  - Do not repeat any code that appears before or after the cursor.
14
16
  - Ensure your completion does not introduce any syntactical or logical errors.
15
- `,n==="fill-in-the-middle"?m+=` - If filling in the middle, replace '${y}' entirely with your completion.
16
- `:n==="completion"&&(m+=` - If completing the code, start from '${y}' and provide a logical continuation.
17
- `),m+=` - Optimize for readability and performance where possible.
17
+ `,n==="fill-in-the-middle"?p+=` - If filling in the middle, replace '${I}' entirely with your completion.
18
+ `:n==="completion"&&(p+=` - If completing the code, start from '${I}' and provide a logical continuation.
19
+ `),p+=` - Optimize for readability and performance where possible.
18
20
 
19
21
  Remember to output only the completion code without any additional explanation, and do not wrap it in markdown code syntax, such as three backticks (\`\`\`).
20
22
 
21
23
  Here's the code snippet for completion:
22
24
 
23
25
  <code>
24
- ${i}${y}${a}
25
- </code>`,s&&s.length>0&&(m+=`
26
+ ${i}${I}${l}
27
+ </code>`,s&&s.length>0&&(p+=`
26
28
 
27
29
  Additional context from related files:
28
30
 
29
- `,m+=s.map(p=>`// Path: ${p.path}
30
- ${p.content}
31
+ `,p+=s.map(m=>`// Path: ${m.path}
32
+ ${m.content}
31
33
  `).join(`
32
- `)),m.endsWith(".")?m:`${m}.`};var me="application/json",Q=async({filename:o,endpoint:e,language:t,technologies:r,externalContext:n,model:i,position:a})=>{try{let{completion:s}=await M.POST(e,{completionMetadata:pe({filename:o,position:a,model:i,language:t,technologies:r,externalContext:n})},{headers:{"Content-Type":me},error:"Error while fetching completion item"});return s}catch(s){return s instanceof Error&&(s.message==="Cancelled"||s.name==="AbortError")||d(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},pe=({filename:o,position:e,model:t,language:r,technologies:n,externalContext:i})=>{let a=ce(e,t),s=w(e,t),l=_(e,t);return{filename:o,language:r,technologies:n,externalContext:i,textBeforeCursor:s,textAfterCursor:l,editorState:{completionMode:a}}},ce=(o,e)=>{let t=w(o,e),r=_(o,e);return t&&r?"fill-in-the-middle":"completion"};var D=class{constructor(e,t){let{provider:r,model:n}=t||{};if(r&&!n)throw new Error("You must provide a model when setting a provider");if(n&&!r)throw new Error("You must provide a provider when setting a model");if(this.model=n||k,this.provider=r||F,!A[this.provider].includes(this.model))throw new Error(`Model ${this.model} is not supported by ${this.provider} provider. Supported models: ${P(A[this.provider])}`);if(!e)throw new Error(`Please provide ${this.provider} API key.`);this.apiKey=e}async complete({completionMetadata:e}){try{let t=this.createRequestBody(e),r=this.createHeaders(),n=this.getEndpoint(),i=await M.POST(n,t,{headers:r});if(!i.choices?.length)throw new Error("No completion choices received from API");return{completion:i.choices[0].message.content}}catch(t){return{error:d(t,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}getEndpoint(){return H[this.provider]}getModelId(){return B[this.model]}createRequestBody(e){return{...U,model:this.getModelId(),messages:[{role:"system",content:z(e)},{role:"user",content:Z(e)}]}}createHeaders(){return{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"}}};var I=class o{constructor(e){this.formattedCompletion="";this.formattedCompletion=e}static create(e){return new o(e)}setCompletion(e){return this.formattedCompletion=e,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(e){let t=/```[\s\S]*?```/g,r=e,n;for(;(n=t.exec(e))!==null;){let i=n[0],a=i.split(`
34
+ `)),p.endsWith(".")?p:`${p}.`};var te=(o,e,t)=>{let r=ee(o),n=oe(o),l={model:Te(e),temperature:V},s={openai:{messages:[{role:"system",content:r},{role:"user",content:n}]},groq:{messages:[{role:"system",content:r},{role:"user",content:n}]},anthropic:{system:r,messages:[{role:"user",content:n}],max_tokens:Pe(e)}};return{...l,...s[t]}},re=(o,e)=>{let t={"Content-Type":"application/json"},r={openai:{Authorization:`Bearer ${o}`},groq:{Authorization:`Bearer ${o}`},anthropic:{"x-api-key":o,"anthropic-version":"2023-06-01"}};return{...t,...r[e]}},ne=(o,e)=>{let r={openai:he,groq:fe,anthropic:Ee}[e];if(!r)throw new Error(`Unsupported provider: ${e}`);return r(o)},he=o=>o.choices?.length?{completion:o.choices[0].message.content}:{completion:null,error:"No completion found in the openai response"},fe=o=>o.choices?.length?{completion:o.choices[0].message.content}:{completion:null,error:"No completion found in the groq response"},Ee=o=>o.content?typeof o.content!="string"?{completion:null,error:"Completion content is not a string"}:{completion:o.content}:{completion:null,error:"No completion found in the anthropic response"},Te=o=>F[o],ie=o=>U[o],Pe=o=>W[o]||4096;var $=class{constructor(e,t={}){this.validateInputs(e,t),this.apiKey=e,this.provider=t.provider??P,this.model=t.model??S}async complete({body:e,options:t}){let{completionMetadata:r}=e,{headers:n={}}=t??{};try{let i=te(r,this.model,this.provider),l=ie(this.provider),s=re(this.apiKey,this.provider),a={...n,...s},c=await R.POST(l,i,{headers:a});return ne(c,this.provider)}catch(i){return{error:d(i,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}validateInputs(e,t){if(!e)throw new Error(`Please provide ${this.provider??P} API key.`);let{provider:r,model:n}=t;if(r&&!n||!r&&n)throw new Error("Both provider and model must be specified together");let i=r??P,l=n??S;if(!_[i].includes(l)){let s=M(_[i]);throw new Error(`Model ${l} is not supported by ${i} provider. Supported models: ${s}`)}}};var b=class o{constructor(e){this.formattedCompletion="";this.formattedCompletion=e}static create(e){return new o(e)}setCompletion(e){return this.formattedCompletion=e,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(e){let t=/```[\s\S]*?```/g,r=e,n;for(;(n=t.exec(e))!==null;){let i=n[0],l=i.split(`
33
35
  `).slice(1,-1).join(`
34
- `);r=r.replace(i,a)}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
36
+ `);r=r.replace(i,l)}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
35
37
 
36
- `),this}build(){return this.formattedCompletion}};var R=class{constructor(e,t){this.cursorPosition=e,this.model=t}shouldProvideCompletions(){return!Y(this.cursorPosition,this.model)&&!K(this.cursorPosition,this.model)}};var O=class O{constructor(){this.cache=[]}getCompletionCache(e,t){return this.cache.filter(r=>this.isCacheItemValid(r,e,t))}addCompletionCache(e){this.cache=[...this.cache.slice(-(O.MAX_CACHE_SIZE-1)),e]}clearCompletionCache(){this.cache=[]}isCacheItemValid(e,t,r){let n=r.getValueInRange(e.range);return h(t,r).startsWith(e.textBeforeCursorInLine)&&this.isPositionValid(e,t,n)}isPositionValid(e,t,r){return e.range.startLineNumber===t.lineNumber&&t.column===e.range.startColumn||e.completion.startsWith(r)&&e.range.startLineNumber===t.lineNumber&&t.column>=e.range.startColumn-r.length&&t.column<=e.range.endColumn}};O.MAX_CACHE_SIZE=10;var b=O;var ee=(o,e,t,r)=>{let n=(o.match(/\n/g)||[]).length,i=W(o),a=x(t,r);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+n,endColumn:o.includes(a)?t.lineNumber===e.startLineNumber&&n===0?t.column+(i-1):i:t.column}};function te(o){return I.create(o).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var u=o=>({items:o,enableForwardStability:!0});var de=300,oe=V(Q,de),L=new b,ue=async({monaco:o,model:e,position:t,token:r,isCompletionAccepted:n,onShowCompletion:i,options:a})=>{if(!new R(t,e).shouldProvideCompletions())return u([]);let s=L.getCompletionCache(t,e).map(l=>({insertText:l.completion,range:l.range}));if(s.length)return i(),u(s);if(r.isCancellationRequested||n)return u([]);try{let l=oe({...a,text:e.getValue(),model:e,position:t});r.onCancellationRequested(()=>{oe.cancel()});let c=await l;if(c){let m=te(c),p=new o.Range(t.lineNumber,t.column,t.lineNumber,t.column),C=ee(m,p,t,e);return L.addCompletionCache({completion:m,range:C,textBeforeCursorInLine:h(t,e)}),i(),u([{insertText:m,range:C}])}}catch(l){if(l instanceof Error&&(l.message==="Cancelled"||l.name==="AbortError"))return u([]);d(l,"FETCH_COMPLETION_ITEM_ERROR")}return u([])},re=ue;var E=new WeakMap,T=null,Ce=(o,e,t)=>{T&&T.deregister();let r=[];E.set(e,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let n=o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,l,c,m)=>{let p=E.get(e);if(p)return re({monaco:o,model:s,position:l,token:m,isCompletionAccepted:p.isCompletionAccepted,onShowCompletion:()=>{p.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});r.push(n);let i=e.onKeyDown(s=>{let l=E.get(e);if(!l)return;let c=s.keyCode===o.KeyCode.Tab||s.keyCode===o.KeyCode.RightArrow&&s.metaKey;l.isCompletionVisible&&c?(l.isCompletionAccepted=!0,l.isCompletionVisible=!1):l.isCompletionAccepted=!1});r.push(i);let a={deregister:()=>{r.forEach(s=>s.dispose()),L.clearCompletionCache(),E.delete(e),T=null}};return T=a,a}catch(n){return d(n,"REGISTER_COPILOT_ERROR"),{deregister:()=>{r.forEach(i=>i.dispose()),E.delete(e),T=null}}}};export{D as Copilot,Ce as registerCopilot};
38
+ `),this}build(){return this.formattedCompletion}};var O=class{constructor(e,t){this.cursorPosition=e,this.model=t}shouldProvideCompletions(){return!z(this.cursorPosition,this.model)&&!J(this.cursorPosition,this.model)}};var L=class L{constructor(){this.cache=[]}getCompletionCache(e,t){return this.cache.filter(r=>this.isCacheItemValid(r,e,t))}addCompletionCache(e){this.cache=[...this.cache.slice(-(L.MAX_CACHE_SIZE-1)),e]}clearCompletionCache(){this.cache=[]}isCacheItemValid(e,t,r){let n=r.getValueInRange(e.range);return g(t,r).startsWith(e.textBeforeCursorInLine)&&this.isPositionValid(e,t,n)}isPositionValid(e,t,r){return e.range.startLineNumber===t.lineNumber&&t.column===e.range.startColumn||e.completion.startsWith(r)&&e.range.startLineNumber===t.lineNumber&&t.column>=e.range.startColumn-r.length&&t.column<=e.range.endColumn}};L.MAX_CACHE_SIZE=10;var v=L;var xe="application/json",se=async({filename:o,endpoint:e,language:t,technologies:r,externalContext:n,model:i,position:l})=>{try{let{completion:s}=await R.POST(e,{body:{completionMetadata:Me({filename:o,position:l,model:i,language:t,technologies:r,externalContext:n})}},{headers:{"Content-Type":xe},error:"Error while fetching completion item"});return s}catch(s){return d(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},Me=({filename:o,position:e,model:t,language:r,technologies:n,externalContext:i})=>{let l=ye(e,t),s=k(e,t),a=B(e,t);return{filename:o,language:r,technologies:n,externalContext:i,textBeforeCursor:s,textAfterCursor:a,editorState:{completionMode:l}}},ye=(o,e)=>{let t=k(o,e),r=B(o,e);return t&&r?"fill-in-the-middle":"completion"};var le=(o,e,t,r)=>{let n=(o.match(/\n/g)||[]).length,i=K(o),l=y(t,r);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+n,endColumn:o.includes(l)?t.lineNumber===e.startLineNumber&&n===0?t.column+(i-1):i:t.column}};function ae(o){return b.create(o).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var u=o=>({items:o,enableForwardStability:!0});var Re=300,pe=G(se,Re),A=new v,Ie=async({monaco:o,model:e,position:t,token:r,isCompletionAccepted:n,onShowCompletion:i,options:l})=>{if(!new O(t,e).shouldProvideCompletions())return u([]);let s=A.getCompletionCache(t,e).map(a=>({insertText:a.completion,range:a.range}));if(s.length)return i(),u(s);if(r.isCancellationRequested||n)return u([]);try{let a=pe({...l,text:e.getValue(),model:e,position:t});r.onCancellationRequested(()=>{pe.cancel()});let c=await a;if(c){let p=ae(c),m=new o.Range(t.lineNumber,t.column,t.lineNumber,t.column),T=le(p,m,t,e);return A.addCompletionCache({completion:p,range:T,textBeforeCursorInLine:g(t,e)}),i(),u([{insertText:p,range:T}])}}catch(a){if(typeof a=="string"&&(a==="Cancelled"||a==="AbortError")||a instanceof Error&&(a.message==="Cancelled"||a.name==="AbortError"))return u([]);d(a,"FETCH_COMPLETION_ITEM_ERROR")}return u([])},ce=Ie;var f=new WeakMap,E=null,be=(o,e,t)=>{E&&E.deregister();let r=[];f.set(e,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let n=o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,a,c,p)=>{let m=f.get(e);if(m)return ce({monaco:o,model:s,position:a,token:p,isCompletionAccepted:m.isCompletionAccepted,onShowCompletion:()=>{m.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});r.push(n);let i=e.onKeyDown(s=>{let a=f.get(e);if(!a)return;let c=s.keyCode===o.KeyCode.Tab||s.keyCode===o.KeyCode.RightArrow&&s.metaKey;a.isCompletionVisible&&c?(a.isCompletionAccepted=!0,a.isCompletionVisible=!1):a.isCompletionAccepted=!1});r.push(i);let l={deregister:()=>{r.forEach(s=>s.dispose()),A.clearCompletionCache(),f.delete(e),E=null}};return E=l,l}catch(n){return d(n,"REGISTER_COPILOT_ERROR"),{deregister:()=>{r.forEach(i=>i.dispose()),f.delete(e),E=null}}}};export{$ as Copilot,be as registerCopilot};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "monacopilot",
3
- "version": "0.9.19",
3
+ "version": "0.9.21",
4
4
  "description": "AI auto-completion plugin for Monaco Editor",
5
5
  "main": "./build/index.js",
6
6
  "module": "./build/index.mjs",
@@ -17,10 +17,11 @@
17
17
  "lint": "eslint . --ext .ts,.tsx --fix",
18
18
  "lint:test-ui": "pnpm -C tests/ui lint",
19
19
  "format": "prettier --write .",
20
- "pre-commit": "pnpm format && pnpm type-check && pnpm lint && pnpm lint:test-ui",
20
+ "pre-commit": "pnpm build && pnpm format && pnpm type-check && pnpm lint && pnpm lint:test-ui",
21
21
  "release": "release-it"
22
22
  },
23
23
  "devDependencies": {
24
+ "@anthropic-ai/sdk": "^0.27.1",
24
25
  "@ianvs/prettier-plugin-sort-imports": "^4.2.1",
25
26
  "@typescript-eslint/eslint-plugin": "^7.3.1",
26
27
  "eslint": "^8.57.0",