Added code execution

This commit is contained in:
Saifeddine ALOUI 2023-08-20 00:12:08 +02:00
parent 1704575ac8
commit 5d8e8c7fcc
8 changed files with 235 additions and 63 deletions

View File

@ -517,6 +517,28 @@ class LoLLMsAPPI(LollmsApplication):
self.socketio.sleep(0)
self.busy = False
@self.socketio.on('execute_python_code')
def execute_python_code(data):
"""Executes Python code and returns the output."""
client_id = request.sid
code = data["code"]
# Import the necessary modules.
import io
import sys
import time
# Create a Python interpreter.
interpreter = io.StringIO()
sys.stdout = interpreter
# Execute the code.
start_time = time.time()
exec(code)
end_time = time.time()
# Get the output.
output = interpreter.getvalue()
self.socketio.emit("execution_output", {"output":output,"execution_time":end_time - start_time}, room=client_id)
# A copy of the original lollms-server generation code needed for playground
@self.socketio.on('generate_text')
@ -935,7 +957,7 @@ class LoLLMsAPPI(LollmsApplication):
if self.config["debug"]:
ASCIIColors.yellow(discussion_messages)
ASCIIColors.info(f"prompt size:{tokens.shape} tokens")
ASCIIColors.info(f"prompt size:{len(tokens)} tokens")
return discussion_messages, message.content, tokens

33
app.py
View File

@ -285,6 +285,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
self.add_endpoint("/", "", self.index, methods=["GET"])
self.add_endpoint("/settings/", "", self.index, methods=["GET"])
self.add_endpoint("/playground/", "", self.index, methods=["GET"])
self.add_endpoint("/<path:filename>", "serve_static", self.serve_static, methods=["GET"])
self.add_endpoint("/user_infos/<path:filename>", "serve_user_infos", self.serve_user_infos, methods=["GET"])
@ -415,7 +416,37 @@ class LoLLMsWebUI(LoLLMsAPPI):
self.add_endpoint(
"/save_presets", "save_presets", self.save_presets, methods=["POST"]
)
)
self.add_endpoint(
"/execute_python_code", "execute_python_code", self.execute_python_code, methods=["POST"]
)
def execute_python_code(self):
"""Executes Python code and returns the output."""
data = request.get_json()
code = data["code"]
# Import the necessary modules.
import io
import sys
import time
# Create a Python interpreter.
interpreter = io.StringIO()
sys.stdout = interpreter
# Execute the code.
start_time = time.time()
try:
exec(code)
# Get the output.
output = interpreter.getvalue()
except Exception as ex:
output = str(ex)
end_time = time.time()
return jsonify({"output":output,"execution_time":end_time - start_time})
def get_presets(self):
presets_file = self.lollms_paths.personal_databases_path/"presets.json"

View File

@ -1,9 +1,15 @@
{
"Writing a Book in Latex": "<Add some context information to give the AI some context about the book or leave blank if you have no specific idea>\n```latex\n\\documentclass[12pt]{book}\n\\usepackage{url}\n\\begin{document}\n\\title{<Put the title of the book here>}\n\\author{<Put the author name here>} % Author\n\\date{\\today} % Date\n\\maketitle\n\\tableofcontents\n\\chapter{Introduction}\n<Add any required text then press generate to push the AI to build your book>\n",
"Simple Book writing":"Once apon a time",
"Simple Question Answer":"User:<Put your question here>\nAssistant:",
"Question Answer with conditionning":"Assistant is a highly developed AI capable of answering any question about any subject.\nUser:<Put your question here>\nAssistant:",
"Instruct mode": "Instructions:\n<Put your instructions here>\nAnswer:",
"Make a python function": "Here is a python function that <describe the function you want lollms to build>:\n```python\ndef",
"Make a c++ function": "Here is a python function that <describe the function you want lollms to build>:\n```c++\n/*"
"Build a Latex Book": "@<Add some context information to give the AI some context about the book or leave blank if you have no specific idea>@\n```latex\n\\documentclass[12pt]{book}\n\\usepackage{url}\n\\begin{document}\n\\title{@<Put the title of the book here>@}\n\\author{@<Put the author name here>@} % Author\n\\date{\\today} % Date\n\\maketitle\n\\tableofcontents\n\\chapter{Introduction}\n@<Add any required text then press generate to push the AI to build your book>@\n\\end{document}\n```", "Simple Book writing":"Once apon a time",
"Simple Question Answer":"User:@<Put your question here>@\nAssistant:",
"Question Answer with conditionning":"Assistant is a highly developed AI capable of answering any question about any subject.\nUser:@<Put your question here>\nAssistant:",
"Instruct mode": "Instructions:\n@<Put your instructions here>@\nAnswer:",
"Make a python function": "Here is a python function that @<describe the function you want lollms to build>@:\n```python\ndef",
"Make a c++ function": "Here is a c++ function that @<describe the function you want lollms to build>@:\n```c++\n/*",
"Make a c# function": "Here is a c# function that @<describe the function you want lollms to build>@:\n```c#\n/*",
"Make a objective-c function": "Here is a objective-c function that @<describe the function you want lollms to build>@:\n```objective-c\n/*",
"Make a java function": "Here is a java function that @<describe the function you want lollms to build>@:\n```java\n/*",
"Make a visual basic.net function": "Here is a visual basic function that <describe the function you want lollms to build>@:\n```vb.net\n/*",
"Make a vue.js ui": "Here is a vue.js template that @<describe the user interface you want to make with this>@:\n```vue.js\n<template>",
"Make a HTML5 ui": "Here is a HTML5 ui that @<describe the user interface you want to make with this>@:\n```html",
"Explain code": "```@<the name of the programming language>\n@<put your code here>@\n```\nHere is an explanation of the previous method:"
}

