@almadar/workspace 0.1.5 → 0.2.0
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 +773 -12
- package/dist/index.js.map +1 -1
- package/dist/internal/path-layout.d.ts +2 -0
- package/dist/types.d.ts +7 -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 +28 -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 +187 -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,133 @@ 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
|
+
rulesAppliedTo(entity) {
|
|
1277
|
+
const out = [];
|
|
1278
|
+
for (const bindings of Object.values(this.manifest.intent.ruleCapabilities)) {
|
|
1279
|
+
for (const b of bindings) if (b.entityName === entity) out.push(b);
|
|
1280
|
+
}
|
|
1281
|
+
return out;
|
|
1282
|
+
}
|
|
1283
|
+
recentlyEdited(opts) {
|
|
1284
|
+
const withinTurns = opts?.withinTurns ?? 5;
|
|
1285
|
+
const entries = [];
|
|
1286
|
+
for (const [orbital, recency] of Object.entries(this.manifest.recency)) {
|
|
1287
|
+
entries.push({ orbital, recencyTurn: recency.recencyTurn });
|
|
1288
|
+
}
|
|
1289
|
+
if (entries.length === 0) return [];
|
|
1290
|
+
const maxTurn = entries.reduce((m, e) => e.recencyTurn > m ? e.recencyTurn : m, -Infinity);
|
|
1291
|
+
entries.sort((a, b) => b.recencyTurn - a.recencyTurn);
|
|
1292
|
+
return entries.filter((e) => e.recencyTurn > maxTurn - withinTurns).map((e) => e.orbital);
|
|
1293
|
+
}
|
|
1294
|
+
// ── Manifest internals ─────────────────────────────────────────────────────
|
|
1295
|
+
scheduleManifestRebuild() {
|
|
1296
|
+
const next = this.manifestQueue.then(() => this.rebuildManifest());
|
|
1297
|
+
this.manifestQueue = next.catch(() => void 0);
|
|
1298
|
+
return next;
|
|
1299
|
+
}
|
|
1300
|
+
async rebuildManifest() {
|
|
1301
|
+
const tokensPerOrbital = {};
|
|
1302
|
+
for (const [orbital, tokens] of this.tokensByOrbital) {
|
|
1303
|
+
tokensPerOrbital[orbital] = tokens;
|
|
1304
|
+
}
|
|
1305
|
+
const specsPerOrbital = {};
|
|
1306
|
+
for (const [orbital, spec] of this.specsByOrbital) {
|
|
1307
|
+
specsPerOrbital[orbital] = spec;
|
|
1308
|
+
}
|
|
1309
|
+
const recency = {};
|
|
1310
|
+
for (const [orbital, entry] of this.recencyByOrbital) {
|
|
1311
|
+
recency[orbital] = entry;
|
|
1312
|
+
}
|
|
1313
|
+
const next = {
|
|
1314
|
+
schemaVersion: WORKSPACE_INDEX_SCHEMA_VERSION,
|
|
1315
|
+
bm25: buildBM25Table(tokensPerOrbital),
|
|
1316
|
+
intent: buildIntentMaps(specsPerOrbital),
|
|
1317
|
+
composed: buildComposedMaps(this.deps.readSchema()),
|
|
1318
|
+
recency,
|
|
1319
|
+
bakedAt: Date.now()
|
|
1320
|
+
};
|
|
1321
|
+
this.manifest = next;
|
|
1322
|
+
await writeManifest(this.deps.backend, this.deps.workDir, next);
|
|
1323
|
+
await this.deps.sinks.notifyAll({
|
|
1324
|
+
kind: "workspace-index-manifest",
|
|
1325
|
+
content: serializeManifestForMirror(next)
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
hydrateRecencyFromManifest(manifest) {
|
|
1329
|
+
for (const [orbital, entry] of Object.entries(manifest.recency)) {
|
|
1330
|
+
this.recencyByOrbital.set(orbital, entry);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
explainKnobMatches(orbital, prompt) {
|
|
1334
|
+
const spec = this.specsByOrbital.get(orbital);
|
|
1335
|
+
if (!spec) return [];
|
|
1336
|
+
const params = asJsonObject4(spec["params"]);
|
|
1337
|
+
if (!params) return [];
|
|
1338
|
+
const traitOverrides = asJsonObject4(params["traitOverrides"]);
|
|
1339
|
+
if (!traitOverrides) return [];
|
|
1340
|
+
const promptLower = prompt.toLowerCase();
|
|
1341
|
+
const out = [];
|
|
1342
|
+
for (const trait of Object.keys(traitOverrides).sort()) {
|
|
1343
|
+
const override = asJsonObject4(traitOverrides[trait]);
|
|
1344
|
+
if (!override) continue;
|
|
1345
|
+
const config = asJsonObject4(override["config"]);
|
|
1346
|
+
if (!config) continue;
|
|
1347
|
+
for (const knob of Object.keys(config).sort()) {
|
|
1348
|
+
const rendered = renderKnobValueForExplain(config[knob]);
|
|
1349
|
+
if (rendered.length === 0) continue;
|
|
1350
|
+
if (promptLower.includes(rendered.toLowerCase())) {
|
|
1351
|
+
out.push(`${trait}.${knob}`);
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
return out;
|
|
1356
|
+
}
|
|
718
1357
|
async rebakeOrbital(orbital, spec) {
|
|
719
1358
|
const checksum = checksumSpec(spec);
|
|
720
1359
|
const existing = this.entries.get(orbital);
|
|
@@ -731,15 +1370,20 @@ var WorkspaceIndexImpl = class {
|
|
|
731
1370
|
async bakeAndPersist(orbital, spec, checksum) {
|
|
732
1371
|
this.stale.add(orbital);
|
|
733
1372
|
const identityFingerprint = composeOrbitalIdentityFingerprint(spec);
|
|
1373
|
+
const contentFingerprint = composeOrbitalContentFingerprint(spec);
|
|
734
1374
|
const extraInputs = extractExtraTraitInputs(spec);
|
|
735
|
-
const allTexts = [
|
|
1375
|
+
const allTexts = [
|
|
1376
|
+
identityFingerprint,
|
|
1377
|
+
contentFingerprint,
|
|
1378
|
+
...extraInputs.map((e) => e.fingerprint)
|
|
1379
|
+
];
|
|
736
1380
|
const { embeddings } = await this.deps.embedder.embedBatch(allTexts);
|
|
737
1381
|
if (embeddings.length !== allTexts.length) {
|
|
738
1382
|
throw new Error(
|
|
739
1383
|
`[workspace-index] embedder returned ${embeddings.length} vectors for ${allTexts.length} inputs`
|
|
740
1384
|
);
|
|
741
1385
|
}
|
|
742
|
-
const [identityVector, ...extraVectors] = embeddings;
|
|
1386
|
+
const [identityVector, contentVector, ...extraVectors] = embeddings;
|
|
743
1387
|
const extraTraitIdentities = extraInputs.map((input, idx) => ({
|
|
744
1388
|
ref: input.ref,
|
|
745
1389
|
alias: input.alias,
|
|
@@ -751,12 +1395,19 @@ var WorkspaceIndexImpl = class {
|
|
|
751
1395
|
specChecksum: checksum,
|
|
752
1396
|
identityVector,
|
|
753
1397
|
identityFingerprint,
|
|
1398
|
+
contentVector,
|
|
1399
|
+
contentFingerprint,
|
|
754
1400
|
extraTraitIdentities,
|
|
755
1401
|
bakedAt: Date.now()
|
|
756
1402
|
};
|
|
757
1403
|
await writeSidecar(this.deps.backend, this.deps.workDir, orbital, entry);
|
|
758
1404
|
this.entries.set(orbital, entry);
|
|
759
1405
|
this.stale.delete(orbital);
|
|
1406
|
+
await this.deps.sinks.notifyAll({
|
|
1407
|
+
kind: "workspace-index",
|
|
1408
|
+
orbital,
|
|
1409
|
+
content: serializeEntryForMirror(entry)
|
|
1410
|
+
});
|
|
760
1411
|
}
|
|
761
1412
|
async embedOne(text) {
|
|
762
1413
|
const { embeddings } = await this.deps.embedder.embedBatch([text]);
|
|
@@ -768,14 +1419,31 @@ var WorkspaceIndexImpl = class {
|
|
|
768
1419
|
return embeddings;
|
|
769
1420
|
}
|
|
770
1421
|
};
|
|
1422
|
+
function serializeEntryForMirror(entry) {
|
|
1423
|
+
return {
|
|
1424
|
+
schemaVersion: entry.schemaVersion,
|
|
1425
|
+
specChecksum: entry.specChecksum,
|
|
1426
|
+
identityVector: [...entry.identityVector],
|
|
1427
|
+
identityFingerprint: entry.identityFingerprint,
|
|
1428
|
+
contentVector: [...entry.contentVector],
|
|
1429
|
+
contentFingerprint: entry.contentFingerprint,
|
|
1430
|
+
extraTraitIdentities: entry.extraTraitIdentities.map((e) => ({
|
|
1431
|
+
ref: e.ref,
|
|
1432
|
+
alias: e.alias,
|
|
1433
|
+
fingerprint: e.fingerprint,
|
|
1434
|
+
vector: [...e.vector]
|
|
1435
|
+
})),
|
|
1436
|
+
bakedAt: entry.bakedAt
|
|
1437
|
+
};
|
|
1438
|
+
}
|
|
771
1439
|
function extractExtraTraitInputs(spec) {
|
|
772
|
-
const params =
|
|
1440
|
+
const params = asJsonObject4(spec["params"]);
|
|
773
1441
|
if (!params) return [];
|
|
774
1442
|
const extras = params["extraTraits"];
|
|
775
1443
|
if (!Array.isArray(extras)) return [];
|
|
776
1444
|
const out = [];
|
|
777
1445
|
for (const entry of extras) {
|
|
778
|
-
const obj =
|
|
1446
|
+
const obj = asJsonObject4(entry);
|
|
779
1447
|
if (!obj) continue;
|
|
780
1448
|
const ref = typeof obj["ref"] === "string" ? obj["ref"] : null;
|
|
781
1449
|
if (ref === null) continue;
|
|
@@ -790,11 +1458,102 @@ function extractExtraTraitInputs(spec) {
|
|
|
790
1458
|
}
|
|
791
1459
|
return out;
|
|
792
1460
|
}
|
|
793
|
-
function
|
|
1461
|
+
function asJsonObject4(value) {
|
|
794
1462
|
if (value === void 0 || value === null) return null;
|
|
795
1463
|
if (typeof value !== "object" || Array.isArray(value)) return null;
|
|
796
1464
|
return value;
|
|
797
1465
|
}
|
|
1466
|
+
function emptyManifest() {
|
|
1467
|
+
return {
|
|
1468
|
+
schemaVersion: WORKSPACE_INDEX_SCHEMA_VERSION,
|
|
1469
|
+
bm25: { documents: {}, docFreq: {}, docCount: 0, avgDocLen: 0 },
|
|
1470
|
+
intent: { entityNameOverrides: {}, traitRefImporters: {}, ruleCapabilities: {}, organism: {} },
|
|
1471
|
+
composed: { events: {}, entityNameComposed: {} },
|
|
1472
|
+
recency: {},
|
|
1473
|
+
bakedAt: 0
|
|
1474
|
+
};
|
|
1475
|
+
}
|
|
1476
|
+
function deriveRecencyEntry(_orbital, rows, prior) {
|
|
1477
|
+
let recencyTurn = prior?.recencyTurn ?? 0;
|
|
1478
|
+
let lastChange = prior?.lastChange ?? 0;
|
|
1479
|
+
for (let i = 0; i < rows.length; i++) {
|
|
1480
|
+
const row = rows[i];
|
|
1481
|
+
const turn = typeof row["turn"] === "number" ? row["turn"] : recencyTurn + 1;
|
|
1482
|
+
const ts = typeof row["timestamp"] === "number" ? row["timestamp"] : 0;
|
|
1483
|
+
if (turn > recencyTurn) recencyTurn = turn;
|
|
1484
|
+
if (ts > lastChange) lastChange = ts;
|
|
1485
|
+
}
|
|
1486
|
+
return { recencyTurn, lastChange };
|
|
1487
|
+
}
|
|
1488
|
+
function renameKey(map, from, to) {
|
|
1489
|
+
if (!map.has(from)) return;
|
|
1490
|
+
const value = map.get(from);
|
|
1491
|
+
if (value === void 0) return;
|
|
1492
|
+
map.delete(from);
|
|
1493
|
+
map.set(to, value);
|
|
1494
|
+
}
|
|
1495
|
+
function renderKnobValueForExplain(value) {
|
|
1496
|
+
if (typeof value === "string") return value;
|
|
1497
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
1498
|
+
return "";
|
|
1499
|
+
}
|
|
1500
|
+
function serializeManifestForMirror(manifest) {
|
|
1501
|
+
return {
|
|
1502
|
+
schemaVersion: manifest.schemaVersion,
|
|
1503
|
+
bm25: serializeBM25(manifest.bm25),
|
|
1504
|
+
intent: serializeIntent(manifest.intent),
|
|
1505
|
+
composed: serializeComposed(manifest.composed),
|
|
1506
|
+
recency: serializeRecency(manifest.recency),
|
|
1507
|
+
bakedAt: manifest.bakedAt
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1510
|
+
function serializeBM25(t) {
|
|
1511
|
+
const documents = {};
|
|
1512
|
+
for (const [orbital, doc] of Object.entries(t.documents)) {
|
|
1513
|
+
documents[orbital] = serializeBM25Doc(doc);
|
|
1514
|
+
}
|
|
1515
|
+
return {
|
|
1516
|
+
documents,
|
|
1517
|
+
docFreq: { ...t.docFreq },
|
|
1518
|
+
docCount: t.docCount,
|
|
1519
|
+
avgDocLen: t.avgDocLen
|
|
1520
|
+
};
|
|
1521
|
+
}
|
|
1522
|
+
function serializeBM25Doc(doc) {
|
|
1523
|
+
return {
|
|
1524
|
+
orbital: doc.orbital,
|
|
1525
|
+
termFreq: { ...doc.termFreq },
|
|
1526
|
+
docLen: doc.docLen
|
|
1527
|
+
};
|
|
1528
|
+
}
|
|
1529
|
+
function serializeIntent(intent) {
|
|
1530
|
+
return {
|
|
1531
|
+
entityNameOverrides: serializeMapOfArrays(intent.entityNameOverrides, (b) => ({ ...b })),
|
|
1532
|
+
traitRefImporters: serializeMapOfArrays(intent.traitRefImporters, (s) => s),
|
|
1533
|
+
ruleCapabilities: serializeMapOfArrays(intent.ruleCapabilities, (b) => ({ ...b })),
|
|
1534
|
+
organism: serializeMapOfArrays(intent.organism, (s) => s)
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1537
|
+
function serializeComposed(composed) {
|
|
1538
|
+
return {
|
|
1539
|
+
events: serializeMapOfArrays(composed.events, (e) => ({ ...e })),
|
|
1540
|
+
entityNameComposed: serializeMapOfArrays(composed.entityNameComposed, (b) => ({ ...b }))
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1543
|
+
function serializeRecency(recency) {
|
|
1544
|
+
const out = {};
|
|
1545
|
+
for (const [orbital, entry] of Object.entries(recency)) {
|
|
1546
|
+
out[orbital] = { recencyTurn: entry.recencyTurn, lastChange: entry.lastChange };
|
|
1547
|
+
}
|
|
1548
|
+
return out;
|
|
1549
|
+
}
|
|
1550
|
+
function serializeMapOfArrays(map, projectOne) {
|
|
1551
|
+
const out = {};
|
|
1552
|
+
for (const [key, items] of Object.entries(map)) {
|
|
1553
|
+
out[key] = items.map(projectOne);
|
|
1554
|
+
}
|
|
1555
|
+
return out;
|
|
1556
|
+
}
|
|
798
1557
|
|
|
799
1558
|
// src/service.ts
|
|
800
1559
|
var COORD_FILES = {
|
|
@@ -827,7 +1586,9 @@ var WorkspaceServiceImpl = class {
|
|
|
827
1586
|
sinks: this.sinks,
|
|
828
1587
|
embedder: args.embedder,
|
|
829
1588
|
listOrbitals: () => this.listOrbitals(),
|
|
830
|
-
readSpec: (orbital) => this.readSpec(orbital)
|
|
1589
|
+
readSpec: (orbital) => this.readSpec(orbital),
|
|
1590
|
+
readSchema: () => this.readSchema(),
|
|
1591
|
+
readHistory: (orbital) => this.readHistory(orbital)
|
|
831
1592
|
});
|
|
832
1593
|
}
|
|
833
1594
|
// === Identity ===
|
|
@@ -1385,6 +2146,6 @@ async function resolveLifecycle(backend, opts) {
|
|
|
1385
2146
|
return { workDir, appId: opts.appId };
|
|
1386
2147
|
}
|
|
1387
2148
|
|
|
1388
|
-
export { DEFAULT_COERCION_THRESHOLD, WORKSPACE_INDEX_SCHEMA_VERSION, openWorkspace };
|
|
2149
|
+
export { DEFAULT_COERCION_THRESHOLD, DEFAULT_RETRIEVAL_TOP_K, RRF_K, WORKSPACE_INDEX_SCHEMA_VERSION, openWorkspace };
|
|
1389
2150
|
//# sourceMappingURL=index.js.map
|
|
1390
2151
|
//# sourceMappingURL=index.js.map
|