@theia/ai-core 1.46.0-next.241

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.
Files changed (209) hide show
  1. package/README.md +31 -0
  2. package/data/prompttemplate.tmLanguage.json +107 -0
  3. package/lib/browser/ai-activation-service.d.ts +17 -0
  4. package/lib/browser/ai-activation-service.d.ts.map +1 -0
  5. package/lib/browser/ai-activation-service.js +63 -0
  6. package/lib/browser/ai-activation-service.js.map +1 -0
  7. package/lib/browser/ai-command-handler-factory.d.ts +4 -0
  8. package/lib/browser/ai-command-handler-factory.d.ts.map +1 -0
  9. package/lib/browser/ai-command-handler-factory.js +20 -0
  10. package/lib/browser/ai-command-handler-factory.js.map +1 -0
  11. package/lib/browser/ai-configuration/agent-configuration-widget.d.ts +28 -0
  12. package/lib/browser/ai-configuration/agent-configuration-widget.d.ts.map +1 -0
  13. package/lib/browser/ai-configuration/agent-configuration-widget.js +242 -0
  14. package/lib/browser/ai-configuration/agent-configuration-widget.js.map +1 -0
  15. package/lib/browser/ai-configuration/ai-configuration-service.d.ts +13 -0
  16. package/lib/browser/ai-configuration/ai-configuration-service.d.ts.map +1 -0
  17. package/lib/browser/ai-configuration/ai-configuration-service.js +44 -0
  18. package/lib/browser/ai-configuration/ai-configuration-service.js.map +1 -0
  19. package/lib/browser/ai-configuration/ai-configuration-view-contribution.d.ts +12 -0
  20. package/lib/browser/ai-configuration/ai-configuration-view-contribution.d.ts.map +1 -0
  21. package/lib/browser/ai-configuration/ai-configuration-view-contribution.js +41 -0
  22. package/lib/browser/ai-configuration/ai-configuration-view-contribution.js.map +1 -0
  23. package/lib/browser/ai-configuration/ai-configuration-widget.d.ts +20 -0
  24. package/lib/browser/ai-configuration/ai-configuration-widget.d.ts.map +1 -0
  25. package/lib/browser/ai-configuration/ai-configuration-widget.js +88 -0
  26. package/lib/browser/ai-configuration/ai-configuration-widget.js.map +1 -0
  27. package/lib/browser/ai-configuration/language-model-renderer.d.ts +13 -0
  28. package/lib/browser/ai-configuration/language-model-renderer.d.ts.map +1 -0
  29. package/lib/browser/ai-configuration/language-model-renderer.js +104 -0
  30. package/lib/browser/ai-configuration/language-model-renderer.js.map +1 -0
  31. package/lib/browser/ai-configuration/template-settings-renderer.d.ts +13 -0
  32. package/lib/browser/ai-configuration/template-settings-renderer.d.ts.map +1 -0
  33. package/lib/browser/ai-configuration/template-settings-renderer.js +71 -0
  34. package/lib/browser/ai-configuration/template-settings-renderer.js.map +1 -0
  35. package/lib/browser/ai-configuration/variable-configuration-widget.d.ts +20 -0
  36. package/lib/browser/ai-configuration/variable-configuration-widget.d.ts.map +1 -0
  37. package/lib/browser/ai-configuration/variable-configuration-widget.js +99 -0
  38. package/lib/browser/ai-configuration/variable-configuration-widget.js.map +1 -0
  39. package/lib/browser/ai-core-frontend-application-contribution.d.ts +10 -0
  40. package/lib/browser/ai-core-frontend-application-contribution.d.ts.map +1 -0
  41. package/lib/browser/ai-core-frontend-application-contribution.js +46 -0
  42. package/lib/browser/ai-core-frontend-application-contribution.js.map +1 -0
  43. package/lib/browser/ai-core-frontend-module.d.ts +4 -0
  44. package/lib/browser/ai-core-frontend-module.d.ts.map +1 -0
  45. package/lib/browser/ai-core-frontend-module.js +122 -0
  46. package/lib/browser/ai-core-frontend-module.js.map +1 -0
  47. package/lib/browser/ai-core-preferences.d.ts +29 -0
  48. package/lib/browser/ai-core-preferences.d.ts.map +1 -0
  49. package/lib/browser/ai-core-preferences.js +98 -0
  50. package/lib/browser/ai-core-preferences.js.map +1 -0
  51. package/lib/browser/ai-settings-service.d.ts +14 -0
  52. package/lib/browser/ai-settings-service.d.ts.map +1 -0
  53. package/lib/browser/ai-settings-service.js +56 -0
  54. package/lib/browser/ai-settings-service.js.map +1 -0
  55. package/lib/browser/ai-view-contribution.d.ts +14 -0
  56. package/lib/browser/ai-view-contribution.d.ts.map +1 -0
  57. package/lib/browser/ai-view-contribution.js +71 -0
  58. package/lib/browser/ai-view-contribution.js.map +1 -0
  59. package/lib/browser/frontend-language-model-registry.d.ts +39 -0
  60. package/lib/browser/frontend-language-model-registry.d.ts.map +1 -0
  61. package/lib/browser/frontend-language-model-registry.js +321 -0
  62. package/lib/browser/frontend-language-model-registry.js.map +1 -0
  63. package/lib/browser/frontend-prompt-customization-service.d.ts +33 -0
  64. package/lib/browser/frontend-prompt-customization-service.d.ts.map +1 -0
  65. package/lib/browser/frontend-prompt-customization-service.js +237 -0
  66. package/lib/browser/frontend-prompt-customization-service.js.map +1 -0
  67. package/lib/browser/frontend-variable-service.d.ts +6 -0
  68. package/lib/browser/frontend-variable-service.d.ts.map +1 -0
  69. package/lib/browser/frontend-variable-service.js +31 -0
  70. package/lib/browser/frontend-variable-service.js.map +1 -0
  71. package/lib/browser/index.d.ts +11 -0
  72. package/lib/browser/index.d.ts.map +1 -0
  73. package/lib/browser/index.js +29 -0
  74. package/lib/browser/index.js.map +1 -0
  75. package/lib/browser/prompttemplate-contribution.d.ts +29 -0
  76. package/lib/browser/prompttemplate-contribution.d.ts.map +1 -0
  77. package/lib/browser/prompttemplate-contribution.js +208 -0
  78. package/lib/browser/prompttemplate-contribution.js.map +1 -0
  79. package/lib/browser/theia-variable-contribution.d.ts +13 -0
  80. package/lib/browser/theia-variable-contribution.d.ts.map +1 -0
  81. package/lib/browser/theia-variable-contribution.js +64 -0
  82. package/lib/browser/theia-variable-contribution.js.map +1 -0
  83. package/lib/common/agent-service.d.ts +66 -0
  84. package/lib/common/agent-service.d.ts.map +1 -0
  85. package/lib/common/agent-service.js +92 -0
  86. package/lib/common/agent-service.js.map +1 -0
  87. package/lib/common/agent.d.ts +45 -0
  88. package/lib/common/agent.d.ts.map +1 -0
  89. package/lib/common/agent.js +20 -0
  90. package/lib/common/agent.js.map +1 -0
  91. package/lib/common/agents-variable-contribution.d.ts +19 -0
  92. package/lib/common/agents-variable-contribution.d.ts.map +1 -0
  93. package/lib/common/agents-variable-contribution.js +56 -0
  94. package/lib/common/agents-variable-contribution.js.map +1 -0
  95. package/lib/common/communication-recording-service.d.ts +29 -0
  96. package/lib/common/communication-recording-service.d.ts.map +1 -0
  97. package/lib/common/communication-recording-service.js +20 -0
  98. package/lib/common/communication-recording-service.js.map +1 -0
  99. package/lib/common/index.d.ts +16 -0
  100. package/lib/common/index.d.ts.map +1 -0
  101. package/lib/common/index.js +34 -0
  102. package/lib/common/index.js.map +1 -0
  103. package/lib/common/language-model-delegate.d.ts +24 -0
  104. package/lib/common/language-model-delegate.d.ts.map +1 -0
  105. package/lib/common/language-model-delegate.js +26 -0
  106. package/lib/common/language-model-delegate.js.map +1 -0
  107. package/lib/common/language-model-util.d.ts +16 -0
  108. package/lib/common/language-model-util.d.ts.map +1 -0
  109. package/lib/common/language-model-util.js +92 -0
  110. package/lib/common/language-model-util.js.map +1 -0
  111. package/lib/common/language-model.d.ts +144 -0
  112. package/lib/common/language-model.d.ts.map +1 -0
  113. package/lib/common/language-model.js +142 -0
  114. package/lib/common/language-model.js.map +1 -0
  115. package/lib/common/language-model.spec.d.ts +2 -0
  116. package/lib/common/language-model.spec.d.ts.map +1 -0
  117. package/lib/common/language-model.spec.js +62 -0
  118. package/lib/common/language-model.spec.js.map +1 -0
  119. package/lib/common/prompt-service-util.d.ts +8 -0
  120. package/lib/common/prompt-service-util.d.ts.map +1 -0
  121. package/lib/common/prompt-service-util.js +34 -0
  122. package/lib/common/prompt-service-util.js.map +1 -0
  123. package/lib/common/prompt-service.d.ts +161 -0
  124. package/lib/common/prompt-service.d.ts.map +1 -0
  125. package/lib/common/prompt-service.js +204 -0
  126. package/lib/common/prompt-service.js.map +1 -0
  127. package/lib/common/prompt-service.spec.d.ts +2 -0
  128. package/lib/common/prompt-service.spec.d.ts.map +1 -0
  129. package/lib/common/prompt-service.spec.js +254 -0
  130. package/lib/common/prompt-service.spec.js.map +1 -0
  131. package/lib/common/protocol.d.ts +7 -0
  132. package/lib/common/protocol.d.ts.map +1 -0
  133. package/lib/common/protocol.js +20 -0
  134. package/lib/common/protocol.js.map +1 -0
  135. package/lib/common/settings-service.d.ts +23 -0
  136. package/lib/common/settings-service.d.ts.map +1 -0
  137. package/lib/common/settings-service.js +5 -0
  138. package/lib/common/settings-service.js.map +1 -0
  139. package/lib/common/today-variable-contribution.d.ts +17 -0
  140. package/lib/common/today-variable-contribution.d.ts.map +1 -0
  141. package/lib/common/today-variable-contribution.js +48 -0
  142. package/lib/common/today-variable-contribution.js.map +1 -0
  143. package/lib/common/tomorrow-variable-contribution.d.ts +17 -0
  144. package/lib/common/tomorrow-variable-contribution.d.ts.map +1 -0
  145. package/lib/common/tomorrow-variable-contribution.js +48 -0
  146. package/lib/common/tomorrow-variable-contribution.js.map +1 -0
  147. package/lib/common/tool-invocation-registry.d.ts +23 -0
  148. package/lib/common/tool-invocation-registry.d.ts.map +1 -0
  149. package/lib/common/tool-invocation-registry.js +72 -0
  150. package/lib/common/tool-invocation-registry.js.map +1 -0
  151. package/lib/common/variable-service.d.ts +70 -0
  152. package/lib/common/variable-service.d.ts.map +1 -0
  153. package/lib/common/variable-service.js +122 -0
  154. package/lib/common/variable-service.js.map +1 -0
  155. package/lib/node/ai-core-backend-module.d.ts +4 -0
  156. package/lib/node/ai-core-backend-module.d.ts.map +1 -0
  157. package/lib/node/ai-core-backend-module.js +47 -0
  158. package/lib/node/ai-core-backend-module.js.map +1 -0
  159. package/lib/node/backend-language-model-registry.d.ts +12 -0
  160. package/lib/node/backend-language-model-registry.d.ts.map +1 -0
  161. package/lib/node/backend-language-model-registry.js +61 -0
  162. package/lib/node/backend-language-model-registry.js.map +1 -0
  163. package/lib/node/language-model-frontend-delegate.d.ts +18 -0
  164. package/lib/node/language-model-frontend-delegate.d.ts.map +1 -0
  165. package/lib/node/language-model-frontend-delegate.js +100 -0
  166. package/lib/node/language-model-frontend-delegate.js.map +1 -0
  167. package/package.json +61 -0
  168. package/src/browser/ai-activation-service.ts +56 -0
  169. package/src/browser/ai-command-handler-factory.ts +20 -0
  170. package/src/browser/ai-configuration/agent-configuration-widget.tsx +324 -0
  171. package/src/browser/ai-configuration/ai-configuration-service.ts +43 -0
  172. package/src/browser/ai-configuration/ai-configuration-view-contribution.ts +54 -0
  173. package/src/browser/ai-configuration/ai-configuration-widget.tsx +80 -0
  174. package/src/browser/ai-configuration/language-model-renderer.tsx +113 -0
  175. package/src/browser/ai-configuration/template-settings-renderer.tsx +128 -0
  176. package/src/browser/ai-configuration/variable-configuration-widget.tsx +110 -0
  177. package/src/browser/ai-core-frontend-application-contribution.ts +39 -0
  178. package/src/browser/ai-core-frontend-module.ts +161 -0
  179. package/src/browser/ai-core-preferences.ts +115 -0
  180. package/src/browser/ai-settings-service.ts +50 -0
  181. package/src/browser/ai-view-contribution.ts +77 -0
  182. package/src/browser/frontend-language-model-registry.ts +405 -0
  183. package/src/browser/frontend-prompt-customization-service.ts +243 -0
  184. package/src/browser/frontend-variable-service.ts +26 -0
  185. package/src/browser/index.ts +26 -0
  186. package/src/browser/prompttemplate-contribution.ts +252 -0
  187. package/src/browser/style/index.css +127 -0
  188. package/src/browser/theia-variable-contribution.ts +58 -0
  189. package/src/common/agent-service.ts +137 -0
  190. package/src/common/agent.ts +70 -0
  191. package/src/common/agents-variable-contribution.ts +64 -0
  192. package/src/common/communication-recording-service.ts +53 -0
  193. package/src/common/index.ts +30 -0
  194. package/src/common/language-model-delegate.ts +45 -0
  195. package/src/common/language-model-util.ts +84 -0
  196. package/src/common/language-model.spec.ts +86 -0
  197. package/src/common/language-model.ts +242 -0
  198. package/src/common/prompt-service-util.ts +31 -0
  199. package/src/common/prompt-service.spec.ts +301 -0
  200. package/src/common/prompt-service.ts +334 -0
  201. package/src/common/protocol.ts +23 -0
  202. package/src/common/settings-service.ts +38 -0
  203. package/src/common/today-variable-contribution.ts +67 -0
  204. package/src/common/tomorrow-variable-contribution.ts +66 -0
  205. package/src/common/tool-invocation-registry.ts +79 -0
  206. package/src/common/variable-service.ts +177 -0
  207. package/src/node/ai-core-backend-module.ts +83 -0
  208. package/src/node/backend-language-model-registry.ts +59 -0
  209. package/src/node/language-model-frontend-delegate.ts +116 -0
