mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2025-01-29 15:44:12 +00:00
Added code execution
This commit is contained in:
parent
1704575ac8
commit
5d8e8c7fcc
@ -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
33
app.py
@ -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"
|
||||
|
@ -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:"
|
||||
}
|
@ -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
2
web/dist/index.html
vendored
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user