Skip to content

Commit a470d33

Browse files
authored
Add shortcut for adding the current file to the AI chat context (#15252)
1 parent 52a7626 commit a470d33

File tree

1 file changed

+81
-40
lines changed

1 file changed

+81
-40
lines changed

packages/ai-core/src/browser/theia-variable-contribution.ts

Lines changed: 81 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ import { inject, injectable } from '@theia/core/shared/inversify';
1919
import { VariableRegistry, VariableResolverService } from '@theia/variable-resolver/lib/browser';
2020
import { AIVariableContribution, AIVariableResolver, AIVariableService, AIVariableResolutionRequest, AIVariableContext, ResolvedAIVariable } from '../common';
2121

22+
/**
23+
* Mapping configuration for a Theia variable to one or more AI variables
24+
*/
25+
interface VariableMapping {
26+
name?: string;
27+
description?: string;
28+
}
29+
2230
/**
2331
* Integrates the Theia VariableRegistry with the Theia AI VariableService
2432
*/
@@ -36,33 +44,52 @@ export class TheiaVariableContribution implements AIVariableContribution, AIVari
3644
@inject(FrontendApplicationStateService)
3745
protected readonly stateService: FrontendApplicationStateService;
3846

39-
// Map original variable name to new name and description. If a mapped value is not present then the original will be kept.
47+
// Map original variable name to one or more mappings with new name and description.
4048
// Only variables present in this map are registered.
41-
protected variableRenameMap: Map<string, { name?: string, description?: string }> = new Map([
42-
['file', {
43-
name: 'currentAbsoluteFilePath', description: nls.localize('theia/ai/core/variable-contribution/currentAbsoluteFilePath', 'The absolute path of the \
44-
currently opened file. Please note that most agents will expect a relative file path (relative to the current workspace).')
45-
}],
46-
['selectedText', {
47-
description: nls.localize('theia/ai/core/variable-contribution/currentSelectedText', 'The plain text that is currently selected in the \
48-
opened file. This excludes the information where the content is coming from. Please note that most agents will work better with a relative file path \
49-
(relative to the current workspace).')
50-
}],
51-
['currentText', {
52-
name: 'currentFileContent', description: nls.localize('theia/ai/core/variable-contribution/currentFileContent', 'The plain content of the \
53-
currently opened file. This excludes the information where the content is coming from. Please note that most agents will work better with a relative file path \
54-
(relative to the current workspace).')
55-
}],
56-
['relativeFile', {
57-
name: 'currentRelativeFilePath', description: nls.localize('theia/ai/core/variable-contribution/currentRelativeFilePath', 'The relative path of the \
58-
currently opened file.')
59-
}],
60-
['relativeFileDirname', {
61-
name: 'currentRelativeDirPath', description: nls.localize('theia/ai/core/variable-contribution/currentRelativeDirPath', 'The relative path of the directory \
62-
containing the currently opened file.')
63-
}],
64-
['lineNumber', {}],
65-
['workspaceFolder', {}]
49+
protected variableRenameMap: Map<string, VariableMapping[]> = new Map([
50+
['file', [
51+
{
52+
name: 'currentAbsoluteFilePath',
53+
description: nls.localize('theia/ai/core/variable-contribution/currentAbsoluteFilePath', 'The absolute path of the \
54+
currently opened file. Please note that most agents will expect a relative file path (relative to the current workspace).')
55+
}
56+
]],
57+
['selectedText', [
58+
{
59+
description: nls.localize('theia/ai/core/variable-contribution/currentSelectedText', 'The plain text that is currently selected in the \
60+
opened file. This excludes the information where the content is coming from. Please note that most agents will work better with a relative file path \
61+
(relative to the current workspace).')
62+
}
63+
]],
64+
['currentText', [
65+
{
66+
name: 'currentFileContent',
67+
description: nls.localize('theia/ai/core/variable-contribution/currentFileContent', 'The plain content of the \
68+
currently opened file. This excludes the information where the content is coming from. Please note that most agents will work better with a relative file path \
69+
(relative to the current workspace).')
70+
}
71+
]],
72+
['relativeFile', [
73+
{
74+
name: 'currentRelativeFilePath',
75+
description: nls.localize('theia/ai/core/variable-contribution/currentRelativeFilePath', 'The relative path of the \
76+
currently opened file.')
77+
},
78+
{
79+
name: '_f',
80+
description: nls.localize('theia/ai/core/variable-contribution/dotRelativePath', 'Short reference to the relative path of the \
81+
currently opened file (\'currentRelativeFilePath\').')
82+
}
83+
]],
84+
['relativeFileDirname', [
85+
{
86+
name: 'currentRelativeDirPath',
87+
description: nls.localize('theia/ai/core/variable-contribution/currentRelativeDirPath', 'The relative path of the directory \
88+
containing the currently opened file.')
89+
}
90+
]],
91+
['lineNumber', [{}]],
92+
['workspaceFolder', [{}]]
6693
]);
6794

6895
registerVariables(service: AIVariableService): void {
@@ -73,25 +100,39 @@ export class TheiaVariableContribution implements AIVariableContribution, AIVari
73100
if (!this.variableRenameMap.has(variable.name)) {
74101
return; // Do not register variables not part of the map
75102
}
76-
const mapping = this.variableRenameMap.get(variable.name)!;
77-
const newName = (mapping.name && mapping.name.trim() !== '') ? mapping.name : variable.name;
78-
const newDescription = (mapping.description && mapping.description.trim() !== '') ? mapping.description
79-
: (variable.description && variable.description.trim() !== '' ? variable.description
80-
: nls.localize('theia/ai/core/variable-contribution/builtInVariable', 'Theia Built-in Variable'));
81-
82-
service.registerResolver({
83-
id: `${TheiaVariableContribution.THEIA_PREFIX}${variable.name}`,
84-
name: newName,
85-
description: newDescription
86-
}, this);
103+
104+
const mappings = this.variableRenameMap.get(variable.name)!;
105+
106+
// Register each mapping for this variable
107+
mappings.forEach((mapping, index) => {
108+
const newName = (mapping.name && mapping.name.trim() !== '') ? mapping.name : variable.name;
109+
const newDescription = (mapping.description && mapping.description.trim() !== '') ? mapping.description
110+
: (variable.description && variable.description.trim() !== '' ? variable.description
111+
: nls.localize('theia/ai/core/variable-contribution/builtInVariable', 'Theia Built-in Variable'));
112+
113+
// For multiple mappings of the same variable, add a suffix to the ID to make it unique
114+
const idSuffix = mappings.length > 1 ? `-${index}` : '';
115+
const id = `${TheiaVariableContribution.THEIA_PREFIX}${variable.name}${idSuffix}`;
116+
117+
service.registerResolver({
118+
id,
119+
name: newName,
120+
description: newDescription
121+
}, this);
122+
});
87123
});
88124
});
89125
}
90126

91127
protected toTheiaVariable(request: AIVariableResolutionRequest): string {
92-
// Remove the THEIA_PREFIX if present before constructing the variable string
93-
const variableId = request.variable.id.startsWith(TheiaVariableContribution.THEIA_PREFIX) ? request.variable.id.slice(TheiaVariableContribution.THEIA_PREFIX.length) :
94-
request.variable.id;
128+
// Extract the base variable name by removing the THEIA_PREFIX and any potential index suffix
129+
let variableId = request.variable.id;
130+
if (variableId.startsWith(TheiaVariableContribution.THEIA_PREFIX)) {
131+
variableId = variableId.slice(TheiaVariableContribution.THEIA_PREFIX.length);
132+
// Remove any potential index suffix (e.g., -0, -1)
133+
variableId = variableId.replace(/-\d+$/, '');
134+
}
135+
95136
return `\${${variableId}${request.arg ? ':' + request.arg : ''}}`;
96137
}
97138

0 commit comments

Comments
 (0)