@theia/ai-core 1.54.0

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 +30 -0
  2. package/data/prompttemplate.tmLanguage.json +52 -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 +27 -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 +231 -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 +11 -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 +33 -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 +8 -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 +14 -0
  48. package/lib/browser/ai-core-preferences.d.ts.map +1 -0
  49. package/lib/browser/ai-core-preferences.js +69 -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 +31 -0
  64. package/lib/browser/frontend-prompt-customization-service.d.ts.map +1 -0
  65. package/lib/browser/frontend-prompt-customization-service.js +194 -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 +28 -0
  76. package/lib/browser/prompttemplate-contribution.d.ts.map +1 -0
  77. package/lib/browser/prompttemplate-contribution.js +207 -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 +48 -0
  84. package/lib/common/agent-service.d.ts.map +1 -0
  85. package/lib/common/agent-service.js +88 -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 +23 -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 +5 -0
  108. package/lib/common/language-model-util.d.ts.map +1 -0
  109. package/lib/common/language-model-util.js +75 -0
  110. package/lib/common/language-model-util.js.map +1 -0
  111. package/lib/common/language-model.d.ts +137 -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 +5 -0
  120. package/lib/common/prompt-service-util.d.ts.map +1 -0
  121. package/lib/common/prompt-service-util.js +23 -0
  122. package/lib/common/prompt-service-util.js.map +1 -0
  123. package/lib/common/prompt-service.d.ts +101 -0
  124. package/lib/common/prompt-service.d.ts.map +1 -0
  125. package/lib/common/prompt-service.js +139 -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 +86 -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 +18 -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 +59 -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 +299 -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 +39 -0
  176. package/src/browser/ai-configuration/variable-configuration-widget.tsx +110 -0
  177. package/src/browser/ai-core-frontend-application-contribution.ts +40 -0
  178. package/src/browser/ai-core-frontend-module.ts +161 -0
  179. package/src/browser/ai-core-preferences.ts +76 -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 +197 -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 +250 -0
  187. package/src/browser/style/index.css +90 -0
  188. package/src/browser/theia-variable-contribution.ts +58 -0
  189. package/src/common/agent-service.ts +108 -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 +44 -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 +67 -0
  196. package/src/common/language-model.spec.ts +86 -0
  197. package/src/common/language-model.ts +237 -0
  198. package/src/common/prompt-service-util.ts +21 -0
  199. package/src/common/prompt-service.spec.ts +98 -0
  200. package/src/common/prompt-service.ts +213 -0
  201. package/src/common/protocol.ts +23 -0
  202. package/src/common/settings-service.ts +33 -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,80 @@
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 { BaseWidget, BoxLayout, codicon, DockPanel, WidgetManager } from '@theia/core/lib/browser';
18
+ import { TheiaDockPanel } from '@theia/core/lib/browser/shell/theia-dock-panel';
19
+ import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
20
+ import '../../../src/browser/style/index.css';
21
+ import { AIAgentConfigurationWidget } from './agent-configuration-widget';
22
+ import { AIVariableConfigurationWidget } from './variable-configuration-widget';
23
+ import { AIConfigurationSelectionService } from './ai-configuration-service';
24
+
25
+ @injectable()
26
+ export class AIConfigurationContainerWidget extends BaseWidget {
27
+
28
+ static readonly ID = 'ai-configuration';
29
+ static readonly LABEL = '✨ AI Configuration [Experimental]';
30
+ protected dockpanel: DockPanel;
31
+
32
+ @inject(TheiaDockPanel.Factory)
33
+ protected readonly dockPanelFactory: TheiaDockPanel.Factory;
34
+ @inject(WidgetManager)
35
+ protected readonly widgetManager: WidgetManager;
36
+ @inject(AIConfigurationSelectionService)
37
+ protected readonly aiConfigurationSelectionService: AIConfigurationSelectionService;
38
+
39
+ protected agentsWidget: AIAgentConfigurationWidget;
40
+ protected variablesWidget: AIVariableConfigurationWidget;
41
+
42
+ @postConstruct()
43
+ protected init(): void {
44
+ this.id = AIConfigurationContainerWidget.ID;
45
+ this.title.label = AIConfigurationContainerWidget.LABEL;
46
+ this.title.closable = true;
47
+ this.addClass('theia-settings-container');
48
+ this.title.iconClass = codicon('hubot');
49
+ this.initUI();
50
+ this.initListeners();
51
+ }
52
+
53
+ protected async initUI(): Promise<void> {
54
+ const layout = (this.layout = new BoxLayout({ direction: 'top-to-bottom', spacing: 0 }));
55
+ this.dockpanel = this.dockPanelFactory({
56
+ mode: 'multiple-document',
57
+ spacing: 0
58
+ });
59
+ BoxLayout.setStretch(this.dockpanel, 1);
60
+ layout.addWidget(this.dockpanel);
61
+ this.dockpanel.addClass('ai-configuration-widget');
62
+
63
+ this.agentsWidget = await this.widgetManager.getOrCreateWidget(AIAgentConfigurationWidget.ID);
64
+ this.variablesWidget = await this.widgetManager.getOrCreateWidget(AIVariableConfigurationWidget.ID);
65
+ this.dockpanel.addWidget(this.agentsWidget);
66
+ this.dockpanel.addWidget(this.variablesWidget);
67
+
68
+ this.update();
69
+ }
70
+
71
+ protected initListeners(): void {
72
+ this.aiConfigurationSelectionService.onDidSelectConfiguration(widgetId => {
73
+ if (widgetId === AIAgentConfigurationWidget.ID) {
74
+ this.dockpanel.activateWidget(this.agentsWidget);
75
+ } else if (widgetId === AIVariableConfigurationWidget.ID) {
76
+ this.dockpanel.activateWidget(this.variablesWidget);
77
+ }
78
+ });
79
+ }
80
+ }
@@ -0,0 +1,113 @@
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 * as React from '@theia/core/shared/react';
17
+ import { Agent, LanguageModelRequirement } from '../../common';
18
+ import { LanguageModel, LanguageModelRegistry } from '../../common/language-model';
19
+ import { AISettingsService } from '../../common/settings-service';
20
+ import { Mutable } from '@theia/core';
21
+
22
+ export interface LanguageModelSettingsProps {
23
+ agent: Agent;
24
+ languageModels?: LanguageModel[];
25
+ aiSettingsService: AISettingsService;
26
+ languageModelRegistry: LanguageModelRegistry;
27
+ }
28
+
29
+ export const LanguageModelRenderer: React.FC<LanguageModelSettingsProps> = (
30
+ { agent, languageModels, aiSettingsService, languageModelRegistry }) => {
31
+
32
+ const findLanguageModelRequirement = async (purpose: string): Promise<LanguageModelRequirement | undefined> => {
33
+ const requirementSetting = await aiSettingsService.getAgentSettings(agent.id);
34
+ return requirementSetting?.languageModelRequirements?.find(e => e.purpose === purpose);
35
+ };
36
+
37
+ const [lmRequirementMap, setLmRequirementMap] = React.useState<Record<string, LanguageModelRequirement>>({});
38
+
39
+ React.useEffect(() => {
40
+ const computeLmRequirementMap = async () => {
41
+ const map = await agent.languageModelRequirements.reduce(async (accPromise, curr) => {
42
+ const acc = await accPromise;
43
+ // take the agents requirements and override them with the user settings if present
44
+ const lmRequirement = await findLanguageModelRequirement(curr.purpose) ?? curr;
45
+ // if no llm is selected through the identifier, see what would be the default
46
+ if (!lmRequirement.identifier) {
47
+ const llm = await languageModelRegistry.selectLanguageModel({ agent: agent.id, ...lmRequirement });
48
+ (lmRequirement as Mutable<LanguageModelRequirement>).identifier = llm?.id;
49
+ }
50
+ acc[curr.purpose] = lmRequirement;
51
+ return acc;
52
+ }, Promise.resolve({} as Record<string, LanguageModelRequirement>));
53
+ setLmRequirementMap(map);
54
+ };
55
+ computeLmRequirementMap();
56
+ }, []);
57
+
58
+ const renderLanguageModelMetadata = (requirement: LanguageModelRequirement, index: number) => {
59
+ const languageModel = languageModels?.find(model => model.id === requirement.identifier);
60
+ if (!languageModel) {
61
+ return <div></div>;
62
+ }
63
+
64
+ return <>
65
+ <div>{requirement.purpose}</div>
66
+ <div key={index}>
67
+ {languageModel.id && <p><strong>Identifier: </strong> {languageModel.id}</p>}
68
+ {languageModel.name && <p><strong>Name: </strong> {languageModel.name}</p>}
69
+ {languageModel.vendor && <p><strong>Vendor: </strong> {languageModel.vendor}</p>}
70
+ {languageModel.version && <p><strong>Version: </strong> {languageModel.version}</p>}
71
+ {languageModel.family && <p><strong>Family: </strong> {languageModel.family}</p>}
72
+ {languageModel.maxInputTokens && <p><strong>Min Input Tokens: </strong> {languageModel.maxInputTokens}</p>}
73
+ {languageModel.maxOutputTokens && <p><strong>Max Output Tokens: </strong> {languageModel.maxOutputTokens}</p>}
74
+ </div>
75
+ </>;
76
+
77
+ };
78
+
79
+ const onSelectedModelChange = (purpose: string, event: React.ChangeEvent<HTMLSelectElement>): void => {
80
+ const newLmRequirementMap = { ...lmRequirementMap, [purpose]: { purpose, identifier: event.target.value } };
81
+ aiSettingsService.updateAgentSettings(agent.id, { languageModelRequirements: Object.values(newLmRequirementMap) });
82
+ setLmRequirementMap(newLmRequirementMap);
83
+ };
84
+
85
+ return <div className='language-model-container'>
86
+ {Object.values(lmRequirementMap).map((requirements, index) => (
87
+ <React.Fragment key={index}>
88
+ <div><strong>Purpose:</strong></div>
89
+ <div>
90
+ {/* language model metadata */}
91
+ {renderLanguageModelMetadata(requirements, index)}
92
+ {/* language model selector */}
93
+ <>
94
+ <label className="theia-header no-select" htmlFor={`model-select-${agent.id}`}>Language Model:</label>
95
+ <select
96
+ className="theia-select"
97
+ id={`model-select-${agent.id}`}
98
+ value={requirements.identifier}
99
+ onChange={event => onSelectedModelChange(requirements.purpose, event)}
100
+ >
101
+ <option value=""></option>
102
+ {languageModels?.map(model => (
103
+ <option key={model.id} value={model.id}>{model.name ?? model.id}</option>
104
+ ))}
105
+ </select>
106
+ </>
107
+ <hr />
108
+ </div>
109
+ </React.Fragment>
110
+ ))}
111
+
112
+ </div>;
113
+ };
@@ -0,0 +1,39 @@
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 * as React from '@theia/core/shared/react';
17
+ import { PromptCustomizationService } from '../../common/prompt-service';
18
+ import { PromptTemplate } from '../../common';
19
+
20
+ export interface TemplateSettingProps {
21
+ agentId: string;
22
+ template: PromptTemplate;
23
+ promptCustomizationService: PromptCustomizationService;
24
+ }
25
+
26
+ export const TemplateRenderer: React.FC<TemplateSettingProps> = ({ agentId, template, promptCustomizationService }) => {
27
+ const openTemplate = React.useCallback(async () => {
28
+ promptCustomizationService.editTemplate(template.id);
29
+ }, [template, promptCustomizationService]);
30
+ const resetTemplate = React.useCallback(async () => {
31
+ promptCustomizationService.resetTemplate(template.id);
32
+ }, [promptCustomizationService, template]);
33
+
34
+ return <>
35
+ {template.id}
36
+ <button className='theia-button main' onClick={openTemplate}>Edit</button>
37
+ <button className='theia-button secondary' onClick={resetTemplate}>Reset</button>
38
+ </>;
39
+ };
@@ -0,0 +1,110 @@
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 { codicon, ReactWidget } from '@theia/core/lib/browser';
18
+ import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
19
+ import * as React from '@theia/core/shared/react';
20
+ import { Agent, AIVariable, AIVariableService } from '../../common';
21
+ import { AIAgentConfigurationWidget } from './agent-configuration-widget';
22
+ import { AIConfigurationSelectionService } from './ai-configuration-service';
23
+ import { AgentService } from '../../common/agent-service';
24
+
25
+ @injectable()
26
+ export class AIVariableConfigurationWidget extends ReactWidget {
27
+
28
+ static readonly ID = 'ai-variable-configuration-container-widget';
29
+ static readonly LABEL = 'Variables';
30
+
31
+ @inject(AIVariableService)
32
+ protected readonly variableService: AIVariableService;
33
+
34
+ @inject(AgentService)
35
+ protected readonly agentService: AgentService;
36
+
37
+ @inject(AIConfigurationSelectionService)
38
+ protected readonly aiConfigurationSelectionService: AIConfigurationSelectionService;
39
+
40
+ @postConstruct()
41
+ protected init(): void {
42
+ this.id = AIVariableConfigurationWidget.ID;
43
+ this.title.label = AIVariableConfigurationWidget.LABEL;
44
+ this.title.closable = false;
45
+ this.update();
46
+ this.toDispose.push(this.variableService.onDidChangeVariables(() => this.update()));
47
+ }
48
+
49
+ protected render(): React.ReactNode {
50
+ return <div className='configuration-variables-list'>
51
+ <ul>
52
+ {this.variableService.getVariables().map(variable =>
53
+ <li key={variable.id} className='variable-item' >
54
+ <div className='settings-section-title settings-section-category-title' style={{ paddingLeft: 0, paddingBottom: 10 }}>{variable.name}</div>
55
+ <small>{variable.id}</small>
56
+ <small>{variable.description}</small>
57
+ {this.renderReferencedVariables(variable)}
58
+ {this.renderArgs(variable)}
59
+ </li>
60
+ )}
61
+ </ul>
62
+ </div>;
63
+ }
64
+
65
+ protected renderReferencedVariables(variable: AIVariable): React.ReactNode | undefined {
66
+ const agents = this.getAgentsForVariable(variable);
67
+ if (agents.length === 0) {
68
+ return;
69
+ }
70
+
71
+ return <div>
72
+ <h3>Agents</h3>
73
+ <ul className='variable-references'>
74
+ {agents.map(agent => <li key={agent.id} className='theia-TreeNode theia-CompositeTreeNode theia-ExpandableTreeNode theia-mod-selected'>
75
+ <div onClick={() => { this.showAgentConfiguration(agent); }} className='variable-reference'>
76
+ <span>{agent.name}</span>
77
+ <i className={codicon('chevron-right')}></i>
78
+ </div></li>)}
79
+ </ul>
80
+ </div>;
81
+ }
82
+
83
+ protected renderArgs(variable: AIVariable): React.ReactNode | undefined {
84
+ if (variable.args === undefined || variable.args.length === 0) {
85
+ return;
86
+ }
87
+
88
+ return <div className='variable-args-container'>
89
+ <h3>Variable Arguments</h3>
90
+ <div className='variable-args'>
91
+ {variable.args.map(arg =>
92
+ <React.Fragment key={arg.name}>
93
+ <span>{arg.name}</span>
94
+ <small>{arg.description}</small>
95
+ </React.Fragment>
96
+ )}
97
+ </div>
98
+ </div>;
99
+ }
100
+
101
+ protected showAgentConfiguration(agent: Agent): void {
102
+ this.aiConfigurationSelectionService.setActiveAgent(agent);
103
+ this.aiConfigurationSelectionService.selectConfigurationTab(AIAgentConfigurationWidget.ID);
104
+ }
105
+
106
+ protected getAgentsForVariable(variable: AIVariable): Agent[] {
107
+ return this.agentService.getAgents().filter(a => a.variables?.includes(variable.id));
108
+ }
109
+ }
110
+
@@ -0,0 +1,40 @@
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 { FrontendApplicationContribution } from '@theia/core/lib/browser';
18
+ import { inject, injectable } from '@theia/core/shared/inversify';
19
+ import { PromptService } from '../common';
20
+ import { AgentService } from '../common/agent-service';
21
+
22
+ @injectable()
23
+ export class AICoreFrontendApplicationContribution implements FrontendApplicationContribution {
24
+ @inject(AgentService)
25
+ private readonly agentService: AgentService;
26
+
27
+ @inject(PromptService)
28
+ private readonly promptService: PromptService;
29
+
30
+ onStart(): void {
31
+ this.agentService.getAllAgents().forEach(a => {
32
+ a.promptTemplates.forEach(t => {
33
+ this.promptService.storePrompt(t.id, t.template);
34
+ });
35
+ });
36
+ }
37
+
38
+ onStop(): void {
39
+ }
40
+ }
@@ -0,0 +1,161 @@
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 { bindContributionProvider, CommandContribution, CommandHandler } from '@theia/core';
17
+ import {
18
+ RemoteConnectionProvider,
19
+ ServiceConnectionProvider,
20
+ } from '@theia/core/lib/browser/messaging/service-connection-provider';
21
+ import { ContainerModule } from '@theia/core/shared/inversify';
22
+ import {
23
+ AIVariableContribution,
24
+ AIVariableService,
25
+ ToolInvocationRegistry,
26
+ ToolInvocationRegistryImpl,
27
+ LanguageModelDelegateClient,
28
+ languageModelDelegatePath,
29
+ LanguageModelFrontendDelegate,
30
+ LanguageModelProvider,
31
+ LanguageModelRegistry,
32
+ LanguageModelRegistryClient,
33
+ languageModelRegistryDelegatePath,
34
+ LanguageModelRegistryFrontendDelegate,
35
+ PromptCustomizationService,
36
+ PromptService,
37
+ PromptServiceImpl,
38
+ ToolProvider
39
+ } from '../common';
40
+ import {
41
+ FrontendLanguageModelRegistryImpl,
42
+ LanguageModelDelegateClientImpl,
43
+ } from './frontend-language-model-registry';
44
+
45
+ import { bindViewContribution, FrontendApplicationContribution, WidgetFactory } from '@theia/core/lib/browser';
46
+ import { TabBarToolbarContribution } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
47
+ import { LanguageGrammarDefinitionContribution } from '@theia/monaco/lib/browser/textmate';
48
+ import { AIAgentConfigurationWidget } from './ai-configuration/agent-configuration-widget';
49
+ import { AIConfigurationSelectionService } from './ai-configuration/ai-configuration-service';
50
+ import { AIAgentConfigurationViewContribution } from './ai-configuration/ai-configuration-view-contribution';
51
+ import { AIConfigurationContainerWidget } from './ai-configuration/ai-configuration-widget';
52
+ import { AIVariableConfigurationWidget } from './ai-configuration/variable-configuration-widget';
53
+ import { AICoreFrontendApplicationContribution } from './ai-core-frontend-application-contribution';
54
+ import { bindAICorePreferences } from './ai-core-preferences';
55
+ import { AISettingsServiceImpl } from './ai-settings-service';
56
+ import { FrontendPromptCustomizationServiceImpl } from './frontend-prompt-customization-service';
57
+ import { FrontendVariableService } from './frontend-variable-service';
58
+ import { PromptTemplateContribution } from './prompttemplate-contribution';
59
+ import { TomorrowVariableContribution } from '../common/tomorrow-variable-contribution';
60
+ import { TheiaVariableContribution } from './theia-variable-contribution';
61
+ import { TodayVariableContribution } from '../common/today-variable-contribution';
62
+ import { AgentsVariableContribution } from '../common/agents-variable-contribution';
63
+ import { AIActivationService } from './ai-activation-service';
64
+ import { AgentService, AgentServiceImpl } from '../common/agent-service';
65
+ import { AICommandHandlerFactory } from './ai-command-handler-factory';
66
+ import { AISettingsService } from '../common/settings-service';
67
+
68
+ export default new ContainerModule(bind => {
69
+ bindContributionProvider(bind, LanguageModelProvider);
70
+
71
+ bind(FrontendLanguageModelRegistryImpl).toSelf().inSingletonScope();
72
+ bind(LanguageModelRegistry).toService(FrontendLanguageModelRegistryImpl);
73
+
74
+ bind(LanguageModelDelegateClientImpl).toSelf().inSingletonScope();
75
+ bind(LanguageModelDelegateClient).toService(LanguageModelDelegateClientImpl);
76
+ bind(LanguageModelRegistryClient).toService(LanguageModelDelegateClient);
77
+
78
+ bind(LanguageModelRegistryFrontendDelegate).toDynamicValue(
79
+ ctx => {
80
+ const connection = ctx.container.get<ServiceConnectionProvider>(RemoteConnectionProvider);
81
+ const client = ctx.container.get<LanguageModelRegistryClient>(LanguageModelRegistryClient);
82
+ return connection.createProxy<LanguageModelRegistryFrontendDelegate>(languageModelRegistryDelegatePath, client);
83
+ }
84
+ );
85
+
86
+ bind(LanguageModelFrontendDelegate)
87
+ .toDynamicValue(ctx => {
88
+ const connection = ctx.container.get<ServiceConnectionProvider>(RemoteConnectionProvider);
89
+ const client = ctx.container.get<LanguageModelDelegateClient>(LanguageModelDelegateClient);
90
+ return connection.createProxy<LanguageModelFrontendDelegate>(languageModelDelegatePath, client);
91
+ })
92
+ .inSingletonScope();
93
+
94
+ bindAICorePreferences(bind);
95
+
96
+ bind(FrontendPromptCustomizationServiceImpl).toSelf().inSingletonScope();
97
+ bind(PromptCustomizationService).toService(FrontendPromptCustomizationServiceImpl);
98
+ bind(PromptServiceImpl).toSelf().inSingletonScope();
99
+ bind(PromptService).toService(PromptServiceImpl);
100
+
101
+ bind(PromptTemplateContribution).toSelf().inSingletonScope();
102
+ bind(LanguageGrammarDefinitionContribution).toService(PromptTemplateContribution);
103
+ bind(CommandContribution).toService(PromptTemplateContribution);
104
+ bind(TabBarToolbarContribution).toService(PromptTemplateContribution);
105
+
106
+ bind(AIConfigurationSelectionService).toSelf().inSingletonScope();
107
+ bind(AIConfigurationContainerWidget).toSelf();
108
+ bind(WidgetFactory)
109
+ .toDynamicValue(ctx => ({
110
+ id: AIConfigurationContainerWidget.ID,
111
+ createWidget: () => ctx.container.get(AIConfigurationContainerWidget)
112
+ }))
113
+ .inSingletonScope();
114
+
115
+ bindViewContribution(bind, AIAgentConfigurationViewContribution);
116
+ bind(AISettingsService).to(AISettingsServiceImpl).inRequestScope();
117
+ bindContributionProvider(bind, AIVariableContribution);
118
+ bind(FrontendVariableService).toSelf().inSingletonScope();
119
+ bind(AIVariableService).toService(FrontendVariableService);
120
+ bind(FrontendApplicationContribution).toService(FrontendVariableService);
121
+ bind(AIVariableContribution).to(TheiaVariableContribution).inSingletonScope();
122
+ bind(AIVariableContribution).to(TodayVariableContribution).inSingletonScope();
123
+ bind(AIVariableContribution).to(TomorrowVariableContribution).inSingletonScope();
124
+ bind(AIVariableContribution).to(AgentsVariableContribution).inSingletonScope();
125
+
126
+ bind(FrontendApplicationContribution).to(AICoreFrontendApplicationContribution).inSingletonScope();
127
+
128
+ bind(AIVariableConfigurationWidget).toSelf();
129
+ bind(WidgetFactory)
130
+ .toDynamicValue(ctx => ({
131
+ id: AIVariableConfigurationWidget.ID,
132
+ createWidget: () => ctx.container.get(AIVariableConfigurationWidget)
133
+ }))
134
+ .inSingletonScope();
135
+
136
+ bind(AIAgentConfigurationWidget).toSelf();
137
+ bind(WidgetFactory)
138
+ .toDynamicValue(ctx => ({
139
+ id: AIAgentConfigurationWidget.ID,
140
+ createWidget: () => ctx.container.get(AIAgentConfigurationWidget)
141
+ }))
142
+ .inSingletonScope();
143
+
144
+ bind(ToolInvocationRegistry).to(ToolInvocationRegistryImpl).inSingletonScope();
145
+ bindContributionProvider(bind, ToolProvider);
146
+
147
+ bind(AIActivationService).toSelf().inSingletonScope();
148
+ bind(FrontendApplicationContribution).toService(AIActivationService);
149
+ bind(AgentServiceImpl).toSelf().inSingletonScope();
150
+ bind(AgentService).toService(AgentServiceImpl);
151
+
152
+ bind(AICommandHandlerFactory).toFactory<CommandHandler>(context => (handler: CommandHandler) => {
153
+ const activationService = context.container.get(AIActivationService);
154
+ return {
155
+ execute: (...args: unknown[]) => handler.execute(...args),
156
+ isEnabled: (...args: unknown[]) => activationService.isActive && (handler.isEnabled?.(...args) ?? true),
157
+ isVisible: (...args: unknown[]) => activationService.isActive && (handler.isVisible?.(...args) ?? true),
158
+ isToggled: (...args: unknown[]) => handler.isToggled?.(...args) ?? false
159
+ };
160
+ });
161
+ });
@@ -0,0 +1,76 @@
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 { PreferenceContribution, PreferenceProxy, PreferenceSchema } from '@theia/core/lib/browser';
18
+ import { PreferenceProxyFactory } from '@theia/core/lib/browser/preferences/injectable-preference-proxy';
19
+ import { interfaces } from '@theia/core/shared/inversify';
20
+
21
+ export const AI_CORE_PREFERENCES_TITLE = '✨ AI Features [Experimental]';
22
+ export const PREFERENCE_NAME_ENABLE_EXPERIMENTAL = 'ai-features.AiEnable.enableAI';
23
+ export const PREFERENCE_NAME_PROMPT_TEMPLATES = 'ai-features.promptTemplates.promptTemplatesFolder';
24
+
25
+ export const aiCorePreferenceSchema: PreferenceSchema = {
26
+ type: 'object',
27
+ properties: {
28
+ [PREFERENCE_NAME_ENABLE_EXPERIMENTAL]: {
29
+ title: AI_CORE_PREFERENCES_TITLE,
30
+ markdownDescription: '❗ This setting allows you to access and experiment with the latest AI capabilities.\
31
+ \n\
32
+ Please note that these features are in an experimental phase, which means they may be unstable and\
33
+ undergo significant changes. It is important to be aware that these experimental features may generate\
34
+ continuous requests to the language models (LLMs) you provide access to. This might incur costs that you\
35
+ need to monitor closely. By enabling this option, you acknowledge these risks.\
36
+ \n\
37
+ **Please note! The settings below in this section will only take effect\n\
38
+ once the main feature setting is enabled. After enabling the feature, you need to configure at least one\
39
+ LLM provider below. Also see [the documentation](https://theia-ide.org/docs/user_ai/)**.',
40
+ type: 'boolean',
41
+ default: false,
42
+ },
43
+ [PREFERENCE_NAME_PROMPT_TEMPLATES]: {
44
+ title: AI_CORE_PREFERENCES_TITLE,
45
+ description: 'Folder for storing customized prompt templates. If not customized the user config directory is used. Please consider to use a folder, which is\
46
+ under version control to manage your variants of prompt templates.',
47
+ type: 'string',
48
+ default: '',
49
+ typeDetails: {
50
+ isFilepath: true,
51
+ selectionProps: {
52
+ openLabel: 'Select Folder',
53
+ canSelectFiles: false,
54
+ canSelectFolders: true,
55
+ canSelectMany: false
56
+ }
57
+ },
58
+
59
+ }
60
+ }
61
+ };
62
+ export interface AICoreConfiguration {
63
+ [PREFERENCE_NAME_ENABLE_EXPERIMENTAL]: boolean | undefined;
64
+ [PREFERENCE_NAME_PROMPT_TEMPLATES]: string | undefined;
65
+ }
66
+
67
+ export const AICorePreferences = Symbol('AICorePreferences');
68
+ export type AICorePreferences = PreferenceProxy<AICoreConfiguration>;
69
+
70
+ export function bindAICorePreferences(bind: interfaces.Bind): void {
71
+ bind(AICorePreferences).toDynamicValue(ctx => {
72
+ const factory = ctx.container.get<PreferenceProxyFactory>(PreferenceProxyFactory);
73
+ return factory(aiCorePreferenceSchema);
74
+ }).inSingletonScope();
75
+ bind(PreferenceContribution).toConstantValue({ schema: aiCorePreferenceSchema });
76
+ }