View File

@ -54,6 +54,15 @@ Content-Type: application/json
"setting_value": "english"
}
############################################
### execute code
############################################
POST http://localhost:9600/execute_python_code
Content-Type: application/json
{
"code": "print('hello world')"
}
############################################
### Get all personalities
############################################
GET http://localhost:9600/get_all_personalities

File diff suppressed because one or more lines are too long

2
web/dist/index.html vendored
View File

@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LoLLMS WebUI - Welcome</title>
<script type="module" crossorigin src="/assets/index-e5fd08e6.js"></script>
<script type="module" crossorigin src="/assets/index-31e94240.js"></script>
<link rel="stylesheet" href="/assets/index-90cbdba9.css">
</head>
<body>

View File

@ -53,12 +53,27 @@ const markdownIt = new MarkdownIt('commonmark', {
id +
')">Copied!</span>' +
'</button>' +
'<button class="px-2 py-1 ml-10 mb-2 text-left p-2 text-sm font-medium bg-bg-dark-tone-panel dark:bg-bg-dark-tone rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200">' +
'<span class="mr-1" id="exec-btn_' +
id +
'" onclick="executeCode(' +
id +
')">Execute</span>'+
'</button>' +
'<pre class="hljs p-1 rounded-md break-all grid grid-cols-1">' +
'<code id="code_' +
id +
'" class="overflow-x-auto break-all scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary">' +
highlightedCode +
'</code>' +
'<code id="code_exec_' +
id +
'" class="overflow-x-auto hidden break-all scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary">' +
'</code>' +
'</pre>' +
'</div>'
);
@ -66,6 +81,14 @@ const markdownIt = new MarkdownIt('commonmark', {
console.error(`Syntax highlighting failed for language '${lang}':`, error);
}
}
let btn_exec_txt = lang=='python'?'<button class="px-2 py-1 ml-10 mb-2 text-left p-2 text-sm font-medium bg-bg-dark-tone-panel dark:bg-bg-dark-tone rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200">' +
'<span class="mr-1" id="exec-btn_' +
id +
'" onclick="executeCode(' +
id +
')">Execute</span>'+
'</button>':''
let codeString =
'<div class="bg-bg-light-tone-panel dark:bg-bg-dark-tone-panel p-2 rounded-lg shadow-sm">' +
lang +
@ -81,12 +104,20 @@ const markdownIt = new MarkdownIt('commonmark', {
id +
')">Copied!</span>' +
'</button>' +
btn_exec_txt +
'<pre class="hljs p-1 rounded-md break-all grid grid-cols-1">' +
'<code id="code_' +
id +
'" class="overflow-x-auto break-all scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary">' +
hljs.highlightAuto(str).value +
'</code>' +
'<code id="code_exec_' +
id +
'" class="overflow-x-auto hidden break-all scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary">' +
'</code>' +
'</pre>' +
'</div>';
return codeString;
@ -158,6 +189,7 @@ export default {
mounted() {
const script = document.createElement('script');
script.textContent = `
// Your inline script code here
function copyContentToClipboard(id) {
console.log("copied");
@ -173,6 +205,32 @@ export default {
document.execCommand('copy');
window.getSelection().removeAllRanges();
}
function executeCode(id) {
const codeElement = document.getElementById('code_' + id);
const codeExecElement = document.getElementById('code_exec_' + id);
codeExecElement.classList.remove('hidden');
const code = codeElement.innerText
const json = JSON.stringify({ 'code': code })
console.log(json)
fetch('http://localhost:9600/execute_python_code', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: json
}).then(response=>{
// Parse the JSON data from the response body
return response.json();
})
.then(jsonData => {
// Now you can work with the JSON data
console.log(jsonData);
codeExecElement.innerText=jsonData.output
})
.catch(error => {
// Handle any errors that occurred during the fetch process
console.error('Fetch error:', error);
});
}
`;
script.async = true; // Set to true if the script should be loaded asynchronously
document.body.appendChild(script);

View File

@ -1,10 +1,10 @@
<template>
<div class="container bg-bg-light dark:bg-bg-dark shadow-lg overflow-y-auto scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary">
<div class="container flex flex-row m-2 border-2">
<div class="container flex flex-row m-2">
<div class="flex-grow m-2">
<div class="mt-4 d-flex justify-content-space-between flex-row">
<div class="flex-grow m-2 p-2 border border-blue-300 rounded-md border-2 border-blue-300 m-2 p-4">
<label class="mt-2">Presets</label>
<select v-model="selectedPreset" class="w-25 m-2 border-2 rounded-md shadow-sm">
<select v-model="selectedPreset" class="m-2 border-2 rounded-md shadow-sm w-full">
<option v-for="preset in Object.keys(presets)" :key="preset" :value="preset">
{{ preset }}
</option>
@ -17,7 +17,8 @@
</div>
<div class="flex-grow m-2 p-2 border border-blue-300 rounded-md border-2 border-blue-300 m-2 p-4">
<textarea v-model="text" id="text_element" class="mt-4 h-64 overflow-y-scroll w-full dark:bg-bg-dark" type="text"></textarea>
<textarea v-model="text" id="text_element" class="mt-4 h-64 overflow-y-scroll w-full dark:bg-bg-dark scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary" type="text"></textarea>
<span>Cursor position {{ cursorPosition }}</span>
</div>
<div class="flex justify-between">
<div class="m-0">
@ -31,7 +32,7 @@
</MarkdownRenderer>
</div>
</div>
<div id="settings" class="border border-blue-300 bg-blue-200 mt-4 w-25 mr-2 h-full mb-10" style="align-items: center; height: fit-content; margin: 10px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); border-radius: 4px;">
<div id="settings" class="border border-blue-300 bg-blue-200 mt-4 w-25 mr-2 h-full mb-10 min-w-500" style="align-items: center; height: fit-content; margin: 10px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); border-radius: 4px;">
<div id="title" class="border border-blue-600 bg-blue-300 m-0 flex justify-center items-center box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) border-radius: 4px;">
<h3 class="text-gray-600 mb-4 text-center m-0">Settings</h3>
</div>
@ -94,8 +95,11 @@ export default {
return {
generating:false,
presets:{},
selectedPreset: '',
selectedPreset: '',
cursorPosition:0,
text:"",
pre_text:"",
post_text:"",
temperature: 0.1,
top_k: 50,
top_p: 0.9,
@ -111,13 +115,14 @@ export default {
MarkdownRenderer
},
mounted() {
//console.log('chatbox mnt',this.$refs)
this.$nextTick(() => {
feather.replace();
});
},
created(){
axios.get('./presets.json').then(response => {
const text_element = document.getElementById('text_element');
text_element.addEventListener('keypress', () => {
this.cursorPosition = text_element.selectionStart;
});
text_element.addEventListener('click', () => {
this.cursorPosition = text_element.selectionStart;
});
axios.get('./presets.json').then(response => {
console.log(response.data)
this.presets=response.data
}).catch(ex=>{
@ -126,6 +131,8 @@ export default {
// Event handler for receiving generated text chunks
socket.on('text_chunk', data => {
this.appendToOutput(data.chunk);
const text_element = document.getElementById('text_element');
text_element.scrollTo(0, text_element.scrollHeight);
});
// Event handler for receiving generated text chunks
@ -154,7 +161,6 @@ export default {
socket.on('buzzy', error => {
console.error('Server is busy. Wait for your turn', error);
this.$refs.toast.showToast(`Error: ${error.message}`,4,false)
this.$refs.text_element.scrollTop = this.$refs.text_element.scrollHeight;
// Toggle button visibility
this.generating=false
});
@ -166,15 +172,28 @@ export default {
console.log("Generation canceled OK")
});
//console.log('chatbox mnt',this.$refs)
this.$nextTick(() => {
feather.replace();
});
},
created(){
},
methods:{
getCursorPosition() {
return this.cursorPosition;
},
appendToOutput(chunk){
this.text += chunk
this.pre_text += chunk
this.text = this.pre_text + this.post_text
},
generate(){
var prompt = this.text
console.log("Finding cursor position")
this.pre_text = this.text.substring(0,this.getCursorPosition())
this.post_text = this.text.substring(this.getCursorPosition(), this.text.length)
var prompt = this.text.substring(0,this.getCursorPosition())
console.log(prompt)
// Trigger the 'generate_text' event with the prompt
socket.emit('generate_text', { prompt: prompt, personality: -1, n_predicts: this.n_predicts , n_crop: this.n_crop,