@asaidimu/utils-workspace 2.1.1 → 3.1.0

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.
Files changed (6) hide show
  1. package/README.md +297 -277
  2. package/index.d.mts +804 -171
  3. package/index.d.ts +804 -171
  4. package/index.js +288 -1
  5. package/index.mjs +287 -1
  6. package/package.json +2 -1
package/index.d.ts CHANGED
@@ -1,10 +1,40 @@
1
1
  import { QueryFilter, PaginationOptions } from '@asaidimu/query';
2
2
  import { IndexDefinition, SchemaDefinition, SchemaChange, DataTransform } from '@asaidimu/anansi';
3
+ import { EventBus } from '@asaidimu/events';
4
+ import * as _google_genai from '@google/genai';
5
+ import { GenerateContentParameters, GenerateContentResponse, GoogleGenAI } from '@google/genai';
3
6
 
7
+ /**
8
+ * Utility type for representing partial updates to the state, allowing deep nesting.
9
+ * It makes all properties optional and applies the same transformation recursively
10
+ * to nested objects and array elements, allowing for selective updates while
11
+ * preserving the original structure. It also includes the original type T and
12
+ * undefined as possibilities for the top level and nested values.
13
+ */
14
+ type DeepPartial<T> = T extends object ? T extends readonly (infer U)[] ? readonly (DeepPartial<U> | undefined)[] | undefined | T : T extends (infer U)[] ? (DeepPartial<U> | undefined)[] | undefined | T : {
15
+ [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> | undefined : T[K] | undefined;
16
+ } | undefined | T : T | undefined;
17
+
18
+ /**
19
+ * core/types.ts
20
+ * * This file contains the primary domain models, data structures, and command types
21
+ * for the AI Workspace. It acts as the "Source of Truth" for all modules.
22
+ */
23
+
24
+ /** RFC 4122 compliant Universally Unique Identifier. */
4
25
  type UUID = string;
26
+ /** ISO-8601 formatted UTC timestamp string. */
5
27
  type Timestamp = string;
28
+ /** Uniform Resource Identifier string. */
6
29
  type URI = string;
30
+ /** Hexadecimal representation of a SHA-256 hash. */
7
31
  type SHA256 = string;
32
+ /** Special marker used to denote a role with no specific instructions or identity. */
33
+ declare const EMPTY_SYSTEM_ROLE = "__system__";
34
+ /**
35
+ * A functional wrapper for operations that can fail.
36
+ * Encourages explicit error handling over try/catch blocks.
37
+ */
8
38
  type Result<T, E = WorkspaceError> = {
9
39
  ok: true;
10
40
  value: T;
@@ -12,44 +42,72 @@ type Result<T, E = WorkspaceError> = {
12
42
  ok: false;
13
43
  error: E;
14
44
  };
15
- type WorkspaceError = {
45
+ /** Occurs when attempting to create a resource with a key that already exists. */
46
+ type DuplicateKeyError = {
16
47
  code: 'DUPLICATE_KEY';
17
48
  resource: string;
18
49
  key: string;
19
- } | {
50
+ };
51
+ /** Occurs when a requested resource cannot be found by its unique identifier. */
52
+ type NotFoundError = {
20
53
  code: 'NOT_FOUND';
21
54
  resource: string;
22
55
  id: string;
23
- } | {
56
+ };
57
+ /** Triggered when a command payload fails validation or is logically inconsistent. */
58
+ type InvalidCommandError = {
24
59
  code: 'INVALID_COMMAND';
25
60
  reason: string;
26
- } | {
61
+ };
62
+ /** Generic wrapper for unexpected infrastructure or downstream service failures. */
63
+ type BackendError = {
27
64
  code: 'BACKEND_ERROR';
28
65
  reason: string;
29
- } | {
66
+ };
67
+ /** Specific errors related to blob storage, retrieval, or corruption. */
68
+ type BlobError = {
30
69
  code: 'BLOB_ERROR';
31
70
  reason: string;
32
71
  };
72
+ /** Triggered when the current actor lacks sufficient privileges for a command. */
73
+ type PermissionDeniedError = {
74
+ code: 'PERMISSION_DENIED';
75
+ command: Command;
76
+ reason: string;
77
+ };
78
+ /** Union of all possible error types within the Workspace domain. */
79
+ type WorkspaceError = DuplicateKeyError | NotFoundError | InvalidCommandError | BackendError | PermissionDeniedError | BlobError;
80
+ /** Global user preferences and defaults for the workspace. */
33
81
  interface Settings {
82
+ /** Default language code (e.g., 'en-US'). */
34
83
  language: string;
84
+ /** The name of the role used when starting a new session. */
35
85
  defaultRole?: string;
86
+ /** Global instructions appended to all system prompts. */
36
87
  prompt?: string;
37
88
  }
38
- interface Project {
89
+ /** * Represents the project-level metadata.
90
+ * Allows for extensible metadata fields via the generic Metadata type.
91
+ */
92
+ type Project<Metadata extends Record<string, any> = Record<string, any>> = Metadata & {
93
+ id: UUID;
39
94
  name: string;
40
- owner: string;
41
- repository?: string;
42
- metadata?: Record<string, any>;
43
- }
95
+ };
96
+ /** Supported mime-types for image assets. */
44
97
  type ImageMediaType = 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp';
98
+ /** Supported mime-types for text-based or structured documents. */
45
99
  type DocumentMediaType = 'application/pdf' | 'application/json' | 'text/plain' | 'text/html' | 'text/markdown' | 'text/csv' | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
100
+ /** Union of all media types handled by the blob system. */
46
101
  type BlobMediaType = ImageMediaType | DocumentMediaType;
47
102
  /**
48
- * Lightweight pointer to a blob — the subset of BlobRecord that content
49
- * blocks and context entries carry. Use this at call sites that only need
50
- * to reference a blob, not inspect its registry metadata.
103
+ * A lightweight reference to a blob.
104
+ * Used in content blocks to avoid passing heavy metadata or binary data.
51
105
  */
52
106
  type BlobRef = Pick<BlobRecord, 'sha256' | 'mediaType' | 'sizeBytes' | 'filename' | 'previewUrl'>;
107
+ /**
108
+ * Represents a blob that has been fetched into memory.
109
+ * Can be 'inline' (binary data present) or 'remote' (stored in an external provider).
110
+ */
53
111
  type ResolvedBlob = {
54
112
  kind: 'inline';
55
113
  sha256: SHA256;
@@ -61,10 +119,11 @@ type ResolvedBlob = {
61
119
  mediaType: BlobMediaType;
62
120
  fileId: string;
63
121
  providerId: string;
122
+ timestamp: Timestamp;
64
123
  };
65
124
  /**
66
- * Full registry entry for a blob. BlobRef is a Pick of this type, so
67
- * a BlobRecord is always assignable to BlobRef.
125
+ * The authoritative registry entry for a file in the system.
126
+ * Includes reference counting for garbage collection and remote mappings.
68
127
  */
69
128
  interface BlobRecord {
70
129
  sha256: SHA256;
@@ -72,86 +131,147 @@ interface BlobRecord {
72
131
  sizeBytes: number;
73
132
  filename?: string;
74
133
  previewUrl?: string;
134
+ /** Number of content blocks currently referencing this blob. */
75
135
  refCount: number;
76
- remoteIds: Record<string, string>;
136
+ /** Map of provider IDs to their specific external file identifiers. */
137
+ remoteIds: Record<string, {
138
+ id: string;
139
+ timestamp: Timestamp;
140
+ }>;
77
141
  createdAt: Timestamp;
78
142
  lastUsedAt: Timestamp;
79
143
  }
144
+ /** Standard text content within a turn. */
80
145
  interface TextBlock {
146
+ id: UUID;
81
147
  type: 'text';
82
148
  text: string;
83
149
  }
150
+ /** An image asset within a turn, optionally containing the resolved binary data. */
84
151
  interface ImageBlock {
152
+ id: UUID;
85
153
  type: 'image';
86
154
  ref?: BlobRef;
87
155
  blob?: ResolvedBlob;
88
156
  altText?: string;
89
157
  }
158
+ /** A document asset within a turn. */
90
159
  interface DocumentBlock {
160
+ id: UUID;
91
161
  type: 'document';
92
162
  ref?: BlobRef;
93
163
  blob?: ResolvedBlob;
94
164
  title?: string;
95
165
  }
166
+ /** Represents a structured proposal to create or modify a task. */
167
+ interface TaskProposalBlock {
168
+ id: UUID;
169
+ taskId?: UUID;
170
+ type: 'task:proposal';
171
+ title: string;
172
+ steps: {
173
+ id?: UUID;
174
+ text: string;
175
+ status: 'todo' | 'done';
176
+ }[];
177
+ action: 'create' | 'update' | 'complete';
178
+ }
179
+ /** Captured request from the AI to execute a specific tool. */
96
180
  interface ToolUseBlock {
97
- type: 'tool_use';
98
- toolUseId: string;
181
+ id: UUID;
182
+ type: 'tool:use';
99
183
  name: string;
100
184
  input: Record<string, unknown>;
101
185
  }
186
+ /** The resulting output (or error) from a tool execution. */
102
187
  interface ToolResultBlock {
103
- type: 'tool_result';
104
- toolUseId: string;
188
+ id: UUID;
189
+ type: 'tool:result';
190
+ /** References the ToolUseBlock ID that generated this result. */
191
+ useId: UUID;
105
192
  content: string | Record<string, unknown>;
106
193
  isError?: boolean;
107
194
  }
195
+ /** Internal "Chain of Thought" or reasoning generated by the model. */
108
196
  interface ThinkingBlock {
197
+ id: UUID;
109
198
  type: 'thinking';
110
199
  thinking: string;
111
200
  }
201
+ /** A condensed summary of previous conversation history. */
112
202
  interface SummaryBlock {
203
+ id: UUID;
113
204
  type: 'summary';
114
205
  text: string;
115
206
  }
207
+ /** Notates that the session has switched from one Role persona to another. */
116
208
  interface RoleTransitionBlock {
117
- type: 'role_transition';
209
+ id: UUID;
210
+ type: 'role:transition';
118
211
  previousRole: string | null;
119
212
  newRole: string;
120
213
  }
121
- type ContentBlock = TextBlock | ImageBlock | DocumentBlock | ToolUseBlock | ToolResultBlock | SummaryBlock | RoleTransitionBlock | ThinkingBlock;
122
- type TurnRole = 'user' | 'assistant' | 'tool';
214
+ /** Union of all possible content types that can exist within a conversation Turn. */
215
+ type ContentBlock = TextBlock | ImageBlock | DocumentBlock | ToolUseBlock | ToolResultBlock | SummaryBlock | RoleTransitionBlock | ThinkingBlock | TaskProposalBlock;
216
+ /** Definition of a tool available to the AI. */
217
+ interface ToolSummary {
218
+ name: string;
219
+ description: string;
220
+ /** JSON Schema defining the required input arguments. */
221
+ parameters: {
222
+ type: 'object';
223
+ properties: Record<string, any>;
224
+ required: string[];
225
+ };
226
+ /** Semantic tags used to help the model find relevant tools. */
227
+ topics: string[];
228
+ }
229
+ /** An instance of a tool being called with specific arguments. */
230
+ interface ToolCall {
231
+ id: UUID;
232
+ tool: UUID;
233
+ arguments: Record<string, any>;
234
+ }
235
+ /** A request for authorization before executing a command or tool. */
236
+ type AuthRequest = {
237
+ type: 'command';
238
+ payload: Command;
239
+ } | {
240
+ type: 'tool';
241
+ payload: ToolCall;
242
+ };
243
+ /** Identifies whether a turn originated from the user, the AI, a tool, or the system. */
244
+ type TurnActor = 'user' | 'assistant' | 'tool' | 'system';
245
+ /** * The flat storage format for a conversation turn.
246
+ * Supports versioning and parent-pointers for branching conversation trees (DAG).
247
+ */
123
248
  interface Turn {
124
249
  id: UUID;
250
+ /** Incrementing number for edits to the same turn ID. */
125
251
  version: number;
126
- role: TurnRole;
252
+ actor: TurnActor;
127
253
  blocks: ContentBlock[];
128
254
  timestamp: Timestamp;
129
- /**
130
- * The name of the role active when this turn was recorded.
131
- * Snapshot so history is stable even if the role is later renamed.
132
- */
133
- roleSnapshot?: string;
134
- /**
135
- * Parent pointer. Null for root turns.
136
- * This is plain data stored on the document — the DAG is reconstructed
137
- * in memory by TurnTree.buildNodeGraph() at session open time.
138
- */
255
+ /** Name of the role active at the time of this turn. */
256
+ role?: string;
257
+ /** Link to the preceding turn in the conversation tree. */
139
258
  parent: {
140
259
  id: UUID;
141
260
  version: number;
142
261
  } | null;
143
- /**
144
- * Partition key. Stored on the Turn document so Collection.filter
145
- * can retrieve all turns for a session in a single query.
146
- * Not present on Turn objects used purely in memory (e.g. dirty buffer).
147
- */
262
+ /** Used for fast filtering within a specific chat session. */
148
263
  sessionId?: UUID;
149
264
  }
265
+ /**
266
+ * An in-memory representation of a turn, including all its versions and children.
267
+ * This is used for rendering threaded/branching conversations.
268
+ */
150
269
  interface TurnNode {
151
270
  id: UUID;
271
+ /** Map of version numbers to the Turn data. */
152
272
  versions: Record<number, Turn>;
153
273
  activeVersion: number;
154
- role: TurnRole;
274
+ role: TurnActor;
155
275
  blocks: ContentBlock[];
156
276
  timestamp: Timestamp;
157
277
  roleSnapshot?: string;
@@ -159,8 +279,10 @@ interface TurnNode {
159
279
  id: UUID;
160
280
  version: number;
161
281
  } | null;
282
+ /** Map of version numbers to an array of child turn IDs. */
162
283
  children: Record<number, UUID[]>;
163
284
  }
285
+ /** UI helper for navigating between different versions of a turn (e.g. "2 of 5"). */
164
286
  interface BranchInfo {
165
287
  versions: number[];
166
288
  currentIndex: number;
@@ -168,19 +290,27 @@ interface BranchInfo {
168
290
  hasPrev: boolean;
169
291
  hasNext: boolean;
170
292
  }
293
+ /** A system persona containing specific instructions and associated preferences. */
171
294
  interface Role {
295
+ /** Unique identifier name (e.g. "software-architect"). */
172
296
  name: string;
297
+ /** Human-readable display label. */
173
298
  label: string;
174
299
  description?: string;
300
+ /** The core instructions (system prompt) for this persona. */
175
301
  persona: string;
302
+ /** Array of Preference IDs associated with this role. */
176
303
  preferences: UUID[];
177
304
  }
305
+ /** A specific user preference or "memory" that informs model behavior. */
178
306
  interface Preference {
179
307
  id: UUID;
180
308
  content: string;
309
+ /** Topics used for retrieval-augmented generation (RAG). */
181
310
  topics: string[];
182
311
  timestamp: Timestamp;
183
312
  }
313
+ /** Discriminated union of types that can be injected into the AI context. */
184
314
  type ContextContent = {
185
315
  kind: 'text';
186
316
  value: string;
@@ -198,20 +328,20 @@ type ContextContent = {
198
328
  uri: URI;
199
329
  mediaType?: BlobMediaType;
200
330
  };
331
+ /** A contextual item (file, snippet, or data) attached to a session or prompt. */
201
332
  interface Context {
333
+ /** Unique lookup key. */
202
334
  key: string;
203
335
  topics: string[];
204
336
  content: ContextContent;
205
337
  timestamp: Timestamp;
206
338
  metadata?: Record<string, any>;
207
339
  }
208
- /**
209
- * SessionMeta is stored as a document in the 'session' collection.
210
- * The head pointer lives here — no separate session_heads store needed.
211
- */
340
+ /** Metadata for a conversation session, stored in the persistent collection. */
212
341
  interface SessionMeta {
213
342
  id: UUID;
214
343
  label: string;
344
+ /** The active Role name for this session. */
215
345
  role: string;
216
346
  topics: string[];
217
347
  preferences: UUID[];
@@ -219,17 +349,39 @@ interface SessionMeta {
219
349
  created?: Timestamp;
220
350
  updated?: Timestamp;
221
351
  };
352
+ /** Tracks how many turns have been persisted to the database. */
222
353
  flushedTurnCount: number;
354
+ /** The current leaf-node of the conversation. */
223
355
  head: {
224
356
  id: UUID;
225
357
  version: number;
226
358
  } | null;
359
+ /** Optional link to a specific Task being worked on. */
360
+ task: UUID | null;
361
+ }
362
+ type TaskStatus = 'todo' | 'active' | 'done' | 'blocked' | 'defered';
363
+ /** A single item within a Task's checklist. */
364
+ interface TaskStep {
365
+ id: UUID;
366
+ text: string;
367
+ completed?: Timestamp;
368
+ }
369
+ /** A high-level objective with nested steps, used for tracking AI progress. */
370
+ interface Task {
371
+ id: UUID;
372
+ title: string;
373
+ description?: string;
374
+ status: TaskStatus;
375
+ steps: TaskStep[];
376
+ topics: string[];
377
+ metadata?: Record<string, any>;
378
+ created: Timestamp;
379
+ updated: Timestamp;
227
380
  }
228
381
  interface RoleSummary {
229
382
  name: string;
230
383
  label: string;
231
384
  description?: string;
232
- /** Number of preference IDs listed on the role. */
233
385
  preferences: number;
234
386
  }
235
387
  interface PreferenceSummary {
@@ -248,30 +400,49 @@ interface ContextSummary {
248
400
  source?: string;
249
401
  metadata?: Record<string, any>;
250
402
  }
403
+ interface TaskSummary {
404
+ id: UUID;
405
+ title: string;
406
+ status: TaskStatus;
407
+ steps: {
408
+ completed: number;
409
+ total: number;
410
+ };
411
+ topics: string[];
412
+ }
413
+ /** Maps topics to the various entities that reference them. */
251
414
  interface TopicIndex {
252
415
  topic: string;
253
416
  contextKeys: string[];
254
417
  preferences: UUID[];
418
+ tasks: UUID[];
255
419
  metadata?: {
256
420
  created?: Timestamp;
257
421
  updated?: Timestamp;
258
422
  entries?: number;
259
423
  };
260
424
  }
425
+ /** The complete in-memory read-model of the Workspace state. */
261
426
  interface Index {
262
427
  roles: Record<string, RoleSummary>;
263
428
  preferences: Record<UUID, PreferenceSummary>;
264
429
  context: Record<string, ContextSummary>;
265
430
  sessions: Record<UUID, SessionMeta>;
431
+ tasks: Record<UUID, TaskSummary>;
266
432
  topics: Record<string, TopicIndex>;
267
433
  blobs: Record<SHA256, BlobRecord>;
434
+ tools: Record<string, ToolSummary>;
268
435
  }
269
- interface Workspace {
436
+ /** The root container for a user's workspace. */
437
+ interface Workspace<ProjectMetadata extends Record<string, any> = Record<string, any>> {
270
438
  id: UUID;
271
439
  settings: Settings;
272
- project: Project;
440
+ project: Project<ProjectMetadata>;
273
441
  index: Index;
274
442
  }
443
+ /** * Format used for exporting/importing a complete workspace state,
444
+ * including all historical turns and binary records.
445
+ */
275
446
  interface WorkspaceBundle {
276
447
  format: 'aiworkspace/4.0';
277
448
  workspace: Workspace;
@@ -281,33 +452,27 @@ interface WorkspaceBundle {
281
452
  sessions: Record<UUID, SessionMeta & {
282
453
  turns: Turn[];
283
454
  }>;
455
+ tasks: Record<UUID, Task>;
284
456
  blobs: Record<SHA256, BlobRecord>;
285
457
  }
458
+ /** A fully hydrated view of a session, including resolved objects for the prompt builder. */
286
459
  interface EffectiveSession {
287
460
  session: SessionMeta;
288
461
  role: Role;
289
462
  preferences: Preference[];
290
463
  context: Context[];
291
464
  transcript: Turn[];
465
+ task: Task | null;
292
466
  instructions?: string;
293
467
  }
294
- interface CacheConfig {
295
- roles?: number;
296
- preferences?: number;
297
- context?: number;
298
- }
299
- interface FlushConfig {
300
- maxBufferSize: number;
301
- flushIntervalMs: number;
302
- }
303
- interface ContentStoreConfig {
304
- cache?: CacheConfig;
305
- flush?: FlushConfig;
306
- }
307
468
  interface BaseCommand {
469
+ /** Discriminator for the command type. */
308
470
  type: string;
309
471
  timestamp: Timestamp;
472
+ /** The ID of the user or system component that initiated the command. */
310
473
  actor?: string;
474
+ description?: string;
475
+ synthetic?: boolean;
311
476
  }
312
477
  interface CreateWorkspace extends BaseCommand {
313
478
  type: 'workspace:create';
@@ -375,6 +540,31 @@ interface DeleteContext extends BaseCommand {
375
540
  key: string;
376
541
  };
377
542
  }
543
+ interface AddTask extends BaseCommand {
544
+ type: 'task:add';
545
+ payload: Task;
546
+ }
547
+ interface UpdateTask extends BaseCommand {
548
+ type: 'task:update';
549
+ payload: Partial<Task> & {
550
+ id: UUID;
551
+ };
552
+ }
553
+ interface DeleteTask extends BaseCommand {
554
+ type: 'task:delete';
555
+ payload: {
556
+ id: UUID;
557
+ };
558
+ }
559
+ /** Updates an existing turn record in storage. */
560
+ interface SaveTurn extends BaseCommand {
561
+ type: 'turn:save';
562
+ payload: {
563
+ sessionId: UUID;
564
+ turn: Turn;
565
+ };
566
+ }
567
+ /** Appends a new turn to a session. */
378
568
  interface AddTurn extends BaseCommand {
379
569
  type: 'turn:add';
380
570
  payload: {
@@ -382,6 +572,7 @@ interface AddTurn extends BaseCommand {
382
572
  turn: Turn;
383
573
  };
384
574
  }
575
+ /** Creates a new version of an existing turn. */
385
576
  interface EditTurn extends BaseCommand {
386
577
  type: 'turn:edit';
387
578
  payload: {
@@ -392,25 +583,26 @@ interface EditTurn extends BaseCommand {
392
583
  roleSnapshot?: string;
393
584
  };
394
585
  }
586
+ /** Creates a new branch in the conversation history from a specific turn. */
395
587
  interface BranchTurn extends BaseCommand {
396
588
  type: 'turn:branch';
397
589
  payload: {
398
590
  sessionId: UUID;
399
- parentTurnId: UUID;
400
- parentVersion: number;
401
- newTurn: Turn;
591
+ turn: Turn;
402
592
  };
403
593
  }
594
+ interface TurnRef {
595
+ id: UUID;
596
+ version: number;
597
+ }
598
+ /** Removes a specific version of a turn and updates the session head if necessary. */
404
599
  interface DeleteTurn extends BaseCommand {
405
600
  type: 'turn:delete';
406
601
  payload: {
407
602
  sessionId: UUID;
408
603
  turnId: UUID;
409
604
  version: number;
410
- newHead: {
411
- id: UUID;
412
- version: number;
413
- } | null;
605
+ newHead: TurnRef | null;
414
606
  };
415
607
  }
416
608
  interface SwitchRole extends BaseCommand {
@@ -434,6 +626,7 @@ interface OverrideSessionPreferences extends BaseCommand {
434
626
  preferences: UUID[];
435
627
  };
436
628
  }
629
+ /** Creates a new session starting from the state of an existing one. */
437
630
  interface ForkSession extends BaseCommand {
438
631
  type: 'session:fork';
439
632
  payload: {
@@ -444,6 +637,17 @@ interface ForkSession extends BaseCommand {
444
637
  topics?: string[];
445
638
  };
446
639
  }
640
+ interface UpdateSession extends BaseCommand {
641
+ type: 'session:update';
642
+ payload: {
643
+ sessionId: UUID;
644
+ label?: string;
645
+ role?: string;
646
+ topics?: string[];
647
+ preferences?: UUID[];
648
+ task?: UUID | null;
649
+ };
650
+ }
447
651
  interface DeleteSession extends BaseCommand {
448
652
  type: 'session:delete';
449
653
  payload: {
@@ -458,64 +662,73 @@ interface RegisterBlob extends BaseCommand {
458
662
  filename?: string;
459
663
  };
460
664
  }
665
+ /** Increases reference count to prevent garbage collection. */
461
666
  interface RetainBlob extends BaseCommand {
462
667
  type: 'blob:retain';
463
668
  payload: {
464
669
  sha256: SHA256;
465
670
  };
466
671
  }
672
+ /** Decreases reference count. */
467
673
  interface ReleaseBlob extends BaseCommand {
468
674
  type: 'blob:release';
469
675
  payload: {
470
676
  sha256: SHA256;
471
677
  };
472
678
  }
679
+ /** Immediately removes a blob regardless of reference count. */
473
680
  interface PurgeBlob extends BaseCommand {
474
681
  type: 'blob:purge';
475
682
  payload: {
476
683
  sha256: SHA256;
477
684
  };
478
685
  }
686
+ /** Maps a local blob to an external provider's file ID. */
479
687
  interface RecordBlobRemoteId extends BaseCommand {
480
688
  type: 'blob:record_remote_id';
481
689
  payload: {
482
690
  sha256: SHA256;
483
691
  providerId: string;
484
692
  fileId: string;
693
+ timestamp?: Timestamp;
485
694
  };
486
695
  }
487
696
  type BlobCommand = RegisterBlob | RetainBlob | ReleaseBlob | PurgeBlob | RecordBlobRemoteId;
488
- type Command = CreateWorkspace | AddRole | UpdateRole | DeleteRole | AddPreference | UpdatePreference | DeletePreference | CreateSession | AddContext | UpdateContext | DeleteContext | AddTurn | EditTurn | BranchTurn | DeleteTurn | SwitchRole | AddSessionTopics | OverrideSessionPreferences | ForkSession | DeleteSession | BlobCommand;
697
+ interface CallTool extends BaseCommand {
698
+ type: 'tool:call';
699
+ payload: ToolCall;
700
+ }
701
+ /** Union of all possible commands that can be dispatched to the Workspace Manager. */
702
+ type Command = CreateWorkspace | AddRole | UpdateRole | DeleteRole | AddPreference | UpdatePreference | DeletePreference | CreateSession | UpdateSession | AddContext | UpdateContext | DeleteContext | AddTask | UpdateTask | DeleteTask | AddTurn | SaveTurn | EditTurn | BranchTurn | DeleteTurn | SwitchRole | AddSessionTopics | OverrideSessionPreferences | ForkSession | DeleteSession | BlobCommand | CallTool;
703
+ /** Configuration for token counting and management during prompt generation. */
489
704
  interface TokenBudget {
490
705
  total: number;
491
706
  estimator?: (text: string) => number;
492
707
  blobTokensPerKB?: number;
493
708
  }
709
+ /** Details regarding why a specific preference was excluded from a prompt. */
494
710
  interface PreferenceConflict {
495
711
  topic: string;
496
712
  kept: UUID;
497
713
  dropped: UUID;
498
714
  reason: 'superseded_by_newer';
499
715
  }
500
- interface ContextRelevanceConfig {
501
- recentMessageWindow?: number;
502
- minScore?: number;
503
- freshnessHalfLifeDays?: number;
504
- }
505
716
  /**
506
- * Prompt.transcript.turns is Turn[].
507
- * Synthetic turns produced by PromptAssembler (summary blocks, truncation
508
- * notices, referential attachments) carry generated UUIDs and version 0,
509
- * with parent: null. They are ephemeral — never stored, never patched.
717
+ * The final structure sent to an LLM provider.
718
+ * Assembled by the PromptAssembler by resolving roles, context, and history.
510
719
  */
511
720
  interface Prompt {
721
+ /** Information destined for the System Message. */
512
722
  system: {
513
723
  instructions?: string;
514
724
  persona: string;
515
725
  preferences: Preference[];
516
726
  context: Context[];
727
+ task: Task | null;
517
728
  };
729
+ /** Additional context items injected separately. */
518
730
  context: Context[];
731
+ /** The conversation history. */
519
732
  transcript: {
520
733
  turns: Turn[];
521
734
  };
@@ -524,6 +737,7 @@ interface Prompt {
524
737
  used: number;
525
738
  breakdown: Record<string, number>;
526
739
  };
740
+ /** Statistics on what was removed to fit within the token limit. */
527
741
  truncated: {
528
742
  preferences: number;
529
743
  interactions: number;
@@ -532,11 +746,116 @@ interface Prompt {
532
746
  warnings: string[];
533
747
  conflicts: PreferenceConflict[];
534
748
  }
535
- interface TranscriptWindow {
536
- sessionId: UUID;
537
- turns: Turn[];
538
- flushedCount: number;
539
- hasMore: boolean;
749
+ /** Typed events emitted by the Workspace when data changes. */
750
+ interface WorkspaceEvents {
751
+ /** Emitted when the index or core settings change. */
752
+ 'workspace:changed': DeepPartial<Workspace>;
753
+ /** Emitted when a blob is registered, updated, or removed. */
754
+ 'blobs:changed': {
755
+ sha256: SHA256;
756
+ record: BlobRecord | null;
757
+ };
758
+ }
759
+
760
+ /**
761
+ * Handles transcript compression and history management.
762
+ * When a conversation exceeds the model's context window, the Summarizer
763
+ * condenses older turns into a single summary string to reclaim tokens.
764
+ */
765
+ interface Summarizer {
766
+ /**
767
+ * Compresses the provided transcript.
768
+ * * @param transcript - The current list of conversation turns.
769
+ * @param tokenBudget - The maximum allowed tokens for the history.
770
+ * @returns A promise resolving to the summary and the remaining uncompressed turns.
771
+ */
772
+ summarize(transcript: Turn[], tokenBudget: number): Promise<{
773
+ summary: string;
774
+ remaining: Turn[];
775
+ }>;
776
+ }
777
+ /**
778
+ * Analyzes model outputs for side effects and workspace actions.
779
+ * The TurnProcessor scans the assistant's response (Turn) for specific
780
+ * triggers, such as file edits, UI updates, or state changes.
781
+ */
782
+ interface TurnProcessor {
783
+ /**
784
+ * Scans a turn for actionable blocks and returns workspace commands.
785
+ * @param turn - The assistant turn to be processed.
786
+ * @param sessionId - The session in which the turn was generated.
787
+ * @returns An array of Commands to synchronize the Workspace state.
788
+ */
789
+ process(turn: Turn, sessionId?: UUID): Command[];
790
+ }
791
+ /**
792
+ * Manages the lifecycle and execution of external tools.
793
+ * Acts as a central hub for discovering available capabilities and
794
+ * routing tool calls to their respective executors.
795
+ */
796
+ interface ToolRegistry {
797
+ /**
798
+ * Subscribes to changes in the tool ecosystem.
799
+ * @param callback - Invoked whenever tools are added, removed, or updated.
800
+ */
801
+ onRegistryChanged(callback: (tools: ToolSummary[]) => void): void;
802
+ /**
803
+ * Retrieves a list of all currently registered and available tools.
804
+ * @returns An array of summaries describing tool capabilities and schemas.
805
+ */
806
+ list(): ToolSummary[];
807
+ /**
808
+ * Executes a tool call in a stateless manner.
809
+ * * @template T - The expected return type of the tool execution.
810
+ * @param call - The specific tool call requested by the model.
811
+ * @returns A promise resolving to a Result wrapper containing the tool output.
812
+ */
813
+ execute<T = any>(call: ToolCall): Promise<Result<T>>;
814
+ }
815
+ /**
816
+ * Enforces security and authorization policies.
817
+ * * The PermissionGuard ensures that the current execution context (User/Session)
818
+ * has the necessary privileges to perform a requested action or tool call.
819
+ */
820
+ interface PermissionGuard {
821
+ /**
822
+ * Validates if the current context has the right to execute the request.
823
+ * * @param request - The authentication payload and target action.
824
+ * @returns A Result containing the authorized payload or an error.
825
+ */
826
+ authenticate(request: AuthRequest): Promise<Result<AuthRequest["payload"] | null>>;
827
+ }
828
+ /**
829
+ * Bridge between the internal Workspace types and external LLM APIs.
830
+ * This generic adapter allows the system to remain vendor-agnostic by
831
+ * centralizing the translation logic for different providers (Google, OpenAI, etc.).
832
+ * @template TRequest - The specific request shape expected by the provider SDK.
833
+ * @template TRequestParams - Extra parameters for the request (e.g., model name, temperature).
834
+ * @template TResponse - The raw response shape returned by the provider SDK.
835
+ */
836
+ interface LLMAdapter<TRequest, TRequestParams, TResponse> {
837
+ /**
838
+ * Maps the internal `Prompt` to the vendor-specific request format.
839
+ * * @param params - The prompt and provider-specific configuration.
840
+ * @returns The formatted request object ready for the SDK.
841
+ */
842
+ /**
843
+ * Prepares the request and identifies necessary side-effects (like uploads).
844
+ */
845
+ prepare(params: {
846
+ prompt: Prompt;
847
+ } & TRequestParams): Promise<{
848
+ request: TRequest;
849
+ effects?: Command[];
850
+ }>;
851
+ /**
852
+ * Maps the vendor-specific response back to an internal `Turn`.
853
+ * * @param params - The raw response received from the model API.
854
+ * @returns A standardized Turn object for the workspace transcript.
855
+ */
856
+ parse(params: {
857
+ response: TResponse;
858
+ }): Turn;
540
859
  }
541
860
 
542
861
  /**
@@ -971,32 +1290,35 @@ declare const COLLECTIONS: {
971
1290
  readonly CONTEXT: "context";
972
1291
  readonly SESSION: "session";
973
1292
  readonly TURN: "turn";
1293
+ readonly TASK: "task";
974
1294
  };
975
1295
  type CollectionName = typeof COLLECTIONS[keyof typeof COLLECTIONS];
976
1296
 
977
- /**
978
- * Utility type for representing partial updates to the state, allowing deep nesting.
979
- * It makes all properties optional and applies the same transformation recursively
980
- * to nested objects and array elements, allowing for selective updates while
981
- * preserving the original structure. It also includes the original type T and
982
- * undefined as possibilities for the top level and nested values.
983
- */
984
- type DeepPartial<T> = T extends object ? T extends readonly (infer U)[] ? readonly (DeepPartial<U> | undefined)[] | undefined | T : T extends (infer U)[] ? (DeepPartial<U> | undefined)[] | undefined | T : {
985
- [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> | undefined : T[K] | undefined;
986
- } | undefined | T : T | undefined;
987
-
988
1297
  declare function del<T>(): T;
989
1298
  declare const merge: <T extends object>(original: T, changes: DeepPartial<T> | symbol) => T;
990
1299
  declare function ok<T>(value: T): Result<T, never>;
991
1300
  declare function err<E = WorkspaceError>(error: E): Result<never, E>;
992
1301
  declare function omitNullUndefined<T extends Record<string, any>>(obj: T): Partial<T>;
993
- declare function createSimpleWorkspace({ name, owner, language }: {
1302
+ declare function createProjectWorkspace<ProjectMetadata extends Record<string, any> = Record<string, any>>({ project, language }: {
1303
+ language: string;
1304
+ project: Omit<Project<ProjectMetadata>, "id">;
1305
+ }): Workspace<ProjectMetadata>;
1306
+ declare function createSimpleWorkspace({ name, actor, language }: {
994
1307
  name: string;
995
1308
  language: string;
996
- owner: string;
1309
+ actor: string;
997
1310
  }): Workspace;
998
1311
  declare function extractBlobRecord(patch: DeepPartial<Workspace>): BlobRecord | null;
999
1312
  declare function extractBlobRef(record: BlobRecord): BlobRef;
1313
+ declare function computeSHA256(data: Uint8Array): Promise<SHA256>;
1314
+ /**
1315
+ * Creates a skeleton Role object with empty defaults.
1316
+ */
1317
+ declare const createEmptyRole: (name: string, label: string) => Role;
1318
+ /**
1319
+ * Isomorphic Base64 converter (Node.js / browser).
1320
+ */
1321
+ declare function bufferToBase64(data: ArrayBuffer | Uint8Array | number[]): string;
1000
1322
 
1001
1323
  /**
1002
1324
  * Persistence contract for binary blob content and blob registry records.
@@ -1045,10 +1367,6 @@ interface BlobStorage {
1045
1367
  registerBlob?(record: BlobRecord, data: Uint8Array): Promise<void>;
1046
1368
  }
1047
1369
 
1048
- interface TurnRef {
1049
- id: UUID;
1050
- version: number;
1051
- }
1052
1370
  declare class TurnTree {
1053
1371
  private readonly db;
1054
1372
  constructor(db: WorkspaceDatabase);
@@ -1059,20 +1377,26 @@ declare class TurnTree {
1059
1377
  * Uses only declared schema fields — never $id.
1060
1378
  */
1061
1379
  private turnFilter;
1380
+ private loadRaw;
1062
1381
  getHead(sessionId: UUID): Promise<TurnRef | null>;
1063
1382
  setHead(sessionId: UUID, head: TurnRef | null): Promise<void>;
1383
+ save(sessionId: UUID, turn: Turn, head?: TurnRef | null): Promise<Turn>;
1064
1384
  append(sessionId: UUID, turn: Turn): Promise<Turn>;
1065
1385
  appendBatch(sessionId: UUID, turns: Turn[], finalHead: TurnRef | null): Promise<void>;
1066
1386
  replaceVersion(sessionId: UUID, newTurn: Turn): Promise<void>;
1067
1387
  branch(sessionId: UUID, newTurn: Turn): Promise<void>;
1068
1388
  loadAllTurns(sessionId: UUID): Promise<Turn[]>;
1069
- getActiveChain(sessionId: UUID, dirtyBuffer?: readonly Turn[]): Promise<Turn[]>;
1389
+ loadTurnVersions(sessionId: UUID, turnId: UUID): Promise<Turn[]>;
1390
+ buildNodes(turns: Turn[], head: TurnRef | null, dirtyBuffer?: readonly Turn[]): Record<UUID, TurnNode>;
1070
1391
  buildNodeGraph(sessionId: UUID, dirtyBuffer?: readonly Turn[]): Promise<Record<UUID, TurnNode>>;
1392
+ getActiveChain(sessionId: UUID, dirtyBuffer?: readonly Turn[]): Promise<Turn[]>;
1393
+ buildActiveChain(sessionId: UUID): Promise<TurnNode[]>;
1394
+ getTurnSiblings(turnId: UUID, sessionId: UUID): Promise<TurnNode[]>;
1395
+ branchInfo(turnId: UUID, sessionId: UUID): Promise<BranchInfo>;
1071
1396
  deleteSubtree(sessionId: UUID, turnId: UUID, version: number, newHead: TurnRef | null): Promise<void>;
1072
1397
  copyTranscript(sourceSessionId: UUID, targetSessionId: UUID): Promise<void>;
1073
1398
  }
1074
1399
 
1075
- declare function computeSHA256(data: Uint8Array): Promise<SHA256>;
1076
1400
  interface BlobStoreConfig {
1077
1401
  /**
1078
1402
  * When true, blobs with refCount === 0 are deleted from the backend
@@ -1084,11 +1408,13 @@ interface BlobStoreConfig {
1084
1408
  declare class BlobStore {
1085
1409
  private readonly storage;
1086
1410
  private readonly config;
1411
+ private bus;
1087
1412
  /**
1088
1413
  * In-memory cache of BlobRecords. Kept consistent with the backend on
1089
1414
  * every write. Records are small (no bytes), so we cache all of them.
1090
1415
  */
1091
1416
  private readonly recordCache;
1417
+ constructor(backend: BlobStorage, bus: EventBus<WorkspaceEvents>, config?: BlobStoreConfig);
1092
1418
  /**
1093
1419
  * Called after any operation that changes the blob registry.
1094
1420
  * Passes the full BlobRecord (or null on deletion). The integration
@@ -1098,14 +1424,17 @@ declare class BlobStore {
1098
1424
  * that only need summary fields (sha256, mediaType, sizeBytes, etc.)
1099
1425
  * can read them directly from BlobRecord without a separate type.
1100
1426
  */
1101
- onRegistryChanged?: (sha256: SHA256, record: BlobRecord | null) => void;
1102
- constructor(backend: BlobStorage, config?: BlobStoreConfig);
1427
+ subscribe<TEventName extends keyof WorkspaceEvents>(event: TEventName, callback: (payload: WorkspaceEvents[TEventName]) => void): () => void;
1103
1428
  init(): Promise<void>;
1104
1429
  register(data: Uint8Array, mediaType: BlobMediaType, filename?: string): Promise<Result<BlobRef, WorkspaceError>>;
1105
1430
  retain(sha256: SHA256): Promise<Result<void, WorkspaceError>>;
1106
1431
  release(sha256: SHA256): Promise<Result<void, WorkspaceError>>;
1107
1432
  recordRemoteId(sha256: SHA256, providerId: string, fileId: string): Promise<Result<void, WorkspaceError>>;
1108
1433
  getRemoteId(sha256: SHA256, providerId: string): string | null;
1434
+ getRemoteRecord(sha256: SHA256, providerId: string): {
1435
+ id: string;
1436
+ timestamp: Timestamp;
1437
+ } | null;
1109
1438
  resolveRef(ref: BlobRef, providerId: string | null): Promise<Result<ResolvedBlob, WorkspaceError>>;
1110
1439
  resolveRefs(refs: BlobRef[], providerId: string | null): Promise<{
1111
1440
  resolved: Map<SHA256, ResolvedBlob>;
@@ -1115,7 +1444,6 @@ declare class BlobStore {
1115
1444
  }>;
1116
1445
  }>;
1117
1446
  gc(): Promise<number>;
1118
- gcFull(): Promise<number>;
1119
1447
  purge(sha256: SHA256): Promise<Result<void, WorkspaceError>>;
1120
1448
  getRecord(sha256: SHA256): BlobRecord | null;
1121
1449
  /**
@@ -1125,6 +1453,15 @@ declare class BlobStore {
1125
1453
  getAllRecords(): Record<SHA256, BlobRecord>;
1126
1454
  }
1127
1455
 
1456
+ interface CacheConfig {
1457
+ roles?: number;
1458
+ preferences?: number;
1459
+ context?: number;
1460
+ tasks?: number;
1461
+ }
1462
+ interface ContentStoreConfig {
1463
+ cache?: CacheConfig;
1464
+ }
1128
1465
  declare class ContentStore {
1129
1466
  private readonly db;
1130
1467
  readonly tree: TurnTree;
@@ -1132,17 +1469,11 @@ declare class ContentStore {
1132
1469
  private readonly roleCache;
1133
1470
  private readonly preferenceCache;
1134
1471
  private readonly contextCache;
1135
- /**
1136
- * Called after any blob registry change with the sha256 and updated
1137
- * BlobRecord (null on deletion). Wire this to your state manager to
1138
- * keep Index.blobs current.
1139
- *
1140
- * ContentStore sets this on BlobStore.onRegistryChanged internally.
1141
- * Consumers set this property to receive the forwarded notifications.
1142
- */
1143
- onBlobRegistryChanged?: (sha256: SHA256, record: BlobRecord | null) => void;
1472
+ private readonly taskCache;
1473
+ private bus;
1474
+ subscribe<TEventName extends keyof WorkspaceEvents>(event: TEventName, callback: (payload: WorkspaceEvents[TEventName]) => void): () => void;
1144
1475
  private constructor();
1145
- static create(db: WorkspaceDatabase, blobStorage: BlobStorage, config?: ContentStoreConfig): Promise<ContentStore>;
1476
+ static create(db: WorkspaceDatabase, blobStorage: BlobStorage, eventBus: EventBus<WorkspaceEvents>, config?: ContentStoreConfig): Promise<ContentStore>;
1146
1477
  private init;
1147
1478
  getTurnTree(): TurnTree;
1148
1479
  getRole(name: string): Promise<Result<Role, WorkspaceError>>;
@@ -1155,6 +1486,10 @@ declare class ContentStore {
1155
1486
  saveContext(context: Context): Promise<void>;
1156
1487
  deleteContext(key: string): Promise<void>;
1157
1488
  getContextByTopics(indexState: Index, topics: string[]): Promise<Context[]>;
1489
+ getTask(id: UUID): Promise<Result<Task, WorkspaceError>>;
1490
+ saveTask(task: Task): Promise<void>;
1491
+ deleteTask(id: UUID): Promise<void>;
1492
+ getTasksByTopics(indexState: Index, topics: string[]): Promise<Task[]>;
1158
1493
  saveSession(meta: SessionMeta): Promise<void>;
1159
1494
  updateSessionMeta(sessionId: UUID, patch: DeepPartial<SessionMeta>): Promise<void>;
1160
1495
  deleteSession(sessionId: UUID): Promise<void>;
@@ -1165,43 +1500,52 @@ declare class ContentStore {
1165
1500
  recordBlobRemoteId(sha256: SHA256, providerId: string, fileId: string): Promise<Result<void, WorkspaceError>>;
1166
1501
  getBlobRecord(sha256: SHA256): BlobRecord | null;
1167
1502
  getAllBlobRecords(): Record<SHA256, BlobRecord>;
1168
- /**
1169
- * Returns the blob resolver function expected by PromptBuilder.
1170
- * Closes over the internal BlobStore — no BlobStore reference leaks out.
1171
- */
1172
1503
  getBlobResolver(): BlobStore['resolveRefs'];
1173
- recordTurn(sessionId: UUID, turn: Turn): Promise<Result<void, WorkspaceError>>;
1504
+ appendTurn(sessionId: UUID, turn: Turn): Promise<Result<Turn, WorkspaceError>>;
1505
+ saveTurn(sessionId: UUID, turn: Turn): Promise<Result<Turn, WorkspaceError>>;
1174
1506
  editTurn(sessionId: UUID, turnId: UUID, newBlocks: ContentBlock[], newVersion: number, roleSnapshot?: string): Promise<Result<void, WorkspaceError>>;
1175
1507
  branchTurn(sessionId: UUID, newTurn: Turn): Promise<Result<void, WorkspaceError>>;
1176
1508
  deleteTurnSubtree(sessionId: UUID, turnId: UUID, version: number, newHead: TurnRef | null): Promise<Result<void, WorkspaceError>>;
1177
1509
  copyTranscript(sourceSessionId: UUID, targetSessionId: UUID): Promise<void>;
1178
1510
  resolveSession(workspace: Workspace, sessionId: UUID, transcript?: Turn[]): Promise<Result<EffectiveSession, WorkspaceError>>;
1511
+ gc(): Promise<number>;
1179
1512
  }
1180
1513
 
1181
- declare function workspaceReducer({ index: state }: Workspace, command: Command): Result<DeepPartial<Workspace>, WorkspaceError>;
1182
-
1183
1514
  declare class WorkspaceManager {
1184
1515
  private readonly contentStore;
1516
+ private readonly permissionGuard?;
1517
+ private readonly toolRegistry?;
1518
+ private readonly processor;
1519
+ private bus;
1520
+ constructor(options: {
1521
+ contentStore: ContentStore;
1522
+ permissionGuard?: PermissionGuard;
1523
+ toolRegistry?: ToolRegistry;
1524
+ eventBus: EventBus<WorkspaceEvents>;
1525
+ turnProcessor?: TurnProcessor;
1526
+ });
1527
+ store(): ContentStore;
1528
+ turnProcessor(): TurnProcessor;
1185
1529
  /**
1186
- * Called when BlobStore triggers a registry change outside of a dispatch()
1187
- * call e.g. eagerEviction deleting a blob on release. The caller should
1188
- * merge this patch into their Workspace.
1530
+ * Initializes a Workspace's in-memory Index from environment-static
1531
+ * sources (like ToolRegistry). Call this when opening a Workspace.
1189
1532
  */
1190
- onWorkspacePatch?: (patch: DeepPartial<Workspace>) => void;
1191
- constructor(contentStore: ContentStore);
1533
+ initTools(_: Workspace): DeepPartial<Workspace>;
1534
+ /**
1535
+ * Called after any workspace change
1536
+ */
1537
+ subscribe<TEventName extends keyof WorkspaceEvents>(event: TEventName, callback: (payload: WorkspaceEvents[TEventName]) => void): () => void;
1192
1538
  reduce(workspace: Workspace, command: Command): Result<DeepPartial<Workspace>, WorkspaceError>;
1193
1539
  dispatch(workspace: Workspace, command: Command): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1194
- resolveSession(workspace: Workspace, sessionId: UUID): Promise<Result<EffectiveSession, WorkspaceError>>;
1540
+ resolveSession(workspace: Workspace, sessionId: UUID, transcript?: Turn[]): Promise<Result<EffectiveSession, WorkspaceError>>;
1195
1541
  private handleContentSideEffects;
1196
1542
  }
1197
1543
 
1198
- interface Summarizer {
1199
- summarize(transcript: Turn[], tokenBudget: number): Promise<{
1200
- summary: string;
1201
- remaining: Turn[];
1202
- }>;
1544
+ interface ContextRelevanceConfig {
1545
+ recentMessageWindow?: number;
1546
+ minScore?: number;
1547
+ freshnessHalfLifeDays?: number;
1203
1548
  }
1204
-
1205
1549
  interface ContextRankingInput {
1206
1550
  entries: Context[];
1207
1551
  recentMessages: string[];
@@ -1215,12 +1559,14 @@ interface PlanningInput {
1215
1559
  persona: string;
1216
1560
  preferences: Preference[];
1217
1561
  context: Context[];
1562
+ task: Task | null;
1218
1563
  transcript: Turn[];
1219
1564
  budget?: TokenBudget;
1220
1565
  }
1221
1566
  interface PlanningOutput {
1222
1567
  preferences: Preference[];
1223
1568
  context: Context[];
1569
+ task: Task | null;
1224
1570
  transcript: Turn[];
1225
1571
  truncated: {
1226
1572
  preferences: number;
@@ -1272,52 +1618,287 @@ declare class PromptBuilder {
1272
1618
  private resolvePreferenceConflicts;
1273
1619
  }
1274
1620
 
1621
+ /**
1622
+ * A fluent builder for creating Turn objects.
1623
+ * This class helps construct a Turn object by adding various content blocks.
1624
+ */
1625
+ declare class TurnBuilder {
1626
+ private readonly _actor;
1627
+ private _turn;
1628
+ constructor(_actor: TurnActor, initialTurn?: Turn);
1629
+ addText(text: string): TurnBuilder;
1630
+ addImage(ref?: BlobRef, altText?: string): TurnBuilder;
1631
+ addDocument(ref?: BlobRef, title?: string): TurnBuilder;
1632
+ addToolUse(name: string, input: Record<string, unknown>): TurnBuilder;
1633
+ addToolResult(useId: UUID, content: string | Record<string, unknown>, isError?: boolean): TurnBuilder;
1634
+ addSummary(text: string): TurnBuilder;
1635
+ addRoleTransition(previousRole: string | null, newRole: string): TurnBuilder;
1636
+ addThinking(thinking: string): TurnBuilder;
1637
+ /**
1638
+ * Adds a task proposal block.
1639
+ * @param title The task title.
1640
+ * @param steps Array of step objects (each with text and optional id/status). Status defaults to 'todo'.
1641
+ * @param action The action type ('create', 'update', 'complete'). Defaults to 'create'.
1642
+ * @param taskId Optional existing task ID (for update/complete).
1643
+ */
1644
+ addTaskProposal(title: string, steps: {
1645
+ text: string;
1646
+ status?: 'todo' | 'done';
1647
+ id?: UUID;
1648
+ }[], action?: 'create' | 'update' | 'complete', taskId?: UUID): TurnBuilder;
1649
+ addBlock(block: ContentBlock): TurnBuilder;
1650
+ deleteBlock(blockId: UUID): TurnBuilder;
1651
+ editTextBlock(blockId: UUID, newText: string): TurnBuilder;
1652
+ withId(id: UUID): TurnBuilder;
1653
+ withVersion(version: number): TurnBuilder;
1654
+ withTimestamp(timestamp: Timestamp): TurnBuilder;
1655
+ withParent(parent: TurnRef): TurnBuilder;
1656
+ withRoleSnapshot(roleSnapshot: string): TurnBuilder;
1657
+ build(): Turn;
1658
+ }
1659
+
1660
+ declare class DefaultTurnProcessor implements TurnProcessor {
1661
+ private readonly handlers;
1662
+ process(turn: Turn, sessionId?: UUID): Command[];
1663
+ }
1664
+
1275
1665
  declare class Session {
1276
- /** The session ID this object manages. */
1277
- readonly sessionId: UUID;
1666
+ private readonly sessionId;
1667
+ private readonly tree;
1668
+ private readonly manager;
1669
+ constructor(sessionId: UUID, tree: TurnTree, manager: WorkspaceManager);
1670
+ /** Returns the UUID of this session. */
1671
+ id(): UUID;
1278
1672
  /**
1279
- * The turn DAG. Keys are turn IDs. Mutated in-place on every write.
1280
- * Callers read this directly for rendering — no copy is made.
1673
+ * Retrieves the full metadata record for this session from the workspace index.
1281
1674
  */
1282
- readonly nodes: Record<UUID, TurnNode>;
1675
+ meta(workspace: Workspace): SessionMeta | undefined;
1676
+ /** Returns the human-readable label for the session. */
1677
+ label(workspace: Workspace): string | undefined;
1678
+ /** Returns the name of the role currently assigned to this session. */
1679
+ private roleName;
1283
1680
  /**
1284
- * Current head of the active branch. Mirrors what is in
1285
- * workspace.index.sessions[sessionId].head after each patch is applied.
1286
- * Session keeps its own copy so reads don't require workspace.
1681
+ * Returns the RoleSummary (label, description, etc.) for the session's active role.
1682
+ */
1683
+ role(workspace: Workspace): RoleSummary | undefined;
1684
+ /** Returns the list of topics associated with this session. */
1685
+ topics(workspace: Workspace): string[];
1686
+ /** Returns the list of preference IDs overriding defaults for this session. */
1687
+ preferences(workspace: Workspace): UUID[];
1688
+ /**
1689
+ * Returns the current "head" pointer (turnId and version) of the conversation DAG.
1690
+ */
1691
+ head(workspace: Workspace): TurnRef | null;
1692
+ /**
1693
+ * Returns the full Task object if the session is currently linked to a task.
1694
+ */
1695
+ task(workspace: Workspace): Promise<Task | undefined>;
1696
+ /**
1697
+ * Returns the TaskSummary if the session is currently linked to a task.
1698
+ */
1699
+ taskSummary(workspace: Workspace): TaskSummary | undefined;
1700
+ /**
1701
+ * Checks whether the session is linked to any task.
1702
+ */
1703
+ hasTask(workspace: Workspace): boolean;
1704
+ /**
1705
+ * Builds the active conversation chain (the current linear history) as an array
1706
+ * of TurnNode objects, following the head pointer and parent links.
1707
+ */
1708
+ turns(): Promise<TurnNode[]>;
1709
+ /**
1710
+ * Returns all sibling turns of the given turn (other turns that share the same parent).
1711
+ */
1712
+ siblings(turnId: UUID): Promise<TurnNode[]>;
1713
+ /**
1714
+ * Returns version‑branching information for a given turn, including available versions,
1715
+ * current index, and navigation capabilities.
1716
+ */
1717
+ branchInfo(turnId: UUID): Promise<BranchInfo>;
1718
+ /**
1719
+ * Retrieves a single turn node by its ID from the session graph.
1720
+ */
1721
+ getTurn(turnId: UUID): Promise<TurnNode | undefined>;
1722
+ /**
1723
+ * Changes the session's display label.
1724
+ * @param workspace Current workspace state.
1725
+ * @param newLabel New human‑readable label.
1726
+ * @returns A patch to merge into the workspace state.
1727
+ */
1728
+ rename(workspace: Workspace, newLabel: string): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1729
+ /**
1730
+ * Replaces the session's topic list entirely.
1731
+ * @param workspace Current workspace state.
1732
+ * @param topics New array of topics (overwrites existing).
1733
+ * @returns A patch to merge into the workspace state.
1734
+ */
1735
+ setTopics(workspace: Workspace, topics: string[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1736
+ /**
1737
+ * Adds topics to the session (union, no duplicates).
1738
+ * @param workspace Current workspace state.
1739
+ * @param topics Topics to add.
1740
+ * @returns A patch to merge into the workspace state.
1741
+ */
1742
+ addTopics(workspace: Workspace, topics: string[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1743
+ /**
1744
+ * Replaces the session's preference override list entirely.
1745
+ * @param workspace Current workspace state.
1746
+ * @param preferenceIds New array of preference IDs.
1747
+ * @returns A patch to merge into the workspace state.
1748
+ */
1749
+ setPreferences(workspace: Workspace, preferenceIds: UUID[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1750
+ /**
1751
+ * Links the session to a task, or removes the link if taskId is null.
1752
+ * @param workspace Current workspace state.
1753
+ * @param taskId ID of the task to link, or null to unlink.
1754
+ * @returns A patch to merge into the workspace state.
1755
+ */
1756
+ setActiveTask(workspace: Workspace, taskId: UUID | null): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1757
+ /**
1758
+ * Removes the link between the session and its current task (if any).
1759
+ * @param workspace Current workspace state.
1760
+ * @returns A patch to merge into the workspace state.
1761
+ */
1762
+ unsetTask(workspace: Workspace): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1763
+ createTask(workspace: Workspace, title: string, description: string | undefined, steps: {
1764
+ text: string;
1765
+ }[], topics: string[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1766
+ /**
1767
+ * Creates a new session as a fork (copy) of this one.
1768
+ * @param workspace Current workspace state.
1769
+ * @param newSessionId Unique ID for the new session.
1770
+ * @param label Display label for the new session.
1771
+ * @param role Optional role override (defaults to current role).
1772
+ * @param topics Optional topic override (defaults to current topics).
1773
+ * @returns A patch to merge into the workspace state.
1774
+ */
1775
+ fork(workspace: Workspace, newSessionId: UUID, label: string, role?: string, topics?: string[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1776
+ /**
1777
+ * Permanently deletes this session and all its turns from the workspace.
1778
+ * @param workspace Current workspace state.
1779
+ * @returns A patch to merge into the workspace state.
1780
+ */
1781
+ delete(workspace: Workspace): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1782
+ dispatch(workspace: Workspace, command: Command): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1783
+ /**
1784
+ * Switches the session to a different role.
1785
+ * @param workspace Current workspace state.
1786
+ * @param newRole Name of the target role (must exist in the workspace).
1787
+ * @returns A patch to merge into the workspace state.
1788
+ */
1789
+ switchRole(workspace: Workspace, newRole: string): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1790
+ /**
1791
+ * Returns all available roles in the workspace.
1792
+ */
1793
+ listRoles(workspace: Workspace): RoleSummary[];
1794
+ /**
1795
+ * Returns a specific role by name, or undefined if not found.
1796
+ */
1797
+ getRole(workspace: Workspace, name: string): RoleSummary | undefined;
1798
+ /**
1799
+ * Creates a new role.
1800
+ * @param workspace Current workspace state.
1801
+ * @param name Unique identifier for the role (e.g., "software-architect").
1802
+ * @param label Human-readable display label.
1803
+ * @param persona The system prompt / instructions for this role.
1804
+ * @param description Optional description.
1805
+ * @param preferenceIds Optional array of preference IDs to associate.
1806
+ * @returns A patch to merge into the workspace state.
1807
+ */
1808
+ createRole(workspace: Workspace, name: string, label: string, persona: string, description?: string, preferenceIds?: UUID[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1809
+ /**
1810
+ * Updates an existing role.
1811
+ * @param workspace Current workspace state.
1812
+ * @param name Name of the role to update (must exist).
1813
+ * @param updates Partial updates (label, description, persona, preferences).
1814
+ * @returns A patch to merge into the workspace state.
1815
+ */
1816
+ updateRole(workspace: Workspace, name: string, updates: Partial<Pick<Role, 'label' | 'description' | 'persona' | 'preferences'>>): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1817
+ /**
1818
+ * Deletes a role. Fails if the role is still referenced by any session.
1819
+ * @param workspace Current workspace state.
1820
+ * @param name Name of the role to delete.
1821
+ * @returns A patch to merge into the workspace state.
1822
+ */
1823
+ deleteRole(workspace: Workspace, name: string): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1824
+ /**
1825
+ * Saves a constructed Turn object to the session. The turn's parent is automatically
1826
+ * set to the current head of the active chain unless overridden in the turn object.
1827
+ * @param workspace Current workspace state.
1828
+ * @param turn The Turn object (can be built with startTurn()).
1829
+ * @returns A patch to merge into the workspace state.
1287
1830
  */
1288
- private head;
1289
- /** Turns not yet flushed to storage. */
1290
- private readonly dirtyBuffer;
1291
- private flushTimer;
1292
- private flushChain;
1293
- private readonly flushConfig;
1294
- private readonly tree;
1295
- private readonly contentStore;
1296
- constructor(sessionId: UUID, nodes: Record<UUID, TurnNode>, head: TurnRef | null, tree: TurnTree, contentStore: ContentStore, flushConfig?: FlushConfig);
1297
- activeChain(): TurnNode[];
1298
- siblings(turnId: UUID): TurnNode[];
1299
- branchInfo(turnId: UUID): BranchInfo;
1300
1831
  addTurn(workspace: Workspace, turn: Turn): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1832
+ recordUserTurn(workspace: Workspace, turn: Turn): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1833
+ recordAssistantTurn(workspace: Workspace, turn: Turn, recordDenial?: boolean): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1834
+ private buildDenialTurn;
1835
+ private describeCommand;
1836
+ /**
1837
+ * Creates a new version of an existing turn with updated content.
1838
+ * @param workspace Current workspace state.
1839
+ * @param turnId ID of the turn to edit.
1840
+ * @param newBlocks New content blocks for the turn.
1841
+ * @param roleSnapshot Optional role name to record with this version.
1842
+ * @returns A patch to merge into the workspace state.
1843
+ */
1301
1844
  editTurn(workspace: Workspace, turnId: UUID, newBlocks: ContentBlock[], roleSnapshot?: string): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1302
- branchFrom(workspace: Workspace, newTurn: Turn): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1845
+ /**
1846
+ * Creates a new branch from a specific turn (the parent must be set on the turn).
1847
+ * @param workspace Current workspace state.
1848
+ * @param turn The new turn that continues from an existing parent.
1849
+ * @returns A patch to merge into the workspace state.
1850
+ */
1851
+ branch(workspace: Workspace, turn: Turn): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1852
+ /**
1853
+ * Deletes a specific version of a turn and all its descendants.
1854
+ * @param workspace Current workspace state.
1855
+ * @param turnId ID of the turn to delete.
1856
+ * @param version Version number of the turn to delete.
1857
+ * @param newHead Optional new head pointer after deletion.
1858
+ * @returns A patch to merge into the workspace state.
1859
+ */
1303
1860
  deleteTurn(workspace: Workspace, turnId: UUID, version: number, newHead: TurnRef | null): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1304
- switchVersionLeft(_: Workspace, turnId: UUID): Result<DeepPartial<Workspace>, WorkspaceError>;
1305
- switchVersionRight(_: Workspace, turnId: UUID): Result<DeepPartial<Workspace>, WorkspaceError>;
1861
+ /**
1862
+ * Switch to the previous version of a turn (if available).
1863
+ * This changes the active chain head but does not create new data.
1864
+ * @param workspace Current workspace state.
1865
+ * @param turnId ID of the turn whose version to switch.
1866
+ * @returns A patch to merge into the workspace state.
1867
+ */
1868
+ switchVersionLeft(workspace: Workspace, turnId: UUID): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1869
+ /**
1870
+ * Switch to the next version of a turn (if available).
1871
+ * This changes the active chain head but does not create new data.
1872
+ * @param workspace Current workspace state.
1873
+ * @param turnId ID of the turn whose version to switch.
1874
+ * @returns A patch to merge into the workspace state.
1875
+ */
1876
+ switchVersionRight(workspace: Workspace, turnId: UUID): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1306
1877
  private switchVersion;
1878
+ addPreference(workspace: Workspace, content: string, topics: string[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1879
+ listPreferences(workspace: Workspace): Promise<PreferenceSummary[]>;
1880
+ addContext(workspace: Workspace, key: string, content: ContextContent, topics: string[], metadata?: Record<string, any>): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
1881
+ listContextSummaries(workspace: Workspace): Promise<ContextSummary[]>;
1882
+ /**
1883
+ * Registers a new blob in the workspace and returns its SHA256 and BlobRef.
1884
+ * This dispatches a blob:register command and extracts the resulting SHA256
1885
+ * from the returned workspace patch.
1886
+ */
1887
+ registerBlob(workspace: Workspace, data: Uint8Array, mediaType: BlobMediaType, filename?: string): Promise<Result<{
1888
+ sha256: SHA256;
1889
+ ref: BlobRef;
1890
+ }, WorkspaceError>>;
1891
+ /**
1892
+ * Resolves the session into an EffectiveSession object, which bundles the
1893
+ * session metadata, role, preferences, context, transcript, and linked task.
1894
+ * @param workspace Current workspace state.
1895
+ * @returns The resolved effective session or an error.
1896
+ */
1307
1897
  resolve(workspace: Workspace): Promise<Result<EffectiveSession, WorkspaceError>>;
1308
- flush(): Promise<void>;
1309
- dispose(): Promise<void>;
1310
- private findSubtreeTipForVersion;
1311
- private collectSubtreeIds;
1312
- private upsertNode;
1313
- private scheduleFlush;
1314
- private cancelFlushTimer;
1315
- private doFlush;
1316
- }
1317
- declare function buildTurnNode(turn: Turn, children?: UUID[]): TurnNode;
1898
+ private findSubtreeTip;
1899
+ }
1318
1900
 
1319
1901
  interface SessionManagerConfig {
1320
- flush?: Partial<FlushConfig>;
1321
1902
  }
1322
1903
  interface OpenResult {
1323
1904
  session: Session;
@@ -1326,11 +1907,30 @@ interface OpenResult {
1326
1907
  declare class SessionManager {
1327
1908
  private readonly workspaceManager;
1328
1909
  private readonly contentStore;
1329
- private readonly flushConfig;
1330
- constructor(workspaceManager: WorkspaceManager, contentStore: ContentStore, config?: SessionManagerConfig);
1910
+ constructor(workspaceManager: WorkspaceManager, contentStore: ContentStore);
1911
+ /**
1912
+ * Returns an array of all session metadata entries in the workspace.
1913
+ */
1914
+ list(workspace: Workspace): SessionMeta[];
1915
+ /**
1916
+ * Retrieves the metadata for a specific session without hydrating a Session object.
1917
+ */
1918
+ meta(workspace: Workspace, sessionId: UUID): SessionMeta | undefined;
1919
+ /**
1920
+ * Creates a new session and returns a hydrated Session instance.
1921
+ * This method dispatches a 'session:create' command which is validated by the
1922
+ * reducer (checking for unique IDs and valid roles) and persisted
1923
+ * to the content store.
1924
+ */
1925
+ create(workspace: Workspace, params: {
1926
+ label: string;
1927
+ role?: string;
1928
+ topics?: string[];
1929
+ preferences?: UUID[];
1930
+ }): Promise<Result<OpenResult, WorkspaceError>>;
1331
1931
  open(workspace: Workspace, sessionId: UUID): Promise<Result<OpenResult, WorkspaceError>>;
1332
- close(session: Session): Promise<void>;
1333
1932
  get workspace(): WorkspaceManager;
1933
+ close(_: Session): Promise<void>;
1334
1934
  }
1335
1935
 
1336
1936
  /**
@@ -1400,4 +2000,37 @@ declare class IndexedDBBlobStorage implements BlobStorage {
1400
2000
  registerBlob(record: BlobRecord, data: Uint8Array): Promise<void>;
1401
2001
  }
1402
2002
 
1403
- export { type AddContext, type AddPreference, type AddRole, type AddSessionTopics, type AddTurn, type BaseCommand, type BlobCommand, type BlobMediaType, type BlobRecord, type BlobRef, type BlobStorage, BlobStore, type BlobStoreConfig, type BranchInfo, type BranchTurn, COLLECTIONS, type CacheConfig, type CollectionName, type Command, type ContentBlock, ContentStore, type ContentStoreConfig, type Context, type ContextContent, type ContextRelevanceConfig, type ContextSummary, type CreateSession, type CreateWorkspace, type DeleteContext, type DeletePreference, type DeleteRole, type DeleteSession, type DeleteTurn, type DocumentBlock, type DocumentMediaType, type EditTurn, type EffectiveSession, type FlushConfig, type ForkSession, type ImageBlock, type ImageMediaType, type Index, type IndexedDBBlobConfig, IndexedDBBlobStorage, MemoryBlobStorage, type OpenResult, type OverrideSessionPreferences, type Preference, type PreferenceConflict, type PreferenceSummary, type Project, type Prompt, PromptBuilder, type PurgeBlob, type RecordBlobRemoteId, type RegisterBlob, type ReleaseBlob, type ResolvedBlob, type Result, type RetainBlob, type Role, type RoleSummary, type RoleTransitionBlock, type SHA256, Session, SessionManager, type SessionManagerConfig, type SessionMeta, type Settings, type SummaryBlock, type SwitchRole, type TextBlock, type ThinkingBlock, type Timestamp, type TokenBudget, type ToolResultBlock, type ToolUseBlock, type TopicIndex, type TranscriptWindow, type Turn, type TurnNode, type TurnRef, type TurnRole, TurnTree, type URI, type UUID, type UpdateContext, type UpdatePreference, type UpdateRole, type Workspace, type WorkspaceBundle, type WorkspaceDatabase, type WorkspaceError, WorkspaceManager, buildTurnNode, computeSHA256, createSimpleWorkspace, createWorkspaceDatabase, del, err, extractBlobRecord, extractBlobRef, merge, ok, omitNullUndefined, workspaceReducer };
2003
+ declare class GoogleGenAIAdapter implements LLMAdapter<{
2004
+ model: string;
2005
+ }, GenerateContentParameters, GenerateContentResponse> {
2006
+ private _;
2007
+ constructor(_: GoogleGenAI);
2008
+ /**
2009
+ * Converts a Prompt into a GenerateContentRequest for @google/genai.
2010
+ */
2011
+ prepare({ prompt, model }: {
2012
+ prompt: Prompt;
2013
+ model: string;
2014
+ }): Promise<{
2015
+ request: {
2016
+ model: string;
2017
+ contents: _google_genai.Content[];
2018
+ config: {
2019
+ systemInstruction: _google_genai.Content;
2020
+ thinkingConfig: {
2021
+ includeThoughts: boolean;
2022
+ };
2023
+ responseMimeType: string;
2024
+ responseSchema: _google_genai.Schema;
2025
+ };
2026
+ };
2027
+ }>;
2028
+ /**
2029
+ * Parses the GenerateContentResponse into a Turn (assistant turn).
2030
+ */
2031
+ parse({ response }: {
2032
+ response: GenerateContentResponse;
2033
+ }): Turn;
2034
+ }
2035
+
2036
+ export { type AddContext, type AddPreference, type AddRole, type AddSessionTopics, type AddTask, type AddTurn, type AuthRequest, type BackendError, type BaseCommand, type BlobCommand, type BlobError, type BlobMediaType, type BlobRecord, type BlobRef, type BlobStorage, BlobStore, type BlobStoreConfig, type BranchInfo, type BranchTurn, COLLECTIONS, type CallTool, type CollectionName, type Command, type ContentBlock, ContentStore, type Context, type ContextContent, type ContextSummary, type CreateSession, type CreateWorkspace, DefaultTurnProcessor, type DeleteContext, type DeletePreference, type DeleteRole, type DeleteSession, type DeleteTask, type DeleteTurn, type DocumentBlock, type DocumentMediaType, type DuplicateKeyError, EMPTY_SYSTEM_ROLE, type EditTurn, type EffectiveSession, type ForkSession, GoogleGenAIAdapter, type ImageBlock, type ImageMediaType, type Index, type IndexedDBBlobConfig, IndexedDBBlobStorage, type InvalidCommandError, type LLMAdapter, MemoryBlobStorage, type NotFoundError, type OpenResult, type OverrideSessionPreferences, type PermissionDeniedError, type PermissionGuard, type Preference, type PreferenceConflict, type PreferenceSummary, type Project, type Prompt, PromptBuilder, type PurgeBlob, type RecordBlobRemoteId, type RegisterBlob, type ReleaseBlob, type ResolvedBlob, type Result, type RetainBlob, type Role, type RoleSummary, type RoleTransitionBlock, type SHA256, type SaveTurn, Session, SessionManager, type SessionManagerConfig, type SessionMeta, type Settings, type Summarizer, type SummaryBlock, type SwitchRole, type Task, type TaskProposalBlock, type TaskStatus, type TaskStep, type TaskSummary, type TextBlock, type ThinkingBlock, type Timestamp, type TokenBudget, type ToolCall, type ToolRegistry, type ToolResultBlock, type ToolSummary, type ToolUseBlock, type TopicIndex, type Turn, type TurnActor, TurnBuilder, type TurnNode, type TurnProcessor, type TurnRef, TurnTree, type URI, type UUID, type UpdateContext, type UpdatePreference, type UpdateRole, type UpdateSession, type UpdateTask, type Workspace, type WorkspaceBundle, type WorkspaceDatabase, type WorkspaceError, type WorkspaceEvents, WorkspaceManager, bufferToBase64, computeSHA256, createEmptyRole, createProjectWorkspace, createSimpleWorkspace, createWorkspaceDatabase, del, err, extractBlobRecord, extractBlobRef, merge, ok, omitNullUndefined };