@semiont/sdk 0.5.4 → 0.5.6
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 +1792 -52
- package/dist/index.js +140 -44
- package/dist/index.js.map +1 -1
- package/package.json +9 -6
- package/dist/awaitable.d.ts +0 -103
- package/dist/awaitable.d.ts.map +0 -1
- package/dist/bus-request.d.ts +0 -18
- package/dist/bus-request.d.ts.map +0 -1
- package/dist/cache.d.ts +0 -57
- package/dist/cache.d.ts.map +0 -1
- package/dist/client.d.ts +0 -138
- package/dist/client.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/namespaces/admin.d.ts +0 -27
- package/dist/namespaces/admin.d.ts.map +0 -1
- package/dist/namespaces/auth.d.ts +0 -26
- package/dist/namespaces/auth.d.ts.map +0 -1
- package/dist/namespaces/beckon.d.ts +0 -12
- package/dist/namespaces/beckon.d.ts.map +0 -1
- package/dist/namespaces/bind.d.ts +0 -11
- package/dist/namespaces/bind.d.ts.map +0 -1
- package/dist/namespaces/browse.d.ts +0 -111
- package/dist/namespaces/browse.d.ts.map +0 -1
- package/dist/namespaces/frame.d.ts +0 -29
- package/dist/namespaces/frame.d.ts.map +0 -1
- package/dist/namespaces/gather.d.ts +0 -16
- package/dist/namespaces/gather.d.ts.map +0 -1
- package/dist/namespaces/job.d.ts +0 -32
- package/dist/namespaces/job.d.ts.map +0 -1
- package/dist/namespaces/mark.d.ts +0 -27
- package/dist/namespaces/mark.d.ts.map +0 -1
- package/dist/namespaces/match.d.ts +0 -15
- package/dist/namespaces/match.d.ts.map +0 -1
- package/dist/namespaces/types.d.ts +0 -438
- package/dist/namespaces/types.d.ts.map +0 -1
- package/dist/namespaces/yield.d.ts +0 -23
- package/dist/namespaces/yield.d.ts.map +0 -1
- package/dist/session/errors.d.ts +0 -18
- package/dist/session/errors.d.ts.map +0 -1
- package/dist/session/http-session-factory.d.ts +0 -15
- package/dist/session/http-session-factory.d.ts.map +0 -1
- package/dist/session/knowledge-base.d.ts +0 -95
- package/dist/session/knowledge-base.d.ts.map +0 -1
- package/dist/session/open-resource.d.ts +0 -22
- package/dist/session/open-resource.d.ts.map +0 -1
- package/dist/session/registry.d.ts +0 -31
- package/dist/session/registry.d.ts.map +0 -1
- package/dist/session/semiont-browser.d.ts +0 -141
- package/dist/session/semiont-browser.d.ts.map +0 -1
- package/dist/session/semiont-session.d.ts +0 -210
- package/dist/session/semiont-session.d.ts.map +0 -1
- package/dist/session/session-factory.d.ts +0 -31
- package/dist/session/session-factory.d.ts.map +0 -1
- package/dist/session/session-signals.d.ts +0 -40
- package/dist/session/session-signals.d.ts.map +0 -1
- package/dist/session/session-storage.d.ts +0 -41
- package/dist/session/session-storage.d.ts.map +0 -1
- package/dist/session/storage.d.ts +0 -52
- package/dist/session/storage.d.ts.map +0 -1
- package/dist/session/testing.d.ts +0 -7
- package/dist/session/testing.d.ts.map +0 -1
- package/dist/state/flows/beckon-state-unit.d.ts +0 -22
- package/dist/state/flows/beckon-state-unit.d.ts.map +0 -1
- package/dist/state/flows/gather-state-unit.d.ts +0 -12
- package/dist/state/flows/gather-state-unit.d.ts.map +0 -1
- package/dist/state/flows/mark-state-unit.d.ts +0 -17
- package/dist/state/flows/mark-state-unit.d.ts.map +0 -1
- package/dist/state/flows/match-state-unit.d.ts +0 -7
- package/dist/state/flows/match-state-unit.d.ts.map +0 -1
- package/dist/state/flows/yield-state-unit.d.ts +0 -25
- package/dist/state/flows/yield-state-unit.d.ts.map +0 -1
- package/dist/state/index.d.ts +0 -10
- package/dist/state/index.d.ts.map +0 -1
- package/dist/state/lib/search-pipeline.d.ts +0 -38
- package/dist/state/lib/search-pipeline.d.ts.map +0 -1
- package/dist/state/lib/state-unit.d.ts +0 -33
- package/dist/state/lib/state-unit.d.ts.map +0 -1
- package/dist/state/lib/worker-bus.d.ts +0 -21
- package/dist/state/lib/worker-bus.d.ts.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,61 +1,1801 @@
|
|
|
1
|
+
import * as rxjs from 'rxjs';
|
|
2
|
+
import { Observable, BehaviorSubject, Subject } from 'rxjs';
|
|
3
|
+
export { firstValueFrom, lastValueFrom } from 'rxjs';
|
|
4
|
+
import * as _semiont_core from '@semiont/core';
|
|
5
|
+
import { ResourceId, components, UserDID, paths, BackendDownload, ProgressEvent, AnnotationId, BodyOperation, EventMap, ResourceDescriptor, Annotation, TagSchema, GraphConnection, Motivation, GatheredContext, JobId, ITransport, EventBus, IContentTransport, IBackendOperations, BaseUrl, AccessToken, SemiontError, ConnectionState, Selector } from '@semiont/core';
|
|
6
|
+
export { AccessToken, Annotation, AnnotationId, BaseUrl, BodyItem, BodyOperation, ConnectionState, EntityType, EventMap, GatheredContext, IContentTransport, ITransport, Logger, Motivation, RefreshToken, ResourceDescriptor, ResourceId, SemiontError, TagCategory, TagSchema, UserId, accessToken, annotationId, baseUrl, entityType, refreshToken, resourceId, userId } from '@semiont/core';
|
|
7
|
+
export { APIError, HttpContentTransport, HttpTransport, HttpTransportConfig, TokenRefresher } from '@semiont/api-client';
|
|
8
|
+
|
|
1
9
|
/**
|
|
2
|
-
*
|
|
10
|
+
* Thenable Observable subclasses.
|
|
3
11
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* and
|
|
12
|
+
* Two thin Observable subclasses that also implement `PromiseLike<T>`. Used as
|
|
13
|
+
* the public return type of namespace methods that emit streams (job
|
|
14
|
+
* lifecycle, generation progress) and cache reads (Browse live queries).
|
|
7
15
|
*
|
|
8
|
-
*
|
|
9
|
-
* `
|
|
10
|
-
* (`
|
|
11
|
-
* convenience so the common case is a single import; non-HTTP transports
|
|
12
|
-
* (e.g. `LocalTransport` from `@semiont/make-meaning`) are constructed
|
|
13
|
-
* by the caller from their own package.
|
|
16
|
+
* The point: scripts can `await` the call directly without `lastValueFrom` /
|
|
17
|
+
* `firstValueFrom` wrappers; reactive consumers keep using `.subscribe(...)`
|
|
18
|
+
* and `.pipe(...)` exactly as before.
|
|
14
19
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* on
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
+
* The asymmetric `.then()` semantics — last-value-on-completion for streams,
|
|
21
|
+
* first-non-undefined-value for caches — is encoded by the subclass name. The
|
|
22
|
+
* docstring on the namespace method tells the consumer which one applies.
|
|
23
|
+
*
|
|
24
|
+
* `.pipe(...)` returns a plain `Observable<T>` (RxJS doesn't propagate
|
|
25
|
+
* subclasses through `pipe`). Once you compose, you've explicitly entered
|
|
26
|
+
* RxJS land; `lastValueFrom` from `rxjs` is the right bridge there.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Bounded Observable stream — emits zero-or-more progress values, then a
|
|
31
|
+
* final value on completion. Used by job-lifecycle methods like
|
|
32
|
+
* `mark.assist`, `gather.annotation`, `match.search`, `yield.fromAnnotation`.
|
|
33
|
+
*
|
|
34
|
+
* Awaiting resolves to the **last** emitted value (via `lastValueFrom`).
|
|
35
|
+
* Subscribing yields every emission, ending in `complete`.
|
|
36
|
+
*/
|
|
37
|
+
declare class StreamObservable<T> extends Observable<T> implements PromiseLike<T> {
|
|
38
|
+
then<R1 = T, R2 = never>(onfulfilled?: ((v: T) => R1 | PromiseLike<R1>) | null, onrejected?: ((e: unknown) => R2 | PromiseLike<R2>) | null): PromiseLike<R1 | R2>;
|
|
39
|
+
/** Wrap an existing Observable's subscribe behavior in a StreamObservable. */
|
|
40
|
+
static from<T>(source: Observable<T>): StreamObservable<T>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Multicast cache observable — emits `undefined` while the underlying value
|
|
44
|
+
* is loading, then the value, then re-emits when bus events invalidate the
|
|
45
|
+
* cache entry. Used by Browse live-query methods (`browse.resource`,
|
|
46
|
+
* `browse.annotations`, etc.).
|
|
47
|
+
*
|
|
48
|
+
* Awaiting (the one-shot path) fetches a **fresh** value via the optional
|
|
49
|
+
* `fetchFresh` action and rejects on failure — a re-read reflects writes
|
|
50
|
+
* (#847). Subscribing yields the SWR sequence: the initial `undefined`, the
|
|
51
|
+
* loaded value, and re-emits on invalidation. (Without a `fetchFresh` action
|
|
52
|
+
* — e.g. a non-cache wrapper — the await falls back to the first
|
|
53
|
+
* non-undefined emission.)
|
|
54
|
+
*
|
|
55
|
+
* The class is parameterized as `CacheObservable<T>` even though the
|
|
56
|
+
* stream's element type is `T | undefined` — `T` is what the consumer
|
|
57
|
+
* gets from `await`, and that's the contract we want to advertise. The
|
|
58
|
+
* `Observable<T | undefined>` shape leaks through `.subscribe` and
|
|
59
|
+
* `.pipe` in the natural way.
|
|
60
|
+
*/
|
|
61
|
+
declare class CacheObservable<T> extends Observable<T | undefined> implements PromiseLike<T> {
|
|
62
|
+
/**
|
|
63
|
+
* Optional one-shot fresh-fetch action. When present, `then()` (the await
|
|
64
|
+
* path) resolves to a freshly fetched value and rejects on fetch failure —
|
|
65
|
+
* so a re-read reflects writes (#847). `.subscribe(...)` never uses it: it
|
|
66
|
+
* keeps the stale-while-revalidate cached view over `source`.
|
|
67
|
+
*/
|
|
68
|
+
private fetchFresh?;
|
|
69
|
+
then<R1 = T, R2 = never>(onfulfilled?: ((v: T) => R1 | PromiseLike<R1>) | null, onrejected?: ((e: unknown) => R2 | PromiseLike<R2>) | null): PromiseLike<R1 | R2>;
|
|
70
|
+
/**
|
|
71
|
+
* Wrap an existing Observable's subscribe behavior in a `CacheObservable`.
|
|
72
|
+
*
|
|
73
|
+
* `fetchFresh`, when supplied, backs the await path: `await` resolves to a
|
|
74
|
+
* freshly fetched value (rejecting on failure), so a one-shot read reflects
|
|
75
|
+
* writes without a scoped subscription (#847). `.subscribe(...)` consumers
|
|
76
|
+
* keep the SWR view over `source`.
|
|
77
|
+
*
|
|
78
|
+
* Memoizes on source identity: passing the same `source` returns the same
|
|
79
|
+
* wrapper instance. The Browse cache primitive already returns a stable
|
|
80
|
+
* Observable per key (its B4 contract), so this preserves that contract
|
|
81
|
+
* through the awaitable wrapping. Without the memo, every public-method
|
|
82
|
+
* call would produce a fresh wrapper and break referential-equality
|
|
83
|
+
* guarantees that hook-style reactive consumers depend on.
|
|
84
|
+
*
|
|
85
|
+
* Backed by a `WeakMap`, so wrappers are GC'd when their source is.
|
|
86
|
+
*/
|
|
87
|
+
static from<T>(source: Observable<T | undefined>, fetchFresh?: () => Promise<T>): CacheObservable<T>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Discriminated phases of an upload's lifecycle.
|
|
91
|
+
*
|
|
92
|
+
* - `started` — emitted immediately on `yield.resource(...)` invocation, before any bytes flow.
|
|
93
|
+
* - `progress` — emitted as bytes flow over the wire. Wired by `HttpContentTransport`'s XHR path when a caller passes `onProgress` (or, transitively, when `yield.resource` is the caller — it always wires the hook so subscribers see byte counts). `bytesUploaded` and `totalBytes` carry the running counts; `totalBytes` may be 0 when the transport can't determine the total (rare, e.g. chunked encoding) — UI consumers should render an indeterminate state in that case.
|
|
94
|
+
* - `finished` — emitted on backend acknowledgement, carries the assigned `resourceId`.
|
|
95
|
+
*
|
|
96
|
+
* Failures surface as `Observable.error(...)` (typically an `APIError` from the transport's `errors$` Subject), not as a `phase: 'failed'` event — `subscribe`'s error callback handles them. Cancellation is honored: unsubscribing before `finished` aborts the in-flight HTTP request on the XHR path.
|
|
97
|
+
*/
|
|
98
|
+
type UploadProgress = {
|
|
99
|
+
phase: 'started';
|
|
100
|
+
totalBytes: number;
|
|
101
|
+
} | {
|
|
102
|
+
phase: 'progress';
|
|
103
|
+
bytesUploaded: number;
|
|
104
|
+
totalBytes: number;
|
|
105
|
+
} | {
|
|
106
|
+
phase: 'finished';
|
|
107
|
+
resourceId: ResourceId;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Specialized `StreamObservable` for `yield.resource`. Subscribers see the
|
|
111
|
+
* full `UploadProgress` event sequence (started → optional progress → finished).
|
|
112
|
+
* Awaiting resolves specifically to `{ resourceId }` extracted from the
|
|
113
|
+
* `'finished'` event — preserving the pre-Phase-18 awaited shape so existing
|
|
114
|
+
* `await client.yield.resource(...)` callers don't need to narrow the union.
|
|
115
|
+
*/
|
|
116
|
+
declare class UploadObservable extends Observable<UploadProgress> implements PromiseLike<{
|
|
117
|
+
resourceId: ResourceId;
|
|
118
|
+
}> {
|
|
119
|
+
then<R1 = {
|
|
120
|
+
resourceId: ResourceId;
|
|
121
|
+
}, R2 = never>(onfulfilled?: ((v: {
|
|
122
|
+
resourceId: ResourceId;
|
|
123
|
+
}) => R1 | PromiseLike<R1>) | null, onrejected?: ((e: unknown) => R2 | PromiseLike<R2>) | null): PromiseLike<R1 | R2>;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Verb Namespace Interfaces
|
|
128
|
+
*
|
|
129
|
+
* These interfaces define the public API of `@semiont/sdk`, organized by
|
|
130
|
+
* the 7 domain flows (Browse, Mark, Bind, Gather, Match, Yield, Beckon)
|
|
131
|
+
* plus infrastructure namespaces (Job, Auth, Admin).
|
|
132
|
+
*
|
|
133
|
+
* Each namespace maps 1:1 to a flow. Each flow maps to a clear actor on
|
|
134
|
+
* the backend. The frontend calls `client.mark.annotation()` and the
|
|
135
|
+
* client handles HTTP, auth, SSE, and caching internally.
|
|
136
|
+
*
|
|
137
|
+
* Return type conventions:
|
|
138
|
+
* - Browse live queries → `CacheObservable<T>` (bus-driven, cached;
|
|
139
|
+
* subscribe yields `T | undefined`, await yields `T` after first load)
|
|
140
|
+
* - Browse one-shot reads → `Promise<T>` (fetch once, no cache)
|
|
141
|
+
* - Commands (mark, bind, yield.resource) → `Promise<T>` (atomic ops)
|
|
142
|
+
* - Long-running ops (gather, match, yield.fromAnnotation, mark.assist)
|
|
143
|
+
* → `StreamObservable<T>` (progress + result; subscribe yields every
|
|
144
|
+
* emit, await yields the last one)
|
|
145
|
+
* - Ephemeral signals (beckon) → `void`
|
|
146
|
+
*
|
|
147
|
+
* `StreamObservable` and `CacheObservable` are `Observable` subclasses
|
|
148
|
+
* that also implement `PromiseLike<T>` — `await client.X.Y(...)` works
|
|
149
|
+
* directly without `lastValueFrom`/`firstValueFrom` wrappers.
|
|
150
|
+
* `.pipe(...)` returns a plain `Observable<T>` (the thenable subclass
|
|
151
|
+
* does not propagate through pipe — by design).
|
|
152
|
+
*/
|
|
153
|
+
|
|
154
|
+
type StoredEventResponse$1 = components['schemas']['StoredEventResponse'];
|
|
155
|
+
type GatherProgress = components['schemas']['GatherProgress'];
|
|
156
|
+
type MatchSearchResult = components['schemas']['MatchSearchResult'];
|
|
157
|
+
type JobProgress$2 = components['schemas']['JobProgress'];
|
|
158
|
+
type GatherAnnotationComplete = components['schemas']['GatherAnnotationComplete'];
|
|
159
|
+
type JobStatusResponse$1 = components['schemas']['JobStatusResponse'];
|
|
160
|
+
type AuthResponse$1 = components['schemas']['AuthResponse'];
|
|
161
|
+
type TokenRefreshResponse$1 = components['schemas']['TokenRefreshResponse'];
|
|
162
|
+
type OAuthConfigResponse$1 = components['schemas']['OAuthConfigResponse'];
|
|
163
|
+
type AdminUserStatsResponse$1 = components['schemas']['AdminUserStatsResponse'];
|
|
164
|
+
type ResponseContent<T> = T extends {
|
|
165
|
+
responses: {
|
|
166
|
+
200: {
|
|
167
|
+
content: {
|
|
168
|
+
'application/json': infer R;
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
} ? R : T extends {
|
|
173
|
+
responses: {
|
|
174
|
+
201: {
|
|
175
|
+
content: {
|
|
176
|
+
'application/json': infer R;
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
};
|
|
180
|
+
} ? R : T extends {
|
|
181
|
+
responses: {
|
|
182
|
+
202: {
|
|
183
|
+
content: {
|
|
184
|
+
'application/json': infer R;
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
} ? R : never;
|
|
189
|
+
type RequestContent<T> = T extends {
|
|
190
|
+
requestBody?: {
|
|
191
|
+
content: {
|
|
192
|
+
'application/json': infer R;
|
|
193
|
+
};
|
|
194
|
+
};
|
|
195
|
+
} ? R : never;
|
|
196
|
+
/** Input for creating an annotation via mark.annotation() */
|
|
197
|
+
type CreateAnnotationInput = components['schemas']['CreateAnnotationRequest'];
|
|
198
|
+
/** Input for creating a resource via yield.resource() */
|
|
199
|
+
interface CreateResourceInput {
|
|
200
|
+
name: string;
|
|
201
|
+
file: File | Buffer;
|
|
202
|
+
format: string;
|
|
203
|
+
entityTypes?: string[];
|
|
204
|
+
language?: string;
|
|
205
|
+
sourceAnnotationId?: string;
|
|
206
|
+
sourceResourceId?: string;
|
|
207
|
+
storageUri: string;
|
|
208
|
+
/** Prompt that drove AI generation (for AI-generated resources). */
|
|
209
|
+
generationPrompt?: string;
|
|
210
|
+
/** Agent(s) that generated the content (for AI-generated resources). */
|
|
211
|
+
generator?: components['schemas']['Agent'] | components['schemas']['Agent'][];
|
|
212
|
+
isDraft?: boolean;
|
|
213
|
+
}
|
|
214
|
+
/** Options for yield.fromAnnotation() */
|
|
215
|
+
interface GenerationOptions {
|
|
216
|
+
title: string;
|
|
217
|
+
storageUri: string;
|
|
218
|
+
context: GatheredContext;
|
|
219
|
+
prompt?: string;
|
|
220
|
+
/** Entity-type tags to stamp on the synthesized resource. Used both as a prompt bias for the generation worker and as the `entityTypes` set on the resulting resource (so `browse.resources({ entityType: ... })` queries can find it). */
|
|
221
|
+
entityTypes?: string[];
|
|
222
|
+
/** Annotation/resource body locale — language the generated resource is written in (typically the user's UI locale). */
|
|
223
|
+
language?: string;
|
|
224
|
+
/** Source-resource locale — language of the resource the annotation lives on, used in the prompt so the LLM understands embedded source-context snippets. BCP-47. */
|
|
225
|
+
sourceLanguage?: string;
|
|
226
|
+
temperature?: number;
|
|
227
|
+
maxTokens?: number;
|
|
228
|
+
}
|
|
229
|
+
/** Options for mark.assist() */
|
|
230
|
+
interface MarkAssistOptions {
|
|
231
|
+
entityTypes?: string[];
|
|
232
|
+
includeDescriptiveReferences?: boolean;
|
|
233
|
+
instructions?: string;
|
|
234
|
+
density?: number;
|
|
235
|
+
tone?: string;
|
|
236
|
+
/** Annotation body locale — language the LLM should write generated body text in (comment text, assessment text, tag/reference body language stamp). BCP-47. */
|
|
237
|
+
language?: string;
|
|
238
|
+
/** Source-resource locale — language of the content being analyzed, used in the prompt so the LLM analyzes non-English source correctly. BCP-47. */
|
|
239
|
+
sourceLanguage?: string;
|
|
240
|
+
schemaId?: string;
|
|
241
|
+
categories?: string[];
|
|
242
|
+
}
|
|
243
|
+
/** Options for yield.createFromToken() */
|
|
244
|
+
type CreateFromTokenOptions = {
|
|
245
|
+
token: string;
|
|
246
|
+
name: string;
|
|
247
|
+
content: string;
|
|
248
|
+
archiveOriginal?: boolean;
|
|
249
|
+
};
|
|
250
|
+
/** Referenced-by entry from browse.referencedBy() */
|
|
251
|
+
type ReferencedByEntry = components['schemas']['GetReferencedByResponse']['referencedBy'][number];
|
|
252
|
+
/** Annotation history from browse.annotationHistory() */
|
|
253
|
+
type AnnotationHistoryResponse = components['schemas']['GetAnnotationHistoryResponse'];
|
|
254
|
+
/** User object from auth/admin responses */
|
|
255
|
+
type User = AuthResponse$1['user'];
|
|
256
|
+
/**
|
|
257
|
+
* Progress emitted by gather.annotation() Observable.
|
|
258
|
+
* Emits GatherProgress during assembly, then GatherAnnotationComplete on finish.
|
|
259
|
+
*/
|
|
260
|
+
type GatherAnnotationProgress = GatherProgress | GatherAnnotationComplete;
|
|
261
|
+
/**
|
|
262
|
+
* Progress emitted by match.search() Observable.
|
|
263
|
+
* Emits the final MatchSearchResult (no intermediate progress events currently).
|
|
264
|
+
*/
|
|
265
|
+
type MatchSearchProgress = MatchSearchResult;
|
|
266
|
+
/**
|
|
267
|
+
* Progress payload emitted by mark.assist() and yield.fromAnnotation()
|
|
268
|
+
* Observables. Each progress emission carries a JobProgress snapshot
|
|
269
|
+
* (unified job lifecycle).
|
|
270
|
+
*/
|
|
271
|
+
type MarkAssistProgress = JobProgress$2;
|
|
272
|
+
/**
|
|
273
|
+
* Discriminated event yielded by the `mark.assist()` Observable. Progress
|
|
274
|
+
* events stream while the worker runs; the final value before the
|
|
275
|
+
* Observable completes is a `complete` event carrying the `JobCompleteCommand`
|
|
276
|
+
* payload (with `result`, `jobId`, `jobType`, etc.). The Observable errors
|
|
277
|
+
* on `job:fail`.
|
|
278
|
+
*/
|
|
279
|
+
type MarkAssistEvent = {
|
|
280
|
+
kind: 'progress';
|
|
281
|
+
data: MarkAssistProgress;
|
|
282
|
+
} | {
|
|
283
|
+
kind: 'complete';
|
|
284
|
+
data: components['schemas']['JobCompleteCommand'];
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Discriminated event yielded by the `yield.fromAnnotation()` Observable.
|
|
288
|
+
* Same shape and semantics as `MarkAssistEvent`.
|
|
289
|
+
*/
|
|
290
|
+
type YieldGenerationEvent = {
|
|
291
|
+
kind: 'progress';
|
|
292
|
+
data: JobProgress$2;
|
|
293
|
+
} | {
|
|
294
|
+
kind: 'complete';
|
|
295
|
+
data: components['schemas']['JobCompleteCommand'];
|
|
296
|
+
};
|
|
297
|
+
/**
|
|
298
|
+
* Browse — reads from materialized views
|
|
299
|
+
*
|
|
300
|
+
* Live queries return Observables that emit initial state and re-emit
|
|
301
|
+
* on bus gateway updates. One-shot reads return Promises.
|
|
302
|
+
*
|
|
303
|
+
* Backend actor: Browser (context classes)
|
|
304
|
+
* Event prefix: browse:*
|
|
305
|
+
*/
|
|
306
|
+
interface BrowseNamespace$1 {
|
|
307
|
+
resource(resourceId: ResourceId): CacheObservable<ResourceDescriptor>;
|
|
308
|
+
resources(filters?: {
|
|
309
|
+
limit?: number;
|
|
310
|
+
archived?: boolean;
|
|
311
|
+
search?: string;
|
|
312
|
+
entityType?: string;
|
|
313
|
+
}): CacheObservable<ResourceDescriptor[]>;
|
|
314
|
+
annotations(resourceId: ResourceId): CacheObservable<Annotation[]>;
|
|
315
|
+
annotation(resourceId: ResourceId, annotationId: AnnotationId): CacheObservable<Annotation>;
|
|
316
|
+
entityTypes(): CacheObservable<string[]>;
|
|
317
|
+
tagSchemas(): CacheObservable<TagSchema[]>;
|
|
318
|
+
referencedBy(resourceId: ResourceId): CacheObservable<ReferencedByEntry[]>;
|
|
319
|
+
events(resourceId: ResourceId): CacheObservable<StoredEventResponse$1[]>;
|
|
320
|
+
resourceContent(resourceId: ResourceId): Promise<string>;
|
|
321
|
+
resourceRepresentation(resourceId: ResourceId, options?: {
|
|
322
|
+
accept?: string;
|
|
323
|
+
}): Promise<{
|
|
324
|
+
data: ArrayBuffer;
|
|
325
|
+
contentType: string;
|
|
326
|
+
}>;
|
|
327
|
+
resourceRepresentationStream(resourceId: ResourceId, options?: {
|
|
328
|
+
accept?: string;
|
|
329
|
+
}): Promise<{
|
|
330
|
+
stream: ReadableStream<Uint8Array>;
|
|
331
|
+
contentType: string;
|
|
332
|
+
}>;
|
|
333
|
+
resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse$1[]>;
|
|
334
|
+
annotationHistory(resourceId: ResourceId, annotationId: AnnotationId): Promise<AnnotationHistoryResponse>;
|
|
335
|
+
connections(resourceId: ResourceId): Promise<GraphConnection[]>;
|
|
336
|
+
backlinks(resourceId: ResourceId): Promise<Annotation[]>;
|
|
337
|
+
resourcesByName(query: string, limit?: number): Promise<ResourceDescriptor[]>;
|
|
338
|
+
files(dirPath?: string, sort?: 'name' | 'mtime' | 'annotationCount'): Promise<components['schemas']['BrowseFilesResponse']>;
|
|
339
|
+
click(annotationId: AnnotationId, motivation: Motivation): void;
|
|
340
|
+
navigateReference(resourceId: ResourceId): void;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Frame — schema-layer flow (the eighth flow).
|
|
344
|
+
*
|
|
345
|
+
* Frame operates on the KB's conceptual vocabulary — what *kinds* of
|
|
346
|
+
* things exist (entity types) and, in the future, what taxonomies are
|
|
347
|
+
* recognized (tag schemas), what relations are typed (predicate types),
|
|
348
|
+
* and how schemas are imported (ontology I/O). The other seven flows
|
|
349
|
+
* (yield, mark, match, bind, gather, browse, beckon) operate on
|
|
350
|
+
* content; Frame operates on the schema layer that content is expressed
|
|
351
|
+
* in.
|
|
352
|
+
*
|
|
353
|
+
* MVP scope is small: entity-type vocabulary writes only. Live reads of
|
|
354
|
+
* the entity-type vocabulary stay on Browse (`browse.entityTypes()` is
|
|
355
|
+
* a `CacheObservable<string[]>` consumed by 8+ call sites). Frame owns
|
|
356
|
+
* writes; Browse owns reads — the same asymmetry that already holds for
|
|
357
|
+
* resources and annotations.
|
|
358
|
+
*
|
|
359
|
+
* Backend actor: Stower
|
|
360
|
+
* Event prefix: frame:*
|
|
361
|
+
*/
|
|
362
|
+
interface FrameNamespace$1 {
|
|
363
|
+
/** Add a single entity type to the KB's vocabulary. Idempotent — adding an existing type is a no-op. */
|
|
364
|
+
addEntityType(type: string): Promise<void>;
|
|
365
|
+
/** Add multiple entity types in one call. Convenience over a loop of `addEntityType`. */
|
|
366
|
+
addEntityTypes(types: string[]): Promise<void>;
|
|
367
|
+
/**
|
|
368
|
+
* Register a tag schema with the KB's runtime registry.
|
|
369
|
+
*
|
|
370
|
+
* Most-recent registration of a given `schema.id` wins; identical
|
|
371
|
+
* re-registrations are silent, differing content overwrites the
|
|
372
|
+
* existing entry and logs a warning. KBs typically call this at
|
|
373
|
+
* session/skill startup so the schema is available for `mark.assist`
|
|
374
|
+
* with motivation `tagging` and surfaces in `browse.tagSchemas()`.
|
|
375
|
+
*/
|
|
376
|
+
addTagSchema(schema: TagSchema): Promise<void>;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Mark — annotation CRUD, AI assist, resource lifecycle
|
|
380
|
+
*
|
|
381
|
+
* Commands return Promises that resolve on HTTP acceptance (202).
|
|
382
|
+
* Results appear on browse Observables via bus gateway.
|
|
383
|
+
* assist() returns an Observable for long-running progress.
|
|
384
|
+
*
|
|
385
|
+
* Backend actor: Stower
|
|
386
|
+
* Event prefix: mark:*
|
|
387
|
+
*/
|
|
388
|
+
interface MarkNamespace$1 {
|
|
389
|
+
annotation(input: CreateAnnotationInput): Promise<{
|
|
390
|
+
annotationId: AnnotationId;
|
|
391
|
+
}>;
|
|
392
|
+
delete(resourceId: ResourceId, annotationId: AnnotationId): Promise<void>;
|
|
393
|
+
archive(resourceId: ResourceId): Promise<void>;
|
|
394
|
+
unarchive(resourceId: ResourceId): Promise<void>;
|
|
395
|
+
assist(resourceId: ResourceId, motivation: Motivation, options: MarkAssistOptions): StreamObservable<MarkAssistEvent>;
|
|
396
|
+
request(selector: components['schemas']['MarkRequestedEvent']['selector'], motivation: Motivation): void;
|
|
397
|
+
/** Fire-and-forget variant of `assist` — mark-state-unit orchestrates the call and its progress Observable. */
|
|
398
|
+
requestAssist(motivation: Motivation, options: MarkAssistOptions, correlationId?: string): void;
|
|
399
|
+
/** Submit the currently pending annotation with its selector and optional body. */
|
|
400
|
+
submit(input: components['schemas']['MarkSubmitEvent']): void;
|
|
401
|
+
/** Cancel the currently pending annotation (if any). */
|
|
402
|
+
cancelPending(): void;
|
|
403
|
+
/** Dismiss the in-progress AI-assist widget. */
|
|
404
|
+
dismissProgress(): void;
|
|
405
|
+
changeSelection(motivation: Motivation | null): void;
|
|
406
|
+
changeClick(action: string): void;
|
|
407
|
+
changeShape(shape: string): void;
|
|
408
|
+
toggleMode(): void;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Bind — reference linking
|
|
412
|
+
*
|
|
413
|
+
* The simplest namespace. One method. The result (updated annotation
|
|
414
|
+
* with resolved reference) arrives on browse.annotations() via the
|
|
415
|
+
* enriched mark:body-updated event.
|
|
416
|
+
*
|
|
417
|
+
* Backend actor: Stower (via mark:update-body)
|
|
418
|
+
* Event prefix: mark:body-updated (shares mark event pipeline)
|
|
419
|
+
*/
|
|
420
|
+
interface BindNamespace$1 {
|
|
421
|
+
body(resourceId: ResourceId, annotationId: AnnotationId, operations: BodyOperation[]): Promise<void>;
|
|
422
|
+
/** UI signal: a reference-binding flow is requested for an annotation. */
|
|
423
|
+
initiate(input: EventMap['bind:initiate']): void;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Gather — context assembly
|
|
427
|
+
*
|
|
428
|
+
* Long-running (LLM calls + graph traversal). Returns Observables
|
|
429
|
+
* that emit progress then the gathered context.
|
|
430
|
+
*
|
|
431
|
+
* Backend actor: Gatherer
|
|
432
|
+
* Event prefix: gather:*
|
|
433
|
+
*/
|
|
434
|
+
interface GatherNamespace$1 {
|
|
435
|
+
annotation(resourceId: ResourceId, annotationId: AnnotationId, options?: {
|
|
436
|
+
contextWindow?: number;
|
|
437
|
+
}): StreamObservable<GatherAnnotationProgress>;
|
|
438
|
+
resource(resourceId: ResourceId, options?: {
|
|
439
|
+
contextWindow?: number;
|
|
440
|
+
}): StreamObservable<GatherAnnotationProgress>;
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Match — search and ranking
|
|
444
|
+
*
|
|
445
|
+
* Long-running (semantic search, optional LLM scoring). Returns
|
|
446
|
+
* Observable with progress then results.
|
|
447
|
+
*
|
|
448
|
+
* Backend actor: Matcher
|
|
449
|
+
* Event prefix: match:*
|
|
450
|
+
*/
|
|
451
|
+
interface MatchNamespace$1 {
|
|
452
|
+
search(resourceId: ResourceId, referenceId: AnnotationId, context: GatheredContext, options?: {
|
|
453
|
+
limit?: number;
|
|
454
|
+
useSemanticScoring?: boolean;
|
|
455
|
+
}): StreamObservable<MatchSearchProgress>;
|
|
456
|
+
/** Fire-and-forget variant: match-state-unit orchestrates the call and its result Observable. */
|
|
457
|
+
requestSearch(input: components['schemas']['MatchSearchRequest']): void;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Yield — resource creation
|
|
461
|
+
*
|
|
462
|
+
* resource() is synchronous file upload (Promise).
|
|
463
|
+
* fromAnnotation() is long-running LLM generation (Observable).
|
|
464
|
+
*
|
|
465
|
+
* Backend actor: Stower + generation worker
|
|
466
|
+
* Event prefix: yield:*
|
|
467
|
+
*/
|
|
468
|
+
interface YieldNamespace$1 {
|
|
469
|
+
resource(data: CreateResourceInput): UploadObservable;
|
|
470
|
+
fromAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options: GenerationOptions): StreamObservable<YieldGenerationEvent>;
|
|
471
|
+
cloneToken(resourceId: ResourceId): Promise<{
|
|
472
|
+
token: string;
|
|
473
|
+
expiresAt: string;
|
|
474
|
+
}>;
|
|
475
|
+
fromToken(token: string): Promise<ResourceDescriptor>;
|
|
476
|
+
createFromToken(options: CreateFromTokenOptions): Promise<{
|
|
477
|
+
resourceId: ResourceId;
|
|
478
|
+
}>;
|
|
479
|
+
/** UI signal: user invoked the clone action from the resource-info panel. */
|
|
480
|
+
clone(): void;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Beckon — attention coordination
|
|
484
|
+
*
|
|
485
|
+
* Fire-and-forget. Ephemeral presence signal delivered via the
|
|
486
|
+
* attention-stream to other participants.
|
|
487
|
+
*
|
|
488
|
+
* Backend actor: (frontend relay via attention-stream)
|
|
489
|
+
* Event prefix: beckon:*
|
|
490
|
+
*/
|
|
491
|
+
interface BeckonNamespace$1 {
|
|
492
|
+
attention(resourceId: ResourceId, annotationId: AnnotationId): void;
|
|
493
|
+
hover(annotationId: AnnotationId | null): void;
|
|
494
|
+
sparkle(annotationId: AnnotationId): void;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Job — worker lifecycle
|
|
498
|
+
*/
|
|
499
|
+
interface JobNamespace$1 {
|
|
500
|
+
/** Live stream of `job:queued` events from the bus. */
|
|
501
|
+
readonly queued$: Observable<EventMap['job:queued']>;
|
|
502
|
+
/** Live stream of `job:report-progress` events from the bus. */
|
|
503
|
+
readonly progress$: Observable<EventMap['job:report-progress']>;
|
|
504
|
+
/** Live stream of `job:complete` events from the bus. */
|
|
505
|
+
readonly complete$: Observable<EventMap['job:complete']>;
|
|
506
|
+
/** Live stream of `job:fail` events from the bus. */
|
|
507
|
+
readonly fail$: Observable<EventMap['job:fail']>;
|
|
508
|
+
status(jobId: JobId): Promise<JobStatusResponse$1>;
|
|
509
|
+
pollUntilComplete(jobId: JobId, options?: {
|
|
510
|
+
interval?: number;
|
|
511
|
+
timeout?: number;
|
|
512
|
+
onProgress?: (status: JobStatusResponse$1) => void;
|
|
513
|
+
}): Promise<JobStatusResponse$1>;
|
|
514
|
+
cancelByType(jobType: 'annotation' | 'generation'): Promise<void>;
|
|
515
|
+
/** UI signal: cancel all active jobs of a given type (e.g. "annotation"). */
|
|
516
|
+
cancelRequest(jobType: 'annotation' | 'generation'): void;
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Auth — authentication
|
|
520
|
+
*/
|
|
521
|
+
interface AuthNamespace$1 {
|
|
522
|
+
password(email: string, password: string): Promise<AuthResponse$1>;
|
|
523
|
+
google(credential: string): Promise<AuthResponse$1>;
|
|
524
|
+
refresh(token: string): Promise<TokenRefreshResponse$1>;
|
|
525
|
+
logout(): Promise<void>;
|
|
526
|
+
me(): Promise<User>;
|
|
527
|
+
acceptTerms(): Promise<void>;
|
|
528
|
+
mcpToken(): Promise<{
|
|
529
|
+
token: string;
|
|
530
|
+
}>;
|
|
531
|
+
mediaToken(resourceId: ResourceId): Promise<{
|
|
532
|
+
token: string;
|
|
533
|
+
}>;
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Admin — administration
|
|
537
|
+
*/
|
|
538
|
+
interface AdminNamespace$1 {
|
|
539
|
+
users(): Promise<User[]>;
|
|
540
|
+
userStats(): Promise<AdminUserStatsResponse$1>;
|
|
541
|
+
updateUser(userId: UserDID, data: RequestContent<paths['/api/admin/users/{id}']['patch']>): Promise<User>;
|
|
542
|
+
oauthConfig(): Promise<OAuthConfigResponse$1>;
|
|
543
|
+
healthCheck(): Promise<ResponseContent<paths['/api/health']['get']>>;
|
|
544
|
+
status(): Promise<ResponseContent<paths['/api/status']['get']>>;
|
|
545
|
+
backup(): Promise<BackendDownload>;
|
|
546
|
+
/**
|
|
547
|
+
* Restore from a backup archive. Returns a `StreamObservable` that
|
|
548
|
+
* emits each `ProgressEvent` as the operation runs (`'started'`,
|
|
549
|
+
* `'parsing'`, `'importing'`, ..., `'complete'`). Subscribers see
|
|
550
|
+
* every step; awaiters get the final event via the PromiseLike sugar.
|
|
551
|
+
*/
|
|
552
|
+
restore(file: File): StreamObservable<ProgressEvent>;
|
|
553
|
+
exportKnowledgeBase(params?: {
|
|
554
|
+
includeArchived?: boolean;
|
|
555
|
+
}): Promise<BackendDownload>;
|
|
556
|
+
importKnowledgeBase(file: File): StreamObservable<ProgressEvent>;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
type StoredEventResponse = components['schemas']['StoredEventResponse'];
|
|
560
|
+
type ResourceListFilters = {
|
|
561
|
+
limit?: number;
|
|
562
|
+
archived?: boolean;
|
|
563
|
+
search?: string;
|
|
564
|
+
entityType?: string;
|
|
565
|
+
};
|
|
566
|
+
declare class BrowseNamespace implements BrowseNamespace$1 {
|
|
567
|
+
private readonly transport;
|
|
568
|
+
private readonly bus;
|
|
569
|
+
private readonly content;
|
|
570
|
+
private readonly resourceCache;
|
|
571
|
+
private readonly resourceListCache;
|
|
572
|
+
private readonly annotationListCache;
|
|
573
|
+
/**
|
|
574
|
+
* Annotation-detail cache keyed by `annotationId` only — the resourceId
|
|
575
|
+
* is a routing hint for the backend fetch, not an identity component.
|
|
576
|
+
* We track the most recent resourceId per annotationId in a side-map
|
|
577
|
+
* so `mark:delete-ok` (which carries only `annotationId`) can reach
|
|
578
|
+
* the right cache entry. Aligns with the pre-refactor semantics.
|
|
579
|
+
*/
|
|
580
|
+
private readonly annotationDetailCache;
|
|
581
|
+
private readonly annotationResources;
|
|
582
|
+
private readonly entityTypesCache;
|
|
583
|
+
private readonly tagSchemasCache;
|
|
584
|
+
private readonly referencedByCache;
|
|
585
|
+
private readonly resourceEventsCache;
|
|
586
|
+
/** Filter-blob memory so `invalidateResourceLists` can replay per-key. */
|
|
587
|
+
private readonly resourceListFilters;
|
|
588
|
+
/**
|
|
589
|
+
* Per-key memo for `annotations()` observables. The cache stores the
|
|
590
|
+
* full `AnnotationsListResponse`; the public shape is just the inner
|
|
591
|
+
* `Annotation[]`. Without this memo, every call to `annotations(rId)`
|
|
592
|
+
* would produce a fresh `.pipe(map(...))` observable, violating B4
|
|
593
|
+
* (per-key observable stability). Consumers that compare observable
|
|
594
|
+
* identity — React hooks depending on the observable reference,
|
|
595
|
+
* `distinctUntilChanged` at a higher level — would misbehave.
|
|
596
|
+
*/
|
|
597
|
+
private readonly annotationListObs;
|
|
598
|
+
/**
|
|
599
|
+
* Per-source memo for the scope-acquiring wrapper (#847 Phase 4), keyed by
|
|
600
|
+
* the underlying (stable, per-key) cache observable so the wrapped
|
|
601
|
+
* observable is itself stable per key — preserving B4/B11 referential
|
|
602
|
+
* identity through to `CacheObservable.from`'s own memo.
|
|
603
|
+
*/
|
|
604
|
+
private readonly scopedSources;
|
|
605
|
+
constructor(transport: ITransport, bus: EventBus, content: IContentTransport);
|
|
606
|
+
/**
|
|
607
|
+
* Wrap a resource-scoped live query's source so that *subscribing* acquires
|
|
608
|
+
* the resource's scope (via the transport's ref-counted
|
|
609
|
+
* `subscribeToResource`) and the last unsubscribe releases it (#847 Phase 4).
|
|
610
|
+
* Freshness follows observation: a `.subscribe()` keeps `rId`'s scoped
|
|
611
|
+
* events flowing — so `mark:*` / entity-tag invalidations reach this cache —
|
|
612
|
+
* with no separate `subscribeToResource` call from the consumer.
|
|
613
|
+
*
|
|
614
|
+
* The one-shot `await` path does NOT go through here (it resolves via the
|
|
615
|
+
* cache's `fetch` — see `CacheObservable.from`'s `fetchFresh`), so a
|
|
616
|
+
* one-shot read acquires no scope.
|
|
617
|
+
*
|
|
618
|
+
* Memoized per source so the wrapped observable is stable per key (B4/B11).
|
|
619
|
+
* Each subscription calls `subscribeToResource(rId)`; the transport
|
|
620
|
+
* ref-counts concurrent subscriptions for the same resource onto a single
|
|
621
|
+
* SSE scope. Single-scope model unchanged — multi-scope is deferred (see
|
|
622
|
+
* `.plans/MULTI-RESOURCE-SCOPE.md`).
|
|
623
|
+
*/
|
|
624
|
+
private withScope;
|
|
625
|
+
resource(resourceId: ResourceId): CacheObservable<ResourceDescriptor>;
|
|
626
|
+
resources(filters?: ResourceListFilters): CacheObservable<ResourceDescriptor[]>;
|
|
627
|
+
annotations(resourceId: ResourceId): CacheObservable<Annotation[]>;
|
|
628
|
+
annotation(resourceId: ResourceId, annotationId: AnnotationId): CacheObservable<Annotation>;
|
|
629
|
+
entityTypes(): CacheObservable<string[]>;
|
|
630
|
+
tagSchemas(): CacheObservable<TagSchema[]>;
|
|
631
|
+
referencedBy(resourceId: ResourceId): CacheObservable<ReferencedByEntry[]>;
|
|
632
|
+
events(resourceId: ResourceId): CacheObservable<StoredEventResponse[]>;
|
|
633
|
+
resourceContent(resourceId: ResourceId): Promise<string>;
|
|
634
|
+
resourceRepresentation(resourceId: ResourceId, options?: {
|
|
635
|
+
accept?: string;
|
|
636
|
+
}): Promise<{
|
|
637
|
+
data: ArrayBuffer;
|
|
638
|
+
contentType: string;
|
|
639
|
+
}>;
|
|
640
|
+
resourceRepresentationStream(resourceId: ResourceId, options?: {
|
|
641
|
+
accept?: string;
|
|
642
|
+
}): Promise<{
|
|
643
|
+
stream: ReadableStream<Uint8Array>;
|
|
644
|
+
contentType: string;
|
|
645
|
+
}>;
|
|
646
|
+
resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse[]>;
|
|
647
|
+
annotationHistory(resourceId: ResourceId, annotationId: AnnotationId): Promise<AnnotationHistoryResponse>;
|
|
648
|
+
connections(_resourceId: ResourceId): Promise<GraphConnection[]>;
|
|
649
|
+
backlinks(_resourceId: ResourceId): Promise<Annotation[]>;
|
|
650
|
+
resourcesByName(_query: string, _limit?: number): Promise<ResourceDescriptor[]>;
|
|
651
|
+
files(dirPath?: string, sort?: 'name' | 'mtime' | 'annotationCount'): Promise<components['schemas']['BrowseFilesResponse']>;
|
|
652
|
+
click(annotationId: AnnotationId, motivation: Motivation): void;
|
|
653
|
+
navigateReference(resourceId: ResourceId): void;
|
|
654
|
+
invalidateAnnotationList(resourceId: ResourceId): void;
|
|
655
|
+
removeAnnotationDetail(annotationId: AnnotationId): void;
|
|
656
|
+
invalidateResourceDetail(id: ResourceId): void;
|
|
657
|
+
invalidateResourceLists(): void;
|
|
658
|
+
invalidateEntityTypes(): void;
|
|
659
|
+
invalidateTagSchemas(): void;
|
|
660
|
+
invalidateReferencedBy(resourceId: ResourceId): void;
|
|
661
|
+
invalidateResourceEvents(resourceId: ResourceId): void;
|
|
662
|
+
updateAnnotationInPlace(resourceId: ResourceId, annotation: Annotation): void;
|
|
663
|
+
/**
|
|
664
|
+
* Typed shorthand for `eventBus.get(channel).subscribe(handler)`.
|
|
665
|
+
* Preserves per-channel payload typing so handlers read
|
|
666
|
+
* `EventMap[K]` without any casts.
|
|
667
|
+
*/
|
|
668
|
+
private on;
|
|
669
|
+
/**
|
|
670
|
+
* Handler shared by `mark:entity-tag-added` and `mark:entity-tag-removed`.
|
|
671
|
+
* Both events carry the same effect: the annotation list, the
|
|
672
|
+
* resource descriptor, and the event log for that resource all may
|
|
673
|
+
* now reflect different entity tagging, so invalidate all three.
|
|
674
|
+
*/
|
|
675
|
+
private onEntityTagChanged;
|
|
676
|
+
/**
|
|
677
|
+
* Handler shared by `mark:archived` and `mark:unarchived`. Both
|
|
678
|
+
* change a resource's archived flag, which is stored on the resource
|
|
679
|
+
* descriptor and affects the resource-list filter.
|
|
680
|
+
*/
|
|
681
|
+
private onArchiveToggled;
|
|
682
|
+
/**
|
|
683
|
+
* Handler shared by `yield:create-ok` and `yield:update-ok`. Both
|
|
684
|
+
* report a resource mutation with the resourceId as a string (not
|
|
685
|
+
* yet branded), so we brand and apply the same effect as
|
|
686
|
+
* `onArchiveToggled`.
|
|
687
|
+
*/
|
|
688
|
+
private onYieldResourceMutated;
|
|
689
|
+
private subscribeToEvents;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
declare class MarkNamespace implements MarkNamespace$1 {
|
|
693
|
+
private readonly transport;
|
|
694
|
+
private readonly bus;
|
|
695
|
+
constructor(transport: ITransport, bus: EventBus);
|
|
696
|
+
annotation(input: CreateAnnotationInput): Promise<{
|
|
697
|
+
annotationId: AnnotationId;
|
|
698
|
+
}>;
|
|
699
|
+
delete(resourceId: ResourceId, annotationId: AnnotationId): Promise<void>;
|
|
700
|
+
archive(resourceId: ResourceId): Promise<void>;
|
|
701
|
+
unarchive(resourceId: ResourceId): Promise<void>;
|
|
702
|
+
assist(resourceId: ResourceId, motivation: Motivation, options: MarkAssistOptions): StreamObservable<MarkAssistEvent>;
|
|
703
|
+
request(selector: components['schemas']['MarkRequestedEvent']['selector'], motivation: Motivation): void;
|
|
704
|
+
requestAssist(motivation: Motivation, options: MarkAssistOptions, correlationId?: string): void;
|
|
705
|
+
submit(input: components['schemas']['MarkSubmitEvent']): void;
|
|
706
|
+
cancelPending(): void;
|
|
707
|
+
dismissProgress(): void;
|
|
708
|
+
changeSelection(motivation: Motivation | null): void;
|
|
709
|
+
changeClick(action: string): void;
|
|
710
|
+
changeShape(shape: string): void;
|
|
711
|
+
toggleMode(): void;
|
|
712
|
+
private dispatchAssist;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
declare class BindNamespace implements BindNamespace$1 {
|
|
716
|
+
private readonly transport;
|
|
717
|
+
private readonly bus;
|
|
718
|
+
constructor(transport: ITransport, bus: EventBus);
|
|
719
|
+
body(resourceId: ResourceId, annotationId: AnnotationId, operations: BodyOperation[]): Promise<void>;
|
|
720
|
+
initiate(input: EventMap['bind:initiate']): void;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
declare class GatherNamespace implements GatherNamespace$1 {
|
|
724
|
+
private readonly transport;
|
|
725
|
+
private readonly bus;
|
|
726
|
+
constructor(transport: ITransport, bus: EventBus);
|
|
727
|
+
annotation(resourceId: ResourceId, annotationId: AnnotationId, options?: {
|
|
728
|
+
contextWindow?: number;
|
|
729
|
+
}): StreamObservable<GatherAnnotationProgress>;
|
|
730
|
+
resource(_resourceId: ResourceId, _options?: {
|
|
731
|
+
contextWindow?: number;
|
|
732
|
+
}): StreamObservable<GatherAnnotationProgress>;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
declare class MatchNamespace implements MatchNamespace$1 {
|
|
736
|
+
private readonly transport;
|
|
737
|
+
private readonly bus;
|
|
738
|
+
constructor(transport: ITransport, bus: EventBus);
|
|
739
|
+
requestSearch(input: components['schemas']['MatchSearchRequest']): void;
|
|
740
|
+
search(resourceId: ResourceId, referenceId: AnnotationId, context: GatheredContext, options?: {
|
|
741
|
+
limit?: number;
|
|
742
|
+
useSemanticScoring?: boolean;
|
|
743
|
+
}): StreamObservable<MatchSearchProgress>;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
declare class YieldNamespace implements YieldNamespace$1 {
|
|
747
|
+
private readonly transport;
|
|
748
|
+
private readonly bus;
|
|
749
|
+
private readonly content;
|
|
750
|
+
constructor(transport: ITransport, bus: EventBus, content: IContentTransport);
|
|
751
|
+
resource(data: CreateResourceInput): UploadObservable;
|
|
752
|
+
fromAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options: GenerationOptions): StreamObservable<YieldGenerationEvent>;
|
|
753
|
+
cloneToken(resourceId: ResourceId): Promise<{
|
|
754
|
+
token: string;
|
|
755
|
+
expiresAt: string;
|
|
756
|
+
}>;
|
|
757
|
+
fromToken(token: string): Promise<ResourceDescriptor>;
|
|
758
|
+
createFromToken(options: CreateFromTokenOptions): Promise<{
|
|
759
|
+
resourceId: ResourceId;
|
|
760
|
+
}>;
|
|
761
|
+
clone(): void;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
declare class BeckonNamespace implements BeckonNamespace$1 {
|
|
765
|
+
private readonly transport;
|
|
766
|
+
private readonly bus;
|
|
767
|
+
constructor(transport: ITransport, bus: EventBus);
|
|
768
|
+
attention(resourceId: ResourceId, annotationId: AnnotationId): void;
|
|
769
|
+
hover(annotationId: AnnotationId | null): void;
|
|
770
|
+
sparkle(annotationId: AnnotationId): void;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/**
|
|
774
|
+
* FrameNamespace — the eighth flow's surface.
|
|
775
|
+
*
|
|
776
|
+
* Frame operates on the KB's **schema layer** — the conceptual vocabulary
|
|
777
|
+
* the other seven flows are expressed in. Where yield/mark/match/bind/
|
|
778
|
+
* gather/browse/beckon act on content (resources, annotations, references,
|
|
779
|
+
* attention), Frame acts on what *kinds* of things exist: entity types,
|
|
780
|
+
* eventually tag schemas, relation/predicate types, ontology imports.
|
|
781
|
+
*
|
|
782
|
+
* The MVP owns a single primitive — entity-type vocabulary writes on the
|
|
783
|
+
* `frame:add-entity-type` channel. See `docs/protocol/flows/FRAME.md`
|
|
784
|
+
* for the per-flow contract.
|
|
785
|
+
*
|
|
786
|
+
* Live reads of the entity-type vocabulary stay on Browse
|
|
787
|
+
* (`browse.entityTypes()` is a `CacheObservable<string[]>`). Frame owns
|
|
788
|
+
* writes; Browse owns reads. The asymmetry is intentional — re-implementing
|
|
789
|
+
* Browse's cache primitives on Frame for a single read would duplicate
|
|
790
|
+
* machinery without benefit.
|
|
791
|
+
*/
|
|
792
|
+
|
|
793
|
+
declare class FrameNamespace implements FrameNamespace$1 {
|
|
794
|
+
private readonly transport;
|
|
795
|
+
constructor(transport: ITransport);
|
|
796
|
+
addEntityType(type: string): Promise<void>;
|
|
797
|
+
addEntityTypes(types: string[]): Promise<void>;
|
|
798
|
+
addTagSchema(schema: TagSchema): Promise<void>;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
type JobStatusResponse = components['schemas']['JobStatusResponse'];
|
|
802
|
+
declare class JobNamespace implements JobNamespace$1 {
|
|
803
|
+
private readonly transport;
|
|
804
|
+
private readonly bus;
|
|
805
|
+
constructor(transport: ITransport, bus: EventBus);
|
|
806
|
+
/**
|
|
807
|
+
* Live stream of `job:queued` events. Surfaces a typed view onto the
|
|
808
|
+
* underlying bus channel for consumers (CLIs, MCP handlers, widgets)
|
|
809
|
+
* that orchestrate jobs and need to react to lifecycle transitions.
|
|
810
|
+
*/
|
|
811
|
+
get queued$(): Observable<EventMap['job:queued']>;
|
|
812
|
+
/** Live stream of `job:report-progress` events. */
|
|
813
|
+
get progress$(): Observable<EventMap['job:report-progress']>;
|
|
814
|
+
/** Live stream of `job:complete` events (global; filter by `jobId`). */
|
|
815
|
+
get complete$(): Observable<EventMap['job:complete']>;
|
|
816
|
+
/** Live stream of `job:fail` events (global; filter by `jobId`). */
|
|
817
|
+
get fail$(): Observable<EventMap['job:fail']>;
|
|
818
|
+
status(jobId: JobId): Promise<JobStatusResponse>;
|
|
819
|
+
pollUntilComplete(jobId: JobId, options?: {
|
|
820
|
+
interval?: number;
|
|
821
|
+
timeout?: number;
|
|
822
|
+
onProgress?: (status: JobStatusResponse) => void;
|
|
823
|
+
}): Promise<JobStatusResponse>;
|
|
824
|
+
cancelByType(jobType: 'annotation' | 'generation'): Promise<void>;
|
|
825
|
+
cancelRequest(jobType: 'annotation' | 'generation'): void;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/**
|
|
829
|
+
* AuthNamespace — authentication. Backend ops only; no bus.
|
|
830
|
+
*/
|
|
831
|
+
|
|
832
|
+
type AuthResponse = components['schemas']['AuthResponse'];
|
|
833
|
+
type TokenRefreshResponse = components['schemas']['TokenRefreshResponse'];
|
|
834
|
+
declare class AuthNamespace implements AuthNamespace$1 {
|
|
835
|
+
private readonly backend;
|
|
836
|
+
constructor(backend: IBackendOperations);
|
|
837
|
+
password(emailStr: string, passwordStr: string): Promise<AuthResponse>;
|
|
838
|
+
google(credential: string): Promise<AuthResponse>;
|
|
839
|
+
refresh(token: string): Promise<TokenRefreshResponse>;
|
|
840
|
+
logout(): Promise<void>;
|
|
841
|
+
me(): Promise<User>;
|
|
842
|
+
acceptTerms(): Promise<void>;
|
|
843
|
+
mcpToken(): Promise<{
|
|
844
|
+
token: string;
|
|
845
|
+
}>;
|
|
846
|
+
mediaToken(resourceId: ResourceId): Promise<{
|
|
847
|
+
token: string;
|
|
848
|
+
}>;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* AdminNamespace — administration. Backend ops only; no bus.
|
|
853
|
+
*/
|
|
854
|
+
|
|
855
|
+
type AdminUserStatsResponse = components['schemas']['AdminUserStatsResponse'];
|
|
856
|
+
type OAuthConfigResponse = components['schemas']['OAuthConfigResponse'];
|
|
857
|
+
declare class AdminNamespace implements AdminNamespace$1 {
|
|
858
|
+
private readonly backend;
|
|
859
|
+
constructor(backend: IBackendOperations);
|
|
860
|
+
users(): Promise<User[]>;
|
|
861
|
+
userStats(): Promise<AdminUserStatsResponse>;
|
|
862
|
+
updateUser(userId: UserDID, data: RequestContent<paths['/api/admin/users/{id}']['patch']>): Promise<User>;
|
|
863
|
+
oauthConfig(): Promise<OAuthConfigResponse>;
|
|
864
|
+
healthCheck(): Promise<ResponseContent<paths['/api/health']['get']>>;
|
|
865
|
+
status(): Promise<ResponseContent<paths['/api/status']['get']>>;
|
|
866
|
+
backup(): Promise<BackendDownload>;
|
|
867
|
+
restore(file: File): StreamObservable<ProgressEvent>;
|
|
868
|
+
exportKnowledgeBase(params?: {
|
|
869
|
+
includeArchived?: boolean;
|
|
870
|
+
}): Promise<BackendDownload>;
|
|
871
|
+
importKnowledgeBase(file: File): StreamObservable<ProgressEvent>;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
declare class SemiontClient {
|
|
875
|
+
/**
|
|
876
|
+
* The wire-facing transport. Owns bus actor, HTTP, auth, admin, exchange,
|
|
877
|
+
* system. Exposed for advanced consumers (workers, custom job adapters)
|
|
878
|
+
* that need raw `transport.emit(channel, payload, scope)` access. Ordinary
|
|
879
|
+
* consumers go through typed namespace methods.
|
|
880
|
+
*/
|
|
881
|
+
readonly transport: ITransport;
|
|
882
|
+
/** Binary I/O transport. */
|
|
883
|
+
private readonly content;
|
|
884
|
+
/**
|
|
885
|
+
* Per-client local EventBus. Wire events flow in via the transport
|
|
886
|
+
* bridge. Read-only public so `SemiontSession.subscribe(channel, …)`
|
|
887
|
+
* can wire arbitrary-channel subscriptions; everything else uses
|
|
888
|
+
* typed namespace methods.
|
|
889
|
+
*/
|
|
890
|
+
readonly bus: EventBus;
|
|
891
|
+
readonly baseUrl: BaseUrl;
|
|
892
|
+
readonly frame: FrameNamespace;
|
|
893
|
+
readonly browse: BrowseNamespace;
|
|
894
|
+
readonly mark: MarkNamespace;
|
|
895
|
+
readonly bind: BindNamespace;
|
|
896
|
+
readonly gather: GatherNamespace;
|
|
897
|
+
readonly match: MatchNamespace;
|
|
898
|
+
readonly yield: YieldNamespace;
|
|
899
|
+
readonly beckon: BeckonNamespace;
|
|
900
|
+
readonly job: JobNamespace;
|
|
901
|
+
readonly auth: AuthNamespace | undefined;
|
|
902
|
+
readonly admin: AdminNamespace | undefined;
|
|
903
|
+
/**
|
|
904
|
+
* The client *owns* its bus. The constructor creates a fresh `EventBus`
|
|
905
|
+
* and hands it to the transport via `transport.bridgeInto(this.bus)`.
|
|
906
|
+
* The reference flows client → transport, never the other way:
|
|
907
|
+
* the transport stores the reference and publishes the events it
|
|
908
|
+
* receives onto that bus. `HttpTransport` does so for every channel
|
|
909
|
+
* delivered on its SSE wire; in-process transports adapt their
|
|
910
|
+
* internal source.
|
|
911
|
+
*
|
|
912
|
+
* Callers do not pass a bus in. If they need to interact with the bus
|
|
913
|
+
* (e.g. for tests or to subscribe to arbitrary channels), they read it
|
|
914
|
+
* back via `client.bus`.
|
|
915
|
+
*
|
|
916
|
+
* `backend` is optional. When provided, the `auth` and `admin`
|
|
917
|
+
* namespaces are constructed against it; when omitted, they're
|
|
918
|
+
* `undefined`. For HTTP setups this is conventionally the same
|
|
919
|
+
* `HttpTransport` instance that's also passed as `transport` (HTTP
|
|
920
|
+
* implements both `ITransport` and `IBackendOperations`).
|
|
921
|
+
*/
|
|
922
|
+
constructor(transport: ITransport, content: IContentTransport, backend?: IBackendOperations);
|
|
923
|
+
/** Transport-level connection state. HTTP reflects SSE health; local is always 'connected'. */
|
|
924
|
+
get state$(): rxjs.Observable<_semiont_core.ConnectionState>;
|
|
925
|
+
dispose(): void;
|
|
926
|
+
/**
|
|
927
|
+
* Convenience factory for the default HTTP setup. Constructs a
|
|
928
|
+
* `BehaviorSubject<AccessToken | null>` internally, plus an
|
|
929
|
+
* `HttpTransport` and `HttpContentTransport`, and returns the wired
|
|
930
|
+
* `SemiontClient`.
|
|
931
|
+
*
|
|
932
|
+
* Use this for one-shot scripts, CLI commands, or any consumer that
|
|
933
|
+
* doesn't need to drive the token from outside (no manual refresh,
|
|
934
|
+
* no cross-tab sync). For long-running scripts that need refresh,
|
|
935
|
+
* use `SemiontSession.fromHttp(...)` (with a token already on hand)
|
|
936
|
+
* or `SemiontSession.signInHttp(...)` (credentials-first) instead —
|
|
937
|
+
* either owns the same transport/client wiring plus the
|
|
938
|
+
* proactive-refresh + storage machinery.
|
|
939
|
+
*
|
|
940
|
+
* Strings are accepted for `baseUrl` and `token`; they are branded
|
|
941
|
+
* via `baseUrl()` / `accessToken()` from `@semiont/core` automatically.
|
|
942
|
+
* Pass the already-branded values if you have them.
|
|
943
|
+
*
|
|
944
|
+
* Omit `token` for unauthenticated usage (public endpoints only).
|
|
945
|
+
*/
|
|
946
|
+
static fromHttp(opts: {
|
|
947
|
+
baseUrl: BaseUrl | string;
|
|
948
|
+
token?: AccessToken | string | null;
|
|
949
|
+
}): SemiontClient;
|
|
950
|
+
/**
|
|
951
|
+
* Async factory for the credentials-first script case. Builds a
|
|
952
|
+
* transient HTTP transport, calls `auth.password(email, password)`
|
|
953
|
+
* to acquire an access token, and returns the wired client with
|
|
954
|
+
* the token populated.
|
|
955
|
+
*
|
|
956
|
+
* This is the right entry point for skills, CLI scripts, and any
|
|
957
|
+
* consumer that starts with email + password rather than a JWT
|
|
958
|
+
* already on hand. For consumers that already hold a token (CLI
|
|
959
|
+
* cached-token path, env-var token, embedded auth flow), use
|
|
960
|
+
* `fromHttp({ baseUrl, token })` instead.
|
|
961
|
+
*
|
|
962
|
+
* For long-running scripts that need refresh, use
|
|
963
|
+
* `SemiontSession.signInHttp(...)` — same credentials shape, plus
|
|
964
|
+
* the session machinery for proactive refresh and persistence.
|
|
965
|
+
*
|
|
966
|
+
* Named `signInHttp` because email+password authentication is
|
|
967
|
+
* inherently an HTTP-shaped operation in the current backend; an
|
|
968
|
+
* in-process `LocalTransport` doesn't have a credentials login
|
|
969
|
+
* path. Non-HTTP transports construct the client directly from
|
|
970
|
+
* their package's transport instance.
|
|
971
|
+
*
|
|
972
|
+
* Throws if authentication fails. The transient client is disposed
|
|
973
|
+
* before the throw, so no resources leak on failure.
|
|
974
|
+
*/
|
|
975
|
+
static signInHttp(opts: {
|
|
976
|
+
baseUrl: BaseUrl | string;
|
|
977
|
+
email: string;
|
|
978
|
+
password: string;
|
|
979
|
+
}): Promise<SemiontClient>;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
type BusRequestErrorCode = 'bus.timeout' | 'bus.rejected' | 'bus.bad-payload' | 'bus.unauthorized' | 'bus.forbidden' | 'bus.not-found';
|
|
983
|
+
declare class BusRequestError extends SemiontError {
|
|
984
|
+
code: BusRequestErrorCode;
|
|
985
|
+
constructor(message: string, code: BusRequestErrorCode, details?: Record<string, unknown>);
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Subset of ITransport that `busRequest` needs: a way to send a command and
|
|
989
|
+
* a way to observe channels. Generic enough that an in-process transport
|
|
990
|
+
* can satisfy it without round-tripping through HTTP.
|
|
991
|
+
*/
|
|
992
|
+
interface BusRequestPrimitive {
|
|
993
|
+
emit<K extends keyof EventMap>(channel: K, payload: EventMap[K]): Promise<void>;
|
|
994
|
+
stream<K extends keyof EventMap>(channel: K): Observable<EventMap[K]>;
|
|
995
|
+
}
|
|
996
|
+
declare function busRequest<TResult>(bus: BusRequestPrimitive, emitChannel: string, payload: Record<string, unknown>, resultChannel: string, failureChannel: string, timeoutMs?: number): Promise<TResult>;
|
|
997
|
+
|
|
998
|
+
/**
|
|
999
|
+
* KnowledgeBase — a connection to a Semiont knowledge system.
|
|
1000
|
+
*
|
|
1001
|
+
* The KB type itself is uniform. The transport-shape variation lives in
|
|
1002
|
+
* the nested `endpoint` field, which is a discriminated union:
|
|
1003
|
+
*
|
|
1004
|
+
* - `endpoint.kind === 'http'` — a remote backend reached over HTTP+SSE.
|
|
1005
|
+
* Carries `host`/`port`/`protocol`.
|
|
1006
|
+
* - `endpoint.kind === 'local'` — an in-process knowledge system reached
|
|
1007
|
+
* via `LocalTransport` from
|
|
1008
|
+
* `@semiont/make-meaning`. Carries an
|
|
1009
|
+
* opaque `kbId` identifying the local
|
|
1010
|
+
* instance to the host process.
|
|
1011
|
+
*
|
|
1012
|
+
* Code that doesn't know how to make a transport (`SemiontSession`,
|
|
1013
|
+
* `SemiontBrowser`, the frontend KB list UI) treats `KnowledgeBase` as
|
|
1014
|
+
* uniform and never inspects `endpoint`. Code that *does* construct
|
|
1015
|
+
* transports (the transport-factory passed to `SemiontBrowser`,
|
|
1016
|
+
* `kbBackendUrl` for HTTP URL construction) inspects `endpoint.kind`
|
|
1017
|
+
* and dispatches.
|
|
1018
|
+
*
|
|
1019
|
+
* Each KB has its own session, its own credentials (where applicable),
|
|
1020
|
+
* and its own JWT (HTTP only). The user is "authenticated against KB X" —
|
|
1021
|
+
* never globally authenticated.
|
|
1022
|
+
*/
|
|
1023
|
+
/** Fields shared by every KB regardless of endpoint kind. */
|
|
1024
|
+
interface KnowledgeBase {
|
|
1025
|
+
id: string;
|
|
1026
|
+
label: string;
|
|
1027
|
+
email: string;
|
|
1028
|
+
gitBranch?: string;
|
|
1029
|
+
endpoint: KbEndpoint;
|
|
1030
|
+
}
|
|
1031
|
+
type KbEndpoint = HttpEndpoint | LocalEndpoint;
|
|
1032
|
+
interface HttpEndpoint {
|
|
1033
|
+
kind: 'http';
|
|
1034
|
+
host: string;
|
|
1035
|
+
port: number;
|
|
1036
|
+
protocol: 'http' | 'https';
|
|
1037
|
+
}
|
|
1038
|
+
interface LocalEndpoint {
|
|
1039
|
+
kind: 'local';
|
|
1040
|
+
/** Opaque identifier for the in-process KB instance the host has loaded. */
|
|
1041
|
+
kbId: string;
|
|
1042
|
+
}
|
|
1043
|
+
/**
|
|
1044
|
+
* Input shape for adding a new KB. The id is generated by the provider.
|
|
1045
|
+
*/
|
|
1046
|
+
type NewKnowledgeBase = Omit<KnowledgeBase, 'id'>;
|
|
1047
|
+
/**
|
|
1048
|
+
* Status of the locally-stored credential for a KB. Derived from the
|
|
1049
|
+
* presence and validity of the JWT in session storage.
|
|
1050
|
+
*/
|
|
1051
|
+
type KbSessionStatus = 'authenticated' | 'expired' | 'signed-out' | 'unreachable';
|
|
1052
|
+
/**
|
|
1053
|
+
* Construct a `KnowledgeBase` for an HTTP-backed Semiont backend without
|
|
1054
|
+
* spelling out the nested `endpoint` literal. Convenience for tests,
|
|
1055
|
+
* worker bootstraps, and one-off scripts.
|
|
20
1056
|
*
|
|
21
1057
|
* ```ts
|
|
22
|
-
*
|
|
23
|
-
*
|
|
1058
|
+
* const kb = httpKb({
|
|
1059
|
+
* id: 'my-watcher',
|
|
1060
|
+
* label: 'My Watcher',
|
|
1061
|
+
* email: 'me@example.com',
|
|
1062
|
+
* host: 'localhost',
|
|
1063
|
+
* port: 4000,
|
|
1064
|
+
* protocol: 'http',
|
|
1065
|
+
* });
|
|
1066
|
+
* ```
|
|
1067
|
+
*
|
|
1068
|
+
* Equivalent to:
|
|
24
1069
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
1070
|
+
* ```ts
|
|
1071
|
+
* const kb: KnowledgeBase = {
|
|
1072
|
+
* id, label, email,
|
|
1073
|
+
* endpoint: { kind: 'http', host, port, protocol },
|
|
1074
|
+
* };
|
|
29
1075
|
* ```
|
|
1076
|
+
*
|
|
1077
|
+
* UI hosts that have a structured form (host / port / protocol pickers)
|
|
1078
|
+
* already construct the literal directly — they don't need this helper.
|
|
1079
|
+
* Local-endpoint KBs construct the literal directly too; the local
|
|
1080
|
+
* endpoint shape (`{ kind: 'local', kbId }`) is one line and doesn't
|
|
1081
|
+
* earn a helper.
|
|
30
1082
|
*/
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
1083
|
+
declare function httpKb(opts: {
|
|
1084
|
+
id: string;
|
|
1085
|
+
label: string;
|
|
1086
|
+
email: string;
|
|
1087
|
+
host: string;
|
|
1088
|
+
port: number;
|
|
1089
|
+
protocol: 'http' | 'https';
|
|
1090
|
+
gitBranch?: string;
|
|
1091
|
+
}): KnowledgeBase;
|
|
1092
|
+
|
|
1093
|
+
/**
|
|
1094
|
+
* Session-level error surface. Emitted on `SemiontBrowser.error$` for
|
|
1095
|
+
* failures that make the session itself unusable (auth failed, actor
|
|
1096
|
+
* couldn't start, token refresh terminally exhausted). Per-request
|
|
1097
|
+
* errors stay with the caller as normal Promise rejections.
|
|
1098
|
+
*
|
|
1099
|
+
* `SemiontSessionError` extends `SemiontError` (the unified Semiont base)
|
|
1100
|
+
* so consumers can catch with `instanceof SemiontError` for any error
|
|
1101
|
+
* surfaced through the SDK.
|
|
1102
|
+
*/
|
|
1103
|
+
|
|
1104
|
+
type SemiontSessionErrorCode = 'session.construct-failed' | 'session.auth-failed' | 'session.refresh-exhausted' | 'browser.sign-in-failed';
|
|
1105
|
+
declare class SemiontSessionError extends SemiontError {
|
|
1106
|
+
code: SemiontSessionErrorCode;
|
|
1107
|
+
readonly kbId: string | null;
|
|
1108
|
+
constructor(code: SemiontSessionErrorCode, message: string, kbId?: string | null);
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
/**
|
|
1112
|
+
* SessionStorage — environment-agnostic persistence adapter for the
|
|
1113
|
+
* Semiont session layer. Decouples `SemiontSession` / `SemiontBrowser`
|
|
1114
|
+
* from `localStorage` / `window` so the same classes can run in a
|
|
1115
|
+
* browser, a CLI process, or tests without environment guards.
|
|
1116
|
+
*
|
|
1117
|
+
* Implementations shipped here:
|
|
1118
|
+
* - `InMemorySessionStorage` — map-backed, for tests.
|
|
1119
|
+
*
|
|
1120
|
+
* Browser-backed (`WebBrowserStorage`) lives in `@semiont/react-ui`
|
|
1121
|
+
* because it touches browser-only globals.
|
|
1122
|
+
*/
|
|
1123
|
+
/** String key/value store with optional cross-context change subscription. */
|
|
1124
|
+
interface SessionStorage {
|
|
1125
|
+
/** Read a string value; null if absent. */
|
|
1126
|
+
get(key: string): string | null;
|
|
1127
|
+
/** Write a string value. */
|
|
1128
|
+
set(key: string, value: string): void;
|
|
1129
|
+
/** Remove a key. No-op if absent. */
|
|
1130
|
+
delete(key: string): void;
|
|
1131
|
+
/**
|
|
1132
|
+
* Optional: subscribe to external changes (cross-tab, cross-process).
|
|
1133
|
+
* Browser implements via the `storage` event; filesystem would use
|
|
1134
|
+
* fs.watch; in-memory omits this method. Returns an unsubscribe
|
|
1135
|
+
* callback. If omitted, cross-context sync simply isn't available
|
|
1136
|
+
* in that environment — the session still works correctly within a
|
|
1137
|
+
* single process.
|
|
1138
|
+
*/
|
|
1139
|
+
subscribe?(handler: (key: string, newValue: string | null) => void): () => void;
|
|
1140
|
+
}
|
|
1141
|
+
/**
|
|
1142
|
+
* Map-backed `SessionStorage`. Cross-context sync is not implemented;
|
|
1143
|
+
* tests that need it can drive it manually.
|
|
1144
|
+
*/
|
|
1145
|
+
declare class InMemorySessionStorage implements SessionStorage {
|
|
1146
|
+
private readonly map;
|
|
1147
|
+
get(key: string): string | null;
|
|
1148
|
+
set(key: string, value: string): void;
|
|
1149
|
+
delete(key: string): void;
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
/**
|
|
1153
|
+
* SemiontSession — per-backend session lifetime object. Owns the
|
|
1154
|
+
* SemiontClient, the access token BehaviorSubject, and optionally
|
|
1155
|
+
* an authenticated user. One SemiontSession exists per active backend
|
|
1156
|
+
* connection; lifetime is decoupled from React mount lifetime.
|
|
1157
|
+
*
|
|
1158
|
+
* Headless by design. Runs in browsers, CLIs, workers, and tests.
|
|
1159
|
+
* UI-specific state (session-expired/permission-denied modals) lives
|
|
1160
|
+
* in `SessionSignals`, which wraps a session — the session
|
|
1161
|
+
* itself has no modal observables, no user-facing notifications.
|
|
1162
|
+
*
|
|
1163
|
+
* Auth is parameterized via callbacks passed at construction:
|
|
1164
|
+
*
|
|
1165
|
+
* - `refresh()` — invoked on 401 / proactive re-auth. Returns the
|
|
1166
|
+
* new access token, or null on failure. The frontend passes a
|
|
1167
|
+
* closure that runs the refresh-token flow; the worker passes
|
|
1168
|
+
* one that exchanges the shared secret.
|
|
1169
|
+
*
|
|
1170
|
+
* - `validate(token)` — optional. If provided, the session calls
|
|
1171
|
+
* it once at startup with the stored token to confirm it's
|
|
1172
|
+
* still good and populate `user$`. Frontend passes `getMe`;
|
|
1173
|
+
* worker omits this (service principals have no user record).
|
|
1174
|
+
*
|
|
1175
|
+
* - `onAuthFailed(message)` — optional. Invoked when refresh
|
|
1176
|
+
* terminally fails (expired token, no recovery possible). UI hosts
|
|
1177
|
+
* typically wire this to `SessionSignals.notifySessionExpired` so a
|
|
1178
|
+
* modal surfaces; headless consumers typically just log.
|
|
1179
|
+
*
|
|
1180
|
+
* Persistence goes through a `SessionStorage` adapter provided at
|
|
1181
|
+
* construction — the session never touches `localStorage` or `window`
|
|
1182
|
+
* directly.
|
|
1183
|
+
*/
|
|
1184
|
+
|
|
1185
|
+
type UserInfo = components['schemas']['UserResponse'];
|
|
1186
|
+
interface SemiontSessionConfig {
|
|
1187
|
+
kb: KnowledgeBase;
|
|
1188
|
+
/** Persistence adapter. Reads/writes tokens via this. */
|
|
1189
|
+
storage: SessionStorage;
|
|
1190
|
+
/**
|
|
1191
|
+
* Pre-built api client. The session does not construct it — caller
|
|
1192
|
+
* builds the transport stack and passes the client in. This is the
|
|
1193
|
+
* seam where consumers swap one `ITransport` implementation for
|
|
1194
|
+
* another (HTTP, in-process, etc.).
|
|
1195
|
+
*/
|
|
1196
|
+
client: SemiontClient;
|
|
1197
|
+
/**
|
|
1198
|
+
* Token observable shared with the transport. Caller must pass the
|
|
1199
|
+
* SAME instance to both the transport (via `HttpTransport` config)
|
|
1200
|
+
* and the session. The session writes refreshed tokens here; the
|
|
1201
|
+
* transport reads from here.
|
|
1202
|
+
*/
|
|
1203
|
+
token$: BehaviorSubject<AccessToken | null>;
|
|
1204
|
+
/**
|
|
1205
|
+
* Re-authenticate after expiry / 401. Returns a new access token
|
|
1206
|
+
* (no "Bearer " prefix) on success, or null if recovery is
|
|
1207
|
+
* impossible. Omit for transports where tokens don't apply.
|
|
1208
|
+
*/
|
|
1209
|
+
refresh?: () => Promise<string | null>;
|
|
1210
|
+
/**
|
|
1211
|
+
* Validate the stored token at startup and populate `user$`. Omit
|
|
1212
|
+
* for service-principal sessions (worker, CLI tools) where there
|
|
1213
|
+
* is no user record to fetch.
|
|
1214
|
+
*/
|
|
1215
|
+
validate?: (token: AccessToken) => Promise<UserInfo | null>;
|
|
1216
|
+
/**
|
|
1217
|
+
* Invoked when refresh terminally fails. Frontend consumers wire
|
|
1218
|
+
* this to a UI signal that surfaces the session-expired modal.
|
|
1219
|
+
*/
|
|
1220
|
+
onAuthFailed?: (message: string | null) => void;
|
|
1221
|
+
/** Called for session-level failures (auth, refresh exhaustion). */
|
|
1222
|
+
onError?: (err: SemiontSessionError) => void;
|
|
1223
|
+
}
|
|
1224
|
+
declare class SemiontSession {
|
|
1225
|
+
readonly kb: KnowledgeBase;
|
|
1226
|
+
readonly client: SemiontClient;
|
|
1227
|
+
readonly token$: BehaviorSubject<AccessToken | null>;
|
|
1228
|
+
readonly user$: BehaviorSubject<UserInfo | null>;
|
|
1229
|
+
readonly streamState$: Observable<ConnectionState>;
|
|
1230
|
+
/**
|
|
1231
|
+
* Stream of `SemiontError` instances surfaced by the underlying transport
|
|
1232
|
+
* just before they're thrown to the caller. For `HttpTransport` this is
|
|
1233
|
+
* an `APIError` (status-coded); other transports emit their own subclass.
|
|
1234
|
+
* Surfaced here so a host layer (e.g. `SemiontBrowser`) can route by
|
|
1235
|
+
* `err.code` to global notifications without every call site handling
|
|
1236
|
+
* errors itself. Headless consumers can subscribe for logging.
|
|
1237
|
+
*
|
|
1238
|
+
* Re-published from `client.transport.errors$` per the `ITransport`
|
|
1239
|
+
* contract — the session is purely a passthrough.
|
|
1240
|
+
*/
|
|
1241
|
+
readonly errors$: Observable<SemiontError>;
|
|
1242
|
+
/** Resolves after the initial validation round-trip completes (success or failure). */
|
|
1243
|
+
readonly ready: Promise<void>;
|
|
1244
|
+
private readonly storage;
|
|
1245
|
+
private readonly doRefresh?;
|
|
1246
|
+
private readonly doValidate?;
|
|
1247
|
+
private readonly onAuthFailed;
|
|
1248
|
+
private readonly onError;
|
|
1249
|
+
private refreshTimer;
|
|
1250
|
+
private unsubscribeStorage;
|
|
1251
|
+
private disposed;
|
|
1252
|
+
constructor(config: SemiontSessionConfig);
|
|
1253
|
+
/**
|
|
1254
|
+
* Run the initial mount-time validation. If a stored access token is
|
|
1255
|
+
* present and unexpired, call the configured `validate` with it to
|
|
1256
|
+
* confirm it still works and populate `user$`. If expired, try
|
|
1257
|
+
* refresh first. On 401 from validate, try refresh once. Surfaces
|
|
1258
|
+
* auth-failed on terminal failure.
|
|
1259
|
+
*
|
|
1260
|
+
* When no `validate` callback is provided (service principals), this
|
|
1261
|
+
* still runs through the refresh-if-expired step so the stored
|
|
1262
|
+
* token is current — it just skips the user-validation round trip.
|
|
1263
|
+
*/
|
|
1264
|
+
private validate;
|
|
1265
|
+
/**
|
|
1266
|
+
* Refresh the access token via the configured `refresh` callback.
|
|
1267
|
+
* On success, pushes the new token into `token$` and schedules the
|
|
1268
|
+
* next proactive refresh. On failure, clears persisted state and
|
|
1269
|
+
* fires `onAuthFailed` — the frontend's wiring of that callback is
|
|
1270
|
+
* what surfaces the session-expired modal.
|
|
1271
|
+
*/
|
|
1272
|
+
refresh(): Promise<AccessToken | null>;
|
|
1273
|
+
private scheduleProactiveRefresh;
|
|
1274
|
+
private clearRefreshTimer;
|
|
1275
|
+
/**
|
|
1276
|
+
* Cross-context sync: another tab/process refreshed or signed out this
|
|
1277
|
+
* KB. Mirror the change into our in-memory state.
|
|
1278
|
+
*/
|
|
1279
|
+
private handleStorageChange;
|
|
1280
|
+
get expiresAt(): Date | null;
|
|
1281
|
+
/**
|
|
1282
|
+
* Subscribe to a session-bus channel. The single sanctioned escape hatch
|
|
1283
|
+
* for generic-channel subscription (the case `useEventSubscription` needs
|
|
1284
|
+
* — channel name is a hook parameter, not known statically). All other
|
|
1285
|
+
* consumers must call typed namespace methods (e.g. `session.client.mark.archive(...)`).
|
|
1286
|
+
*
|
|
1287
|
+
* @returns disposer that unsubscribes the handler.
|
|
1288
|
+
*/
|
|
1289
|
+
subscribe<K extends keyof EventMap>(channel: K, handler: (payload: EventMap[K]) => void): () => void;
|
|
1290
|
+
dispose(): Promise<void>;
|
|
1291
|
+
/**
|
|
1292
|
+
* Convenience factory for the default HTTP setup. Constructs the
|
|
1293
|
+
* shared `BehaviorSubject<AccessToken | null>`, an `HttpTransport`,
|
|
1294
|
+
* an `HttpContentTransport`, and a `SemiontClient`, then wires
|
|
1295
|
+
* the session over them. Removes the load-bearing
|
|
1296
|
+
* "same-token$-instance" invariant from the caller's hands.
|
|
1297
|
+
*
|
|
1298
|
+
* Strings are accepted for `baseUrl` and `token`; they are branded
|
|
1299
|
+
* via `baseUrl()` / `accessToken()` from `@semiont/core` automatically.
|
|
1300
|
+
*
|
|
1301
|
+
* The remaining options (`refresh`, `validate`, `onAuthFailed`,
|
|
1302
|
+
* `onError`) match `SemiontSessionConfig` exactly.
|
|
1303
|
+
*/
|
|
1304
|
+
static fromHttp(opts: {
|
|
1305
|
+
kb: KnowledgeBase;
|
|
1306
|
+
storage: SessionStorage;
|
|
1307
|
+
baseUrl: BaseUrl | string;
|
|
1308
|
+
token?: AccessToken | string | null;
|
|
1309
|
+
refresh?: () => Promise<string | null>;
|
|
1310
|
+
validate?: (token: AccessToken) => Promise<UserInfo | null>;
|
|
1311
|
+
onAuthFailed?: (message: string | null) => void;
|
|
1312
|
+
onError?: (err: SemiontSessionError) => void;
|
|
1313
|
+
}): SemiontSession;
|
|
1314
|
+
/**
|
|
1315
|
+
* Async factory for the credentials-first long-running script case.
|
|
1316
|
+
* Builds the HTTP transport stack, calls `auth.password(email,
|
|
1317
|
+
* password)` to acquire access + refresh tokens, persists them via
|
|
1318
|
+
* the storage adapter, wires a default `refresh` callback that
|
|
1319
|
+
* exchanges the refresh token via `auth.refresh(...)`, and returns
|
|
1320
|
+
* the ready session.
|
|
1321
|
+
*
|
|
1322
|
+
* The consumer-supplied `refresh` callback becomes optional — only
|
|
1323
|
+
* needed for non-standard refresh flows (worker-pool shared secret,
|
|
1324
|
+
* OAuth refresh-token grant, interactive re-prompt). The default
|
|
1325
|
+
* uses the refresh token returned by `auth.password`.
|
|
1326
|
+
*
|
|
1327
|
+
* `kb` is required and must be a full `KnowledgeBase`. The `id` field
|
|
1328
|
+
* is the storage key for this session — distinct scripts sharing the
|
|
1329
|
+
* same `SessionStorage` instance must use distinct ids to avoid
|
|
1330
|
+
* trampling each other's tokens. The factory does not synthesize a
|
|
1331
|
+
* default; the consumer makes the choice.
|
|
1332
|
+
*
|
|
1333
|
+
* Named `signInHttp` because email+password authentication is
|
|
1334
|
+
* inherently an HTTP-shaped operation in the current backend; an
|
|
1335
|
+
* in-process `LocalTransport` doesn't have a credentials login
|
|
1336
|
+
* path. Non-HTTP transports construct the session directly from
|
|
1337
|
+
* their package's transport instance.
|
|
1338
|
+
*
|
|
1339
|
+
* Throws on auth failure with no resources leaked. On success, the
|
|
1340
|
+
* returned session's `ready` promise has already resolved.
|
|
1341
|
+
*/
|
|
1342
|
+
static signInHttp(opts: {
|
|
1343
|
+
kb: KnowledgeBase;
|
|
1344
|
+
storage: SessionStorage;
|
|
1345
|
+
baseUrl: BaseUrl | string;
|
|
1346
|
+
email: string;
|
|
1347
|
+
password: string;
|
|
1348
|
+
validate?: (token: AccessToken) => Promise<UserInfo | null>;
|
|
1349
|
+
onAuthFailed?: (message: string | null) => void;
|
|
1350
|
+
onError?: (err: SemiontSessionError) => void;
|
|
1351
|
+
}): Promise<SemiontSession>;
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
/**
|
|
1355
|
+
* OpenResource — a single entry in the open-resources list (tabs).
|
|
1356
|
+
*
|
|
1357
|
+
* The list itself lives on `SemiontBrowser.openResources$`. The CRUD
|
|
1358
|
+
* methods (`addOpenResource`, `removeOpenResource`, `updateOpenResourceName`,
|
|
1359
|
+
* `reorderOpenResources`) live on `SemiontBrowser` too.
|
|
1360
|
+
*/
|
|
1361
|
+
interface OpenResource {
|
|
1362
|
+
/** Unique identifier for the resource */
|
|
1363
|
+
id: string;
|
|
1364
|
+
/** Display name of the resource */
|
|
1365
|
+
name: string;
|
|
1366
|
+
/** Timestamp when the resource was opened */
|
|
1367
|
+
openedAt: number;
|
|
1368
|
+
/** Order/position for manual sorting (optional for backward compatibility) */
|
|
1369
|
+
order?: number;
|
|
1370
|
+
/** Media type for icon display (e.g., 'application/pdf', 'text/plain') */
|
|
1371
|
+
mediaType?: string;
|
|
1372
|
+
/** Working-tree URI (e.g. "file://docs/overview.md") — used as tooltip in navigation */
|
|
1373
|
+
storageUri?: string;
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
/**
|
|
1377
|
+
* SessionSignals — UI-facing notification state that belongs to the host
|
|
1378
|
+
* surface, not to the session itself.
|
|
1379
|
+
*
|
|
1380
|
+
* `SemiontSession` is a headless per-backend client + token + user
|
|
1381
|
+
* holder. It can run in any process: browser, worker, CLI, test. But
|
|
1382
|
+
* the session-expired / permission-denied *notifications* are inherently
|
|
1383
|
+
* a UI-host concern. Keeping those observables on `SemiontSession` meant
|
|
1384
|
+
* workers and CLIs carried four dead BehaviorSubjects that nothing would
|
|
1385
|
+
* ever fire.
|
|
1386
|
+
*
|
|
1387
|
+
* `SessionSignals` owns the notification state and has no hard reference
|
|
1388
|
+
* to a session. A UI host (e.g. `SemiontBrowser`) constructs one alongside
|
|
1389
|
+
* every active session and wires:
|
|
1390
|
+
*
|
|
1391
|
+
* - `session.onAuthFailed` → `signals.notifySessionExpired` so
|
|
1392
|
+
* proactive-refresh failures surface as a notification
|
|
1393
|
+
*
|
|
1394
|
+
* UI consumers that need to render modal/banner state subscribe here;
|
|
1395
|
+
* consumers that need bus/HTTP access continue to subscribe to the session.
|
|
1396
|
+
*
|
|
1397
|
+
* Session auth-state cleanup (clearing token, clearing storage) is
|
|
1398
|
+
* the session's own responsibility inside `refresh()` — by the time
|
|
1399
|
+
* `notifySessionExpired` runs, the session has already torn down.
|
|
1400
|
+
* Signals only surfaces the notification.
|
|
1401
|
+
*/
|
|
1402
|
+
|
|
1403
|
+
declare class SessionSignals {
|
|
1404
|
+
readonly sessionExpiredAt$: BehaviorSubject<number | null>;
|
|
1405
|
+
readonly sessionExpiredMessage$: BehaviorSubject<string | null>;
|
|
1406
|
+
readonly permissionDeniedAt$: BehaviorSubject<number | null>;
|
|
1407
|
+
readonly permissionDeniedMessage$: BehaviorSubject<string | null>;
|
|
1408
|
+
constructor();
|
|
1409
|
+
notifySessionExpired(message: string | null): void;
|
|
1410
|
+
notifyPermissionDenied(message: string | null): void;
|
|
1411
|
+
acknowledgeSessionExpired(): void;
|
|
1412
|
+
acknowledgePermissionDenied(): void;
|
|
1413
|
+
dispose(): void;
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
/**
|
|
1417
|
+
* SessionFactory — the injection point that lets `SemiontBrowser` stay
|
|
1418
|
+
* transport-agnostic.
|
|
1419
|
+
*
|
|
1420
|
+
* The browser knows how to manage the *lifecycle* of an active session
|
|
1421
|
+
* (track it in `activeSession$`, dispose on KB switch, serialize
|
|
1422
|
+
* overlapping activations) but does not know how to *construct* one —
|
|
1423
|
+
* because that's where transport choice lives. The construction step
|
|
1424
|
+
* is parameterized via this factory.
|
|
1425
|
+
*
|
|
1426
|
+
* The HTTP factory is provided by `createHttpSessionFactory`. A
|
|
1427
|
+
* future in-process variant from `@semiont/make-meaning` would expose
|
|
1428
|
+
* its own factory.
|
|
1429
|
+
*/
|
|
1430
|
+
|
|
1431
|
+
interface SessionFactoryOptions {
|
|
1432
|
+
/** The KB the session is being constructed for. */
|
|
1433
|
+
kb: KnowledgeBase;
|
|
1434
|
+
/** Persistence adapter — same one the browser uses. */
|
|
1435
|
+
storage: SessionStorage;
|
|
1436
|
+
/** Modal-signal sink for auth-failed / permission-denied notifications. */
|
|
1437
|
+
signals: SessionSignals;
|
|
1438
|
+
/** Receives session-level errors (auth-failed, refresh-exhausted, ...). */
|
|
1439
|
+
onError: (err: SemiontSessionError) => void;
|
|
1440
|
+
}
|
|
1441
|
+
type SessionFactory = (opts: SessionFactoryOptions) => SemiontSession;
|
|
1442
|
+
|
|
1443
|
+
/**
|
|
1444
|
+
* SemiontBrowser — top-level app-facing container for non-KB state.
|
|
1445
|
+
*
|
|
1446
|
+
* Holds the list of configured KBs, the active KB selection, the active
|
|
1447
|
+
* SemiontSession, the identity token, the open-resources list, and a
|
|
1448
|
+
* session-level error stream. Held as a process-wide instance for the
|
|
1449
|
+
* host's lifetime — see `getBrowser()` in `registry.ts` for the canonical
|
|
1450
|
+
* accessor.
|
|
1451
|
+
*
|
|
1452
|
+
* Transport-agnostic: the browser orchestrates session *lifecycle* but
|
|
1453
|
+
* delegates session *construction* to a `SessionFactory` injected at
|
|
1454
|
+
* construction. HTTP-backed apps pass `createHttpSessionFactory()` from
|
|
1455
|
+
* `@semiont/sdk`; in-process apps pass their own factory.
|
|
1456
|
+
*
|
|
1457
|
+
* Persistence goes through a `SessionStorage` adapter provided at
|
|
1458
|
+
* construction — the browser never touches `localStorage` or `window`
|
|
1459
|
+
* directly.
|
|
1460
|
+
*/
|
|
1461
|
+
|
|
1462
|
+
interface SemiontBrowserConfig {
|
|
1463
|
+
/** Persistence adapter. The browser reads/writes all persisted state via this. */
|
|
1464
|
+
storage: SessionStorage;
|
|
1465
|
+
/**
|
|
1466
|
+
* Builds a `SemiontSession` for a KB. The browser is transport-
|
|
1467
|
+
* agnostic — every HTTP-vs-local construction concern lives in the
|
|
1468
|
+
* factory. HTTP-backed apps pass `createHttpSessionFactory()` from
|
|
1469
|
+
* `@semiont/sdk`; a future in-process variant from `@semiont/make-meaning`
|
|
1470
|
+
* would expose its own factory.
|
|
1471
|
+
*/
|
|
1472
|
+
sessionFactory: SessionFactory;
|
|
1473
|
+
}
|
|
1474
|
+
declare class SemiontBrowser {
|
|
1475
|
+
readonly kbs$: BehaviorSubject<KnowledgeBase[]>;
|
|
1476
|
+
readonly activeKbId$: BehaviorSubject<string | null>;
|
|
1477
|
+
readonly activeSession$: BehaviorSubject<SemiontSession | null>;
|
|
1478
|
+
/**
|
|
1479
|
+
* Modal signals (session-expired / permission-denied) for the
|
|
1480
|
+
* currently-active session. Parallels `activeSession$` — always
|
|
1481
|
+
* non-null when `activeSession$` is non-null, always null when it
|
|
1482
|
+
* is. Extracted from the session itself so headless sessions
|
|
1483
|
+
* (workers, CLIs, tests) don't carry dead modal observables.
|
|
1484
|
+
* See [SessionSignals](./session-signals.ts).
|
|
1485
|
+
*/
|
|
1486
|
+
readonly activeSignals$: BehaviorSubject<SessionSignals | null>;
|
|
1487
|
+
/**
|
|
1488
|
+
* True while a session is actively being constructed (setActiveKb /
|
|
1489
|
+
* signIn in flight, awaiting `session.ready`). Distinguishes the
|
|
1490
|
+
* "session about to arrive" intermediate state from "session
|
|
1491
|
+
* intentionally null" (after signOut, or when the active KB has no
|
|
1492
|
+
* stored credentials). UIs that want a loading spinner should gate
|
|
1493
|
+
* on this; otherwise they get stuck spinning after every signOut.
|
|
1494
|
+
*/
|
|
1495
|
+
readonly sessionActivating$: BehaviorSubject<boolean>;
|
|
1496
|
+
readonly openResources$: BehaviorSubject<OpenResource[]>;
|
|
1497
|
+
readonly error$: Subject<SemiontSessionError>;
|
|
1498
|
+
readonly identityToken$: BehaviorSubject<string | null>;
|
|
1499
|
+
private readonly storage;
|
|
1500
|
+
private readonly sessionFactory;
|
|
1501
|
+
/**
|
|
1502
|
+
* App-scoped EventBus. Hosts UI-shell events that must work regardless
|
|
1503
|
+
* of whether a KB session is active: panel toggles, sidebar state,
|
|
1504
|
+
* tab reorders, routing, settings, etc. Disjoint from the per-session
|
|
1505
|
+
* bus inside `SemiontClient`, which carries KB-content events
|
|
1506
|
+
* (mark:*, beckon:*, gather:*, match:*, bind:*, yield:*, browse:click).
|
|
1507
|
+
*/
|
|
1508
|
+
private readonly eventBus;
|
|
1509
|
+
private unsubscribeStorage;
|
|
1510
|
+
private disposed;
|
|
1511
|
+
private activating;
|
|
1512
|
+
constructor(config: SemiontBrowserConfig);
|
|
1513
|
+
/** Emit an event on the browser's app-scoped bus. */
|
|
1514
|
+
emit<K extends keyof EventMap>(channel: K, payload: EventMap[K]): void;
|
|
1515
|
+
/** Subscribe to an event; returns unsubscribe. */
|
|
1516
|
+
on<K extends keyof EventMap>(channel: K, handler: (payload: EventMap[K]) => void): () => void;
|
|
1517
|
+
/** Read-only observable for an app-scoped channel. */
|
|
1518
|
+
stream<K extends keyof EventMap>(channel: K): Observable<EventMap[K]>;
|
|
1519
|
+
/**
|
|
1520
|
+
* Set the app-level identity token. Sourced from whatever the host
|
|
1521
|
+
* environment uses for OAuth sessions (e.g. NextAuth in a browser app).
|
|
1522
|
+
* Should be called once from the host's startup-and-on-change site;
|
|
1523
|
+
* no other code should write to this slot.
|
|
1524
|
+
*/
|
|
1525
|
+
setIdentityToken(token: string | null): void;
|
|
1526
|
+
addKb(input: NewKnowledgeBase, access: string, refresh: string): KnowledgeBase;
|
|
1527
|
+
removeKb(id: string): void;
|
|
1528
|
+
/**
|
|
1529
|
+
* Patch a KB in the list. Restricted to the common, endpoint-agnostic
|
|
1530
|
+
* fields (`label`, `email`, `gitBranch`) — the `endpoint` shape isn't
|
|
1531
|
+
* editable in place; remove and re-add to change the connection
|
|
1532
|
+
* target.
|
|
1533
|
+
*/
|
|
1534
|
+
updateKb(id: string, updates: {
|
|
1535
|
+
label?: string;
|
|
1536
|
+
email?: string;
|
|
1537
|
+
gitBranch?: string;
|
|
1538
|
+
}): void;
|
|
1539
|
+
/**
|
|
1540
|
+
* Read the locally-stored credential status for a KB. Pure / synchronous —
|
|
1541
|
+
* does not subscribe to context changes. Used by KB-list UI to color status
|
|
1542
|
+
* dots without requiring re-renders on every tick.
|
|
1543
|
+
*/
|
|
1544
|
+
getKbSessionStatus(kbId: string): KbSessionStatus;
|
|
1545
|
+
/**
|
|
1546
|
+
* Switch the active KB. Follows the D2 disposal contract:
|
|
1547
|
+
* 1. Synchronously announce the new id on `activeKbId$` and null out
|
|
1548
|
+
* `activeSession$` so views see a safe empty state first.
|
|
1549
|
+
* 2. Serialize overlapping calls — if an activation is in flight, wait
|
|
1550
|
+
* for it before proceeding.
|
|
1551
|
+
* 3. Dispose whatever session is currently live.
|
|
1552
|
+
* 4. Construct the next session and await `session.ready`.
|
|
1553
|
+
* 5. Before emitting, re-check `activeKbId$` — if a newer call superseded
|
|
1554
|
+
* us while we waited, dispose our session and skip the emit.
|
|
1555
|
+
* 6. Emit the new session.
|
|
1556
|
+
*/
|
|
1557
|
+
setActiveKb(id: string | null): Promise<void>;
|
|
1558
|
+
/**
|
|
1559
|
+
* Sign in to an existing KB: store the tokens and (re)activate the
|
|
1560
|
+
* session. If the KB is already active, the current session is disposed
|
|
1561
|
+
* and replaced so the new tokens take effect.
|
|
1562
|
+
*/
|
|
1563
|
+
signIn(id: string, access: string, refresh: string): Promise<void>;
|
|
1564
|
+
/**
|
|
1565
|
+
* Sign out of a KB: clear stored tokens. If the KB is active, dispose
|
|
1566
|
+
* its session + signals and emit null for both.
|
|
1567
|
+
*/
|
|
1568
|
+
signOut(id: string): Promise<void>;
|
|
1569
|
+
addOpenResource(id: string, name: string, mediaType?: string, storageUri?: string): void;
|
|
1570
|
+
removeOpenResource(id: string): void;
|
|
1571
|
+
updateOpenResourceName(id: string, name: string): void;
|
|
1572
|
+
reorderOpenResources(oldIndex: number, newIndex: number): void;
|
|
1573
|
+
dispose(): Promise<void>;
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
/**
|
|
1577
|
+
* createHttpSessionFactory — the default `SessionFactory` for HTTP-backed
|
|
1578
|
+
* KBs. Owns every HTTP-specific construction concern that used to live in
|
|
1579
|
+
* `SemiontBrowser`: building `HttpTransport`/`HttpContentTransport`,
|
|
1580
|
+
* wiring the `tokenRefresher` callback, deduplicating concurrent 401
|
|
1581
|
+
* refresh round trips, and invoking the auth endpoints for token refresh
|
|
1582
|
+
* and user-validate.
|
|
1583
|
+
*
|
|
1584
|
+
* Returned as a closure so a single `inFlightRefreshes` map is shared
|
|
1585
|
+
* across every session this factory builds — the dedup is meaningful
|
|
1586
|
+
* across concurrent session reactivations for the same KB id.
|
|
1587
|
+
*/
|
|
1588
|
+
|
|
1589
|
+
declare function createHttpSessionFactory(): SessionFactory;
|
|
1590
|
+
|
|
1591
|
+
/**
|
|
1592
|
+
* Process-wide accessor for `SemiontBrowser`. Constructed lazily on the
|
|
1593
|
+
* first `getBrowser()` call and held for the host's lifetime — a single
|
|
1594
|
+
* instance owns the KB list, identity token, and active-session state,
|
|
1595
|
+
* so callers throughout the host get the same view of "which KB am I
|
|
1596
|
+
* talking to right now" regardless of where they pick it up.
|
|
1597
|
+
*
|
|
1598
|
+
* The caller provides a `SessionStorage` implementation and a
|
|
1599
|
+
* `SessionFactory` — both are environment-specific (browsers use
|
|
1600
|
+
* `WebBrowserStorage` + `createHttpSessionFactory()`, CLI/embedded
|
|
1601
|
+
* hosts use a filesystem adapter and possibly a local-process
|
|
1602
|
+
* factory, tests use `InMemorySessionStorage` and stubs). The first
|
|
1603
|
+
* call to `getBrowser` wins; subsequent calls return the cached
|
|
1604
|
+
* instance regardless of the options passed.
|
|
1605
|
+
*/
|
|
1606
|
+
|
|
1607
|
+
interface GetBrowserOptions {
|
|
1608
|
+
/** Persistence adapter used to construct the singleton on first call. */
|
|
1609
|
+
storage: SessionStorage;
|
|
1610
|
+
/** Session factory used to build a `SemiontSession` per active KB. */
|
|
1611
|
+
sessionFactory: SessionFactory;
|
|
1612
|
+
}
|
|
1613
|
+
declare function getBrowser(options: GetBrowserOptions): SemiontBrowser;
|
|
1614
|
+
|
|
1615
|
+
/**
|
|
1616
|
+
* Pure helpers and storage-adapter-driven loaders for the Semiont
|
|
1617
|
+
* session layer.
|
|
1618
|
+
*
|
|
1619
|
+
* Contains:
|
|
1620
|
+
* - Storage key shape (constants, `sessionKey(kbId)`)
|
|
1621
|
+
* - JWT expiry parsing and "is expired" check
|
|
1622
|
+
* - URL/protocol helpers for KB instances
|
|
1623
|
+
* - Loaders/savers that take a `SessionStorage` and operate over it
|
|
1624
|
+
* (no direct `localStorage` access)
|
|
1625
|
+
*
|
|
1626
|
+
* No React imports, no module-scoped state, no side effects beyond
|
|
1627
|
+
* whatever the passed-in `SessionStorage` does.
|
|
1628
|
+
*/
|
|
1629
|
+
|
|
1630
|
+
/** The shape persisted per KB. */
|
|
1631
|
+
interface StoredSession {
|
|
1632
|
+
access: string;
|
|
1633
|
+
refresh: string;
|
|
1634
|
+
}
|
|
1635
|
+
declare function setStoredSession(storage: SessionStorage, kbId: string, session: StoredSession): void;
|
|
1636
|
+
declare function defaultProtocol(host: string): 'http' | 'https';
|
|
1637
|
+
declare function isValidHostname(host: string): boolean;
|
|
1638
|
+
/**
|
|
1639
|
+
* Build the wire URL for an HTTP KB endpoint. HTTP-shaped helper —
|
|
1640
|
+
* lives next to the KB list machinery because the frontend Panel needs
|
|
1641
|
+
* it for the auth round-trip when adding a KB. Code that holds a
|
|
1642
|
+
* uniform `KnowledgeBase` should not call this; it should hand the KB
|
|
1643
|
+
* to a transport factory and let the factory inspect `endpoint.kind`.
|
|
1644
|
+
*/
|
|
1645
|
+
declare function kbBackendUrl(endpoint: HttpEndpoint): string;
|
|
1646
|
+
|
|
1647
|
+
/**
|
|
1648
|
+
* Marker for the state-unit pattern: a stateful, lifecycled object with an
|
|
1649
|
+
* RxJS-shaped public surface, constructed by a factory function
|
|
1650
|
+
* (`createFooStateUnit`), with internal state held in a closure.
|
|
1651
|
+
*
|
|
1652
|
+
* The structural contract is `dispose()` — the rest of the pattern
|
|
1653
|
+
* (closure-based identity, Observable public surface, internal Subjects
|
|
1654
|
+
* exposed as `.asObservable()` views, no leaked subscriptions, composition
|
|
1655
|
+
* by parameter rather than ownership) is convention enforced by review,
|
|
1656
|
+
* not the type system.
|
|
1657
|
+
*
|
|
1658
|
+
* See `packages/sdk/docs/STATE-UNITS.md` for the full axioms and rationale.
|
|
1659
|
+
*/
|
|
1660
|
+
interface StateUnit {
|
|
1661
|
+
/**
|
|
1662
|
+
* Idempotent, total teardown. Completes every Subject the unit owns,
|
|
1663
|
+
* unsubscribes every internal subscription, releases timers / abort
|
|
1664
|
+
* controllers / network handles. Safe to call multiple times — the
|
|
1665
|
+
* second call is a no-op.
|
|
1666
|
+
*/
|
|
1667
|
+
dispose(): void;
|
|
1668
|
+
}
|
|
1669
|
+
/**
|
|
1670
|
+
* Compose multiple disposers into a single `dispose()` call. Accepts either
|
|
1671
|
+
* a `StateUnit` (whose `dispose()` will be invoked) or a plain teardown
|
|
1672
|
+
* function. The returned object is itself disposable; call its `dispose()`
|
|
1673
|
+
* once to tear down everything that was added.
|
|
1674
|
+
*/
|
|
1675
|
+
declare function createDisposer(): {
|
|
1676
|
+
add(item: StateUnit | (() => void)): void;
|
|
1677
|
+
dispose(): void;
|
|
1678
|
+
};
|
|
1679
|
+
|
|
1680
|
+
/**
|
|
1681
|
+
* createSearchPipeline
|
|
1682
|
+
*
|
|
1683
|
+
* A debounced-search RxJS pipeline factory. Combines an input Subject with a
|
|
1684
|
+
* downstream fetch function and emits typed `{ results, isSearching }` state.
|
|
1685
|
+
*
|
|
1686
|
+
* Designed to be created once per consumer instance and held for its lifetime
|
|
1687
|
+
* (e.g. by a view layer's lazy initializer), then observed via `state$`. The
|
|
1688
|
+
* pipeline is pure RxJS — unit-testable without any view-layer dependency.
|
|
1689
|
+
*
|
|
1690
|
+
* The fetch function is expected to return `Observable<T[] | undefined>`,
|
|
1691
|
+
* matching the cache-miss-then-data shape of `BrowseNamespace` Observables:
|
|
1692
|
+
* `undefined` means "fetch in flight, no value yet"; an array means "data
|
|
1693
|
+
* available (possibly empty)".
|
|
1694
|
+
*/
|
|
1695
|
+
|
|
1696
|
+
interface SearchState<T> {
|
|
1697
|
+
results: T[];
|
|
1698
|
+
isSearching: boolean;
|
|
1699
|
+
}
|
|
1700
|
+
interface SearchPipeline<T> {
|
|
1701
|
+
/** Latest query string. Bind to a controlled input. */
|
|
1702
|
+
query$: Observable<string>;
|
|
1703
|
+
/** Latest search state — results plus a loading flag. */
|
|
1704
|
+
state$: Observable<SearchState<T>>;
|
|
1705
|
+
/** Push a new query value. Triggers the debounced fetch. */
|
|
1706
|
+
setQuery(value: string): void;
|
|
1707
|
+
/** Tear down the input Subject. Call from the consumer's cleanup hook. */
|
|
1708
|
+
dispose(): void;
|
|
1709
|
+
}
|
|
1710
|
+
interface SearchPipelineOptions {
|
|
1711
|
+
/** Milliseconds to wait after the last keystroke before fetching. Default 250. */
|
|
1712
|
+
debounceMs?: number;
|
|
1713
|
+
/** Initial query value. Useful for modals that open with a pre-filled term. */
|
|
1714
|
+
initialQuery?: string;
|
|
1715
|
+
}
|
|
1716
|
+
declare function createSearchPipeline<T>(fetch: (query: string) => Observable<T[] | undefined>, options?: SearchPipelineOptions): SearchPipeline<T>;
|
|
1717
|
+
|
|
1718
|
+
/**
|
|
1719
|
+
* WorkerBus — minimal channel-bus surface that worker-side adapters
|
|
1720
|
+
* (e.g. `JobClaimAdapter` in `@semiont/jobs`, `SmelterActorStateUnit` in
|
|
1721
|
+
* `@semiont/make-meaning`) need.
|
|
1722
|
+
*
|
|
1723
|
+
* Transport-neutral by design. HTTP `ActorStateUnit` (from `@semiont/api-client`)
|
|
1724
|
+
* satisfies it directly; an in-process worker can pass a small shim around
|
|
1725
|
+
* an `EventBus` with a `() => Promise<void>` `emit` that calls into the
|
|
1726
|
+
* actor system.
|
|
1727
|
+
*
|
|
1728
|
+
* `addChannels` is optional because in-process buses receive every emit
|
|
1729
|
+
* implicitly — only HTTP needs to widen its SSE subscription set to
|
|
1730
|
+
* include worker-only channels (`job:queued`, `yield:created`, etc.).
|
|
1731
|
+
*/
|
|
1732
|
+
|
|
1733
|
+
interface WorkerBus {
|
|
1734
|
+
on$<T = Record<string, unknown>>(channel: string): Observable<T>;
|
|
1735
|
+
emit(channel: string, payload: Record<string, unknown>): Promise<void>;
|
|
1736
|
+
addChannels?(channels: readonly string[]): void;
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
interface BeckonStateUnit extends StateUnit {
|
|
1740
|
+
hoveredAnnotationId$: Observable<AnnotationId | null>;
|
|
1741
|
+
hover(annotationId: AnnotationId | null): void;
|
|
1742
|
+
focus(annotationId: AnnotationId): void;
|
|
1743
|
+
sparkle(annotationId: AnnotationId): void;
|
|
1744
|
+
}
|
|
1745
|
+
declare function createBeckonStateUnit(client: SemiontClient): BeckonStateUnit;
|
|
1746
|
+
/** Default milliseconds the mouse must dwell before beckon:hover is emitted. */
|
|
1747
|
+
declare const HOVER_DELAY_MS = 150;
|
|
1748
|
+
type EmitHover = (annotationId: AnnotationId | null) => void;
|
|
1749
|
+
interface HoverHandlers {
|
|
1750
|
+
handleMouseEnter: (annotationId: AnnotationId) => void;
|
|
1751
|
+
handleMouseLeave: () => void;
|
|
1752
|
+
cleanup: () => void;
|
|
1753
|
+
}
|
|
1754
|
+
declare function createHoverHandlers(emit: EmitHover, delayMs: number): HoverHandlers;
|
|
1755
|
+
|
|
1756
|
+
interface GatherStateUnit extends StateUnit {
|
|
1757
|
+
context$: Observable<GatheredContext | null>;
|
|
1758
|
+
loading$: Observable<boolean>;
|
|
1759
|
+
error$: Observable<Error | null>;
|
|
1760
|
+
annotationId$: Observable<AnnotationId | null>;
|
|
1761
|
+
}
|
|
1762
|
+
declare function createGatherStateUnit(client: SemiontClient, resourceId: ResourceId): GatherStateUnit;
|
|
1763
|
+
|
|
1764
|
+
interface MatchStateUnit extends StateUnit {
|
|
1765
|
+
}
|
|
1766
|
+
declare function createMatchStateUnit(client: SemiontClient, _resourceId: ResourceId): MatchStateUnit;
|
|
1767
|
+
|
|
1768
|
+
type JobProgress$1 = components['schemas']['JobProgress'];
|
|
1769
|
+
interface GenerateDocumentOptions {
|
|
1770
|
+
title: string;
|
|
1771
|
+
storageUri: string;
|
|
1772
|
+
prompt?: string;
|
|
1773
|
+
/** Body locale — language the generated resource is written in. Falls back to the state unit's UI locale when unset. */
|
|
1774
|
+
language?: string;
|
|
1775
|
+
/** Source-resource locale — language of the resource the annotation lives on. Forwarded to the prompt for context-snippet awareness. BCP-47. */
|
|
1776
|
+
sourceLanguage?: string;
|
|
1777
|
+
temperature?: number;
|
|
1778
|
+
maxTokens?: number;
|
|
1779
|
+
context: GatheredContext;
|
|
1780
|
+
}
|
|
1781
|
+
interface YieldStateUnit extends StateUnit {
|
|
1782
|
+
isGenerating$: Observable<boolean>;
|
|
1783
|
+
progress$: Observable<JobProgress$1 | null>;
|
|
1784
|
+
generate(referenceId: string, options: GenerateDocumentOptions): void;
|
|
1785
|
+
}
|
|
1786
|
+
declare function createYieldStateUnit(client: SemiontClient, resourceId: ResourceId, locale: string): YieldStateUnit;
|
|
1787
|
+
|
|
1788
|
+
type JobProgress = components['schemas']['JobProgress'];
|
|
1789
|
+
interface PendingAnnotation {
|
|
1790
|
+
selector: Selector | Selector[];
|
|
1791
|
+
motivation: Motivation;
|
|
1792
|
+
}
|
|
1793
|
+
interface MarkStateUnit extends StateUnit {
|
|
1794
|
+
pendingAnnotation$: Observable<PendingAnnotation | null>;
|
|
1795
|
+
assistingMotivation$: Observable<Motivation | null>;
|
|
1796
|
+
progress$: Observable<JobProgress | null>;
|
|
1797
|
+
}
|
|
1798
|
+
declare function createMarkStateUnit(client: SemiontClient, resourceId: ResourceId): MarkStateUnit;
|
|
1799
|
+
|
|
1800
|
+
export { AdminNamespace, AuthNamespace, BeckonNamespace, BindNamespace, BrowseNamespace, BusRequestError, CacheObservable, FrameNamespace, GatherNamespace, HOVER_DELAY_MS, InMemorySessionStorage, JobNamespace, MarkNamespace, MatchNamespace, SemiontBrowser, SemiontClient, SemiontSession, SemiontSessionError, SessionSignals, StreamObservable, UploadObservable, YieldNamespace, busRequest, createBeckonStateUnit, createDisposer, createGatherStateUnit, createHoverHandlers, createHttpSessionFactory, createMarkStateUnit, createMatchStateUnit, createSearchPipeline, createYieldStateUnit, defaultProtocol, getBrowser, httpKb, isValidHostname, kbBackendUrl, setStoredSession };
|
|
1801
|
+
export type { AnnotationHistoryResponse, BeckonStateUnit, BusRequestErrorCode, BusRequestPrimitive, CreateAnnotationInput, CreateFromTokenOptions, CreateResourceInput, GatherAnnotationProgress, GatherStateUnit, GenerateDocumentOptions, GenerationOptions, GetBrowserOptions, HoverHandlers, HttpEndpoint, KbEndpoint, KbSessionStatus, KnowledgeBase, LocalEndpoint, MarkAssistEvent, MarkAssistOptions, MarkAssistProgress, MarkStateUnit, MatchSearchProgress, MatchStateUnit, NewKnowledgeBase, OpenResource, PendingAnnotation, ReferencedByEntry, RequestContent, ResponseContent, SearchPipeline, SearchPipelineOptions, SearchState, SemiontBrowserConfig, SemiontSessionConfig, SemiontSessionErrorCode, SessionFactory, SessionFactoryOptions, SessionStorage, StateUnit, StoredSession, UploadProgress, User, UserInfo, WorkerBus, YieldGenerationEvent, YieldStateUnit };
|