genlayer 0.4.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 +14 -0
- package/dist/index.js +1372 -412
- package/docker-compose.yml +144 -0
- package/package.json +4 -2
- package/scripts/postinstall.js +18 -0
- package/src/commands/general/index.ts +0 -4
- package/src/commands/general/init.ts +6 -43
- package/src/commands/general/start.ts +3 -16
- package/src/lib/config/simulator.ts +5 -6
- package/src/lib/interfaces/ISimulatorService.ts +2 -8
- package/src/lib/services/simulator.ts +57 -90
- package/tests/actions/init.test.ts +25 -84
- package/tests/actions/start.test.ts +2 -17
- package/tests/commands/init.test.ts +0 -17
- package/tests/commands/up.test.ts +1 -13
- package/tests/services/simulator.test.ts +159 -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.
|
|
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",
|
|
@@ -61,6 +62,7 @@
|
|
|
61
62
|
"inquirer": "^9.2.19",
|
|
62
63
|
"node-fetch": "^2.7.0",
|
|
63
64
|
"open": "^10.1.0",
|
|
65
|
+
"update-check": "^1.5.4",
|
|
64
66
|
"uuid": "^9.0.1",
|
|
65
67
|
"vitest": "^2.1.4"
|
|
66
68
|
}
|
|
@@ -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,9 +32,10 @@ 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
|
|
|
37
|
+
await simulatorService.checkCliVersion();
|
|
38
|
+
|
|
45
39
|
// Check if requirements are installed
|
|
46
40
|
try {
|
|
47
41
|
const requirementsInstalled = await simulatorService.checkInstallRequirements();
|
|
@@ -97,33 +91,6 @@ export async function initAction(options: InitActionOptions, simulatorService: I
|
|
|
97
91
|
return;
|
|
98
92
|
}
|
|
99
93
|
|
|
100
|
-
// Ask for confirmation on downloading the GenLayer Simulator from GitHub
|
|
101
|
-
const answers = await inquirer.prompt([
|
|
102
|
-
{
|
|
103
|
-
type: "confirm",
|
|
104
|
-
name: "confirmDownload",
|
|
105
|
-
message: `This action is going to download the GenLayer Simulator from GitHub (branch ${options.branch}) into "${simulatorService.getSimulatorLocation()}". Do you want to continue?`,
|
|
106
|
-
default: true,
|
|
107
|
-
},
|
|
108
|
-
]);
|
|
109
|
-
|
|
110
|
-
if (!answers.confirmDownload) {
|
|
111
|
-
console.log("Aborted!");
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Download the GenLayer Simulator from GitHub
|
|
116
|
-
console.log(`Downloading GenLayer Simulator from GitHub...`);
|
|
117
|
-
try {
|
|
118
|
-
const {wasInstalled} = await simulatorService.downloadSimulator(options.branch);
|
|
119
|
-
if (wasInstalled) {
|
|
120
|
-
await simulatorService.updateSimulator(options.branch);
|
|
121
|
-
}
|
|
122
|
-
} catch (error) {
|
|
123
|
-
console.error(error);
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
94
|
// Check LLM configuration
|
|
128
95
|
const questions = [
|
|
129
96
|
{
|
|
@@ -171,12 +138,8 @@ export async function initAction(options: InitActionOptions, simulatorService: I
|
|
|
171
138
|
}
|
|
172
139
|
|
|
173
140
|
console.log("Configuring GenLayer Simulator environment...");
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
} catch (error) {
|
|
177
|
-
console.error(error);
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
141
|
+
simulatorService.addConfigToEnvFile(aiProvidersEnvVars);
|
|
142
|
+
|
|
180
143
|
|
|
181
144
|
// Run the GenLayer Simulator
|
|
182
145
|
console.log("Running the GenLayer Simulator...");
|
|
@@ -5,18 +5,16 @@ 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
|
|
|
17
|
+
await simulatorService.checkCliVersion();
|
|
20
18
|
|
|
21
19
|
const restartValidatorsHintText = resetValidators
|
|
22
20
|
? `creating new ${numValidators} random validators`
|
|
@@ -24,17 +22,6 @@ export async function startAction(options: StartActionOptions, simulatorService:
|
|
|
24
22
|
|
|
25
23
|
console.log(`Starting GenLayer simulator ${restartValidatorsHintText}`);
|
|
26
24
|
|
|
27
|
-
// Update the simulator to the latest version
|
|
28
|
-
console.log(`Updating GenLayer Simulator...`);
|
|
29
|
-
try {
|
|
30
|
-
await simulatorService.updateSimulator(branch);
|
|
31
|
-
} catch (error) {
|
|
32
|
-
console.error(error);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Run the GenLayer Simulator
|
|
37
|
-
console.log("Running the GenLayer Simulator...");
|
|
38
25
|
try {
|
|
39
26
|
await simulatorService.runSimulator();
|
|
40
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>;
|
|
@@ -20,12 +15,11 @@ export interface ISimulatorService {
|
|
|
20
15
|
openFrontend(): Promise<boolean>;
|
|
21
16
|
resetDockerContainers(): Promise<boolean>;
|
|
22
17
|
resetDockerImages(): Promise<boolean>;
|
|
18
|
+
checkCliVersion(): Promise<void>;
|
|
23
19
|
cleanDatabase(): Promise<boolean>;
|
|
20
|
+
addConfigToEnvFile(newConfig: Record<string, string>): void;
|
|
24
21
|
}
|
|
25
22
|
|
|
26
|
-
export type DownloadSimulatorResultType = {
|
|
27
|
-
wasInstalled: boolean;
|
|
28
|
-
};
|
|
29
23
|
|
|
30
24
|
export type WaitForSimulatorToBeReadyResultType = {
|
|
31
25
|
initialized: boolean;
|
|
@@ -3,10 +3,11 @@ import * as fs from "fs";
|
|
|
3
3
|
import * as dotenv from "dotenv";
|
|
4
4
|
import * as path from "path";
|
|
5
5
|
import * as semver from "semver";
|
|
6
|
+
import updateCheck from "update-check";
|
|
7
|
+
import pkg from '../../../package.json'
|
|
6
8
|
|
|
7
9
|
import {rpcClient} from "../clients/jsonRpcClient";
|
|
8
10
|
import {
|
|
9
|
-
DEFAULT_REPO_GH_URL,
|
|
10
11
|
DOCKER_IMAGES_AND_CONTAINERS_NAME_PREFIX,
|
|
11
12
|
DEFAULT_RUN_SIMULATOR_COMMAND,
|
|
12
13
|
DEFAULT_RUN_DOCKER_COMMAND,
|
|
@@ -26,7 +27,6 @@ import {MissingRequirementError} from "../errors/missingRequirement";
|
|
|
26
27
|
|
|
27
28
|
import {
|
|
28
29
|
ISimulatorService,
|
|
29
|
-
DownloadSimulatorResultType,
|
|
30
30
|
WaitForSimulatorToBeReadyResultType,
|
|
31
31
|
} from "../interfaces/ISimulatorService";
|
|
32
32
|
import {VersionRequiredError} from "../errors/versionRequired";
|
|
@@ -39,39 +39,16 @@ function sleep(millliseconds: number): Promise<void> {
|
|
|
39
39
|
export class SimulatorService implements ISimulatorService {
|
|
40
40
|
private composeOptions: string
|
|
41
41
|
private docker: Docker;
|
|
42
|
-
public
|
|
42
|
+
public location: string;
|
|
43
43
|
|
|
44
44
|
constructor() {
|
|
45
|
-
this.
|
|
45
|
+
this.location = path.resolve(__dirname, '..');
|
|
46
46
|
this.composeOptions = "";
|
|
47
47
|
this.docker = new Docker();
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
public
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
public getSimulatorLocation(): string {
|
|
55
|
-
return this.simulatorLocation;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
public setComposeOptions(headless: boolean): void {
|
|
59
|
-
this.composeOptions = headless ? '--scale frontend=0' : '';
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
public getComposeOptions(): string {
|
|
63
|
-
return this.composeOptions;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
private readEnvConfigValue(key: string): string {
|
|
67
|
-
const envFilePath = path.join(this.simulatorLocation, ".env");
|
|
68
|
-
// Transform the config string to object
|
|
69
|
-
const envConfig = dotenv.parse(fs.readFileSync(envFilePath, "utf8"));
|
|
70
|
-
return envConfig[key];
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
private addConfigToEnvFile(newConfig: Record<string, string>): void {
|
|
74
|
-
const envFilePath = path.join(this.simulatorLocation, ".env");
|
|
50
|
+
public addConfigToEnvFile(newConfig: Record<string, string>): void {
|
|
51
|
+
const envFilePath = path.join(this.location, ".env");
|
|
75
52
|
|
|
76
53
|
// Create a backup of the original .env file
|
|
77
54
|
fs.writeFileSync(`${envFilePath}.bak`, fs.readFileSync(envFilePath));
|
|
@@ -93,21 +70,33 @@ export class SimulatorService implements ISimulatorService {
|
|
|
93
70
|
fs.writeFileSync(envFilePath, updatedConfig);
|
|
94
71
|
}
|
|
95
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
|
+
|
|
88
|
+
public async checkCliVersion(): Promise<void> {
|
|
89
|
+
const update = await updateCheck(pkg);
|
|
90
|
+
if (update && update.latest !== pkg.version) {
|
|
91
|
+
console.warn(`\nA new version (${update.latest}) is available! You're using version ${pkg.version}.\nRun npm install -g genlayer to update\n`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
96
95
|
public async checkInstallRequirements(): Promise<Record<string, boolean>> {
|
|
97
96
|
const requirementsInstalled = {
|
|
98
|
-
git: false,
|
|
99
97
|
docker: false,
|
|
100
98
|
};
|
|
101
99
|
|
|
102
|
-
try {
|
|
103
|
-
await checkCommand("git --version", "git");
|
|
104
|
-
requirementsInstalled.git = true;
|
|
105
|
-
} catch (error) {
|
|
106
|
-
if (!(error instanceof MissingRequirementError)) {
|
|
107
|
-
throw error;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
100
|
try {
|
|
112
101
|
await checkCommand("docker --version", "docker");
|
|
113
102
|
requirementsInstalled.docker = true;
|
|
@@ -117,7 +106,6 @@ export class SimulatorService implements ISimulatorService {
|
|
|
117
106
|
}
|
|
118
107
|
}
|
|
119
108
|
|
|
120
|
-
|
|
121
109
|
if (requirementsInstalled.docker) {
|
|
122
110
|
try {
|
|
123
111
|
await this.docker.ping()
|
|
@@ -164,62 +152,41 @@ export class SimulatorService implements ISimulatorService {
|
|
|
164
152
|
}
|
|
165
153
|
}
|
|
166
154
|
|
|
167
|
-
public async
|
|
155
|
+
public async pullOllamaModel(): Promise<boolean> {
|
|
168
156
|
try {
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
|
|
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;
|
|
178
184
|
}
|
|
179
|
-
return {wasInstalled: false};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
public async updateSimulator(branch: string = "main"): Promise<boolean> {
|
|
183
|
-
const gitCleanCommand = `git -C "${this.simulatorLocation}" clean -f`;
|
|
184
|
-
const cleanCmdsByPlatform = {darwin: gitCleanCommand, win32: gitCleanCommand, linux: gitCleanCommand};
|
|
185
|
-
await executeCommand(cleanCmdsByPlatform, "git");
|
|
186
|
-
|
|
187
|
-
const gitFetchCommand = `git -C "${this.simulatorLocation}" fetch`;
|
|
188
|
-
const fetchCmdsByPlatform = {darwin: gitFetchCommand, win32: gitFetchCommand, linux: gitFetchCommand};
|
|
189
|
-
await executeCommand(fetchCmdsByPlatform, "git");
|
|
190
|
-
|
|
191
|
-
const gitCheckoutCommand = `git -C "${this.simulatorLocation}" checkout ${branch}`;
|
|
192
|
-
const checkoutCmdsByPlatform = {
|
|
193
|
-
darwin: gitCheckoutCommand,
|
|
194
|
-
win32: gitCheckoutCommand,
|
|
195
|
-
linux: gitCheckoutCommand,
|
|
196
|
-
};
|
|
197
|
-
await executeCommand(checkoutCmdsByPlatform, "git");
|
|
198
|
-
|
|
199
|
-
const gitPullCommand = `git -C "${this.simulatorLocation}" pull`;
|
|
200
|
-
const pullCmdsByPlatform = {darwin: gitPullCommand, win32: gitPullCommand, linux: gitPullCommand};
|
|
201
|
-
await executeCommand(pullCmdsByPlatform, "git");
|
|
202
|
-
return true;
|
|
203
185
|
}
|
|
204
186
|
|
|
205
|
-
public async pullOllamaModel(): Promise<boolean> {
|
|
206
|
-
const ollamaContainer = this.docker.getContainer("ollama");
|
|
207
|
-
await ollamaContainer.exec({
|
|
208
|
-
Cmd: ["ollama", "pull", "llama3"],
|
|
209
|
-
});
|
|
210
|
-
return true;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
public async configSimulator(newConfig: Record<string, string>): Promise<boolean> {
|
|
214
|
-
const envExample = path.join(this.simulatorLocation, ".env.example");
|
|
215
|
-
const envFilePath = path.join(this.simulatorLocation, ".env");
|
|
216
|
-
fs.copyFileSync(envExample, envFilePath);
|
|
217
|
-
this.addConfigToEnvFile(newConfig);
|
|
218
|
-
return true;
|
|
219
|
-
}
|
|
220
187
|
|
|
221
188
|
public runSimulator(): Promise<{stdout: string; stderr: string}> {
|
|
222
|
-
const commandsByPlatform = DEFAULT_RUN_SIMULATOR_COMMAND(this.
|
|
189
|
+
const commandsByPlatform = DEFAULT_RUN_SIMULATOR_COMMAND(this.location, this.getComposeOptions());
|
|
223
190
|
return executeCommand(commandsByPlatform);
|
|
224
191
|
}
|
|
225
192
|
|