@psiclawops/hypermem 0.1.0 → 0.5.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/ARCHITECTURE.md +4 -3
- package/README.md +457 -174
- package/dist/background-indexer.d.ts +19 -4
- package/dist/background-indexer.d.ts.map +1 -1
- package/dist/background-indexer.js +329 -17
- package/dist/cache.d.ts +110 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +495 -0
- package/dist/compaction-fence.d.ts +1 -1
- package/dist/compaction-fence.js +1 -1
- package/dist/compositor.d.ts +114 -27
- package/dist/compositor.d.ts.map +1 -1
- package/dist/compositor.js +1678 -229
- package/dist/content-type-classifier.d.ts +41 -0
- package/dist/content-type-classifier.d.ts.map +1 -0
- package/dist/content-type-classifier.js +181 -0
- package/dist/cross-agent.d.ts +5 -0
- package/dist/cross-agent.d.ts.map +1 -1
- package/dist/cross-agent.js +5 -0
- package/dist/db.d.ts +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +6 -2
- package/dist/desired-state-store.d.ts +1 -1
- package/dist/desired-state-store.d.ts.map +1 -1
- package/dist/desired-state-store.js +15 -5
- package/dist/doc-chunk-store.d.ts +26 -1
- package/dist/doc-chunk-store.d.ts.map +1 -1
- package/dist/doc-chunk-store.js +114 -1
- package/dist/doc-chunker.d.ts +1 -1
- package/dist/doc-chunker.js +1 -1
- package/dist/dreaming-promoter.d.ts +86 -0
- package/dist/dreaming-promoter.d.ts.map +1 -0
- package/dist/dreaming-promoter.js +381 -0
- package/dist/episode-store.d.ts +2 -1
- package/dist/episode-store.d.ts.map +1 -1
- package/dist/episode-store.js +4 -4
- package/dist/fact-store.d.ts +19 -1
- package/dist/fact-store.d.ts.map +1 -1
- package/dist/fact-store.js +64 -3
- package/dist/fleet-store.d.ts +1 -1
- package/dist/fleet-store.js +1 -1
- package/dist/fos-mod.d.ts +178 -0
- package/dist/fos-mod.d.ts.map +1 -0
- package/dist/fos-mod.js +416 -0
- package/dist/hybrid-retrieval.d.ts +5 -1
- package/dist/hybrid-retrieval.d.ts.map +1 -1
- package/dist/hybrid-retrieval.js +7 -3
- package/dist/image-eviction.d.ts +49 -0
- package/dist/image-eviction.d.ts.map +1 -0
- package/dist/image-eviction.js +251 -0
- package/dist/index.d.ts +50 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +73 -43
- package/dist/keystone-scorer.d.ts +51 -0
- package/dist/keystone-scorer.d.ts.map +1 -0
- package/dist/keystone-scorer.js +52 -0
- package/dist/knowledge-graph.d.ts +1 -1
- package/dist/knowledge-graph.js +1 -1
- package/dist/knowledge-lint.d.ts +29 -0
- package/dist/knowledge-lint.d.ts.map +1 -0
- package/dist/knowledge-lint.js +116 -0
- package/dist/knowledge-store.d.ts +1 -1
- package/dist/knowledge-store.d.ts.map +1 -1
- package/dist/knowledge-store.js +8 -2
- package/dist/library-schema.d.ts +3 -3
- package/dist/library-schema.d.ts.map +1 -1
- package/dist/library-schema.js +324 -3
- package/dist/message-store.d.ts +15 -2
- package/dist/message-store.d.ts.map +1 -1
- package/dist/message-store.js +51 -1
- package/dist/metrics-dashboard.d.ts +114 -0
- package/dist/metrics-dashboard.d.ts.map +1 -0
- package/dist/metrics-dashboard.js +260 -0
- package/dist/obsidian-exporter.d.ts +57 -0
- package/dist/obsidian-exporter.d.ts.map +1 -0
- package/dist/obsidian-exporter.js +274 -0
- package/dist/obsidian-watcher.d.ts +147 -0
- package/dist/obsidian-watcher.d.ts.map +1 -0
- package/dist/obsidian-watcher.js +403 -0
- package/dist/open-domain.d.ts +46 -0
- package/dist/open-domain.d.ts.map +1 -0
- package/dist/open-domain.js +125 -0
- package/dist/preference-store.d.ts +1 -1
- package/dist/preference-store.js +1 -1
- package/dist/preservation-gate.d.ts +1 -1
- package/dist/preservation-gate.js +1 -1
- package/dist/proactive-pass.d.ts +63 -0
- package/dist/proactive-pass.d.ts.map +1 -0
- package/dist/proactive-pass.js +239 -0
- package/dist/profiles.d.ts +44 -0
- package/dist/profiles.d.ts.map +1 -0
- package/dist/profiles.js +227 -0
- package/dist/provider-translator.d.ts +13 -3
- package/dist/provider-translator.d.ts.map +1 -1
- package/dist/provider-translator.js +63 -9
- package/dist/rate-limiter.d.ts +1 -1
- package/dist/rate-limiter.js +1 -1
- package/dist/repair-tool-pairs.d.ts +38 -0
- package/dist/repair-tool-pairs.d.ts.map +1 -0
- package/dist/repair-tool-pairs.js +138 -0
- package/dist/retrieval-policy.d.ts +51 -0
- package/dist/retrieval-policy.d.ts.map +1 -0
- package/dist/retrieval-policy.js +77 -0
- package/dist/schema.d.ts +2 -2
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +28 -2
- package/dist/secret-scanner.d.ts +1 -1
- package/dist/secret-scanner.js +1 -1
- package/dist/seed.d.ts +2 -2
- package/dist/seed.js +2 -2
- package/dist/session-flusher.d.ts +53 -0
- package/dist/session-flusher.d.ts.map +1 -0
- package/dist/session-flusher.js +69 -0
- package/dist/session-topic-map.d.ts +41 -0
- package/dist/session-topic-map.d.ts.map +1 -0
- package/dist/session-topic-map.js +77 -0
- package/dist/spawn-context.d.ts +54 -0
- package/dist/spawn-context.d.ts.map +1 -0
- package/dist/spawn-context.js +159 -0
- package/dist/system-store.d.ts +1 -1
- package/dist/system-store.js +1 -1
- package/dist/temporal-store.d.ts +80 -0
- package/dist/temporal-store.d.ts.map +1 -0
- package/dist/temporal-store.js +149 -0
- package/dist/topic-detector.d.ts +35 -0
- package/dist/topic-detector.d.ts.map +1 -0
- package/dist/topic-detector.js +249 -0
- package/dist/topic-store.d.ts +1 -1
- package/dist/topic-store.js +1 -1
- package/dist/topic-synthesizer.d.ts +51 -0
- package/dist/topic-synthesizer.d.ts.map +1 -0
- package/dist/topic-synthesizer.js +315 -0
- package/dist/trigger-registry.d.ts +63 -0
- package/dist/trigger-registry.d.ts.map +1 -0
- package/dist/trigger-registry.js +163 -0
- package/dist/types.d.ts +214 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/vector-store.d.ts +43 -5
- package/dist/vector-store.d.ts.map +1 -1
- package/dist/vector-store.js +189 -10
- package/dist/version.d.ts +34 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +34 -0
- package/dist/wiki-page-emitter.d.ts +65 -0
- package/dist/wiki-page-emitter.d.ts.map +1 -0
- package/dist/wiki-page-emitter.js +258 -0
- package/dist/work-store.d.ts +1 -1
- package/dist/work-store.js +1 -1
- package/package.json +15 -5
- package/dist/redis.d.ts +0 -188
- package/dist/redis.d.ts.map +0 -1
- package/dist/redis.js +0 -534
package/dist/library-schema.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* hypermem Library Schema — Fleet-Wide Structured Knowledge
|
|
3
3
|
*
|
|
4
4
|
* Single database: ~/.openclaw/hypermem/library.db
|
|
5
5
|
* The "crown jewel" — durable, backed up, low-write-frequency.
|
|
@@ -17,6 +17,6 @@
|
|
|
17
17
|
* 10. Topics (cross-session thread tracking)
|
|
18
18
|
*/
|
|
19
19
|
import type { DatabaseSync } from 'node:sqlite';
|
|
20
|
-
export declare const LIBRARY_SCHEMA_VERSION =
|
|
21
|
-
export declare function migrateLibrary(db: DatabaseSync): void;
|
|
20
|
+
export declare const LIBRARY_SCHEMA_VERSION = 13;
|
|
21
|
+
export declare function migrateLibrary(db: DatabaseSync, engineVersion?: string): void;
|
|
22
22
|
//# sourceMappingURL=library-schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"library-schema.d.ts","sourceRoot":"","sources":["../src/library-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"library-schema.d.ts","sourceRoot":"","sources":["../src/library-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAs5BzC,wBAAgB,cAAc,CAAC,EAAE,EAAE,YAAY,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CA8L7E"}
|
package/dist/library-schema.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* hypermem Library Schema — Fleet-Wide Structured Knowledge
|
|
3
3
|
*
|
|
4
4
|
* Single database: ~/.openclaw/hypermem/library.db
|
|
5
5
|
* The "crown jewel" — durable, backed up, low-write-frequency.
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* 9. Work items (fleet kanban)
|
|
17
17
|
* 10. Topics (cross-session thread tracking)
|
|
18
18
|
*/
|
|
19
|
-
export const LIBRARY_SCHEMA_VERSION =
|
|
19
|
+
export const LIBRARY_SCHEMA_VERSION = 13;
|
|
20
20
|
function nowIso() {
|
|
21
21
|
return new Date().toISOString();
|
|
22
22
|
}
|
|
@@ -662,8 +662,211 @@ function applyV7KnowledgeVersioning(db) {
|
|
|
662
662
|
END
|
|
663
663
|
`);
|
|
664
664
|
}
|
|
665
|
+
// ── V9: Add session_key to doc_chunks ───────────────────────
|
|
666
|
+
// Enables ephemeral session-scoped doc chunks for subagent context inheritance.
|
|
667
|
+
// Chunks stored with a session_key are transient — clearSessionChunks() removes them.
|
|
668
|
+
function applyV9DocChunkSessionKey(db) {
|
|
669
|
+
const cols = db.prepare('PRAGMA table_info(doc_chunks)').all()
|
|
670
|
+
.map(r => r.name);
|
|
671
|
+
if (!cols.includes('session_key')) {
|
|
672
|
+
db.exec('ALTER TABLE doc_chunks ADD COLUMN session_key TEXT');
|
|
673
|
+
}
|
|
674
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_doc_chunks_session ON doc_chunks(session_key) WHERE session_key IS NOT NULL');
|
|
675
|
+
}
|
|
676
|
+
// ── V8: Add source_message_id to episodes ───────────────────
|
|
677
|
+
function applyV8EpisodeSourceMessageId(db) {
|
|
678
|
+
// ALTER TABLE ADD COLUMN is safe — existing rows get NULL for new column
|
|
679
|
+
const cols = db.prepare('PRAGMA table_info(episodes)').all()
|
|
680
|
+
.map(r => r.name);
|
|
681
|
+
if (!cols.includes('source_message_id')) {
|
|
682
|
+
db.exec('ALTER TABLE episodes ADD COLUMN source_message_id INTEGER');
|
|
683
|
+
}
|
|
684
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_episodes_source_msg ON episodes(agent_id, source_message_id)');
|
|
685
|
+
}
|
|
686
|
+
// ── V12: FOS / MOD tables + builtin seed data ──────────────
|
|
687
|
+
function applyV12FosMod(db) {
|
|
688
|
+
// fleet_output_standard: fleet-wide output formatting standards
|
|
689
|
+
db.exec(`
|
|
690
|
+
CREATE TABLE IF NOT EXISTS fleet_output_standard (
|
|
691
|
+
id TEXT PRIMARY KEY,
|
|
692
|
+
name TEXT NOT NULL,
|
|
693
|
+
directives TEXT NOT NULL,
|
|
694
|
+
task_variants TEXT DEFAULT '{}',
|
|
695
|
+
token_budget INTEGER DEFAULT 250,
|
|
696
|
+
active INTEGER DEFAULT 0,
|
|
697
|
+
source TEXT DEFAULT 'builtin',
|
|
698
|
+
version INTEGER DEFAULT 1,
|
|
699
|
+
last_validated_at TEXT,
|
|
700
|
+
created_at TEXT NOT NULL,
|
|
701
|
+
updated_at TEXT NOT NULL
|
|
702
|
+
)
|
|
703
|
+
`);
|
|
704
|
+
// model_output_directives: per-model corrections and calibration
|
|
705
|
+
db.exec(`
|
|
706
|
+
CREATE TABLE IF NOT EXISTS model_output_directives (
|
|
707
|
+
id TEXT PRIMARY KEY,
|
|
708
|
+
match_pattern TEXT NOT NULL,
|
|
709
|
+
priority INTEGER DEFAULT 0,
|
|
710
|
+
corrections TEXT NOT NULL,
|
|
711
|
+
calibration TEXT NOT NULL,
|
|
712
|
+
task_overrides TEXT DEFAULT '{}',
|
|
713
|
+
token_budget INTEGER DEFAULT 150,
|
|
714
|
+
version INTEGER DEFAULT 1,
|
|
715
|
+
source TEXT DEFAULT 'builtin',
|
|
716
|
+
enabled INTEGER DEFAULT 1,
|
|
717
|
+
last_validated_at TEXT,
|
|
718
|
+
created_at TEXT NOT NULL,
|
|
719
|
+
updated_at TEXT NOT NULL
|
|
720
|
+
)
|
|
721
|
+
`);
|
|
722
|
+
// output_metrics: per-request telemetry for drift analytics
|
|
723
|
+
db.exec(`
|
|
724
|
+
CREATE TABLE IF NOT EXISTS output_metrics (
|
|
725
|
+
id TEXT PRIMARY KEY,
|
|
726
|
+
timestamp TEXT NOT NULL,
|
|
727
|
+
agent_id TEXT NOT NULL,
|
|
728
|
+
session_key TEXT NOT NULL,
|
|
729
|
+
model_id TEXT NOT NULL,
|
|
730
|
+
provider TEXT NOT NULL,
|
|
731
|
+
fos_version INTEGER,
|
|
732
|
+
mod_version INTEGER,
|
|
733
|
+
mod_id TEXT,
|
|
734
|
+
task_type TEXT,
|
|
735
|
+
output_tokens INTEGER NOT NULL,
|
|
736
|
+
input_tokens INTEGER,
|
|
737
|
+
cache_read_tokens INTEGER,
|
|
738
|
+
corrections_fired TEXT DEFAULT '[]',
|
|
739
|
+
latency_ms INTEGER,
|
|
740
|
+
created_at TEXT NOT NULL
|
|
741
|
+
)
|
|
742
|
+
`);
|
|
743
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_output_metrics_model ON output_metrics(model_id, timestamp)');
|
|
744
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_output_metrics_agent ON output_metrics(agent_id, timestamp)');
|
|
745
|
+
// ── Seed builtin FOS profile ──
|
|
746
|
+
const now = nowIso();
|
|
747
|
+
const fosDirectives = JSON.stringify({
|
|
748
|
+
structural: [
|
|
749
|
+
'Lead with the answer. Conclusion first, reasoning after.',
|
|
750
|
+
'Headers earn their place. Under 200 words: no headers.',
|
|
751
|
+
'Lists cap at 7 items. Technical enumerations exempt.',
|
|
752
|
+
'One metaphor lands. Two is the limit.',
|
|
753
|
+
],
|
|
754
|
+
anti_patterns: [
|
|
755
|
+
'No sycophantic openings: Great question, Certainly, Absolutely, Of course',
|
|
756
|
+
'No em dashes',
|
|
757
|
+
'No preamble restating the question',
|
|
758
|
+
'No: Let me know if you need anything else',
|
|
759
|
+
'No AI vocabulary: delve, tapestry, pivotal, fostering, garner, underscore, vibrant, leverage, noteworthy, realm',
|
|
760
|
+
'No unverifiable references — don\'t cite "you mentioned earlier" or "as discussed" without a direct quote',
|
|
761
|
+
'No claiming actions completed without tool results to back them up',
|
|
762
|
+
'No attributing statements to people without quoting the actual message',
|
|
763
|
+
],
|
|
764
|
+
density_targets: {
|
|
765
|
+
simple: '1-3 sentences',
|
|
766
|
+
analysis: '200-500 words',
|
|
767
|
+
code: 'code first, explain only non-obvious parts',
|
|
768
|
+
},
|
|
769
|
+
voice: [
|
|
770
|
+
'Every sentence states a fact, makes a decision, or advances an argument',
|
|
771
|
+
'Numbers over adjectives',
|
|
772
|
+
'Vary sentence length deliberately',
|
|
773
|
+
'Match confidence to evidence: facts zero hedges, inference one hedge max',
|
|
774
|
+
],
|
|
775
|
+
});
|
|
776
|
+
const fosVariants = JSON.stringify({
|
|
777
|
+
'council-deliberation': {
|
|
778
|
+
density_target: '400-800 words. Depth over brevity.',
|
|
779
|
+
structure: 'Headers required. Position statement, risk assessment, confidence, action.',
|
|
780
|
+
},
|
|
781
|
+
'code-generation': {
|
|
782
|
+
density_target: 'Minimize prose. Code is the deliverable.',
|
|
783
|
+
list_cap: 'DISABLED',
|
|
784
|
+
},
|
|
785
|
+
'quick-answer': {
|
|
786
|
+
density_target: '1-3 sentences.',
|
|
787
|
+
structure: 'No headers. No lists unless the answer is genuinely a list.',
|
|
788
|
+
},
|
|
789
|
+
});
|
|
790
|
+
const existingFos = db.prepare("SELECT id FROM fleet_output_standard WHERE id = 'psiclawops-default'").get();
|
|
791
|
+
if (!existingFos) {
|
|
792
|
+
db.prepare(`
|
|
793
|
+
INSERT INTO fleet_output_standard (id, name, directives, task_variants, token_budget, active, source, version, created_at, updated_at)
|
|
794
|
+
VALUES ('psiclawops-default', 'PsiClawOps Default', ?, ?, 250, 1, 'builtin', 1, ?, ?)
|
|
795
|
+
`).run(fosDirectives, fosVariants, now, now);
|
|
796
|
+
}
|
|
797
|
+
// ── Seed builtin MOD profiles ──
|
|
798
|
+
const mods = [
|
|
799
|
+
{
|
|
800
|
+
id: 'gpt-5.4',
|
|
801
|
+
match_pattern: 'gpt-5.4*',
|
|
802
|
+
priority: 10,
|
|
803
|
+
corrections: JSON.stringify([
|
|
804
|
+
{ id: 'plan-loop', rule: 'If 2+ responses without concrete output, execute immediately. Ship partial.', severity: 'hard' },
|
|
805
|
+
{ id: 'first-person-opening', rule: 'Do not open with I.', severity: 'medium' },
|
|
806
|
+
{ id: 'throat-clearing', rule: 'No preamble before the answer.', severity: 'medium' },
|
|
807
|
+
{ id: 'conditional-hedging', rule: 'Decision questions: answer + 1-2 reasons. No if-X-then-Y branching.', severity: 'medium' },
|
|
808
|
+
]),
|
|
809
|
+
calibration: JSON.stringify([
|
|
810
|
+
{ id: 'verbosity-offset', fos_target: 'analysis: 200-500 words', model_tendency: '~600 words vs Opus baseline', adjustment: 'Actively compress. Your natural output is ~2x the target. Cut first drafts in half.' },
|
|
811
|
+
{ id: 'list-length-offset', fos_target: '7 items max', model_tendency: 'defaults to 12-15 items', adjustment: 'After drafting a list, cut the bottom half.' },
|
|
812
|
+
]),
|
|
813
|
+
},
|
|
814
|
+
{
|
|
815
|
+
id: 'claude-opus-4.6',
|
|
816
|
+
match_pattern: 'claude-opus-4*',
|
|
817
|
+
priority: 10,
|
|
818
|
+
corrections: JSON.stringify([
|
|
819
|
+
{ id: 'over-structuring', rule: 'Resist adding headers and sections to short answers.', severity: 'medium' },
|
|
820
|
+
{ id: 'premature-enumeration', rule: "Don't list when prose works. Lists require 3+ genuinely distinct items.", severity: 'medium' },
|
|
821
|
+
]),
|
|
822
|
+
calibration: JSON.stringify([
|
|
823
|
+
{ id: 'verbosity-offset', fos_target: 'analysis: 200-500 words', model_tendency: '1.1x target', adjustment: 'Near target. Minor compression on detailed analysis.' },
|
|
824
|
+
]),
|
|
825
|
+
},
|
|
826
|
+
{
|
|
827
|
+
id: 'claude-sonnet-4.6',
|
|
828
|
+
match_pattern: 'claude-sonnet-4*',
|
|
829
|
+
priority: 10,
|
|
830
|
+
corrections: JSON.stringify([
|
|
831
|
+
{ id: 'caveat-frontloading', rule: "Don't open with caveats. State the answer, then caveats if needed.", severity: 'medium' },
|
|
832
|
+
{ id: 'safety-hedging', rule: 'Minimize safety qualifiers on unambiguous requests.', severity: 'medium' },
|
|
833
|
+
]),
|
|
834
|
+
calibration: JSON.stringify([
|
|
835
|
+
{ id: 'verbosity-offset', fos_target: 'analysis: 200-500 words', model_tendency: '1.3x target', adjustment: 'Compress by ~25%. Cut qualifications and restatements.' },
|
|
836
|
+
]),
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
id: 'gemini-3.1',
|
|
840
|
+
match_pattern: 'gemini-3.1*',
|
|
841
|
+
priority: 10,
|
|
842
|
+
corrections: JSON.stringify([
|
|
843
|
+
{ id: 'numbered-list-default', rule: "Don't default to numbered lists. Use prose unless order matters.", severity: 'hard' },
|
|
844
|
+
{ id: 'source-attribution-noise', rule: 'Skip attribution boilerplate unless sourcing is specifically requested.', severity: 'medium' },
|
|
845
|
+
]),
|
|
846
|
+
calibration: JSON.stringify([
|
|
847
|
+
{ id: 'list-length-offset', fos_target: '7 items max', model_tendency: '1.5x target', adjustment: 'Cut lists to 7 items. Merge or drop the rest.' },
|
|
848
|
+
]),
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
id: 'default',
|
|
852
|
+
match_pattern: '*',
|
|
853
|
+
priority: 0,
|
|
854
|
+
corrections: JSON.stringify([]),
|
|
855
|
+
calibration: JSON.stringify([]),
|
|
856
|
+
},
|
|
857
|
+
];
|
|
858
|
+
for (const mod of mods) {
|
|
859
|
+
const existing = db.prepare('SELECT id FROM model_output_directives WHERE id = ?').get(mod.id);
|
|
860
|
+
if (!existing) {
|
|
861
|
+
db.prepare(`
|
|
862
|
+
INSERT INTO model_output_directives (id, match_pattern, priority, corrections, calibration, task_overrides, token_budget, version, source, enabled, created_at, updated_at)
|
|
863
|
+
VALUES (?, ?, ?, ?, ?, '{}', 150, 1, 'builtin', 1, ?, ?)
|
|
864
|
+
`).run(mod.id, mod.match_pattern, mod.priority, mod.corrections, mod.calibration, now, now);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
665
868
|
// ── Migration runner ──────────────────────────────────────────
|
|
666
|
-
export function migrateLibrary(db) {
|
|
869
|
+
export function migrateLibrary(db, engineVersion) {
|
|
667
870
|
db.exec(`
|
|
668
871
|
CREATE TABLE IF NOT EXISTS schema_version (
|
|
669
872
|
version INTEGER PRIMARY KEY,
|
|
@@ -713,5 +916,123 @@ export function migrateLibrary(db) {
|
|
|
713
916
|
db.prepare('INSERT INTO schema_version (version, applied_at) VALUES (?, ?)')
|
|
714
917
|
.run(7, nowIso());
|
|
715
918
|
}
|
|
919
|
+
if (currentVersion < 8) {
|
|
920
|
+
applyV8EpisodeSourceMessageId(db);
|
|
921
|
+
db.prepare('INSERT INTO schema_version (version, applied_at) VALUES (?, ?)')
|
|
922
|
+
.run(8, nowIso());
|
|
923
|
+
}
|
|
924
|
+
if (currentVersion < 9) {
|
|
925
|
+
applyV9DocChunkSessionKey(db);
|
|
926
|
+
db.prepare('INSERT INTO schema_version (version, applied_at) VALUES (?, ?)')
|
|
927
|
+
.run(9, nowIso());
|
|
928
|
+
}
|
|
929
|
+
if (currentVersion < 10) {
|
|
930
|
+
db.exec(`
|
|
931
|
+
CREATE TABLE IF NOT EXISTS meta (
|
|
932
|
+
key TEXT PRIMARY KEY,
|
|
933
|
+
value TEXT NOT NULL,
|
|
934
|
+
updated_at TEXT NOT NULL
|
|
935
|
+
)
|
|
936
|
+
`);
|
|
937
|
+
db.prepare('INSERT INTO schema_version (version, applied_at) VALUES (?, ?)')
|
|
938
|
+
.run(10, nowIso());
|
|
939
|
+
}
|
|
940
|
+
// ── V11: Topics FTS + indexer watermarks ──────────────────
|
|
941
|
+
// topics_fts was missing from V3 (topics table was created without FTS).
|
|
942
|
+
// indexer_watermarks tracks per-agent indexer progress for resumable indexing.
|
|
943
|
+
if (currentVersion < 11) {
|
|
944
|
+
db.exec(`
|
|
945
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS topics_fts USING fts5(
|
|
946
|
+
name,
|
|
947
|
+
description,
|
|
948
|
+
content='topics',
|
|
949
|
+
content_rowid='id'
|
|
950
|
+
)
|
|
951
|
+
`);
|
|
952
|
+
db.exec(`
|
|
953
|
+
CREATE TRIGGER IF NOT EXISTS topics_fts_ai AFTER INSERT ON topics BEGIN
|
|
954
|
+
INSERT INTO topics_fts(rowid, name, description) VALUES (new.id, new.name, new.description);
|
|
955
|
+
END
|
|
956
|
+
`);
|
|
957
|
+
db.exec(`
|
|
958
|
+
CREATE TRIGGER IF NOT EXISTS topics_fts_ad AFTER DELETE ON topics BEGIN
|
|
959
|
+
INSERT INTO topics_fts(topics_fts, rowid, name, description) VALUES('delete', old.id, old.name, old.description);
|
|
960
|
+
END
|
|
961
|
+
`);
|
|
962
|
+
db.exec(`
|
|
963
|
+
CREATE TRIGGER IF NOT EXISTS topics_fts_au AFTER UPDATE ON topics BEGIN
|
|
964
|
+
INSERT INTO topics_fts(topics_fts, rowid, name, description) VALUES('delete', old.id, old.name, old.description);
|
|
965
|
+
INSERT INTO topics_fts(rowid, name, description) VALUES (new.id, new.name, new.description);
|
|
966
|
+
END
|
|
967
|
+
`);
|
|
968
|
+
db.exec(`
|
|
969
|
+
CREATE TABLE IF NOT EXISTS indexer_watermarks (
|
|
970
|
+
agent_id TEXT PRIMARY KEY,
|
|
971
|
+
last_message_id INTEGER NOT NULL DEFAULT 0,
|
|
972
|
+
last_run_at TEXT NOT NULL
|
|
973
|
+
)
|
|
974
|
+
`);
|
|
975
|
+
db.prepare('INSERT INTO schema_version (version, applied_at) VALUES (?, ?)')
|
|
976
|
+
.run(11, nowIso());
|
|
977
|
+
}
|
|
978
|
+
// ── V12: FOS/MOD tables + builtin seed data ──────────────
|
|
979
|
+
// fleet_output_standard: fleet-wide output standards
|
|
980
|
+
// model_output_directives: per-model correction & calibration profiles
|
|
981
|
+
// output_metrics: per-request telemetry for drift analytics
|
|
982
|
+
if (currentVersion < 12) {
|
|
983
|
+
applyV12FosMod(db);
|
|
984
|
+
db.prepare('INSERT INTO schema_version (version, applied_at) VALUES (?, ?)')
|
|
985
|
+
.run(12, nowIso());
|
|
986
|
+
}
|
|
987
|
+
// ── V13: Temporal index ──────────────────────────────────────────────────
|
|
988
|
+
// Maps fact_id → occurred_at (unix ms). Initially backfilled from created_at
|
|
989
|
+
// (ingest time as proxy). Enables time-range retrieval for LoCoMo temporal
|
|
990
|
+
// questions without vector similarity.
|
|
991
|
+
if (currentVersion < 13) {
|
|
992
|
+
db.exec(`
|
|
993
|
+
CREATE TABLE IF NOT EXISTS temporal_index (
|
|
994
|
+
fact_id INTEGER PRIMARY KEY REFERENCES facts(id) ON DELETE CASCADE,
|
|
995
|
+
agent_id TEXT NOT NULL,
|
|
996
|
+
occurred_at INTEGER NOT NULL,
|
|
997
|
+
ingest_at INTEGER NOT NULL,
|
|
998
|
+
time_ref TEXT,
|
|
999
|
+
confidence REAL NOT NULL DEFAULT 0.5
|
|
1000
|
+
)
|
|
1001
|
+
`);
|
|
1002
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_temporal_agent_time ON temporal_index(agent_id, occurred_at DESC)');
|
|
1003
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_temporal_occurred ON temporal_index(occurred_at DESC)');
|
|
1004
|
+
// Backfill existing facts using created_at as occurred_at proxy
|
|
1005
|
+
db.exec(`
|
|
1006
|
+
INSERT OR IGNORE INTO temporal_index (fact_id, agent_id, occurred_at, ingest_at, confidence)
|
|
1007
|
+
SELECT
|
|
1008
|
+
id,
|
|
1009
|
+
agent_id,
|
|
1010
|
+
CAST((julianday(created_at) - 2440587.5) * 86400000 AS INTEGER),
|
|
1011
|
+
CAST((julianday(created_at) - 2440587.5) * 86400000 AS INTEGER),
|
|
1012
|
+
0.5
|
|
1013
|
+
FROM facts
|
|
1014
|
+
WHERE superseded_by IS NULL
|
|
1015
|
+
`);
|
|
1016
|
+
db.prepare('INSERT INTO schema_version (version, applied_at) VALUES (?, ?)')
|
|
1017
|
+
.run(13, nowIso());
|
|
1018
|
+
}
|
|
1019
|
+
// Always ensure meta exists before stamping the running engine version.
|
|
1020
|
+
// Some legacy/stale DBs reached schema >=10 without the V10 migration having
|
|
1021
|
+
// actually created the table, which would make startup fail with
|
|
1022
|
+
// "no such table: meta" during an otherwise unrelated init path.
|
|
1023
|
+
db.exec(`
|
|
1024
|
+
CREATE TABLE IF NOT EXISTS meta (
|
|
1025
|
+
key TEXT PRIMARY KEY,
|
|
1026
|
+
value TEXT NOT NULL,
|
|
1027
|
+
updated_at TEXT NOT NULL
|
|
1028
|
+
)
|
|
1029
|
+
`);
|
|
1030
|
+
// Always stamp the running engine version so any query can surface it.
|
|
1031
|
+
if (engineVersion) {
|
|
1032
|
+
db.prepare(`
|
|
1033
|
+
INSERT INTO meta (key, value, updated_at) VALUES ('engine_version', ?, ?)
|
|
1034
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at
|
|
1035
|
+
`).run(engineVersion, nowIso());
|
|
1036
|
+
}
|
|
716
1037
|
}
|
|
717
1038
|
//# sourceMappingURL=library-schema.js.map
|
package/dist/message-store.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* hypermem Message Store
|
|
3
3
|
*
|
|
4
4
|
* CRUD operations for conversations and messages in SQLite.
|
|
5
5
|
* All messages are stored in provider-neutral format.
|
|
6
6
|
* This is the write-through layer: Redis → here.
|
|
7
7
|
*/
|
|
8
8
|
import type { DatabaseSync } from 'node:sqlite';
|
|
9
|
-
import type { NeutralMessage, StoredMessage, Conversation, ChannelType, ConversationStatus } from './types.js';
|
|
9
|
+
import type { NeutralMessage, StoredMessage, Conversation, ChannelType, ConversationStatus, RecentTurn } from './types.js';
|
|
10
10
|
export declare class MessageStore {
|
|
11
11
|
private readonly db;
|
|
12
12
|
constructor(db: DatabaseSync);
|
|
@@ -52,6 +52,13 @@ export declare class MessageStore {
|
|
|
52
52
|
* Get recent messages for a conversation.
|
|
53
53
|
*/
|
|
54
54
|
getRecentMessages(conversationId: number, limit?: number): StoredMessage[];
|
|
55
|
+
/**
|
|
56
|
+
* Get recent messages scoped to a topic (P3.4, Option B).
|
|
57
|
+
* Returns messages matching the topic_id OR with topic_id IS NULL
|
|
58
|
+
* (legacy messages created before topic tracking was introduced).
|
|
59
|
+
* This is transition-safe: no legacy messages are silently dropped.
|
|
60
|
+
*/
|
|
61
|
+
getRecentMessagesByTopic(conversationId: number, topicId: string, limit?: number): StoredMessage[];
|
|
55
62
|
/**
|
|
56
63
|
* Get messages across all conversations for an agent (cross-session query).
|
|
57
64
|
*/
|
|
@@ -64,6 +71,12 @@ export declare class MessageStore {
|
|
|
64
71
|
* Full-text search across all messages for an agent.
|
|
65
72
|
*/
|
|
66
73
|
searchMessages(agentId: string, query: string, limit?: number): StoredMessage[];
|
|
74
|
+
/**
|
|
75
|
+
* Get recent turns for a session, in chronological order, with tool calls stripped.
|
|
76
|
+
* Joins messages through conversations to find by session_key.
|
|
77
|
+
* Returns up to `n` turns (capped at 50).
|
|
78
|
+
*/
|
|
79
|
+
getRecentTurns(sessionKey: string, n: number): RecentTurn[];
|
|
67
80
|
/**
|
|
68
81
|
* Get message count for a conversation.
|
|
69
82
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-store.d.ts","sourceRoot":"","sources":["../src/message-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,YAAY,EACZ,WAAW,EACX,kBAAkB,
|
|
1
|
+
{"version":3,"file":"message-store.d.ts","sourceRoot":"","sources":["../src/message-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,UAAU,EACX,MAAM,YAAY,CAAC;AA8CpB,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,YAAY;IAI7C;;OAEG;IACH,uBAAuB,CACrB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE;QACL,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GACA,YAAY;IAgDf;;OAEG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAQxD;;OAEG;IACH,gBAAgB,CACd,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,kBAAkB,CAAC;QAC5B,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GACA,YAAY,EAAE;IAwBjB;;OAEG;IACH,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE;QAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,kBAAkB,CAAC;QAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI;IA2BR;;;OAGG;IACH,aAAa,CACX,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,cAAc,EACvB,IAAI,CAAC,EAAE;QACL,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,GACA,aAAa;IA+DhB;;OAEG;IACH,iBAAiB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,aAAa,EAAE;IAY9E;;;;;OAKG;IACH,wBAAwB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,aAAa,EAAE;IAYtG;;OAEG;IACH,gBAAgB,CACd,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;QACL,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,iBAAiB,CAAC,EAAE,OAAO,CAAC;KAC7B,GACA,aAAa,EAAE;IAuBlB;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,aAAa,EAAE;IAmBnF;;;;OAIG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE;IA+B3D;;OAEG;IACH,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM;IAS/C;;OAEG;IACH,OAAO,CAAC,gBAAgB;CASzB"}
|
package/dist/message-store.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* hypermem Message Store
|
|
3
3
|
*
|
|
4
4
|
* CRUD operations for conversations and messages in SQLite.
|
|
5
5
|
* All messages are stored in provider-neutral format.
|
|
@@ -200,6 +200,22 @@ export class MessageStore {
|
|
|
200
200
|
// Reverse to get chronological order
|
|
201
201
|
return rows.reverse().map(parseMessageRow);
|
|
202
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Get recent messages scoped to a topic (P3.4, Option B).
|
|
205
|
+
* Returns messages matching the topic_id OR with topic_id IS NULL
|
|
206
|
+
* (legacy messages created before topic tracking was introduced).
|
|
207
|
+
* This is transition-safe: no legacy messages are silently dropped.
|
|
208
|
+
*/
|
|
209
|
+
getRecentMessagesByTopic(conversationId, topicId, limit = 50) {
|
|
210
|
+
const rows = this.db.prepare(`
|
|
211
|
+
SELECT * FROM messages
|
|
212
|
+
WHERE conversation_id = ? AND (topic_id = ? OR topic_id IS NULL)
|
|
213
|
+
ORDER BY message_index DESC
|
|
214
|
+
LIMIT ?
|
|
215
|
+
`).all(conversationId, topicId, limit);
|
|
216
|
+
// Reverse to get chronological order
|
|
217
|
+
return rows.reverse().map(parseMessageRow);
|
|
218
|
+
}
|
|
203
219
|
/**
|
|
204
220
|
* Get messages across all conversations for an agent (cross-session query).
|
|
205
221
|
*/
|
|
@@ -241,6 +257,40 @@ export class MessageStore {
|
|
|
241
257
|
`).all(query, limit);
|
|
242
258
|
return rows.map(parseMessageRow);
|
|
243
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* Get recent turns for a session, in chronological order, with tool calls stripped.
|
|
262
|
+
* Joins messages through conversations to find by session_key.
|
|
263
|
+
* Returns up to `n` turns (capped at 50).
|
|
264
|
+
*/
|
|
265
|
+
getRecentTurns(sessionKey, n) {
|
|
266
|
+
const limit = Math.min(n, 50);
|
|
267
|
+
try {
|
|
268
|
+
const rows = this.db.prepare(`
|
|
269
|
+
SELECT m.role, m.text_content, m.created_at, m.message_index
|
|
270
|
+
FROM messages m
|
|
271
|
+
JOIN conversations c ON m.conversation_id = c.id
|
|
272
|
+
WHERE c.session_key = ?
|
|
273
|
+
AND m.role IN ('user', 'assistant')
|
|
274
|
+
ORDER BY m.message_index DESC
|
|
275
|
+
LIMIT ?
|
|
276
|
+
`).all(sessionKey, limit);
|
|
277
|
+
// Reverse to chronological order
|
|
278
|
+
rows.reverse();
|
|
279
|
+
return rows.map(row => ({
|
|
280
|
+
role: row.role,
|
|
281
|
+
// text_content only — tool calls are stored separately and excluded here
|
|
282
|
+
content: row.text_content ?? '',
|
|
283
|
+
timestamp: row.created_at
|
|
284
|
+
? new Date(row.created_at).getTime()
|
|
285
|
+
: Date.now(),
|
|
286
|
+
seq: row.message_index,
|
|
287
|
+
}));
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
console.warn('[hypermem:message-store] getRecentTurns failed:', err.message);
|
|
291
|
+
return [];
|
|
292
|
+
}
|
|
293
|
+
}
|
|
244
294
|
/**
|
|
245
295
|
* Get message count for a conversation.
|
|
246
296
|
*/
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hypermem Metrics Dashboard
|
|
3
|
+
*
|
|
4
|
+
* Provides a unified surface for observing system health:
|
|
5
|
+
* - Memory counts (facts, pages, episodes, vectors)
|
|
6
|
+
* - Composition performance (avg assembly time, budget utilization)
|
|
7
|
+
* - Ingestion stats (indexer throughput, promotion rate)
|
|
8
|
+
* - Embedding stats (cache hit rate, Ollama availability)
|
|
9
|
+
*
|
|
10
|
+
* All queries are read-only and safe to call on hot DBs.
|
|
11
|
+
*/
|
|
12
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
13
|
+
export interface FactMetrics {
|
|
14
|
+
/** Total facts indexed across all agents */
|
|
15
|
+
totalFacts: number;
|
|
16
|
+
/** Facts per agent breakdown */
|
|
17
|
+
byAgent: Record<string, number>;
|
|
18
|
+
/** Facts added in the last 24h */
|
|
19
|
+
recentFacts: number;
|
|
20
|
+
}
|
|
21
|
+
export interface WikiMetrics {
|
|
22
|
+
/** Total synthesized wiki pages (non-superseded) */
|
|
23
|
+
totalPages: number;
|
|
24
|
+
/** Pages per agent */
|
|
25
|
+
byAgent: Record<string, number>;
|
|
26
|
+
/** Pages synthesized in the last 24h */
|
|
27
|
+
recentPages: number;
|
|
28
|
+
/** Oldest page age in hours (staleness indicator) */
|
|
29
|
+
oldestPageAgeHours: number | null;
|
|
30
|
+
}
|
|
31
|
+
export interface EpisodeMetrics {
|
|
32
|
+
/** Total episodes stored */
|
|
33
|
+
totalEpisodes: number;
|
|
34
|
+
/** Episodes per agent */
|
|
35
|
+
byAgent: Record<string, number>;
|
|
36
|
+
/** Average episode significance score (0-1) */
|
|
37
|
+
avgSignificance: number | null;
|
|
38
|
+
}
|
|
39
|
+
export interface VectorMetrics {
|
|
40
|
+
/** Total vectors indexed */
|
|
41
|
+
totalVectors: number;
|
|
42
|
+
/** Breakdown by source table */
|
|
43
|
+
byTable: Record<string, number>;
|
|
44
|
+
/** Embedding cache hit rate (0-1) for this process lifetime */
|
|
45
|
+
cacheHitRate: number | null;
|
|
46
|
+
}
|
|
47
|
+
export interface CompositionMetrics {
|
|
48
|
+
/** Average assembly time in ms (from output_metrics table) */
|
|
49
|
+
avgAssemblyMs: number | null;
|
|
50
|
+
/** p95 assembly time in ms */
|
|
51
|
+
p95AssemblyMs: number | null;
|
|
52
|
+
/** Average output tokens per turn */
|
|
53
|
+
avgOutputTokens: number | null;
|
|
54
|
+
/** Average input tokens per turn (context size) */
|
|
55
|
+
avgInputTokens: number | null;
|
|
56
|
+
/** Number of turns recorded */
|
|
57
|
+
totalTurns: number;
|
|
58
|
+
/** Average cache read tokens (Anthropic prompt cache utilization) */
|
|
59
|
+
avgCacheReadTokens: number | null;
|
|
60
|
+
}
|
|
61
|
+
export interface IngestionMetrics {
|
|
62
|
+
/** Total messages processed by the background indexer */
|
|
63
|
+
totalMessagesIndexed: number;
|
|
64
|
+
/** Total facts extracted */
|
|
65
|
+
totalFactsExtracted: number;
|
|
66
|
+
/** Noise rejection rate (1 - facts/messages, approximate) */
|
|
67
|
+
noiseRejectionRate: number | null;
|
|
68
|
+
/** Total episodes created */
|
|
69
|
+
totalEpisodesCreated: number;
|
|
70
|
+
/** Total knowledge items promoted by dreaming promoter */
|
|
71
|
+
totalKnowledgePromoted: number;
|
|
72
|
+
}
|
|
73
|
+
export interface SystemHealth {
|
|
74
|
+
/** Whether the main DB is readable */
|
|
75
|
+
mainDbOk: boolean;
|
|
76
|
+
/** Whether the library DB is readable */
|
|
77
|
+
libraryDbOk: boolean;
|
|
78
|
+
/** Main DB schema version */
|
|
79
|
+
mainSchemaVersion: number | null;
|
|
80
|
+
/** Library DB schema version */
|
|
81
|
+
librarySchemaVersion: number | null;
|
|
82
|
+
/** hypermem package version */
|
|
83
|
+
packageVersion: string;
|
|
84
|
+
/** Cache connection status (if provided) */
|
|
85
|
+
cacheOk: boolean | null;
|
|
86
|
+
/** Timestamp of this snapshot */
|
|
87
|
+
snapshotAt: string;
|
|
88
|
+
}
|
|
89
|
+
export interface HyperMemMetrics {
|
|
90
|
+
facts: FactMetrics;
|
|
91
|
+
wiki: WikiMetrics;
|
|
92
|
+
episodes: EpisodeMetrics;
|
|
93
|
+
vectors: VectorMetrics;
|
|
94
|
+
composition: CompositionMetrics;
|
|
95
|
+
ingestion: IngestionMetrics;
|
|
96
|
+
health: SystemHealth;
|
|
97
|
+
}
|
|
98
|
+
export interface MetricsDashboardOptions {
|
|
99
|
+
/** Agent IDs to scope to. If omitted, returns fleet-wide metrics. */
|
|
100
|
+
agentIds?: string[];
|
|
101
|
+
/** Include per-agent breakdowns. Default: true */
|
|
102
|
+
includeBreakdowns?: boolean;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Collect all metrics in a single pass.
|
|
106
|
+
* Safe to call on live DBs — all queries are read-only.
|
|
107
|
+
*/
|
|
108
|
+
export declare function collectMetrics(mainDb: DatabaseSync, libraryDb: DatabaseSync, opts?: MetricsDashboardOptions): Promise<HyperMemMetrics>;
|
|
109
|
+
/**
|
|
110
|
+
* Format metrics as a human-readable summary string.
|
|
111
|
+
* Suitable for logging or status replies.
|
|
112
|
+
*/
|
|
113
|
+
export declare function formatMetricsSummary(m: HyperMemMetrics): string;
|
|
114
|
+
//# sourceMappingURL=metrics-dashboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics-dashboard.d.ts","sourceRoot":"","sources":["../src/metrics-dashboard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,aAAa,CAAC;AAE/D,MAAM,WAAW,WAAW;IAC1B,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,+CAA+C;IAC/C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,+DAA+D;IAC/D,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,8BAA8B;IAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qCAAqC;IACrC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,mDAAmD;IACnD,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,oBAAoB,EAAE,MAAM,CAAC;IAC7B,4BAA4B;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,6DAA6D;IAC7D,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,6BAA6B;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,0DAA0D;IAC1D,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,yCAAyC;IACzC,WAAW,EAAE,OAAO,CAAC;IACrB,6BAA6B;IAC7B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gCAAgC;IAChC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,+BAA+B;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB,WAAW,EAAE,kBAAkB,CAAC;IAChC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,kDAAkD;IAClD,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AA2TD;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,YAAY,EACvB,IAAI,GAAE,uBAA4B,GACjC,OAAO,CAAC,eAAe,CAAC,CAU1B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CA6C/D"}
|