Skip to content

Commit

Permalink
Merge pull request #86 from cloudnautique/main
Browse files Browse the repository at this point in the history
fix - ux and messaging when components start/stop
  • Loading branch information
cloudnautique authored Feb 21, 2024
2 parents 5dc8c89 + f13ff2a commit 2d0cb19
Show file tree
Hide file tree
Showing 22 changed files with 66 additions and 44 deletions.
Binary file added tauri/app-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tauri/src-tauri/icons/128x128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tauri/src-tauri/icons/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tauri/src-tauri/icons/32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tauri/src-tauri/icons/Square107x107Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tauri/src-tauri/icons/Square142x142Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tauri/src-tauri/icons/Square150x150Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tauri/src-tauri/icons/Square284x284Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tauri/src-tauri/icons/Square30x30Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tauri/src-tauri/icons/Square310x310Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tauri/src-tauri/icons/Square44x44Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tauri/src-tauri/icons/Square71x71Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tauri/src-tauri/icons/Square89x89Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tauri/src-tauri/icons/StoreLogo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tauri/src-tauri/icons/icon.icns
Binary file not shown.
Binary file modified tauri/src-tauri/icons/icon.ico
Binary file not shown.
Binary file added tauri/src-tauri/icons/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed tauri/src-tauri/icons/rubra-32x32.png
Binary file not shown.
34 changes: 17 additions & 17 deletions tauri/src-tauri/src/compose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::fs::{self, File};
use std::io::Write;
use std::path::PathBuf;
use std::process::Command;
use std::str;

pub fn start_docker_containers(version: &String) -> Result<(), String> {
let home_dir = dirs::home_dir().ok_or("Could not find the home directory.")?;
Expand Down Expand Up @@ -62,27 +63,26 @@ pub fn check_containers_status(network: &str) -> Result<Vec<(String, String)>, S
.expect("Failed to inspect Docker network");

if !output.status.success() {
return Err("Failed to get container IDs".to_string());
}

let container_ids = String::from_utf8(output.stdout).unwrap();
let mut container_statuses = Vec::new();

for container_id in container_ids.split_whitespace() {
let output = Command::new("docker")
.args(["inspect", "--format", "{{.State.Status}}", container_id])
.output()
.expect("Failed to inspect container");
let stderr = str::from_utf8(&output.stderr).unwrap_or("").trim();

if output.status.success() {
let status = String::from_utf8(output.stdout).unwrap();
container_statuses.push((container_id.to_string(), status));
} else {
container_statuses.push((container_id.to_string(), "unknown".to_string()));
// Check if the stderr contains specific error text
if stderr.contains("Cannot connect to the Docker daemon") {
return Err("Docker stopped".to_string());
}

// For other errors, you can return or handle them as needed
return Err("No Rubra containers are running".to_string());
}

Ok(container_statuses)
let stdout = str::from_utf8(&output.stdout).unwrap_or("").trim();
// Split the stdout by whitespace and create a vector of tuples
// Assuming each container name is followed by a status or similar property, adjust accordingly
let containers = stdout
.split_whitespace()
.map(|name| (name.to_string(), "Unknown Status".to_string())) // Placeholder for actual status
.collect::<Vec<(String, String)>>();

Ok(containers)
}

pub fn write_compose_yaml(rubra_dir: &PathBuf, compose_resource: &PathBuf) -> Result<(), String> {
Expand Down
11 changes: 6 additions & 5 deletions tauri/src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,11 +311,11 @@ async fn check_rubra_llamafile_ready() -> Result<String, String> {
"messages": [
{
"role": "system",
"content": "You are ChatGPT, an AI assistant. Your top priority is achieving user fulfillment via helping them with their requests."
"content": "respond with 'pong' when someone sends 'ping'"
},
{
"role": "user",
"content": "Write a limerick about python exceptions"
"content": "ping"
}
]
}))
Expand All @@ -335,7 +335,7 @@ async fn check_rubra_llamafile_ready() -> Result<String, String> {
}
}

Err("Rubra's local model did not start successfully or is not accepting requests. Please check the logs.".to_string())
Err("Rubra's local model is not accepting requests.".to_string())
}

#[tauri::command]
Expand All @@ -348,13 +348,13 @@ async fn rubra_event(
let _ = start_docker_containers(&version);
let _ = execute_rubra_llamafile(state);
} else if event == "stop" {
let _ = stop_docker_containers();

let mut state_lock = state.lock().unwrap();
if let Some(process) = &mut state_lock.llm_process {
let _ = stop_llm_process(process);
state_lock.llm_process = None;
}

let _ = stop_docker_containers();
}

