@semiont/make-meaning 0.5.28 → 0.5.29
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 +7 -5
- package/dist/archivist-main.d.ts +2 -0
- package/dist/archivist-main.js +12568 -0
- package/dist/archivist-main.js.map +1 -0
- package/dist/index.d.ts +649 -460
- package/dist/index.js +580 -1060
- package/dist/index.js.map +1 -1
- package/dist/librarian-main.d.ts +2 -0
- package/dist/librarian-main.js +11449 -0
- package/dist/librarian-main.js.map +1 -0
- package/dist/smelter-main.js +21 -15
- package/dist/smelter-main.js.map +1 -1
- package/dist/weaver-main.d.ts +2 -0
- package/dist/weaver-main.js +13 -8
- package/dist/weaver-main.js.map +1 -1
- package/package.json +27 -16
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { JobQueue } from '@semiont/jobs';
|
|
2
|
-
import { SemiontProject } from '@semiont/core/node';
|
|
3
|
-
import { GraphServiceConfig, VectorsServiceConfig, EmbeddingServiceConfig, StateUnit, EventBus, Logger, ResourceId, ResourceDescriptor, AnnotationId,
|
|
4
|
-
import { EventStore, ViewStorage } from '@semiont/event-sourcing';
|
|
5
|
-
import { WorkingTreeStore, AnchoredTextStore } from '@semiont/content';
|
|
2
|
+
import { SemiontProject, SemiontState } from '@semiont/core/node';
|
|
3
|
+
import { GraphServiceConfig, VectorsServiceConfig, EmbeddingServiceConfig, ArchivistServiceConfig, EnvironmentConfig, StateUnit, EventBus, Logger, ResourceId, ResourceDescriptor, components, AnnotationId, GatheredContext, ResourceAnnotations, Annotation, AnnotationCategory, ITransport, BaseUrl, ConnectionState, SemiontError, UserDID, EventMap, IContentTransport, PutBinaryRequest, PutBinaryOptions, ExtractionOutcome, AccessToken, BusRequestPrimitive, ChunkingConfig, UserId } from '@semiont/core';
|
|
4
|
+
import { EventReadStorage, ViewMaterializer, EventStore, ViewStorage, EventLog } from '@semiont/event-sourcing';
|
|
5
|
+
import { WorkingTreeStore, AnchoredTextStore, ContentReads } from '@semiont/content';
|
|
6
6
|
import { GraphDatabase } from '@semiont/graph';
|
|
7
7
|
import { VectorStore, EmbeddingProvider } from '@semiont/vectors';
|
|
8
8
|
import { InferenceClient } from '@semiont/inference';
|
|
9
|
+
import { Server } from 'http';
|
|
9
10
|
import { BehaviorSubject, Observable } from 'rxjs';
|
|
10
11
|
import { WorkerBus } from '@semiont/sdk';
|
|
11
|
-
import { Writable, Readable } from 'node:stream';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Inference configuration for a single actor or worker.
|
|
@@ -74,10 +74,14 @@ interface MakeMeaningConfig {
|
|
|
74
74
|
/** REQUIRED (same ruling): the embedding provider is the KB's semantic
|
|
75
75
|
* identity — always named, never detected or defaulted. */
|
|
76
76
|
embedding: EmbeddingServiceConfig;
|
|
77
|
+
/** Where the record is. Optional in the type because the actors that
|
|
78
|
+
* hold a KB mount never dial it; the Librarian does, and refuses at
|
|
79
|
+
* boot when it is absent (SINGLE-KB-MOUNT P4). */
|
|
80
|
+
archivist?: ArchivistServiceConfig;
|
|
77
81
|
};
|
|
78
82
|
/**
|
|
79
83
|
* The KB's canonical identity domain — the SAME value `/api/tokens/agent`
|
|
80
|
-
* mints agent DIDs from (
|
|
84
|
+
* mints agent DIDs from (gateway `site.domain`). The agent roster consumes
|
|
81
85
|
* it verbatim, so directory DIDs and work-stamped `generator` DIDs are
|
|
82
86
|
* equal by construction; it is never derived from service topology
|
|
83
87
|
* (.plans/bugs/agent-did-host-skew.md).
|
|
@@ -90,9 +94,25 @@ interface MakeMeaningConfig {
|
|
|
90
94
|
/** Per-worker-type inference config */
|
|
91
95
|
workers?: WorkerInferenceConfig;
|
|
92
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Extract the MakeMeaningConfig slice from a full EnvironmentConfig.
|
|
99
|
+
* actors and workers come from _metadata (populated by the TOML loader).
|
|
100
|
+
*
|
|
101
|
+
* Lives here (not in a consumer) because every composition root that runs
|
|
102
|
+
* make-meaning actors — the gateway's startMakeMeaning and the Archivist's
|
|
103
|
+
* archivist-main — needs the identical mapping; two copies would drift.
|
|
104
|
+
*/
|
|
105
|
+
/**
|
|
106
|
+
* The KB name a mountless service composes its state paths from —
|
|
107
|
+
* `[kb] name`, staged by the launcher (SINGLE-KB-MOUNT D4). Refusing is the
|
|
108
|
+
* point: a defaulted name composes a state path nobody writes to, and the
|
|
109
|
+
* service reads an empty view store forever, silently.
|
|
110
|
+
*/
|
|
111
|
+
declare function requireKBName(config: EnvironmentConfig): string;
|
|
112
|
+
declare function makeMeaningConfigFrom(config: EnvironmentConfig): MakeMeaningConfig;
|
|
93
113
|
|
|
94
114
|
/**
|
|
95
|
-
* WeaveProgress —
|
|
115
|
+
* WeaveProgress — gateway-local fold of `weave:applied` signals
|
|
96
116
|
* (GRAPH-PROJECTION-SYNC P2, D2 = push).
|
|
97
117
|
*
|
|
98
118
|
* The Weaver emits `weave:applied` after applying an event (or a batch's
|
|
@@ -108,7 +128,7 @@ interface MakeMeaningConfig {
|
|
|
108
128
|
* WEAVER-ISOLATION the same channel arrives through the bus gateway and
|
|
109
129
|
* this unit does not change.
|
|
110
130
|
*
|
|
111
|
-
* The map is ephemeral by design — on
|
|
131
|
+
* The map is ephemeral by design — on gateway restart it rebuilds lazily
|
|
112
132
|
* from live signals. That loses nothing: a waiter only ever waits for an
|
|
113
133
|
* apply that has not happened yet, and those signals are still to come.
|
|
114
134
|
*/
|
|
@@ -126,7 +146,7 @@ interface WeaveProgress extends StateUnit {
|
|
|
126
146
|
}
|
|
127
147
|
|
|
128
148
|
/**
|
|
129
|
-
* SmeltProgress —
|
|
149
|
+
* SmeltProgress — gateway-local fold of `smelt:settled` signals
|
|
130
150
|
* (SMELTER-INDEX-SYNC P1, D1 = push barrier).
|
|
131
151
|
*
|
|
132
152
|
* The Smelter emits `smelt:settled` after deciding a resource's content:
|
|
@@ -144,7 +164,7 @@ interface WeaveProgress extends StateUnit {
|
|
|
144
164
|
* worker; an in-process Smelter would ride the core EventBus and this unit
|
|
145
165
|
* would not change (the WeaveProgress precedent).
|
|
146
166
|
*
|
|
147
|
-
* The fold is ephemeral by design — on
|
|
167
|
+
* The fold is ephemeral by design — on gateway restart it rebuilds lazily
|
|
148
168
|
* from live signals. Barrier callers probe the vector store first
|
|
149
169
|
* (SMELTER-INDEX-SYNC A3), so a cold fold only costs waits for resources
|
|
150
170
|
* whose settlement genuinely hasn't been observed yet.
|
|
@@ -200,6 +220,30 @@ interface KnowledgeBase {
|
|
|
200
220
|
vectors: VectorStore;
|
|
201
221
|
projectionsDir: string;
|
|
202
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* Capability slices of the record (EXTRACT-ARCHIVIST P1).
|
|
225
|
+
*
|
|
226
|
+
* An Archivist actor takes the slice it actually uses, never the whole
|
|
227
|
+
* KnowledgeBase. Every slice is DERIVED from the owning type with Pick;
|
|
228
|
+
* a hand-restated shape here would be a mirror of a fact someone else owns.
|
|
229
|
+
*/
|
|
230
|
+
/** The lifecycle half of the working tree (GATEWAY.md D4a): the Archivist
|
|
231
|
+
* accessions, moves, removes and resolves — it never serves bytes. */
|
|
232
|
+
type ContentLifecycle = Pick<WorkingTreeStore, 'register' | 'move' | 'remove' | 'resolveUri'>;
|
|
233
|
+
/** The record's single write seam. `Stower` is the only appendEvent caller
|
|
234
|
+
* anywhere in make-meaning or the gateway (post-#1252): single-owner by
|
|
235
|
+
* construction. A second caller is a design smell, not a wiring chore. */
|
|
236
|
+
type EventAppends = Pick<EventStore, 'appendEvent'>;
|
|
237
|
+
/** Read-only reach into the event store: the log for queries, the
|
|
238
|
+
* materializer for on-demand view assembly (`assembleResourceGraph`). */
|
|
239
|
+
interface EventStoreReads {
|
|
240
|
+
log: {
|
|
241
|
+
storage: EventReadStorage;
|
|
242
|
+
};
|
|
243
|
+
views: {
|
|
244
|
+
materializer: Pick<ViewMaterializer, 'materialize'>;
|
|
245
|
+
};
|
|
246
|
+
}
|
|
203
247
|
interface CreateKnowledgeBaseOptions {
|
|
204
248
|
/** Required (MANDATORY-EMBEDDING D0): a KB without vector search is not a
|
|
205
249
|
* configuration we support; `MemoryVectorStore` is the explicit named
|
|
@@ -227,6 +271,7 @@ declare function createKnowledgeBase(eventStore: EventStore, project: SemiontPro
|
|
|
227
271
|
*
|
|
228
272
|
* Subscriptions:
|
|
229
273
|
* - yield:create → resource.created (+ content store) → yield:created / yield:create-failed
|
|
274
|
+
* - yield:clone-persist → resource.cloned (+ content store) → yield:cloned / yield:clone-persist-failed
|
|
230
275
|
* - yield:update → resource.updated (+ content store) → yield:updated / yield:update-failed
|
|
231
276
|
* - yield:mv → resource.moved (+ working tree move) → yield:moved / yield:move-failed
|
|
232
277
|
* - mark:create → annotation.added → mark:created / mark:create-failed
|
|
@@ -252,15 +297,43 @@ interface CreateResourceResult {
|
|
|
252
297
|
resourceId: ResourceId;
|
|
253
298
|
resource: ResourceDescriptor;
|
|
254
299
|
}
|
|
300
|
+
/**
|
|
301
|
+
* The stores Stower writes through (EXTRACT-ARCHIVIST P1): the record's
|
|
302
|
+
* single write seam plus the content lifecycle — never bytes (GATEWAY.md
|
|
303
|
+
* D4a). Resource resolution for moves goes through `project.projectionsDir`.
|
|
304
|
+
*/
|
|
305
|
+
interface StowerStores {
|
|
306
|
+
content: ContentLifecycle;
|
|
307
|
+
eventStore: EventAppends;
|
|
308
|
+
}
|
|
255
309
|
declare class Stower {
|
|
256
|
-
private
|
|
310
|
+
private stores;
|
|
257
311
|
private eventBus;
|
|
258
312
|
private project;
|
|
259
313
|
private subscription;
|
|
260
314
|
private readonly logger;
|
|
261
|
-
constructor(
|
|
315
|
+
constructor(stores: StowerStores, eventBus: EventBus, project: SemiontProject, logger: Logger);
|
|
262
316
|
initialize(): Promise<void>;
|
|
263
317
|
private handleYieldCreate;
|
|
318
|
+
/**
|
|
319
|
+
* Persist a clone (the CloneTokenManager's second half).
|
|
320
|
+
*
|
|
321
|
+
* A clone is its own domain fact, not a creation with an extra field: it
|
|
322
|
+
* NAMES the resource it came from, and `ResourceClonedPayload` requires
|
|
323
|
+
* that name. So it gets its own command and appends its own event, rather
|
|
324
|
+
* than an optional parent turning `yield:created` into something else at
|
|
325
|
+
* runtime.
|
|
326
|
+
*
|
|
327
|
+
* The token was already validated and the source's entity types already
|
|
328
|
+
* read by the CloneTokenManager — the one party that can do either. What
|
|
329
|
+
* happens here is what only the Stower may do: register the bytes and
|
|
330
|
+
* append the event (single-writer, GATEWAY.md D4b).
|
|
331
|
+
*
|
|
332
|
+
* Generated resources do NOT come through here. Their provenance is
|
|
333
|
+
* `generatedFrom` on `yield:created`, which is a different relation: a
|
|
334
|
+
* generated resource is derived from a source, a clone IS a copy of one.
|
|
335
|
+
*/
|
|
336
|
+
private handleYieldClonePersist;
|
|
264
337
|
private handleYieldUpdate;
|
|
265
338
|
private handleYieldMv;
|
|
266
339
|
private handleMarkCreate;
|
|
@@ -277,6 +350,218 @@ declare class Stower {
|
|
|
277
350
|
stop(): Promise<void>;
|
|
278
351
|
}
|
|
279
352
|
|
|
353
|
+
/**
|
|
354
|
+
* Graph Context
|
|
355
|
+
*
|
|
356
|
+
* Provides graph database operations for resources and annotations.
|
|
357
|
+
* All methods require graph traversal - must use graph database.
|
|
358
|
+
*/
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* What the unified graph builder reads (EXTRACT-LIBRARIAN P2) — Pick-derived,
|
|
362
|
+
* never restated. The weave fold is bus-fed (`weave:applied`), so this slice
|
|
363
|
+
* works identically in-process and in the standalone Librarian.
|
|
364
|
+
*/
|
|
365
|
+
interface KnowledgeGraphReads {
|
|
366
|
+
graph: Pick<GraphDatabase, 'getResource' | 'getResourceConnections' | 'getResourceReferencedBy' | 'getResourceAnnotations'>;
|
|
367
|
+
views: Pick<ViewStorage, 'get'>;
|
|
368
|
+
weaveProgress: Pick<WeaveProgress, 'whenApplied'>;
|
|
369
|
+
}
|
|
370
|
+
type KnowledgeGraph = components['schemas']['KnowledgeGraph'];
|
|
371
|
+
declare class GraphContext {
|
|
372
|
+
/**
|
|
373
|
+
* Build the unified knowledge graph for a resource's neighborhood:
|
|
374
|
+
* resources AND annotations as typed nodes, typed/directional edges.
|
|
375
|
+
*
|
|
376
|
+
* This is the single graph builder (CONTEXT-UNIFICATION D3) — both the
|
|
377
|
+
* matcher (ranking) and the resource/viz path consume it. The flattened
|
|
378
|
+
* signals the matcher reads today (`connections`, `citedBy`/count,
|
|
379
|
+
* `siblingEntityTypes`, `bidirectional`) are all derivable from this:
|
|
380
|
+
* - peer connections → resource nodes + main→peer edges carrying `bidirectional`
|
|
381
|
+
* - inbound citations → citing-resource nodes + `citation` edges (citing→main),
|
|
382
|
+
* so citedByCount = inbound citation-edge count
|
|
383
|
+
* - annotations on the resource → `annotation` nodes + `annotation-of` edges,
|
|
384
|
+
* so siblingEntityTypes = union of those nodes' entityTypes
|
|
385
|
+
*/
|
|
386
|
+
static buildKnowledgeGraph(resourceId: ResourceId, kb: KnowledgeGraphReads,
|
|
387
|
+
/** Breadcrumb sink for the projection-lag degrade path; the degrade counter fires regardless. */
|
|
388
|
+
logger?: Logger): Promise<KnowledgeGraph>;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Annotation Context
|
|
393
|
+
*
|
|
394
|
+
* Assembles annotation context from view storage and content store.
|
|
395
|
+
* Provides methods for:
|
|
396
|
+
* - Getting resource annotations
|
|
397
|
+
* - Building LLM context for annotations
|
|
398
|
+
* - Extracting annotation text context
|
|
399
|
+
* - Generating AI summaries
|
|
400
|
+
*/
|
|
401
|
+
|
|
402
|
+
/** The view slice the annotation reads run on (EXTRACT-ARCHIVIST P1). */
|
|
403
|
+
type ViewGet = {
|
|
404
|
+
views: Pick<ViewStorage, 'get'>;
|
|
405
|
+
};
|
|
406
|
+
/**
|
|
407
|
+
* What the annotation-gather path reads (EXTRACT-LIBRARIAN P2; content
|
|
408
|
+
* re-keyed by D-CONTENT b) — the graph builder's slice plus this module's
|
|
409
|
+
* own reads. Pick-derived, never restated. In-process roots satisfy it with
|
|
410
|
+
* `workingTreeContentReads` over their `kb`; the Librarian passes
|
|
411
|
+
* `HttpContentTransport`.
|
|
412
|
+
*/
|
|
413
|
+
interface AnnotationGatherReads {
|
|
414
|
+
views: Pick<ViewStorage, 'get'>;
|
|
415
|
+
content: ContentReads;
|
|
416
|
+
graph: KnowledgeGraphReads['graph'] & Pick<GraphDatabase, 'getEntityTypeStats'>;
|
|
417
|
+
vectors: Pick<VectorStore, 'searchAnnotations'>;
|
|
418
|
+
weaveProgress: KnowledgeGraphReads['weaveProgress'];
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
type AnnotationContextResponse = components['schemas']['AnnotationContextResponse'];
|
|
422
|
+
type ContextualSummaryResponse = components['schemas']['ContextualSummaryResponse'];
|
|
423
|
+
interface BuildContextOptions {
|
|
424
|
+
includeSourceContext?: boolean;
|
|
425
|
+
includeTargetContext?: boolean;
|
|
426
|
+
contextWindow?: number;
|
|
427
|
+
}
|
|
428
|
+
declare class AnnotationContext {
|
|
429
|
+
/**
|
|
430
|
+
* Build LLM context for an annotation
|
|
431
|
+
*
|
|
432
|
+
* @param annotationId - Bare annotation ID
|
|
433
|
+
* @param resourceId - Source resource ID
|
|
434
|
+
* @param kb - Knowledge base stores
|
|
435
|
+
* @param options - Context building options
|
|
436
|
+
* @param inferenceClient - Optional inference client for target context summary
|
|
437
|
+
* @returns Rich context for LLM processing
|
|
438
|
+
* @throws Error if annotation or resource not found
|
|
439
|
+
*/
|
|
440
|
+
static buildLLMContext(annotationId: AnnotationId, resourceId: ResourceId, kb: AnnotationGatherReads, embeddingProvider: EmbeddingProvider, options?: BuildContextOptions, inferenceClient?: InferenceClient, logger?: Logger): Promise<GatheredContext>;
|
|
441
|
+
/**
|
|
442
|
+
* Get resource annotations from view storage (fast path)
|
|
443
|
+
* Throws if view missing
|
|
444
|
+
*/
|
|
445
|
+
static getResourceAnnotations(resourceId: ResourceId, kb: ViewGet): Promise<ResourceAnnotations>;
|
|
446
|
+
/**
|
|
447
|
+
* Get all annotations
|
|
448
|
+
* @returns Array of all annotation objects
|
|
449
|
+
*/
|
|
450
|
+
static getAllAnnotations(resourceId: ResourceId, kb: ViewGet): Promise<Annotation[]>;
|
|
451
|
+
/**
|
|
452
|
+
* Enrich reference annotations with resolved document names
|
|
453
|
+
* Adds _resolvedDocumentName property to annotations that link to documents
|
|
454
|
+
* @private
|
|
455
|
+
*/
|
|
456
|
+
private static enrichResolvedReferences;
|
|
457
|
+
/**
|
|
458
|
+
* Get resource stats (version info)
|
|
459
|
+
* @returns Version and timestamp info for the annotations
|
|
460
|
+
*/
|
|
461
|
+
static getResourceStats(resourceId: ResourceId, kb: ViewGet): Promise<{
|
|
462
|
+
resourceId: ResourceId;
|
|
463
|
+
version: number;
|
|
464
|
+
updatedAt: string;
|
|
465
|
+
}>;
|
|
466
|
+
/**
|
|
467
|
+
* Check if resource exists in view storage
|
|
468
|
+
*/
|
|
469
|
+
static resourceExists(resourceId: ResourceId, kb: {
|
|
470
|
+
views: Pick<ViewStorage, 'exists'>;
|
|
471
|
+
}): Promise<boolean>;
|
|
472
|
+
/**
|
|
473
|
+
* Get a single annotation by ID
|
|
474
|
+
* O(1) lookup using resource ID to access view storage
|
|
475
|
+
*/
|
|
476
|
+
static getAnnotation(annotationId: AnnotationId, resourceId: ResourceId, kb: ViewGet): Promise<Annotation | null>;
|
|
477
|
+
/**
|
|
478
|
+
* List annotations with optional filtering
|
|
479
|
+
* @param filters - Optional filters like resourceId and type
|
|
480
|
+
* @throws Error if resourceId not provided (cross-resource queries not supported in view storage)
|
|
481
|
+
*/
|
|
482
|
+
static listAnnotations(filters: {
|
|
483
|
+
resourceId?: ResourceId;
|
|
484
|
+
type?: AnnotationCategory;
|
|
485
|
+
} | undefined, kb: ViewGet): Promise<Annotation[]>;
|
|
486
|
+
/**
|
|
487
|
+
* Get annotation context (selected text with surrounding context)
|
|
488
|
+
*/
|
|
489
|
+
static getAnnotationContext(annotationId: AnnotationId, resourceId: ResourceId, contextBefore: number, contextAfter: number, kb: ViewGet & {
|
|
490
|
+
content: ContentReads;
|
|
491
|
+
}): Promise<AnnotationContextResponse>;
|
|
492
|
+
/**
|
|
493
|
+
* Generate AI summary of annotation in context
|
|
494
|
+
*/
|
|
495
|
+
static generateAnnotationSummary(annotationId: AnnotationId, resourceId: ResourceId, kb: ViewGet & {
|
|
496
|
+
content: ContentReads;
|
|
497
|
+
}, inferenceClient: InferenceClient): Promise<ContextualSummaryResponse>;
|
|
498
|
+
/**
|
|
499
|
+
* Get resource content as string. ResourceId-keyed (D-CONTENT b): the
|
|
500
|
+
* primary representation's `storageUri` stays the has-content signal, the
|
|
501
|
+
* fetch goes by id.
|
|
502
|
+
*/
|
|
503
|
+
private static getResourceContent;
|
|
504
|
+
/**
|
|
505
|
+
* Extract annotation context from resource content
|
|
506
|
+
*/
|
|
507
|
+
private static extractAnnotationContext;
|
|
508
|
+
/**
|
|
509
|
+
* Generate LLM summary of annotation in context
|
|
510
|
+
* Creates inference client per-request (HTTP handler context)
|
|
511
|
+
*/
|
|
512
|
+
private static generateSummary;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* LLM Context
|
|
517
|
+
*
|
|
518
|
+
* Builds comprehensive context for LLM processing of resources
|
|
519
|
+
* Orchestrates: ResourceContext, GraphContext, AnnotationContext, and generation functions
|
|
520
|
+
*/
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* What the resource-gather path reads (EXTRACT-LIBRARIAN P2; content re-keyed
|
|
524
|
+
* by D-CONTENT b) — the graph builder's slice plus this module's own reads.
|
|
525
|
+
* Pick-derived, never restated. In-process roots satisfy it with
|
|
526
|
+
* `workingTreeContentReads` over their `kb`; the Librarian passes
|
|
527
|
+
* `HttpContentTransport`.
|
|
528
|
+
*/
|
|
529
|
+
interface ResourceGatherReads {
|
|
530
|
+
views: Pick<ViewStorage, 'get'>;
|
|
531
|
+
content: ContentReads;
|
|
532
|
+
graph: KnowledgeGraphReads['graph'];
|
|
533
|
+
vectors: Pick<VectorStore, 'searchByResource'>;
|
|
534
|
+
weaveProgress: KnowledgeGraphReads['weaveProgress'];
|
|
535
|
+
smeltProgress: Pick<SmeltProgress, 'whenSettled'>;
|
|
536
|
+
}
|
|
537
|
+
interface LLMContextOptions {
|
|
538
|
+
depth: number;
|
|
539
|
+
maxResources: number;
|
|
540
|
+
includeContent: boolean;
|
|
541
|
+
includeSummary: boolean;
|
|
542
|
+
/**
|
|
543
|
+
* Entity types to exclude from the resource-gather semantic recall
|
|
544
|
+
* (caller-supplied; e.g. ['Question']). Optional; default none.
|
|
545
|
+
*/
|
|
546
|
+
excludeEntityTypes?: string[];
|
|
547
|
+
}
|
|
548
|
+
declare class LLMContext {
|
|
549
|
+
/**
|
|
550
|
+
* Get comprehensive LLM context for a resource
|
|
551
|
+
* Includes: main resource, related resources, annotations, graph, content, summary, references
|
|
552
|
+
*/
|
|
553
|
+
static getResourceContext(resourceId: ResourceId, options: LLMContextOptions, kb: ResourceGatherReads, inferenceClient: InferenceClient,
|
|
554
|
+
/**
|
|
555
|
+
* Bound on the semanticContext read-your-writes barrier
|
|
556
|
+
* (SMELTER-INDEX-SYNC D3/D5). Operator-owned deployment policy: born in
|
|
557
|
+
* `[environments.<env>.make-meaning.gather] settleTimeoutMs` (the TOML
|
|
558
|
+
* loader holds the ONE default, 15s), threaded here as a plain argument
|
|
559
|
+
* via `MakeMeaningConfig.gather` → Gatherer. Must nest inside downstream
|
|
560
|
+
* watchdogs (A4) — e.g. my-chat's 90s generation stall watchdog.
|
|
561
|
+
*/
|
|
562
|
+
settleTimeoutMs: number, logger: Logger): Promise<GatheredContext>;
|
|
563
|
+
}
|
|
564
|
+
|
|
280
565
|
/**
|
|
281
566
|
* Gatherer Actor
|
|
282
567
|
*
|
|
@@ -303,8 +588,16 @@ declare class Stower {
|
|
|
303
588
|
* by RPC-style services.
|
|
304
589
|
*/
|
|
305
590
|
|
|
306
|
-
|
|
307
|
-
|
|
591
|
+
/**
|
|
592
|
+
* The Gatherer's capability slice (EXTRACT-LIBRARIAN P2) — DERIVED as the
|
|
593
|
+
* intersection of the two gather paths' reads, never restated. A full
|
|
594
|
+
* `KnowledgeBase` satisfies it structurally; the standalone Librarian (P3)
|
|
595
|
+
* builds it from the shared stateDir (views), the network clients
|
|
596
|
+
* (graph/vectors), bus-fed progress folds, and D-CONTENT's answer (content).
|
|
597
|
+
*/
|
|
598
|
+
type GathererStores = AnnotationGatherReads & ResourceGatherReads;
|
|
599
|
+
declare class Gatherer {
|
|
600
|
+
private stores;
|
|
308
601
|
private eventBus;
|
|
309
602
|
private inferenceClient;
|
|
310
603
|
/** Settle bound for the resource-gather barrier — operator-owned config (D5), threaded from `MakeMeaningConfig.gather`. */
|
|
@@ -312,7 +605,7 @@ declare class Gatherer$1 {
|
|
|
312
605
|
private embeddingProvider;
|
|
313
606
|
private subscriptions;
|
|
314
607
|
private readonly logger;
|
|
315
|
-
constructor(
|
|
608
|
+
constructor(stores: GathererStores, eventBus: EventBus, inferenceClient: InferenceClient,
|
|
316
609
|
/** Settle bound for the resource-gather barrier — operator-owned config (D5), threaded from `MakeMeaningConfig.gather`. */
|
|
317
610
|
settleTimeoutMs: number, logger: Logger, embeddingProvider: EmbeddingProvider);
|
|
318
611
|
initialize(): Promise<void>;
|
|
@@ -335,14 +628,27 @@ declare class Gatherer$1 {
|
|
|
335
628
|
* is available from auth context.
|
|
336
629
|
*/
|
|
337
630
|
|
|
631
|
+
/**
|
|
632
|
+
* The Matcher's capability slice (EXTRACT-LIBRARIAN P1) — Pick-derived,
|
|
633
|
+
* never restated. `graph.getResource` + `views.get` are
|
|
634
|
+
* `resourceWithViewGrace`'s two halves: the view fallback is a
|
|
635
|
+
* filesystem-backed projection read, served to the standalone service by
|
|
636
|
+
* the shared stateDir mount (D6), and to in-process callers by the same
|
|
637
|
+
* `kb` object, which satisfies this slice structurally.
|
|
638
|
+
*/
|
|
639
|
+
interface MatcherStores {
|
|
640
|
+
graph: Pick<GraphDatabase, 'listResources' | 'getResource'>;
|
|
641
|
+
views: Pick<ViewStorage, 'get'>;
|
|
642
|
+
vectors: Pick<VectorStore, 'searchResources'>;
|
|
643
|
+
}
|
|
338
644
|
declare class Matcher {
|
|
339
|
-
private
|
|
645
|
+
private stores;
|
|
340
646
|
private eventBus;
|
|
341
647
|
private inferenceClient;
|
|
342
648
|
private embeddingProvider;
|
|
343
649
|
private subscriptions;
|
|
344
650
|
private readonly logger;
|
|
345
|
-
constructor(
|
|
651
|
+
constructor(stores: MatcherStores, eventBus: EventBus, logger: Logger, inferenceClient: InferenceClient, embeddingProvider: EmbeddingProvider);
|
|
346
652
|
initialize(): Promise<void>;
|
|
347
653
|
private handleSearch;
|
|
348
654
|
/**
|
|
@@ -416,6 +722,8 @@ interface LimitsDiscovery {
|
|
|
416
722
|
*
|
|
417
723
|
* Handles:
|
|
418
724
|
* - browse:resource-requested — single resource metadata (materialized from events)
|
|
725
|
+
* - browse:anchored-text-by-checksum-requested — the detection workers' read-through
|
|
726
|
+
* cache consult: a stored extraction outcome by content identity (ANCHORED-TEXT-TO-SMELTER P2)
|
|
419
727
|
* - browse:resources-requested — list resources
|
|
420
728
|
* - browse:annotations-requested — all annotations for a resource
|
|
421
729
|
* - browse:annotation-requested — single annotation with resolved resource
|
|
@@ -429,8 +737,22 @@ interface LimitsDiscovery {
|
|
|
429
737
|
* - browse:directory-requested — list a project directory, merging fs + ViewStorage
|
|
430
738
|
*/
|
|
431
739
|
|
|
740
|
+
/**
|
|
741
|
+
* Browser's measured surface of the record (EXTRACT-ARCHIVIST P1) — reads
|
|
742
|
+
* only, every member a derived slice of its owning type. What is absent is
|
|
743
|
+
* the point: no appendEvent, no content bytes beyond `retrieve`, no
|
|
744
|
+
* projectionsDir, no weaveProgress.
|
|
745
|
+
*/
|
|
746
|
+
interface BrowserReads {
|
|
747
|
+
views: Pick<ViewStorage, 'get' | 'getAll' | 'exists'>;
|
|
748
|
+
eventStore: EventStoreReads;
|
|
749
|
+
graph: Pick<GraphDatabase, 'getResource' | 'getResourceReferencedBy' | 'listResources' | 'getEntityTypeStats'>;
|
|
750
|
+
vectors: Pick<VectorStore, 'searchResources' | 'searchAnnotations'>;
|
|
751
|
+
content: Pick<WorkingTreeStore, 'retrieve'>;
|
|
752
|
+
anchoredText: Pick<AnchoredTextStore, 'read'>;
|
|
753
|
+
smeltProgress: Pick<SmeltProgress, 'whenSettled'>;
|
|
754
|
+
}
|
|
432
755
|
declare class Browser {
|
|
433
|
-
private views;
|
|
434
756
|
private kb;
|
|
435
757
|
private eventBus;
|
|
436
758
|
private project;
|
|
@@ -441,7 +763,7 @@ declare class Browser {
|
|
|
441
763
|
private embeddingProvider;
|
|
442
764
|
private subscriptions;
|
|
443
765
|
private readonly logger;
|
|
444
|
-
constructor(
|
|
766
|
+
constructor(kb: BrowserReads, eventBus: EventBus, project: SemiontProject, config: MakeMeaningConfig,
|
|
445
767
|
/** Discovered per-(provider, model) ceilings for the roster (INFERENCE-LIMITS-EXPOSURE P2). */
|
|
446
768
|
limitsDiscovery: LimitsDiscovery,
|
|
447
769
|
/** For the semantic search fallback — mandatory (MANDATORY-EMBEDDING D0). */
|
|
@@ -462,6 +784,17 @@ declare class Browser {
|
|
|
462
784
|
* this design exists to avoid.
|
|
463
785
|
*/
|
|
464
786
|
private handleAnchoredText;
|
|
787
|
+
/**
|
|
788
|
+
* Serve the checksum-addressed consult (ANCHORED-TEXT-TO-SMELTER P2, D2) —
|
|
789
|
+
* the detection workers' read-through cache. The caller computed the key
|
|
790
|
+
* from bytes it already holds, so unlike the resource-addressed read there
|
|
791
|
+
* is nothing to resolve and no settle barrier: with no resourceId there is
|
|
792
|
+
* no content generation to wait on, and a miss means "extract it yourself".
|
|
793
|
+
* A hit — success or decline — is served whole, so the caller runs neither
|
|
794
|
+
* parser nor engine. Read-only over the wire: the Smelter is the sole
|
|
795
|
+
* writer and never answers here.
|
|
796
|
+
*/
|
|
797
|
+
private handleAnchoredTextByChecksum;
|
|
465
798
|
private handleBrowseResource;
|
|
466
799
|
private handleBrowseResources;
|
|
467
800
|
private handleBrowseAnnotations;
|
|
@@ -491,13 +824,24 @@ declare class Browser {
|
|
|
491
824
|
* "Clone tokens produce new resources — that's yield."
|
|
492
825
|
*/
|
|
493
826
|
|
|
827
|
+
/**
|
|
828
|
+
* What the clone workflow touches (EXTRACT-ARCHIVIST P1/P3): resource
|
|
829
|
+
* metadata via views, and `resolveUri` for existence checks — never bytes
|
|
830
|
+
* (GATEWAY.md D4a). The clone's own bytes are stored by the gateway's
|
|
831
|
+
* upload path before `yield:clone-create` arrives; this actor holds NO
|
|
832
|
+
* byte capability at all.
|
|
833
|
+
*/
|
|
834
|
+
interface CloneTokenStores {
|
|
835
|
+
views: Pick<ViewStorage, 'get'>;
|
|
836
|
+
content: Pick<WorkingTreeStore, 'resolveUri'>;
|
|
837
|
+
}
|
|
494
838
|
declare class CloneTokenManager {
|
|
495
|
-
private
|
|
839
|
+
private stores;
|
|
496
840
|
private eventBus;
|
|
497
841
|
private subscriptions;
|
|
498
842
|
private readonly logger;
|
|
499
843
|
private readonly tokens;
|
|
500
|
-
constructor(
|
|
844
|
+
constructor(stores: CloneTokenStores, eventBus: EventBus, logger: Logger);
|
|
501
845
|
initialize(): Promise<void>;
|
|
502
846
|
private handleGenerateToken;
|
|
503
847
|
private handleGetResource;
|
|
@@ -521,7 +865,7 @@ declare class CloneTokenManager {
|
|
|
521
865
|
* These are the five access actors. Two projection-pipeline actors complete
|
|
522
866
|
* the seven, and BOTH run standalone (D4: the projections are part of their
|
|
523
867
|
* stores' stacks, not of the embedding process): the Weaver (weaver-main →
|
|
524
|
-
* graph) and the Smelter (smelter-main → vectors). The
|
|
868
|
+
* graph) and the Smelter (smelter-main → vectors). The gateway keeps only
|
|
525
869
|
* the Weaver's `weave:applied` fold (kb.weaveProgress).
|
|
526
870
|
*
|
|
527
871
|
* EventBus, JobQueue, and workers are peers to KnowledgeSystem, not members.
|
|
@@ -530,12 +874,24 @@ declare class CloneTokenManager {
|
|
|
530
874
|
interface KnowledgeSystem {
|
|
531
875
|
kb: KnowledgeBase;
|
|
532
876
|
stower: Stower;
|
|
533
|
-
gatherer: Gatherer
|
|
877
|
+
gatherer: Gatherer;
|
|
534
878
|
matcher: Matcher;
|
|
535
879
|
browser: Browser;
|
|
536
880
|
cloneTokenManager: CloneTokenManager;
|
|
537
881
|
stop: () => Promise<void>;
|
|
538
882
|
}
|
|
883
|
+
/**
|
|
884
|
+
* The gateway's view of the system after EXTRACT-ARCHIVIST P3 and
|
|
885
|
+
* EXTRACT-LIBRARIAN P3: the Archivist service owns
|
|
886
|
+
* Stower/Browser/CloneTokenManager and the Librarian owns Matcher and
|
|
887
|
+
* Gatherer, out-of-process. The gateway hosts NO actors — `kb` here is a
|
|
888
|
+
* READ bundle over the shared stateDir for the handler subset and the
|
|
889
|
+
* gateway's routes; the one writer is the Archivist (D4b/D6).
|
|
890
|
+
*/
|
|
891
|
+
interface GatewayKnowledgeSystem {
|
|
892
|
+
kb: KnowledgeBase;
|
|
893
|
+
stop: () => Promise<void>;
|
|
894
|
+
}
|
|
539
895
|
declare function stopKnowledgeSystem(ks: KnowledgeSystem): Promise<void>;
|
|
540
896
|
|
|
541
897
|
/**
|
|
@@ -549,7 +905,7 @@ interface MakeMeaningService {
|
|
|
549
905
|
knowledgeSystem: KnowledgeSystem;
|
|
550
906
|
jobQueue: JobQueue;
|
|
551
907
|
/**
|
|
552
|
-
* The one SemiontProject this
|
|
908
|
+
* The one SemiontProject this gateway is serving — the same instance the
|
|
553
909
|
* KnowledgeSystem, the job queue and the bus handlers were built from.
|
|
554
910
|
*
|
|
555
911
|
* Exposed so request handlers reach for it instead of improvising their own
|
|
@@ -561,17 +917,132 @@ interface MakeMeaningService {
|
|
|
561
917
|
project: SemiontProject;
|
|
562
918
|
stop: () => Promise<void>;
|
|
563
919
|
}
|
|
920
|
+
/**
|
|
921
|
+
* The in-process composition root: every access actor and handler on one
|
|
922
|
+
* caller-owned bus, for `LocalTransport` consumers — the SDK test seam and
|
|
923
|
+
* embedding. Production composes the same actors as extracted services
|
|
924
|
+
* (archivist-main, librarian-main); this second root is supported, not legacy.
|
|
925
|
+
*/
|
|
564
926
|
declare function startMakeMeaning(project: SemiontProject, config: MakeMeaningConfig, eventBus: EventBus, logger: Logger, options?: {
|
|
565
927
|
skipRebuild?: boolean;
|
|
566
928
|
}): Promise<MakeMeaningService>;
|
|
929
|
+
interface GatewayMakeMeaningService {
|
|
930
|
+
jobQueue: JobQueue;
|
|
931
|
+
/** Name + the state-mount paths. NOT a `SemiontProject`: the gateway
|
|
932
|
+
* mounts no KB tree, and the type is what says so (SINGLE-KB-MOUNT P5). */
|
|
933
|
+
state: SemiontState;
|
|
934
|
+
stop: () => Promise<void>;
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* The gateway's composition root: everything startMakeMeaning builds EXCEPT
|
|
938
|
+
* the actors, which have all left. The Archivist (archivist-main) owns
|
|
939
|
+
* Stower/Browser/CloneTokenManager, enrichment, the entity-type bootstrap +
|
|
940
|
+
* warm, and the view rebuild; the Librarian (librarian-main) owns Matcher
|
|
941
|
+
* and Gatherer (EXTRACT-LIBRARIAN P1/P3).
|
|
942
|
+
*
|
|
943
|
+
* What remains is the JOB QUEUE, and nothing else. It used to call
|
|
944
|
+
* `connectStores` as well — a graph connection, a vector store, an embedding
|
|
945
|
+
* provider, an event store, a working tree and an anchored-text store — and
|
|
946
|
+
* SINGLE-KB-MOUNT P5 measured that **no consumer read any of it**: the whole
|
|
947
|
+
* `kb` bundle existed to be constructed. Deleting it is what lets the gateway
|
|
948
|
+
* take a `SemiontState` instead of a `SemiontProject`, and therefore what
|
|
949
|
+
* lets P6 drop the `/kb` mount: the type no longer HAS a KB root to want.
|
|
950
|
+
*
|
|
951
|
+
* The job queue lives on the shared state mount (D6), so what is left needs
|
|
952
|
+
* no tree at all.
|
|
953
|
+
*/
|
|
954
|
+
declare function startMakeMeaningGateway(state: SemiontState, config: MakeMeaningConfig, eventBus: EventBus, logger: Logger): Promise<GatewayMakeMeaningService>;
|
|
567
955
|
|
|
568
956
|
/**
|
|
569
|
-
*
|
|
957
|
+
* The Archivist's HTTP surface: the /health probe, the D1 sequence-ranged
|
|
958
|
+
* event read path (EXTRACT-ARCHIVIST P2a), and the content write and read
|
|
959
|
+
* paths (SINGLE-KB-MOUNT P2/P3).
|
|
960
|
+
*
|
|
961
|
+
* ⚠️ STANDING RULE, load-bearing: **this surface serves the KB tree, and
|
|
962
|
+
* nothing else.** `browse:*`, `match:*`, `gather:*` stay on the bus. The
|
|
963
|
+
* earlier, narrower rule — exactly one customer, the gateway's SSE resume —
|
|
964
|
+
* was re-examined by SINGLE-KB-MOUNT D1 (2026-08-29), which reversed
|
|
965
|
+
* GATEWAY.md D4a: the Archivist is the knowledge base's storage authority,
|
|
966
|
+
* and this HTTP surface is how bytes and record reads reach it (D2: bytes
|
|
967
|
+
* ride HTTP, never the bus). That is a change of design, not a widened seam;
|
|
968
|
+
* an endpoint that is not a KB-tree read or write still does not belong here.
|
|
969
|
+
*
|
|
970
|
+
* D1 (settled 2026-08-27): moving the event store out of the gateway breaks
|
|
971
|
+
* `/bus/subscribe`'s `Last-Event-ID` replay, which reads the log in-process
|
|
972
|
+
* (apps/gateway/src/routes/bus.ts). The answer is one narrow call —
|
|
973
|
+
* the events for ONE resource from ONE sequence — which the gateway calls
|
|
974
|
+
* directly:
|
|
975
|
+
*
|
|
976
|
+
* GET /events/:resourceId?fromSequence=N (inclusive, like the filter it
|
|
977
|
+
* mirrors: `queryEvents(rId, { fromSequence })`; the caller does the +1)
|
|
978
|
+
*
|
|
979
|
+
* SINGLE-KB-MOUNT P2/P3: the gateway stops touching the shared mount for
|
|
980
|
+
* bytes and proxies both directions here —
|
|
981
|
+
*
|
|
982
|
+
* PUT /content/:storageUri[?checksum=sha256hex] (storageUri URI-encoded
|
|
983
|
+
* as one path segment; an optional checksum is verified BEFORE anything is
|
|
984
|
+
* written, and a disagreement is a 409)
|
|
985
|
+
*
|
|
986
|
+
* GET /resources/:id/content (the bytes, streamed,
|
|
987
|
+
* with the media type the record stores; the 404 carries `reason` so the
|
|
988
|
+
* gateway can serve its two different not-found messages)
|
|
989
|
+
*
|
|
990
|
+
* **The addresses differ because the lifecycle does**, not by oversight: at
|
|
991
|
+
* write time neither the resource nor its view exists — bytes land before the
|
|
992
|
+
* event — so the write has only a tree address to be addressed by, while the
|
|
993
|
+
* read has a record. Both go through ONE resolution (`representation.ts`);
|
|
994
|
+
* neither restates where bytes live.
|
|
995
|
+
*
|
|
996
|
+
* The write is `noGit` and emits nothing: the event contract is untouched —
|
|
997
|
+
* the Stower still `register`s the bytes from disk and does the one `git add`
|
|
998
|
+
* on event apply (GATEWAY.md D4b, single-writer).
|
|
999
|
+
*
|
|
1000
|
+
* Auth: callers authenticate with the same SEMIONT_WORKER_SECRET the
|
|
1001
|
+
* agent-token flow uses — service-to-service, one shared deployment fact.
|
|
1002
|
+
* With no secret configured, every path but /health refuses loudly (503)
|
|
1003
|
+
* rather than serving unauthenticated: absence fails, it is never a
|
|
1004
|
+
* default-open.
|
|
1005
|
+
*/
|
|
1006
|
+
|
|
1007
|
+
interface ArchivistServerDeps {
|
|
1008
|
+
/** The record's log — the read half only. */
|
|
1009
|
+
events: Pick<EventLog, 'queryEvents'>;
|
|
1010
|
+
/** The KB tree's byte paths. `register` and the git index stay the
|
|
1011
|
+
* Stower's on event apply; reads go through `resolveRepresentation`. */
|
|
1012
|
+
content: Pick<WorkingTreeStore, 'store' | 'retrieveStream'>;
|
|
1013
|
+
/** The record's views — the resource half of the one resolution. */
|
|
1014
|
+
views: Pick<ViewStorage, 'get'>;
|
|
1015
|
+
/** Shared service secret; empty disables everything but /health (503), never opens it. */
|
|
1016
|
+
workerSecret: string;
|
|
1017
|
+
/** Liveness payload for /health — actor states, counters. */
|
|
1018
|
+
health: () => Record<string, unknown>;
|
|
1019
|
+
/**
|
|
1020
|
+
* The KB working tree's current branch, `null` outside a git checkout.
|
|
1021
|
+
*
|
|
1022
|
+
* A live fact about the tree, so it is answered by the process that HOLDS
|
|
1023
|
+
* the tree (SINGLE-KB-MOUNT P5). The gateway used to read it off its own
|
|
1024
|
+
* `/kb` mount; the launcher cannot stage it because a branch switch does
|
|
1025
|
+
* not restart the stack, and a staged value would quietly go stale.
|
|
1026
|
+
*/
|
|
1027
|
+
branch: () => string | null;
|
|
1028
|
+
logger: Logger;
|
|
1029
|
+
}
|
|
1030
|
+
declare function createArchivistServer(deps: ArchivistServerDeps): Server;
|
|
1031
|
+
|
|
1032
|
+
/**
|
|
1033
|
+
* LocalTransport — `ITransport` onto an in-process make-meaning `EventBus`.
|
|
1034
|
+
*
|
|
1035
|
+
* It takes NO knowledge system. This is a bus transport: it publishes emits
|
|
1036
|
+
* onto the bus and bridges the reply channels back. It never touched a
|
|
1037
|
+
* `KnowledgeSystem` — the field that used to be here was declared and never
|
|
1038
|
+
* read, which made the transport look coupled to the monolith's shape when it
|
|
1039
|
+
* is coupled only to the bus. Whatever process hosts the actors on that bus
|
|
1040
|
+
* satisfies it.
|
|
570
1041
|
*
|
|
571
1042
|
* Bus-ownership pattern (see `docs/protocol/TRANSPORT-CONTRACT.md`):
|
|
572
1043
|
* - The caller owns a make-meaning `EventBus` and passes it to both
|
|
573
1044
|
* `startMakeMeaning` and `LocalTransport` so the transport can publish
|
|
574
|
-
* directly onto the bus the
|
|
1045
|
+
* directly onto the bus the actors are listening on.
|
|
575
1046
|
* - `SemiontClient` constructs its own `clientBus` and calls
|
|
576
1047
|
* `bridgeInto(clientBus)` during construction. `LocalTransport`
|
|
577
1048
|
* subscribes to every `BRIDGED_CHANNELS` entry on the make-meaning bus
|
|
@@ -579,22 +1050,17 @@ declare function startMakeMeaning(project: SemiontProject, config: MakeMeaningCo
|
|
|
579
1050
|
* - The bus reference flows client → transport, never the other way.
|
|
580
1051
|
*
|
|
581
1052
|
* LocalTransport implements `ITransport` only. Auth, admin, and exchange
|
|
582
|
-
* (`
|
|
1053
|
+
* (`IGatewayOperations`) are HTTP-shaped concepts that don't apply
|
|
583
1054
|
* in-process — local mode runs as a single host-process identity supplied
|
|
584
1055
|
* at construction, with no token/credential lifecycle. A `SemiontClient`
|
|
585
1056
|
* built over this transport has no `.auth` / `.admin` namespaces.
|
|
586
1057
|
*/
|
|
587
1058
|
|
|
588
1059
|
interface LocalTransportConfig {
|
|
589
|
-
/**
|
|
590
|
-
* The in-process knowledge system. Lifetime is owned by the caller —
|
|
591
|
-
* `dispose()` on this transport does not stop the KnowledgeSystem.
|
|
592
|
-
*/
|
|
593
|
-
knowledgeSystem: KnowledgeSystem;
|
|
594
1060
|
/**
|
|
595
1061
|
* The make-meaning `EventBus`. Must be the same instance passed to
|
|
596
|
-
* `startMakeMeaning` so that emits land on the bus
|
|
597
|
-
*
|
|
1062
|
+
* `startMakeMeaning` so that emits land on the bus the actors are
|
|
1063
|
+
* subscribed to.
|
|
598
1064
|
*/
|
|
599
1065
|
eventBus: EventBus;
|
|
600
1066
|
/**
|
|
@@ -641,8 +1107,13 @@ declare class LocalTransport implements ITransport {
|
|
|
641
1107
|
}
|
|
642
1108
|
|
|
643
1109
|
/**
|
|
644
|
-
* LocalContentTransport — `IContentTransport`
|
|
645
|
-
* `
|
|
1110
|
+
* LocalContentTransport — `IContentTransport` over an in-process
|
|
1111
|
+
* `KnowledgeBase`.
|
|
1112
|
+
*
|
|
1113
|
+
* Takes the KB, not the whole `KnowledgeSystem`: every read below goes through
|
|
1114
|
+
* `kb.*` and no actor is ever touched. The wider parameter forced callers that
|
|
1115
|
+
* legitimately hold only a KB to cast (`representation.test.ts` used
|
|
1116
|
+
* `as never`), which is a cast hiding nothing but an over-wide signature.
|
|
646
1117
|
*
|
|
647
1118
|
* Reads go straight to `kb.views` (resource lookup) + `kb.content`
|
|
648
1119
|
* (byte retrieval). No network, no auth — local mode runs as a single
|
|
@@ -657,8 +1128,8 @@ declare class LocalTransport implements ITransport {
|
|
|
657
1128
|
|
|
658
1129
|
type GetResourceResponse = components['schemas']['GetResourceResponse'];
|
|
659
1130
|
declare class LocalContentTransport implements IContentTransport {
|
|
660
|
-
private readonly
|
|
661
|
-
constructor(
|
|
1131
|
+
private readonly kb;
|
|
1132
|
+
constructor(kb: KnowledgeBase);
|
|
662
1133
|
putBinary(_request: PutBinaryRequest, _options?: PutBinaryOptions): Promise<{
|
|
663
1134
|
resourceId: ResourceId;
|
|
664
1135
|
}>;
|
|
@@ -704,6 +1175,12 @@ declare class LocalContentTransport implements IContentTransport {
|
|
|
704
1175
|
stream: ReadableStream<Uint8Array>;
|
|
705
1176
|
contentType: string;
|
|
706
1177
|
}>;
|
|
1178
|
+
/**
|
|
1179
|
+
* The same resolution the wire path serves, buffered — local and hosted
|
|
1180
|
+
* modes must answer identically, which they did not before
|
|
1181
|
+
* SINGLE-KB-MOUNT P3: this resolved through `representations[].storageUri`,
|
|
1182
|
+
* a field `ViewMaterializer` never writes, so every binary read here threw.
|
|
1183
|
+
*/
|
|
707
1184
|
private loadBinary;
|
|
708
1185
|
/**
|
|
709
1186
|
* Assemble the resource's JSON-LD graph in-process from the KB — the local
|
|
@@ -718,7 +1195,7 @@ declare class LocalContentTransport implements IContentTransport {
|
|
|
718
1195
|
|
|
719
1196
|
/**
|
|
720
1197
|
* Adapt a raw in-process `EventBus` to the `BusRequestPrimitive` that
|
|
721
|
-
* `busRequest` consumes. Lets
|
|
1198
|
+
* `busRequest` consumes. Lets gateway-internal callers (bootstrap, event
|
|
722
1199
|
* replay, linked-data import) use the same confirmed request/reply path as the
|
|
723
1200
|
* SDK — `busRequest(asBusRequestPrimitive(eventBus), …)` — instead of
|
|
724
1201
|
* hand-rolled `race(domain-event, *-failed, timeout)` blocks. The reply is
|
|
@@ -742,13 +1219,42 @@ declare function asBusRequestPrimitive(eventBus: EventBus): BusRequestPrimitive;
|
|
|
742
1219
|
*
|
|
743
1220
|
* This is a deferred-ack pattern: the result event attests that Stower has
|
|
744
1221
|
* persisted the annotation, not merely that the command was well-formed.
|
|
1222
|
+
*
|
|
1223
|
+
* ## The annotatability gate (MEDIA-CAPABILITY-DISPATCH D6)
|
|
1224
|
+
*
|
|
1225
|
+
* Every GUI and SDK caller travels `mark:create-request` and is checked here.
|
|
1226
|
+
* The check is deliberately NOT on `mark:create`, which Stower consumes: that
|
|
1227
|
+
* channel is the fact-writing path, and gating it would need a leniency flag
|
|
1228
|
+
* for restore — the compatibility switch D6 was written to avoid.
|
|
1229
|
+
*
|
|
1230
|
+
* D6's original second emitter, the TypeScript import/replay path, was deleted
|
|
1231
|
+
* by EXPORT-VIA-LAUNCHER P3 (2026-08-27), so nothing travels the ungated
|
|
1232
|
+
* channel today. The separation is kept anyway, because restore returns in the
|
|
1233
|
+
* launcher and its fact-writing seam is still an open decision (that plan's
|
|
1234
|
+
* P5) — a restore that re-subjected historical facts to this gate would be the
|
|
1235
|
+
* 2026-07-09 "events are facts, commands are requests" ruling undone.
|
|
745
1236
|
*/
|
|
746
|
-
declare function registerAnnotationAssemblyHandler(eventBus: EventBus,
|
|
1237
|
+
declare function registerAnnotationAssemblyHandler(eventBus: EventBus, kb: {
|
|
1238
|
+
views: Pick<ViewStorage, 'get'>;
|
|
1239
|
+
}, parentLogger: Logger): void;
|
|
747
1240
|
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
1241
|
+
/**
|
|
1242
|
+
* Annotation lookup handlers — split along the EXTRACT-LIBRARIAN P3 cutover:
|
|
1243
|
+
*
|
|
1244
|
+
* - `browse:annotation-context-requested` is a pure views+content read with
|
|
1245
|
+
* no Gatherer. It registers wherever those capabilities live — the gateway
|
|
1246
|
+
* and the standalone root.
|
|
1247
|
+
* - `gather:summary-requested` calls the Gatherer's inference path, so it
|
|
1248
|
+
* follows the Gatherer (the Archivist's D2-i pattern): the standalone root
|
|
1249
|
+
* and librarian-main register it beside their Gatherer; the gateway does
|
|
1250
|
+
* NOT.
|
|
1251
|
+
*/
|
|
1252
|
+
|
|
1253
|
+
declare function registerAnnotationContextHandler(eventBus: EventBus, kb: {
|
|
1254
|
+
views: Pick<ViewStorage, 'get'>;
|
|
1255
|
+
content: ContentReads;
|
|
1256
|
+
}, parentLogger: Logger): void;
|
|
1257
|
+
declare function registerGatherSummaryHandler(eventBus: EventBus, gatherer: Pick<Gatherer, 'generateAnnotationSummary'>, parentLogger: Logger): void;
|
|
752
1258
|
|
|
753
1259
|
/**
|
|
754
1260
|
* Handles `bind:update-body` — the Bind flow's authoritative "apply body
|
|
@@ -768,7 +1274,7 @@ declare function registerAnnotationLookupHandlers(eventBus: EventBus, kb: Knowle
|
|
|
768
1274
|
*/
|
|
769
1275
|
declare function registerBindUpdateBodyHandler(eventBus: EventBus, parentLogger: Logger): void;
|
|
770
1276
|
|
|
771
|
-
declare function registerJobCommandHandlers(eventBus: EventBus, jobQueue: JobQueue,
|
|
1277
|
+
declare function registerJobCommandHandlers(eventBus: EventBus, jobQueue: JobQueue, state: SemiontState, parentLogger: Logger): void;
|
|
772
1278
|
|
|
773
1279
|
/**
|
|
774
1280
|
* Bus command handlers — pure bus-event translators that bridge the
|
|
@@ -777,7 +1283,7 @@ declare function registerJobCommandHandlers(eventBus: EventBus, jobQueue: JobQue
|
|
|
777
1283
|
* `gather:summary-requested`) to the underlying make-meaning pipeline
|
|
778
1284
|
* (Stower, Browser, Gatherer, JobQueue).
|
|
779
1285
|
*
|
|
780
|
-
* These ran in `apps/
|
|
1286
|
+
* These ran in `apps/gateway` historically because the HTTP gateway was
|
|
781
1287
|
* the only consumer that needed them. They are not HTTP-specific — moving
|
|
782
1288
|
* them here means `LocalTransport` consumers (and any future transport)
|
|
783
1289
|
* get the same contract automatically.
|
|
@@ -787,7 +1293,7 @@ declare function registerJobCommandHandlers(eventBus: EventBus, jobQueue: JobQue
|
|
|
787
1293
|
* Register all bus command handlers on the make-meaning EventBus. Called
|
|
788
1294
|
* during `startMakeMeaning` after the JobQueue and KnowledgeSystem exist.
|
|
789
1295
|
*/
|
|
790
|
-
declare function registerBusHandlers(eventBus: EventBus, knowledgeSystem: KnowledgeSystem, jobQueue: JobQueue,
|
|
1296
|
+
declare function registerBusHandlers(eventBus: EventBus, knowledgeSystem: Pick<KnowledgeSystem, 'kb' | 'gatherer'>, jobQueue: JobQueue, state: SemiontState, logger: Logger): void;
|
|
791
1297
|
|
|
792
1298
|
/**
|
|
793
1299
|
* Entity Types Bootstrap
|
|
@@ -824,7 +1330,7 @@ declare function bootstrapEntityTypes(eventBus: EventBus, eventStore: EventStore
|
|
|
824
1330
|
/**
|
|
825
1331
|
* Read entity types from view storage projection
|
|
826
1332
|
*/
|
|
827
|
-
declare function readEntityTypesProjection(
|
|
1333
|
+
declare function readEntityTypesProjection(state: SemiontState): Promise<string[]>;
|
|
828
1334
|
|
|
829
1335
|
/**
|
|
830
1336
|
* SmelterActorStateUnit — domain-event fan-in for the Smelter worker.
|
|
@@ -862,8 +1368,8 @@ declare function createSmelterActorStateUnit(options: SmelterActorStateUnitOptio
|
|
|
862
1368
|
*
|
|
863
1369
|
* Consumes the smelter-relevant domain events surfaced by
|
|
864
1370
|
* `SmelterActorStateUnit.events$`, reads resource content via the injected
|
|
865
|
-
* `
|
|
866
|
-
*
|
|
1371
|
+
* `ContentReads` (in the fleet, the Archivist's byte route — the stored
|
|
1372
|
+
* bytes, untouched), chunks and embeds it via the configured
|
|
867
1373
|
* EmbeddingProvider, and indexes vectors into the VectorStore (Qdrant).
|
|
868
1374
|
* `smelter-main` is the container entry point that wires this up.
|
|
869
1375
|
*
|
|
@@ -950,7 +1456,19 @@ declare class Smelter {
|
|
|
950
1456
|
private rebuildAnchors$;
|
|
951
1457
|
private vectorStore;
|
|
952
1458
|
private embeddingProvider;
|
|
1459
|
+
/** Byte reads only — the Smelter never writes through this seam, so it
|
|
1460
|
+
* declares `ContentReads` and any implementation satisfies it: the
|
|
1461
|
+
* Archivist's client in the fleet, the working tree in-process. */
|
|
953
1462
|
private content;
|
|
1463
|
+
/**
|
|
1464
|
+
* The anchored-text store, held DIRECTLY (ANCHORED-TEXT-TO-SMELTER P1).
|
|
1465
|
+
*
|
|
1466
|
+
* It used to be built here over the content transport, which put the
|
|
1467
|
+
* gateway between this process and an artifact it produces itself. The
|
|
1468
|
+
* Smelter now owns the store on its own mount and is the only writer;
|
|
1469
|
+
* every read of it moved to the Archivist's bus channels.
|
|
1470
|
+
*/
|
|
1471
|
+
private anchoredStore;
|
|
954
1472
|
private bus;
|
|
955
1473
|
private chunkingConfig;
|
|
956
1474
|
private timing;
|
|
@@ -976,8 +1494,20 @@ declare class Smelter {
|
|
|
976
1494
|
private drainChain;
|
|
977
1495
|
constructor(events$: Observable<SmelterEvent>,
|
|
978
1496
|
/** `smelt:rebuild-anchors` commands — a separate stream, never the event mailbox (see SmelterActorStateUnit). */
|
|
979
|
-
rebuildAnchors$: Observable<EventMap['smelt:rebuild-anchors']>, vectorStore: VectorStore, embeddingProvider: EmbeddingProvider,
|
|
980
|
-
|
|
1497
|
+
rebuildAnchors$: Observable<EventMap['smelt:rebuild-anchors']>, vectorStore: VectorStore, embeddingProvider: EmbeddingProvider,
|
|
1498
|
+
/** Byte reads only — the Smelter never writes through this seam, so it
|
|
1499
|
+
* declares `ContentReads` and any implementation satisfies it: the
|
|
1500
|
+
* Archivist's client in the fleet, the working tree in-process. */
|
|
1501
|
+
content: ContentReads,
|
|
1502
|
+
/**
|
|
1503
|
+
* The anchored-text store, held DIRECTLY (ANCHORED-TEXT-TO-SMELTER P1).
|
|
1504
|
+
*
|
|
1505
|
+
* It used to be built here over the content transport, which put the
|
|
1506
|
+
* gateway between this process and an artifact it produces itself. The
|
|
1507
|
+
* Smelter now owns the store on its own mount and is the only writer;
|
|
1508
|
+
* every read of it moved to the Archivist's bus channels.
|
|
1509
|
+
*/
|
|
1510
|
+
anchoredStore: AnchoredTextStore, bus: BusRequestPrimitive, chunkingConfig: ChunkingConfig, timing: SmelterTiming, logger: Logger);
|
|
981
1511
|
get eventsProcessed(): number;
|
|
982
1512
|
get reconcileState(): ReconcileState;
|
|
983
1513
|
initialize(): void;
|
|
@@ -1135,228 +1665,6 @@ declare class Smelter {
|
|
|
1135
1665
|
private listAllResources;
|
|
1136
1666
|
}
|
|
1137
1667
|
|
|
1138
|
-
/**
|
|
1139
|
-
* Exchange Format Manifest Types
|
|
1140
|
-
*
|
|
1141
|
-
* Defines the metadata structures for backup archives.
|
|
1142
|
-
* The manifest is the first entry in an archive and describes its contents.
|
|
1143
|
-
*/
|
|
1144
|
-
declare const BACKUP_FORMAT: "semiont-backup";
|
|
1145
|
-
declare const FORMAT_VERSION = 1;
|
|
1146
|
-
interface BackupManifestHeader {
|
|
1147
|
-
format: typeof BACKUP_FORMAT;
|
|
1148
|
-
version: number;
|
|
1149
|
-
exportedAt: string;
|
|
1150
|
-
sourceUrl: string;
|
|
1151
|
-
stats: {
|
|
1152
|
-
streams: number;
|
|
1153
|
-
events: number;
|
|
1154
|
-
blobs: number;
|
|
1155
|
-
contentBytes: number;
|
|
1156
|
-
};
|
|
1157
|
-
}
|
|
1158
|
-
interface BackupStreamSummary {
|
|
1159
|
-
stream: string;
|
|
1160
|
-
eventCount: number;
|
|
1161
|
-
}
|
|
1162
|
-
declare const LINKED_DATA_FORMAT: "semiont-linked-data";
|
|
1163
|
-
interface LinkedDataManifest {
|
|
1164
|
-
'@context': Record<string, string>;
|
|
1165
|
-
'@type': string;
|
|
1166
|
-
'semiont:format': typeof LINKED_DATA_FORMAT;
|
|
1167
|
-
'semiont:version': number;
|
|
1168
|
-
'dct:created': string;
|
|
1169
|
-
'prov:wasGeneratedBy': {
|
|
1170
|
-
'@type': string;
|
|
1171
|
-
'prov:used': string;
|
|
1172
|
-
};
|
|
1173
|
-
'semiont:entityTypes': string[];
|
|
1174
|
-
'void:entities': number;
|
|
1175
|
-
}
|
|
1176
|
-
declare function isBackupManifest(obj: unknown): obj is BackupManifestHeader;
|
|
1177
|
-
declare function validateManifestVersion(version: number): void;
|
|
1178
|
-
|
|
1179
|
-
/**
|
|
1180
|
-
* Backup Exporter
|
|
1181
|
-
*
|
|
1182
|
-
* Produces a lossless tar.gz archive of the system of record:
|
|
1183
|
-
* - Event log (all streams, JSONL format)
|
|
1184
|
-
* - Working-tree content (archived as checksum-named blobs)
|
|
1185
|
-
*
|
|
1186
|
-
* Reads events via EventStore and content via WorkingTreeStore.
|
|
1187
|
-
* The archive can restore a complete knowledge base.
|
|
1188
|
-
*/
|
|
1189
|
-
|
|
1190
|
-
/** Subset of EventStore used by the backup exporter. */
|
|
1191
|
-
interface BackupEventStoreReader {
|
|
1192
|
-
log: {
|
|
1193
|
-
storage: {
|
|
1194
|
-
getAllResourceIds(): Promise<ResourceId[]>;
|
|
1195
|
-
};
|
|
1196
|
-
getEvents(resourceId: ResourceId): Promise<StoredEvent[]>;
|
|
1197
|
-
};
|
|
1198
|
-
}
|
|
1199
|
-
/** Subset of WorkingTreeStore used by the backup exporter. */
|
|
1200
|
-
interface BackupContentReader {
|
|
1201
|
-
retrieve(storageUri: string): Promise<Buffer>;
|
|
1202
|
-
}
|
|
1203
|
-
interface BackupExporterOptions {
|
|
1204
|
-
eventStore: BackupEventStoreReader;
|
|
1205
|
-
content: BackupContentReader;
|
|
1206
|
-
sourceUrl: string;
|
|
1207
|
-
logger?: Logger;
|
|
1208
|
-
}
|
|
1209
|
-
/**
|
|
1210
|
-
* Export a full backup of the knowledge base to a tar.gz stream.
|
|
1211
|
-
*
|
|
1212
|
-
* Archive structure:
|
|
1213
|
-
* .semiont/manifest.jsonl - Format metadata + per-stream checksums
|
|
1214
|
-
* .semiont/events/__system__.jsonl - System events
|
|
1215
|
-
* .semiont/events/{resourceId}.jsonl - Per-resource events
|
|
1216
|
-
* {checksum}.{ext} - Content blobs (root level)
|
|
1217
|
-
*/
|
|
1218
|
-
declare function exportBackup(options: BackupExporterOptions, output: Writable): Promise<BackupManifestHeader>;
|
|
1219
|
-
|
|
1220
|
-
/**
|
|
1221
|
-
* Event Replay
|
|
1222
|
-
*
|
|
1223
|
-
* Replays parsed JSONL event streams through the EventBus.
|
|
1224
|
-
* Each domain event is translated to the corresponding command event
|
|
1225
|
-
* (e.g. yield:created → yield:create), emitted, and the result
|
|
1226
|
-
* event is awaited before proceeding (backpressure).
|
|
1227
|
-
*
|
|
1228
|
-
* Content blobs are resolved lazily via a lookup function so that
|
|
1229
|
-
* the caller controls memory strategy (streaming, on-disk, etc.).
|
|
1230
|
-
*/
|
|
1231
|
-
|
|
1232
|
-
/**
|
|
1233
|
-
* Resolves a content blob by its checksum.
|
|
1234
|
-
* Returned by the caller so replay doesn't dictate memory strategy.
|
|
1235
|
-
*/
|
|
1236
|
-
type ContentBlobResolver = (checksum: string) => Buffer | undefined;
|
|
1237
|
-
interface ReplayStats {
|
|
1238
|
-
eventsReplayed: number;
|
|
1239
|
-
resourcesCreated: number;
|
|
1240
|
-
annotationsCreated: number;
|
|
1241
|
-
entityTypesAdded: number;
|
|
1242
|
-
}
|
|
1243
|
-
|
|
1244
|
-
/**
|
|
1245
|
-
* Backup Importer
|
|
1246
|
-
*
|
|
1247
|
-
* Restores a knowledge base from a backup tar.gz archive.
|
|
1248
|
-
* Replays events through the EventBus → Stower pipeline so all
|
|
1249
|
-
* derived state (materialized views, graph) rebuilds naturally.
|
|
1250
|
-
*
|
|
1251
|
-
* Accepts a Readable stream so callers can pipe directly from disk
|
|
1252
|
-
* or network without buffering the entire archive first.
|
|
1253
|
-
* Content blobs are resolved lazily via a closure over the parsed
|
|
1254
|
-
* tar entries, avoiding a separate copy of all blob data in memory.
|
|
1255
|
-
*/
|
|
1256
|
-
|
|
1257
|
-
interface BackupImporterOptions {
|
|
1258
|
-
eventBus: EventBus;
|
|
1259
|
-
/** Replay appends historical events directly (facts, not commands). */
|
|
1260
|
-
eventStore: EventStore;
|
|
1261
|
-
contentStore: WorkingTreeStore;
|
|
1262
|
-
logger?: Logger;
|
|
1263
|
-
}
|
|
1264
|
-
interface BackupImportResult {
|
|
1265
|
-
manifest: BackupManifestHeader;
|
|
1266
|
-
stats: ReplayStats;
|
|
1267
|
-
}
|
|
1268
|
-
/**
|
|
1269
|
-
* Import a backup archive by replaying events through the EventBus.
|
|
1270
|
-
*
|
|
1271
|
-
* Flow:
|
|
1272
|
-
* 1. Stream and decompress tar.gz entries
|
|
1273
|
-
* 2. Parse .semiont/manifest.jsonl → validate format
|
|
1274
|
-
* 3. Build blob resolver over root-level content entries
|
|
1275
|
-
* 4. Replay .semiont/events/__system__.jsonl (entity types)
|
|
1276
|
-
* 5. Replay each .semiont/events/{resourceId}.jsonl (resources, annotations)
|
|
1277
|
-
*
|
|
1278
|
-
* Events flow: importer → EventBus → Stower → EventStore + Views
|
|
1279
|
-
*/
|
|
1280
|
-
declare function importBackup(archive: Readable, options: BackupImporterOptions): Promise<BackupImportResult>;
|
|
1281
|
-
|
|
1282
|
-
/**
|
|
1283
|
-
* Linked Data Exporter
|
|
1284
|
-
*
|
|
1285
|
-
* Produces a JSON-LD tar.gz archive from the current state of the knowledge base.
|
|
1286
|
-
* Reads materialized views (not the event log) for a fast, current-state export.
|
|
1287
|
-
*
|
|
1288
|
-
* Archive structure:
|
|
1289
|
-
* .semiont/manifest.jsonld - JSON-LD manifest with format metadata
|
|
1290
|
-
* .semiont/resources/{resourceId}.jsonld - One JSON-LD document per resource
|
|
1291
|
-
* {checksum}.{ext} - Content blobs (root level)
|
|
1292
|
-
*/
|
|
1293
|
-
|
|
1294
|
-
/** Subset of ViewStorage used by the linked-data exporter. */
|
|
1295
|
-
interface LinkedDataViewReader {
|
|
1296
|
-
getAll(): Promise<Array<{
|
|
1297
|
-
resource: ResourceDescriptor;
|
|
1298
|
-
annotations: {
|
|
1299
|
-
annotations: Annotation[];
|
|
1300
|
-
};
|
|
1301
|
-
}>>;
|
|
1302
|
-
}
|
|
1303
|
-
/** Subset of WorkingTreeStore used by the linked-data exporter. */
|
|
1304
|
-
interface LinkedDataContentReader {
|
|
1305
|
-
retrieve(storageUri: string): Promise<Buffer>;
|
|
1306
|
-
}
|
|
1307
|
-
interface LinkedDataExporterOptions {
|
|
1308
|
-
views: LinkedDataViewReader;
|
|
1309
|
-
content: LinkedDataContentReader;
|
|
1310
|
-
sourceUrl: string;
|
|
1311
|
-
entityTypes: string[];
|
|
1312
|
-
includeArchived?: boolean;
|
|
1313
|
-
logger?: Logger;
|
|
1314
|
-
}
|
|
1315
|
-
/**
|
|
1316
|
-
* Export the knowledge base as a JSON-LD tar.gz archive.
|
|
1317
|
-
*/
|
|
1318
|
-
declare function exportLinkedData(options: LinkedDataExporterOptions, output: Writable): Promise<LinkedDataManifest>;
|
|
1319
|
-
|
|
1320
|
-
/**
|
|
1321
|
-
* Linked Data Importer
|
|
1322
|
-
*
|
|
1323
|
-
* Creates resources from a JSON-LD tar.gz archive exported by the linked-data exporter.
|
|
1324
|
-
* Unlike the backup importer, this is lossy — new resources are created (new IDs),
|
|
1325
|
-
* no event history is preserved. Entity types are restored from the manifest.
|
|
1326
|
-
*
|
|
1327
|
-
* Parses .semiont/manifest.jsonld for format validation and entity types,
|
|
1328
|
-
* then processes each .semiont/resources/{resourceId}.jsonld to create
|
|
1329
|
-
* resources and annotations via the EventBus → Stower pipeline.
|
|
1330
|
-
*/
|
|
1331
|
-
|
|
1332
|
-
interface LinkedDataImporterOptions {
|
|
1333
|
-
eventBus: EventBus;
|
|
1334
|
-
contentStore: WorkingTreeStore;
|
|
1335
|
-
userId: UserId;
|
|
1336
|
-
logger?: Logger;
|
|
1337
|
-
}
|
|
1338
|
-
interface LinkedDataImportResult {
|
|
1339
|
-
manifest: LinkedDataManifest;
|
|
1340
|
-
resourcesCreated: number;
|
|
1341
|
-
annotationsCreated: number;
|
|
1342
|
-
entityTypesAdded: number;
|
|
1343
|
-
}
|
|
1344
|
-
/**
|
|
1345
|
-
* Import a JSON-LD archive by creating resources through the EventBus.
|
|
1346
|
-
*
|
|
1347
|
-
* Flow:
|
|
1348
|
-
* 1. Stream and decompress tar.gz entries
|
|
1349
|
-
* 2. Parse .semiont/manifest.jsonld → validate format
|
|
1350
|
-
* 3. Build blob resolver over root-level content entries
|
|
1351
|
-
* 4. Add entity types from manifest via frame:add-entity-type
|
|
1352
|
-
* 5. For each .semiont/resources/{id}.jsonld:
|
|
1353
|
-
* a. Parse JSON-LD document
|
|
1354
|
-
* b. Resolve content blob by checksum from representations
|
|
1355
|
-
* c. Emit yield:create → await yield:created
|
|
1356
|
-
* d. For each annotation: emit mark:create → await mark:created
|
|
1357
|
-
*/
|
|
1358
|
-
declare function importLinkedData(archive: Readable, options: LinkedDataImporterOptions): Promise<LinkedDataImportResult>;
|
|
1359
|
-
|
|
1360
1668
|
/**
|
|
1361
1669
|
* Resource Operations
|
|
1362
1670
|
*
|
|
@@ -1390,6 +1698,39 @@ declare class ResourceOperations {
|
|
|
1390
1698
|
* Create a new resource via EventBus → Stower
|
|
1391
1699
|
*/
|
|
1392
1700
|
static createResource(input: CreateResourceInput, userId: UserId, eventBus: EventBus): Promise<ResourceId>;
|
|
1701
|
+
/**
|
|
1702
|
+
* Persist a CLONE via EventBus → Stower.
|
|
1703
|
+
*
|
|
1704
|
+
* Separate from `createResource` because a clone is a separate fact: it
|
|
1705
|
+
* names its parent, and `yield:cloned` requires that name. Callers reach
|
|
1706
|
+
* this only after the CloneTokenManager has validated the token — it is the
|
|
1707
|
+
* inner half of the flow, not a public entry point.
|
|
1708
|
+
*/
|
|
1709
|
+
static persistClone(input: {
|
|
1710
|
+
name: string;
|
|
1711
|
+
storageUri: string;
|
|
1712
|
+
contentChecksum: string;
|
|
1713
|
+
byteSize: number;
|
|
1714
|
+
format: ContentFormat;
|
|
1715
|
+
parentResourceId: string;
|
|
1716
|
+
entityTypes?: string[];
|
|
1717
|
+
language?: string;
|
|
1718
|
+
}, userId: UserId, eventBus: EventBus): Promise<ResourceId>;
|
|
1719
|
+
/**
|
|
1720
|
+
* Create a resource from a clone token via EventBus → CloneTokenManager.
|
|
1721
|
+
* The bytes are already stored (the gateway's upload path, `noGit` — the
|
|
1722
|
+
* Archivist's register does the one `git add`, D4b); the command carries
|
|
1723
|
+
* storage coordinates only (EXTRACT-ARCHIVIST P3, D4a).
|
|
1724
|
+
*/
|
|
1725
|
+
static createFromCloneToken(input: {
|
|
1726
|
+
token: string;
|
|
1727
|
+
name: string;
|
|
1728
|
+
storageUri: string;
|
|
1729
|
+
contentChecksum: string;
|
|
1730
|
+
byteSize: number;
|
|
1731
|
+
format: ContentFormat;
|
|
1732
|
+
archiveOriginal?: boolean;
|
|
1733
|
+
}, userId: UserId, eventBus: EventBus): Promise<ResourceId>;
|
|
1393
1734
|
}
|
|
1394
1735
|
|
|
1395
1736
|
/**
|
|
@@ -1418,15 +1759,21 @@ declare class AnnotationOperations {
|
|
|
1418
1759
|
/**
|
|
1419
1760
|
* Create a new annotation via EventBus → Stower
|
|
1420
1761
|
*/
|
|
1421
|
-
static createAnnotation(request: CreateAnnotationRequest, userId: UserId, creator: Agent, eventBus: EventBus
|
|
1762
|
+
static createAnnotation(request: CreateAnnotationRequest, userId: UserId, creator: Agent, eventBus: EventBus, kb: {
|
|
1763
|
+
views: Pick<ViewStorage, 'get'>;
|
|
1764
|
+
}): Promise<CreateAnnotationResult>;
|
|
1422
1765
|
/**
|
|
1423
1766
|
* Update annotation body via EventBus → Stower
|
|
1424
1767
|
*/
|
|
1425
|
-
static updateAnnotationBody(id: string, request: UpdateAnnotationBodyRequest, userId: UserId, eventBus: EventBus, kb:
|
|
1768
|
+
static updateAnnotationBody(id: string, request: UpdateAnnotationBodyRequest, userId: UserId, eventBus: EventBus, kb: {
|
|
1769
|
+
views: Pick<ViewStorage, 'get'>;
|
|
1770
|
+
}): Promise<UpdateAnnotationBodyResult>;
|
|
1426
1771
|
/**
|
|
1427
1772
|
* Delete an annotation via EventBus → Stower
|
|
1428
1773
|
*/
|
|
1429
|
-
static deleteAnnotation(id: string, resourceIdStr: string, userId: UserId, eventBus: EventBus, kb:
|
|
1774
|
+
static deleteAnnotation(id: string, resourceIdStr: string, userId: UserId, eventBus: EventBus, kb: {
|
|
1775
|
+
views: Pick<ViewStorage, 'get'>;
|
|
1776
|
+
}, logger?: Logger): Promise<void>;
|
|
1430
1777
|
}
|
|
1431
1778
|
|
|
1432
1779
|
/**
|
|
@@ -1439,6 +1786,14 @@ declare class AnnotationOperations {
|
|
|
1439
1786
|
* single-index reads; anything that FUSES sources belongs to the Matcher.
|
|
1440
1787
|
*/
|
|
1441
1788
|
|
|
1789
|
+
/** What the listing paths read (EXTRACT-ARCHIVIST P1): lexical search in
|
|
1790
|
+
* the graph, unsearched listings from views, the semantic fallback in the
|
|
1791
|
+
* vector index — plus `resourceWithViewGrace`'s graph-first hydration. */
|
|
1792
|
+
interface ListResourcesReads {
|
|
1793
|
+
views: Pick<ViewStorage, 'get' | 'getAll'>;
|
|
1794
|
+
graph: Pick<GraphDatabase, 'listResources' | 'getResource'>;
|
|
1795
|
+
vectors: Pick<VectorStore, 'searchResources'>;
|
|
1796
|
+
}
|
|
1442
1797
|
interface ListResourcesFilters {
|
|
1443
1798
|
search?: string;
|
|
1444
1799
|
archived?: boolean;
|
|
@@ -1481,7 +1836,9 @@ declare class ResourceContext {
|
|
|
1481
1836
|
/**
|
|
1482
1837
|
* Get resource metadata from view storage
|
|
1483
1838
|
*/
|
|
1484
|
-
static getResourceMetadata(resourceId: ResourceId, kb:
|
|
1839
|
+
static getResourceMetadata(resourceId: ResourceId, kb: {
|
|
1840
|
+
views: Pick<ViewStorage, 'get'>;
|
|
1841
|
+
}): Promise<ResourceDescriptor | null>;
|
|
1485
1842
|
/**
|
|
1486
1843
|
* List resources, optionally filtered, as one page plus the size of the whole
|
|
1487
1844
|
* match set. Every filter is applied before pagination on both paths — a
|
|
@@ -1496,7 +1853,7 @@ declare class ResourceContext {
|
|
|
1496
1853
|
* barrier-stamped projection, so an unsearched listing is read-your-writes
|
|
1497
1854
|
* where the graph is only eventually consistent.
|
|
1498
1855
|
*/
|
|
1499
|
-
static listResources(filters: ListResourcesFilters | undefined, kb:
|
|
1856
|
+
static listResources(filters: ListResourcesFilters | undefined, kb: ListResourcesReads, semantic: SemanticFallbackDeps): Promise<ListResourcesResult>;
|
|
1500
1857
|
/**
|
|
1501
1858
|
* Answer an empty lexical search from the vector index (SEMANTIC-FALLBACK):
|
|
1502
1859
|
* embed the query once, fold chunk hits per resource, floor them, and label
|
|
@@ -1517,189 +1874,21 @@ declare class ResourceContext {
|
|
|
1517
1874
|
* Add content previews to resources (for search results)
|
|
1518
1875
|
* Retrieves and decodes the first 200 characters of each resource's primary representation
|
|
1519
1876
|
*/
|
|
1520
|
-
static addContentPreviews(resources: ResourceDescriptor[], kb:
|
|
1877
|
+
static addContentPreviews(resources: ResourceDescriptor[], kb: {
|
|
1878
|
+
content: Pick<WorkingTreeStore, 'retrieve'>;
|
|
1879
|
+
}): Promise<Array<ResourceDescriptor & {
|
|
1521
1880
|
content: string;
|
|
1522
1881
|
}>>;
|
|
1523
1882
|
/**
|
|
1524
1883
|
* Get full content for a resource
|
|
1525
|
-
* Retrieves and decodes the primary representation
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
* Assembles annotation context from view storage and content store.
|
|
1534
|
-
* Provides methods for:
|
|
1535
|
-
* - Getting resource annotations
|
|
1536
|
-
* - Building LLM context for annotations
|
|
1537
|
-
* - Extracting annotation text context
|
|
1538
|
-
* - Generating AI summaries
|
|
1539
|
-
*/
|
|
1540
|
-
|
|
1541
|
-
type AnnotationContextResponse = components['schemas']['AnnotationContextResponse'];
|
|
1542
|
-
type ContextualSummaryResponse = components['schemas']['ContextualSummaryResponse'];
|
|
1543
|
-
interface BuildContextOptions {
|
|
1544
|
-
includeSourceContext?: boolean;
|
|
1545
|
-
includeTargetContext?: boolean;
|
|
1546
|
-
contextWindow?: number;
|
|
1547
|
-
}
|
|
1548
|
-
declare class AnnotationContext {
|
|
1549
|
-
/**
|
|
1550
|
-
* Build LLM context for an annotation
|
|
1551
|
-
*
|
|
1552
|
-
* @param annotationId - Bare annotation ID
|
|
1553
|
-
* @param resourceId - Source resource ID
|
|
1554
|
-
* @param kb - Knowledge base stores
|
|
1555
|
-
* @param options - Context building options
|
|
1556
|
-
* @param inferenceClient - Optional inference client for target context summary
|
|
1557
|
-
* @returns Rich context for LLM processing
|
|
1558
|
-
* @throws Error if annotation or resource not found
|
|
1559
|
-
*/
|
|
1560
|
-
static buildLLMContext(annotationId: AnnotationId, resourceId: ResourceId, kb: KnowledgeBase, embeddingProvider: EmbeddingProvider, options?: BuildContextOptions, inferenceClient?: InferenceClient, logger?: Logger): Promise<GatheredContext>;
|
|
1561
|
-
/**
|
|
1562
|
-
* Get resource annotations from view storage (fast path)
|
|
1563
|
-
* Throws if view missing
|
|
1564
|
-
*/
|
|
1565
|
-
static getResourceAnnotations(resourceId: ResourceId, kb: KnowledgeBase): Promise<ResourceAnnotations>;
|
|
1566
|
-
/**
|
|
1567
|
-
* Get all annotations
|
|
1568
|
-
* @returns Array of all annotation objects
|
|
1569
|
-
*/
|
|
1570
|
-
static getAllAnnotations(resourceId: ResourceId, kb: KnowledgeBase): Promise<Annotation[]>;
|
|
1571
|
-
/**
|
|
1572
|
-
* Enrich reference annotations with resolved document names
|
|
1573
|
-
* Adds _resolvedDocumentName property to annotations that link to documents
|
|
1574
|
-
* @private
|
|
1575
|
-
*/
|
|
1576
|
-
private static enrichResolvedReferences;
|
|
1577
|
-
/**
|
|
1578
|
-
* Get resource stats (version info)
|
|
1579
|
-
* @returns Version and timestamp info for the annotations
|
|
1580
|
-
*/
|
|
1581
|
-
static getResourceStats(resourceId: ResourceId, kb: KnowledgeBase): Promise<{
|
|
1582
|
-
resourceId: ResourceId;
|
|
1583
|
-
version: number;
|
|
1584
|
-
updatedAt: string;
|
|
1585
|
-
}>;
|
|
1586
|
-
/**
|
|
1587
|
-
* Check if resource exists in view storage
|
|
1588
|
-
*/
|
|
1589
|
-
static resourceExists(resourceId: ResourceId, kb: KnowledgeBase): Promise<boolean>;
|
|
1590
|
-
/**
|
|
1591
|
-
* Get a single annotation by ID
|
|
1592
|
-
* O(1) lookup using resource ID to access view storage
|
|
1593
|
-
*/
|
|
1594
|
-
static getAnnotation(annotationId: AnnotationId, resourceId: ResourceId, kb: KnowledgeBase): Promise<Annotation | null>;
|
|
1595
|
-
/**
|
|
1596
|
-
* List annotations with optional filtering
|
|
1597
|
-
* @param filters - Optional filters like resourceId and type
|
|
1598
|
-
* @throws Error if resourceId not provided (cross-resource queries not supported in view storage)
|
|
1599
|
-
*/
|
|
1600
|
-
static listAnnotations(filters: {
|
|
1601
|
-
resourceId?: ResourceId;
|
|
1602
|
-
type?: AnnotationCategory;
|
|
1603
|
-
} | undefined, kb: KnowledgeBase): Promise<Annotation[]>;
|
|
1604
|
-
/**
|
|
1605
|
-
* Get annotation context (selected text with surrounding context)
|
|
1606
|
-
*/
|
|
1607
|
-
static getAnnotationContext(annotationId: AnnotationId, resourceId: ResourceId, contextBefore: number, contextAfter: number, kb: KnowledgeBase): Promise<AnnotationContextResponse>;
|
|
1608
|
-
/**
|
|
1609
|
-
* Generate AI summary of annotation in context
|
|
1610
|
-
*/
|
|
1611
|
-
static generateAnnotationSummary(annotationId: AnnotationId, resourceId: ResourceId, kb: KnowledgeBase, inferenceClient: InferenceClient): Promise<ContextualSummaryResponse>;
|
|
1612
|
-
/**
|
|
1613
|
-
* Get resource content as string
|
|
1614
|
-
*/
|
|
1615
|
-
private static getResourceContent;
|
|
1616
|
-
/**
|
|
1617
|
-
* Extract annotation context from resource content
|
|
1618
|
-
*/
|
|
1619
|
-
private static extractAnnotationContext;
|
|
1620
|
-
/**
|
|
1621
|
-
* Generate LLM summary of annotation in context
|
|
1622
|
-
* Creates inference client per-request (HTTP handler context)
|
|
1623
|
-
*/
|
|
1624
|
-
private static generateSummary;
|
|
1625
|
-
}
|
|
1626
|
-
|
|
1627
|
-
/**
|
|
1628
|
-
* Graph Context
|
|
1629
|
-
*
|
|
1630
|
-
* Provides graph database operations for resources and annotations.
|
|
1631
|
-
* All methods require graph traversal - must use graph database.
|
|
1632
|
-
*/
|
|
1633
|
-
|
|
1634
|
-
type KnowledgeGraph = components['schemas']['KnowledgeGraph'];
|
|
1635
|
-
declare class GraphContext {
|
|
1636
|
-
/**
|
|
1637
|
-
* Get all resources referencing this resource (backlinks)
|
|
1638
|
-
* Requires graph traversal - must use graph database
|
|
1639
|
-
*/
|
|
1640
|
-
static getBacklinks(resourceId: ResourceId, kb: KnowledgeBase): Promise<Annotation[]>;
|
|
1641
|
-
/**
|
|
1642
|
-
* Find shortest path between two resources
|
|
1643
|
-
* Requires graph traversal - must use graph database
|
|
1644
|
-
*/
|
|
1645
|
-
static findPath(fromResourceId: ResourceId, toResourceId: ResourceId, kb: KnowledgeBase, maxDepth?: number): Promise<GraphPath[]>;
|
|
1646
|
-
/**
|
|
1647
|
-
* Get resource connections (graph edges)
|
|
1648
|
-
* Requires graph traversal - must use graph database
|
|
1649
|
-
*/
|
|
1650
|
-
static getResourceConnections(resourceId: ResourceId, kb: KnowledgeBase): Promise<GraphConnection[]>;
|
|
1651
|
-
/**
|
|
1652
|
-
* Build the unified knowledge graph for a resource's neighborhood:
|
|
1653
|
-
* resources AND annotations as typed nodes, typed/directional edges.
|
|
1654
|
-
*
|
|
1655
|
-
* This is the single graph builder (CONTEXT-UNIFICATION D3) — both the
|
|
1656
|
-
* matcher (ranking) and the resource/viz path consume it. The flattened
|
|
1657
|
-
* signals the matcher reads today (`connections`, `citedBy`/count,
|
|
1658
|
-
* `siblingEntityTypes`, `bidirectional`) are all derivable from this:
|
|
1659
|
-
* - peer connections → resource nodes + main→peer edges carrying `bidirectional`
|
|
1660
|
-
* - inbound citations → citing-resource nodes + `citation` edges (citing→main),
|
|
1661
|
-
* so citedByCount = inbound citation-edge count
|
|
1662
|
-
* - annotations on the resource → `annotation` nodes + `annotation-of` edges,
|
|
1663
|
-
* so siblingEntityTypes = union of those nodes' entityTypes
|
|
1664
|
-
*/
|
|
1665
|
-
static buildKnowledgeGraph(resourceId: ResourceId, kb: KnowledgeBase,
|
|
1666
|
-
/** Breadcrumb sink for the projection-lag degrade path; the degrade counter fires regardless. */
|
|
1667
|
-
logger?: Logger): Promise<KnowledgeGraph>;
|
|
1668
|
-
}
|
|
1669
|
-
|
|
1670
|
-
/**
|
|
1671
|
-
* LLM Context
|
|
1672
|
-
*
|
|
1673
|
-
* Builds comprehensive context for LLM processing of resources
|
|
1674
|
-
* Orchestrates: ResourceContext, GraphContext, AnnotationContext, and generation functions
|
|
1675
|
-
*/
|
|
1676
|
-
|
|
1677
|
-
interface LLMContextOptions {
|
|
1678
|
-
depth: number;
|
|
1679
|
-
maxResources: number;
|
|
1680
|
-
includeContent: boolean;
|
|
1681
|
-
includeSummary: boolean;
|
|
1682
|
-
/**
|
|
1683
|
-
* Entity types to exclude from the resource-gather semantic recall
|
|
1684
|
-
* (caller-supplied; e.g. ['Question']). Optional; default none.
|
|
1685
|
-
*/
|
|
1686
|
-
excludeEntityTypes?: string[];
|
|
1687
|
-
}
|
|
1688
|
-
declare class LLMContext {
|
|
1689
|
-
/**
|
|
1690
|
-
* Get comprehensive LLM context for a resource
|
|
1691
|
-
* Includes: main resource, related resources, annotations, graph, content, summary, references
|
|
1692
|
-
*/
|
|
1693
|
-
static getResourceContext(resourceId: ResourceId, options: LLMContextOptions, kb: KnowledgeBase, inferenceClient: InferenceClient,
|
|
1694
|
-
/**
|
|
1695
|
-
* Bound on the semanticContext read-your-writes barrier
|
|
1696
|
-
* (SMELTER-INDEX-SYNC D3/D5). Operator-owned deployment policy: born in
|
|
1697
|
-
* `[environments.<env>.make-meaning.gather] settleTimeoutMs` (the TOML
|
|
1698
|
-
* loader holds the ONE default, 15s), threaded here as a plain argument
|
|
1699
|
-
* via `MakeMeaningConfig.gather` → Gatherer. Must nest inside downstream
|
|
1700
|
-
* watchdogs (A4) — e.g. my-chat's 90s generation stall watchdog.
|
|
1701
|
-
*/
|
|
1702
|
-
settleTimeoutMs: number, logger: Logger): Promise<GatheredContext>;
|
|
1884
|
+
* Retrieves and decodes the primary representation. ResourceId-keyed
|
|
1885
|
+
* (EXTRACT-LIBRARIAN P3, D-CONTENT b): the descriptor's `storageUri` is the
|
|
1886
|
+
* has-content signal; the fetch itself goes by id, so the standalone
|
|
1887
|
+
* Librarian serves it over the transport.
|
|
1888
|
+
*/
|
|
1889
|
+
static getResourceContent(resource: ResourceDescriptor, kb: {
|
|
1890
|
+
content: ContentReads;
|
|
1891
|
+
}): Promise<string | undefined>;
|
|
1703
1892
|
}
|
|
1704
1893
|
|
|
1705
1894
|
/**
|
|
@@ -1722,5 +1911,5 @@ declare function generateResourceSummary(resourceName: string, content: string,
|
|
|
1722
1911
|
*/
|
|
1723
1912
|
declare function generateReferenceSuggestions(referenceTitle: string, client: InferenceClient, entityType?: string, currentContent?: string): Promise<string[] | null>;
|
|
1724
1913
|
|
|
1725
|
-
export { AnnotationContext, AnnotationOperations,
|
|
1726
|
-
export type {
|
|
1914
|
+
export { AnnotationContext, AnnotationOperations, Browser, CloneTokenManager, Gatherer, GraphContext, LLMContext, LocalContentTransport, LocalTransport, Matcher, ResourceContext, ResourceOperations, Smelter, Stower, asBusRequestPrimitive, bootstrapEntityTypes, createArchivistServer, createKnowledgeBase, createSmelterActorStateUnit, generateReferenceSuggestions, generateResourceSummary, makeMeaningConfigFrom, readEntityTypesProjection, registerAnnotationAssemblyHandler, registerAnnotationContextHandler, registerBindUpdateBodyHandler, registerBusHandlers, registerGatherSummaryHandler, registerJobCommandHandlers, requireKBName, startMakeMeaning, startMakeMeaningGateway, stopKnowledgeSystem };
|
|
1915
|
+
export type { ArchivistServerDeps, BuildContextOptions, CreateAnnotationResult, CreateResourceInput, CreateResourceResult, GatewayKnowledgeSystem, GatewayMakeMeaningService, KnowledgeBase, KnowledgeSystem, LLMContextOptions, ListResourcesFilters, ListResourcesResult, LocalTransportConfig, MakeMeaningConfig, MakeMeaningService, ReconcileState, ReconcileSummary, SmelterActorStateUnit, SmelterActorStateUnitOptions, SmelterEvent, SmelterInput, SmelterTiming, SmelterWorkItem, UpdateAnnotationBodyResult };
|