From fcf58fa7cf230347ca5be72df54aaa5891444f10 Mon Sep 17 00:00:00 2001 From: Tomas Kracmar Date: Mon, 8 Sep 2025 13:16:48 +0200 Subject: [PATCH] Fixing KB name resolution --- scripts/podx-tools.sh | 92 ++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 57 deletions(-) diff --git a/scripts/podx-tools.sh b/scripts/podx-tools.sh index ad867b9..6d6e26e 100755 --- a/scripts/podx-tools.sh +++ b/scripts/podx-tools.sh @@ -82,6 +82,8 @@ fi : "${OPENWEBUI_URL:=http://localhost:3003}" : "${OPENWEBUI_URL_HOST:=}" : "${OPENWEBUI_API_KEY:=}" +# Optional: explicit KB id to use for all KB operations (bypasses name resolution) +: "${OPENWEBUI_KB_ID:=}" # Resolve a working OpenWebUI base URL (fallback from host.docker.internal -> localhost) _owui_url() { @@ -127,9 +129,14 @@ _kb_create() { _kb_id_by_name() { local kb_name="$1" + # If an explicit KB id is provided via env, use it directly + if [ -n "${OPENWEBUI_KB_ID:-}" ]; then + echo "$OPENWEBUI_KB_ID" + return 0 + fi local json; json="$(_owui_get_kb_list)" - # Robust KB name resolver: Unicode/space-insensitive, prefers most recently updated - printf '%s' "$json" | python3 - "$kb_name" <<'PY' || true + local __id="" + __id=$(printf '%s' "$json" | python3 - "$kb_name" <<'PY' || true import sys, json, unicodedata as ud def norm(s: str) -> str: @@ -139,32 +146,49 @@ def norm(s: str) -> str: want = norm(sys.argv[1] if len(sys.argv) > 1 else '') raw = sys.stdin.read().strip() if not raw: - sys.exit(0) + print('', end=''); raise SystemExit(0) try: d = json.loads(raw) except Exception: - sys.exit(0) + print('', end=''); raise SystemExit(0) items = d.get('data') if isinstance(d, dict) and isinstance(d.get('data'), list) else (d if isinstance(d, list) else []) -# If only one KB exists and a name was provided, return it -if want and isinstance(items, list) and len(items) == 1: - print(items[0].get('id',''), end=''); sys.exit(0) +# If only one KB exists, return it +if isinstance(items, list) and len(items) == 1: + print(items[0].get('id',''), end=''); raise SystemExit(0) -# Prefer exact name match (normalized) +# Prefer exact normalized name match exact = [kb for kb in items if norm(kb.get('name')) == want] if exact: exact.sort(key=lambda kb: int(kb.get('updated_at') or kb.get('created_at') or 0), reverse=True) - print(exact[0].get('id',''), end=''); sys.exit(0) + print(exact[0].get('id',''), end=''); raise SystemExit(0) # Fallback: substring match subs = [kb for kb in items if want and want in norm(kb.get('name'))] if subs: subs.sort(key=lambda kb: int(kb.get('updated_at') or kb.get('created_at') or 0), reverse=True) - print(subs[0].get('id',''), end=''); sys.exit(0) + print(subs[0].get('id',''), end=''); raise SystemExit(0) print('', end='') PY + ) + + # If python resolution failed, try jq (if available) + if [ -z "${__id:-}" ]; then + if command -v jq >/dev/null 2>&1; then + __id=$(printf '%s' "$json" | jq -r ' + if type=="array" and length==1 then .[0].id // empty + elif type=="array" then (map(select((.name // "")|ascii_downcase==("'"$kb_name"'"|ascii_downcase))) | .[0].id) // empty + elif has("data") and (.data|type=="array") and (.data|length==1) then .data[0].id // empty + else empty end') + fi + fi + # Last resort: naive sed/grep — take the first id field + if [ -z "${__id:-}" ]; then + __id=$(printf '%s' "$json" | sed -n 's/.*"id"[[:space:]]*:[[:space:]]*"\([^"]\+\)".*/\1/p' | head -n1) + fi + printf '%s' "${__id:-}" } _help() { @@ -348,53 +372,7 @@ PY cat "$tmp_body" | ppjson echo "[owui] http_code=$http_code bytes=$bytes" json="$(cat "$tmp_body")"; rm -f "$tmp_body" - id="$(python3 - "$name" <<'PY' -import sys, json, unicodedata as ud - -def norm(s: str) -> str: - s = ud.normalize('NFKC', s or '') - return s.strip().casefold() - -want = norm(sys.argv[1] if len(sys.argv) > 1 else '') -raw = sys.stdin.read() -try: - d = json.loads(raw) -except Exception: - print('', end=''); sys.exit(0) -items = d.get('data') if isinstance(d, dict) and isinstance(d.get('data'), list) else (d if isinstance(d, list) else []) - -# Single-KB fallback -if want and isinstance(items, list) and len(items) == 1: - print(items[0].get('id',''), end=''); sys.exit(0) - -exact = [kb for kb in items if norm(kb.get('name')) == want] -subs = [kb for kb in items if want and want in norm(kb.get('name'))] - -cands = exact or subs -if cands: - cands.sort(key=lambda kb: int(kb.get('updated_at') or kb.get('created_at') or 0), reverse=True) - print(cands[0].get('id',''), end='') -else: - print('', end='') -PY - <<<"$json")" || id="" - # Fallback: if the list contains exactly one KB, use its id - if [ -z "$id" ]; then - id="$(printf '%s' "$json" | python3 - <<'PY' -import sys, json -raw=sys.stdin.read().strip() -try: - d=json.loads(raw) -except Exception: - print('', end=''); raise SystemExit(0) -items = d.get('data') if isinstance(d, dict) and isinstance(d.get('data'), list) else (d if isinstance(d, list) else []) -if isinstance(items, list) and len(items)==1: - print(items[0].get('id',''), end='') -else: - print('', end='') -PY -)" || id="" - fi + id="$(_kb_id_by_name "$name")" if [ -n "$id" ]; then echo "[owui] resolved id for \"$name\": $id" else