diff --git a/scripts/podx-tools.sh b/scripts/podx-tools.sh index b99663e..798b155 100755 --- a/scripts/podx-tools.sh +++ b/scripts/podx-tools.sh @@ -128,10 +128,15 @@ _kb_create() { _kb_id_by_name() { local kb_name="$1" local json; json="$(_owui_get_kb_list)" - # Normalize to a flat list and choose the most recently updated match (robust name matching) + # Robust KB name resolver: Unicode/space-insensitive, prefers most recently updated python3 - "$kb_name" <<'PY' || true -import sys, json -want = (sys.argv[1] or "").strip() +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().strip() if not raw: sys.exit(0) @@ -139,36 +144,26 @@ try: d = json.loads(raw) except Exception: sys.exit(0) -# Support both list and {data:[...]} -if isinstance(d, dict) and isinstance(d.get("data"), list): - items = d["data"] -elif isinstance(d, list): - items = d -else: - items = [] -def ts(kb): - for key in ("updated_at", "created_at"): - v = kb.get(key) - if isinstance(v, (int, float)): - return int(v) - return 0 +items = d.get('data') if isinstance(d, dict) and isinstance(d.get('data'), list) else (d if isinstance(d, list) else []) -# Helper to normalize a KB name for comparison -norm = lambda s: (s or "").strip().casefold() -want_n = norm(want) +# 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) -# Try exact match (case/space-insensitive) -exact = [kb for kb in items if norm(kb.get("name")) == want_n] +# Prefer exact name match (normalized) +exact = [kb for kb in items if norm(kb.get('name')) == want] if exact: - print(sorted(exact, key=ts, reverse=True)[0].get("id", ""), end=""); sys.exit(0) + 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) -# Then case-insensitive substring match -subs = [kb for kb in items if want_n and want_n in norm(kb.get("name"))] +# Fallback: substring match +subs = [kb for kb in items if want and want in norm(kb.get('name'))] if subs: - print(sorted(subs, key=ts, reverse=True)[0].get("id", ""), end=""); sys.exit(0) + 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("", end="") +print('', end='') PY } @@ -191,6 +186,7 @@ OpenWebUI: owui-kb-id "" # print the KB UUID by exact name owui-kb-id-all "" # list all matching KB ids (if duplicates exist) owui-kb-resolve "" # debug name->id resolution with raw listing + # Name resolution is Unicode/space-insensitive and prefers the most recently updated match. owui-upload # upload a file, prints file_id owui-attach "" # upload + attach to KB owui-attach-id # upload + attach using explicit KB id @@ -353,25 +349,33 @@ PY echo "[owui] http_code=$http_code bytes=$bytes" json="$(cat "$tmp_body")"; rm -f "$tmp_body" id="$(python3 - "$name" <<'PY' -import sys, json -want = (sys.argv[1] or "").strip() +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 []) -norm = lambda s: (s or "").strip().casefold() -want_n = norm(want) -def ts(kb): - for k in ("updated_at","created_at"): - v = kb.get(k) - if isinstance(v,(int,float)): return int(v) - return 0 -exact = [kb for kb in items if norm(kb.get("name")) == want_n] -subs = [kb for kb in items if want_n and want_n in norm(kb.get("name"))] + 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 -print((sorted(cands, key=ts, reverse=True)[0].get("id","")) if cands else "", end="") +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")" if [ -n "$id" ]; then