genlayer 0.12.1 → 0.12.2-beta.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.
- package/.github/workflows/publish-beta.yml +2 -2
- package/.github/workflows/publish.yml +2 -2
- package/.github/workflows/validate-code.yml +1 -1
- package/CHANGELOG.md +6 -0
- package/dist/index.js +24736 -108331
- package/docker-compose.yml +1 -1
- package/esbuild.config.dev.js +18 -0
- package/esbuild.config.js +10 -5
- package/esbuild.config.prod.js +16 -0
- package/eslint.config.js +59 -0
- package/package.json +12 -9
- package/scripts/postinstall.js +10 -6
- package/src/commands/config/getSetReset.ts +25 -18
- package/src/commands/contracts/deploy.ts +105 -25
- package/src/commands/contracts/index.ts +5 -1
- package/src/commands/general/index.ts +10 -4
- package/src/commands/general/init.ts +136 -189
- package/src/commands/general/start.ts +76 -77
- package/src/commands/general/stop.ts +6 -5
- package/src/commands/keygen/create.ts +9 -11
- package/src/commands/update/index.ts +3 -8
- package/src/commands/update/ollama.ts +56 -56
- package/src/commands/validators/validators.ts +48 -55
- package/src/lib/actions/BaseAction.ts +75 -4
- package/src/lib/config/simulator.ts +1 -1
- package/src/lib/services/simulator.ts +3 -2
- package/tests/actions/create.test.ts +18 -30
- package/tests/actions/deploy.test.ts +200 -30
- package/tests/actions/getSetReset.test.ts +29 -42
- package/tests/actions/init.test.ts +240 -475
- package/tests/actions/ollama.test.ts +40 -55
- package/tests/actions/start.test.ts +107 -108
- package/tests/actions/stop.test.ts +23 -4
- package/tests/actions/validators.test.ts +273 -142
- package/tests/commands/call.test.ts +4 -1
- package/tests/commands/deploy.test.ts +11 -0
- package/tests/commands/init.test.ts +11 -12
- package/tests/commands/up.test.ts +31 -23
- package/tests/commands/update.test.ts +2 -5
- package/tests/libs/baseAction.test.ts +175 -0
- package/tests/services/simulator.test.ts +15 -0
- package/.eslintrc.js +0 -58
- package/esbuild.config.dev +0 -16
- package/esbuild.config.prod +0 -16
|
@@ -1,523 +1,288 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describe, test, vi, beforeEach, afterEach, expect } from "vitest";
|
|
2
2
|
import inquirer from "inquirer";
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import { tmpdir } from "os";
|
|
6
|
-
import {mkdtempSync} from "fs";
|
|
7
|
-
import {join} from "path";
|
|
8
|
-
import fs from "fs";
|
|
9
|
-
import * as dotenv from "dotenv";
|
|
10
|
-
import {localnetCompatibleVersion} from "../../src/lib/config/simulator";
|
|
3
|
+
import { InitAction, InitActionOptions } from "../../src/commands/general/init";
|
|
4
|
+
import { SimulatorService } from "../../src/lib/services/simulator";
|
|
11
5
|
import { OllamaAction } from "../../src/commands/update/ollama";
|
|
12
|
-
import { ConfigFileManager } from "../../src/lib/config/ConfigFileManager";
|
|
13
6
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
vi.
|
|
18
|
-
vi.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
let
|
|
26
|
-
let
|
|
27
|
-
let
|
|
28
|
-
|
|
29
|
-
let
|
|
30
|
-
let
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
let simAddConfigToEnvFile: ReturnType<any>;
|
|
7
|
+
describe("InitAction", () => {
|
|
8
|
+
let initAction: InitAction;
|
|
9
|
+
let inquirerPromptSpy: ReturnType<any>;
|
|
10
|
+
let checkCliVersionSpy: ReturnType<typeof vi.spyOn>;
|
|
11
|
+
let checkInstallRequirementsSpy: ReturnType<typeof vi.spyOn>;
|
|
12
|
+
let checkVersionRequirementsSpy: ReturnType<typeof vi.spyOn>;
|
|
13
|
+
let resetDockerContainersSpy: ReturnType<typeof vi.spyOn>;
|
|
14
|
+
let resetDockerImagesSpy: ReturnType<typeof vi.spyOn>;
|
|
15
|
+
let addConfigToEnvFileSpy: ReturnType<typeof vi.spyOn>;
|
|
16
|
+
let runSimulatorSpy: ReturnType<typeof vi.spyOn>;
|
|
17
|
+
let waitForSimulatorSpy: ReturnType<typeof vi.spyOn>;
|
|
18
|
+
let deleteAllValidatorsSpy: ReturnType<typeof vi.spyOn>;
|
|
19
|
+
let createRandomValidatorsSpy: ReturnType<typeof vi.spyOn>;
|
|
20
|
+
let cleanDatabaseSpy: ReturnType<typeof vi.spyOn>;
|
|
21
|
+
let openFrontendSpy: ReturnType<typeof vi.spyOn>;
|
|
22
|
+
let getFrontendUrlSpy: ReturnType<typeof vi.spyOn>;
|
|
23
|
+
let normalizeLocalnetVersionSpy: ReturnType<typeof vi.spyOn>;
|
|
24
|
+
|
|
25
|
+
const defaultConfig = { defaultOllamaModel: "llama3" };
|
|
26
|
+
|
|
27
|
+
const defaultOptions: InitActionOptions = {
|
|
28
|
+
numValidators: 5,
|
|
29
|
+
headless: false,
|
|
30
|
+
resetDb: false,
|
|
31
|
+
localnetVersion: "v1.0.0",
|
|
32
|
+
};
|
|
41
33
|
|
|
42
34
|
beforeEach(() => {
|
|
43
35
|
vi.clearAllMocks();
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
git: true,
|
|
68
|
-
docker: true,
|
|
69
|
-
})
|
|
70
|
-
simAddConfigToEnvFile.mockResolvedValue(true);
|
|
71
|
-
const mockEnvContent = "FRONTEND_PORT=8080";
|
|
72
|
-
const mockEnvConfig = { FRONTEND_PORT: "8080" };
|
|
73
|
-
vi.mocked(fs.readFileSync).mockReturnValue(mockEnvContent);
|
|
74
|
-
vi.mocked(dotenv.parse).mockReturnValue(mockEnvConfig);
|
|
36
|
+
initAction = new InitAction();
|
|
37
|
+
inquirerPromptSpy = vi.spyOn(inquirer, "prompt");
|
|
38
|
+
vi.spyOn(initAction as any, "startSpinner").mockImplementation(() => {});
|
|
39
|
+
vi.spyOn(initAction as any, "setSpinnerText").mockImplementation(() => {});
|
|
40
|
+
vi.spyOn(initAction as any, "succeedSpinner").mockImplementation(() => {});
|
|
41
|
+
vi.spyOn(initAction as any, "failSpinner").mockImplementation(() => {});
|
|
42
|
+
vi.spyOn(initAction as any, "stopSpinner").mockImplementation(() => {});
|
|
43
|
+
vi.spyOn(initAction as any, "logError").mockImplementation(() => {});
|
|
44
|
+
vi.spyOn(initAction, "getConfig").mockReturnValue(defaultConfig);
|
|
45
|
+
checkCliVersionSpy = vi.spyOn(SimulatorService.prototype, "checkCliVersion").mockResolvedValue(undefined);
|
|
46
|
+
checkInstallRequirementsSpy = vi.spyOn(SimulatorService.prototype, "checkInstallRequirements").mockResolvedValue({ git: true, docker: true });
|
|
47
|
+
checkVersionRequirementsSpy = vi.spyOn(SimulatorService.prototype, "checkVersionRequirements").mockResolvedValue({ node: "", docker: "" });
|
|
48
|
+
resetDockerContainersSpy = vi.spyOn(SimulatorService.prototype, "resetDockerContainers").mockResolvedValue(undefined);
|
|
49
|
+
resetDockerImagesSpy = vi.spyOn(SimulatorService.prototype, "resetDockerImages").mockResolvedValue(undefined);
|
|
50
|
+
addConfigToEnvFileSpy = vi.spyOn(SimulatorService.prototype, "addConfigToEnvFile").mockResolvedValue();
|
|
51
|
+
runSimulatorSpy = vi.spyOn(SimulatorService.prototype, "runSimulator").mockResolvedValue(undefined as any);
|
|
52
|
+
waitForSimulatorSpy = vi.spyOn(SimulatorService.prototype, "waitForSimulatorToBeReady").mockResolvedValue({ initialized: true }) as any;
|
|
53
|
+
deleteAllValidatorsSpy = vi.spyOn(SimulatorService.prototype, "deleteAllValidators").mockResolvedValue(undefined);
|
|
54
|
+
createRandomValidatorsSpy = vi.spyOn(SimulatorService.prototype, "createRandomValidators").mockResolvedValue(undefined) as any;
|
|
55
|
+
cleanDatabaseSpy = vi.spyOn(SimulatorService.prototype, "cleanDatabase").mockResolvedValue(true);
|
|
56
|
+
openFrontendSpy = vi.spyOn(SimulatorService.prototype, "openFrontend").mockResolvedValue(true);
|
|
57
|
+
getFrontendUrlSpy = vi.spyOn(SimulatorService.prototype, "getFrontendUrl").mockReturnValue("http://localhost:8080");
|
|
58
|
+
normalizeLocalnetVersionSpy = vi.spyOn(SimulatorService.prototype, "normalizeLocalnetVersion").mockImplementation((v: string) => v) as any;
|
|
75
59
|
});
|
|
76
60
|
|
|
77
61
|
afterEach(() => {
|
|
78
62
|
vi.restoreAllMocks();
|
|
79
63
|
});
|
|
80
64
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
65
|
+
describe("Successful Execution", () => {
|
|
66
|
+
test("executes the full flow in non-headless mode", async () => {
|
|
67
|
+
inquirerPromptSpy
|
|
68
|
+
.mockResolvedValueOnce({ confirmAction: true })
|
|
69
|
+
.mockResolvedValueOnce({ selectedLlmProviders: ["openai", "heuristai"] })
|
|
70
|
+
.mockResolvedValueOnce({ openai: "API_KEY_OPENAI" })
|
|
71
|
+
.mockResolvedValueOnce({ heuristai: "API_KEY_HEURIST" });
|
|
72
|
+
await initAction.execute(defaultOptions);
|
|
73
|
+
expect(checkCliVersionSpy).toHaveBeenCalled();
|
|
74
|
+
expect(checkInstallRequirementsSpy).toHaveBeenCalled();
|
|
75
|
+
expect(checkVersionRequirementsSpy).toHaveBeenCalled();
|
|
76
|
+
expect(resetDockerContainersSpy).toHaveBeenCalled();
|
|
77
|
+
expect(resetDockerImagesSpy).toHaveBeenCalled();
|
|
78
|
+
expect(addConfigToEnvFileSpy).toHaveBeenCalledWith({ OPENAIKEY: "API_KEY_OPENAI", HEURISTAIAPIKEY: "API_KEY_HEURIST" });
|
|
79
|
+
expect(addConfigToEnvFileSpy).toHaveBeenCalledWith({ LOCALNETVERSION: "v1.0.0" });
|
|
80
|
+
expect(runSimulatorSpy).toHaveBeenCalled();
|
|
81
|
+
expect(waitForSimulatorSpy).toHaveBeenCalled();
|
|
82
|
+
expect(deleteAllValidatorsSpy).toHaveBeenCalled();
|
|
83
|
+
expect(createRandomValidatorsSpy).toHaveBeenCalledWith(5, ["openai", "heuristai"]);
|
|
84
|
+
expect(getFrontendUrlSpy).toHaveBeenCalled();
|
|
85
|
+
expect(openFrontendSpy).toHaveBeenCalled();
|
|
86
|
+
expect((initAction as any).succeedSpinner).toHaveBeenCalledWith("GenLayer Localnet initialized successfully! Go to http://localhost:8080 in your browser to access it.");
|
|
102
87
|
});
|
|
103
88
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
89
|
+
test("executes correctly in headless mode with DB reset and 'ollama' selected", async () => {
|
|
90
|
+
inquirerPromptSpy
|
|
91
|
+
.mockResolvedValueOnce({ confirmAction: true })
|
|
92
|
+
.mockResolvedValueOnce({ selectedLlmProviders: ["openai", "ollama"] })
|
|
93
|
+
.mockResolvedValueOnce({ openai: "API_KEY_OPENAI" });
|
|
94
|
+
const ollamaUpdateSpy = vi.spyOn(OllamaAction.prototype, "updateModel").mockResolvedValue(undefined);
|
|
95
|
+
const headlessOptions: InitActionOptions = {
|
|
96
|
+
numValidators: 5,
|
|
97
|
+
headless: true,
|
|
98
|
+
resetDb: true,
|
|
99
|
+
localnetVersion: "v1.0.0",
|
|
100
|
+
};
|
|
101
|
+
await initAction.execute(headlessOptions);
|
|
102
|
+
expect(cleanDatabaseSpy).toHaveBeenCalled();
|
|
103
|
+
expect(openFrontendSpy).not.toHaveBeenCalled();
|
|
104
|
+
expect((initAction as any).succeedSpinner).toHaveBeenCalledWith("GenLayer Localnet initialized successfully! ");
|
|
105
|
+
expect(ollamaUpdateSpy).toHaveBeenCalledWith("llama3");
|
|
115
106
|
});
|
|
116
107
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
node: mockVersionNumber
|
|
108
|
+
test("normalizes localnetVersion if not 'latest'", async () => {
|
|
109
|
+
const customVersion = "custom-v1";
|
|
110
|
+
normalizeLocalnetVersionSpy.mockReturnValue(customVersion);
|
|
111
|
+
inquirerPromptSpy
|
|
112
|
+
.mockResolvedValueOnce({ confirmAction: true })
|
|
113
|
+
.mockResolvedValueOnce({ selectedLlmProviders: ["openai"] })
|
|
114
|
+
.mockResolvedValueOnce({ openai: "API_KEY_OPENAI" });
|
|
115
|
+
await initAction.execute({ ...defaultOptions, localnetVersion: customVersion });
|
|
116
|
+
expect(normalizeLocalnetVersionSpy).toHaveBeenCalledWith(customVersion);
|
|
117
|
+
expect(addConfigToEnvFileSpy).toHaveBeenCalledWith({ LOCALNETVERSION: customVersion });
|
|
128
118
|
});
|
|
129
119
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
await initAction(defaultActionOptions, simulatorService);
|
|
142
|
-
|
|
143
|
-
expect(log).toHaveBeenCalledWith("Aborted!");
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
test("if resetDockerContainers fail, then the execution aborts", async () => {
|
|
147
|
-
inquirerPrompt.mockResolvedValue({ confirmReset: true });
|
|
148
|
-
simServResetDockerContainers.mockRejectedValue(new Error("Error"));
|
|
149
|
-
|
|
150
|
-
await initAction(defaultActionOptions, simulatorService);
|
|
151
|
-
|
|
152
|
-
expect(error).toHaveBeenCalledWith(new Error("Error"));
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
test("should open the frontend if everything went well", async () => {
|
|
156
|
-
inquirerPrompt.mockResolvedValue({
|
|
157
|
-
confirmReset: true,
|
|
158
|
-
confirmDownload: true,
|
|
159
|
-
selectedLlmProviders: ["openai", "heuristai"],
|
|
160
|
-
openai: "API_KEY1",
|
|
161
|
-
heuristai: "API_KEY2",
|
|
120
|
+
test("should set defaultOllamaModel to 'llama3' if not provided in config", async () => {
|
|
121
|
+
vi.spyOn(initAction, "getConfig").mockReturnValue({});
|
|
122
|
+
const writeConfigSpy = vi.spyOn(initAction, "writeConfig").mockImplementation(() => {});
|
|
123
|
+
const ollamaUpdateSpy = vi.spyOn(OllamaAction.prototype, "updateModel").mockResolvedValue(undefined);
|
|
124
|
+
inquirerPromptSpy
|
|
125
|
+
.mockResolvedValueOnce({ confirmAction: true })
|
|
126
|
+
.mockResolvedValueOnce({ selectedLlmProviders: ["ollama"] })
|
|
127
|
+
.mockResolvedValueOnce({ ollama: "API_KEY_OLLAMA" });
|
|
128
|
+
await initAction.execute(defaultOptions);
|
|
129
|
+
expect(writeConfigSpy).toHaveBeenCalledWith("defaultOllamaModel", "llama3");
|
|
130
|
+
expect(ollamaUpdateSpy).toHaveBeenCalledWith("llama3");
|
|
162
131
|
});
|
|
163
|
-
simServgetAiProvidersOptions.mockReturnValue([
|
|
164
|
-
{ name: "OpenAI", value: "openai" },
|
|
165
|
-
{ name: "Heurist", value: "heuristai" },
|
|
166
|
-
]);
|
|
167
|
-
|
|
168
|
-
vi.mocked(OllamaAction.prototype.updateModel).mockResolvedValueOnce(undefined);
|
|
169
|
-
|
|
170
|
-
simServRunSimulator.mockResolvedValue(true);
|
|
171
|
-
simServWaitForSimulator.mockResolvedValue({ initialized: true });
|
|
172
|
-
simServDeleteAllValidators.mockResolvedValue(true);
|
|
173
|
-
simServCreateRandomValidators.mockResolvedValue(true);
|
|
174
|
-
simServOpenFrontend.mockResolvedValue(true);
|
|
175
|
-
simGetSimulatorUrl.mockResolvedValue('http://localhost:8080/');
|
|
176
|
-
simServResetDockerContainers.mockResolvedValue(true);
|
|
177
|
-
simServResetDockerImages.mockResolvedValue(true);
|
|
178
132
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
openai: "API_KEY1",
|
|
193
|
-
heuristai: "API_KEY2",
|
|
133
|
+
test("validates API key input for configurable provider", async () => {
|
|
134
|
+
inquirerPromptSpy.mockResolvedValueOnce({ confirmAction: true });
|
|
135
|
+
inquirerPromptSpy.mockResolvedValueOnce({ selectedLlmProviders: ["openai"] });
|
|
136
|
+
let capturedQuestion: any;
|
|
137
|
+
inquirerPromptSpy.mockImplementationOnce((questions: any) => {
|
|
138
|
+
capturedQuestion = questions[0];
|
|
139
|
+
return Promise.resolve({ openai: "dummy-key" });
|
|
140
|
+
});
|
|
141
|
+
await initAction.execute(defaultOptions);
|
|
142
|
+
expect(capturedQuestion).toBeDefined();
|
|
143
|
+
const expectedError = `Please enter a valid API Key for OpenAI.`;
|
|
144
|
+
expect(capturedQuestion.validate("")).toBe(expectedError);
|
|
145
|
+
expect(capturedQuestion.validate("non-empty-key")).toBe(true);
|
|
194
146
|
});
|
|
195
|
-
simServgetAiProvidersOptions.mockReturnValue([
|
|
196
|
-
{ name: "OpenAI", value: "openai" },
|
|
197
|
-
{ name: "Heurist", value: "heuristai" },
|
|
198
|
-
]);
|
|
199
|
-
|
|
200
|
-
vi.mocked(OllamaAction.prototype.updateModel).mockResolvedValueOnce(undefined);
|
|
201
|
-
|
|
202
|
-
simServRunSimulator.mockResolvedValue(true);
|
|
203
|
-
simServWaitForSimulator.mockResolvedValue({ initialized: true });
|
|
204
|
-
simServDeleteAllValidators.mockResolvedValue(true);
|
|
205
|
-
simServCreateRandomValidators.mockResolvedValue(true);
|
|
206
|
-
simServOpenFrontend.mockResolvedValue(true);
|
|
207
|
-
simGetSimulatorUrl.mockResolvedValue('http://localhost:8080/');
|
|
208
|
-
simServResetDockerContainers.mockResolvedValue(true);
|
|
209
|
-
simServResetDockerImages.mockResolvedValue(true);
|
|
210
|
-
|
|
211
|
-
await initAction({...defaultActionOptions, headless: true, resetDb: true, localnetVersion: "v1.0.0"}, simulatorService);
|
|
212
147
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
148
|
+
test("validates LLM provider selection prompt", async () => {
|
|
149
|
+
let capturedQuestion: any;
|
|
150
|
+
inquirerPromptSpy
|
|
151
|
+
.mockResolvedValueOnce({ confirmAction: true })
|
|
152
|
+
.mockImplementationOnce((questions: any) => {
|
|
153
|
+
capturedQuestion = questions[0];
|
|
154
|
+
return Promise.resolve({ selectedLlmProviders: ["openai"] });
|
|
155
|
+
})
|
|
156
|
+
.mockResolvedValueOnce({ openai: "API_KEY_OPENAI" });
|
|
157
|
+
await initAction.execute(defaultOptions);
|
|
158
|
+
expect(capturedQuestion.validate([])).toBe("You must choose at least one option.");
|
|
159
|
+
expect(capturedQuestion.validate(["openai"])).toBe(true);
|
|
225
160
|
});
|
|
226
|
-
simServgetAiProvidersOptions.mockReturnValue([
|
|
227
|
-
{ name: "OpenAI", value: "openai" },
|
|
228
|
-
{ name: "Heurist", value: "heuristai" },
|
|
229
|
-
]);
|
|
230
|
-
|
|
231
|
-
vi.mocked(OllamaAction.prototype.updateModel).mockResolvedValueOnce(undefined);
|
|
232
|
-
|
|
233
|
-
simServRunSimulator.mockResolvedValue(true);
|
|
234
|
-
simServWaitForSimulator.mockResolvedValue({ initialized: true });
|
|
235
|
-
simServDeleteAllValidators.mockResolvedValue(true);
|
|
236
|
-
simServResetDockerContainers.mockResolvedValue(true);
|
|
237
|
-
simServResetDockerImages.mockResolvedValue(true);
|
|
238
|
-
simServCreateRandomValidators.mockRejectedValue();
|
|
239
|
-
simServOpenFrontend.mockResolvedValue(true);
|
|
240
|
-
simServResetDockerContainers.mockResolvedValue(true);
|
|
241
|
-
simServResetDockerImages.mockResolvedValue(true);
|
|
242
|
-
|
|
243
|
-
await initAction({...defaultActionOptions, headless: true}, simulatorService);
|
|
244
|
-
|
|
245
|
-
expect(log).toHaveBeenCalledWith('Initializing validators...');
|
|
246
|
-
expect(error).toHaveBeenCalledWith('Unable to initialize the validators.');
|
|
247
161
|
});
|
|
248
162
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
await initAction(defaultActionOptions, simulatorService);
|
|
256
|
-
|
|
257
|
-
expect(error).toHaveBeenCalledWith(new Error("Error"));
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
test("should pull Ollama model if 'ollama' is in providers", async () => {
|
|
261
|
-
|
|
262
|
-
inquirerPrompt.mockResolvedValue({
|
|
263
|
-
confirmReset: true,
|
|
264
|
-
confirmDownload: true,
|
|
265
|
-
selectedLlmProviders: ["openai", "heuristai", "ollama"],
|
|
266
|
-
openai: "API_KEY1",
|
|
267
|
-
heuristai: "API_KEY2",
|
|
268
|
-
ollama: "API_KEY3",
|
|
163
|
+
describe("Error Handling", () => {
|
|
164
|
+
test("fails if Docker is not installed", async () => {
|
|
165
|
+
checkInstallRequirementsSpy.mockResolvedValue({ git: true, docker: false });
|
|
166
|
+
await initAction.execute(defaultOptions);
|
|
167
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith("Docker is not installed. Please install Docker and try again.\n");
|
|
269
168
|
});
|
|
270
|
-
simServgetAiProvidersOptions.mockReturnValue([
|
|
271
|
-
{ name: "OpenAI", value: "openai" },
|
|
272
|
-
{ name: "Heurist", value: "heuristai" },
|
|
273
|
-
{ name: "Ollama", value: "ollama" },
|
|
274
|
-
]);
|
|
275
|
-
|
|
276
|
-
vi.mocked(OllamaAction.prototype.updateModel).mockResolvedValueOnce(undefined);
|
|
277
|
-
|
|
278
|
-
simServRunSimulator.mockResolvedValue(true);
|
|
279
|
-
simServWaitForSimulator.mockResolvedValue({ initialized: true });
|
|
280
|
-
simServDeleteAllValidators.mockResolvedValue(true);
|
|
281
|
-
simServResetDockerContainers.mockResolvedValue(true);
|
|
282
|
-
simServResetDockerImages.mockResolvedValue(true);
|
|
283
|
-
vi.mocked(ConfigFileManager.prototype.getConfig).mockReturnValue({});
|
|
284
169
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
test("should pull Ollama model if 'ollama' is in providers using defaultOllamaModel", async () => {
|
|
292
|
-
const ollamaModel = "gemma";
|
|
293
|
-
|
|
294
|
-
inquirerPrompt.mockResolvedValue({
|
|
295
|
-
confirmReset: true,
|
|
296
|
-
confirmDownload: true,
|
|
297
|
-
selectedLlmProviders: ["openai", "heuristai", "ollama"],
|
|
298
|
-
openai: "API_KEY1",
|
|
299
|
-
heuristai: "API_KEY2",
|
|
300
|
-
ollama: "API_KEY3",
|
|
170
|
+
test("fails if checkInstallRequirements throws an error", async () => {
|
|
171
|
+
const error = new Error("Install error");
|
|
172
|
+
checkInstallRequirementsSpy.mockRejectedValue(error);
|
|
173
|
+
await initAction.execute(defaultOptions);
|
|
174
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith("An error occurred during initialization.", error);
|
|
301
175
|
});
|
|
302
|
-
simServgetAiProvidersOptions.mockReturnValue([
|
|
303
|
-
{ name: "OpenAI", value: "openai" },
|
|
304
|
-
{ name: "Heurist", value: "heuristai" },
|
|
305
|
-
{ name: "Ollama", value: "ollama" },
|
|
306
|
-
]);
|
|
307
|
-
|
|
308
|
-
vi.mocked(OllamaAction.prototype.updateModel).mockResolvedValueOnce(undefined);
|
|
309
|
-
|
|
310
|
-
simServRunSimulator.mockResolvedValue(true);
|
|
311
|
-
simServWaitForSimulator.mockResolvedValue({ initialized: true });
|
|
312
|
-
simServDeleteAllValidators.mockResolvedValue(true);
|
|
313
|
-
simServResetDockerContainers.mockResolvedValue(true);
|
|
314
|
-
simServResetDockerImages.mockResolvedValue(true);
|
|
315
|
-
vi.mocked(ConfigFileManager.prototype.getConfig).mockReturnValue({defaultOllamaModel: ollamaModel});
|
|
316
|
-
|
|
317
|
-
await initAction(defaultActionOptions, simulatorService);
|
|
318
176
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
inquirerPrompt.mockResolvedValue({
|
|
326
|
-
confirmReset: true,
|
|
327
|
-
confirmDownload: true,
|
|
328
|
-
selectedLlmProviders: ["openai", "heuristai", "ollama"],
|
|
329
|
-
openai: "API_KEY1",
|
|
330
|
-
heuristai: "API_KEY2",
|
|
331
|
-
ollama: "API_KEY3",
|
|
177
|
+
test("fails if version requirements are not met (both docker and node)", async () => {
|
|
178
|
+
const version = "99.9.9";
|
|
179
|
+
checkVersionRequirementsSpy.mockResolvedValue({ docker: version, node: version });
|
|
180
|
+
await initAction.execute(defaultOptions);
|
|
181
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith(`Docker version ${version} or higher is required. Please update Docker and try again.\nNode version ${version} or higher is required. Please update Node and try again.\n`);
|
|
332
182
|
});
|
|
333
|
-
simServgetAiProvidersOptions.mockReturnValue([
|
|
334
|
-
{ name: "OpenAI", value: "openai" },
|
|
335
|
-
{ name: "Heurist", value: "heuristai" },
|
|
336
|
-
{ name: "Ollama", value: "ollama" },
|
|
337
|
-
]);
|
|
338
|
-
|
|
339
|
-
vi.mocked(ConfigFileManager.prototype.getConfig).mockResolvedValueOnce({})
|
|
340
|
-
vi.mocked(OllamaAction.prototype.updateModel).mockResolvedValueOnce(undefined);
|
|
341
|
-
|
|
342
|
-
simServRunSimulator.mockResolvedValue(true);
|
|
343
|
-
simServWaitForSimulator.mockResolvedValue({ initialized: true });
|
|
344
|
-
simServDeleteAllValidators.mockResolvedValue(true);
|
|
345
|
-
simServResetDockerContainers.mockResolvedValue(true);
|
|
346
|
-
simServResetDockerImages.mockResolvedValue(true);
|
|
347
|
-
vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify({}));
|
|
348
|
-
|
|
349
|
-
await initAction(defaultActionOptions, simulatorService);
|
|
350
|
-
|
|
351
|
-
expect(ConfigFileManager.prototype.writeConfig).toHaveBeenCalledWith('defaultOllamaModel', 'llama3')
|
|
352
|
-
expect(log).toHaveBeenCalledWith(`Pulling llama3 from Ollama...`);
|
|
353
|
-
expect(OllamaAction.prototype.updateModel).toHaveBeenCalled();
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
test("logs error if checkVersionRequirements throws", async () => {
|
|
357
|
-
simServCheckInstallRequirements.mockResolvedValue({ git: true, docker: true });
|
|
358
|
-
const errorMsg = new Error("checkVersionRequirements error");
|
|
359
|
-
simServCheckVersionRequirements.mockRejectedValueOnce(errorMsg);
|
|
360
|
-
|
|
361
|
-
await initAction(defaultActionOptions, simulatorService);
|
|
362
|
-
|
|
363
|
-
expect(error).toHaveBeenCalledWith(errorMsg);
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
test("logs error if resetDockerContainers throws", async () => {
|
|
367
|
-
inquirerPrompt.mockResolvedValue({ confirmReset: true });
|
|
368
|
-
simServCheckInstallRequirements.mockResolvedValue({ git: true, docker: true });
|
|
369
|
-
const errorMsg = new Error("resetDockerContainers error");
|
|
370
|
-
simServResetDockerContainers.mockRejectedValueOnce(errorMsg);
|
|
371
|
-
|
|
372
|
-
await initAction(defaultActionOptions, simulatorService);
|
|
373
|
-
|
|
374
|
-
expect(error).toHaveBeenCalledWith(errorMsg);
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
test("prompts for LLM providers and validates that at least one is selected", async () => {
|
|
378
|
-
const mockEnvContent = "FRONTEND_PORT=8080";
|
|
379
|
-
vi.mocked(fs.readFileSync).mockReturnValue(mockEnvContent);
|
|
380
|
-
|
|
381
|
-
inquirerPrompt
|
|
382
|
-
.mockResolvedValueOnce({ confirmReset: true })
|
|
383
|
-
.mockImplementation((questions: any) => {
|
|
384
|
-
if (questions[0].type === "checkbox") {
|
|
385
|
-
const validateFunction = questions[0].validate;
|
|
386
|
-
expect(validateFunction([])).toBe("You must choose at least one option.");
|
|
387
|
-
expect(validateFunction(["openai"])).toBe(true);
|
|
388
|
-
return Promise.resolve({ selectedLlmProviders: ["openai"] });
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
if (questions[0].type === "input") {
|
|
392
|
-
const validateFunction = questions[0].validate;
|
|
393
|
-
expect(validateFunction("")).toBe("Please enter a valid API Key for OpenAI.");
|
|
394
|
-
expect(validateFunction("API_KEY1")).toBe(true);
|
|
395
|
-
return Promise.resolve({ openai: "API_KEY1" });
|
|
396
|
-
}
|
|
397
|
-
});
|
|
398
183
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
simServDeleteAllValidators.mockResolvedValue(true);
|
|
405
|
-
simServCreateRandomValidators.mockResolvedValue(true);
|
|
406
|
-
simServOpenFrontend.mockResolvedValue(true);
|
|
407
|
-
|
|
408
|
-
await initAction(defaultActionOptions, simulatorService);
|
|
409
|
-
});
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
test("logs error message if simulator fails to initialize with ERROR code", async () => {
|
|
413
|
-
inquirerPrompt
|
|
414
|
-
.mockResolvedValueOnce({ confirmReset: true })
|
|
415
|
-
.mockResolvedValueOnce({ selectedLlmProviders: ["openai"] })
|
|
416
|
-
.mockResolvedValueOnce({ openai: "API_KEY1" });
|
|
417
|
-
|
|
418
|
-
simServCheckInstallRequirements.mockResolvedValue({ docker: true });
|
|
419
|
-
simServResetDockerContainers.mockResolvedValue(true);
|
|
420
|
-
simServResetDockerImages.mockResolvedValue(true);
|
|
421
|
-
simServRunSimulator.mockResolvedValue(true);
|
|
422
|
-
|
|
423
|
-
simServWaitForSimulator.mockResolvedValue({
|
|
424
|
-
initialized: false,
|
|
425
|
-
errorCode: "ERROR",
|
|
426
|
-
errorMessage: "Simulator failed to initialize due to configuration error.",
|
|
184
|
+
test("fails if version requirement for docker is not met", async () => {
|
|
185
|
+
const version = "99.9.9";
|
|
186
|
+
checkVersionRequirementsSpy.mockResolvedValue({ docker: version });
|
|
187
|
+
await initAction.execute(defaultOptions);
|
|
188
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith(`Docker version ${version} or higher is required. Please update Docker and try again.\n`);
|
|
427
189
|
});
|
|
428
190
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
test("logs error if runSimulator throws", async () => {
|
|
436
|
-
inquirerPrompt.mockResolvedValue({
|
|
437
|
-
confirmReset: true,
|
|
438
|
-
confirmDownload: true,
|
|
439
|
-
selectedLlmProviders: ["openai"],
|
|
440
|
-
openai: "API_KEY1",
|
|
191
|
+
test("fails if version requirement for node is not met", async () => {
|
|
192
|
+
const version = "99.9.9";
|
|
193
|
+
checkVersionRequirementsSpy.mockResolvedValue({ node: version });
|
|
194
|
+
await initAction.execute(defaultOptions);
|
|
195
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith(`Node version ${version} or higher is required. Please update Node and try again.\n`);
|
|
441
196
|
});
|
|
442
|
-
simServCheckInstallRequirements.mockResolvedValue({ git: true, docker: true });
|
|
443
|
-
simServResetDockerContainers.mockResolvedValue(true);
|
|
444
|
-
simServResetDockerImages.mockResolvedValue(true);
|
|
445
|
-
const errorMsg = new Error("runSimulator error");
|
|
446
|
-
simServRunSimulator.mockRejectedValueOnce(errorMsg);
|
|
447
197
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
test("logs specific message if waitForSimulatorToBeReady returns TIMEOUT errorCode", async () => {
|
|
454
|
-
inquirerPrompt.mockResolvedValue({
|
|
455
|
-
confirmReset: true,
|
|
456
|
-
confirmDownload: true,
|
|
457
|
-
selectedLlmProviders: ["openai"],
|
|
458
|
-
openai: "API_KEY1",
|
|
459
|
-
});
|
|
460
|
-
simServCheckInstallRequirements.mockResolvedValue({ git: true, docker: true });
|
|
461
|
-
simServResetDockerContainers.mockResolvedValue(true);
|
|
462
|
-
simServResetDockerImages.mockResolvedValue(true);
|
|
463
|
-
simServRunSimulator.mockResolvedValue(true);
|
|
464
|
-
simServWaitForSimulator.mockResolvedValue({
|
|
465
|
-
initialized: false,
|
|
466
|
-
errorCode: "TIMEOUT",
|
|
467
|
-
errorMessage: "errorMessage",
|
|
198
|
+
test("aborts if user does not confirm reset action", async () => {
|
|
199
|
+
inquirerPromptSpy.mockResolvedValueOnce({ confirmAction: false });
|
|
200
|
+
await initAction.execute(defaultOptions)
|
|
201
|
+
expect((initAction as any).logError).toHaveBeenCalledWith(`Operation aborted!`);
|
|
468
202
|
});
|
|
469
203
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
test("catches and logs error if waitForSimulatorToBeReady throws an exception", async () => {
|
|
478
|
-
inquirerPrompt
|
|
479
|
-
.mockResolvedValueOnce({ confirmReset: true })
|
|
480
|
-
.mockResolvedValueOnce({ selectedLlmProviders: ["openai"] })
|
|
481
|
-
.mockResolvedValueOnce({ openai: "API_KEY1" });
|
|
482
|
-
|
|
483
|
-
simServCheckInstallRequirements.mockResolvedValue({ docker: true });
|
|
484
|
-
simServResetDockerContainers.mockResolvedValue(true);
|
|
485
|
-
simServResetDockerImages.mockResolvedValue(true);
|
|
486
|
-
simServRunSimulator.mockResolvedValue(true);
|
|
487
|
-
|
|
488
|
-
const errorMsg = new Error("Unexpected simulator error");
|
|
489
|
-
simServWaitForSimulator.mockRejectedValueOnce(errorMsg);
|
|
204
|
+
test("fails if resetDockerContainers throws an error", async () => {
|
|
205
|
+
inquirerPromptSpy.mockResolvedValueOnce({ confirmAction: true });
|
|
206
|
+
resetDockerContainersSpy.mockRejectedValue(new Error("Container reset error"));
|
|
207
|
+
await initAction.execute(defaultOptions);
|
|
208
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith("An error occurred during initialization.", new Error("Container reset error"));
|
|
209
|
+
});
|
|
490
210
|
|
|
491
|
-
|
|
211
|
+
test("fails if runSimulator throws an error", async () => {
|
|
212
|
+
inquirerPromptSpy
|
|
213
|
+
.mockResolvedValueOnce({ confirmAction: true })
|
|
214
|
+
.mockResolvedValueOnce({ selectedLlmProviders: ["openai"] })
|
|
215
|
+
.mockResolvedValueOnce({ openai: "API_KEY_OPENAI" });
|
|
216
|
+
runSimulatorSpy.mockRejectedValue(new Error("Run simulator error"));
|
|
217
|
+
await initAction.execute(defaultOptions);
|
|
218
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith("An error occurred during initialization.", new Error("Run simulator error"));
|
|
219
|
+
});
|
|
492
220
|
|
|
493
|
-
|
|
494
|
-
|
|
221
|
+
test("fails if waitForSimulatorToBeReady returns ERROR code", async () => {
|
|
222
|
+
inquirerPromptSpy
|
|
223
|
+
.mockResolvedValueOnce({ confirmAction: true })
|
|
224
|
+
.mockResolvedValueOnce({ selectedLlmProviders: ["openai"] })
|
|
225
|
+
.mockResolvedValueOnce({ openai: "API_KEY_OPENAI" });
|
|
226
|
+
waitForSimulatorSpy.mockResolvedValue({ initialized: false, errorCode: "ERROR", errorMessage: "Initialization failed" });
|
|
227
|
+
await initAction.execute(defaultOptions);
|
|
228
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith("Unable to initialize the GenLayer Localnet: Initialization failed");
|
|
229
|
+
});
|
|
495
230
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
231
|
+
test("fails if waitForSimulatorToBeReady returns TIMEOUT code", async () => {
|
|
232
|
+
inquirerPromptSpy
|
|
233
|
+
.mockResolvedValueOnce({ confirmAction: true })
|
|
234
|
+
.mockResolvedValueOnce({ selectedLlmProviders: ["openai"] })
|
|
235
|
+
.mockResolvedValueOnce({ openai: "API_KEY_OPENAI" });
|
|
236
|
+
waitForSimulatorSpy.mockResolvedValue({ initialized: false, errorCode: "TIMEOUT", errorMessage: "Timeout" });
|
|
237
|
+
await initAction.execute(defaultOptions);
|
|
238
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith("The localnet is taking too long to initialize. Please try again after the localnet is ready.");
|
|
239
|
+
});
|
|
499
240
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
241
|
+
test("fails if deleteAllValidators throws an error", async () => {
|
|
242
|
+
inquirerPromptSpy
|
|
243
|
+
.mockResolvedValueOnce({ confirmAction: true })
|
|
244
|
+
.mockResolvedValueOnce({ selectedLlmProviders: ["openai"] })
|
|
245
|
+
.mockResolvedValueOnce({ openai: "API_KEY_OPENAI" });
|
|
246
|
+
deleteAllValidatorsSpy.mockRejectedValue(new Error("Validator deletion error"));
|
|
247
|
+
await initAction.execute(defaultOptions);
|
|
248
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith("An error occurred during initialization.", expect.any(Error));
|
|
249
|
+
});
|
|
504
250
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
251
|
+
test("fails if createRandomValidators throws an error", async () => {
|
|
252
|
+
inquirerPromptSpy
|
|
253
|
+
.mockResolvedValueOnce({ confirmAction: true })
|
|
254
|
+
.mockResolvedValueOnce({ selectedLlmProviders: ["openai"] })
|
|
255
|
+
.mockResolvedValueOnce({ openai: "API_KEY_OPENAI" });
|
|
256
|
+
createRandomValidatorsSpy.mockRejectedValue(new Error("Validator creation error"));
|
|
257
|
+
await initAction.execute(defaultOptions);
|
|
258
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith("An error occurred during initialization.", Error("Validator creation error"));
|
|
259
|
+
});
|
|
512
260
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
261
|
+
test("fails if cleanDatabase throws an error when resetDb is true", async () => {
|
|
262
|
+
inquirerPromptSpy
|
|
263
|
+
.mockResolvedValueOnce({ confirmAction: true })
|
|
264
|
+
.mockResolvedValueOnce({ selectedLlmProviders: ["openai"] })
|
|
265
|
+
.mockResolvedValueOnce({ openai: "API_KEY_OPENAI" });
|
|
266
|
+
cleanDatabaseSpy.mockRejectedValue(new Error("Database error"));
|
|
267
|
+
const optionsWithResetDb: InitActionOptions = { ...defaultOptions, resetDb: true };
|
|
268
|
+
await initAction.execute(optionsWithResetDb);
|
|
269
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith("An error occurred during initialization.", new Error("Database error"));
|
|
516
270
|
});
|
|
517
271
|
|
|
518
|
-
|
|
272
|
+
test("fails if openFrontend throws an error", async () => {
|
|
273
|
+
inquirerPromptSpy
|
|
274
|
+
.mockResolvedValueOnce({ confirmAction: true })
|
|
275
|
+
.mockResolvedValueOnce({ selectedLlmProviders: ["openai"] })
|
|
276
|
+
.mockResolvedValueOnce({ openai: "API_KEY_OPENAI" });
|
|
277
|
+
openFrontendSpy.mockRejectedValue(new Error("Frontend error"));
|
|
278
|
+
await initAction.execute(defaultOptions);
|
|
279
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith("An error occurred during initialization.", new Error("Frontend error"));
|
|
280
|
+
});
|
|
519
281
|
|
|
520
|
-
|
|
282
|
+
test("catches and logs unexpected errors", async () => {
|
|
283
|
+
inquirerPromptSpy.mockRejectedValueOnce(new Error("Unexpected prompt error"));
|
|
284
|
+
await initAction.execute(defaultOptions);
|
|
285
|
+
expect((initAction as any).failSpinner).toHaveBeenCalledWith("An error occurred during initialization.", new Error("Unexpected prompt error"));
|
|
286
|
+
});
|
|
521
287
|
});
|
|
522
|
-
|
|
523
288
|
});
|