genlayer 0.38.8 → 0.38.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/.eslintignore +2 -0
  2. package/.github/workflows/cli-docs.yml +124 -0
  3. package/.github/workflows/publish.yml +55 -0
  4. package/.github/workflows/smoke.yml +27 -0
  5. package/.github/workflows/validate-code.yml +51 -0
  6. package/.prettierignore +19 -0
  7. package/.prettierrc +12 -0
  8. package/.release-it.json +66 -0
  9. package/CHANGELOG.md +545 -0
  10. package/CLAUDE.md +55 -0
  11. package/CONTRIBUTING.md +117 -0
  12. package/dist/index.js +221 -62
  13. package/docs/api-references/_meta.json +9 -0
  14. package/docs/api-references/accounts/_meta.json +3 -0
  15. package/docs/api-references/accounts/account/create.mdx +19 -0
  16. package/docs/api-references/accounts/account/export.mdx +19 -0
  17. package/docs/api-references/accounts/account/import.mdx +22 -0
  18. package/docs/api-references/accounts/account/list.mdx +15 -0
  19. package/docs/api-references/accounts/account/lock.mdx +16 -0
  20. package/docs/api-references/accounts/account/remove.mdx +20 -0
  21. package/docs/api-references/accounts/account/send.mdx +24 -0
  22. package/docs/api-references/accounts/account/show.mdx +17 -0
  23. package/docs/api-references/accounts/account/unlock.mdx +17 -0
  24. package/docs/api-references/accounts/account/use.mdx +19 -0
  25. package/docs/api-references/accounts/account.mdx +32 -0
  26. package/docs/api-references/configuration/_meta.json +4 -0
  27. package/docs/api-references/configuration/config/get.mdx +21 -0
  28. package/docs/api-references/configuration/config/reset.mdx +21 -0
  29. package/docs/api-references/configuration/config/set.mdx +21 -0
  30. package/docs/api-references/configuration/config.mdx +25 -0
  31. package/docs/api-references/configuration/network/info.mdx +15 -0
  32. package/docs/api-references/configuration/network/list.mdx +15 -0
  33. package/docs/api-references/configuration/network/set.mdx +21 -0
  34. package/docs/api-references/configuration/network.mdx +25 -0
  35. package/docs/api-references/contracts/_meta.json +7 -0
  36. package/docs/api-references/contracts/call.mdx +21 -0
  37. package/docs/api-references/contracts/code.mdx +20 -0
  38. package/docs/api-references/contracts/deploy.mdx +17 -0
  39. package/docs/api-references/contracts/schema.mdx +20 -0
  40. package/docs/api-references/contracts/write.mdx +21 -0
  41. package/docs/api-references/environment/_meta.json +7 -0
  42. package/docs/api-references/environment/init.mdx +20 -0
  43. package/docs/api-references/environment/new.mdx +21 -0
  44. package/docs/api-references/environment/stop.mdx +15 -0
  45. package/docs/api-references/environment/up.mdx +20 -0
  46. package/docs/api-references/environment/update/ollama.mdx +16 -0
  47. package/docs/api-references/environment/update.mdx +23 -0
  48. package/docs/api-references/index.mdx +35 -0
  49. package/docs/api-references/localnet/_meta.json +3 -0
  50. package/docs/api-references/localnet/localnet/validators/count.mdx +15 -0
  51. package/docs/api-references/localnet/localnet/validators/create-random.mdx +16 -0
  52. package/docs/api-references/localnet/localnet/validators/create.mdx +19 -0
  53. package/docs/api-references/localnet/localnet/validators/delete.mdx +16 -0
  54. package/docs/api-references/localnet/localnet/validators/get.mdx +16 -0
  55. package/docs/api-references/localnet/localnet/validators/update.mdx +23 -0
  56. package/docs/api-references/localnet/localnet/validators.mdx +28 -0
  57. package/docs/api-references/localnet/localnet.mdx +23 -0
  58. package/docs/api-references/staking/_meta.json +3 -0
  59. package/docs/api-references/staking/staking/active-validators.mdx +18 -0
  60. package/docs/api-references/staking/staking/banned-validators.mdx +18 -0
  61. package/docs/api-references/staking/staking/delegation-info.mdx +25 -0
  62. package/docs/api-references/staking/staking/delegator-claim.mdx +26 -0
  63. package/docs/api-references/staking/staking/delegator-exit.mdx +26 -0
  64. package/docs/api-references/staking/staking/delegator-join.mdx +26 -0
  65. package/docs/api-references/staking/staking/epoch-info.mdx +19 -0
  66. package/docs/api-references/staking/staking/prime-all.mdx +20 -0
  67. package/docs/api-references/staking/staking/quarantined-validators.mdx +18 -0
  68. package/docs/api-references/staking/staking/set-identity.mdx +33 -0
  69. package/docs/api-references/staking/staking/set-operator.mdx +26 -0
  70. package/docs/api-references/staking/staking/validator-claim.mdx +24 -0
  71. package/docs/api-references/staking/staking/validator-deposit.mdx +25 -0
  72. package/docs/api-references/staking/staking/validator-exit.mdx +25 -0
  73. package/docs/api-references/staking/staking/validator-history.mdx +29 -0
  74. package/docs/api-references/staking/staking/validator-info.mdx +25 -0
  75. package/docs/api-references/staking/staking/validator-join.mdx +22 -0
  76. package/docs/api-references/staking/staking/validator-prime.mdx +25 -0
  77. package/docs/api-references/staking/staking/validators.mdx +19 -0
  78. package/docs/api-references/staking/staking/wizard.mdx +20 -0
  79. package/docs/api-references/staking/staking.mdx +42 -0
  80. package/docs/api-references/transactions/_meta.json +6 -0
  81. package/docs/api-references/transactions/appeal-bond.mdx +20 -0
  82. package/docs/api-references/transactions/appeal.mdx +21 -0
  83. package/docs/api-references/transactions/receipt.mdx +25 -0
  84. package/docs/api-references/transactions/trace.mdx +21 -0
  85. package/docs/delegator-guide.md +203 -0
  86. package/docs/validator-guide.md +329 -0
  87. package/esbuild.config.dev.js +17 -0
  88. package/esbuild.config.js +22 -0
  89. package/esbuild.config.prod.js +17 -0
  90. package/eslint.config.js +60 -0
  91. package/package.json +2 -11
  92. package/renovate.json +22 -0
  93. package/scripts/generate-cli-docs.mjs +68 -5
  94. package/src/commands/account/create.ts +30 -0
  95. package/src/commands/account/export.ts +106 -0
  96. package/src/commands/account/import.ts +135 -0
  97. package/src/commands/account/index.ts +129 -0
  98. package/src/commands/account/list.ts +34 -0
  99. package/src/commands/account/lock.ts +39 -0
  100. package/src/commands/account/remove.ts +30 -0
  101. package/src/commands/account/send.ts +162 -0
  102. package/src/commands/account/show.ts +74 -0
  103. package/src/commands/account/unlock.ts +56 -0
  104. package/src/commands/account/use.ts +21 -0
  105. package/src/commands/config/getSetReset.ts +51 -0
  106. package/src/commands/config/index.ts +30 -0
  107. package/src/commands/contracts/call.ts +39 -0
  108. package/src/commands/contracts/code.ts +33 -0
  109. package/src/commands/contracts/deploy.ts +161 -0
  110. package/src/commands/contracts/index.ts +150 -0
  111. package/src/commands/contracts/schema.ts +31 -0
  112. package/src/commands/contracts/write.ts +49 -0
  113. package/src/commands/general/index.ts +45 -0
  114. package/src/commands/general/init.ts +180 -0
  115. package/src/commands/general/start.ts +128 -0
  116. package/src/commands/general/stop.ts +26 -0
  117. package/src/commands/localnet/index.ts +100 -0
  118. package/src/commands/localnet/validators.ts +269 -0
  119. package/src/commands/network/index.ts +29 -0
  120. package/src/commands/network/setNetwork.ts +77 -0
  121. package/src/commands/scaffold/index.ts +16 -0
  122. package/src/commands/scaffold/new.ts +34 -0
  123. package/src/commands/staking/StakingAction.ts +279 -0
  124. package/src/commands/staking/delegatorClaim.ts +41 -0
  125. package/src/commands/staking/delegatorExit.ts +56 -0
  126. package/src/commands/staking/delegatorJoin.ts +44 -0
  127. package/src/commands/staking/index.ts +357 -0
  128. package/src/commands/staking/setIdentity.ts +78 -0
  129. package/src/commands/staking/setOperator.ts +46 -0
  130. package/src/commands/staking/stakingInfo.ts +584 -0
  131. package/src/commands/staking/validatorClaim.ts +43 -0
  132. package/src/commands/staking/validatorDeposit.ts +48 -0
  133. package/src/commands/staking/validatorExit.ts +63 -0
  134. package/src/commands/staking/validatorHistory.ts +300 -0
  135. package/src/commands/staking/validatorJoin.ts +47 -0
  136. package/src/commands/staking/validatorPrime.ts +73 -0
  137. package/src/commands/staking/wizard.ts +809 -0
  138. package/src/commands/transactions/appeal.ts +83 -0
  139. package/src/commands/transactions/index.ts +60 -0
  140. package/src/commands/transactions/receipt.ts +90 -0
  141. package/src/commands/transactions/trace.ts +42 -0
  142. package/src/commands/update/index.ts +25 -0
  143. package/src/commands/update/ollama.ts +103 -0
  144. package/src/lib/actions/BaseAction.ts +301 -0
  145. package/src/lib/clients/jsonRpcClient.ts +41 -0
  146. package/src/lib/clients/system.ts +73 -0
  147. package/src/lib/config/ConfigFileManager.ts +194 -0
  148. package/src/lib/config/KeychainManager.ts +89 -0
  149. package/src/lib/config/simulator.ts +68 -0
  150. package/src/lib/config/text.ts +2 -0
  151. package/src/lib/errors/missingRequirement.ts +9 -0
  152. package/src/lib/errors/versionRequired.ts +9 -0
  153. package/src/lib/interfaces/ISimulatorService.ts +39 -0
  154. package/src/lib/services/simulator.ts +386 -0
  155. package/src/types/node-fetch.d.ts +1 -0
  156. package/tests/actions/appeal.test.ts +141 -0
  157. package/tests/actions/call.test.ts +94 -0
  158. package/tests/actions/code.test.ts +87 -0
  159. package/tests/actions/create.test.ts +65 -0
  160. package/tests/actions/deploy.test.ts +420 -0
  161. package/tests/actions/getSetReset.test.ts +88 -0
  162. package/tests/actions/init.test.ts +483 -0
  163. package/tests/actions/lock.test.ts +86 -0
  164. package/tests/actions/new.test.ts +80 -0
  165. package/tests/actions/ollama.test.ts +193 -0
  166. package/tests/actions/receipt.test.ts +261 -0
  167. package/tests/actions/schema.test.ts +94 -0
  168. package/tests/actions/setNetwork.test.ts +161 -0
  169. package/tests/actions/staking.test.ts +280 -0
  170. package/tests/actions/start.test.ts +257 -0
  171. package/tests/actions/stop.test.ts +77 -0
  172. package/tests/actions/unlock.test.ts +139 -0
  173. package/tests/actions/validators.test.ts +750 -0
  174. package/tests/actions/write.test.ts +102 -0
  175. package/tests/commands/account.test.ts +146 -0
  176. package/tests/commands/appeal.test.ts +97 -0
  177. package/tests/commands/call.test.ts +78 -0
  178. package/tests/commands/code.test.ts +69 -0
  179. package/tests/commands/config.test.ts +54 -0
  180. package/tests/commands/deploy.test.ts +83 -0
  181. package/tests/commands/init.test.ts +101 -0
  182. package/tests/commands/localnet.test.ts +131 -0
  183. package/tests/commands/network.test.ts +60 -0
  184. package/tests/commands/new.test.ts +68 -0
  185. package/tests/commands/parseArg.test.ts +156 -0
  186. package/tests/commands/receipt.test.ts +142 -0
  187. package/tests/commands/schema.test.ts +67 -0
  188. package/tests/commands/staking.test.ts +329 -0
  189. package/tests/commands/stop.test.ts +27 -0
  190. package/tests/commands/up.test.ts +105 -0
  191. package/tests/commands/update.test.ts +45 -0
  192. package/tests/commands/write.test.ts +76 -0
  193. package/tests/index.test.ts +56 -0
  194. package/tests/libs/baseAction.test.ts +535 -0
  195. package/tests/libs/configFileManager.test.ts +118 -0
  196. package/tests/libs/jsonRpcClient.test.ts +59 -0
  197. package/tests/libs/keychainManager.test.ts +156 -0
  198. package/tests/libs/platformCommands.test.ts +78 -0
  199. package/tests/libs/system.test.ts +148 -0
  200. package/tests/services/simulator.test.ts +789 -0
  201. package/tests/smoke.test.ts +134 -0
  202. package/tests/utils.ts +13 -0
  203. package/tsconfig.json +120 -0
  204. package/vitest.config.ts +13 -0
  205. package/vitest.smoke.config.ts +17 -0
