@mce-bt/microagents-memory 0.1.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.
@@ -0,0 +1,321 @@
1
+ /**
2
+ * Simple extraction adapter that uses a completion function.
3
+ * Wraps any LLM completion call into the ExtractionLLMAdapter interface.
4
+ */
5
+ export function createExtractionAdapter(completeFn) {
6
+ return {
7
+ async extract(systemPrompt, text) {
8
+ const raw = await completeFn([
9
+ { role: 'system', content: systemPrompt },
10
+ { role: 'user', content: text },
11
+ ]);
12
+ // Try to parse JSON from the response (handle markdown code blocks)
13
+ const jsonMatch = raw.match(/```(?:json)?\s*([\s\S]*?)```/) ?? [null, raw];
14
+ const jsonStr = (jsonMatch[1] ?? raw).trim();
15
+ try {
16
+ const parsed = JSON.parse(jsonStr);
17
+ return {
18
+ entities: Array.isArray(parsed.entities) ? parsed.entities : [],
19
+ relations: Array.isArray(parsed.relations) ? parsed.relations : [],
20
+ };
21
+ }
22
+ catch {
23
+ // If parsing fails, return empty result
24
+ return { entities: [], relations: [] };
25
+ }
26
+ },
27
+ };
28
+ }
29
+ // ─── Extraction Prompt ───
30
+ const EXTRACTION_SYSTEM_PROMPT = `You are a memory extraction system. Your job is to extract structured knowledge from conversation logs.
31
+
32
+ Extract:
33
+ 1. **Entities**: People, tools, concepts, organizations, projects, preferences, or any other notable noun mentioned.
34
+ 2. **Relations**: Directed connections between entities in active voice (e.g., "uses", "prefers", "works_on", "is_part_of").
35
+
36
+ Rules:
37
+ - Entity names should be normalized (e.g., "John Smith" not "john" or "John"). Use underscores for multi-word names.
38
+ - Observations should be atomic — one fact per observation.
39
+ - Relations should be in active voice (e.g., "works_at", "prefers", "created").
40
+ - Only extract facts that are explicitly stated or strongly implied.
41
+ - Do NOT infer facts that are speculative.
42
+ - Entity types should be lowercase (e.g., "person", "tool", "concept", "project", "preference").
43
+ - If an entity was mentioned before with different info, include all observations — deduplication happens downstream.
44
+
45
+ Respond ONLY with valid JSON matching this schema:
46
+ {
47
+ "entities": [
48
+ {
49
+ "name": "Entity_Name",
50
+ "entityType": "type",
51
+ "observations": ["fact 1", "fact 2"]
52
+ }
53
+ ],
54
+ "relations": [
55
+ {
56
+ "from": "Entity_A",
57
+ "to": "Entity_B",
58
+ "relationType": "relation_type"
59
+ }
60
+ ]
61
+ }
62
+
63
+ If there is nothing worth extracting, return: {"entities": [], "relations": []}`;
64
+ /**
65
+ * Memory Extraction Pipeline — Extracts structured knowledge from conversations.
66
+ *
67
+ * Inspired by Mem0's automatic extraction pattern. Uses an LLM to analyze
68
+ * conversation logs and extract entities, observations, and relations,
69
+ * then stores them in the knowledge graph with temporal validity.
70
+ */
71
+ export class MemoryExtractor {
72
+ kg;
73
+ llm;
74
+ logger;
75
+ constructor(kg, llm, logger) {
76
+ this.kg = kg;
77
+ this.llm = llm;
78
+ this.logger = logger;
79
+ }
80
+ /**
81
+ * Extract knowledge from a list of memory entries (e.g., a session log).
82
+ * Formats entries into text, sends to LLM for extraction, then stores results.
83
+ */
84
+ async extractFromEntries(entries) {
85
+ const start = performance.now();
86
+ const stats = {
87
+ entitiesCreated: 0,
88
+ entitiesUpdated: 0,
89
+ relationsCreated: 0,
90
+ relationsSuperseded: 0,
91
+ durationMs: 0,
92
+ };
93
+ if (entries.length === 0) {
94
+ stats.durationMs = performance.now() - start;
95
+ return stats;
96
+ }
97
+ // Format entries into readable text
98
+ const text = this.formatEntries(entries);
99
+ // Extract via LLM
100
+ const result = await this.llm.extract(EXTRACTION_SYSTEM_PROMPT, text);
101
+ this.logger?.debug('Extraction result', {
102
+ entityCount: result.entities.length,
103
+ relationCount: result.relations.length,
104
+ });
105
+ // Store extracted entities
106
+ for (const entity of result.entities) {
107
+ try {
108
+ const existing = await this.kg.getEntityByName(entity.name);
109
+ await this.kg.upsertEntity({
110
+ name: entity.name,
111
+ entityType: entity.entityType,
112
+ observations: entity.observations,
113
+ });
114
+ if (existing) {
115
+ stats.entitiesUpdated++;
116
+ }
117
+ else {
118
+ stats.entitiesCreated++;
119
+ }
120
+ }
121
+ catch (err) {
122
+ this.logger?.warn('Failed to store entity', {
123
+ name: entity.name,
124
+ error: err instanceof Error ? err.message : String(err),
125
+ });
126
+ }
127
+ }
128
+ // Store extracted relations
129
+ for (const relation of result.relations) {
130
+ try {
131
+ const created = await this.kg.createRelation({
132
+ from: relation.from,
133
+ to: relation.to,
134
+ relationType: relation.relationType,
135
+ });
136
+ if (created) {
137
+ stats.relationsCreated++;
138
+ }
139
+ }
140
+ catch (err) {
141
+ this.logger?.warn('Failed to store relation', {
142
+ from: relation.from,
143
+ to: relation.to,
144
+ type: relation.relationType,
145
+ error: err instanceof Error ? err.message : String(err),
146
+ });
147
+ }
148
+ }
149
+ stats.durationMs = performance.now() - start;
150
+ this.logger?.info('Memory extraction complete', {
151
+ entitiesCreated: stats.entitiesCreated,
152
+ entitiesUpdated: stats.entitiesUpdated,
153
+ relationsCreated: stats.relationsCreated,
154
+ durationMs: Math.round(stats.durationMs),
155
+ });
156
+ return stats;
157
+ }
158
+ /**
159
+ * Extract knowledge from raw text (e.g., a document or summary).
160
+ */
161
+ async extractFromText(text) {
162
+ const start = performance.now();
163
+ const stats = {
164
+ entitiesCreated: 0,
165
+ entitiesUpdated: 0,
166
+ relationsCreated: 0,
167
+ relationsSuperseded: 0,
168
+ durationMs: 0,
169
+ };
170
+ if (!text.trim()) {
171
+ stats.durationMs = performance.now() - start;
172
+ return stats;
173
+ }
174
+ const result = await this.llm.extract(EXTRACTION_SYSTEM_PROMPT, text);
175
+ for (const entity of result.entities) {
176
+ try {
177
+ const existing = await this.kg.getEntityByName(entity.name);
178
+ await this.kg.upsertEntity({
179
+ name: entity.name,
180
+ entityType: entity.entityType,
181
+ observations: entity.observations,
182
+ });
183
+ if (existing)
184
+ stats.entitiesUpdated++;
185
+ else
186
+ stats.entitiesCreated++;
187
+ }
188
+ catch (err) {
189
+ this.logger?.warn('Failed to store entity', {
190
+ name: entity.name,
191
+ error: err instanceof Error ? err.message : String(err),
192
+ });
193
+ }
194
+ }
195
+ for (const relation of result.relations) {
196
+ try {
197
+ const created = await this.kg.createRelation({
198
+ from: relation.from,
199
+ to: relation.to,
200
+ relationType: relation.relationType,
201
+ });
202
+ if (created)
203
+ stats.relationsCreated++;
204
+ }
205
+ catch (err) {
206
+ this.logger?.warn('Failed to store relation', {
207
+ from: relation.from,
208
+ to: relation.to,
209
+ error: err instanceof Error ? err.message : String(err),
210
+ });
211
+ }
212
+ }
213
+ stats.durationMs = performance.now() - start;
214
+ return stats;
215
+ }
216
+ /**
217
+ * Extract with contradiction handling — supersedes existing relations
218
+ * when the LLM finds conflicting facts.
219
+ */
220
+ async extractWithContradictions(entries, existingContext) {
221
+ const start = performance.now();
222
+ const stats = {
223
+ entitiesCreated: 0,
224
+ entitiesUpdated: 0,
225
+ relationsCreated: 0,
226
+ relationsSuperseded: 0,
227
+ durationMs: 0,
228
+ };
229
+ if (entries.length === 0) {
230
+ stats.durationMs = performance.now() - start;
231
+ return stats;
232
+ }
233
+ const text = this.formatEntries(entries);
234
+ const contextualPrompt = existingContext
235
+ ? `${EXTRACTION_SYSTEM_PROMPT}\n\n## Existing Knowledge\nThe following is what is currently known. If anything in the conversation contradicts or updates these facts, extract the NEW information (the old will be automatically superseded):\n\n${existingContext}`
236
+ : EXTRACTION_SYSTEM_PROMPT;
237
+ const result = await this.llm.extract(contextualPrompt, text);
238
+ // Store entities (same as normal extraction)
239
+ for (const entity of result.entities) {
240
+ try {
241
+ const existing = await this.kg.getEntityByName(entity.name);
242
+ await this.kg.upsertEntity({
243
+ name: entity.name,
244
+ entityType: entity.entityType,
245
+ observations: entity.observations,
246
+ });
247
+ if (existing)
248
+ stats.entitiesUpdated++;
249
+ else
250
+ stats.entitiesCreated++;
251
+ }
252
+ catch (err) {
253
+ this.logger?.warn('Failed to store entity', {
254
+ name: entity.name,
255
+ error: err instanceof Error ? err.message : String(err),
256
+ });
257
+ }
258
+ }
259
+ // Store relations with contradiction detection
260
+ for (const relation of result.relations) {
261
+ try {
262
+ // Use supersede to handle contradictions
263
+ const created = await this.kg.supersedRelation({
264
+ from: relation.from,
265
+ to: relation.to,
266
+ relationType: relation.relationType,
267
+ });
268
+ if (created) {
269
+ // Check if a previous relation was invalidated
270
+ const history = await this.kg.getRelationHistory(relation.from, relation.to, relation.relationType);
271
+ if (history.length > 1) {
272
+ stats.relationsSuperseded++;
273
+ }
274
+ stats.relationsCreated++;
275
+ }
276
+ }
277
+ catch (err) {
278
+ this.logger?.warn('Failed to store relation', {
279
+ from: relation.from,
280
+ to: relation.to,
281
+ error: err instanceof Error ? err.message : String(err),
282
+ });
283
+ }
284
+ }
285
+ stats.durationMs = performance.now() - start;
286
+ return stats;
287
+ }
288
+ // ─── Helpers ───
289
+ formatEntries(entries) {
290
+ return entries
291
+ .filter((e) => e.type === 'message' || e.type === 'tool_result')
292
+ .map((e) => {
293
+ const role = e.metadata?.role ?? e.type;
294
+ const ts = new Date(e.timestamp).toISOString();
295
+ return `[${ts}] ${role}: ${e.content}`;
296
+ })
297
+ .join('\n');
298
+ }
299
+ /**
300
+ * Build a text summary of existing knowledge for contradiction detection context.
301
+ */
302
+ async buildExistingContext(entityNames) {
303
+ const lines = [];
304
+ for (const name of entityNames) {
305
+ const entity = await this.kg.getEntityByName(name);
306
+ if (!entity)
307
+ continue;
308
+ lines.push(`Entity: ${entity.name} (${entity.entityType})`);
309
+ for (const obs of entity.observations) {
310
+ lines.push(` - ${obs}`);
311
+ }
312
+ const relations = await this.kg.getEntityRelations(name);
313
+ for (const rel of relations) {
314
+ lines.push(` ${rel.fromName} --[${rel.relationType}]--> ${rel.toName}`);
315
+ }
316
+ lines.push('');
317
+ }
318
+ return lines.join('\n');
319
+ }
320
+ }
321
+ //# sourceMappingURL=memory-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-extractor.js","sourceRoot":"","sources":["../src/memory-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { RegisteredTool } from '@mce-bt/microagents-core';
2
+ import type { MemoryManager } from './manager.js';
3
+ /**
4
+ * Create memory tools that agents can use during conversations.
5
+ * Inspired by Letta's approach of giving agents explicit memory control.
6
+ *
7
+ * Returns an array of RegisteredTool objects ready for the tool registry.
8
+ */
9
+ export declare function createMemoryTools(manager: MemoryManager): RegisteredTool[];
10
+ //# sourceMappingURL=memory-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-tools.d.ts","sourceRoot":"","sources":["../src/memory-tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,aAAa,GACrB,cAAc,EAAE,CAYlB"}
@@ -0,0 +1,239 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Create memory tools that agents can use during conversations.
4
+ * Inspired by Letta's approach of giving agents explicit memory control.
5
+ *
6
+ * Returns an array of RegisteredTool objects ready for the tool registry.
7
+ */
8
+ export function createMemoryTools(manager) {
9
+ const kg = manager.kg;
10
+ if (!kg)
11
+ return [];
12
+ return [
13
+ searchKnowledgeTool(kg),
14
+ storFactTool(kg),
15
+ recallEntityTool(kg),
16
+ relateEntitiesTool(kg),
17
+ listEntitiesTool(kg),
18
+ recallRecentEpisodesTool(manager),
19
+ ];
20
+ }
21
+ // ─── Tool Definitions ───
22
+ function searchKnowledgeTool(kg) {
23
+ return {
24
+ name: 'search_knowledge',
25
+ description: 'Search the knowledge graph for entities, facts, and relationships. ' +
26
+ 'Use this when you need to recall information about people, concepts, tools, ' +
27
+ 'or any previously learned knowledge.',
28
+ parameters: z.object({
29
+ query: z.string().describe('Search query — matches entity names, types, and observations'),
30
+ entityType: z.string().optional().describe('Filter by entity type (e.g., "person", "tool", "concept")'),
31
+ limit: z.number().optional().describe('Max results to return (default: 10)'),
32
+ }),
33
+ visibility: 'internal',
34
+ handler: async (params) => {
35
+ const { query, entityType, limit } = params;
36
+ const entities = await kg.searchEntities({
37
+ query,
38
+ entityType,
39
+ limit: limit ?? 10,
40
+ });
41
+ if (entities.length === 0) {
42
+ return { found: false, message: 'No matching knowledge found.' };
43
+ }
44
+ // For each entity, also fetch its relations
45
+ const results = await Promise.all(entities.map(async (entity) => {
46
+ const relations = await kg.getEntityRelations(entity.name);
47
+ return {
48
+ name: entity.name,
49
+ type: entity.entityType,
50
+ observations: entity.observations,
51
+ relations: relations.map((r) => ({
52
+ from: r.fromName,
53
+ to: r.toName,
54
+ type: r.relationType,
55
+ })),
56
+ };
57
+ }));
58
+ return { found: true, count: results.length, results };
59
+ },
60
+ };
61
+ }
62
+ function storFactTool(kg) {
63
+ return {
64
+ name: 'store_fact',
65
+ description: 'Store a new fact or observation about an entity in long-term memory. ' +
66
+ 'Use this when you learn something important that should be remembered ' +
67
+ 'across conversations (e.g., user preferences, project details, key decisions).',
68
+ parameters: z.object({
69
+ entityName: z.string().describe('Name of the entity (e.g., "user", "Project_Alpha", "Redis")'),
70
+ entityType: z.string().describe('Type of entity (e.g., "person", "project", "tool", "concept", "preference")'),
71
+ observations: z.array(z.string()).describe('List of atomic facts to store (one fact per item)'),
72
+ }),
73
+ visibility: 'internal',
74
+ handler: async (params) => {
75
+ const { entityName, entityType, observations } = params;
76
+ const entity = await kg.upsertEntity({
77
+ name: entityName,
78
+ entityType,
79
+ observations,
80
+ });
81
+ return {
82
+ stored: true,
83
+ entity: entity.name,
84
+ totalObservations: entity.observations.length,
85
+ };
86
+ },
87
+ };
88
+ }
89
+ function recallEntityTool(kg) {
90
+ return {
91
+ name: 'recall_entity',
92
+ description: 'Recall everything known about a specific entity — its observations, ' +
93
+ 'relationships, and history. Use this when you need detailed context ' +
94
+ 'about a person, project, tool, or concept.',
95
+ parameters: z.object({
96
+ name: z.string().describe('Exact name of the entity to recall'),
97
+ includeHistory: z.boolean().optional().describe('Include expired/superseded relations (default: false)'),
98
+ }),
99
+ visibility: 'internal',
100
+ handler: async (params) => {
101
+ const { name, includeHistory } = params;
102
+ const entity = await kg.getEntityByName(name);
103
+ if (!entity) {
104
+ return { found: false, message: `No entity named "${name}" found.` };
105
+ }
106
+ const relations = await kg.getEntityRelations(name, {
107
+ includeExpired: includeHistory ?? false,
108
+ });
109
+ return {
110
+ found: true,
111
+ entity: {
112
+ name: entity.name,
113
+ type: entity.entityType,
114
+ observations: entity.observations,
115
+ createdAt: entity.createdAt.toISOString(),
116
+ updatedAt: entity.updatedAt.toISOString(),
117
+ },
118
+ relations: relations.map((r) => ({
119
+ from: r.fromName,
120
+ to: r.toName,
121
+ type: r.relationType,
122
+ validFrom: r.validFrom.toISOString(),
123
+ validUntil: r.validUntil?.toISOString() ?? null,
124
+ active: r.validUntil === null,
125
+ })),
126
+ };
127
+ },
128
+ };
129
+ }
130
+ function relateEntitiesTool(kg) {
131
+ return {
132
+ name: 'relate_entities',
133
+ description: 'Create a relationship between two entities in the knowledge graph. ' +
134
+ 'Use this to capture connections like "user works_on Project_Alpha" or ' +
135
+ '"Redis is_used_by Coordinator_Agent". If the relationship already exists, ' +
136
+ 'it will be updated (old one preserved in history).',
137
+ parameters: z.object({
138
+ from: z.string().describe('Source entity name'),
139
+ to: z.string().describe('Target entity name'),
140
+ relationType: z.string().describe('Relationship type in active voice (e.g., "works_on", "uses", "prefers")'),
141
+ supersede: z.boolean().optional().describe('If true, replaces any existing relation of same type (default: false)'),
142
+ }),
143
+ visibility: 'internal',
144
+ handler: async (params) => {
145
+ const { from, to, relationType, supersede } = params;
146
+ try {
147
+ let relation;
148
+ if (supersede) {
149
+ relation = await kg.supersedRelation({ from, to, relationType });
150
+ }
151
+ else {
152
+ relation = await kg.createRelation({ from, to, relationType });
153
+ }
154
+ if (relation) {
155
+ return {
156
+ created: true,
157
+ relation: {
158
+ from,
159
+ to,
160
+ type: relationType,
161
+ validFrom: relation.validFrom.toISOString(),
162
+ },
163
+ };
164
+ }
165
+ return { created: false, message: 'Relation already exists.' };
166
+ }
167
+ catch (err) {
168
+ return {
169
+ created: false,
170
+ error: err instanceof Error ? err.message : String(err),
171
+ };
172
+ }
173
+ },
174
+ };
175
+ }
176
+ function listEntitiesTool(kg) {
177
+ return {
178
+ name: 'list_entities',
179
+ description: 'List all known entities, optionally filtered by type. ' +
180
+ 'Use this to see what knowledge is available in memory.',
181
+ parameters: z.object({
182
+ entityType: z.string().optional().describe('Filter by type (e.g., "person", "tool")'),
183
+ limit: z.number().optional().describe('Max results (default: 20)'),
184
+ }),
185
+ visibility: 'internal',
186
+ handler: async (params) => {
187
+ const { entityType, limit } = params;
188
+ const entities = await kg.searchEntities({
189
+ entityType,
190
+ limit: limit ?? 20,
191
+ });
192
+ return {
193
+ count: entities.length,
194
+ entities: entities.map((e) => ({
195
+ name: e.name,
196
+ type: e.entityType,
197
+ observationCount: e.observations.length,
198
+ })),
199
+ };
200
+ },
201
+ };
202
+ }
203
+ function recallRecentEpisodesTool(manager) {
204
+ return {
205
+ name: 'recall_recent_episodes',
206
+ description: 'Recall recent conversation episodes (session summaries). ' +
207
+ 'Use this to remember what happened in past conversations.',
208
+ parameters: z.object({
209
+ domain: z.string().optional().describe('Filter by domain/topic'),
210
+ tags: z.array(z.string()).optional().describe('Filter by tags'),
211
+ limit: z.number().optional().describe('Max episodes to return (default: 5)'),
212
+ }),
213
+ visibility: 'internal',
214
+ handler: async (params) => {
215
+ const { domain, tags, limit } = params;
216
+ const episodes = await manager.mtm.getRecent({
217
+ domain,
218
+ tags,
219
+ limit: limit ?? 5,
220
+ });
221
+ if (episodes.length === 0) {
222
+ return { found: false, message: 'No recent episodes found.' };
223
+ }
224
+ return {
225
+ found: true,
226
+ count: episodes.length,
227
+ episodes: episodes.map((ep) => ({
228
+ id: ep.id,
229
+ summary: ep.summary,
230
+ domain: ep.domain,
231
+ tags: ep.tags,
232
+ startedAt: ep.startedAt.toISOString(),
233
+ endedAt: ep.endedAt?.toISOString() ?? null,
234
+ })),
235
+ };
236
+ },
237
+ };
238
+ }
239
+ //# sourceMappingURL=memory-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-tools.js","sourceRoot":"","sources":["../src/memory-tools.ts"],"names":[],"mappings":"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"}
package/dist/mtm.d.ts ADDED
@@ -0,0 +1,55 @@
1
+ export interface MTMConfig {
2
+ connectionString: string;
3
+ }
4
+ export interface EpisodicMemory {
5
+ id: string;
6
+ agentId: string;
7
+ sessionId: string;
8
+ summary: string;
9
+ tags: string[];
10
+ domain: string | null;
11
+ startedAt: Date;
12
+ endedAt: Date | null;
13
+ metadata: Record<string, unknown>;
14
+ createdAt: Date;
15
+ }
16
+ /**
17
+ * Mid-Term Memory (MTM) — PostgreSQL-backed episodic summaries.
18
+ *
19
+ * Stores session summaries and recent episode timeline.
20
+ * Tagged by domain/topic for efficient querying.
21
+ * "What happened recently regarding X?"
22
+ */
23
+ export declare class MidTermMemory {
24
+ private pool;
25
+ private config;
26
+ private agentId;
27
+ constructor(config: MTMConfig);
28
+ start(agentId: string): Promise<void>;
29
+ stop(): Promise<void>;
30
+ private ensureSchema;
31
+ /**
32
+ * Store a session summary as an episodic memory.
33
+ */
34
+ storeSummary(episode: Omit<EpisodicMemory, 'id' | 'createdAt'>): Promise<string>;
35
+ /**
36
+ * Get recent episodes, optionally filtered by domain or tags.
37
+ */
38
+ getRecent(options?: {
39
+ domain?: string;
40
+ tags?: string[];
41
+ agentId?: string;
42
+ limit?: number;
43
+ sinceDate?: Date;
44
+ }): Promise<EpisodicMemory[]>;
45
+ /**
46
+ * Get a specific episode by ID.
47
+ */
48
+ getById(id: string): Promise<EpisodicMemory | null>;
49
+ /**
50
+ * Delete an episode.
51
+ */
52
+ delete(id: string): Promise<void>;
53
+ private rowToEpisode;
54
+ }
55
+ //# sourceMappingURL=mtm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mtm.d.ts","sourceRoot":"","sources":["../src/mtm.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACxB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAwB;IACpC,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAAc;gBAEjB,MAAM,EAAE,SAAS;IAIvB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOrC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAOb,YAAY;IAwB1B;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAwBtF;;OAEG;IACG,SAAS,CAAC,OAAO,GAAE;QACvB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,IAAI,CAAC;KACb,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAyClC;;OAEG;IACG,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAYzD;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvC,OAAO,CAAC,YAAY;CAcrB"}