From a3739aa934c74a6293c118ebf7d957188af215fe Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 11 Feb 2025 20:04:52 -0800 Subject: [PATCH] add mycop in addition to code complete Signed-off-by: Nikolaj Bjorner --- genaisrc/codecomplete.genai.mts | 149 ++++++++++++++++++++++++++++++++ genaisrc/genaiscript.d.ts | Bin 78662 -> 127269 bytes genaisrc/mycop.genai.mts | 76 ++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 genaisrc/codecomplete.genai.mts create mode 100644 genaisrc/mycop.genai.mts diff --git a/genaisrc/codecomplete.genai.mts b/genaisrc/codecomplete.genai.mts new file mode 100644 index 000000000..a1217cfe6 --- /dev/null +++ b/genaisrc/codecomplete.genai.mts @@ -0,0 +1,149 @@ + +script({ + title: "Invoke LLM completion for code snippets", +}) + + +import * as fs from 'fs'; +import * as path from 'path'; + + +async function runCodePrompt(role, message, code) { + const answer = await runPrompt( + (_) => { + _.def("ROLE", role); + _.def("REQUEST", message); + _.def("CODE", code); + _.$`Your role is . + The request is given by + original code snippet: + .` + } + ) + console.log(answer.text); + return answer.text; +} + +async function invokeLLMCompletion(code, prefix) { + + let role = `You are a highly experienced compiler engineer with over 20 years of expertise, + specializing in C and C++ programming. Your deep knowledge of best coding practices + and software engineering principles enables you to produce robust, efficient, and + maintainable code in any scenario.`; + + let userMessage = `Please complete the provided C/C++ code to ensure it is compilable and executable. + Return only the fully modified code while preserving the original logic. + Add any necessary stubs, infer data types, and make essential changes to enable + successful compilation and execution. Avoid unnecessary code additions. + Ensure the final code is robust, secure, and adheres to best practices.`; + + return runCodePrompt(role, userMessage, code); +} + +async function invokeLLMAnalyzer(code, inputFilename, funcName) { + // Define the llm role + let role = + `You are a highly experienced compiler engineer with over 20 years of expertise, + specializing in C and C++ programming. Your deep knowledge of best coding practices + and software engineering principles enables you to produce robust, efficient, and + maintainable code in any scenario.`; + + // Define the message to send + let userMessage = + `Please analyze the provided C/C++ code and identify any potential issues, bugs, or opportunities for performance improvement. For each observation: + + - Clearly describe the issue or inefficiency. + - Explain the reasoning behind the problem or performance bottleneck. + - Suggest specific code changes or optimizations, including code examples where applicable. + - Ensure recommendations follow best practices for efficiency, maintainability, and correctness. + + At the end of the analysis, provide a detailed report in **Markdown format** summarizing: + + 1. **Identified Issues and Their Impact:** + - Description of each issue and its potential consequences. + + 2. **Suggested Fixes (with Code Examples):** + - Detailed code snippets showing the recommended improvements. + + 3. **Performance Improvement Recommendations:** + - Explanation of optimizations and their expected benefits. + + 4. **Additional Insights or Best Practices:** + - Suggestions to further enhance the code's quality and maintainability.`; + + return runCodePrompt(role, userMessage, code); + } + +async function createGitUpdateRequest(src_directory : string, filename : string, modifiedCode : string) { + // extract relative path from filename after slice_directory, extract function and source file name. + // Relative path: code_slices\ast\sls\orig_sls_smt_solver.cpp_updt_params.cpp file name: orig_sls_smt.cpp + const regex = /code_slices\\(.*)\\([^_]*)_(.*)\.cpp_(.*)\.cpp/; + const match = filename.match(regex); + if (!match) { + console.log(`Filename does not match expected pattern: ${filename}`); + return ""; + } + const [_, relative_path, prefix, fileName, funcName] = match; + + console.log(`Relative path: ${relative_path} file name: ${fileName}.cpp`); + + const srcFilePath = path.join(src_directory, relative_path, fileName + ".cpp"); + const srcFileContent = await workspace.readText(srcFilePath); + + let role = + `You are a highly experienced compiler engineer with over 20 years of expertise, + specializing in C and C++ programming. Your deep knowledge of best coding practices + and software engineering principles enables you to produce robust, efficient, and + maintainable code in any scenario.`; + + const answer = await runPrompt( + (_) => { + _.def("ROLE", role); + _.def("SOURCE", srcFileContent); + _.def("REVIEW", modifiedCode); + _.def("FUNCTION", funcName); + _.$`Your role is . + Please create a well-formed git patch based on the source code given in + + A code analysis is for the method or function . + The analysis is he following: + ` + } + ) + console.log(answer.text); + return answer.text; +} + +const input_directory = "code_slices"; +const output_directory = "code_slices_analyzed"; +const src_directory = "src"; +const code_slice_files = await workspace.findFiles("code_slices/**/*.cpp"); + +let count = 0; +for (const file of code_slice_files) { + if (path.extname(file.filename) === '.cpp') { + console.log(`Processing file: ${file.filename}`); + + const regex = /(.*)_(.*)\.cpp_(.*)\.cpp/; + const match = file.filename.match(regex); + + if (!match) { + console.log(`Filename does not match expected pattern: ${file.filename}`); + continue; + } + const [_, prefix, fileName, funcName] = match; + + const content = file.content; + const answer1 = await invokeLLMCompletion(content, fileName); + const answer2 = await invokeLLMAnalyzer(answer1, fileName, funcName); + const outputFilePath = path.join(output_directory, fileName + "_" + funcName + ".md"); + await workspace.writeText(outputFilePath, answer2); + const answer3 = await createGitUpdateRequest(src_directory, file.filename, answer2); + const outputFilePath2 = path.join(output_directory, fileName + "_" + funcName + ".patch"); + await workspace.writeText(outputFilePath2, answer3); + ++count; + if (count > 3) + break; + } +} + diff --git a/genaisrc/genaiscript.d.ts b/genaisrc/genaiscript.d.ts index e11a3edd76e417e0aa88b2dc42a15e63ac4c0898..94df8d9efe6fd0e158c4766ef464361ffb2e9e1d 100644 GIT binary patch literal 127269 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

NDpqMJs?-@b0leO%VXZbPcYQxDaxF& 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 delta 3969 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 diff --git a/genaisrc/mycop.genai.mts b/genaisrc/mycop.genai.mts new file mode 100644 index 000000000..5ab897313 --- /dev/null +++ b/genaisrc/mycop.genai.mts @@ -0,0 +1,76 @@ + +script({ + title: "Invoke LLM code update", +}) + + +async function runCodePrompt(role, message, code) { + const answer = await runPrompt( + (_) => { + _.def("ROLE", role); + _.def("REQUEST", message); + _.def("CODE", code); + _.$`Your role is . + The request is given by + original code: + .` + } + ) + console.log(answer.text); + return answer.text; +} + +async function invokeLLMUpdate(code, inputFile) { + + let role = `You are a highly experienced compiler engineer with over 20 years of expertise, + specializing in C and C++ programming. Your deep knowledge of best coding practices + and software engineering principles enables you to produce robust, efficient, and + maintainable code in any scenario.`; + + let userMessage = `Please modify the original code to ensure that it enforces the following: + - do not use pointer arithmetic. + - do not introduce uses of std::vector. + - only make replacements that are compatible with the ones listed below. + - add white space between operators: + For example: + i=0 + by + i = 0 + For example + a+b + by + a + b + - remove brackets around single statements: + For example: + { break; } + by + break; + - replaces uses of for loops using begin(), end() iterator patterns by C++21 style for loops + For example replace + for (auto it = x.begin(), end = x.end(); it != end; ++it) + by + for (auto & e : x) + + For example, replace + for (unsigned i = 0; i < a->get_num_args(); ++i) { + expr* arg = a->get_arg(i); + ... + } + by + for (auto arg : *a) { + ... + } + `; + + return runCodePrompt(role, userMessage, code); +} + + +const inputFile = env.files[0]; +const file = await workspace.readText(inputFile); +const answer = await invokeLLMUpdate(file.content, inputFile); +// Extract the code from the answer by removing ```cpp and ```: +let code = answer.replace(/```cpp/g, "").replace(/```/g, ""); +const outputFile = inputFile.filename + ".patch"; +await workspace.writeText(outputFile, code); +