@@ -0,0 +1,83 @@
1
+ import {TransactionHash} from "genlayer-js/types";
2
+ import {parseStakingAmount, formatStakingAmount} from "genlayer-js";
3
+ import {BaseAction} from "../../lib/actions/BaseAction";
4
+
5
+ export interface AppealOptions {
6
+ rpc?: string;
7
+ bond?: string;
8
+ }
9
+
10
+ export interface AppealBondOptions {
11
+ rpc?: string;
12
+ }
13
+
14
+ export class AppealAction extends BaseAction {
15
+ constructor() {
16
+ super();
17
+ }
18
+
19
+ async appeal({
20
+ txId,
21
+ rpc,
22
+ bond,
23
+ }: {
24
+ txId: TransactionHash;
25
+ rpc?: string;
26
+ bond?: string;
27
+ }): Promise<void> {
28
+ const client = await this.getClient(rpc);
29
+
30
+ try {
31
+ let value: bigint | undefined;
32
+ if (bond) {
33
+ value = parseStakingAmount(bond);
34
+ } else {
35
+ this.startSpinner("Calculating appeal bond...");
36
+ try {
37
+ value = await client.getMinAppealBond({txId});
38
+ this.stopSpinner();
39
+ this.logInfo(`Appeal bond: ${formatStakingAmount(value)}`);
40
+ } catch {
41
+ this.stopSpinner();
42
+ value = undefined;
43
+ }
44
+ }
45
+
46
+ await this.confirmPrompt("Proceed with appeal?");
47
+
48
+ this.startSpinner(`Appealing transaction ${txId}...`);
49
+ const hash = await client.appealTransaction({
50
+ txId,
51
+ value,
52
+ });
53
+
54
+ this.setSpinnerText("Waiting for finalization...");
55
+ const result = await client.waitForTransactionReceipt({
56
+ hash,
57
+ retries: 100,
58
+ interval: 5000,
59
+ });
60
+ this.succeedSpinner("Appeal successfully executed", result);
61
+ } catch (error) {
62
+ this.failSpinner("Error during appeal operation", error);
63
+ }
64
+ }
65
+
66
+ async appealBond({
67
+ txId,
68
+ rpc,
69
+ }: {
70
+ txId: TransactionHash;
71
+ rpc?: string;
72
+ }): Promise<void> {
73
+ const client = await this.getClient(rpc, true);
74
+ this.startSpinner(`Calculating appeal bond for ${txId}...`);
75
+
76
+ try {
77
+ const bond = await client.getMinAppealBond({txId});
78
+ this.succeedSpinner(`Minimum appeal bond: ${formatStakingAmount(bond)}`);
79
+ } catch (error) {
80
+ this.failSpinner("Error calculating appeal bond", error);
81
+ }
82
+ }
83
+ }
@@ -0,0 +1,60 @@
1
+ import {Command} from "commander";
2
+ import {TransactionStatus, TransactionHash} from "genlayer-js/types";
3
+ import {ReceiptAction, ReceiptOptions} from "./receipt";
4
+ import {AppealAction, AppealOptions, AppealBondOptions} from "./appeal";
5
+ import {TraceAction, TraceOptions} from "./trace";
6
+
7
+ function parseIntOption(value: string, fallback: number): number {
8
+ const parsed = parseInt(value, 10);
9
+ return isNaN(parsed) ? fallback : parsed;
10
+ }
11
+
12
+ export function initializeTransactionsCommands(program: Command) {
13
+ const validStatuses = Object.values(TransactionStatus).join(", ");
14
+
15
+ program
16
+ .command("receipt <txId>")
17
+ .description("Get transaction receipt by hash")
18
+ .option("--status <status>", `Transaction status to wait for (${validStatuses})`, TransactionStatus.FINALIZED)
19
+ .option("--retries <retries>", "Number of retries", (value) => parseIntOption(value, 100), 100)
20
+ .option("--interval <interval>", "Interval between retries in milliseconds", (value) => parseIntOption(value, 5000), 5000)
21
+ .option("--rpc <rpcUrl>", "RPC URL for the network")
22
+ .option("--stdout", "Print only stdout from the receipt")
23
+ .option("--stderr", "Print only stderr from the receipt")
24
+ .action(async (txId: TransactionHash, options: ReceiptOptions) => {
25
+ const receiptAction = new ReceiptAction();
26
+
27
+ await receiptAction.receipt({txId, ...options});
28
+ })
29
+
30
+ program
31
+ .command("appeal <txId>")
32
+ .description("Appeal a transaction by its hash")
33
+ .option("--bond <amount>", "Appeal bond amount (e.g. 500gen, 0.5gen). Auto-calculated if omitted")
34
+ .option("--rpc <rpcUrl>", "RPC URL for the network")
35
+ .action(async (txId: TransactionHash, options: AppealOptions) => {
36
+ const appealAction = new AppealAction();
37
+ await appealAction.appeal({txId, ...options});
38
+ });
39
+
40
+ program
41
+ .command("appeal-bond <txId>")
42
+ .description("Show minimum appeal bond required for a transaction")
43
+ .option("--rpc <rpcUrl>", "RPC URL for the network")
44
+ .action(async (txId: TransactionHash, options: AppealBondOptions) => {
45
+ const appealAction = new AppealAction();
46
+ await appealAction.appealBond({txId, ...options});
47
+ });
48
+
49
+ program
50
+ .command("trace <txId>")
51
+ .description("Get execution trace for a transaction (return data, stdout, stderr, GenVM logs)")
52
+ .option("--round <round>", "Consensus round number (default: 0)", (value) => parseIntOption(value, 0), 0)
53
+ .option("--rpc <rpcUrl>", "RPC URL for the network")
54
+ .action(async (txId: TransactionHash, options: TraceOptions) => {
55
+ const traceAction = new TraceAction();
56
+ await traceAction.trace({txId, ...options});
57
+ });
58
+
59
+ return program;
60
+ }
@@ -0,0 +1,90 @@
1
+ import {BaseAction} from "../../lib/actions/BaseAction";
2
+ import {TransactionHash, TransactionStatus} from "genlayer-js/types";
3
+
4
+ export interface ReceiptParams {
5
+ txId: TransactionHash;
6
+ status?: string | TransactionStatus;
7
+ retries?: number;
8
+ interval?: number;
9
+ rpc?: string;
10
+ stdout?: boolean;
11
+ stderr?: boolean;
12
+ }
13
+
14
+ export interface ReceiptOptions extends Omit<ReceiptParams, 'txId'> {}
15
+
16
+ export class ReceiptAction extends BaseAction {
17
+ constructor() {
18
+ super();
19
+ }
20
+
21
+ private validateTransactionStatus(status: string): TransactionStatus | undefined {
22
+ const upperStatus = status.toUpperCase() as keyof typeof TransactionStatus;
23
+
24
+ if (!(upperStatus in TransactionStatus)) {
25
+ const validStatuses = Object.values(TransactionStatus);
26
+ this.failSpinner(
27
+ "Invalid transaction status",
28
+ `Invalid status: ${status}. Valid values are: ${validStatuses.join(", ")}`
29
+ );
30
+ return
31
+ }
32
+
33
+ return TransactionStatus[upperStatus];
34
+ }
35
+
36
+ async receipt({
37
+ txId,
38
+ status = TransactionStatus.FINALIZED,
39
+ retries,
40
+ interval,
41
+ rpc,
42
+ stdout,
43
+ stderr,
44
+ }: ReceiptParams): Promise<void> {
45
+ const client = await this.getClient(rpc);
46
+ await client.initializeConsensusSmartContract();
47
+ this.startSpinner(`Waiting for transaction receipt ${txId} (status: ${status})...`);
48
+
49
+ try {
50
+ let validatedStatus = this.validateTransactionStatus(status);
51
+
52
+ if (!validatedStatus) {
53
+ return;
54
+ }
55
+
56
+ const result = await client.waitForTransactionReceipt({
57
+ hash: txId,
58
+ status: validatedStatus,
59
+ retries,
60
+ interval,
61
+ });
62
+
63
+ // If specific output flags are provided, print only those fields
64
+ if (stdout || stderr) {
65
+ const stdoutValue = (result as any)?.consensus_data?.leader_receipt[0]?.genvm_result?.stdout;
66
+ const stderrValue = (result as any)?.consensus_data?.leader_receipt[0]?.genvm_result?.stderr;
67
+
68
+ if (stdout && stderr) {
69
+ this.succeedSpinner("Transaction stdout and stderr", { stdout: stdoutValue, stderr: stderrValue });
70
+ return;
71
+ }
72
+
73
+ if (stdout) {
74
+ this.succeedSpinner("Transaction stdout retrieved successfully", stdoutValue);
75
+ return;
76
+ }
77
+
78
+ if (stderr) {
79
+ this.succeedSpinner("Transaction stderr retrieved successfully", stderrValue);
80
+ return;
81
+ }
82
+ }
83
+
84
+ // Default behavior (no flags): show full receipt result
85
+ this.succeedSpinner("Transaction receipt retrieved successfully", result);
86
+ } catch (error) {
87
+ this.failSpinner("Error retrieving transaction receipt", error);
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,42 @@
1
+ import {BaseAction} from "../../lib/actions/BaseAction";
2
+ import {TransactionHash} from "genlayer-js/types";
3
+
4
+ export interface TraceParams {
5
+ txId: TransactionHash;
6
+ round?: number;
7
+ rpc?: string;
8
+ }
9
+
10
+ export interface TraceOptions extends Omit<TraceParams, 'txId'> {}
11
+
12
+ export class TraceAction extends BaseAction {
13
+ constructor() {
14
+ super();
15
+ }
16
+
17
+ async trace({
18
+ txId,
19
+ round = 0,
20
+ rpc,
21
+ }: TraceParams): Promise<void> {
22
+ const client = await this.getClient(rpc, true);
23
+ this.startSpinner(`Fetching execution trace for ${txId} (round: ${round})...`);
24
+
25
+ try {
26
+ const result = await client.request({
27
+ method: "gen_dbg_traceTransaction" as any,
28
+ params: [{txID: txId, round}],
29
+ });
30
+
31
+ const trace = (result as any);
32
+ if (!trace) {
33
+ this.failSpinner("No trace found", `No execution trace found for transaction ${txId}`);
34
+ return;
35
+ }
36
+
37
+ this.succeedSpinner("Execution trace retrieved", trace);
38
+ } catch (error) {
39
+ this.failSpinner("Error retrieving execution trace", error);
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,25 @@
1
+ import { Command } from "commander";
2
+ import { OllamaAction } from "./ollama";
3
+
4
+ export function initializeUpdateCommands(program: Command) {
5
+ const updateCommand = program
6
+ .command("update")
7
+ .description("Update resources like models or configurations");
8
+
9
+ updateCommand
10
+ .command("ollama")
11
+ .description("Manage Ollama models (update or remove)")
12
+ .option("--model [model-name]", "Specify the model to update or remove", '')
13
+ .option("--remove", "Remove the specified model instead of updating")
14
+ .action(async (options) => {
15
+ const ollamaAction = new OllamaAction();
16
+
17
+ if (options.remove) {
18
+ await ollamaAction.removeModel(options.model);
19
+ } else {
20
+ await ollamaAction.updateModel(options.model);
21
+ }
22
+ });
23
+
24
+ return program;
25
+ }
@@ -0,0 +1,103 @@
1
+ import Docker from "dockerode";
2
+ import { rpcClient } from "../../lib/clients/jsonRpcClient";
3
+ import { BaseAction } from "../../lib/actions/BaseAction";
4
+
5
+ export class OllamaAction extends BaseAction {
6
+ private docker: Docker;
7
+
8
+ constructor() {
9
+ super();
10
+ this.docker = new Docker();
11
+ }
12
+
13
+ async updateModel(modelName: string) {
14
+ try {
15
+ this.startSpinner(`Updating model "${modelName}"...`);
16
+
17
+ if(!modelName){
18
+ modelName = this.getConfig().defaultOllamaModel;
19
+ }
20
+
21
+ const providersAndModels = await rpcClient.request({
22
+ method: "sim_getProvidersAndModels",
23
+ params: [],
24
+ });
25
+
26
+ const existingOllamaProvider = providersAndModels.result.find(
27
+ (entry: any) => entry.plugin === "ollama"
28
+ );
29
+
30
+ if (!existingOllamaProvider) {
31
+ return this.failSpinner("No existing 'ollama' provider found. Unable to add/update a model.");
32
+ }
33
+
34
+ await this.executeModelCommand("pull", modelName, `Model "${modelName}" updated successfully`);
35
+
36
+ const existingModel = providersAndModels.result.some(
37
+ (entry: any) => entry.plugin === "ollama" && entry.model === modelName
38
+ );
39
+ if (!existingModel) {
40
+ this.startSpinner(`Adding model "${modelName}" to Provider Presets...`);
41
+
42
+ const newModelConfig = {
43
+ config: existingOllamaProvider.config,
44
+ model: modelName,
45
+ plugin: "ollama",
46
+ plugin_config: existingOllamaProvider.plugin_config,
47
+ provider: "ollama",
48
+ };
49
+
50
+ await rpcClient.request({
51
+ method: "sim_addProvider",
52
+ params: [newModelConfig],
53
+ });
54
+ this.succeedSpinner(`Model "${modelName}" added to Provider Presets successfully.`);
55
+ }
56
+ } catch (error) {
57
+ this.failSpinner(`Error updating model "${modelName}"`, error);
58
+ }
59
+ }
60
+
61
+ async removeModel(modelName: string) {
62
+ await this.executeModelCommand("rm", modelName, `Model "${modelName}" removed successfully`);
63
+ }
64
+
65
+ private async executeModelCommand(command: string, modelName: string, successMessage: string) {
66
+ try {
67
+ this.startSpinner(`Executing '${command}' command on model "${modelName}"...`);
68
+
69
+ let success = false;
70
+ const ollamaContainer = this.docker.getContainer("genlayer-ollama");
71
+ const exec = await ollamaContainer.exec({
72
+ Cmd: ["ollama", command, modelName],
73
+ AttachStdout: true,
74
+ AttachStderr: true,
75
+ });
76
+ const stream = await exec.start({ Detach: false, Tty: false });
77
+
78
+ stream.on("data", (chunk: any) => {
79
+ const output = chunk.toString();
80
+ this.setSpinnerText(output.trim());
81
+
82
+ if (output.includes("success") || output.includes("deleted")) {
83
+ success = true;
84
+ }
85
+ });
86
+
87
+ await new Promise<void>((resolve, reject) => {
88
+ stream.on("end", () => {
89
+ if (success) {
90
+ this.succeedSpinner(successMessage);
91
+ resolve();
92
+ } else {
93
+ this.failSpinner(`Failed to execute '${command}' on model "${modelName}".`);
94
+ reject('internal error');
95
+ }
96
+ });
97
+ stream.on("error", reject);
98
+ });
99
+ } catch (error) {
100
+ this.failSpinner(`Error executing command "${command}" on model "${modelName}"`, error);
101
+ }
102
+ }
103
+ }