genlayer 0.10.1 → 0.11.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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
 
2
2
 
3
+ ## 0.11.0 (2025-01-31)
4
+
5
+
6
+ ### Features
7
+
8
+ * Enhance Ollama Command Workflow and Default Model Handling ([#171](https://github.com/yeagerai/genlayer-cli/issues/171)) ([3dc7a96](https://github.com/yeagerai/genlayer-cli/commit/3dc7a9673ada8116b1fb99e089439a75e06237ec))
9
+
10
+ ## 0.10.2 (2025-01-30)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * updated studio version ([#174](https://github.com/yeagerai/genlayer-cli/issues/174)) ([e70e7f2](https://github.com/yeagerai/genlayer-cli/commit/e70e7f2e549abc9c9633ae066820fb272c9334ee))
16
+
3
17
  ## 0.10.1 (2025-01-29)
4
18
 
5
19
 
package/dist/index.js CHANGED
@@ -54537,7 +54537,7 @@ var {
54537
54537
  } = import_index.default;
54538
54538
 
54539
54539
  // package.json
54540
- var version = "0.10.1";
54540
+ var version = "0.11.0";
54541
54541
  var package_default = {
54542
54542
  name: "genlayer",
54543
54543
  version,
@@ -54678,7 +54678,7 @@ function v4(options, buf, offset) {
54678
54678
  var v4_default = v4;
54679
54679
 
54680
54680
  // src/lib/config/simulator.ts
54681
- var localnetCompatibleVersion = "v0.34.3";
54681
+ var localnetCompatibleVersion = "v0.35.2";
54682
54682
  var DEFAULT_JSON_RPC_URL = "http://localhost:4000/api";
54683
54683
  var CONTAINERS_NAME_PREFIX = "/genlayer-";
54684
54684
  var IMAGES_NAME_PREFIX = "yeagerai";
@@ -54726,26 +54726,23 @@ var JsonRpcClient = class {
54726
54726
  this.serverUrl = serverUrl;
54727
54727
  }
54728
54728
  async request({ method, params }) {
54729
- try {
54730
- const response = await (0, import_node_fetch.default)(this.serverUrl, {
54731
- method: "POST",
54732
- headers: {
54733
- "Content-Type": "application/json"
54734
- },
54735
- body: JSON.stringify({
54736
- jsonrpc: "2.0",
54737
- id: v4_default(),
54738
- method,
54739
- params
54740
- })
54741
- });
54742
- if (response.ok) {
54743
- return response.json();
54744
- }
54745
- } catch (error) {
54746
- throw new Error(`Fetch Error: ${error.message}`);
54729
+ const response = await (0, import_node_fetch.default)(this.serverUrl, {
54730
+ method: "POST",
54731
+ headers: {
54732
+ "Content-Type": "application/json"
54733
+ },
54734
+ body: JSON.stringify({
54735
+ jsonrpc: "2.0",
54736
+ id: v4_default(),
54737
+ method,
54738
+ params
54739
+ })
54740
+ });
54741
+ if (response.ok) {
54742
+ return response.json();
54747
54743
  }
54748
- return null;
54744
+ const result = await response.json();
54745
+ throw new Error(result?.error?.message || response.statusText);
54749
54746
  }
54750
54747
  };
54751
54748
  var rpcClient = new JsonRpcClient(DEFAULT_JSON_RPC_URL);
@@ -55382,12 +55379,12 @@ Run npm install -g genlayer to update
55382
55379
  }
55383
55380
  createRandomValidators(numValidators, llmProviders) {
55384
55381
  return rpcClient.request({
55385
- method: "create_random_validators",
55382
+ method: "sim_createRandomValidators",
55386
55383
  params: [numValidators, 1, 10, llmProviders]
55387
55384
  });
55388
55385
  }
55389
55386
  deleteAllValidators() {
55390
- return rpcClient.request({ method: "delete_all_validators", params: [] });
55387
+ return rpcClient.request({ method: "sim_deleteAllValidators", params: [] });
55391
55388
  }
55392
55389
  getAiProvidersOptions(withHint = true) {
55393
55390
  return Object.values(AI_PROVIDERS_CONFIG).map((providerConfig) => {
@@ -57584,13 +57581,50 @@ var OllamaAction = class {
57584
57581
  this.docker = new import_dockerode2.default();
57585
57582
  }
57586
57583
  async updateModel(modelName) {
57587
- await this.executeModelCommand("pull", modelName, `Model "${modelName}" updated successfully`);
57584
+ const providersAndModels = await rpcClient.request({
57585
+ method: "sim_getProvidersAndModels",
57586
+ params: []
57587
+ });
57588
+ const existingOllamaProvider = providersAndModels.result.find(
57589
+ (entry) => entry.plugin === "ollama"
57590
+ );
57591
+ if (!existingOllamaProvider) {
57592
+ throw new Error("No existing 'ollama' provider found. Unable to add/update a model.");
57593
+ }
57594
+ await this.executeModelCommand(
57595
+ "pull",
57596
+ modelName,
57597
+ `Model "${modelName}" updated successfully`
57598
+ );
57599
+ const existingModel = providersAndModels.result.some(
57600
+ (entry) => entry.plugin === "ollama" && entry.model === modelName
57601
+ );
57602
+ if (!existingModel) {
57603
+ console.log(`Model "${modelName}" not found in Provider Presets. Adding...`);
57604
+ const newModelConfig = {
57605
+ config: existingOllamaProvider.config,
57606
+ model: modelName,
57607
+ plugin: "ollama",
57608
+ plugin_config: existingOllamaProvider.plugin_config,
57609
+ provider: "ollama"
57610
+ };
57611
+ await rpcClient.request({
57612
+ method: "sim_addProvider",
57613
+ params: [newModelConfig]
57614
+ });
57615
+ console.log(`Model "${modelName}" added successfully.`);
57616
+ }
57588
57617
  }
57589
57618
  async removeModel(modelName) {
57590
- await this.executeModelCommand("rm", modelName, `Model "${modelName}" removed successfully`);
57619
+ await this.executeModelCommand(
57620
+ "rm",
57621
+ modelName,
57622
+ `Model "${modelName}" removed successfully`
57623
+ );
57591
57624
  }
57592
57625
  async executeModelCommand(command, modelName, successMessage) {
57593
57626
  try {
57627
+ let success = false;
57594
57628
  const ollamaContainer = this.docker.getContainer("ollama");
57595
57629
  const exec2 = await ollamaContainer.exec({
57596
57630
  Cmd: ["ollama", command, modelName],
@@ -57599,10 +57633,20 @@ var OllamaAction = class {
57599
57633
  });
57600
57634
  const stream = await exec2.start({ Detach: false, Tty: false });
57601
57635
  stream.on("data", (chunk) => {
57602
- console.log(chunk.toString());
57636
+ const chunkStr = chunk.toString();
57637
+ console.log(chunkStr);
57638
+ if (chunkStr.includes("success") || chunkStr.includes("deleted")) {
57639
+ success = true;
57640
+ }
57603
57641
  });
57604
57642
  await new Promise((resolve2, reject) => {
57605
- stream.on("end", resolve2);
57643
+ stream.on("end", () => {
57644
+ if (success) {
57645
+ resolve2();
57646
+ } else {
57647
+ reject("internal error");
57648
+ }
57649
+ });
57606
57650
  stream.on("error", reject);
57607
57651
  });
57608
57652
  console.log(successMessage);
@@ -57796,7 +57840,11 @@ async function initAction(options, simulatorService) {
57796
57840
  const ollamaAction = new OllamaAction();
57797
57841
  const configManager = new ConfigFileManager();
57798
57842
  const config = configManager.getConfig();
57799
- let ollamaModel = config.defaultOllamaModel || "llama3";
57843
+ let ollamaModel = config.defaultOllamaModel;
57844
+ if (!config.defaultOllamaModel) {
57845
+ configManager.writeConfig("defaultOllamaModel", "llama3");
57846
+ ollamaModel = "llama3";
57847
+ }
57800
57848
  console.log(`Pulling ${ollamaModel} from Ollama...`);
57801
57849
  await ollamaAction.updateModel(ollamaModel);
57802
57850
  }
@@ -86776,11 +86824,280 @@ function initializeConfigCommands(program2) {
86776
86824
  return program2;
86777
86825
  }
86778
86826
 
86827
+ // src/lib/actions/BaseAction.ts
86828
+ var BaseAction = class {
86829
+ async confirmPrompt(message) {
86830
+ const answer = await lib_default.prompt([
86831
+ {
86832
+ type: "confirm",
86833
+ name: "confirmAction",
86834
+ message,
86835
+ default: true
86836
+ }
86837
+ ]);
86838
+ if (!answer.confirmAction) {
86839
+ console.log("Operation aborted!");
86840
+ process.exit(0);
86841
+ }
86842
+ }
86843
+ };
86844
+
86845
+ // src/commands/validators/validators.ts
86846
+ var ValidatorsAction = class extends BaseAction {
86847
+ async getValidator(options) {
86848
+ try {
86849
+ if (options.address) {
86850
+ console.log(`Fetching validator with address: ${options.address}`);
86851
+ const result = await rpcClient.request({
86852
+ method: "sim_getValidator",
86853
+ params: [options.address]
86854
+ });
86855
+ console.log("Validator Details:", result.result);
86856
+ } else {
86857
+ console.log("Fetching all validators...");
86858
+ const result = await rpcClient.request({
86859
+ method: "sim_getAllValidators",
86860
+ params: []
86861
+ });
86862
+ console.log("All Validators:", result.result);
86863
+ }
86864
+ } catch (error) {
86865
+ console.error("Error fetching validators:", error);
86866
+ }
86867
+ }
86868
+ async deleteValidator(options) {
86869
+ try {
86870
+ if (options.address) {
86871
+ await this.confirmPrompt(`This command will delete the validator with the address: ${options.address}. Do you want to continue?`);
86872
+ console.log(`Deleting validator with address: ${options.address}`);
86873
+ const result = await rpcClient.request({
86874
+ method: "sim_deleteValidator",
86875
+ params: [options.address]
86876
+ });
86877
+ console.log("Deleted Address:", result.result);
86878
+ } else {
86879
+ await this.confirmPrompt(`This command will delete all validators. Do you want to continue?`);
86880
+ console.log("Deleting all validators...");
86881
+ await rpcClient.request({
86882
+ method: "sim_deleteAllValidators",
86883
+ params: []
86884
+ });
86885
+ console.log("Successfully deleted all validators");
86886
+ }
86887
+ } catch (error) {
86888
+ console.error("Error deleting validators:", error);
86889
+ }
86890
+ }
86891
+ async countValidators() {
86892
+ try {
86893
+ console.log("Counting all validators...");
86894
+ const result = await rpcClient.request({
86895
+ method: "sim_countValidators",
86896
+ params: []
86897
+ });
86898
+ console.log("Total Validators:", result.result);
86899
+ } catch (error) {
86900
+ console.error("Error counting validators:", error);
86901
+ }
86902
+ }
86903
+ async updateValidator(options) {
86904
+ try {
86905
+ console.log(`Fetching validator with address: ${options.address}...`);
86906
+ const currentValidator = await rpcClient.request({
86907
+ method: "sim_getValidator",
86908
+ params: [options.address]
86909
+ });
86910
+ if (!currentValidator.result) {
86911
+ throw new Error(`Validator with address ${options.address} not found.`);
86912
+ }
86913
+ console.log("Current Validator Details:", currentValidator.result);
86914
+ const parsedStake = options.stake ? parseInt(options.stake, 10) : currentValidator.result.stake;
86915
+ if (isNaN(parsedStake) || parsedStake < 0) {
86916
+ return console.error("Invalid stake value. Stake must be a positive integer.");
86917
+ }
86918
+ const updatedValidator = {
86919
+ address: options.address,
86920
+ stake: options.stake || currentValidator.result.stake,
86921
+ provider: options.provider || currentValidator.result.provider,
86922
+ model: options.model || currentValidator.result.model,
86923
+ config: options.config ? JSON.parse(options.config) : currentValidator.result.config
86924
+ };
86925
+ console.log("Updated Validator Details:", updatedValidator);
86926
+ const result = await rpcClient.request({
86927
+ method: "sim_updateValidator",
86928
+ params: [
86929
+ updatedValidator.address,
86930
+ updatedValidator.stake,
86931
+ updatedValidator.provider,
86932
+ updatedValidator.model,
86933
+ updatedValidator.config
86934
+ ]
86935
+ });
86936
+ console.log("Validator successfully updated:", result.result);
86937
+ } catch (error) {
86938
+ console.error("Error updating validator:", error);
86939
+ }
86940
+ }
86941
+ async createRandomValidators(options) {
86942
+ try {
86943
+ const count = parseInt(options.count, 10);
86944
+ if (isNaN(count) || count < 1) {
86945
+ return console.error("Invalid count. Please provide a positive integer.");
86946
+ }
86947
+ console.log(`Creating ${count} random validator(s)...`);
86948
+ console.log(`Providers: ${options.providers.length > 0 ? options.providers.join(", ") : "None"}`);
86949
+ console.log(`Models: ${options.models.length > 0 ? options.models.join(", ") : "None"}`);
86950
+ const result = await rpcClient.request({
86951
+ method: "sim_createRandomValidators",
86952
+ params: [count, 1, 10, options.providers, options.models]
86953
+ });
86954
+ console.log("Random validators successfully created:", result.result);
86955
+ } catch (error) {
86956
+ console.error("Error creating random validators:", error);
86957
+ }
86958
+ }
86959
+ async createValidator(options) {
86960
+ try {
86961
+ const stake = parseInt(options.stake, 10);
86962
+ if (isNaN(stake) || stake < 1) {
86963
+ return console.error("Invalid stake. Please provide a positive integer.");
86964
+ }
86965
+ if (options.model && !options.provider) {
86966
+ return console.error("You must specify a provider if using a model.");
86967
+ }
86968
+ console.log("Fetching available providers and models...");
86969
+ const providersAndModels = await rpcClient.request({
86970
+ method: "sim_getProvidersAndModels",
86971
+ params: []
86972
+ });
86973
+ if (!providersAndModels.result || providersAndModels.result.length === 0) {
86974
+ return console.error("No providers or models available.");
86975
+ }
86976
+ const availableProviders = [
86977
+ ...new Map(
86978
+ providersAndModels.result.filter((entry) => entry.is_available).map((entry) => [entry.provider, entry])
86979
+ ).values()
86980
+ ];
86981
+ let provider = options.provider;
86982
+ if (!provider) {
86983
+ const { selectedProvider } = await lib_default.prompt([
86984
+ {
86985
+ type: "list",
86986
+ name: "selectedProvider",
86987
+ message: "Select a provider:",
86988
+ choices: availableProviders.map((entry) => entry.provider)
86989
+ }
86990
+ ]);
86991
+ provider = selectedProvider;
86992
+ }
86993
+ const availableModels = providersAndModels.result.filter(
86994
+ (entry) => entry.provider === provider && entry.is_model_available
86995
+ );
86996
+ if (availableModels.length === 0) {
86997
+ return console.error("No models available for the selected provider.");
86998
+ }
86999
+ let model = options.model;
87000
+ if (!model) {
87001
+ const { selectedModel } = await lib_default.prompt([
87002
+ {
87003
+ type: "list",
87004
+ name: "selectedModel",
87005
+ message: "Select a model:",
87006
+ choices: availableModels.map((entry) => entry.model)
87007
+ }
87008
+ ]);
87009
+ model = selectedModel;
87010
+ }
87011
+ const modelDetails = availableModels.find(
87012
+ (entry) => entry.model === model
87013
+ );
87014
+ if (!modelDetails) {
87015
+ return console.error("Selected model details not found.");
87016
+ }
87017
+ const config = options.config ? JSON.parse(options.config) : modelDetails.config;
87018
+ console.log("Creating validator with the following details:");
87019
+ console.log(`Stake: ${stake}`);
87020
+ console.log(`Provider: ${modelDetails.provider}`);
87021
+ console.log(`Model: ${modelDetails.model}`);
87022
+ console.log(`Config:`, config);
87023
+ console.log(`Plugin:`, modelDetails.plugin);
87024
+ console.log(`Plugin Config:`, modelDetails.plugin_config);
87025
+ const result = await rpcClient.request({
87026
+ method: "sim_createValidator",
87027
+ params: [
87028
+ stake,
87029
+ modelDetails.provider,
87030
+ modelDetails.model,
87031
+ config,
87032
+ modelDetails.plugin,
87033
+ modelDetails.plugin_config
87034
+ ]
87035
+ });
87036
+ console.log("Validator successfully created:", result.result);
87037
+ } catch (error) {
87038
+ console.error("Error creating validator:", error);
87039
+ }
87040
+ }
87041
+ };
87042
+
87043
+ // src/commands/validators/index.ts
87044
+ function initializeValidatorCommands(program2) {
87045
+ const validatorsAction = new ValidatorsAction();
87046
+ const validatorsCommand = program2.command("validators").description("Manage validator operations");
87047
+ validatorsCommand.command("get").description("Retrieve details of a specific validator or all validators").option("--address <validatorAddress>", "The address of the validator to retrieve (omit to retrieve all validators)").action(async (options) => {
87048
+ await validatorsAction.getValidator({ address: options.address });
87049
+ });
87050
+ validatorsCommand.command("delete").description("Delete a specific validator or all validators").option("--address <validatorAddress>", "The address of the validator to delete (omit to delete all validators)").action(async (options) => {
87051
+ await validatorsAction.deleteValidator({ address: options.address });
87052
+ });
87053
+ validatorsCommand.command("count").description("Count all validators").action(async () => {
87054
+ await validatorsAction.countValidators();
87055
+ });
87056
+ validatorsCommand.command("update <validatorAddress>").description("Update a validator's details").option("--stake <stake>", "New stake for the validator").option("--provider <provider>", "New provider for the validator").option("--model <model>", "New model for the validator").option("--config <config>", "New JSON config for the validator").action(async (validatorAddress, options) => {
87057
+ await validatorsAction.updateValidator({
87058
+ address: validatorAddress,
87059
+ stake: options.stake,
87060
+ provider: options.provider,
87061
+ model: options.model,
87062
+ config: options.config
87063
+ });
87064
+ });
87065
+ validatorsCommand.command("create-random").description("Create random validators").option("--count <count>", "Number of validators to create", "1").option(
87066
+ "--providers <providers...>",
87067
+ "Space-separated list of provider names (e.g., openai ollama)",
87068
+ []
87069
+ ).option(
87070
+ "--models <models...>",
87071
+ "Space-separated list of model names (e.g., gpt-4 gpt-4o)",
87072
+ []
87073
+ ).action(async (options) => {
87074
+ await validatorsAction.createRandomValidators({
87075
+ count: options.count,
87076
+ providers: options.providers,
87077
+ models: options.models
87078
+ });
87079
+ });
87080
+ validatorsCommand.command("create").description("Create a new validator").option("--stake <stake>", "Stake amount for the validator (default: 1)", "1").option(
87081
+ "--config <config>",
87082
+ `Optional JSON configuration for the validator (e.g., '{"max_tokens": 500, "temperature": 0.75}')`
87083
+ ).option("--provider <provider>", "Specify the provider for the validator").option("--model <model>", "Specify the model for the validator").action(async (options) => {
87084
+ await validatorsAction.createValidator({
87085
+ stake: options.stake,
87086
+ config: options.config,
87087
+ provider: options.provider,
87088
+ model: options.model
87089
+ });
87090
+ });
87091
+ return program2;
87092
+ }
87093
+
86779
87094
  // src/commands/update/index.ts
86780
87095
  function initializeUpdateCommands(program2) {
86781
87096
  const updateCommand = program2.command("update").description("Update resources like models or configurations");
86782
87097
  updateCommand.command("ollama").description("Manage Ollama models (update or remove)").option("--model [model-name]", "Specify the model to update or remove").option("--remove", "Remove the specified model instead of updating").action(async (options) => {
86783
- const modelName = options.model || "default-model";
87098
+ const configManager = new ConfigFileManager();
87099
+ const config = configManager.getConfig();
87100
+ const modelName = options.model || config.defaultOllamaModel;
86784
87101
  const ollamaAction = new OllamaAction();
86785
87102
  if (options.remove) {
86786
87103
  await ollamaAction.removeModel(modelName);
@@ -86799,6 +87116,7 @@ function initializeCLI() {
86799
87116
  initializeContractsCommands(program);
86800
87117
  initializeConfigCommands(program);
86801
87118
  initializeUpdateCommands(program);
87119
+ initializeValidatorCommands(program);
86802
87120
  program.parse(process.argv);
86803
87121
  }
86804
87122
  initializeCLI();
@@ -61,6 +61,9 @@ services:
61
61
  max-file: "3"
62
62
  deploy:
63
63
  replicas: ${JSONRPC_REPLICAS:-1}
64
+ volumes:
65
+ - hardhat_artifacts:/app/hardhat/artifacts
66
+ - hardhat_deployments:/app/hardhat/deployments
64
67
 
65
68
  webrequest:
66
69
  image: yeagerai/simulator-webrequest:${LOCALNETVERSION:-latest}
@@ -144,8 +147,15 @@ services:
144
147
  condition: service_healthy
145
148
 
146
149
  hardhat:
147
- image: yeagerai/simulator-hardhat
150
+ image: yeagerai/simulator-hardhat:${LOCALNETVERSION:-latest}
148
151
  ports:
149
152
  - "${HARDHAT_PORT:-8545}:8545"
150
153
  environment:
151
- - HARDHAT_NETWORK=hardhat
154
+ - HARDHAT_NETWORK=hardhat
155
+ volumes:
156
+ - hardhat_artifacts:/app/artifacts
157
+ - hardhat_deployments:/app/deployments
158
+
159
+ volumes:
160
+ hardhat_artifacts:
161
+ hardhat_deployments:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genlayer",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "description": "GenLayer Command Line Tool",
5
5
  "main": "src/index.ts",
6
6
  "bin": {
@@ -184,8 +184,12 @@ export async function initAction(options: InitActionOptions, simulatorService: I
184
184
  const ollamaAction = new OllamaAction();
185
185
  const configManager = new ConfigFileManager();
186
186
  const config = configManager.getConfig()
187
+ let ollamaModel = config.defaultOllamaModel;
187
188
 
188
- let ollamaModel = config.defaultOllamaModel || 'llama3';
189
+ if(!config.defaultOllamaModel){
190
+ configManager.writeConfig('defaultOllamaModel', 'llama3');
191
+ ollamaModel = 'llama3'
192
+ }
189
193
 
190
194
  console.log(`Pulling ${ollamaModel} from Ollama...`);
191
195
 
@@ -1,5 +1,6 @@
1
1
  import { Command } from "commander";
2
2
  import { OllamaAction } from "./ollama";
3
+ import { ConfigFileManager } from "../../lib/config/ConfigFileManager";
3
4
 
4
5
  export function initializeUpdateCommands(program: Command) {
5
6
  const updateCommand = program
@@ -12,7 +13,10 @@ export function initializeUpdateCommands(program: Command) {
12
13
  .option("--model [model-name]", "Specify the model to update or remove")
13
14
  .option("--remove", "Remove the specified model instead of updating")
14
15
  .action(async (options) => {
15
- const modelName = options.model || "default-model";
16
+ const configManager = new ConfigFileManager();
17
+ const config = configManager.getConfig()
18
+
19
+ const modelName = options.model || config.defaultOllamaModel;
16
20
  const ollamaAction = new OllamaAction();
17
21
 
18
22
  if (options.remove) {
@@ -1,4 +1,5 @@
1
- import Docker from "dockerode"
1
+ import Docker from "dockerode";
2
+ import { rpcClient } from "../../lib/clients/jsonRpcClient";
2
3
 
3
4
  export class OllamaAction {
4
5
  private docker: Docker;
@@ -8,34 +9,94 @@ export class OllamaAction {
8
9
  }
9
10
 
10
11
  async updateModel(modelName: string) {
11
- await this.executeModelCommand("pull", modelName, `Model "${modelName}" updated successfully`);
12
+ const providersAndModels = await rpcClient.request({
13
+ method: "sim_getProvidersAndModels",
14
+ params: [],
15
+ });
16
+
17
+ const existingOllamaProvider = providersAndModels.result.find(
18
+ (entry: any) => entry.plugin === "ollama"
19
+ );
20
+
21
+ if (!existingOllamaProvider) {
22
+ throw new Error("No existing 'ollama' provider found. Unable to add/update a model.");
23
+ }
24
+
25
+ await this.executeModelCommand(
26
+ "pull",
27
+ modelName,
28
+ `Model "${modelName}" updated successfully`
29
+ );
30
+
31
+ const existingModel = providersAndModels.result.some(
32
+ (entry: any) =>
33
+ entry.plugin === "ollama" && entry.model === modelName
34
+ );
35
+
36
+ if (!existingModel) {
37
+ console.log(`Model "${modelName}" not found in Provider Presets. Adding...`);
38
+
39
+ const newModelConfig = {
40
+ config: existingOllamaProvider.config,
41
+ model: modelName,
42
+ plugin: "ollama",
43
+ plugin_config: existingOllamaProvider.plugin_config,
44
+ provider: "ollama",
45
+ };
46
+
47
+ await rpcClient.request({
48
+ method: "sim_addProvider",
49
+ params: [newModelConfig],
50
+ });
51
+
52
+ console.log(`Model "${modelName}" added successfully.`);
53
+ }
12
54
  }
13
55
 
14
56
  async removeModel(modelName: string) {
15
- await this.executeModelCommand("rm", modelName, `Model "${modelName}" removed successfully`);
57
+ await this.executeModelCommand(
58
+ "rm",
59
+ modelName,
60
+ `Model "${modelName}" removed successfully`
61
+ );
16
62
  }
17
63
 
18
- private async executeModelCommand(command: string, modelName: string, successMessage: string) {
64
+ private async executeModelCommand(
65
+ command: string,
66
+ modelName: string,
67
+ successMessage: string
68
+ ) {
19
69
  try {
70
+ let success = false;
20
71
  const ollamaContainer = this.docker.getContainer("ollama");
21
72
  const exec = await ollamaContainer.exec({
22
73
  Cmd: ["ollama", command, modelName],
23
74
  AttachStdout: true,
24
75
  AttachStderr: true,
25
76
  });
26
- const stream = await exec.start({ Detach: false, Tty: false });
77
+ const stream = await exec.start({Detach: false, Tty: false});
27
78
 
28
79
  stream.on("data", (chunk: any) => {
29
- console.log(chunk.toString());
80
+ const chunkStr = chunk.toString();
81
+ console.log(chunkStr);
82
+ if (chunkStr.includes("success") || chunkStr.includes("deleted")) {
83
+ success = true;
84
+ }
30
85
  });
31
86
 
32
87
  await new Promise<void>((resolve, reject) => {
33
- stream.on("end", resolve);
88
+ stream.on("end", () => {
89
+ if (success) {
90
+ resolve();
91
+ } else {
92
+ reject('internal error');
93
+ }
94
+ });
34
95
  stream.on("error", reject);
35
96
  });
36
97
 
37
98
  console.log(successMessage);
38
- } catch (error) {
99
+ }catch (error) {
39
100
  console.error(`Error executing command "${command}" on model "${modelName}":`, error);
40
101
  }
41
102
  }