check_containers_status("rubra")
Expand Down Expand Up @@ -422,6 +422,7 @@ fn main() {
let app_version = format!("v{}", app.package_info().version.to_string());
state.lock().unwrap().app_version = app_version.clone();
state.lock().unwrap().rubra_dir = home_dir.join(".rubra");

Ok(())
})
.invoke_handler(tauri::generate_handler![
Expand Down
9 changes: 6 additions & 3 deletions tauri/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@
"targets": "all",
"identifier": "io.acorn.rubra",
"icon": [
"icons/rubra-32x32.png",
"icons/icon.icns"
"icons/32x32.png",
"icons/128x128.png",
"icons/[email protected]",
"icons/icon.icns",
"icons/icon.ico"
],
"resources": [
"assets/docker-compose.yml"
Expand All @@ -57,4 +60,4 @@
"menuOnLeftClick": true
}
}
}
}
56 changes: 37 additions & 19 deletions tauri/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ function startRubra() {
})
.catch((error) => {
console.error('Error:', error);
updateRubraStatus();
});
}

Expand All @@ -80,26 +81,42 @@ function stopRubra() {
})
.catch((error) => {
console.error('Error:', error);
updateRubraStatus();
});
}

function updateRubraStatus() {
const rubraLlamafileReadyPromise = window.__TAURI__.invoke('check_rubra_llamafile_ready');
const rubraContainerStatusPromise = window.__TAURI__.invoke('check_rubra_container_status');
const rubraLlamafileReadyPromise = window.__TAURI__.invoke('check_rubra_llamafile_ready')
.catch((error) => ({ error, 'type': 'llamafile' }));
const rubraContainerStatusPromise = window.__TAURI__.invoke('check_rubra_container_status')
.catch((error) => ({ error, 'type': 'container' }));

Promise.all([rubraLlamafileReadyPromise, rubraContainerStatusPromise])
.then(([llamafileReadyResult, rubraStatusResult]) => {
updateModelStatus(true);

let status = checkContainerHealthy(rubraStatusResult);
updateContainerStatus(status);
updateFooterButtons(status);
const buttonStatuses = { "start": false, "ui": false };

if (llamafileReadyResult.error) {
updateModelStatus(false, `${llamafileReadyResult.error}`);
} else {
buttonStatuses.start = true;
updateModelStatus(true);
}

if (rubraStatusResult.error) {
updateContainerStatus(false, `${rubraStatusResult.error}`);
} else {
buttonStatuses.start = true;
updateContainerStatus(true);
}

if (llamafileReadyResult.error || rubraStatusResult.error) {
return updateFooterButtons(buttonStatuses);
}
buttonStatuses.ui = true;
updateFooterButtons(buttonStatuses);
})
.catch((error) => {
console.warn('warn:', error)
updateContainerStatus(false);
updateFooterButtons(false);
updateModelStatus(false);
});
}

Expand All @@ -115,22 +132,23 @@ function checkContainerHealthy(containers) {
return true;
}

function updateFooterButtons(status) {
function updateFooterButtons(statuses) {
const rubraAction = document.getElementById('rubra-action');
const uiBtn = document.getElementById('ui-btn');

if (status) {
if (statuses.start) {
rubraAction.textContent = 'Stop Rubra';
rubraAction.setAttribute('data-action', 'stop');
rubraAction.style.display = 'inline';
rubraAction.disabled = false;
rubraAction.classList.remove('disabled');

uiBtn.style.display = 'inline';
} else {
rubraAction.textContent = 'Start Rubra';
rubraAction.setAttribute('data-action', 'start');

}
if (statuses.ui) {
uiBtn.style.display = 'inline';
} else {
uiBtn.style.display = 'none';
}
}
Expand All @@ -144,16 +162,16 @@ function getStatusColor(status) {
}
}

function updateModelStatus(isHealthy) {
function updateModelStatus(isHealthy, unhealthyMessage = 'unhealthy') {
const modelStatusText = document.getElementById('model-status-text');
const modelStatusDot = modelStatusText.previousElementSibling;
modelStatusDot.className = `status-dot ${isHealthy ? 'healthy' : 'unhealthy'}`; // Update class to reflect current status
modelStatusText.textContent = `Model Status: ${isHealthy ? 'Healthy' : 'Unhealthy'}`;
modelStatusText.textContent = `Model Status: ${isHealthy ? 'Healthy' : unhealthyMessage}`;
}

function updateContainerStatus(isHealthy) {
function updateContainerStatus(isHealthy, unhealthyMessage = 'unhealthy') {
const containerStatusText = document.querySelector('#container-statuses p');
const containerStatusDot = containerStatusText.previousElementSibling; // Assuming the dot is the next sibling
containerStatusDot.className = `status-dot ${isHealthy ? 'healthy' : 'unhealthy'}`; // Update class to reflect current status
containerStatusText.textContent = `Container Status: ${isHealthy ? 'Healthy' : 'Unhealthy'}`;
containerStatusText.textContent = `Container Status: ${isHealthy ? 'Healthy' : unhealthyMessage}`;
}

0 comments on commit 2d0cb19

Please sign in to comment.