@almadar/workspace 0.1.6 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/workspace-content-retrieval-real-embedder.test.d.ts +8 -0
- package/dist/__tests__/workspace-index-bm25.test.d.ts +1 -0
- package/dist/__tests__/workspace-index-graph-builders.test.d.ts +1 -0
- package/dist/__tests__/workspace-index-manifest.test.d.ts +1 -0
- package/dist/__tests__/workspace-index-retrieval.test.d.ts +8 -0
- package/dist/__tests__/workspace-index-rrf.test.d.ts +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +769 -12
- package/dist/index.js.map +1 -1
- package/dist/internal/path-layout.d.ts +2 -0
- package/dist/types.d.ts +3 -0
- package/dist/workspace-index/bm25.d.ts +21 -0
- package/dist/workspace-index/fingerprint.d.ts +25 -0
- package/dist/workspace-index/graph-builders.d.ts +17 -0
- package/dist/workspace-index/index-impl.d.ts +31 -1
- package/dist/workspace-index/manifest.d.ts +13 -0
- package/dist/workspace-index/rrf.d.ts +17 -0
- package/dist/workspace-index/types.d.ts +206 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -233,6 +233,9 @@ function compiledFile(workDir, relPath) {
|
|
|
233
233
|
function appMarkerFile(workDir) {
|
|
234
234
|
return path2.join(workDir, WORKSPACE_LAYOUT.APP_MARKER);
|
|
235
235
|
}
|
|
236
|
+
function workspaceIndexManifestFile(workDir) {
|
|
237
|
+
return path2.join(workDir, WORKSPACE_LAYOUT.ALMADAR_DIR, "index.json");
|
|
238
|
+
}
|
|
236
239
|
function sandboxedPath(workDir, relPath) {
|
|
237
240
|
if (typeof relPath !== "string" || relPath.length === 0) {
|
|
238
241
|
throw new Error("sandbox: empty relative path");
|
|
@@ -549,8 +552,10 @@ async function appendJsonLine(backend, absPath, value) {
|
|
|
549
552
|
}
|
|
550
553
|
|
|
551
554
|
// src/workspace-index/types.ts
|
|
552
|
-
var WORKSPACE_INDEX_SCHEMA_VERSION =
|
|
555
|
+
var WORKSPACE_INDEX_SCHEMA_VERSION = 2;
|
|
553
556
|
var DEFAULT_COERCION_THRESHOLD = 0.85;
|
|
557
|
+
var RRF_K = 60;
|
|
558
|
+
var DEFAULT_RETRIEVAL_TOP_K = 3;
|
|
554
559
|
|
|
555
560
|
// src/workspace-index/cosine.ts
|
|
556
561
|
function cosineSimilarity(a, b) {
|
|
@@ -593,6 +598,75 @@ function deriveExtraTraitAlias(emit) {
|
|
|
593
598
|
if (emit.name && emit.name.length > 0) return emit.name;
|
|
594
599
|
return tailOfRef(emit.ref);
|
|
595
600
|
}
|
|
601
|
+
function composeOrbitalContentFingerprint(spec) {
|
|
602
|
+
const segments = [composeOrbitalIdentityFingerprint(spec)];
|
|
603
|
+
const params = asJsonObject(spec["params"]);
|
|
604
|
+
if (params) {
|
|
605
|
+
const traitOverrides = asJsonObject(params["traitOverrides"]);
|
|
606
|
+
if (traitOverrides) {
|
|
607
|
+
for (const trait of Object.keys(traitOverrides).sort()) {
|
|
608
|
+
segments.push(trait);
|
|
609
|
+
const override = asJsonObject(traitOverrides[trait]);
|
|
610
|
+
if (!override) continue;
|
|
611
|
+
const config = asJsonObject(override["config"]);
|
|
612
|
+
if (!config) continue;
|
|
613
|
+
for (const knob of Object.keys(config).sort()) {
|
|
614
|
+
const rendered = renderKnobValue(config[knob]);
|
|
615
|
+
if (rendered.length > 0) segments.push(`${trait}.${knob}: ${rendered}`);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
const fields = params["entityFields"];
|
|
620
|
+
if (Array.isArray(fields)) {
|
|
621
|
+
const names = [];
|
|
622
|
+
for (const f of fields) {
|
|
623
|
+
const obj = asJsonObject(f);
|
|
624
|
+
if (obj && typeof obj["name"] === "string") names.push(obj["name"]);
|
|
625
|
+
}
|
|
626
|
+
if (names.length > 0) segments.push(names.join(", "));
|
|
627
|
+
}
|
|
628
|
+
const extras = params["extraTraits"];
|
|
629
|
+
if (Array.isArray(extras)) {
|
|
630
|
+
const labels = [];
|
|
631
|
+
for (const e of extras) {
|
|
632
|
+
const obj = asJsonObject(e);
|
|
633
|
+
if (!obj) continue;
|
|
634
|
+
const ref = typeof obj["ref"] === "string" ? obj["ref"] : null;
|
|
635
|
+
const name = typeof obj["name"] === "string" ? obj["name"] : null;
|
|
636
|
+
const label = name && name.length > 0 ? name : ref ? tailOfRef(ref) : null;
|
|
637
|
+
if (label) labels.push(label);
|
|
638
|
+
}
|
|
639
|
+
if (labels.length > 0) segments.push(labels.join(", "));
|
|
640
|
+
}
|
|
641
|
+
const ruleOverlay = asJsonObject(params["ruleOverlay"]);
|
|
642
|
+
if (ruleOverlay) {
|
|
643
|
+
const rules = ruleOverlay["rules"];
|
|
644
|
+
if (Array.isArray(rules)) {
|
|
645
|
+
const caps = [];
|
|
646
|
+
for (const r of rules) {
|
|
647
|
+
const obj = asJsonObject(r);
|
|
648
|
+
if (obj && typeof obj["capability"] === "string") caps.push(obj["capability"]);
|
|
649
|
+
}
|
|
650
|
+
if (caps.length > 0) segments.push(caps.join(", "));
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
return segments.filter((s) => s.length > 0).join(" \xB7 ");
|
|
655
|
+
}
|
|
656
|
+
function renderKnobValue(value) {
|
|
657
|
+
if (value === void 0 || value === null) return "";
|
|
658
|
+
if (typeof value === "string") return value;
|
|
659
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
660
|
+
if (Array.isArray(value)) {
|
|
661
|
+
const parts = [];
|
|
662
|
+
for (const entry of value) {
|
|
663
|
+
if (typeof entry === "string") parts.push(entry);
|
|
664
|
+
else if (typeof entry === "number" || typeof entry === "boolean") parts.push(String(entry));
|
|
665
|
+
}
|
|
666
|
+
return parts.join(", ");
|
|
667
|
+
}
|
|
668
|
+
return "";
|
|
669
|
+
}
|
|
596
670
|
function pushString(out, value) {
|
|
597
671
|
if (typeof value === "string" && value.length > 0) out.push(value);
|
|
598
672
|
}
|
|
@@ -627,6 +701,392 @@ function checksumSpec(spec) {
|
|
|
627
701
|
return createHash("sha256").update(JSON.stringify(spec)).digest("hex");
|
|
628
702
|
}
|
|
629
703
|
|
|
704
|
+
// src/workspace-index/bm25.ts
|
|
705
|
+
function tokenizeSpec(spec) {
|
|
706
|
+
const tokens = [];
|
|
707
|
+
pushTokens(tokens, spec["orbitalName"]);
|
|
708
|
+
const params = asJsonObject2(spec["params"]);
|
|
709
|
+
if (params) {
|
|
710
|
+
pushTokens(tokens, params["entityName"]);
|
|
711
|
+
const fields = params["entityFields"];
|
|
712
|
+
if (Array.isArray(fields)) {
|
|
713
|
+
for (const f of fields) {
|
|
714
|
+
const obj = asJsonObject2(f);
|
|
715
|
+
if (obj) pushTokens(tokens, obj["name"]);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
const extras = params["extraTraits"];
|
|
719
|
+
if (Array.isArray(extras)) {
|
|
720
|
+
for (const e of extras) {
|
|
721
|
+
const obj = asJsonObject2(e);
|
|
722
|
+
if (!obj) continue;
|
|
723
|
+
pushTokens(tokens, obj["name"]);
|
|
724
|
+
const ref = obj["ref"];
|
|
725
|
+
if (typeof ref === "string") {
|
|
726
|
+
pushTokens(tokens, tailOfRef2(ref));
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
const pages = params["pages"];
|
|
731
|
+
if (Array.isArray(pages)) {
|
|
732
|
+
for (const p of pages) {
|
|
733
|
+
const obj = asJsonObject2(p);
|
|
734
|
+
if (!obj) continue;
|
|
735
|
+
const path9 = obj["path"];
|
|
736
|
+
if (typeof path9 === "string") pushTokens(tokens, path9);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
const ruleOverlay = asJsonObject2(params["ruleOverlay"]);
|
|
740
|
+
if (ruleOverlay) {
|
|
741
|
+
const rules = ruleOverlay["rules"];
|
|
742
|
+
if (Array.isArray(rules)) {
|
|
743
|
+
for (const r of rules) {
|
|
744
|
+
const obj = asJsonObject2(r);
|
|
745
|
+
if (obj) pushTokens(tokens, obj["capability"]);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
const traitOverrides = asJsonObject2(params["traitOverrides"]);
|
|
750
|
+
if (traitOverrides) {
|
|
751
|
+
for (const trait of Object.keys(traitOverrides)) {
|
|
752
|
+
pushTokens(tokens, trait);
|
|
753
|
+
const override = asJsonObject2(traitOverrides[trait]);
|
|
754
|
+
if (!override) continue;
|
|
755
|
+
const config = asJsonObject2(override["config"]);
|
|
756
|
+
if (!config) continue;
|
|
757
|
+
for (const knob of Object.keys(config)) {
|
|
758
|
+
pushPrimitiveValue(tokens, config[knob]);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
return tokens;
|
|
764
|
+
}
|
|
765
|
+
function buildBM25Table(tokensPerOrbital) {
|
|
766
|
+
const documents = {};
|
|
767
|
+
const docFreq = {};
|
|
768
|
+
let totalLen = 0;
|
|
769
|
+
const orbitals = Object.keys(tokensPerOrbital);
|
|
770
|
+
for (const orbital of orbitals) {
|
|
771
|
+
const list = tokensPerOrbital[orbital] ?? [];
|
|
772
|
+
const termFreq = {};
|
|
773
|
+
for (const t of list) {
|
|
774
|
+
termFreq[t] = (termFreq[t] ?? 0) + 1;
|
|
775
|
+
}
|
|
776
|
+
const docLen = list.length;
|
|
777
|
+
totalLen += docLen;
|
|
778
|
+
documents[orbital] = { orbital, termFreq, docLen };
|
|
779
|
+
for (const term of Object.keys(termFreq)) {
|
|
780
|
+
docFreq[term] = (docFreq[term] ?? 0) + 1;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
const docCount = orbitals.length;
|
|
784
|
+
const avgDocLen = docCount > 0 ? totalLen / docCount : 0;
|
|
785
|
+
return { documents, docFreq, docCount, avgDocLen };
|
|
786
|
+
}
|
|
787
|
+
function queryBM25(table, query, opts) {
|
|
788
|
+
const k1 = opts?.k1 ?? 1.5;
|
|
789
|
+
const b = opts?.b ?? 0.75;
|
|
790
|
+
const queryTokensRaw = tokenize(query);
|
|
791
|
+
if (queryTokensRaw.length === 0) return [];
|
|
792
|
+
const uniqueQueryTokens = Array.from(new Set(queryTokensRaw));
|
|
793
|
+
const { documents, docFreq, docCount, avgDocLen } = table;
|
|
794
|
+
if (docCount === 0 || avgDocLen === 0) return [];
|
|
795
|
+
const results = [];
|
|
796
|
+
for (const orbital of Object.keys(documents)) {
|
|
797
|
+
const doc = documents[orbital];
|
|
798
|
+
if (!doc) continue;
|
|
799
|
+
let score = 0;
|
|
800
|
+
const matched = [];
|
|
801
|
+
for (const qt of uniqueQueryTokens) {
|
|
802
|
+
const tf = doc.termFreq[qt] ?? 0;
|
|
803
|
+
if (tf === 0) continue;
|
|
804
|
+
const df = docFreq[qt] ?? 0;
|
|
805
|
+
const idf = Math.log1p((docCount - df + 0.5) / (df + 0.5));
|
|
806
|
+
const norm = tf + k1 * (1 - b + b * doc.docLen / avgDocLen);
|
|
807
|
+
const contribution = idf * tf * (k1 + 1) / norm;
|
|
808
|
+
if (contribution > 0) {
|
|
809
|
+
score += contribution;
|
|
810
|
+
matched.push(qt);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
if (score > 0) results.push({ orbital, score, matchedTokens: matched });
|
|
814
|
+
}
|
|
815
|
+
results.sort((a, b2) => b2.score - a.score);
|
|
816
|
+
return results;
|
|
817
|
+
}
|
|
818
|
+
function tokenize(text) {
|
|
819
|
+
if (text.length === 0) return [];
|
|
820
|
+
const out = [];
|
|
821
|
+
const pieces = text.split(/[\s_\-/.:]+/u);
|
|
822
|
+
for (const piece of pieces) {
|
|
823
|
+
if (piece.length === 0) continue;
|
|
824
|
+
const lower = piece.toLowerCase();
|
|
825
|
+
if (lower.length >= 2) out.push(lower);
|
|
826
|
+
const parts = splitCamel(piece);
|
|
827
|
+
if (parts.length > 1) {
|
|
828
|
+
for (const part of parts) {
|
|
829
|
+
const p = part.toLowerCase();
|
|
830
|
+
if (p.length >= 2) out.push(p);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
return out;
|
|
835
|
+
}
|
|
836
|
+
function splitCamel(s) {
|
|
837
|
+
return s.split(/(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/u);
|
|
838
|
+
}
|
|
839
|
+
function pushTokens(out, value) {
|
|
840
|
+
if (typeof value !== "string" || value.length === 0) return;
|
|
841
|
+
for (const t of tokenize(value)) out.push(t);
|
|
842
|
+
}
|
|
843
|
+
function pushPrimitiveValue(out, value) {
|
|
844
|
+
if (value === void 0 || value === null) return;
|
|
845
|
+
if (typeof value === "string") {
|
|
846
|
+
for (const t of tokenize(value)) out.push(t);
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
850
|
+
for (const t of tokenize(String(value))) out.push(t);
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
if (Array.isArray(value)) {
|
|
854
|
+
for (const entry of value) pushPrimitiveValue(out, entry);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
function asJsonObject2(value) {
|
|
858
|
+
if (value === void 0 || value === null) return null;
|
|
859
|
+
if (typeof value !== "object" || Array.isArray(value)) return null;
|
|
860
|
+
return value;
|
|
861
|
+
}
|
|
862
|
+
function tailOfRef2(ref) {
|
|
863
|
+
const match = /\.traits\.([A-Za-z0-9_]+)$/.exec(ref);
|
|
864
|
+
return match ? match[1] : ref;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
// src/workspace-index/rrf.ts
|
|
868
|
+
function rrfFuse(rankings, k = RRF_K) {
|
|
869
|
+
if (rankings.length === 0) return [];
|
|
870
|
+
const order = [];
|
|
871
|
+
const seen = /* @__PURE__ */ new Set();
|
|
872
|
+
for (const ranking of rankings) {
|
|
873
|
+
for (const key of ranking) {
|
|
874
|
+
if (!seen.has(key)) {
|
|
875
|
+
seen.add(key);
|
|
876
|
+
order.push(key);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
const ranksByKey = /* @__PURE__ */ new Map();
|
|
881
|
+
const scoreByKey = /* @__PURE__ */ new Map();
|
|
882
|
+
for (const key of order) {
|
|
883
|
+
ranksByKey.set(
|
|
884
|
+
key,
|
|
885
|
+
rankings.map(() => null)
|
|
886
|
+
);
|
|
887
|
+
scoreByKey.set(key, 0);
|
|
888
|
+
}
|
|
889
|
+
for (let i = 0; i < rankings.length; i++) {
|
|
890
|
+
const ranking = rankings[i];
|
|
891
|
+
if (!ranking) continue;
|
|
892
|
+
for (let j = 0; j < ranking.length; j++) {
|
|
893
|
+
const key = ranking[j];
|
|
894
|
+
if (key === void 0) continue;
|
|
895
|
+
const rank = j + 1;
|
|
896
|
+
const ranks = ranksByKey.get(key);
|
|
897
|
+
if (ranks) ranks[i] = rank;
|
|
898
|
+
scoreByKey.set(key, (scoreByKey.get(key) ?? 0) + 1 / (k + rank));
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
const indexed = order.map((key, idx) => ({
|
|
902
|
+
key,
|
|
903
|
+
idx,
|
|
904
|
+
score: scoreByKey.get(key) ?? 0,
|
|
905
|
+
ranks: ranksByKey.get(key) ?? []
|
|
906
|
+
}));
|
|
907
|
+
indexed.sort((a, b) => {
|
|
908
|
+
if (b.score !== a.score) return b.score - a.score;
|
|
909
|
+
return a.idx - b.idx;
|
|
910
|
+
});
|
|
911
|
+
return indexed.map(({ key, score, ranks }) => ({ key, score, ranks }));
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
// src/workspace-index/graph-builders.ts
|
|
915
|
+
function buildIntentMaps(specs) {
|
|
916
|
+
const entityNameOverrides = {};
|
|
917
|
+
const traitRefImporters = {};
|
|
918
|
+
const ruleCapabilities = {};
|
|
919
|
+
const organism = {};
|
|
920
|
+
const orbitalNames = Object.keys(specs).sort();
|
|
921
|
+
for (const orbital of orbitalNames) {
|
|
922
|
+
const spec = specs[orbital];
|
|
923
|
+
if (!spec) continue;
|
|
924
|
+
const organismName = typeof spec["organism"] === "string" ? spec["organism"] : null;
|
|
925
|
+
if (organismName && organismName.length > 0) {
|
|
926
|
+
(organism[organismName] ?? (organism[organismName] = [])).push(orbital);
|
|
927
|
+
}
|
|
928
|
+
const params = asJsonObject3(spec["params"]);
|
|
929
|
+
if (!params) continue;
|
|
930
|
+
const defaultEntity = typeof params["entityName"] === "string" ? params["entityName"] : null;
|
|
931
|
+
const traitOverrides = asJsonObject3(params["traitOverrides"]);
|
|
932
|
+
if (traitOverrides) {
|
|
933
|
+
for (const trait of Object.keys(traitOverrides).sort()) {
|
|
934
|
+
const override = asJsonObject3(traitOverrides[trait]);
|
|
935
|
+
if (!override) continue;
|
|
936
|
+
const linked = override["linkedEntity"];
|
|
937
|
+
if (typeof linked === "string" && linked.length > 0) {
|
|
938
|
+
(entityNameOverrides[linked] ?? (entityNameOverrides[linked] = [])).push({
|
|
939
|
+
orbital,
|
|
940
|
+
trait,
|
|
941
|
+
source: "override"
|
|
942
|
+
});
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
const extras = params["extraTraits"];
|
|
947
|
+
if (Array.isArray(extras)) {
|
|
948
|
+
for (const e of extras) {
|
|
949
|
+
const obj = asJsonObject3(e);
|
|
950
|
+
if (!obj) continue;
|
|
951
|
+
const ref = obj["ref"];
|
|
952
|
+
if (typeof ref === "string" && ref.length > 0) {
|
|
953
|
+
(traitRefImporters[ref] ?? (traitRefImporters[ref] = [])).push(orbital);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
const ruleOverlay = asJsonObject3(params["ruleOverlay"]);
|
|
958
|
+
if (ruleOverlay) {
|
|
959
|
+
const rules = ruleOverlay["rules"];
|
|
960
|
+
if (Array.isArray(rules)) {
|
|
961
|
+
for (const r of rules) {
|
|
962
|
+
const obj = asJsonObject3(r);
|
|
963
|
+
if (!obj) continue;
|
|
964
|
+
const capability = obj["capability"];
|
|
965
|
+
if (typeof capability !== "string" || capability.length === 0) continue;
|
|
966
|
+
const entityName = typeof obj["entityName"] === "string" && obj["entityName"].length > 0 ? obj["entityName"] : defaultEntity;
|
|
967
|
+
if (!entityName) continue;
|
|
968
|
+
(ruleCapabilities[capability] ?? (ruleCapabilities[capability] = [])).push({
|
|
969
|
+
orbital,
|
|
970
|
+
entityName,
|
|
971
|
+
capability
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
return { entityNameOverrides, traitRefImporters, ruleCapabilities, organism };
|
|
978
|
+
}
|
|
979
|
+
function buildComposedMaps(schemaOrbContent) {
|
|
980
|
+
if (schemaOrbContent === null) return { events: {}, entityNameComposed: {} };
|
|
981
|
+
let parsed;
|
|
982
|
+
try {
|
|
983
|
+
parsed = JSON.parse(schemaOrbContent);
|
|
984
|
+
} catch {
|
|
985
|
+
return { events: {}, entityNameComposed: {} };
|
|
986
|
+
}
|
|
987
|
+
const root = asJsonObject3(parsed);
|
|
988
|
+
if (!root) return { events: {}, entityNameComposed: {} };
|
|
989
|
+
const orbitals = root["orbitals"];
|
|
990
|
+
if (!Array.isArray(orbitals)) return { events: {}, entityNameComposed: {} };
|
|
991
|
+
const events = {};
|
|
992
|
+
const entityNameComposed = {};
|
|
993
|
+
for (const o of orbitals) {
|
|
994
|
+
const orbObj = asJsonObject3(o);
|
|
995
|
+
if (!orbObj) continue;
|
|
996
|
+
const orbitalName = typeof orbObj["name"] === "string" ? orbObj["name"] : null;
|
|
997
|
+
if (!orbitalName) continue;
|
|
998
|
+
const entity = asJsonObject3(orbObj["entity"]);
|
|
999
|
+
if (entity) {
|
|
1000
|
+
const entityName = entity["name"];
|
|
1001
|
+
if (typeof entityName === "string" && entityName.length > 0) {
|
|
1002
|
+
(entityNameComposed[entityName] ?? (entityNameComposed[entityName] = [])).push({
|
|
1003
|
+
orbital: orbitalName,
|
|
1004
|
+
trait: "<orbital-entity>",
|
|
1005
|
+
source: "composed"
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
const traits = orbObj["traits"];
|
|
1010
|
+
if (!Array.isArray(traits)) continue;
|
|
1011
|
+
for (const t of traits) {
|
|
1012
|
+
const traitObj = asJsonObject3(t);
|
|
1013
|
+
if (!traitObj) continue;
|
|
1014
|
+
const traitName = typeof traitObj["name"] === "string" ? traitObj["name"] : null;
|
|
1015
|
+
if (!traitName) continue;
|
|
1016
|
+
const linked = traitObj["linkedEntity"];
|
|
1017
|
+
if (typeof linked === "string" && linked.length > 0) {
|
|
1018
|
+
(entityNameComposed[linked] ?? (entityNameComposed[linked] = [])).push({
|
|
1019
|
+
orbital: orbitalName,
|
|
1020
|
+
trait: traitName,
|
|
1021
|
+
source: "composed"
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
const states = traitObj["states"];
|
|
1025
|
+
if (!Array.isArray(states)) continue;
|
|
1026
|
+
for (const s of states) {
|
|
1027
|
+
const stateObj = asJsonObject3(s);
|
|
1028
|
+
if (!stateObj) continue;
|
|
1029
|
+
const stateName = typeof stateObj["name"] === "string" ? stateObj["name"] : void 0;
|
|
1030
|
+
const transitions = stateObj["transitions"];
|
|
1031
|
+
if (!Array.isArray(transitions)) continue;
|
|
1032
|
+
for (const tr of transitions) {
|
|
1033
|
+
const trObj = asJsonObject3(tr);
|
|
1034
|
+
if (!trObj) continue;
|
|
1035
|
+
const listenEvent = trObj["event"];
|
|
1036
|
+
if (typeof listenEvent === "string" && listenEvent.length > 0) {
|
|
1037
|
+
(events[listenEvent] ?? (events[listenEvent] = [])).push({
|
|
1038
|
+
orbital: orbitalName,
|
|
1039
|
+
trait: traitName,
|
|
1040
|
+
state: stateName,
|
|
1041
|
+
role: "listen"
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1044
|
+
const emit = asJsonObject3(trObj["emit"]);
|
|
1045
|
+
if (emit) {
|
|
1046
|
+
const emitEvent = emit["event"];
|
|
1047
|
+
if (typeof emitEvent === "string" && emitEvent.length > 0) {
|
|
1048
|
+
const scope = emit["scope"];
|
|
1049
|
+
const scopeNarrowed = scope === "internal" || scope === "external" ? scope : void 0;
|
|
1050
|
+
const edge = {
|
|
1051
|
+
orbital: orbitalName,
|
|
1052
|
+
trait: traitName,
|
|
1053
|
+
state: stateName,
|
|
1054
|
+
role: "emit",
|
|
1055
|
+
...scopeNarrowed ? { scope: scopeNarrowed } : {}
|
|
1056
|
+
};
|
|
1057
|
+
(events[emitEvent] ?? (events[emitEvent] = [])).push(edge);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
return { events, entityNameComposed };
|
|
1065
|
+
}
|
|
1066
|
+
function asJsonObject3(value) {
|
|
1067
|
+
if (value === void 0 || value === null) return null;
|
|
1068
|
+
if (typeof value !== "object" || Array.isArray(value)) return null;
|
|
1069
|
+
return value;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// src/workspace-index/manifest.ts
|
|
1073
|
+
function manifestPath(workDir) {
|
|
1074
|
+
return workspaceIndexManifestFile(workDir);
|
|
1075
|
+
}
|
|
1076
|
+
async function readManifest(backend, workDir) {
|
|
1077
|
+
const raw = await readJsonFile(backend, manifestPath(workDir));
|
|
1078
|
+
if (raw === null) return null;
|
|
1079
|
+
if (raw.schemaVersion !== WORKSPACE_INDEX_SCHEMA_VERSION) return null;
|
|
1080
|
+
return raw;
|
|
1081
|
+
}
|
|
1082
|
+
async function writeManifest(backend, workDir, manifest) {
|
|
1083
|
+
await writeJsonFile(
|
|
1084
|
+
backend,
|
|
1085
|
+
manifestPath(workDir),
|
|
1086
|
+
manifest
|
|
1087
|
+
);
|
|
1088
|
+
}
|
|
1089
|
+
|
|
630
1090
|
// src/workspace-index/index-impl.ts
|
|
631
1091
|
var WorkspaceIndexImpl = class {
|
|
632
1092
|
constructor(deps) {
|
|
@@ -636,13 +1096,53 @@ var WorkspaceIndexImpl = class {
|
|
|
636
1096
|
this.bakeQueue = /* @__PURE__ */ new Map();
|
|
637
1097
|
/** Names whose checksum doesn't match the current spec — surfaced via stats. */
|
|
638
1098
|
this.stale = /* @__PURE__ */ new Set();
|
|
1099
|
+
/** Cached spec.json per orbital so manifest rebuilds don't re-read disk. */
|
|
1100
|
+
this.specsByOrbital = /* @__PURE__ */ new Map();
|
|
1101
|
+
/** Tokenized BM25 rows per orbital — rebuilt incrementally. */
|
|
1102
|
+
this.tokensByOrbital = /* @__PURE__ */ new Map();
|
|
1103
|
+
/** Last-known recency timeline per orbital. */
|
|
1104
|
+
this.recencyByOrbital = /* @__PURE__ */ new Map();
|
|
1105
|
+
/** Latest manifest payload (BM25 + intent + composed + recency). */
|
|
1106
|
+
this.manifest = emptyManifest();
|
|
1107
|
+
/** Serialized manifest writes so concurrent observer fires don't race. */
|
|
1108
|
+
this.manifestQueue = Promise.resolve();
|
|
639
1109
|
this.deps.sinks.subscribe({
|
|
640
|
-
onWrite:
|
|
641
|
-
if (event.kind !== "spec") return;
|
|
642
|
-
await this.rebakeOrbital(event.orbital, event.content);
|
|
643
|
-
}
|
|
1110
|
+
onWrite: (event) => this.onWorkspaceWrite(event)
|
|
644
1111
|
});
|
|
645
1112
|
}
|
|
1113
|
+
async onWorkspaceWrite(event) {
|
|
1114
|
+
switch (event.kind) {
|
|
1115
|
+
case "spec":
|
|
1116
|
+
await this.rebakeOrbital(event.orbital, event.content);
|
|
1117
|
+
this.specsByOrbital.set(event.orbital, event.content);
|
|
1118
|
+
this.tokensByOrbital.set(event.orbital, tokenizeSpec(event.content));
|
|
1119
|
+
await this.scheduleManifestRebuild();
|
|
1120
|
+
return;
|
|
1121
|
+
case "schema":
|
|
1122
|
+
await this.scheduleManifestRebuild();
|
|
1123
|
+
return;
|
|
1124
|
+
case "params-history":
|
|
1125
|
+
this.recencyByOrbital.set(event.orbital, deriveRecencyEntry(event.orbital, [event.row], this.recencyByOrbital.get(event.orbital)));
|
|
1126
|
+
await this.scheduleManifestRebuild();
|
|
1127
|
+
return;
|
|
1128
|
+
case "orbital-archived":
|
|
1129
|
+
this.entries.delete(event.name);
|
|
1130
|
+
this.specsByOrbital.delete(event.name);
|
|
1131
|
+
this.tokensByOrbital.delete(event.name);
|
|
1132
|
+
this.recencyByOrbital.delete(event.name);
|
|
1133
|
+
await this.scheduleManifestRebuild();
|
|
1134
|
+
return;
|
|
1135
|
+
case "orbital-renamed":
|
|
1136
|
+
renameKey(this.entries, event.from, event.to);
|
|
1137
|
+
renameKey(this.specsByOrbital, event.from, event.to);
|
|
1138
|
+
renameKey(this.tokensByOrbital, event.from, event.to);
|
|
1139
|
+
renameKey(this.recencyByOrbital, event.from, event.to);
|
|
1140
|
+
await this.scheduleManifestRebuild();
|
|
1141
|
+
return;
|
|
1142
|
+
default:
|
|
1143
|
+
return;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
646
1146
|
async warm() {
|
|
647
1147
|
const orbitals = this.deps.listOrbitals();
|
|
648
1148
|
const work = [];
|
|
@@ -651,6 +1151,12 @@ var WorkspaceIndexImpl = class {
|
|
|
651
1151
|
if (spec === null) {
|
|
652
1152
|
continue;
|
|
653
1153
|
}
|
|
1154
|
+
this.specsByOrbital.set(orbital, spec);
|
|
1155
|
+
this.tokensByOrbital.set(orbital, tokenizeSpec(spec));
|
|
1156
|
+
const history = this.deps.readHistory(orbital);
|
|
1157
|
+
if (history.length > 0) {
|
|
1158
|
+
this.recencyByOrbital.set(orbital, deriveRecencyEntry(orbital, history, void 0));
|
|
1159
|
+
}
|
|
654
1160
|
const checksum = checksumSpec(spec);
|
|
655
1161
|
const existing = await readSidecar(this.deps.backend, this.deps.workDir, orbital);
|
|
656
1162
|
if (existing !== null && existing.specChecksum === checksum) {
|
|
@@ -661,6 +1167,12 @@ var WorkspaceIndexImpl = class {
|
|
|
661
1167
|
work.push(this.bakeAndPersist(orbital, spec, checksum));
|
|
662
1168
|
}
|
|
663
1169
|
await Promise.all(work);
|
|
1170
|
+
const restored = await readManifest(this.deps.backend, this.deps.workDir);
|
|
1171
|
+
if (restored !== null) {
|
|
1172
|
+
this.manifest = restored;
|
|
1173
|
+
this.hydrateRecencyFromManifest(restored);
|
|
1174
|
+
}
|
|
1175
|
+
await this.rebuildManifest();
|
|
664
1176
|
}
|
|
665
1177
|
async resolveOrbitalName(name, opts) {
|
|
666
1178
|
const threshold = opts?.threshold ?? DEFAULT_COERCION_THRESHOLD;
|
|
@@ -715,6 +1227,149 @@ var WorkspaceIndexImpl = class {
|
|
|
715
1227
|
staleOrbitals: Array.from(this.stale).sort()
|
|
716
1228
|
};
|
|
717
1229
|
}
|
|
1230
|
+
// ── Phase B — RRF-hybrid retrieval ──────────────────────────────────────────
|
|
1231
|
+
async retrieveOrbitalsForPrompt(prompt, opts) {
|
|
1232
|
+
const topK = opts?.topK ?? DEFAULT_RETRIEVAL_TOP_K;
|
|
1233
|
+
const rrfK = opts?.rrfK ?? RRF_K;
|
|
1234
|
+
if (this.entries.size === 0) return [];
|
|
1235
|
+
const sparseHits = queryBM25(this.manifest.bm25, prompt, opts?.bm25);
|
|
1236
|
+
const sparseRanking = sparseHits.map((h) => h.orbital);
|
|
1237
|
+
const matchedTokensByOrbital = /* @__PURE__ */ new Map();
|
|
1238
|
+
for (const hit of sparseHits) matchedTokensByOrbital.set(hit.orbital, hit.matchedTokens);
|
|
1239
|
+
const [promptVector] = await this.embedOne(prompt);
|
|
1240
|
+
const dense = [];
|
|
1241
|
+
for (const [orbital, entry] of this.entries) {
|
|
1242
|
+
const sim = cosineSimilarity(promptVector, entry.contentVector);
|
|
1243
|
+
if (sim > 0) dense.push({ orbital, sim });
|
|
1244
|
+
}
|
|
1245
|
+
dense.sort((a, b) => b.sim - a.sim);
|
|
1246
|
+
const denseRanking = dense.map((d) => d.orbital);
|
|
1247
|
+
const fused = rrfFuse([denseRanking, sparseRanking], rrfK);
|
|
1248
|
+
return fused.slice(0, topK).map((entry) => ({
|
|
1249
|
+
orbitalName: entry.key,
|
|
1250
|
+
score: entry.score,
|
|
1251
|
+
matchedTokens: matchedTokensByOrbital.get(entry.key) ?? [],
|
|
1252
|
+
matchedKnobs: this.explainKnobMatches(entry.key, prompt),
|
|
1253
|
+
rankByDense: entry.ranks[0] ?? null,
|
|
1254
|
+
rankBySparse: entry.ranks[1] ?? null
|
|
1255
|
+
}));
|
|
1256
|
+
}
|
|
1257
|
+
findByToken(query) {
|
|
1258
|
+
const hits = queryBM25(this.manifest.bm25, query);
|
|
1259
|
+
return hits.map((h) => h.orbital);
|
|
1260
|
+
}
|
|
1261
|
+
// ── Phase C — graph queries ────────────────────────────────────────────────
|
|
1262
|
+
orbitalsListeningTo(event) {
|
|
1263
|
+
return (this.manifest.composed.events[event] ?? []).filter((e) => e.role === "listen");
|
|
1264
|
+
}
|
|
1265
|
+
orbitalsEmitting(event) {
|
|
1266
|
+
return (this.manifest.composed.events[event] ?? []).filter((e) => e.role === "emit");
|
|
1267
|
+
}
|
|
1268
|
+
orbitalsLinkedToEntity(entity) {
|
|
1269
|
+
const composed = this.manifest.composed.entityNameComposed[entity] ?? [];
|
|
1270
|
+
const override = this.manifest.intent.entityNameOverrides[entity] ?? [];
|
|
1271
|
+
return [...composed, ...override];
|
|
1272
|
+
}
|
|
1273
|
+
extraTraitImporters(refPath) {
|
|
1274
|
+
return this.manifest.intent.traitRefImporters[refPath] ?? [];
|
|
1275
|
+
}
|
|
1276
|
+
composedEvents() {
|
|
1277
|
+
return Object.keys(this.manifest.composed.events);
|
|
1278
|
+
}
|
|
1279
|
+
composedEntities() {
|
|
1280
|
+
const set = /* @__PURE__ */ new Set();
|
|
1281
|
+
for (const name of Object.keys(this.manifest.composed.entityNameComposed)) {
|
|
1282
|
+
set.add(name);
|
|
1283
|
+
}
|
|
1284
|
+
for (const name of Object.keys(this.manifest.intent.entityNameOverrides)) {
|
|
1285
|
+
set.add(name);
|
|
1286
|
+
}
|
|
1287
|
+
return Array.from(set);
|
|
1288
|
+
}
|
|
1289
|
+
composedTraitRefPaths() {
|
|
1290
|
+
return Object.keys(this.manifest.intent.traitRefImporters);
|
|
1291
|
+
}
|
|
1292
|
+
rulesAppliedTo(entity) {
|
|
1293
|
+
const out = [];
|
|
1294
|
+
for (const bindings of Object.values(this.manifest.intent.ruleCapabilities)) {
|
|
1295
|
+
for (const b of bindings) if (b.entityName === entity) out.push(b);
|
|
1296
|
+
}
|
|
1297
|
+
return out;
|
|
1298
|
+
}
|
|
1299
|
+
recentlyEdited(opts) {
|
|
1300
|
+
const withinTurns = opts?.withinTurns ?? 5;
|
|
1301
|
+
const entries = [];
|
|
1302
|
+
for (const [orbital, recency] of Object.entries(this.manifest.recency)) {
|
|
1303
|
+
entries.push({ orbital, recencyTurn: recency.recencyTurn });
|
|
1304
|
+
}
|
|
1305
|
+
if (entries.length === 0) return [];
|
|
1306
|
+
const maxTurn = entries.reduce((m, e) => e.recencyTurn > m ? e.recencyTurn : m, -Infinity);
|
|
1307
|
+
entries.sort((a, b) => b.recencyTurn - a.recencyTurn);
|
|
1308
|
+
return entries.filter((e) => e.recencyTurn > maxTurn - withinTurns).map((e) => e.orbital);
|
|
1309
|
+
}
|
|
1310
|
+
// ── Manifest internals ─────────────────────────────────────────────────────
|
|
1311
|
+
scheduleManifestRebuild() {
|
|
1312
|
+
const next = this.manifestQueue.then(() => this.rebuildManifest());
|
|
1313
|
+
this.manifestQueue = next.catch(() => void 0);
|
|
1314
|
+
return next;
|
|
1315
|
+
}
|
|
1316
|
+
async rebuildManifest() {
|
|
1317
|
+
const tokensPerOrbital = {};
|
|
1318
|
+
for (const [orbital, tokens] of this.tokensByOrbital) {
|
|
1319
|
+
tokensPerOrbital[orbital] = tokens;
|
|
1320
|
+
}
|
|
1321
|
+
const specsPerOrbital = {};
|
|
1322
|
+
for (const [orbital, spec] of this.specsByOrbital) {
|
|
1323
|
+
specsPerOrbital[orbital] = spec;
|
|
1324
|
+
}
|
|
1325
|
+
const recency = {};
|
|
1326
|
+
for (const [orbital, entry] of this.recencyByOrbital) {
|
|
1327
|
+
recency[orbital] = entry;
|
|
1328
|
+
}
|
|
1329
|
+
const next = {
|
|
1330
|
+
schemaVersion: WORKSPACE_INDEX_SCHEMA_VERSION,
|
|
1331
|
+
bm25: buildBM25Table(tokensPerOrbital),
|
|
1332
|
+
intent: buildIntentMaps(specsPerOrbital),
|
|
1333
|
+
composed: buildComposedMaps(this.deps.readSchema()),
|
|
1334
|
+
recency,
|
|
1335
|
+
bakedAt: Date.now()
|
|
1336
|
+
};
|
|
1337
|
+
this.manifest = next;
|
|
1338
|
+
await writeManifest(this.deps.backend, this.deps.workDir, next);
|
|
1339
|
+
await this.deps.sinks.notifyAll({
|
|
1340
|
+
kind: "workspace-index-manifest",
|
|
1341
|
+
content: serializeManifestForMirror(next)
|
|
1342
|
+
});
|
|
1343
|
+
}
|
|
1344
|
+
hydrateRecencyFromManifest(manifest) {
|
|
1345
|
+
for (const [orbital, entry] of Object.entries(manifest.recency)) {
|
|
1346
|
+
this.recencyByOrbital.set(orbital, entry);
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
explainKnobMatches(orbital, prompt) {
|
|
1350
|
+
const spec = this.specsByOrbital.get(orbital);
|
|
1351
|
+
if (!spec) return [];
|
|
1352
|
+
const params = asJsonObject4(spec["params"]);
|
|
1353
|
+
if (!params) return [];
|
|
1354
|
+
const traitOverrides = asJsonObject4(params["traitOverrides"]);
|
|
1355
|
+
if (!traitOverrides) return [];
|
|
1356
|
+
const promptLower = prompt.toLowerCase();
|
|
1357
|
+
const out = [];
|
|
1358
|
+
for (const trait of Object.keys(traitOverrides).sort()) {
|
|
1359
|
+
const override = asJsonObject4(traitOverrides[trait]);
|
|
1360
|
+
if (!override) continue;
|
|
1361
|
+
const config = asJsonObject4(override["config"]);
|
|
1362
|
+
if (!config) continue;
|
|
1363
|
+
for (const knob of Object.keys(config).sort()) {
|
|
1364
|
+
const rendered = renderKnobValueForExplain(config[knob]);
|
|
1365
|
+
if (rendered.length === 0) continue;
|
|
1366
|
+
if (promptLower.includes(rendered.toLowerCase())) {
|
|
1367
|
+
out.push(`${trait}.${knob}`);
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
return out;
|
|
1372
|
+
}
|
|
718
1373
|
async rebakeOrbital(orbital, spec) {
|
|
719
1374
|
const checksum = checksumSpec(spec);
|
|
720
1375
|
const existing = this.entries.get(orbital);
|
|
@@ -731,15 +1386,20 @@ var WorkspaceIndexImpl = class {
|
|
|
731
1386
|
async bakeAndPersist(orbital, spec, checksum) {
|
|
732
1387
|
this.stale.add(orbital);
|
|
733
1388
|
const identityFingerprint = composeOrbitalIdentityFingerprint(spec);
|
|
1389
|
+
const contentFingerprint = composeOrbitalContentFingerprint(spec);
|
|
734
1390
|
const extraInputs = extractExtraTraitInputs(spec);
|
|
735
|
-
const allTexts = [
|
|
1391
|
+
const allTexts = [
|
|
1392
|
+
identityFingerprint,
|
|
1393
|
+
contentFingerprint,
|
|
1394
|
+
...extraInputs.map((e) => e.fingerprint)
|
|
1395
|
+
];
|
|
736
1396
|
const { embeddings } = await this.deps.embedder.embedBatch(allTexts);
|
|
737
1397
|
if (embeddings.length !== allTexts.length) {
|
|
738
1398
|
throw new Error(
|
|
739
1399
|
`[workspace-index] embedder returned ${embeddings.length} vectors for ${allTexts.length} inputs`
|
|
740
1400
|
);
|
|
741
1401
|
}
|
|
742
|
-
const [identityVector, ...extraVectors] = embeddings;
|
|
1402
|
+
const [identityVector, contentVector, ...extraVectors] = embeddings;
|
|
743
1403
|
const extraTraitIdentities = extraInputs.map((input, idx) => ({
|
|
744
1404
|
ref: input.ref,
|
|
745
1405
|
alias: input.alias,
|
|
@@ -751,6 +1411,8 @@ var WorkspaceIndexImpl = class {
|
|
|
751
1411
|
specChecksum: checksum,
|
|
752
1412
|
identityVector,
|
|
753
1413
|
identityFingerprint,
|
|
1414
|
+
contentVector,
|
|
1415
|
+
contentFingerprint,
|
|
754
1416
|
extraTraitIdentities,
|
|
755
1417
|
bakedAt: Date.now()
|
|
756
1418
|
};
|
|
@@ -779,6 +1441,8 @@ function serializeEntryForMirror(entry) {
|
|
|
779
1441
|
specChecksum: entry.specChecksum,
|
|
780
1442
|
identityVector: [...entry.identityVector],
|
|
781
1443
|
identityFingerprint: entry.identityFingerprint,
|
|
1444
|
+
contentVector: [...entry.contentVector],
|
|
1445
|
+
contentFingerprint: entry.contentFingerprint,
|
|
782
1446
|
extraTraitIdentities: entry.extraTraitIdentities.map((e) => ({
|
|
783
1447
|
ref: e.ref,
|
|
784
1448
|
alias: e.alias,
|
|
@@ -789,13 +1453,13 @@ function serializeEntryForMirror(entry) {
|
|
|
789
1453
|
};
|
|
790
1454
|
}
|
|
791
1455
|
function extractExtraTraitInputs(spec) {
|
|
792
|
-
const params =
|
|
1456
|
+
const params = asJsonObject4(spec["params"]);
|
|
793
1457
|
if (!params) return [];
|
|
794
1458
|
const extras = params["extraTraits"];
|
|
795
1459
|
if (!Array.isArray(extras)) return [];
|
|
796
1460
|
const out = [];
|
|
797
1461
|
for (const entry of extras) {
|
|
798
|
-
const obj =
|
|
1462
|
+
const obj = asJsonObject4(entry);
|
|
799
1463
|
if (!obj) continue;
|
|
800
1464
|
const ref = typeof obj["ref"] === "string" ? obj["ref"] : null;
|
|
801
1465
|
if (ref === null) continue;
|
|
@@ -810,11 +1474,102 @@ function extractExtraTraitInputs(spec) {
|
|
|
810
1474
|
}
|
|
811
1475
|
return out;
|
|
812
1476
|
}
|
|
813
|
-
function
|
|
1477
|
+
function asJsonObject4(value) {
|
|
814
1478
|
if (value === void 0 || value === null) return null;
|
|
815
1479
|
if (typeof value !== "object" || Array.isArray(value)) return null;
|
|
816
1480
|
return value;
|
|
817
1481
|
}
|
|
1482
|
+
function emptyManifest() {
|
|
1483
|
+
return {
|
|
1484
|
+
schemaVersion: WORKSPACE_INDEX_SCHEMA_VERSION,
|
|
1485
|
+
bm25: { documents: {}, docFreq: {}, docCount: 0, avgDocLen: 0 },
|
|
1486
|
+
intent: { entityNameOverrides: {}, traitRefImporters: {}, ruleCapabilities: {}, organism: {} },
|
|
1487
|
+
composed: { events: {}, entityNameComposed: {} },
|
|
1488
|
+
recency: {},
|
|
1489
|
+
bakedAt: 0
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1492
|
+
function deriveRecencyEntry(_orbital, rows, prior) {
|
|
1493
|
+
let recencyTurn = prior?.recencyTurn ?? 0;
|
|
1494
|
+
let lastChange = prior?.lastChange ?? 0;
|
|
1495
|
+
for (let i = 0; i < rows.length; i++) {
|
|
1496
|
+
const row = rows[i];
|
|
1497
|
+
const turn = typeof row["turn"] === "number" ? row["turn"] : recencyTurn + 1;
|
|
1498
|
+
const ts = typeof row["timestamp"] === "number" ? row["timestamp"] : 0;
|
|
1499
|
+
if (turn > recencyTurn) recencyTurn = turn;
|
|
1500
|
+
if (ts > lastChange) lastChange = ts;
|
|
1501
|
+
}
|
|
1502
|
+
return { recencyTurn, lastChange };
|
|
1503
|
+
}
|
|
1504
|
+
function renameKey(map, from, to) {
|
|
1505
|
+
if (!map.has(from)) return;
|
|
1506
|
+
const value = map.get(from);
|
|
1507
|
+
if (value === void 0) return;
|
|
1508
|
+
map.delete(from);
|
|
1509
|
+
map.set(to, value);
|
|
1510
|
+
}
|
|
1511
|
+
function renderKnobValueForExplain(value) {
|
|
1512
|
+
if (typeof value === "string") return value;
|
|
1513
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
1514
|
+
return "";
|
|
1515
|
+
}
|
|
1516
|
+
function serializeManifestForMirror(manifest) {
|
|
1517
|
+
return {
|
|
1518
|
+
schemaVersion: manifest.schemaVersion,
|
|
1519
|
+
bm25: serializeBM25(manifest.bm25),
|
|
1520
|
+
intent: serializeIntent(manifest.intent),
|
|
1521
|
+
composed: serializeComposed(manifest.composed),
|
|
1522
|
+
recency: serializeRecency(manifest.recency),
|
|
1523
|
+
bakedAt: manifest.bakedAt
|
|
1524
|
+
};
|
|
1525
|
+
}
|
|
1526
|
+
function serializeBM25(t) {
|
|
1527
|
+
const documents = {};
|
|
1528
|
+
for (const [orbital, doc] of Object.entries(t.documents)) {
|
|
1529
|
+
documents[orbital] = serializeBM25Doc(doc);
|
|
1530
|
+
}
|
|
1531
|
+
return {
|
|
1532
|
+
documents,
|
|
1533
|
+
docFreq: { ...t.docFreq },
|
|
1534
|
+
docCount: t.docCount,
|
|
1535
|
+
avgDocLen: t.avgDocLen
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
function serializeBM25Doc(doc) {
|
|
1539
|
+
return {
|
|
1540
|
+
orbital: doc.orbital,
|
|
1541
|
+
termFreq: { ...doc.termFreq },
|
|
1542
|
+
docLen: doc.docLen
|
|
1543
|
+
};
|
|
1544
|
+
}
|
|
1545
|
+
function serializeIntent(intent) {
|
|
1546
|
+
return {
|
|
1547
|
+
entityNameOverrides: serializeMapOfArrays(intent.entityNameOverrides, (b) => ({ ...b })),
|
|
1548
|
+
traitRefImporters: serializeMapOfArrays(intent.traitRefImporters, (s) => s),
|
|
1549
|
+
ruleCapabilities: serializeMapOfArrays(intent.ruleCapabilities, (b) => ({ ...b })),
|
|
1550
|
+
organism: serializeMapOfArrays(intent.organism, (s) => s)
|
|
1551
|
+
};
|
|
1552
|
+
}
|
|
1553
|
+
function serializeComposed(composed) {
|
|
1554
|
+
return {
|
|
1555
|
+
events: serializeMapOfArrays(composed.events, (e) => ({ ...e })),
|
|
1556
|
+
entityNameComposed: serializeMapOfArrays(composed.entityNameComposed, (b) => ({ ...b }))
|
|
1557
|
+
};
|
|
1558
|
+
}
|
|
1559
|
+
function serializeRecency(recency) {
|
|
1560
|
+
const out = {};
|
|
1561
|
+
for (const [orbital, entry] of Object.entries(recency)) {
|
|
1562
|
+
out[orbital] = { recencyTurn: entry.recencyTurn, lastChange: entry.lastChange };
|
|
1563
|
+
}
|
|
1564
|
+
return out;
|
|
1565
|
+
}
|
|
1566
|
+
function serializeMapOfArrays(map, projectOne) {
|
|
1567
|
+
const out = {};
|
|
1568
|
+
for (const [key, items] of Object.entries(map)) {
|
|
1569
|
+
out[key] = items.map(projectOne);
|
|
1570
|
+
}
|
|
1571
|
+
return out;
|
|
1572
|
+
}
|
|
818
1573
|
|
|
819
1574
|
// src/service.ts
|
|
820
1575
|
var COORD_FILES = {
|
|
@@ -847,7 +1602,9 @@ var WorkspaceServiceImpl = class {
|
|
|
847
1602
|
sinks: this.sinks,
|
|
848
1603
|
embedder: args.embedder,
|
|
849
1604
|
listOrbitals: () => this.listOrbitals(),
|
|
850
|
-
readSpec: (orbital) => this.readSpec(orbital)
|
|
1605
|
+
readSpec: (orbital) => this.readSpec(orbital),
|
|
1606
|
+
readSchema: () => this.readSchema(),
|
|
1607
|
+
readHistory: (orbital) => this.readHistory(orbital)
|
|
851
1608
|
});
|
|
852
1609
|
}
|
|
853
1610
|
// === Identity ===
|
|
@@ -1405,6 +2162,6 @@ async function resolveLifecycle(backend, opts) {
|
|
|
1405
2162
|
return { workDir, appId: opts.appId };
|
|
1406
2163
|
}
|
|
1407
2164
|
|
|
1408
|
-
export { DEFAULT_COERCION_THRESHOLD, WORKSPACE_INDEX_SCHEMA_VERSION, openWorkspace };
|
|
2165
|
+
export { DEFAULT_COERCION_THRESHOLD, DEFAULT_RETRIEVAL_TOP_K, RRF_K, WORKSPACE_INDEX_SCHEMA_VERSION, openWorkspace };
|
|
1409
2166
|
//# sourceMappingURL=index.js.map
|
|
1410
2167
|
//# sourceMappingURL=index.js.map
|