@@ -0,0 +1,334 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 EclipseSource GmbH.
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 { URI, Event } from '@theia/core';
18
+ import { inject, injectable, optional } from '@theia/core/shared/inversify';
19
+ import { AIVariableService } from './variable-service';
20
+ import { ToolInvocationRegistry } from './tool-invocation-registry';
21
+ import { toolRequestToPromptText } from './language-model-util';
22
+ import { ToolRequest } from './language-model';
23
+ import { matchFunctionsRegEx, matchVariablesRegEx } from './prompt-service-util';
24
+ import { AISettingsService } from './settings-service';
25
+
26
+ export interface PromptTemplate {
27
+ id: string;
28
+ template: string;
29
+ /**
30
+ * (Optional) The ID of the main template for which this template is a variant.
31
+ * If present, this indicates that the current template represents an alternative version of the specified main template.
32
+ */
33
+ variantOf?: string;
34
+ }
35
+
36
+ export interface PromptMap { [id: string]: PromptTemplate }
37
+
38
+ export interface ResolvedPromptTemplate {
39
+ id: string;
40
+ /** The resolved prompt text with variables and function requests being replaced. */
41
+ text: string;
42
+ /** All functions referenced in the prompt template. */
43
+ functionDescriptions?: Map<string, ToolRequest>;
44
+ }
45
+
46
+ export const PromptService = Symbol('PromptService');
47
+ export interface PromptService {
48
+ /**
49
+ * Retrieve the raw {@link PromptTemplate} object (unresolved variables, functions and including comments).
50
+ * @param id the id of the {@link PromptTemplate}
51
+ */
52
+ getRawPrompt(id: string): PromptTemplate | undefined;
53
+ /**
54
+ * Retrieve the unresolved {@link PromptTemplate} object (unresolved variables, functions, excluding comments)
55
+ * @param id the id of the {@link PromptTemplate}
56
+ */
57
+ getUnresolvedPrompt(id: string): PromptTemplate | undefined;
58
+ /**
59
+ * Retrieve the default raw {@link PromptTemplate} object.
60
+ * @param id the id of the {@link PromptTemplate}
61
+ */
62
+ getDefaultRawPrompt(id: string): PromptTemplate | undefined;
63
+ /**
64
+ * Allows to directly replace placeholders in the prompt. The supported format is 'Hi {{name}}!'.
65
+ * The placeholder is then searched inside the args object and replaced.
66
+ * Function references are also supported via format '~{functionId}'.
67
+ * @param id the id of the prompt
68
+ * @param args the object with placeholders, mapping the placeholder key to the value
69
+ */
70
+ getPrompt(id: string, args?: { [key: string]: unknown }): Promise<ResolvedPromptTemplate | undefined>;
71
+ /**
72
+ * Adds a {@link PromptTemplate} to the list of prompts.
73
+ * @param promptTemplate the prompt template to store
74
+ */
75
+ storePromptTemplate(promptTemplate: PromptTemplate): void;
76
+ /**
77
+ * Removes a prompt from the list of prompts.
78
+ * @param id the id of the prompt
79
+ */
80
+ removePrompt(id: string): void;
81
+ /**
82
+ * Return all known prompts as a {@link PromptMap map}.
83
+ */
84
+ getAllPrompts(): PromptMap;
85
+ /**
86
+ * Retrieve all variant IDs of a given {@link PromptTemplate}.
87
+ * @param id the id of the main {@link PromptTemplate}
88
+ * @returns an array of string IDs representing the variants of the given template
89
+ */
90
+ getVariantIds(id: string): string[];
91
+ /**
92
+ * Retrieve the currently selected variant ID for a given main prompt ID.
93
+ * If a variant is selected for the main prompt, it will be returned.
94
+ * Otherwise, the main prompt ID will be returned.
95
+ * @param id the id of the main prompt
96
+ * @returns the variant ID if one is selected, or the main prompt ID otherwise
97
+ */
98
+ getVariantId(id: string): Promise<string>;
99
+ }
100
+
101
+ export interface CustomAgentDescription {
102
+ id: string;
103
+ name: string;
104
+ description: string;
105
+ prompt: string;
106
+ defaultLLM: string;
107
+ }
108
+ export namespace CustomAgentDescription {
109
+ export function is(entry: unknown): entry is CustomAgentDescription {
110
+ // eslint-disable-next-line no-null/no-null
111
+ return typeof entry === 'object' && entry !== null
112
+ && 'id' in entry && typeof entry.id === 'string'
113
+ && 'name' in entry && typeof entry.name === 'string'
114
+ && 'description' in entry && typeof entry.description === 'string'
115
+ && 'prompt' in entry
116
+ && typeof entry.prompt === 'string'
117
+ && 'defaultLLM' in entry
118
+ && typeof entry.defaultLLM === 'string';
119
+ }
120
+ export function equals(a: CustomAgentDescription, b: CustomAgentDescription): boolean {
121
+ return a.id === b.id && a.name === b.name && a.description === b.description && a.prompt === b.prompt && a.defaultLLM === b.defaultLLM;
122
+ }
123
+ }
124
+
125
+ export const PromptCustomizationService = Symbol('PromptCustomizationService');
126
+ export interface PromptCustomizationService {
127
+ /**
128
+ * Whether there is a customization for a {@link PromptTemplate} object
129
+ * @param id the id of the {@link PromptTemplate} to check
130
+ */
131
+ isPromptTemplateCustomized(id: string): boolean;
132
+
133
+ /**
134
+ * Returns the customization of {@link PromptTemplate} object or undefined if there is none
135
+ * @param id the id of the {@link PromptTemplate} to check
136
+ */
137
+ getCustomizedPromptTemplate(id: string): string | undefined
138
+
139
+ getCustomPromptTemplateIDs(): string[];
140
+ /**
141
+ * Edit the template. If the content is specified, is will be
142
+ * used to customize the template. Otherwise, the behavior depends
143
+ * on the implementation. Implementation may for example decide to
144
+ * open an editor, or request more information from the user, ...
145
+ * @param id the template id.
146
+ * @param content optional default content to initialize the template
147
+ */
148
+ editTemplate(id: string, defaultContent?: string): void;
149
+
150
+ /**
151
+ * Reset the template to its default value.
152
+ * @param id the template id.
153
+ */
154
+ resetTemplate(id: string): void;
155
+
156
+ /**
157
+ * Return the template id for a given template file.
158
+ * @param uri the uri of the template file
159
+ */
160
+ getTemplateIDFromURI(uri: URI): string | undefined;
161
+
162
+ /**
163
+ * Event which is fired when the prompt template is changed.
164
+ */
165
+ readonly onDidChangePrompt: Event<string>;
166
+
167
+ /**
168
+ * Return all custom agents.
169
+ * @returns all custom agents
170
+ */
171
+ getCustomAgents(): Promise<CustomAgentDescription[]>;
172
+
173
+ /**
174
+ * Event which is fired when custom agents are modified.
175
+ */
176
+ readonly onDidChangeCustomAgents: Event<void>;
177
+
178
+ /**
179
+ * Open the custom agent yaml file.
180
+ */
181
+ openCustomAgentYaml(): void;
182
+ }
183
+
184
+ @injectable()
185
+ export class PromptServiceImpl implements PromptService {
186
+ @inject(AISettingsService) @optional()
187
+ protected readonly settingsService: AISettingsService | undefined;
188
+
189
+ @inject(PromptCustomizationService) @optional()
190
+ protected readonly customizationService: PromptCustomizationService | undefined;
191
+
192
+ @inject(AIVariableService) @optional()
193
+ protected readonly variableService: AIVariableService | undefined;
194
+
195
+ @inject(ToolInvocationRegistry) @optional()
196
+ protected readonly toolInvocationRegistry: ToolInvocationRegistry | undefined;
197
+
198
+ protected _prompts: PromptMap = {};
199
+
200
+ getRawPrompt(id: string): PromptTemplate | undefined {
201
+ if (this.customizationService !== undefined && this.customizationService.isPromptTemplateCustomized(id)) {
202
+ const template = this.customizationService.getCustomizedPromptTemplate(id);
203
+ if (template !== undefined) {
204
+ return { id, template };
205
+ }
206
+ }
207
+ return this.getDefaultRawPrompt(id);
208
+ }
209
+ getDefaultRawPrompt(id: string): PromptTemplate | undefined {
210
+ return this._prompts[id];
211
+ }
212
+
213
+ getUnresolvedPrompt(id: string): PromptTemplate | undefined {
214
+ const rawPrompt = this.getRawPrompt(id);
215
+ if (!rawPrompt) {
216
+ return undefined;
217
+ }
218
+ return {
219
+ id: rawPrompt.id,
220
+ template: this.stripComments(rawPrompt.template)
221
+ };
222
+ }
223
+
224
+ protected stripComments(template: string): string {
225
+ const commentRegex = /^\s*{{!--[\s\S]*?--}}\s*\n?/;
226
+ return commentRegex.test(template) ? template.replace(commentRegex, '').trimStart() : template;
227
+ }
228
+
229
+ async getVariantId(id: string): Promise<string> {
230
+ if (this.settingsService !== undefined) {
231
+ const agentSettingsMap = await this.settingsService.getSettings();
232
+
233
+ for (const agentSettings of Object.values(agentSettingsMap)) {
234
+ if (agentSettings.selectedVariants && agentSettings.selectedVariants[id]) {
235
+ return agentSettings.selectedVariants[id];
236
+ }
237
+ }
238
+ }
239
+ return id;
240
+ }
241
+
242
+ async getPrompt(id: string, args?: { [key: string]: unknown }): Promise<ResolvedPromptTemplate | undefined> {
243
+ const variantId = await this.getVariantId(id);
244
+ const prompt = this.getUnresolvedPrompt(variantId);
245
+ if (prompt === undefined) {
246
+ return undefined;
247
+ }
248
+
249
+ const matches = matchVariablesRegEx(prompt.template);
250
+ const variableAndArgReplacements = await Promise.all(matches.map(async match => {
251
+ const completeText = match[0];
252
+ const variableAndArg = match[1];
253
+ let variableName = variableAndArg;
254
+ let argument: string | undefined;
255
+ const parts = variableAndArg.split(':', 2);
256
+ if (parts.length > 1) {
257
+ variableName = parts[0];
258
+ argument = parts[1];
259
+ }
260
+ return {
261
+ placeholder: completeText,
262
+ value: String(args?.[variableAndArg] ?? (await this.variableService?.resolveVariable({
263
+ variable: variableName,
264
+ arg: argument
265
+ }, {}))?.value ?? completeText)
266
+ };
267
+ }));
268
+
269
+ const functionMatches = matchFunctionsRegEx(prompt.template);
270
+ const functions = new Map<string, ToolRequest>();
271
+ const functionReplacements = functionMatches.map(match => {
272
+ const completeText = match[0];
273
+ const functionId = match[1];
274
+ const toolRequest = this.toolInvocationRegistry?.getFunction(functionId);
275
+ if (toolRequest) {
276
+ functions.set(toolRequest.id, toolRequest);
277
+ }
278
+ return {
279
+ placeholder: completeText,
280
+ value: toolRequest ? toolRequestToPromptText(toolRequest) : completeText
281
+ };
282
+ });
283
+
284
+ let resolvedTemplate = prompt.template;
285
+ const replacements = [...variableAndArgReplacements, ...functionReplacements];
286
+ replacements.forEach(replacement => resolvedTemplate = resolvedTemplate.replace(replacement.placeholder, replacement.value));
287
+ return {
288
+ id,
289
+ text: resolvedTemplate,
290
+ functionDescriptions: functions.size > 0 ? functions : undefined
291
+ };
292
+ }
293
+ getAllPrompts(): PromptMap {
294
+ if (this.customizationService !== undefined) {
295
+ const myCustomization = this.customizationService;
296
+ const result: PromptMap = {};
297
+ Object.keys(this._prompts).forEach(id => {
298
+ if (myCustomization.isPromptTemplateCustomized(id)) {
299
+ const template = myCustomization.getCustomizedPromptTemplate(id);
300
+ if (template !== undefined) {
301
+ result[id] = { id, template };
302
+ } else {
303
+ result[id] = { ...this._prompts[id] };
304
+ }
305
+ } else {
306
+ result[id] = { ...this._prompts[id] };
307
+ }
308
+ });
309
+ return result;
310
+ } else {
311
+ return { ...this._prompts };
312
+ }
313
+ }
314
+ removePrompt(id: string): void {
315
+ delete this._prompts[id];
316
+ }
317
+ getVariantIds(id: string): string[] {
318
+ const allCustomPromptTemplateIds = this.customizationService?.getCustomPromptTemplateIDs() || [];
319
+ const knownPromptIds = Object.keys(this._prompts);
320
+
321
+ // We filter out known IDs from the custom prompt template IDs, these are no variants, but customizations. Then we retain IDs that start with the main ID
322
+ const customVariantIds = allCustomPromptTemplateIds.filter(customId =>
323
+ !knownPromptIds.includes(customId) && customId.startsWith(id)
324
+ );
325
+ const variantIds = Object.values(this._prompts)
326
+ .filter(prompt => prompt.variantOf === id)
327
+ .map(variant => variant.id);
328
+
329
+ return [...variantIds, ...customVariantIds];
330
+ }
331
+ storePromptTemplate(promptTemplate: PromptTemplate): void {
332
+ this._prompts[promptTemplate.id] = promptTemplate;
333
+ }
334
+ }
@@ -0,0 +1,23 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 EclipseSource GmbH.
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 { LanguageModelMetaData } from './language-model';
18
+
19
+ export const LanguageModelRegistryClient = Symbol('LanguageModelRegistryClient');
20
+ export interface LanguageModelRegistryClient {
21
+ languageModelAdded(metadata: LanguageModelMetaData): void;
22
+ languageModelRemoved(id: string): void;
23
+ }
@@ -0,0 +1,38 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 EclipseSource GmbH.
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
+ import { Event } from '@theia/core';
17
+ import { LanguageModelRequirement } from './language-model';
18
+
19
+ export const AISettingsService = Symbol('AISettingsService');
20
+ /**
21
+ * Service to store and retrieve settings on a per-agent basis.
22
+ */
23
+ export interface AISettingsService {
24
+ updateAgentSettings(agent: string, agentSettings: Partial<AgentSettings>): Promise<void>;
25
+ getAgentSettings(agent: string): Promise<AgentSettings | undefined>;
26
+ getSettings(): Promise<AISettings>;
27
+ onDidChange: Event<void>;
28
+ }
29
+ export type AISettings = Record<string, AgentSettings>;
30
+ export interface AgentSettings {
31
+ languageModelRequirements?: LanguageModelRequirement[];
32
+ enable?: boolean;
33
+ /**
34
+ * A mapping of main template IDs to their selected variant IDs.
35
+ * If a main template is not present in this mapping, it means the main template is used.
36
+ */
37
+ selectedVariants?: Record<string, string>;
38
+ }
@@ -0,0 +1,67 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 EclipseSource GmbH.
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
+ import { MaybePromise } from '@theia/core';
17
+ import { injectable } from '@theia/core/shared/inversify';
18
+ import { AIVariable, ResolvedAIVariable, AIVariableContribution, AIVariableResolver, AIVariableService, AIVariableResolutionRequest, AIVariableContext } from './variable-service';
19
+
20
+ export namespace TodayVariableArgs {
21
+ export const IN_UNIX_SECONDS = 'inUnixSeconds';
22
+ export const IN_ISO_8601 = 'inIso8601';
23
+ }
24
+
25
+ export const TODAY_VARIABLE: AIVariable = {
26
+ id: 'today-provider',
27
+ description: 'Does something for today',
28
+ name: 'today',
29
+ args: [
30
+ { name: TodayVariableArgs.IN_ISO_8601, description: 'Returns the current date in ISO 8601 format' },
31
+ { name: TodayVariableArgs.IN_UNIX_SECONDS, description: 'Returns the current date in unix seconds format' }
32
+ ]
33
+ };
34
+
35
+ export interface ResolvedTodayVariable extends ResolvedAIVariable {
36
+ date: Date;
37
+ }
38
+
39
+ @injectable()
40
+ export class TodayVariableContribution implements AIVariableContribution, AIVariableResolver {
41
+ registerVariables(service: AIVariableService): void {
42
+ service.registerResolver(TODAY_VARIABLE, this);
43
+ }
44
+
45
+ canResolve(request: AIVariableResolutionRequest, context: AIVariableContext): MaybePromise<number> {
46
+ return 1;
47
+ }
48
+
49
+ async resolve(request: AIVariableResolutionRequest, context: AIVariableContext): Promise<ResolvedAIVariable | undefined> {
50
+ if (request.variable.name === TODAY_VARIABLE.name) {
51
+ return this.resolveTodayVariable(request);
52
+ }
53
+ return undefined;
54
+ }
55
+
56
+ private resolveTodayVariable(request: AIVariableResolutionRequest): ResolvedTodayVariable {
57
+ const date = new Date();
58
+ if (request.arg === TodayVariableArgs.IN_ISO_8601) {
59
+ return { variable: request.variable, value: date.toISOString(), date };
60
+ }
61
+ if (request.arg === TodayVariableArgs.IN_UNIX_SECONDS) {
62
+ return { variable: request.variable, value: Math.round(date.getTime() / 1000).toString(), date };
63
+ }
64
+ return { variable: request.variable, value: date.toDateString(), date };
65
+ }
66
+ }
67
+
@@ -0,0 +1,66 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 EclipseSource GmbH.
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
+ import { MaybePromise } from '@theia/core';
17
+ import { injectable } from '@theia/core/shared/inversify';
18
+ import { AIVariable, AIVariableContext, AIVariableContribution, AIVariableResolutionRequest, AIVariableResolver, AIVariableService, ResolvedAIVariable } from './variable-service';
19
+
20
+ export namespace TomorrowVariableArgs {
21
+ export const IN_UNIX_SECONDS = 'inUnixSeconds';
22
+ export const IN_ISO_8601 = 'inIso8601';
23
+ }
24
+
25
+ export const TOMORROW_VARIABLE: AIVariable = {
26
+ id: 'tomorrow-provider',
27
+ description: 'Does something for tomorrow',
28
+ name: 'tomorrow',
29
+ args: [
30
+ { name: TomorrowVariableArgs.IN_ISO_8601, description: 'Returns the current date in ISO 8601 format' },
31
+ { name: TomorrowVariableArgs.IN_UNIX_SECONDS, description: 'Returns the current date in unix seconds format' }
32
+ ]
33
+ };
34
+
35
+ export interface ResolvedTomorrowVariable extends ResolvedAIVariable {
36
+ date: Date;
37
+ }
38
+
39
+ @injectable()
40
+ export class TomorrowVariableContribution implements AIVariableContribution, AIVariableResolver {
41
+ registerVariables(service: AIVariableService): void {
42
+ service.registerResolver(TOMORROW_VARIABLE, this);
43
+ }
44
+
45
+ canResolve(request: AIVariableResolutionRequest, context: AIVariableContext): MaybePromise<number> {
46
+ return 1;
47
+ }
48
+
49
+ async resolve(request: AIVariableResolutionRequest, context: AIVariableContext): Promise<ResolvedAIVariable | undefined> {
50
+ if (request.variable.name === TOMORROW_VARIABLE.name) {
51
+ return this.resolveTomorrowVariable(request);
52
+ }
53
+ return undefined;
54
+ }
55
+
56
+ private resolveTomorrowVariable(request: AIVariableResolutionRequest): ResolvedTomorrowVariable {
57
+ const date = new Date(+new Date() + 86400000);
58
+ if (request.arg === TomorrowVariableArgs.IN_ISO_8601) {
59
+ return { variable: request.variable, value: date.toISOString(), date };
60
+ }
61
+ if (request.arg === TomorrowVariableArgs.IN_UNIX_SECONDS) {
62
+ return { variable: request.variable, value: Math.round(date.getTime() / 1000).toString(), date };
63
+ }
64
+ return { variable: request.variable, value: date.toDateString(), date };
65
+ }
66
+ }
@@ -0,0 +1,79 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 EclipseSource GmbH.
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 { inject, injectable, named, postConstruct } from '@theia/core/shared/inversify';
18
+ import { ToolRequest } from './language-model';
19
+ import { ContributionProvider } from '@theia/core';
20
+
21
+ export const ToolInvocationRegistry = Symbol('ToolInvocationRegistry');
22
+
23
+ /**
24
+ * Registry for all the function calls available to Agents.
25
+ */
26
+ export interface ToolInvocationRegistry {
27
+ registerTool(tool: ToolRequest): void;
28
+
29
+ getFunction(toolId: string): ToolRequest | undefined;
30
+
31
+ getFunctions(...toolIds: string[]): ToolRequest[];
32
+ }
33
+
34
+ export const ToolProvider = Symbol('ToolProvider');
35
+ export interface ToolProvider {
36
+ getTool(): ToolRequest;
37
+ }
38
+
39
+ @injectable()
40
+ export class ToolInvocationRegistryImpl implements ToolInvocationRegistry {
41
+
42
+ private tools: Map<string, ToolRequest> = new Map<string, ToolRequest>();
43
+
44
+ @inject(ContributionProvider)
45
+ @named(ToolProvider)
46
+ private providers: ContributionProvider<ToolProvider>;
47
+
48
+ @postConstruct()
49
+ init(): void {
50
+ this.providers.getContributions().forEach(provider => {
51
+ this.registerTool(provider.getTool());
52
+ });
53
+ }
54
+
55
+ registerTool(tool: ToolRequest): void {
56
+ if (this.tools.has(tool.id)) {
57
+ console.warn(`Function with id ${tool.id} is already registered.`);
58
+ } else {
59
+ this.tools.set(tool.id, tool);
60
+ }
61
+ }
62
+
63
+ getFunction(toolId: string): ToolRequest | undefined {
64
+ return this.tools.get(toolId);
65
+ }
66
+
67
+ getFunctions(...toolIds: string[]): ToolRequest[] {
68
+ const tools: ToolRequest[] = toolIds.map(toolId => {
69
+ const tool = this.tools.get(toolId);
70
+ if (tool) {
71
+ return tool;
72
+ } else {
73
+ throw new Error(`Function with id ${toolId} does not exist.`);
74
+ }
75
+ });
76
+ return tools;
77
+ }
78
+ }
79
+