chainlesschain 0.51.0 → 0.81.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.
Files changed (70) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/.build-hash +1 -1
  3. package/src/assets/web-panel/assets/{AppLayout-Rvi759IS.js → AppLayout-6SPt_8Y_.js} +1 -1
  4. package/src/assets/web-panel/assets/{Dashboard-DBhFxXYQ.js → Dashboard-Br7kCwKJ.js} +2 -2
  5. package/src/assets/web-panel/assets/Dashboard-CKeMmCoT.css +1 -0
  6. package/src/assets/web-panel/assets/{index-uL0cZ8N_.js → index-tN-8TosE.js} +2 -2
  7. package/src/assets/web-panel/index.html +2 -2
  8. package/src/commands/a2a.js +380 -0
  9. package/src/commands/agent-network.js +785 -0
  10. package/src/commands/automation.js +654 -0
  11. package/src/commands/bi.js +348 -0
  12. package/src/commands/crosschain.js +218 -0
  13. package/src/commands/dao.js +565 -0
  14. package/src/commands/did-v2.js +620 -0
  15. package/src/commands/dlp.js +341 -0
  16. package/src/commands/economy.js +578 -0
  17. package/src/commands/evolution.js +391 -0
  18. package/src/commands/evomap.js +394 -0
  19. package/src/commands/federation.js +283 -0
  20. package/src/commands/hmemory.js +442 -0
  21. package/src/commands/inference.js +318 -0
  22. package/src/commands/lowcode.js +356 -0
  23. package/src/commands/marketplace.js +256 -0
  24. package/src/commands/perf.js +433 -0
  25. package/src/commands/pipeline.js +449 -0
  26. package/src/commands/plugin-ecosystem.js +517 -0
  27. package/src/commands/privacy.js +321 -0
  28. package/src/commands/reputation.js +261 -0
  29. package/src/commands/sandbox.js +401 -0
  30. package/src/commands/siem.js +246 -0
  31. package/src/commands/sla.js +259 -0
  32. package/src/commands/social.js +311 -0
  33. package/src/commands/sso.js +798 -0
  34. package/src/commands/stress.js +230 -0
  35. package/src/commands/terraform.js +245 -0
  36. package/src/commands/workflow.js +320 -0
  37. package/src/commands/zkp.js +562 -1
  38. package/src/index.js +21 -0
  39. package/src/lib/a2a-protocol.js +451 -0
  40. package/src/lib/agent-economy.js +479 -0
  41. package/src/lib/agent-network.js +1121 -0
  42. package/src/lib/app-builder.js +239 -0
  43. package/src/lib/automation-engine.js +948 -0
  44. package/src/lib/bi-engine.js +338 -0
  45. package/src/lib/cross-chain.js +345 -0
  46. package/src/lib/dao-governance.js +569 -0
  47. package/src/lib/did-v2-manager.js +1127 -0
  48. package/src/lib/dlp-engine.js +389 -0
  49. package/src/lib/evolution-system.js +453 -0
  50. package/src/lib/evomap-federation.js +177 -0
  51. package/src/lib/evomap-governance.js +276 -0
  52. package/src/lib/federation-hardening.js +259 -0
  53. package/src/lib/hierarchical-memory.js +481 -0
  54. package/src/lib/inference-network.js +330 -0
  55. package/src/lib/perf-tuning.js +734 -0
  56. package/src/lib/pipeline-orchestrator.js +928 -0
  57. package/src/lib/plugin-ecosystem.js +1109 -0
  58. package/src/lib/privacy-computing.js +427 -0
  59. package/src/lib/reputation-optimizer.js +299 -0
  60. package/src/lib/sandbox-v2.js +306 -0
  61. package/src/lib/siem-exporter.js +333 -0
  62. package/src/lib/skill-marketplace.js +325 -0
  63. package/src/lib/sla-manager.js +275 -0
  64. package/src/lib/social-graph-analytics.js +707 -0
  65. package/src/lib/sso-manager.js +841 -0
  66. package/src/lib/stress-tester.js +330 -0
  67. package/src/lib/terraform-manager.js +363 -0
  68. package/src/lib/workflow-engine.js +454 -1
  69. package/src/lib/zkp-engine.js +523 -20
  70. package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +0 -1
