fix(luci-app-localai): Fix chat timeout and port issues
- Change default API port from 8080 to 8081 - Increase chat API timeout to 120 seconds (LLMs can be slow on ARM) - Use custom fetch-based chat call with AbortController for timeout control - Fix wget/curl timeout for RPCD backend Resolves "XHR request timed out" errors when using chat with TinyLlama. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
612a1be6ea
commit
6b07a613f1
@ -9,12 +9,52 @@ var callModels = rpc.declare({
|
|||||||
expect: { models: [] }
|
expect: { models: [] }
|
||||||
});
|
});
|
||||||
|
|
||||||
var callChat = rpc.declare({
|
// Custom chat function with longer timeout (LLMs can be slow)
|
||||||
object: 'luci.localai',
|
function callChatWithTimeout(model, messages, timeoutMs) {
|
||||||
method: 'chat',
|
return new Promise(function(resolve, reject) {
|
||||||
params: ['model', 'messages'],
|
var timeout = timeoutMs || 120000; // 2 minutes default
|
||||||
expect: { response: '' }
|
var controller = new AbortController();
|
||||||
});
|
var timeoutId = setTimeout(function() {
|
||||||
|
controller.abort();
|
||||||
|
reject(new Error('Request timed out - model may need more time'));
|
||||||
|
}, timeout);
|
||||||
|
|
||||||
|
// Use ubus directly via L.Request or fetch
|
||||||
|
var payload = JSON.stringify({
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
id: 1,
|
||||||
|
method: 'call',
|
||||||
|
params: [
|
||||||
|
L.env.sessionid || '00000000000000000000000000000000',
|
||||||
|
'luci.localai',
|
||||||
|
'chat',
|
||||||
|
{ model: model, messages: JSON.parse(messages) }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch(L.env.requestpath + 'admin/ubus', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: payload,
|
||||||
|
signal: controller.signal
|
||||||
|
})
|
||||||
|
.then(function(response) { return response.json(); })
|
||||||
|
.then(function(data) {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
if (data.result && data.result[1]) {
|
||||||
|
resolve(data.result[1]);
|
||||||
|
} else if (data.error) {
|
||||||
|
reject(new Error(data.error.message || 'RPC error'));
|
||||||
|
} else {
|
||||||
|
resolve({ response: '', error: 'Unexpected response format' });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
title: _('LocalAI Chat'),
|
title: _('LocalAI Chat'),
|
||||||
@ -137,8 +177,8 @@ return view.extend({
|
|||||||
// Build messages array
|
// Build messages array
|
||||||
this.messages.push({ role: 'user', content: message });
|
this.messages.push({ role: 'user', content: message });
|
||||||
|
|
||||||
// Send to API
|
// Send to API (120s timeout for slow models)
|
||||||
callChat(this.selectedModel, JSON.stringify(this.messages))
|
callChatWithTimeout(this.selectedModel, JSON.stringify(this.messages), 120000)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
var loading = document.getElementById('loading-msg');
|
var loading = document.getElementById('loading-msg');
|
||||||
if (loading) loading.remove();
|
if (loading) loading.remove();
|
||||||
|
|||||||
@ -10,7 +10,7 @@ LOCALAI_CTL="/usr/sbin/localaictl"
|
|||||||
# Load UCI config
|
# Load UCI config
|
||||||
load_config() {
|
load_config() {
|
||||||
config_load "$CONFIG"
|
config_load "$CONFIG"
|
||||||
config_get API_PORT main api_port "8080"
|
config_get API_PORT main api_port "8081"
|
||||||
config_get DATA_PATH main data_path "/srv/localai"
|
config_get DATA_PATH main data_path "/srv/localai"
|
||||||
config_get MODELS_PATH main models_path "/srv/localai/models"
|
config_get MODELS_PATH main models_path "/srv/localai/models"
|
||||||
config_get MEMORY_LIMIT main memory_limit "2G"
|
config_get MEMORY_LIMIT main memory_limit "2G"
|
||||||
@ -388,13 +388,14 @@ do_chat() {
|
|||||||
local tmpfile="/tmp/localai_chat_$$"
|
local tmpfile="/tmp/localai_chat_$$"
|
||||||
local tmpfile_err="/tmp/localai_chat_err_$$"
|
local tmpfile_err="/tmp/localai_chat_err_$$"
|
||||||
|
|
||||||
|
# Use longer timeout for LLM responses (120 seconds)
|
||||||
if command -v curl >/dev/null 2>&1; then
|
if command -v curl >/dev/null 2>&1; then
|
||||||
curl -s -X POST "http://127.0.0.1:$API_PORT/v1/chat/completions" \
|
curl -s -m 120 -X POST "http://127.0.0.1:$API_PORT/v1/chat/completions" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "$request_body" \
|
-d "$request_body" \
|
||||||
-o "$tmpfile" 2>"$tmpfile_err"
|
-o "$tmpfile" 2>"$tmpfile_err"
|
||||||
else
|
else
|
||||||
wget -q -O "$tmpfile" --post-data "$request_body" \
|
wget -q -T 120 -O "$tmpfile" --post-data "$request_body" \
|
||||||
--header="Content-Type: application/json" \
|
--header="Content-Type: application/json" \
|
||||||
"http://127.0.0.1:$API_PORT/v1/chat/completions" 2>"$tmpfile_err"
|
"http://127.0.0.1:$API_PORT/v1/chat/completions" 2>"$tmpfile_err"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user