Skip to content

Commit 0bc1228

Browse files
authored
- fix: several fixes in shinkai node manager (#376)
* - fix: scape control characters from string in logs * - fix: api port * - fix: ollama and shinkai-node health proof * - fix: isInUse state when auth change and node is not running
1 parent 167692e commit 0bc1228

File tree

8 files changed

+89
-53
lines changed

8 files changed

+89
-53
lines changed

apps/shinkai-desktop/src-tauri/Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/shinkai-desktop/src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ hound = "3.4.0"
2323
# fix this dependency later on
2424
reqwest = { version = "0.11", features = ["json", "stream"] }
2525
lazy_static = "1.4.0"
26-
tokio = "1.36.0"
26+
tokio = { version = "1.36.0", features = ["macros"] }
2727
chrono = "0.4.38"
2828
futures-util = "0.3"
2929
regex = "1.10.4"

apps/shinkai-desktop/src-tauri/src/local_shinkai_node/process_handlers/logger.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ impl Logger {
2727
LogEntry {
2828
timestamp: current_timestamp,
2929
process: self.process_name.clone(),
30-
message,
30+
message: message.chars().filter(|&c| !c.is_control()).collect(),
3131
}
3232
}
3333

apps/shinkai-desktop/src-tauri/src/local_shinkai_node/process_handlers/ollama_process_handler.rs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::time::Duration;
2+
13
use regex::Regex;
24
use serde::Serialize;
35
use tokio::sync::mpsc::Sender;
@@ -24,7 +26,7 @@ pub struct OllamaProcessHandler {
2426
}
2527

2628
impl OllamaProcessHandler {
27-
const HEALTH_TIMEOUT_MS: u64 = 500;
29+
const HEALTH_TIMEOUT_MS: u64 = 5000;
2830
const PROCESS_NAME: &'static str = "ollama";
2931
const READY_MATCHER: &'static str = "Listening on ";
3032

@@ -58,23 +60,25 @@ impl OllamaProcessHandler {
5860
}
5961

6062
async fn wait_ollama_server(&self) -> Result<(), String> {
63+
let timeout = Duration::from_millis(Self::HEALTH_TIMEOUT_MS);
6164
let start_time = std::time::Instant::now();
62-
let mut success = false;
6365
let ollama_api = OllamaApiClient::new(self.get_ollama_api_base_url());
64-
while std::time::Instant::now().duration_since(start_time)
65-
< std::time::Duration::from_millis(Self::HEALTH_TIMEOUT_MS)
66-
{
67-
let status = ollama_api.health().await;
68-
if status.is_ok() && status.unwrap() {
69-
success = true;
70-
break;
66+
tokio::select! {
67+
_ = tokio::time::sleep(timeout) => {
68+
let elapsed = start_time.elapsed();
69+
Err(format!("wait ollama server timeout after {}ms", elapsed.as_millis()))
70+
}
71+
_ = tokio::spawn(async move {
72+
loop {
73+
match ollama_api.health().await {
74+
Ok(true) => break,
75+
Ok(false) | Err(_) => tokio::time::sleep(Duration::from_millis(50)).await
76+
}
77+
}
78+
}) => {
79+
Ok(())
7180
}
72-
std::thread::sleep(std::time::Duration::from_millis(500));
73-
}
74-
if !success {
75-
return Err("wait ollama server timeout".to_string());
7681
}
77-
Ok(())
7882
}
7983

8084
pub async fn spawn(&self, ensure_model: Option<&str>) -> Result<(), String> {

apps/shinkai-desktop/src-tauri/src/local_shinkai_node/process_handlers/shinkai_node_process_handler.rs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use std::fs;
1+
use std::{fs, time::Duration};
22

33
use regex::Regex;
4-
use tokio::sync::mpsc::Sender;
4+
use tokio::{sync::mpsc::Sender};
55

66
use crate::local_shinkai_node::shinkai_node_options::ShinkaiNodeOptions;
77

@@ -18,7 +18,8 @@ pub struct ShinkaiNodeProcessHandler {
1818
}
1919

2020
impl ShinkaiNodeProcessHandler {
21-
const HEALTH_TIMEOUT_MS: u64 = 500;
21+
const HEALTH_REQUEST_TIMEOUT_MS: u64 = 250;
22+
const HEALTH_TIMEOUT_MS: u64 = 5000;
2223
const PROCESS_NAME: &'static str = "shinkai-node";
2324
const READY_MATCHER: &'static str = "listening on ";
2425

@@ -44,12 +45,12 @@ impl ShinkaiNodeProcessHandler {
4445
base_url
4546
}
4647

47-
async fn health(&self) -> Result<bool, ()> {
48-
let url = format!("{}/v1/shinkai_health", self.get_base_url());
48+
async fn health(base_url: &str, timeout_ms: u64) -> Result<bool, ()> {
49+
let url = format!("{}/v1/shinkai_health", base_url);
4950
let client = reqwest::Client::new();
5051
if let Ok(response) = client
5152
.get(&url)
52-
.timeout(std::time::Duration::from_millis(400))
53+
.timeout(std::time::Duration::from_millis(timeout_ms))
5354
.send()
5455
.await
5556
{
@@ -60,22 +61,25 @@ impl ShinkaiNodeProcessHandler {
6061
}
6162

6263
async fn wait_shinkai_node_server(&self) -> Result<(), String> {
64+
let timeout = Duration::from_millis(Self::HEALTH_TIMEOUT_MS);
6365
let start_time = std::time::Instant::now();
64-
let mut success = false;
65-
while std::time::Instant::now().duration_since(start_time)
66-
< std::time::Duration::from_millis(Self::HEALTH_TIMEOUT_MS)
67-
{
68-
let status = self.health().await.unwrap();
69-
if status {
70-
success = true;
71-
break;
66+
let base_url = self.get_base_url();
67+
tokio::select! {
68+
_ = tokio::time::sleep(timeout) => {
69+
let elapsed = start_time.elapsed();
70+
Err(format!("wait shinkai-node server timeout after {}ms", elapsed.as_millis()))
71+
}
72+
_ = tokio::spawn(async move {
73+
loop {
74+
match Self::health(base_url.as_str(), Self::HEALTH_REQUEST_TIMEOUT_MS).await {
75+
Ok(true) => break,
76+
Ok(false) | Err(_) => tokio::time::sleep(Duration::from_millis(50)).await
77+
}
78+
}
79+
}) => {
80+
Ok(())
7281
}
73-
std::thread::sleep(std::time::Duration::from_millis(500));
74-
}
75-
if !success {
76-
return Err("wait shinkai-node server timeout".to_string());
7782
}
78-
Ok(())
7983
}
8084

8185
pub fn set_options(&mut self, options: ShinkaiNodeOptions) -> ShinkaiNodeOptions {

apps/shinkai-desktop/src/lib/shinkai-node-manager/shinkai-node-manager-client-types.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,24 @@ export type ShinkaiNodeManagerEventMap =
9393
};
9494

9595
export type ShinkaiNodeOptions = {
96-
port?: number;
97-
ws_port?: number;
98-
unstructured_server_url?: string;
99-
embeddings_server_url?: string;
100-
first_device_needs_registration_code?: string;
101-
initial_agent_names?: string;
102-
initial_agent_urls?: string;
103-
initial_agent_models?: string;
104-
initial_agent_api_keys?: string;
105-
starting_num_qr_devices?: number;
96+
node_api_ip?: string,
97+
node_api_port?: string,
98+
node_ws_port?: string,
99+
node_ip?: string,
100+
node_port?: string,
101+
global_identity_name?: string,
102+
node_storage_path?: string,
103+
unstructured_server_url?: string,
104+
embeddings_server_url?: string,
105+
first_device_needs_registration_code?: string,
106+
initial_agent_names?: string,
107+
initial_agent_urls?: string,
108+
initial_agent_models?: string,
109+
initial_agent_api_keys?: string,
110+
starting_num_qr_devices?: string,
111+
log_all?: string,
112+
proxy_identity?: string,
113+
rpc_url?: string,
106114
};
107115

108116
export type LogEntry = {

apps/shinkai-desktop/src/store/shinkai-node-manager.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { devtools, persist } from 'zustand/middleware';
44

55
import { ShinkaiNodeOptions } from '../lib/shinkai-node-manager/shinkai-node-manager-client-types';
66
import { isLocalShinkaiNode } from '../lib/shinkai-node-manager/shinkai-node-manager-windows-utils';
7-
import { useAuth } from './auth';
7+
import { SetupData, useAuth } from './auth';
88

99
type ShinkaiNodeManagerStore = {
1010
isInUse: boolean | null;
@@ -35,12 +35,20 @@ export const useShinkaiNodeManager = create<ShinkaiNodeManagerStore>()(
3535
),
3636
);
3737

38-
useAuth.subscribe((state) => {
39-
handleAuthSideEffect(state.auth?.node_address || '');
38+
useAuth.subscribe((state, prevState) => {
39+
handleAuthSideEffect(state.auth, prevState.auth);
4040
});
4141

42-
const handleAuthSideEffect = async (nodeAddress: string) => {
43-
const isLocal = isLocalShinkaiNode(nodeAddress);
44-
const isRunning: boolean = await invoke('shinkai_node_is_running');
45-
useShinkaiNodeManager.getState().setIsInUse(isLocal && isRunning);
42+
const handleAuthSideEffect = async (auth: SetupData | null, prevAuth: SetupData | null) => {
43+
// SignOut case
44+
if (prevAuth && !auth) {
45+
useShinkaiNodeManager.getState().setIsInUse(false);
46+
return;
47+
}
48+
// SignIn
49+
if (!prevAuth) {
50+
const isLocal = isLocalShinkaiNode(auth?.node_address || '');
51+
const isRunning: boolean = await invoke('shinkai_node_is_running');
52+
useShinkaiNodeManager.getState().setIsInUse(isLocal && isRunning);
53+
}
4654
};

apps/shinkai-desktop/src/windows/shinkai-node-manager/main.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ const App = () => {
203203
<img alt="shinkai logo" className="h-10 w-10" src={logo} />
204204
<div className="ml-4 flex flex-col">
205205
<span className="text-lg">Local Shinkai Node</span>
206-
<span className="text-gray-80 text-sm">{`http://localhost:${shinkaiNodeOptions?.port}`}</span>
206+
<span className="text-gray-80 text-sm">{`API URL: http://${shinkaiNodeOptions?.node_api_ip}:${shinkaiNodeOptions?.node_api_port}`}</span>
207207
</div>
208208
<div className="flex grow flex-row items-center justify-end space-x-4">
209209
<TooltipProvider>

0 commit comments

Comments
 (0)