@jupyterlite/ai 0.8.0 → 0.9.0-a0

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 (162) hide show
  1. package/lib/agent.d.ts +233 -0
  2. package/lib/agent.js +604 -0
  3. package/lib/chat-model.d.ts +195 -0
  4. package/lib/chat-model.js +590 -0
  5. package/lib/completion/completion-provider.d.ts +83 -0
  6. package/lib/completion/completion-provider.js +209 -0
  7. package/lib/completion/index.d.ts +1 -0
  8. package/lib/completion/index.js +1 -0
  9. package/lib/components/clear-button.d.ts +18 -0
  10. package/lib/components/clear-button.js +31 -0
  11. package/lib/components/index.d.ts +3 -0
  12. package/lib/components/index.js +3 -0
  13. package/lib/components/model-select.d.ts +19 -0
  14. package/lib/components/model-select.js +154 -0
  15. package/lib/components/stop-button.d.ts +3 -3
  16. package/lib/components/stop-button.js +8 -9
  17. package/lib/components/token-usage-display.d.ts +45 -0
  18. package/lib/components/token-usage-display.js +74 -0
  19. package/lib/components/tool-select.d.ts +27 -0
  20. package/lib/components/tool-select.js +130 -0
  21. package/lib/icons.d.ts +3 -1
  22. package/lib/icons.js +10 -13
  23. package/lib/index.d.ts +4 -5
  24. package/lib/index.js +322 -167
  25. package/lib/mcp/browser.d.ts +68 -0
  26. package/lib/mcp/browser.js +132 -0
  27. package/lib/models/settings-model.d.ts +69 -0
  28. package/lib/models/settings-model.js +295 -0
  29. package/lib/providers/built-in-providers.d.ts +9 -0
  30. package/lib/providers/built-in-providers.js +192 -0
  31. package/lib/providers/models.d.ts +37 -0
  32. package/lib/providers/models.js +28 -0
  33. package/lib/providers/provider-registry.d.ts +94 -0
  34. package/lib/providers/provider-registry.js +155 -0
  35. package/lib/tokens.d.ts +157 -86
  36. package/lib/tokens.js +16 -12
  37. package/lib/tools/commands.d.ts +11 -0
  38. package/lib/tools/commands.js +126 -0
  39. package/lib/tools/file.d.ts +27 -0
  40. package/lib/tools/file.js +262 -0
  41. package/lib/tools/notebook.d.ts +40 -0
  42. package/lib/tools/notebook.js +762 -0
  43. package/lib/tools/tool-registry.d.ts +35 -0
  44. package/lib/tools/tool-registry.js +55 -0
  45. package/lib/widgets/ai-settings.d.ts +39 -0
  46. package/lib/widgets/ai-settings.js +506 -0
  47. package/lib/widgets/chat-wrapper.d.ts +144 -0
  48. package/lib/widgets/chat-wrapper.js +390 -0
  49. package/lib/widgets/provider-config-dialog.d.ts +13 -0
  50. package/lib/widgets/provider-config-dialog.js +104 -0
  51. package/package.json +150 -41
  52. package/schema/settings-model.json +153 -0
  53. package/src/agent.ts +800 -0
  54. package/src/chat-model.ts +770 -0
  55. package/src/completion/completion-provider.ts +308 -0
  56. package/src/completion/index.ts +1 -0
  57. package/src/components/clear-button.tsx +56 -0
  58. package/src/components/index.ts +3 -0
  59. package/src/components/model-select.tsx +245 -0
  60. package/src/components/stop-button.tsx +11 -11
  61. package/src/components/token-usage-display.tsx +130 -0
  62. package/src/components/tool-select.tsx +218 -0
  63. package/src/icons.ts +12 -14
  64. package/src/index.ts +468 -238
  65. package/src/mcp/browser.ts +213 -0
  66. package/src/models/settings-model.ts +409 -0
  67. package/src/providers/built-in-providers.ts +216 -0
  68. package/src/providers/models.ts +79 -0
  69. package/src/providers/provider-registry.ts +189 -0
  70. package/src/tokens.ts +203 -90
  71. package/src/tools/commands.ts +151 -0
  72. package/src/tools/file.ts +307 -0
  73. package/src/tools/notebook.ts +964 -0
  74. package/src/tools/tool-registry.ts +63 -0
  75. package/src/types.d.ts +4 -0
  76. package/src/widgets/ai-settings.tsx +1100 -0
  77. package/src/widgets/chat-wrapper.tsx +543 -0
  78. package/src/widgets/provider-config-dialog.tsx +256 -0
  79. package/style/base.css +335 -14
  80. package/style/icons/jupyternaut-lite.svg +1 -1
  81. package/lib/base-completer.d.ts +0 -49
  82. package/lib/base-completer.js +0 -14
  83. package/lib/chat-handler.d.ts +0 -56
  84. package/lib/chat-handler.js +0 -201
  85. package/lib/completion-provider.d.ts +0 -34
  86. package/lib/completion-provider.js +0 -32
  87. package/lib/default-prompts.d.ts +0 -2
  88. package/lib/default-prompts.js +0 -31
  89. package/lib/default-providers/Anthropic/completer.d.ts +0 -12
  90. package/lib/default-providers/Anthropic/completer.js +0 -46
  91. package/lib/default-providers/Anthropic/settings-schema.json +0 -70
  92. package/lib/default-providers/ChromeAI/completer.d.ts +0 -12
  93. package/lib/default-providers/ChromeAI/completer.js +0 -56
  94. package/lib/default-providers/ChromeAI/instructions.d.ts +0 -6
  95. package/lib/default-providers/ChromeAI/instructions.js +0 -42
  96. package/lib/default-providers/ChromeAI/settings-schema.json +0 -18
  97. package/lib/default-providers/Gemini/completer.d.ts +0 -12
  98. package/lib/default-providers/Gemini/completer.js +0 -48
  99. package/lib/default-providers/Gemini/instructions.d.ts +0 -2
  100. package/lib/default-providers/Gemini/instructions.js +0 -9
  101. package/lib/default-providers/Gemini/settings-schema.json +0 -64
  102. package/lib/default-providers/MistralAI/completer.d.ts +0 -13
  103. package/lib/default-providers/MistralAI/completer.js +0 -52
  104. package/lib/default-providers/MistralAI/instructions.d.ts +0 -2
  105. package/lib/default-providers/MistralAI/instructions.js +0 -18
  106. package/lib/default-providers/MistralAI/settings-schema.json +0 -75
  107. package/lib/default-providers/Ollama/completer.d.ts +0 -12
  108. package/lib/default-providers/Ollama/completer.js +0 -43
  109. package/lib/default-providers/Ollama/instructions.d.ts +0 -2
  110. package/lib/default-providers/Ollama/instructions.js +0 -70
  111. package/lib/default-providers/Ollama/settings-schema.json +0 -143
  112. package/lib/default-providers/OpenAI/completer.d.ts +0 -12
  113. package/lib/default-providers/OpenAI/completer.js +0 -43
  114. package/lib/default-providers/OpenAI/settings-schema.json +0 -628
  115. package/lib/default-providers/WebLLM/completer.d.ts +0 -21
  116. package/lib/default-providers/WebLLM/completer.js +0 -127
  117. package/lib/default-providers/WebLLM/instructions.d.ts +0 -6
  118. package/lib/default-providers/WebLLM/instructions.js +0 -32
  119. package/lib/default-providers/WebLLM/settings-schema.json +0 -19
  120. package/lib/default-providers/index.d.ts +0 -2
  121. package/lib/default-providers/index.js +0 -179
  122. package/lib/provider.d.ts +0 -144
  123. package/lib/provider.js +0 -412
  124. package/lib/settings/base.json +0 -7
  125. package/lib/settings/index.d.ts +0 -3
  126. package/lib/settings/index.js +0 -3
  127. package/lib/settings/panel.d.ts +0 -226
  128. package/lib/settings/panel.js +0 -510
  129. package/lib/settings/textarea.d.ts +0 -2
  130. package/lib/settings/textarea.js +0 -18
  131. package/lib/settings/utils.d.ts +0 -2
  132. package/lib/settings/utils.js +0 -4
  133. package/lib/types/ai-model.d.ts +0 -24
  134. package/lib/types/ai-model.js +0 -5
  135. package/schema/chat.json +0 -28
  136. package/schema/provider-registry.json +0 -29
  137. package/schema/system-prompts.json +0 -22
  138. package/src/base-completer.ts +0 -75
  139. package/src/chat-handler.ts +0 -262
  140. package/src/completion-provider.ts +0 -64
  141. package/src/default-prompts.ts +0 -33
  142. package/src/default-providers/Anthropic/completer.ts +0 -59
  143. package/src/default-providers/ChromeAI/completer.ts +0 -73
  144. package/src/default-providers/ChromeAI/instructions.ts +0 -45
  145. package/src/default-providers/Gemini/completer.ts +0 -61
  146. package/src/default-providers/Gemini/instructions.ts +0 -9
  147. package/src/default-providers/MistralAI/completer.ts +0 -69
  148. package/src/default-providers/MistralAI/instructions.ts +0 -18
  149. package/src/default-providers/Ollama/completer.ts +0 -54
  150. package/src/default-providers/Ollama/instructions.ts +0 -70
  151. package/src/default-providers/OpenAI/completer.ts +0 -54
  152. package/src/default-providers/WebLLM/completer.ts +0 -151
  153. package/src/default-providers/WebLLM/instructions.ts +0 -33
  154. package/src/default-providers/index.ts +0 -211
  155. package/src/global.d.ts +0 -9
  156. package/src/provider.ts +0 -514
  157. package/src/settings/index.ts +0 -3
  158. package/src/settings/panel.tsx +0 -773
  159. package/src/settings/textarea.tsx +0 -33
  160. package/src/settings/utils.ts +0 -5
  161. package/src/types/ai-model.ts +0 -37
  162. package/src/types/service-worker.d.ts +0 -6
