@semiont/api-client 0.4.20 → 0.4.22

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/dist/index.d.ts CHANGED
@@ -1,1327 +1,173 @@
1
- import * as _semiont_core from '@semiont/core';
2
- import { BaseUrl, Logger, ResourceId, AccessToken, components, UserDID, paths, AnnotationId, GraphConnection, UpdateResourceInput, Motivation, MarkProgress, BodyOperation, GatheredContext, YieldProgress as YieldProgress$1, JobId, EventBus, Email, RefreshToken, GoogleCredential, ContentFormat, SearchQuery, CloneToken, EntityType } from '@semiont/core';
3
- export { Logger, Selector, getFragmentSelector, getSvgSelector, getTextPositionSelector, validateSvgMarkup } from '@semiont/core';
4
- import { Observable } from 'rxjs';
5
- export { BoundingBox, ContentCache, FragmentSelector, JWTTokenSchema, LOCALES, LocaleInfo, MatchQuality, Point, SvgSelector, TextPosition, TextPositionSelector, TextQuoteSelector, ValidatedAnnotation, ValidationFailure, ValidationResult, ValidationSuccess, buildContentCache, createCircleSvg, createPolygonSvg, createRectangleSvg, decodeRepresentation, decodeWithCharset, extractBoundingBox, extractCharset, extractContext, findBestTextMatch, findTextWithContext, formatLocaleDisplay, getAllLocaleCodes, getAnnotationExactText, getBodySource, getBodyType, getChecksum, getCommentText, getCreator, getDerivedFrom, getExactText, getLanguage, getLocaleEnglishName, getLocaleInfo, getLocaleNativeName, getNodeEncoding, getPrimaryMediaType, getPrimaryRepresentation, getPrimarySelector, getResourceEntityTypes, getResourceId, getStorageUri, getTargetSelector, getTargetSource, getTextQuoteSelector, hasTargetSelector, isArchived, isAssessment, isBodyResolved, isComment, isDraft, isHighlight, isReference, isResolvedReference, isStubReference, isTag, isValidEmail, normalizeCoordinates, normalizeText, parseSvgSelector, scaleSvgToNative, validateAndCorrectOffsets, validateData, verifyPosition } from './utils/index.js';
1
+ import { KyInstance } from 'ky';
2
+ import { Observable, BehaviorSubject } from 'rxjs';
3
+ import { ConnectionState, ITransport, BaseUrl, AccessToken, Logger, EventMap, ResourceId, EventBus, Email, components, GoogleCredential, RefreshToken, UserResponse, ListUsersResponse, UserDID, UpdateUserRequest, UpdateUserResponse, ProgressCallback, ProgressEvent, HealthCheckResponse, StatusResponse, IContentTransport, PutBinaryRequest, ContentFormat } from '@semiont/core';
6
4
 
