genlayer 0.5.0 → 0.5.1-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/.env.example +71 -0
- package/CHANGELOG.md +7 -0
- package/dist/index.js +327 -415
- package/docker-compose.yml +144 -0
- package/package.json +3 -2
- package/scripts/postinstall.js +18 -0
- package/src/commands/general/index.ts +0 -4
- package/src/commands/general/init.ts +4 -43
- package/src/commands/general/start.ts +2 -16
- package/src/lib/config/simulator.ts +5 -6
- package/src/lib/interfaces/ISimulatorService.ts +1 -8
- package/src/lib/services/simulator.ts +48 -90
- package/tests/actions/init.test.ts +25 -84
- package/tests/actions/start.test.ts +1 -17
- package/tests/commands/init.test.ts +0 -17
- package/tests/commands/up.test.ts +1 -13
- package/tests/services/simulator.test.ts +111 -65
- package/vitest.config.ts +1 -1
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
version: "3.8"
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
frontend:
|
|
5
|
+
image: yeagerai/simulator-frontend:latest
|
|
6
|
+
ports:
|
|
7
|
+
- "${FRONTEND_PORT:-8080}:8080"
|
|
8
|
+
environment:
|
|
9
|
+
- VITE_*
|
|
10
|
+
volumes:
|
|
11
|
+
- ./.env:/app/.env
|
|
12
|
+
depends_on:
|
|
13
|
+
jsonrpc:
|
|
14
|
+
condition: service_healthy
|
|
15
|
+
expose:
|
|
16
|
+
- "${FRONTEND_PORT:-8080}"
|
|
17
|
+
restart: always
|
|
18
|
+
security_opt:
|
|
19
|
+
- "no-new-privileges=true"
|
|
20
|
+
logging:
|
|
21
|
+
driver: "json-file"
|
|
22
|
+
options:
|
|
23
|
+
max-size: "10m"
|
|
24
|
+
max-file: "3"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
jsonrpc:
|
|
28
|
+
image: yeagerai/simulator-jsonrpc:latest
|
|
29
|
+
environment:
|
|
30
|
+
- FLASK_SERVER_PORT=${RPCPORT:-5000}
|
|
31
|
+
- PYTHONUNBUFFERED=1
|
|
32
|
+
- RPCDEBUGPORT=${RPCDEBUGPORT:-5001}
|
|
33
|
+
- WEBREQUESTPORT=${WEBREQUESTPORT:-5002}
|
|
34
|
+
- WEBREQUESTHOST=${WEBREQUESTHOST:-localhost}
|
|
35
|
+
- WEBREQUESTPROTOCOL=${WEBREQUESTPROTOCOL:-http}
|
|
36
|
+
ports:
|
|
37
|
+
- "${RPCPORT:-5000}:${RPCPORT:-5000}"
|
|
38
|
+
- "${RPCDEBUGPORT:-5001}:${RPCDEBUGPORT:-5001}"
|
|
39
|
+
volumes:
|
|
40
|
+
- ./.env:/app/.env
|
|
41
|
+
healthcheck:
|
|
42
|
+
test: [ "CMD", "python", "backend/healthcheck.py", "--port", "${RPCPORT}" ]
|
|
43
|
+
interval: 30s
|
|
44
|
+
timeout: 10s
|
|
45
|
+
retries: 3
|
|
46
|
+
start_period: 30s
|
|
47
|
+
depends_on:
|
|
48
|
+
database-migration:
|
|
49
|
+
condition: service_completed_successfully
|
|
50
|
+
webrequest:
|
|
51
|
+
condition: service_healthy
|
|
52
|
+
expose:
|
|
53
|
+
- "${RPCPORT:-5000}"
|
|
54
|
+
restart: always
|
|
55
|
+
security_opt:
|
|
56
|
+
- "no-new-privileges=true"
|
|
57
|
+
logging:
|
|
58
|
+
driver: "json-file"
|
|
59
|
+
options:
|
|
60
|
+
max-size: "10m"
|
|
61
|
+
max-file: "3"
|
|
62
|
+
deploy:
|
|
63
|
+
replicas: ${JSONRPC_REPLICAS:-1}
|
|
64
|
+
|
|
65
|
+
webrequest:
|
|
66
|
+
image: yeagerai/simulator-webrequest:latest
|
|
67
|
+
shm_size: 2gb
|
|
68
|
+
environment:
|
|
69
|
+
- FLASK_SERVER_PORT=${WEBREQUESTPORT:-5002}
|
|
70
|
+
- WEBREQUESTSELENIUMPORT=${WEBREQUESTSELENIUMPORT:-4444}
|
|
71
|
+
- PYTHONUNBUFFERED=1
|
|
72
|
+
- WEBREQUESTPORT=${WEBREQUESTPORT}
|
|
73
|
+
- WEBREQUESTHOST=${WEBREQUESTHOST}
|
|
74
|
+
- WEBREQUESTPROTOCOL=${WEBREQUESTPROTOCOL}
|
|
75
|
+
expose:
|
|
76
|
+
- "${WEBREQUESTPORT:-5002}:${WEBREQUESTPORT:-5002}"
|
|
77
|
+
- "${WEBREQUESTSELENIUMPORT:-4444}:${WEBREQUESTSELENIUMPORT:-4444}"
|
|
78
|
+
volumes:
|
|
79
|
+
- ./.env:/app/webrequest/.env
|
|
80
|
+
depends_on:
|
|
81
|
+
ollama:
|
|
82
|
+
condition: service_started
|
|
83
|
+
restart: always
|
|
84
|
+
security_opt:
|
|
85
|
+
- "no-new-privileges=true"
|
|
86
|
+
logging:
|
|
87
|
+
driver: "json-file"
|
|
88
|
+
options:
|
|
89
|
+
max-size: "10m"
|
|
90
|
+
max-file: "3"
|
|
91
|
+
|
|
92
|
+
ollama:
|
|
93
|
+
image: ollama/ollama:0.3.11
|
|
94
|
+
ports:
|
|
95
|
+
- 11434:11434
|
|
96
|
+
container_name: ollama
|
|
97
|
+
tty: true
|
|
98
|
+
restart: always
|
|
99
|
+
security_opt:
|
|
100
|
+
- "no-new-privileges=true"
|
|
101
|
+
logging:
|
|
102
|
+
driver: "json-file"
|
|
103
|
+
options:
|
|
104
|
+
max-size: "10m"
|
|
105
|
+
max-file: "3"
|
|
106
|
+
|
|
107
|
+
postgres:
|
|
108
|
+
image: postgres:16-alpine
|
|
109
|
+
ports:
|
|
110
|
+
- "${DBPORT:-5432}:5432"
|
|
111
|
+
environment:
|
|
112
|
+
- POSTGRES_USER=${DBUSER:-postgres}
|
|
113
|
+
- POSTGRES_PASSWORD=${DBPASSWORD:-postgres}
|
|
114
|
+
- POSTGRES_DB=${DBNAME:-simulator_db}
|
|
115
|
+
healthcheck:
|
|
116
|
+
test: pg_isready -U ${DBUSER:-postgres} -d ${DBNAME:-simulator_db}
|
|
117
|
+
interval: 10s
|
|
118
|
+
timeout: 3s
|
|
119
|
+
retries: 3
|
|
120
|
+
restart: always
|
|
121
|
+
security_opt:
|
|
122
|
+
- "no-new-privileges=true"
|
|
123
|
+
logging:
|
|
124
|
+
driver: "json-file"
|
|
125
|
+
options:
|
|
126
|
+
max-size: "10m"
|
|
127
|
+
max-file: "3"
|
|
128
|
+
|
|
129
|
+
# Uncomment the following lines if you want your DB to persist
|
|
130
|
+
# volumes:
|
|
131
|
+
# - "./data/postgres:/var/lib/postgresql/data"
|
|
132
|
+
|
|
133
|
+
database-migration:
|
|
134
|
+
image: yeagerai/simulator-database-migration:latest
|
|
135
|
+
environment:
|
|
136
|
+
- DB_URL=postgresql://${DBUSER:-postgres}:${DBPASSWORD:-postgres}@postgres/${DBNAME:-simulator_db}
|
|
137
|
+
- WEBREQUESTPORT=${WEBREQUESTPORT:-5002}
|
|
138
|
+
- WEBREQUESTHOST=${WEBREQUESTHOST:-localhost}
|
|
139
|
+
- WEBREQUESTPROTOCOL=${WEBREQUESTPROTOCOL:-http}
|
|
140
|
+
depends_on:
|
|
141
|
+
postgres:
|
|
142
|
+
condition: service_healthy
|
|
143
|
+
webrequest:
|
|
144
|
+
condition: service_healthy
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genlayer",
|
|
3
|
-
"version": "0.5.0",
|
|
3
|
+
"version": "0.5.1-beta.0",
|
|
4
4
|
"description": "GenLayer Command Line Tool",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"dev": "cross-env NODE_ENV=development node esbuild.config.js",
|
|
14
14
|
"build": "cross-env NODE_ENV=production node esbuild.config.js",
|
|
15
15
|
"release": "release-it --ci",
|
|
16
|
-
"release-beta": "release-it --ci --preRelease=beta"
|
|
16
|
+
"release-beta": "release-it --ci --preRelease=beta",
|
|
17
|
+
"postinstall": "node ./scripts/postinstall.js"
|
|
17
18
|
},
|
|
18
19
|
"repository": {
|
|
19
20
|
"type": "git",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const envExamplePath = path.resolve(__dirname, '../.env.example');
|
|
7
|
+
const envPath = path.resolve(__dirname, '../.env');
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
if (fs.existsSync(envPath)) {
|
|
11
|
+
console.log(`⚠️ .env file already exists. Skipping creation.`);
|
|
12
|
+
} else {
|
|
13
|
+
fs.copyFileSync(envExamplePath, envPath);
|
|
14
|
+
console.log(`✅ .env file created successfully from .env.example.`);
|
|
15
|
+
}
|
|
16
|
+
} catch (error) {
|
|
17
|
+
console.error(`❌ Error during post-install script: ${error.message}`);
|
|
18
|
+
}
|
|
@@ -10,8 +10,6 @@ export function initializeGeneralCommands(program: Command) {
|
|
|
10
10
|
.command("init")
|
|
11
11
|
.description("Initialize the GenLayer Environment")
|
|
12
12
|
.option("--numValidators <numValidators>", "Number of validators", "5")
|
|
13
|
-
.option("--branch <branch>", "Branch", "main")
|
|
14
|
-
.option("--location <folder>", "Location where it will be installed", process.cwd())
|
|
15
13
|
.option("--headless", "Headless mode", false)
|
|
16
14
|
.option("--reset-db", "Reset Database", false)
|
|
17
15
|
.action((options: InitActionOptions) => initAction(options, simulatorService));
|
|
@@ -21,8 +19,6 @@ export function initializeGeneralCommands(program: Command) {
|
|
|
21
19
|
.description("Starts GenLayer's simulator")
|
|
22
20
|
.option("--reset-validators", "Remove all current validators and create new random ones", false)
|
|
23
21
|
.option("--numValidators <numValidators>", "Number of validators", "5")
|
|
24
|
-
.option("--branch <branch>", "Branch", "main")
|
|
25
|
-
.option("--location <folder>", "Location where it will be installed", process.cwd())
|
|
26
22
|
.option("--headless", "Headless mode", false)
|
|
27
23
|
.option("--reset-db", "Reset Database", false)
|
|
28
24
|
.action((options: StartActionOptions) => startAction(options, simulatorService));
|
|
@@ -4,19 +4,12 @@ import {ISimulatorService} from "../../lib/interfaces/ISimulatorService";
|
|
|
4
4
|
import {AI_PROVIDERS_CONFIG, AiProviders} from "../../lib/config/simulator";
|
|
5
5
|
export interface InitActionOptions {
|
|
6
6
|
numValidators: number;
|
|
7
|
-
branch: string;
|
|
8
|
-
location: string;
|
|
9
7
|
headless: boolean;
|
|
10
8
|
resetDb: boolean;
|
|
11
9
|
}
|
|
12
10
|
|
|
13
|
-
function getRequirementsErrorMessage({
|
|
14
|
-
|
|
15
|
-
return "Git and Docker are not installed. Please install them and try again.\n";
|
|
16
|
-
}
|
|
17
|
-
if (!git) {
|
|
18
|
-
return "Git is not installed. Please install Git and try again.\n";
|
|
19
|
-
}
|
|
11
|
+
function getRequirementsErrorMessage({docker}: Record<string, boolean>): string {
|
|
12
|
+
|
|
20
13
|
if (!docker) {
|
|
21
14
|
return "Docker is not installed. Please install Docker and try again.\n";
|
|
22
15
|
}
|
|
@@ -39,7 +32,6 @@ function getVersionErrorMessage({docker, node}: Record<string, string>): string
|
|
|
39
32
|
}
|
|
40
33
|
|
|
41
34
|
export async function initAction(options: InitActionOptions, simulatorService: ISimulatorService) {
|
|
42
|
-
simulatorService.setSimulatorLocation(options.location);
|
|
43
35
|
simulatorService.setComposeOptions(options.headless);
|
|
44
36
|
|
|
45
37
|
await simulatorService.checkCliVersion();
|
|
@@ -99,33 +91,6 @@ export async function initAction(options: InitActionOptions, simulatorService: I
|
|
|
99
91
|
return;
|
|
100
92
|
}
|
|
101
93
|
|
|
102
|
-
// Ask for confirmation on downloading the GenLayer Simulator from GitHub
|
|
103
|
-
const answers = await inquirer.prompt([
|
|
104
|
-
{
|
|
105
|
-
type: "confirm",
|
|
106
|
-
name: "confirmDownload",
|
|
107
|
-
message: `This action is going to download the GenLayer Simulator from GitHub (branch ${options.branch}) into "${simulatorService.getSimulatorLocation()}". Do you want to continue?`,
|
|
108
|
-
default: true,
|
|
109
|
-
},
|
|
110
|
-
]);
|
|
111
|
-
|
|
112
|
-
if (!answers.confirmDownload) {
|
|
113
|
-
console.log("Aborted!");
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Download the GenLayer Simulator from GitHub
|
|
118
|
-
console.log(`Downloading GenLayer Simulator from GitHub...`);
|
|
119
|
-
try {
|
|
120
|
-
const {wasInstalled} = await simulatorService.downloadSimulator(options.branch);
|
|
121
|
-
if (wasInstalled) {
|
|
122
|
-
await simulatorService.updateSimulator(options.branch);
|
|
123
|
-
}
|
|
124
|
-
} catch (error) {
|
|
125
|
-
console.error(error);
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
94
|
// Check LLM configuration
|
|
130
95
|
const questions = [
|
|
131
96
|
{
|
|
@@ -173,12 +138,8 @@ export async function initAction(options: InitActionOptions, simulatorService: I
|
|
|
173
138
|
}
|
|
174
139
|
|
|
175
140
|
console.log("Configuring GenLayer Simulator environment...");
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
} catch (error) {
|
|
179
|
-
console.error(error);
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
141
|
+
simulatorService.addConfigToEnvFile(aiProvidersEnvVars);
|
|
142
|
+
|
|
182
143
|
|
|
183
144
|
// Run the GenLayer Simulator
|
|
184
145
|
console.log("Running the GenLayer Simulator...");
|
|
@@ -5,17 +5,14 @@ import {ISimulatorService} from "../../lib/interfaces/ISimulatorService";
|
|
|
5
5
|
export interface StartActionOptions {
|
|
6
6
|
resetValidators: boolean;
|
|
7
7
|
numValidators: number;
|
|
8
|
-
branch: string;
|
|
9
|
-
location: string;
|
|
10
8
|
headless: boolean;
|
|
11
9
|
resetDb: boolean
|
|
12
10
|
}
|
|
13
11
|
|
|
14
12
|
export async function startAction(options: StartActionOptions, simulatorService: ISimulatorService) {
|
|
15
|
-
const {resetValidators, numValidators,
|
|
16
|
-
|
|
13
|
+
const {resetValidators, numValidators, headless, resetDb} = options;
|
|
14
|
+
|
|
17
15
|
simulatorService.setComposeOptions(headless);
|
|
18
|
-
simulatorService.setSimulatorLocation(location);
|
|
19
16
|
|
|
20
17
|
await simulatorService.checkCliVersion();
|
|
21
18
|
|
|
@@ -25,17 +22,6 @@ export async function startAction(options: StartActionOptions, simulatorService:
|
|
|
25
22
|
|
|
26
23
|
console.log(`Starting GenLayer simulator ${restartValidatorsHintText}`);
|
|
27
24
|
|
|
28
|
-
// Update the simulator to the latest version
|
|
29
|
-
console.log(`Updating GenLayer Simulator...`);
|
|
30
|
-
try {
|
|
31
|
-
await simulatorService.updateSimulator(branch);
|
|
32
|
-
} catch (error) {
|
|
33
|
-
console.error(error);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Run the GenLayer Simulator
|
|
38
|
-
console.log("Running the GenLayer Simulator...");
|
|
39
25
|
try {
|
|
40
26
|
await simulatorService.runSimulator();
|
|
41
27
|
} catch (error) {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
export const DEFAULT_JSON_RPC_URL = "http://localhost:4000/api";
|
|
2
|
-
export const
|
|
3
|
-
export const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
linux: `nohup bash -c 'cd ${simulatorLocation} && docker compose build && docker compose up -d ${options}'`,
|
|
2
|
+
export const DOCKER_IMAGES_AND_CONTAINERS_NAME_PREFIX = "/genlayer-cli-";
|
|
3
|
+
export const DEFAULT_RUN_SIMULATOR_COMMAND = (location: string, options: string) => ({
|
|
4
|
+
darwin: `osascript -e 'tell application "Terminal" to do script "cd ${location} && docker compose build && docker compose up ${options}"'`,
|
|
5
|
+
win32: `start cmd.exe /c "cd /d ${location} && docker compose build && docker compose up && pause ${options}"`,
|
|
6
|
+
linux: `nohup bash -c 'cd ${location} && docker compose build && docker compose up -d ${options}'`,
|
|
8
7
|
});
|
|
9
8
|
export const DEFAULT_RUN_DOCKER_COMMAND = {
|
|
10
9
|
darwin: "open -a Docker",
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import {AiProviders} from "../config/simulator";
|
|
2
2
|
|
|
3
3
|
export interface ISimulatorService {
|
|
4
|
-
setSimulatorLocation(location: string): void;
|
|
5
|
-
getSimulatorLocation(): string;
|
|
6
4
|
setComposeOptions(headless: boolean): void;
|
|
7
5
|
getComposeOptions(): string;
|
|
8
6
|
checkInstallRequirements(): Promise<Record<string, boolean>>;
|
|
9
7
|
checkVersionRequirements(): Promise<Record<string, string>>;
|
|
10
|
-
downloadSimulator(branch?: string): Promise<DownloadSimulatorResultType>;
|
|
11
|
-
updateSimulator(branch?: string): Promise<boolean>;
|
|
12
8
|
pullOllamaModel(): Promise<boolean>;
|
|
13
|
-
configSimulator(newConfig: Record<string, string>): Promise<boolean>;
|
|
14
9
|
runSimulator(): Promise<{stdout: string; stderr: string}>;
|
|
15
10
|
waitForSimulatorToBeReady(retries?: number): Promise<WaitForSimulatorToBeReadyResultType>;
|
|
16
11
|
createRandomValidators(numValidators: number, llmProviders: AiProviders[]): Promise<any>;
|
|
@@ -22,11 +17,9 @@ export interface ISimulatorService {
|
|
|
22
17
|
resetDockerImages(): Promise<boolean>;
|
|
23
18
|
checkCliVersion(): Promise<void>;
|
|
24
19
|
cleanDatabase(): Promise<boolean>;
|
|
20
|
+
addConfigToEnvFile(newConfig: Record<string, string>): void;
|
|
25
21
|
}
|
|
26
22
|
|
|
27
|
-
export type DownloadSimulatorResultType = {
|
|
28
|
-
wasInstalled: boolean;
|
|
29
|
-
};
|
|
30
23
|
|
|
31
24
|
export type WaitForSimulatorToBeReadyResultType = {
|
|
32
25
|
initialized: boolean;
|
|
@@ -8,7 +8,6 @@ import pkg from '../../../package.json'
|
|
|
8
8
|
|
|
9
9
|
import {rpcClient} from "../clients/jsonRpcClient";
|
|
10
10
|
import {
|
|
11
|
-
DEFAULT_REPO_GH_URL,
|
|
12
11
|
DOCKER_IMAGES_AND_CONTAINERS_NAME_PREFIX,
|
|
13
12
|
DEFAULT_RUN_SIMULATOR_COMMAND,
|
|
14
13
|
DEFAULT_RUN_DOCKER_COMMAND,
|
|
@@ -28,7 +27,6 @@ import {MissingRequirementError} from "../errors/missingRequirement";
|
|
|
28
27
|
|
|
29
28
|
import {
|
|
30
29
|
ISimulatorService,
|
|
31
|
-
DownloadSimulatorResultType,
|
|
32
30
|
WaitForSimulatorToBeReadyResultType,
|
|
33
31
|
} from "../interfaces/ISimulatorService";
|
|
34
32
|
import {VersionRequiredError} from "../errors/versionRequired";
|
|
@@ -41,39 +39,16 @@ function sleep(millliseconds: number): Promise<void> {
|
|
|
41
39
|
export class SimulatorService implements ISimulatorService {
|
|
42
40
|
private composeOptions: string
|
|
43
41
|
private docker: Docker;
|
|
44
|
-
public
|
|
42
|
+
public location: string;
|
|
45
43
|
|
|
46
44
|
constructor() {
|
|
47
|
-
this.
|
|
45
|
+
this.location = path.resolve(__dirname, '..');
|
|
48
46
|
this.composeOptions = "";
|
|
49
47
|
this.docker = new Docker();
|
|
50
48
|
}
|
|
51
49
|
|
|
52
|
-
public
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
public getSimulatorLocation(): string {
|
|
57
|
-
return this.simulatorLocation;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
public setComposeOptions(headless: boolean): void {
|
|
61
|
-
this.composeOptions = headless ? '--scale frontend=0' : '';
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
public getComposeOptions(): string {
|
|
65
|
-
return this.composeOptions;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
private readEnvConfigValue(key: string): string {
|
|
69
|
-
const envFilePath = path.join(this.simulatorLocation, ".env");
|
|
70
|
-
// Transform the config string to object
|
|
71
|
-
const envConfig = dotenv.parse(fs.readFileSync(envFilePath, "utf8"));
|
|
72
|
-
return envConfig[key];
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
private addConfigToEnvFile(newConfig: Record<string, string>): void {
|
|
76
|
-
const envFilePath = path.join(this.simulatorLocation, ".env");
|
|
50
|
+
public addConfigToEnvFile(newConfig: Record<string, string>): void {
|
|
51
|
+
const envFilePath = path.join(this.location, ".env");
|
|
77
52
|
|
|
78
53
|
// Create a backup of the original .env file
|
|
79
54
|
fs.writeFileSync(`${envFilePath}.bak`, fs.readFileSync(envFilePath));
|
|
@@ -95,6 +70,21 @@ export class SimulatorService implements ISimulatorService {
|
|
|
95
70
|
fs.writeFileSync(envFilePath, updatedConfig);
|
|
96
71
|
}
|
|
97
72
|
|
|
73
|
+
public setComposeOptions(headless: boolean): void {
|
|
74
|
+
this.composeOptions = headless ? '--scale frontend=0' : '';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public getComposeOptions(): string {
|
|
78
|
+
return this.composeOptions;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private readEnvConfigValue(key: string): string {
|
|
82
|
+
const envFilePath = path.join(this.location, ".env");
|
|
83
|
+
// Transform the config string to object
|
|
84
|
+
const envConfig = dotenv.parse(fs.readFileSync(envFilePath, "utf8"));
|
|
85
|
+
return envConfig[key];
|
|
86
|
+
}
|
|
87
|
+
|
|
98
88
|
public async checkCliVersion(): Promise<void> {
|
|
99
89
|
const update = await updateCheck(pkg);
|
|
100
90
|
if (update && update.latest !== pkg.version) {
|
|
@@ -104,19 +94,9 @@ export class SimulatorService implements ISimulatorService {
|
|
|
104
94
|
|
|
105
95
|
public async checkInstallRequirements(): Promise<Record<string, boolean>> {
|
|
106
96
|
const requirementsInstalled = {
|
|
107
|
-
git: false,
|
|
108
97
|
docker: false,
|
|
109
98
|
};
|
|
110
99
|
|
|
111
|
-
try {
|
|
112
|
-
await checkCommand("git --version", "git");
|
|
113
|
-
requirementsInstalled.git = true;
|
|
114
|
-
} catch (error) {
|
|
115
|
-
if (!(error instanceof MissingRequirementError)) {
|
|
116
|
-
throw error;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
100
|
try {
|
|
121
101
|
await checkCommand("docker --version", "docker");
|
|
122
102
|
requirementsInstalled.docker = true;
|
|
@@ -126,7 +106,6 @@ export class SimulatorService implements ISimulatorService {
|
|
|
126
106
|
}
|
|
127
107
|
}
|
|
128
108
|
|
|
129
|
-
|
|
130
109
|
if (requirementsInstalled.docker) {
|
|
131
110
|
try {
|
|
132
111
|
await this.docker.ping()
|
|
@@ -173,62 +152,41 @@ export class SimulatorService implements ISimulatorService {
|
|
|
173
152
|
}
|
|
174
153
|
}
|
|
175
154
|
|
|
176
|
-
public async
|
|
155
|
+
public async pullOllamaModel(): Promise<boolean> {
|
|
177
156
|
try {
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
|
|
157
|
+
const ollamaContainer = this.docker.getContainer("ollama");
|
|
158
|
+
|
|
159
|
+
// Create the exec instance
|
|
160
|
+
const exec = await ollamaContainer.exec({
|
|
161
|
+
Cmd: ["ollama", "pull", "llama3"],
|
|
162
|
+
AttachStdout: true,
|
|
163
|
+
AttachStderr: true,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Start the exec instance and attach to the stream
|
|
167
|
+
const stream = await exec.start({ Detach: false, Tty: false });
|
|
168
|
+
|
|
169
|
+
// Collect and log the output
|
|
170
|
+
stream.on("data", (chunk) => {
|
|
171
|
+
console.log(chunk.toString());
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
await new Promise<void>((resolve, reject) => {
|
|
175
|
+
stream.on("end", resolve);
|
|
176
|
+
stream.on("error", reject);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
console.log("Command executed successfully");
|
|
180
|
+
return true;
|
|
181
|
+
} catch (error) {
|
|
182
|
+
console.error("Error executing ollama pull llama3:", error);
|
|
183
|
+
return false;
|
|
187
184
|
}
|
|
188
|
-
return {wasInstalled: false};
|
|
189
185
|
}
|
|
190
186
|
|
|
191
|
-
public async updateSimulator(branch: string = "main"): Promise<boolean> {
|
|
192
|
-
const gitCleanCommand = `git -C "${this.simulatorLocation}" clean -f`;
|
|
193
|
-
const cleanCmdsByPlatform = {darwin: gitCleanCommand, win32: gitCleanCommand, linux: gitCleanCommand};
|
|
194
|
-
await executeCommand(cleanCmdsByPlatform, "git");
|
|
195
|
-
|
|
196
|
-
const gitFetchCommand = `git -C "${this.simulatorLocation}" fetch`;
|
|
197
|
-
const fetchCmdsByPlatform = {darwin: gitFetchCommand, win32: gitFetchCommand, linux: gitFetchCommand};
|
|
198
|
-
await executeCommand(fetchCmdsByPlatform, "git");
|
|
199
|
-
|
|
200
|
-
const gitCheckoutCommand = `git -C "${this.simulatorLocation}" checkout ${branch}`;
|
|
201
|
-
const checkoutCmdsByPlatform = {
|
|
202
|
-
darwin: gitCheckoutCommand,
|
|
203
|
-
win32: gitCheckoutCommand,
|
|
204
|
-
linux: gitCheckoutCommand,
|
|
205
|
-
};
|
|
206
|
-
await executeCommand(checkoutCmdsByPlatform, "git");
|
|
207
|
-
|
|
208
|
-
const gitPullCommand = `git -C "${this.simulatorLocation}" pull`;
|
|
209
|
-
const pullCmdsByPlatform = {darwin: gitPullCommand, win32: gitPullCommand, linux: gitPullCommand};
|
|
210
|
-
await executeCommand(pullCmdsByPlatform, "git");
|
|
211
|
-
return true;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
public async pullOllamaModel(): Promise<boolean> {
|
|
215
|
-
const ollamaContainer = this.docker.getContainer("ollama");
|
|
216
|
-
await ollamaContainer.exec({
|
|
217
|
-
Cmd: ["ollama", "pull", "llama3"],
|
|
218
|
-
});
|
|
219
|
-
return true;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
public async configSimulator(newConfig: Record<string, string>): Promise<boolean> {
|
|
223
|
-
const envExample = path.join(this.simulatorLocation, ".env.example");
|
|
224
|
-
const envFilePath = path.join(this.simulatorLocation, ".env");
|
|
225
|
-
fs.copyFileSync(envExample, envFilePath);
|
|
226
|
-
this.addConfigToEnvFile(newConfig);
|
|
227
|
-
return true;
|
|
228
|
-
}
|
|
229
187
|
|
|
230
188
|
public runSimulator(): Promise<{stdout: string; stderr: string}> {
|
|
231
|
-
const commandsByPlatform = DEFAULT_RUN_SIMULATOR_COMMAND(this.
|
|
189
|
+
const commandsByPlatform = DEFAULT_RUN_SIMULATOR_COMMAND(this.location, this.getComposeOptions());
|
|
232
190
|
return executeCommand(commandsByPlatform);
|
|
233
191
|
}
|
|
234
192
|
|