@kapeta/local-cluster-service 0.48.4 → 0.48.5

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.
@@ -6,7 +6,7 @@
6
6
  "request": "launch",
7
7
  "name": "Debug Node.js (npm run dev)",
8
8
  "runtimeExecutable": "npm",
9
- "runtimeArgs": ["run-script", "dev"],
9
+ "runtimeArgs": ["run", "start:dev"],
10
10
  "restart": true,
11
11
  "console": "integratedTerminal",
12
12
  "internalConsoleOptions": "neverOpen",
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [0.48.5](https://github.com/kapetacom/local-cluster-service/compare/v0.48.4...v0.48.5) (2024-06-04)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * we should read the file previously written ([fe0b78e](https://github.com/kapetacom/local-cluster-service/commit/fe0b78efd5018be28308170a0c76b2619425a158))
7
+
1
8
  ## [0.48.4](https://github.com/kapetacom/local-cluster-service/compare/v0.48.3...v0.48.4) (2024-06-03)
2
9
 
3
10
 
@@ -22,6 +22,13 @@ export declare class StormCodegen {
22
22
  * Generates the code for a block and sends it to the AI
23
23
  */
24
24
  private processBlockCode;
25
+ private verifyAndFixCode;
26
+ removePrefix(prefix: string, str: string): string;
27
+ writeToFile(fileName: string, code: Promise<string>): Promise<void>;
28
+ /**
29
+ * Sends the code to the AI for a fix
30
+ */
31
+ private codeFix;
25
32
  /**
26
33
  * Emits the text-based files to the stream
27
34
  */
@@ -39,6 +39,7 @@ const stream_1 = require("./stream");
39
39
  const promises_1 = require("fs/promises");
40
40
  const path_1 = __importStar(require("path"));
41
41
  const node_os_1 = __importDefault(require("node:os"));
42
+ const fs_1 = require("fs");
42
43
  class StormCodegen {
43
44
  userPrompt;
44
45
  blocks;
@@ -154,6 +155,89 @@ class StormCodegen {
154
155
  const filePath = (0, path_1.join)(basePath, uiFile.filename);
155
156
  await (0, promises_1.writeFile)(filePath, uiFile.content);
156
157
  }
158
+ const filesToBeFixed = serviceFiles.concat(contextFiles);
159
+ const codeGenerator = new codegen_1.BlockCodeGenerator(block.content);
160
+ await this.verifyAndFixCode(codeGenerator, basePath, filesToBeFixed, allFiles);
161
+ }
162
+ async verifyAndFixCode(codeGenerator, basePath, filesToBeFixed, knownFiles) {
163
+ let attempts = 0;
164
+ let validCode = false;
165
+ for (let i = 0; i <= 3; i++) {
166
+ attempts++;
167
+ try {
168
+ console.log(`Validating the code in ${basePath} attempt #${attempts}`);
169
+ const result = await codeGenerator.validateForTarget(basePath);
170
+ if (result && result.valid) {
171
+ validCode = true;
172
+ break;
173
+ }
174
+ if (result && !result.valid) {
175
+ console.debug('Validation error:', result);
176
+ const errorStream = await stormClient_1.stormClient.createErrorClassification(result.error, []);
177
+ const fixes = new Map();
178
+ errorStream.on('data', (evt) => {
179
+ if (evt.type === 'ERROR_CLASSIFIER') {
180
+ // find the file that caused the error
181
+ // strip base path from event file name, if it exists sometimes the AI sends the full path
182
+ const eventFileName = this.removePrefix(basePath + '/', evt.payload.filename);
183
+ const file = filesToBeFixed.find((f) => f.filename === eventFileName);
184
+ if (!file) {
185
+ console.log(`Could not find the file ${eventFileName} in the list of files to be fixed, Henrik might wanna create a new file for this fix`);
186
+ }
187
+ // read the content of the file
188
+ const content = (0, fs_1.readFileSync)((0, path_1.join)(basePath, eventFileName), 'utf8');
189
+ const fix = `${evt.payload.potentialFix}\n---\n${knownFiles.map(e => e.filename).join("\n")}\n---\n${content}`;
190
+ console.log(`trying to fix the code in ${eventFileName}`);
191
+ console.debug(`with the fix:\n${fix}`);
192
+ const code = this.codeFix(fix);
193
+ fixes.set((0, path_1.join)(basePath, eventFileName), code);
194
+ }
195
+ });
196
+ await errorStream.waitForDone();
197
+ for (const [filename, codePromise] of fixes) {
198
+ const code = await codePromise;
199
+ (0, fs_1.writeFileSync)(filename, code);
200
+ }
201
+ }
202
+ }
203
+ catch (e) {
204
+ console.error('Error:', e);
205
+ }
206
+ }
207
+ if (validCode) {
208
+ console.log(`Validation successful after ${attempts} attempts`);
209
+ }
210
+ else {
211
+ console.error(`Validation failed for ${basePath} after ${attempts} attempts`);
212
+ }
213
+ }
214
+ removePrefix(prefix, str) {
215
+ if (str.startsWith(prefix)) {
216
+ return str.slice(prefix.length);
217
+ }
218
+ return str;
219
+ }
220
+ async writeToFile(fileName, code) {
221
+ console.log(`writing the fixed code to ${fileName}`);
222
+ const resolvedCode = await code;
223
+ (0, fs_1.writeFileSync)(fileName, resolvedCode);
224
+ }
225
+ /**
226
+ * Sends the code to the AI for a fix
227
+ */
228
+ async codeFix(fix) {
229
+ return new Promise(async (resolve, reject) => {
230
+ const fixStream = await stormClient_1.stormClient.createCodeFix(fix, []);
231
+ fixStream.on('data', (evt) => {
232
+ if (evt.type === 'CODE_FIX') {
233
+ resolve(evt.payload.content);
234
+ }
235
+ });
236
+ fixStream.on('error', (err) => {
237
+ reject(err);
238
+ });
239
+ await fixStream.waitForDone();
240
+ });
157
241
  }
158
242
  /**
159
243
  * Emits the text-based files to the stream
@@ -100,6 +100,26 @@ export interface StormEventError {
100
100
  error: string;
101
101
  };
102
102
  }
103
+ export interface StormEventErrorClassifier {
104
+ type: 'ERROR_CLASSIFIER';
105
+ reason: string;
106
+ created: number;
107
+ payload: StormEventErrorClassifierInfo;
108
+ }
109
+ export interface StormEventCodeFix {
110
+ type: 'CODE_FIX';
111
+ reason: string;
112
+ created: number;
113
+ payload: {
114
+ filename: string;
115
+ content: string;
116
+ };
117
+ }
118
+ export interface StormEventErrorClassifierInfo {
119
+ error: string;
120
+ filename: string;
121
+ potentialFix: string;
122
+ }
103
123
  export interface ScreenTemplate {
104
124
  name: string;
105
125
  template: string;
@@ -153,4 +173,4 @@ export interface StormEventDefinitionChange {
153
173
  created: number;
154
174
  payload: StormDefinitions;
155
175
  }
156
- export type StormEvent = StormEventCreateBlock | StormEventCreateConnection | StormEventCreatePlanProperties | StormEventInvalidResponse | StormEventPlanRetry | StormEventCreateDSL | StormEventCreateDSLResource | StormEventError | StormEventScreen | StormEventScreenCandidate | StormEventFile | StormEventDone | StormEventDefinitionChange;
176
+ export type StormEvent = StormEventCreateBlock | StormEventCreateConnection | StormEventCreatePlanProperties | StormEventInvalidResponse | StormEventPlanRetry | StormEventCreateDSL | StormEventCreateDSLResource | StormEventError | StormEventScreen | StormEventScreenCandidate | StormEventFile | StormEventDone | StormEventDefinitionChange | StormEventErrorClassifier | StormEventCodeFix;
@@ -1,4 +1,4 @@
1
- import { StormFileImplementationPrompt, StormStream, StormUIImplementationPrompt } from './stream';
1
+ import { ConversationItem, StormFileImplementationPrompt, StormStream, StormUIImplementationPrompt } from './stream';
2
2
  export declare const STORM_ID = "storm";
3
3
  export declare const ConversationIdHeader = "Conversation-Id";
4
4
  declare class StormClient {
@@ -9,6 +9,8 @@ declare class StormClient {
9
9
  createMetadata(prompt: string, conversationId?: string): Promise<StormStream>;
10
10
  createUIImplementation(prompt: StormUIImplementationPrompt, conversationId?: string): Promise<StormStream>;
11
11
  createServiceImplementation(prompt: StormFileImplementationPrompt, conversationId?: string): Promise<StormStream>;
12
+ createErrorClassification(prompt: string, history?: ConversationItem[], conversationId?: string): Promise<StormStream>;
13
+ createCodeFix(prompt: string, history?: ConversationItem[], conversationId?: string): Promise<StormStream>;
12
14
  }
13
15
  export declare const stormClient: StormClient;
14
16
  export {};
@@ -83,5 +83,17 @@ class StormClient {
83
83
  conversationId,
84
84
  });
85
85
  }
86
+ createErrorClassification(prompt, history, conversationId) {
87
+ return this.send('/v2/code/errorclassifier', {
88
+ conversationId: conversationId,
89
+ prompt,
90
+ });
91
+ }
92
+ createCodeFix(prompt, history, conversationId) {
93
+ return this.send('/v2/code/fix', {
94
+ conversationId: conversationId,
95
+ prompt,
96
+ });
97
+ }
86
98
  }
87
99
  exports.stormClient = new StormClient();
@@ -22,6 +22,13 @@ export declare class StormCodegen {
22
22
  * Generates the code for a block and sends it to the AI
23
23
  */
24
24
  private processBlockCode;
25
+ private verifyAndFixCode;
26
+ removePrefix(prefix: string, str: string): string;
27
+ writeToFile(fileName: string, code: Promise<string>): Promise<void>;
28
+ /**
29
+ * Sends the code to the AI for a fix
30
+ */
31
+ private codeFix;
25
32
  /**
26
33
  * Emits the text-based files to the stream
27
34
  */
@@ -39,6 +39,7 @@ const stream_1 = require("./stream");
39
39
  const promises_1 = require("fs/promises");
40
40
  const path_1 = __importStar(require("path"));
41
41
  const node_os_1 = __importDefault(require("node:os"));
42
+ const fs_1 = require("fs");
42
43
  class StormCodegen {
43
44
  userPrompt;
44
45
  blocks;
@@ -154,6 +155,89 @@ class StormCodegen {
154
155
  const filePath = (0, path_1.join)(basePath, uiFile.filename);
155
156
  await (0, promises_1.writeFile)(filePath, uiFile.content);
156
157
  }
158
+ const filesToBeFixed = serviceFiles.concat(contextFiles);
159
+ const codeGenerator = new codegen_1.BlockCodeGenerator(block.content);
160
+ await this.verifyAndFixCode(codeGenerator, basePath, filesToBeFixed, allFiles);
161
+ }
162
+ async verifyAndFixCode(codeGenerator, basePath, filesToBeFixed, knownFiles) {
163
+ let attempts = 0;
164
+ let validCode = false;
165
+ for (let i = 0; i <= 3; i++) {
166
+ attempts++;
167
+ try {
168
+ console.log(`Validating the code in ${basePath} attempt #${attempts}`);
169
+ const result = await codeGenerator.validateForTarget(basePath);
170
+ if (result && result.valid) {
171
+ validCode = true;
172
+ break;
173
+ }
174
+ if (result && !result.valid) {
175
+ console.debug('Validation error:', result);
176
+ const errorStream = await stormClient_1.stormClient.createErrorClassification(result.error, []);
177
+ const fixes = new Map();
178
+ errorStream.on('data', (evt) => {
179
+ if (evt.type === 'ERROR_CLASSIFIER') {
180
+ // find the file that caused the error
181
+ // strip base path from event file name, if it exists sometimes the AI sends the full path
182
+ const eventFileName = this.removePrefix(basePath + '/', evt.payload.filename);
183
+ const file = filesToBeFixed.find((f) => f.filename === eventFileName);
184
+ if (!file) {
185
+ console.log(`Could not find the file ${eventFileName} in the list of files to be fixed, Henrik might wanna create a new file for this fix`);
186
+ }
187
+ // read the content of the file
188
+ const content = (0, fs_1.readFileSync)((0, path_1.join)(basePath, eventFileName), 'utf8');
189
+ const fix = `${evt.payload.potentialFix}\n---\n${knownFiles.map(e => e.filename).join("\n")}\n---\n${content}`;
190
+ console.log(`trying to fix the code in ${eventFileName}`);
191
+ console.debug(`with the fix:\n${fix}`);
192
+ const code = this.codeFix(fix);
193
+ fixes.set((0, path_1.join)(basePath, eventFileName), code);
194
+ }
195
+ });
196
+ await errorStream.waitForDone();
197
+ for (const [filename, codePromise] of fixes) {
198
+ const code = await codePromise;
199
+ (0, fs_1.writeFileSync)(filename, code);
200
+ }
201
+ }
202
+ }
203
+ catch (e) {
204
+ console.error('Error:', e);
205
+ }
206
+ }
207
+ if (validCode) {
208
+ console.log(`Validation successful after ${attempts} attempts`);
209
+ }
210
+ else {
211
+ console.error(`Validation failed for ${basePath} after ${attempts} attempts`);
212
+ }
213
+ }
214
+ removePrefix(prefix, str) {
215
+ if (str.startsWith(prefix)) {
216
+ return str.slice(prefix.length);
217
+ }
218
+ return str;
219
+ }
220
+ async writeToFile(fileName, code) {
221
+ console.log(`writing the fixed code to ${fileName}`);
222
+ const resolvedCode = await code;
223
+ (0, fs_1.writeFileSync)(fileName, resolvedCode);
224
+ }
225
+ /**
226
+ * Sends the code to the AI for a fix
227
+ */
228
+ async codeFix(fix) {
229
+ return new Promise(async (resolve, reject) => {
230
+ const fixStream = await stormClient_1.stormClient.createCodeFix(fix, []);
231
+ fixStream.on('data', (evt) => {
232
+ if (evt.type === 'CODE_FIX') {
233
+ resolve(evt.payload.content);
234
+ }
235
+ });
236
+ fixStream.on('error', (err) => {
237
+ reject(err);
238
+ });
239
+ await fixStream.waitForDone();
240
+ });
157
241
  }
158
242
  /**
159
243
  * Emits the text-based files to the stream
@@ -100,6 +100,26 @@ export interface StormEventError {
100
100
  error: string;
101
101
  };
102
102
  }
103
+ export interface StormEventErrorClassifier {
104
+ type: 'ERROR_CLASSIFIER';
105
+ reason: string;
106
+ created: number;
107
+ payload: StormEventErrorClassifierInfo;
108
+ }
109
+ export interface StormEventCodeFix {
110
+ type: 'CODE_FIX';
111
+ reason: string;
112
+ created: number;
113
+ payload: {
114
+ filename: string;
115
+ content: string;
116
+ };
117
+ }
118
+ export interface StormEventErrorClassifierInfo {
119
+ error: string;
120
+ filename: string;
121
+ potentialFix: string;
122
+ }
103
123
  export interface ScreenTemplate {
104
124
  name: string;
105
125
  template: string;
@@ -153,4 +173,4 @@ export interface StormEventDefinitionChange {
153
173
  created: number;
154
174
  payload: StormDefinitions;
155
175
  }
156
- export type StormEvent = StormEventCreateBlock | StormEventCreateConnection | StormEventCreatePlanProperties | StormEventInvalidResponse | StormEventPlanRetry | StormEventCreateDSL | StormEventCreateDSLResource | StormEventError | StormEventScreen | StormEventScreenCandidate | StormEventFile | StormEventDone | StormEventDefinitionChange;
176
+ export type StormEvent = StormEventCreateBlock | StormEventCreateConnection | StormEventCreatePlanProperties | StormEventInvalidResponse | StormEventPlanRetry | StormEventCreateDSL | StormEventCreateDSLResource | StormEventError | StormEventScreen | StormEventScreenCandidate | StormEventFile | StormEventDone | StormEventDefinitionChange | StormEventErrorClassifier | StormEventCodeFix;
@@ -1,4 +1,4 @@
1
- import { StormFileImplementationPrompt, StormStream, StormUIImplementationPrompt } from './stream';
1
+ import { ConversationItem, StormFileImplementationPrompt, StormStream, StormUIImplementationPrompt } from './stream';
2
2
  export declare const STORM_ID = "storm";
3
3
  export declare const ConversationIdHeader = "Conversation-Id";
4
4
  declare class StormClient {
@@ -9,6 +9,8 @@ declare class StormClient {
9
9
  createMetadata(prompt: string, conversationId?: string): Promise<StormStream>;
10
10
  createUIImplementation(prompt: StormUIImplementationPrompt, conversationId?: string): Promise<StormStream>;
11
11
  createServiceImplementation(prompt: StormFileImplementationPrompt, conversationId?: string): Promise<StormStream>;
12
+ createErrorClassification(prompt: string, history?: ConversationItem[], conversationId?: string): Promise<StormStream>;
13
+ createCodeFix(prompt: string, history?: ConversationItem[], conversationId?: string): Promise<StormStream>;
12
14
  }
13
15
  export declare const stormClient: StormClient;
14
16
  export {};
@@ -83,5 +83,17 @@ class StormClient {
83
83
  conversationId,
84
84
  });
85
85
  }
86
+ createErrorClassification(prompt, history, conversationId) {
87
+ return this.send('/v2/code/errorclassifier', {
88
+ conversationId: conversationId,
89
+ prompt,
90
+ });
91
+ }
92
+ createCodeFix(prompt, history, conversationId) {
93
+ return this.send('/v2/code/fix', {
94
+ conversationId: conversationId,
95
+ prompt,
96
+ });
97
+ }
86
98
  }
87
99
  exports.stormClient = new StormClient();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kapeta/local-cluster-service",
3
- "version": "0.48.4",
3
+ "version": "0.48.5",
4
4
  "description": "Manages configuration, ports and service discovery for locally running Kapeta systems",
5
5
  "type": "commonjs",
6
6
  "exports": {
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { Definition } from '@kapeta/local-cluster-config';
7
- import { AIFileTypes, BlockCodeGenerator, CodeWriter, GeneratedFile, GeneratedResult } from '@kapeta/codegen';
7
+ import { AIFileTypes, BlockCodeGenerator, CodeGenerator, CodeWriter, GeneratedFile, GeneratedResult } from '@kapeta/codegen';
8
8
  import { BlockDefinition } from '@kapeta/schemas';
9
9
  import { codeGeneratorManager } from '../codeGeneratorManager';
10
10
  import { STORM_ID, stormClient } from './stormClient';
@@ -15,6 +15,7 @@ import { KapetaURI } from '@kapeta/nodejs-utils';
15
15
  import { writeFile } from 'fs/promises';
16
16
  import path, { join } from 'path';
17
17
  import os from 'node:os';
18
+ import { readFile, readFileSync, writeFileSync } from 'fs';
18
19
 
19
20
  type ImplementationGenerator = (prompt: StormFileImplementationPrompt, conversationId?: string) => Promise<StormStream>;
20
21
 
@@ -163,6 +164,93 @@ export class StormCodegen {
163
164
  const filePath = join(basePath, uiFile.filename);
164
165
  await writeFile(filePath, uiFile.content);
165
166
  }
167
+
168
+ const filesToBeFixed = serviceFiles.concat(contextFiles);
169
+ const codeGenerator = new BlockCodeGenerator(block.content as BlockDefinition);
170
+ await this.verifyAndFixCode(codeGenerator, basePath, filesToBeFixed, allFiles);
171
+ }
172
+
173
+ private async verifyAndFixCode(codeGenerator: CodeGenerator, basePath: string, filesToBeFixed: StormFileInfo[], knownFiles: StormFileInfo[]) {
174
+ let attempts = 0;
175
+ let validCode = false;
176
+ for (let i = 0; i <= 3; i++) {
177
+ attempts++;
178
+ try {
179
+ console.log(`Validating the code in ${basePath} attempt #${attempts}`)
180
+ const result = await codeGenerator.validateForTarget(basePath);
181
+ if (result && result.valid) {
182
+ validCode = true;
183
+ break;
184
+ }
185
+
186
+ if (result && !result.valid) {
187
+ console.debug('Validation error:', result);
188
+ const errorStream = await stormClient.createErrorClassification(result.error, []);
189
+ const fixes = new Map<string, Promise<string>>();
190
+
191
+ errorStream.on('data', (evt) => {
192
+ if (evt.type === 'ERROR_CLASSIFIER') {
193
+ // find the file that caused the error
194
+ // strip base path from event file name, if it exists sometimes the AI sends the full path
195
+ const eventFileName = this.removePrefix(basePath+'/', evt.payload.filename);
196
+ const file = filesToBeFixed.find((f) => f.filename === eventFileName);
197
+ if(!file) {
198
+ console.log(`Could not find the file ${eventFileName} in the list of files to be fixed, Henrik might wanna create a new file for this fix`);
199
+ }
200
+ // read the content of the file
201
+ const content = readFileSync(join(basePath, eventFileName), 'utf8');
202
+ const fix = `${evt.payload.potentialFix}\n---\n${knownFiles.map(e => e.filename).join("\n")}\n---\n${content}`;
203
+ console.log(`trying to fix the code in ${eventFileName}`);
204
+ console.debug(`with the fix:\n${fix}`)
205
+ const code = this.codeFix(fix);
206
+ fixes.set(join(basePath, eventFileName), code);
207
+ }
208
+ });
209
+
210
+ await errorStream.waitForDone();
211
+ for (const [filename, codePromise] of fixes) {
212
+ const code = await codePromise;
213
+ writeFileSync(filename, code);
214
+ }
215
+ }
216
+ } catch (e) {
217
+ console.error('Error:', e);
218
+ }
219
+ }
220
+ if (validCode) {
221
+ console.log(`Validation successful after ${attempts} attempts`);
222
+ } else {
223
+ console.error(`Validation failed for ${basePath} after ${attempts} attempts`);
224
+ }
225
+ }
226
+
227
+ removePrefix(prefix: string, str: string): string {
228
+ if (str.startsWith(prefix)) {
229
+ return str.slice(prefix.length);
230
+ }
231
+ return str;
232
+ }
233
+ async writeToFile(fileName: string, code: Promise<string>) {
234
+ console.log(`writing the fixed code to ${fileName}`);
235
+ const resolvedCode = await code;
236
+ writeFileSync(fileName, resolvedCode);
237
+ }
238
+ /**
239
+ * Sends the code to the AI for a fix
240
+ */
241
+ private async codeFix(fix: string): Promise<string> {
242
+ return new Promise<string>(async (resolve, reject) => {
243
+ const fixStream = await stormClient.createCodeFix(fix, []);
244
+ fixStream.on('data', (evt) => {
245
+ if (evt.type === 'CODE_FIX') {
246
+ resolve(evt.payload.content);
247
+ }
248
+ });
249
+ fixStream.on('error', (err) => {
250
+ reject(err);
251
+ });
252
+ await fixStream.waitForDone();
253
+ });
166
254
  }
167
255
 
168
256
  /**
@@ -127,6 +127,28 @@ export interface StormEventError {
127
127
  };
128
128
  }
129
129
 
130
+ export interface StormEventErrorClassifier {
131
+ type: 'ERROR_CLASSIFIER';
132
+ reason: string;
133
+ created: number;
134
+ payload: StormEventErrorClassifierInfo;
135
+ }
136
+
137
+ export interface StormEventCodeFix {
138
+ type: 'CODE_FIX';
139
+ reason: string;
140
+ created: number;
141
+ payload: {
142
+ filename: string;
143
+ content: string;
144
+ };
145
+ }
146
+ export interface StormEventErrorClassifierInfo {
147
+ error: string,
148
+ filename: string,
149
+ potentialFix: string
150
+ }
151
+
130
152
  export interface ScreenTemplate {
131
153
  name: string;
132
154
  template: string;
@@ -199,4 +221,6 @@ export type StormEvent =
199
221
  | StormEventScreenCandidate
200
222
  | StormEventFile
201
223
  | StormEventDone
202
- | StormEventDefinitionChange;
224
+ | StormEventDefinitionChange
225
+ | StormEventErrorClassifier
226
+ | StormEventCodeFix;
@@ -10,7 +10,6 @@ import {
10
10
  ConversationItem,
11
11
  StormContextRequest,
12
12
  StormFileImplementationPrompt,
13
- StormFileInfo,
14
13
  StormStream,
15
14
  StormUIImplementationPrompt,
16
15
  } from './stream';
@@ -111,6 +110,19 @@ class StormClient {
111
110
  conversationId,
112
111
  });
113
112
  }
113
+
114
+ public createErrorClassification(prompt: string, history?: ConversationItem[], conversationId?: string) {
115
+ return this.send('/v2/code/errorclassifier', {
116
+ conversationId: conversationId,
117
+ prompt,
118
+ });
119
+ }
120
+ public createCodeFix(prompt: string, history?: ConversationItem[], conversationId?: string) {
121
+ return this.send('/v2/code/fix', {
122
+ conversationId: conversationId,
123
+ prompt,
124
+ });
125
+ }
114
126
  }
115
127
 
116
128
  export const stormClient = new StormClient();