7
- /**
8
- * TypeScript types for SSE event payloads.
9
- *
10
- * Progress and result types for events delivered via the long-lived
11
- * events-stream. These match the payloads emitted by job workers on
12
- * the resource-scoped EventBus. Used by the MCP server for type-safe
13
- * event handling.
14
- */
15
- /**
16
- * Progress event for reference/linking detection stream
17
- *
18
- * Sent by POST /resources/:id/annotate-references
19
- *
20
- * @example
21
- * ```typescript
22
- * stream.onProgress((progress: ReferenceDetectionProgress) => {
23
- * if (progress.status === 'scanning') {
24
- * console.log(`Scanning for ${progress.currentEntityType}...`);
25
- * console.log(`Progress: ${progress.processedEntityTypes}/${progress.totalEntityTypes}`);
26
- * }
27
- * });
28
- * ```
29
- */
30
- interface ReferenceDetectionProgress {
31
- /** Current status of detection operation */
32
- status: 'started' | 'scanning' | 'complete' | 'error';
33
- /** Resource ID being scanned */
34
- resourceId: string;
35
- /** Currently scanning for this entity type (only present during 'scanning') */
36
- currentEntityType?: string;
37
- /** Total number of entity types to scan */
38
- totalEntityTypes: number;
39
- /** Number of entity types processed so far */
40
- processedEntityTypes: number;
41
- /** Human-readable status message */
42
- message?: string;
43
- /** Total entities found (only present in 'complete') */
44
- foundCount?: number;
45
- }
46
- /**
47
- * Progress event for resource generation stream
48
- *
49
- * Sent by POST /resources/:resourceId/annotations/:annotationId/yield-resource
50
- *
51
- * @example
52
- * ```typescript
53
- * stream.onProgress((progress: YieldProgress) => {
54
- * console.log(`${progress.status}: ${progress.percentage}%`);
55
- * console.log(progress.message);
56
- * });
57
- * ```
58
- */
59
- interface YieldProgress {
60
- /** Current stage of generation operation */
61
- status: 'started' | 'fetching' | 'generating' | 'creating' | 'complete' | 'error';
62
- /** Annotation ID being used as source */
63
- referenceId: string;
64
- /** Name of resource being generated */
65
- resourceName?: string;
66
- /** ID of generated resource (only present in 'complete') */
67
- resourceId?: string;
68
- /** ID of source resource */
69
- sourceResourceId?: string;
70
- /** Percentage complete (0-100) */
71
- percentage: number;
72
- /** Human-readable status message */
73
- message?: string;
74
- }
75
- /**
76
- * Resource event from real-time event stream
77
- *
78
- * Sent by GET /resources/:id/events/stream
79
- *
80
- * This represents a single event from the event store, broadcast in real-time
81
- * as it occurs. Used for real-time collaboration - multiple users see each
82
- * other's changes as they happen.
83
- *
84
- * Re-exported from @semiont/core (authoritative source).
85
- * The discriminated union type provides type-safe event handling.
86
- *
87
- * @example
88
- * ```typescript
89
- * stream.onEvent((event) => {
90
- * console.log(`Event: ${event.type}`);
91
- * console.log(`User: ${event.userId}`);
92
- * console.log(`Payload:`, event.payload);
93
- * });
94
- * ```
95
- */
96
- /**
97
- * SSE stream controller interface
98
- *
99
- * Returned by all SSE methods. Events auto-emit to EventBus (required).
100
- *
101
- * **Architecture Note**: All SSE methods require `eventBus` in options to enforce
102
- * event-driven architecture. This is enforced at compile time via TypeScript.
103
- *
104
- * @example
105
- * ```typescript
106
- * const eventBus = new EventBus();
107
- *
108
- * // Subscribe to events
109
- * eventBus.get('detection:progress').subscribe((p) => console.log(p.message));
110
- * eventBus.get('detection:complete').subscribe(() => console.log('Done!'));
111
- * eventBus.get('detection:failed').subscribe(({ error }) => console.error(error));
112
- *
113
- * // Start stream - eventBus is required (TypeScript enforced)
114
- * const stream = client.sse.markReferences(resourceId, request, { auth, eventBus });
115
- *
116
- * // Cleanup when done
117
- * stream.close();
118
- * ```
119
- */
120
- interface SSEStream {
121
- /**
122
- * Close the SSE stream and abort the connection
123
- *
124
- * Should be called to cleanup resources when stream is no longer needed.
125
- * Safe to call multiple times.
126
- *
127
- * @example
128
- * ```typescript
129
- * // React cleanup
130
- * useEffect(() => {
131
- * const stream = client.sse.markReferences(..., { auth, eventBus });
132
- * return () => stream.close();
133
- * }, []);
134
- * ```
135
- */
136
- close(): void;
137
- }
138
-
139
- /**
140
- * SSE meta event for stream connection lifecycle
141
- * Internal to SSE infrastructure, not part of core event protocol
142
- */
143
- declare const SSE_STREAM_CONNECTED: "stream-connected";
144
- type SSEStreamConnected = typeof SSE_STREAM_CONNECTED;
145
- /**
146
- * SSE Client configuration
147
- */
148
- interface SSEClientConfig {
149
- baseUrl: BaseUrl;
150
- logger?: Logger;
151
- }
152
- /**
153
- * Options for SSE requests
154
- */
155
- interface SSERequestOptions {
156
- auth?: AccessToken;
157
- /** EventBus for event-driven architecture (required) */
158
- eventBus: _semiont_core.EventBus;
159
- }
160
- /**
161
- * SSE Client for long-lived streaming connections.
162
- *
163
- * This client has three methods — one per long-lived broadcast stream.
164
- * Per-operation SSE routes have been replaced by plain HTTP POSTs with
165
- * results delivered via the events-stream.
166
- *
167
- * Uses native fetch() instead of ky for SSE support.
168
- * Auth tokens are passed per-request via options.
169
- *
170
- * @example
171
- * ```typescript
172
- * const sseClient = new SSEClient({ baseUrl: 'http://localhost:4000' });
173
- *
174
- * // Open a long-lived resource events stream (auto-reconnects on disconnect)
175
- * const stream = sseClient.resourceEvents(resourceId, { auth, eventBus });
176
- *
177
- * // Events auto-route to EventBus typed channels
178
- * eventBus.get('mark:body-updated').subscribe((event) => { ... });
179
- *
180
- * // Close when done
181
- * stream.close();
182
- * ```
183
- */
184
- declare class SSEClient {
185
- private baseUrl;
186
- private logger?;
187
- constructor(config: SSEClientConfig);
188
- /**
189
- * Get common headers for SSE requests
190
- */
191
- private getHeaders;
192
- /**
193
- * Subscribe to resource events (long-lived stream)
194
- *
195
- * Opens a long-lived SSE connection to receive real-time events for a resource.
196
- * Used for collaborative editing - see events from other users as they happen.
197
- *
198
- * This stream does NOT have a complete event - it stays open until explicitly closed.
199
- *
200
- * @param resourceId - Resource URI or ID to subscribe to
201
- * @param options - Request options (auth token)
202
- * @returns SSE stream controller with event callback
203
- *
204
- * @example
205
- * ```typescript
206
- * const stream = sseClient.resourceEvents(
207
- * 'http://localhost:4000/resources/doc-123',
208
- * { auth: 'your-token' }
209
- * );
210
- *
211
- * stream.onProgress((event) => {
212
- * console.log(`Event: ${event.type}`);
213
- * console.log(`User: ${event.userId}`);
214
- * console.log(`Sequence: ${event.metadata.sequenceNumber}`);
215
- * console.log(`Payload:`, event.payload);
216
- * });
217
- *
218
- * stream.onError((error) => {
219
- * console.error('Stream error:', error.message);
220
- * });
221
- *
222
- * // Close when no longer needed (e.g., component unmount)
223
- * stream.close();
224
- * ```
225
- */
226
- resourceEvents(resourceId: ResourceId, options: SSERequestOptions & {
227
- onConnected?: () => void;
228
- }): SSEStream;
229
- /**
230
- * Subscribe to global system events (long-lived stream)
231
- *
232
- * Opens a long-lived SSE connection to receive system-level domain events
233
- * (entity type additions, etc.) that are not scoped to a specific resource.
234
- *
235
- * @param options - Request options (auth token, eventBus)
236
- * @returns SSE stream controller
237
- *
238
- * @example
239
- * ```typescript
240
- * const stream = sseClient.globalEvents({ auth: 'your-token', eventBus });
241
- *
242
- * // Events auto-emit to EventBus typed channels — subscribe there
243
- * eventBus.get('mark:entity-type-added').subscribe((stored) => {
244
- * // Invalidate entity types query
245
- * });
246
- *
247
- * // Close when no longer needed
248
- * stream.close();
249
- * ```
250
- */
251
- globalEvents(options: SSERequestOptions & {
252
- onConnected?: () => void;
253
- }): SSEStream;
254
- /**
255
- * Subscribe to participant attention stream (long-lived stream)
256
- *
257
- * Opens a participant-scoped SSE connection to receive cross-participant
258
- * beckon signals. Signals are delivered as 'beckon:focus' events routed
259
- * to the EventBus — the existing scroll/highlight machinery handles them.
260
- *
261
- * Signals are ephemeral — delivered if connected, dropped if not.
262
- *
263
- * @param options - Request options (auth token, eventBus)
264
- * @returns SSE stream controller
265
- */
266
- attentionStream(options: SSERequestOptions & {
267
- onConnected?: () => void;
268
- }): SSEStream;
269
- }
270
-
271
- /**
272
- * Verb Namespace Interfaces
273
- *
274
- * These interfaces define the public API of the Semiont api-client,
275
- * organized by the 7 domain flows (Browse, Mark, Bind, Gather, Match,
276
- * Yield, Beckon) plus infrastructure namespaces (Job, Auth, Admin).
277
- *
278
- * Each namespace maps 1:1 to a flow. Each flow maps to a clear actor
279
- * on the backend. The frontend calls `client.mark.annotation()` and the
280
- * proxy handles HTTP, auth, SSE, and caching internally.
281
- *
282
- * Return type conventions:
283
- * - Browse live queries → Observable (events-stream driven, cached)
284
- * - Browse one-shot reads → Promise (fetch once, no cache)
285
- * - Commands (mark, bind, yield.resource) → Promise (fire-and-forget)
286
- * - Long-running ops (gather, match, yield.fromAnnotation, mark.assist) → Observable (progress + result)
287
- * - Ephemeral signals (beckon) → void
288
- */
289
-
290
- type Annotation$1 = components['schemas']['Annotation'];
291
- type ResourceDescriptor$2 = components['schemas']['ResourceDescriptor'];
292
- type StoredEventResponse$1 = components['schemas']['StoredEventResponse'];
293
- type GatherProgress = components['schemas']['GatherProgress'];
294
- type MatchSearchResult = components['schemas']['MatchSearchResult'];
295
- type MarkAssistFinished = components['schemas']['MarkAssistFinished'];
296
- type GatherAnnotationComplete = components['schemas']['GatherAnnotationComplete'];
297
- type JobStatusResponse$1 = components['schemas']['JobStatusResponse'];
298
- type AuthResponse$1 = components['schemas']['AuthResponse'];
299
- type OAuthConfigResponse$1 = components['schemas']['OAuthConfigResponse'];
300
- type AdminUserStatsResponse$1 = components['schemas']['AdminUserStatsResponse'];
301
- type ResponseContent$1<T> = T extends {
302
- responses: {
303
- 200: {
304
- content: {
305
- 'application/json': infer R;
306
- };
307
- };
308
- };
309
- } ? R : T extends {
310
- responses: {
311
- 201: {
312
- content: {
313
- 'application/json': infer R;
314
- };
315
- };
316
- };
317
- } ? R : never;
318
- type RequestContent$1<T> = T extends {
319
- requestBody?: {
320
- content: {
321
- 'application/json': infer R;
322
- };
323
- };
324
- } ? R : never;
325
- /** Input for creating an annotation via mark.annotation() */
326
- type CreateAnnotationInput = RequestContent$1<paths['/resources/{id}/annotations']['post']>;
327
- /** Input for creating a resource via yield.resource() */
328
- interface CreateResourceInput {
329
- name: string;
330
- file: File | Buffer;
331
- format: string;
332
- entityTypes?: string[];
333
- language?: string;
334
- creationMethod?: string;
335
- sourceAnnotationId?: string;
336
- sourceResourceId?: string;
337
- storageUri: string;
338
- }
339
- /** Options for yield.fromAnnotation() */
340
- interface GenerationOptions {
341
- title: string;
342
- storageUri: string;
343
- context: GatheredContext;
344
- prompt?: string;
345
- language?: string;
346
- temperature?: number;
347
- maxTokens?: number;
348
- }
349
- /** Options for mark.assist() */
350
- interface MarkAssistOptions {
351
- entityTypes?: string[];
352
- includeDescriptiveReferences?: boolean;
353
- instructions?: string;
354
- density?: number;
355
- tone?: string;
356
- language?: string;
357
- schemaId?: string;
358
- categories?: string[];
359
- }
360
- /** Options for yield.createFromToken() */
361
- type CreateFromTokenOptions = RequestContent$1<paths['/api/clone-tokens/create-resource']['post']>;
362
- /** Referenced-by entry from browse.referencedBy() */
363
- type ReferencedByEntry = ResponseContent$1<paths['/resources/{id}/referenced-by']['get']>['referencedBy'][number];
364
- /** Annotation history from browse.annotationHistory() */
365
- type AnnotationHistoryResponse = ResponseContent$1<paths['/resources/{resourceId}/annotations/{annotationId}/history']['get']>;
366
- /** User object from auth/admin responses */
367
- type User = AuthResponse$1['user'];
368
- /**
369
- * Progress emitted by gather.annotation() Observable.
370
- * Emits GatherProgress during assembly, then GatherAnnotationComplete on finish.
371
- */
372
- type GatherAnnotationProgress = GatherProgress | GatherAnnotationComplete;
373
- /**
374
- * Progress emitted by match.search() Observable.
375
- * Emits the final MatchSearchResult (no intermediate progress events currently).
376
- */
377
- type MatchSearchProgress = MatchSearchResult;
378
- /**
379
- * Progress emitted by mark.assist() Observable.
380
- * Emits MarkProgress during scanning, then MarkAssistFinished on completion.
381
- * On failure, the Observable errors with MarkAssistFailed.
382
- */
383
- type MarkAssistProgress = MarkProgress | MarkAssistFinished;
384
- /**
385
- * Browse — reads from materialized views
386
- *
387
- * Live queries return Observables that emit initial state and re-emit
388
- * on events-stream updates. One-shot reads return Promises.
389
- *
390
- * Backend actor: Browser (context classes)
391
- * Event prefix: browse:*
392
- */
393
- interface BrowseNamespace$1 {
394
- resource(resourceId: ResourceId): Observable<ResourceDescriptor$2 | undefined>;
395
- resources(filters?: {
396
- limit?: number;
397
- archived?: boolean;
398
- search?: string;
399
- }): Observable<ResourceDescriptor$2[] | undefined>;
400
- annotations(resourceId: ResourceId): Observable<Annotation$1[] | undefined>;
401
- annotation(resourceId: ResourceId, annotationId: AnnotationId): Observable<Annotation$1 | undefined>;
402
- entityTypes(): Observable<string[] | undefined>;
403
- referencedBy(resourceId: ResourceId): Observable<ReferencedByEntry[] | undefined>;
404
- resourceContent(resourceId: ResourceId): Promise<string>;
405
- resourceRepresentation(resourceId: ResourceId, options?: {
406
- accept?: string;
407
- }): Promise<{
408
- data: ArrayBuffer;
409
- contentType: string;
410
- }>;
411
- resourceRepresentationStream(resourceId: ResourceId, options?: {
412
- accept?: string;
413
- }): Promise<{
414
- stream: ReadableStream<Uint8Array>;
415
- contentType: string;
416
- }>;
417
- resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse$1[]>;
418
- annotationHistory(resourceId: ResourceId, annotationId: AnnotationId): Promise<AnnotationHistoryResponse>;
419
- connections(resourceId: ResourceId): Promise<GraphConnection[]>;
420
- backlinks(resourceId: ResourceId): Promise<Annotation$1[]>;
421
- resourcesByName(query: string, limit?: number): Promise<ResourceDescriptor$2[]>;
422
- files(dirPath?: string, sort?: 'name' | 'mtime' | 'annotationCount'): Promise<ResponseContent$1<paths['/api/browse/files']['get']>>;
423
- }
424
- /**
425
- * Mark — annotation CRUD, entity types, AI assist
426
- *
427
- * Commands return Promises that resolve on HTTP acceptance (202).
428
- * Results appear on browse Observables via events-stream.
429
- * assist() returns an Observable for long-running progress.
430
- *
431
- * Backend actor: Stower
432
- * Event prefix: mark:*
433
- */
434
- interface MarkNamespace$1 {
435
- annotation(resourceId: ResourceId, input: CreateAnnotationInput): Promise<{
436
- annotationId: string;
437
- }>;
438
- delete(resourceId: ResourceId, annotationId: AnnotationId): Promise<void>;
439
- entityType(type: string): Promise<void>;
440
- entityTypes(types: string[]): Promise<void>;
441
- updateResource(resourceId: ResourceId, data: UpdateResourceInput): Promise<void>;
442
- archive(resourceId: ResourceId): Promise<void>;
443
- unarchive(resourceId: ResourceId): Promise<void>;
444
- assist(resourceId: ResourceId, motivation: Motivation, options: MarkAssistOptions): Observable<MarkAssistProgress>;
445
- }
446
- /**
447
- * Bind — reference linking
448
- *
449
- * The simplest namespace. One method. The result (updated annotation
450
- * with resolved reference) arrives on browse.annotations() via the
451
- * enriched mark:body-updated event.
452
- *
453
- * Backend actor: Stower (via mark:update-body)
454
- * Event prefix: mark:body-updated (shares mark event pipeline)
455
- */
456
- interface BindNamespace$1 {
457
- body(resourceId: ResourceId, annotationId: AnnotationId, operations: BodyOperation[]): Promise<void>;
458
- }
459
- /**
460
- * Gather — context assembly
461
- *
462
- * Long-running (LLM calls + graph traversal). Returns Observables
463
- * that emit progress then the gathered context.
464
- *
465
- * Backend actor: Gatherer
466
- * Event prefix: gather:*
467
- */
468
- interface GatherNamespace$1 {
469
- annotation(annotationId: AnnotationId, resourceId: ResourceId, options?: {
470
- contextWindow?: number;
471
- }): Observable<GatherAnnotationProgress>;
472
- resource(resourceId: ResourceId, options?: {
473
- contextWindow?: number;
474
- }): Observable<GatherAnnotationProgress>;
475
- }
476
- /**
477
- * Match — search and ranking
478
- *
479
- * Long-running (semantic search, optional LLM scoring). Returns
480
- * Observable with progress then results.
481
- *
482
- * Backend actor: Matcher
483
- * Event prefix: match:*
484
- */
485
- interface MatchNamespace$1 {
486
- search(resourceId: ResourceId, referenceId: string, context: GatheredContext, options?: {
487
- limit?: number;
488
- useSemanticScoring?: boolean;
489
- }): Observable<MatchSearchProgress>;
490
- }
491
- /**
492
- * Yield — resource creation
493
- *
494
- * resource() is synchronous file upload (Promise).
495
- * fromAnnotation() is long-running LLM generation (Observable).
496
- *
497
- * Backend actor: Stower + generation worker
498
- * Event prefix: yield:*
499
- */
500
- interface YieldNamespace$1 {
501
- resource(data: CreateResourceInput): Promise<{
502
- resourceId: string;
503
- }>;
504
- fromAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options: GenerationOptions): Observable<YieldProgress$1>;
505
- cloneToken(resourceId: ResourceId): Promise<{
506
- token: string;
507
- expiresAt: string;
508
- }>;
509
- fromToken(token: string): Promise<ResourceDescriptor$2>;
510
- createFromToken(options: CreateFromTokenOptions): Promise<{
511
- resourceId: string;
512
- }>;
513
- }
514
- /**
515
- * Beckon — attention coordination
516
- *
517
- * Fire-and-forget. Ephemeral presence signal delivered via the
518
- * attention-stream to other participants.
519
- *
520
- * Backend actor: (frontend relay via attention-stream)
521
- * Event prefix: beckon:*
522
- */
523
- interface BeckonNamespace$1 {
524
- attention(annotationId: AnnotationId, resourceId: ResourceId): void;
525
- }
526
- /**
527
- * Job — worker lifecycle
528
- */
529
- interface JobNamespace$1 {
530
- status(jobId: JobId): Promise<JobStatusResponse$1>;
531
- pollUntilComplete(jobId: JobId, options?: {
532
- interval?: number;
533
- timeout?: number;
534
- onProgress?: (status: JobStatusResponse$1) => void;
535
- }): Promise<JobStatusResponse$1>;
536
- cancel(jobId: JobId, type: string): Promise<void>;
537
- }
538
- /**
539
- * Auth — authentication
540
- */
541
- interface AuthNamespace$1 {
542
- password(email: string, password: string): Promise<AuthResponse$1>;
543
- google(credential: string): Promise<AuthResponse$1>;
544
- refresh(token: string): Promise<AuthResponse$1>;
545
- logout(): Promise<void>;
546
- me(): Promise<User>;
547
- acceptTerms(): Promise<void>;
548
- mcpToken(): Promise<{
549
- token: string;
550
- }>;
551
- mediaToken(resourceId: ResourceId): Promise<{
552
- token: string;
553
- }>;
554
- }
555
- /**
556
- * Admin — administration
557
- */
558
- interface AdminNamespace$1 {
559
- users(): Promise<User[]>;
560
- userStats(): Promise<AdminUserStatsResponse$1>;
561
- updateUser(userId: UserDID, data: RequestContent$1<paths['/api/admin/users/{id}']['patch']>): Promise<User>;
562
- oauthConfig(): Promise<OAuthConfigResponse$1>;
563
- healthCheck(): Promise<ResponseContent$1<paths['/api/health']['get']>>;
564
- status(): Promise<ResponseContent$1<paths['/api/status']['get']>>;
565
- backup(): Promise<Response>;
566
- restore(file: File, onProgress?: (event: {
567
- phase: string;
568
- message?: string;
569
- result?: Record<string, unknown>;
570
- }) => void): Promise<{
571
- phase: string;
572
- message?: string;
573
- result?: Record<string, unknown>;
574
- }>;
575
- exportKnowledgeBase(params?: {
576
- includeArchived?: boolean;
577
- }): Promise<Response>;
578
- importKnowledgeBase(file: File, onProgress?: (event: {
579
- phase: string;
580
- message?: string;
581
- result?: Record<string, unknown>;
582
- }) => void): Promise<{
583
- phase: string;
584
- message?: string;
585
- result?: Record<string, unknown>;
586
- }>;
587
- }
588
-
589
- /**
590
- * BrowseNamespace — reads from materialized views
591
- *
592
- * Absorbs AnnotationStore and ResourceStore logic. Live queries return
593
- * Observables backed by BehaviorSubjects that update reactively when
594
- * EventBus events arrive. One-shot reads are Promise wrappers over HTTP.
595
- *
596
- * Backend actor: Browser (context classes)
597
- * Event prefix: browse:*
598
- */
599
-
600
- type Annotation = components['schemas']['Annotation'];
601
- type ResourceDescriptor$1 = components['schemas']['ResourceDescriptor'];
602
- type StoredEventResponse = components['schemas']['StoredEventResponse'];
603
- type TokenGetter$9 = () => AccessToken | undefined;
604
- declare class BrowseNamespace implements BrowseNamespace$1 {
605
- private readonly http;
606
- private readonly eventBus;
607
- private readonly annotationList$;
608
- private readonly fetchingAnnotationList;
609
- private readonly annotationListObs$;
610
- private readonly annotationDetail$;
611
- private readonly fetchingAnnotationDetail;
612
- private readonly annotationDetailObs$;
613
- private readonly resourceDetail$;
614
- private readonly fetchingResourceDetail;
615
- private readonly resourceDetailObs$;
616
- private readonly resourceList$;
617
- private readonly fetchingResourceList;
618
- private readonly resourceListObs$;
619
- private readonly entityTypes$;
620
- private fetchingEntityTypes;
621
- private readonly referencedBy$;
622
- private readonly fetchingReferencedBy;
623
- private readonly referencedByObs$;
624
- private readonly getToken;
625
- constructor(http: SemiontApiClient, eventBus: EventBus, getToken: TokenGetter$9);
626
- resource(resourceId: ResourceId): Observable<ResourceDescriptor$1 | undefined>;
627
- resources(filters?: {
628
- limit?: number;
629
- archived?: boolean;
630
- search?: string;
631
- }): Observable<ResourceDescriptor$1[] | undefined>;
632
- annotations(resourceId: ResourceId): Observable<Annotation[] | undefined>;
633
- annotation(resourceId: ResourceId, annotationId: AnnotationId): Observable<Annotation | undefined>;
634
- entityTypes(): Observable<string[] | undefined>;
635
- referencedBy(resourceId: ResourceId): Observable<ReferencedByEntry[] | undefined>;
636
- resourceContent(resourceId: ResourceId): Promise<string>;
637
- resourceRepresentation(resourceId: ResourceId, options?: {
638
- accept?: string;
639
- }): Promise<{
640
- data: ArrayBuffer;
641
- contentType: string;
642
- }>;
643
- resourceRepresentationStream(resourceId: ResourceId, options?: {
644
- accept?: string;
645
- }): Promise<{
646
- stream: ReadableStream<Uint8Array>;
647
- contentType: string;
648
- }>;
649
- resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse[]>;
650
- annotationHistory(resourceId: ResourceId, annotationId: AnnotationId): Promise<AnnotationHistoryResponse>;
651
- connections(_resourceId: ResourceId): Promise<GraphConnection[]>;
652
- backlinks(_resourceId: ResourceId): Promise<Annotation[]>;
653
- resourcesByName(_query: string, _limit?: number): Promise<ResourceDescriptor$1[]>;
654
- files(dirPath?: string, sort?: 'name' | 'mtime' | 'annotationCount'): Promise<ResponseContent$1<paths['/api/browse/files']['get']>>;
655
- invalidateAnnotationList(resourceId: ResourceId): void;
656
- invalidateAnnotationDetail(annotationId: AnnotationId): void;
657
- invalidateResourceDetail(id: ResourceId): void;
658
- invalidateResourceLists(): void;
659
- invalidateEntityTypes(): void;
660
- invalidateReferencedBy(resourceId: ResourceId): void;
661
- updateAnnotationInPlace(resourceId: ResourceId, annotation: Annotation): void;
662
- private subscribeToEvents;
663
- private fetchAnnotationList;
664
- private fetchAnnotationDetail;
665
- private fetchResourceDetail;
666
- private fetchResourceList;
667
- private fetchEntityTypes;
668
- private fetchReferencedBy;
669
- }
670
-
671
- /**
672
- * MarkNamespace — annotation CRUD, entity types, AI assist
673
- *
674
- * Commands return Promises that resolve on HTTP acceptance.
675
- * Results appear on browse Observables via events-stream.
676
- * assist() returns an Observable for long-running progress.
677
- *
678
- * Backend actor: Stower
679
- * Event prefix: mark:*
680
- */
681
-
682
- type TokenGetter$8 = () => AccessToken | undefined;
683
- declare class MarkNamespace implements MarkNamespace$1 {
684
- private readonly http;
685
- private readonly eventBus;
686
- private readonly getToken;
687
- constructor(http: SemiontApiClient, eventBus: EventBus, getToken: TokenGetter$8);
688
- annotation(resourceId: ResourceId, input: CreateAnnotationInput): Promise<{
689
- annotationId: string;
690
- }>;
691
- delete(resourceId: ResourceId, annotationId: AnnotationId): Promise<void>;
692
- entityType(type: string): Promise<void>;
693
- entityTypes(types: string[]): Promise<void>;
694
- updateResource(resourceId: ResourceId, data: UpdateResourceInput): Promise<void>;
695
- archive(resourceId: ResourceId): Promise<void>;
696
- unarchive(resourceId: ResourceId): Promise<void>;
697
- assist(resourceId: ResourceId, motivation: Motivation, options: MarkAssistOptions): Observable<MarkAssistProgress>;
698
- private dispatchAssist;
699
- }
700
-
701
- /**
702
- * BindNamespace — reference linking
703
- *
704
- * The simplest namespace. One method. The result (updated annotation
705
- * with resolved reference) arrives on browse.annotations() via the
706
- * enriched mark:body-updated event.
707
- *
708
- * Backend actor: Stower (via mark:update-body)
709
- * Event prefix: mark:body-updated (shares mark event pipeline)
710
- */
711
-
712
- type TokenGetter$7 = () => AccessToken | undefined;
713
- declare class BindNamespace implements BindNamespace$1 {
714
- private readonly http;
715
- private readonly getToken;
716
- constructor(http: SemiontApiClient, getToken: TokenGetter$7);
717
- body(resourceId: ResourceId, annotationId: AnnotationId, operations: BodyOperation[]): Promise<void>;
5
+ /** Minimal ViewModel surface — anything with a `dispose()` method. */
6
+ interface ViewModel {
7
+ dispose(): void;
718
8
  }
719
9
 
720
- /**
721
- * GatherNamespace — context assembly
722
- *
723
- * Long-running (LLM calls + graph traversal). Returns Observables
724
- * that emit progress then the gathered context.
725
- *
726
- * Backend actor: Gatherer
727
- * Event prefix: gather:*
728
- */
729
-
730
- type TokenGetter$6 = () => AccessToken | undefined;
731
- declare class GatherNamespace implements GatherNamespace$1 {
732
- private readonly http;
733
- private readonly eventBus;
734
- private readonly getToken;
735
- constructor(http: SemiontApiClient, eventBus: EventBus, getToken: TokenGetter$6);
736
- annotation(annotationId: AnnotationId, resourceId: ResourceId, options?: {
737
- contextWindow?: number;
738
- }): Observable<GatherAnnotationProgress>;
739
- resource(_resourceId: ResourceId, _options?: {
740
- contextWindow?: number;
741
- }): Observable<GatherAnnotationProgress>;
10
+ interface BusEvent {
11
+ channel: string;
12
+ payload: Record<string, unknown>;
13
+ scope?: string;
742
14
  }
743
-
744
- /**
745
- * MatchNamespace search and ranking
746
- *
747
- * Long-running (semantic search, optional LLM scoring). Returns
748
- * Observable with results.
749
- *
750
- * Backend actor: Matcher
751
- * Event prefix: match:*
752
- */
753
-
754
- type TokenGetter$5 = () => AccessToken | undefined;
755
- declare class MatchNamespace implements MatchNamespace$1 {
756
- private readonly http;
757
- private readonly eventBus;
758
- private readonly getToken;
759
- constructor(http: SemiontApiClient, eventBus: EventBus, getToken: TokenGetter$5);
760
- search(resourceId: ResourceId, referenceId: string, context: GatheredContext, options?: {
761
- limit?: number;
762
- useSemanticScoring?: boolean;
763
- }): Observable<MatchSearchProgress>;
15
+ interface ActorVMOptions {
16
+ baseUrl: string;
17
+ token: string | (() => string);
18
+ channels: string[];
19
+ scope?: string;
20
+ reconnectMs?: number;
764
21
  }
765
-
766
- /**
767
- * YieldNamespace resource creation
768
- *
769
- * resource() is synchronous file upload (Promise).
770
- * fromAnnotation() is long-running LLM generation (Observable).
771
- *
772
- * Backend actor: Stower + generation worker
773
- * Event prefix: yield:*
774
- */
775
-
776
- type ResourceDescriptor = components['schemas']['ResourceDescriptor'];
777
- type TokenGetter$4 = () => AccessToken | undefined;
778
- declare class YieldNamespace implements YieldNamespace$1 {
779
- private readonly http;
780
- private readonly eventBus;
781
- private readonly getToken;
782
- constructor(http: SemiontApiClient, eventBus: EventBus, getToken: TokenGetter$4);
783
- resource(data: CreateResourceInput): Promise<{
784
- resourceId: string;
785
- }>;
786
- fromAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options: GenerationOptions): Observable<YieldProgress$1>;
787
- cloneToken(resourceId: ResourceId): Promise<{
788
- token: string;
789
- expiresAt: string;
790
- }>;
791
- fromToken(token: string): Promise<ResourceDescriptor>;
792
- createFromToken(options: CreateFromTokenOptions): Promise<{
793
- resourceId: string;
794
- }>;
22
+ /** Time in the `reconnecting` state before transitioning to `degraded`. */
23
+ declare const DEGRADED_THRESHOLD_MS = 3000;
24
+ interface ActorVM extends ViewModel {
25
+ on$<T = Record<string, unknown>>(channel: string): Observable<T>;
26
+ emit(channel: string, payload: Record<string, unknown>, emitScope?: string): Promise<void>;
27
+ state$: Observable<ConnectionState>;
28
+ addChannels(channels: string[], scope?: string): void;
29
+ removeChannels(channels: string[]): void;
30
+ start(): void;
31
+ stop(): void;
795
32
  }
33
+ declare function createActorVM(options: ActorVMOptions): ActorVM;
796
34
 
797
35
  /**
798
- * BeckonNamespaceattention coordination
36
+ * HttpTransportthe HTTP/SSE implementation of ITransport.
799
37
  *
800
- * Fire-and-forget. Ephemeral presence signal delivered via the
801
- * attention-stream to other participants.
38
+ * Phase 1 of TRANSPORT-ABSTRACTION. Owns everything that crosses the wire
39
+ * in remote mode: the bus actor (SSE + POST /bus/emit), auth/admin/exchange/
40
+ * system HTTP endpoints, and connection-state plumbing.
802
41
  *
803
- * Backend actor: (frontend relay via attention-stream)
804
- * Event prefix: beckon:*
805
- */
806
-
807
- type TokenGetter$3 = () => AccessToken | undefined;
808
- declare class BeckonNamespace implements BeckonNamespace$1 {
809
- private readonly http;
810
- private readonly getToken;
811
- constructor(http: SemiontApiClient, getToken: TokenGetter$3);
812
- attention(annotationId: AnnotationId, resourceId: ResourceId): void;
813
- }
814
-
815
- /**
816
- * JobNamespace — worker lifecycle
817
- */
818
-
819
- type JobStatusResponse = components['schemas']['JobStatusResponse'];
820
- type TokenGetter$2 = () => AccessToken | undefined;
821
- declare class JobNamespace implements JobNamespace$1 {
822
- private readonly http;
823
- private readonly getToken;
824
- constructor(http: SemiontApiClient, getToken: TokenGetter$2);
825
- status(jobId: JobId): Promise<JobStatusResponse>;
826
- pollUntilComplete(jobId: JobId, options?: {
827
- interval?: number;
828
- timeout?: number;
829
- onProgress?: (status: JobStatusResponse) => void;
830
- }): Promise<JobStatusResponse>;
831
- cancel(jobId: JobId, type: string): Promise<void>;
832
- }
833
-
834
- /**
835
- * AuthNamespace — authentication
42
+ * Does NOT own the local coordination bus — that lives on `SemiontClient`.
43
+ * `bridgeInto(bus)` wires SSE-received events into the caller-supplied bus
44
+ * once at construction.
836
45
  */
837
46
 
838
47
  type AuthResponse = components['schemas']['AuthResponse'];
839
- type TokenGetter$1 = () => AccessToken | undefined;
840
- declare class AuthNamespace implements AuthNamespace$1 {
841
- private readonly http;
842
- private readonly getToken;
843
- constructor(http: SemiontApiClient, getToken: TokenGetter$1);
844
- password(emailStr: string, passwordStr: string): Promise<AuthResponse>;
845
- google(credential: string): Promise<AuthResponse>;
846
- refresh(token: string): Promise<AuthResponse>;
847
- logout(): Promise<void>;
848
- me(): Promise<User>;
849
- acceptTerms(): Promise<void>;
850
- mcpToken(): Promise<{
851
- token: string;
852
- }>;
853
- mediaToken(resourceId: ResourceId): Promise<{
854
- token: string;
855
- }>;
856
- }
857
-
858
- /**
859
- * AdminNamespace — administration
860
- */
861
-
48
+ type TokenRefreshResponse = components['schemas']['TokenRefreshResponse'];
862
49
  type AdminUserStatsResponse = components['schemas']['AdminUserStatsResponse'];
863
50
  type OAuthConfigResponse = components['schemas']['OAuthConfigResponse'];
864
- type TokenGetter = () => AccessToken | undefined;
865
- declare class AdminNamespace implements AdminNamespace$1 {
866
- private readonly http;
867
- private readonly getToken;
868
- constructor(http: SemiontApiClient, getToken: TokenGetter);
869
- users(): Promise<User[]>;
870
- userStats(): Promise<AdminUserStatsResponse>;
871
- updateUser(userId: UserDID, data: RequestContent$1<paths['/api/admin/users/{id}']['patch']>): Promise<User>;
872
- oauthConfig(): Promise<OAuthConfigResponse>;
873
- healthCheck(): Promise<ResponseContent$1<paths['/api/health']['get']>>;
874
- status(): Promise<ResponseContent$1<paths['/api/status']['get']>>;
875
- backup(): Promise<Response>;
876
- restore(file: File, onProgress?: (event: {
877
- phase: string;
878
- message?: string;
879
- result?: Record<string, unknown>;
880
- }) => void): Promise<{
881
- phase: string;
882
- message?: string;
883
- result?: Record<string, unknown>;
884
- }>;
885
- exportKnowledgeBase(params?: {
886
- includeArchived?: boolean;
887
- }): Promise<Response>;
888
- importKnowledgeBase(file: File, onProgress?: (event: {
889
- phase: string;
890
- message?: string;
891
- result?: Record<string, unknown>;
892
- }) => void): Promise<{
893
- phase: string;
894
- message?: string;
895
- result?: Record<string, unknown>;
896
- }>;
897
- }
898
-
899
- /**
900
- * Common API client for Semiont backend
901
- *
902
- * This client can be used by:
903
- * - MCP server (Node.js)
904
- * - Demo scripts (Node.js)
905
- * - Frontend (Next.js/React - can wrap with hooks)
906
- *
907
- * Uses ky for HTTP requests with built-in retry, timeout, and error handling.
908
- */
909
-
910
- type ResponseContent<T> = T extends {
911
- responses: {
912
- 200: {
913
- content: {
914
- 'application/json': infer R;
915
- };
916
- };
917
- };
918
- } ? R : T extends {
919
- responses: {
920
- 201: {
921
- content: {
922
- 'application/json': infer R;
923
- };
924
- };
925
- };
926
- } ? R : never;
927
- type RequestContent<T> = T extends {
928
- requestBody?: {
929
- content: {
930
- 'application/json': infer R;
931
- };
932
- };
933
- } ? R : never;
934
51
  declare class APIError extends Error {
935
52
  status: number;
936
53
  statusText: string;
937
54
  details?: unknown | undefined;
938
55
  constructor(message: string, status: number, statusText: string, details?: unknown | undefined);
939
56
  }
940
- /**
941
- * Optional callback invoked when a request fails with HTTP 401. If it
942
- * resolves to a non-null token, the failed request is retried once with
943
- * the new Bearer token. If it resolves to null (or throws), the original
944
- * 401 propagates as an APIError.
945
- *
946
- * Implementations must dedupe concurrent calls so that simultaneous 401s
947
- * don't fire multiple parallel refresh requests. The frontend's
948
- * KnowledgeBaseSessionProvider provides this via an in-flight Promise map
949
- * keyed by KB id.
950
- */
951
57
  type TokenRefresher = () => Promise<string | null>;
952
- interface SemiontApiClientConfig {
58
+ interface HttpTransportConfig {
953
59
  baseUrl: BaseUrl;
954
- /** Per-workspace EventBus. Required one bus per workspace, constructed externally. */
955
- eventBus: EventBus;
60
+ /** Observable token source; headers read the current value. */
61
+ token$?: BehaviorSubject<AccessToken | null>;
956
62
  timeout?: number;
957
63
  retry?: number;
958
64
  logger?: Logger;
959
65
  /** Optional 401-recovery hook. See {@link TokenRefresher}. */
960
66
  tokenRefresher?: TokenRefresher;
961
- /**
962
- * Token getter for the verb-namespace API (client.browse, client.mark, etc.).
963
- * When provided, auth is managed internally — no per-call auth needed.
964
- * The getter is called on each request to get the current token.
965
- * If not provided, namespace methods use undefined auth (public endpoints only).
966
- */
967
- getToken?: () => AccessToken | undefined;
968
67
  }
969
- /**
970
- * Options for individual API requests
971
- */
972
- interface RequestOptions {
973
- /** Access token for this request */
974
- auth?: AccessToken;
975
- }
976
- /**
977
- * Semiont API Client
978
- *
979
- * Provides type-safe methods for all Semiont backend API endpoints.
980
- * This client is fully stateless - authentication must be provided per request.
981
- */
982
- declare class SemiontApiClient {
983
- private http;
68
+ declare class HttpTransport implements ITransport {
984
69
  readonly baseUrl: BaseUrl;
985
- /** The workspace-scoped EventBus this client was constructed with. */
986
- readonly eventBus: EventBus;
987
- private logger?;
988
- /**
989
- * Shared mutable token getter. All verb namespaces read from this.
990
- * Updated via setTokenGetter() from the React auth layer.
991
- */
992
- private _getToken;
993
- /**
994
- * SSE streaming client for real-time operations
995
- *
996
- * Separate from the main HTTP client to clearly mark streaming endpoints.
997
- * Uses native fetch() instead of ky for SSE support.
998
- */
999
- readonly sse: SSEClient;
1000
- readonly browse: BrowseNamespace;
1001
- readonly mark: MarkNamespace;
1002
- readonly bind: BindNamespace;
1003
- readonly gather: GatherNamespace;
1004
- readonly match: MatchNamespace;
1005
- readonly yield: YieldNamespace;
1006
- readonly beckon: BeckonNamespace;
1007
- readonly job: JobNamespace;
1008
- readonly auth: AuthNamespace;
1009
- readonly admin: AdminNamespace;
1010
- constructor(config: SemiontApiClientConfig);
1011
- /**
1012
- * Update the token getter for all verb namespaces.
1013
- * Called from the React auth layer when the token changes.
1014
- * All namespaces share this getter via closure — no per-namespace sync needed.
1015
- */
1016
- setTokenGetter(getter: () => AccessToken | undefined): void;
70
+ private readonly http;
71
+ private readonly token$;
72
+ private readonly logger?;
73
+ private _actor;
74
+ private _actorStarted;
75
+ private disposed;
76
+ private activeResource;
77
+ /** Buses we've been asked to bridge wire events into. */
78
+ private readonly bridges;
79
+ constructor(config: HttpTransportConfig);
80
+ get actor(): ActorVM;
81
+ emit<K extends keyof EventMap>(channel: K, payload: EventMap[K], resourceScope?: ResourceId): Promise<void>;
82
+ on<K extends keyof EventMap>(channel: K, handler: (payload: EventMap[K]) => void): () => void;
83
+ stream<K extends keyof EventMap>(channel: K): Observable<EventMap[K]>;
84
+ /**
85
+ * Wire this transport's SSE fan-in into the given bus. Every channel
86
+ * in `BRIDGED_CHANNELS` (and subsequently per-resource scoped channels
87
+ * opened by `subscribeToResource`) is published on the bus. Safe to
88
+ * call multiple times — each bus is added to the fan-out list.
89
+ */
90
+ bridgeInto(bus: EventBus): void;
91
+ subscribeToResource(resourceId: ResourceId): () => void;
92
+ private makeUnsubscriber;
93
+ get state$(): Observable<ConnectionState>;
94
+ dispose(): void;
1017
95
  private authHeaders;
1018
- authenticatePassword(email: Email, password: string, options?: RequestOptions): Promise<ResponseContent<paths['/api/tokens/password']['post']>>;
1019
- refreshToken(token: RefreshToken, options?: RequestOptions): Promise<ResponseContent<paths['/api/tokens/refresh']['post']>>;
1020
- authenticateGoogle(credential: GoogleCredential, options?: RequestOptions): Promise<ResponseContent<paths['/api/tokens/google']['post']>>;
1021
- generateMCPToken(options?: RequestOptions): Promise<ResponseContent<paths['/api/tokens/mcp-generate']['post']>>;
1022
- getMediaToken(resourceId: ResourceId, options?: RequestOptions): Promise<{
96
+ authenticatePassword(email: Email, password: string): Promise<AuthResponse>;
97
+ authenticateGoogle(credential: GoogleCredential): Promise<AuthResponse>;
98
+ refreshAccessToken(token: RefreshToken): Promise<TokenRefreshResponse>;
99
+ logout(): Promise<void>;
100
+ acceptTerms(): Promise<void>;
101
+ getCurrentUser(): Promise<UserResponse>;
102
+ generateMcpToken(): Promise<{
1023
103
  token: string;
1024
104
  }>;
1025
- getMe(options?: RequestOptions): Promise<ResponseContent<paths['/api/users/me']['get']>>;
1026
- acceptTerms(options?: RequestOptions): Promise<ResponseContent<paths['/api/users/accept-terms']['post']>>;
1027
- logout(options?: RequestOptions): Promise<ResponseContent<paths['/api/users/logout']['post']>>;
105
+ getMediaToken(resourceId: ResourceId): Promise<{
106
+ token: string;
107
+ }>;
108
+ listUsers(): Promise<ListUsersResponse>;
109
+ getUserStats(): Promise<AdminUserStatsResponse>;
110
+ updateUser(id: UserDID, data: UpdateUserRequest): Promise<UpdateUserResponse>;
111
+ getOAuthConfig(): Promise<OAuthConfigResponse>;
112
+ backupKnowledgeBase(): Promise<Response>;
113
+ restoreKnowledgeBase(file: File, onProgress?: ProgressCallback): Promise<ProgressEvent>;
114
+ exportKnowledgeBase(params?: {
115
+ includeArchived?: boolean;
116
+ }): Promise<Response>;
117
+ importKnowledgeBase(file: File, onProgress?: ProgressCallback): Promise<ProgressEvent>;
118
+ private parseSSEStream;
119
+ healthCheck(): Promise<HealthCheckResponse>;
120
+ getStatus(): Promise<StatusResponse>;
1028
121
  /**
1029
- * Create a new resource with binary content support
1030
- *
1031
- * @param data - Resource creation data
1032
- * @param data.name - Resource name
1033
- * @param data.file - File object or Buffer with binary content
1034
- * @param data.format - MIME type (e.g., 'text/markdown', 'image/png')
1035
- * @param data.entityTypes - Optional array of entity types
1036
- * @param data.language - Optional ISO 639-1 language code
1037
- * @param data.creationMethod - Optional creation method
1038
- * @param data.sourceAnnotationId - Optional source annotation ID
1039
- * @param data.sourceResourceId - Optional source resource ID
1040
- * @param options - Request options including auth
122
+ * Temporary escape hatch for the ongoing transport migration: namespaces
123
+ * that still need to issue ad-hoc HTTP calls (e.g. legacy browse/mark
124
+ * HTTP fallbacks) can borrow the configured `ky` instance here. Will be
125
+ * deleted once all namespaces route through bus channels or through
126
+ * typed methods on this transport.
1041
127
  */
1042
- yieldResource(data: {
1043
- name: string;
1044
- file: File | Buffer;
1045
- format: string;
1046
- entityTypes?: string[];
1047
- language?: string;
1048
- creationMethod?: string;
1049
- sourceAnnotationId?: string;
1050
- sourceResourceId?: string;
1051
- storageUri: string;
1052
- }, options?: RequestOptions): Promise<{
1053
- resourceId: string;
1054
- }>;
1055
- browseResource(id: ResourceId, options?: RequestOptions): Promise<ResponseContent<paths['/resources/{id}']['get']>>;
128
+ get rawHttp(): KyInstance;
1056
129
  /**
1057
- * Get resource representation using W3C content negotiation
1058
- * Returns raw binary content (images, PDFs, text, etc.) with content type
1059
- *
1060
- * @param resourceUri - Full resource URI
1061
- * @param options - Options including Accept header for content negotiation and auth
1062
- * @returns Object with data (ArrayBuffer) and contentType (string)
1063
- *
1064
- * @example
1065
- * ```typescript
1066
- * // Get markdown representation
1067
- * const { data, contentType } = await client.getResourceRepresentation(rUri, { accept: 'text/markdown', auth: token });
1068
- * const markdown = new TextDecoder().decode(data);
1069
- *
1070
- * // Get image representation
1071
- * const { data, contentType } = await client.getResourceRepresentation(rUri, { accept: 'image/png', auth: token });
1072
- * const blob = new Blob([data], { type: contentType });
1073
- *
1074
- * // Get PDF representation
1075
- * const { data, contentType } = await client.getResourceRepresentation(rUri, { accept: 'application/pdf', auth: token });
1076
- * ```
130
+ * Current access token (synchronously read from the BehaviorSubject).
131
+ * Used by content-transport and legacy namespace HTTP fallbacks that
132
+ * need to pass `auth: token` through some code paths.
1077
133
  */
1078
- getResourceRepresentation(id: ResourceId, options?: {
1079
- accept?: ContentFormat;
134
+ getToken(): AccessToken | undefined;
135
+ }
136
+
137
+ /**
138
+ * HttpContentTransport — binary I/O over HTTP.
139
+ *
140
+ * Phase 1 of TRANSPORT-ABSTRACTION. Narrow by design because binary has
141
+ * different backpressure and streaming characteristics than typed command
142
+ * payloads. Uses the HttpTransport's underlying ky instance + token, so
143
+ * retries, logging, and auth behave identically to the rest of the wire.
144
+ */
145
+
146
+ declare class HttpContentTransport implements IContentTransport {
147
+ private readonly transport;
148
+ constructor(transport: HttpTransport);
149
+ putBinary(request: PutBinaryRequest, options?: {
150
+ auth?: AccessToken;
151
+ }): Promise<{
152
+ resourceId: ResourceId;
153
+ }>;
154
+ getBinary(resourceId: ResourceId, options?: {
155
+ accept?: ContentFormat | string;
1080
156
  auth?: AccessToken;
1081
157
  }): Promise<{
1082
158
  data: ArrayBuffer;
1083
159
  contentType: string;
1084
160
  }>;
1085
- /**
1086
- * Get resource representation as a stream using W3C content negotiation
1087
- * Returns streaming binary content (for large files: videos, large PDFs, etc.)
1088
- *
1089
- * Use this for large files to avoid loading entire content into memory.
1090
- * The stream is consumed incrementally and the backend connection stays open
1091
- * until the stream is fully consumed or closed.
1092
- *
1093
- * @param resourceUri - Full resource URI
1094
- * @param options - Options including Accept header for content negotiation and auth
1095
- * @returns Object with stream (ReadableStream) and contentType (string)
1096
- *
1097
- * @example
1098
- * ```typescript
1099
- * // Stream large file
1100
- * const { stream, contentType } = await client.getResourceRepresentationStream(rUri, {
1101
- * accept: 'video/mp4',
1102
- * auth: token
1103
- * });
1104
- *
1105
- * // Consume stream chunk by chunk (never loads entire file into memory)
1106
- * for await (const chunk of stream) {
1107
- * // Process chunk
1108
- * console.log(`Received ${chunk.length} bytes`);
1109
- * }
1110
- *
1111
- * // Or pipe to a file in Node.js
1112
- * const fileStream = fs.createWriteStream('output.mp4');
1113
- * const reader = stream.getReader();
1114
- * while (true) {
1115
- * const { done, value } = await reader.read();
1116
- * if (done) break;
1117
- * fileStream.write(value);
1118
- * }
1119
- * ```
1120
- */
1121
- getResourceRepresentationStream(id: ResourceId, options?: {
1122
- accept?: ContentFormat;
161
+ getBinaryStream(resourceId: ResourceId, options?: {
162
+ accept?: ContentFormat | string;
1123
163
  auth?: AccessToken;
1124
164
  }): Promise<{
1125
165
  stream: ReadableStream<Uint8Array>;
1126
166
  contentType: string;
1127
167
  }>;
1128
- browseResources(limit?: number, archived?: boolean, query?: SearchQuery, options?: RequestOptions): Promise<ResponseContent<paths['/resources']['get']>>;
1129
- updateResource(id: ResourceId, data: RequestContent<paths['/resources/{id}']['patch']>, options?: RequestOptions): Promise<void>;
1130
- getResourceEvents(id: ResourceId, options?: RequestOptions): Promise<ResponseContent<paths['/resources/{id}/events']['get']>>;
1131
- browseReferences(id: ResourceId, options?: RequestOptions): Promise<ResponseContent<paths['/resources/{id}/referenced-by']['get']>>;
1132
- generateCloneToken(id: ResourceId, options?: RequestOptions): Promise<ResponseContent<paths['/resources/{id}/clone-with-token']['post']>>;
1133
- getResourceByToken(token: CloneToken, options?: RequestOptions): Promise<ResponseContent<paths['/api/clone-tokens/{token}']['get']>>;
1134
- createResourceFromToken(data: RequestContent<paths['/api/clone-tokens/create-resource']['post']>, options?: RequestOptions): Promise<{
1135
- resourceId: string;
1136
- }>;
1137
- markAnnotation(id: ResourceId, data: RequestContent<paths['/resources/{id}/annotations']['post']>, options?: RequestOptions): Promise<{
1138
- annotationId: string;
1139
- }>;
1140
- getAnnotation(id: AnnotationId, options?: RequestOptions): Promise<ResponseContent<paths['/annotations/{id}']['get']>>;
1141
- browseAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options?: RequestOptions): Promise<ResponseContent<paths['/resources/{resourceId}/annotations/{annotationId}']['get']>>;
1142
- browseAnnotations(id: ResourceId, motivation?: Motivation, options?: RequestOptions): Promise<ResponseContent<paths['/resources/{id}/annotations']['get']>>;
1143
- deleteAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options?: RequestOptions): Promise<void>;
1144
- bindAnnotation(resourceId: ResourceId, annotationId: AnnotationId, data: {
1145
- operations: BodyOperation[];
1146
- }, options?: RequestOptions): Promise<{
1147
- correlationId: string;
1148
- }>;
1149
- getAnnotationHistory(resourceId: ResourceId, annotationId: AnnotationId, options?: RequestOptions): Promise<ResponseContent<paths['/resources/{resourceId}/annotations/{annotationId}/history']['get']>>;
1150
- annotateReferences(resourceId: ResourceId, data: {
1151
- entityTypes: string[];
1152
- includeDescriptiveReferences?: boolean;
1153
- }, options?: RequestOptions): Promise<{
1154
- correlationId: string;
1155
- jobId: string;
1156
- }>;
1157
- annotateHighlights(resourceId: ResourceId, data: {
1158
- instructions?: string;
1159
- density?: number;
1160
- }, options?: RequestOptions): Promise<{
1161
- correlationId: string;
1162
- jobId: string;
1163
- }>;
1164
- annotateAssessments(resourceId: ResourceId, data: {
1165
- instructions?: string;
1166
- tone?: string;
1167
- density?: number;
1168
- language?: string;
1169
- }, options?: RequestOptions): Promise<{
1170
- correlationId: string;
1171
- jobId: string;
1172
- }>;
1173
- annotateComments(resourceId: ResourceId, data: {
1174
- instructions?: string;
1175
- tone?: string;
1176
- density?: number;
1177
- language?: string;
1178
- }, options?: RequestOptions): Promise<{
1179
- correlationId: string;
1180
- jobId: string;
1181
- }>;
1182
- annotateTags(resourceId: ResourceId, data: {
1183
- schemaId: string;
1184
- categories: string[];
1185
- }, options?: RequestOptions): Promise<{
1186
- correlationId: string;
1187
- jobId: string;
1188
- }>;
1189
- yieldResourceFromAnnotation(resourceId: ResourceId, annotationId: AnnotationId, data: {
1190
- title: string;
1191
- storageUri: string;
1192
- context: unknown;
1193
- prompt?: string;
1194
- language?: string;
1195
- temperature?: number;
1196
- maxTokens?: number;
1197
- }, options?: RequestOptions): Promise<{
1198
- correlationId: string;
1199
- jobId: string;
1200
- }>;
1201
- gatherAnnotationContext(resourceId: ResourceId, annotationId: AnnotationId, data: {
1202
- correlationId: string;
1203
- contextWindow?: number;
1204
- }, options?: RequestOptions): Promise<{
1205
- correlationId: string;
1206
- }>;
1207
- matchSearch(resourceId: ResourceId, data: {
1208
- correlationId: string;
1209
- referenceId: string;
1210
- context: unknown;
1211
- limit?: number;
1212
- useSemanticScoring?: boolean;
1213
- }, options?: RequestOptions): Promise<{
1214
- correlationId: string;
1215
- }>;
1216
- addEntityType(type: EntityType, options?: RequestOptions): Promise<void>;
1217
- addEntityTypesBulk(types: EntityType[], options?: RequestOptions): Promise<void>;
1218
- listEntityTypes(options?: RequestOptions): Promise<ResponseContent<paths['/api/entity-types']['get']>>;
1219
- beckonAttention(participantId: string, data: RequestContent<paths['/api/participants/{id}/attention']['post']>, options?: RequestOptions): Promise<ResponseContent<paths['/api/participants/{id}/attention']['post']>>;
1220
- listUsers(options?: RequestOptions): Promise<ResponseContent<paths['/api/admin/users']['get']>>;
1221
- getUserStats(options?: RequestOptions): Promise<ResponseContent<paths['/api/admin/users/stats']['get']>>;
1222
- /**
1223
- * Update a user by ID
1224
- * Note: Users use DID identifiers (did:web:domain:users:id), not HTTP URIs.
1225
- */
1226
- updateUser(id: UserDID, data: RequestContent<paths['/api/admin/users/{id}']['patch']>, options?: RequestOptions): Promise<ResponseContent<paths['/api/admin/users/{id}']['patch']>>;
1227
- getOAuthConfig(options?: RequestOptions): Promise<ResponseContent<paths['/api/admin/oauth/config']['get']>>;
1228
- /**
1229
- * Create a backup of the knowledge base. Returns raw Response for streaming download.
1230
- * Caller should use response.blob() to trigger a file download.
1231
- */
1232
- backupKnowledgeBase(options?: RequestOptions): Promise<Response>;
1233
- /**
1234
- * Restore knowledge base from a backup file. Parses SSE progress events and calls onProgress.
1235
- * Returns the final SSE event (phase: 'complete' or 'error').
1236
- */
1237
- restoreKnowledgeBase(file: File, options?: RequestOptions & {
1238
- onProgress?: (event: {
1239
- phase: string;
1240
- message?: string;
1241
- result?: Record<string, unknown>;
1242
- }) => void;
1243
- }): Promise<{
1244
- phase: string;
1245
- message?: string;
1246
- result?: Record<string, unknown>;
1247
- }>;
1248
- /**
1249
- * Export the knowledge base as a JSON-LD Linked Data archive. Returns raw Response for streaming download.
1250
- * Caller should use response.blob() to trigger a file download.
1251
- */
1252
- exportKnowledgeBase(params?: {
1253
- includeArchived?: boolean;
1254
- }, options?: RequestOptions): Promise<Response>;
1255
- /**
1256
- * Import a JSON-LD Linked Data archive into the knowledge base. Parses SSE progress events and calls onProgress.
1257
- * Returns the final SSE event (phase: 'complete' or 'error').
1258
- */
1259
- importKnowledgeBase(file: File, options?: RequestOptions & {
1260
- onProgress?: (event: {
1261
- phase: string;
1262
- message?: string;
1263
- result?: Record<string, unknown>;
1264
- }) => void;
1265
- }): Promise<{
1266
- phase: string;
1267
- message?: string;
1268
- result?: Record<string, unknown>;
1269
- }>;
1270
- private parseSSEStream;
1271
- getJobStatus(id: JobId, options?: RequestOptions): Promise<ResponseContent<paths['/api/jobs/{id}']['get']>>;
1272
- /**
1273
- * Poll a job until it completes or fails
1274
- * @param id - The job ID to poll
1275
- * @param options - Polling options
1276
- * @returns The final job status
1277
- */
1278
- pollJobUntilComplete(id: JobId, options?: {
1279
- interval?: number;
1280
- timeout?: number;
1281
- onProgress?: (status: ResponseContent<paths['/api/jobs/{id}']['get']>) => void;
1282
- auth?: AccessToken;
1283
- }): Promise<ResponseContent<paths['/api/jobs/{id}']['get']>>;
1284
- healthCheck(options?: RequestOptions): Promise<ResponseContent<paths['/api/health']['get']>>;
1285
- getStatus(options?: RequestOptions): Promise<ResponseContent<paths['/api/status']['get']>>;
1286
- browseFiles(dirPath?: string, sort?: 'name' | 'mtime' | 'annotationCount', options?: RequestOptions): Promise<ResponseContent<paths['/api/browse/files']['get']>>;
168
+ dispose(): void;
169
+ /** Auth header + W3C trace propagation for the active span. */
170
+ private requestHeaders;
1287
171
  }
1288
172
 
1289
- /**
1290
- * MIME type utilities for Semiont
1291
- *
1292
- * Initial support for:
1293
- * - text/plain
1294
- * - text/markdown
1295
- * - image/png
1296
- * - image/jpeg
1297
- * - application/pdf
1298
- */
1299
- /**
1300
- * Map MIME type to file extension
1301
- */
1302
- declare function getExtensionForMimeType(mimeType: string): string;
1303
- /**
1304
- * Detect if MIME type is an image (png or jpeg only for now)
1305
- */
1306
- declare function isImageMimeType(mimeType: string): boolean;
1307
- /**
1308
- * Detect if MIME type is text-based (plain or markdown only for now)
1309
- */
1310
- declare function isTextMimeType(mimeType: string): boolean;
1311
- /**
1312
- * Detect if MIME type is PDF
1313
- */
1314
- declare function isPdfMimeType(mimeType: string): boolean;
1315
- /**
1316
- * Get category for MIME type (for routing to appropriate viewer)
1317
- *
1318
- * Categories represent annotation models, not file formats:
1319
- * - 'text': Text-based annotations (TextPositionSelector, TextQuoteSelector)
1320
- * - 'image': Spatial coordinate annotations (SvgSelector, FragmentSelector)
1321
- *
1322
- * PDFs use spatial coordinates for annotations, so they belong to 'image' category.
1323
- */
1324
- type MimeCategory = 'text' | 'image' | 'unsupported';
1325
- declare function getMimeCategory(mimeType: string): MimeCategory;
1326
-
1327
- export { APIError, AdminNamespace, type AnnotationHistoryResponse, AuthNamespace, BeckonNamespace, BindNamespace, BrowseNamespace, type CreateAnnotationInput, type CreateFromTokenOptions, type CreateResourceInput, type GatherAnnotationProgress, GatherNamespace, type GenerationOptions, JobNamespace, type MarkAssistOptions, type MarkAssistProgress, MarkNamespace, MatchNamespace, type MatchSearchProgress, type MimeCategory, type ReferenceDetectionProgress, type ReferencedByEntry, type RequestContent$1 as RequestContent, type RequestOptions, type ResponseContent$1 as ResponseContent, SSEClient, type SSEClientConfig, type SSEStream, type SSEStreamConnected, SSE_STREAM_CONNECTED, SemiontApiClient, type SemiontApiClientConfig, type TokenRefresher, type User, YieldNamespace, type YieldProgress, getExtensionForMimeType, getMimeCategory, isImageMimeType, isPdfMimeType, isTextMimeType };
173
+ export { APIError, type ActorVM, type ActorVMOptions, type BusEvent, DEGRADED_THRESHOLD_MS, HttpContentTransport, HttpTransport, type HttpTransportConfig, type TokenRefresher, createActorVM };