mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2024-12-18 20:17:50 +00:00
enhanced
This commit is contained in:
parent
2b959c7b76
commit
5491bff53a
@ -94,11 +94,11 @@ async def execute_code(request: CodeRequest):
|
|||||||
if language=="javascript":
|
if language=="javascript":
|
||||||
ASCIIColors.info("Executing javascript code:")
|
ASCIIColors.info("Executing javascript code:")
|
||||||
ASCIIColors.yellow(code)
|
ASCIIColors.yellow(code)
|
||||||
return execute_javascript(code)
|
return execute_javascript(code, client, message_id)
|
||||||
if language in ["html","html5","svg"]:
|
if language in ["html","html5","svg"]:
|
||||||
ASCIIColors.info("Executing javascript code:")
|
ASCIIColors.info("Executing javascript code:")
|
||||||
ASCIIColors.yellow(code)
|
ASCIIColors.yellow(code)
|
||||||
return execute_html(code)
|
return execute_html(code, client, message_id)
|
||||||
|
|
||||||
elif language=="latex":
|
elif language=="latex":
|
||||||
ASCIIColors.info("Executing latex code:")
|
ASCIIColors.info("Executing latex code:")
|
||||||
@ -111,18 +111,78 @@ async def execute_code(request: CodeRequest):
|
|||||||
elif language in ["mermaid"]:
|
elif language in ["mermaid"]:
|
||||||
ASCIIColors.info("Executing mermaid code:")
|
ASCIIColors.info("Executing mermaid code:")
|
||||||
ASCIIColors.yellow(code)
|
ASCIIColors.yellow(code)
|
||||||
return execute_mermaid(code)
|
return execute_mermaid(code, client, message_id)
|
||||||
elif language in ["graphviz","dot"]:
|
elif language in ["graphviz","dot"]:
|
||||||
ASCIIColors.info("Executing graphviz code:")
|
ASCIIColors.info("Executing graphviz code:")
|
||||||
ASCIIColors.yellow(code)
|
ASCIIColors.yellow(code)
|
||||||
return execute_graphviz(code)
|
return execute_graphviz(code, client, message_id)
|
||||||
return {"status": False, "error": "Unsupported language", "execution_time": 0}
|
return {"status": False, "error": "Unsupported language", "execution_time": 0}
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
trace_exception(ex)
|
trace_exception(ex)
|
||||||
lollmsElfServer.error(ex)
|
lollmsElfServer.error(ex)
|
||||||
return {"status":False,"error":str(ex)}
|
return {"status":False,"error":str(ex)}
|
||||||
|
|
||||||
|
@router.post("/execute_code_in_new_tab")
|
||||||
|
async def execute_code_in_new_tab(request: CodeRequest):
|
||||||
|
"""
|
||||||
|
Executes Python code and returns the output.
|
||||||
|
|
||||||
|
:param request: The HTTP request object.
|
||||||
|
:return: A JSON response with the status of the operation.
|
||||||
|
"""
|
||||||
|
client = check_access(lollmsElfServer, request.client_id)
|
||||||
|
if lollmsElfServer.config.headless_server_mode:
|
||||||
|
return {"status":False,"error":"Code execution is blocked when in headless mode for obvious security reasons!"}
|
||||||
|
|
||||||
|
forbid_remote_access(lollmsElfServer, "Code execution is blocked when the server is exposed outside for very obvious reasons!")
|
||||||
|
if not lollmsElfServer.config.turn_on_code_execution:
|
||||||
|
return {"status":False,"error":"Code execution is blocked by the configuration!"}
|
||||||
|
|
||||||
|
if lollmsElfServer.config.turn_on_code_validation:
|
||||||
|
if not show_yes_no_dialog("Validation","Do you validate the execution of the code?"):
|
||||||
|
return {"status":False,"error":"User refused the execution!"}
|
||||||
|
|
||||||
|
try:
|
||||||
|
code = request.code
|
||||||
|
discussion_id = request.discussion_id
|
||||||
|
message_id = request.message_id
|
||||||
|
language = request.language
|
||||||
|
|
||||||
|
if language=="python":
|
||||||
|
ASCIIColors.info("Executing python code:")
|
||||||
|
ASCIIColors.yellow(code)
|
||||||
|
return execute_python(code, client, message_id, True)
|
||||||
|
if language=="javascript":
|
||||||
|
ASCIIColors.info("Executing javascript code:")
|
||||||
|
ASCIIColors.yellow(code)
|
||||||
|
return execute_javascript(code, client, message_id, True)
|
||||||
|
if language in ["html","html5","svg"]:
|
||||||
|
ASCIIColors.info("Executing javascript code:")
|
||||||
|
ASCIIColors.yellow(code)
|
||||||
|
return execute_html(code, client, message_id, True)
|
||||||
|
|
||||||
|
elif language=="latex":
|
||||||
|
ASCIIColors.info("Executing latex code:")
|
||||||
|
ASCIIColors.yellow(code)
|
||||||
|
return execute_latex(code, client, message_id, True)
|
||||||
|
elif language in ["bash","shell","cmd","powershell"]:
|
||||||
|
ASCIIColors.info("Executing shell code:")
|
||||||
|
ASCIIColors.yellow(code)
|
||||||
|
return execute_bash(code, client)
|
||||||
|
elif language in ["mermaid"]:
|
||||||
|
ASCIIColors.info("Executing mermaid code:")
|
||||||
|
ASCIIColors.yellow(code)
|
||||||
|
return execute_mermaid(code, client, message_id, True)
|
||||||
|
elif language in ["graphviz","dot"]:
|
||||||
|
ASCIIColors.info("Executing graphviz code:")
|
||||||
|
ASCIIColors.yellow(code)
|
||||||
|
return execute_graphviz(code, client, message_id, True)
|
||||||
|
return {"status": False, "error": "Unsupported language", "execution_time": 0}
|
||||||
|
except Exception as ex:
|
||||||
|
trace_exception(ex)
|
||||||
|
lollmsElfServer.error(ex)
|
||||||
|
return {"status":False,"error":str(ex)}
|
||||||
|
|
||||||
|
|
||||||
class FilePath(BaseModel):
|
class FilePath(BaseModel):
|
||||||
path: Optional[str] = Field(None, max_length=500)
|
path: Optional[str] = Field(None, max_length=500)
|
||||||
|
@ -799,6 +799,22 @@ class LOLLMSWebUI(LOLLMSElfServer):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def send_refresh(self, client_id):
|
||||||
|
client = self.session.get_client(client_id)
|
||||||
|
run_async(
|
||||||
|
partial(self.sio.emit,'update_message', {
|
||||||
|
"sender": client.discussion.current_message.sender,
|
||||||
|
'id':client.discussion.current_message.id,
|
||||||
|
'content': client.discussion.current_message.content,
|
||||||
|
'discussion_id':client.discussion.discussion_id,
|
||||||
|
'message_type': client.discussion.current_message.message_type,
|
||||||
|
'created_at':client.discussion.current_message.created_at,
|
||||||
|
'started_generating_at': client.discussion.current_message.started_generating_at,
|
||||||
|
'finished_generating_at': client.discussion.current_message.finished_generating_at,
|
||||||
|
'nb_tokens': client.discussion.current_message.nb_tokens,
|
||||||
|
}, to=client_id
|
||||||
|
)
|
||||||
|
)
|
||||||
def update_message(self, client_id, chunk,
|
def update_message(self, client_id, chunk,
|
||||||
parameters=None,
|
parameters=None,
|
||||||
metadata=[],
|
metadata=[],
|
||||||
@ -1129,6 +1145,7 @@ class LOLLMSWebUI(LOLLMSElfServer):
|
|||||||
client.discussion.load_message(message_id)
|
client.discussion.load_message(message_id)
|
||||||
client.generated_text = message.content
|
client.generated_text = message.content
|
||||||
else:
|
else:
|
||||||
|
self.send_refresh(client_id)
|
||||||
self.new_message(client_id, self.personality.name, "")
|
self.new_message(client_id, self.personality.name, "")
|
||||||
self.update_message(client_id, "✍ warming up ...", msg_type=MSG_TYPE.MSG_TYPE_STEP_START)
|
self.update_message(client_id, "✍ warming up ...", msg_type=MSG_TYPE.MSG_TYPE_STEP_START)
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import time
|
|||||||
import subprocess
|
import subprocess
|
||||||
import json
|
import json
|
||||||
from lollms.client_session import Client
|
from lollms.client_session import Client
|
||||||
|
from lollms.utilities import discussion_path_2_url
|
||||||
|
|
||||||
|
|
||||||
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
||||||
@ -68,6 +69,23 @@ def build_graphviz_output(code, ifram_name="unnamed"):
|
|||||||
execution_time = time.time() - start_time
|
execution_time = time.time() - start_time
|
||||||
return {"output": rendered, "execution_time": execution_time}
|
return {"output": rendered, "execution_time": execution_time}
|
||||||
|
|
||||||
def execute_graphviz(code):
|
def execute_graphviz(code, client:Client, message_id, build_file=False):
|
||||||
|
if build_file:
|
||||||
|
# Start the timer.
|
||||||
|
start_time = time.time()
|
||||||
|
if not "http" in lollmsElfServer.config.host and not "https" in lollmsElfServer.config.host:
|
||||||
|
host = "http://"+lollmsElfServer.config.host
|
||||||
|
else:
|
||||||
|
host = lollmsElfServer.config.host
|
||||||
|
|
||||||
return build_graphviz_output(code)
|
# Create a temporary file.
|
||||||
|
root_folder = client.discussion.discussion_folder
|
||||||
|
root_folder.mkdir(parents=True,exist_ok=True)
|
||||||
|
tmp_file = root_folder/f"ai_code_{message_id}.html"
|
||||||
|
with open(tmp_file,"w",encoding="utf8") as f:
|
||||||
|
f.write(build_graphviz_output(code))
|
||||||
|
link = f"{host}:{lollmsElfServer.config.port}/{discussion_path_2_url(tmp_file)}"
|
||||||
|
output_json = {"output": f'<b>Page built successfully</b><br><a href="{link}" target="_blank">Press here to view the page</a>', "execution_time": execution_time}
|
||||||
|
return output_json
|
||||||
|
else:
|
||||||
|
return build_graphviz_output(code)
|
||||||
|
@ -12,6 +12,7 @@ import time
|
|||||||
import subprocess
|
import subprocess
|
||||||
import json
|
import json
|
||||||
from lollms.client_session import Client
|
from lollms.client_session import Client
|
||||||
|
from lollms.utilities import discussion_path_2_url
|
||||||
|
|
||||||
|
|
||||||
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
||||||
@ -40,5 +41,25 @@ def build_html_output(code, ifram_name="unnamed"):
|
|||||||
execution_time = time.time() - start_time
|
execution_time = time.time() - start_time
|
||||||
return {"output": rendered, "execution_time": execution_time}
|
return {"output": rendered, "execution_time": execution_time}
|
||||||
|
|
||||||
def execute_html(code):
|
def execute_html(code, client:Client, message_id, build_file=False):
|
||||||
return build_html_output(code)
|
if build_file:
|
||||||
|
# Start the timer.
|
||||||
|
start_time = time.time()
|
||||||
|
if not "http" in lollmsElfServer.config.host and not "https" in lollmsElfServer.config.host:
|
||||||
|
host = "http://"+lollmsElfServer.config.host
|
||||||
|
else:
|
||||||
|
host = lollmsElfServer.config.host
|
||||||
|
|
||||||
|
# Create a temporary file.
|
||||||
|
root_folder = client.discussion.discussion_folder
|
||||||
|
root_folder.mkdir(parents=True,exist_ok=True)
|
||||||
|
tmp_file = root_folder/f"ai_code_{message_id}.html"
|
||||||
|
with open(tmp_file,"w",encoding="utf8") as f:
|
||||||
|
f.write(code)
|
||||||
|
link = f"{host}:{lollmsElfServer.config.port}/{discussion_path_2_url(tmp_file)}"
|
||||||
|
# Stop the timer.
|
||||||
|
execution_time = time.time() - start_time
|
||||||
|
output_json = {"output": f'<b>Page built successfully</b><br><a href="{link}" target="_blank">Press here to view the page</a>', "execution_time": execution_time}
|
||||||
|
return output_json
|
||||||
|
else:
|
||||||
|
return build_html_output(code)
|
@ -12,6 +12,7 @@ import time
|
|||||||
import subprocess
|
import subprocess
|
||||||
import json
|
import json
|
||||||
from lollms.client_session import Client
|
from lollms.client_session import Client
|
||||||
|
from lollms.utilities import discussion_path_2_url
|
||||||
|
|
||||||
|
|
||||||
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
||||||
@ -49,5 +50,23 @@ def build_javascript_output(code, ifram_name="unnamed"):
|
|||||||
execution_time = time.time() - start_time
|
execution_time = time.time() - start_time
|
||||||
return {"output": rendered, "execution_time": execution_time}
|
return {"output": rendered, "execution_time": execution_time}
|
||||||
|
|
||||||
def execute_javascript(code):
|
def execute_javascript(code, client:Client, message_id, build_file=False):
|
||||||
return build_javascript_output(code)
|
if build_file:
|
||||||
|
# Start the timer.
|
||||||
|
start_time = time.time()
|
||||||
|
if not "http" in lollmsElfServer.config.host and not "https" in lollmsElfServer.config.host:
|
||||||
|
host = "http://"+lollmsElfServer.config.host
|
||||||
|
else:
|
||||||
|
host = lollmsElfServer.config.host
|
||||||
|
|
||||||
|
# Create a temporary file.
|
||||||
|
root_folder = client.discussion.discussion_folder
|
||||||
|
root_folder.mkdir(parents=True,exist_ok=True)
|
||||||
|
tmp_file = root_folder/f"ai_code_{message_id}.html"
|
||||||
|
with open(tmp_file,"w",encoding="utf8") as f:
|
||||||
|
f.write(build_javascript_output(code))
|
||||||
|
link = f"{host}:{lollmsElfServer.config.port}/{discussion_path_2_url(tmp_file)}"
|
||||||
|
output_json = {"output": f'<b>Page built successfully</b><br><a href="{link}" target="_blank">Press here to view the page</a>', "execution_time": execution_time}
|
||||||
|
return output_json
|
||||||
|
else:
|
||||||
|
return build_javascript_output(code)
|
||||||
|
@ -12,6 +12,7 @@ import time
|
|||||||
import subprocess
|
import subprocess
|
||||||
import json
|
import json
|
||||||
from lollms.client_session import Client
|
from lollms.client_session import Client
|
||||||
|
from lollms.utilities import discussion_path_2_url
|
||||||
|
|
||||||
|
|
||||||
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
||||||
@ -82,6 +83,25 @@ def build_mermaid_output(code, ifram_name="unnamed"):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def execute_mermaid(code):
|
def execute_mermaid(code, client:Client, message_id, build_file=False):
|
||||||
|
if build_file:
|
||||||
|
# Start the timer.
|
||||||
|
start_time = time.time()
|
||||||
|
if not "http" in lollmsElfServer.config.host and not "https" in lollmsElfServer.config.host:
|
||||||
|
host = "http://"+lollmsElfServer.config.host
|
||||||
|
else:
|
||||||
|
host = lollmsElfServer.config.host
|
||||||
|
|
||||||
return build_mermaid_output(code)
|
# Create a temporary file.
|
||||||
|
root_folder = client.discussion.discussion_folder
|
||||||
|
root_folder.mkdir(parents=True,exist_ok=True)
|
||||||
|
tmp_file = root_folder/f"ai_code_{message_id}.html"
|
||||||
|
with open(tmp_file,"w",encoding="utf8") as f:
|
||||||
|
f.write(build_mermaid_output(code))
|
||||||
|
link = f"{host}:{lollmsElfServer.config.port}/{discussion_path_2_url(tmp_file)}"
|
||||||
|
# Stop the timer.
|
||||||
|
execution_time = time.time() - start_time
|
||||||
|
output_json = {"output": f'<b>Page built successfully</b><br><a href="{link}" target="_blank">Press here to view the page</a>', "execution_time": execution_time}
|
||||||
|
return output_json
|
||||||
|
else:
|
||||||
|
return build_mermaid_output(code)
|
||||||
|
@ -16,7 +16,7 @@ from lollms.client_session import Client
|
|||||||
|
|
||||||
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
||||||
|
|
||||||
def execute_python(code, client:Client, message_id):
|
def execute_python(code, client:Client, message_id, build_file=True):
|
||||||
def spawn_process(code):
|
def spawn_process(code):
|
||||||
"""Executes Python code and returns the output as JSON."""
|
"""Executes Python code and returns the output as JSON."""
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ from lollms.client_session import Client
|
|||||||
|
|
||||||
|
|
||||||
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
||||||
def execute_bash(code, client:Client):
|
def execute_bash(code, client:Client, message_id, build_file=False):
|
||||||
def spawn_process(code):
|
def spawn_process(code):
|
||||||
"""Executes Python code and returns the output as JSON."""
|
"""Executes Python code and returns the output as JSON."""
|
||||||
|
|
||||||
|
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">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>LoLLMS WebUI - Welcome</title>
|
<title>LoLLMS WebUI - Welcome</title>
|
||||||
<script type="module" crossorigin src="/assets/index-1841272f.js"></script>
|
<script type="module" crossorigin src="/assets/index-4fb85597.js"></script>
|
||||||
<link rel="stylesheet" href="/assets/index-49ced084.css">
|
<link rel="stylesheet" href="/assets/index-49ced084.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -12,15 +12,20 @@
|
|||||||
:class="isExecuting?'bg-green-500':''">
|
:class="isExecuting?'bg-green-500':''">
|
||||||
<i data-feather="play-circle"></i>
|
<i data-feather="play-circle"></i>
|
||||||
</button>
|
</button>
|
||||||
<button v-if="['python', 'latex'].includes(language)" @click="openFolder" title="open code project folder"
|
<button v-if="['airplay', 'mermaid', 'graphviz', 'dot', 'javascript', 'html', 'html5', 'svg'].includes(language)" ref="btn_code_exec_in_new_tab" @click="executeCode_in_new_tab" title="execute"
|
||||||
|
class="px-2 py-1 ml-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"
|
||||||
|
:class="isExecuting?'bg-green-500':''">
|
||||||
|
<i data-feather="airplay"></i>
|
||||||
|
</button>
|
||||||
|
<button v-if="['python', 'latex', 'html'].includes(language)" @click="openFolder" title="open code project folder"
|
||||||
class="px-2 py-1 ml-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">
|
class="px-2 py-1 ml-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">
|
||||||
<i data-feather="folder"></i>
|
<i data-feather="folder"></i>
|
||||||
</button>
|
</button>
|
||||||
<button v-if="['python'].includes(language)" @click="openFolderVsCode" title="open code project folder in vscode"
|
<button v-if="['python', 'latex', 'html'].includes(language)" @click="openFolderVsCode" title="open code project folder in vscode"
|
||||||
class="px-2 py-1 ml-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">
|
class="px-2 py-1 ml-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">
|
||||||
<img src="@/assets/vscode_black.svg" width="25" height="25">
|
<img src="@/assets/vscode_black.svg" width="25" height="25">
|
||||||
</button>
|
</button>
|
||||||
<button v-if="['python'].includes(language)" @click="openVsCode" title="open code in vscode"
|
<button v-if="['python', 'latex', 'html'].includes(language)" @click="openVsCode" title="open code in vscode"
|
||||||
class="px-2 py-1 ml-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">
|
class="px-2 py-1 ml-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">
|
||||||
<img src="@/assets/vscode.svg" width="25" height="25">
|
<img src="@/assets/vscode.svg" width="25" height="25">
|
||||||
</button>
|
</button>
|
||||||
@ -167,6 +172,36 @@ export default {
|
|||||||
console.error('Fetch error:', error);
|
console.error('Fetch error:', error);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
executeCode_in_new_tab(){
|
||||||
|
this.isExecuting=true;
|
||||||
|
const json = JSON.stringify({
|
||||||
|
'client_id': this.client_id,
|
||||||
|
'code': this.code,
|
||||||
|
'discussion_id': this.discussion_id,
|
||||||
|
'message_id': this.message_id,
|
||||||
|
'language': this.language
|
||||||
|
})
|
||||||
|
console.log(json)
|
||||||
|
fetch(`${this.host}/execute_code_in_new_tab`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: json
|
||||||
|
}).then(response=>{
|
||||||
|
this.isExecuting=false;
|
||||||
|
// Parse the JSON data from the response body
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(jsonData => {
|
||||||
|
// Now you can work with the JSON data
|
||||||
|
console.log(jsonData);
|
||||||
|
this.executionOutput = jsonData.output;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.isExecuting=false;
|
||||||
|
// Handle any errors that occurred during the fetch process
|
||||||
|
console.error('Fetch error:', error);
|
||||||
|
});
|
||||||
|
},
|
||||||
openFolderVsCode(){
|
openFolderVsCode(){
|
||||||
const json = JSON.stringify({
|
const json = JSON.stringify({
|
||||||
'client_id': this.client_id,
|
'client_id': this.client_id,
|
||||||
|
Loading…
Reference in New Issue
Block a user