memorix 1.2.0 → 1.2.2
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/CHANGELOG.md +30 -1
- package/README.md +18 -4
- package/README.zh-CN.md +18 -4
- package/TEAM.md +86 -86
- package/dist/cli/index.js +15919 -14055
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +1997 -1021
- package/dist/index.js.map +1 -1
- package/dist/maintenance-runner.d.ts +1 -1
- package/dist/maintenance-runner.js +8481 -8005
- package/dist/maintenance-runner.js.map +1 -1
- package/dist/memcode-runtime/CHANGELOG.md +30 -1
- package/dist/sdk.d.ts +7 -2
- package/dist/sdk.js +2022 -1024
- package/dist/sdk.js.map +1 -1
- package/dist/types.d.ts +49 -1
- package/dist/types.js.map +1 -1
- package/docs/1.2.2-MEMORY-CONTROL-PLANE.md +434 -0
- package/docs/AGENT_OPERATOR_PLAYBOOK.md +4 -0
- package/docs/API_REFERENCE.md +27 -5
- package/docs/DESIGN_DECISIONS.md +357 -357
- package/docs/DEVELOPMENT.md +4 -0
- package/docs/README.md +1 -1
- package/docs/SETUP.md +7 -1
- package/docs/dev-log/progress.txt +91 -11
- package/docs/knowledge/workflows/memorix-release.md +57 -0
- package/package.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/src/audit/index.ts +156 -156
- package/src/cli/command-guide.ts +192 -0
- package/src/cli/commands/audit-list.ts +89 -89
- package/src/cli/commands/audit.ts +9 -4
- package/src/cli/commands/background.ts +659 -659
- package/src/cli/commands/cleanup.ts +5 -1
- package/src/cli/commands/codegraph.ts +17 -8
- package/src/cli/commands/context.ts +3 -2
- package/src/cli/commands/doctor.ts +4 -2
- package/src/cli/commands/explain.ts +9 -3
- package/src/cli/commands/formation.ts +48 -48
- package/src/cli/commands/git-hook-install.ts +111 -111
- package/src/cli/commands/handoff.ts +75 -61
- package/src/cli/commands/hooks-status.ts +63 -63
- package/src/cli/commands/identity.ts +116 -0
- package/src/cli/commands/ingest-commit.ts +153 -153
- package/src/cli/commands/ingest-image.ts +71 -69
- package/src/cli/commands/ingest-log.ts +180 -180
- package/src/cli/commands/ingest.ts +44 -44
- package/src/cli/commands/integrate-shared.ts +15 -15
- package/src/cli/commands/knowledge.ts +40 -0
- package/src/cli/commands/lock.ts +93 -92
- package/src/cli/commands/memory.ts +58 -21
- package/src/cli/commands/message.ts +123 -118
- package/src/cli/commands/operator-shared.ts +98 -3
- package/src/cli/commands/poll.ts +74 -64
- package/src/cli/commands/purge-all-memory.ts +85 -85
- package/src/cli/commands/purge-project-memory.ts +83 -83
- package/src/cli/commands/reasoning.ts +135 -121
- package/src/cli/commands/retention.ts +9 -4
- package/src/cli/commands/serve-http.ts +22 -43
- package/src/cli/commands/serve-shared.ts +118 -118
- package/src/cli/commands/session.ts +29 -3
- package/src/cli/commands/setup.ts +9 -3
- package/src/cli/commands/skills.ts +124 -119
- package/src/cli/commands/status.ts +4 -3
- package/src/cli/commands/task.ts +193 -184
- package/src/cli/commands/team.ts +14 -10
- package/src/cli/commands/transfer.ts +108 -55
- package/src/cli/commands/uninstall-project-artifacts.ts +85 -85
- package/src/cli/identity.ts +89 -0
- package/src/cli/index.ts +96 -19
- package/src/cli/invocation.ts +115 -0
- package/src/cli/tui/ChatView.tsx +234 -234
- package/src/cli/tui/CommandBar.tsx +312 -312
- package/src/cli/tui/ContextRail.tsx +118 -118
- package/src/cli/tui/HeaderBar.tsx +72 -72
- package/src/cli/tui/LogoBanner.tsx +51 -51
- package/src/cli/tui/Sidebar.tsx +179 -179
- package/src/cli/tui/chat-service.ts +41 -18
- package/src/cli/tui/data.ts +23 -44
- package/src/cli/tui/index.ts +41 -41
- package/src/cli/tui/markdown-render.tsx +371 -371
- package/src/cli/tui/operator-context.ts +60 -0
- package/src/cli/tui/use-mouse.ts +157 -157
- package/src/cli/tui/useNavigation.ts +56 -56
- package/src/cli/tui/views/MemoryView.tsx +10 -8
- package/src/cli/update-checker.ts +211 -211
- package/src/cli/version.ts +7 -7
- package/src/cli/workbench.ts +1 -1
- package/src/codegraph/auto-context.ts +34 -17
- package/src/codegraph/context-pack.ts +1 -0
- package/src/codegraph/current-facts.ts +19 -1
- package/src/codegraph/project-context.ts +2 -0
- package/src/codegraph/task-lens.ts +49 -5
- package/src/compact/engine.ts +26 -10
- package/src/compact/index-format.ts +25 -2
- package/src/compact/token-budget.ts +74 -74
- package/src/dashboard/project-classification.ts +64 -64
- package/src/dashboard/server.ts +58 -52
- package/src/embedding/fastembed-provider.ts +142 -142
- package/src/embedding/transformers-provider.ts +111 -111
- package/src/git/extractor.ts +209 -209
- package/src/git/hooks-path.ts +85 -85
- package/src/hooks/admission.ts +117 -0
- package/src/hooks/handler.ts +98 -91
- package/src/hooks/pattern-detector.ts +173 -173
- package/src/hooks/significance-filter.ts +250 -250
- package/src/knowledge/claims.ts +51 -1
- package/src/knowledge/context-assembly.ts +97 -0
- package/src/knowledge/types.ts +1 -0
- package/src/knowledge/workflows.ts +34 -3
- package/src/knowledge/workset.ts +179 -10
- package/src/llm/memory-manager.ts +328 -328
- package/src/llm/provider.ts +885 -885
- package/src/llm/quality.ts +248 -248
- package/src/memory/admission.ts +57 -0
- package/src/memory/attribution-guard.ts +249 -249
- package/src/memory/auto-relations.ts +21 -0
- package/src/memory/consolidation.ts +13 -2
- package/src/memory/disclosure-policy.ts +140 -135
- package/src/memory/entity-extractor.ts +197 -197
- package/src/memory/export-import.ts +11 -3
- package/src/memory/formation/evaluate.ts +217 -217
- package/src/memory/formation/extract.ts +361 -361
- package/src/memory/formation/index.ts +417 -417
- package/src/memory/formation/resolve.ts +344 -344
- package/src/memory/formation/types.ts +315 -315
- package/src/memory/freshness.ts +122 -122
- package/src/memory/graph-context.ts +8 -2
- package/src/memory/graph-scope.ts +46 -0
- package/src/memory/graph.ts +197 -197
- package/src/memory/observations.ts +162 -4
- package/src/memory/quality-audit.ts +2 -0
- package/src/memory/refs.ts +94 -94
- package/src/memory/retention.ts +22 -2
- package/src/memory/secret-filter.ts +79 -79
- package/src/memory/session.ts +5 -2
- package/src/memory/visibility.ts +80 -0
- package/src/multimodal/image-loader.ts +143 -143
- package/src/orchestrate/adapters/claude-stream.ts +192 -192
- package/src/orchestrate/adapters/claude.ts +111 -111
- package/src/orchestrate/adapters/codex-stream.ts +134 -134
- package/src/orchestrate/adapters/codex.ts +41 -41
- package/src/orchestrate/adapters/gemini-stream.ts +166 -166
- package/src/orchestrate/adapters/gemini.ts +42 -42
- package/src/orchestrate/adapters/index.ts +73 -73
- package/src/orchestrate/adapters/opencode-stream.ts +143 -143
- package/src/orchestrate/adapters/opencode.ts +47 -47
- package/src/orchestrate/adapters/spawn-helper.ts +286 -286
- package/src/orchestrate/adapters/types.ts +77 -77
- package/src/orchestrate/capability-router.ts +284 -284
- package/src/orchestrate/context-compact.ts +188 -188
- package/src/orchestrate/cost-tracker.ts +219 -219
- package/src/orchestrate/error-recovery.ts +191 -191
- package/src/orchestrate/evidence.ts +140 -140
- package/src/orchestrate/ledger.ts +110 -110
- package/src/orchestrate/memorix-bridge.ts +378 -340
- package/src/orchestrate/output-budget.ts +80 -80
- package/src/orchestrate/permission.ts +152 -152
- package/src/orchestrate/pipeline-trace.ts +131 -131
- package/src/orchestrate/prompt-builder.ts +155 -155
- package/src/orchestrate/ring-buffer.ts +37 -37
- package/src/orchestrate/task-graph.ts +389 -389
- package/src/orchestrate/verify-gate.ts +33 -10
- package/src/orchestrate/worktree.ts +232 -232
- package/src/project/aliases.ts +374 -374
- package/src/project/detector.ts +268 -268
- package/src/rules/adapters/claude-code.ts +99 -99
- package/src/rules/adapters/codex.ts +97 -97
- package/src/rules/adapters/copilot.ts +124 -124
- package/src/rules/adapters/cursor.ts +114 -114
- package/src/rules/adapters/kiro.ts +126 -126
- package/src/rules/adapters/trae.ts +56 -56
- package/src/rules/adapters/windsurf.ts +83 -83
- package/src/rules/syncer.ts +235 -235
- package/src/runtime/control-plane-maintenance.ts +1 -0
- package/src/runtime/isolated-maintenance.ts +1 -0
- package/src/runtime/lifecycle.ts +18 -0
- package/src/runtime/maintenance-jobs.ts +1 -0
- package/src/runtime/maintenance-runner.ts +2 -0
- package/src/runtime/project-maintenance.ts +89 -0
- package/src/sdk.ts +334 -304
- package/src/search/intent-detector.ts +289 -289
- package/src/search/query-expansion.ts +52 -52
- package/src/server/formation-timeout.ts +27 -27
- package/src/server.ts +334 -93
- package/src/skills/mini-skills.ts +386 -386
- package/src/store/chat-store.ts +119 -119
- package/src/store/graph-store.ts +249 -249
- package/src/store/mini-skill-store.ts +349 -349
- package/src/store/orama-store.ts +61 -6
- package/src/store/persistence-json.ts +212 -212
- package/src/store/persistence.ts +291 -291
- package/src/store/project-affinity.ts +195 -195
- package/src/store/sqlite-db.ts +23 -1
- package/src/store/sqlite-store.ts +12 -2
- package/src/team/event-bus.ts +76 -76
- package/src/team/file-locks.ts +173 -173
- package/src/team/handoff.ts +168 -161
- package/src/team/messages.ts +203 -203
- package/src/team/poll.ts +132 -132
- package/src/team/tasks.ts +211 -211
- package/src/types.ts +51 -0
- package/src/wiki/generator.ts +2 -0
- package/src/workspace/mcp-adapters/codex.ts +191 -191
- package/src/workspace/mcp-adapters/copilot.ts +105 -105
- package/src/workspace/mcp-adapters/cursor.ts +53 -53
- package/src/workspace/mcp-adapters/kiro.ts +64 -64
- package/src/workspace/mcp-adapters/opencode.ts +123 -123
- package/src/workspace/mcp-adapters/trae.ts +134 -134
- package/src/workspace/mcp-adapters/windsurf.ts +91 -91
- package/src/workspace/sanitizer.ts +60 -60
- package/src/workspace/workflow-sync.ts +131 -131
package/src/memory/freshness.ts
CHANGED
|
@@ -1,122 +1,122 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unified Freshness Gate (Phase 3a)
|
|
3
|
-
*
|
|
4
|
-
* Replaces withFreshObservations() as the public API for all retrieval
|
|
5
|
-
* surfaces. Checks both observation and mini-skill generation counters
|
|
6
|
-
* to ensure the Orama index is fully up-to-date before any read.
|
|
7
|
-
*
|
|
8
|
-
* withFreshObservations() remains in observations.ts as @internal —
|
|
9
|
-
* only called by this module and legacy test code.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { ensureFreshObservations } from './observations.js';
|
|
13
|
-
import { getMiniSkillStore, isMiniSkillStoreInitialized } from '../store/mini-skill-store.js';
|
|
14
|
-
import { miniSkillToDocument } from '../skills/mini-skills.js';
|
|
15
|
-
import { insert, remove } from '@orama/orama';
|
|
16
|
-
|
|
17
|
-
// ── Mini-skill index state ──────────────────────────────────────
|
|
18
|
-
|
|
19
|
-
let lastMiniSkillGeneration = -1;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Check if mini-skills have changed since our last index sync.
|
|
23
|
-
* If stale, reindex all mini-skills in Orama.
|
|
24
|
-
*
|
|
25
|
-
* Returns true if the index was refreshed.
|
|
26
|
-
*/
|
|
27
|
-
export async function ensureFreshMiniSkills(): Promise<boolean> {
|
|
28
|
-
// Skip silently when the store has not been initialized yet —
|
|
29
|
-
// observation-only paths never call initMiniSkillStore().
|
|
30
|
-
if (!isMiniSkillStoreInitialized()) return false;
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
const store = getMiniSkillStore();
|
|
34
|
-
const wasStale = await store.ensureFresh();
|
|
35
|
-
const currentGen = store.getGeneration();
|
|
36
|
-
|
|
37
|
-
if (wasStale || currentGen !== lastMiniSkillGeneration) {
|
|
38
|
-
await reindexMiniSkills();
|
|
39
|
-
lastMiniSkillGeneration = currentGen;
|
|
40
|
-
return true;
|
|
41
|
-
}
|
|
42
|
-
} catch (err) {
|
|
43
|
-
// Best-effort — don't crash the read path, but log for diagnostics
|
|
44
|
-
console.warn(`[memorix] ensureFreshMiniSkills failed: ${err instanceof Error ? err.message : err}`);
|
|
45
|
-
}
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Deterministic tracking of indexed mini-skill doc IDs — avoids empty-term search
|
|
50
|
-
const indexedSkillDocIds = new Set<string>();
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Reindex all mini-skills into the Orama database.
|
|
54
|
-
* Uses deterministic doc ID tracking instead of empty-term search to ensure
|
|
55
|
-
* all stale documents are removed reliably.
|
|
56
|
-
*/
|
|
57
|
-
export async function reindexMiniSkills(): Promise<number> {
|
|
58
|
-
// Lazy import to avoid circular dependency
|
|
59
|
-
const { getDb } = await import('../store/orama-store.js');
|
|
60
|
-
const database = await getDb();
|
|
61
|
-
|
|
62
|
-
// Remove previously tracked mini-skill documents by their known IDs
|
|
63
|
-
for (const docId of indexedSkillDocIds) {
|
|
64
|
-
try { await remove(database, docId); } catch { /* already removed or never existed */ }
|
|
65
|
-
}
|
|
66
|
-
indexedSkillDocIds.clear();
|
|
67
|
-
|
|
68
|
-
// Load and index all current mini-skills
|
|
69
|
-
const store = getMiniSkillStore();
|
|
70
|
-
const skills = await store.loadAll();
|
|
71
|
-
let indexed = 0;
|
|
72
|
-
|
|
73
|
-
for (const skill of skills) {
|
|
74
|
-
try {
|
|
75
|
-
const doc = miniSkillToDocument(skill);
|
|
76
|
-
await insert(database, doc);
|
|
77
|
-
indexedSkillDocIds.add(doc.id);
|
|
78
|
-
indexed++;
|
|
79
|
-
} catch (err) {
|
|
80
|
-
console.error(`[memorix] Failed to index mini-skill ${skill.id}: ${err instanceof Error ? err.message : err}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return indexed;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// ── Unified gate ────────────────────────────────────────────────
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Ensure both observations and mini-skills are fresh in the Orama index.
|
|
91
|
-
* Returns true if any data source was refreshed.
|
|
92
|
-
*/
|
|
93
|
-
export async function ensureFreshIndex(): Promise<boolean> {
|
|
94
|
-
let anyStale = false;
|
|
95
|
-
const obsStale = await ensureFreshObservations();
|
|
96
|
-
if (obsStale) anyStale = true;
|
|
97
|
-
const skillsStale = await ensureFreshMiniSkills();
|
|
98
|
-
if (skillsStale) anyStale = true;
|
|
99
|
-
return anyStale;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Centralized freshness gate — wraps a read-facing function with
|
|
104
|
-
* ensureFreshIndex() so callers cannot forget the freshness check.
|
|
105
|
-
*
|
|
106
|
-
* Usage:
|
|
107
|
-
* return withFreshIndex(async () => { ... read from Orama ... });
|
|
108
|
-
*
|
|
109
|
-
* Phase 3a: replaces withFreshObservations() at all retrieval call sites.
|
|
110
|
-
*/
|
|
111
|
-
export async function withFreshIndex<T>(fn: () => T | Promise<T>): Promise<T> {
|
|
112
|
-
await ensureFreshIndex();
|
|
113
|
-
return fn();
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Reset mini-skill freshness tracking. Used in tests.
|
|
118
|
-
*/
|
|
119
|
-
export function resetMiniSkillFreshness(): void {
|
|
120
|
-
lastMiniSkillGeneration = -1;
|
|
121
|
-
indexedSkillDocIds.clear();
|
|
122
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Unified Freshness Gate (Phase 3a)
|
|
3
|
+
*
|
|
4
|
+
* Replaces withFreshObservations() as the public API for all retrieval
|
|
5
|
+
* surfaces. Checks both observation and mini-skill generation counters
|
|
6
|
+
* to ensure the Orama index is fully up-to-date before any read.
|
|
7
|
+
*
|
|
8
|
+
* withFreshObservations() remains in observations.ts as @internal —
|
|
9
|
+
* only called by this module and legacy test code.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { ensureFreshObservations } from './observations.js';
|
|
13
|
+
import { getMiniSkillStore, isMiniSkillStoreInitialized } from '../store/mini-skill-store.js';
|
|
14
|
+
import { miniSkillToDocument } from '../skills/mini-skills.js';
|
|
15
|
+
import { insert, remove } from '@orama/orama';
|
|
16
|
+
|
|
17
|
+
// ── Mini-skill index state ──────────────────────────────────────
|
|
18
|
+
|
|
19
|
+
let lastMiniSkillGeneration = -1;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Check if mini-skills have changed since our last index sync.
|
|
23
|
+
* If stale, reindex all mini-skills in Orama.
|
|
24
|
+
*
|
|
25
|
+
* Returns true if the index was refreshed.
|
|
26
|
+
*/
|
|
27
|
+
export async function ensureFreshMiniSkills(): Promise<boolean> {
|
|
28
|
+
// Skip silently when the store has not been initialized yet —
|
|
29
|
+
// observation-only paths never call initMiniSkillStore().
|
|
30
|
+
if (!isMiniSkillStoreInitialized()) return false;
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const store = getMiniSkillStore();
|
|
34
|
+
const wasStale = await store.ensureFresh();
|
|
35
|
+
const currentGen = store.getGeneration();
|
|
36
|
+
|
|
37
|
+
if (wasStale || currentGen !== lastMiniSkillGeneration) {
|
|
38
|
+
await reindexMiniSkills();
|
|
39
|
+
lastMiniSkillGeneration = currentGen;
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
} catch (err) {
|
|
43
|
+
// Best-effort — don't crash the read path, but log for diagnostics
|
|
44
|
+
console.warn(`[memorix] ensureFreshMiniSkills failed: ${err instanceof Error ? err.message : err}`);
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Deterministic tracking of indexed mini-skill doc IDs — avoids empty-term search
|
|
50
|
+
const indexedSkillDocIds = new Set<string>();
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Reindex all mini-skills into the Orama database.
|
|
54
|
+
* Uses deterministic doc ID tracking instead of empty-term search to ensure
|
|
55
|
+
* all stale documents are removed reliably.
|
|
56
|
+
*/
|
|
57
|
+
export async function reindexMiniSkills(): Promise<number> {
|
|
58
|
+
// Lazy import to avoid circular dependency
|
|
59
|
+
const { getDb } = await import('../store/orama-store.js');
|
|
60
|
+
const database = await getDb();
|
|
61
|
+
|
|
62
|
+
// Remove previously tracked mini-skill documents by their known IDs
|
|
63
|
+
for (const docId of indexedSkillDocIds) {
|
|
64
|
+
try { await remove(database, docId); } catch { /* already removed or never existed */ }
|
|
65
|
+
}
|
|
66
|
+
indexedSkillDocIds.clear();
|
|
67
|
+
|
|
68
|
+
// Load and index all current mini-skills
|
|
69
|
+
const store = getMiniSkillStore();
|
|
70
|
+
const skills = await store.loadAll();
|
|
71
|
+
let indexed = 0;
|
|
72
|
+
|
|
73
|
+
for (const skill of skills) {
|
|
74
|
+
try {
|
|
75
|
+
const doc = miniSkillToDocument(skill);
|
|
76
|
+
await insert(database, doc);
|
|
77
|
+
indexedSkillDocIds.add(doc.id);
|
|
78
|
+
indexed++;
|
|
79
|
+
} catch (err) {
|
|
80
|
+
console.error(`[memorix] Failed to index mini-skill ${skill.id}: ${err instanceof Error ? err.message : err}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return indexed;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ── Unified gate ────────────────────────────────────────────────
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Ensure both observations and mini-skills are fresh in the Orama index.
|
|
91
|
+
* Returns true if any data source was refreshed.
|
|
92
|
+
*/
|
|
93
|
+
export async function ensureFreshIndex(): Promise<boolean> {
|
|
94
|
+
let anyStale = false;
|
|
95
|
+
const obsStale = await ensureFreshObservations();
|
|
96
|
+
if (obsStale) anyStale = true;
|
|
97
|
+
const skillsStale = await ensureFreshMiniSkills();
|
|
98
|
+
if (skillsStale) anyStale = true;
|
|
99
|
+
return anyStale;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Centralized freshness gate — wraps a read-facing function with
|
|
104
|
+
* ensureFreshIndex() so callers cannot forget the freshness check.
|
|
105
|
+
*
|
|
106
|
+
* Usage:
|
|
107
|
+
* return withFreshIndex(async () => { ... read from Orama ... });
|
|
108
|
+
*
|
|
109
|
+
* Phase 3a: replaces withFreshObservations() at all retrieval call sites.
|
|
110
|
+
*/
|
|
111
|
+
export async function withFreshIndex<T>(fn: () => T | Promise<T>): Promise<T> {
|
|
112
|
+
await ensureFreshIndex();
|
|
113
|
+
return fn();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Reset mini-skill freshness tracking. Used in tests.
|
|
118
|
+
*/
|
|
119
|
+
export function resetMiniSkillFreshness(): void {
|
|
120
|
+
lastMiniSkillGeneration = -1;
|
|
121
|
+
indexedSkillDocIds.clear();
|
|
122
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { auditMemoryQuality, type MemoryQualityAuditReport } from './quality-audit.js';
|
|
2
2
|
import type { Observation } from '../types.js';
|
|
3
3
|
import { getRetentionZone } from './retention.js';
|
|
4
|
+
import { isEligibleForAutomaticDelivery } from './admission.js';
|
|
4
5
|
|
|
5
6
|
export interface GraphContextPacketOptions {
|
|
6
7
|
projectId: string;
|
|
@@ -225,6 +226,8 @@ function scoreForPacket(obs: Observation, queryTokens: string[], referenceTime:
|
|
|
225
226
|
source: obs.source ?? 'agent',
|
|
226
227
|
sourceDetail: obs.sourceDetail ?? '',
|
|
227
228
|
valueCategory: obs.valueCategory ?? '',
|
|
229
|
+
admissionState: obs.admissionState ?? '',
|
|
230
|
+
admissionReason: obs.admissionReason ?? '',
|
|
228
231
|
}, referenceTime) !== 'active') {
|
|
229
232
|
score -= 2;
|
|
230
233
|
}
|
|
@@ -348,8 +351,11 @@ export function buildGraphContextPacket(
|
|
|
348
351
|
...audit.issues.orphans.map((entry) => entry.id),
|
|
349
352
|
...audit.issues.retentionCandidates.map((entry) => entry.id),
|
|
350
353
|
]);
|
|
351
|
-
const
|
|
352
|
-
|
|
354
|
+
const deliveryEligible = observations.filter(
|
|
355
|
+
(obs) => obs.projectId === options.projectId && isEligibleForAutomaticDelivery(obs),
|
|
356
|
+
);
|
|
357
|
+
const filteredObservations = deliveryEligible.filter((obs) => !riskIds.has(obs.id));
|
|
358
|
+
const baseObservations = filteredObservations.length > 0 ? filteredObservations : deliveryEligible;
|
|
353
359
|
const memories = pickMemories(baseObservations, options.projectId, options.query, options.limit ?? 5, referenceTime);
|
|
354
360
|
const entities = buildEntities(memories);
|
|
355
361
|
const entityNames = new Set(entities.map((entity) => entity.name));
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface GraphScopeObservation {
|
|
2
|
+
entityName?: string;
|
|
3
|
+
relatedEntities?: string[];
|
|
4
|
+
status?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface ScopedKnowledgeGraph<Entity extends { name: string }, Relation extends { from: string; to: string }> {
|
|
8
|
+
entities: Entity[];
|
|
9
|
+
relations: Relation[];
|
|
10
|
+
entityNames: Set<string>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Return the active project entities, including explicit cross-references. */
|
|
14
|
+
export function projectGraphEntityNames(observations: readonly GraphScopeObservation[]): Set<string> {
|
|
15
|
+
const entityNames = new Set<string>();
|
|
16
|
+
for (const observation of observations) {
|
|
17
|
+
if ((observation.status ?? 'active') !== 'active') continue;
|
|
18
|
+
const entityName = observation.entityName?.trim();
|
|
19
|
+
if (entityName) entityNames.add(entityName);
|
|
20
|
+
for (const relatedEntity of observation.relatedEntities ?? []) {
|
|
21
|
+
const name = relatedEntity.trim();
|
|
22
|
+
if (name) entityNames.add(name);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return entityNames;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Give every graph surface the same project projection: active entities plus
|
|
30
|
+
* explicit related entities, with only edges whose endpoints remain visible.
|
|
31
|
+
*/
|
|
32
|
+
export function scopeKnowledgeGraphToProject<
|
|
33
|
+
Entity extends { name: string },
|
|
34
|
+
Relation extends { from: string; to: string },
|
|
35
|
+
>(
|
|
36
|
+
graph: { entities: readonly Entity[]; relations: readonly Relation[] },
|
|
37
|
+
observations: readonly GraphScopeObservation[],
|
|
38
|
+
): ScopedKnowledgeGraph<Entity, Relation> {
|
|
39
|
+
const entityNames = projectGraphEntityNames(observations);
|
|
40
|
+
const entities = graph.entities.filter(entity => entityNames.has(entity.name));
|
|
41
|
+
const visibleNames = new Set(entities.map(entity => entity.name));
|
|
42
|
+
const relations = graph.relations.filter(relation =>
|
|
43
|
+
visibleNames.has(relation.from) && visibleNames.has(relation.to),
|
|
44
|
+
);
|
|
45
|
+
return { entities, relations, entityNames };
|
|
46
|
+
}
|