aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/ai
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/modules/ai')
-rw-r--r--desktop/modules/ai/AiModule.qml16
-rw-r--r--desktop/modules/ai/AiPage.qml2
-rw-r--r--desktop/modules/ai/README.md10
-rwxr-xr-xdesktop/modules/ai/ai-state.sh27
-rwxr-xr-xdesktop/modules/ai/test-ai-state.sh22
5 files changed, 16 insertions, 61 deletions
diff --git a/desktop/modules/ai/AiModule.qml b/desktop/modules/ai/AiModule.qml
index d58ebfe..4c50224 100644
--- a/desktop/modules/ai/AiModule.qml
+++ b/desktop/modules/ai/AiModule.qml
@@ -41,16 +41,12 @@ Module {
sd: "stable-diffusion.cpp",
assistant: "Desktop assistant",
chat: "Local chat",
- imggen: "imggen",
- fanfic: "Fanfictioner",
})
readonly property string assistantSh:
Quickshell.env("HOME") + "/Programming/GIT/desktop-assistant/assistant.sh"
- // Each project's own control. Fanfictioner has no start, a run needs a
- // story file, and its stop needs the pid, see stop(). llamachat has no
- // restart, and --quit answers before the app is gone, so a --daemon
+ // Each project's own control. llamachat has no restart, and --quit answers before the app is gone, so a --daemon
// straight after would find it still running and do nothing: wait for
// --ping to fail first, up to 5s.
readonly property var controls: ({
@@ -59,7 +55,6 @@ Module {
chat: { start: ["llamachat", "--daemon"], stop: ["llamachat", "--quit"],
restart: ["sh", "-c", "llamachat --quit; for _ in $(seq 50); do "
+ "llamachat --ping || break; sleep 0.1; done; exec llamachat --daemon"] },
- imggen: { start: ["imggen", "start"], stop: ["imggen", "stop"] },
})
function canStart(app) { return controls[app.name] !== undefined; }
@@ -75,14 +70,7 @@ Module {
}
function stop(app) {
- if (app.name !== "fanfic") {
- exec(controls[app.name].stop);
- return;
- }
- // The sd-cli children first, then the script, by pid only: a name
- // match would take unrelated sd-cli and python processes with it.
- if (!/^[0-9]+$/.test(app.detail)) return;
- exec(["sh", "-c", 'pkill -TERM -P "$1"; kill -TERM "$1"', "sh", app.detail]);
+ exec(controls[app.name].stop);
}
// The router frees the model's VRAM; the next request for it loads it
diff --git a/desktop/modules/ai/AiPage.qml b/desktop/modules/ai/AiPage.qml
index 369c1b5..c1cb07c 100644
--- a/desktop/modules/ai/AiPage.qml
+++ b/desktop/modules/ai/AiPage.qml
@@ -68,7 +68,7 @@ Column {
detail: {
if (!modelData.running) return "Stopped";
if (modelData.detail === "") return "Running";
- return "Running · " + (modelData.name === "fanfic" ? "pid " : "") + modelData.detail;
+ return "Running · " + modelData.detail;
}
action: modelData.running ? "Stop" : page.ai.canStart(modelData) ? "Start" : ""
danger: modelData.running
diff --git a/desktop/modules/ai/README.md b/desktop/modules/ai/README.md
index e71159b..d87087a 100644
--- a/desktop/modules/ai/README.md
+++ b/desktop/modules/ai/README.md
@@ -18,10 +18,10 @@ llama's state comes from its API: `/models` for the loaded model, then
`autoload=false` matters: a plain `/slots?model=` on an unloaded model loads
it into VRAM, which is how this was found.
-The sd row covers two processes. A running `sd-cli`, the one-shot runs
-fanfictioner makes, reads up and generating with its model marked `(sd-cli)`,
-whatever the web UI is doing: it holds VRAM for as long as it lives. The first
-version watched only `sd-server` and showed the engine down mid-run.
+The sd row covers two processes. A running one-shot `sd-cli` reads up and
+generating with its model marked `(sd-cli)`, whatever the web UI is doing: it
+holds VRAM for as long as it lives. The first version watched only
+`sd-server` and showed the engine down mid-run.
sd-server has no progress endpoint. Its log, `~/.cache/sd-server.log`, streams
progress bars while it generates, so the row reads busy while the log was
@@ -33,8 +33,6 @@ written in the last 5s. A step slower than that reads idle.
| --- | --- | --- | --- | --- |
| desktop-assistant | `assistant.sh status` | `assistant.sh start` | `assistant.sh stop` | `assistant.sh restart` |
| local chat | `llamachat --ping` | `llamachat --daemon` | `llamachat --quit` | quit, wait for `--ping` to fail (5s at most), `--daemon` |
-| imggen | `imggen status` | `imggen start` (default model) | `imggen stop` | none |
-| fanfictioner | `pgrep` on `python3 .../fanfictioner` | none | TERM its children, then it, by pid | none |
Restart shows only while an app is running. llamachat's `--quit` answers
before the app has exited, so a `--daemon` sent straight after finds it still
diff --git a/desktop/modules/ai/ai-state.sh b/desktop/modules/ai/ai-state.sh
index 8b10368..a4406ce 100755
--- a/desktop/modules/ai/ai-state.sh
+++ b/desktop/modules/ai/ai-state.sh
@@ -12,19 +12,17 @@
# GNU General Public License for more details.
#
# One sweep of the local AI stack for the drawer's AI page. Always prints
-# these six lines, tab separated, and exits 0:
+# these four lines, tab separated, and exits 0:
#
# engine<TAB>llama<TAB>up|down<TAB>idle|busy<TAB>model
# engine<TAB>sd<TAB>up|down<TAB>idle|busy<TAB>model, "(sd-cli)" for a CLI run
# app<TAB>assistant<TAB>running|stopped<TAB>-
# app<TAB>chat<TAB>running|stopped<TAB>-
-# app<TAB>imggen<TAB>running|stopped<TAB>model
-# app<TAB>fanfic<TAB>running|stopped<TAB>pid
#
# An empty value is "-". A probe that fails reads as down or stopped, not as
# an error: every row is something that may simply not be running.
#
-# The test stubs curl, pgrep, llamachat and imggen on PATH and points
+# The test stubs curl, pgrep and llamachat on PATH and points
# AI_ASSISTANT and AI_SD_LOG at fixtures; see test-ai-state.sh.
set -u
@@ -65,7 +63,7 @@ model_of() {
sd() {
local line busy=idle mtime
- # A one-shot sd-cli (fanfictioner runs them) holds VRAM and generates for
+ # A one-shot sd-cli holds VRAM and generates for
# as long as it lives, so it outranks whatever the web UI is doing.
if line="$(pgrep -axo sd-cli)"; then
row engine sd up busy "$(model_of "$line") (sd-cli)"
@@ -81,8 +79,6 @@ sd() {
}
apps() {
- local out pid
-
if "$ASSISTANT" status >/dev/null 2>&1; then
row app assistant running -
else
@@ -94,23 +90,6 @@ apps() {
else
row app chat stopped -
fi
-
- # imggen status exits 0 either way: the daemon's JSON when it is up,
- # "daemon down" when it is not.
- out="$(imggen status 2>/dev/null)"
- if [[ "$out" == "{"* ]]; then
- row app imggen running "$(jq -r '.model // "-"' <<<"$out" 2>/dev/null || echo -)"
- else
- row app imggen stopped -
- fi
-
- # It runs through env, so the command line is python3 then the script,
- # by path from ~/bin or by ./fanfictioner from the repo.
- if pid="$(pgrep -u "$USER" -fo '^[^ ]*python3[^ ]* [^ ]*fanfictioner( |$)')"; then
- row app fanfic running "$pid"
- else
- row app fanfic stopped -
- fi
}
llama
diff --git a/desktop/modules/ai/test-ai-state.sh b/desktop/modules/ai/test-ai-state.sh
index e3e8ba0..aac83fb 100755
--- a/desktop/modules/ai/test-ai-state.sh
+++ b/desktop/modules/ai/test-ai-state.sh
@@ -11,8 +11,8 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
-# The one runnable check for ai-state.sh. It puts stub curl, pgrep,
-# llamachat and imggen on PATH and a stub assistant.sh beside them, then runs
+# The one runnable check for ai-state.sh. It puts stub curl, pgrep
+# and llamachat on PATH and a stub assistant.sh beside them, then runs
# the real script, so nothing here touches the live stack. T_* variables pick
# the state each stub reports.
#
@@ -57,9 +57,6 @@ case "$*" in
*sd-server*)
[[ -n "${T_SD:-}" ]] || exit 1
echo "4242 sd-server --listen-port 7860 --diffusion-model /data/SD/z_image_turbo-Q8_0.gguf --vae /data/SD/vae/flux1-ae.safetensors" ;;
- *fanfictioner*)
- [[ -n "${T_FANFIC:-}" ]] || exit 1
- echo 31337 ;;
*) exit 1 ;;
esac
STUB
@@ -69,13 +66,6 @@ cat > "$stub/llamachat" <<'STUB'
[[ "$1" == --ping && -n "${T_CHAT:-}" ]]
STUB
-# The real imggen exits 0 either way and says which on stdout.
-cat > "$stub/imggen" <<'STUB'
-#!/bin/bash
-[[ "$1" == status ]] || exit 1
-if [[ -n "${T_IMG:-}" ]]; then echo '{"model": "realvis", "ready": true}'; else echo "daemon down"; fi
-STUB
-
cat > "$stub/assistant.sh" <<'STUB'
#!/bin/bash
[[ "$1" == status && -n "${T_ASSIST:-}" ]]
@@ -106,7 +96,7 @@ run() {
bash "$here/ai-state.sh"
}
-apps_down="$(l app assistant stopped -; l app chat stopped -; l app imggen stopped -; l app fanfic stopped -)"
+apps_down="$(l app assistant stopped -; l app chat stopped -)"
want="$(l engine llama down idle -; l engine sd down idle -)
$apps_down"
@@ -131,7 +121,7 @@ touch -d '1 minute ago' "$log"
got="$(run T_SD=1 | sed -n 2p)"
check "sd running, log quiet" "$(l engine sd up idle z_image_turbo-Q8_0.gguf)" "$got"
-# A one-shot sd-cli (fanfictioner's) holds VRAM and is generating for as
+# A one-shot sd-cli holds VRAM and is generating for as
# long as it runs, whatever the web UI is doing. Its prompt is free text, so
# a "-m" inside it must not be read as the model.
got="$(run T_CLI=1 | sed -n 2p)"
@@ -140,8 +130,8 @@ check "sd-cli running" "$(l engine sd up busy "Krea-2-Turbo-Q6_K.gguf (sd-cli)")
got="$(run T_CLI=1 T_SD=1 | sed -n 2p)"
check "sd-cli wins over an idle web UI" "$(l engine sd up busy "Krea-2-Turbo-Q6_K.gguf (sd-cli)")" "$got"
-want="$(l app assistant running -; l app chat running -; l app imggen running realvis; l app fanfic running 31337)"
-got="$(run T_ASSIST=1 T_CHAT=1 T_IMG=1 T_FANFIC=1 | tail -n4)"
+want="$(l app assistant running -; l app chat running -)"
+got="$(run T_ASSIST=1 T_CHAT=1 | tail -n2)"
check "every app running" "$want" "$got"
printf '\n%d passed, %d failed\n' "$pass" "$fail"