@theia/ai-code-completion 1.62.1 → 1.63.0-next.24
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/lib/browser/ai-code-completion-frontend-module.d.ts.map +1 -1
- package/lib/browser/ai-code-completion-frontend-module.js +6 -4
- package/lib/browser/ai-code-completion-frontend-module.js.map +1 -1
- package/lib/browser/code-completion-agent.d.ts +0 -3
- package/lib/browser/code-completion-agent.d.ts.map +1 -1
- package/lib/browser/code-completion-agent.js +7 -45
- package/lib/browser/code-completion-agent.js.map +1 -1
- package/lib/browser/code-completion-prompt-template.d.ts.map +1 -1
- package/lib/browser/code-completion-prompt-template.js +7 -6
- package/lib/browser/code-completion-prompt-template.js.map +1 -1
- package/lib/browser/code-completion-variable-context.d.ts +11 -0
- package/lib/browser/code-completion-variable-context.d.ts.map +1 -0
- package/lib/browser/code-completion-variable-context.js +26 -0
- package/lib/browser/code-completion-variable-context.js.map +1 -0
- package/lib/browser/code-completion-variable-contribution.d.ts +16 -0
- package/lib/browser/code-completion-variable-contribution.d.ts.map +1 -0
- package/lib/browser/code-completion-variable-contribution.js +127 -0
- package/lib/browser/code-completion-variable-contribution.js.map +1 -0
- package/lib/browser/code-completion-variable-contribution.spec.d.ts +2 -0
- package/lib/browser/code-completion-variable-contribution.spec.d.ts.map +1 -0
- package/lib/browser/code-completion-variable-contribution.spec.js +143 -0
- package/lib/browser/code-completion-variable-contribution.spec.js.map +1 -0
- package/lib/browser/code-completion-variables.d.ts +6 -0
- package/lib/browser/code-completion-variables.d.ts.map +1 -0
- package/lib/browser/code-completion-variables.js +39 -0
- package/lib/browser/code-completion-variables.js.map +1 -0
- package/package.json +8 -8
- package/src/browser/ai-code-completion-frontend-module.ts +6 -4
- package/src/browser/code-completion-agent.ts +8 -57
- package/src/browser/code-completion-prompt-template.ts +7 -6
- package/src/browser/code-completion-variable-context.ts +30 -0
- package/src/browser/code-completion-variable-contribution.spec.ts +160 -0
- package/src/browser/code-completion-variable-contribution.ts +145 -0
- package/src/browser/code-completion-variables.ts +41 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-code-completion-frontend-module.d.ts","sourceRoot":"","sources":["../../src/browser/ai-code-completion-frontend-module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ai-code-completion-frontend-module.d.ts","sourceRoot":"","sources":["../../src/browser/ai-code-completion-frontend-module.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;;AAQ/D,wBAWG"}
|
|
@@ -15,14 +15,15 @@
|
|
|
15
15
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
16
|
// *****************************************************************************
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
const inversify_1 = require("@theia/core/shared/inversify");
|
|
19
|
-
const code_completion_agent_1 = require("./code-completion-agent");
|
|
20
|
-
const ai_code_frontend_application_contribution_1 = require("./ai-code-frontend-application-contribution");
|
|
21
|
-
const browser_1 = require("@theia/core/lib/browser");
|
|
22
18
|
const ai_core_1 = require("@theia/ai-core");
|
|
19
|
+
const browser_1 = require("@theia/core/lib/browser");
|
|
20
|
+
const inversify_1 = require("@theia/core/shared/inversify");
|
|
23
21
|
const ai_code_completion_preference_1 = require("./ai-code-completion-preference");
|
|
22
|
+
const ai_code_frontend_application_contribution_1 = require("./ai-code-frontend-application-contribution");
|
|
24
23
|
const ai_code_inline_completion_provider_1 = require("./ai-code-inline-completion-provider");
|
|
24
|
+
const code_completion_agent_1 = require("./code-completion-agent");
|
|
25
25
|
const code_completion_postprocessor_1 = require("./code-completion-postprocessor");
|
|
26
|
+
const code_completion_variable_contribution_1 = require("./code-completion-variable-contribution");
|
|
26
27
|
exports.default = new inversify_1.ContainerModule(bind => {
|
|
27
28
|
bind(code_completion_agent_1.CodeCompletionAgentImpl).toSelf().inSingletonScope();
|
|
28
29
|
bind(code_completion_agent_1.CodeCompletionAgent).toService(code_completion_agent_1.CodeCompletionAgentImpl);
|
|
@@ -33,5 +34,6 @@ exports.default = new inversify_1.ContainerModule(bind => {
|
|
|
33
34
|
bind(browser_1.KeybindingContribution).toService(ai_code_frontend_application_contribution_1.AIFrontendApplicationContribution);
|
|
34
35
|
bind(browser_1.PreferenceContribution).toConstantValue({ schema: ai_code_completion_preference_1.AICodeCompletionPreferencesSchema });
|
|
35
36
|
bind(code_completion_postprocessor_1.CodeCompletionPostProcessor).to(code_completion_postprocessor_1.DefaultCodeCompletionPostProcessor).inSingletonScope();
|
|
37
|
+
bind(ai_core_1.AIVariableContribution).to(code_completion_variable_contribution_1.CodeCompletionVariableContribution).inSingletonScope();
|
|
36
38
|
});
|
|
37
39
|
//# sourceMappingURL=ai-code-completion-frontend-module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-code-completion-frontend-module.js","sourceRoot":"","sources":["../../src/browser/ai-code-completion-frontend-module.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,
|
|
1
|
+
{"version":3,"file":"ai-code-completion-frontend-module.js","sourceRoot":"","sources":["../../src/browser/ai-code-completion-frontend-module.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,4CAA+D;AAC/D,qDAA0H;AAC1H,4DAA+D;AAC/D,mFAAoF;AACpF,2GAAgG;AAChG,6FAAuF;AACvF,mEAAuF;AACvF,mFAAkH;AAClH,mGAA6F;AAE7F,kBAAe,IAAI,2BAAe,CAAC,IAAI,CAAC,EAAE;IACtC,IAAI,CAAC,+CAAuB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC1D,IAAI,CAAC,2CAAmB,CAAC,CAAC,SAAS,CAAC,+CAAuB,CAAC,CAAC;IAC7D,IAAI,CAAC,eAAK,CAAC,CAAC,SAAS,CAAC,+CAAuB,CAAC,CAAC;IAC/C,IAAI,CAAC,oEAA+B,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAClE,IAAI,CAAC,6EAAiC,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IACpE,IAAI,CAAC,yCAA+B,CAAC,CAAC,EAAE,CAAC,6EAAiC,CAAC,CAAC;IAC5E,IAAI,CAAC,gCAAsB,CAAC,CAAC,SAAS,CAAC,6EAAiC,CAAC,CAAC;IAC1E,IAAI,CAAC,gCAAsB,CAAC,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,iEAAiC,EAAE,CAAC,CAAC;IAC5F,IAAI,CAAC,2DAA2B,CAAC,CAAC,EAAE,CAAC,kEAAkC,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAC5F,IAAI,CAAC,gCAAsB,CAAC,CAAC,EAAE,CAAC,0EAAkC,CAAC,CAAC,gBAAgB,EAAE,CAAC;AAC3F,CAAC,CAAC,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { LanguageModelService } from '@theia/ai-core/lib/browser';
|
|
2
2
|
import { Agent, AgentSpecificVariables, LanguageModelRegistry, LanguageModelRequirement, PromptService, PromptVariantSet } from '@theia/ai-core/lib/common';
|
|
3
3
|
import { ILogger, ProgressService } from '@theia/core';
|
|
4
|
-
import { PreferenceService } from '@theia/core/lib/browser';
|
|
5
4
|
import * as monaco from '@theia/monaco-editor-core';
|
|
6
5
|
import { CodeCompletionPostProcessor } from './code-completion-postprocessor';
|
|
7
6
|
export declare const CodeCompletionAgent: unique symbol;
|
|
@@ -15,7 +14,6 @@ export declare class CodeCompletionAgentImpl implements CodeCompletionAgent {
|
|
|
15
14
|
protected languageModelRegistry: LanguageModelRegistry;
|
|
16
15
|
protected promptService: PromptService;
|
|
17
16
|
protected progressService: ProgressService;
|
|
18
|
-
protected preferences: PreferenceService;
|
|
19
17
|
protected postProcessor: CodeCompletionPostProcessor;
|
|
20
18
|
id: string;
|
|
21
19
|
name: string;
|
|
@@ -25,6 +23,5 @@ export declare class CodeCompletionAgentImpl implements CodeCompletionAgent {
|
|
|
25
23
|
readonly variables: string[];
|
|
26
24
|
readonly functions: string[];
|
|
27
25
|
readonly agentSpecificVariables: AgentSpecificVariables[];
|
|
28
|
-
readonly tags?: string[] | undefined;
|
|
29
26
|
}
|
|
30
27
|
//# sourceMappingURL=code-completion-agent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-completion-agent.d.ts","sourceRoot":"","sources":["../../src/browser/code-completion-agent.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EACH,KAAK,EAAE,sBAAsB,EAC7B,qBAAqB,EAAE,wBAAwB,EAAE,aAAa,EAC9D,gBAAgB,EAEnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAgB,OAAO,EAAO,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"code-completion-agent.d.ts","sourceRoot":"","sources":["../../src/browser/code-completion-agent.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EACH,KAAK,EAAE,sBAAsB,EAC7B,qBAAqB,EAAE,wBAAwB,EAAE,aAAa,EAC9D,gBAAgB,EAEnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAgB,OAAO,EAAO,eAAe,EAAE,MAAM,aAAa,CAAC;AAE1E,OAAO,KAAK,MAAM,MAAM,2BAA2B,CAAC;AAEpD,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAG9E,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AACjE,MAAM,WAAW,mBAAoB,SAAQ,KAAK;IAC9C,wBAAwB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAC/E,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,uBAAuB,EAAE,KAAK,EAAE,MAAM,CAAC,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAA;CACnJ;AAED,qBACa,uBAAwB,YAAW,mBAAmB;IAE/D,SAAS,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IAE/C,wBAAwB,CAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,EAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,uBAAuB,EACjD,KAAK,EAAE,MAAM,CAAC,iBAAiB,GAChC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,iBAAiB,GAAG,SAAS,CAAC;IA+E1D,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC;IAG1B,SAAS,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;IAGvD,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;IAGvC,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAG3C,SAAS,CAAC,aAAa,EAAE,2BAA2B,CAAC;IAErD,EAAE,SAAqB;IACvB,IAAI,SAAqB;IACzB,WAAW,SACkI;IAC7I,OAAO,EAAE,gBAAgB,EAAE,CAAyB;IACpD,yBAAyB,EAAE,wBAAwB,EAAE,CAKnD;IACF,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,CAAM;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,CAAM;IAClC,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB,EAAE,CAAM;CAClE"}
|
|
@@ -20,10 +20,8 @@ const tslib_1 = require("tslib");
|
|
|
20
20
|
const browser_1 = require("@theia/ai-core/lib/browser");
|
|
21
21
|
const common_1 = require("@theia/ai-core/lib/common");
|
|
22
22
|
const core_1 = require("@theia/core");
|
|
23
|
-
const browser_2 = require("@theia/core/lib/browser");
|
|
24
23
|
const inversify_1 = require("@theia/core/shared/inversify");
|
|
25
24
|
const monaco = require("@theia/monaco-editor-core");
|
|
26
|
-
const ai_code_completion_preference_1 = require("./ai-code-completion-preference");
|
|
27
25
|
const code_completion_prompt_template_1 = require("./code-completion-prompt-template");
|
|
28
26
|
const code_completion_postprocessor_1 = require("./code-completion-postprocessor");
|
|
29
27
|
exports.CodeCompletionAgent = Symbol('CodeCompletionAgent');
|
|
@@ -41,12 +39,7 @@ let CodeCompletionAgentImpl = class CodeCompletionAgentImpl {
|
|
|
41
39
|
];
|
|
42
40
|
this.variables = [];
|
|
43
41
|
this.functions = [];
|
|
44
|
-
this.agentSpecificVariables = [
|
|
45
|
-
{ name: 'file', usedInPrompt: true, description: 'The uri of the file being edited.' },
|
|
46
|
-
{ name: 'language', usedInPrompt: true, description: 'The languageId of the file being edited.' },
|
|
47
|
-
{ name: 'prefix', usedInPrompt: true, description: 'The code before the current position of the cursor.' },
|
|
48
|
-
{ name: 'suffix', usedInPrompt: true, description: 'The code after the current position of the cursor.' }
|
|
49
|
-
];
|
|
42
|
+
this.agentSpecificVariables = [];
|
|
50
43
|
}
|
|
51
44
|
async provideInlineCompletions(model, position, context, token) {
|
|
52
45
|
const progress = await this.progressService.showProgress({ text: core_1.nls.localize('theia/ai/code-completion/progressText', 'Calculating AI code completion...'), options: { location: 'window' } });
|
|
@@ -59,43 +52,16 @@ let CodeCompletionAgentImpl = class CodeCompletionAgentImpl {
|
|
|
59
52
|
this.logger.error('No language model found for code-completion-agent');
|
|
60
53
|
return undefined;
|
|
61
54
|
}
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// Only the cursor line
|
|
68
|
-
prefixStartLine = position.lineNumber;
|
|
69
|
-
suffixEndLine = position.lineNumber;
|
|
70
|
-
}
|
|
71
|
-
else if (maxContextLines > 0) {
|
|
72
|
-
const linesBeforeCursor = position.lineNumber - 1;
|
|
73
|
-
const linesAfterCursor = model.getLineCount() - position.lineNumber;
|
|
74
|
-
// Allocate one more line to the prefix in case of an odd maxContextLines
|
|
75
|
-
const prefixLines = Math.min(Math.ceil(maxContextLines / 2), linesBeforeCursor);
|
|
76
|
-
const suffixLines = Math.min(Math.floor(maxContextLines / 2), linesAfterCursor);
|
|
77
|
-
prefixStartLine = Math.max(1, position.lineNumber - prefixLines);
|
|
78
|
-
suffixEndLine = Math.min(model.getLineCount(), position.lineNumber + suffixLines);
|
|
79
|
-
}
|
|
80
|
-
const prefix = model.getValueInRange({
|
|
81
|
-
startLineNumber: prefixStartLine,
|
|
82
|
-
startColumn: 1,
|
|
83
|
-
endLineNumber: position.lineNumber,
|
|
84
|
-
endColumn: position.column,
|
|
85
|
-
});
|
|
86
|
-
const suffix = model.getValueInRange({
|
|
87
|
-
startLineNumber: position.lineNumber,
|
|
88
|
-
startColumn: position.column,
|
|
89
|
-
endLineNumber: suffixEndLine,
|
|
90
|
-
endColumn: model.getLineMaxColumn(suffixEndLine),
|
|
91
|
-
});
|
|
92
|
-
const file = model.uri.toString(false);
|
|
93
|
-
const language = model.getLanguageId();
|
|
55
|
+
const variableContext = {
|
|
56
|
+
model,
|
|
57
|
+
position,
|
|
58
|
+
context
|
|
59
|
+
};
|
|
94
60
|
if (token.isCancellationRequested) {
|
|
95
61
|
return undefined;
|
|
96
62
|
}
|
|
97
63
|
const prompt = await this.promptService
|
|
98
|
-
.getResolvedPromptFragment('code-completion-prompt',
|
|
64
|
+
.getResolvedPromptFragment('code-completion-prompt', undefined, variableContext)
|
|
99
65
|
.then(p => p === null || p === void 0 ? void 0 : p.text);
|
|
100
66
|
if (!prompt) {
|
|
101
67
|
this.logger.error('No prompt found for code-completion-agent');
|
|
@@ -166,10 +132,6 @@ tslib_1.__decorate([
|
|
|
166
132
|
(0, inversify_1.inject)(core_1.ProgressService),
|
|
167
133
|
tslib_1.__metadata("design:type", core_1.ProgressService)
|
|
168
134
|
], CodeCompletionAgentImpl.prototype, "progressService", void 0);
|
|
169
|
-
tslib_1.__decorate([
|
|
170
|
-
(0, inversify_1.inject)(browser_2.PreferenceService),
|
|
171
|
-
tslib_1.__metadata("design:type", Object)
|
|
172
|
-
], CodeCompletionAgentImpl.prototype, "preferences", void 0);
|
|
173
135
|
tslib_1.__decorate([
|
|
174
136
|
(0, inversify_1.inject)(code_completion_postprocessor_1.CodeCompletionPostProcessor),
|
|
175
137
|
tslib_1.__metadata("design:type", Object)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-completion-agent.js","sourceRoot":"","sources":["../../src/browser/code-completion-agent.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;;AAEhF,wDAAkE;AAClE,sDAKmC;AACnC,sCAA0E;AAC1E,
|
|
1
|
+
{"version":3,"file":"code-completion-agent.js","sourceRoot":"","sources":["../../src/browser/code-completion-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-completion-prompt-template.d.ts","sourceRoot":"","sources":["../../src/browser/code-completion-prompt-template.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"code-completion-prompt-template.d.ts","sourceRoot":"","sources":["../../src/browser/code-completion-prompt-template.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAG7D,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,EAgCnD,CAAC"}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// *****************************************************************************
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.codeCompletionPrompts = void 0;
|
|
14
|
+
const code_completion_variables_1 = require("./code-completion-variables");
|
|
14
15
|
exports.codeCompletionPrompts = [{
|
|
15
16
|
id: 'code-completion-prompt',
|
|
16
17
|
variants: [{
|
|
@@ -18,11 +19,11 @@ exports.codeCompletionPrompts = [{
|
|
|
18
19
|
template: `{{!-- This prompt is licensed under the MIT License (https://opensource.org/license/mit).
|
|
19
20
|
Made improvements or adaptations to this prompt template? We’d love for you to share it with the community! Contribute back here:
|
|
20
21
|
https://github.com/eclipse-theia/theia/discussions/new?category=prompt-template-contribution --}}
|
|
21
|
-
You are a code completion agent. The current file you have to complete is named {{
|
|
22
|
-
The language of the file is {{
|
|
22
|
+
You are a code completion agent. The current file you have to complete is named {{${code_completion_variables_1.FILE.id}}}.
|
|
23
|
+
The language of the file is {{${code_completion_variables_1.LANGUAGE.id}}}. Return your result as plain text without markdown formatting.
|
|
23
24
|
Finish the following code snippet.
|
|
24
25
|
|
|
25
|
-
{{
|
|
26
|
+
{{${code_completion_variables_1.PREFIX.id}}}[[MARKER]]{{${code_completion_variables_1.SUFFIX.id}}}
|
|
26
27
|
|
|
27
28
|
Only return the exact replacement for [[MARKER]] to complete the snippet.`
|
|
28
29
|
}],
|
|
@@ -33,12 +34,12 @@ Made improvements or adaptations to this prompt template? We’d love for you to
|
|
|
33
34
|
https://github.com/eclipse-theia/theia/discussions/new?category=prompt-template-contribution --}}
|
|
34
35
|
## Code snippet
|
|
35
36
|
\`\`\`
|
|
36
|
-
{{
|
|
37
|
+
{{${code_completion_variables_1.PREFIX.id}}}[[MARKER]]{{${code_completion_variables_1.SUFFIX.id}}}
|
|
37
38
|
\`\`\`
|
|
38
39
|
|
|
39
40
|
## Meta Data
|
|
40
|
-
- File: {{
|
|
41
|
-
- Language: {{
|
|
41
|
+
- File: {{${code_completion_variables_1.FILE.id}}}
|
|
42
|
+
- Language: {{${code_completion_variables_1.LANGUAGE.id}}}
|
|
42
43
|
|
|
43
44
|
Replace [[MARKER]] with the exact code to complete the code snippet. Return only the replacement of [[MARKER]] as plain text.`,
|
|
44
45
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-completion-prompt-template.js","sourceRoot":"","sources":["../../src/browser/code-completion-prompt-template.ts"],"names":[],"mappings":";AAAA,qDAAqD;AACrD,gFAAgF;AAChF,oDAAoD;AACpD,EAAE;AACF,+CAA+C;AAC/C,mEAAmE;AACnE,sCAAsC;AACtC,EAAE;AACF,+BAA+B;AAC/B,gFAAgF;;;
|
|
1
|
+
{"version":3,"file":"code-completion-prompt-template.js","sourceRoot":"","sources":["../../src/browser/code-completion-prompt-template.ts"],"names":[],"mappings":";AAAA,qDAAqD;AACrD,gFAAgF;AAChF,oDAAoD;AACpD,EAAE;AACF,+CAA+C;AAC/C,mEAAmE;AACnE,sCAAsC;AACtC,EAAE;AACF,+BAA+B;AAC/B,gFAAgF;;;AAGhF,2EAA6E;AAEhE,QAAA,qBAAqB,GAAuB,CAAC;QACtD,EAAE,EAAE,wBAAwB;QAC5B,QAAQ,EAAE,CAAC;gBACP,EAAE,EAAE,iCAAiC;gBACrC,QAAQ,EAAE;;;oFAGkE,gCAAI,CAAC,EAAE;gCAC3D,oCAAQ,CAAC,EAAE;;;IAGvC,kCAAM,CAAC,EAAE,iBAAiB,kCAAM,CAAC,EAAE;;0EAEmC;aACrE,CAAC;QACF,cAAc,EAAE;YACZ,EAAE,EAAE,gCAAgC;YACpC,QAAQ,EAAE;;;;;IAKd,kCAAM,CAAC,EAAE,iBAAiB,kCAAM,CAAC,EAAE;;;;YAI3B,gCAAI,CAAC,EAAE;gBACH,oCAAQ,CAAC,EAAE;;8HAEmG;SACzH;KACJ;CACA,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AIVariableContext } from '@theia/ai-core';
|
|
2
|
+
import * as monaco from '@theia/monaco-editor-core';
|
|
3
|
+
export interface CodeCompletionVariableContext {
|
|
4
|
+
model: monaco.editor.ITextModel;
|
|
5
|
+
position: monaco.Position;
|
|
6
|
+
context: monaco.languages.InlineCompletionContext;
|
|
7
|
+
}
|
|
8
|
+
export declare namespace CodeCompletionVariableContext {
|
|
9
|
+
function is(context: AIVariableContext): context is CodeCompletionVariableContext;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=code-completion-variable-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-completion-variable-context.d.ts","sourceRoot":"","sources":["../../src/browser/code-completion-variable-context.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,MAAM,MAAM,2BAA2B,CAAC;AAEpD,MAAM,WAAW,6BAA6B;IAC1C,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,uBAAuB,CAAA;CACpD;AAED,yBAAiB,6BAA6B,CAAC;IAC3C,SAAgB,EAAE,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,IAAI,6BAA6B,CAEvF;CACJ"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2025 Lonti.com Pty Ltd.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.CodeCompletionVariableContext = void 0;
|
|
19
|
+
var CodeCompletionVariableContext;
|
|
20
|
+
(function (CodeCompletionVariableContext) {
|
|
21
|
+
function is(context) {
|
|
22
|
+
return !!context && 'model' in context && 'position' in context && 'context' in context;
|
|
23
|
+
}
|
|
24
|
+
CodeCompletionVariableContext.is = is;
|
|
25
|
+
})(CodeCompletionVariableContext || (exports.CodeCompletionVariableContext = CodeCompletionVariableContext = {}));
|
|
26
|
+
//# sourceMappingURL=code-completion-variable-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-completion-variable-context.js","sourceRoot":"","sources":["../../src/browser/code-completion-variable-context.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,wCAAwC;AACxC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;AAWhF,IAAiB,6BAA6B,CAI7C;AAJD,WAAiB,6BAA6B;IAC1C,SAAgB,EAAE,CAAC,OAA0B;QACzC,OAAO,CAAC,CAAC,OAAO,IAAI,OAAO,IAAI,OAAO,IAAI,UAAU,IAAI,OAAO,IAAI,SAAS,IAAI,OAAO,CAAC;IAC5F,CAAC;IAFe,gCAAE,KAEjB,CAAA;AACL,CAAC,EAJgB,6BAA6B,6CAA7B,6BAA6B,QAI7C"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AIVariableContext, AIVariableResolutionRequest, AIVariableResolver, ResolvedAIVariable } from '@theia/ai-core';
|
|
2
|
+
import { FrontendVariableContribution, FrontendVariableService } from '@theia/ai-core/lib/browser';
|
|
3
|
+
import { MaybePromise } from '@theia/core';
|
|
4
|
+
import { PreferenceService } from '@theia/core/lib/browser/preferences/preference-service';
|
|
5
|
+
import { CodeCompletionVariableContext } from './code-completion-variable-context';
|
|
6
|
+
export declare class CodeCompletionVariableContribution implements FrontendVariableContribution, AIVariableResolver {
|
|
7
|
+
protected preferences: PreferenceService;
|
|
8
|
+
registerVariables(service: FrontendVariableService): void;
|
|
9
|
+
canResolve(_request: AIVariableResolutionRequest, context: AIVariableContext): MaybePromise<number>;
|
|
10
|
+
resolve(request: AIVariableResolutionRequest, context: AIVariableContext): Promise<ResolvedAIVariable | undefined>;
|
|
11
|
+
protected resolvePrefix(context: CodeCompletionVariableContext): ResolvedAIVariable | undefined;
|
|
12
|
+
protected resolveSuffix(context: CodeCompletionVariableContext): ResolvedAIVariable | undefined;
|
|
13
|
+
protected resolveLanguage(context: CodeCompletionVariableContext): ResolvedAIVariable | undefined;
|
|
14
|
+
protected resolveFile(context: CodeCompletionVariableContext): ResolvedAIVariable | undefined;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=code-completion-variable-contribution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-completion-variable-contribution.d.ts","sourceRoot":"","sources":["../../src/browser/code-completion-variable-contribution.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACxH,OAAO,EAAE,4BAA4B,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACnG,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wDAAwD,CAAC;AAG3F,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AAGnF,qBACa,kCAAmC,YAAW,4BAA4B,EAAE,kBAAkB;IAEvG,SAAS,CAAC,WAAW,EAAE,iBAAiB,CAAC;IAEzC,iBAAiB,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI;IAWzD,UAAU,CAAC,QAAQ,EAAE,2BAA2B,EAAE,OAAO,EAAE,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC;IAI7F,OAAO,CAAC,OAAO,EAAE,2BAA2B,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC;IAmBxH,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,6BAA6B,GAAG,kBAAkB,GAAG,SAAS;IAkC/F,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,6BAA6B,GAAG,kBAAkB,GAAG,SAAS;IAgC/F,SAAS,CAAC,eAAe,CAAC,OAAO,EAAE,6BAA6B,GAAG,kBAAkB,GAAG,SAAS;IAOjG,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,6BAA6B,GAAG,kBAAkB,GAAG,SAAS;CAOhG"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2025 Lonti.com Pty Ltd.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.CodeCompletionVariableContribution = void 0;
|
|
19
|
+
const tslib_1 = require("tslib");
|
|
20
|
+
const preference_service_1 = require("@theia/core/lib/browser/preferences/preference-service");
|
|
21
|
+
const inversify_1 = require("@theia/core/shared/inversify");
|
|
22
|
+
const ai_code_completion_preference_1 = require("./ai-code-completion-preference");
|
|
23
|
+
const code_completion_variable_context_1 = require("./code-completion-variable-context");
|
|
24
|
+
const code_completion_variables_1 = require("./code-completion-variables");
|
|
25
|
+
let CodeCompletionVariableContribution = class CodeCompletionVariableContribution {
|
|
26
|
+
registerVariables(service) {
|
|
27
|
+
[
|
|
28
|
+
code_completion_variables_1.FILE,
|
|
29
|
+
code_completion_variables_1.PREFIX,
|
|
30
|
+
code_completion_variables_1.SUFFIX,
|
|
31
|
+
code_completion_variables_1.LANGUAGE
|
|
32
|
+
].forEach(variable => {
|
|
33
|
+
service.registerResolver(variable, this);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
canResolve(_request, context) {
|
|
37
|
+
return code_completion_variable_context_1.CodeCompletionVariableContext.is(context) ? 1 : 0;
|
|
38
|
+
}
|
|
39
|
+
async resolve(request, context) {
|
|
40
|
+
if (!code_completion_variable_context_1.CodeCompletionVariableContext.is(context)) {
|
|
41
|
+
return Promise.resolve(undefined);
|
|
42
|
+
}
|
|
43
|
+
switch (request.variable.id) {
|
|
44
|
+
case code_completion_variables_1.FILE.id:
|
|
45
|
+
return this.resolveFile(context);
|
|
46
|
+
case code_completion_variables_1.LANGUAGE.id:
|
|
47
|
+
return this.resolveLanguage(context);
|
|
48
|
+
case code_completion_variables_1.PREFIX.id:
|
|
49
|
+
return this.resolvePrefix(context);
|
|
50
|
+
case code_completion_variables_1.SUFFIX.id:
|
|
51
|
+
return this.resolveSuffix(context);
|
|
52
|
+
default:
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
resolvePrefix(context) {
|
|
57
|
+
const position = context.position;
|
|
58
|
+
const model = context.model;
|
|
59
|
+
const maxContextLines = this.preferences.get(ai_code_completion_preference_1.PREF_AI_INLINE_COMPLETION_MAX_CONTEXT_LINES, -1);
|
|
60
|
+
let prefixStartLine = 1;
|
|
61
|
+
if (maxContextLines === 0) {
|
|
62
|
+
// Only the cursor line
|
|
63
|
+
prefixStartLine = position.lineNumber;
|
|
64
|
+
}
|
|
65
|
+
else if (maxContextLines > 0) {
|
|
66
|
+
const linesBeforeCursor = position.lineNumber - 1;
|
|
67
|
+
// Allocate one more line to the prefix in case of an odd maxContextLines
|
|
68
|
+
const prefixLines = Math.min(Math.ceil(maxContextLines / 2), linesBeforeCursor);
|
|
69
|
+
prefixStartLine = Math.max(1, position.lineNumber - prefixLines);
|
|
70
|
+
}
|
|
71
|
+
const prefix = model.getValueInRange({
|
|
72
|
+
startLineNumber: prefixStartLine,
|
|
73
|
+
startColumn: 1,
|
|
74
|
+
endLineNumber: position.lineNumber,
|
|
75
|
+
endColumn: position.column,
|
|
76
|
+
});
|
|
77
|
+
return {
|
|
78
|
+
variable: code_completion_variables_1.PREFIX,
|
|
79
|
+
value: prefix
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
resolveSuffix(context) {
|
|
83
|
+
const position = context.position;
|
|
84
|
+
const model = context.model;
|
|
85
|
+
const maxContextLines = this.preferences.get(ai_code_completion_preference_1.PREF_AI_INLINE_COMPLETION_MAX_CONTEXT_LINES, -1);
|
|
86
|
+
let suffixEndLine = model.getLineCount();
|
|
87
|
+
if (maxContextLines === 0) {
|
|
88
|
+
suffixEndLine = position.lineNumber;
|
|
89
|
+
}
|
|
90
|
+
else if (maxContextLines > 0) {
|
|
91
|
+
const linesAfterCursor = model.getLineCount() - position.lineNumber;
|
|
92
|
+
const suffixLines = Math.min(Math.floor(maxContextLines / 2), linesAfterCursor);
|
|
93
|
+
suffixEndLine = Math.min(model.getLineCount(), position.lineNumber + suffixLines);
|
|
94
|
+
}
|
|
95
|
+
const suffix = model.getValueInRange({
|
|
96
|
+
startLineNumber: position.lineNumber,
|
|
97
|
+
startColumn: position.column,
|
|
98
|
+
endLineNumber: suffixEndLine,
|
|
99
|
+
endColumn: model.getLineMaxColumn(suffixEndLine),
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
variable: code_completion_variables_1.SUFFIX,
|
|
103
|
+
value: suffix
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
resolveLanguage(context) {
|
|
107
|
+
return {
|
|
108
|
+
variable: code_completion_variables_1.LANGUAGE,
|
|
109
|
+
value: context.model.getLanguageId()
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
resolveFile(context) {
|
|
113
|
+
return {
|
|
114
|
+
variable: code_completion_variables_1.FILE,
|
|
115
|
+
value: context.model.uri.toString(false)
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
exports.CodeCompletionVariableContribution = CodeCompletionVariableContribution;
|
|
120
|
+
tslib_1.__decorate([
|
|
121
|
+
(0, inversify_1.inject)(preference_service_1.PreferenceService),
|
|
122
|
+
tslib_1.__metadata("design:type", Object)
|
|
123
|
+
], CodeCompletionVariableContribution.prototype, "preferences", void 0);
|
|
124
|
+
exports.CodeCompletionVariableContribution = CodeCompletionVariableContribution = tslib_1.__decorate([
|
|
125
|
+
(0, inversify_1.injectable)()
|
|
126
|
+
], CodeCompletionVariableContribution);
|
|
127
|
+
//# sourceMappingURL=code-completion-variable-contribution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-completion-variable-contribution.js","sourceRoot":"","sources":["../../src/browser/code-completion-variable-contribution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-completion-variable-contribution.spec.d.ts","sourceRoot":"","sources":["../../src/browser/code-completion-variable-contribution.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2025 Lonti.com Pty Ltd.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const frontend_application_config_provider_1 = require("@theia/core/lib/browser/frontend-application-config-provider");
|
|
19
|
+
const jsdom_1 = require("@theia/core/lib/browser/test/jsdom");
|
|
20
|
+
let disableJSDOM = (0, jsdom_1.enableJSDOM)();
|
|
21
|
+
frontend_application_config_provider_1.FrontendApplicationConfigProvider.set({});
|
|
22
|
+
const browser_1 = require("@theia/core/lib/browser");
|
|
23
|
+
const inversify_1 = require("@theia/core/shared/inversify");
|
|
24
|
+
const editor_api_1 = require("@theia/monaco-editor-core/esm/vs/editor/editor.api");
|
|
25
|
+
const chai_1 = require("chai");
|
|
26
|
+
const sinon = require("sinon");
|
|
27
|
+
const code_completion_variable_contribution_1 = require("./code-completion-variable-contribution");
|
|
28
|
+
const code_completion_variables_1 = require("./code-completion-variables");
|
|
29
|
+
disableJSDOM();
|
|
30
|
+
describe('CodeCompletionVariableContribution', () => {
|
|
31
|
+
let contribution;
|
|
32
|
+
let model;
|
|
33
|
+
before(() => {
|
|
34
|
+
disableJSDOM = (0, jsdom_1.enableJSDOM)();
|
|
35
|
+
const container = new inversify_1.Container();
|
|
36
|
+
container.bind(browser_1.PreferenceService).toConstantValue({
|
|
37
|
+
get: () => 1000,
|
|
38
|
+
});
|
|
39
|
+
container.bind(code_completion_variable_contribution_1.CodeCompletionVariableContribution).toSelf().inSingletonScope();
|
|
40
|
+
contribution = container.get(code_completion_variable_contribution_1.CodeCompletionVariableContribution);
|
|
41
|
+
});
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
model = editor_api_1.editor.createModel('//line 1\nconsole.\n//line 2', 'javascript', editor_api_1.Uri.file('/home/user/workspace/test.js'));
|
|
44
|
+
sinon.stub(model, 'getLanguageId').returns('javascript');
|
|
45
|
+
});
|
|
46
|
+
afterEach(() => {
|
|
47
|
+
model.dispose();
|
|
48
|
+
});
|
|
49
|
+
after(() => {
|
|
50
|
+
// Disable JSDOM after all tests
|
|
51
|
+
disableJSDOM();
|
|
52
|
+
model.dispose();
|
|
53
|
+
});
|
|
54
|
+
describe('canResolve', () => {
|
|
55
|
+
it('should be able to resolve the file from the CodeCompletionVariableContext', () => {
|
|
56
|
+
const context = {
|
|
57
|
+
model,
|
|
58
|
+
position: model.getPositionAt(8),
|
|
59
|
+
context: {
|
|
60
|
+
triggerKind: editor_api_1.languages.InlineCompletionTriggerKind.Automatic,
|
|
61
|
+
selectedSuggestionInfo: undefined,
|
|
62
|
+
includeInlineEdits: false,
|
|
63
|
+
includeInlineCompletions: false
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
(0, chai_1.expect)(contribution.canResolve({ variable: code_completion_variables_1.FILE }, context)).to.equal(1);
|
|
67
|
+
});
|
|
68
|
+
it('should not be able to resolve the file from unknown context', () => {
|
|
69
|
+
(0, chai_1.expect)(contribution.canResolve({ variable: code_completion_variables_1.FILE }, {})).to.equal(0);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('resolve', () => {
|
|
73
|
+
it('should resolve the file variable', async () => {
|
|
74
|
+
const context = {
|
|
75
|
+
model,
|
|
76
|
+
position: model.getPositionAt(17),
|
|
77
|
+
context: {
|
|
78
|
+
triggerKind: editor_api_1.languages.InlineCompletionTriggerKind.Automatic,
|
|
79
|
+
selectedSuggestionInfo: undefined,
|
|
80
|
+
includeInlineEdits: false,
|
|
81
|
+
includeInlineCompletions: false
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const resolved = await contribution.resolve({ variable: code_completion_variables_1.FILE }, context);
|
|
85
|
+
(0, chai_1.expect)(resolved).to.deep.equal({
|
|
86
|
+
variable: code_completion_variables_1.FILE,
|
|
87
|
+
value: 'file:///home/user/workspace/test.js'
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
it('should resolve the language variable', async () => {
|
|
91
|
+
const context = {
|
|
92
|
+
model,
|
|
93
|
+
position: model.getPositionAt(17),
|
|
94
|
+
context: {
|
|
95
|
+
triggerKind: editor_api_1.languages.InlineCompletionTriggerKind.Automatic,
|
|
96
|
+
selectedSuggestionInfo: undefined,
|
|
97
|
+
includeInlineEdits: false,
|
|
98
|
+
includeInlineCompletions: false
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const resolved = await contribution.resolve({ variable: code_completion_variables_1.LANGUAGE }, context);
|
|
102
|
+
(0, chai_1.expect)(resolved).to.deep.equal({
|
|
103
|
+
variable: code_completion_variables_1.LANGUAGE,
|
|
104
|
+
value: 'javascript'
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
it('should resolve the prefix variable', async () => {
|
|
108
|
+
const context = {
|
|
109
|
+
model,
|
|
110
|
+
position: model.getPositionAt(17),
|
|
111
|
+
context: {
|
|
112
|
+
triggerKind: editor_api_1.languages.InlineCompletionTriggerKind.Automatic,
|
|
113
|
+
selectedSuggestionInfo: undefined,
|
|
114
|
+
includeInlineEdits: false,
|
|
115
|
+
includeInlineCompletions: false
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const resolved = await contribution.resolve({ variable: code_completion_variables_1.PREFIX }, context);
|
|
119
|
+
(0, chai_1.expect)(resolved).to.deep.equal({
|
|
120
|
+
variable: code_completion_variables_1.PREFIX,
|
|
121
|
+
value: '//line 1\nconsole.'
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
it('should resolve the suffix variable', async () => {
|
|
125
|
+
const context = {
|
|
126
|
+
model,
|
|
127
|
+
position: model.getPositionAt(17),
|
|
128
|
+
context: {
|
|
129
|
+
triggerKind: editor_api_1.languages.InlineCompletionTriggerKind.Automatic,
|
|
130
|
+
selectedSuggestionInfo: undefined,
|
|
131
|
+
includeInlineEdits: false,
|
|
132
|
+
includeInlineCompletions: false
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
const resolved = await contribution.resolve({ variable: code_completion_variables_1.SUFFIX }, context);
|
|
136
|
+
(0, chai_1.expect)(resolved).to.deep.equal({
|
|
137
|
+
variable: code_completion_variables_1.SUFFIX,
|
|
138
|
+
value: '\n//line 2'
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
//# sourceMappingURL=code-completion-variable-contribution.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-completion-variable-contribution.spec.js","sourceRoot":"","sources":["../../src/browser/code-completion-variable-contribution.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AIVariable } from '@theia/ai-core/lib/common/variable-service';
|
|
2
|
+
export declare const FILE: AIVariable;
|
|
3
|
+
export declare const PREFIX: AIVariable;
|
|
4
|
+
export declare const SUFFIX: AIVariable;
|
|
5
|
+
export declare const LANGUAGE: AIVariable;
|
|
6
|
+
//# sourceMappingURL=code-completion-variables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-completion-variables.d.ts","sourceRoot":"","sources":["../../src/browser/code-completion-variables.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,UAAU,EAAE,MAAM,4CAA4C,CAAC;AAExE,eAAO,MAAM,IAAI,EAAE,UAIlB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,UAIpB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,UAIpB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,UAItB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2025 Lonti.com Pty Ltd.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.LANGUAGE = exports.SUFFIX = exports.PREFIX = exports.FILE = void 0;
|
|
19
|
+
exports.FILE = {
|
|
20
|
+
id: 'codeCompletionFile',
|
|
21
|
+
name: 'codeCompletionFile',
|
|
22
|
+
description: 'The uri of the file being edited.',
|
|
23
|
+
};
|
|
24
|
+
exports.PREFIX = {
|
|
25
|
+
id: 'codeCompletionPrefix',
|
|
26
|
+
name: 'codeCompletionPrefix',
|
|
27
|
+
description: 'The code before the current position of the cursor.',
|
|
28
|
+
};
|
|
29
|
+
exports.SUFFIX = {
|
|
30
|
+
id: 'codeCompletionSuffix',
|
|
31
|
+
name: 'codeCompletionSuffix',
|
|
32
|
+
description: 'The code after the current position of the cursor.',
|
|
33
|
+
};
|
|
34
|
+
exports.LANGUAGE = {
|
|
35
|
+
id: 'codeCompletionLanguage',
|
|
36
|
+
name: 'codeCompletionLanguage',
|
|
37
|
+
description: 'The languageId of the file being edited.',
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=code-completion-variables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-completion-variables.js","sourceRoot":"","sources":["../../src/browser/code-completion-variables.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,wCAAwC;AACxC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;AAInE,QAAA,IAAI,GAAe;IAC5B,EAAE,EAAE,oBAAoB;IACxB,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EAAE,mCAAmC;CACnD,CAAC;AAEW,QAAA,MAAM,GAAe;IAC9B,EAAE,EAAE,sBAAsB;IAC1B,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EAAE,qDAAqD;CACrE,CAAC;AAEW,QAAA,MAAM,GAAe;IAC9B,EAAE,EAAE,sBAAsB;IAC1B,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EAAE,oDAAoD;CACpE,CAAC;AAEW,QAAA,QAAQ,GAAe;IAChC,EAAE,EAAE,wBAAwB;IAC5B,IAAI,EAAE,wBAAwB;IAC9B,WAAW,EAAE,0CAA0C;CAC1D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theia/ai-code-completion",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.63.0-next.24+83b50cc66",
|
|
4
4
|
"description": "Theia - AI Core",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@theia/ai-core": "1.
|
|
7
|
-
"@theia/core": "1.
|
|
8
|
-
"@theia/filesystem": "1.
|
|
6
|
+
"@theia/ai-core": "1.63.0-next.24+83b50cc66",
|
|
7
|
+
"@theia/core": "1.63.0-next.24+83b50cc66",
|
|
8
|
+
"@theia/filesystem": "1.63.0-next.24+83b50cc66",
|
|
9
9
|
"@theia/monaco-editor-core": "1.96.302",
|
|
10
|
-
"@theia/output": "1.
|
|
11
|
-
"@theia/workspace": "1.
|
|
10
|
+
"@theia/output": "1.63.0-next.24+83b50cc66",
|
|
11
|
+
"@theia/workspace": "1.63.0-next.24+83b50cc66",
|
|
12
12
|
"minimatch": "^5.1.0",
|
|
13
13
|
"tslib": "^2.6.2"
|
|
14
14
|
},
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"watch": "theiaext watch"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@theia/ext-scripts": "1.62.
|
|
49
|
+
"@theia/ext-scripts": "1.62.0"
|
|
50
50
|
},
|
|
51
51
|
"nyc": {
|
|
52
52
|
"extends": "../../configs/nyc.json"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "83b50cc66b001a5b9100ccd944dcace04cd4ae2e"
|
|
55
55
|
}
|
|
@@ -14,14 +14,15 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import {
|
|
18
|
-
import { CodeCompletionAgent, CodeCompletionAgentImpl } from './code-completion-agent';
|
|
19
|
-
import { AIFrontendApplicationContribution } from './ai-code-frontend-application-contribution';
|
|
17
|
+
import { Agent, AIVariableContribution } from '@theia/ai-core';
|
|
20
18
|
import { FrontendApplicationContribution, KeybindingContribution, PreferenceContribution } from '@theia/core/lib/browser';
|
|
21
|
-
import {
|
|
19
|
+
import { ContainerModule } from '@theia/core/shared/inversify';
|
|
22
20
|
import { AICodeCompletionPreferencesSchema } from './ai-code-completion-preference';
|
|
21
|
+
import { AIFrontendApplicationContribution } from './ai-code-frontend-application-contribution';
|
|
23
22
|
import { AICodeInlineCompletionsProvider } from './ai-code-inline-completion-provider';
|
|
23
|
+
import { CodeCompletionAgent, CodeCompletionAgentImpl } from './code-completion-agent';
|
|
24
24
|
import { CodeCompletionPostProcessor, DefaultCodeCompletionPostProcessor } from './code-completion-postprocessor';
|
|
25
|
+
import { CodeCompletionVariableContribution } from './code-completion-variable-contribution';
|
|
25
26
|
|
|
26
27
|
export default new ContainerModule(bind => {
|
|
27
28
|
bind(CodeCompletionAgentImpl).toSelf().inSingletonScope();
|
|
@@ -33,4 +34,5 @@ export default new ContainerModule(bind => {
|
|
|
33
34
|
bind(KeybindingContribution).toService(AIFrontendApplicationContribution);
|
|
34
35
|
bind(PreferenceContribution).toConstantValue({ schema: AICodeCompletionPreferencesSchema });
|
|
35
36
|
bind(CodeCompletionPostProcessor).to(DefaultCodeCompletionPostProcessor).inSingletonScope();
|
|
37
|
+
bind(AIVariableContribution).to(CodeCompletionVariableContribution).inSingletonScope();
|
|
36
38
|
});
|
|
@@ -22,12 +22,11 @@ import {
|
|
|
22
22
|
UserRequest
|
|
23
23
|
} from '@theia/ai-core/lib/common';
|
|
24
24
|
import { generateUuid, ILogger, nls, ProgressService } from '@theia/core';
|
|
25
|
-
import { PreferenceService } from '@theia/core/lib/browser';
|
|
26
25
|
import { inject, injectable, named } from '@theia/core/shared/inversify';
|
|
27
26
|
import * as monaco from '@theia/monaco-editor-core';
|
|
28
|
-
import { PREF_AI_INLINE_COMPLETION_MAX_CONTEXT_LINES } from './ai-code-completion-preference';
|
|
29
27
|
import { codeCompletionPrompts } from './code-completion-prompt-template';
|
|
30
28
|
import { CodeCompletionPostProcessor } from './code-completion-postprocessor';
|
|
29
|
+
import { CodeCompletionVariableContext } from './code-completion-variable-context';
|
|
31
30
|
|
|
32
31
|
export const CodeCompletionAgent = Symbol('CodeCompletionAgent');
|
|
33
32
|
export interface CodeCompletionAgent extends Agent {
|
|
@@ -62,56 +61,17 @@ export class CodeCompletionAgentImpl implements CodeCompletionAgent {
|
|
|
62
61
|
return undefined;
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (maxContextLines === 0) {
|
|
72
|
-
// Only the cursor line
|
|
73
|
-
prefixStartLine = position.lineNumber;
|
|
74
|
-
suffixEndLine = position.lineNumber;
|
|
75
|
-
} else if (maxContextLines > 0) {
|
|
76
|
-
const linesBeforeCursor = position.lineNumber - 1;
|
|
77
|
-
const linesAfterCursor = model.getLineCount() - position.lineNumber;
|
|
78
|
-
|
|
79
|
-
// Allocate one more line to the prefix in case of an odd maxContextLines
|
|
80
|
-
const prefixLines = Math.min(
|
|
81
|
-
Math.ceil(maxContextLines / 2),
|
|
82
|
-
linesBeforeCursor
|
|
83
|
-
);
|
|
84
|
-
const suffixLines = Math.min(
|
|
85
|
-
Math.floor(maxContextLines / 2),
|
|
86
|
-
linesAfterCursor
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
prefixStartLine = Math.max(1, position.lineNumber - prefixLines);
|
|
90
|
-
suffixEndLine = Math.min(model.getLineCount(), position.lineNumber + suffixLines);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const prefix = model.getValueInRange({
|
|
94
|
-
startLineNumber: prefixStartLine,
|
|
95
|
-
startColumn: 1,
|
|
96
|
-
endLineNumber: position.lineNumber,
|
|
97
|
-
endColumn: position.column,
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
const suffix = model.getValueInRange({
|
|
101
|
-
startLineNumber: position.lineNumber,
|
|
102
|
-
startColumn: position.column,
|
|
103
|
-
endLineNumber: suffixEndLine,
|
|
104
|
-
endColumn: model.getLineMaxColumn(suffixEndLine),
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
const file = model.uri.toString(false);
|
|
108
|
-
const language = model.getLanguageId();
|
|
64
|
+
const variableContext: CodeCompletionVariableContext = {
|
|
65
|
+
model,
|
|
66
|
+
position,
|
|
67
|
+
context
|
|
68
|
+
};
|
|
109
69
|
|
|
110
70
|
if (token.isCancellationRequested) {
|
|
111
71
|
return undefined;
|
|
112
72
|
}
|
|
113
73
|
const prompt = await this.promptService
|
|
114
|
-
.getResolvedPromptFragment('code-completion-prompt',
|
|
74
|
+
.getResolvedPromptFragment('code-completion-prompt', undefined, variableContext)
|
|
115
75
|
.then(p => p?.text);
|
|
116
76
|
if (!prompt) {
|
|
117
77
|
this.logger.error('No prompt found for code-completion-agent');
|
|
@@ -174,9 +134,6 @@ export class CodeCompletionAgentImpl implements CodeCompletionAgent {
|
|
|
174
134
|
@inject(ProgressService)
|
|
175
135
|
protected progressService: ProgressService;
|
|
176
136
|
|
|
177
|
-
@inject(PreferenceService)
|
|
178
|
-
protected preferences: PreferenceService;
|
|
179
|
-
|
|
180
137
|
@inject(CodeCompletionPostProcessor)
|
|
181
138
|
protected postProcessor: CodeCompletionPostProcessor;
|
|
182
139
|
|
|
@@ -193,11 +150,5 @@ export class CodeCompletionAgentImpl implements CodeCompletionAgent {
|
|
|
193
150
|
];
|
|
194
151
|
readonly variables: string[] = [];
|
|
195
152
|
readonly functions: string[] = [];
|
|
196
|
-
readonly agentSpecificVariables: AgentSpecificVariables[] = [
|
|
197
|
-
{ name: 'file', usedInPrompt: true, description: 'The uri of the file being edited.' },
|
|
198
|
-
{ name: 'language', usedInPrompt: true, description: 'The languageId of the file being edited.' },
|
|
199
|
-
{ name: 'prefix', usedInPrompt: true, description: 'The code before the current position of the cursor.' },
|
|
200
|
-
{ name: 'suffix', usedInPrompt: true, description: 'The code after the current position of the cursor.' }
|
|
201
|
-
];
|
|
202
|
-
readonly tags?: string[] | undefined;
|
|
153
|
+
readonly agentSpecificVariables: AgentSpecificVariables[] = [];
|
|
203
154
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
// *****************************************************************************
|
|
11
11
|
|
|
12
12
|
import { PromptVariantSet } from '@theia/ai-core/lib/common';
|
|
13
|
+
import { FILE, LANGUAGE, PREFIX, SUFFIX } from './code-completion-variables';
|
|
13
14
|
|
|
14
15
|
export const codeCompletionPrompts: PromptVariantSet[] = [{
|
|
15
16
|
id: 'code-completion-prompt',
|
|
@@ -18,11 +19,11 @@ export const codeCompletionPrompts: PromptVariantSet[] = [{
|
|
|
18
19
|
template: `{{!-- This prompt is licensed under the MIT License (https://opensource.org/license/mit).
|
|
19
20
|
Made improvements or adaptations to this prompt template? We’d love for you to share it with the community! Contribute back here:
|
|
20
21
|
https://github.com/eclipse-theia/theia/discussions/new?category=prompt-template-contribution --}}
|
|
21
|
-
You are a code completion agent. The current file you have to complete is named {{
|
|
22
|
-
The language of the file is {{
|
|
22
|
+
You are a code completion agent. The current file you have to complete is named {{${FILE.id}}}.
|
|
23
|
+
The language of the file is {{${LANGUAGE.id}}}. Return your result as plain text without markdown formatting.
|
|
23
24
|
Finish the following code snippet.
|
|
24
25
|
|
|
25
|
-
{{
|
|
26
|
+
{{${PREFIX.id}}}[[MARKER]]{{${SUFFIX.id}}}
|
|
26
27
|
|
|
27
28
|
Only return the exact replacement for [[MARKER]] to complete the snippet.`
|
|
28
29
|
}],
|
|
@@ -33,12 +34,12 @@ Made improvements or adaptations to this prompt template? We’d love for you to
|
|
|
33
34
|
https://github.com/eclipse-theia/theia/discussions/new?category=prompt-template-contribution --}}
|
|
34
35
|
## Code snippet
|
|
35
36
|
\`\`\`
|
|
36
|
-
{{
|
|
37
|
+
{{${PREFIX.id}}}[[MARKER]]{{${SUFFIX.id}}}
|
|
37
38
|
\`\`\`
|
|
38
39
|
|
|
39
40
|
## Meta Data
|
|
40
|
-
- File: {{
|
|
41
|
-
- Language: {{
|
|
41
|
+
- File: {{${FILE.id}}}
|
|
42
|
+
- Language: {{${LANGUAGE.id}}}
|
|
42
43
|
|
|
43
44
|
Replace [[MARKER]] with the exact code to complete the code snippet. Return only the replacement of [[MARKER]] as plain text.`,
|
|
44
45
|
},
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 Lonti.com Pty Ltd.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { AIVariableContext } from '@theia/ai-core';
|
|
18
|
+
import * as monaco from '@theia/monaco-editor-core';
|
|
19
|
+
|
|
20
|
+
export interface CodeCompletionVariableContext {
|
|
21
|
+
model: monaco.editor.ITextModel,
|
|
22
|
+
position: monaco.Position,
|
|
23
|
+
context: monaco.languages.InlineCompletionContext
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export namespace CodeCompletionVariableContext {
|
|
27
|
+
export function is(context: AIVariableContext): context is CodeCompletionVariableContext {
|
|
28
|
+
return !!context && 'model' in context && 'position' in context && 'context' in context;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 Lonti.com Pty Ltd.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
|
|
18
|
+
import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
|
|
19
|
+
let disableJSDOM = enableJSDOM();
|
|
20
|
+
FrontendApplicationConfigProvider.set({});
|
|
21
|
+
|
|
22
|
+
import { PreferenceService } from '@theia/core/lib/browser';
|
|
23
|
+
import { Container } from '@theia/core/shared/inversify';
|
|
24
|
+
import { editor, languages, Uri } from '@theia/monaco-editor-core/esm/vs/editor/editor.api';
|
|
25
|
+
import { expect } from 'chai';
|
|
26
|
+
import * as sinon from 'sinon';
|
|
27
|
+
import { CodeCompletionVariableContext } from './code-completion-variable-context';
|
|
28
|
+
import { CodeCompletionVariableContribution } from './code-completion-variable-contribution';
|
|
29
|
+
import { FILE, LANGUAGE, PREFIX, SUFFIX } from './code-completion-variables';
|
|
30
|
+
|
|
31
|
+
disableJSDOM();
|
|
32
|
+
|
|
33
|
+
describe('CodeCompletionVariableContribution', () => {
|
|
34
|
+
let contribution: CodeCompletionVariableContribution;
|
|
35
|
+
let model: editor.ITextModel;
|
|
36
|
+
|
|
37
|
+
before(() => {
|
|
38
|
+
disableJSDOM = enableJSDOM();
|
|
39
|
+
const container = new Container();
|
|
40
|
+
container.bind(PreferenceService).toConstantValue({
|
|
41
|
+
get: () => 1000,
|
|
42
|
+
});
|
|
43
|
+
container.bind(CodeCompletionVariableContribution).toSelf().inSingletonScope();
|
|
44
|
+
contribution = container.get(CodeCompletionVariableContribution);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
beforeEach(() => {
|
|
48
|
+
model = editor.createModel('//line 1\nconsole.\n//line 2', 'javascript', Uri.file('/home/user/workspace/test.js'));
|
|
49
|
+
sinon.stub(model, 'getLanguageId').returns('javascript');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
afterEach(() => {
|
|
53
|
+
model.dispose();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
after(() => {
|
|
57
|
+
// Disable JSDOM after all tests
|
|
58
|
+
disableJSDOM();
|
|
59
|
+
model.dispose();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe('canResolve', () => {
|
|
63
|
+
it('should be able to resolve the file from the CodeCompletionVariableContext', () => {
|
|
64
|
+
const context: CodeCompletionVariableContext = {
|
|
65
|
+
model,
|
|
66
|
+
position: model.getPositionAt(8),
|
|
67
|
+
context: {
|
|
68
|
+
triggerKind: languages.InlineCompletionTriggerKind.Automatic,
|
|
69
|
+
selectedSuggestionInfo: undefined,
|
|
70
|
+
includeInlineEdits: false,
|
|
71
|
+
includeInlineCompletions: false
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
expect(contribution.canResolve({ variable: FILE }, context)).to.equal(1);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should not be able to resolve the file from unknown context', () => {
|
|
79
|
+
expect(contribution.canResolve({ variable: FILE }, {})).to.equal(0);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('resolve', () => {
|
|
84
|
+
it('should resolve the file variable', async () => {
|
|
85
|
+
const context: CodeCompletionVariableContext = {
|
|
86
|
+
model,
|
|
87
|
+
position: model.getPositionAt(17),
|
|
88
|
+
context: {
|
|
89
|
+
triggerKind: languages.InlineCompletionTriggerKind.Automatic,
|
|
90
|
+
selectedSuggestionInfo: undefined,
|
|
91
|
+
includeInlineEdits: false,
|
|
92
|
+
includeInlineCompletions: false
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const resolved = await contribution.resolve({ variable: FILE }, context);
|
|
97
|
+
expect(resolved).to.deep.equal({
|
|
98
|
+
variable: FILE,
|
|
99
|
+
value: 'file:///home/user/workspace/test.js'
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('should resolve the language variable', async () => {
|
|
104
|
+
const context: CodeCompletionVariableContext = {
|
|
105
|
+
model,
|
|
106
|
+
position: model.getPositionAt(17),
|
|
107
|
+
context: {
|
|
108
|
+
triggerKind: languages.InlineCompletionTriggerKind.Automatic,
|
|
109
|
+
selectedSuggestionInfo: undefined,
|
|
110
|
+
includeInlineEdits: false,
|
|
111
|
+
includeInlineCompletions: false
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const resolved = await contribution.resolve({ variable: LANGUAGE }, context);
|
|
116
|
+
expect(resolved).to.deep.equal({
|
|
117
|
+
variable: LANGUAGE,
|
|
118
|
+
value: 'javascript'
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should resolve the prefix variable', async () => {
|
|
123
|
+
const context: CodeCompletionVariableContext = {
|
|
124
|
+
model,
|
|
125
|
+
position: model.getPositionAt(17),
|
|
126
|
+
context: {
|
|
127
|
+
triggerKind: languages.InlineCompletionTriggerKind.Automatic,
|
|
128
|
+
selectedSuggestionInfo: undefined,
|
|
129
|
+
includeInlineEdits: false,
|
|
130
|
+
includeInlineCompletions: false
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const resolved = await contribution.resolve({ variable: PREFIX }, context);
|
|
135
|
+
expect(resolved).to.deep.equal({
|
|
136
|
+
variable: PREFIX,
|
|
137
|
+
value: '//line 1\nconsole.'
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should resolve the suffix variable', async () => {
|
|
142
|
+
const context: CodeCompletionVariableContext = {
|
|
143
|
+
model,
|
|
144
|
+
position: model.getPositionAt(17),
|
|
145
|
+
context: {
|
|
146
|
+
triggerKind: languages.InlineCompletionTriggerKind.Automatic,
|
|
147
|
+
selectedSuggestionInfo: undefined,
|
|
148
|
+
includeInlineEdits: false,
|
|
149
|
+
includeInlineCompletions: false
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const resolved = await contribution.resolve({ variable: SUFFIX }, context);
|
|
154
|
+
expect(resolved).to.deep.equal({
|
|
155
|
+
variable: SUFFIX,
|
|
156
|
+
value: '\n//line 2'
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 Lonti.com Pty Ltd.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { AIVariableContext, AIVariableResolutionRequest, AIVariableResolver, ResolvedAIVariable } from '@theia/ai-core';
|
|
18
|
+
import { FrontendVariableContribution, FrontendVariableService } from '@theia/ai-core/lib/browser';
|
|
19
|
+
import { MaybePromise } from '@theia/core';
|
|
20
|
+
import { PreferenceService } from '@theia/core/lib/browser/preferences/preference-service';
|
|
21
|
+
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
22
|
+
import { PREF_AI_INLINE_COMPLETION_MAX_CONTEXT_LINES } from './ai-code-completion-preference';
|
|
23
|
+
import { CodeCompletionVariableContext } from './code-completion-variable-context';
|
|
24
|
+
import { FILE, LANGUAGE, PREFIX, SUFFIX } from './code-completion-variables';
|
|
25
|
+
|
|
26
|
+
@injectable()
|
|
27
|
+
export class CodeCompletionVariableContribution implements FrontendVariableContribution, AIVariableResolver {
|
|
28
|
+
@inject(PreferenceService)
|
|
29
|
+
protected preferences: PreferenceService;
|
|
30
|
+
|
|
31
|
+
registerVariables(service: FrontendVariableService): void {
|
|
32
|
+
[
|
|
33
|
+
FILE,
|
|
34
|
+
PREFIX,
|
|
35
|
+
SUFFIX,
|
|
36
|
+
LANGUAGE
|
|
37
|
+
].forEach(variable => {
|
|
38
|
+
service.registerResolver(variable, this);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
canResolve(_request: AIVariableResolutionRequest, context: AIVariableContext): MaybePromise<number> {
|
|
43
|
+
return CodeCompletionVariableContext.is(context) ? 1 : 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async resolve(request: AIVariableResolutionRequest, context: AIVariableContext): Promise<ResolvedAIVariable | undefined> {
|
|
47
|
+
if (!CodeCompletionVariableContext.is(context)) {
|
|
48
|
+
return Promise.resolve(undefined);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
switch (request.variable.id) {
|
|
52
|
+
case FILE.id:
|
|
53
|
+
return this.resolveFile(context);
|
|
54
|
+
case LANGUAGE.id:
|
|
55
|
+
return this.resolveLanguage(context);
|
|
56
|
+
case PREFIX.id:
|
|
57
|
+
return this.resolvePrefix(context);
|
|
58
|
+
case SUFFIX.id:
|
|
59
|
+
return this.resolveSuffix(context);
|
|
60
|
+
default:
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
protected resolvePrefix(context: CodeCompletionVariableContext): ResolvedAIVariable | undefined {
|
|
66
|
+
const position = context.position;
|
|
67
|
+
const model = context.model;
|
|
68
|
+
const maxContextLines = this.preferences.get<number>(PREF_AI_INLINE_COMPLETION_MAX_CONTEXT_LINES, -1);
|
|
69
|
+
let prefixStartLine = 1;
|
|
70
|
+
|
|
71
|
+
if (maxContextLines === 0) {
|
|
72
|
+
// Only the cursor line
|
|
73
|
+
prefixStartLine = position.lineNumber;
|
|
74
|
+
} else if (maxContextLines > 0) {
|
|
75
|
+
const linesBeforeCursor = position.lineNumber - 1;
|
|
76
|
+
|
|
77
|
+
// Allocate one more line to the prefix in case of an odd maxContextLines
|
|
78
|
+
const prefixLines = Math.min(
|
|
79
|
+
Math.ceil(maxContextLines / 2),
|
|
80
|
+
linesBeforeCursor
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
prefixStartLine = Math.max(1, position.lineNumber - prefixLines);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const prefix = model.getValueInRange({
|
|
87
|
+
startLineNumber: prefixStartLine,
|
|
88
|
+
startColumn: 1,
|
|
89
|
+
endLineNumber: position.lineNumber,
|
|
90
|
+
endColumn: position.column,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
variable: PREFIX,
|
|
95
|
+
value: prefix
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
protected resolveSuffix(context: CodeCompletionVariableContext): ResolvedAIVariable | undefined {
|
|
100
|
+
const position = context.position;
|
|
101
|
+
const model = context.model;
|
|
102
|
+
const maxContextLines = this.preferences.get<number>(PREF_AI_INLINE_COMPLETION_MAX_CONTEXT_LINES, -1);
|
|
103
|
+
let suffixEndLine = model.getLineCount();
|
|
104
|
+
|
|
105
|
+
if (maxContextLines === 0) {
|
|
106
|
+
suffixEndLine = position.lineNumber;
|
|
107
|
+
} else if (maxContextLines > 0) {
|
|
108
|
+
const linesAfterCursor = model.getLineCount() - position.lineNumber;
|
|
109
|
+
|
|
110
|
+
const suffixLines = Math.min(
|
|
111
|
+
Math.floor(maxContextLines / 2),
|
|
112
|
+
linesAfterCursor
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
suffixEndLine = Math.min(model.getLineCount(), position.lineNumber + suffixLines);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const suffix = model.getValueInRange({
|
|
119
|
+
startLineNumber: position.lineNumber,
|
|
120
|
+
startColumn: position.column,
|
|
121
|
+
endLineNumber: suffixEndLine,
|
|
122
|
+
endColumn: model.getLineMaxColumn(suffixEndLine),
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
variable: SUFFIX,
|
|
127
|
+
value: suffix
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
protected resolveLanguage(context: CodeCompletionVariableContext): ResolvedAIVariable | undefined {
|
|
132
|
+
return {
|
|
133
|
+
variable: LANGUAGE,
|
|
134
|
+
value: context.model.getLanguageId()
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
protected resolveFile(context: CodeCompletionVariableContext): ResolvedAIVariable | undefined {
|
|
139
|
+
return {
|
|
140
|
+
variable: FILE,
|
|
141
|
+
value: context.model.uri.toString(false)
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 Lonti.com Pty Ltd.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { AIVariable } from '@theia/ai-core/lib/common/variable-service';
|
|
18
|
+
|
|
19
|
+
export const FILE: AIVariable = {
|
|
20
|
+
id: 'codeCompletionFile',
|
|
21
|
+
name: 'codeCompletionFile',
|
|
22
|
+
description: 'The uri of the file being edited.',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const PREFIX: AIVariable = {
|
|
26
|
+
id: 'codeCompletionPrefix',
|
|
27
|
+
name: 'codeCompletionPrefix',
|
|
28
|
+
description: 'The code before the current position of the cursor.',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const SUFFIX: AIVariable = {
|
|
32
|
+
id: 'codeCompletionSuffix',
|
|
33
|
+
name: 'codeCompletionSuffix',
|
|
34
|
+
description: 'The code after the current position of the cursor.',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const LANGUAGE: AIVariable = {
|
|
38
|
+
id: 'codeCompletionLanguage',
|
|
39
|
+
name: 'codeCompletionLanguage',
|
|
40
|
+
description: 'The languageId of the file being edited.',
|
|
41
|
+
};
|