@soleri/core 7.0.0 → 8.0.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/agency/agency-manager.d.ts +27 -1
- package/dist/agency/agency-manager.d.ts.map +1 -1
- package/dist/agency/agency-manager.js +180 -9
- package/dist/agency/agency-manager.js.map +1 -1
- package/dist/agency/default-rules.d.ts +7 -0
- package/dist/agency/default-rules.d.ts.map +1 -0
- package/dist/agency/default-rules.js +79 -0
- package/dist/agency/default-rules.js.map +1 -0
- package/dist/agency/types.d.ts +48 -0
- package/dist/agency/types.d.ts.map +1 -1
- package/dist/brain/brain.d.ts +17 -2
- package/dist/brain/brain.d.ts.map +1 -1
- package/dist/brain/brain.js +118 -8
- package/dist/brain/brain.js.map +1 -1
- package/dist/brain/knowledge-synthesizer.d.ts +37 -0
- package/dist/brain/knowledge-synthesizer.d.ts.map +1 -0
- package/dist/brain/knowledge-synthesizer.js +161 -0
- package/dist/brain/knowledge-synthesizer.js.map +1 -0
- package/dist/brain/learning-radar.d.ts +96 -0
- package/dist/brain/learning-radar.d.ts.map +1 -0
- package/dist/brain/learning-radar.js +202 -0
- package/dist/brain/learning-radar.js.map +1 -0
- package/dist/brain/types.d.ts +15 -0
- package/dist/brain/types.d.ts.map +1 -1
- package/dist/context/context-engine.d.ts.map +1 -1
- package/dist/context/context-engine.js +82 -17
- package/dist/context/context-engine.js.map +1 -1
- package/dist/context/types.d.ts +5 -0
- package/dist/context/types.d.ts.map +1 -1
- package/dist/control/intent-router.d.ts +12 -1
- package/dist/control/intent-router.d.ts.map +1 -1
- package/dist/control/intent-router.js +68 -0
- package/dist/control/intent-router.js.map +1 -1
- package/dist/control/types.d.ts +17 -0
- package/dist/control/types.d.ts.map +1 -1
- package/dist/curator/classifier.d.ts +18 -0
- package/dist/curator/classifier.d.ts.map +1 -0
- package/dist/curator/classifier.js +61 -0
- package/dist/curator/classifier.js.map +1 -0
- package/dist/curator/quality-gate.d.ts +29 -0
- package/dist/curator/quality-gate.d.ts.map +1 -0
- package/dist/curator/quality-gate.js +88 -0
- package/dist/curator/quality-gate.js.map +1 -0
- package/dist/engine/bin/soleri-engine.js +1 -0
- package/dist/engine/bin/soleri-engine.js.map +1 -1
- package/dist/events/event-bus.d.ts +30 -0
- package/dist/events/event-bus.d.ts.map +1 -0
- package/dist/events/event-bus.js +51 -0
- package/dist/events/event-bus.js.map +1 -0
- package/dist/flows/chain-runner.d.ts +46 -0
- package/dist/flows/chain-runner.d.ts.map +1 -0
- package/dist/flows/chain-runner.js +271 -0
- package/dist/flows/chain-runner.js.map +1 -0
- package/dist/flows/chain-types.d.ts +103 -0
- package/dist/flows/chain-types.d.ts.map +1 -0
- package/dist/flows/chain-types.js +23 -0
- package/dist/flows/chain-types.js.map +1 -0
- package/dist/health/doctor-checks.d.ts +15 -0
- package/dist/health/doctor-checks.d.ts.map +1 -0
- package/dist/health/doctor-checks.js +98 -0
- package/dist/health/doctor-checks.js.map +1 -0
- package/dist/intake/text-ingester.d.ts +52 -0
- package/dist/intake/text-ingester.d.ts.map +1 -0
- package/dist/intake/text-ingester.js +181 -0
- package/dist/intake/text-ingester.js.map +1 -0
- package/dist/llm/llm-client.d.ts.map +1 -1
- package/dist/llm/llm-client.js +37 -1
- package/dist/llm/llm-client.js.map +1 -1
- package/dist/llm/oauth-discovery.d.ts +26 -0
- package/dist/llm/oauth-discovery.d.ts.map +1 -0
- package/dist/llm/oauth-discovery.js +149 -0
- package/dist/llm/oauth-discovery.js.map +1 -0
- package/dist/planning/evidence-collector.d.ts +41 -0
- package/dist/planning/evidence-collector.d.ts.map +1 -0
- package/dist/planning/evidence-collector.js +194 -0
- package/dist/planning/evidence-collector.js.map +1 -0
- package/dist/planning/planner.d.ts +4 -0
- package/dist/planning/planner.d.ts.map +1 -1
- package/dist/planning/planner.js +11 -0
- package/dist/planning/planner.js.map +1 -1
- package/dist/queue/job-queue.d.ts +92 -0
- package/dist/queue/job-queue.d.ts.map +1 -0
- package/dist/queue/job-queue.js +180 -0
- package/dist/queue/job-queue.js.map +1 -0
- package/dist/queue/pipeline-runner.d.ts +62 -0
- package/dist/queue/pipeline-runner.d.ts.map +1 -0
- package/dist/queue/pipeline-runner.js +126 -0
- package/dist/queue/pipeline-runner.js.map +1 -0
- package/dist/runtime/admin-setup-ops.d.ts +20 -0
- package/dist/runtime/admin-setup-ops.d.ts.map +1 -0
- package/dist/runtime/admin-setup-ops.js +583 -0
- package/dist/runtime/admin-setup-ops.js.map +1 -0
- package/dist/runtime/chain-ops.d.ts +9 -0
- package/dist/runtime/chain-ops.d.ts.map +1 -0
- package/dist/runtime/chain-ops.js +107 -0
- package/dist/runtime/chain-ops.js.map +1 -0
- package/dist/runtime/claude-md-helpers.d.ts +65 -0
- package/dist/runtime/claude-md-helpers.d.ts.map +1 -0
- package/dist/runtime/claude-md-helpers.js +173 -0
- package/dist/runtime/claude-md-helpers.js.map +1 -0
- package/dist/runtime/curator-extra-ops.d.ts +3 -2
- package/dist/runtime/curator-extra-ops.d.ts.map +1 -1
- package/dist/runtime/curator-extra-ops.js +81 -3
- package/dist/runtime/curator-extra-ops.js.map +1 -1
- package/dist/runtime/facades/admin-facade.d.ts.map +1 -1
- package/dist/runtime/facades/admin-facade.js +4 -0
- package/dist/runtime/facades/admin-facade.js.map +1 -1
- package/dist/runtime/facades/agency-facade.d.ts.map +1 -1
- package/dist/runtime/facades/agency-facade.js +64 -0
- package/dist/runtime/facades/agency-facade.js.map +1 -1
- package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
- package/dist/runtime/facades/brain-facade.js +122 -1
- package/dist/runtime/facades/brain-facade.js.map +1 -1
- package/dist/runtime/facades/control-facade.d.ts.map +1 -1
- package/dist/runtime/facades/control-facade.js +42 -0
- package/dist/runtime/facades/control-facade.js.map +1 -1
- package/dist/runtime/facades/memory-facade.d.ts.map +1 -1
- package/dist/runtime/facades/memory-facade.js +20 -2
- package/dist/runtime/facades/memory-facade.js.map +1 -1
- package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
- package/dist/runtime/facades/plan-facade.js +2 -0
- package/dist/runtime/facades/plan-facade.js.map +1 -1
- package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
- package/dist/runtime/facades/vault-facade.js +25 -5
- package/dist/runtime/facades/vault-facade.js.map +1 -1
- package/dist/runtime/intake-ops.d.ts +7 -5
- package/dist/runtime/intake-ops.d.ts.map +1 -1
- package/dist/runtime/intake-ops.js +98 -5
- package/dist/runtime/intake-ops.js.map +1 -1
- package/dist/runtime/memory-extra-ops.d.ts +6 -3
- package/dist/runtime/memory-extra-ops.d.ts.map +1 -1
- package/dist/runtime/memory-extra-ops.js +292 -4
- package/dist/runtime/memory-extra-ops.js.map +1 -1
- package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
- package/dist/runtime/planning-extra-ops.js +85 -0
- package/dist/runtime/planning-extra-ops.js.map +1 -1
- package/dist/runtime/playbook-ops.js +1 -1
- package/dist/runtime/playbook-ops.js.map +1 -1
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +143 -2
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/session-briefing.d.ts +23 -0
- package/dist/runtime/session-briefing.d.ts.map +1 -0
- package/dist/runtime/session-briefing.js +140 -0
- package/dist/runtime/session-briefing.js.map +1 -0
- package/dist/runtime/types.d.ts +23 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/vault-linking-ops.d.ts.map +1 -1
- package/dist/runtime/vault-linking-ops.js +1 -3
- package/dist/runtime/vault-linking-ops.js.map +1 -1
- package/dist/vault/vault.d.ts +25 -0
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +67 -3
- package/dist/vault/vault.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/admin-setup-ops.test.ts +355 -0
- package/src/__tests__/async-infrastructure.test.ts +307 -0
- package/src/__tests__/cognee-client-gaps.test.ts +6 -2
- package/src/__tests__/cognee-hybrid-search.test.ts +49 -35
- package/src/__tests__/cognee-sync-manager-deep.test.ts +89 -65
- package/src/__tests__/curator-extra-ops.test.ts +6 -2
- package/src/__tests__/curator-pipeline-e2e.test.ts +358 -0
- package/src/__tests__/memory-extra-ops.test.ts +2 -2
- package/src/__tests__/planning-extra-ops.test.ts +2 -2
- package/src/__tests__/second-brain-features.test.ts +583 -0
- package/src/agency/agency-manager.ts +217 -9
- package/src/agency/default-rules.ts +83 -0
- package/src/agency/types.ts +61 -0
- package/src/brain/brain.ts +110 -8
- package/src/brain/knowledge-synthesizer.ts +218 -0
- package/src/brain/learning-radar.ts +340 -0
- package/src/brain/types.ts +16 -0
- package/src/context/context-engine.ts +114 -15
- package/src/context/types.ts +5 -0
- package/src/control/intent-router.ts +107 -0
- package/src/control/types.ts +10 -0
- package/src/curator/classifier.ts +88 -0
- package/src/curator/quality-gate.ts +129 -0
- package/src/engine/bin/soleri-engine.ts +1 -0
- package/src/events/event-bus.ts +58 -0
- package/src/flows/chain-runner.ts +369 -0
- package/src/flows/chain-types.ts +57 -0
- package/src/health/doctor-checks.ts +115 -0
- package/src/intake/text-ingester.ts +234 -0
- package/src/llm/llm-client.ts +38 -1
- package/src/llm/oauth-discovery.ts +169 -0
- package/src/planning/evidence-collector.ts +247 -0
- package/src/planning/planner.ts +11 -0
- package/src/queue/job-queue.ts +281 -0
- package/src/queue/pipeline-runner.ts +149 -0
- package/src/runtime/admin-setup-ops.ts +664 -0
- package/src/runtime/chain-ops.ts +121 -0
- package/src/runtime/claude-md-helpers.ts +236 -0
- package/src/runtime/curator-extra-ops.ts +86 -3
- package/src/runtime/facades/admin-facade.ts +4 -0
- package/src/runtime/facades/agency-facade.ts +68 -0
- package/src/runtime/facades/brain-facade.ts +142 -1
- package/src/runtime/facades/control-facade.ts +45 -0
- package/src/runtime/facades/memory-facade.ts +20 -2
- package/src/runtime/facades/plan-facade.ts +2 -0
- package/src/runtime/facades/vault-facade.ts +28 -5
- package/src/runtime/intake-ops.ts +107 -5
- package/src/runtime/memory-extra-ops.ts +312 -4
- package/src/runtime/planning-extra-ops.ts +94 -0
- package/src/runtime/playbook-ops.ts +1 -1
- package/src/runtime/runtime.ts +138 -2
- package/src/runtime/session-briefing.ts +161 -0
- package/src/runtime/types.ts +23 -0
- package/src/runtime/vault-linking-ops.ts +1 -3
- package/src/vault/vault.ts +79 -4
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Briefing — proactive context loading on session start.
|
|
3
|
+
*
|
|
4
|
+
* Gathers data from all subsystems (sessions, plans, vault, brain, curator)
|
|
5
|
+
* and produces a concise, structured briefing for the agent.
|
|
6
|
+
*
|
|
7
|
+
* Design: gather all data in parallel, skip sections with nothing to report.
|
|
8
|
+
* Target: < 15 lines of output, < 3 seconds latency.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import type { OpDefinition } from '../facades/types.js';
|
|
13
|
+
import type { AgentRuntime } from './types.js';
|
|
14
|
+
|
|
15
|
+
export interface BriefingSection {
|
|
16
|
+
label: string;
|
|
17
|
+
content: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface SessionBriefing {
|
|
21
|
+
sections: BriefingSection[];
|
|
22
|
+
generatedAt: number;
|
|
23
|
+
/** Total entries consulted across all data sources. */
|
|
24
|
+
dataPointsConsulted: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function createSessionBriefingOps(runtime: AgentRuntime): OpDefinition[] {
|
|
28
|
+
const { brainIntelligence, planner, vault, curator } = runtime;
|
|
29
|
+
|
|
30
|
+
return [
|
|
31
|
+
{
|
|
32
|
+
name: 'session_briefing',
|
|
33
|
+
description:
|
|
34
|
+
'Proactive session briefing — gathers last session, active plans, recent vault captures, brain recommendations, and stale knowledge warnings into a concise summary.',
|
|
35
|
+
auth: 'read',
|
|
36
|
+
schema: z.object({
|
|
37
|
+
maxSections: z.number().optional().default(6).describe('Max sections to include'),
|
|
38
|
+
recencyHours: z.number().optional().default(48).describe('Look back window in hours'),
|
|
39
|
+
}),
|
|
40
|
+
handler: async (params) => {
|
|
41
|
+
const maxSections = params.maxSections as number;
|
|
42
|
+
const sections: BriefingSection[] = [];
|
|
43
|
+
let dataPoints = 0;
|
|
44
|
+
|
|
45
|
+
// 1. Last session
|
|
46
|
+
try {
|
|
47
|
+
const sessions = brainIntelligence.listSessions({ limit: 1, active: false });
|
|
48
|
+
dataPoints += sessions.length;
|
|
49
|
+
if (sessions.length > 0) {
|
|
50
|
+
const last = sessions[0];
|
|
51
|
+
const ago = formatTimeAgo(last.endedAt ? new Date(last.endedAt).getTime() : Date.now());
|
|
52
|
+
const domain = last.domain ? ` [${last.domain}]` : '';
|
|
53
|
+
const context = last.context ? `: ${last.context.slice(0, 80)}` : '';
|
|
54
|
+
const tools = last.toolsUsed.length > 0 ? `, used ${last.toolsUsed.length} tools` : '';
|
|
55
|
+
const files =
|
|
56
|
+
last.filesModified.length > 0 ? `, modified ${last.filesModified.length} files` : '';
|
|
57
|
+
sections.push({
|
|
58
|
+
label: 'Last session',
|
|
59
|
+
content: `(${ago})${domain}${context}${tools}${files}`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
} catch {
|
|
63
|
+
// Session data unavailable — skip
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 2. Active plans
|
|
67
|
+
try {
|
|
68
|
+
const plans = planner.list();
|
|
69
|
+
const active = plans.filter(
|
|
70
|
+
(p) =>
|
|
71
|
+
p.status === 'executing' ||
|
|
72
|
+
p.status === 'approved' ||
|
|
73
|
+
p.status === 'reconciling' ||
|
|
74
|
+
p.status === 'validating',
|
|
75
|
+
);
|
|
76
|
+
dataPoints += plans.length;
|
|
77
|
+
if (active.length > 0) {
|
|
78
|
+
const summaries = active.map((p) => {
|
|
79
|
+
const tasksDone = p.tasks.filter((t) => t.status === 'completed').length;
|
|
80
|
+
return `${p.objective?.slice(0, 40) || p.id} (${p.status}, ${tasksDone}/${p.tasks.length} tasks)`;
|
|
81
|
+
});
|
|
82
|
+
sections.push({
|
|
83
|
+
label: active.length === 1 ? 'Active plan' : `Active plans (${active.length})`,
|
|
84
|
+
content: summaries.join('; '),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
} catch {
|
|
88
|
+
// Planner unavailable — skip
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// 3. Recent vault captures
|
|
92
|
+
try {
|
|
93
|
+
const recent = vault.getRecent(10);
|
|
94
|
+
dataPoints += recent.length;
|
|
95
|
+
if (recent.length > 0) {
|
|
96
|
+
const count = Math.min(recent.length, 5);
|
|
97
|
+
const titles = recent.slice(0, 3).map((e) => e.title.slice(0, 50));
|
|
98
|
+
sections.push({
|
|
99
|
+
label: 'Recent captures',
|
|
100
|
+
content: `${count} entries — ${titles.join(', ')}${count > 3 ? '...' : ''}`,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
} catch {
|
|
104
|
+
// Vault unavailable — skip
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 4. Brain recommendations
|
|
108
|
+
try {
|
|
109
|
+
const recs = brainIntelligence.recommend({ limit: 3 });
|
|
110
|
+
dataPoints += recs.length;
|
|
111
|
+
if (recs.length > 0) {
|
|
112
|
+
const items = recs.map((r) => `"${r.pattern}" (strength: ${r.strength.toFixed(2)})`);
|
|
113
|
+
sections.push({
|
|
114
|
+
label: 'Brain recommends',
|
|
115
|
+
content: items.join(', '),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
} catch {
|
|
119
|
+
// Brain unavailable — skip
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// 5. Stale knowledge / health warnings
|
|
123
|
+
try {
|
|
124
|
+
const health = curator.healthAudit();
|
|
125
|
+
dataPoints += 1;
|
|
126
|
+
const warnings: string[] = [];
|
|
127
|
+
if (health.score < 70) {
|
|
128
|
+
warnings.push(`vault health: ${health.score}/100`);
|
|
129
|
+
}
|
|
130
|
+
if (health.recommendations && health.recommendations.length > 0) {
|
|
131
|
+
warnings.push(health.recommendations[0]);
|
|
132
|
+
}
|
|
133
|
+
if (warnings.length > 0) {
|
|
134
|
+
sections.push({
|
|
135
|
+
label: 'Attention',
|
|
136
|
+
content: warnings.join('. '),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
} catch {
|
|
140
|
+
// Curator unavailable — skip
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
sections: sections.slice(0, maxSections),
|
|
145
|
+
generatedAt: Date.now(),
|
|
146
|
+
dataPointsConsulted: dataPoints,
|
|
147
|
+
} satisfies SessionBriefing;
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
];
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function formatTimeAgo(timestamp: number): string {
|
|
154
|
+
const diff = Date.now() - timestamp;
|
|
155
|
+
const minutes = Math.floor(diff / 60000);
|
|
156
|
+
if (minutes < 60) return `${minutes}m ago`;
|
|
157
|
+
const hours = Math.floor(minutes / 60);
|
|
158
|
+
if (hours < 24) return `${hours}h ago`;
|
|
159
|
+
const days = Math.floor(hours / 24);
|
|
160
|
+
return `${days}d ago`;
|
|
161
|
+
}
|
package/src/runtime/types.ts
CHANGED
|
@@ -28,6 +28,13 @@ import type { VaultBranching } from '../vault/vault-branching.js';
|
|
|
28
28
|
import type { ContextEngine } from '../context/context-engine.js';
|
|
29
29
|
import type { AgencyManager } from '../agency/agency-manager.js';
|
|
30
30
|
import type { KnowledgeReview } from '../vault/knowledge-review.js';
|
|
31
|
+
import type { LinkManager } from '../vault/linking.js';
|
|
32
|
+
import type { LearningRadar } from '../brain/learning-radar.js';
|
|
33
|
+
import type { TextIngester } from '../intake/text-ingester.js';
|
|
34
|
+
import type { KnowledgeSynthesizer } from '../brain/knowledge-synthesizer.js';
|
|
35
|
+
import type { ChainRunner } from '../flows/chain-runner.js';
|
|
36
|
+
import type { JobQueue } from '../queue/job-queue.js';
|
|
37
|
+
import type { PipelineRunner } from '../queue/pipeline-runner.js';
|
|
31
38
|
|
|
32
39
|
/**
|
|
33
40
|
* Configuration for creating an agent runtime.
|
|
@@ -50,6 +57,8 @@ export interface AgentRuntimeConfig {
|
|
|
50
57
|
sharedVaultPath?: string;
|
|
51
58
|
/** Enable Cognee vector search integration. Default: false (opt-in). */
|
|
52
59
|
cognee?: boolean;
|
|
60
|
+
/** Path to the agent's root directory (containing agent.yaml, instructions/, etc.). Optional — set by engine binary. */
|
|
61
|
+
agentDir?: string;
|
|
53
62
|
}
|
|
54
63
|
|
|
55
64
|
/**
|
|
@@ -100,6 +109,20 @@ export interface AgentRuntime {
|
|
|
100
109
|
agencyManager: AgencyManager;
|
|
101
110
|
/** Knowledge review — team review workflows (submit/approve/reject). */
|
|
102
111
|
knowledgeReview: KnowledgeReview;
|
|
112
|
+
/** Link manager — Zettelkasten bidirectional linking with auto-link on ingestion. */
|
|
113
|
+
linkManager: LinkManager;
|
|
114
|
+
/** Learning radar — automatic pattern detection from session signals. */
|
|
115
|
+
learningRadar: LearningRadar;
|
|
116
|
+
/** Text ingester — ingest articles, transcripts, and plain text into vault. */
|
|
117
|
+
textIngester: TextIngester;
|
|
118
|
+
/** Knowledge synthesizer — turn vault knowledge into briefs, outlines, posts. */
|
|
119
|
+
knowledgeSynthesizer: KnowledgeSynthesizer;
|
|
120
|
+
/** Chain runner — composable multi-step workflows with data flow and gates. */
|
|
121
|
+
chainRunner: ChainRunner;
|
|
122
|
+
/** Job queue — SQLite-backed async job processing with DAG dependencies. */
|
|
123
|
+
jobQueue: JobQueue;
|
|
124
|
+
/** Pipeline runner — background polling loop for job execution. */
|
|
125
|
+
pipelineRunner: PipelineRunner;
|
|
103
126
|
/** Timestamp (ms since epoch) when this runtime was created. */
|
|
104
127
|
createdAt: number;
|
|
105
128
|
/** Close the vault database connection. Call on shutdown. */
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
import { z } from 'zod';
|
|
12
12
|
import type { OpDefinition } from '../facades/types.js';
|
|
13
13
|
import type { AgentRuntime } from './types.js';
|
|
14
|
-
import { LinkManager } from '../vault/linking.js';
|
|
15
14
|
|
|
16
15
|
const EVAL_SYSTEM_PROMPT = `You evaluate pairs of knowledge entries to determine if they should be linked in a Zettelkasten vault. For EACH pair, decide:
|
|
17
16
|
- If meaningfully related → return { "link": true, "type": "<type>", "note": "<1 sentence why>" }
|
|
@@ -26,8 +25,7 @@ Link types:
|
|
|
26
25
|
Rules: Same category alone is NOT enough. Be selective. Return a JSON array.`;
|
|
27
26
|
|
|
28
27
|
export function createVaultLinkingOps(runtime: AgentRuntime): OpDefinition[] {
|
|
29
|
-
const { vault } = runtime;
|
|
30
|
-
const linkManager = new LinkManager(vault.getProvider());
|
|
28
|
+
const { vault, linkManager } = runtime;
|
|
31
29
|
|
|
32
30
|
return [
|
|
33
31
|
{
|
package/src/vault/vault.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { PersistenceProvider } from '../persistence/types.js';
|
|
|
2
2
|
import { SQLitePersistenceProvider } from '../persistence/sqlite-provider.js';
|
|
3
3
|
import type { IntelligenceEntry } from '../intelligence/types.js';
|
|
4
4
|
import { computeContentHash } from './content-hash.js';
|
|
5
|
+
import type { LinkManager } from './linking.js';
|
|
5
6
|
|
|
6
7
|
export interface SearchResult {
|
|
7
8
|
entry: IntelligenceEntry;
|
|
@@ -29,6 +30,16 @@ export interface Memory {
|
|
|
29
30
|
topics: string[];
|
|
30
31
|
filesModified: string[];
|
|
31
32
|
toolsUsed: string[];
|
|
33
|
+
/** What the user was trying to accomplish. */
|
|
34
|
+
intent: string | null;
|
|
35
|
+
/** Key decisions made and their rationale. */
|
|
36
|
+
decisions: string[];
|
|
37
|
+
/** Where things stand at capture time. */
|
|
38
|
+
currentState: string | null;
|
|
39
|
+
/** What should happen next session. */
|
|
40
|
+
nextSteps: string[];
|
|
41
|
+
/** Vault entries that informed this session. */
|
|
42
|
+
vaultEntriesReferenced: string[];
|
|
32
43
|
createdAt: number;
|
|
33
44
|
archivedAt: number | null;
|
|
34
45
|
}
|
|
@@ -42,6 +53,10 @@ export class Vault {
|
|
|
42
53
|
private provider: PersistenceProvider;
|
|
43
54
|
private sqliteProvider: SQLitePersistenceProvider | null;
|
|
44
55
|
private syncManager: import('../cognee/sync-manager.js').CogneeSyncManager | null = null;
|
|
56
|
+
private linkManager: LinkManager | null = null;
|
|
57
|
+
private autoLinkEnabled = true;
|
|
58
|
+
/** Minimum number of FTS5 suggestions to auto-link. Top N are linked. */
|
|
59
|
+
private autoLinkMaxLinks = 3;
|
|
45
60
|
|
|
46
61
|
/**
|
|
47
62
|
* Create a Vault with a PersistenceProvider or a SQLite path (backward compat).
|
|
@@ -67,6 +82,28 @@ export class Vault {
|
|
|
67
82
|
this.syncManager = mgr;
|
|
68
83
|
}
|
|
69
84
|
|
|
85
|
+
setLinkManager(mgr: LinkManager, opts?: { enabled?: boolean; maxLinks?: number }): void {
|
|
86
|
+
this.linkManager = mgr;
|
|
87
|
+
if (opts?.enabled !== undefined) this.autoLinkEnabled = opts.enabled;
|
|
88
|
+
if (opts?.maxLinks !== undefined) this.autoLinkMaxLinks = opts.maxLinks;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Auto-link a newly added entry using FTS5 suggestions.
|
|
93
|
+
* Called after seed() for each entry. Creates links for top N suggestions.
|
|
94
|
+
*/
|
|
95
|
+
private autoLink(entryId: string): void {
|
|
96
|
+
if (!this.linkManager || !this.autoLinkEnabled) return;
|
|
97
|
+
try {
|
|
98
|
+
const suggestions = this.linkManager.suggestLinks(entryId, this.autoLinkMaxLinks);
|
|
99
|
+
for (const s of suggestions) {
|
|
100
|
+
this.linkManager.addLink(entryId, s.entryId, s.suggestedType, `auto: ${s.reason}`);
|
|
101
|
+
}
|
|
102
|
+
} catch {
|
|
103
|
+
// Auto-linking is best-effort — never block ingestion
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
70
107
|
/** Backward-compatible factory. */
|
|
71
108
|
static createWithSQLite(dbPath: string = ':memory:'): Vault {
|
|
72
109
|
return new Vault(dbPath);
|
|
@@ -140,7 +177,23 @@ export class Vault {
|
|
|
140
177
|
CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
|
|
141
178
|
id, context, summary, topics,
|
|
142
179
|
content='memories', content_rowid='rowid', tokenize='porter unicode61'
|
|
143
|
-
);
|
|
180
|
+
);`);
|
|
181
|
+
|
|
182
|
+
// Add new columns if they don't exist (backward-compatible migration)
|
|
183
|
+
const memCols = this.provider
|
|
184
|
+
.all<{ name: string }>(`PRAGMA table_info(memories)`)
|
|
185
|
+
.map((r) => r.name);
|
|
186
|
+
if (!memCols.includes('intent')) {
|
|
187
|
+
this.provider.execSql(`
|
|
188
|
+
ALTER TABLE memories ADD COLUMN intent TEXT;
|
|
189
|
+
ALTER TABLE memories ADD COLUMN decisions TEXT NOT NULL DEFAULT '[]';
|
|
190
|
+
ALTER TABLE memories ADD COLUMN current_state TEXT;
|
|
191
|
+
ALTER TABLE memories ADD COLUMN next_steps TEXT NOT NULL DEFAULT '[]';
|
|
192
|
+
ALTER TABLE memories ADD COLUMN vault_entries_referenced TEXT NOT NULL DEFAULT '[]';
|
|
193
|
+
`);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
this.provider.execSql(`
|
|
144
197
|
CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
|
|
145
198
|
INSERT INTO memories_fts(rowid,id,context,summary,topics) VALUES(new.rowid,new.id,new.context,new.summary,new.topics);
|
|
146
199
|
END;
|
|
@@ -339,6 +392,13 @@ export class Vault {
|
|
|
339
392
|
this.syncManager.enqueue('ingest', entry.id, entry);
|
|
340
393
|
}
|
|
341
394
|
}
|
|
395
|
+
// Auto-link after all entries are inserted (so they can link to each other).
|
|
396
|
+
// Skip for large batches (>100) — use relink_vault for bulk imports.
|
|
397
|
+
if (entries.length <= 100) {
|
|
398
|
+
for (const entry of entries) {
|
|
399
|
+
this.autoLink(entry.id);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
342
402
|
return count;
|
|
343
403
|
});
|
|
344
404
|
}
|
|
@@ -676,7 +736,7 @@ export class Vault {
|
|
|
676
736
|
}
|
|
677
737
|
return {
|
|
678
738
|
total: rows.length,
|
|
679
|
-
buckets: bucketDefs.map((b, i) => ({
|
|
739
|
+
buckets: bucketDefs.map((b, i) => Object.assign({}, b, { count: counts[i] })),
|
|
680
740
|
oldestTimestamp: oldest,
|
|
681
741
|
newestTimestamp: newest,
|
|
682
742
|
};
|
|
@@ -727,7 +787,8 @@ export class Vault {
|
|
|
727
787
|
captureMemory(memory: Omit<Memory, 'id' | 'createdAt' | 'archivedAt'>): Memory {
|
|
728
788
|
const id = `mem-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
729
789
|
this.provider.run(
|
|
730
|
-
`INSERT INTO memories (id, project_path, type, context, summary, topics, files_modified, tools_used
|
|
790
|
+
`INSERT INTO memories (id, project_path, type, context, summary, topics, files_modified, tools_used, intent, decisions, current_state, next_steps, vault_entries_referenced)
|
|
791
|
+
VALUES (@id, @projectPath, @type, @context, @summary, @topics, @filesModified, @toolsUsed, @intent, @decisions, @currentState, @nextSteps, @vaultEntriesReferenced)`,
|
|
731
792
|
{
|
|
732
793
|
id,
|
|
733
794
|
projectPath: memory.projectPath,
|
|
@@ -737,6 +798,11 @@ export class Vault {
|
|
|
737
798
|
topics: JSON.stringify(memory.topics),
|
|
738
799
|
filesModified: JSON.stringify(memory.filesModified),
|
|
739
800
|
toolsUsed: JSON.stringify(memory.toolsUsed),
|
|
801
|
+
intent: memory.intent ?? null,
|
|
802
|
+
decisions: JSON.stringify(memory.decisions ?? []),
|
|
803
|
+
currentState: memory.currentState ?? null,
|
|
804
|
+
nextSteps: JSON.stringify(memory.nextSteps ?? []),
|
|
805
|
+
vaultEntriesReferenced: JSON.stringify(memory.vaultEntriesReferenced ?? []),
|
|
740
806
|
},
|
|
741
807
|
);
|
|
742
808
|
return this.getMemory(id)!;
|
|
@@ -744,7 +810,7 @@ export class Vault {
|
|
|
744
810
|
|
|
745
811
|
searchMemories(
|
|
746
812
|
query: string,
|
|
747
|
-
options?: { type?: string; projectPath?: string; limit?: number },
|
|
813
|
+
options?: { type?: string; projectPath?: string; intent?: string; limit?: number },
|
|
748
814
|
): Memory[] {
|
|
749
815
|
const limit = options?.limit ?? 10;
|
|
750
816
|
const filters: string[] = ['m.archived_at IS NULL'];
|
|
@@ -757,6 +823,10 @@ export class Vault {
|
|
|
757
823
|
filters.push('m.project_path = @projectPath');
|
|
758
824
|
fp.projectPath = options.projectPath;
|
|
759
825
|
}
|
|
826
|
+
if (options?.intent) {
|
|
827
|
+
filters.push('m.intent = @intent');
|
|
828
|
+
fp.intent = options.intent;
|
|
829
|
+
}
|
|
760
830
|
const wc = filters.length > 0 ? `AND ${filters.join(' AND ')}` : '';
|
|
761
831
|
try {
|
|
762
832
|
const rows = this.provider.all<Record<string, unknown>>(
|
|
@@ -1239,6 +1309,11 @@ function rowToMemory(row: Record<string, unknown>): Memory {
|
|
|
1239
1309
|
topics: JSON.parse((row.topics as string) || '[]'),
|
|
1240
1310
|
filesModified: JSON.parse((row.files_modified as string) || '[]'),
|
|
1241
1311
|
toolsUsed: JSON.parse((row.tools_used as string) || '[]'),
|
|
1312
|
+
intent: (row.intent as string) ?? null,
|
|
1313
|
+
decisions: JSON.parse((row.decisions as string) || '[]'),
|
|
1314
|
+
currentState: (row.current_state as string) ?? null,
|
|
1315
|
+
nextSteps: JSON.parse((row.next_steps as string) || '[]'),
|
|
1316
|
+
vaultEntriesReferenced: JSON.parse((row.vault_entries_referenced as string) || '[]'),
|
|
1242
1317
|
createdAt: row.created_at as number,
|
|
1243
1318
|
archivedAt: (row.archived_at as number) ?? null,
|
|
1244
1319
|
};
|