@@ -0,0 +1,216 @@
1
+ import { createAnthropic } from '@ai-sdk/anthropic';
2
+ import { createMistral } from '@ai-sdk/mistral';
3
+ import { aisdk } from '@openai/agents-extensions';
4
+ import { createOllama } from 'ollama-ai-provider-v2';
5
+
6
+ import type {
7
+ IChatProviderInfo,
8
+ ICompletionProviderInfo,
9
+ IChatProviderRegistry,
10
+ ICompletionProviderRegistry
11
+ } from '../tokens';
12
+ import type { IModelOptions } from './models';
13
+
14
+ /**
15
+ * Register all built-in chat providers
16
+ */
17
+ export function registerBuiltInChatProviders(
18
+ registry: IChatProviderRegistry
19
+ ): void {
20
+ // Anthropic provider
21
+ const anthropicInfo: IChatProviderInfo = {
22
+ id: 'anthropic',
23
+ name: 'Anthropic Claude',
24
+ requiresApiKey: true,
25
+ defaultModels: [
26
+ 'claude-sonnet-4-20250514',
27
+ 'claude-opus-4-20250514',
28
+ 'claude-opus-4-1-20250805',
29
+ 'claude-3-5-haiku-latest'
30
+ ],
31
+ supportsBaseURL: true,
32
+ supportsHeaders: true,
33
+ factory: (options: IModelOptions) => {
34
+ if (!options.apiKey) {
35
+ throw new Error('API key required for Anthropic');
36
+ }
37
+ const anthropic = createAnthropic({
38
+ apiKey: options.apiKey,
39
+ headers: {
40
+ 'anthropic-dangerous-direct-browser-access': 'true',
41
+ ...options.headers
42
+ },
43
+ ...(options.baseURL && { baseURL: options.baseURL })
44
+ });
45
+ const modelName = options.model ?? '';
46
+ return aisdk(anthropic(modelName));
47
+ }
48
+ };
49
+
50
+ registry.registerProvider(anthropicInfo);
51
+
52
+ // Mistral provider
53
+ const mistralInfo: IChatProviderInfo = {
54
+ id: 'mistral',
55
+ name: 'Mistral AI',
56
+ requiresApiKey: true,
57
+ defaultModels: [
58
+ 'mistral-medium-latest',
59
+ 'mistral-large-latest',
60
+ 'mistral-small-latest',
61
+ 'codestral-latest'
62
+ ],
63
+ supportsBaseURL: true,
64
+ factory: (options: IModelOptions) => {
65
+ if (!options.apiKey) {
66
+ throw new Error('API key required for Mistral');
67
+ }
68
+ const mistral = createMistral({
69
+ apiKey: options.apiKey,
70
+ ...(options.baseURL && { baseURL: options.baseURL })
71
+ });
72
+ const modelName = options.model || 'mistral-large-latest';
73
+ return aisdk(mistral(modelName));
74
+ }
75
+ };
76
+
77
+ registry.registerProvider(mistralInfo);
78
+
79
+ // Ollama provider
80
+ const ollamaInfo: IChatProviderInfo = {
81
+ id: 'ollama',
82
+ name: 'Ollama',
83
+ requiresApiKey: false,
84
+ defaultModels: [],
85
+ supportsBaseURL: true,
86
+ supportsHeaders: true,
87
+ factory: (options: IModelOptions) => {
88
+ const ollama = createOllama({
89
+ baseURL: options.baseURL || 'http://localhost:11434/api',
90
+ ...(options.headers && { headers: options.headers })
91
+ });
92
+ const modelName = options.model || 'phi3';
93
+ return aisdk(ollama(modelName));
94
+ }
95
+ };
96
+
97
+ registry.registerProvider(ollamaInfo);
98
+ }
99
+
100
+ /**
101
+ * Register all built-in completion providers
102
+ */
103
+ export function registerBuiltInCompletionProviders(
104
+ registry: ICompletionProviderRegistry
105
+ ): void {
106
+ // Anthropic provider
107
+ const anthropicInfo: ICompletionProviderInfo = {
108
+ id: 'anthropic',
109
+ name: 'Anthropic Claude',
110
+ requiresApiKey: true,
111
+ defaultModels: [
112
+ 'claude-sonnet-4-20250514',
113
+ 'claude-opus-4-20250514',
114
+ 'claude-opus-4-1-20250805',
115
+ 'claude-3-5-haiku-latest'
116
+ ],
117
+ supportsBaseURL: true,
118
+ supportsHeaders: true,
119
+ customSettings: {
120
+ completionConfig: {
121
+ temperature: 0.3,
122
+ supportsFillInMiddle: false,
123
+ useFilterText: true
124
+ }
125
+ },
126
+ factory: (options: IModelOptions) => {
127
+ if (!options.apiKey) {
128
+ throw new Error('API key required for Anthropic');
129
+ }
130
+ const anthropic = createAnthropic({
131
+ apiKey: options.apiKey,
132
+ headers: {
133
+ 'anthropic-dangerous-direct-browser-access': 'true',
134
+ ...options.headers
135
+ },
136
+ ...(options.baseURL && { baseURL: options.baseURL })
137
+ });
138
+ const modelName = options.model ?? '';
139
+ return anthropic(modelName);
140
+ }
141
+ };
142
+
143
+ registry.registerProvider(anthropicInfo);
144
+
145
+ // Mistral provider
146
+ const mistralInfo: ICompletionProviderInfo = {
147
+ id: 'mistral',
148
+ name: 'Mistral AI',
149
+ requiresApiKey: true,
150
+ defaultModels: [
151
+ 'mistral-medium-latest',
152
+ 'mistral-large-latest',
153
+ 'mistral-small-latest',
154
+ 'codestral-latest'
155
+ ],
156
+ supportsBaseURL: true,
157
+ customSettings: {
158
+ completionConfig: {
159
+ temperature: 0.2,
160
+ supportsFillInMiddle: true,
161
+ customPromptFormat: (prompt: string, suffix: string) => {
162
+ return suffix.trim() ? `<PRE>${prompt}<SUF>${suffix}<MID>` : prompt;
163
+ },
164
+ cleanupCompletion: (completion: string) => {
165
+ return completion
166
+ .replace(/<PRE>/g, '')
167
+ .replace(/<SUF>/g, '')
168
+ .replace(/<MID>/g, '')
169
+ .replace(/```[\s\S]*?```/g, '')
170
+ .trim();
171
+ },
172
+ useFilterText: false
173
+ }
174
+ },
175
+ factory: (options: IModelOptions) => {
176
+ if (!options.apiKey) {
177
+ throw new Error('API key required for Mistral');
178
+ }
179
+ const mistral = createMistral({
180
+ apiKey: options.apiKey,
181
+ ...(options.baseURL && { baseURL: options.baseURL })
182
+ });
183
+ const modelName = options.model || 'mistral-large-latest';
184
+ return mistral(modelName);
185
+ }
186
+ };
187
+
188
+ registry.registerProvider(mistralInfo);
189
+
190
+ // Ollama provider
191
+ const ollamaInfo: ICompletionProviderInfo = {
192
+ id: 'ollama',
193
+ name: 'Ollama',
194
+ requiresApiKey: false,
195
+ defaultModels: ['phi3'],
196
+ supportsBaseURL: true,
197
+ supportsHeaders: true,
198
+ customSettings: {
199
+ completionConfig: {
200
+ temperature: 0.3,
201
+ supportsFillInMiddle: false,
202
+ useFilterText: false
203
+ }
204
+ },
205
+ factory: (options: IModelOptions) => {
206
+ const ollama = createOllama({
207
+ baseURL: options.baseURL || 'http://localhost:11434/api',
208
+ ...(options.headers && { headers: options.headers })
209
+ });
210
+ const modelName = options.model || 'phi3';
211
+ return ollama(modelName);
212
+ }
213
+ };
214
+
215
+ registry.registerProvider(ollamaInfo);
216
+ }
@@ -0,0 +1,79 @@
1
+ import type { LanguageModel } from 'ai';
2
+ import type {
3
+ IChatProviderRegistry,
4
+ ICompletionProviderRegistry
5
+ } from '../tokens';
6
+
7
+ /**
8
+ * Configuration options for creating language models.
9
+ */
10
+ export interface IModelOptions {
11
+ /**
12
+ * The provider name (e.g., 'openai', 'anthropic', 'huggingface')
13
+ */
14
+ provider: string;
15
+
16
+ /**
17
+ * The specific model name. If not provided, uses provider's default model
18
+ */
19
+ model?: string;
20
+
21
+ /**
22
+ * API key for authentication with the provider
23
+ */
24
+ apiKey?: string;
25
+
26
+ /**
27
+ * Additional HTTP headers to send with requests
28
+ */
29
+ headers?: Record<string, string>;
30
+
31
+ /**
32
+ * Custom base URL for the provider's API endpoint
33
+ */
34
+ baseURL?: string;
35
+ }
36
+
37
+ /**
38
+ * Create a completion model using the provider registry.
39
+ * Built-in providers are automatically registered during extension initialization.
40
+ */
41
+ export function createCompletionModel(
42
+ options: IModelOptions,
43
+ registry?: ICompletionProviderRegistry
44
+ ): LanguageModel {
45
+ if (!registry) {
46
+ throw new Error('Completion provider registry not available');
47
+ }
48
+
49
+ const model = registry.createCompletionModel(options.provider, options);
50
+ if (!model) {
51
+ throw new Error(
52
+ `Provider ${options.provider} not found or failed to create model`
53
+ );
54
+ }
55
+
56
+ return model;
57
+ }
58
+
59
+ /**
60
+ * Create a chat model using the provider registry.
61
+ * Built-in providers are automatically registered during extension initialization.
62
+ */
63
+ export function createModel(
64
+ options: IModelOptions,
65
+ registry?: IChatProviderRegistry
66
+ ) {
67
+ if (!registry) {
68
+ throw new Error('Chat provider registry not available');
69
+ }
70
+
71
+ const model = registry.createChatModel(options.provider, options);
72
+ if (!model) {
73
+ throw new Error(
74
+ `Provider ${options.provider} not found or failed to create model`
75
+ );
76
+ }
77
+
78
+ return model;
79
+ }
@@ -0,0 +1,189 @@
1
+ import { ISignal, Signal } from '@lumino/signaling';
2
+ import type { LanguageModel } from 'ai';
3
+ import type { IModelOptions } from './models';
4
+ import {
5
+ IChatProviderFactory,
6
+ IChatProviderInfo,
7
+ IChatProviderRegistry,
8
+ ICompletionProviderFactory,
9
+ ICompletionProviderInfo,
10
+ ICompletionProviderRegistry
11
+ } from '../tokens';
12
+
13
+ /**
14
+ * Implementation of the chat provider registry
15
+ */
16
+ export class ChatProviderRegistry implements IChatProviderRegistry {
17
+ /**
18
+ * Get a copy of all registered providers
19
+ */
20
+ get providers(): Record<string, IChatProviderInfo> {
21
+ return { ...this._providers };
22
+ }
23
+
24
+ /**
25
+ * Signal emitted when providers are added or removed
26
+ */
27
+ get providersChanged(): ISignal<IChatProviderRegistry, void> {
28
+ return this._providersChanged;
29
+ }
30
+
31
+ /**
32
+ * Register a new chat provider
33
+ * @param info Provider information including factory
34
+ */
35
+ registerProvider(info: IChatProviderInfo): void {
36
+ this._providers[info.id] = { ...info };
37
+ this._factories[info.id] = info.factory;
38
+ this._providersChanged.emit();
39
+ }
40
+
41
+ /**
42
+ * Unregister a chat provider by ID
43
+ * @param id Provider ID to remove
44
+ * @returns true if provider was found and removed, false otherwise
45
+ */
46
+ unregisterProvider(id: string): boolean {
47
+ if (id in this._providers) {
48
+ delete this._providers[id];
49
+ delete this._factories[id];
50
+ this._providersChanged.emit();
51
+ return true;
52
+ }
53
+ return false;
54
+ }
55
+
56
+ /**
57
+ * Get provider information by ID
58
+ * @param id Provider ID
59
+ * @returns Provider info or null if not found
60
+ */
61
+ getProviderInfo(id: string): IChatProviderInfo | null {
62
+ return this._providers[id] || null;
63
+ }
64
+
65
+ /**
66
+ * Create a chat model instance using the specified provider
67
+ * @param id Provider ID
68
+ * @param options Model configuration options
69
+ * @returns Chat model instance or null if creation fails
70
+ */
71
+ createChatModel(id: string, options: IModelOptions): any | null {
72
+ const factory = this._factories[id];
73
+ if (!factory) {
74
+ return null;
75
+ }
76
+
77
+ try {
78
+ return factory(options);
79
+ } catch (error) {
80
+ console.error(`Failed to create chat model for provider ${id}:`, error);
81
+ return null;
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Get list of all available provider IDs
87
+ * @returns Array of provider IDs
88
+ */
89
+ getAvailableProviders(): string[] {
90
+ return Object.keys(this._providers);
91
+ }
92
+
93
+ private _providers: Record<string, IChatProviderInfo> = {};
94
+ private _factories: Record<string, IChatProviderFactory> = {};
95
+ private _providersChanged = new Signal<IChatProviderRegistry, void>(this);
96
+ }
97
+
98
+ /**
99
+ * Implementation of the completion provider registry
100
+ */
101
+ export class CompletionProviderRegistry implements ICompletionProviderRegistry {
102
+ /**
103
+ * Get a copy of all registered providers
104
+ */
105
+ get providers(): Record<string, ICompletionProviderInfo> {
106
+ return { ...this._providers };
107
+ }
108
+
109
+ /**
110
+ * Signal emitted when providers are added or removed
111
+ */
112
+ get providersChanged(): ISignal<ICompletionProviderRegistry, void> {
113
+ return this._providersChanged;
114
+ }
115
+
116
+ /**
117
+ * Register a new completion provider
118
+ * @param info Provider information including factory
119
+ */
120
+ registerProvider(info: ICompletionProviderInfo): void {
121
+ this._providers[info.id] = { ...info };
122
+ this._factories[info.id] = info.factory;
123
+ this._providersChanged.emit();
124
+ }
125
+
126
+ /**
127
+ * Unregister a completion provider by ID
128
+ * @param id Provider ID to remove
129
+ * @returns true if provider was found and removed, false otherwise
130
+ */
131
+ unregisterProvider(id: string): boolean {
132
+ if (id in this._providers) {
133
+ delete this._providers[id];
134
+ delete this._factories[id];
135
+ this._providersChanged.emit();
136
+ return true;
137
+ }
138
+ return false;
139
+ }
140
+
141
+ /**
142
+ * Get provider information by ID
143
+ * @param id Provider ID
144
+ * @returns Provider info or null if not found
145
+ */
146
+ getProviderInfo(id: string): ICompletionProviderInfo | null {
147
+ return this._providers[id] || null;
148
+ }
149
+
150
+ /**
151
+ * Create a completion model instance using the specified provider
152
+ * @param id Provider ID
153
+ * @param options Model configuration options
154
+ * @returns Language model instance or null if creation fails
155
+ */
156
+ createCompletionModel(
157
+ id: string,
158
+ options: IModelOptions
159
+ ): LanguageModel | null {
160
+ const factory = this._factories[id];
161
+ if (!factory) {
162
+ return null;
163
+ }
164
+
165
+ try {
166
+ return factory(options);
167
+ } catch (error) {
168
+ console.error(
169
+ `Failed to create completion model for provider ${id}:`,
170
+ error
171
+ );
172
+ return null;
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Get list of all available provider IDs
178
+ * @returns Array of provider IDs
179
+ */
180
+ getAvailableProviders(): string[] {
181
+ return Object.keys(this._providers);
182
+ }
183
+
184
+ private _providers: Record<string, ICompletionProviderInfo> = {};
185
+ private _factories: Record<string, ICompletionProviderFactory> = {};
186
+ private _providersChanged = new Signal<ICompletionProviderRegistry, void>(
187
+ this
188
+ );
189
+ }