Skip to content

Commit

Permalink
added model download
Browse files Browse the repository at this point in the history
  • Loading branch information
STetsing committed Jun 26, 2024
1 parent 8ed1077 commit ea50608
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 73 deletions.
7 changes: 4 additions & 3 deletions apps/remix-ide/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,13 +371,14 @@ class AppComponent {
const remixAIDesktop = new remixAIDesktopPlugin()
this.engine.register([remixAIDesktop])
}

const remixAI = new RemixAIPlugin(isElectron())
this.engine.register([remixAI])

const compilerloader = isElectron()? new compilerLoaderPluginDesktop(): new compilerLoaderPlugin()
this.engine.register([compilerloader])

const remixAI = new RemixAIPlugin(isElectron())
this.engine.register([remixAI])


// LAYOUT & SYSTEM VIEWS
const appPanel = new MainPanel()
Registry.getInstance().put({api: this.mainview, name: 'mainview'})
Expand Down
51 changes: 18 additions & 33 deletions apps/remix-ide/src/app/plugins/electron/remixAIDesktopPlugin.tsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,41 @@
import { ElectronPlugin } from '@remixproject/engine-electron'
import { IModel, ModelType, DefaultModels } from '@remix/remix-ai-core';
import axios from 'axios';
import fs from 'fs';
import { Model } from '@remix/remix-ai-core';

const desktop_profile = {
name: 'remixAID',
displayName: 'RemixAI Desktop',
maintainedBy: 'Remix',
description: 'RemixAI provides AI services to Remix IDE Desktop.',
documentation: 'https://remix-ide.readthedocs.io/en/latest/remixai.html',
icon: 'assets/img/remix-logo-blue.png',
methods: ['downloadModel'],
}

