@semiont/make-meaning 0.2.30 → 0.2.31
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 +177 -570
- package/dist/index.d.ts +489 -9
- package/dist/index.js +2702 -109
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -1,46 +1,57 @@
|
|
|
1
1
|
# @semiont/make-meaning
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@semiont/make-meaning)
|
|
4
3
|
[](https://github.com/The-AI-Alliance/semiont/actions/workflows/package-tests.yml?query=branch%3Amain+is%3Asuccess+job%3A%22Test+make-meaning%22)
|
|
4
|
+
[](https://codecov.io/gh/The-AI-Alliance/semiont?flag=make-meaning)
|
|
5
|
+
[](https://www.npmjs.com/package/@semiont/make-meaning)
|
|
6
|
+
[](https://www.npmjs.com/package/@semiont/make-meaning)
|
|
7
|
+
[](https://github.com/The-AI-Alliance/semiont/blob/main/LICENSE)
|
|
5
8
|
|
|
6
9
|
**Making meaning from resources through context assembly, pattern detection, and relationship reasoning.**
|
|
7
10
|
|
|
8
|
-
This package transforms raw resources into meaningful, interconnected knowledge
|
|
11
|
+
This package transforms raw resources into meaningful, interconnected knowledge through:
|
|
9
12
|
|
|
10
13
|
- **Context Assembly**: Gathering resource metadata, content, and annotations from distributed storage
|
|
11
14
|
- **Pattern Detection**: AI-powered discovery of semantic patterns (comments, highlights, assessments, tags)
|
|
12
|
-
- **
|
|
15
|
+
- **Relationship Reasoning**: Navigating connections between resources through graph traversal
|
|
16
|
+
- **Job Workers**: Asynchronous processing of detection tasks with progress tracking
|
|
13
17
|
|
|
14
|
-
##
|
|
18
|
+
## Quick Start
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
```bash
|
|
21
|
+
npm install @semiont/make-meaning
|
|
22
|
+
```
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
### Start Make-Meaning Service
|
|
19
25
|
|
|
20
|
-
|
|
26
|
+
The simplest way to use make-meaning infrastructure is through the service module:
|
|
21
27
|
|
|
22
|
-
```
|
|
23
|
-
|
|
28
|
+
```typescript
|
|
29
|
+
import { startMakeMeaning } from '@semiont/make-meaning';
|
|
30
|
+
import type { EnvironmentConfig } from '@semiont/core';
|
|
31
|
+
|
|
32
|
+
// Start all infrastructure (job queue, workers, graph consumer)
|
|
33
|
+
const makeMeaning = await startMakeMeaning(config);
|
|
34
|
+
|
|
35
|
+
// Access job queue for route handlers
|
|
36
|
+
const jobQueue = makeMeaning.jobQueue;
|
|
37
|
+
|
|
38
|
+
// Graceful shutdown
|
|
39
|
+
await makeMeaning.stop();
|
|
24
40
|
```
|
|
25
41
|
|
|
26
|
-
|
|
42
|
+
This single call initializes:
|
|
43
|
+
- Job queue
|
|
44
|
+
- All 6 detection/generation workers
|
|
45
|
+
- Graph consumer (event-to-graph synchronization)
|
|
46
|
+
- Shared event store connection
|
|
27
47
|
|
|
28
48
|
### Assemble Resource Context
|
|
29
49
|
|
|
30
50
|
```typescript
|
|
31
51
|
import { ResourceContext } from '@semiont/make-meaning';
|
|
32
|
-
import type { EnvironmentConfig } from '@semiont/core';
|
|
33
52
|
|
|
34
|
-
// Get resource metadata from event-sourced view storage
|
|
35
53
|
const resource = await ResourceContext.getResourceMetadata(resourceId, config);
|
|
36
|
-
|
|
37
|
-
// List all resources with optional filtering
|
|
38
|
-
const resources = await ResourceContext.listResources(
|
|
39
|
-
{ createdAfter: '2024-01-01' },
|
|
40
|
-
config
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
// Add content previews to resource descriptors
|
|
54
|
+
const resources = await ResourceContext.listResources({ createdAfter: '2024-01-01' }, config);
|
|
44
55
|
const withContent = await ResourceContext.addContentPreviews(resources, config);
|
|
45
56
|
```
|
|
46
57
|
|
|
@@ -59,13 +70,6 @@ const context = await AnnotationContext.buildLLMContext(
|
|
|
59
70
|
config,
|
|
60
71
|
{ contextLines: 5 }
|
|
61
72
|
);
|
|
62
|
-
|
|
63
|
-
// Generate AI summary of an annotation
|
|
64
|
-
const summary = await AnnotationContext.generateAnnotationSummary(
|
|
65
|
-
annotationId,
|
|
66
|
-
resourceId,
|
|
67
|
-
config
|
|
68
|
-
);
|
|
69
73
|
```
|
|
70
74
|
|
|
71
75
|
### Detect Semantic Patterns
|
|
@@ -90,15 +94,6 @@ const highlights = await AnnotationDetection.detectHighlights(
|
|
|
90
94
|
0.5
|
|
91
95
|
);
|
|
92
96
|
|
|
93
|
-
// Detect passages that merit assessment/evaluation
|
|
94
|
-
const assessments = await AnnotationDetection.detectAssessments(
|
|
95
|
-
resourceId,
|
|
96
|
-
config,
|
|
97
|
-
'Evaluate clarity and technical accuracy',
|
|
98
|
-
'constructive',
|
|
99
|
-
0.6
|
|
100
|
-
);
|
|
101
|
-
|
|
102
97
|
// Detect and extract structured tags from text using ontology schemas
|
|
103
98
|
const tags = await AnnotationDetection.detectTags(
|
|
104
99
|
resourceId,
|
|
@@ -108,41 +103,6 @@ const tags = await AnnotationDetection.detectTags(
|
|
|
108
103
|
);
|
|
109
104
|
```
|
|
110
105
|
|
|
111
|
-
### Structured Tagging with Ontology Schemas
|
|
112
|
-
|
|
113
|
-
A powerful use case is **structured tagging** using tag schemas defined in [@semiont/ontology](../ontology/). For example, legal writing can be analyzed using the IRAC framework (Issue, Rule, Application, Conclusion):
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
import { AnnotationDetection } from '@semiont/make-meaning';
|
|
117
|
-
|
|
118
|
-
// Analyze a legal brief using IRAC schema
|
|
119
|
-
const categories = ['issue', 'rule', 'application', 'conclusion'];
|
|
120
|
-
|
|
121
|
-
for (const category of categories) {
|
|
122
|
-
const tags = await AnnotationDetection.detectTags(
|
|
123
|
-
resourceId,
|
|
124
|
-
config,
|
|
125
|
-
'irac', // Tag schema from @semiont/ontology
|
|
126
|
-
category // Which category to detect
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
console.log(`Found ${tags.length} ${category} passages`);
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
**Why this matters:**
|
|
134
|
-
|
|
135
|
-
When you tag multiple documents with the same schema (e.g., IRAC for legal briefs, IMRAD for scientific papers), you create a **structured semantic layer** across your corpus:
|
|
136
|
-
|
|
137
|
-
- **Rich traversal**: Find all "issue" statements across 100 legal briefs
|
|
138
|
-
- **Cross-document analysis**: Compare how different authors structure their "application" sections
|
|
139
|
-
- **Context retrieval**: When reading one brief, see related "rule" passages from other cases
|
|
140
|
-
- **Graph-based reasoning**: Trace argument patterns across your entire document collection
|
|
141
|
-
|
|
142
|
-
This transforms a collection of unstructured documents into a queryable knowledge base organized by domain-specific rhetorical structures.
|
|
143
|
-
|
|
144
|
-
See [@semiont/ontology](../ontology/) for available tag schemas and how to define custom schemas.
|
|
145
|
-
|
|
146
106
|
### Navigate Resource Relationships
|
|
147
107
|
|
|
148
108
|
```typescript
|
|
@@ -154,473 +114,199 @@ const backlinks = await GraphContext.getBacklinks(resourceId, config);
|
|
|
154
114
|
// Find shortest path between two resources
|
|
155
115
|
const paths = await GraphContext.findPath(fromResourceId, toResourceId, config, 3);
|
|
156
116
|
|
|
157
|
-
// Get all connections for a resource
|
|
158
|
-
const connections = await GraphContext.getResourceConnections(resourceId, config);
|
|
159
|
-
|
|
160
117
|
// Full-text search across all resources
|
|
161
118
|
const results = await GraphContext.searchResources('neural networks', config, 10);
|
|
162
119
|
```
|
|
163
120
|
|
|
164
|
-
|
|
121
|
+
### Use Individual Workers (Advanced)
|
|
165
122
|
|
|
166
|
-
|
|
123
|
+
For fine-grained control, workers can be instantiated directly:
|
|
167
124
|
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
125
|
+
```typescript
|
|
126
|
+
import {
|
|
127
|
+
ReferenceDetectionWorker,
|
|
128
|
+
HighlightDetectionWorker,
|
|
129
|
+
GenerationWorker,
|
|
130
|
+
} from '@semiont/make-meaning';
|
|
131
|
+
import { JobQueue } from '@semiont/jobs';
|
|
132
|
+
import { createEventStore } from '@semiont/event-sourcing';
|
|
133
|
+
|
|
134
|
+
// Create shared dependencies
|
|
135
|
+
const jobQueue = new JobQueue({ dataDir: './data' });
|
|
136
|
+
await jobQueue.initialize();
|
|
137
|
+
const eventStore = createEventStore('./data', 'http://localhost:3000');
|
|
138
|
+
|
|
139
|
+
// Create workers with explicit dependencies
|
|
140
|
+
const referenceWorker = new ReferenceDetectionWorker(jobQueue, config, eventStore);
|
|
141
|
+
const highlightWorker = new HighlightDetectionWorker(jobQueue, config, eventStore);
|
|
142
|
+
const generationWorker = new GenerationWorker(jobQueue, config, eventStore);
|
|
143
|
+
|
|
144
|
+
// Start workers
|
|
145
|
+
await Promise.all([
|
|
146
|
+
referenceWorker.start(),
|
|
147
|
+
highlightWorker.start(),
|
|
148
|
+
generationWorker.start(),
|
|
149
|
+
]);
|
|
186
150
|
```
|
|
187
151
|
|
|
188
|
-
**
|
|
152
|
+
**Note**: In most cases, use `startMakeMeaning()` instead, which handles all initialization automatically.
|
|
189
153
|
|
|
190
|
-
|
|
191
|
-
- **Content-addressed storage**: Content retrieved using checksums, enabling deduplication and caching
|
|
192
|
-
- **Graph-backed relationships**: @semiont/graph provides graph traversal for backlinks, paths, and connections
|
|
193
|
-
- **Separation of concerns**: Detection logic (make-meaning) is separate from job orchestration (backend)
|
|
154
|
+
## Documentation
|
|
194
155
|
|
|
195
|
-
|
|
156
|
+
- **[API Reference](./docs/api-reference.md)** - Complete API documentation for all classes and methods
|
|
157
|
+
- **[Job Workers](./docs/job-workers.md)** - Asynchronous task processing with progress tracking
|
|
158
|
+
- **[Architecture](./docs/architecture.md)** - System design and data flow
|
|
159
|
+
- **[Examples](./docs/examples.md)** - Common use cases and patterns
|
|
196
160
|
|
|
197
|
-
##
|
|
161
|
+
## Philosophy
|
|
198
162
|
|
|
199
|
-
|
|
163
|
+
Resources don't exist in isolation. A document becomes meaningful when we understand its annotations, its relationships to other resources, and the patterns within its content. `@semiont/make-meaning` provides the infrastructure to:
|
|
200
164
|
|
|
201
|
-
|
|
165
|
+
1. **Assemble context** from event-sourced storage
|
|
166
|
+
2. **Detect patterns** using AI inference
|
|
167
|
+
3. **Reason about relationships** through graph traversal
|
|
202
168
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
*/
|
|
209
|
-
static async getResourceMetadata(
|
|
210
|
-
resourceId: ResourceId,
|
|
211
|
-
config: EnvironmentConfig
|
|
212
|
-
): Promise<ResourceDescriptor | null>
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* List resources with optional filtering
|
|
216
|
-
* Implementation: packages/make-meaning/src/resource-context.ts:30-48
|
|
217
|
-
*/
|
|
218
|
-
static async listResources(
|
|
219
|
-
filters: ListResourcesFilters | undefined,
|
|
220
|
-
config: EnvironmentConfig
|
|
221
|
-
): Promise<ResourceDescriptor[]>
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Add content previews to resource descriptors
|
|
225
|
-
* Implementation: packages/make-meaning/src/resource-context.ts:50-77
|
|
226
|
-
*/
|
|
227
|
-
static async addContentPreviews(
|
|
228
|
-
resources: ResourceDescriptor[],
|
|
229
|
-
config: EnvironmentConfig
|
|
230
|
-
): Promise<Array<ResourceDescriptor & { content: string }>>
|
|
231
|
-
}
|
|
232
|
-
```
|
|
169
|
+
This is the "applied meaning-making" layer - it sits between low-level AI primitives ([@semiont/inference](../inference/)) and high-level application orchestration ([apps/backend](../../apps/backend/)).
|
|
170
|
+
|
|
171
|
+
## Infrastructure Ownership
|
|
172
|
+
|
|
173
|
+
**MakeMeaningService is the single source of truth for all infrastructure:**
|
|
233
174
|
|
|
234
|
-
**Filters:**
|
|
235
175
|
```typescript
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
176
|
+
import { startMakeMeaning } from '@semiont/make-meaning';
|
|
177
|
+
|
|
178
|
+
// Create ALL infrastructure once at startup
|
|
179
|
+
const makeMeaning = await startMakeMeaning(config);
|
|
180
|
+
|
|
181
|
+
// Access infrastructure components
|
|
182
|
+
const { eventStore, graphDb, repStore, inferenceClient, jobQueue } = makeMeaning;
|
|
242
183
|
```
|
|
243
184
|
|
|
244
|
-
|
|
185
|
+
**What MakeMeaningService Owns:**
|
|
245
186
|
|
|
246
|
-
|
|
187
|
+
1. **EventStore** - Event log and materialized views (single source of truth)
|
|
188
|
+
2. **GraphDatabase** - Graph database connection for relationships and traversal
|
|
189
|
+
3. **RepresentationStore** - Content-addressed document storage
|
|
190
|
+
4. **InferenceClient** - LLM client for AI operations
|
|
191
|
+
5. **JobQueue** - Background job processing queue
|
|
192
|
+
6. **Workers** - All 6 detection/generation workers
|
|
193
|
+
7. **GraphDBConsumer** - Event-to-graph synchronization
|
|
247
194
|
|
|
248
|
-
|
|
249
|
-
class AnnotationContext {
|
|
250
|
-
/**
|
|
251
|
-
* Build LLM context for an annotation (includes surrounding text)
|
|
252
|
-
* Implementation: packages/make-meaning/src/annotation-context.ts:35-120
|
|
253
|
-
*/
|
|
254
|
-
static async buildLLMContext(
|
|
255
|
-
annotationUri: AnnotationUri,
|
|
256
|
-
resourceId: ResourceId,
|
|
257
|
-
config: EnvironmentConfig,
|
|
258
|
-
options: BuildContextOptions
|
|
259
|
-
): Promise<AnnotationLLMContextResponse>
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Get all annotations for a resource, organized by motivation
|
|
263
|
-
* Implementation: packages/make-meaning/src/annotation-context.ts:122-172
|
|
264
|
-
*/
|
|
265
|
-
static async getResourceAnnotations(
|
|
266
|
-
resourceId: ResourceId,
|
|
267
|
-
config: EnvironmentConfig
|
|
268
|
-
): Promise<ResourceAnnotations>
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Get all annotations for a resource (flat list)
|
|
272
|
-
* Implementation: packages/make-meaning/src/annotation-context.ts:174-187
|
|
273
|
-
*/
|
|
274
|
-
static async getAllAnnotations(
|
|
275
|
-
resourceId: ResourceId,
|
|
276
|
-
config: EnvironmentConfig
|
|
277
|
-
): Promise<Annotation[]>
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Get a specific annotation by ID
|
|
281
|
-
* Implementation: packages/make-meaning/src/annotation-context.ts:189-202
|
|
282
|
-
*/
|
|
283
|
-
static async getAnnotation(
|
|
284
|
-
annotationId: AnnotationId,
|
|
285
|
-
resourceId: ResourceId,
|
|
286
|
-
config: EnvironmentConfig
|
|
287
|
-
): Promise<Annotation | null>
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* List annotations with optional filtering
|
|
291
|
-
* Implementation: packages/make-meaning/src/annotation-context.ts:204-225
|
|
292
|
-
*/
|
|
293
|
-
static async listAnnotations(
|
|
294
|
-
filters: { resourceId?: ResourceId; type?: AnnotationCategory } | undefined,
|
|
295
|
-
config: EnvironmentConfig
|
|
296
|
-
): Promise<Annotation[]>
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Check if a resource exists in view storage
|
|
300
|
-
* Implementation: packages/make-meaning/src/annotation-context.ts:227-236
|
|
301
|
-
*/
|
|
302
|
-
static async resourceExists(
|
|
303
|
-
resourceId: ResourceId,
|
|
304
|
-
config: EnvironmentConfig
|
|
305
|
-
): Promise<boolean>
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Get resource statistics (version, last updated)
|
|
309
|
-
* Implementation: packages/make-meaning/src/annotation-context.ts:238-254
|
|
310
|
-
*/
|
|
311
|
-
static async getResourceStats(
|
|
312
|
-
resourceId: ResourceId,
|
|
313
|
-
config: EnvironmentConfig
|
|
314
|
-
): Promise<{
|
|
315
|
-
resourceId: ResourceId;
|
|
316
|
-
version: number;
|
|
317
|
-
updatedAt: string;
|
|
318
|
-
}>
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* Get annotation context (surrounding text)
|
|
322
|
-
* Implementation: packages/make-meaning/src/annotation-context.ts:256-314
|
|
323
|
-
*/
|
|
324
|
-
static async getAnnotationContext(
|
|
325
|
-
annotationId: AnnotationId,
|
|
326
|
-
resourceId: ResourceId,
|
|
327
|
-
contextBefore: number,
|
|
328
|
-
contextAfter: number,
|
|
329
|
-
config: EnvironmentConfig
|
|
330
|
-
): Promise<AnnotationContextResponse>
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* Generate AI summary of an annotation
|
|
334
|
-
* Implementation: packages/make-meaning/src/annotation-context.ts:316-381
|
|
335
|
-
*/
|
|
336
|
-
static async generateAnnotationSummary(
|
|
337
|
-
annotationId: AnnotationId,
|
|
338
|
-
resourceId: ResourceId,
|
|
339
|
-
config: EnvironmentConfig
|
|
340
|
-
): Promise<ContextualSummaryResponse>
|
|
341
|
-
}
|
|
342
|
-
```
|
|
195
|
+
**Critical Design Rule:**
|
|
343
196
|
|
|
344
|
-
**Options:**
|
|
345
197
|
```typescript
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
198
|
+
// ✅ CORRECT: Access infrastructure from MakeMeaningService
|
|
199
|
+
const { graphDb } = makeMeaning;
|
|
200
|
+
|
|
201
|
+
// ❌ WRONG: NEVER create infrastructure outside of startMakeMeaning()
|
|
202
|
+
const graphDb = await getGraphDatabase(config); // NEVER DO THIS
|
|
203
|
+
const repStore = new FilesystemRepresentationStore(...); // NEVER DO THIS
|
|
204
|
+
const eventStore = createEventStore(...); // NEVER DO THIS
|
|
350
205
|
```
|
|
351
206
|
|
|
352
|
-
|
|
207
|
+
**Why This Matters:**
|
|
353
208
|
|
|
354
|
-
|
|
209
|
+
- **Single initialization** - All infrastructure created once, shared everywhere
|
|
210
|
+
- **No resource leaks** - Single connection per resource type (database, storage, etc.)
|
|
211
|
+
- **Consistent configuration** - Same config across all components
|
|
212
|
+
- **Testability** - Single injection point for mocking
|
|
213
|
+
- **Lifecycle management** - Centralized shutdown via `makeMeaning.stop()`
|
|
355
214
|
|
|
356
|
-
|
|
357
|
-
class GraphContext {
|
|
358
|
-
/**
|
|
359
|
-
* Get all resources referencing this resource (backlinks)
|
|
360
|
-
* Requires graph traversal - uses @semiont/graph
|
|
361
|
-
* Implementation: packages/make-meaning/src/graph-context.ts:26-30
|
|
362
|
-
*/
|
|
363
|
-
static async getBacklinks(
|
|
364
|
-
resourceId: ResourceId,
|
|
365
|
-
config: EnvironmentConfig
|
|
366
|
-
): Promise<Annotation[]>
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Find shortest path between two resources
|
|
370
|
-
* Requires graph traversal - uses @semiont/graph
|
|
371
|
-
* Implementation: packages/make-meaning/src/graph-context.ts:36-44
|
|
372
|
-
*/
|
|
373
|
-
static async findPath(
|
|
374
|
-
fromResourceId: ResourceId,
|
|
375
|
-
toResourceId: ResourceId,
|
|
376
|
-
config: EnvironmentConfig,
|
|
377
|
-
maxDepth?: number
|
|
378
|
-
): Promise<GraphPath[]>
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Get resource connections (graph edges)
|
|
382
|
-
* Requires graph traversal - uses @semiont/graph
|
|
383
|
-
* Implementation: packages/make-meaning/src/graph-context.ts:50-53
|
|
384
|
-
*/
|
|
385
|
-
static async getResourceConnections(
|
|
386
|
-
resourceId: ResourceId,
|
|
387
|
-
config: EnvironmentConfig
|
|
388
|
-
): Promise<GraphConnection[]>
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* Search resources by name (cross-resource query)
|
|
392
|
-
* Requires full-text search - uses @semiont/graph
|
|
393
|
-
* Implementation: packages/make-meaning/src/graph-context.ts:59-62
|
|
394
|
-
*/
|
|
395
|
-
static async searchResources(
|
|
396
|
-
query: string,
|
|
397
|
-
config: EnvironmentConfig,
|
|
398
|
-
limit?: number
|
|
399
|
-
): Promise<ResourceDescriptor[]>
|
|
400
|
-
}
|
|
401
|
-
```
|
|
215
|
+
**Implementation Pattern:**
|
|
402
216
|
|
|
403
|
-
|
|
217
|
+
- Backend creates MakeMeaningService in [apps/backend/src/index.ts:56](../../apps/backend/src/index.ts#L56)
|
|
218
|
+
- Routes access via Hono context: `c.get('makeMeaning')`
|
|
219
|
+
- Services receive infrastructure as parameters (dependency injection)
|
|
220
|
+
- Workers receive EventStore and InferenceClient via constructor
|
|
404
221
|
|
|
405
|
-
|
|
222
|
+
This architectural pattern prevents duplicate connections, ensures consistent state, and provides clear ownership boundaries across the entire system.
|
|
406
223
|
|
|
407
|
-
|
|
408
|
-
class AnnotationDetection {
|
|
409
|
-
/**
|
|
410
|
-
* Detect passages that merit commentary
|
|
411
|
-
* Implementation: packages/make-meaning/src/annotation-detection.ts:27-65
|
|
412
|
-
* Uses: MotivationPrompts.buildCommentPrompt, MotivationParsers.parseComments
|
|
413
|
-
*/
|
|
414
|
-
static async detectComments(
|
|
415
|
-
resourceId: ResourceId,
|
|
416
|
-
config: EnvironmentConfig,
|
|
417
|
-
instructions?: string,
|
|
418
|
-
tone?: string,
|
|
419
|
-
density?: number
|
|
420
|
-
): Promise<CommentMatch[]>
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* Detect passages that should be highlighted
|
|
424
|
-
* Implementation: packages/make-meaning/src/annotation-detection.ts:67-101
|
|
425
|
-
* Uses: MotivationPrompts.buildHighlightPrompt, MotivationParsers.parseHighlights
|
|
426
|
-
*/
|
|
427
|
-
static async detectHighlights(
|
|
428
|
-
resourceId: ResourceId,
|
|
429
|
-
config: EnvironmentConfig,
|
|
430
|
-
instructions?: string,
|
|
431
|
-
density?: number
|
|
432
|
-
): Promise<HighlightMatch[]>
|
|
433
|
-
|
|
434
|
-
/**
|
|
435
|
-
* Detect passages that merit assessment/evaluation
|
|
436
|
-
* Implementation: packages/make-meaning/src/annotation-detection.ts:103-141
|
|
437
|
-
* Uses: MotivationPrompts.buildAssessmentPrompt, MotivationParsers.parseAssessments
|
|
438
|
-
*/
|
|
439
|
-
static async detectAssessments(
|
|
440
|
-
resourceId: ResourceId,
|
|
441
|
-
config: EnvironmentConfig,
|
|
442
|
-
instructions?: string,
|
|
443
|
-
tone?: string,
|
|
444
|
-
density?: number
|
|
445
|
-
): Promise<AssessmentMatch[]>
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Detect and extract structured tags from text
|
|
449
|
-
* Implementation: packages/make-meaning/src/annotation-detection.ts:143-197
|
|
450
|
-
* Uses: MotivationPrompts.buildTagPrompt, MotivationParsers.parseTags
|
|
451
|
-
*/
|
|
452
|
-
static async detectTags(
|
|
453
|
-
resourceId: ResourceId,
|
|
454
|
-
config: EnvironmentConfig,
|
|
455
|
-
schemaId: string,
|
|
456
|
-
category: string
|
|
457
|
-
): Promise<TagMatch[]>
|
|
458
|
-
}
|
|
459
|
-
```
|
|
224
|
+
## Architecture
|
|
460
225
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
start: number;
|
|
476
|
-
end: number;
|
|
477
|
-
prefix?: string;
|
|
478
|
-
suffix?: string;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
interface AssessmentMatch {
|
|
482
|
-
exact: string;
|
|
483
|
-
start: number;
|
|
484
|
-
end: number;
|
|
485
|
-
prefix?: string;
|
|
486
|
-
suffix?: string;
|
|
487
|
-
assessment: string; // The AI-generated assessment
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
interface TagMatch {
|
|
491
|
-
exact: string;
|
|
492
|
-
start: number;
|
|
493
|
-
end: number;
|
|
494
|
-
prefix?: string;
|
|
495
|
-
suffix?: string;
|
|
496
|
-
category: string; // The tag category
|
|
497
|
-
}
|
|
226
|
+
Three-layer design separating concerns:
|
|
227
|
+
|
|
228
|
+
```mermaid
|
|
229
|
+
graph TB
|
|
230
|
+
Backend["<b>apps/backend</b><br/>Job orchestration, HTTP APIs, streaming"]
|
|
231
|
+
MakeMeaning["<b>@semiont/make-meaning</b><br/>Context assembly, detection/generation,<br/>prompt engineering, response parsing,<br/>job workers"]
|
|
232
|
+
Inference["<b>@semiont/inference</b><br/>AI primitives only:<br/>generateText, client management"]
|
|
233
|
+
|
|
234
|
+
Backend --> MakeMeaning
|
|
235
|
+
MakeMeaning --> Inference
|
|
236
|
+
|
|
237
|
+
style Backend fill:#e1f5ff
|
|
238
|
+
style MakeMeaning fill:#fff4e6
|
|
239
|
+
style Inference fill:#f3e5f5
|
|
498
240
|
```
|
|
499
241
|
|
|
500
|
-
**
|
|
242
|
+
**Key principles:**
|
|
501
243
|
|
|
502
|
-
-
|
|
503
|
-
-
|
|
504
|
-
-
|
|
244
|
+
- **Centralized infrastructure**: All infrastructure owned by MakeMeaningService (single initialization point)
|
|
245
|
+
- **Event-sourced context**: Resources and annotations assembled from event streams
|
|
246
|
+
- **Content-addressed storage**: Content retrieved using checksums (deduplication, caching)
|
|
247
|
+
- **Graph-backed relationships**: @semiont/graph provides traversal for backlinks, paths, connections
|
|
248
|
+
- **Explicit dependencies**: Workers receive infrastructure via constructor (dependency injection, no singletons)
|
|
249
|
+
- **No ad-hoc creation**: Routes and services NEVER create their own infrastructure instances
|
|
505
250
|
|
|
506
|
-
|
|
251
|
+
See [Architecture](./docs/architecture.md) for complete details.
|
|
507
252
|
|
|
508
|
-
|
|
253
|
+
## Exports
|
|
509
254
|
|
|
510
|
-
|
|
511
|
-
import { AnnotationContext, ResourceContext } from '@semiont/make-meaning';
|
|
255
|
+
### Service Module (Primary)
|
|
512
256
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
resourceId,
|
|
517
|
-
config,
|
|
518
|
-
{ contextLines: 10 }
|
|
519
|
-
);
|
|
257
|
+
- `startMakeMeaning(config)` - Initialize all make-meaning infrastructure
|
|
258
|
+
- `MakeMeaningService` - Type for service return value
|
|
259
|
+
- `GraphDBConsumer` - Graph consumer class (for advanced use)
|
|
520
260
|
|
|
521
|
-
|
|
522
|
-
// - The annotation itself
|
|
523
|
-
// - Surrounding text (10 lines before/after)
|
|
524
|
-
// - Resource metadata
|
|
525
|
-
// - Related annotations in the vicinity
|
|
526
|
-
```
|
|
261
|
+
### Context Assembly
|
|
527
262
|
|
|
528
|
-
|
|
263
|
+
- `ResourceContext` - Resource metadata and content
|
|
264
|
+
- `AnnotationContext` - Annotation queries and context building
|
|
265
|
+
- `GraphContext` - Graph traversal and search
|
|
529
266
|
|
|
530
|
-
|
|
531
|
-
import { AnnotationDetection } from '@semiont/make-meaning';
|
|
532
|
-
import { createEventStore } from '@semiont/event-sourcing';
|
|
267
|
+
### Detection & Generation
|
|
533
268
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
269
|
+
- `AnnotationDetection` - AI-powered semantic pattern detection (orchestrates detection pipeline)
|
|
270
|
+
- `MotivationPrompts` - Prompt builders for comment/highlight/assessment/tag detection
|
|
271
|
+
- `MotivationParsers` - Response parsers with offset validation
|
|
272
|
+
- `extractEntities` - Entity extraction with context-based disambiguation
|
|
273
|
+
- `generateResourceFromTopic` - Markdown resource generation with language support
|
|
274
|
+
- `generateResourceSummary` - Resource summarization
|
|
275
|
+
- `generateReferenceSuggestions` - Smart suggestion generation
|
|
541
276
|
|
|
542
|
-
|
|
543
|
-
const eventStore = await createEventStore(config);
|
|
544
|
-
for (const highlight of highlights) {
|
|
545
|
-
const annotation = {
|
|
546
|
-
'@context': 'http://www.w3.org/ns/anno.jsonld',
|
|
547
|
-
type: 'Annotation',
|
|
548
|
-
id: generateAnnotationId(),
|
|
549
|
-
motivation: 'highlighting',
|
|
550
|
-
target: {
|
|
551
|
-
type: 'SpecificResource',
|
|
552
|
-
source: resourceUri,
|
|
553
|
-
selector: [
|
|
554
|
-
{
|
|
555
|
-
type: 'TextPositionSelector',
|
|
556
|
-
start: highlight.start,
|
|
557
|
-
end: highlight.end,
|
|
558
|
-
},
|
|
559
|
-
{
|
|
560
|
-
type: 'TextQuoteSelector',
|
|
561
|
-
exact: highlight.exact,
|
|
562
|
-
prefix: highlight.prefix,
|
|
563
|
-
suffix: highlight.suffix,
|
|
564
|
-
},
|
|
565
|
-
],
|
|
566
|
-
},
|
|
567
|
-
body: [],
|
|
568
|
-
};
|
|
569
|
-
|
|
570
|
-
await eventStore.appendEvent({
|
|
571
|
-
type: 'annotation.added',
|
|
572
|
-
resourceId,
|
|
573
|
-
userId,
|
|
574
|
-
version: 1,
|
|
575
|
-
payload: { annotation },
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
```
|
|
277
|
+
### Job Workers (Advanced)
|
|
579
278
|
|
|
580
|
-
|
|
279
|
+
- `ReferenceDetectionWorker` - Entity reference detection
|
|
280
|
+
- `GenerationWorker` - AI content generation
|
|
281
|
+
- `HighlightDetectionWorker` - Highlight detection
|
|
282
|
+
- `CommentDetectionWorker` - Comment detection
|
|
283
|
+
- `AssessmentDetectionWorker` - Assessment detection
|
|
284
|
+
- `TagDetectionWorker` - Structured tag detection
|
|
581
285
|
|
|
582
|
-
|
|
583
|
-
import { GraphContext, ResourceContext } from '@semiont/make-meaning';
|
|
286
|
+
**Note**: Workers are typically managed by `startMakeMeaning()`, not instantiated directly.
|
|
584
287
|
|
|
585
|
-
|
|
586
|
-
const backlinks = await GraphContext.getBacklinks(resourceId, config);
|
|
587
|
-
console.log(`Found ${backlinks.length} resources linking here`);
|
|
288
|
+
See [Job Workers](./docs/job-workers.md) for implementation details.
|
|
588
289
|
|
|
589
|
-
|
|
590
|
-
const paths = await GraphContext.findPath(sourceId, targetId, config, 3);
|
|
591
|
-
if (paths.length > 0) {
|
|
592
|
-
console.log(`Shortest path has ${paths[0].nodes.length} nodes`);
|
|
593
|
-
}
|
|
290
|
+
### Types
|
|
594
291
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
292
|
+
```typescript
|
|
293
|
+
export type {
|
|
294
|
+
CommentMatch,
|
|
295
|
+
HighlightMatch,
|
|
296
|
+
AssessmentMatch,
|
|
297
|
+
TagMatch,
|
|
298
|
+
} from './detection/motivation-parsers';
|
|
299
|
+
|
|
300
|
+
export type { ExtractedEntity } from './detection/entity-extractor';
|
|
598
301
|
```
|
|
599
302
|
|
|
600
303
|
## Configuration
|
|
601
304
|
|
|
602
|
-
All methods require an `EnvironmentConfig` object
|
|
305
|
+
All methods require an `EnvironmentConfig` object:
|
|
603
306
|
|
|
604
307
|
```typescript
|
|
605
|
-
|
|
606
|
-
services: {
|
|
607
|
-
backend: {
|
|
608
|
-
publicURL: string; // Base URL for resource URIs
|
|
609
|
-
};
|
|
610
|
-
openai?: {
|
|
611
|
-
apiKey: string; // Required for detection methods
|
|
612
|
-
model?: string; // Default: 'gpt-4o-mini'
|
|
613
|
-
temperature?: number; // Default: 0.7
|
|
614
|
-
};
|
|
615
|
-
};
|
|
616
|
-
storage: {
|
|
617
|
-
base: string; // Base path for filesystem storage
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
```
|
|
308
|
+
import type { EnvironmentConfig } from '@semiont/core';
|
|
621
309
|
|
|
622
|
-
Example:
|
|
623
|
-
```typescript
|
|
624
310
|
const config: EnvironmentConfig = {
|
|
625
311
|
services: {
|
|
626
312
|
backend: {
|
|
@@ -649,95 +335,16 @@ const config: EnvironmentConfig = {
|
|
|
649
335
|
- **[@semiont/graph](../graph/)**: Neo4j graph database client
|
|
650
336
|
- **[@semiont/ontology](../ontology/)**: Schema definitions for tags
|
|
651
337
|
- **[@semiont/inference](../inference/)**: AI primitives (prompts, parsers, generateText)
|
|
338
|
+
- **[@semiont/jobs](../jobs/)**: Job queue and worker base class
|
|
652
339
|
|
|
653
|
-
##
|
|
654
|
-
|
|
655
|
-
See [packages/inference/README.md](../inference/README.md) for details on the AI pipeline.
|
|
656
|
-
|
|
657
|
-
**High-level flow:**
|
|
658
|
-
|
|
659
|
-
1. **Context Assembly**: `ResourceContext.getResourceMetadata()` retrieves resource content
|
|
660
|
-
2. **Prompt Building**: `MotivationPrompts.buildXPrompt()` creates AI prompt with domain knowledge
|
|
661
|
-
3. **AI Inference**: `generateText()` calls OpenAI API with prompt
|
|
662
|
-
4. **Response Parsing**: `MotivationParsers.parseX()` extracts structured matches from response
|
|
663
|
-
5. **Offset Validation**: Parser validates that `start`/`end` offsets match `exact` text in content
|
|
664
|
-
|
|
665
|
-
**Example for highlights:**
|
|
666
|
-
|
|
667
|
-
```typescript
|
|
668
|
-
// 1. Get content
|
|
669
|
-
const resource = await ResourceContext.getResourceMetadata(resourceId, config);
|
|
670
|
-
const content = await representationStore.retrieve(resource.contentId);
|
|
671
|
-
|
|
672
|
-
// 2. Build prompt
|
|
673
|
-
const prompt = MotivationPrompts.buildHighlightPrompt(
|
|
674
|
-
content,
|
|
675
|
-
'Find key definitions',
|
|
676
|
-
0.6
|
|
677
|
-
);
|
|
678
|
-
|
|
679
|
-
// 3. Generate AI response
|
|
680
|
-
const response = await generateText(prompt, config);
|
|
681
|
-
|
|
682
|
-
// 4. Parse and validate
|
|
683
|
-
const highlights = MotivationParsers.parseHighlights(response, content);
|
|
684
|
-
// Returns: HighlightMatch[] with validated offsets
|
|
685
|
-
```
|
|
686
|
-
|
|
687
|
-
## Worker Integration
|
|
340
|
+
## Testing
|
|
688
341
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
- [assessment-detection-worker.ts](../../apps/backend/src/jobs/workers/assessment-detection-worker.ts) - Delegated detection to `AnnotationDetection.detectAssessments()`
|
|
694
|
-
- [tag-detection-worker.ts](../../apps/backend/src/jobs/workers/tag-detection-worker.ts) - Delegated detection to `AnnotationDetection.detectTags()`
|
|
695
|
-
|
|
696
|
-
Workers handle:
|
|
697
|
-
- Job lifecycle (pending → running → completed/failed)
|
|
698
|
-
- Progress tracking and event emission
|
|
699
|
-
- Annotation creation via event store
|
|
700
|
-
- Error handling and retries
|
|
701
|
-
|
|
702
|
-
All detection logic lives in `@semiont/make-meaning`, keeping workers focused on orchestration.
|
|
703
|
-
|
|
704
|
-
## Future Direction
|
|
705
|
-
|
|
706
|
-
### Deterministic Reasoning
|
|
707
|
-
|
|
708
|
-
Future versions will add deterministic reasoning capabilities alongside AI-powered detection:
|
|
709
|
-
|
|
710
|
-
- **Rule-based pattern matching**: Detect annotations using regex, string matching, or custom predicates
|
|
711
|
-
- **Ontology-driven inference**: Apply OWL/RDFS reasoning over resource relationships
|
|
712
|
-
- **Compositional reasoning**: Combine multiple reasoning strategies (AI + rules + ontology)
|
|
713
|
-
|
|
714
|
-
Example (aspirational):
|
|
715
|
-
|
|
716
|
-
```typescript
|
|
717
|
-
// AI-powered detection
|
|
718
|
-
const aiHighlights = await AnnotationDetection.detectHighlights(resourceId, config);
|
|
719
|
-
|
|
720
|
-
// Rule-based detection
|
|
721
|
-
const ruleHighlights = await ResourceReasoning.findMatches(resourceId, {
|
|
722
|
-
pattern: /\btheorem\b.*\bproof\b/gi,
|
|
723
|
-
motivation: 'highlighting',
|
|
724
|
-
});
|
|
725
|
-
|
|
726
|
-
// Ontology-based reasoning
|
|
727
|
-
const inferences = await ResourceReasoning.inferRelationships(resourceId, {
|
|
728
|
-
ontology: 'http://example.org/math-ontology',
|
|
729
|
-
rules: ['transitive-proof-chain'],
|
|
730
|
-
});
|
|
342
|
+
```bash
|
|
343
|
+
npm test # Run tests
|
|
344
|
+
npm run test:watch # Watch mode
|
|
345
|
+
npm run test:coverage # Coverage report
|
|
731
346
|
```
|
|
732
347
|
|
|
733
|
-
This will enable hybrid approaches where AI handles semantic understanding and deterministic rules handle structural patterns.
|
|
734
|
-
|
|
735
|
-
### Enhanced Context Assembly
|
|
736
|
-
|
|
737
|
-
- **Multi-resource context**: Build context spanning multiple related resources
|
|
738
|
-
- **Temporal context**: Access historical versions of resources and annotations
|
|
739
|
-
- **Provenance tracking**: Track reasoning chains and decision paths
|
|
740
|
-
|
|
741
348
|
## License
|
|
742
349
|
|
|
743
|
-
|
|
350
|
+
Apache-2.0
|