@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 CHANGED
@@ -1,46 +1,57 @@
1
1
  # @semiont/make-meaning
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/@semiont/make-meaning)](https://www.npmjs.com/package/@semiont/make-meaning)
4
3
  [![Tests](https://github.com/The-AI-Alliance/semiont/actions/workflows/package-tests.yml/badge.svg)](https://github.com/The-AI-Alliance/semiont/actions/workflows/package-tests.yml?query=branch%3Amain+is%3Asuccess+job%3A%22Test+make-meaning%22)
4
+ [![codecov](https://codecov.io/gh/The-AI-Alliance/semiont/graph/badge.svg?flag=make-meaning)](https://codecov.io/gh/The-AI-Alliance/semiont?flag=make-meaning)
5
+ [![npm version](https://img.shields.io/npm/v/@semiont/make-meaning.svg)](https://www.npmjs.com/package/@semiont/make-meaning)
6
+ [![npm downloads](https://img.shields.io/npm/dm/@semiont/make-meaning.svg)](https://www.npmjs.com/package/@semiont/make-meaning)
7
+ [![License](https://img.shields.io/npm/l/@semiont/make-meaning.svg)](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. It provides the core capabilities for:
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
- - **Graph Reasoning**: Navigating relationships and connections between resources
15
+ - **Relationship Reasoning**: Navigating connections between resources through graph traversal
16
+ - **Job Workers**: Asynchronous processing of detection tasks with progress tracking
13
17
 
14
- ## Philosophy
18
+ ## Quick Start
15
19
 
16
- 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 assemble this context from event-sourced storage, detect semantic patterns using AI, and reason about resource relationships through graph traversal.
20
+ ```bash
21
+ npm install @semiont/make-meaning
22
+ ```
17
23
 
18
- 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/)).
24
+ ### Start Make-Meaning Service
19
25
 
20
- ## Installation
26
+ The simplest way to use make-meaning infrastructure is through the service module:
21
27
 
22
- ```bash
23
- npm install @semiont/make-meaning
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
- ## Quick Start
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
- ## Architecture
121
+ ### Use Individual Workers (Advanced)
165
122
 
166
- `@semiont/make-meaning` implements a **three-layer architecture**:
123
+ For fine-grained control, workers can be instantiated directly:
167
124
 
168
- ```
169
- ┌─────────────────────────────────────────────┐
170
- apps/backend │
171
- Job orchestration, progress tracking, │
172
- HTTP APIs, event emission │
173
- └─────────────────────────────────────────────┘
174
-
175
- ┌─────────────────────────────────────────────┐
176
- │ @semiont/make-meaning │
177
- │ Context assembly, pattern detection, │
178
- │ relationship reasoning │
179
- └─────────────────────────────────────────────┘
180
-
181
- ┌─────────────────────────────────────────────┐
182
- │ @semiont/inference │
183
- │ AI primitives: prompts, parsers,
184
- │ generateText abstraction │
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
- **Key principles:**
152
+ **Note**: In most cases, use `startMakeMeaning()` instead, which handles all initialization automatically.
189
153
 
190
- - **Event-sourced context**: Resources and annotations are assembled from event streams via view storage
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
- See [MAKE-MEANING-PACKAGE.md](../../MAKE-MEANING-PACKAGE.md) for complete architecture documentation.
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
- ## API Reference
161
+ ## Philosophy
198
162
 
199
- ### ResourceContext
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
- Provides resource metadata and content assembly from event-sourced storage.
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
- ```typescript
204
- class ResourceContext {
205
- /**
206
- * Get resource metadata from view storage
207
- * Implementation: packages/make-meaning/src/resource-context.ts:15-28
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
- interface ListResourcesFilters {
237
- createdAfter?: string;
238
- createdBefore?: string;
239
- mimeType?: string;
240
- limit?: number;
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
- ### AnnotationContext
185
+ **What MakeMeaningService Owns:**
245
186
 
246
- Consolidated annotation operations including queries, context building, and AI summarization.
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
- ```typescript
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
- interface BuildContextOptions {
347
- contextLines?: number; // Lines of surrounding text (default: 5)
348
- includeMetadata?: boolean; // Include resource metadata (default: true)
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
- ### GraphContext
207
+ **Why This Matters:**
353
208
 
354
- Provides graph database operations for traversing resource relationships. All operations are delegated to @semiont/graph (which may use Neo4j or other graph database implementations).
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
- ```typescript
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
- ### AnnotationDetection
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
- AI-powered semantic pattern detection. Orchestrates the full pipeline: resource content AI prompts response parsing validated matches.
222
+ This architectural pattern prevents duplicate connections, ensures consistent state, and provides clear ownership boundaries across the entire system.
406
223
 
407
- ```typescript
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
- **Match types:**
462
- ```typescript
463
- // Re-exported from @semiont/inference for convenience
464
- interface CommentMatch {
465
- exact: string; // The exact text passage
466
- start: number; // Character offset start
467
- end: number; // Character offset end
468
- prefix?: string; // Context before (for fuzzy anchoring)
469
- suffix?: string; // Context after (for fuzzy anchoring)
470
- comment: string; // The AI-generated comment
471
- }
472
-
473
- interface HighlightMatch {
474
- exact: string;
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
- **Detection parameters:**
242
+ **Key principles:**
501
243
 
502
- - `instructions`: Custom guidance for the AI (e.g., "Focus on technical concepts")
503
- - `tone`: Tone for comments/assessments (e.g., "educational", "constructive", "analytical")
504
- - `density`: Target density 0.0-1.0 (0.5 = ~50% of passages should be detected)
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
- ## Examples
251
+ See [Architecture](./docs/architecture.md) for complete details.
507
252
 
508
- ### Building Annotation Context for AI
253
+ ## Exports
509
254
 
510
- ```typescript
511
- import { AnnotationContext, ResourceContext } from '@semiont/make-meaning';
255
+ ### Service Module (Primary)
512
256
 
513
- // Get the full context needed for AI to process an annotation
514
- const context = await AnnotationContext.buildLLMContext(
515
- annotationUri,
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
- // context includes:
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
- ### Detecting Patterns and Creating Annotations
263
+ - `ResourceContext` - Resource metadata and content
264
+ - `AnnotationContext` - Annotation queries and context building
265
+ - `GraphContext` - Graph traversal and search
529
266
 
530
- ```typescript
531
- import { AnnotationDetection } from '@semiont/make-meaning';
532
- import { createEventStore } from '@semiont/event-sourcing';
267
+ ### Detection & Generation
533
268
 
534
- // Detect highlights using AI
535
- const highlights = await AnnotationDetection.detectHighlights(
536
- resourceId,
537
- config,
538
- 'Find key definitions and important claims',
539
- 0.6 // Medium density
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
- // Create annotations for each detected highlight
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
- ### Navigating Resource Relationships
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
- ```typescript
583
- import { GraphContext, ResourceContext } from '@semiont/make-meaning';
286
+ **Note**: Workers are typically managed by `startMakeMeaning()`, not instantiated directly.
584
287
 
585
- // Find all resources that link to this one
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
- // Find connection path between two resources
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
- // Get all connections for a resource
596
- const connections = await GraphContext.getResourceConnections(resourceId, config);
597
- // connections = [{ from: ResourceId, to: ResourceId, via: AnnotationId }, ...]
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 with:
305
+ All methods require an `EnvironmentConfig` object:
603
306
 
604
307
  ```typescript
605
- interface EnvironmentConfig {
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
- ## How Detection Works
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
- Detection jobs are orchestrated by workers in [apps/backend/src/jobs/workers/](../../apps/backend/src/jobs/workers/):
690
-
691
- - [highlight-detection-worker.ts](../../apps/backend/src/jobs/workers/highlight-detection-worker.ts) - Delegated detection to `AnnotationDetection.detectHighlights()`
692
- - [comment-detection-worker.ts](../../apps/backend/src/jobs/workers/comment-detection-worker.ts) - Delegated detection to `AnnotationDetection.detectComments()`
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
- MIT
350
+ Apache-2.0