Expose DuckLM runtime status

This commit is contained in:
2026-05-22 07:45:47 +08:00
parent ff98224eb6
commit 8452673994
8 changed files with 319 additions and 9 deletions
+67 -1
View File
@@ -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
View File
@@ -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 "$@"