diff --git a/package.json b/package.json index f559074..1d44165 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "jenkins-log-reader", "displayName": "AI Log Reader", "description": "Read jenkins log, analyse with local AI.", - "version": "0.8.20", + "version": "0.8.21", "engines": { "vscode": "^1.96.0" }, @@ -73,7 +73,9 @@ "gemma:latest", "phi3.5:latest", "phi4:latest", + "deepseek-r1:7b", "deepseek-r1:8b", + "deepseek-r1:14b", "mistral-small:latest", "mistral:7b" ], @@ -221,16 +223,16 @@ "prepare": "husky" }, "devDependencies": { - "@eslint/js": "^9.18.0", + "@eslint/js": "^9.19.0", "@types/glob": "^8.1.0", "@types/mocha": "^10.0.10", - "@types/node": "22.10.9", + "@types/node": "22.12.0", "@types/vscode": "^1.96.0", "@types/vscode-webview": "^1.57.5", "@vscode/l10n": "^0.0.18", "esbuild": "^0.24.2", "esbuild-plugin-copy": "^2.1.1", - "eslint": "^9.18.0", + "eslint": "^9.19.0", "eslint-config-prettier": "^10.0.1", "eslint-plugin-prettier": "^5.2.3", "glob": "^11.0.1", @@ -241,7 +243,7 @@ "react": "19.0.0", "react-dom": "19.0.0", "typescript": "^5.7.3", - "typescript-eslint": "^8.21.0" + "typescript-eslint": "^8.22.0" }, "dependencies": { "@tailwindcss/typography": "^0.5.16", @@ -251,7 +253,7 @@ "crypto": "^1.0.1", "marked": "^15.0.6", "ollama": "^0.5.12", - "openai": "^4.80.0", + "openai": "^4.80.1", "p-limit": "^6.2.0", "tailwindcss": "^3.4.17" }, diff --git a/src/extension.ts b/src/extension.ts index 529f603..d2a27b6 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -7,10 +7,9 @@ import { LogReaderSettingWebViewProvider } from "./LogReaderSettingWebViewProvid import { GroovyCodeFormat } from "./GroovyFormat"; import * as fs from "fs"; import { getImageAnalysis } from "./getInfoFromJenkins"; -import { exec } from "child_process"; -import pLimit from "p-limit"; +// import pLimit from "p-limit"; -const limit = pLimit(1); // at most, 3 concurrent tasks can be run at the same time +// const limit = pLimit(1); // at most, 3 concurrent tasks can be run at the same time export function activate(context: ExtensionContext) { const storagePath = context.globalStorageUri.fsPath; @@ -56,7 +55,7 @@ export function activate(context: ExtensionContext) { const imagePrompt = getConfig("jenkins-log-reader.imagePrompt"); - const videoPrompt = getConfig("jenkins-log-reader.videoPrompt"); + // const videoPrompt = getConfig("jenkins-log-reader.videoPrompt"); const settings = new JenkinsSettings( jenkinsServerUrl, @@ -105,139 +104,139 @@ function registerCommandOfFormatGrooby(context: ExtensionContext) { ); } -function registerCommandOfReadImages( - context: ExtensionContext, - provider: LogReaderResultWebViewProvider, - imageAiModel: string, - imagePrompt: string -) { - commands.registerCommand("jenkins-log-reader.readImages", async (uri: Uri) => { - // get image file - // turn it into base64 - // send to AI (llama3.2-vision) - // show result in result view - if (uri) { - // uri need to be a folder, then we check files one by one, only handle image files(check extension) - const dirItems = fs.readdir(uri.fsPath, (err, files) => { - if (err) { - console.error(err); - } else { - files - .filter((file) => { - return ( - file.toLowerCase().endsWith(".png") || - file.toLowerCase().endsWith(".jpg") || - file.toLowerCase().endsWith(".jpeg") || - file.toLowerCase().endsWith(".gif") || - file.toLowerCase().endsWith(".bmp") || - file.toLowerCase().endsWith(".webp") || - file.toLowerCase().endsWith(".tiff") || - file.toLowerCase().endsWith(".svg") - ); - }) - .map(async (file) => { - console.log("file: " + file); - const base64String = fs.readFileSync(uri.fsPath + "/" + file).toString("base64"); - const long_run_task = analyse_image( - base64String, - provider, - imageAiModel, - imagePrompt - ); - showStatusBarProgress( - long_run_task, - "Analysing the image..." + uri.fsPath + "/" + file - ); - }); - } - }); - } - }); -} - -function registerCommandOfReadVideos( - context: ExtensionContext, - provider: LogReaderResultWebViewProvider, - imageAiModel: string, - videoPrompt: string -) { - commands.registerCommand("jenkins-log-reader.readVideos", async (uri: Uri) => { - // get image file - // turn it into base64 - // send to AI (llama3.2-vision) - // show result in result view - if (uri) { - // uri need to be a folder, then we check files one by one, only handle video files(check extension) - fs.readdir(uri.fsPath, (err, files) => { - if (err) { - console.error(err); - } else { - files - .filter((file) => { - file.toLowerCase().endsWith(".mp4") || - file.toLowerCase().endsWith(".3pg") || - file.toLowerCase().endsWith(".mov") || - file.toLowerCase().endsWith(".ogg") || - file.toLowerCase().endsWith(".avi") || - file.toLowerCase().endsWith(".mpeg"); - }) - .map(async (file) => { - console.log("file: " + file); - }); - // const image_uri = uri; - // const base64String = fs.readFileSync(image_uri.fsPath).toString("base64"); - // const long_run_task = analyse_image(base64String, provider, imageAiModel, imagePrompt); - // showStatusBarProgress(long_run_task, "Analysing the image..."); - } - }); - } - }); -} - -function registerCommandOfReadVideo( - context: ExtensionContext, - provider: LogReaderResultWebViewProvider, - imageAiModel: string, - videoPrompt: string -) { - context.subscriptions.push( - commands.registerCommand("jenkins-log-reader.readVideo", async (uri: Uri) => { - const output_temp_dir = "/tmp/jenkins-log-reader/video/output/"; - if (!fs.existsSync(output_temp_dir)) { - fs.mkdirSync(output_temp_dir, { recursive: true }); - } else { - fs.rmSync(output_temp_dir, { recursive: true }); - fs.mkdirSync(output_temp_dir, { recursive: true }); - } - let tasks: any[] = []; - if (uri) { - const command = `ffmpeg -i ${uri.fsPath} -r 1/1 ${output_temp_dir}frame-%04d.png`; - console.log(command); - exec(command, (error: any, stdout: any, stderr: any): void => { - if (error) { - window.showErrorMessage(`Error: ${error.message}`, "error"); - return; - } - }); - console.log("after exec ffmpeg command"); - // for each file under the output_temp_dir, call analyse_image - - fs.readdirSync(output_temp_dir).forEach((file) => { - console.log("file: " + output_temp_dir + file); - const base64String = fs.readFileSync(output_temp_dir + file).toString("base64"); - const long_task = limit(() => - analyse_image(base64String, provider, imageAiModel, videoPrompt) - ); - tasks.push(long_task); - }); - - showStatusBarProgress(Promise.all(tasks), "Analysing the video..."); - console.log("after analysing finished, delete the output_temp_dir"); - // after analysing finished, delete the output_temp_dir ??? - } - }) - ); -} +// function registerCommandOfReadImages( +// context: ExtensionContext, +// provider: LogReaderResultWebViewProvider, +// imageAiModel: string, +// imagePrompt: string +// ) { +// commands.registerCommand("jenkins-log-reader.readImages", async (uri: Uri) => { +// // get image file +// // turn it into base64 +// // send to AI (llama3.2-vision) +// // show result in result view +// if (uri) { +// // uri need to be a folder, then we check files one by one, only handle image files(check extension) +// const dirItems = fs.readdir(uri.fsPath, (err, files) => { +// if (err) { +// console.error(err); +// } else { +// files +// .filter((file) => { +// return ( +// file.toLowerCase().endsWith(".png") || +// file.toLowerCase().endsWith(".jpg") || +// file.toLowerCase().endsWith(".jpeg") || +// file.toLowerCase().endsWith(".gif") || +// file.toLowerCase().endsWith(".bmp") || +// file.toLowerCase().endsWith(".webp") || +// file.toLowerCase().endsWith(".tiff") || +// file.toLowerCase().endsWith(".svg") +// ); +// }) +// .map(async (file) => { +// console.log("file: " + file); +// const base64String = fs.readFileSync(uri.fsPath + "/" + file).toString("base64"); +// const long_run_task = analyse_image( +// base64String, +// provider, +// imageAiModel, +// imagePrompt +// ); +// showStatusBarProgress( +// long_run_task, +// "Analysing the image..." + uri.fsPath + "/" + file +// ); +// }); +// } +// }); +// } +// }); +// } + +// function registerCommandOfReadVideos( +// context: ExtensionContext, +// provider: LogReaderResultWebViewProvider, +// imageAiModel: string, +// videoPrompt: string +// ) { +// commands.registerCommand("jenkins-log-reader.readVideos", async (uri: Uri) => { +// // get image file +// // turn it into base64 +// // send to AI (llama3.2-vision) +// // show result in result view +// if (uri) { +// // uri need to be a folder, then we check files one by one, only handle video files(check extension) +// fs.readdir(uri.fsPath, (err, files) => { +// if (err) { +// console.error(err); +// } else { +// files +// .filter((file) => { +// file.toLowerCase().endsWith(".mp4") || +// file.toLowerCase().endsWith(".3pg") || +// file.toLowerCase().endsWith(".mov") || +// file.toLowerCase().endsWith(".ogg") || +// file.toLowerCase().endsWith(".avi") || +// file.toLowerCase().endsWith(".mpeg"); +// }) +// .map(async (file) => { +// console.log("file: " + file); +// }); +// // const image_uri = uri; +// // const base64String = fs.readFileSync(image_uri.fsPath).toString("base64"); +// // const long_run_task = analyse_image(base64String, provider, imageAiModel, imagePrompt); +// // showStatusBarProgress(long_run_task, "Analysing the image..."); +// } +// }); +// } +// }); +// } + +// function registerCommandOfReadVideo( +// context: ExtensionContext, +// provider: LogReaderResultWebViewProvider, +// imageAiModel: string, +// videoPrompt: string +// ) { +// context.subscriptions.push( +// commands.registerCommand("jenkins-log-reader.readVideo", async (uri: Uri) => { +// const output_temp_dir = "/tmp/jenkins-log-reader/video/output/"; +// if (!fs.existsSync(output_temp_dir)) { +// fs.mkdirSync(output_temp_dir, { recursive: true }); +// } else { +// fs.rmSync(output_temp_dir, { recursive: true }); +// fs.mkdirSync(output_temp_dir, { recursive: true }); +// } +// const tasks: any[] = []; +// if (uri) { +// const command = `ffmpeg -i ${uri.fsPath} -r 1/1 ${output_temp_dir}frame-%04d.png`; +// console.log(command); +// exec(command, (error: any, stdout: any, stderr: any): void => { +// if (error) { +// window.showErrorMessage(`Error: ${error.message}`, "error"); +// return; +// } +// }); +// console.log("after exec ffmpeg command"); +// // for each file under the output_temp_dir, call analyse_image + +// fs.readdirSync(output_temp_dir).forEach((file) => { +// console.log("file: " + output_temp_dir + file); +// const base64String = fs.readFileSync(output_temp_dir + file).toString("base64"); +// const long_task = limit(() => +// analyse_image(base64String, provider, imageAiModel, videoPrompt) +// ); +// tasks.push(long_task); +// }); + +// showStatusBarProgress(Promise.all(tasks), "Analysing the video..."); +// console.log("after analysing finished, delete the output_temp_dir"); +// // after analysing finished, delete the output_temp_dir ??? +// } +// }) +// ); +// } function registerCommandOfReadImage( context: ExtensionContext,