mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
feat(authority): detect BME manifest capability
This commit is contained in:
6
index.js
6
index.js
@@ -1626,6 +1626,12 @@ function buildAuthorityPersistenceStatePatch(settings = getSettings()) {
|
||||
authorityTriviumPrimaryReady: Boolean(capability.triviumPrimaryReady),
|
||||
authorityJobsReady: Boolean(capability.jobsReady),
|
||||
authorityBlobReady: Boolean(capability.blobReady),
|
||||
authorityBmeProtocolVersion: Math.max(0, Number(capability.bmeProtocolVersion) || 0),
|
||||
authorityBmeVectorManifestReady: Boolean(capability.bmeVectorManifestReady),
|
||||
authorityBmeVectorApplyReady: Boolean(capability.bmeVectorApplyReady),
|
||||
authorityBmeVectorApplyJobsReady: Boolean(capability.bmeVectorApplyJobsReady),
|
||||
authorityBmeServerEmbeddingProbeReady: Boolean(capability.bmeServerEmbeddingProbeReady),
|
||||
authorityBmeCandidateSearchReady: Boolean(capability.bmeCandidateSearchReady),
|
||||
authorityBrowserCacheMode: String(browserState.mode || "minimal"),
|
||||
authorityOfflineQueueBytes: Number(browserState.offlineQueueBytes || 0),
|
||||
authorityOfflineQueueItems: Number(browserState.offlineQueueItems || 0),
|
||||
|
||||
@@ -6,6 +6,11 @@ const SQL_MUTATION_FEATURES = ["sql", "sql.mutation", "sql.execute", "sql.exec",
|
||||
const TRIVIUM_FEATURES = ["trivium", "trivium.search", "trivium.query", "trivium.filterwhere", "trivium.bulkupsert", "trivium.upsert", "trivium.bulkmutations"];
|
||||
const JOB_FEATURES = ["jobs", "jobs.background", "jobs.list", "jobs.wait", "diagnostics.jobspage", "events", "sse"];
|
||||
const BLOB_FEATURES = ["blob", "blob.write", "storage.blob", "transfers.blob", "transfers.fs", "fs.private", "privatefiles", "private.files", "files.private"];
|
||||
const BME_VECTOR_MANIFEST_FEATURES = ["bme.vectormanifest", "bme.vector.manifest", "bme.vector-manifest"];
|
||||
const BME_VECTOR_APPLY_FEATURES = ["bme.vectorapply", "bme.vector.apply"];
|
||||
const BME_VECTOR_APPLY_JOB_FEATURES = ["bme.vectorapplyjobs", "bme.vector.applyjobs", "bme.vector.apply.jobs"];
|
||||
const BME_SERVER_EMBEDDING_FEATURES = ["bme.serverembeddingprobe", "bme.server.embedding.probe"];
|
||||
const BME_CANDIDATE_SEARCH_FEATURES = ["bme.candidatesearch", "bme.candidate.search"];
|
||||
|
||||
function toBoolean(value, fallback = false) {
|
||||
if (typeof value === "boolean") return value;
|
||||
@@ -65,9 +70,20 @@ function createFeatureReadiness(features) {
|
||||
trivium: hasAnyFeature(features, TRIVIUM_FEATURES),
|
||||
jobs: hasAnyFeature(features, JOB_FEATURES),
|
||||
blob: hasAnyFeature(features, BLOB_FEATURES),
|
||||
bmeVectorManifest: hasAnyFeature(features, BME_VECTOR_MANIFEST_FEATURES),
|
||||
bmeVectorApply: hasAnyFeature(features, BME_VECTOR_APPLY_FEATURES),
|
||||
bmeVectorApplyJobs: hasAnyFeature(features, BME_VECTOR_APPLY_JOB_FEATURES),
|
||||
bmeServerEmbeddingProbe: hasAnyFeature(features, BME_SERVER_EMBEDDING_FEATURES),
|
||||
bmeCandidateSearch: hasAnyFeature(features, BME_CANDIDATE_SEARCH_FEATURES),
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeBmeProtocolVersion(features, source = {}) {
|
||||
const direct = Number(source?.bme?.protocolVersion ?? source?.features?.bme?.protocolVersion ?? 0);
|
||||
if (Number.isFinite(direct) && direct > 0) return Math.trunc(direct);
|
||||
return features.has("bme.protocolversion") ? 1 : 0;
|
||||
}
|
||||
|
||||
function collectMissingFeatures(readiness) {
|
||||
const missing = [];
|
||||
if (!readiness.sql) missing.push("sql.query");
|
||||
@@ -430,6 +446,12 @@ export function createDefaultAuthorityCapabilityState(overrides = {}) {
|
||||
supportedJobTypes: [],
|
||||
supportedJobTypesKnown: false,
|
||||
blobReady: false,
|
||||
bmeVectorManifestReady: false,
|
||||
bmeVectorApplyReady: false,
|
||||
bmeVectorApplyJobsReady: false,
|
||||
bmeServerEmbeddingProbeReady: false,
|
||||
bmeCandidateSearchReady: false,
|
||||
bmeProtocolVersion: 0,
|
||||
features: [],
|
||||
missingFeatures: ["sql.query", "sql.mutation", "trivium.search", "jobs", "blob-or-private-files"],
|
||||
reason: "not-probed",
|
||||
@@ -461,6 +483,12 @@ export function normalizeAuthorityCapabilityState(input = {}, settings = {}) {
|
||||
const triviumPrimaryReady = healthy && sessionReady && permissionReady && readiness.trivium;
|
||||
const jobsReady = healthy && readiness.jobs;
|
||||
const blobReady = healthy && readiness.blob;
|
||||
const bmeProtocolVersion = normalizeBmeProtocolVersion(features, source);
|
||||
const bmeVectorManifestReady = healthy && sessionReady && permissionReady && readiness.bmeVectorManifest;
|
||||
const bmeVectorApplyReady = healthy && sessionReady && permissionReady && readiness.bmeVectorApply;
|
||||
const bmeVectorApplyJobsReady = healthy && sessionReady && permissionReady && readiness.bmeVectorApplyJobs;
|
||||
const bmeServerEmbeddingProbeReady = healthy && sessionReady && permissionReady && readiness.bmeServerEmbeddingProbe;
|
||||
const bmeCandidateSearchReady = healthy && sessionReady && permissionReady && readiness.bmeCandidateSearch;
|
||||
const minimumFeatureSetReady = storagePrimaryReady && triviumPrimaryReady && jobsReady && blobReady;
|
||||
const serverPrimaryRequested =
|
||||
normalizedSettings.enabled &&
|
||||
@@ -483,6 +511,12 @@ export function normalizeAuthorityCapabilityState(input = {}, settings = {}) {
|
||||
supportedJobTypes: supportedJobs.supportedJobTypes,
|
||||
supportedJobTypesKnown: supportedJobs.supportedJobTypesKnown,
|
||||
blobReady,
|
||||
bmeVectorManifestReady,
|
||||
bmeVectorApplyReady,
|
||||
bmeVectorApplyJobsReady,
|
||||
bmeServerEmbeddingProbeReady,
|
||||
bmeCandidateSearchReady,
|
||||
bmeProtocolVersion,
|
||||
features: Array.from(features).sort(),
|
||||
missingFeatures,
|
||||
reason: String(source.reason || (healthy ? "ok" : "not-ready")),
|
||||
|
||||
@@ -25,6 +25,9 @@ export function createAuthorityUpgradeState(overrides = {}) {
|
||||
storageReady: Boolean(overrides.storageReady),
|
||||
vectorReady: Boolean(overrides.vectorReady),
|
||||
jobsReady: Boolean(overrides.jobsReady),
|
||||
bmeVectorManifestReady: Boolean(overrides.bmeVectorManifestReady),
|
||||
bmeVectorApplyReady: Boolean(overrides.bmeVectorApplyReady),
|
||||
bmeProtocolVersion: Math.max(0, Number(overrides.bmeProtocolVersion) || 0),
|
||||
browserCacheMode: normalizeString(overrides.browserCacheMode, "minimal"),
|
||||
updatedAt: normalizeString(overrides.updatedAt, new Date().toISOString()),
|
||||
};
|
||||
@@ -42,6 +45,9 @@ export function deriveAuthorityUpgradeState({
|
||||
const vectorReady = Boolean(capability.triviumPrimaryReady);
|
||||
const serverPrimaryReady = Boolean(capability.serverPrimaryReady || storageReady);
|
||||
const jobsReady = Boolean(capability.jobsReady);
|
||||
const bmeVectorManifestReady = Boolean(capability.bmeVectorManifestReady);
|
||||
const bmeVectorApplyReady = Boolean(capability.bmeVectorApplyReady);
|
||||
const bmeProtocolVersion = Math.max(0, Number(capability.bmeProtocolVersion) || 0);
|
||||
const browserCacheMode = normalizeString(browserState.mode, "minimal");
|
||||
const reason = normalizeString(capability.reason || capability.lastError, "standalone");
|
||||
const updatedAt = new Date(Number.isFinite(Number(now)) ? Number(now) : Date.now()).toISOString();
|
||||
@@ -93,6 +99,9 @@ export function deriveAuthorityUpgradeState({
|
||||
storageReady,
|
||||
vectorReady,
|
||||
jobsReady,
|
||||
bmeVectorManifestReady,
|
||||
bmeVectorApplyReady,
|
||||
bmeProtocolVersion,
|
||||
browserCacheMode,
|
||||
updatedAt,
|
||||
});
|
||||
@@ -103,7 +112,9 @@ export function deriveAuthorityUpgradeState({
|
||||
mode: AUTHORITY_UPGRADE_MODES.ENHANCED,
|
||||
text: "服务端增强已启用",
|
||||
meta: jobsReady
|
||||
? "图谱与向量存储已自动升级到 DOA/Authority 增强路径"
|
||||
? bmeVectorManifestReady
|
||||
? "图谱与向量存储已增强,服务端向量清单可用"
|
||||
: "图谱与向量存储已增强,等待 BME 向量清单能力"
|
||||
: "图谱与向量存储已增强,服务端后台任务能力暂不可用",
|
||||
level: "success",
|
||||
ready: true,
|
||||
@@ -112,6 +123,9 @@ export function deriveAuthorityUpgradeState({
|
||||
storageReady,
|
||||
vectorReady,
|
||||
jobsReady,
|
||||
bmeVectorManifestReady,
|
||||
bmeVectorApplyReady,
|
||||
bmeProtocolVersion,
|
||||
browserCacheMode,
|
||||
updatedAt,
|
||||
});
|
||||
@@ -130,6 +144,9 @@ export function deriveAuthorityUpgradeState({
|
||||
storageReady,
|
||||
vectorReady,
|
||||
jobsReady,
|
||||
bmeVectorManifestReady,
|
||||
bmeVectorApplyReady,
|
||||
bmeProtocolVersion,
|
||||
browserCacheMode,
|
||||
updatedAt,
|
||||
});
|
||||
|
||||
43
tests/authority-bme-capabilities.mjs
Normal file
43
tests/authority-bme-capabilities.mjs
Normal file
@@ -0,0 +1,43 @@
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
import {
|
||||
normalizeAuthorityProbeResponse,
|
||||
normalizeAuthorityCapabilityState,
|
||||
} from "../runtime/authority-capabilities.js";
|
||||
|
||||
const capability = normalizeAuthorityProbeResponse({
|
||||
healthy: true,
|
||||
features: {
|
||||
sql: { queryPage: true, stat: true },
|
||||
trivium: { bulkMutations: true, searchContext: true },
|
||||
jobs: { background: true, builtinTypes: ["delay", "trivium.flush"] },
|
||||
transfers: { blob: true, fs: true },
|
||||
bme: {
|
||||
protocolVersion: 1,
|
||||
vectorManifest: true,
|
||||
vectorApply: false,
|
||||
vectorApplyJobs: false,
|
||||
serverEmbeddingProbe: false,
|
||||
candidateSearch: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(capability.bmeProtocolVersion, 1);
|
||||
assert.equal(capability.bmeVectorManifestReady, true);
|
||||
assert.equal(capability.bmeVectorApplyReady, false);
|
||||
assert.equal(capability.bmeServerEmbeddingProbeReady, false);
|
||||
assert.ok(capability.features.includes("bme.vectormanifest"));
|
||||
assert.ok(capability.features.includes("bme.protocolversion"));
|
||||
|
||||
const legacy = normalizeAuthorityCapabilityState({
|
||||
installed: true,
|
||||
healthy: true,
|
||||
sessionReady: true,
|
||||
permissionReady: true,
|
||||
features: ["sql.query", "sql.mutation", "trivium.search"],
|
||||
});
|
||||
assert.equal(legacy.bmeVectorManifestReady, false);
|
||||
assert.equal(legacy.bmeProtocolVersion, 0);
|
||||
|
||||
console.log("authority-bme-capabilities tests passed");
|
||||
@@ -53,12 +53,16 @@ const enhanced = deriveAuthorityUpgradeState({
|
||||
storagePrimaryReady: true,
|
||||
triviumPrimaryReady: true,
|
||||
jobsReady: true,
|
||||
bmeVectorManifestReady: true,
|
||||
bmeProtocolVersion: 1,
|
||||
},
|
||||
browserState: { mode: "off" },
|
||||
});
|
||||
assert.equal(enhanced.mode, "authority-enhanced");
|
||||
assert.equal(enhanced.ready, true);
|
||||
assert.equal(enhanced.text, "服务端增强已启用");
|
||||
assert.equal(enhanced.bmeVectorManifestReady, true);
|
||||
assert.equal(enhanced.bmeProtocolVersion, 1);
|
||||
|
||||
assert.equal(
|
||||
formatAuthorityUpgradeMeta("准备就绪", enhanced),
|
||||
|
||||
@@ -156,6 +156,12 @@ export function createGraphPersistenceState() {
|
||||
authorityMigrationLastError: "",
|
||||
lastAuthorityMigrationResult: null,
|
||||
authorityJobsReady: false,
|
||||
authorityBmeProtocolVersion: 0,
|
||||
authorityBmeVectorManifestReady: false,
|
||||
authorityBmeVectorApplyReady: false,
|
||||
authorityBmeVectorApplyJobsReady: false,
|
||||
authorityBmeServerEmbeddingProbeReady: false,
|
||||
authorityBmeCandidateSearchReady: false,
|
||||
authorityJobQueueState: "idle",
|
||||
authorityLastJob: null,
|
||||
authorityLastJobId: "",
|
||||
|
||||
Reference in New Issue
Block a user