diff --git a/scripts/podx-tools.sh b/scripts/podx-tools.sh index 61c247f..90be100 100755 --- a/scripts/podx-tools.sh +++ b/scripts/podx-tools.sh @@ -107,14 +107,60 @@ _kb_id_by_name() { _require "OPENWEBUI_URL" "$OPENWEBUI_URL" local url url="$(_owui_url)/api/v1/knowledge/list" - curl -sS -H "Authorization: Bearer $OPENWEBUI_API_KEY" "$url" \ - | python3 -c 'import sys,json,os; name=os.environ.get("KB_NAME"); + + # Fetch list once + local body tmp_code + body="$(_mktemp)"; tmp_code="$(_mktemp)" + curl -sS -H "Authorization: Bearer $OPENWEBUI_API_KEY" \ + -w "%{http_code}" --output "$body" "$url" >"$tmp_code" || true + local http_code; http_code="$(cat "$tmp_code" 2>/dev/null || echo 0)"; rm -f "$tmp_code" + + # If non-200, return empty + if [ "$http_code" != "200" ]; then + rm -f "$body"; echo ""; return + fi + + # Parse with python: prefer exact name match; if multiple, choose by latest updated_at; else try substring match + local id + id="$(python3 - "$kb_name" <"$body" 2>/dev/null <<'PY' +import sys, json +name = sys.argv[1] try: - data=json.load(sys.stdin) + data = json.load(sys.stdin) except Exception: - print("", end=""); sys.exit(0) -print(next((kb.get("id","") for kb in data if kb.get("name")==name), ""), end="")' \ - KB_NAME="$kb_name" + print("") + sys.exit(0) + +# Normalize to list +if not isinstance(data, list): + print("") + sys.exit(0) + +candidates = [kb for kb in data if (kb.get('name') or '') == name] +# If nothing exact, try substring (case-insensitive) +if not candidates: + lname = name.lower() + candidates = [kb for kb in data if lname in (kb.get('name') or '').lower()] + +if not candidates: + print("") + sys.exit(0) + +# Choose the one with the newest updated_at (numeric seconds); fall back to created_at; else first. +from operator import itemgetter + +def ts(kb, key): + try: + return int(kb.get(key) or 0) + except Exception: + return 0 + +best = sorted(candidates, key=lambda kb: (ts(kb,'updated_at'), ts(kb,'created_at')), reverse=True)[0] +print(best.get('id','')) +PY +)" + rm -f "$body" + echo "$id" } _help() { @@ -133,6 +179,8 @@ Meilisearch: OpenWebUI: owui-health # check API health (200) owui-kbs # list knowledge bases + owui-kbs-raw # list knowledge bases raw JSON (debug) + owui-kb-debug "" # debug KB id resolution owui-kb-id "" # print the KB UUID by exact name owui-upload # upload a file, prints file_id owui-attach "" # upload + attach to KB @@ -235,6 +283,27 @@ print(f\"Indexed {n} document(s).\")" "$(_owui_url)/api/v1/knowledge/list" | ppjson ;; + owui-kbs-raw) + _require "OPENWEBUI_URL" "$OPENWEBUI_URL" + _require "OPENWEBUI_API_KEY" "$OPENWEBUI_API_KEY" + curl -sS -H "Authorization: Bearer $OPENWEBUI_API_KEY" \ + "$(_owui_url)/api/v1/knowledge/list" + ;; + + owui-kb-debug) + shift || true + name="${1:-}" + if [ -z "$name" ]; then echo "Usage: owui-kb-debug \"\"" >&2; exit 1; fi + _require "OPENWEBUI_URL" "$OPENWEBUI_URL" + _require "OPENWEBUI_API_KEY" "$OPENWEBUI_API_KEY" + echo "[debug] Resolved KB URL: $(_owui_url)" + echo "[debug] Looking for KB name: $name" + echo "[debug] Listing KBs (pretty):" + curl -sS -H "Authorization: Bearer $OPENWEBUI_API_KEY" \ + "$(_owui_url)/api/v1/knowledge/list" | ppjson + echo "[debug] Resolved KB id: $(_kb_id_by_name "$name")" + ;; + owui-kb-id) shift || true name="${1:-}" @@ -304,7 +373,11 @@ print(f\"Indexed {n} document(s).\")" # 2) Resolve KB and attach KB_ID="$(_kb_id_by_name "$kb_name")" echo "[owui] attaching to KB: $kb_name (id: $KB_ID)" - if [ -z "$KB_ID" ]; then echo "KB '$kb_name' not found"; exit 1; fi + if [ -z "$KB_ID" ]; then + echo "KB '$kb_name' not found (or ambiguous)." >&2 + echo "Tip: run './scripts/podx-tools.sh owui-kb-debug \"$kb_name\"' to inspect the KB list and resolved id." >&2 + exit 1 + fi # Attach: capture headers, body, http code and curl exit tmp_body="$(_mktemp)"; tmp_code="$(_mktemp)"; tmp_hdrs="$(_mktemp)"