export class remixAIDesktopPlugin extends ElectronPlugin {
selectedModel: IModel | null = DefaultModels()[0]
constructor() {
console.log('remixAIDesktopPlugin')
console.log('remixAIDesktopPlugin loaded')
super(desktop_profile)

this

}

onActivation(): void {
this.on('remixAI', 'enabled', () => {console.log('someone enable the remixAI desktop plugin')} )
console.log('remixAIDesktopPlugin ---------------------- activated')
console.log('remixAIDesktopPlugin Model: ', this.selectedModel)
}

async downloadModel(model: Model, outputLocationPath: string): Promise<void> {
console.log(`Downloading model ${model.name}`)

// Make a HEAD request to get the file size
const { headers } = await axios.head(model.download_url);
const totalSize = parseInt(headers['content-length'], 10);

// Create a write stream to save the file
const writer = fs.createWriteStream(outputLocationPath);

// Start the file download
const response = await axios({
method: 'get',
url: model.download_url,
responseType: 'stream'
});

let downloadedSize = 0;

response.data.on('data', (chunk: Buffer) => {
downloadedSize += chunk.length;
const progress = (downloadedSize / totalSize) * 100;
this.emit('download_progress', progress);
});

response.data.pipe(writer);

}

return new Promise((resolve, reject) => {
writer.on('finish', resolve);
writer.on('error', reject);
});
}
}
// class RemixAIPlugin extends ElectronPlugin {
// constructor() {
// super(dek)
// this.methods = ['downloadModel']
// }
// }
3 changes: 1 addition & 2 deletions apps/remix-ide/src/app/plugins/remixAIPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class RemixAIPlugin extends ViewPlugin {
isOnDesktop:boolean = false
aiIsActivated:boolean = false
constructor(inDesktop:boolean) {
console.log('remixAIPlugin')
console.log('remixAIPlugin loaded')
super(profile)
this.isOnDesktop = inDesktop
}
Expand All @@ -32,7 +32,6 @@ export class RemixAIPlugin extends ViewPlugin {

if (this.isOnDesktop) {
console.log('Activating RemixAIPlugin on desktop')
// Do some desktop specific stuff
}
}

Expand Down
5 changes: 3 additions & 2 deletions apps/remix-ide/src/remixAppManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ let requiredModules = [ // services + layout views + system views
'home',
'doc-viewer',
'doc-gen',
'remix-templates'
'remix-templates',
'remixAID'
]


Expand Down Expand Up @@ -153,7 +154,7 @@ export class RemixAppManager extends PluginManager {
this.pluginsDirectory = 'https://raw.githubusercontent.com/ethereum/remix-plugins-directory/master/build/metadata.json'
this.pluginLoader = new PluginLoader()
if (Registry.getInstance().get('platform').api.isDesktop()) {
requiredModules = [...requiredModules, 'fs', 'electronTemplates', 'isogit', 'remix-templates', 'electronconfig', 'xterm', 'compilerloader', 'ripgrep']
requiredModules = [...requiredModules, 'fs', 'electronTemplates', 'isogit', 'remix-templates', 'electronconfig', 'xterm', 'compilerloader', 'ripgrep', 'remixAID']
}

}
Expand Down
2 changes: 1 addition & 1 deletion apps/remix-ide/src/remixEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export class RemixEngine extends Engine {
if (name === 'compilerloader') return { queueTimeout: 60000 * 4 }
if (name === 'filePanel') return { queueTimeout: 60000 * 20 }
if (name === 'fileManager') return { queueTimeout: 60000 * 20 }
if (name === 'openaigpt') return { queueTimeout: 60000 * 2 }
if (name === 'solcoder') return { queueTimeout: 60000 * 2 }
if (name === 'remixAID') return { queueTimeout: 60000 * 20 }
if (name === 'cookbookdev') return { queueTimeout: 60000 * 3 }
return { queueTimeout: 10000 }
}
Expand Down
78 changes: 70 additions & 8 deletions apps/remixdesktop/src/plugins/remixAIDektop.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { ElectronBasePlugin, ElectronBasePluginClient } from "@remixproject/plugin-electron"
import { Profile } from "@remixproject/plugin-utils"
import { app } from 'electron';
// import { Model, ModelType, DefaultModels } from '@remix/remix-ai-core';
import axios from "axios";
import fs from 'fs';
import path from 'path';

// import { isE2E } from "../main";

const profile = {
name: 'remixAID',
displayName: 'RemixAI desktop',
methods: [''],
description: 'RemixAI provides AI services to Remix IDE Desktop.',
displayName: 'RemixAI Desktop',
maintainedBy: 'Remix',
description: 'RemixAI provides AI services to Remix IDE Desktop.',
kind: '',
documentation: 'https://remix-ide.readthedocs.io/en/latest/remixai.html',
}

export class RemixAIDesktopPlugin extends ElectronBasePlugin {
Expand All @@ -27,10 +33,12 @@ export class RemixAIDesktopPlugin extends ElectronBasePlugin {

const clientProfile: Profile = {
name: 'remixAID',
displayName: 'RemixAI desktop',
methods: ['enable', 'downloadModel'],
description: 'RemixAI provides AI services to Remix IDE Desktop.',
displayName: 'RemixAI Desktop',
maintainedBy: 'Remix',
description: 'RemixAI provides AI services to Remix IDE Desktop.',
kind: '',
documentation: 'https://remix-ide.readthedocs.io/en/latest/remixai.html',
methods: ['downloadModel']
}

class RemixAIDesktopPluginClient extends ElectronBasePluginClient {
Expand All @@ -40,10 +48,10 @@ class RemixAIDesktopPluginClient extends ElectronBasePluginClient {
}

async onActivation(): Promise<void> {
console.log("Activation", "loaded the remix plugin client")
console.log("Activation", "loaded the remix plugin client application side")
this.onload(() => {
this.emit('loaded')
console.log("loaded the remix plugin client")
console.log("loaded the remix plugin client application side")
})
}
async listAvailableModels(){
Expand All @@ -54,6 +62,60 @@ class RemixAIDesktopPluginClient extends ElectronBasePluginClient {
console.log('Remix AI desktop plugin enabled')
this.emit('enabled')
}



async downloadModel(model): Promise<void> {
console.log('Downloading the model model', model)
console.log('Downloading model', model.downloadUrl)

const wdir = await this.call('fs' as any, 'getWorkingDir');
console.log('working dir is', wdir)
const outputLocationDir = await this.call('fs' as any, 'selectFolder', wdir);
console.log('output location dir is', outputLocationDir)

if (outputLocationDir === undefined) {
console.log('No output location selected');
return;
}

const outputLocationPath = path.join(outputLocationDir, model.modelName);
console.log('output location path is', outputLocationDir)
if (fs.existsSync(outputLocationPath)) {
console.log('Model already exists in the output location', outputLocationPath);
return;
}

// Make a HEAD request to get the file size
const { headers } = await axios.head(model.downloadUrl);
const totalSize = parseInt(headers['content-length'], 10);

// Create a write stream to save the file
const writer = fs.createWriteStream(outputLocationPath);

// Start the file download
const response = await axios({
method: 'get',
url: model.downloadUrl,
responseType: 'stream'
});

let downloadedSize = 0;

response.data.on('data', (chunk: Buffer) => {
downloadedSize += chunk.length;
const progress = (downloadedSize / totalSize) * 100;
console.log(`Downloaded ${progress}%`);
this.emit('download_progress', progress);
});

response.data.pipe(writer);
console.log('Download complete');
return new Promise((resolve, reject) => {
writer.on('finish', resolve);
writer.on('error', reject);
});
}


}
Expand Down
5 changes: 4 additions & 1 deletion apps/remixdesktop/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
"moduleResolution": "node",
"resolveJsonModule": true,
"paths": {
"*": ["node_modules/*"]
"*": ["node_modules/*"],
// "@remix/remix-ai-core": [
// "../../libs/remix-ai-core/src/index.ts"
// ],
},
"typeRoots": ["src/**/*.d.ts", "node_modules/@types", "test/**/*.d.ts", "../remix-ide-e2e/src/**/*.d.ts"]
},
Expand Down
5 changes: 3 additions & 2 deletions libs/remix-ai-core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict'

import { Model, ModelResponse, ModelRequest, InferenceModel} from './types/types'
import { IModel, IModelResponse, IModelRequest, InferenceModel} from './types/types'
import { ModelType } from './types/constants'
import { DefaultModels } from './types/models'


export { Model, ModelResponse, ModelRequest, InferenceModel }
export { IModel, IModelResponse, IModelRequest, InferenceModel, ModelType, DefaultModels}
1 change: 0 additions & 1 deletion libs/remix-ai-core/src/types/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ export enum ModelType {
CODE_COMPLETION = 'code_completion',
GENERAL = 'general',
}

33 changes: 24 additions & 9 deletions libs/remix-ai-core/src/types/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,34 @@
// create a function getModels returning a list of all supported models
// create a function getModel returning a model by its name

import { Model } from './types';
import { IModel} from './types';
import { ModelType} from './constants';

const supportedModels: Model[] = [];


const getModels = async (): Promise<Model[]> => {
return supportedModels;
const DefaultModels = (): IModel[] => {
const model1:IModel = {
name: 'DeepSeek',
modelName: 'deepseek-coder-1.3b-instruct.gguf',
downloadUrl: 'https://huggingface.co/TheBloke/deepseek-coder-1.3b-instruct-GGUF/resolve/main/deepseek-coder-1.3b-instruct.Q4_K_M.gguf?download=true',
modelType: ModelType.CODE_COMPLETION,
modelReqs: { backend: 'llamacpp', minSysMemory: 2, GPURequired: false, MinGPUVRAM: 2}
};
const model2: IModel = {
name: 'DeepSeek',
modelName: 'deepseek-coder-6.7b-instruct.gguf',
downloadUrl: 'https://huggingface.co/TheBloke/deepseek-coder-6.7B-instruct-GGUF/resolve/main/deepseek-coder-6.7b-instruct.Q4_K_M.gguf?download=true',
modelType: ModelType.GENERAL,
modelReqs: { backend: 'llamacpp', minSysMemory: 8, GPURequired: true, MinGPUVRAM: 8}
};

return [model1, model2];
}

const getModel = async (name: string): Promise<Model | undefined> => {
return supportedModels.find(model => model.name === name);
const getModel = async (name: string): Promise<IModel | undefined> => {
return DefaultModels().find(model => model.name === name);
}

const loadModel = async (modelname: string): Promise<void> => {
console.log(`Loading model ${modelname}`);
}
}

export { DefaultModels}
26 changes: 17 additions & 9 deletions libs/remix-ai-core/src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,35 @@
import exp from 'constants';
import { ModelType } from './constants';

export interface Model {
export interface IModelRequirements{
backend: string,
minSysMemory: number,
GPURequired: boolean,
MinGPUVRAM: number,
}

export interface IModel {
name: string;
download_url: string;
type: ModelType;
url: string;
downloadUrl: string;
modelName?: string;
modelType: ModelType;
modelReqs: IModelRequirements;
}

export interface ModelResponse {
export interface IModelResponse {
output: string;
error: string;
success: boolean;
model: Model;
model: IModel;
}

export interface ModelRequest {
export interface IModelRequest {
input: string;
model: Model;
model: IModel;
}

export interface InferenceModel {
model: Model;
model: IModel;
location: string;
isRemote: boolean;
}
Loading

0 comments on commit ea50608

Please sign in to comment.