Expose DuckLM runtime status
This commit is contained in:
+67
-1
@@ -53,6 +53,7 @@ Commands:
|
||||
stop Stop DuckLM API and managed MTP llama-server
|
||||
restart Stop and start the whole local DuckLM stack
|
||||
status Print process and HTTP health status
|
||||
Use "status --probe" to include live model/vector checks
|
||||
logs Show DuckLM API and llama-server logs; use --follow/-f and --lines N
|
||||
help Show this help
|
||||
|
||||
@@ -169,6 +170,20 @@ stop_stack() {
|
||||
}
|
||||
|
||||
status_stack() {
|
||||
local probe=0
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--probe)
|
||||
probe=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown status argument: $1" >&2
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
local rc=0
|
||||
if api_is_running; then
|
||||
local pid
|
||||
@@ -176,6 +191,7 @@ status_stack() {
|
||||
echo "DuckLM API running: pid=${pid}"
|
||||
if command -v curl >/dev/null 2>&1 && curl --noproxy "*" -fsS "${API_URL}/health" >/dev/null 2>&1; then
|
||||
echo "DuckLM API health: ok (${API_URL})"
|
||||
print_runtime_status "${probe}"
|
||||
else
|
||||
echo "DuckLM API health: not ready (${API_URL})"
|
||||
fi
|
||||
@@ -197,6 +213,55 @@ status_stack() {
|
||||
return "${rc}"
|
||||
}
|
||||
|
||||
print_runtime_status() {
|
||||
local probe="${1:-0}"
|
||||
local status_url="${API_URL}/v1/status"
|
||||
if [[ "${probe}" == "1" ]]; then
|
||||
status_url="${status_url}?probe=true"
|
||||
fi
|
||||
local payload
|
||||
if ! payload="$(curl --noproxy "*" -fsS "${status_url}" 2>/dev/null)"; then
|
||||
echo "DuckLM runtime status: unavailable (${status_url})"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local python_bin="${DUCK_PYTHON_BIN:-${ROOT_DIR}/.venv/bin/python}"
|
||||
if [[ ! -x "${python_bin}" ]]; then
|
||||
python_bin="python3"
|
||||
fi
|
||||
if ! command -v "${python_bin}" >/dev/null 2>&1 && [[ ! -x "${python_bin}" ]]; then
|
||||
echo "DuckLM runtime status: ${status_url}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
printf '%s' "${payload}" | "${python_bin}" -c '
|
||||
import json
|
||||
import sys
|
||||
|
||||
data = json.load(sys.stdin)
|
||||
models = data.get("models", {})
|
||||
roles = sorted((models.get("roles") or {}).keys())
|
||||
services = data.get("services", {})
|
||||
llama = services.get("llama", {})
|
||||
vector = services.get("vector_memory", {})
|
||||
|
||||
def service_line(name, service):
|
||||
if not service.get("probed"):
|
||||
return f"{name}: not probed"
|
||||
ok = "ok" if service.get("ok") else "failed"
|
||||
error = service.get("error")
|
||||
return f"{name}: {ok}" + (f" ({error})" if error else "")
|
||||
|
||||
print("DuckLM runtime:")
|
||||
print(" workspace: {}".format(data.get("workspace")))
|
||||
print(" db: {}".format(data.get("db_path")))
|
||||
print(" model endpoints: {}".format(len(models.get("endpoints") or [])))
|
||||
print(" roles: {}".format(", ".join(roles)))
|
||||
print(" {}".format(service_line("llama", llama)))
|
||||
print(" {}".format(service_line("vector memory", vector)))
|
||||
'
|
||||
}
|
||||
|
||||
logs_stack() {
|
||||
local follow=0
|
||||
local lines=100
|
||||
@@ -246,7 +311,8 @@ case "${ACTION}" in
|
||||
start_stack
|
||||
;;
|
||||
status)
|
||||
status_stack
|
||||
shift || true
|
||||
status_stack "$@"
|
||||
;;
|
||||
logs)
|
||||
logs_stack "$@"
|
||||
|
||||
+67
-1
@@ -53,6 +53,7 @@ Commands:
|
||||
stop Stop DuckLM API and managed llama-server
|
||||
restart Stop and start the whole local DuckLM stack
|
||||
status Print process and HTTP health status
|
||||
Use "status --probe" to include live model/vector checks
|
||||
logs Show DuckLM API and llama-server logs; use --follow/-f and --lines N
|
||||
help Show this help
|
||||
|
||||
@@ -169,6 +170,20 @@ stop_stack() {
|
||||
}
|
||||
|
||||
status_stack() {
|
||||
local probe=0
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--probe)
|
||||
probe=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown status argument: $1" >&2
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
local rc=0
|
||||
if api_is_running; then
|
||||
local pid
|
||||
@@ -176,6 +191,7 @@ status_stack() {
|
||||
echo "DuckLM API running: pid=${pid}"
|
||||
if command -v curl >/dev/null 2>&1 && curl --noproxy "*" -fsS "${API_URL}/health" >/dev/null 2>&1; then
|
||||
echo "DuckLM API health: ok (${API_URL})"
|
||||
print_runtime_status "${probe}"
|
||||
else
|
||||
echo "DuckLM API health: not ready (${API_URL})"
|
||||
fi
|
||||
@@ -197,6 +213,55 @@ status_stack() {
|
||||
return "${rc}"
|
||||
}
|
||||
|
||||
print_runtime_status() {
|
||||
local probe="${1:-0}"
|
||||
local status_url="${API_URL}/v1/status"
|
||||
if [[ "${probe}" == "1" ]]; then
|
||||
status_url="${status_url}?probe=true"
|
||||
fi
|
||||
local payload
|
||||
if ! payload="$(curl --noproxy "*" -fsS "${status_url}" 2>/dev/null)"; then
|
||||
echo "DuckLM runtime status: unavailable (${status_url})"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local python_bin="${DUCK_PYTHON_BIN:-${ROOT_DIR}/.venv/bin/python}"
|
||||
if [[ ! -x "${python_bin}" ]]; then
|
||||
python_bin="python3"
|
||||
fi
|
||||
if ! command -v "${python_bin}" >/dev/null 2>&1 && [[ ! -x "${python_bin}" ]]; then
|
||||
echo "DuckLM runtime status: ${status_url}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
printf '%s' "${payload}" | "${python_bin}" -c '
|
||||
import json
|
||||
import sys
|
||||
|
||||
data = json.load(sys.stdin)
|
||||
models = data.get("models", {})
|
||||
roles = sorted((models.get("roles") or {}).keys())
|
||||
services = data.get("services", {})
|
||||
llama = services.get("llama", {})
|
||||
vector = services.get("vector_memory", {})
|
||||
|
||||
def service_line(name, service):
|
||||
if not service.get("probed"):
|
||||
return f"{name}: not probed"
|
||||
ok = "ok" if service.get("ok") else "failed"
|
||||
error = service.get("error")
|
||||
return f"{name}: {ok}" + (f" ({error})" if error else "")
|
||||
|
||||
print("DuckLM runtime:")
|
||||
print(" workspace: {}".format(data.get("workspace")))
|
||||
print(" db: {}".format(data.get("db_path")))
|
||||
print(" model endpoints: {}".format(len(models.get("endpoints") or [])))
|
||||
print(" roles: {}".format(", ".join(roles)))
|
||||
print(" {}".format(service_line("llama", llama)))
|
||||
print(" {}".format(service_line("vector memory", vector)))
|
||||
'
|
||||
}
|
||||
|
||||
logs_stack() {
|
||||
local follow=0
|
||||
local lines=100
|
||||
@@ -246,7 +311,8 @@ case "${ACTION}" in
|
||||
start_stack
|
||||
;;
|
||||
status)
|
||||
status_stack
|
||||
shift || true
|
||||
status_stack "$@"
|
||||
;;
|
||||
logs)
|
||||
logs_stack "$@"
|
||||
|
||||
Reference in New Issue
Block a user