@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,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?.sort((a, b) => (a.name ?? a.id).localeCompare(b.name ?? b.id)).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,128 @@
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, PromptService } from '../../common/prompt-service';
18
+ import { AISettingsService, PromptTemplate } from '../../common';
19
+
20
+ const DEFAULT_VARIANT = 'default';
21
+
22
+ export interface TemplateRendererProps {
23
+ agentId: string;
24
+ template: PromptTemplate;
25
+ promptCustomizationService: PromptCustomizationService;
26
+ promptService: PromptService;
27
+ aiSettingsService: AISettingsService;
28
+ }
29
+
30
+ export const TemplateRenderer: React.FC<TemplateRendererProps> = ({
31
+ agentId,
32
+ template,
33
+ promptCustomizationService,
34
+ promptService,
35
+ aiSettingsService,
36
+ }) => {
37
+ const variantIds = [DEFAULT_VARIANT, ...promptService.getVariantIds(template.id)];
38
+ const [selectedVariant, setSelectedVariant] = React.useState<string>(DEFAULT_VARIANT);
39
+
40
+ React.useEffect(() => {
41
+ (async () => {
42
+ const agentSettings = await aiSettingsService.getAgentSettings(agentId);
43
+ const currentVariant =
44
+ agentSettings?.selectedVariants?.[template.id] || DEFAULT_VARIANT;
45
+ setSelectedVariant(currentVariant);
46
+ })();
47
+ }, [template.id, aiSettingsService, agentId]);
48
+
49
+ const isInvalidVariant = !variantIds.includes(selectedVariant);
50
+
51
+ const handleVariantChange = async (event: React.ChangeEvent<HTMLSelectElement>) => {
52
+ const newVariant = event.target.value;
53
+ setSelectedVariant(newVariant);
54
+
55
+ const agentSettings = await aiSettingsService.getAgentSettings(agentId);
56
+ const selectedVariants = agentSettings?.selectedVariants || {};
57
+
58
+ const updatedVariants = { ...selectedVariants };
59
+ if (newVariant === DEFAULT_VARIANT) {
60
+ delete updatedVariants[template.id];
61
+ } else {
62
+ updatedVariants[template.id] = newVariant;
63
+ }
64
+
65
+ await aiSettingsService.updateAgentSettings(agentId, {
66
+ selectedVariants: updatedVariants,
67
+ });
68
+ };
69
+
70
+ const openTemplate = () => {
71
+ const templateId = selectedVariant === DEFAULT_VARIANT ? template.id : selectedVariant;
72
+ const selectedTemplate = promptService.getRawPrompt(templateId);
73
+ promptCustomizationService.editTemplate(templateId, selectedTemplate?.template || '');
74
+ };
75
+
76
+ const resetTemplate = () => {
77
+ const templateId = selectedVariant === DEFAULT_VARIANT ? template.id : selectedVariant;
78
+ promptCustomizationService.resetTemplate(templateId);
79
+ };
80
+
81
+ return (
82
+ <div className="template-renderer">
83
+ <div className="settings-section-title template-header">
84
+ <strong>{template.id}</strong>
85
+ </div>
86
+ <div className="template-controls">
87
+ {(variantIds.length > 1 || isInvalidVariant) && (
88
+ <>
89
+ <label htmlFor={`variant-selector-${template.id}`} className="template-select-label">
90
+ Select Variant:
91
+ </label>
92
+ <select
93
+ id={`variant-selector-${template.id}`}
94
+ className={`theia-select template-variant-selector ${isInvalidVariant ? 'error' : ''}`}
95
+ value={isInvalidVariant ? 'invalid' : selectedVariant}
96
+ onChange={handleVariantChange}
97
+ >
98
+ {isInvalidVariant && (
99
+ <option value="invalid" disabled>
100
+ The selected variant is no longer available
101
+ </option>
102
+ )}
103
+ {variantIds.map(variantId => (
104
+ <option key={variantId} value={variantId}>
105
+ {variantId}
106
+ </option>
107
+ ))}
108
+ </select>
109
+ </>
110
+ )}
111
+ <button
112
+ className="theia-button main"
113
+ onClick={openTemplate}
114
+ disabled={isInvalidVariant}
115
+ >
116
+ Edit
117
+ </button>
118
+ <button
119
+ className="theia-button secondary"
120
+ onClick={resetTemplate}
121
+ disabled={isInvalidVariant}
122
+ >
123
+ Reset
124
+ </button>
125
+ </div>
126
+ </div>
127
+ );
128
+ };
@@ -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,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
+
17
+ import { FrontendApplicationContribution } from '@theia/core/lib/browser';
18
+ import { inject, injectable, named } from '@theia/core/shared/inversify';
19
+ import { Agent } from '../common';
20
+ import { AgentService } from '../common/agent-service';
21
+ import { ContributionProvider } from '@theia/core/lib/common/contribution-provider';
22
+
23
+ @injectable()
24
+ export class AICoreFrontendApplicationContribution implements FrontendApplicationContribution {
25
+ @inject(AgentService)
26
+ private readonly agentService: AgentService;
27
+
28
+ @inject(ContributionProvider) @named(Agent)
29
+ protected readonly agentsProvider: ContributionProvider<Agent>;
30
+
31
+ onStart(): void {
32
+ this.agentsProvider.getContributions().forEach(agent => {
33
+ this.agentService.registerAgent(agent);
34
+ });
35
+ }
36
+
37
+ onStop(): void {
38
+ }
39
+ }
@@ -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,115 @@
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
+ export const PREFERENCE_NAME_REQUEST_SETTINGS = 'ai-features.modelSettings.requestSettings';
25
+
26
+ export const aiCorePreferenceSchema: PreferenceSchema = {
27
+ type: 'object',
28
+ properties: {
29
+ [PREFERENCE_NAME_ENABLE_EXPERIMENTAL]: {
30
+ title: AI_CORE_PREFERENCES_TITLE,
31
+ markdownDescription: '❗ This setting allows you to access and experiment with the latest AI capabilities.\
32
+ \n\
33
+ Please note that these features are in an experimental phase, which means they may be unstable and\
34
+ undergo significant changes. It is important to be aware that these experimental features may generate\
35
+ continuous requests to the language models (LLMs) you provide access to. This might incur costs that you\
36
+ need to monitor closely. By enabling this option, you acknowledge these risks.\
37
+ \n\
38
+ **Please note! The settings below in this section will only take effect\n\
39
+ once the main feature setting is enabled. After enabling the feature, you need to configure at least one\
40
+ LLM provider below. Also see [the documentation](https://theia-ide.org/docs/user_ai/)**.',
41
+ type: 'boolean',
42
+ default: false,
43
+ },
44
+ [PREFERENCE_NAME_PROMPT_TEMPLATES]: {
45
+ title: AI_CORE_PREFERENCES_TITLE,
46
+ description: 'Folder for storing customized prompt templates. If not customized the user config directory is used. Please consider to use a folder, which is\
47
+ under version control to manage your variants of prompt templates.',
48
+ type: 'string',
49
+ default: '',
50
+ typeDetails: {
51
+ isFilepath: true,
52
+ selectionProps: {
53
+ openLabel: 'Select Folder',
54
+ canSelectFiles: false,
55
+ canSelectFolders: true,
56
+ canSelectMany: false
57
+ }
58
+ },
59
+ },
60
+ [PREFERENCE_NAME_REQUEST_SETTINGS]: {
61
+ title: 'Custom Request Settings',
62
+ markdownDescription: 'Allows specifying custom request settings for multiple models.\n\
63
+ Each object represents the configuration for a specific model. The `modelId` field specifies the model ID, `requestSettings` defines model-specific settings.\n\
64
+ The `providerId` field is optional and allows you to apply the settings to a specific provider. If not set, the settings will be applied to all providers.\n\
65
+ Example providerIds: huggingface, openai, ollama, llamafile.\n\
66
+ Refer to [our documentation](https://theia-ide.org/docs/user_ai/#custom-request-settings) for more information.',
67
+ type: 'array',
68
+ items: {
69
+ type: 'object',
70
+ properties: {
71
+ modelId: {
72
+ type: 'string',
73
+ description: 'The model id'
74
+ },
75
+ requestSettings: {
76
+ type: 'object',
77
+ additionalProperties: true,
78
+ description: 'Settings for the specific model ID.',
79
+ },
80
+ providerId: {
81
+ type: 'string',
82
+ description: 'The (optional) provider id to apply the settings to. If not set, the settings will be applied to all providers.',
83
+ },
84
+ },
85
+ },
86
+ default: [],
87
+ }
88
+ }
89
+ };
90
+ export interface AICoreConfiguration {
91
+ [PREFERENCE_NAME_ENABLE_EXPERIMENTAL]: boolean | undefined;
92
+ [PREFERENCE_NAME_PROMPT_TEMPLATES]: string | undefined;
93
+ [PREFERENCE_NAME_REQUEST_SETTINGS]: Array<{
94
+ modelId: string;
95
+ requestSettings?: { [key: string]: unknown };
96
+ providerId?: string;
97
+ }> | undefined;
98
+ }
99
+
100
+ export interface RequestSetting {
101
+ modelId: string;
102
+ requestSettings?: { [key: string]: unknown };
103
+ providerId?: string;
104
+ }
105
+
106
+ export const AICorePreferences = Symbol('AICorePreferences');
107
+ export type AICorePreferences = PreferenceProxy<AICoreConfiguration>;
108
+
109
+ export function bindAICorePreferences(bind: interfaces.Bind): void {
110
+ bind(AICorePreferences).toDynamicValue(ctx => {
111
+ const factory = ctx.container.get<PreferenceProxyFactory>(PreferenceProxyFactory);
112
+ return factory(aiCorePreferenceSchema);
113
+ }).inSingletonScope();
114
+ bind(PreferenceContribution).toConstantValue({ schema: aiCorePreferenceSchema });
115
+ }