diff options
| author | Michael Peter Christen <mc@yacy.net> | 2025-12-06 17:33:31 +0100 |
|---|---|---|
| committer | Michael Peter Christen <mc@yacy.net> | 2025-12-06 17:33:31 +0100 |
| commit | ed9ea238b1e7d4a89d77acea790b08b6f2b1ed49 (patch) | |
| tree | 29e59c24d5d7f16ca497feeb367632cc2ebb22df /source | |
| parent | 5f4575ad6b0d615b16e8dcbef409b81f8ab7ab43 (diff) | |
added build page for the AI lab
Diffstat (limited to 'source')
| -rw-r--r-- | source/net/yacy/htroot/AILab.java | 87 | ||||
| -rw-r--r-- | source/net/yacy/htroot/LLMSelection_p.java | 20 |
2 files changed, 106 insertions, 1 deletions
diff --git a/source/net/yacy/htroot/AILab.java b/source/net/yacy/htroot/AILab.java new file mode 100644 index 000000000..461a8c32e --- /dev/null +++ b/source/net/yacy/htroot/AILab.java @@ -0,0 +1,87 @@ +// AILab.java +// ------------- +// (C) 2024 by contributors to the YaCy project +// +// This servlet feeds the AI Lab landing page with completion hints +// derived from existing configuration and index state. + +package net.yacy.htroot; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; + +import net.yacy.cora.protocol.RequestHeader; +import net.yacy.search.Switchboard; +import net.yacy.server.serverObjects; +import net.yacy.server.serverSwitch; + +public class AILab { + + public static serverObjects respond(@SuppressWarnings("unused") final RequestHeader header, final serverObjects post, final serverSwitch env) { + final Switchboard sb = (Switchboard) env; + final serverObjects prop = new serverObjects(); + + boolean hasEngine = false; + boolean hasModel = false; + boolean hasRagRole = false; + + // Parse configured production models to infer readiness of engine/model/RAG quests. + final String productionModelJson = sb.getConfig("ai.production_models", "[]"); + try { + final JSONArray productionModels = new JSONArray(new JSONTokener(productionModelJson)); + for (int i = 0; i < productionModels.length(); i++) { + final org.json.JSONObject row = productionModels.getJSONObject(i); + if (!hasEngine) { + hasEngine = !row.optString("hoststub", "").isEmpty(); + } + if (!hasModel) { + hasModel = !row.optString("model", "").isEmpty(); + } + if (!hasRagRole) { + hasRagRole = row.optBoolean("search", false) || row.optBoolean("query", false) || row.optBoolean("qapairs", false); + } + if (hasEngine && hasModel && hasRagRole) { + break; + } + } + } catch (final JSONException e) { + // ignore malformed configuration; fallback statuses will stay "pending" + } + + // consider explicit inference_system configuration as an engine binding + if (!hasEngine) { + final String inferenceJson = sb.getConfig("ai.inference_system", "{}"); + try { + final JSONObject inference = new JSONObject(new JSONTokener(inferenceJson)); + final String hoststub = inference.optString("hoststub", "").trim(); + if (!hoststub.isEmpty()) { + hasEngine = true; + } + } catch (final JSONException e) { + // ignore malformed inference_system + } + } + + // Index presence check: if there are documents in the default fulltext collection, we consider the quest ready. + final long indexDocs = sb.index.fulltext().collectionSize(); + final long indexNeeded = 1000L; + final boolean hasIndex = indexDocs >= indexNeeded; + + // Shield configuration: treat any non-empty custom value as "ready". + final String shieldDefinition = sb.getConfig("ai.shield.definition", "").trim(); + final boolean hasShield = !shieldDefinition.isEmpty(); + + prop.put("ailab_inference_status", hasEngine ? "ready" : "pending"); + prop.put("ailab_model_status", hasModel ? "ready" : "pending"); + prop.put("ailab_inference_configured", hasEngine ? "1" : "0"); + prop.put("ailab_index_status", hasIndex ? "ready" : "pending"); + prop.putNum("ailab_index_count", indexDocs); + prop.putNum("ailab_index_needed", indexNeeded); + prop.put("ailab_rag_status", hasRagRole ? "ready" : "pending"); + prop.put("ailab_shield_status", hasShield ? "ready" : "pending"); + + return prop; + } +} diff --git a/source/net/yacy/htroot/LLMSelection_p.java b/source/net/yacy/htroot/LLMSelection_p.java index 3877ffdac..305864739 100644 --- a/source/net/yacy/htroot/LLMSelection_p.java +++ b/source/net/yacy/htroot/LLMSelection_p.java @@ -58,6 +58,11 @@ public class LLMSelection_p { //e.printStackTrace(); } } + + JSONObject inferenceSystem = bodyj.optJSONObject("inference_system"); + if (inferenceSystem != null) { + sb.setConfig("ai.inference_system", inferenceSystem.toString()); + } /* {"production_models":[{ "service":"OLLAMA", @@ -104,6 +109,19 @@ public class LLMSelection_p { e.printStackTrace(); } + // prefill inference system configuration if present + final String inferenceJson = sb.getConfig("ai.inference_system", "{}"); + try { + JSONObject inference = new JSONObject(new JSONTokener(inferenceJson)); + prop.put("llm_service", inference.optString("service", "OLLAMA")); + prop.put("llm_hoststub", inference.optString("hoststub", "http://localhost:11434")); + prop.put("llm_apikey", inference.optString("api_key", "")); + } catch (JSONException e) { + prop.put("llm_service", "OLLAMA"); + prop.put("llm_hoststub", "http://localhost:11434"); + prop.put("llm_apikey", ""); + } + if (post == null || env == null) { return prop; // nothing to do } @@ -112,4 +130,4 @@ public class LLMSelection_p { return prop; } -}
\ No newline at end of file +} |
