@framers/agentos 0.1.101 → 0.1.102
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/README.md +16 -0
- package/dist/memory/config.d.ts +39 -0
- package/dist/memory/config.d.ts.map +1 -1
- package/dist/memory/config.js.map +1 -1
- package/dist/memory/consolidation/ConsolidationLoop.d.ts +177 -0
- package/dist/memory/consolidation/ConsolidationLoop.d.ts.map +1 -0
- package/dist/memory/consolidation/ConsolidationLoop.js +517 -0
- package/dist/memory/consolidation/ConsolidationLoop.js.map +1 -0
- package/dist/memory/consolidation/ConsolidationPipeline.d.ts.map +1 -1
- package/dist/memory/consolidation/ConsolidationPipeline.js +7 -0
- package/dist/memory/consolidation/ConsolidationPipeline.js.map +1 -1
- package/dist/memory/consolidation/index.d.ts +8 -0
- package/dist/memory/consolidation/index.d.ts.map +1 -0
- package/dist/memory/consolidation/index.js +7 -0
- package/dist/memory/consolidation/index.js.map +1 -0
- package/dist/memory/decay/DecayModel.d.ts +33 -0
- package/dist/memory/decay/DecayModel.d.ts.map +1 -1
- package/dist/memory/decay/DecayModel.js +31 -0
- package/dist/memory/decay/DecayModel.js.map +1 -1
- package/dist/memory/facade/Memory.d.ts +228 -0
- package/dist/memory/facade/Memory.d.ts.map +1 -0
- package/dist/memory/facade/Memory.js +823 -0
- package/dist/memory/facade/Memory.js.map +1 -0
- package/dist/memory/facade/index.d.ts +13 -0
- package/dist/memory/facade/index.d.ts.map +1 -0
- package/dist/memory/facade/index.js +11 -0
- package/dist/memory/facade/index.js.map +1 -0
- package/dist/memory/facade/types.d.ts +606 -0
- package/dist/memory/facade/types.d.ts.map +1 -0
- package/dist/memory/facade/types.js +11 -0
- package/dist/memory/facade/types.js.map +1 -0
- package/dist/memory/feedback/RetrievalFeedbackSignal.d.ts +132 -0
- package/dist/memory/feedback/RetrievalFeedbackSignal.d.ts.map +1 -0
- package/dist/memory/feedback/RetrievalFeedbackSignal.js +178 -0
- package/dist/memory/feedback/RetrievalFeedbackSignal.js.map +1 -0
- package/dist/memory/feedback/index.d.ts +13 -0
- package/dist/memory/feedback/index.d.ts.map +1 -0
- package/dist/memory/feedback/index.js +12 -0
- package/dist/memory/feedback/index.js.map +1 -0
- package/dist/memory/index.d.ts +22 -0
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +24 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/ingestion/ChunkingEngine.d.ts +143 -0
- package/dist/memory/ingestion/ChunkingEngine.d.ts.map +1 -0
- package/dist/memory/ingestion/ChunkingEngine.js +508 -0
- package/dist/memory/ingestion/ChunkingEngine.js.map +1 -0
- package/dist/memory/ingestion/DoclingLoader.d.ts +44 -0
- package/dist/memory/ingestion/DoclingLoader.d.ts.map +1 -0
- package/dist/memory/ingestion/DoclingLoader.js +228 -0
- package/dist/memory/ingestion/DoclingLoader.js.map +1 -0
- package/dist/memory/ingestion/DocxLoader.d.ts +37 -0
- package/dist/memory/ingestion/DocxLoader.d.ts.map +1 -0
- package/dist/memory/ingestion/DocxLoader.js +111 -0
- package/dist/memory/ingestion/DocxLoader.js.map +1 -0
- package/dist/memory/ingestion/FolderScanner.d.ts +116 -0
- package/dist/memory/ingestion/FolderScanner.d.ts.map +1 -0
- package/dist/memory/ingestion/FolderScanner.js +127 -0
- package/dist/memory/ingestion/FolderScanner.js.map +1 -0
- package/dist/memory/ingestion/HtmlLoader.d.ts +49 -0
- package/dist/memory/ingestion/HtmlLoader.d.ts.map +1 -0
- package/dist/memory/ingestion/HtmlLoader.js +202 -0
- package/dist/memory/ingestion/HtmlLoader.js.map +1 -0
- package/dist/memory/ingestion/IDocumentLoader.d.ts +63 -0
- package/dist/memory/ingestion/IDocumentLoader.d.ts.map +1 -0
- package/dist/memory/ingestion/IDocumentLoader.js +11 -0
- package/dist/memory/ingestion/IDocumentLoader.js.map +1 -0
- package/dist/memory/ingestion/LoaderRegistry.d.ts +140 -0
- package/dist/memory/ingestion/LoaderRegistry.d.ts.map +1 -0
- package/dist/memory/ingestion/LoaderRegistry.js +229 -0
- package/dist/memory/ingestion/LoaderRegistry.js.map +1 -0
- package/dist/memory/ingestion/MarkdownLoader.d.ts +50 -0
- package/dist/memory/ingestion/MarkdownLoader.d.ts.map +1 -0
- package/dist/memory/ingestion/MarkdownLoader.js +169 -0
- package/dist/memory/ingestion/MarkdownLoader.js.map +1 -0
- package/dist/memory/ingestion/MultimodalAggregator.d.ts +88 -0
- package/dist/memory/ingestion/MultimodalAggregator.d.ts.map +1 -0
- package/dist/memory/ingestion/MultimodalAggregator.js +96 -0
- package/dist/memory/ingestion/MultimodalAggregator.js.map +1 -0
- package/dist/memory/ingestion/OcrPdfLoader.d.ts +41 -0
- package/dist/memory/ingestion/OcrPdfLoader.d.ts.map +1 -0
- package/dist/memory/ingestion/OcrPdfLoader.js +149 -0
- package/dist/memory/ingestion/OcrPdfLoader.js.map +1 -0
- package/dist/memory/ingestion/PdfLoader.d.ts +78 -0
- package/dist/memory/ingestion/PdfLoader.d.ts.map +1 -0
- package/dist/memory/ingestion/PdfLoader.js +179 -0
- package/dist/memory/ingestion/PdfLoader.js.map +1 -0
- package/dist/memory/ingestion/TextLoader.d.ts +66 -0
- package/dist/memory/ingestion/TextLoader.d.ts.map +1 -0
- package/dist/memory/ingestion/TextLoader.js +207 -0
- package/dist/memory/ingestion/TextLoader.js.map +1 -0
- package/dist/memory/ingestion/UrlLoader.d.ts +95 -0
- package/dist/memory/ingestion/UrlLoader.d.ts.map +1 -0
- package/dist/memory/ingestion/UrlLoader.js +174 -0
- package/dist/memory/ingestion/UrlLoader.js.map +1 -0
- package/dist/memory/io/ChatGptImporter.d.ts +85 -0
- package/dist/memory/io/ChatGptImporter.d.ts.map +1 -0
- package/dist/memory/io/ChatGptImporter.js +231 -0
- package/dist/memory/io/ChatGptImporter.js.map +1 -0
- package/dist/memory/io/JsonExporter.d.ts +67 -0
- package/dist/memory/io/JsonExporter.d.ts.map +1 -0
- package/dist/memory/io/JsonExporter.js +132 -0
- package/dist/memory/io/JsonExporter.js.map +1 -0
- package/dist/memory/io/JsonImporter.d.ts +84 -0
- package/dist/memory/io/JsonImporter.d.ts.map +1 -0
- package/dist/memory/io/JsonImporter.js +234 -0
- package/dist/memory/io/JsonImporter.js.map +1 -0
- package/dist/memory/io/MarkdownExporter.d.ts +95 -0
- package/dist/memory/io/MarkdownExporter.d.ts.map +1 -0
- package/dist/memory/io/MarkdownExporter.js +130 -0
- package/dist/memory/io/MarkdownExporter.js.map +1 -0
- package/dist/memory/io/MarkdownImporter.d.ts +84 -0
- package/dist/memory/io/MarkdownImporter.d.ts.map +1 -0
- package/dist/memory/io/MarkdownImporter.js +166 -0
- package/dist/memory/io/MarkdownImporter.js.map +1 -0
- package/dist/memory/io/ObsidianExporter.d.ts +80 -0
- package/dist/memory/io/ObsidianExporter.d.ts.map +1 -0
- package/dist/memory/io/ObsidianExporter.js +127 -0
- package/dist/memory/io/ObsidianExporter.js.map +1 -0
- package/dist/memory/io/ObsidianImporter.d.ts +93 -0
- package/dist/memory/io/ObsidianImporter.d.ts.map +1 -0
- package/dist/memory/io/ObsidianImporter.js +221 -0
- package/dist/memory/io/ObsidianImporter.js.map +1 -0
- package/dist/memory/io/SqliteExporter.d.ts +47 -0
- package/dist/memory/io/SqliteExporter.d.ts.map +1 -0
- package/dist/memory/io/SqliteExporter.js +56 -0
- package/dist/memory/io/SqliteExporter.js.map +1 -0
- package/dist/memory/io/SqliteImporter.d.ts +82 -0
- package/dist/memory/io/SqliteImporter.d.ts.map +1 -0
- package/dist/memory/io/SqliteImporter.js +232 -0
- package/dist/memory/io/SqliteImporter.js.map +1 -0
- package/dist/memory/io/index.d.ts +31 -0
- package/dist/memory/io/index.d.ts.map +1 -0
- package/dist/memory/io/index.js +31 -0
- package/dist/memory/io/index.js.map +1 -0
- package/dist/memory/store/SqliteBrain.d.ts +125 -0
- package/dist/memory/store/SqliteBrain.d.ts.map +1 -0
- package/dist/memory/store/SqliteBrain.js +407 -0
- package/dist/memory/store/SqliteBrain.js.map +1 -0
- package/dist/memory/store/SqliteKnowledgeGraph.d.ts +259 -0
- package/dist/memory/store/SqliteKnowledgeGraph.d.ts.map +1 -0
- package/dist/memory/store/SqliteKnowledgeGraph.js +1062 -0
- package/dist/memory/store/SqliteKnowledgeGraph.js.map +1 -0
- package/dist/memory/store/SqliteMemoryGraph.d.ts +251 -0
- package/dist/memory/store/SqliteMemoryGraph.d.ts.map +1 -0
- package/dist/memory/store/SqliteMemoryGraph.js +637 -0
- package/dist/memory/store/SqliteMemoryGraph.js.map +1 -0
- package/dist/memory/tools/MemoryAddTool.d.ts +98 -0
- package/dist/memory/tools/MemoryAddTool.d.ts.map +1 -0
- package/dist/memory/tools/MemoryAddTool.js +131 -0
- package/dist/memory/tools/MemoryAddTool.js.map +1 -0
- package/dist/memory/tools/MemoryDeleteTool.d.ts +83 -0
- package/dist/memory/tools/MemoryDeleteTool.d.ts.map +1 -0
- package/dist/memory/tools/MemoryDeleteTool.js +96 -0
- package/dist/memory/tools/MemoryDeleteTool.js.map +1 -0
- package/dist/memory/tools/MemoryMergeTool.d.ts +95 -0
- package/dist/memory/tools/MemoryMergeTool.d.ts.map +1 -0
- package/dist/memory/tools/MemoryMergeTool.js +164 -0
- package/dist/memory/tools/MemoryMergeTool.js.map +1 -0
- package/dist/memory/tools/MemoryReflectTool.d.ts +86 -0
- package/dist/memory/tools/MemoryReflectTool.d.ts.map +1 -0
- package/dist/memory/tools/MemoryReflectTool.js +102 -0
- package/dist/memory/tools/MemoryReflectTool.js.map +1 -0
- package/dist/memory/tools/MemorySearchTool.d.ts +117 -0
- package/dist/memory/tools/MemorySearchTool.d.ts.map +1 -0
- package/dist/memory/tools/MemorySearchTool.js +162 -0
- package/dist/memory/tools/MemorySearchTool.js.map +1 -0
- package/dist/memory/tools/MemoryUpdateTool.d.ts +92 -0
- package/dist/memory/tools/MemoryUpdateTool.d.ts.map +1 -0
- package/dist/memory/tools/MemoryUpdateTool.js +125 -0
- package/dist/memory/tools/MemoryUpdateTool.js.map +1 -0
- package/dist/memory/tools/index.d.ts +32 -0
- package/dist/memory/tools/index.d.ts.map +1 -0
- package/dist/memory/tools/index.js +26 -0
- package/dist/memory/tools/index.js.map +1 -0
- package/package.json +6 -1
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview JSON importer for AgentOS memory brain.
|
|
3
|
+
*
|
|
4
|
+
* Reads a JSON file produced by `JsonExporter` (or a compatible schema) and
|
|
5
|
+
* merges its traces, knowledge nodes, and edges into a target `SqliteBrain`.
|
|
6
|
+
* Deduplication is performed via SHA-256 content hash — any trace whose hash
|
|
7
|
+
* already exists in the target brain is skipped rather than duplicated.
|
|
8
|
+
*
|
|
9
|
+
* @module memory/io/JsonImporter
|
|
10
|
+
*/
|
|
11
|
+
import fs from 'node:fs/promises';
|
|
12
|
+
import crypto from 'node:crypto';
|
|
13
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// JsonImporter
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
/**
|
|
18
|
+
* Imports a `JsonExporter`-compatible JSON file into a `SqliteBrain`.
|
|
19
|
+
*
|
|
20
|
+
* **Usage:**
|
|
21
|
+
* ```ts
|
|
22
|
+
* const importer = new JsonImporter(brain);
|
|
23
|
+
* const result = await importer.import('/path/to/export.json');
|
|
24
|
+
* console.log(result.imported, result.skipped, result.errors);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export class JsonImporter {
|
|
28
|
+
/**
|
|
29
|
+
* @param brain - The target `SqliteBrain` to import into.
|
|
30
|
+
*/
|
|
31
|
+
constructor(brain) {
|
|
32
|
+
this.brain = brain;
|
|
33
|
+
}
|
|
34
|
+
// -------------------------------------------------------------------------
|
|
35
|
+
// Public API
|
|
36
|
+
// -------------------------------------------------------------------------
|
|
37
|
+
/**
|
|
38
|
+
* Read and merge a JSON export file into the target brain.
|
|
39
|
+
*
|
|
40
|
+
* Validation:
|
|
41
|
+
* - The file must be valid JSON.
|
|
42
|
+
* - The top-level object must contain a `traces` array.
|
|
43
|
+
*
|
|
44
|
+
* Deduplication:
|
|
45
|
+
* - For `memory_traces`: SHA-256 of `content` is used as the dedup key.
|
|
46
|
+
* Existing rows with the same hash are skipped.
|
|
47
|
+
* - For `knowledge_nodes`: SHA-256 of `label` + `type`.
|
|
48
|
+
* - For `knowledge_edges`: SHA-256 of `source_id` + `target_id` + `type`.
|
|
49
|
+
*
|
|
50
|
+
* @param sourcePath - Absolute path to the JSON file to import.
|
|
51
|
+
* @returns `ImportResult` with counts of imported, skipped, and errored items.
|
|
52
|
+
*/
|
|
53
|
+
async import(sourcePath) {
|
|
54
|
+
const result = { imported: 0, skipped: 0, errors: [] };
|
|
55
|
+
// ---- Load + parse ----
|
|
56
|
+
let raw;
|
|
57
|
+
try {
|
|
58
|
+
raw = await fs.readFile(sourcePath, 'utf8');
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
result.errors.push(`Failed to read file: ${String(err)}`);
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
let payload;
|
|
65
|
+
try {
|
|
66
|
+
payload = JSON.parse(raw);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
result.errors.push(`Invalid JSON: ${String(err)}`);
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
if (!Array.isArray(payload.traces)) {
|
|
73
|
+
result.errors.push('Invalid export format: missing top-level "traces" array.');
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
// ---- Import in a single transaction for atomicity ----
|
|
77
|
+
this.brain.db.transaction(() => {
|
|
78
|
+
this._importTraces(payload.traces, result);
|
|
79
|
+
this._importNodes(payload.nodes ?? [], result);
|
|
80
|
+
this._importEdges(payload.edges ?? [], result);
|
|
81
|
+
})();
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
// -------------------------------------------------------------------------
|
|
85
|
+
// Private helpers
|
|
86
|
+
// -------------------------------------------------------------------------
|
|
87
|
+
/**
|
|
88
|
+
* Compute a SHA-256 hex digest of arbitrary string content.
|
|
89
|
+
* Used as a stable dedup key across import operations.
|
|
90
|
+
*
|
|
91
|
+
* @param content - The string to hash.
|
|
92
|
+
* @returns 64-character lowercase hex string.
|
|
93
|
+
*/
|
|
94
|
+
_sha256(content) {
|
|
95
|
+
return crypto.createHash('sha256').update(content, 'utf8').digest('hex');
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Import memory trace records into `memory_traces`.
|
|
99
|
+
*
|
|
100
|
+
* Each trace is deduplicated by the SHA-256 of its `content` field.
|
|
101
|
+
* If a trace with the same content hash already exists, it is skipped.
|
|
102
|
+
*
|
|
103
|
+
* @param traces - Array of serialised trace objects from the export.
|
|
104
|
+
* @param result - Mutable `ImportResult` to accumulate counts.
|
|
105
|
+
*/
|
|
106
|
+
_importTraces(traces, result) {
|
|
107
|
+
const db = this.brain.db;
|
|
108
|
+
// Prepare dedup check using a JSON column approach — we store the content
|
|
109
|
+
// hash in the `metadata` JSON under the key `__import_hash`. This lets us
|
|
110
|
+
// do a fast exact-match lookup without a schema change.
|
|
111
|
+
const checkStmt = db.prepare(`SELECT id FROM memory_traces WHERE json_extract(metadata, '$.import_hash') = ? LIMIT 1`);
|
|
112
|
+
const insertStmt = db.prepare(`INSERT INTO memory_traces
|
|
113
|
+
(id, type, scope, content, embedding, strength, created_at, last_accessed,
|
|
114
|
+
retrieval_count, tags, emotions, metadata, deleted)
|
|
115
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
116
|
+
for (const t of traces) {
|
|
117
|
+
try {
|
|
118
|
+
const hash = this._sha256(t.content);
|
|
119
|
+
const existing = checkStmt.get(hash);
|
|
120
|
+
if (existing) {
|
|
121
|
+
result.skipped++;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
// Merge import_hash into the metadata JSON so future imports can dedup.
|
|
125
|
+
let meta = {};
|
|
126
|
+
try {
|
|
127
|
+
meta = JSON.parse(t.metadata ?? '{}');
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// If metadata is malformed, start fresh.
|
|
131
|
+
}
|
|
132
|
+
meta['import_hash'] = hash;
|
|
133
|
+
// Decode embedding if present.
|
|
134
|
+
let embeddingBuf = null;
|
|
135
|
+
if (typeof t.embedding === 'string') {
|
|
136
|
+
embeddingBuf = Buffer.from(t.embedding, 'base64');
|
|
137
|
+
}
|
|
138
|
+
insertStmt.run(t.id ?? `mt_${uuidv4()}`, t.type ?? 'episodic', t.scope ?? 'user', t.content, embeddingBuf, t.strength ?? 1.0, t.created_at ?? Date.now(), t.last_accessed ?? null, t.retrieval_count ?? 0, t.tags ?? '[]', t.emotions ?? '{}', JSON.stringify(meta), t.deleted ?? 0);
|
|
139
|
+
result.imported++;
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
result.errors.push(`Trace import error: ${String(err)}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Import knowledge node records into `knowledge_nodes`.
|
|
148
|
+
*
|
|
149
|
+
* Dedup key: SHA-256 of `label` concatenated with `type`.
|
|
150
|
+
*
|
|
151
|
+
* @param nodes - Array of serialised node objects.
|
|
152
|
+
* @param result - Mutable `ImportResult` to accumulate counts.
|
|
153
|
+
*/
|
|
154
|
+
_importNodes(nodes, result) {
|
|
155
|
+
const db = this.brain.db;
|
|
156
|
+
const checkStmt = db.prepare(`SELECT id FROM knowledge_nodes WHERE json_extract(properties, '$.import_hash') = ? LIMIT 1`);
|
|
157
|
+
const insertStmt = db.prepare(`INSERT OR IGNORE INTO knowledge_nodes
|
|
158
|
+
(id, type, label, properties, embedding, confidence, source, created_at)
|
|
159
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
160
|
+
for (const n of nodes) {
|
|
161
|
+
try {
|
|
162
|
+
const hash = this._sha256(`${n.label ?? ''}::${n.type ?? ''}`);
|
|
163
|
+
const existing = checkStmt.get(hash);
|
|
164
|
+
if (existing) {
|
|
165
|
+
result.skipped++;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
let props = {};
|
|
169
|
+
try {
|
|
170
|
+
props = JSON.parse(n.properties ?? '{}');
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
// ignore malformed JSON
|
|
174
|
+
}
|
|
175
|
+
props['import_hash'] = hash;
|
|
176
|
+
let embeddingBuf = null;
|
|
177
|
+
if (typeof n.embedding === 'string') {
|
|
178
|
+
embeddingBuf = Buffer.from(n.embedding, 'base64');
|
|
179
|
+
}
|
|
180
|
+
insertStmt.run(n.id ?? `kn_${uuidv4()}`, n.type ?? 'concept', n.label ?? '', JSON.stringify(props), embeddingBuf, n.confidence ?? 1.0, n.source ?? '{}', n.created_at ?? Date.now());
|
|
181
|
+
result.imported++;
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
result.errors.push(`Node import error: ${String(err)}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Import knowledge edge records into `knowledge_edges`.
|
|
190
|
+
*
|
|
191
|
+
* Dedup key: SHA-256 of `source_id + target_id + type`.
|
|
192
|
+
* Edges referencing non-existent nodes are silently skipped (FK constraint).
|
|
193
|
+
*
|
|
194
|
+
* @param edges - Array of serialised edge objects.
|
|
195
|
+
* @param result - Mutable `ImportResult` to accumulate counts.
|
|
196
|
+
*/
|
|
197
|
+
_importEdges(edges, result) {
|
|
198
|
+
const db = this.brain.db;
|
|
199
|
+
const checkStmt = db.prepare(`SELECT id FROM knowledge_edges WHERE json_extract(metadata, '$.import_hash') = ? LIMIT 1`);
|
|
200
|
+
const insertStmt = db.prepare(`INSERT OR IGNORE INTO knowledge_edges
|
|
201
|
+
(id, source_id, target_id, type, weight, bidirectional, metadata, created_at)
|
|
202
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
203
|
+
for (const e of edges) {
|
|
204
|
+
try {
|
|
205
|
+
if (!e.source_id || !e.target_id) {
|
|
206
|
+
result.skipped++;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
const hash = this._sha256(`${e.source_id}::${e.target_id}::${e.type ?? ''}`);
|
|
210
|
+
const existing = checkStmt.get(hash);
|
|
211
|
+
if (existing) {
|
|
212
|
+
result.skipped++;
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
let meta = {};
|
|
216
|
+
try {
|
|
217
|
+
meta = JSON.parse(e.metadata ?? '{}');
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
// ignore malformed JSON
|
|
221
|
+
}
|
|
222
|
+
meta['import_hash'] = hash;
|
|
223
|
+
insertStmt.run(e.id ?? `ke_${uuidv4()}`, e.source_id, e.target_id, e.type ?? 'related_to', e.weight ?? 1.0, e.bidirectional ?? 0, JSON.stringify(meta), e.created_at ?? Date.now());
|
|
224
|
+
result.imported++;
|
|
225
|
+
}
|
|
226
|
+
catch (err) {
|
|
227
|
+
// FK constraint violation (referenced node doesn't exist) is common
|
|
228
|
+
// when importing partial exports — log but don't fail.
|
|
229
|
+
result.errors.push(`Edge import error: ${String(err)}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=JsonImporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonImporter.js","sourceRoot":"","sources":["../../../src/memory/io/JsonImporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Markdown exporter for AgentOS memory brain.
|
|
3
|
+
*
|
|
4
|
+
* Creates a directory of Markdown files — one per memory trace — organised
|
|
5
|
+
* into a `{output}/{scope}/{type}/` folder hierarchy. Each file contains
|
|
6
|
+
* YAML front-matter (id, type, scope, strength, tags, createdAt) followed
|
|
7
|
+
* by the plain-text trace content.
|
|
8
|
+
*
|
|
9
|
+
* The `gray-matter` library is used to serialise the front-matter block so
|
|
10
|
+
* that the same library can later round-trip back via `MarkdownImporter`.
|
|
11
|
+
*
|
|
12
|
+
* ## Folder layout
|
|
13
|
+
* ```
|
|
14
|
+
* {outputDir}/
|
|
15
|
+
* user/
|
|
16
|
+
* episodic/
|
|
17
|
+
* mt_abc123.md
|
|
18
|
+
* mt_def456.md
|
|
19
|
+
* semantic/
|
|
20
|
+
* mt_789.md
|
|
21
|
+
* thread/
|
|
22
|
+
* procedural/
|
|
23
|
+
* ...
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @module memory/io/MarkdownExporter
|
|
27
|
+
*/
|
|
28
|
+
import type { ExportOptions } from '../facade/types.js';
|
|
29
|
+
import type { SqliteBrain } from '../store/SqliteBrain.js';
|
|
30
|
+
/** Raw row shape from the `memory_traces` table. */
|
|
31
|
+
interface TraceRow {
|
|
32
|
+
id: string;
|
|
33
|
+
type: string;
|
|
34
|
+
scope: string;
|
|
35
|
+
content: string;
|
|
36
|
+
strength: number;
|
|
37
|
+
created_at: number;
|
|
38
|
+
tags: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Exports memory traces as Markdown files with YAML front-matter.
|
|
42
|
+
*
|
|
43
|
+
* **Usage:**
|
|
44
|
+
* ```ts
|
|
45
|
+
* const exporter = new MarkdownExporter(brain);
|
|
46
|
+
* await exporter.export('/path/to/vault');
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare class MarkdownExporter {
|
|
50
|
+
protected readonly brain: SqliteBrain;
|
|
51
|
+
/**
|
|
52
|
+
* @param brain - The `SqliteBrain` instance to read from.
|
|
53
|
+
*/
|
|
54
|
+
constructor(brain: SqliteBrain);
|
|
55
|
+
/**
|
|
56
|
+
* Export all memory traces as `.md` files into `outputDir`.
|
|
57
|
+
*
|
|
58
|
+
* Directories are created on demand (equivalent to `mkdir -p`).
|
|
59
|
+
*
|
|
60
|
+
* @param outputDir - Root directory to write the Markdown vault into.
|
|
61
|
+
* @param options - Optional export configuration (currently unused but
|
|
62
|
+
* accepted for API consistency with other exporters).
|
|
63
|
+
*/
|
|
64
|
+
export(outputDir: string, _options?: ExportOptions): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Build the Markdown content for a single trace.
|
|
67
|
+
*
|
|
68
|
+
* Subclasses (e.g. `ObsidianExporter`) override this to inject wiki-links
|
|
69
|
+
* and `#tag` decorations into the body.
|
|
70
|
+
*
|
|
71
|
+
* @param trace - Parsed trace row from the database.
|
|
72
|
+
* @returns Full Markdown file content (front-matter + body).
|
|
73
|
+
*/
|
|
74
|
+
protected buildFileContent(trace: TraceRow): string;
|
|
75
|
+
/**
|
|
76
|
+
* Determine the relative file path for a trace within the output directory.
|
|
77
|
+
*
|
|
78
|
+
* Default: `{scope}/{type}/{id}.md`
|
|
79
|
+
*
|
|
80
|
+
* @param trace - The trace row.
|
|
81
|
+
* @returns Relative path string (no leading slash).
|
|
82
|
+
*/
|
|
83
|
+
protected traceRelativePath(trace: TraceRow): string;
|
|
84
|
+
/**
|
|
85
|
+
* Write a single trace to disk.
|
|
86
|
+
*
|
|
87
|
+
* Creates any missing parent directories before writing.
|
|
88
|
+
*
|
|
89
|
+
* @param outputDir - Root output directory.
|
|
90
|
+
* @param trace - Trace row to serialise.
|
|
91
|
+
*/
|
|
92
|
+
private _writeTrace;
|
|
93
|
+
}
|
|
94
|
+
export {};
|
|
95
|
+
//# sourceMappingURL=MarkdownExporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownExporter.d.ts","sourceRoot":"","sources":["../../../src/memory/io/MarkdownExporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAM3D,oDAAoD;AACpD,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAMD;;;;;;;;GAQG;AACH,qBAAa,gBAAgB;IAIf,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW;IAHjD;;OAEG;gBAC4B,KAAK,EAAE,WAAW;IAMjD;;;;;;;;OAQG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxE;;;;;;;;OAQG;IACH,SAAS,CAAC,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM;IAmBnD;;;;;;;OAOG;IACH,SAAS,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM;IAQpD;;;;;;;OAOG;YACW,WAAW;CAU1B"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Markdown exporter for AgentOS memory brain.
|
|
3
|
+
*
|
|
4
|
+
* Creates a directory of Markdown files — one per memory trace — organised
|
|
5
|
+
* into a `{output}/{scope}/{type}/` folder hierarchy. Each file contains
|
|
6
|
+
* YAML front-matter (id, type, scope, strength, tags, createdAt) followed
|
|
7
|
+
* by the plain-text trace content.
|
|
8
|
+
*
|
|
9
|
+
* The `gray-matter` library is used to serialise the front-matter block so
|
|
10
|
+
* that the same library can later round-trip back via `MarkdownImporter`.
|
|
11
|
+
*
|
|
12
|
+
* ## Folder layout
|
|
13
|
+
* ```
|
|
14
|
+
* {outputDir}/
|
|
15
|
+
* user/
|
|
16
|
+
* episodic/
|
|
17
|
+
* mt_abc123.md
|
|
18
|
+
* mt_def456.md
|
|
19
|
+
* semantic/
|
|
20
|
+
* mt_789.md
|
|
21
|
+
* thread/
|
|
22
|
+
* procedural/
|
|
23
|
+
* ...
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @module memory/io/MarkdownExporter
|
|
27
|
+
*/
|
|
28
|
+
import fs from 'node:fs/promises';
|
|
29
|
+
import path from 'node:path';
|
|
30
|
+
import matter from 'gray-matter';
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// MarkdownExporter
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
/**
|
|
35
|
+
* Exports memory traces as Markdown files with YAML front-matter.
|
|
36
|
+
*
|
|
37
|
+
* **Usage:**
|
|
38
|
+
* ```ts
|
|
39
|
+
* const exporter = new MarkdownExporter(brain);
|
|
40
|
+
* await exporter.export('/path/to/vault');
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export class MarkdownExporter {
|
|
44
|
+
/**
|
|
45
|
+
* @param brain - The `SqliteBrain` instance to read from.
|
|
46
|
+
*/
|
|
47
|
+
constructor(brain) {
|
|
48
|
+
this.brain = brain;
|
|
49
|
+
}
|
|
50
|
+
// -------------------------------------------------------------------------
|
|
51
|
+
// Public API
|
|
52
|
+
// -------------------------------------------------------------------------
|
|
53
|
+
/**
|
|
54
|
+
* Export all memory traces as `.md` files into `outputDir`.
|
|
55
|
+
*
|
|
56
|
+
* Directories are created on demand (equivalent to `mkdir -p`).
|
|
57
|
+
*
|
|
58
|
+
* @param outputDir - Root directory to write the Markdown vault into.
|
|
59
|
+
* @param options - Optional export configuration (currently unused but
|
|
60
|
+
* accepted for API consistency with other exporters).
|
|
61
|
+
*/
|
|
62
|
+
async export(outputDir, _options) {
|
|
63
|
+
const db = this.brain.db;
|
|
64
|
+
const traces = db
|
|
65
|
+
.prepare('SELECT id, type, scope, content, strength, created_at, tags FROM memory_traces WHERE deleted = 0')
|
|
66
|
+
.all();
|
|
67
|
+
await Promise.all(traces.map((trace) => this._writeTrace(outputDir, trace)));
|
|
68
|
+
}
|
|
69
|
+
// -------------------------------------------------------------------------
|
|
70
|
+
// Protected helpers (overridden by ObsidianExporter)
|
|
71
|
+
// -------------------------------------------------------------------------
|
|
72
|
+
/**
|
|
73
|
+
* Build the Markdown content for a single trace.
|
|
74
|
+
*
|
|
75
|
+
* Subclasses (e.g. `ObsidianExporter`) override this to inject wiki-links
|
|
76
|
+
* and `#tag` decorations into the body.
|
|
77
|
+
*
|
|
78
|
+
* @param trace - Parsed trace row from the database.
|
|
79
|
+
* @returns Full Markdown file content (front-matter + body).
|
|
80
|
+
*/
|
|
81
|
+
buildFileContent(trace) {
|
|
82
|
+
let tags = [];
|
|
83
|
+
try {
|
|
84
|
+
tags = JSON.parse(trace.tags);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
tags = [];
|
|
88
|
+
}
|
|
89
|
+
// gray-matter's `stringify` method generates the YAML block for us.
|
|
90
|
+
return matter.stringify(trace.content, {
|
|
91
|
+
id: trace.id,
|
|
92
|
+
type: trace.type,
|
|
93
|
+
scope: trace.scope,
|
|
94
|
+
strength: trace.strength,
|
|
95
|
+
tags,
|
|
96
|
+
createdAt: trace.created_at,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Determine the relative file path for a trace within the output directory.
|
|
101
|
+
*
|
|
102
|
+
* Default: `{scope}/{type}/{id}.md`
|
|
103
|
+
*
|
|
104
|
+
* @param trace - The trace row.
|
|
105
|
+
* @returns Relative path string (no leading slash).
|
|
106
|
+
*/
|
|
107
|
+
traceRelativePath(trace) {
|
|
108
|
+
return path.join(trace.scope, trace.type, `${trace.id}.md`);
|
|
109
|
+
}
|
|
110
|
+
// -------------------------------------------------------------------------
|
|
111
|
+
// Private helpers
|
|
112
|
+
// -------------------------------------------------------------------------
|
|
113
|
+
/**
|
|
114
|
+
* Write a single trace to disk.
|
|
115
|
+
*
|
|
116
|
+
* Creates any missing parent directories before writing.
|
|
117
|
+
*
|
|
118
|
+
* @param outputDir - Root output directory.
|
|
119
|
+
* @param trace - Trace row to serialise.
|
|
120
|
+
*/
|
|
121
|
+
async _writeTrace(outputDir, trace) {
|
|
122
|
+
const relPath = this.traceRelativePath(trace);
|
|
123
|
+
const absPath = path.join(outputDir, relPath);
|
|
124
|
+
// Ensure parent directory exists.
|
|
125
|
+
await fs.mkdir(path.dirname(absPath), { recursive: true });
|
|
126
|
+
const content = this.buildFileContent(trace);
|
|
127
|
+
await fs.writeFile(absPath, content, 'utf8');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=MarkdownExporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownExporter.js","sourceRoot":"","sources":["../../../src/memory/io/MarkdownExporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,aAAa,CAAC;AAmBjC,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,OAAO,gBAAgB;IAC3B;;OAEG;IACH,YAA+B,KAAkB;QAAlB,UAAK,GAAL,KAAK,CAAa;IAAG,CAAC;IAErD,4EAA4E;IAC5E,aAAa;IACb,4EAA4E;IAE5E;;;;;;;;OAQG;IACH,KAAK,CAAC,MAAM,CAAC,SAAiB,EAAE,QAAwB;QACtD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAEzB,MAAM,MAAM,GAAG,EAAE;aACd,OAAO,CACN,kGAAkG,CACnG;aACA,GAAG,EAAE,CAAC;QAET,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAC1D,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,qDAAqD;IACrD,4EAA4E;IAE5E;;;;;;;;OAQG;IACO,gBAAgB,CAAC,KAAe;QACxC,IAAI,IAAI,GAAa,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAa,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,GAAG,EAAE,CAAC;QACZ,CAAC;QAED,oEAAoE;QACpE,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE;YACrC,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,IAAI;YACJ,SAAS,EAAE,KAAK,CAAC,UAAU;SAC5B,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACO,iBAAiB,CAAC,KAAe;QACzC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IAC9D,CAAC;IAED,4EAA4E;IAC5E,kBAAkB;IAClB,4EAA4E;IAE5E;;;;;;;OAOG;IACK,KAAK,CAAC,WAAW,CAAC,SAAiB,EAAE,KAAe;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAE9C,kCAAkC;QAClC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3D,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;CACF"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Markdown importer for AgentOS memory brain.
|
|
3
|
+
*
|
|
4
|
+
* Recursively walks a directory of Markdown files and inserts each file as a
|
|
5
|
+
* memory trace in the target `SqliteBrain`. Front-matter fields (parsed via
|
|
6
|
+
* `gray-matter`) are mapped to trace columns; the document body becomes the
|
|
7
|
+
* trace content.
|
|
8
|
+
*
|
|
9
|
+
* Deduplication uses SHA-256 of the content body — files already present in
|
|
10
|
+
* the target brain (same hash in `metadata.import_hash`) are skipped.
|
|
11
|
+
*
|
|
12
|
+
* @module memory/io/MarkdownImporter
|
|
13
|
+
*/
|
|
14
|
+
import type { ImportResult } from '../facade/types.js';
|
|
15
|
+
import type { SqliteBrain } from '../store/SqliteBrain.js';
|
|
16
|
+
/**
|
|
17
|
+
* Parsed front-matter fields extracted from a Markdown trace file.
|
|
18
|
+
* All fields are optional — the importer falls back to safe defaults.
|
|
19
|
+
*/
|
|
20
|
+
interface TraceFrontmatter {
|
|
21
|
+
id?: string;
|
|
22
|
+
type?: string;
|
|
23
|
+
scope?: string;
|
|
24
|
+
strength?: number;
|
|
25
|
+
tags?: string[];
|
|
26
|
+
createdAt?: number;
|
|
27
|
+
[key: string]: unknown;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Imports Markdown files from a directory into a `SqliteBrain`.
|
|
31
|
+
*
|
|
32
|
+
* **Usage:**
|
|
33
|
+
* ```ts
|
|
34
|
+
* const importer = new MarkdownImporter(brain);
|
|
35
|
+
* const result = await importer.import('/path/to/vault');
|
|
36
|
+
* console.log(result.imported, result.skipped);
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare class MarkdownImporter {
|
|
40
|
+
protected readonly brain: SqliteBrain;
|
|
41
|
+
/**
|
|
42
|
+
* @param brain - The target `SqliteBrain` to import into.
|
|
43
|
+
*/
|
|
44
|
+
constructor(brain: SqliteBrain);
|
|
45
|
+
/**
|
|
46
|
+
* Recursively walk `sourceDir`, parse every `.md` file, and insert traces.
|
|
47
|
+
*
|
|
48
|
+
* Non-Markdown files are silently ignored. Files that fail to parse are
|
|
49
|
+
* recorded in `result.errors` and processing continues.
|
|
50
|
+
*
|
|
51
|
+
* @param sourceDir - Directory to recursively scan for `.md` files.
|
|
52
|
+
* @returns `ImportResult` with counts of imported, skipped, and errored items.
|
|
53
|
+
*/
|
|
54
|
+
import(sourceDir: string): Promise<ImportResult>;
|
|
55
|
+
/**
|
|
56
|
+
* Post-process a parsed file before it is inserted into the database.
|
|
57
|
+
*
|
|
58
|
+
* The base implementation is a no-op. `ObsidianImporter` overrides this
|
|
59
|
+
* to extract `[[wikilinks]]` and `#tags`.
|
|
60
|
+
*
|
|
61
|
+
* @param _filePath - Absolute path of the source file.
|
|
62
|
+
* @param _frontmatter - Parsed front-matter data.
|
|
63
|
+
* @param _body - Markdown body content.
|
|
64
|
+
* @param _result - Mutable result accumulator.
|
|
65
|
+
* @param _traceId - The ID assigned (or taken from front-matter) for this trace.
|
|
66
|
+
*/
|
|
67
|
+
protected postProcess(_filePath: string, _frontmatter: TraceFrontmatter, _body: string, _result: ImportResult, _traceId: string): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Recursively collect all `.md` file paths under `dir`.
|
|
70
|
+
*
|
|
71
|
+
* @param dir - Root directory to scan.
|
|
72
|
+
* @returns Sorted list of absolute file paths.
|
|
73
|
+
*/
|
|
74
|
+
private _collectMarkdownFiles;
|
|
75
|
+
/**
|
|
76
|
+
* Parse and insert a single Markdown file.
|
|
77
|
+
*
|
|
78
|
+
* @param filePath - Absolute path to the `.md` file.
|
|
79
|
+
* @param result - Mutable `ImportResult` accumulator.
|
|
80
|
+
*/
|
|
81
|
+
private _processFile;
|
|
82
|
+
}
|
|
83
|
+
export {};
|
|
84
|
+
//# sourceMappingURL=MarkdownImporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownImporter.d.ts","sourceRoot":"","sources":["../../../src/memory/io/MarkdownImporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAM3D;;;GAGG;AACH,UAAU,gBAAgB;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAMD;;;;;;;;;GASG;AACH,qBAAa,gBAAgB;IAIf,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW;IAHjD;;OAEG;gBAC4B,KAAK,EAAE,WAAW;IAMjD;;;;;;;;OAQG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAgBtD;;;;;;;;;;;OAWG;cACa,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,gBAAgB,EAC9B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAQhB;;;;;OAKG;YACW,qBAAqB;IAyBnC;;;;;OAKG;YACW,YAAY;CAuE3B"}
|