@@ -587,3 +587,484 @@ export function getMemoryStats(db) {
587
587
  total: workingTotal + shortTermTotal + ltCount.count + coreCount.count,
588
588
  };
589
589
  }
590
+
591
+ // ═════════════════════════════════════════════════════════════════
592
+ // Phase 83 — Hierarchical Memory 2.0 additions (strictly-additive)
593
+ // Frozen canonical enums + metadata-aware store + promote/demote
594
+ // + permission-based sharing + episodic/semantic V2 search
595
+ // + consolidation status tracking + timer lifecycle
596
+ // ═════════════════════════════════════════════════════════════════
597
+
598
+ export const MEMORY_LAYER = Object.freeze({
599
+ WORKING: "working",
600
+ SHORT_TERM: "short-term",
601
+ LONG_TERM: "long-term",
602
+ CORE: "core",
603
+ });
604
+
605
+ export const MEMORY_TYPE = Object.freeze({
606
+ EPISODIC: "episodic",
607
+ SEMANTIC: "semantic",
608
+ PROCEDURAL: "procedural",
609
+ });
610
+
611
+ export const CONSOLIDATION_STATUS = Object.freeze({
612
+ PENDING: "pending",
613
+ PROCESSING: "processing",
614
+ COMPLETED: "completed",
615
+ FAILED: "failed",
616
+ });
617
+
618
+ export const SHARE_PERMISSION = Object.freeze({
619
+ READ: "read",
620
+ COPY: "copy",
621
+ MODIFY: "modify",
622
+ });
623
+
624
+ const _LAYER_VALUES = new Set(Object.values(MEMORY_LAYER));
625
+ const _TYPE_VALUES = new Set(Object.values(MEMORY_TYPE));
626
+ const _PERM_VALUES = new Set(Object.values(SHARE_PERMISSION));
627
+
628
+ // V2 state (parallel to existing in-memory maps)
629
+ const _v2MetaNS = new Map();
630
+ const _v2Shares = [];
631
+ const _v2Consolidations = [];
632
+ let _consolidationTimer = null;
633
+
634
+ /**
635
+ * Public accessor for the Ebbinghaus forgetting curve used internally.
636
+ * retention = e^(-decay_rate * age_hours)
637
+ */
638
+ export function applyForgettingCurve(
639
+ createdOrAccessed,
640
+ rate = MEMORY_CONFIG.forgettingRate,
641
+ ) {
642
+ return calcRetention(createdOrAccessed, rate);
643
+ }
644
+
645
+ /**
646
+ * Record V2 metadata for an already-stored memory. Metadata is not
647
+ * persisted to the DB — lives alongside the in-memory layer.
648
+ */
649
+ export function attachMetadata(memoryId, metadata, namespace = DEFAULT_NS) {
650
+ if (!memoryId) throw new Error("memoryId is required");
651
+ if (!metadata || typeof metadata !== "object")
652
+ throw new Error("metadata must be an object");
653
+ if (!_v2MetaNS.has(namespace)) _v2MetaNS.set(namespace, new Map());
654
+ const meta = _v2MetaNS.get(namespace).get(memoryId) || {};
655
+ const merged = { ...meta, ...metadata, memoryId };
656
+ _v2MetaNS.get(namespace).set(memoryId, merged);
657
+ return merged;
658
+ }
659
+
660
+ /**
661
+ * Find which layer a memoryId lives in (in-memory only).
662
+ */
663
+ function _locateInMemory(memoryId) {
664
+ for (const [ns, nsMap] of _workingNS) {
665
+ if (nsMap.has(memoryId))
666
+ return { layer: MEMORY_LAYER.WORKING, namespace: ns, nsMap };
667
+ }
668
+ for (const [ns, nsMap] of _shortTermNS) {
669
+ if (nsMap.has(memoryId))
670
+ return { layer: MEMORY_LAYER.SHORT_TERM, namespace: ns, nsMap };
671
+ }
672
+ return null;
673
+ }
674
+
675
+ /**
676
+ * Promote a memory one layer up: working → short-term → long-term.
677
+ */
678
+ export function promoteMemoryV2(db, memoryId) {
679
+ if (!memoryId) throw new Error("memoryId is required");
680
+ const loc = _locateInMemory(memoryId);
681
+ if (loc && loc.layer === MEMORY_LAYER.WORKING) {
682
+ const mem = loc.nsMap.get(memoryId);
683
+ loc.nsMap.delete(memoryId);
684
+ _getShortTermNS(loc.namespace).set(memoryId, {
685
+ ...mem,
686
+ lastAccessed: nowISO(),
687
+ });
688
+ return {
689
+ id: memoryId,
690
+ from: MEMORY_LAYER.WORKING,
691
+ to: MEMORY_LAYER.SHORT_TERM,
692
+ };
693
+ }
694
+ if (loc && loc.layer === MEMORY_LAYER.SHORT_TERM) {
695
+ const mem = loc.nsMap.get(memoryId);
696
+ loc.nsMap.delete(memoryId);
697
+ ensureMemoryTables(db);
698
+ const now = nowISO();
699
+ db.prepare(
700
+ `INSERT INTO memory_long_term (id, content, type, importance, access_count, layer, created_at, last_accessed) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
701
+ ).run(
702
+ memoryId,
703
+ mem.content,
704
+ mem.type,
705
+ mem.importance,
706
+ mem.accessCount,
707
+ "long-term",
708
+ mem.createdAt,
709
+ now,
710
+ );
711
+ return {
712
+ id: memoryId,
713
+ from: MEMORY_LAYER.SHORT_TERM,
714
+ to: MEMORY_LAYER.LONG_TERM,
715
+ };
716
+ }
717
+ throw new Error(`Memory not found in working/short-term: ${memoryId}`);
718
+ }
719
+
720
+ /**
721
+ * Demote a memory one layer down: short-term → working.
722
+ * (long-term/core demotion requires DB round-trip; not exposed here.)
723
+ */
724
+ export function demoteMemoryV2(memoryId) {
725
+ if (!memoryId) throw new Error("memoryId is required");
726
+ for (const [ns, nsMap] of _shortTermNS) {
727
+ if (nsMap.has(memoryId)) {
728
+ const mem = nsMap.get(memoryId);
729
+ nsMap.delete(memoryId);
730
+ _getWorkingNS(ns).set(memoryId, { ...mem, lastAccessed: nowISO() });
731
+ return {
732
+ id: memoryId,
733
+ from: MEMORY_LAYER.SHORT_TERM,
734
+ to: MEMORY_LAYER.WORKING,
735
+ };
736
+ }
737
+ }
738
+ throw new Error(`Memory not in short-term: ${memoryId}`);
739
+ }
740
+
741
+ /**
742
+ * Share a memory with fine-grained permissions.
743
+ * permissions: subset of {read, copy, modify} — validated against SHARE_PERMISSION.
744
+ */
745
+ export function shareMemoryV2(
746
+ db,
747
+ { memoryId, sourceAgent, targetAgent, permissions = ["read"] } = {},
748
+ ) {
749
+ if (!memoryId || !targetAgent) {
750
+ throw new Error("memoryId and targetAgent are required");
751
+ }
752
+ const perms = Array.isArray(permissions) ? permissions : [permissions];
753
+ for (const p of perms) {
754
+ if (!_PERM_VALUES.has(p)) throw new Error(`Invalid permission: ${p}`);
755
+ }
756
+ ensureMemoryTables(db);
757
+ const id = `sharev2-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
758
+ const sharedAt = nowISO();
759
+ const record = {
760
+ id,
761
+ memoryId,
762
+ sourceAgent: sourceAgent || "local",
763
+ targetAgent,
764
+ permissions: [...perms],
765
+ sharedAt,
766
+ revokedAt: null,
767
+ };
768
+ _v2Shares.push(record);
769
+ try {
770
+ db.prepare(
771
+ `INSERT INTO memory_sharing (id, memory_id, source_agent, target_agent, privacy_level, shared_at) VALUES (?, ?, ?, ?, ?, ?)`,
772
+ ).run(
773
+ id,
774
+ memoryId,
775
+ record.sourceAgent,
776
+ targetAgent,
777
+ perms.join(","),
778
+ sharedAt,
779
+ );
780
+ } catch {
781
+ /* schema drift tolerated */
782
+ }
783
+ return record;
784
+ }
785
+
786
+ export function revokeShare(shareId) {
787
+ const record = _v2Shares.find((s) => s.id === shareId);
788
+ if (!record) throw new Error(`Share not found: ${shareId}`);
789
+ if (record.revokedAt) throw new Error(`Share already revoked`);
790
+ record.revokedAt = nowISO();
791
+ return record;
792
+ }
793
+
794
+ export function listShares(options = {}) {
795
+ let result = [..._v2Shares];
796
+ if (options.memoryId)
797
+ result = result.filter((s) => s.memoryId === options.memoryId);
798
+ if (options.targetAgent)
799
+ result = result.filter((s) => s.targetAgent === options.targetAgent);
800
+ if (options.activeOnly) result = result.filter((s) => !s.revokedAt);
801
+ return result;
802
+ }
803
+
804
+ function _timeInRange(ts, range) {
805
+ if (!range) return true;
806
+ const t = new Date(ts).getTime();
807
+ if (range.from && t < new Date(range.from).getTime()) return false;
808
+ if (range.to && t > new Date(range.to).getTime()) return false;
809
+ return true;
810
+ }
811
+
812
+ /**
813
+ * Search episodic memories with time range + scene + context filters.
814
+ */
815
+ export function searchEpisodicV2(db, options = {}) {
816
+ const { timeRange, scene, context, query, limit = 20, namespace } = options;
817
+ const results = [];
818
+ const scanLayer = (nsMap, ns, layerName) => {
819
+ for (const [id, mem] of nsMap) {
820
+ if (mem.type !== MEMORY_TYPE.EPISODIC) continue;
821
+ const meta = _v2MetaNS.get(ns)?.get(id);
822
+ if (timeRange && !_timeInRange(mem.createdAt, timeRange)) continue;
823
+ if (scene && meta?.scene !== scene) continue;
824
+ if (context && !(meta?.context || "").includes(context)) continue;
825
+ if (query && !mem.content.toLowerCase().includes(query.toLowerCase()))
826
+ continue;
827
+ results.push({ ...mem, layer: layerName, metadata: meta || null });
828
+ }
829
+ };
830
+ for (const [ns, nsMap] of _workingNS) {
831
+ if (namespace && ns !== namespace) continue;
832
+ scanLayer(nsMap, ns, MEMORY_LAYER.WORKING);
833
+ }
834
+ for (const [ns, nsMap] of _shortTermNS) {
835
+ if (namespace && ns !== namespace) continue;
836
+ scanLayer(nsMap, ns, MEMORY_LAYER.SHORT_TERM);
837
+ }
838
+ return results.slice(0, limit);
839
+ }
840
+
841
+ /**
842
+ * Search semantic memories with concept-overlap similarity.
843
+ * similarity = |A ∩ B| / max(|A|, |B|) (Szymkiewicz–Simpson-like)
844
+ */
845
+ export function searchSemanticV2(db, options = {}) {
846
+ const {
847
+ concepts = [],
848
+ query,
849
+ similarityThreshold = 0,
850
+ limit = 20,
851
+ namespace,
852
+ } = options;
853
+ const results = [];
854
+ const scanLayer = (nsMap, ns, layerName) => {
855
+ for (const [id, mem] of nsMap) {
856
+ if (mem.type !== MEMORY_TYPE.SEMANTIC) continue;
857
+ const meta = _v2MetaNS.get(ns)?.get(id);
858
+ const memConcepts = meta?.concepts || [];
859
+ let sim = 0;
860
+ if (concepts.length > 0) {
861
+ const overlap = concepts.filter((c) => memConcepts.includes(c)).length;
862
+ const denom = Math.max(concepts.length, memConcepts.length) || 1;
863
+ sim = overlap / denom;
864
+ if (sim < similarityThreshold) continue;
865
+ }
866
+ if (query && !mem.content.toLowerCase().includes(query.toLowerCase()))
867
+ continue;
868
+ results.push({
869
+ ...mem,
870
+ layer: layerName,
871
+ metadata: meta || null,
872
+ similarity: sim,
873
+ });
874
+ }
875
+ };
876
+ for (const [ns, nsMap] of _workingNS) {
877
+ if (namespace && ns !== namespace) continue;
878
+ scanLayer(nsMap, ns, MEMORY_LAYER.WORKING);
879
+ }
880
+ for (const [ns, nsMap] of _shortTermNS) {
881
+ if (namespace && ns !== namespace) continue;
882
+ scanLayer(nsMap, ns, MEMORY_LAYER.SHORT_TERM);
883
+ }
884
+ results.sort((a, b) => (b.similarity || 0) - (a.similarity || 0));
885
+ return results.slice(0, limit);
886
+ }
887
+
888
+ /**
889
+ * Consolidation run with status tracking and optional pattern extraction.
890
+ * Delegates to existing consolidateMemory() for promotion logic.
891
+ */
892
+ export function consolidateV2(db, options = {}) {
893
+ const id = `consol-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
894
+ const record = {
895
+ id,
896
+ status: CONSOLIDATION_STATUS.PROCESSING,
897
+ startedAt: nowISO(),
898
+ completedAt: null,
899
+ promoted: 0,
900
+ forgotten: 0,
901
+ patterns: [],
902
+ error: null,
903
+ };
904
+ _v2Consolidations.push(record);
905
+ try {
906
+ // Pattern extraction snapshot BEFORE consolidation (so we can see
907
+ // frequently-accessed short-term items before they get promoted out).
908
+ if (options.extractPatterns) {
909
+ for (const [, nsMap] of _shortTermNS) {
910
+ for (const mem of nsMap.values()) {
911
+ if (mem.accessCount >= 2) {
912
+ record.patterns.push({
913
+ id: mem.id,
914
+ type: mem.type,
915
+ content: mem.content.slice(0, 80),
916
+ accessCount: mem.accessCount,
917
+ });
918
+ }
919
+ }
920
+ }
921
+ }
922
+ const result = consolidateMemory(db);
923
+ record.promoted = result.promoted;
924
+ record.forgotten = result.forgotten;
925
+ record.status = CONSOLIDATION_STATUS.COMPLETED;
926
+ record.completedAt = nowISO();
927
+ } catch (err) {
928
+ record.status = CONSOLIDATION_STATUS.FAILED;
929
+ record.completedAt = nowISO();
930
+ record.error = err.message;
931
+ }
932
+ return record;
933
+ }
934
+
935
+ export function listConsolidations(options = {}) {
936
+ let result = [..._v2Consolidations];
937
+ if (options.status)
938
+ result = result.filter((c) => c.status === options.status);
939
+ return result;
940
+ }
941
+
942
+ /**
943
+ * Prune with per-layer scope + custom threshold.
944
+ */
945
+ export function pruneV2(db, options = {}) {
946
+ const { layer, maxAge = 720, threshold } = options;
947
+ if (layer && !_LAYER_VALUES.has(layer))
948
+ throw new Error(`Invalid layer: ${layer}`);
949
+ const effectiveThreshold = threshold ?? MEMORY_CONFIG.recallThreshold;
950
+ let pruned = 0;
951
+
952
+ if (!layer || layer === MEMORY_LAYER.WORKING) {
953
+ for (const [, nsMap] of _workingNS) {
954
+ for (const [id, mem] of nsMap) {
955
+ const retention = calcRetention(mem.lastAccessed);
956
+ if (retention < effectiveThreshold) {
957
+ nsMap.delete(id);
958
+ pruned++;
959
+ }
960
+ }
961
+ }
962
+ }
963
+ if (!layer || layer === MEMORY_LAYER.SHORT_TERM) {
964
+ for (const [, nsMap] of _shortTermNS) {
965
+ for (const [id, mem] of nsMap) {
966
+ const retention = calcRetention(mem.lastAccessed);
967
+ if (retention < effectiveThreshold) {
968
+ nsMap.delete(id);
969
+ pruned++;
970
+ }
971
+ }
972
+ }
973
+ }
974
+ if (!layer || layer === MEMORY_LAYER.LONG_TERM) {
975
+ const cutoff = new Date(Date.now() - maxAge * 60 * 60 * 1000).toISOString();
976
+ ensureMemoryTables(db);
977
+ const result = db
978
+ .prepare(
979
+ `DELETE FROM memory_long_term WHERE last_accessed < ? AND access_count < 3`,
980
+ )
981
+ .run(cutoff);
982
+ pruned += result.changes || 0;
983
+ }
984
+
985
+ return { pruned, layer: layer || "all" };
986
+ }
987
+
988
+ /**
989
+ * Start a periodic consolidation timer. Returns timer handle.
990
+ * Only one timer at a time — repeat calls return the existing handle.
991
+ */
992
+ export function startConsolidationTimer({
993
+ intervalMs = 60_000,
994
+ db,
995
+ onTick,
996
+ } = {}) {
997
+ if (_consolidationTimer) return _consolidationTimer;
998
+ if (!db) throw new Error("db is required for consolidation timer");
999
+ _consolidationTimer = setInterval(() => {
1000
+ const rec = consolidateV2(db);
1001
+ if (onTick) {
1002
+ try {
1003
+ onTick(rec);
1004
+ } catch {
1005
+ /* swallow */
1006
+ }
1007
+ }
1008
+ }, intervalMs);
1009
+ return _consolidationTimer;
1010
+ }
1011
+
1012
+ export function stopConsolidationTimer() {
1013
+ if (_consolidationTimer) {
1014
+ clearInterval(_consolidationTimer);
1015
+ _consolidationTimer = null;
1016
+ return true;
1017
+ }
1018
+ return false;
1019
+ }
1020
+
1021
+ /**
1022
+ * Extended stats — base + per-layer breakdown + consolidation + shares.
1023
+ */
1024
+ export function getStatsV2(db) {
1025
+ const base = getMemoryStats(db);
1026
+
1027
+ const perLayer = {
1028
+ [MEMORY_LAYER.WORKING]: base.working,
1029
+ [MEMORY_LAYER.SHORT_TERM]: base.shortTerm,
1030
+ [MEMORY_LAYER.LONG_TERM]: base.longTerm,
1031
+ [MEMORY_LAYER.CORE]: base.core,
1032
+ };
1033
+
1034
+ const byStatus = {};
1035
+ for (const c of _v2Consolidations) {
1036
+ byStatus[c.status] = (byStatus[c.status] || 0) + 1;
1037
+ }
1038
+
1039
+ return {
1040
+ ...base,
1041
+ perLayer,
1042
+ consolidation: {
1043
+ total: _v2Consolidations.length,
1044
+ byStatus,
1045
+ last: _v2Consolidations[_v2Consolidations.length - 1] || null,
1046
+ },
1047
+ shares: {
1048
+ total: _v2Shares.length,
1049
+ active: _v2Shares.filter((s) => !s.revokedAt).length,
1050
+ revoked: _v2Shares.filter((s) => s.revokedAt).length,
1051
+ },
1052
+ metadataEntries: [..._v2MetaNS.values()].reduce(
1053
+ (sum, m) => sum + m.size,
1054
+ 0,
1055
+ ),
1056
+ };
1057
+ }
1058
+
1059
+ /**
1060
+ * Test helper — clear all V2 state + stop timer.
1061
+ */
1062
+ export function _resetV2State() {
1063
+ _v2MetaNS.clear();
1064
+ _v2Shares.length = 0;
1065
+ _v2Consolidations.length = 0;
1066
+ if (_consolidationTimer) {
1067
+ clearInterval(_consolidationTimer);
1068
+ _consolidationTimer = null;
1069
+ }
1070
+ }