fix(singbox): экспорт COMMUNITY_SERVICES для загрузки ruleset и исправление RAG эмбеддингов AI Doctor
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
let fs = require("fs");
|
let fs = require("fs");
|
||||||
let common = require("core.common");
|
let common = require("core.common");
|
||||||
|
|
||||||
|
let as_string = common.as_string;
|
||||||
let command_from_args = common.command_from_args;
|
let command_from_args = common.command_from_args;
|
||||||
let rag_index = null;
|
let rag_index = null;
|
||||||
let rag_embed_cache = null;
|
let rag_embed_cache = null;
|
||||||
@@ -156,6 +157,12 @@ function call_embedding_api(api_url, api_key, model, texts) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sqrt_val(x) {
|
||||||
|
if (x <= 0)
|
||||||
|
return 0.0;
|
||||||
|
return x ** 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
function cosine_similarity(a, b) {
|
function cosine_similarity(a, b) {
|
||||||
let len = length(a);
|
let len = length(a);
|
||||||
if (len == 0 || length(b) != len)
|
if (len == 0 || length(b) != len)
|
||||||
@@ -166,7 +173,7 @@ function cosine_similarity(a, b) {
|
|||||||
norm_a += a[i] * a[i];
|
norm_a += a[i] * a[i];
|
||||||
norm_b += b[i] * b[i];
|
norm_b += b[i] * b[i];
|
||||||
}
|
}
|
||||||
let denom = sqrt(norm_a) * sqrt(norm_b);
|
let denom = sqrt_val(norm_a) * sqrt_val(norm_b);
|
||||||
if (denom == 0)
|
if (denom == 0)
|
||||||
return 0;
|
return 0;
|
||||||
return dot / denom;
|
return dot / denom;
|
||||||
@@ -223,12 +230,12 @@ function search(query_embedding, index, top_k) {
|
|||||||
if (length(chunk.embedding) == 0)
|
if (length(chunk.embedding) == 0)
|
||||||
continue;
|
continue;
|
||||||
let score = cosine_similarity(query_embedding, chunk.embedding);
|
let score = cosine_similarity(query_embedding, chunk.embedding);
|
||||||
push({ chunk: chunk, score: score }, scored);
|
push(scored, { chunk: chunk, score: score });
|
||||||
}
|
}
|
||||||
sort(scored, function(a, b) { return b.score - a.score; });
|
sort(scored, function(a, b) { return b.score - a.score; });
|
||||||
let limit = top_k || 3;
|
let limit = top_k || 3;
|
||||||
if (length(scored) > limit)
|
if (length(scored) > limit)
|
||||||
scored = scored.slice(0, limit);
|
scored = slice(scored, 0, limit);
|
||||||
return scored;
|
return scored;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,8 +257,8 @@ function retrieve(query, provider, api_key, custom_url, model_override, top_k) {
|
|||||||
let r = results[i];
|
let r = results[i];
|
||||||
if (r.score < 0.3)
|
if (r.score < 0.3)
|
||||||
continue;
|
continue;
|
||||||
push(sprintf("[Source: %s — %s] (relevance: %.0f%%)\n%s",
|
push(parts, sprintf("[Source: %s — %s] (relevance: %.0f%%)\n%s",
|
||||||
r.chunk.file, r.chunk.heading, r.score * 100, r.chunk.text), parts);
|
r.chunk.file, r.chunk.heading, r.score * 100, r.chunk.text));
|
||||||
}
|
}
|
||||||
return join("\n\n---\n\n", parts);
|
return join("\n\n---\n\n", parts);
|
||||||
}
|
}
|
||||||
@@ -278,5 +285,7 @@ return {
|
|||||||
retrieve: retrieve,
|
retrieve: retrieve,
|
||||||
invalidate_cache: invalidate_cache,
|
invalidate_cache: invalidate_cache,
|
||||||
status: status,
|
status: status,
|
||||||
load_raw_index: load_raw_index
|
load_raw_index: load_raw_index,
|
||||||
|
get_embedding_model: get_embedding_model,
|
||||||
|
search: search
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ function remote_format(reference) {
|
|||||||
|
|
||||||
function module_exports() {
|
function module_exports() {
|
||||||
return {
|
return {
|
||||||
|
COMMUNITY_SERVICES,
|
||||||
is_community,
|
is_community,
|
||||||
community_url,
|
community_url,
|
||||||
hash12,
|
hash12,
|
||||||
|
|||||||
@@ -56,4 +56,26 @@ print((length(out) == 2 && length(out[0]) == 2 && out[1][1] == 4) ? "OK" : "BAD"
|
|||||||
[ "$push_check" = "OK" ] ||
|
[ "$push_check" = "OK" ] ||
|
||||||
fail "ucode push(array, value) did not behave as expected (saw '$push_check')"
|
fail "ucode push(array, value) did not behave as expected (saw '$push_check')"
|
||||||
|
|
||||||
|
# 6. Runtime verification of rag.uc functions (as_string, get_embedding_model, search, sqrt_val, slice)
|
||||||
|
runtime_check="$(ucode -L "$TACHYON_LIB" -e '
|
||||||
|
let rag = require("diagnostics.rag");
|
||||||
|
assert(rag.get_embedding_model("OpenAI") == "text-embedding-3-small", "OpenAI");
|
||||||
|
assert(rag.get_embedding_model("DEEPSEEK") == "deepseek-embedding", "DeepSeek");
|
||||||
|
assert(rag.get_embedding_model(null, null) == "text-embedding-3-small", "null");
|
||||||
|
|
||||||
|
let idx = {
|
||||||
|
chunks: [
|
||||||
|
{ file: "f1.md", heading: "H1", text: "T1", embedding: [1.0, 0.0] },
|
||||||
|
{ file: "f2.md", heading: "H2", text: "T2", embedding: [0.9, 0.1] },
|
||||||
|
{ file: "f3.md", heading: "H3", text: "T3", embedding: [0.8, 0.2] }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let res = rag.search([1.0, 0.0], idx, 2);
|
||||||
|
assert(length(res) == 2, "limit 2");
|
||||||
|
assert(res[0].chunk.file == "f1.md", "best match");
|
||||||
|
print("OK");
|
||||||
|
' 2>&1 || echo "FAIL")"
|
||||||
|
[ "$runtime_check" = "OK" ] ||
|
||||||
|
fail "rag.uc runtime execution failed (saw '$runtime_check')"
|
||||||
|
|
||||||
printf 'rag embeddings checks passed\n'
|
printf 'rag embeddings checks passed\n'
|
||||||
|
|||||||
@@ -46,5 +46,7 @@ assert_eq binary \
|
|||||||
"unknown remote ruleset format"
|
"unknown remote ruleset format"
|
||||||
|
|
||||||
ucode -L "$TACHYON_LIB" -e 'let rulesets = require("singbox.rulesets"); if (rulesets.kind_from_reference_hint("geoip") != "subnets") exit(1);'
|
ucode -L "$TACHYON_LIB" -e 'let rulesets = require("singbox.rulesets"); if (rulesets.kind_from_reference_hint("geoip") != "subnets") exit(1);'
|
||||||
|
ucode -L "$TACHYON_LIB" -e 'let rulesets = require("singbox.rulesets"); if (type(rulesets.COMMUNITY_SERVICES) != "object" || !rulesets.COMMUNITY_SERVICES.discord) exit(1);'
|
||||||
|
|
||||||
printf 'singbox rulesets checks passed\n'
|
printf 'singbox rulesets checks passed\n'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user