@asaidimu/utils-workspace 6.4.1 → 6.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/index.d.mts +53 -3
- package/index.d.ts +53 -3
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
package/index.d.mts
CHANGED
|
@@ -784,6 +784,8 @@ interface Turn {
|
|
|
784
784
|
timestamp: Timestamp;
|
|
785
785
|
/** Name of the role (persona) active at the exact time this turn occurred. */
|
|
786
786
|
role?: string;
|
|
787
|
+
/** Name of the model that produced this turn. */
|
|
788
|
+
model?: string;
|
|
787
789
|
/** Link to the preceding turn in the conversation tree, defining the DAG graph. */
|
|
788
790
|
parent?: {
|
|
789
791
|
/** The ID of the parent turn. */
|
|
@@ -793,6 +795,8 @@ interface Turn {
|
|
|
793
795
|
};
|
|
794
796
|
/** Local model constraints applied explicitly at the time of this turn. */
|
|
795
797
|
constraints?: ModelConstraintMap;
|
|
798
|
+
/** Extensible key-value store for turn-specific metadata (e.g., error logs). */
|
|
799
|
+
metadata?: Record<string, any>;
|
|
796
800
|
}
|
|
797
801
|
/** Unique composite key used to lookup a specific turn version. */
|
|
798
802
|
type TurnKey = Pick<Turn, "version" | "id" | "session">;
|
|
@@ -815,6 +819,8 @@ interface TurnNode {
|
|
|
815
819
|
timestamp: Timestamp;
|
|
816
820
|
/** The role name active when this node was created. */
|
|
817
821
|
roleSnapshot?: string;
|
|
822
|
+
/** The model name active when this node was created. */
|
|
823
|
+
modelSnapshot?: string;
|
|
818
824
|
/** Reference to the preceding turn in the conversation DAG. */
|
|
819
825
|
parent?: {
|
|
820
826
|
/** Parent turn ID. */
|
|
@@ -1210,6 +1216,7 @@ interface EditTurn extends BaseCommand {
|
|
|
1210
1216
|
newBlocks: ContentBlock[];
|
|
1211
1217
|
newVersion: number;
|
|
1212
1218
|
roleSnapshot?: string;
|
|
1219
|
+
modelSnapshot?: string;
|
|
1213
1220
|
};
|
|
1214
1221
|
}
|
|
1215
1222
|
/** Creates a new branch in the conversation history from a specific turn. */
|
|
@@ -2544,6 +2551,29 @@ declare class WorkspaceManager {
|
|
|
2544
2551
|
ctx(): WorkspaceContext;
|
|
2545
2552
|
}
|
|
2546
2553
|
|
|
2554
|
+
/**
|
|
2555
|
+
* A lightweight registry for managing workspaces without full initialization.
|
|
2556
|
+
* Solves the 'chicken and egg' problem where you need a workspace to delete a workspace.
|
|
2557
|
+
*/
|
|
2558
|
+
declare class WorkspaceRegistry {
|
|
2559
|
+
private readonly db;
|
|
2560
|
+
constructor(db: Database);
|
|
2561
|
+
/**
|
|
2562
|
+
* Lists all workspaces currently registered in the database.
|
|
2563
|
+
*/
|
|
2564
|
+
list(): Promise<WorkspaceMetadata[]>;
|
|
2565
|
+
/**
|
|
2566
|
+
* Deletes a workspace record.
|
|
2567
|
+
* Note: This does not currently purge associated data (sessions, turns)
|
|
2568
|
+
* as they are not explicitly linked to the workspace ID in the flat schema.
|
|
2569
|
+
*/
|
|
2570
|
+
delete(id: UUID): Promise<boolean>;
|
|
2571
|
+
/**
|
|
2572
|
+
* Purges ALL collections in the database.
|
|
2573
|
+
* Useful for a total reset. Use with extreme caution.
|
|
2574
|
+
*/
|
|
2575
|
+
purge(): Promise<void>;
|
|
2576
|
+
}
|
|
2547
2577
|
declare class WorkspaceApi {
|
|
2548
2578
|
private readonly manager;
|
|
2549
2579
|
constructor(manager: WorkspaceManager);
|
|
@@ -2601,6 +2631,14 @@ declare class Session {
|
|
|
2601
2631
|
getTurn(turnId: UUID): Promise<TurnNode | undefined>;
|
|
2602
2632
|
rename(newLabel: string): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2603
2633
|
setTopics(topics: string[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2634
|
+
/**
|
|
2635
|
+
* Updates the session's model identifier.
|
|
2636
|
+
*/
|
|
2637
|
+
setModel(model: string): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2638
|
+
/**
|
|
2639
|
+
* Merges the provided metadata into the session's current metadata.
|
|
2640
|
+
*/
|
|
2641
|
+
updateMetadata(metadata: Record<string, any>): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2604
2642
|
addTopics(topics: string[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2605
2643
|
setPreferences(preferenceIds: UUID[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2606
2644
|
fork(newSessionId: UUID, label: string, role?: string, topics?: string[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
@@ -2611,9 +2649,13 @@ declare class Session {
|
|
|
2611
2649
|
recordAssistantTurn(turn: Turn, recordDenial?: boolean): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2612
2650
|
private buildDenialTurn;
|
|
2613
2651
|
private describeCommand;
|
|
2614
|
-
editTurn(turnId: UUID, newBlocks: ContentBlock[], roleSnapshot?: string): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2652
|
+
editTurn(turnId: UUID, newBlocks: ContentBlock[], roleSnapshot?: string, modelSnapshot?: string): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2615
2653
|
branch(turn: Turn): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2616
2654
|
deleteTurn(turnId: UUID, version: number, newHead: TurnRef | null): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2655
|
+
/**
|
|
2656
|
+
* Updates the status of a specific turn using the Result pattern.
|
|
2657
|
+
*/
|
|
2658
|
+
updateTurnStatus(turnId: UUID, status: Result<undefined, WorkspaceError>): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2617
2659
|
switchVersionLeft(turnId: UUID): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2618
2660
|
switchVersionRight(turnId: UUID): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2619
2661
|
private switchVersion;
|
|
@@ -2628,7 +2670,7 @@ declare class Session {
|
|
|
2628
2670
|
*
|
|
2629
2671
|
* Returns undefined if the session no longer exists in the workspace index.
|
|
2630
2672
|
*/
|
|
2631
|
-
snapshot(): Promise<SessionSnapshot | undefined>;
|
|
2673
|
+
snapshot(turnId?: UUID): Promise<SessionSnapshot | undefined>;
|
|
2632
2674
|
private refreshTurnTree;
|
|
2633
2675
|
private findSubtreeTip;
|
|
2634
2676
|
}
|
|
@@ -2676,6 +2718,8 @@ declare class TurnBuilder {
|
|
|
2676
2718
|
withTimestamp(timestamp: Timestamp): TurnBuilder;
|
|
2677
2719
|
withParent(parent: TurnRef): TurnBuilder;
|
|
2678
2720
|
withRoleSnapshot(roleSnapshot: string): TurnBuilder;
|
|
2721
|
+
withRole(role: string): TurnBuilder;
|
|
2722
|
+
withModel(model: string): TurnBuilder;
|
|
2679
2723
|
build(): Turn;
|
|
2680
2724
|
}
|
|
2681
2725
|
|
|
@@ -2735,6 +2779,10 @@ declare class TurnTree {
|
|
|
2735
2779
|
static build(sessionId: UUID, repository: TurnRepository): Promise<TurnTree>;
|
|
2736
2780
|
head(): TurnRef | null;
|
|
2737
2781
|
chain(): TurnNode[];
|
|
2782
|
+
/**
|
|
2783
|
+
* Returns a chronological chain of TurnNodes ending at the specified turn.
|
|
2784
|
+
*/
|
|
2785
|
+
chainFrom(turnId: UUID): TurnNode[];
|
|
2738
2786
|
getTurnSiblings(turnId: UUID): TurnNode[];
|
|
2739
2787
|
branchInfo(turnId: UUID): BranchInfo;
|
|
2740
2788
|
graph(): Readonly<Record<UUID, TurnNode>>;
|
|
@@ -2867,6 +2915,8 @@ declare const GOOGLE_MODELS: Array<ModelProfile>;
|
|
|
2867
2915
|
* - Block validation and construction is fully delegated to the registry.
|
|
2868
2916
|
* Unknown block types returned by the model are silently dropped (registry
|
|
2869
2917
|
* returns null for unregistered types) and logged by the registry itself.
|
|
2918
|
+
* - If the model ignores the structured JSON schema and returns raw text,
|
|
2919
|
+
* it automatically wraps the response in a TextBlock with markdown repair.
|
|
2870
2920
|
*/
|
|
2871
2921
|
declare function parseModelResponse(response: GenerateContentResponse, registry: ContentBlockRegistry): Result<ContentBlock[], WorkspaceError>;
|
|
2872
2922
|
|
|
@@ -2959,4 +3009,4 @@ declare function createWorkspace(params: CreateWorkspaceParams): Promise<{
|
|
|
2959
3009
|
bootstrap: (config: BootstrapConfig) => Promise<BootstrapResult>;
|
|
2960
3010
|
}>;
|
|
2961
3011
|
|
|
2962
|
-
export { type AddContext, type AddPreference, type AddRole, type AddSessionTopics, type AddTopic, type AddTurn, type AuthRequest, type BackendError, type BaseCommand, type BaseContentBlock, type BlobCommand, type BlobContextContent, type BlobError, type BlobMediaType, type BlobRecord, type BlobRef, type BlobResolver, type BootstrapConfig, type BootstrapResult, type BranchInfo, type BranchTurn, COLLECTIONS, type Collections, type Command, type ContentBlock, type Context, type ContextContent, type ContextDefinition, type ContextRetriever, type ContextSummary, type CreateSession, type CreateWorkspace, type CreateWorkspaceParams, type DeepPartial, type DefaultContextContent, DefaultPromptBuilder, DefaultSystemPromptAssembler, type DeleteContext, type DeletePreference, type DeleteRole, type DeleteSession, type DeleteTopic, type DeleteTurn, type DocumentBlock, type DocumentMediaType, type DuplicateKeyError, EMPTY_SYSTEM_ROLE, type EditTurn, type ForkSession, index as GoogleAdapter, type ImageBlock, type ImageMediaType, type Index, type IndexExtensions, type IndexedDBBlobConfig, IndexedDBBlobStorage, type Indexer, type InvalidCommandError, JaccardContextRetriever, type JsonContextContent, type LLMAdapter, type LLMAdapterStatic, LRUCache, MemoryBlobStorage, type MergeTopics, type ModelConstraint, type ModelConstraintMap, type ModelName, type ModelProfile, type ModelRegistry, type NotFoundError, type OverrideSessionPreferences, type PermissionDeniedError, type PermissionGuard, type Preference, type PreferenceSummary, type Project, type PromptBuilder, type PromptBuilderOptions, type PurgeBlob, type RecordBlobRemoteId, type RegisterBlob, type ReleaseBlob, type RemoteContextContent, type ResolvedBlob, type ResolvedSession, type Result, type RetainBlob, type Role, type RoleSummary, type RoleTransitionBlock, type SHA256, Session, SessionManager, type SessionMetadata, type SessionSnapshot, type Settings, type Store, type Summarizer, type SummaryBlock, type SwitchSessionRole, type SyncWorkspace, type SystemActor, type TextBlock, type TextContextContent, type ThinkingBlock, type Timestamp, type ToolCall, type ToolCallCommand, type ToolRegistry, type ToolResultBlock, type ToolSummary, type ToolUseBlock, type Topic, type TopicIndex, type Turn, TurnBuilder, type TurnKey, type TurnNode, type TurnProcessor, type TurnRef, TurnTree, type URI, type UUID, type UpdateContext, type UpdatePreference, type UpdateRole, type UpdateSession, type UpdateTopic, type UpdateTurn, type Workspace, type WorkspaceBundle, type WorkspaceContext, type WorkspaceDatabase, type WorkspaceError, type WorkspaceEvents, type WorkspaceExtension, WorkspaceManager, type WorkspaceMiddleware, type WorkspaceReducer, bufferToBase64, computeSHA256, createDefaultAssembler, createEmptySession, createEmptyTurn, createEmptyWorkspace, createWorkspace, createWorkspaceDatabase, del, error, getExtension, merge, omitNullUndefined, shortHash, success };
|
|
3012
|
+
export { type AddContext, type AddPreference, type AddRole, type AddSessionTopics, type AddTopic, type AddTurn, type AuthRequest, type BackendError, type BaseCommand, type BaseContentBlock, type BlobCommand, type BlobContextContent, type BlobError, type BlobMediaType, type BlobRecord, type BlobRef, type BlobResolver, type BootstrapConfig, type BootstrapResult, type BranchInfo, type BranchTurn, COLLECTIONS, type Collections, type Command, type ContentBlock, type Context, type ContextContent, type ContextDefinition, type ContextRetriever, type ContextSummary, type CreateSession, type CreateWorkspace, type CreateWorkspaceParams, type DeepPartial, type DefaultContextContent, DefaultPromptBuilder, DefaultSystemPromptAssembler, type DeleteContext, type DeletePreference, type DeleteRole, type DeleteSession, type DeleteTopic, type DeleteTurn, type DocumentBlock, type DocumentMediaType, type DuplicateKeyError, EMPTY_SYSTEM_ROLE, type EditTurn, type ForkSession, index as GoogleAdapter, type ImageBlock, type ImageMediaType, type Index, type IndexExtensions, type IndexedDBBlobConfig, IndexedDBBlobStorage, type Indexer, type InvalidCommandError, JaccardContextRetriever, type JsonContextContent, type LLMAdapter, type LLMAdapterStatic, LRUCache, MemoryBlobStorage, type MergeTopics, type ModelConstraint, type ModelConstraintMap, type ModelName, type ModelProfile, type ModelRegistry, type NotFoundError, type OverrideSessionPreferences, type PermissionDeniedError, type PermissionGuard, type Preference, type PreferenceSummary, type Project, type PromptBuilder, type PromptBuilderOptions, type PurgeBlob, type RecordBlobRemoteId, type RegisterBlob, type ReleaseBlob, type RemoteContextContent, type ResolvedBlob, type ResolvedSession, type Result, type RetainBlob, type Role, type RoleSummary, type RoleTransitionBlock, type SHA256, Session, SessionManager, type SessionMetadata, type SessionSnapshot, type Settings, type Store, type Summarizer, type SummaryBlock, type SwitchSessionRole, type SyncWorkspace, type SystemActor, type TextBlock, type TextContextContent, type ThinkingBlock, type Timestamp, type ToolCall, type ToolCallCommand, type ToolRegistry, type ToolResultBlock, type ToolSummary, type ToolUseBlock, type Topic, type TopicIndex, type Turn, TurnBuilder, type TurnKey, type TurnNode, type TurnProcessor, type TurnRef, TurnTree, type URI, type UUID, type UpdateContext, type UpdatePreference, type UpdateRole, type UpdateSession, type UpdateTopic, type UpdateTurn, type Workspace, WorkspaceApi, type WorkspaceBundle, type WorkspaceContext, type WorkspaceDatabase, type WorkspaceError, type WorkspaceEvents, type WorkspaceExtension, WorkspaceManager, type WorkspaceMiddleware, type WorkspaceReducer, WorkspaceRegistry, bufferToBase64, computeSHA256, createDefaultAssembler, createEmptySession, createEmptyTurn, createEmptyWorkspace, createWorkspace, createWorkspaceDatabase, del, error, getExtension, merge, omitNullUndefined, shortHash, success };
|
package/index.d.ts
CHANGED
|
@@ -784,6 +784,8 @@ interface Turn {
|
|
|
784
784
|
timestamp: Timestamp;
|
|
785
785
|
/** Name of the role (persona) active at the exact time this turn occurred. */
|
|
786
786
|
role?: string;
|
|
787
|
+
/** Name of the model that produced this turn. */
|
|
788
|
+
model?: string;
|
|
787
789
|
/** Link to the preceding turn in the conversation tree, defining the DAG graph. */
|
|
788
790
|
parent?: {
|
|
789
791
|
/** The ID of the parent turn. */
|
|
@@ -793,6 +795,8 @@ interface Turn {
|
|
|
793
795
|
};
|
|
794
796
|
/** Local model constraints applied explicitly at the time of this turn. */
|
|
795
797
|
constraints?: ModelConstraintMap;
|
|
798
|
+
/** Extensible key-value store for turn-specific metadata (e.g., error logs). */
|
|
799
|
+
metadata?: Record<string, any>;
|
|
796
800
|
}
|
|
797
801
|
/** Unique composite key used to lookup a specific turn version. */
|
|
798
802
|
type TurnKey = Pick<Turn, "version" | "id" | "session">;
|
|
@@ -815,6 +819,8 @@ interface TurnNode {
|
|
|
815
819
|
timestamp: Timestamp;
|
|
816
820
|
/** The role name active when this node was created. */
|
|
817
821
|
roleSnapshot?: string;
|
|
822
|
+
/** The model name active when this node was created. */
|
|
823
|
+
modelSnapshot?: string;
|
|
818
824
|
/** Reference to the preceding turn in the conversation DAG. */
|
|
819
825
|
parent?: {
|
|
820
826
|
/** Parent turn ID. */
|
|
@@ -1210,6 +1216,7 @@ interface EditTurn extends BaseCommand {
|
|
|
1210
1216
|
newBlocks: ContentBlock[];
|
|
1211
1217
|
newVersion: number;
|
|
1212
1218
|
roleSnapshot?: string;
|
|
1219
|
+
modelSnapshot?: string;
|
|
1213
1220
|
};
|
|
1214
1221
|
}
|
|
1215
1222
|
/** Creates a new branch in the conversation history from a specific turn. */
|
|
@@ -2544,6 +2551,29 @@ declare class WorkspaceManager {
|
|
|
2544
2551
|
ctx(): WorkspaceContext;
|
|
2545
2552
|
}
|
|
2546
2553
|
|
|
2554
|
+
/**
|
|
2555
|
+
* A lightweight registry for managing workspaces without full initialization.
|
|
2556
|
+
* Solves the 'chicken and egg' problem where you need a workspace to delete a workspace.
|
|
2557
|
+
*/
|
|
2558
|
+
declare class WorkspaceRegistry {
|
|
2559
|
+
private readonly db;
|
|
2560
|
+
constructor(db: Database);
|
|
2561
|
+
/**
|
|
2562
|
+
* Lists all workspaces currently registered in the database.
|
|
2563
|
+
*/
|
|
2564
|
+
list(): Promise<WorkspaceMetadata[]>;
|
|
2565
|
+
/**
|
|
2566
|
+
* Deletes a workspace record.
|
|
2567
|
+
* Note: This does not currently purge associated data (sessions, turns)
|
|
2568
|
+
* as they are not explicitly linked to the workspace ID in the flat schema.
|
|
2569
|
+
*/
|
|
2570
|
+
delete(id: UUID): Promise<boolean>;
|
|
2571
|
+
/**
|
|
2572
|
+
* Purges ALL collections in the database.
|
|
2573
|
+
* Useful for a total reset. Use with extreme caution.
|
|
2574
|
+
*/
|
|
2575
|
+
purge(): Promise<void>;
|
|
2576
|
+
}
|
|
2547
2577
|
declare class WorkspaceApi {
|
|
2548
2578
|
private readonly manager;
|
|
2549
2579
|
constructor(manager: WorkspaceManager);
|
|
@@ -2601,6 +2631,14 @@ declare class Session {
|
|
|
2601
2631
|
getTurn(turnId: UUID): Promise<TurnNode | undefined>;
|
|
2602
2632
|
rename(newLabel: string): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2603
2633
|
setTopics(topics: string[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2634
|
+
/**
|
|
2635
|
+
* Updates the session's model identifier.
|
|
2636
|
+
*/
|
|
2637
|
+
setModel(model: string): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2638
|
+
/**
|
|
2639
|
+
* Merges the provided metadata into the session's current metadata.
|
|
2640
|
+
*/
|
|
2641
|
+
updateMetadata(metadata: Record<string, any>): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2604
2642
|
addTopics(topics: string[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2605
2643
|
setPreferences(preferenceIds: UUID[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2606
2644
|
fork(newSessionId: UUID, label: string, role?: string, topics?: string[]): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
@@ -2611,9 +2649,13 @@ declare class Session {
|
|
|
2611
2649
|
recordAssistantTurn(turn: Turn, recordDenial?: boolean): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2612
2650
|
private buildDenialTurn;
|
|
2613
2651
|
private describeCommand;
|
|
2614
|
-
editTurn(turnId: UUID, newBlocks: ContentBlock[], roleSnapshot?: string): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2652
|
+
editTurn(turnId: UUID, newBlocks: ContentBlock[], roleSnapshot?: string, modelSnapshot?: string): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2615
2653
|
branch(turn: Turn): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2616
2654
|
deleteTurn(turnId: UUID, version: number, newHead: TurnRef | null): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2655
|
+
/**
|
|
2656
|
+
* Updates the status of a specific turn using the Result pattern.
|
|
2657
|
+
*/
|
|
2658
|
+
updateTurnStatus(turnId: UUID, status: Result<undefined, WorkspaceError>): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2617
2659
|
switchVersionLeft(turnId: UUID): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2618
2660
|
switchVersionRight(turnId: UUID): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
2619
2661
|
private switchVersion;
|
|
@@ -2628,7 +2670,7 @@ declare class Session {
|
|
|
2628
2670
|
*
|
|
2629
2671
|
* Returns undefined if the session no longer exists in the workspace index.
|
|
2630
2672
|
*/
|
|
2631
|
-
snapshot(): Promise<SessionSnapshot | undefined>;
|
|
2673
|
+
snapshot(turnId?: UUID): Promise<SessionSnapshot | undefined>;
|
|
2632
2674
|
private refreshTurnTree;
|
|
2633
2675
|
private findSubtreeTip;
|
|
2634
2676
|
}
|
|
@@ -2676,6 +2718,8 @@ declare class TurnBuilder {
|
|
|
2676
2718
|
withTimestamp(timestamp: Timestamp): TurnBuilder;
|
|
2677
2719
|
withParent(parent: TurnRef): TurnBuilder;
|
|
2678
2720
|
withRoleSnapshot(roleSnapshot: string): TurnBuilder;
|
|
2721
|
+
withRole(role: string): TurnBuilder;
|
|
2722
|
+
withModel(model: string): TurnBuilder;
|
|
2679
2723
|
build(): Turn;
|
|
2680
2724
|
}
|
|
2681
2725
|
|
|
@@ -2735,6 +2779,10 @@ declare class TurnTree {
|
|
|
2735
2779
|
static build(sessionId: UUID, repository: TurnRepository): Promise<TurnTree>;
|
|
2736
2780
|
head(): TurnRef | null;
|
|
2737
2781
|
chain(): TurnNode[];
|
|
2782
|
+
/**
|
|
2783
|
+
* Returns a chronological chain of TurnNodes ending at the specified turn.
|
|
2784
|
+
*/
|
|
2785
|
+
chainFrom(turnId: UUID): TurnNode[];
|
|
2738
2786
|
getTurnSiblings(turnId: UUID): TurnNode[];
|
|
2739
2787
|
branchInfo(turnId: UUID): BranchInfo;
|
|
2740
2788
|
graph(): Readonly<Record<UUID, TurnNode>>;
|
|
@@ -2867,6 +2915,8 @@ declare const GOOGLE_MODELS: Array<ModelProfile>;
|
|
|
2867
2915
|
* - Block validation and construction is fully delegated to the registry.
|
|
2868
2916
|
* Unknown block types returned by the model are silently dropped (registry
|
|
2869
2917
|
* returns null for unregistered types) and logged by the registry itself.
|
|
2918
|
+
* - If the model ignores the structured JSON schema and returns raw text,
|
|
2919
|
+
* it automatically wraps the response in a TextBlock with markdown repair.
|
|
2870
2920
|
*/
|
|
2871
2921
|
declare function parseModelResponse(response: GenerateContentResponse, registry: ContentBlockRegistry): Result<ContentBlock[], WorkspaceError>;
|
|
2872
2922
|
|
|
@@ -2959,4 +3009,4 @@ declare function createWorkspace(params: CreateWorkspaceParams): Promise<{
|
|
|
2959
3009
|
bootstrap: (config: BootstrapConfig) => Promise<BootstrapResult>;
|
|
2960
3010
|
}>;
|
|
2961
3011
|
|
|
2962
|
-
export { type AddContext, type AddPreference, type AddRole, type AddSessionTopics, type AddTopic, type AddTurn, type AuthRequest, type BackendError, type BaseCommand, type BaseContentBlock, type BlobCommand, type BlobContextContent, type BlobError, type BlobMediaType, type BlobRecord, type BlobRef, type BlobResolver, type BootstrapConfig, type BootstrapResult, type BranchInfo, type BranchTurn, COLLECTIONS, type Collections, type Command, type ContentBlock, type Context, type ContextContent, type ContextDefinition, type ContextRetriever, type ContextSummary, type CreateSession, type CreateWorkspace, type CreateWorkspaceParams, type DeepPartial, type DefaultContextContent, DefaultPromptBuilder, DefaultSystemPromptAssembler, type DeleteContext, type DeletePreference, type DeleteRole, type DeleteSession, type DeleteTopic, type DeleteTurn, type DocumentBlock, type DocumentMediaType, type DuplicateKeyError, EMPTY_SYSTEM_ROLE, type EditTurn, type ForkSession, index as GoogleAdapter, type ImageBlock, type ImageMediaType, type Index, type IndexExtensions, type IndexedDBBlobConfig, IndexedDBBlobStorage, type Indexer, type InvalidCommandError, JaccardContextRetriever, type JsonContextContent, type LLMAdapter, type LLMAdapterStatic, LRUCache, MemoryBlobStorage, type MergeTopics, type ModelConstraint, type ModelConstraintMap, type ModelName, type ModelProfile, type ModelRegistry, type NotFoundError, type OverrideSessionPreferences, type PermissionDeniedError, type PermissionGuard, type Preference, type PreferenceSummary, type Project, type PromptBuilder, type PromptBuilderOptions, type PurgeBlob, type RecordBlobRemoteId, type RegisterBlob, type ReleaseBlob, type RemoteContextContent, type ResolvedBlob, type ResolvedSession, type Result, type RetainBlob, type Role, type RoleSummary, type RoleTransitionBlock, type SHA256, Session, SessionManager, type SessionMetadata, type SessionSnapshot, type Settings, type Store, type Summarizer, type SummaryBlock, type SwitchSessionRole, type SyncWorkspace, type SystemActor, type TextBlock, type TextContextContent, type ThinkingBlock, type Timestamp, type ToolCall, type ToolCallCommand, type ToolRegistry, type ToolResultBlock, type ToolSummary, type ToolUseBlock, type Topic, type TopicIndex, type Turn, TurnBuilder, type TurnKey, type TurnNode, type TurnProcessor, type TurnRef, TurnTree, type URI, type UUID, type UpdateContext, type UpdatePreference, type UpdateRole, type UpdateSession, type UpdateTopic, type UpdateTurn, type Workspace, type WorkspaceBundle, type WorkspaceContext, type WorkspaceDatabase, type WorkspaceError, type WorkspaceEvents, type WorkspaceExtension, WorkspaceManager, type WorkspaceMiddleware, type WorkspaceReducer, bufferToBase64, computeSHA256, createDefaultAssembler, createEmptySession, createEmptyTurn, createEmptyWorkspace, createWorkspace, createWorkspaceDatabase, del, error, getExtension, merge, omitNullUndefined, shortHash, success };
|
|
3012
|
+
export { type AddContext, type AddPreference, type AddRole, type AddSessionTopics, type AddTopic, type AddTurn, type AuthRequest, type BackendError, type BaseCommand, type BaseContentBlock, type BlobCommand, type BlobContextContent, type BlobError, type BlobMediaType, type BlobRecord, type BlobRef, type BlobResolver, type BootstrapConfig, type BootstrapResult, type BranchInfo, type BranchTurn, COLLECTIONS, type Collections, type Command, type ContentBlock, type Context, type ContextContent, type ContextDefinition, type ContextRetriever, type ContextSummary, type CreateSession, type CreateWorkspace, type CreateWorkspaceParams, type DeepPartial, type DefaultContextContent, DefaultPromptBuilder, DefaultSystemPromptAssembler, type DeleteContext, type DeletePreference, type DeleteRole, type DeleteSession, type DeleteTopic, type DeleteTurn, type DocumentBlock, type DocumentMediaType, type DuplicateKeyError, EMPTY_SYSTEM_ROLE, type EditTurn, type ForkSession, index as GoogleAdapter, type ImageBlock, type ImageMediaType, type Index, type IndexExtensions, type IndexedDBBlobConfig, IndexedDBBlobStorage, type Indexer, type InvalidCommandError, JaccardContextRetriever, type JsonContextContent, type LLMAdapter, type LLMAdapterStatic, LRUCache, MemoryBlobStorage, type MergeTopics, type ModelConstraint, type ModelConstraintMap, type ModelName, type ModelProfile, type ModelRegistry, type NotFoundError, type OverrideSessionPreferences, type PermissionDeniedError, type PermissionGuard, type Preference, type PreferenceSummary, type Project, type PromptBuilder, type PromptBuilderOptions, type PurgeBlob, type RecordBlobRemoteId, type RegisterBlob, type ReleaseBlob, type RemoteContextContent, type ResolvedBlob, type ResolvedSession, type Result, type RetainBlob, type Role, type RoleSummary, type RoleTransitionBlock, type SHA256, Session, SessionManager, type SessionMetadata, type SessionSnapshot, type Settings, type Store, type Summarizer, type SummaryBlock, type SwitchSessionRole, type SyncWorkspace, type SystemActor, type TextBlock, type TextContextContent, type ThinkingBlock, type Timestamp, type ToolCall, type ToolCallCommand, type ToolRegistry, type ToolResultBlock, type ToolSummary, type ToolUseBlock, type Topic, type TopicIndex, type Turn, TurnBuilder, type TurnKey, type TurnNode, type TurnProcessor, type TurnRef, TurnTree, type URI, type UUID, type UpdateContext, type UpdatePreference, type UpdateRole, type UpdateSession, type UpdateTopic, type UpdateTurn, type Workspace, WorkspaceApi, type WorkspaceBundle, type WorkspaceContext, type WorkspaceDatabase, type WorkspaceError, type WorkspaceEvents, type WorkspaceExtension, WorkspaceManager, type WorkspaceMiddleware, type WorkspaceReducer, WorkspaceRegistry, bufferToBase64, computeSHA256, createDefaultAssembler, createEmptySession, createEmptyTurn, createEmptyWorkspace, createWorkspace, createWorkspaceDatabase, del, error, getExtension, merge, omitNullUndefined, shortHash, success };
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("@asaidimu/utils-events"),t=require("uuid"),s=Object.defineProperty,r=[async e=>{const t=await e.workspaceStore.list();if(0===t.length)return{};const s=t[0];return{id:s.id,settings:s.settings,project:s.project}},async e=>{const t=await e.roles.list(),s={};for(const r of t)s[r.name]=e.roles.summarize(r);return{index:{roles:s}}},async e=>{const t=await e.preferences.list(),s={};for(const r of t)s[r.id]=e.preferences.summarize(r);return{index:{preferences:s}}},async e=>{const t=await e.context.list(),s={};for(const r of t)s[r.key]=e.context.summarize(r);return{index:{context:s}}},async e=>{const t=await e.sessions.list(),s={};for(const r of t)s[r.id]=e.sessions.summarize(r);return{index:{sessions:s}}},async e=>{const t=await e.topics.list(),s={};for(const r of t)s[r.name]=e.topics.summarize(r);return{index:{topics:s}}},async e=>({index:{blobs:await e.blobs.getAllRecords()}})],n=[{name:"workspace",version:"1.0.0",description:"Workspace root containing global settings and project metadata.",fields:{id:{name:"id",type:"string",required:!0},settings:{name:"settings",type:"record",required:!0},project:{name:"project",type:"record",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"}],constraints:[],migrations:[]},{name:"role",version:"1.0.0",description:"AI persona with a system prompt and associated preference defaults.",fields:{name:{name:"name",type:"string",required:!0},label:{name:"label",type:"string",required:!0},description:{name:"description",type:"string",required:!1},persona:{name:"persona",type:"string",required:!0},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"},topics:{name:"topics",type:"array",required:!1},constraints:{name:"constraints",type:"record",required:!1}},indexes:[{name:"by_name",fields:["name"],type:"unique"},{name:"by_label",fields:["label"],type:"normal"}],constraints:[],migrations:[]},{name:"preference",version:"1.0.0",description:"A user behavioural instruction, scoped to zero or more topics.",fields:{id:{name:"id",type:"string",required:!0},content:{name:"content",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},timestamp:{name:"timestamp",type:"string",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"context",version:"1.0.0",description:"Injected background knowledge, scoped to topics. Content is a discriminated union.",fields:{key:{name:"key",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},content:{name:"content",type:"record",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},metadata:{name:"metadata",type:"record",required:!1}},indexes:[{name:"by_key",fields:["key"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"session",version:"1.0.0",description:"Session metadata. The head field tracks the current tip of the turn DAG.",fields:{id:{name:"id",type:"string",required:!0},label:{name:"label",type:"string",required:!0},role:{name:"role",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"},metadata:{name:"metadata",type:"record",required:!1},head:{name:"head",type:"record",required:!1},constraints:{name:"constraints",type:"record",required:!1}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_role",fields:["role"],type:"normal"}],constraints:[],migrations:[]},{name:"turn",version:"1.0.0",description:["A single message in a session transcript, stored as a flat document.","The DAG is reconstructed in memory by TurnTree.buildNodeGraph() at session open time."].join(" "),fields:{id:{name:"id",type:"string",required:!0},session:{name:"session",type:"string",required:!0},version:{name:"version",type:"number",required:!0},actor:{name:"actor",type:"enum",required:!0,values:["user","assistant","tool"]},blocks:{name:"blocks",type:"array",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},role:{name:"role",type:"string",required:!1},parent:{name:"parent",type:"record",required:!1},constraints:{name:"constraints",type:"record",required:!1}},indexes:[{name:"by_session",fields:["session"],type:"normal"},{name:"by_session_parent",fields:["session","parent"],type:"composite"},{name:"by_session_id_ver",fields:["session","id","version"],type:"composite",unique:!0}],constraints:[],migrations:[]},{name:"topic",version:"1.0.0",description:"A categorization for context and preferences, used for retrieval.",fields:{name:{name:"name",type:"string",required:!0},label:{name:"label",type:"string",required:!1},description:{name:"description",type:"string",required:!1},metadata:{name:"metadata",type:"record",required:!1},created:{name:"created",type:"string",required:!0},updated:{name:"updated",type:"string",required:!0}},indexes:[{name:"by_name",fields:["name"],type:"unique"}],constraints:[],migrations:[]}],i=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},o=class extends i{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},a=class extends i{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},c=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const s=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await s;let r;await Promise.race([s.then((()=>clearTimeout(r))),new Promise(((s,n)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),n(new o("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},d=class{mutex=new c({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,s="Operation timed out"){if(null==t)return e;let r;return Promise.race([e.then((e=>(clearTimeout(r),e))),new Promise(((e,n)=>{r=setTimeout((()=>n(new o(s))),t)}))])}},l=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new c({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new a};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,r=null;try{if(this._done)throw new a;r=await e(),this._lastValue=r,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:r,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}};function u(e){const t=new d({retry:!0,throws:!0}),s=new d({retry:!0,throws:!0});return{open:async(s=[])=>(await t.do((async()=>{const t=[...n,...s];await e.setupCollections(t)}))).value,collection:async t=>e.collection(t),close:async()=>(await s.do((()=>{e.close()}))).value,database:()=>e}}var p={WORKSPACE:"workspace",ROLE:"role",PREFERENCE:"preference",CONTEXT:"context",SESSION:"session",TURN:"turn",BLOB:"blob",TOPIC:"topic"},h=Symbol.for("delete"),m=e=>Array.isArray(e)?[...e]:{...e};function f(e){return{ok:!0,value:e}}function y(e){return{ok:!1,error:e}}var g=function(e){const t=e?.deleteMarker||h;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const r={};for(const[n,i]of Object.entries(e))if(i!==t)if("object"==typeof i&&null!==i){const e=s(i);void 0!==e&&(r[n]=e)}else r[n]=i;return r}return e===t?void 0:e}return function(e,r){if("object"!=typeof e||null===e)return"object"==typeof r&&null!==r?s(r):r===t?{}:r;if("object"!=typeof r||null===r)return e;const n=m(e),i=[{target:n,source:r}];for(;i.length>0;){const{target:e,source:s}=i.pop();for(const r of Object.keys(s)){const n=s[r];if(n!==t)if(Array.isArray(n))e[r]=n;else if("object"==typeof n&&null!==n){const t=r in e&&"object"==typeof e[r]&&null!==e[r]?e[r]:{};e[r]=m(t),i.push({target:e[r],source:n})}else e[r]=n;else delete e[r]}}return n}}({deleteMarker:h});async function w(e){const t=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join("")}function b(e){if("undefined"!=typeof Buffer)return Buffer.from(e).toString("base64");const t=[];for(let s=0;s<e.length;s+=32768){const r=e.subarray(s,s+32768);t.push(String.fromCharCode.apply(null,Array.from(r)))}return btoa(t.join(""))}var k=class{registry=new Map;middlewares=[];serializer=new l;bus;_getWorkspace;updateWorkspace;guard;_ctx;constructor(e){this._ctx=e.ctx,this._getWorkspace=e.getWorkspace,this.updateWorkspace=e.updateWorkspace,this.guard=e.guard,this.bus=e.bus}register(e,t){return this.registry.set(e,t),this}use(e){return this.middlewares.push(e),this}workspace(){return this._getWorkspace()}async dispatch(e){const t=await this.serializer.do((async()=>{if(this.guard){const t=await this.guard.authenticate({type:"command",payload:e});if(!t.ok)return y(t.error)}const t=this.registry.get(e.type);if(!t)return y({code:"INVALID_COMMAND",reason:`No reducer registered for command type: ${e.type}`});const s=this._getWorkspace(),r=await t({workspace:s,...this._ctx},e.payload);if(!r.ok)return r;let n=r.value;for(const t of this.middlewares){const r=await t({workspace:s,command:e,patch:n,...this._ctx});n=g(n,r)}return await this.updateWorkspace(n),this.bus.emit({name:"workspace:changed",payload:n}),"workspace:sync"===e.type&&this.bus.emit({name:"workspace:synced",payload:void 0}),f(n)}));if(t.error)throw t.error;return t.value}subscribe(e,t){return this.bus.subscribe(e,t)}ctx(){return{workspace:this._getWorkspace(),...this._ctx}}},x=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;const r=s.state();return this.cache.set(e,r),r}async add(e){await this.collection.create(e),this.cache.set(e.name,e)}async update(e,t){const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;await s.update(t);const r=s.state();return this.cache.set(e,r),r}async delete(e){const t=await this.collection.find({field:"name",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async getMany(e){if(0===e.length)return[];const t=[],s=[];for(const r of e){const e=this.cache.get(r);e?t.push(e):s.push(r)}if(s.length>0){const e=await this.collection.filter({operator:"or",conditions:s.map((e=>({field:"name",operator:"eq",value:e})))});for(const s of e){const e=s.state();this.cache.set(e.name,e),t.push(e)}}return t}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}referencedBy(e,t){for(const s in t.roles)if(t.roles[s].topics?.includes(e))return!0;for(const s in t.sessions)if(t.sessions[s].topics?.includes(e))return!0;for(const s in t.context)if(t.context[s].topics?.includes(e))return!0;for(const s in t.preferences)if(t.preferences[s].topics?.includes(e))return!0;return!1}summarize(e){return{topic:e.name,contextKeys:[],preferences:[],metadata:{created:e.created,updated:e.updated,entries:0}}}};function v(e,t,s,r,n,i){const o={};for(const a of t){let t=e[a];if(!t){if("add"!==n||!i)continue;t={topic:a,contextKeys:[],preferences:[],metadata:{created:(new Date).toISOString(),updated:(new Date).toISOString(),entries:0}},i.add({name:a,created:t.metadata.created,updated:t.metadata.updated})}const c=t[r],d=c.includes(s);if("add"!==n||d){if("remove"===n&&d){const e=Math.max(0,(t.metadata.entries||0)-1);o[a]={...t,[r]:c.filter((e=>e!==s)),metadata:{...t.metadata,updated:(new Date).toISOString(),entries:e}}}}else o[a]={...t,[r]:[...c,s],metadata:{...t.metadata,updated:(new Date).toISOString(),entries:(t.metadata.entries||0)+1}}}return{index:{topics:o}}}function _(e,t,s,r){return v(e,t,s,"contextKeys","add",r)}function O(e,t,s){return v(e,t,s,"contextKeys","remove")}function S(e,t,s,r){return v(e,t,s,"preferences","add",r)}function T(e,t,s){return v(e,t,s,"preferences","remove")}var N=async e=>{if(!e.patch)return;const{workspace:t,patch:s}=e,r=t.index.topics;let n={};const i=e=>{const t=e?.index?.topics;t&&(n=g(n,t))};if(s.index?.context)for(const[n,o]of Object.entries(s.index.context)){const s=t.index.context[n];if(void 0===o&&s)i(O(r,s.topics,s.key));else if(s||!o){if(s&&o){const t=s.topics??[],n=o.topics??t,a=n.filter((e=>!t.includes(e))),c=t.filter((e=>!n.includes(e)));c.length&&i(O(r,c,s.key)),a.length&&i(_(r,a,s.key,e.topics))}}else i(_(r,o.topics??[],o.key,e.topics))}if(s.index?.preferences)for(const[n,o]of Object.entries(s.index.preferences)){const s=t.index.preferences[n];if(void 0===o&&s)i(T(r,s.topics,s.id));else if(s||!o){if(s&&o){const t=s.topics??[],n=o.topics??t,a=n.filter((e=>!t.includes(e))),c=t.filter((e=>!n.includes(e)));c.length&&i(T(r,c,s.id)),a.length&&i(S(r,a,s.id,e.topics))}}else i(S(r,o.topics??[],o.id,e.topics))}return Object.keys(n).length?{index:{topics:n}}:{}},R="\n# WORKSPACE OPERATING SYSTEM\nYou are operating within a structured workspace. Your output MUST be a JSON object matching the provided schema.\nYour entire response MUST be valid JSON. Nothing else.\n".trim();function D(e){if(!e||"append"===e)return{placement:"append",label:null};if("prepend"===e)return{placement:"prepend",label:null};const[t,...s]=e.split(":");return("before"===t||"after"===t)&&s.length>0?{placement:t,label:s.join(":")}:(console.warn(`[SystemPromptAssembler] Unrecognised position "${e}", defaulting to "append".`),{placement:"append",label:null})}var I=class{build(e,t=[]){const s=[...e.system.extensions||[],...t],r=[];var n,i,o;r.push({label:"operating-system",content:R}),e.role.persona&&r.push({label:"persona",content:(n=e.role.persona,`# Persona\n${n}`)}),e.system.preferences.length>0&&r.push({label:"preferences",content:(i=e.system.preferences,`# User Preferences\n${i.map((e=>`- ${e.content}`)).join("\n")}`),metadata:{count:e.system.preferences.length}}),e.system.context.length>0&&r.push({label:"context",content:(o=e.system.context,`# Context\n${o.map((e=>{switch(e.content.kind){case"text":return`[${e.key}] ${e.content.value}`;case"json":return`[${e.key}] JSON: ${JSON.stringify(e.content.value)}`;case"blob":return`[${e.key}] Blob: ${e.content.filename??"unnamed"} (${e.content.mediaType}, ${e.content.sizeBytes} bytes)`;case"remote":return`[${e.key}] Remote: ${e.content.uri}`;default:return`[${e.key}] Unsupported context type`}})).join("\n")}`),metadata:{count:e.system.context.length}}),e.system.instructions&&r.push({label:"instructions",content:`# Instructions\n${e.system.instructions}`});const a=[...r],c=[];for(const e of s){const{position:t,...s}=e,r=D(t);if("prepend"===r.placement){c.push(s);continue}if("append"===r.placement){a.push(s);continue}const n=a.findIndex((e=>e.label===r.label));if(-1===n){console.warn(`[SystemPromptAssembler] Anchor target "${r.label}" not found in sections. Extension "${e.label}" will be appended.`),a.push(s);continue}const i="before"===r.placement?n:n+1;a.splice(i,0,s)}return[...c,...a]}join(e){return e.map((e=>e.content)).join("\n\n---\n\n")}};var E={"workspace:create":async function(e,t){const{workspaceStore:s}=e,{id:r,settings:n,project:i}=t,o=await s.get(r);return o?f({id:o.id,settings:o.settings,project:o.project}):(await s.add({id:r,settings:n,project:i}),f({id:r,settings:n,project:i,index:{roles:{},preferences:{},context:{},sessions:{},topics:{},blobs:{},tools:{},extensions:{}}}))},"workspace:sync":async function(e,t){let s={};for(const t of e.indexers){const r=await t(e);s=g(s,r)}return t&&(t.id&&(s.id=t.id),t.settings&&(s.settings=g(s.settings||{},t.settings)),t.project&&(s.project=g(s.project||{},t.project))),f(s)},"role:add":async function(e,t){const{workspace:s,roles:r}=e,n=t;return s.index.roles[n.name]?y({code:"DUPLICATE_KEY",resource:"Role",key:n.name}):(await r.add(n),f({index:{roles:{[n.name]:r.summarize(n)}}}))},"role:update":async function(e,t){const{workspace:s,roles:r}=e,{name:n,...i}=t;if(!s.index.roles[n])return y({code:"NOT_FOUND",resource:"Role",id:n});const o=await r.update(n,i);return o?f({index:{roles:{[n]:r.summarize(o)}}}):y({code:"BACKEND_ERROR",reason:`Failed to update role ${n} in store.`})},"role:delete":async function(e,t){const{workspace:s,roles:r}=e,{name:n}=t;return s.index.roles[n]?await r.delete(n)?f({index:{roles:{[n]:h}}}):y({code:"BACKEND_ERROR",reason:`Failed to delete role ${n} from store.`}):y({code:"NOT_FOUND",resource:"Role",id:n})},"preference:add":async function(e,t){const{workspace:s,preferences:r}=e,n=t;return s.index.preferences[n.id]?y({code:"DUPLICATE_KEY",resource:"Preference",key:n.id}):(await r.add(n),f({index:{preferences:{[n.id]:r.summarize(n)}}}))},"preference:update":async function(e,t){const{workspace:s,preferences:r}=e,{id:n,...i}=t;if(!s.index.preferences[n])return y({code:"NOT_FOUND",resource:"Preference",id:n});const o=await r.update(n,i);return o?f({index:{preferences:{[n]:r.summarize(o)}}}):y({code:"BACKEND_ERROR",reason:`Failed to update preference ${n} in store.`})},"preference:delete":async function(e,t){const{workspace:s,preferences:r}=e,{id:n}=t;return s.index.preferences[n]?await r.delete(n)?f({index:{preferences:{[n]:h}}}):y({code:"BACKEND_ERROR",reason:`Failed to delete preference ${n} from store.`}):y({code:"NOT_FOUND",resource:"Preference",id:n})},"context:add":async function(e,t){const{workspace:s,context:r}=e,n=t;return s.index.context[n.key]?y({code:"DUPLICATE_KEY",resource:"Context",key:n.key}):(await r.add(n),f({index:{context:{[n.key]:r.summarize(n)}}}))},"context:update":async function(e,t){const{workspace:s,context:r}=e,{key:n,...i}=t,o=s.index.context[n];if(!o)return y({code:"NOT_FOUND",resource:"Context",id:n});const a=await r.update(n,i,o.kind);return a?f({index:{context:{[n]:r.summarize(a)}}}):y({code:"BACKEND_ERROR",reason:`Failed to update context ${n} in store.`})},"context:delete":async function(e,t){const{workspace:s,context:r}=e,{key:n}=t,i=s.index.context[n];return i?await r.delete(n,i.kind)?f({index:{context:{[n]:h}}}):y({code:"BACKEND_ERROR",reason:`Failed to delete context ${n} from store.`}):y({code:"NOT_FOUND",resource:"Context",id:n})},"topic:add":async function(e,t){const{workspace:s,topics:r}=e,n=t;return s.index.topics[n.name]?y({code:"DUPLICATE_KEY",resource:"Topic",key:n.name}):(await r.add(n),f({index:{topics:{[n.name]:r.summarize(n)}}}))},"topic:update":async function(e,t){const{workspace:s,topics:r}=e,{name:n,...i}=t;if(!s.index.topics[n])return y({code:"NOT_FOUND",resource:"Topic",id:n});const o=await r.update(n,i);return o?f({index:{topics:{[n]:{metadata:{updated:o.updated}}}}}):y({code:"BACKEND_ERROR",reason:`Failed to update topic ${n} in store.`})},"topic:delete":async function(e,t){const{workspace:s,topics:r,roles:n,sessions:i}=e,{name:o,cascade:a}=t;if(!s.index.topics[o])return y({code:"NOT_FOUND",resource:"Topic",id:o});if(r.referencedBy(o,s.index)&&!a)return y({code:"INVALID_COMMAND",reason:`Topic '${o}' is referenced by other entities. Use 'cascade: true' to force deletion.`});if(a){for(const e in s.index.roles){const t=s.index.roles[e];if(t.topics?.includes(o)){const t=await n.get(e);t&&await n.update(e,{topics:t.topics.filter((e=>e!==o))})}}for(const e in s.index.sessions){const t=s.index.sessions[e];t.topics?.includes(o)&&await i.update(e,{topics:t.topics.filter((e=>e!==o))})}}return await r.delete(o)?f({index:{topics:{[o]:h}}}):y({code:"BACKEND_ERROR",reason:`Failed to delete topic ${o} from store.`})},"topic:merge":async function(e,t){const{workspace:s,topics:r,roles:n,sessions:i}=e,{source:o,target:a}=t;if(!s.index.topics[o]||!s.index.topics[a])return y({code:"NOT_FOUND",resource:"Topic",id:s.index.topics[o]?a:o});for(const e in s.index.roles){const t=s.index.roles[e];if(t.topics?.includes(o)){const t=await n.get(e);if(t){const s=t.topics.filter((e=>e!==o));s.includes(a)||s.push(a),await n.update(e,{topics:s})}}}for(const e in s.index.sessions){const t=s.index.sessions[e];if(t.topics?.includes(o)){const s=t.topics.filter((e=>e!==o));s.includes(a)||s.push(a),await i.update(e,{topics:s})}}return await r.delete(o),f({index:{topics:{[o]:h}}})},"session:create":async function(e,t){const{workspace:s,sessions:r}=e,n=t;return s.index.sessions[n.id]?y({code:"DUPLICATE_KEY",resource:"Session",key:n.id}):(await r.add(n),f({index:{sessions:{[n.id]:r.summarize(n)}}}))},"session:update":async function(e,t){const{workspace:s,sessions:r}=e,{sessionId:n,...i}=t;if(!s.index.sessions[n])return y({code:"NOT_FOUND",resource:"Session",id:n});const o=await r.update(n,i);return o?f({index:{sessions:{[n]:r.summarize(o)}}}):y({code:"BACKEND_ERROR",reason:`Failed to update session ${n} in store.`})},"session:fork":async function(e,t){const{workspace:s,sessions:r}=e,{sessionId:n,newSessionId:i,label:o}=t,a=s.index.sessions[n];if(!a)return y({code:"NOT_FOUND",resource:"Session",id:n});const c={...a,id:i,label:o||`Fork of ${a.label}`,role:t.role?t.role:a.role,topics:t.topics?t.topics:a.topics};return await r.add(c),f({index:{sessions:{[i]:r.summarize(c)}}})},"session:delete":async function(e,t){const{workspace:s,sessions:r}=e,{sessionId:n}=t;return s.index.sessions[n]?(await r.delete(n),f({index:{sessions:{[n]:h}}})):y({code:"NOT_FOUND",resource:"Session",id:n})},"session:role:switch":async function(e,t){const{workspace:s,sessions:r}=e,{sessionId:n,roleName:i}=t;return s.index.sessions[n]?(await r.update(n,{role:i}),f({index:{sessions:{[n]:{role:i}}}})):y({code:"NOT_FOUND",resource:"Session",id:n})},"session:topics:add":async function(e,t){const{workspace:s,sessions:r}=e,{sessionId:n,topics:i}=t,o=s.index.sessions[n];if(!o)return y({code:"NOT_FOUND",resource:"Session",id:n});const a=Array.from(new Set([...o.topics,...i]));return await r.update(n,{topics:a}),f({index:{sessions:{[n]:{topics:a}}}})},"session:preferences:override":async function(e,t){const{workspace:s,sessions:r}=e,{sessionId:n,preferences:i}=t;return s.index.sessions[n]?(await r.update(n,{preferences:i}),f({index:{sessions:{[n]:{preferences:i}}}})):y({code:"NOT_FOUND",resource:"Session",id:n})},"turn:add":async function(e,t){const{workspace:s,sessions:r,turns:n}=e,{sessionId:i,turn:o}=t;if(!s.index.sessions[i])return y({code:"NOT_FOUND",resource:"Session",id:i});await n.add(o);const a={id:o.id,version:o.version};return await r.update(i,{head:a}),f({index:{sessions:{[i]:{head:a}}}})},"turn:update":async function(e,t){const{workspace:s,sessions:r,turns:n}=e,{sessionId:i,turn:o}=t;if(!s.index.sessions[i])return y({code:"NOT_FOUND",resource:"Session",id:i});await n.update(o,o);const a={id:o.id,version:o.version};return await r.update(i,{head:a}),f({index:{sessions:{[i]:{head:a}}}})},"turn:edit":async function(e,t){const{workspace:s,sessions:r,turns:n}=e,{sessionId:i,turnId:o,newBlocks:a,newVersion:c,roleSnapshot:d}=t,l=s.index.sessions[i];if(!l)return y({code:"NOT_FOUND",resource:"Session",id:i});const u=l.head;let p={};if(u&&u.id===o){const e=await n.get({id:u.id,version:u.version,session:i});e&&(p={...e})}const h={...p,id:o,version:c,blocks:a,role:d??p.role,timestamp:(new Date).toISOString(),parent:p.parent,actor:p.actor||"assistant",session:i};if(await n.add(h),l.head?.id===o){const e={id:o,version:c};return await r.update(i,{head:e}),f({index:{sessions:{[i]:{head:e}}}})}return f({})},"turn:branch":async function(e,t){const{workspace:s,sessions:r,turns:n}=e,{sessionId:i,turn:o}=t;if(!s.index.sessions[i])return y({code:"NOT_FOUND",resource:"Session",id:i});await n.add(o);const a={id:o.id,version:o.version};return await r.update(i,{head:a}),f({index:{sessions:{[i]:{head:a}}}})},"turn:delete":async function(e,t){const{workspace:s,sessions:r,turns:n}=e,{sessionId:i,turnId:o,newHead:a}=t;return s.index.sessions[i]?(await n.delete({session:i,id:o,version:t.version}),a?(await r.update(i,{head:a}),f({index:{sessions:{[i]:{head:a}}}})):f({})):y({code:"NOT_FOUND",resource:"Session",id:i})},"blob:register":async function(e,t){const{blobs:s}=e,r=await s.register(t.data,t.mediaType,t.filename);if(!r.ok)return r;const n=await s.getRecord(r.value.sha256);return n?f({index:{blobs:{[n.sha256]:n}}}):y({code:"BACKEND_ERROR",reason:`Failed to retrieve registered blob record for ${r.value.sha256}`})},"blob:retain":async function(e,t){const{blobs:s}=e,r=await s.retain(t.sha256);if(!r.ok)return r;const n=await s.getRecord(t.sha256);return f({index:{blobs:{[t.sha256]:n}}})},"blob:release":async function(e,t){const{blobs:s}=e,r=await s.release(t.sha256);if(!r.ok)return r;const n=await s.getRecord(t.sha256);return f({index:{blobs:{[t.sha256]:n||h}}})},"blob:purge":async function(e,t){const{blobs:s}=e,r=await s.purge(t.sha256);return r.ok?f({index:{blobs:{[t.sha256]:h}}}):r},"blob:record_remote_id":async function(e,t){const{blobs:s}=e,{sha256:r,providerId:n,fileId:i,timestamp:o}=t,a=await s.recordRemoteId(r,n,i,o);if(!a.ok)return a;const c=await s.getRecord(r);return f({index:{blobs:{[r]:c}}})},"tool:call":async function(e,t){return f({})}},j=class{profiles;constructor(e=[]){this.profiles=new Map;for(const t of e)this.profiles.set(t.name,t)}get(e){return this.profiles.get(e)}list(e){const t=Array.from(this.profiles.values());return e?t.filter((t=>t.provider===e)):t}register(e){this.profiles.set(e.name,e)}},B=[{type:"text",emittable:!0,description:["## Block: `text`","Primary communication block. Use for all conversational responses, explanations, and prose.","A response may contain multiple `text` blocks interleaved with other block types."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["text"]},text:{type:"string",description:"The raw markdown or plain text content of the response."}},required:["type","text"]}},{type:"summary",emittable:!0,description:["## Block: `summary`","Context compression block. Replaces older conversation history with a concise digest."].join("\n"),rules:["Only emit when explicitly instructed by the system to summarise.","Never emit more than one summary block per turn.","Preserve key decisions, outcomes, and unresolved questions.","Do not summarise the current turn — only prior history."],schema:{type:"object",properties:{type:{type:"string",enum:["summary"]},text:{type:"string",description:"A concise summary replacing older conversation context."}},required:["type","text"]}},{type:"thinking",emittable:!1,description:["## Block: `thinking`","Internal chain-of-thought produced by the model before its final response.","Injected by the workspace from provider reasoning tokens — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["thinking"]},thinking:{type:"string",description:"The internal reasoning text produced before the final response."}},required:["type","thinking"]}},{type:"tool:use",emittable:!1,description:["## Block: `tool:use`","Captures a model request to execute a registered tool.","Constructed by the workspace from the provider native function-call response — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["tool:use"]},name:{type:"string",description:"The exact registered name of the tool to execute."},input:{type:"object",description:"The parameter arguments for the tool execution.",additionalProperties:!0}},required:["type","name","input"]}},{type:"tool:result",emittable:!1,description:["## Block: `tool:result`","Contains the output of a tool execution, including any errors.","Injected by the workspace after a tool runs — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["tool:result"]},useId:{type:"string",description:"The UUID of the ToolUseBlock that triggered this execution."},content:{oneOf:[{type:"string"},{type:"object",additionalProperties:!0}],description:"The serialized output of the tool, or a structured JSON response."},isError:{type:"boolean",description:"True if the tool execution resulted in an error."}},required:["type","useId","content"]}},{type:"image",emittable:!1,description:["## Block: `image`","An image asset attached to a turn, resolved from the workspace blob store.","Constructed by the workspace from user uploads — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["image"]},altText:{type:"string",description:"Accessible description of the image content."}},required:["type"]}},{type:"document",emittable:!1,description:["## Block: `document`","A document asset (PDF, DOCX, etc.) attached to a turn, resolved from the workspace blob store.","Constructed by the workspace from user uploads — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["document"]},title:{type:"string",description:"Human-readable title or filename of the document."}},required:["type"]}},{type:"role:transition",emittable:!1,description:["## Block: `role:transition`","Marks that the active session persona has switched from one role to another.","Emitted by the workspace when the active persona changes — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["role:transition"]},previousRole:{type:"string",description:"The name of the role the session is leaving."},newRole:{type:"string",description:"The name of the role the session is adopting."}},required:["type","newRole"]}}];function A(e,t){let s=e.filter((e=>e.emittable));if(!t)return s;if(t.only&&t.only.length>0){const e=new Set(t.only);return s.filter((t=>e.has(t.type)))}if(t.exclude&&t.exclude.length>0){const e=new Set(t.exclude);return s.filter((t=>!e.has(t.type)))}return s}var C=class{store=new Map;constructor(){for(const e of B)this.store.set(e.type,e)}register(e){if(this.store.has(e.type))throw new Error(`[BlockRegistry] Block type "${e.type}" is already registered. Use update() to modify it.`);this.store.set(e.type,{...e,emittable:!0,rules:[]})}unregister(e){if(!this.store.has(e))throw new Error(`[BlockRegistry] Cannot unregister unknown block type "${e}".`);this.store.delete(e)}update(e,t){const s=this.store.get(e);s?this.store.set(e,{...s,...t,type:e}):this.store.set(e,{emittable:!0,rules:[],...t,type:e})}get(e){return this.store.get(e)}list(){return Array.from(this.store.values())}isType(e,t){return e.type===t}guard(e){return t=>t.type===e}schema(e){return{type:"object",description:"The model's structured response, containing an ordered sequence of content blocks.",properties:{blocks:{type:"array",description:"An ordered array of content blocks comprising the model's response.",items:{anyOf:A(Array.from(this.store.values()),e).map((e=>e.schema))}}},required:["blocks"]}}description(e){return["# BLOCK TYPES & USAGE RULES","","Your response MUST be a JSON object with a `blocks` array.","Each element of `blocks` must be one of the following types:","",A(Array.from(this.store.values()),e).map((e=>{const t=[e.description];return e.rules.length>0&&(t.push("**Rules:**"),t.push(...e.rules.map((e=>`- ${e}`)))),t.join("\n")})).join("\n\n"),"","## GLOBAL CONSTRAINTS","","- Output must be **valid JSON only** — no prose before or after the JSON object.","- Responses may contain multiple blocks. Blocks are rendered in order.","- **Do NOT generate IDs.** The workspace is solely responsible for block ID assignment.","- Do not infer or invent fields not defined in the block schemas above."].join("\n")}rules(e){const t=A(Array.from(this.store.values()),e);return Object.fromEntries(t.map((e=>[e.type,[...e.rules]])))}setRules(e,t){const s=this.store.get(e);if(!s)throw new Error(`[BlockRegistry] Cannot set rules on unknown block type "${e}".`);this.store.set(e,{...s,rules:t})}parse(e,s){const r=this.store.get(e.type);if(!r)return console.warn(`[BlockRegistry] parse() received unknown block type "${e.type}". Returning null.`),null;if(s&&r.mappings?.[s])return r.mappings[s].from(e);const{id:n,...i}=e;return{id:t.v7(),...i}}create(e,s){if(!this.store.has(e))throw new Error(`[BlockRegistry] Cannot create block of unknown type "${e}".`);return{...s,id:t.v7(),type:e}}clone(e,s){return{...structuredClone(e),...s,id:t.v7()}}},q=class{store=new Map;constructor(){this.registerDefaults()}registerDefaults(){this.register({kind:"text",target:"system",render:e=>({id:e.key,type:"text",text:e.content.value}),toString:e=>e.content.value,summarize:e=>({key:e.key,kind:"text",topics:e.topics,timestamp:e.timestamp,preview:e.content.value.slice(0,100)})}),this.register({kind:"json",target:"system",render:e=>({id:e.key,type:"text",text:JSON.stringify(e.content.value,null,2)}),toString:e=>JSON.stringify(e.content.value),summarize:e=>({key:e.key,kind:"json",topics:e.topics,timestamp:e.timestamp,preview:"JSON Data"})}),this.register({kind:"blob",target:"transcript",render:e=>{const{sha256:t,mediaType:s,sizeBytes:r,filename:n}=e.content,i={sha256:t,mediaType:s,sizeBytes:r,filename:n};return s.startsWith("image/")?{id:e.key,type:"image",ref:i}:{id:e.key,type:"document",ref:i,title:n}},toString:e=>e.content.filename||"unnamed blob",summarize:e=>({key:e.key,kind:"blob",topics:e.topics,timestamp:e.timestamp,mime:e.content.mediaType,size:e.content.sizeBytes,preview:e.content.filename})})}register(e){if(this.store.has(e.kind))throw new Error(`[ContextRegistry] Context kind "${e.kind}" is already registered.`);this.store.set(e.kind,e)}get(e){return this.store.get(e)}list(){return Array.from(this.store.values())}},U="__system__",$=class{constructor(e,s,r){this._actor=e,this._turn=r?JSON.parse(JSON.stringify(r)):{id:t.v7(),session:s,version:0,actor:this._actor,blocks:[],timestamp:(new Date).toISOString(),role:void 0}}_turn;addText(e){const s={id:t.v7(),type:"text",text:e};return this._turn.blocks.push(s),this}addImage(e,s){const r={id:t.v7(),type:"image",ref:e,altText:s};return this._turn.blocks.push(r),this}addDocument(e,s){const r={id:t.v7(),type:"document",ref:e,title:s};return this._turn.blocks.push(r),this}addToolUse(e,s){const r={id:t.v7(),type:"tool:use",name:e,input:s};return this._turn.blocks.push(r),this}addToolResult(e,s,r){const n={id:t.v7(),type:"tool:result",useId:e,content:s,isError:r};return this._turn.blocks.push(n),this}addSummary(e){const s={id:t.v7(),type:"summary",text:e};return this._turn.blocks.push(s),this}addRoleTransition(e,s){const r={id:t.v7(),type:"role:transition",previousRole:e,newRole:s};return this._turn.blocks.push(r),this}addThinking(e){const s={id:t.v7(),type:"thinking",thinking:e};return this._turn.blocks.push(s),this}addBlock(e){return e.id||(e.id=t.v7()),this._turn.blocks.push(e),this}deleteBlock(e){return this._turn.blocks=this._turn.blocks.filter((t=>t.id!==e)),this}editTextBlock(e,t){const s=this._turn.blocks.findIndex((t=>t.id===e));if(-1===s)throw new Error(`Block with ID ${e} not found.`);const r=this._turn.blocks[s];if("text"!==r.type)throw new Error(`Block with ID ${e} is not a TextBlock.`);return this._turn.blocks[s]={...r,text:t},this}withId(e){return this._turn.id=e,this}withVersion(e){return this._turn.version=e,this}withTimestamp(e){return this._turn.timestamp=e,this}withParent(e){return this._turn.parent=e,this}withRoleSnapshot(e){return this._turn.role=e,this}build(){return JSON.parse(JSON.stringify(this._turn))}},z=class{constructor(e,t){this.turnStore=e,this.sessionStore=t}async loadAllTurns(e){return this.turnStore.listBySession(e)}async loadHead(e){const t=await this.sessionStore.get(e);return t?.head??null}},M=class e{constructor(e,t){this.nodes=e,this._head=t}static async build(t,s){const[r,n]=await Promise.all([s.loadAllTurns(t),s.loadHead(t)]),i=function(e,t){const s=function(e,t){if(!t)return new Set;const s=new Map;for(const t of e)s.set(`${t.id}:${t.version}`,t);const r=new Set;let n=t;for(;n;){const e=`${n.id}:${n.version}`;if(r.has(e))break;r.add(e);const t=s.get(e);if(!t)break;n=t.parent}return r}(e,t),r={},n={};for(const t of e){r[t.id]||(r[t.id]={id:t.id,versions:{},activeVersion:t.version,actor:t.actor,blocks:t.blocks,timestamp:t.timestamp,roleSnapshot:t.role,parent:t.parent,children:{}},n[t.id]=new Set);const e=r[t.id];e.versions[t.version]=t;const i=s.has(`${t.id}:${t.version}`),o=s.has(`${t.id}:${e.activeVersion}`);if(i&&(!o||t.version>=e.activeVersion)&&(e.activeVersion=t.version,e.blocks=t.blocks,e.timestamp=t.timestamp,e.roleSnapshot=t.role,e.parent=t.parent),t.parent){const e=`${t.parent.id}:${t.parent.version}`;if(n[t.parent.id]||(n[t.parent.id]=new Set),!n[t.parent.id].has(e+":"+t.id)){n[t.parent.id].add(e+":"+t.id),r[t.parent.id]||(r[t.parent.id]={id:t.parent.id,versions:{},activeVersion:t.parent.version,actor:"user",blocks:[],timestamp:"",roleSnapshot:void 0,children:{}});const s=r[t.parent.id];s.children[t.parent.version]||(s.children[t.parent.version]=[]),s.children[t.parent.version].push(t.id)}}}return r}(r,n);return new e(i,n)}head(){return this._head}chain(){if(!this._head)return[];const e=[];let t=this._head.id;for(;t;){const s=this.nodes[t];if(!s)break;e.push(s),t=s.parent?.id??null}return e.reverse()}getTurnSiblings(e){const t=this.nodes[e];if(!t)return[];if(!t.parent)return Object.values(this.nodes).filter((e=>!e.parent));const s=this.nodes[t.parent.id];if(!s)return[t];const r=s.children[t.parent.version];return r?r.map((e=>this.nodes[e])).filter((e=>!!e)):[t]}branchInfo(e){const t=this.nodes[e];if(!t)return{versions:[],currentIndex:-1,total:0,hasPrev:!1,hasNext:!1};const s=Object.keys(t.versions).map(Number).sort(((e,t)=>e-t)),r=s.indexOf(t.activeVersion);return{versions:s,currentIndex:r,total:s.length,hasPrev:r>0,hasNext:r<s.length-1}}graph(){return{...this.nodes}}};var P=class{constructor(e){this.manager=e}get workspace(){return this.manager.workspace()}roles(){return this.manager.ctx().roles.list()}role(e){return this.manager.ctx().roles.get(e)}async createRole(e,t,s,r,n=[]){if(this.workspace.index.roles[e])return y({code:"DUPLICATE_KEY",resource:"role",key:e});const i={name:e,label:t,description:r,persona:s,preferences:n,topics:[]};return this.manager.dispatch({type:"role:add",payload:i,timestamp:(new Date).toISOString()})}async updateRole(e,t){return this.workspace.index.roles[e]?this.manager.dispatch({type:"role:update",payload:{name:e,...t},timestamp:(new Date).toISOString()}):y({code:"NOT_FOUND",resource:"role",id:e})}async deleteRole(e){const t=this.workspace;if(!t.index.roles[e])return y({code:"NOT_FOUND",resource:"role",id:e});return Object.values(t.index.sessions).some((t=>t.role===e))?y({code:"INVALID_COMMAND",reason:`Cannot delete role "${e}" — it is still referenced by one or more sessions`}):this.manager.dispatch({type:"role:delete",payload:{name:e},timestamp:(new Date).toISOString()})}async addPreference(e,t){const s={id:crypto.randomUUID(),content:e,topics:t,timestamp:(new Date).toISOString()};return this.manager.dispatch({type:"preference:add",payload:s,timestamp:s.timestamp})}preferences(){return this.manager.ctx().preferences.list()}async addContext(e,t,s,r){const n={key:e,topics:s,content:t,timestamp:(new Date).toISOString(),metadata:r};return this.manager.dispatch({type:"context:add",payload:n,timestamp:n.timestamp})}context(){return this.manager.ctx().context.list()}async registerBlob(e,t,s){const r=await this.manager.dispatch({type:"blob:register",payload:{data:e,mediaType:t,filename:s},timestamp:(new Date).toISOString()});if(!r.ok)return y(r.error);const n=r.value,i=n?.index?.blobs;if(!i)return y({code:"BACKEND_ERROR",reason:"Blob registration succeeded but no blobs patch returned"});const o=Object.keys(i)[0];if(!o)return y({code:"BACKEND_ERROR",reason:"No SHA256 in patch"});const a=i[o];if(!a)return y({code:"BACKEND_ERROR",reason:"Blob record missing"});return f({sha256:o,ref:{sha256:o,mediaType:a.mediaType,sizeBytes:a.sizeBytes,filename:a.filename,previewUrl:a.previewUrl}})}},F=class e{constructor(e,t,s,r){this._id=e,this.manager=t,this.processor=s,this.turnRepository=r,this.workspace=new P(t),this.unsubscribe=t.subscribe("workspace:synced",(()=>this.sync()))}workspace;_role=void 0;_preferences=[];tree;unsubscribe;static async create(t,s,r){s.ctx().workspace;const n=new z(s.ctx().turns,s.ctx().sessions),i=new e(t,s,r,n);return await i.sync(),i}async sync(){await this._setRole(),await this._setPreference(),await this.refreshTurnTree()}close(){this.unsubscribe?.()}async _setRole(){const e=this.meta(),t=await this.manager.ctx().roles.get(e.role);t&&(this._role=t)}async _setPreference(){const e=this.meta();this._preferences=await this.manager.ctx().preferences.load(e.preferences)}id(){return this._id}ws(){return this.manager.workspace()}meta(){return this.ws().index.sessions[this._id]}label(){return this.meta()?.label}role(){return this._role}topics(){return this.meta()?.topics??[]}preferences(){return this._preferences}head(){return this.meta()?.head??null}turns(){return this.tree.chain()}async siblings(e){return this.tree.getTurnSiblings(e)}async branchInfo(e){return this.tree.branchInfo(e)}async getTurn(e){return this.tree.graph()[e]}async rename(e){return this.meta()?this.dispatch({type:"session:update",payload:{sessionId:this._id,label:e},timestamp:(new Date).toISOString()}):y({code:"NOT_FOUND",resource:"session",id:this._id})}async setTopics(e){return this.meta()?this.dispatch({type:"session:update",payload:{sessionId:this._id,topics:e},timestamp:(new Date).toISOString()}):y({code:"NOT_FOUND",resource:"session",id:this._id})}async addTopics(e){return this.meta()?this.dispatch({type:"session:topics:add",payload:{sessionId:this._id,topics:e},timestamp:(new Date).toISOString()}):y({code:"NOT_FOUND",resource:"session",id:this._id})}async setPreferences(e){if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});const t=await this.dispatch({type:"session:preferences:override",payload:{sessionId:this._id,preferences:e},timestamp:(new Date).toISOString()});return t.ok&&await this._setPreference(),t}async fork(e,t,s,r){return this.meta()?this.dispatch({type:"session:fork",payload:{sessionId:this._id,newSessionId:e,label:t,role:s,topics:r},timestamp:(new Date).toISOString()}):y({code:"NOT_FOUND",resource:"session",id:this._id})}async dispatch(e){return this.manager.dispatch(e)}async switchRole(e){const t=this.ws();if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});if(e!==U&&!t.index.roles[e])return y({code:"NOT_FOUND",resource:"role",id:e});const s=await this.dispatch({type:"session:update",payload:{sessionId:this._id,role:e},timestamp:(new Date).toISOString()});return s.ok&&await this._setRole(),s}async addTurn(e){if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});const t={...e,session:this._id,version:e.version??0,parent:!e.parent&&this.head()?this.head():void 0},s=await this.dispatch({type:"turn:add",payload:{sessionId:this._id,turn:t},timestamp:t.timestamp});return s.ok&&await this.refreshTurnTree(),s}async recordUserTurn(e){return this.meta()?this.addTurn(e):y({code:"NOT_FOUND",resource:"session",id:this._id})}async recordAssistantTurn(e,t){const s=this.ws();if(!s)return y({code:"NOT_FOUND",resource:"workspace",id:"current"});if(!s.index.sessions[this._id])return y({code:"NOT_FOUND",resource:"session",id:this._id});const r=this.processor.process(e,this._id);let n={};const i=[];for(const e of r){const t=await this.manager.dispatch(e);if(t.ok)n=g(n,t.value);else{if("PERMISSION_DENIED"!==t.error.code||e.synthetic)return t;{const t=this.describeCommand(e);i.push({cmd:e,description:t})}}}const o=await this.addTurn(e);if(!o.ok)return o;if(n=g(n,o.value),t&&i.length>0){const e=this.buildDenialTurn(i),t=await this.addTurn(e);t.ok&&(n=g(n,t.value))}return f(n)}buildDenialTurn(e){const t=new $("user",this._id);for(const s of e)t.addText(`[System] User denied: ${s.description}.`);return t.build()}describeCommand(e){return"tool:call"===e.type?`tool execution: ${e.payload.tool}`:`command: ${e.type}`}async editTurn(e,t,s){if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});const r=this.tree.graph()[e];if(!r)return y({code:"NOT_FOUND",resource:"turn",id:e});const n=r.versions[r.activeVersion],i=r.activeVersion+1,o=await this.dispatch({type:"turn:edit",payload:{sessionId:this._id,turnId:e,newBlocks:t,roleSnapshot:s??n.role,newVersion:i},timestamp:(new Date).toISOString()});return o.ok&&(await this.dispatch({type:"session:update",payload:{sessionId:this._id,head:{id:e,version:i}},timestamp:(new Date).toISOString()}),await this.refreshTurnTree()),o}async branch(e){if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});if(!e.parent)return y({code:"INVALID_COMMAND",reason:"branch requires turn.parent to be set"});const t=await this.dispatch({type:"turn:branch",payload:{sessionId:this._id,turn:{...e,session:this._id}},timestamp:e.timestamp});return t.ok&&await this.refreshTurnTree(),t}async deleteTurn(e,t,s){if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});const r=this.tree.graph();if(!r[e]?.versions[t])return y({code:"NOT_FOUND",resource:"turn version",id:`${e}:${t}`});const n=await this.dispatch({type:"turn:delete",payload:{sessionId:this._id,turnId:e,version:t,newHead:s},timestamp:(new Date).toISOString()});return n.ok&&await this.refreshTurnTree(),n}async switchVersionLeft(e){return this.switchVersion(e,-1)}async switchVersionRight(e){return this.switchVersion(e,1)}async switchVersion(e,t){if(!this.ws())return y({code:"NOT_FOUND",resource:"workspace",id:"current"});if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});const s=this.tree.graph()[e];if(!s)return y({code:"NOT_FOUND",resource:"turn",id:e});const r=Object.keys(s.versions).map(Number).sort(((e,t)=>e-t)),n=r.indexOf(s.activeVersion);if(-1===n)return y({code:"INVALID_COMMAND",reason:"Active version not found"});const i=n+t;if(i<0||i>=r.length)return y({code:"INVALID_COMMAND",reason:`No ${t<0?"previous":"next"} version available for turn ${e}`});const o=r[i],a=this.findSubtreeTip(this.tree.graph(),e,o),c=await this.dispatch({type:"session:update",payload:{sessionId:this._id,head:a},timestamp:(new Date).toISOString()});return c.ok&&await this.refreshTurnTree(),c}async snapshot(){const e=this,t=e.meta();if(!t)return;const s=e.ws(),r=e._role;if(!r)return;const n=await e.manager.ctx().context.getByTopics(s.index,t.topics),i=Array.from(new Set([...r.preferences,...t.preferences])),o=i.length>0?await e.manager.ctx().preferences.load(i):e._preferences,a=e.tree.chain().map((e=>e.versions[e.activeVersion])).filter((e=>!!e)),c=[...a].reverse().find((e=>"user"===e.actor));return{id:e._id,meta:t,role:r,preferences:o,context:n,model:t.metadata?.model,transcript:a,topics:t.topics,instructions:s.settings?.prompt,constraints:{role:r.constraints,session:t.constraints,turn:c?.constraints}}}async refreshTurnTree(){this.tree=await M.build(this._id,this.turnRepository)}findSubtreeTip(e,t,s){let r=t,n=s;for(;;){const t=e[r];if(!t)break;const s=t.children[n];if(!s||0===s.length)break;const i=s[0],o=e[i];if(!o)break;r=i,n=o.activeVersion}return{id:r,version:n}}},K=class{constructor(e,t){this.manager=e,this.processor=t}openOnce=new Map;async open(e){let t=this.openOnce.get(e);t||(t=new d,this.openOnce.set(e,t));const s=await t.do((async()=>{if(!this.manager.workspace().index.sessions[e])throw new Error(`Session ${e} not found in workspace index`);return F.create(e,this.manager,this.processor)}));if(s.error)throw s.error;return s.value}close(e){this.openOnce.delete(e)}async delete(e){const t=await this.manager.dispatch({type:"session:delete",payload:{sessionId:e},timestamp:(new Date).toISOString()});if(t.ok)return this.close(e),t.value=void 0,t;throw t.error}async has(e){return!this.manager.workspace().index.sessions[e]}async create(e){const s=t.v7(),r=await this.manager.dispatch({type:"session:create",payload:{id:s,label:e.label,role:e.role,topics:e.topics,preferences:e.preferences??[],metadata:{created:(new Date).toISOString()}},timestamp:(new Date).toISOString()});if(r.ok)return this.open(s);throw r.error}list(){return Object.values(this.manager.workspace().index.sessions)}metadata(e){return this.manager.workspace().index.sessions[e]}},L=class{constructor(e,t,s){this.storage=e,this.cache=t,this.bus=s}async register(e,t,s){const r=await w(e),n=await this.getRecord(r);if(n){const e={...n,refCount:n.refCount+1,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(e),this.cache.set(r,e),f(this.reference(e))}const i={sha256:r,mediaType:t,sizeBytes:e.byteLength,filename:s,refCount:1,remoteIds:{},createdAt:(new Date).toISOString(),lastUsedAt:(new Date).toISOString()};return this.storage.registerBlob?await this.storage.registerBlob(i,e):(await this.storage.storeBytes(r,e),await this.storage.saveRecord(i)),this.cache.set(r,i),this.bus.emit({name:"blobs:changed",payload:{sha256:r,record:i}}),f(this.reference(i))}async retain(e){const t=await this.getRecord(e);if(!t)return y({code:"NOT_FOUND",resource:"blob",id:e});const s={...t,refCount:t.refCount+1,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(s),this.cache.set(e,s),f(void 0)}async release(e){const t=await this.getRecord(e);if(!t)return y({code:"NOT_FOUND",resource:"blob",id:e});const s=Math.max(0,t.refCount-1),r={...t,refCount:s,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(r),this.cache.set(e,r),f(void 0)}async purge(e){return await this.storage.deleteBytes(e),await this.storage.deleteRecord(e),this.cache.delete(e),this.bus.emit({name:"blobs:changed",payload:{sha256:e}}),f(void 0)}async recordRemoteId(e,t,s,r){const n=await this.getRecord(e);if(!n)return y({code:"NOT_FOUND",resource:"blob",id:e});const i={...n,remoteIds:{...n.remoteIds,[t]:{id:s,timestamp:r||(new Date).toISOString()}},lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(i),this.cache.set(e,i),this.bus.emit({name:"blobs:changed",payload:{sha256:e,record:i}}),f(void 0)}async getRecord(e){const t=this.cache.get(e);if(t)return t;const s=await this.storage.loadRecord(e);return s&&this.cache.set(e,s),s}async getAllRecords(){const e=await this.storage.listRecords(),t={};for(const s of e)t[s.sha256]=s,this.cache.set(s.sha256,s);return t}reference(e){return{sha256:e.sha256,mediaType:e.mediaType,sizeBytes:e.sizeBytes,filename:e.filename}}async resolve(e,t){const s=await this.getRecord(e.sha256);if(!s)return f(null);if(t){const e=s.remoteIds[t];if(e)return f({kind:"remote",sha256:s.sha256,mediaType:s.mediaType,fileId:e.id,providerId:t,timestamp:e.timestamp});const r=await this.storage.loadBytes(s.sha256);return f(r?{kind:"inline",sha256:s.sha256,mediaType:s.mediaType,data:r}:null)}const r=await this.storage.loadBytes(s.sha256);return f(r?{kind:"inline",sha256:s.sha256,mediaType:s.mediaType,data:r}:null)}async resolveMany(e,t){const s=new Map;for(const r of e){const e=await this.resolve(r,t);if(!e.ok)return y(e.error);if(null===e.value)return y({code:"BLOB_ERROR",reason:`Unable to resolve blob ${r.sha256}${t?` with adapter ${t}`:""}`});s.set(r.sha256,e.value)}return f(s)}},W=class{constructor(e,t,s){this.collection=e,this.cache=t,this.registry=s}delegates=new Map;registerDelegate(e,t){this.delegates.set(e,t)}async get(e,t){const s=this.cache.get(e);if(s)return s;if(t){const s=this.delegates.get(t);if(s){const t=await s.get(e);return t&&this.cache.set(e,t),t}}const r=await this.collection.find({field:"key",operator:"eq",value:e});if(!r)return null;const n=r.state();return this.cache.set(e,n),n}async add(e){const t=this.delegates.get(e.content.kind);t?await t.add(e):await this.collection.create(e),this.cache.set(e.key,e)}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"}),t=((await e.next()).value||[]).map((e=>e.state()));for(const e of this.delegates.values()){const s=await e.list();t.push(...s)}return t}async update(e,t,s){if(s){const r=this.delegates.get(s);if(r){const s=await r.update(e,t);return s&&this.cache.set(e,s),s}}const r=await this.collection.find({field:"key",operator:"eq",value:e});if(!r)return null;await r.update(t);const n=r.state();return this.cache.set(e,n),n}async delete(e,t){if(t){const s=this.delegates.get(t);if(s){const t=await s.delete(e);return t&&this.cache.delete(e),t}}const s=await this.collection.find({field:"key",operator:"eq",value:e});if(!s)return!1;const r=await s.delete();return r&&this.cache.delete(e),r}async getByTopics(e,t){const s=new Map;for(const r of t){const t=e.topics[r];t&&t.contextKeys.forEach((t=>{const r=e.context[t],n=r?.kind||"unknown";s.has(n)||s.set(n,new Set),s.get(n).add(t)}))}if(0===s.size)return[];const r=[],n=[];for(const[e,t]of s.entries()){if(this.delegates.get(e))for(const s of t){const t=await this.get(s,e);t&&r.push(t)}else t.forEach((e=>n.push(e)))}if(n.length>0){const e=[];for(const t of n){const s=this.cache.get(t);s?r.push(s):e.push(t)}if(e.length>0){const t=await this.collection.filter({operator:"or",conditions:e.map((e=>({field:"key",operator:"eq",value:e})))});for(const e of t){const t=e.state();this.cache.set(t.key,t),r.push(t)}}}return r.sort(((e,t)=>new Date(t.timestamp).getTime()-new Date(e.timestamp).getTime()))}summarize(e){const t=this.registry?.get(e.content.kind);return t?t.summarize(e):{kind:e.content.kind,key:e.key,topics:e.topics,timestamp:e.timestamp,metadata:e.metadata}}},V=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;const r=s.state();return this.cache.set(e,r),r}async add(e){await this.collection.create(e),this.cache.set(e.id,e)}async update(e,t){const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;await s.update(t);const r=s.state();return this.cache.set(e,r),r}async delete(e){const t=await this.collection.find({field:"id",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async load(e){if(0===e.length)return[];const t=[],s=[];for(const r of e){const e=this.cache.get(r);e?s.push(e):t.push(r)}if(t.length>0){const e=await this.collection.filter({operator:"or",conditions:t.map((e=>({field:"id",operator:"eq",value:e})))});for(const t of e){const e=t.state();this.cache.set(e.id,e),s.push(e)}}return s}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return{id:e.id,topics:e.topics,timestamp:e.timestamp,snippet:e.content.slice(0,100)}}},J=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;const r=s.state();return this.cache.set(e,r),r}async add(e){await this.collection.create(e),this.cache.set(e.name,e)}async update(e,t){const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;await s.update(t);const r=s.state();return this.cache.set(e,r),r}async delete(e){const t=await this.collection.find({field:"name",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return{name:e.name,label:e.label,description:e.description,preferences:e.preferences?.length??0,topics:e.topics??[],constraints:e.constraints}}},G=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;const r=s.state();return this.cache.set(e,r),r}async add(e){await this.collection.create(e),this.cache.set(e.id,e)}async update(e,t){const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;await s.update(t);const r=s.state();return this.cache.set(e,r),r}async delete(e){const t=await this.collection.find({field:"id",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return e}},Y=class{constructor(e,t){this.collection=e,this.cache=t}key({id:e,session:t,version:s}){return`${t}:${s}:${e}`}async find({id:e,session:t,version:s},r=!0){const n=this.key({id:e,session:t,version:s});this.cache.get(n)&&this.cache.get(n);const i=await this.collection.find({operator:"and",conditions:[{field:"id",operator:"eq",value:e},{field:"session",operator:"eq",value:t},{field:"version",operator:"eq",value:s}]});return i?(r&&this.cache.set(n,i),i):null}async get(e){return this.find(e)}async add(e){const t=await this.collection.create(e);this.cache.set(this.key(e),t)}async update(e,t){const s=await this.find(e);return s?(await s.update(t),s.state()):null}async listBySession(e){return(await this.collection.filter({field:"session",operator:"eq",value:e})).map((e=>e.state()))}async delete(e){const t=await this.find(e,!1);if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(this.key(e)),s}},H=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;const r=s.state();return this.cache.set(e,r),r}async add(e){await this.collection.create(e),this.cache.set(e.id,e)}async update(e,t){const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;await s.update(t);const r=s.state();return this.cache.set(e,r),r}async delete(e){const t=await this.collection.find({field:"id",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async list(){const e=await this.collection.list({limit:100,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return e}},X=class{cache;maxSize;constructor(e){this.cache=new Map,this.maxSize=e}get(e){const t=this.cache.get(e);return void 0!==t&&(this.cache.delete(e),this.cache.set(e,t)),t}set(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.maxSize){const e=this.cache.keys().next().value;void 0!==e&&this.cache.delete(e)}this.cache.set(e,t)}has(e){return this.cache.has(e)}delete(e){this.cache.delete(e)}clear(){this.cache.clear()}},Q=(e={})=>({id:e.id??t.v7(),settings:g({language:"en-US",defaultRole:void 0,prompt:void 0},e.settings),project:g({id:t.v7(),name:"Unnamed Project"},e.project),index:g({roles:{},preferences:{},context:{},sessions:{},topics:{},blobs:{},tools:{},extensions:{}},e.index)});function Z(e,t,s){const r=new Set([...Object.keys(e??{}),...Object.keys(t??{}),...Object.keys(s??{})]),n={};for(const i of r){const r=e?.[i]??{},o=t?.[i]??{},a=s?.[i]??{};n[i]={temperature:a.temperature??o.temperature??r.temperature,tokens:{max:a.tokens?.max??o.tokens?.max??r.tokens?.max,stops:a.tokens?.stops??o.tokens?.stops??r.tokens?.stops,thought:a.tokens?.thought??o.tokens?.thought??r.tokens?.thought}}}return n}function ee(e,s,r){return{id:t.v7(),session:e,version:0,actor:s,blocks:r,timestamp:(new Date).toISOString()}}var te="blob_bytes",se="blob_records";function re(e){return new Promise(((t,s)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>s(e.error)}))}function ne(e){return new Promise(((t,s)=>{e.oncomplete=()=>t(),e.onerror=()=>s(e.error),e.onabort=()=>s(new Error("Transaction aborted"))}))}var ie={};((e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})})(ie,{GOOGLE_MODELS:()=>ae,GoogleGenAIAdapter:()=>he,mapBlockToPart:()=>le,mapTurnToContent:()=>de,mappings:()=>oe,parseModelResponse:()=>ce});var oe={text:{to:e=>({text:e.text}),from:e=>({id:t.v4(),type:"text",text:e.text})},summary:{to:e=>({text:`[Summary]: ${e.text}`}),from:e=>({id:t.v4(),type:"summary",text:e.text})},thinking:{to:e=>({text:e.thinking}),from:e=>({id:t.v4(),type:"thinking",thinking:e.thinking})},"tool:use":{to:e=>({functionCall:{name:e.name,args:e.input}}),from:e=>({id:t.v4(),type:"tool:use",name:e.functionCall?.name??e.name,input:e.functionCall?.args??e.input??{}})},"tool:result":{to:e=>({functionResponse:{name:e.useId,response:{result:e.content}}}),from:e=>({id:t.v4(),type:"tool:result",useId:e.useId,content:e.content,isError:e.isError})},"role:transition":{to:e=>({text:`[Role transition: ${e.previousRole??"none"} → ${e.newRole}]`}),from:e=>({id:t.v4(),type:"role:transition",previousRole:e.previousRole,newRole:e.newRole})}},ae=[{provider:"google",name:"gemini-3.1-pro-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:2,output:12,cache:{read:.2,write:4.5}}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-3-flash-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.5,output:3,cache:{read:.05,write:1}}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-3.1-flash-lite-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.25,output:1.5,cache:{read:.025,write:1}}}],capacity:[{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-2.5-pro",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:1.25,output:10,cache:{read:.125,write:4.5}}}],capacity:[{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-2.5-flash",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.3,output:2.5,cache:{read:.03,write:1}}}],capacity:[{unit:"call",max:4e3,period:60},{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-2.5-flash-lite",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.1,output:.4,cache:{read:.01,write:1}}}],capacity:[{unit:"call",max:4e3,period:60},{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-3-pro-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:2,output:12,cache:{read:.2,write:4.5}}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-2.5-flash-image",window:{size:4096,out:0},feature:{vision:!1,tools:!1,json:!1,cache:!1,streaming:!1,thinking:!1},pricing:[{unit:"image",scale:0,cost:{input:.02,output:0}}],capacity:[{unit:"call",max:100,period:60}]},{provider:"google",name:"gemini-2.5-flash-live-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.5,output:3}}],capacity:[{unit:"concurrent",max:10,period:0}]},{provider:"google",name:"gemini-3.1-flash-live-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.5,output:3}}],capacity:[{unit:"concurrent",max:10,period:0}]},{provider:"google",name:"gemini-2.5-computer-use-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:1.25,output:10}}],capacity:[{unit:"call",max:200,period:60},{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-embedding-001",window:{size:2048,out:0},feature:{vision:!1,tools:!1,json:!1,cache:!1,streaming:!1,thinking:!1},pricing:[{unit:"token",scale:6,cost:{input:.5,output:0}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-embedding-2",window:{size:8192,out:0},feature:{vision:!1,tools:!1,json:!1,cache:!1,streaming:!1,thinking:!1},pricing:[{unit:"token",scale:6,cost:{input:.3,output:0}}],capacity:[{unit:"token",max:1e6,period:60}]}];function ce(e,s){const r=e.candidates?.[0];if(!r?.content?.parts)return y({code:"BACKEND_ERROR",reason:"No valid content parts in response"});const n=[];let i;for(const e of r.content.parts)if(e.thought)n.push((o=e.text??"",{id:t.v7(),type:"thinking",thinking:o}));else if(e.text){i=e;break}var o;if(!i)return y({code:"BACKEND_ERROR",reason:"Response missing JSON part"});const a=function(e){try{const t=JSON.parse(e);return t.blocks&&Array.isArray(t.blocks)?f(t.blocks):y({code:"BACKEND_ERROR",reason:'Invalid response: missing or malformed "blocks" array'})}catch(e){return y({code:"BACKEND_ERROR",reason:`Failed to parse response JSON: ${e instanceof Error?e.message:String(e)}`})}}(i.text);if(!a.ok)return a;for(const e of a.value){const t=s.parse(e,he.provider());t&&n.push(t)}return f(n)}async function de(e,t,s){const r="assistant"===e.actor?"model":"user",n=[];for(const r of e.blocks){if("image"===r.type||"document"===r.type){const e=r.ref;if(!e)continue;const s=await ue(e,t);s&&n.push(s);continue}const e=le(r,s);e&&n.push(e)}return{role:r,parts:n}}function le(e,t){const s=t.get(e.type);if(!s)throw new Error(`[GoogleGenAIAdapter] mapBlockToPart: block type "${e.type}" is not registered. Register it via registry.register() before use.`);const r=s.mappings?.[he.provider()];if(!r)throw new Error(`[GoogleGenAIAdapter] mapBlockToPart: no "${he.provider()}" mapping for block type "${e.type}". Add a mapping via registry.update("${e.type}", { mappings: { ${he.provider()}: { to, from } } }).`);return r.to(e)}async function ue(e,t){const s=await t(e,he.provider());if(!s.ok||!s.value)return null;const{value:r}=s;return"remote"===r.kind?{fileData:{fileUri:r.fileId,mimeType:r.mediaType}}:{inlineData:{data:b(r.data),mimeType:r.mediaType}}}function pe(e){return Math.ceil(e.length/4)}var he=class e{constructor(e,t,s={model:"gemini-2.5-flash"}){this.client=e,this.services=t,this._models=t.models;const r=this._models.get(s.model);if(!r)throw new Error(`Could not get model: ${s.model} profile in registry.`);this.model=r,this.registerGeminiMappings()}model;_models;registerGeminiMappings(){const t=this.services.blockRegistry;for(const[s,r]of Object.entries(oe))t.update(s,{mappings:{[e.provider()]:r}})}async status(t){return{provider:e.provider(),model:this.model.name,ready:!0,window:this.model.window,feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.1,output:.4}}],rate:{load:0,capacity:[{unit:"call",max:1e3,period:60},{unit:"token",max:4e6,period:60}]}}}async resolve(e){const{prompt:s}=e,{assembler:r,blockRegistry:n,blobResolver:i}=this.services,o=s.model&&this._models.get(s.model)||this.model,a=r.build(s,[{label:"block-architecture",content:n.description(),position:"after:instructions"}]),c=r.join(a),d={role:"system",parts:[{text:c}]},l=s.constraints[o.name]??{tokens:{}},u=await Promise.all(s.transcript.map((e=>de(e,i,n)))),p=n.schema(),h={model:o.name,contents:u,config:{systemInstruction:d,thinkingConfig:{includeThoughts:!0},responseMimeType:"application/json",responseSchema:p,...void 0!==l.temperature&&{temperature:l.temperature},...void 0!==l.tokens.max&&{maxOutputTokens:l.tokens.max},...l.tokens.stops?.length&&{stopSequences:l.tokens.stops},...void 0!==l.tokens.thought&&{thinkingConfig:{includeThoughts:!0,thinkingBudget:l.tokens.thought}}}},m=u.flatMap((e=>e.parts??[])).map((e=>e.text??"")).join(""),g=pe(c),w=pe(m),b=g+w,k=this;return{model:o.name,instructions:a,transcript:s.transcript,context:s.system.context,preferences:s.system.preferences,constraints:l,tokens:{breakdown:{system:g,transcript:w},total:b,source:"estimated",output:l.tokens.max??o.window.out,remaining:o.window.size-b},async execute(){let e;try{e=await k.client.models.generateContent(h)}catch(e){return y({code:"BACKEND_ERROR",reason:e instanceof Error?e.message:String(e)})}const t=ce(e,k.services.blockRegistry);if(!t.ok)return t;const r=t.value,n=new $("assistant",s.session);for(const e of r)n.addBlock(e);return f({turn:n.build(),effects:[]})},async*executeStream(){let e;try{e=await k.client.models.generateContentStream(h)}catch(e){const r=e instanceof Error?e.message:String(e),n=new $("assistant",s.session);return n.addBlock({id:t.v7(),type:"text",text:`[Stream error: ${r}]`}),void(yield{turn:n.build(),effects:[]})}const r=[];for await(const s of e){const e=s.candidates?.[0];if(e?.content?.parts)for(const s of e.content.parts)s.thought||s.text&&(r.push(s.text),yield{blocks:[{id:t.v7(),type:"text",text:s.text}]})}const n=r.join(""),i=new $("assistant",s.session);i.addBlock({id:t.v7(),type:"text",text:n}),yield{turn:i.build(),effects:[]}}}}static provider(){return"google"}static models(){return ae}};exports.COLLECTIONS=p,exports.DefaultPromptBuilder=class{constructor(e,t,s){this.contextRegistry=e,this.retriever=t,this.summarizer=s}async build(e,s,r={}){const n=[],{resolved:i}=function(e){const t=[],s=new Map;for(const r of e)for(const e of r.topics){const n=s.get(e);if(!n){s.set(e,r);continue}const i=new Date(n.timestamp).getTime(),o=new Date(r.timestamp).getTime();o>i?(t.push({topic:e,kept:r.id,dropped:n.id}),s.set(e,r)):i>o&&t.push({topic:e,kept:n.id,dropped:r.id})}const r=new Map,n=new Map;for(const t of e)n.set(t.id,t.topics.length);for(const e of t)r.set(e.dropped,(r.get(e.dropped)??0)+1);const i=new Set;for(const t of e){const e=r.get(t.id)??0,s=n.get(t.id)??0;s>0&&e>=s&&i.add(t.id)}return{resolved:e.filter((e=>!i.has(e.id))),conflicts:Array.from(new Map(t.map((e=>[`${e.topic}:${e.dropped}`,e]))).values())}}(e.preferences),o=function(e,t=3){return e.filter((e=>"user"===e.actor)).slice(-t).flatMap((e=>e.blocks.filter((e=>"text"===e.type)).map((e=>e.text)).filter(Boolean)))}(e.transcript),a=this.retriever.rank({entries:e.context,recentMessages:o,topics:e.topics,config:r.retrieverConfig}),c=[],d=[];for(const e of a){const t=this.contextRegistry.get(e.content.kind);if(!t){n.push(`No ContextDefinition found for kind: ${e.content.kind}`);continue}const s=t.render(e),r=Array.isArray(s)?s:[s];"system"===t.target?c.push({label:`context:${e.content.kind}:${e.key}`,content:r.map((t=>"text"===t.type?t.text:`[${e.content.kind}] ${JSON.stringify(t,null,2)}`)).join("\n"),position:"after:context"}):d.push(...r)}let l=e.transcript;if(r.summarize&&this.summarizer&&l.length>0){const s=2e3;try{const r=await this.summarizer.summarize(l,s),n=[];r.summary&&n.push(ee(e.id,"system",[{id:t.v7(),type:"summary",text:r.summary}])),l=[...n,...r.remaining]}catch(e){n.push(`Summarizer failed: ${e instanceof Error?e.message:String(e)}`)}}const u=[];d.length>0&&u.push(ee(e.id,"user",d));const p=function(e,s){const r=[];let n=null,i=!1;for(const o of e)"user"===o.actor&&o.role&&(i&&o.role!==n&&r.push(ee(s,"system",[{id:t.v7(),type:"role:transition",previousRole:n??void 0,newRole:o.role}])),n=o.role,i=!0),r.push(o);return r}(l,e.id),h=[...u,...p],m=function(e,t){const s=new Map;for(const t of e)if("blob"===t.content.kind){const{sha256:e,mediaType:r,sizeBytes:n,filename:i,previewUrl:o}=t.content;s.has(e)||s.set(e,{sha256:e,mediaType:r,sizeBytes:n,filename:i,previewUrl:o})}for(const e of t)for(const t of e.blocks)if("image"===t.type||"document"===t.type){const e=t.ref;e&&!s.has(e.sha256)&&s.set(e.sha256,e)}return s}(a,h);return f({session:e.id,model:e.model,system:{persona:e.role.persona,instructions:e.instructions,preferences:i,context:[],extensions:c},transcript:h,blobs:m,role:e.role,constraints:Z(e.constraints.role,e.constraints.session,e.constraints.turn),warnings:n})}},exports.DefaultSystemPromptAssembler=I,exports.EMPTY_SYSTEM_ROLE=U,exports.GoogleAdapter=ie,exports.IndexedDBBlobStorage=class{dbName;db=null;constructor(e={}){this.dbName=e.dbName??"aiworkspace-blobs"}async open(){this.db||(this.db=await new Promise(((e,t)=>{const s=indexedDB.open(this.dbName,1);s.onupgradeneeded=e=>{const t=e.target.result;this.createSchema(t)},s.onsuccess=()=>e(s.result),s.onerror=()=>t(s.error),s.onblocked=()=>t(new Error(`[IndexedDBBlobStorage] Database "${this.dbName}" blocked.`))})),this.db.onversionchange=()=>{this.db?.close(),this.db=null})}createSchema(e){e.objectStoreNames.contains(te)||e.createObjectStore(te,{keyPath:"sha256"}),e.objectStoreNames.contains(se)||e.createObjectStore(se,{keyPath:"sha256"})}close(){this.db?.close(),this.db=null}async deleteDatabase(){this.close(),await new Promise(((e,t)=>{const s=indexedDB.deleteDatabase(this.dbName);s.onsuccess=()=>e(),s.onerror=()=>t(s.error)}))}getDB(){if(!this.db)throw new Error("[IndexedDBBlobStorage] Database not open. Call open() first.");return this.db}readTx(...e){return this.getDB().transaction(e,"readonly")}writeTx(...e){return this.getDB().transaction(e,"readwrite")}async storeBytes(e,t){const s=this.readTx(te);if(await re(s.objectStore(te).get(e)))return;const r=this.writeTx(te);r.objectStore(te).put({sha256:e,data:t}),await ne(r)}async loadBytes(e){const t=this.readTx(te),s=await re(t.objectStore(te).get(e));return s?.data??null}async hasBytes(e){const t=this.readTx(te);return await re(t.objectStore(te).count(e))>0}async deleteBytes(e){const t=this.writeTx(te);t.objectStore(te).delete(e),await ne(t)}async saveRecord(e){const t=this.writeTx(se);t.objectStore(se).put(e),await ne(t)}async loadRecord(e){const t=this.readTx(se);return await re(t.objectStore(se).get(e))??null}async deleteRecord(e){const t=this.writeTx(se);t.objectStore(se).delete(e),await ne(t)}async listRecords(){return re(this.readTx(se).objectStore(se).getAll())}async exportAllBytes(){const e=this.readTx(te);return(await re(e.objectStore(te).getAll())).map((({sha256:e,data:t})=>[e,t]))}async registerBlob(e,t){await new Promise(((s,r)=>{const n=this.getDB().transaction([te,se],"readwrite"),i=n.objectStore(te),o=n.objectStore(se),a=i.count(e.sha256);a.onsuccess=()=>{0===a.result&&i.put({sha256:e.sha256,data:t}),o.put(e)},a.onerror=()=>r(a.error),n.oncomplete=()=>s(),n.onerror=()=>r(n.error),n.onabort=()=>r(new Error("registerBlob transaction aborted"))}))}},exports.JaccardContextRetriever=class{constructor(e){this.contextRegistry=e}rank(e){const{entries:t,recentMessages:s,config:r={}}=e,n=r.minScore??0,i=r.freshnessHalfLifeDays??30,o=r.recentMessageWindow??3;if(0===s.length)return[...t].sort(((e,t)=>this.freshnessWeight(t.timestamp,i)-this.freshnessWeight(e.timestamp,i)));const a=this.tokenize(s.slice(-o).join(" "));return t.map((e=>{const t=function(e,t){const s=t.get(e.content.kind);return s?s.toString(e):""}(e,this.contextRegistry);return{entry:e,score:.7*this.jaccardSimilarity(a,this.tokenize(t))+.3*this.freshnessWeight(e.timestamp,i)}})).filter((e=>e.score>n)).sort(((e,t)=>t.score-e.score)).map((e=>e.entry))}tokenize(e){return new Set(e.toLowerCase().replace(/[^\w\s]/g," ").split(/\s+/).filter((e=>e.length>2)))}jaccardSimilarity(e,t){if(0===e.size&&0===t.size)return 0;let s=0;for(const r of e)t.has(r)&&s++;const r=e.size+t.size-s;return 0===r?0:s/r}freshnessWeight(e,t){const s=(Date.now()-new Date(e).getTime())/864e5;return Math.pow(.5,s/t)}},exports.LRUCache=X,exports.MemoryBlobStorage=class{bytes=new Map;records=new Map;async storeBytes(e,t){this.bytes.has(e)||this.bytes.set(e,t)}async loadBytes(e){return this.bytes.get(e)??null}async hasBytes(e){return this.bytes.has(e)}async deleteBytes(e){this.bytes.delete(e)}async saveRecord(e){this.records.set(e.sha256,{...e})}async loadRecord(e){return this.records.get(e)??null}async deleteRecord(e){this.records.delete(e)}async listRecords(){return Array.from(this.records.values()).map((e=>({...e})))}async exportAllBytes(){return Array.from(this.bytes.entries()).map((([e,t])=>[e,new Uint8Array(t)]))}async registerBlob(e,t){this.bytes.has(e.sha256)||this.bytes.set(e.sha256,t),this.records.set(e.sha256,{...e})}},exports.Session=F,exports.SessionManager=K,exports.TurnBuilder=$,exports.TurnTree=M,exports.WorkspaceManager=k,exports.bufferToBase64=b,exports.computeSHA256=w,exports.createDefaultAssembler=function(){return new I},exports.createEmptySession=(e={})=>({id:t.v7(),label:"New Conversation",role:"assistant-default",topics:[],preferences:[],metadata:{created:(new Date).toString(),updated:(new Date).toString()},...e,head:e.head?e.head:void 0}),exports.createEmptyTurn=(e={},s)=>({id:e.id??t.v7(),version:e.version??0,session:e.session??s?.id??t.v7(),actor:"user",blocks:[{id:t.v7(),type:"text",content:"Hello, world!"}],timestamp:(new Date).toString(),role:s?.role??"default",...e,parent:e.parent?e.parent:void 0}),exports.createEmptyWorkspace=Q,exports.createWorkspace=async function(t){const{blobStorage:s,eventBus:n=e.createEventBus(),getWorkspace:i,setWorkspace:o,processor:a,guard:c,toolRegistry:d,models:l=[],extensions:h=[],extensionReducers:m={},extensionMiddleware:f=[],extensionIndexers:y=[],extensionStores:g,extensionSchemas:w=[]}=t,b=u(t.db),v=[...w,...h.flatMap((e=>e.schemas??[]))],_={...m,...h.reduce(((e,t)=>({...e,...t.reducers})),{})},O=[...f,...h.flatMap((e=>e.middleware??[]))],S=[...y,...h.flatMap((e=>e.indexers??[]))],T=h.flatMap((e=>e.blocks??[]));await b.open(v);const R={workspace:await b.collection(p.WORKSPACE),role:await b.collection(p.ROLE),preference:await b.collection(p.PREFERENCE),context:await b.collection(p.CONTEXT),session:await b.collection(p.SESSION),topic:await b.collection(p.TOPIC),turn:await b.collection(p.TURN)},D=new L(s,new X(200),n),B=new q,A={workspaceStore:new H(R.workspace,new X(1)),roles:new J(R.role,new X(100)),preferences:new V(R.preference,new X(500)),context:new W(R.context,new X(500),B),topics:new x(R.topic,new X(100)),sessions:new G(R.session,new X(50)),turns:new Y(R.turn,new X(50)),blobs:D,tools:d,db:b,indexers:[...r,...S]};if(g){const e=g(A);Object.assign(A,e)}await Promise.all(h.map((async e=>{if(e.stores){const t=await e.stores(A);Object.assign(A,t)}})));const U=new k({ctx:A,getWorkspace:i,updateWorkspace:async e=>{if(await o(e),e?.id||e?.settings||e?.project){const e=i();await A.workspaceStore.update(e.id,{id:e.id,settings:e.settings,project:e.project})}},guard:c,bus:n});Object.entries(E).forEach((([e,t])=>{U.register(e,t)})),Object.entries(_).forEach((([e,t])=>{U.register(e,t)})),U.use(N),O.forEach((e=>{U.use(e)}));const $=new K(U,a),z=new C;T.forEach((e=>z.register(e))),h.forEach((e=>{e.contexts&&e.contexts.forEach((e=>{if(B.register(e),e.store){const t=e.store(A);A.context.registerDelegate(e.kind,t)}}))}));const M=new j(l),P={assembler:new I,processor:a,blobResolver:A.blobs.resolve.bind(A.blobs),blockRegistry:z,contextRegistry:B,models:M},F=async e=>{await U.dispatch({type:"workspace:sync",payload:void 0,timestamp:(new Date).toISOString()});let t=i();t.id&&""!==t.id&&"00000000-0000-0000-0000-000000000000"!==t.id||(await U.dispatch({type:"workspace:create",payload:e.workspace,timestamp:(new Date).toISOString()}),t=i());const s=[];if(e.roles)for(const r of e.roles)t.index.roles[r.name]||(await U.dispatch({type:"role:add",payload:r,timestamp:(new Date).toISOString()}),s.push(r.name));return e.workspace.settings.defaultRole&&t.settings.defaultRole!==e.workspace.settings.defaultRole&&await U.dispatch({type:"workspace:sync",payload:{settings:{...t.settings,defaultRole:e.workspace.settings.defaultRole}},timestamp:(new Date).toISOString()}),{workspace:i(),roles:s}};if(t.bootstrap){const e=i();if(!e||!e.index){const e=Q({id:t.bootstrap.workspace.id,settings:t.bootstrap.workspace.settings,project:t.bootstrap.workspace.project});await o(e)}await F(t.bootstrap)}return{manager:U,sessions:$,ctx:A,services:P,bootstrap:F}},exports.createWorkspaceDatabase=u,exports.del=function(){return h},exports.error=y,exports.getExtension=function(e,t){return e.extensions[t]},exports.merge=g,exports.omitNullUndefined=function(e){return Object.fromEntries(Object.entries(e).filter((([e,t])=>null!=t)))},exports.shortHash=function(e,t=4){let s=0;for(let t=0;t<e.length;t++)s=(s<<5)-s+e.charCodeAt(t),s|=0;return Math.abs(s).toString(36).padEnd(t,"0").slice(0,t)},exports.success=f;
|
|
1
|
+
"use strict";var e=require("@asaidimu/utils-events"),t=require("uuid"),s=Object.defineProperty,r=[async e=>{const t=await e.workspaceStore.list();if(0===t.length)return{};const s=t[0];return{id:s.id,settings:s.settings,project:s.project}},async e=>{const t=await e.roles.list(),s={};for(const r of t)s[r.name]=e.roles.summarize(r);return{index:{roles:s}}},async e=>{const t=await e.preferences.list(),s={};for(const r of t)s[r.id]=e.preferences.summarize(r);return{index:{preferences:s}}},async e=>{const t=await e.context.list(),s={};for(const r of t)s[r.key]=e.context.summarize(r);return{index:{context:s}}},async e=>{const t=await e.sessions.list(),s={};for(const r of t)s[r.id]=e.sessions.summarize(r);return{index:{sessions:s}}},async e=>{const t=await e.topics.list(),s={};for(const r of t)s[r.name]=e.topics.summarize(r);return{index:{topics:s}}},async e=>({index:{blobs:await e.blobs.getAllRecords()}})],n=[{name:"workspace",version:"1.0.0",description:"Workspace root containing global settings and project metadata.",fields:{id:{name:"id",type:"string",required:!0},settings:{name:"settings",type:"record",required:!0},project:{name:"project",type:"record",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"}],constraints:[],migrations:[]},{name:"role",version:"1.0.0",description:"AI persona with a system prompt and associated preference defaults.",fields:{name:{name:"name",type:"string",required:!0},label:{name:"label",type:"string",required:!0},description:{name:"description",type:"string",required:!1},persona:{name:"persona",type:"string",required:!0},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"},topics:{name:"topics",type:"array",required:!1},constraints:{name:"constraints",type:"record",required:!1}},indexes:[{name:"by_name",fields:["name"],type:"unique"},{name:"by_label",fields:["label"],type:"normal"}],constraints:[],migrations:[]},{name:"preference",version:"1.0.0",description:"A user behavioural instruction, scoped to zero or more topics.",fields:{id:{name:"id",type:"string",required:!0},content:{name:"content",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},timestamp:{name:"timestamp",type:"string",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"context",version:"1.0.0",description:"Injected background knowledge, scoped to topics. Content is a discriminated union.",fields:{key:{name:"key",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},content:{name:"content",type:"record",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},metadata:{name:"metadata",type:"record",required:!1}},indexes:[{name:"by_key",fields:["key"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"session",version:"1.0.0",description:"Session metadata. The head field tracks the current tip of the turn DAG.",fields:{id:{name:"id",type:"string",required:!0},label:{name:"label",type:"string",required:!0},role:{name:"role",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"},metadata:{name:"metadata",type:"record",required:!1},head:{name:"head",type:"record",required:!1},constraints:{name:"constraints",type:"record",required:!1}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_role",fields:["role"],type:"normal"}],constraints:[],migrations:[]},{name:"turn",version:"1.0.0",description:["A single message in a session transcript, stored as a flat document.","The DAG is reconstructed in memory by TurnTree.buildNodeGraph() at session open time."].join(" "),fields:{id:{name:"id",type:"string",required:!0},session:{name:"session",type:"string",required:!0},version:{name:"version",type:"number",required:!0},actor:{name:"actor",type:"enum",required:!0,values:["user","assistant","tool"]},blocks:{name:"blocks",type:"array",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},role:{name:"role",type:"string",required:!1},model:{name:"model",type:"string",required:!1},parent:{name:"parent",type:"record",required:!1},constraints:{name:"constraints",type:"record",required:!1},metadata:{name:"metadata",type:"record",required:!1}},indexes:[{name:"by_session",fields:["session"],type:"normal"},{name:"by_session_parent",fields:["session","parent"],type:"composite"},{name:"by_session_id_ver",fields:["session","id","version"],type:"composite",unique:!0}],constraints:[],migrations:[]},{name:"topic",version:"1.0.0",description:"A categorization for context and preferences, used for retrieval.",fields:{name:{name:"name",type:"string",required:!0},label:{name:"label",type:"string",required:!1},description:{name:"description",type:"string",required:!1},metadata:{name:"metadata",type:"record",required:!1},created:{name:"created",type:"string",required:!0},updated:{name:"updated",type:"string",required:!0}},indexes:[{name:"by_name",fields:["name"],type:"unique"}],constraints:[],migrations:[]}],i=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},o=class extends i{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},a=class extends i{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},c=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const s=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await s;let r;await Promise.race([s.then((()=>clearTimeout(r))),new Promise(((s,n)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),n(new o("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},d=class{mutex=new c({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,s="Operation timed out"){if(null==t)return e;let r;return Promise.race([e.then((e=>(clearTimeout(r),e))),new Promise(((e,n)=>{r=setTimeout((()=>n(new o(s))),t)}))])}},l=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new c({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new a};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,r=null;try{if(this._done)throw new a;r=await e(),this._lastValue=r,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:r,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}};function u(e){const t=new d({retry:!0,throws:!0}),s=new d({retry:!0,throws:!0});return{open:async(s=[])=>(await t.do((async()=>{const t=[...n,...s];await e.setupCollections(t)}))).value,collection:async t=>e.collection(t),close:async()=>(await s.do((()=>{e.close()}))).value,database:()=>e}}var p={WORKSPACE:"workspace",ROLE:"role",PREFERENCE:"preference",CONTEXT:"context",SESSION:"session",TURN:"turn",BLOB:"blob",TOPIC:"topic"},h=Symbol.for("delete"),m=e=>Array.isArray(e)?[...e]:{...e};function f(e){return{ok:!0,value:e}}function y(e){return{ok:!1,error:e}}var g=function(e){const t=e?.deleteMarker||h;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const r={};for(const[n,i]of Object.entries(e))if(i!==t)if("object"==typeof i&&null!==i){const e=s(i);void 0!==e&&(r[n]=e)}else r[n]=i;return r}return e===t?void 0:e}return function(e,r){if("object"!=typeof e||null===e)return"object"==typeof r&&null!==r?s(r):r===t?{}:r;if("object"!=typeof r||null===r)return e;const n=m(e),i=[{target:n,source:r}];for(;i.length>0;){const{target:e,source:s}=i.pop();for(const r of Object.keys(s)){const n=s[r];if(n!==t)if(Array.isArray(n))e[r]=n;else if("object"==typeof n&&null!==n){const t=r in e&&"object"==typeof e[r]&&null!==e[r]?e[r]:{};e[r]=m(t),i.push({target:e[r],source:n})}else e[r]=n;else delete e[r]}}return n}}({deleteMarker:h});async function w(e){const t=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join("")}function b(e){if("undefined"!=typeof Buffer)return Buffer.from(e).toString("base64");const t=[];for(let s=0;s<e.length;s+=32768){const r=e.subarray(s,s+32768);t.push(String.fromCharCode.apply(null,Array.from(r)))}return btoa(t.join(""))}var k=class{registry=new Map;middlewares=[];serializer=new l;bus;_getWorkspace;updateWorkspace;guard;_ctx;constructor(e){this._ctx=e.ctx,this._getWorkspace=e.getWorkspace,this.updateWorkspace=e.updateWorkspace,this.guard=e.guard,this.bus=e.bus}register(e,t){return this.registry.set(e,t),this}use(e){return this.middlewares.push(e),this}workspace(){return this._getWorkspace()}async dispatch(e){const t=await this.serializer.do((async()=>{if(this.guard){const t=await this.guard.authenticate({type:"command",payload:e});if(!t.ok)return y(t.error)}const t=this.registry.get(e.type);if(!t)return y({code:"INVALID_COMMAND",reason:`No reducer registered for command type: ${e.type}`});const s=this._getWorkspace(),r=await t({workspace:s,...this._ctx},e.payload);if(!r.ok)return r;let n=r.value;for(const t of this.middlewares){const r=await t({workspace:s,command:e,patch:n,...this._ctx});n=g(n,r)}return await this.updateWorkspace(n),this.bus.emit({name:"workspace:changed",payload:n}),"workspace:sync"===e.type&&this.bus.emit({name:"workspace:synced",payload:void 0}),f(n)}));if(t.error)throw t.error;return t.value}subscribe(e,t){return this.bus.subscribe(e,t)}ctx(){return{workspace:this._getWorkspace(),...this._ctx}}},x=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;const r=s.state();return this.cache.set(e,r),r}async add(e){await this.collection.create(e),this.cache.set(e.name,e)}async update(e,t){const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;await s.update(t);const r=s.state();return this.cache.set(e,r),r}async delete(e){const t=await this.collection.find({field:"name",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async getMany(e){if(0===e.length)return[];const t=[],s=[];for(const r of e){const e=this.cache.get(r);e?t.push(e):s.push(r)}if(s.length>0){const e=await this.collection.filter({operator:"or",conditions:s.map((e=>({field:"name",operator:"eq",value:e})))});for(const s of e){const e=s.state();this.cache.set(e.name,e),t.push(e)}}return t}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}referencedBy(e,t){for(const s in t.roles)if(t.roles[s].topics?.includes(e))return!0;for(const s in t.sessions)if(t.sessions[s].topics?.includes(e))return!0;for(const s in t.context)if(t.context[s].topics?.includes(e))return!0;for(const s in t.preferences)if(t.preferences[s].topics?.includes(e))return!0;return!1}summarize(e){return{topic:e.name,contextKeys:[],preferences:[],metadata:{created:e.created,updated:e.updated,entries:0}}}};function v(e,t,s,r,n,i){const o={};for(const a of t){let t=e[a];if(!t){if("add"!==n||!i)continue;t={topic:a,contextKeys:[],preferences:[],metadata:{created:(new Date).toISOString(),updated:(new Date).toISOString(),entries:0}},i.add({name:a,created:t.metadata.created,updated:t.metadata.updated})}const c=t[r],d=c.includes(s);if("add"!==n||d){if("remove"===n&&d){const e=Math.max(0,(t.metadata.entries||0)-1);o[a]={...t,[r]:c.filter((e=>e!==s)),metadata:{...t.metadata,updated:(new Date).toISOString(),entries:e}}}}else o[a]={...t,[r]:[...c,s],metadata:{...t.metadata,updated:(new Date).toISOString(),entries:(t.metadata.entries||0)+1}}}return{index:{topics:o}}}function _(e,t,s,r){return v(e,t,s,"contextKeys","add",r)}function O(e,t,s){return v(e,t,s,"contextKeys","remove")}function S(e,t,s,r){return v(e,t,s,"preferences","add",r)}function T(e,t,s){return v(e,t,s,"preferences","remove")}var N=async e=>{if(!e.patch)return;const{workspace:t,patch:s}=e,r=t.index.topics;let n={};const i=e=>{const t=e?.index?.topics;t&&(n=g(n,t))};if(s.index?.context)for(const[n,o]of Object.entries(s.index.context)){const s=t.index.context[n];if(void 0===o&&s)i(O(r,s.topics,s.key));else if(s||!o){if(s&&o){const t=s.topics??[],n=o.topics??t,a=n.filter((e=>!t.includes(e))),c=t.filter((e=>!n.includes(e)));c.length&&i(O(r,c,s.key)),a.length&&i(_(r,a,s.key,e.topics))}}else i(_(r,o.topics??[],o.key,e.topics))}if(s.index?.preferences)for(const[n,o]of Object.entries(s.index.preferences)){const s=t.index.preferences[n];if(void 0===o&&s)i(T(r,s.topics,s.id));else if(s||!o){if(s&&o){const t=s.topics??[],n=o.topics??t,a=n.filter((e=>!t.includes(e))),c=t.filter((e=>!n.includes(e)));c.length&&i(T(r,c,s.id)),a.length&&i(S(r,a,s.id,e.topics))}}else i(S(r,o.topics??[],o.id,e.topics))}return Object.keys(n).length?{index:{topics:n}}:{}},R="\n# WORKSPACE OPERATING SYSTEM\nYou are operating within a structured workspace. Your output MUST be a JSON object matching the provided schema.\nYour entire response MUST be valid JSON. Nothing else.\n".trim();function D(e){if(!e||"append"===e)return{placement:"append",label:null};if("prepend"===e)return{placement:"prepend",label:null};const[t,...s]=e.split(":");return("before"===t||"after"===t)&&s.length>0?{placement:t,label:s.join(":")}:(console.warn(`[SystemPromptAssembler] Unrecognised position "${e}", defaulting to "append".`),{placement:"append",label:null})}var I=class{build(e,t=[]){const s=[...e.system.extensions||[],...t],r=[];var n,i,o;r.push({label:"operating-system",content:R}),e.role.persona&&r.push({label:"persona",content:(n=e.role.persona,`# Persona\n${n}`)}),e.system.preferences.length>0&&r.push({label:"preferences",content:(i=e.system.preferences,`# User Preferences\n${i.map((e=>`- ${e.content}`)).join("\n")}`),metadata:{count:e.system.preferences.length}}),e.system.context.length>0&&r.push({label:"context",content:(o=e.system.context,`# Context\n${o.map((e=>{switch(e.content.kind){case"text":return`[${e.key}] ${e.content.value}`;case"json":return`[${e.key}] JSON: ${JSON.stringify(e.content.value)}`;case"blob":return`[${e.key}] Blob: ${e.content.filename??"unnamed"} (${e.content.mediaType}, ${e.content.sizeBytes} bytes)`;case"remote":return`[${e.key}] Remote: ${e.content.uri}`;default:return`[${e.key}] Unsupported context type`}})).join("\n")}`),metadata:{count:e.system.context.length}}),e.system.instructions&&r.push({label:"instructions",content:`# Instructions\n${e.system.instructions}`});const a=[...r],c=[];for(const e of s){const{position:t,...s}=e,r=D(t);if("prepend"===r.placement){c.push(s);continue}if("append"===r.placement){a.push(s);continue}const n=a.findIndex((e=>e.label===r.label));if(-1===n){console.warn(`[SystemPromptAssembler] Anchor target "${r.label}" not found in sections. Extension "${e.label}" will be appended.`),a.push(s);continue}const i="before"===r.placement?n:n+1;a.splice(i,0,s)}return[...c,...a]}join(e){return e.map((e=>e.content)).join("\n\n---\n\n")}};var E={"workspace:create":async function(e,t){const{workspaceStore:s}=e,{id:r,settings:n,project:i}=t,o=await s.get(r);return o?f({id:o.id,settings:o.settings,project:o.project}):(await s.add({id:r,settings:n,project:i}),f({id:r,settings:n,project:i,index:{roles:{},preferences:{},context:{},sessions:{},topics:{},blobs:{},tools:{},extensions:{}}}))},"workspace:sync":async function(e,t){let s={};for(const t of e.indexers){const r=await t(e);s=g(s,r)}return t&&(t.id&&(s.id=t.id),t.settings&&(s.settings=g(s.settings||{},t.settings)),t.project&&(s.project=g(s.project||{},t.project))),f(s)},"role:add":async function(e,t){const{workspace:s,roles:r}=e,n=t;return s.index.roles[n.name]?y({code:"DUPLICATE_KEY",resource:"Role",key:n.name}):(await r.add(n),f({index:{roles:{[n.name]:r.summarize(n)}}}))},"role:update":async function(e,t){const{workspace:s,roles:r}=e,{name:n,...i}=t;if(!s.index.roles[n])return y({code:"NOT_FOUND",resource:"Role",id:n});const o=await r.update(n,i);return o?f({index:{roles:{[n]:r.summarize(o)}}}):y({code:"BACKEND_ERROR",reason:`Failed to update role ${n} in store.`})},"role:delete":async function(e,t){const{workspace:s,roles:r}=e,{name:n}=t;return s.index.roles[n]?await r.delete(n)?f({index:{roles:{[n]:h}}}):y({code:"BACKEND_ERROR",reason:`Failed to delete role ${n} from store.`}):y({code:"NOT_FOUND",resource:"Role",id:n})},"preference:add":async function(e,t){const{workspace:s,preferences:r}=e,n=t;return s.index.preferences[n.id]?y({code:"DUPLICATE_KEY",resource:"Preference",key:n.id}):(await r.add(n),f({index:{preferences:{[n.id]:r.summarize(n)}}}))},"preference:update":async function(e,t){const{workspace:s,preferences:r}=e,{id:n,...i}=t;if(!s.index.preferences[n])return y({code:"NOT_FOUND",resource:"Preference",id:n});const o=await r.update(n,i);return o?f({index:{preferences:{[n]:r.summarize(o)}}}):y({code:"BACKEND_ERROR",reason:`Failed to update preference ${n} in store.`})},"preference:delete":async function(e,t){const{workspace:s,preferences:r}=e,{id:n}=t;return s.index.preferences[n]?await r.delete(n)?f({index:{preferences:{[n]:h}}}):y({code:"BACKEND_ERROR",reason:`Failed to delete preference ${n} from store.`}):y({code:"NOT_FOUND",resource:"Preference",id:n})},"context:add":async function(e,t){const{workspace:s,context:r}=e,n=t;return s.index.context[n.key]?y({code:"DUPLICATE_KEY",resource:"Context",key:n.key}):(await r.add(n),f({index:{context:{[n.key]:r.summarize(n)}}}))},"context:update":async function(e,t){const{workspace:s,context:r}=e,{key:n,...i}=t,o=s.index.context[n];if(!o)return y({code:"NOT_FOUND",resource:"Context",id:n});const a=await r.update(n,i,o.kind);return a?f({index:{context:{[n]:r.summarize(a)}}}):y({code:"BACKEND_ERROR",reason:`Failed to update context ${n} in store.`})},"context:delete":async function(e,t){const{workspace:s,context:r}=e,{key:n}=t,i=s.index.context[n];return i?await r.delete(n,i.kind)?f({index:{context:{[n]:h}}}):y({code:"BACKEND_ERROR",reason:`Failed to delete context ${n} from store.`}):y({code:"NOT_FOUND",resource:"Context",id:n})},"topic:add":async function(e,t){const{workspace:s,topics:r}=e,n=t;return s.index.topics[n.name]?y({code:"DUPLICATE_KEY",resource:"Topic",key:n.name}):(await r.add(n),f({index:{topics:{[n.name]:r.summarize(n)}}}))},"topic:update":async function(e,t){const{workspace:s,topics:r}=e,{name:n,...i}=t;if(!s.index.topics[n])return y({code:"NOT_FOUND",resource:"Topic",id:n});const o=await r.update(n,i);return o?f({index:{topics:{[n]:{metadata:{updated:o.updated}}}}}):y({code:"BACKEND_ERROR",reason:`Failed to update topic ${n} in store.`})},"topic:delete":async function(e,t){const{workspace:s,topics:r,roles:n,sessions:i}=e,{name:o,cascade:a}=t;if(!s.index.topics[o])return y({code:"NOT_FOUND",resource:"Topic",id:o});if(r.referencedBy(o,s.index)&&!a)return y({code:"INVALID_COMMAND",reason:`Topic '${o}' is referenced by other entities. Use 'cascade: true' to force deletion.`});if(a){for(const e in s.index.roles){const t=s.index.roles[e];if(t.topics?.includes(o)){const t=await n.get(e);t&&await n.update(e,{topics:t.topics.filter((e=>e!==o))})}}for(const e in s.index.sessions){const t=s.index.sessions[e];t.topics?.includes(o)&&await i.update(e,{topics:t.topics.filter((e=>e!==o))})}}return await r.delete(o)?f({index:{topics:{[o]:h}}}):y({code:"BACKEND_ERROR",reason:`Failed to delete topic ${o} from store.`})},"topic:merge":async function(e,t){const{workspace:s,topics:r,roles:n,sessions:i}=e,{source:o,target:a}=t;if(!s.index.topics[o]||!s.index.topics[a])return y({code:"NOT_FOUND",resource:"Topic",id:s.index.topics[o]?a:o});for(const e in s.index.roles){const t=s.index.roles[e];if(t.topics?.includes(o)){const t=await n.get(e);if(t){const s=t.topics.filter((e=>e!==o));s.includes(a)||s.push(a),await n.update(e,{topics:s})}}}for(const e in s.index.sessions){const t=s.index.sessions[e];if(t.topics?.includes(o)){const s=t.topics.filter((e=>e!==o));s.includes(a)||s.push(a),await i.update(e,{topics:s})}}return await r.delete(o),f({index:{topics:{[o]:h}}})},"session:create":async function(e,t){const{workspace:s,sessions:r}=e,n=t;return s.index.sessions[n.id]?y({code:"DUPLICATE_KEY",resource:"Session",key:n.id}):(await r.add(n),f({index:{sessions:{[n.id]:r.summarize(n)}}}))},"session:update":async function(e,t){const{workspace:s,sessions:r}=e,{sessionId:n,...i}=t;if(!s.index.sessions[n])return y({code:"NOT_FOUND",resource:"Session",id:n});const o=await r.update(n,i);return o?f({index:{sessions:{[n]:r.summarize(o)}}}):y({code:"BACKEND_ERROR",reason:`Failed to update session ${n} in store.`})},"session:fork":async function(e,t){const{workspace:s,sessions:r}=e,{sessionId:n,newSessionId:i,label:o}=t,a=s.index.sessions[n];if(!a)return y({code:"NOT_FOUND",resource:"Session",id:n});const c={...a,id:i,label:o||`Fork of ${a.label}`,role:t.role?t.role:a.role,topics:t.topics?t.topics:a.topics};return await r.add(c),f({index:{sessions:{[i]:r.summarize(c)}}})},"session:delete":async function(e,t){const{workspace:s,sessions:r}=e,{sessionId:n}=t;return s.index.sessions[n]?(await r.delete(n),f({index:{sessions:{[n]:h}}})):y({code:"NOT_FOUND",resource:"Session",id:n})},"session:role:switch":async function(e,t){const{workspace:s,sessions:r}=e,{sessionId:n,roleName:i}=t;return s.index.sessions[n]?(await r.update(n,{role:i}),f({index:{sessions:{[n]:{role:i}}}})):y({code:"NOT_FOUND",resource:"Session",id:n})},"session:topics:add":async function(e,t){const{workspace:s,sessions:r}=e,{sessionId:n,topics:i}=t,o=s.index.sessions[n];if(!o)return y({code:"NOT_FOUND",resource:"Session",id:n});const a=Array.from(new Set([...o.topics,...i]));return await r.update(n,{topics:a}),f({index:{sessions:{[n]:{topics:a}}}})},"session:preferences:override":async function(e,t){const{workspace:s,sessions:r}=e,{sessionId:n,preferences:i}=t;return s.index.sessions[n]?(await r.update(n,{preferences:i}),f({index:{sessions:{[n]:{preferences:i}}}})):y({code:"NOT_FOUND",resource:"Session",id:n})},"turn:add":async function(e,t){const{workspace:s,sessions:r,turns:n}=e,{sessionId:i,turn:o}=t;if(!s.index.sessions[i])return y({code:"NOT_FOUND",resource:"Session",id:i});await n.add(o);const a={id:o.id,version:o.version};return await r.update(i,{head:a}),f({index:{sessions:{[i]:{head:a}}}})},"turn:update":async function(e,t){const{workspace:s,sessions:r,turns:n}=e,{sessionId:i,turn:o}=t;if(!s.index.sessions[i])return y({code:"NOT_FOUND",resource:"Session",id:i});const{id:a,session:c,version:d,...l}=o;await n.update({id:a,session:c,version:d},l);const u={id:o.id,version:o.version};return await r.update(i,{head:u}),f({index:{sessions:{[i]:{head:u}}}})},"turn:edit":async function(e,t){const{workspace:s,sessions:r,turns:n}=e,{sessionId:i,turnId:o,newBlocks:a,newVersion:c,roleSnapshot:d,modelSnapshot:l}=t,u=s.index.sessions[i];if(!u)return y({code:"NOT_FOUND",resource:"Session",id:i});const p=u.head;let h={};if(p&&p.id===o){const e=await n.get({id:p.id,version:p.version,session:i});e&&(h={...e})}const m={...h,id:o,version:c,blocks:a,role:d??h.role,model:l??h.model,timestamp:(new Date).toISOString(),parent:h.parent,actor:h.actor||"assistant",session:i};if(await n.add(m),u.head?.id===o){const e={id:o,version:c};return await r.update(i,{head:e}),f({index:{sessions:{[i]:{head:e}}}})}return f({})},"turn:branch":async function(e,t){const{workspace:s,sessions:r,turns:n}=e,{sessionId:i,turn:o}=t;if(!s.index.sessions[i])return y({code:"NOT_FOUND",resource:"Session",id:i});await n.add(o);const a={id:o.id,version:o.version};return await r.update(i,{head:a}),f({index:{sessions:{[i]:{head:a}}}})},"turn:delete":async function(e,t){const{workspace:s,sessions:r,turns:n}=e,{sessionId:i,turnId:o,newHead:a}=t;return s.index.sessions[i]?(await n.delete({session:i,id:o,version:t.version}),a?(await r.update(i,{head:a}),f({index:{sessions:{[i]:{head:a}}}})):f({})):y({code:"NOT_FOUND",resource:"Session",id:i})},"blob:register":async function(e,t){const{blobs:s}=e,r=await s.register(t.data,t.mediaType,t.filename);if(!r.ok)return r;const n=await s.getRecord(r.value.sha256);return n?f({index:{blobs:{[n.sha256]:n}}}):y({code:"BACKEND_ERROR",reason:`Failed to retrieve registered blob record for ${r.value.sha256}`})},"blob:retain":async function(e,t){const{blobs:s}=e,r=await s.retain(t.sha256);if(!r.ok)return r;const n=await s.getRecord(t.sha256);return f({index:{blobs:{[t.sha256]:n}}})},"blob:release":async function(e,t){const{blobs:s}=e,r=await s.release(t.sha256);if(!r.ok)return r;const n=await s.getRecord(t.sha256);return f({index:{blobs:{[t.sha256]:n||h}}})},"blob:purge":async function(e,t){const{blobs:s}=e,r=await s.purge(t.sha256);return r.ok?f({index:{blobs:{[t.sha256]:h}}}):r},"blob:record_remote_id":async function(e,t){const{blobs:s}=e,{sha256:r,providerId:n,fileId:i,timestamp:o}=t,a=await s.recordRemoteId(r,n,i,o);if(!a.ok)return a;const c=await s.getRecord(r);return f({index:{blobs:{[r]:c}}})},"tool:call":async function(e,t){return f({})}},j=class{profiles;constructor(e=[]){this.profiles=new Map;for(const t of e)this.profiles.set(t.name,t)}get(e){return this.profiles.get(e)}list(e){const t=Array.from(this.profiles.values());return e?t.filter((t=>t.provider===e)):t}register(e){this.profiles.set(e.name,e)}},A=[{type:"text",emittable:!0,description:["## Block: `text`","Primary communication block. Use for all conversational responses, explanations, and prose.","A response may contain multiple `text` blocks interleaved with other block types."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["text"]},text:{type:"string",description:"The raw markdown or plain text content of the response."}},required:["type","text"]}},{type:"summary",emittable:!0,description:["## Block: `summary`","Context compression block. Replaces older conversation history with a concise digest."].join("\n"),rules:["Only emit when explicitly instructed by the system to summarise.","Never emit more than one summary block per turn.","Preserve key decisions, outcomes, and unresolved questions.","Do not summarise the current turn — only prior history."],schema:{type:"object",properties:{type:{type:"string",enum:["summary"]},text:{type:"string",description:"A concise summary replacing older conversation context."}},required:["type","text"]}},{type:"thinking",emittable:!1,description:["## Block: `thinking`","Internal chain-of-thought produced by the model before its final response.","Injected by the workspace from provider reasoning tokens — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["thinking"]},thinking:{type:"string",description:"The internal reasoning text produced before the final response."}},required:["type","thinking"]}},{type:"tool:use",emittable:!1,description:["## Block: `tool:use`","Captures a model request to execute a registered tool.","Constructed by the workspace from the provider native function-call response — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["tool:use"]},name:{type:"string",description:"The exact registered name of the tool to execute."},input:{type:"object",description:"The parameter arguments for the tool execution.",additionalProperties:!0}},required:["type","name","input"]}},{type:"tool:result",emittable:!1,description:["## Block: `tool:result`","Contains the output of a tool execution, including any errors.","Injected by the workspace after a tool runs — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["tool:result"]},useId:{type:"string",description:"The UUID of the ToolUseBlock that triggered this execution."},content:{oneOf:[{type:"string"},{type:"object",additionalProperties:!0}],description:"The serialized output of the tool, or a structured JSON response."},isError:{type:"boolean",description:"True if the tool execution resulted in an error."}},required:["type","useId","content"]}},{type:"image",emittable:!1,description:["## Block: `image`","An image asset attached to a turn, resolved from the workspace blob store.","Constructed by the workspace from user uploads — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["image"]},altText:{type:"string",description:"Accessible description of the image content."}},required:["type"]}},{type:"document",emittable:!1,description:["## Block: `document`","A document asset (PDF, DOCX, etc.) attached to a turn, resolved from the workspace blob store.","Constructed by the workspace from user uploads — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["document"]},title:{type:"string",description:"Human-readable title or filename of the document."}},required:["type"]}},{type:"role:transition",emittable:!1,description:["## Block: `role:transition`","Marks that the active session persona has switched from one role to another.","Emitted by the workspace when the active persona changes — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["role:transition"]},previousRole:{type:"string",description:"The name of the role the session is leaving."},newRole:{type:"string",description:"The name of the role the session is adopting."}},required:["type","newRole"]}}];function B(e,t){let s=e.filter((e=>e.emittable));if(!t)return s;if(t.only&&t.only.length>0){const e=new Set(t.only);return s.filter((t=>e.has(t.type)))}if(t.exclude&&t.exclude.length>0){const e=new Set(t.exclude);return s.filter((t=>!e.has(t.type)))}return s}var C=class{store=new Map;constructor(){for(const e of A)this.store.set(e.type,e)}register(e){if(this.store.has(e.type))throw new Error(`[BlockRegistry] Block type "${e.type}" is already registered. Use update() to modify it.`);this.store.set(e.type,{...e,emittable:!0,rules:[]})}unregister(e){if(!this.store.has(e))throw new Error(`[BlockRegistry] Cannot unregister unknown block type "${e}".`);this.store.delete(e)}update(e,t){const s=this.store.get(e);s?this.store.set(e,{...s,...t,type:e}):this.store.set(e,{emittable:!0,rules:[],...t,type:e})}get(e){return this.store.get(e)}list(){return Array.from(this.store.values())}isType(e,t){return e.type===t}guard(e){return t=>t.type===e}schema(e){return{type:"object",description:"The model's structured response, containing an ordered sequence of content blocks.",properties:{blocks:{type:"array",description:"An ordered array of content blocks comprising the model's response.",items:{anyOf:B(Array.from(this.store.values()),e).map((e=>e.schema))}}},required:["blocks"]}}description(e){return["# BLOCK TYPES & USAGE RULES","","Your response MUST be a JSON object with a `blocks` array.","Each element of `blocks` must be one of the following types:","",B(Array.from(this.store.values()),e).map((e=>{const t=[e.description];return e.rules.length>0&&(t.push("**Rules:**"),t.push(...e.rules.map((e=>`- ${e}`)))),t.join("\n")})).join("\n\n"),"","## GLOBAL CONSTRAINTS","","- Output must be **valid JSON only** — no prose before or after the JSON object.","- Responses may contain multiple blocks. Blocks are rendered in order.","- **Do NOT generate IDs.** The workspace is solely responsible for block ID assignment.","- Do not infer or invent fields not defined in the block schemas above."].join("\n")}rules(e){const t=B(Array.from(this.store.values()),e);return Object.fromEntries(t.map((e=>[e.type,[...e.rules]])))}setRules(e,t){const s=this.store.get(e);if(!s)throw new Error(`[BlockRegistry] Cannot set rules on unknown block type "${e}".`);this.store.set(e,{...s,rules:t})}parse(e,s){const r=this.store.get(e.type);if(!r)return console.warn(`[BlockRegistry] parse() received unknown block type "${e.type}". Returning null.`),null;if(s&&r.mappings?.[s])return r.mappings[s].from(e);const{id:n,...i}=e;return{id:t.v7(),...i}}create(e,s){if(!this.store.has(e))throw new Error(`[BlockRegistry] Cannot create block of unknown type "${e}".`);return{...s,id:t.v7(),type:e}}clone(e,s){return{...structuredClone(e),...s,id:t.v7()}}},q=class{store=new Map;constructor(){this.registerDefaults()}registerDefaults(){this.register({kind:"text",target:"system",render:e=>({id:e.key,type:"text",text:e.content.value}),toString:e=>e.content.value,summarize:e=>({key:e.key,kind:"text",topics:e.topics,timestamp:e.timestamp,preview:e.content.value.slice(0,100)})}),this.register({kind:"json",target:"system",render:e=>({id:e.key,type:"text",text:JSON.stringify(e.content.value,null,2)}),toString:e=>JSON.stringify(e.content.value),summarize:e=>({key:e.key,kind:"json",topics:e.topics,timestamp:e.timestamp,preview:"JSON Data"})}),this.register({kind:"blob",target:"transcript",render:e=>{const{sha256:t,mediaType:s,sizeBytes:r,filename:n}=e.content,i={sha256:t,mediaType:s,sizeBytes:r,filename:n};return s.startsWith("image/")?{id:e.key,type:"image",ref:i}:{id:e.key,type:"document",ref:i,title:n}},toString:e=>e.content.filename||"unnamed blob",summarize:e=>({key:e.key,kind:"blob",topics:e.topics,timestamp:e.timestamp,mime:e.content.mediaType,size:e.content.sizeBytes,preview:e.content.filename})})}register(e){if(this.store.has(e.kind))throw new Error(`[ContextRegistry] Context kind "${e.kind}" is already registered.`);this.store.set(e.kind,e)}get(e){return this.store.get(e)}list(){return Array.from(this.store.values())}},U="__system__",$=class{constructor(e,s,r){this._actor=e,this._turn=r?JSON.parse(JSON.stringify(r)):{id:t.v7(),session:s,version:0,actor:this._actor,blocks:[],timestamp:(new Date).toISOString(),role:void 0,model:void 0}}_turn;addText(e){const s={id:t.v7(),type:"text",text:e};return this._turn.blocks.push(s),this}addImage(e,s){const r={id:t.v7(),type:"image",ref:e,altText:s};return this._turn.blocks.push(r),this}addDocument(e,s){const r={id:t.v7(),type:"document",ref:e,title:s};return this._turn.blocks.push(r),this}addToolUse(e,s){const r={id:t.v7(),type:"tool:use",name:e,input:s};return this._turn.blocks.push(r),this}addToolResult(e,s,r){const n={id:t.v7(),type:"tool:result",useId:e,content:s,isError:r};return this._turn.blocks.push(n),this}addSummary(e){const s={id:t.v7(),type:"summary",text:e};return this._turn.blocks.push(s),this}addRoleTransition(e,s){const r={id:t.v7(),type:"role:transition",previousRole:e,newRole:s};return this._turn.blocks.push(r),this}addThinking(e){const s={id:t.v7(),type:"thinking",thinking:e};return this._turn.blocks.push(s),this}addBlock(e){return e.id||(e.id=t.v7()),this._turn.blocks.push(e),this}deleteBlock(e){return this._turn.blocks=this._turn.blocks.filter((t=>t.id!==e)),this}editTextBlock(e,t){const s=this._turn.blocks.findIndex((t=>t.id===e));if(-1===s)throw new Error(`Block with ID ${e} not found.`);const r=this._turn.blocks[s];if("text"!==r.type)throw new Error(`Block with ID ${e} is not a TextBlock.`);return this._turn.blocks[s]={...r,text:t},this}withId(e){return this._turn.id=e,this}withVersion(e){return this._turn.version=e,this}withTimestamp(e){return this._turn.timestamp=e,this}withParent(e){return this._turn.parent=e,this}withRoleSnapshot(e){return this._turn.role=e,this}withRole(e){return this._turn.role=e,this}withModel(e){return this._turn.model=e,this}build(){return JSON.parse(JSON.stringify(this._turn))}},M=class{constructor(e,t){this.turnStore=e,this.sessionStore=t}async loadAllTurns(e){return this.turnStore.listBySession(e)}async loadHead(e){const t=await this.sessionStore.get(e);return t?.head??null}},z=class e{constructor(e,t){this.nodes=e,this._head=t}static async build(t,s){const[r,n]=await Promise.all([s.loadAllTurns(t),s.loadHead(t)]),i=function(e,t){const s=function(e,t){if(!t)return new Set;const s=new Map;for(const t of e)s.set(`${t.id}:${t.version}`,t);const r=new Set;let n=t;for(;n;){const e=`${n.id}:${n.version}`;if(r.has(e))break;r.add(e);const t=s.get(e);if(!t)break;n=t.parent}return r}(e,t),r={},n={};for(const t of e){r[t.id]||(r[t.id]={id:t.id,versions:{},activeVersion:t.version,actor:t.actor,blocks:t.blocks,timestamp:t.timestamp,roleSnapshot:t.role,modelSnapshot:t.model,parent:t.parent,children:{}},n[t.id]=new Set);const e=r[t.id];e.versions[t.version]=t;const i=s.has(`${t.id}:${t.version}`),o=s.has(`${t.id}:${e.activeVersion}`);if(i&&(!o||t.version>=e.activeVersion)&&(e.activeVersion=t.version,e.blocks=t.blocks,e.timestamp=t.timestamp,e.roleSnapshot=t.role,e.modelSnapshot=t.model,e.parent=t.parent),t.parent){const e=`${t.parent.id}:${t.parent.version}`;if(n[t.parent.id]||(n[t.parent.id]=new Set),!n[t.parent.id].has(e+":"+t.id)){n[t.parent.id].add(e+":"+t.id),r[t.parent.id]||(r[t.parent.id]={id:t.parent.id,versions:{},activeVersion:t.parent.version,actor:"user",blocks:[],timestamp:"",roleSnapshot:void 0,modelSnapshot:void 0,children:{}});const s=r[t.parent.id];s.children[t.parent.version]||(s.children[t.parent.version]=[]),s.children[t.parent.version].push(t.id)}}}return r}(r,n);return new e(i,n)}head(){return this._head}chain(){return this._head?this.chainFrom(this._head.id):[]}chainFrom(e){const t=[];let s=e;for(;s;){const e=this.nodes[s];if(!e)break;t.push(e),s=e.parent?.id??null}return t.reverse()}getTurnSiblings(e){const t=this.nodes[e];if(!t)return[];if(!t.parent)return Object.values(this.nodes).filter((e=>!e.parent));const s=this.nodes[t.parent.id];if(!s)return[t];const r=s.children[t.parent.version];return r?r.map((e=>this.nodes[e])).filter((e=>!!e)):[t]}branchInfo(e){const t=this.nodes[e];if(!t)return{versions:[],currentIndex:-1,total:0,hasPrev:!1,hasNext:!1};const s=Object.keys(t.versions).map(Number).sort(((e,t)=>e-t)),r=s.indexOf(t.activeVersion);return{versions:s,currentIndex:r,total:s.length,hasPrev:r>0,hasNext:r<s.length-1}}graph(){return{...this.nodes}}};var F=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;const r=s.state();return this.cache.set(e,r),r}async add(e){await this.collection.create(e),this.cache.set(e.id,e)}async update(e,t){const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;await s.update(t);const r=s.state();return this.cache.set(e,r),r}async delete(e){const t=await this.collection.find({field:"id",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async list(){const e=await this.collection.list({limit:100,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return e}},P=class{cache;maxSize;constructor(e){this.cache=new Map,this.maxSize=e}get(e){const t=this.cache.get(e);return void 0!==t&&(this.cache.delete(e),this.cache.set(e,t)),t}set(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.maxSize){const e=this.cache.keys().next().value;void 0!==e&&this.cache.delete(e)}this.cache.set(e,t)}has(e){return this.cache.has(e)}delete(e){this.cache.delete(e)}clear(){this.cache.clear()}},W=class{constructor(e){this.manager=e}get workspace(){return this.manager.workspace()}roles(){return this.manager.ctx().roles.list()}role(e){return this.manager.ctx().roles.get(e)}async createRole(e,t,s,r,n=[]){if(this.workspace.index.roles[e])return y({code:"DUPLICATE_KEY",resource:"role",key:e});const i={name:e,label:t,description:r,persona:s,preferences:n,topics:[]};return this.manager.dispatch({type:"role:add",payload:i,timestamp:(new Date).toISOString()})}async updateRole(e,t){return this.workspace.index.roles[e]?this.manager.dispatch({type:"role:update",payload:{name:e,...t},timestamp:(new Date).toISOString()}):y({code:"NOT_FOUND",resource:"role",id:e})}async deleteRole(e){const t=this.workspace;if(!t.index.roles[e])return y({code:"NOT_FOUND",resource:"role",id:e});return Object.values(t.index.sessions).some((t=>t.role===e))?y({code:"INVALID_COMMAND",reason:`Cannot delete role "${e}" — it is still referenced by one or more sessions`}):this.manager.dispatch({type:"role:delete",payload:{name:e},timestamp:(new Date).toISOString()})}async addPreference(e,t){const s={id:crypto.randomUUID(),content:e,topics:t,timestamp:(new Date).toISOString()};return this.manager.dispatch({type:"preference:add",payload:s,timestamp:s.timestamp})}preferences(){return this.manager.ctx().preferences.list()}async addContext(e,t,s,r){const n={key:e,topics:s,content:t,timestamp:(new Date).toISOString(),metadata:r};return this.manager.dispatch({type:"context:add",payload:n,timestamp:n.timestamp})}context(){return this.manager.ctx().context.list()}async registerBlob(e,t,s){const r=await this.manager.dispatch({type:"blob:register",payload:{data:e,mediaType:t,filename:s},timestamp:(new Date).toISOString()});if(!r.ok)return y(r.error);const n=r.value,i=n?.index?.blobs;if(!i)return y({code:"BACKEND_ERROR",reason:"Blob registration succeeded but no blobs patch returned"});const o=Object.keys(i)[0];if(!o)return y({code:"BACKEND_ERROR",reason:"No SHA256 in patch"});const a=i[o];if(!a)return y({code:"BACKEND_ERROR",reason:"Blob record missing"});return f({sha256:o,ref:{sha256:o,mediaType:a.mediaType,sizeBytes:a.sizeBytes,filename:a.filename,previewUrl:a.previewUrl}})}},K=class e{constructor(e,t,s,r){this._id=e,this.manager=t,this.processor=s,this.turnRepository=r,this.workspace=new W(t),this.unsubscribe=t.subscribe("workspace:synced",(()=>this.sync()))}workspace;_role=void 0;_preferences=[];tree;unsubscribe;static async create(t,s,r){s.ctx().workspace;const n=new M(s.ctx().turns,s.ctx().sessions),i=new e(t,s,r,n);return await i.sync(),i}async sync(){await this._setRole(),await this._setPreference(),await this.refreshTurnTree()}close(){this.unsubscribe?.()}async _setRole(){const e=this.meta(),t=await this.manager.ctx().roles.get(e.role);t&&(this._role=t)}async _setPreference(){const e=this.meta();this._preferences=await this.manager.ctx().preferences.load(e.preferences)}id(){return this._id}ws(){return this.manager.workspace()}meta(){return this.ws().index.sessions[this._id]}label(){return this.meta()?.label}role(){return this._role}topics(){return this.meta()?.topics??[]}preferences(){return this._preferences}head(){return this.meta()?.head??null}turns(){return this.tree.chain()}async siblings(e){return this.tree.getTurnSiblings(e)}async branchInfo(e){return this.tree.branchInfo(e)}async getTurn(e){return this.tree.graph()[e]}async rename(e){return this.meta()?this.dispatch({type:"session:update",payload:{sessionId:this._id,label:e},timestamp:(new Date).toISOString()}):y({code:"NOT_FOUND",resource:"session",id:this._id})}async setTopics(e){return this.meta()?this.dispatch({type:"session:update",payload:{sessionId:this._id,topics:e},timestamp:(new Date).toISOString()}):y({code:"NOT_FOUND",resource:"session",id:this._id})}async setModel(e){return this.meta()?this.updateMetadata({model:e}):y({code:"NOT_FOUND",resource:"session",id:this._id})}async updateMetadata(e){const t=this.meta();if(!t)return y({code:"NOT_FOUND",resource:"session",id:this._id});const s={...t.metadata||{},...e};return this.dispatch({type:"session:update",payload:{sessionId:this._id,metadata:s},timestamp:(new Date).toISOString()})}async addTopics(e){return this.meta()?this.dispatch({type:"session:topics:add",payload:{sessionId:this._id,topics:e},timestamp:(new Date).toISOString()}):y({code:"NOT_FOUND",resource:"session",id:this._id})}async setPreferences(e){if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});const t=await this.dispatch({type:"session:preferences:override",payload:{sessionId:this._id,preferences:e},timestamp:(new Date).toISOString()});return t.ok&&await this._setPreference(),t}async fork(e,t,s,r){return this.meta()?this.dispatch({type:"session:fork",payload:{sessionId:this._id,newSessionId:e,label:t,role:s,topics:r},timestamp:(new Date).toISOString()}):y({code:"NOT_FOUND",resource:"session",id:this._id})}async dispatch(e){return this.manager.dispatch(e)}async switchRole(e){const t=this.ws();if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});if(e!==U&&!t.index.roles[e])return y({code:"NOT_FOUND",resource:"role",id:e});const s=await this.dispatch({type:"session:update",payload:{sessionId:this._id,role:e},timestamp:(new Date).toISOString()});return s.ok&&await this._setRole(),s}async addTurn(e){if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});const t=this.meta(),s={...e,session:this._id,version:e.version??0,parent:e.parent??this.head()??void 0,role:e.role??t?.role,model:e.model??t?.metadata?.model},r=await this.dispatch({type:"turn:add",payload:{sessionId:this._id,turn:s},timestamp:s.timestamp});return r.ok&&await this.refreshTurnTree(),r}async recordUserTurn(e){return this.meta()?this.addTurn(e):y({code:"NOT_FOUND",resource:"session",id:this._id})}async recordAssistantTurn(e,t){const s=this.ws();if(!s)return y({code:"NOT_FOUND",resource:"workspace",id:"current"});if(!s.index.sessions[this._id])return y({code:"NOT_FOUND",resource:"session",id:this._id});const r=this.processor.process(e,this._id);let n={};const i=[];let o;for(const e of r){const t=await this.manager.dispatch(e);if(t.ok)n=g(n,t.value);else{if("PERMISSION_DENIED"!==t.error.code||e.synthetic){o=t.error;break}{const t=this.describeCommand(e);i.push({cmd:e,description:t})}}}e.metadata=o?{...e.metadata,status:"unsuccessful",error:o}:{...e.metadata,status:"success"};const a=await this.addTurn(e);if(!a.ok)return a;if(n=g(n,a.value),t&&i.length>0){const e=this.buildDenialTurn(i),t=await this.addTurn(e);t.ok&&(n=g(n,t.value))}return o?y(o):f(n)}buildDenialTurn(e){const t=new $("user",this._id);for(const s of e)t.addText(`[System] User denied: ${s.description}.`);return t.build()}describeCommand(e){return"tool:call"===e.type?`tool execution: ${e.payload.tool}`:`command: ${e.type}`}async editTurn(e,t,s,r){if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});const n=this.tree.graph()[e];if(!n)return y({code:"NOT_FOUND",resource:"turn",id:e});const i=n.versions[n.activeVersion],o=n.activeVersion+1,a=await this.dispatch({type:"turn:edit",payload:{sessionId:this._id,turnId:e,newBlocks:t,roleSnapshot:s??i.role,modelSnapshot:r??i.model,newVersion:o},timestamp:(new Date).toISOString()});return a.ok&&(await this.dispatch({type:"session:update",payload:{sessionId:this._id,head:{id:e,version:o}},timestamp:(new Date).toISOString()}),await this.refreshTurnTree()),a}async branch(e){if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});if(!e.parent)return y({code:"INVALID_COMMAND",reason:"branch requires turn.parent to be set"});const t=await this.dispatch({type:"turn:branch",payload:{sessionId:this._id,turn:{...e,session:this._id}},timestamp:e.timestamp});return t.ok&&await this.refreshTurnTree(),t}async deleteTurn(e,t,s){if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});const r=this.tree.graph();if(!r[e]?.versions[t])return y({code:"NOT_FOUND",resource:"turn version",id:`${e}:${t}`});const n=await this.dispatch({type:"turn:delete",payload:{sessionId:this._id,turnId:e,version:t,newHead:s},timestamp:(new Date).toISOString()});return n.ok&&await this.refreshTurnTree(),n}async updateTurnStatus(e,t){const s=this.tree.graph()[e];if(!s)return y({code:"NOT_FOUND",resource:"turn",id:e});const r=s.versions[s.activeVersion],n={...r,metadata:{...r.metadata,status:t.ok?"success":"unsuccessful",error:t.ok?void 0:t.error}},i=await this.dispatch({type:"turn:update",payload:{sessionId:this._id,turn:n},timestamp:(new Date).toISOString()});return i.ok&&await this.refreshTurnTree(),i}async switchVersionLeft(e){return this.switchVersion(e,-1)}async switchVersionRight(e){return this.switchVersion(e,1)}async switchVersion(e,t){if(!this.ws())return y({code:"NOT_FOUND",resource:"workspace",id:"current"});if(!this.meta())return y({code:"NOT_FOUND",resource:"session",id:this._id});const s=this.tree.graph()[e];if(!s)return y({code:"NOT_FOUND",resource:"turn",id:e});const r=Object.keys(s.versions).map(Number).sort(((e,t)=>e-t)),n=r.indexOf(s.activeVersion);if(-1===n)return y({code:"INVALID_COMMAND",reason:"Active version not found"});const i=n+t;if(i<0||i>=r.length)return y({code:"INVALID_COMMAND",reason:`No ${t<0?"previous":"next"} version available for turn ${e}`});const o=r[i],a=this.findSubtreeTip(this.tree.graph(),e,o),c=await this.dispatch({type:"session:update",payload:{sessionId:this._id,head:a},timestamp:(new Date).toISOString()});return c.ok&&await this.refreshTurnTree(),c}async snapshot(e){const t=this,s=t.meta();if(!s)return;const r=t.ws(),n=t._role;if(!n)return;const i=await t.manager.ctx().context.getByTopics(r.index,s.topics),o=Array.from(new Set([...n.preferences,...s.preferences])),a=o.length>0?await t.manager.ctx().preferences.load(o):t._preferences,c=(e?t.tree.chainFrom(e):t.tree.chain()).map((e=>e.versions[e.activeVersion])).filter((e=>!!e)),d=[...c].reverse().find((e=>"user"===e.actor));return{id:t._id,meta:s,role:n,preferences:a,context:i,model:s.metadata?.model,transcript:c,topics:s.topics,instructions:r.settings?.prompt,constraints:{role:n.constraints,session:s.constraints,turn:d?.constraints}}}async refreshTurnTree(){this.tree=await z.build(this._id,this.turnRepository)}findSubtreeTip(e,t,s){let r=t,n=s;for(;;){const t=e[r];if(!t)break;const s=t.children[n];if(!s||0===s.length)break;const i=s[0],o=e[i];if(!o)break;r=i,n=o.activeVersion}return{id:r,version:n}}},L=class{constructor(e,t){this.manager=e,this.processor=t}openOnce=new Map;async open(e){let t=this.openOnce.get(e);t||(t=new d,this.openOnce.set(e,t));const s=await t.do((async()=>{if(!this.manager.workspace().index.sessions[e])throw new Error(`Session ${e} not found in workspace index`);return K.create(e,this.manager,this.processor)}));if(s.error)throw s.error;return s.value}close(e){this.openOnce.delete(e)}async delete(e){const t=await this.manager.dispatch({type:"session:delete",payload:{sessionId:e},timestamp:(new Date).toISOString()});if(t.ok)return this.close(e),t.value=void 0,t;throw t.error}async has(e){return!this.manager.workspace().index.sessions[e]}async create(e){const s=t.v7(),r=await this.manager.dispatch({type:"session:create",payload:{id:s,label:e.label,role:e.role,topics:e.topics,preferences:e.preferences??[],metadata:{created:(new Date).toISOString()}},timestamp:(new Date).toISOString()});if(r.ok)return this.open(s);throw r.error}list(){return Object.values(this.manager.workspace().index.sessions)}metadata(e){return this.manager.workspace().index.sessions[e]}},V=class{constructor(e,t,s){this.storage=e,this.cache=t,this.bus=s}async register(e,t,s){const r=await w(e),n=await this.getRecord(r);if(n){const e={...n,refCount:n.refCount+1,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(e),this.cache.set(r,e),f(this.reference(e))}const i={sha256:r,mediaType:t,sizeBytes:e.byteLength,filename:s,refCount:1,remoteIds:{},createdAt:(new Date).toISOString(),lastUsedAt:(new Date).toISOString()};return this.storage.registerBlob?await this.storage.registerBlob(i,e):(await this.storage.storeBytes(r,e),await this.storage.saveRecord(i)),this.cache.set(r,i),this.bus.emit({name:"blobs:changed",payload:{sha256:r,record:i}}),f(this.reference(i))}async retain(e){const t=await this.getRecord(e);if(!t)return y({code:"NOT_FOUND",resource:"blob",id:e});const s={...t,refCount:t.refCount+1,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(s),this.cache.set(e,s),f(void 0)}async release(e){const t=await this.getRecord(e);if(!t)return y({code:"NOT_FOUND",resource:"blob",id:e});const s=Math.max(0,t.refCount-1),r={...t,refCount:s,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(r),this.cache.set(e,r),f(void 0)}async purge(e){return await this.storage.deleteBytes(e),await this.storage.deleteRecord(e),this.cache.delete(e),this.bus.emit({name:"blobs:changed",payload:{sha256:e}}),f(void 0)}async recordRemoteId(e,t,s,r){const n=await this.getRecord(e);if(!n)return y({code:"NOT_FOUND",resource:"blob",id:e});const i={...n,remoteIds:{...n.remoteIds,[t]:{id:s,timestamp:r||(new Date).toISOString()}},lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(i),this.cache.set(e,i),this.bus.emit({name:"blobs:changed",payload:{sha256:e,record:i}}),f(void 0)}async getRecord(e){const t=this.cache.get(e);if(t)return t;const s=await this.storage.loadRecord(e);return s&&this.cache.set(e,s),s}async getAllRecords(){const e=await this.storage.listRecords(),t={};for(const s of e)t[s.sha256]=s,this.cache.set(s.sha256,s);return t}reference(e){return{sha256:e.sha256,mediaType:e.mediaType,sizeBytes:e.sizeBytes,filename:e.filename}}async resolve(e,t){const s=await this.getRecord(e.sha256);if(!s)return f(null);if(t){const e=s.remoteIds[t];if(e)return f({kind:"remote",sha256:s.sha256,mediaType:s.mediaType,fileId:e.id,providerId:t,timestamp:e.timestamp});const r=await this.storage.loadBytes(s.sha256);return f(r?{kind:"inline",sha256:s.sha256,mediaType:s.mediaType,data:r}:null)}const r=await this.storage.loadBytes(s.sha256);return f(r?{kind:"inline",sha256:s.sha256,mediaType:s.mediaType,data:r}:null)}async resolveMany(e,t){const s=new Map;for(const r of e){const e=await this.resolve(r,t);if(!e.ok)return y(e.error);if(null===e.value)return y({code:"BLOB_ERROR",reason:`Unable to resolve blob ${r.sha256}${t?` with adapter ${t}`:""}`});s.set(r.sha256,e.value)}return f(s)}},J=class{constructor(e,t,s){this.collection=e,this.cache=t,this.registry=s}delegates=new Map;registerDelegate(e,t){this.delegates.set(e,t)}async get(e,t){const s=this.cache.get(e);if(s)return s;if(t){const s=this.delegates.get(t);if(s){const t=await s.get(e);return t&&this.cache.set(e,t),t}}const r=await this.collection.find({field:"key",operator:"eq",value:e});if(!r)return null;const n=r.state();return this.cache.set(e,n),n}async add(e){const t=this.delegates.get(e.content.kind);t?await t.add(e):await this.collection.create(e),this.cache.set(e.key,e)}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"}),t=((await e.next()).value||[]).map((e=>e.state()));for(const e of this.delegates.values()){const s=await e.list();t.push(...s)}return t}async update(e,t,s){if(s){const r=this.delegates.get(s);if(r){const s=await r.update(e,t);return s&&this.cache.set(e,s),s}}const r=await this.collection.find({field:"key",operator:"eq",value:e});if(!r)return null;await r.update(t);const n=r.state();return this.cache.set(e,n),n}async delete(e,t){if(t){const s=this.delegates.get(t);if(s){const t=await s.delete(e);return t&&this.cache.delete(e),t}}const s=await this.collection.find({field:"key",operator:"eq",value:e});if(!s)return!1;const r=await s.delete();return r&&this.cache.delete(e),r}async getByTopics(e,t){const s=new Map;for(const r of t){const t=e.topics[r];t&&t.contextKeys.forEach((t=>{const r=e.context[t],n=r?.kind||"unknown";s.has(n)||s.set(n,new Set),s.get(n).add(t)}))}if(0===s.size)return[];const r=[],n=[];for(const[e,t]of s.entries()){if(this.delegates.get(e))for(const s of t){const t=await this.get(s,e);t&&r.push(t)}else t.forEach((e=>n.push(e)))}if(n.length>0){const e=[];for(const t of n){const s=this.cache.get(t);s?r.push(s):e.push(t)}if(e.length>0){const t=await this.collection.filter({operator:"or",conditions:e.map((e=>({field:"key",operator:"eq",value:e})))});for(const e of t){const t=e.state();this.cache.set(t.key,t),r.push(t)}}}return r.sort(((e,t)=>new Date(t.timestamp).getTime()-new Date(e.timestamp).getTime()))}summarize(e){const t=this.registry?.get(e.content.kind);return t?t.summarize(e):{kind:e.content.kind,key:e.key,topics:e.topics,timestamp:e.timestamp,metadata:e.metadata}}},G=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;const r=s.state();return this.cache.set(e,r),r}async add(e){await this.collection.create(e),this.cache.set(e.id,e)}async update(e,t){const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;await s.update(t);const r=s.state();return this.cache.set(e,r),r}async delete(e){const t=await this.collection.find({field:"id",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async load(e){if(0===e.length)return[];const t=[],s=[];for(const r of e){const e=this.cache.get(r);e?s.push(e):t.push(r)}if(t.length>0){const e=await this.collection.filter({operator:"or",conditions:t.map((e=>({field:"id",operator:"eq",value:e})))});for(const t of e){const e=t.state();this.cache.set(e.id,e),s.push(e)}}return s}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return{id:e.id,topics:e.topics,timestamp:e.timestamp,snippet:e.content.slice(0,100)}}},Y=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;const r=s.state();return this.cache.set(e,r),r}async add(e){await this.collection.create(e),this.cache.set(e.name,e)}async update(e,t){const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;await s.update(t);const r=s.state();return this.cache.set(e,r),r}async delete(e){const t=await this.collection.find({field:"name",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return{name:e.name,label:e.label,description:e.description,preferences:e.preferences?.length??0,topics:e.topics??[],constraints:e.constraints}}},H=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;const r=s.state();return this.cache.set(e,r),r}async add(e){await this.collection.create(e),this.cache.set(e.id,e)}async update(e,t){const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;await s.update(t);const r=s.state();return this.cache.set(e,r),r}async delete(e){const t=await this.collection.find({field:"id",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return e}},X=class{constructor(e,t){this.collection=e,this.cache=t}key({id:e,session:t,version:s}){return`${t}:${s}:${e}`}async find({id:e,session:t,version:s},r=!0){const n=this.key({id:e,session:t,version:s});this.cache.get(n)&&this.cache.get(n);const i=await this.collection.find({operator:"and",conditions:[{field:"id",operator:"eq",value:e},{field:"session",operator:"eq",value:t},{field:"version",operator:"eq",value:s}]});return i?(r&&this.cache.set(n,i),i):null}async get(e){return this.find(e)}async add(e){const t=await this.collection.create(e);this.cache.set(this.key(e),t)}async update(e,t){const s=await this.find(e);return s?(await s.update(t),s.state()):null}async listBySession(e){return(await this.collection.filter({field:"session",operator:"eq",value:e})).map((e=>e.state()))}async delete(e){const t=await this.find(e,!1);if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(this.key(e)),s}},Q=(e={})=>({id:e.id??t.v7(),settings:g({language:"en-US",defaultRole:void 0,prompt:void 0},e.settings),project:g({id:t.v7(),name:"Unnamed Project"},e.project),index:g({roles:{},preferences:{},context:{},sessions:{},topics:{},blobs:{},tools:{},extensions:{}},e.index)});function Z(e,t,s){const r=new Set([...Object.keys(e??{}),...Object.keys(t??{}),...Object.keys(s??{})]),n={};for(const i of r){const r=e?.[i]??{},o=t?.[i]??{},a=s?.[i]??{};n[i]={temperature:a.temperature??o.temperature??r.temperature,tokens:{max:a.tokens?.max??o.tokens?.max??r.tokens?.max,stops:a.tokens?.stops??o.tokens?.stops??r.tokens?.stops,thought:a.tokens?.thought??o.tokens?.thought??r.tokens?.thought}}}return n}function ee(e,s,r){return{id:t.v7(),session:e,version:0,actor:s,blocks:r,timestamp:(new Date).toISOString()}}var te="blob_bytes",se="blob_records";function re(e){return new Promise(((t,s)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>s(e.error)}))}function ne(e){return new Promise(((t,s)=>{e.oncomplete=()=>t(),e.onerror=()=>s(e.error),e.onabort=()=>s(new Error("Transaction aborted"))}))}var ie={};((e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})})(ie,{GOOGLE_MODELS:()=>ae,GoogleGenAIAdapter:()=>me,mapBlockToPart:()=>ue,mapTurnToContent:()=>le,mappings:()=>oe,parseModelResponse:()=>de});var oe={text:{to:e=>({text:e.text}),from:e=>({id:t.v4(),type:"text",text:e.text})},summary:{to:e=>({text:`[Summary]: ${e.text}`}),from:e=>({id:t.v4(),type:"summary",text:e.text})},thinking:{to:e=>({text:e.thinking}),from:e=>({id:t.v4(),type:"thinking",thinking:e.thinking})},"tool:use":{to:e=>({functionCall:{name:e.name,args:e.input}}),from:e=>({id:t.v4(),type:"tool:use",name:e.functionCall?.name??e.name,input:e.functionCall?.args??e.input??{}})},"tool:result":{to:e=>({functionResponse:{name:e.useId,response:{result:e.content}}}),from:e=>({id:t.v4(),type:"tool:result",useId:e.useId,content:e.content,isError:e.isError})},"role:transition":{to:e=>({text:`[Role transition: ${e.previousRole??"none"} → ${e.newRole}]`}),from:e=>({id:t.v4(),type:"role:transition",previousRole:e.previousRole,newRole:e.newRole})}},ae=[{provider:"google",name:"gemini-3.1-pro-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:2,output:12,cache:{read:.2,write:4.5}}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-3-flash-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.5,output:3,cache:{read:.05,write:1}}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-3.1-flash-lite-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.25,output:1.5,cache:{read:.025,write:1}}}],capacity:[{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-2.5-pro",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:1.25,output:10,cache:{read:.125,write:4.5}}}],capacity:[{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-2.5-flash",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.3,output:2.5,cache:{read:.03,write:1}}}],capacity:[{unit:"call",max:4e3,period:60},{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-2.5-flash-lite",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.1,output:.4,cache:{read:.01,write:1}}}],capacity:[{unit:"call",max:4e3,period:60},{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-3-pro-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:2,output:12,cache:{read:.2,write:4.5}}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-2.5-flash-image",window:{size:4096,out:0},feature:{vision:!1,tools:!1,json:!1,cache:!1,streaming:!1,thinking:!1},pricing:[{unit:"image",scale:0,cost:{input:.02,output:0}}],capacity:[{unit:"call",max:100,period:60}]},{provider:"google",name:"gemini-2.5-flash-live-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.5,output:3}}],capacity:[{unit:"concurrent",max:10,period:0}]},{provider:"google",name:"gemini-3.1-flash-live-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.5,output:3}}],capacity:[{unit:"concurrent",max:10,period:0}]},{provider:"google",name:"gemini-2.5-computer-use-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:1.25,output:10}}],capacity:[{unit:"call",max:200,period:60},{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-embedding-001",window:{size:2048,out:0},feature:{vision:!1,tools:!1,json:!1,cache:!1,streaming:!1,thinking:!1},pricing:[{unit:"token",scale:6,cost:{input:.5,output:0}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-embedding-2",window:{size:8192,out:0},feature:{vision:!1,tools:!1,json:!1,cache:!1,streaming:!1,thinking:!1},pricing:[{unit:"token",scale:6,cost:{input:.3,output:0}}],capacity:[{unit:"token",max:1e6,period:60}]}];function ce(e){let t=e;return(t.match(/```/g)||[]).length%2!=0&&(t+="\n```"),t.includes('\\"')&&!t.includes('"')&&(t=t.replace(/\\"/g,'"')),t}function de(e,s){const r=e.candidates?.[0];if(!r?.content?.parts)return y({code:"BACKEND_ERROR",reason:"No valid content parts in response"});const n=[];let i;for(const e of r.content.parts)if(e.thought)n.push((o=e.text??"",{id:t.v7(),type:"thinking",thinking:o}));else if(e.text){i=e;break}var o;if(!i)return n.length>0?f(n):y({code:"BACKEND_ERROR",reason:"Response missing JSON part"});const a=function(e){try{const t=JSON.parse(e);return t.blocks&&Array.isArray(t.blocks)?f(t.blocks):y({code:"BACKEND_ERROR",reason:'Invalid response: missing or malformed "blocks" array'})}catch(e){return y({code:"BACKEND_ERROR",reason:`Failed to parse response JSON: ${e instanceof Error?e.message:String(e)}`})}}(i.text);if(!a.ok)return n.push(function(e){return{id:t.v7(),type:"text",text:ce(e)}}(i.text)),f(n);for(const e of a.value){const t=s.parse(e,me.provider());t&&n.push(t)}return f(n)}async function le(e,t,s){const r="assistant"===e.actor?"model":"user",n=[];for(const r of e.blocks){if("image"===r.type||"document"===r.type){const e=r.ref;if(!e)continue;const s=await pe(e,t);s&&n.push(s);continue}const e=ue(r,s);e&&n.push(e)}return{role:r,parts:n}}function ue(e,t){const s=t.get(e.type);if(!s)throw new Error(`[GoogleGenAIAdapter] mapBlockToPart: block type "${e.type}" is not registered. Register it via registry.register() before use.`);const r=s.mappings?.[me.provider()];if(!r)throw new Error(`[GoogleGenAIAdapter] mapBlockToPart: no "${me.provider()}" mapping for block type "${e.type}". Add a mapping via registry.update("${e.type}", { mappings: { ${me.provider()}: { to, from } } }).`);return r.to(e)}async function pe(e,t){const s=await t(e,me.provider());if(!s.ok||!s.value)return null;const{value:r}=s;return"remote"===r.kind?{fileData:{fileUri:r.fileId,mimeType:r.mediaType}}:{inlineData:{data:b(r.data),mimeType:r.mediaType}}}function he(e){return Math.ceil(e.length/4)}var me=class e{constructor(e,t,s={model:"gemini-2.5-flash"}){this.client=e,this.services=t,this._models=t.models;const r=this._models.get(s.model);if(!r)throw new Error(`Could not get model: ${s.model} profile in registry.`);this.model=r,this.registerGeminiMappings()}model;_models;registerGeminiMappings(){const t=this.services.blockRegistry;for(const[s,r]of Object.entries(oe))t.update(s,{mappings:{[e.provider()]:r}})}async status(t){return{provider:e.provider(),model:this.model.name,ready:!0,window:this.model.window,feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.1,output:.4}}],rate:{load:0,capacity:[{unit:"call",max:1e3,period:60},{unit:"token",max:4e6,period:60}]}}}async resolve(e){const{prompt:s}=e,{assembler:r,blockRegistry:n,blobResolver:i}=this.services,o=s.model&&this._models.get(s.model)||this.model,a=r.build(s,[{label:"block-architecture",content:n.description(),position:"after:instructions"}]),c=r.join(a),d={role:"system",parts:[{text:c}]},l=s.constraints[o.name]??{tokens:{}},u=await Promise.all(s.transcript.map((e=>le(e,i,n)))),p=n.schema(),h={model:o.name,contents:u,config:{systemInstruction:d,thinkingConfig:{includeThoughts:!0},responseMimeType:"application/json",responseSchema:p,...void 0!==l.temperature&&{temperature:l.temperature},...void 0!==l.tokens.max&&{maxOutputTokens:l.tokens.max},...l.tokens.stops?.length&&{stopSequences:l.tokens.stops},...void 0!==l.tokens.thought&&{thinkingConfig:{includeThoughts:!0,thinkingBudget:l.tokens.thought}}}},m=u.flatMap((e=>e.parts??[])).map((e=>e.text??"")).join(""),g=he(c),w=he(m),b=g+w,k=this;return{model:o.name,instructions:a,transcript:s.transcript,context:s.system.context,preferences:s.system.preferences,constraints:l,tokens:{breakdown:{system:g,transcript:w},total:b,source:"estimated",output:l.tokens.max??o.window.out,remaining:o.window.size-b},async execute(){let e;try{e=await k.client.models.generateContent(h)}catch(e){return y({code:"BACKEND_ERROR",reason:e instanceof Error?e.message:String(e)})}const t=de(e,k.services.blockRegistry);if(!t.ok)return t;const r=t.value,n=new $("assistant",s.session);for(const e of r)n.addBlock(e);return f({turn:n.build(),effects:[]})},async*executeStream(){let e;try{e=await k.client.models.generateContentStream(h)}catch(e){const r=e instanceof Error?e.message:String(e),n=new $("assistant",s.session);return n.addBlock({id:t.v7(),type:"text",text:`[Stream error: ${r}]`}),void(yield{turn:n.build(),effects:[]})}const r=[];for await(const s of e){const e=s.candidates?.[0];if(e?.content?.parts)for(const s of e.content.parts)s.thought||s.text&&(r.push(s.text),yield{blocks:[{id:t.v7(),type:"text",text:s.text}]})}const n=r.join(""),i=new $("assistant",s.session);i.addBlock({id:t.v7(),type:"text",text:n}),yield{turn:i.build(),effects:[]}}}}static provider(){return"google"}static models(){return ae}};exports.COLLECTIONS=p,exports.DefaultPromptBuilder=class{constructor(e,t,s){this.contextRegistry=e,this.retriever=t,this.summarizer=s}async build(e,s,r={}){const n=[],{resolved:i}=function(e){const t=[],s=new Map;for(const r of e)for(const e of r.topics){const n=s.get(e);if(!n){s.set(e,r);continue}const i=new Date(n.timestamp).getTime(),o=new Date(r.timestamp).getTime();o>i?(t.push({topic:e,kept:r.id,dropped:n.id}),s.set(e,r)):i>o&&t.push({topic:e,kept:n.id,dropped:r.id})}const r=new Map,n=new Map;for(const t of e)n.set(t.id,t.topics.length);for(const e of t)r.set(e.dropped,(r.get(e.dropped)??0)+1);const i=new Set;for(const t of e){const e=r.get(t.id)??0,s=n.get(t.id)??0;s>0&&e>=s&&i.add(t.id)}return{resolved:e.filter((e=>!i.has(e.id))),conflicts:Array.from(new Map(t.map((e=>[`${e.topic}:${e.dropped}`,e]))).values())}}(e.preferences),o=function(e,t=3){return e.filter((e=>"user"===e.actor)).slice(-t).flatMap((e=>e.blocks.filter((e=>"text"===e.type)).map((e=>e.text)).filter(Boolean)))}(e.transcript),a=this.retriever.rank({entries:e.context,recentMessages:o,topics:e.topics,config:r.retrieverConfig}),c=[],d=[];for(const e of a){const t=this.contextRegistry.get(e.content.kind);if(!t){n.push(`No ContextDefinition found for kind: ${e.content.kind}`);continue}const s=t.render(e),r=Array.isArray(s)?s:[s];"system"===t.target?c.push({label:`context:${e.content.kind}:${e.key}`,content:r.map((t=>"text"===t.type?t.text:`[${e.content.kind}] ${JSON.stringify(t,null,2)}`)).join("\n"),position:"after:context"}):d.push(...r)}let l=e.transcript;if(r.summarize&&this.summarizer&&l.length>0){const s=2e3;try{const r=await this.summarizer.summarize(l,s),n=[];r.summary&&n.push(ee(e.id,"system",[{id:t.v7(),type:"summary",text:r.summary}])),l=[...n,...r.remaining]}catch(e){n.push(`Summarizer failed: ${e instanceof Error?e.message:String(e)}`)}}const u=[];d.length>0&&u.push(ee(e.id,"user",d));const p=function(e,s){const r=[];let n=null,i=!1;for(const o of e)"user"===o.actor&&o.role&&(i&&o.role!==n&&r.push(ee(s,"system",[{id:t.v7(),type:"role:transition",previousRole:n??void 0,newRole:o.role}])),n=o.role,i=!0),r.push(o);return r}(l,e.id),h=[...u,...p],m=function(e,t){const s=new Map;for(const t of e)if("blob"===t.content.kind){const{sha256:e,mediaType:r,sizeBytes:n,filename:i,previewUrl:o}=t.content;s.has(e)||s.set(e,{sha256:e,mediaType:r,sizeBytes:n,filename:i,previewUrl:o})}for(const e of t)for(const t of e.blocks)if("image"===t.type||"document"===t.type){const e=t.ref;e&&!s.has(e.sha256)&&s.set(e.sha256,e)}return s}(a,h);return f({session:e.id,model:e.model,system:{persona:e.role.persona,instructions:e.instructions,preferences:i,context:[],extensions:c},transcript:h,blobs:m,role:e.role,constraints:Z(e.constraints.role,e.constraints.session,e.constraints.turn),warnings:n})}},exports.DefaultSystemPromptAssembler=I,exports.EMPTY_SYSTEM_ROLE=U,exports.GoogleAdapter=ie,exports.IndexedDBBlobStorage=class{dbName;db=null;constructor(e={}){this.dbName=e.dbName??"aiworkspace-blobs"}async open(){this.db||(this.db=await new Promise(((e,t)=>{const s=indexedDB.open(this.dbName,1);s.onupgradeneeded=e=>{const t=e.target.result;this.createSchema(t)},s.onsuccess=()=>e(s.result),s.onerror=()=>t(s.error),s.onblocked=()=>t(new Error(`[IndexedDBBlobStorage] Database "${this.dbName}" blocked.`))})),this.db.onversionchange=()=>{this.db?.close(),this.db=null})}createSchema(e){e.objectStoreNames.contains(te)||e.createObjectStore(te,{keyPath:"sha256"}),e.objectStoreNames.contains(se)||e.createObjectStore(se,{keyPath:"sha256"})}close(){this.db?.close(),this.db=null}async deleteDatabase(){this.close(),await new Promise(((e,t)=>{const s=indexedDB.deleteDatabase(this.dbName);s.onsuccess=()=>e(),s.onerror=()=>t(s.error)}))}getDB(){if(!this.db)throw new Error("[IndexedDBBlobStorage] Database not open. Call open() first.");return this.db}readTx(...e){return this.getDB().transaction(e,"readonly")}writeTx(...e){return this.getDB().transaction(e,"readwrite")}async storeBytes(e,t){const s=this.readTx(te);if(await re(s.objectStore(te).get(e)))return;const r=this.writeTx(te);r.objectStore(te).put({sha256:e,data:t}),await ne(r)}async loadBytes(e){const t=this.readTx(te),s=await re(t.objectStore(te).get(e));return s?.data??null}async hasBytes(e){const t=this.readTx(te);return await re(t.objectStore(te).count(e))>0}async deleteBytes(e){const t=this.writeTx(te);t.objectStore(te).delete(e),await ne(t)}async saveRecord(e){const t=this.writeTx(se);t.objectStore(se).put(e),await ne(t)}async loadRecord(e){const t=this.readTx(se);return await re(t.objectStore(se).get(e))??null}async deleteRecord(e){const t=this.writeTx(se);t.objectStore(se).delete(e),await ne(t)}async listRecords(){return re(this.readTx(se).objectStore(se).getAll())}async exportAllBytes(){const e=this.readTx(te);return(await re(e.objectStore(te).getAll())).map((({sha256:e,data:t})=>[e,t]))}async registerBlob(e,t){await new Promise(((s,r)=>{const n=this.getDB().transaction([te,se],"readwrite"),i=n.objectStore(te),o=n.objectStore(se),a=i.count(e.sha256);a.onsuccess=()=>{0===a.result&&i.put({sha256:e.sha256,data:t}),o.put(e)},a.onerror=()=>r(a.error),n.oncomplete=()=>s(),n.onerror=()=>r(n.error),n.onabort=()=>r(new Error("registerBlob transaction aborted"))}))}},exports.JaccardContextRetriever=class{constructor(e){this.contextRegistry=e}rank(e){const{entries:t,recentMessages:s,config:r={}}=e,n=r.minScore??0,i=r.freshnessHalfLifeDays??30,o=r.recentMessageWindow??3;if(0===s.length)return[...t].sort(((e,t)=>this.freshnessWeight(t.timestamp,i)-this.freshnessWeight(e.timestamp,i)));const a=this.tokenize(s.slice(-o).join(" "));return t.map((e=>{const t=function(e,t){const s=t.get(e.content.kind);return s?s.toString(e):""}(e,this.contextRegistry);return{entry:e,score:.7*this.jaccardSimilarity(a,this.tokenize(t))+.3*this.freshnessWeight(e.timestamp,i)}})).filter((e=>e.score>n)).sort(((e,t)=>t.score-e.score)).map((e=>e.entry))}tokenize(e){return new Set(e.toLowerCase().replace(/[^\w\s]/g," ").split(/\s+/).filter((e=>e.length>2)))}jaccardSimilarity(e,t){if(0===e.size&&0===t.size)return 0;let s=0;for(const r of e)t.has(r)&&s++;const r=e.size+t.size-s;return 0===r?0:s/r}freshnessWeight(e,t){const s=(Date.now()-new Date(e).getTime())/864e5;return Math.pow(.5,s/t)}},exports.LRUCache=P,exports.MemoryBlobStorage=class{bytes=new Map;records=new Map;async storeBytes(e,t){this.bytes.has(e)||this.bytes.set(e,t)}async loadBytes(e){return this.bytes.get(e)??null}async hasBytes(e){return this.bytes.has(e)}async deleteBytes(e){this.bytes.delete(e)}async saveRecord(e){this.records.set(e.sha256,{...e})}async loadRecord(e){return this.records.get(e)??null}async deleteRecord(e){this.records.delete(e)}async listRecords(){return Array.from(this.records.values()).map((e=>({...e})))}async exportAllBytes(){return Array.from(this.bytes.entries()).map((([e,t])=>[e,new Uint8Array(t)]))}async registerBlob(e,t){this.bytes.has(e.sha256)||this.bytes.set(e.sha256,t),this.records.set(e.sha256,{...e})}},exports.Session=K,exports.SessionManager=L,exports.TurnBuilder=$,exports.TurnTree=z,exports.WorkspaceApi=W,exports.WorkspaceManager=k,exports.WorkspaceRegistry=class{constructor(e){this.db=e}async list(){const e=u(this.db);await e.open();const t=await e.collection(p.WORKSPACE);return new F(t,new P(100)).list()}async delete(e){const t=u(this.db);await t.open();const s=await t.collection(p.WORKSPACE);return new F(s,new P(1)).delete(e)}async purge(){this.db.clear()}},exports.bufferToBase64=b,exports.computeSHA256=w,exports.createDefaultAssembler=function(){return new I},exports.createEmptySession=(e={})=>({id:t.v7(),label:"New Conversation",role:"assistant-default",topics:[],preferences:[],metadata:{created:(new Date).toString(),updated:(new Date).toString()},...e,head:e.head?e.head:void 0}),exports.createEmptyTurn=(e={},s)=>({id:e.id??t.v7(),version:e.version??0,session:e.session??s?.id??t.v7(),actor:"user",blocks:[{id:t.v7(),type:"text",text:"Hello, world!"}],timestamp:(new Date).toString(),role:s?.role,...e,parent:e.parent?e.parent:void 0}),exports.createEmptyWorkspace=Q,exports.createWorkspace=async function(t){const{blobStorage:s,eventBus:n=e.createEventBus(),getWorkspace:i,setWorkspace:o,processor:a,guard:c,toolRegistry:d,models:l=[],extensions:h=[],extensionReducers:m={},extensionMiddleware:f=[],extensionIndexers:y=[],extensionStores:g,extensionSchemas:w=[]}=t,b=u(t.db),v=[...w,...h.flatMap((e=>e.schemas??[]))],_={...m,...h.reduce(((e,t)=>({...e,...t.reducers})),{})},O=[...f,...h.flatMap((e=>e.middleware??[]))],S=[...y,...h.flatMap((e=>e.indexers??[]))],T=h.flatMap((e=>e.blocks??[]));await b.open(v);const R={workspace:await b.collection(p.WORKSPACE),role:await b.collection(p.ROLE),preference:await b.collection(p.PREFERENCE),context:await b.collection(p.CONTEXT),session:await b.collection(p.SESSION),topic:await b.collection(p.TOPIC),turn:await b.collection(p.TURN)},D=new V(s,new P(200),n),A=new q,B={workspaceStore:new F(R.workspace,new P(1)),roles:new Y(R.role,new P(100)),preferences:new G(R.preference,new P(500)),context:new J(R.context,new P(500),A),topics:new x(R.topic,new P(100)),sessions:new H(R.session,new P(50)),turns:new X(R.turn,new P(50)),blobs:D,tools:d,db:b,indexers:[...r,...S]};if(g){const e=g(B);Object.assign(B,e)}await Promise.all(h.map((async e=>{if(e.stores){const t=await e.stores(B);Object.assign(B,t)}})));const U=new k({ctx:B,getWorkspace:i,updateWorkspace:async e=>{if(await o(e),e?.id||e?.settings||e?.project){const e=i();await B.workspaceStore.update(e.id,{id:e.id,settings:e.settings,project:e.project})}},guard:c,bus:n});Object.entries(E).forEach((([e,t])=>{U.register(e,t)})),Object.entries(_).forEach((([e,t])=>{U.register(e,t)})),U.use(N),O.forEach((e=>{U.use(e)}));const $=new L(U,a),M=new C;T.forEach((e=>M.register(e))),h.forEach((e=>{e.contexts&&e.contexts.forEach((e=>{if(A.register(e),e.store){const t=e.store(B);B.context.registerDelegate(e.kind,t)}}))}));const z=new j(l),W={assembler:new I,processor:a,blobResolver:B.blobs.resolve.bind(B.blobs),blockRegistry:M,contextRegistry:A,models:z},K=async e=>{await U.dispatch({type:"workspace:sync",payload:void 0,timestamp:(new Date).toISOString()});let t=i();await U.dispatch({type:"workspace:create",payload:e.workspace,timestamp:(new Date).toISOString()}),t=i();const s=[];if(e.roles)for(const r of e.roles)t.index.roles[r.name]||(await U.dispatch({type:"role:add",payload:r,timestamp:(new Date).toISOString()}),s.push(r.name));return e.workspace.settings.defaultRole&&t.settings.defaultRole!==e.workspace.settings.defaultRole&&await U.dispatch({type:"workspace:sync",payload:{settings:{...t.settings,defaultRole:e.workspace.settings.defaultRole}},timestamp:(new Date).toISOString()}),{workspace:i(),roles:s}};if(t.bootstrap){const e=i();if(!e||!e.index){const e=Q({id:t.bootstrap.workspace.id,settings:t.bootstrap.workspace.settings,project:t.bootstrap.workspace.project});await o(e)}await K(t.bootstrap)}return{manager:U,sessions:$,ctx:B,services:W,bootstrap:K}},exports.createWorkspaceDatabase=u,exports.del=function(){return h},exports.error=y,exports.getExtension=function(e,t){return e.extensions[t]},exports.merge=g,exports.omitNullUndefined=function(e){return Object.fromEntries(Object.entries(e).filter((([e,t])=>null!=t)))},exports.shortHash=function(e,t=4){let s=0;for(let t=0;t<e.length;t++)s=(s<<5)-s+e.charCodeAt(t),s|=0;return Math.abs(s).toString(36).padEnd(t,"0").slice(0,t)},exports.success=f;
|
package/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createEventBus as e}from"@asaidimu/utils-events";import{v7 as t,v4 as s}from"uuid";var n=Object.defineProperty,r=[async e=>{const t=await e.workspaceStore.list();if(0===t.length)return{};const s=t[0];return{id:s.id,settings:s.settings,project:s.project}},async e=>{const t=await e.roles.list(),s={};for(const n of t)s[n.name]=e.roles.summarize(n);return{index:{roles:s}}},async e=>{const t=await e.preferences.list(),s={};for(const n of t)s[n.id]=e.preferences.summarize(n);return{index:{preferences:s}}},async e=>{const t=await e.context.list(),s={};for(const n of t)s[n.key]=e.context.summarize(n);return{index:{context:s}}},async e=>{const t=await e.sessions.list(),s={};for(const n of t)s[n.id]=e.sessions.summarize(n);return{index:{sessions:s}}},async e=>{const t=await e.topics.list(),s={};for(const n of t)s[n.name]=e.topics.summarize(n);return{index:{topics:s}}},async e=>({index:{blobs:await e.blobs.getAllRecords()}})],i=[{name:"workspace",version:"1.0.0",description:"Workspace root containing global settings and project metadata.",fields:{id:{name:"id",type:"string",required:!0},settings:{name:"settings",type:"record",required:!0},project:{name:"project",type:"record",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"}],constraints:[],migrations:[]},{name:"role",version:"1.0.0",description:"AI persona with a system prompt and associated preference defaults.",fields:{name:{name:"name",type:"string",required:!0},label:{name:"label",type:"string",required:!0},description:{name:"description",type:"string",required:!1},persona:{name:"persona",type:"string",required:!0},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"},topics:{name:"topics",type:"array",required:!1},constraints:{name:"constraints",type:"record",required:!1}},indexes:[{name:"by_name",fields:["name"],type:"unique"},{name:"by_label",fields:["label"],type:"normal"}],constraints:[],migrations:[]},{name:"preference",version:"1.0.0",description:"A user behavioural instruction, scoped to zero or more topics.",fields:{id:{name:"id",type:"string",required:!0},content:{name:"content",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},timestamp:{name:"timestamp",type:"string",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"context",version:"1.0.0",description:"Injected background knowledge, scoped to topics. Content is a discriminated union.",fields:{key:{name:"key",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},content:{name:"content",type:"record",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},metadata:{name:"metadata",type:"record",required:!1}},indexes:[{name:"by_key",fields:["key"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"session",version:"1.0.0",description:"Session metadata. The head field tracks the current tip of the turn DAG.",fields:{id:{name:"id",type:"string",required:!0},label:{name:"label",type:"string",required:!0},role:{name:"role",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"},metadata:{name:"metadata",type:"record",required:!1},head:{name:"head",type:"record",required:!1},constraints:{name:"constraints",type:"record",required:!1}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_role",fields:["role"],type:"normal"}],constraints:[],migrations:[]},{name:"turn",version:"1.0.0",description:["A single message in a session transcript, stored as a flat document.","The DAG is reconstructed in memory by TurnTree.buildNodeGraph() at session open time."].join(" "),fields:{id:{name:"id",type:"string",required:!0},session:{name:"session",type:"string",required:!0},version:{name:"version",type:"number",required:!0},actor:{name:"actor",type:"enum",required:!0,values:["user","assistant","tool"]},blocks:{name:"blocks",type:"array",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},role:{name:"role",type:"string",required:!1},parent:{name:"parent",type:"record",required:!1},constraints:{name:"constraints",type:"record",required:!1}},indexes:[{name:"by_session",fields:["session"],type:"normal"},{name:"by_session_parent",fields:["session","parent"],type:"composite"},{name:"by_session_id_ver",fields:["session","id","version"],type:"composite",unique:!0}],constraints:[],migrations:[]},{name:"topic",version:"1.0.0",description:"A categorization for context and preferences, used for retrieval.",fields:{name:{name:"name",type:"string",required:!0},label:{name:"label",type:"string",required:!1},description:{name:"description",type:"string",required:!1},metadata:{name:"metadata",type:"record",required:!1},created:{name:"created",type:"string",required:!0},updated:{name:"updated",type:"string",required:!0}},indexes:[{name:"by_name",fields:["name"],type:"unique"}],constraints:[],migrations:[]}],o=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},a=class extends o{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},c=class extends o{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},d=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const s=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await s;let n;await Promise.race([s.then((()=>clearTimeout(n))),new Promise(((s,r)=>{n=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),r(new a("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},l=class{mutex=new d({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,s="Operation timed out"){if(null==t)return e;let n;return Promise.race([e.then((e=>(clearTimeout(n),e))),new Promise(((e,r)=>{n=setTimeout((()=>r(new a(s))),t)}))])}},u=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new d({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new c};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,n=null;try{if(this._done)throw new c;n=await e(),this._lastValue=n,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:n,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}};function p(e){const t=new l({retry:!0,throws:!0}),s=new l({retry:!0,throws:!0});return{open:async(s=[])=>(await t.do((async()=>{const t=[...i,...s];await e.setupCollections(t)}))).value,collection:async t=>e.collection(t),close:async()=>(await s.do((()=>{e.close()}))).value,database:()=>e}}var h={WORKSPACE:"workspace",ROLE:"role",PREFERENCE:"preference",CONTEXT:"context",SESSION:"session",TURN:"turn",BLOB:"blob",TOPIC:"topic"},m=Symbol.for("delete"),f=e=>Array.isArray(e)?[...e]:{...e};function y(e){return{ok:!0,value:e}}function g(e){return{ok:!1,error:e}}function w(e){return Object.fromEntries(Object.entries(e).filter((([e,t])=>null!=t)))}function b(){return m}var k=function(e){const t=e?.deleteMarker||m;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const n={};for(const[r,i]of Object.entries(e))if(i!==t)if("object"==typeof i&&null!==i){const e=s(i);void 0!==e&&(n[r]=e)}else n[r]=i;return n}return e===t?void 0:e}return function(e,n){if("object"!=typeof e||null===e)return"object"==typeof n&&null!==n?s(n):n===t?{}:n;if("object"!=typeof n||null===n)return e;const r=f(e),i=[{target:r,source:n}];for(;i.length>0;){const{target:e,source:s}=i.pop();for(const n of Object.keys(s)){const r=s[n];if(r!==t)if(Array.isArray(r))e[n]=r;else if("object"==typeof r&&null!==r){const t=n in e&&"object"==typeof e[n]&&null!==e[n]?e[n]:{};e[n]=f(t),i.push({target:e[n],source:r})}else e[n]=r;else delete e[n]}}return r}}({deleteMarker:m});async function x(e){const t=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join("")}function v(e){if("undefined"!=typeof Buffer)return Buffer.from(e).toString("base64");const t=[];for(let s=0;s<e.length;s+=32768){const n=e.subarray(s,s+32768);t.push(String.fromCharCode.apply(null,Array.from(n)))}return btoa(t.join(""))}function _(e,t=4){let s=0;for(let t=0;t<e.length;t++)s=(s<<5)-s+e.charCodeAt(t),s|=0;return Math.abs(s).toString(36).padEnd(t,"0").slice(0,t)}function O(e,t){return e.extensions[t]}var S=class{registry=new Map;middlewares=[];serializer=new u;bus;_getWorkspace;updateWorkspace;guard;_ctx;constructor(e){this._ctx=e.ctx,this._getWorkspace=e.getWorkspace,this.updateWorkspace=e.updateWorkspace,this.guard=e.guard,this.bus=e.bus}register(e,t){return this.registry.set(e,t),this}use(e){return this.middlewares.push(e),this}workspace(){return this._getWorkspace()}async dispatch(e){const t=await this.serializer.do((async()=>{if(this.guard){const t=await this.guard.authenticate({type:"command",payload:e});if(!t.ok)return g(t.error)}const t=this.registry.get(e.type);if(!t)return g({code:"INVALID_COMMAND",reason:`No reducer registered for command type: ${e.type}`});const s=this._getWorkspace(),n=await t({workspace:s,...this._ctx},e.payload);if(!n.ok)return n;let r=n.value;for(const t of this.middlewares){const n=await t({workspace:s,command:e,patch:r,...this._ctx});r=k(r,n)}return await this.updateWorkspace(r),this.bus.emit({name:"workspace:changed",payload:r}),"workspace:sync"===e.type&&this.bus.emit({name:"workspace:synced",payload:void 0}),y(r)}));if(t.error)throw t.error;return t.value}subscribe(e,t){return this.bus.subscribe(e,t)}ctx(){return{workspace:this._getWorkspace(),...this._ctx}}},T=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;const n=s.state();return this.cache.set(e,n),n}async add(e){await this.collection.create(e),this.cache.set(e.name,e)}async update(e,t){const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;await s.update(t);const n=s.state();return this.cache.set(e,n),n}async delete(e){const t=await this.collection.find({field:"name",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async getMany(e){if(0===e.length)return[];const t=[],s=[];for(const n of e){const e=this.cache.get(n);e?t.push(e):s.push(n)}if(s.length>0){const e=await this.collection.filter({operator:"or",conditions:s.map((e=>({field:"name",operator:"eq",value:e})))});for(const s of e){const e=s.state();this.cache.set(e.name,e),t.push(e)}}return t}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}referencedBy(e,t){for(const s in t.roles)if(t.roles[s].topics?.includes(e))return!0;for(const s in t.sessions)if(t.sessions[s].topics?.includes(e))return!0;for(const s in t.context)if(t.context[s].topics?.includes(e))return!0;for(const s in t.preferences)if(t.preferences[s].topics?.includes(e))return!0;return!1}summarize(e){return{topic:e.name,contextKeys:[],preferences:[],metadata:{created:e.created,updated:e.updated,entries:0}}}};function N(e,t,s,n,r,i){const o={};for(const a of t){let t=e[a];if(!t){if("add"!==r||!i)continue;t={topic:a,contextKeys:[],preferences:[],metadata:{created:(new Date).toISOString(),updated:(new Date).toISOString(),entries:0}},i.add({name:a,created:t.metadata.created,updated:t.metadata.updated})}const c=t[n],d=c.includes(s);if("add"!==r||d){if("remove"===r&&d){const e=Math.max(0,(t.metadata.entries||0)-1);o[a]={...t,[n]:c.filter((e=>e!==s)),metadata:{...t.metadata,updated:(new Date).toISOString(),entries:e}}}}else o[a]={...t,[n]:[...c,s],metadata:{...t.metadata,updated:(new Date).toISOString(),entries:(t.metadata.entries||0)+1}}}return{index:{topics:o}}}function R(e,t,s,n){return N(e,t,s,"contextKeys","add",n)}function D(e,t,s){return N(e,t,s,"contextKeys","remove")}function I(e,t,s,n){return N(e,t,s,"preferences","add",n)}function j(e,t,s){return N(e,t,s,"preferences","remove")}var E=async e=>{if(!e.patch)return;const{workspace:t,patch:s}=e,n=t.index.topics;let r={};const i=e=>{const t=e?.index?.topics;t&&(r=k(r,t))};if(s.index?.context)for(const[r,o]of Object.entries(s.index.context)){const s=t.index.context[r];if(void 0===o&&s)i(D(n,s.topics,s.key));else if(s||!o){if(s&&o){const t=s.topics??[],r=o.topics??t,a=r.filter((e=>!t.includes(e))),c=t.filter((e=>!r.includes(e)));c.length&&i(D(n,c,s.key)),a.length&&i(R(n,a,s.key,e.topics))}}else i(R(n,o.topics??[],o.key,e.topics))}if(s.index?.preferences)for(const[r,o]of Object.entries(s.index.preferences)){const s=t.index.preferences[r];if(void 0===o&&s)i(j(n,s.topics,s.id));else if(s||!o){if(s&&o){const t=s.topics??[],r=o.topics??t,a=r.filter((e=>!t.includes(e))),c=t.filter((e=>!r.includes(e)));c.length&&i(j(n,c,s.id)),a.length&&i(I(n,a,s.id,e.topics))}}else i(I(n,o.topics??[],o.id,e.topics))}return Object.keys(r).length?{index:{topics:r}}:{}},A="\n# WORKSPACE OPERATING SYSTEM\nYou are operating within a structured workspace. Your output MUST be a JSON object matching the provided schema.\nYour entire response MUST be valid JSON. Nothing else.\n".trim();function B(e){if(!e||"append"===e)return{placement:"append",label:null};if("prepend"===e)return{placement:"prepend",label:null};const[t,...s]=e.split(":");return("before"===t||"after"===t)&&s.length>0?{placement:t,label:s.join(":")}:(console.warn(`[SystemPromptAssembler] Unrecognised position "${e}", defaulting to "append".`),{placement:"append",label:null})}var C=class{build(e,t=[]){const s=[...e.system.extensions||[],...t],n=[];var r,i,o;n.push({label:"operating-system",content:A}),e.role.persona&&n.push({label:"persona",content:(r=e.role.persona,`# Persona\n${r}`)}),e.system.preferences.length>0&&n.push({label:"preferences",content:(i=e.system.preferences,`# User Preferences\n${i.map((e=>`- ${e.content}`)).join("\n")}`),metadata:{count:e.system.preferences.length}}),e.system.context.length>0&&n.push({label:"context",content:(o=e.system.context,`# Context\n${o.map((e=>{switch(e.content.kind){case"text":return`[${e.key}] ${e.content.value}`;case"json":return`[${e.key}] JSON: ${JSON.stringify(e.content.value)}`;case"blob":return`[${e.key}] Blob: ${e.content.filename??"unnamed"} (${e.content.mediaType}, ${e.content.sizeBytes} bytes)`;case"remote":return`[${e.key}] Remote: ${e.content.uri}`;default:return`[${e.key}] Unsupported context type`}})).join("\n")}`),metadata:{count:e.system.context.length}}),e.system.instructions&&n.push({label:"instructions",content:`# Instructions\n${e.system.instructions}`});const a=[...n],c=[];for(const e of s){const{position:t,...s}=e,n=B(t);if("prepend"===n.placement){c.push(s);continue}if("append"===n.placement){a.push(s);continue}const r=a.findIndex((e=>e.label===n.label));if(-1===r){console.warn(`[SystemPromptAssembler] Anchor target "${n.label}" not found in sections. Extension "${e.label}" will be appended.`),a.push(s);continue}const i="before"===n.placement?r:r+1;a.splice(i,0,s)}return[...c,...a]}join(e){return e.map((e=>e.content)).join("\n\n---\n\n")}};function q(){return new C}var $={"workspace:create":async function(e,t){const{workspaceStore:s}=e,{id:n,settings:r,project:i}=t,o=await s.get(n);return o?y({id:o.id,settings:o.settings,project:o.project}):(await s.add({id:n,settings:r,project:i}),y({id:n,settings:r,project:i,index:{roles:{},preferences:{},context:{},sessions:{},topics:{},blobs:{},tools:{},extensions:{}}}))},"workspace:sync":async function(e,t){let s={};for(const t of e.indexers){const n=await t(e);s=k(s,n)}return t&&(t.id&&(s.id=t.id),t.settings&&(s.settings=k(s.settings||{},t.settings)),t.project&&(s.project=k(s.project||{},t.project))),y(s)},"role:add":async function(e,t){const{workspace:s,roles:n}=e,r=t;return s.index.roles[r.name]?g({code:"DUPLICATE_KEY",resource:"Role",key:r.name}):(await n.add(r),y({index:{roles:{[r.name]:n.summarize(r)}}}))},"role:update":async function(e,t){const{workspace:s,roles:n}=e,{name:r,...i}=t;if(!s.index.roles[r])return g({code:"NOT_FOUND",resource:"Role",id:r});const o=await n.update(r,i);return o?y({index:{roles:{[r]:n.summarize(o)}}}):g({code:"BACKEND_ERROR",reason:`Failed to update role ${r} in store.`})},"role:delete":async function(e,t){const{workspace:s,roles:n}=e,{name:r}=t;return s.index.roles[r]?await n.delete(r)?y({index:{roles:{[r]:m}}}):g({code:"BACKEND_ERROR",reason:`Failed to delete role ${r} from store.`}):g({code:"NOT_FOUND",resource:"Role",id:r})},"preference:add":async function(e,t){const{workspace:s,preferences:n}=e,r=t;return s.index.preferences[r.id]?g({code:"DUPLICATE_KEY",resource:"Preference",key:r.id}):(await n.add(r),y({index:{preferences:{[r.id]:n.summarize(r)}}}))},"preference:update":async function(e,t){const{workspace:s,preferences:n}=e,{id:r,...i}=t;if(!s.index.preferences[r])return g({code:"NOT_FOUND",resource:"Preference",id:r});const o=await n.update(r,i);return o?y({index:{preferences:{[r]:n.summarize(o)}}}):g({code:"BACKEND_ERROR",reason:`Failed to update preference ${r} in store.`})},"preference:delete":async function(e,t){const{workspace:s,preferences:n}=e,{id:r}=t;return s.index.preferences[r]?await n.delete(r)?y({index:{preferences:{[r]:m}}}):g({code:"BACKEND_ERROR",reason:`Failed to delete preference ${r} from store.`}):g({code:"NOT_FOUND",resource:"Preference",id:r})},"context:add":async function(e,t){const{workspace:s,context:n}=e,r=t;return s.index.context[r.key]?g({code:"DUPLICATE_KEY",resource:"Context",key:r.key}):(await n.add(r),y({index:{context:{[r.key]:n.summarize(r)}}}))},"context:update":async function(e,t){const{workspace:s,context:n}=e,{key:r,...i}=t,o=s.index.context[r];if(!o)return g({code:"NOT_FOUND",resource:"Context",id:r});const a=await n.update(r,i,o.kind);return a?y({index:{context:{[r]:n.summarize(a)}}}):g({code:"BACKEND_ERROR",reason:`Failed to update context ${r} in store.`})},"context:delete":async function(e,t){const{workspace:s,context:n}=e,{key:r}=t,i=s.index.context[r];return i?await n.delete(r,i.kind)?y({index:{context:{[r]:m}}}):g({code:"BACKEND_ERROR",reason:`Failed to delete context ${r} from store.`}):g({code:"NOT_FOUND",resource:"Context",id:r})},"topic:add":async function(e,t){const{workspace:s,topics:n}=e,r=t;return s.index.topics[r.name]?g({code:"DUPLICATE_KEY",resource:"Topic",key:r.name}):(await n.add(r),y({index:{topics:{[r.name]:n.summarize(r)}}}))},"topic:update":async function(e,t){const{workspace:s,topics:n}=e,{name:r,...i}=t;if(!s.index.topics[r])return g({code:"NOT_FOUND",resource:"Topic",id:r});const o=await n.update(r,i);return o?y({index:{topics:{[r]:{metadata:{updated:o.updated}}}}}):g({code:"BACKEND_ERROR",reason:`Failed to update topic ${r} in store.`})},"topic:delete":async function(e,t){const{workspace:s,topics:n,roles:r,sessions:i}=e,{name:o,cascade:a}=t;if(!s.index.topics[o])return g({code:"NOT_FOUND",resource:"Topic",id:o});if(n.referencedBy(o,s.index)&&!a)return g({code:"INVALID_COMMAND",reason:`Topic '${o}' is referenced by other entities. Use 'cascade: true' to force deletion.`});if(a){for(const e in s.index.roles){const t=s.index.roles[e];if(t.topics?.includes(o)){const t=await r.get(e);t&&await r.update(e,{topics:t.topics.filter((e=>e!==o))})}}for(const e in s.index.sessions){const t=s.index.sessions[e];t.topics?.includes(o)&&await i.update(e,{topics:t.topics.filter((e=>e!==o))})}}return await n.delete(o)?y({index:{topics:{[o]:m}}}):g({code:"BACKEND_ERROR",reason:`Failed to delete topic ${o} from store.`})},"topic:merge":async function(e,t){const{workspace:s,topics:n,roles:r,sessions:i}=e,{source:o,target:a}=t;if(!s.index.topics[o]||!s.index.topics[a])return g({code:"NOT_FOUND",resource:"Topic",id:s.index.topics[o]?a:o});for(const e in s.index.roles){const t=s.index.roles[e];if(t.topics?.includes(o)){const t=await r.get(e);if(t){const s=t.topics.filter((e=>e!==o));s.includes(a)||s.push(a),await r.update(e,{topics:s})}}}for(const e in s.index.sessions){const t=s.index.sessions[e];if(t.topics?.includes(o)){const s=t.topics.filter((e=>e!==o));s.includes(a)||s.push(a),await i.update(e,{topics:s})}}return await n.delete(o),y({index:{topics:{[o]:m}}})},"session:create":async function(e,t){const{workspace:s,sessions:n}=e,r=t;return s.index.sessions[r.id]?g({code:"DUPLICATE_KEY",resource:"Session",key:r.id}):(await n.add(r),y({index:{sessions:{[r.id]:n.summarize(r)}}}))},"session:update":async function(e,t){const{workspace:s,sessions:n}=e,{sessionId:r,...i}=t;if(!s.index.sessions[r])return g({code:"NOT_FOUND",resource:"Session",id:r});const o=await n.update(r,i);return o?y({index:{sessions:{[r]:n.summarize(o)}}}):g({code:"BACKEND_ERROR",reason:`Failed to update session ${r} in store.`})},"session:fork":async function(e,t){const{workspace:s,sessions:n}=e,{sessionId:r,newSessionId:i,label:o}=t,a=s.index.sessions[r];if(!a)return g({code:"NOT_FOUND",resource:"Session",id:r});const c={...a,id:i,label:o||`Fork of ${a.label}`,role:t.role?t.role:a.role,topics:t.topics?t.topics:a.topics};return await n.add(c),y({index:{sessions:{[i]:n.summarize(c)}}})},"session:delete":async function(e,t){const{workspace:s,sessions:n}=e,{sessionId:r}=t;return s.index.sessions[r]?(await n.delete(r),y({index:{sessions:{[r]:m}}})):g({code:"NOT_FOUND",resource:"Session",id:r})},"session:role:switch":async function(e,t){const{workspace:s,sessions:n}=e,{sessionId:r,roleName:i}=t;return s.index.sessions[r]?(await n.update(r,{role:i}),y({index:{sessions:{[r]:{role:i}}}})):g({code:"NOT_FOUND",resource:"Session",id:r})},"session:topics:add":async function(e,t){const{workspace:s,sessions:n}=e,{sessionId:r,topics:i}=t,o=s.index.sessions[r];if(!o)return g({code:"NOT_FOUND",resource:"Session",id:r});const a=Array.from(new Set([...o.topics,...i]));return await n.update(r,{topics:a}),y({index:{sessions:{[r]:{topics:a}}}})},"session:preferences:override":async function(e,t){const{workspace:s,sessions:n}=e,{sessionId:r,preferences:i}=t;return s.index.sessions[r]?(await n.update(r,{preferences:i}),y({index:{sessions:{[r]:{preferences:i}}}})):g({code:"NOT_FOUND",resource:"Session",id:r})},"turn:add":async function(e,t){const{workspace:s,sessions:n,turns:r}=e,{sessionId:i,turn:o}=t;if(!s.index.sessions[i])return g({code:"NOT_FOUND",resource:"Session",id:i});await r.add(o);const a={id:o.id,version:o.version};return await n.update(i,{head:a}),y({index:{sessions:{[i]:{head:a}}}})},"turn:update":async function(e,t){const{workspace:s,sessions:n,turns:r}=e,{sessionId:i,turn:o}=t;if(!s.index.sessions[i])return g({code:"NOT_FOUND",resource:"Session",id:i});await r.update(o,o);const a={id:o.id,version:o.version};return await n.update(i,{head:a}),y({index:{sessions:{[i]:{head:a}}}})},"turn:edit":async function(e,t){const{workspace:s,sessions:n,turns:r}=e,{sessionId:i,turnId:o,newBlocks:a,newVersion:c,roleSnapshot:d}=t,l=s.index.sessions[i];if(!l)return g({code:"NOT_FOUND",resource:"Session",id:i});const u=l.head;let p={};if(u&&u.id===o){const e=await r.get({id:u.id,version:u.version,session:i});e&&(p={...e})}const h={...p,id:o,version:c,blocks:a,role:d??p.role,timestamp:(new Date).toISOString(),parent:p.parent,actor:p.actor||"assistant",session:i};if(await r.add(h),l.head?.id===o){const e={id:o,version:c};return await n.update(i,{head:e}),y({index:{sessions:{[i]:{head:e}}}})}return y({})},"turn:branch":async function(e,t){const{workspace:s,sessions:n,turns:r}=e,{sessionId:i,turn:o}=t;if(!s.index.sessions[i])return g({code:"NOT_FOUND",resource:"Session",id:i});await r.add(o);const a={id:o.id,version:o.version};return await n.update(i,{head:a}),y({index:{sessions:{[i]:{head:a}}}})},"turn:delete":async function(e,t){const{workspace:s,sessions:n,turns:r}=e,{sessionId:i,turnId:o,newHead:a}=t;return s.index.sessions[i]?(await r.delete({session:i,id:o,version:t.version}),a?(await n.update(i,{head:a}),y({index:{sessions:{[i]:{head:a}}}})):y({})):g({code:"NOT_FOUND",resource:"Session",id:i})},"blob:register":async function(e,t){const{blobs:s}=e,n=await s.register(t.data,t.mediaType,t.filename);if(!n.ok)return n;const r=await s.getRecord(n.value.sha256);return r?y({index:{blobs:{[r.sha256]:r}}}):g({code:"BACKEND_ERROR",reason:`Failed to retrieve registered blob record for ${n.value.sha256}`})},"blob:retain":async function(e,t){const{blobs:s}=e,n=await s.retain(t.sha256);if(!n.ok)return n;const r=await s.getRecord(t.sha256);return y({index:{blobs:{[t.sha256]:r}}})},"blob:release":async function(e,t){const{blobs:s}=e,n=await s.release(t.sha256);if(!n.ok)return n;const r=await s.getRecord(t.sha256);return y({index:{blobs:{[t.sha256]:r||m}}})},"blob:purge":async function(e,t){const{blobs:s}=e,n=await s.purge(t.sha256);return n.ok?y({index:{blobs:{[t.sha256]:m}}}):n},"blob:record_remote_id":async function(e,t){const{blobs:s}=e,{sha256:n,providerId:r,fileId:i,timestamp:o}=t,a=await s.recordRemoteId(n,r,i,o);if(!a.ok)return a;const c=await s.getRecord(n);return y({index:{blobs:{[n]:c}}})},"tool:call":async function(e,t){return y({})}},U=class{profiles;constructor(e=[]){this.profiles=new Map;for(const t of e)this.profiles.set(t.name,t)}get(e){return this.profiles.get(e)}list(e){const t=Array.from(this.profiles.values());return e?t.filter((t=>t.provider===e)):t}register(e){this.profiles.set(e.name,e)}},z=[{type:"text",emittable:!0,description:["## Block: `text`","Primary communication block. Use for all conversational responses, explanations, and prose.","A response may contain multiple `text` blocks interleaved with other block types."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["text"]},text:{type:"string",description:"The raw markdown or plain text content of the response."}},required:["type","text"]}},{type:"summary",emittable:!0,description:["## Block: `summary`","Context compression block. Replaces older conversation history with a concise digest."].join("\n"),rules:["Only emit when explicitly instructed by the system to summarise.","Never emit more than one summary block per turn.","Preserve key decisions, outcomes, and unresolved questions.","Do not summarise the current turn — only prior history."],schema:{type:"object",properties:{type:{type:"string",enum:["summary"]},text:{type:"string",description:"A concise summary replacing older conversation context."}},required:["type","text"]}},{type:"thinking",emittable:!1,description:["## Block: `thinking`","Internal chain-of-thought produced by the model before its final response.","Injected by the workspace from provider reasoning tokens — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["thinking"]},thinking:{type:"string",description:"The internal reasoning text produced before the final response."}},required:["type","thinking"]}},{type:"tool:use",emittable:!1,description:["## Block: `tool:use`","Captures a model request to execute a registered tool.","Constructed by the workspace from the provider native function-call response — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["tool:use"]},name:{type:"string",description:"The exact registered name of the tool to execute."},input:{type:"object",description:"The parameter arguments for the tool execution.",additionalProperties:!0}},required:["type","name","input"]}},{type:"tool:result",emittable:!1,description:["## Block: `tool:result`","Contains the output of a tool execution, including any errors.","Injected by the workspace after a tool runs — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["tool:result"]},useId:{type:"string",description:"The UUID of the ToolUseBlock that triggered this execution."},content:{oneOf:[{type:"string"},{type:"object",additionalProperties:!0}],description:"The serialized output of the tool, or a structured JSON response."},isError:{type:"boolean",description:"True if the tool execution resulted in an error."}},required:["type","useId","content"]}},{type:"image",emittable:!1,description:["## Block: `image`","An image asset attached to a turn, resolved from the workspace blob store.","Constructed by the workspace from user uploads — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["image"]},altText:{type:"string",description:"Accessible description of the image content."}},required:["type"]}},{type:"document",emittable:!1,description:["## Block: `document`","A document asset (PDF, DOCX, etc.) attached to a turn, resolved from the workspace blob store.","Constructed by the workspace from user uploads — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["document"]},title:{type:"string",description:"Human-readable title or filename of the document."}},required:["type"]}},{type:"role:transition",emittable:!1,description:["## Block: `role:transition`","Marks that the active session persona has switched from one role to another.","Emitted by the workspace when the active persona changes — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["role:transition"]},previousRole:{type:"string",description:"The name of the role the session is leaving."},newRole:{type:"string",description:"The name of the role the session is adopting."}},required:["type","newRole"]}}];function M(e,t){let s=e.filter((e=>e.emittable));if(!t)return s;if(t.only&&t.only.length>0){const e=new Set(t.only);return s.filter((t=>e.has(t.type)))}if(t.exclude&&t.exclude.length>0){const e=new Set(t.exclude);return s.filter((t=>!e.has(t.type)))}return s}var F=class{store=new Map;constructor(){for(const e of z)this.store.set(e.type,e)}register(e){if(this.store.has(e.type))throw new Error(`[BlockRegistry] Block type "${e.type}" is already registered. Use update() to modify it.`);this.store.set(e.type,{...e,emittable:!0,rules:[]})}unregister(e){if(!this.store.has(e))throw new Error(`[BlockRegistry] Cannot unregister unknown block type "${e}".`);this.store.delete(e)}update(e,t){const s=this.store.get(e);s?this.store.set(e,{...s,...t,type:e}):this.store.set(e,{emittable:!0,rules:[],...t,type:e})}get(e){return this.store.get(e)}list(){return Array.from(this.store.values())}isType(e,t){return e.type===t}guard(e){return t=>t.type===e}schema(e){return{type:"object",description:"The model's structured response, containing an ordered sequence of content blocks.",properties:{blocks:{type:"array",description:"An ordered array of content blocks comprising the model's response.",items:{anyOf:M(Array.from(this.store.values()),e).map((e=>e.schema))}}},required:["blocks"]}}description(e){return["# BLOCK TYPES & USAGE RULES","","Your response MUST be a JSON object with a `blocks` array.","Each element of `blocks` must be one of the following types:","",M(Array.from(this.store.values()),e).map((e=>{const t=[e.description];return e.rules.length>0&&(t.push("**Rules:**"),t.push(...e.rules.map((e=>`- ${e}`)))),t.join("\n")})).join("\n\n"),"","## GLOBAL CONSTRAINTS","","- Output must be **valid JSON only** — no prose before or after the JSON object.","- Responses may contain multiple blocks. Blocks are rendered in order.","- **Do NOT generate IDs.** The workspace is solely responsible for block ID assignment.","- Do not infer or invent fields not defined in the block schemas above."].join("\n")}rules(e){const t=M(Array.from(this.store.values()),e);return Object.fromEntries(t.map((e=>[e.type,[...e.rules]])))}setRules(e,t){const s=this.store.get(e);if(!s)throw new Error(`[BlockRegistry] Cannot set rules on unknown block type "${e}".`);this.store.set(e,{...s,rules:t})}parse(e,s){const n=this.store.get(e.type);if(!n)return console.warn(`[BlockRegistry] parse() received unknown block type "${e.type}". Returning null.`),null;if(s&&n.mappings?.[s])return n.mappings[s].from(e);const{id:r,...i}=e;return{id:t(),...i}}create(e,s){if(!this.store.has(e))throw new Error(`[BlockRegistry] Cannot create block of unknown type "${e}".`);return{...s,id:t(),type:e}}clone(e,s){return{...structuredClone(e),...s,id:t()}}},P=class{store=new Map;constructor(){this.registerDefaults()}registerDefaults(){this.register({kind:"text",target:"system",render:e=>({id:e.key,type:"text",text:e.content.value}),toString:e=>e.content.value,summarize:e=>({key:e.key,kind:"text",topics:e.topics,timestamp:e.timestamp,preview:e.content.value.slice(0,100)})}),this.register({kind:"json",target:"system",render:e=>({id:e.key,type:"text",text:JSON.stringify(e.content.value,null,2)}),toString:e=>JSON.stringify(e.content.value),summarize:e=>({key:e.key,kind:"json",topics:e.topics,timestamp:e.timestamp,preview:"JSON Data"})}),this.register({kind:"blob",target:"transcript",render:e=>{const{sha256:t,mediaType:s,sizeBytes:n,filename:r}=e.content,i={sha256:t,mediaType:s,sizeBytes:n,filename:r};return s.startsWith("image/")?{id:e.key,type:"image",ref:i}:{id:e.key,type:"document",ref:i,title:r}},toString:e=>e.content.filename||"unnamed blob",summarize:e=>({key:e.key,kind:"blob",topics:e.topics,timestamp:e.timestamp,mime:e.content.mediaType,size:e.content.sizeBytes,preview:e.content.filename})})}register(e){if(this.store.has(e.kind))throw new Error(`[ContextRegistry] Context kind "${e.kind}" is already registered.`);this.store.set(e.kind,e)}get(e){return this.store.get(e)}list(){return Array.from(this.store.values())}},K="__system__",L=class{constructor(e,s,n){this._actor=e,this._turn=n?JSON.parse(JSON.stringify(n)):{id:t(),session:s,version:0,actor:this._actor,blocks:[],timestamp:(new Date).toISOString(),role:void 0}}_turn;addText(e){const s={id:t(),type:"text",text:e};return this._turn.blocks.push(s),this}addImage(e,s){const n={id:t(),type:"image",ref:e,altText:s};return this._turn.blocks.push(n),this}addDocument(e,s){const n={id:t(),type:"document",ref:e,title:s};return this._turn.blocks.push(n),this}addToolUse(e,s){const n={id:t(),type:"tool:use",name:e,input:s};return this._turn.blocks.push(n),this}addToolResult(e,s,n){const r={id:t(),type:"tool:result",useId:e,content:s,isError:n};return this._turn.blocks.push(r),this}addSummary(e){const s={id:t(),type:"summary",text:e};return this._turn.blocks.push(s),this}addRoleTransition(e,s){const n={id:t(),type:"role:transition",previousRole:e,newRole:s};return this._turn.blocks.push(n),this}addThinking(e){const s={id:t(),type:"thinking",thinking:e};return this._turn.blocks.push(s),this}addBlock(e){return e.id||(e.id=t()),this._turn.blocks.push(e),this}deleteBlock(e){return this._turn.blocks=this._turn.blocks.filter((t=>t.id!==e)),this}editTextBlock(e,t){const s=this._turn.blocks.findIndex((t=>t.id===e));if(-1===s)throw new Error(`Block with ID ${e} not found.`);const n=this._turn.blocks[s];if("text"!==n.type)throw new Error(`Block with ID ${e} is not a TextBlock.`);return this._turn.blocks[s]={...n,text:t},this}withId(e){return this._turn.id=e,this}withVersion(e){return this._turn.version=e,this}withTimestamp(e){return this._turn.timestamp=e,this}withParent(e){return this._turn.parent=e,this}withRoleSnapshot(e){return this._turn.role=e,this}build(){return JSON.parse(JSON.stringify(this._turn))}},V=class{constructor(e,t){this.turnStore=e,this.sessionStore=t}async loadAllTurns(e){return this.turnStore.listBySession(e)}async loadHead(e){const t=await this.sessionStore.get(e);return t?.head??null}},W=class e{constructor(e,t){this.nodes=e,this._head=t}static async build(t,s){const[n,r]=await Promise.all([s.loadAllTurns(t),s.loadHead(t)]),i=function(e,t){const s=function(e,t){if(!t)return new Set;const s=new Map;for(const t of e)s.set(`${t.id}:${t.version}`,t);const n=new Set;let r=t;for(;r;){const e=`${r.id}:${r.version}`;if(n.has(e))break;n.add(e);const t=s.get(e);if(!t)break;r=t.parent}return n}(e,t),n={},r={};for(const t of e){n[t.id]||(n[t.id]={id:t.id,versions:{},activeVersion:t.version,actor:t.actor,blocks:t.blocks,timestamp:t.timestamp,roleSnapshot:t.role,parent:t.parent,children:{}},r[t.id]=new Set);const e=n[t.id];e.versions[t.version]=t;const i=s.has(`${t.id}:${t.version}`),o=s.has(`${t.id}:${e.activeVersion}`);if(i&&(!o||t.version>=e.activeVersion)&&(e.activeVersion=t.version,e.blocks=t.blocks,e.timestamp=t.timestamp,e.roleSnapshot=t.role,e.parent=t.parent),t.parent){const e=`${t.parent.id}:${t.parent.version}`;if(r[t.parent.id]||(r[t.parent.id]=new Set),!r[t.parent.id].has(e+":"+t.id)){r[t.parent.id].add(e+":"+t.id),n[t.parent.id]||(n[t.parent.id]={id:t.parent.id,versions:{},activeVersion:t.parent.version,actor:"user",blocks:[],timestamp:"",roleSnapshot:void 0,children:{}});const s=n[t.parent.id];s.children[t.parent.version]||(s.children[t.parent.version]=[]),s.children[t.parent.version].push(t.id)}}}return n}(n,r);return new e(i,r)}head(){return this._head}chain(){if(!this._head)return[];const e=[];let t=this._head.id;for(;t;){const s=this.nodes[t];if(!s)break;e.push(s),t=s.parent?.id??null}return e.reverse()}getTurnSiblings(e){const t=this.nodes[e];if(!t)return[];if(!t.parent)return Object.values(this.nodes).filter((e=>!e.parent));const s=this.nodes[t.parent.id];if(!s)return[t];const n=s.children[t.parent.version];return n?n.map((e=>this.nodes[e])).filter((e=>!!e)):[t]}branchInfo(e){const t=this.nodes[e];if(!t)return{versions:[],currentIndex:-1,total:0,hasPrev:!1,hasNext:!1};const s=Object.keys(t.versions).map(Number).sort(((e,t)=>e-t)),n=s.indexOf(t.activeVersion);return{versions:s,currentIndex:n,total:s.length,hasPrev:n>0,hasNext:n<s.length-1}}graph(){return{...this.nodes}}};var J=class{constructor(e){this.manager=e}get workspace(){return this.manager.workspace()}roles(){return this.manager.ctx().roles.list()}role(e){return this.manager.ctx().roles.get(e)}async createRole(e,t,s,n,r=[]){if(this.workspace.index.roles[e])return g({code:"DUPLICATE_KEY",resource:"role",key:e});const i={name:e,label:t,description:n,persona:s,preferences:r,topics:[]};return this.manager.dispatch({type:"role:add",payload:i,timestamp:(new Date).toISOString()})}async updateRole(e,t){return this.workspace.index.roles[e]?this.manager.dispatch({type:"role:update",payload:{name:e,...t},timestamp:(new Date).toISOString()}):g({code:"NOT_FOUND",resource:"role",id:e})}async deleteRole(e){const t=this.workspace;if(!t.index.roles[e])return g({code:"NOT_FOUND",resource:"role",id:e});return Object.values(t.index.sessions).some((t=>t.role===e))?g({code:"INVALID_COMMAND",reason:`Cannot delete role "${e}" — it is still referenced by one or more sessions`}):this.manager.dispatch({type:"role:delete",payload:{name:e},timestamp:(new Date).toISOString()})}async addPreference(e,t){const s={id:crypto.randomUUID(),content:e,topics:t,timestamp:(new Date).toISOString()};return this.manager.dispatch({type:"preference:add",payload:s,timestamp:s.timestamp})}preferences(){return this.manager.ctx().preferences.list()}async addContext(e,t,s,n){const r={key:e,topics:s,content:t,timestamp:(new Date).toISOString(),metadata:n};return this.manager.dispatch({type:"context:add",payload:r,timestamp:r.timestamp})}context(){return this.manager.ctx().context.list()}async registerBlob(e,t,s){const n=await this.manager.dispatch({type:"blob:register",payload:{data:e,mediaType:t,filename:s},timestamp:(new Date).toISOString()});if(!n.ok)return g(n.error);const r=n.value,i=r?.index?.blobs;if(!i)return g({code:"BACKEND_ERROR",reason:"Blob registration succeeded but no blobs patch returned"});const o=Object.keys(i)[0];if(!o)return g({code:"BACKEND_ERROR",reason:"No SHA256 in patch"});const a=i[o];if(!a)return g({code:"BACKEND_ERROR",reason:"Blob record missing"});return y({sha256:o,ref:{sha256:o,mediaType:a.mediaType,sizeBytes:a.sizeBytes,filename:a.filename,previewUrl:a.previewUrl}})}},G=class e{constructor(e,t,s,n){this._id=e,this.manager=t,this.processor=s,this.turnRepository=n,this.workspace=new J(t),this.unsubscribe=t.subscribe("workspace:synced",(()=>this.sync()))}workspace;_role=void 0;_preferences=[];tree;unsubscribe;static async create(t,s,n){s.ctx().workspace;const r=new V(s.ctx().turns,s.ctx().sessions),i=new e(t,s,n,r);return await i.sync(),i}async sync(){await this._setRole(),await this._setPreference(),await this.refreshTurnTree()}close(){this.unsubscribe?.()}async _setRole(){const e=this.meta(),t=await this.manager.ctx().roles.get(e.role);t&&(this._role=t)}async _setPreference(){const e=this.meta();this._preferences=await this.manager.ctx().preferences.load(e.preferences)}id(){return this._id}ws(){return this.manager.workspace()}meta(){return this.ws().index.sessions[this._id]}label(){return this.meta()?.label}role(){return this._role}topics(){return this.meta()?.topics??[]}preferences(){return this._preferences}head(){return this.meta()?.head??null}turns(){return this.tree.chain()}async siblings(e){return this.tree.getTurnSiblings(e)}async branchInfo(e){return this.tree.branchInfo(e)}async getTurn(e){return this.tree.graph()[e]}async rename(e){return this.meta()?this.dispatch({type:"session:update",payload:{sessionId:this._id,label:e},timestamp:(new Date).toISOString()}):g({code:"NOT_FOUND",resource:"session",id:this._id})}async setTopics(e){return this.meta()?this.dispatch({type:"session:update",payload:{sessionId:this._id,topics:e},timestamp:(new Date).toISOString()}):g({code:"NOT_FOUND",resource:"session",id:this._id})}async addTopics(e){return this.meta()?this.dispatch({type:"session:topics:add",payload:{sessionId:this._id,topics:e},timestamp:(new Date).toISOString()}):g({code:"NOT_FOUND",resource:"session",id:this._id})}async setPreferences(e){if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});const t=await this.dispatch({type:"session:preferences:override",payload:{sessionId:this._id,preferences:e},timestamp:(new Date).toISOString()});return t.ok&&await this._setPreference(),t}async fork(e,t,s,n){return this.meta()?this.dispatch({type:"session:fork",payload:{sessionId:this._id,newSessionId:e,label:t,role:s,topics:n},timestamp:(new Date).toISOString()}):g({code:"NOT_FOUND",resource:"session",id:this._id})}async dispatch(e){return this.manager.dispatch(e)}async switchRole(e){const t=this.ws();if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});if(e!==K&&!t.index.roles[e])return g({code:"NOT_FOUND",resource:"role",id:e});const s=await this.dispatch({type:"session:update",payload:{sessionId:this._id,role:e},timestamp:(new Date).toISOString()});return s.ok&&await this._setRole(),s}async addTurn(e){if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});const t={...e,session:this._id,version:e.version??0,parent:!e.parent&&this.head()?this.head():void 0},s=await this.dispatch({type:"turn:add",payload:{sessionId:this._id,turn:t},timestamp:t.timestamp});return s.ok&&await this.refreshTurnTree(),s}async recordUserTurn(e){return this.meta()?this.addTurn(e):g({code:"NOT_FOUND",resource:"session",id:this._id})}async recordAssistantTurn(e,t){const s=this.ws();if(!s)return g({code:"NOT_FOUND",resource:"workspace",id:"current"});if(!s.index.sessions[this._id])return g({code:"NOT_FOUND",resource:"session",id:this._id});const n=this.processor.process(e,this._id);let r={};const i=[];for(const e of n){const t=await this.manager.dispatch(e);if(t.ok)r=k(r,t.value);else{if("PERMISSION_DENIED"!==t.error.code||e.synthetic)return t;{const t=this.describeCommand(e);i.push({cmd:e,description:t})}}}const o=await this.addTurn(e);if(!o.ok)return o;if(r=k(r,o.value),t&&i.length>0){const e=this.buildDenialTurn(i),t=await this.addTurn(e);t.ok&&(r=k(r,t.value))}return y(r)}buildDenialTurn(e){const t=new L("user",this._id);for(const s of e)t.addText(`[System] User denied: ${s.description}.`);return t.build()}describeCommand(e){return"tool:call"===e.type?`tool execution: ${e.payload.tool}`:`command: ${e.type}`}async editTurn(e,t,s){if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});const n=this.tree.graph()[e];if(!n)return g({code:"NOT_FOUND",resource:"turn",id:e});const r=n.versions[n.activeVersion],i=n.activeVersion+1,o=await this.dispatch({type:"turn:edit",payload:{sessionId:this._id,turnId:e,newBlocks:t,roleSnapshot:s??r.role,newVersion:i},timestamp:(new Date).toISOString()});return o.ok&&(await this.dispatch({type:"session:update",payload:{sessionId:this._id,head:{id:e,version:i}},timestamp:(new Date).toISOString()}),await this.refreshTurnTree()),o}async branch(e){if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});if(!e.parent)return g({code:"INVALID_COMMAND",reason:"branch requires turn.parent to be set"});const t=await this.dispatch({type:"turn:branch",payload:{sessionId:this._id,turn:{...e,session:this._id}},timestamp:e.timestamp});return t.ok&&await this.refreshTurnTree(),t}async deleteTurn(e,t,s){if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});const n=this.tree.graph();if(!n[e]?.versions[t])return g({code:"NOT_FOUND",resource:"turn version",id:`${e}:${t}`});const r=await this.dispatch({type:"turn:delete",payload:{sessionId:this._id,turnId:e,version:t,newHead:s},timestamp:(new Date).toISOString()});return r.ok&&await this.refreshTurnTree(),r}async switchVersionLeft(e){return this.switchVersion(e,-1)}async switchVersionRight(e){return this.switchVersion(e,1)}async switchVersion(e,t){if(!this.ws())return g({code:"NOT_FOUND",resource:"workspace",id:"current"});if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});const s=this.tree.graph()[e];if(!s)return g({code:"NOT_FOUND",resource:"turn",id:e});const n=Object.keys(s.versions).map(Number).sort(((e,t)=>e-t)),r=n.indexOf(s.activeVersion);if(-1===r)return g({code:"INVALID_COMMAND",reason:"Active version not found"});const i=r+t;if(i<0||i>=n.length)return g({code:"INVALID_COMMAND",reason:`No ${t<0?"previous":"next"} version available for turn ${e}`});const o=n[i],a=this.findSubtreeTip(this.tree.graph(),e,o),c=await this.dispatch({type:"session:update",payload:{sessionId:this._id,head:a},timestamp:(new Date).toISOString()});return c.ok&&await this.refreshTurnTree(),c}async snapshot(){const e=this,t=e.meta();if(!t)return;const s=e.ws(),n=e._role;if(!n)return;const r=await e.manager.ctx().context.getByTopics(s.index,t.topics),i=Array.from(new Set([...n.preferences,...t.preferences])),o=i.length>0?await e.manager.ctx().preferences.load(i):e._preferences,a=e.tree.chain().map((e=>e.versions[e.activeVersion])).filter((e=>!!e)),c=[...a].reverse().find((e=>"user"===e.actor));return{id:e._id,meta:t,role:n,preferences:o,context:r,model:t.metadata?.model,transcript:a,topics:t.topics,instructions:s.settings?.prompt,constraints:{role:n.constraints,session:t.constraints,turn:c?.constraints}}}async refreshTurnTree(){this.tree=await W.build(this._id,this.turnRepository)}findSubtreeTip(e,t,s){let n=t,r=s;for(;;){const t=e[n];if(!t)break;const s=t.children[r];if(!s||0===s.length)break;const i=s[0],o=e[i];if(!o)break;n=i,r=o.activeVersion}return{id:n,version:r}}},Y=class{constructor(e,t){this.manager=e,this.processor=t}openOnce=new Map;async open(e){let t=this.openOnce.get(e);t||(t=new l,this.openOnce.set(e,t));const s=await t.do((async()=>{if(!this.manager.workspace().index.sessions[e])throw new Error(`Session ${e} not found in workspace index`);return G.create(e,this.manager,this.processor)}));if(s.error)throw s.error;return s.value}close(e){this.openOnce.delete(e)}async delete(e){const t=await this.manager.dispatch({type:"session:delete",payload:{sessionId:e},timestamp:(new Date).toISOString()});if(t.ok)return this.close(e),t.value=void 0,t;throw t.error}async has(e){return!this.manager.workspace().index.sessions[e]}async create(e){const s=t(),n=await this.manager.dispatch({type:"session:create",payload:{id:s,label:e.label,role:e.role,topics:e.topics,preferences:e.preferences??[],metadata:{created:(new Date).toISOString()}},timestamp:(new Date).toISOString()});if(n.ok)return this.open(s);throw n.error}list(){return Object.values(this.manager.workspace().index.sessions)}metadata(e){return this.manager.workspace().index.sessions[e]}},H=class{constructor(e,t,s){this.storage=e,this.cache=t,this.bus=s}async register(e,t,s){const n=await x(e),r=await this.getRecord(n);if(r){const e={...r,refCount:r.refCount+1,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(e),this.cache.set(n,e),y(this.reference(e))}const i={sha256:n,mediaType:t,sizeBytes:e.byteLength,filename:s,refCount:1,remoteIds:{},createdAt:(new Date).toISOString(),lastUsedAt:(new Date).toISOString()};return this.storage.registerBlob?await this.storage.registerBlob(i,e):(await this.storage.storeBytes(n,e),await this.storage.saveRecord(i)),this.cache.set(n,i),this.bus.emit({name:"blobs:changed",payload:{sha256:n,record:i}}),y(this.reference(i))}async retain(e){const t=await this.getRecord(e);if(!t)return g({code:"NOT_FOUND",resource:"blob",id:e});const s={...t,refCount:t.refCount+1,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(s),this.cache.set(e,s),y(void 0)}async release(e){const t=await this.getRecord(e);if(!t)return g({code:"NOT_FOUND",resource:"blob",id:e});const s=Math.max(0,t.refCount-1),n={...t,refCount:s,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(n),this.cache.set(e,n),y(void 0)}async purge(e){return await this.storage.deleteBytes(e),await this.storage.deleteRecord(e),this.cache.delete(e),this.bus.emit({name:"blobs:changed",payload:{sha256:e}}),y(void 0)}async recordRemoteId(e,t,s,n){const r=await this.getRecord(e);if(!r)return g({code:"NOT_FOUND",resource:"blob",id:e});const i={...r,remoteIds:{...r.remoteIds,[t]:{id:s,timestamp:n||(new Date).toISOString()}},lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(i),this.cache.set(e,i),this.bus.emit({name:"blobs:changed",payload:{sha256:e,record:i}}),y(void 0)}async getRecord(e){const t=this.cache.get(e);if(t)return t;const s=await this.storage.loadRecord(e);return s&&this.cache.set(e,s),s}async getAllRecords(){const e=await this.storage.listRecords(),t={};for(const s of e)t[s.sha256]=s,this.cache.set(s.sha256,s);return t}reference(e){return{sha256:e.sha256,mediaType:e.mediaType,sizeBytes:e.sizeBytes,filename:e.filename}}async resolve(e,t){const s=await this.getRecord(e.sha256);if(!s)return y(null);if(t){const e=s.remoteIds[t];if(e)return y({kind:"remote",sha256:s.sha256,mediaType:s.mediaType,fileId:e.id,providerId:t,timestamp:e.timestamp});const n=await this.storage.loadBytes(s.sha256);return y(n?{kind:"inline",sha256:s.sha256,mediaType:s.mediaType,data:n}:null)}const n=await this.storage.loadBytes(s.sha256);return y(n?{kind:"inline",sha256:s.sha256,mediaType:s.mediaType,data:n}:null)}async resolveMany(e,t){const s=new Map;for(const n of e){const e=await this.resolve(n,t);if(!e.ok)return g(e.error);if(null===e.value)return g({code:"BLOB_ERROR",reason:`Unable to resolve blob ${n.sha256}${t?` with adapter ${t}`:""}`});s.set(n.sha256,e.value)}return y(s)}},X=class{constructor(e,t,s){this.collection=e,this.cache=t,this.registry=s}delegates=new Map;registerDelegate(e,t){this.delegates.set(e,t)}async get(e,t){const s=this.cache.get(e);if(s)return s;if(t){const s=this.delegates.get(t);if(s){const t=await s.get(e);return t&&this.cache.set(e,t),t}}const n=await this.collection.find({field:"key",operator:"eq",value:e});if(!n)return null;const r=n.state();return this.cache.set(e,r),r}async add(e){const t=this.delegates.get(e.content.kind);t?await t.add(e):await this.collection.create(e),this.cache.set(e.key,e)}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"}),t=((await e.next()).value||[]).map((e=>e.state()));for(const e of this.delegates.values()){const s=await e.list();t.push(...s)}return t}async update(e,t,s){if(s){const n=this.delegates.get(s);if(n){const s=await n.update(e,t);return s&&this.cache.set(e,s),s}}const n=await this.collection.find({field:"key",operator:"eq",value:e});if(!n)return null;await n.update(t);const r=n.state();return this.cache.set(e,r),r}async delete(e,t){if(t){const s=this.delegates.get(t);if(s){const t=await s.delete(e);return t&&this.cache.delete(e),t}}const s=await this.collection.find({field:"key",operator:"eq",value:e});if(!s)return!1;const n=await s.delete();return n&&this.cache.delete(e),n}async getByTopics(e,t){const s=new Map;for(const n of t){const t=e.topics[n];t&&t.contextKeys.forEach((t=>{const n=e.context[t],r=n?.kind||"unknown";s.has(r)||s.set(r,new Set),s.get(r).add(t)}))}if(0===s.size)return[];const n=[],r=[];for(const[e,t]of s.entries()){if(this.delegates.get(e))for(const s of t){const t=await this.get(s,e);t&&n.push(t)}else t.forEach((e=>r.push(e)))}if(r.length>0){const e=[];for(const t of r){const s=this.cache.get(t);s?n.push(s):e.push(t)}if(e.length>0){const t=await this.collection.filter({operator:"or",conditions:e.map((e=>({field:"key",operator:"eq",value:e})))});for(const e of t){const t=e.state();this.cache.set(t.key,t),n.push(t)}}}return n.sort(((e,t)=>new Date(t.timestamp).getTime()-new Date(e.timestamp).getTime()))}summarize(e){const t=this.registry?.get(e.content.kind);return t?t.summarize(e):{kind:e.content.kind,key:e.key,topics:e.topics,timestamp:e.timestamp,metadata:e.metadata}}},Q=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;const n=s.state();return this.cache.set(e,n),n}async add(e){await this.collection.create(e),this.cache.set(e.id,e)}async update(e,t){const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;await s.update(t);const n=s.state();return this.cache.set(e,n),n}async delete(e){const t=await this.collection.find({field:"id",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async load(e){if(0===e.length)return[];const t=[],s=[];for(const n of e){const e=this.cache.get(n);e?s.push(e):t.push(n)}if(t.length>0){const e=await this.collection.filter({operator:"or",conditions:t.map((e=>({field:"id",operator:"eq",value:e})))});for(const t of e){const e=t.state();this.cache.set(e.id,e),s.push(e)}}return s}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return{id:e.id,topics:e.topics,timestamp:e.timestamp,snippet:e.content.slice(0,100)}}},Z=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;const n=s.state();return this.cache.set(e,n),n}async add(e){await this.collection.create(e),this.cache.set(e.name,e)}async update(e,t){const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;await s.update(t);const n=s.state();return this.cache.set(e,n),n}async delete(e){const t=await this.collection.find({field:"name",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return{name:e.name,label:e.label,description:e.description,preferences:e.preferences?.length??0,topics:e.topics??[],constraints:e.constraints}}},ee=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;const n=s.state();return this.cache.set(e,n),n}async add(e){await this.collection.create(e),this.cache.set(e.id,e)}async update(e,t){const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;await s.update(t);const n=s.state();return this.cache.set(e,n),n}async delete(e){const t=await this.collection.find({field:"id",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return e}},te=class{constructor(e,t){this.collection=e,this.cache=t}key({id:e,session:t,version:s}){return`${t}:${s}:${e}`}async find({id:e,session:t,version:s},n=!0){const r=this.key({id:e,session:t,version:s});this.cache.get(r)&&this.cache.get(r);const i=await this.collection.find({operator:"and",conditions:[{field:"id",operator:"eq",value:e},{field:"session",operator:"eq",value:t},{field:"version",operator:"eq",value:s}]});return i?(n&&this.cache.set(r,i),i):null}async get(e){return this.find(e)}async add(e){const t=await this.collection.create(e);this.cache.set(this.key(e),t)}async update(e,t){const s=await this.find(e);return s?(await s.update(t),s.state()):null}async listBySession(e){return(await this.collection.filter({field:"session",operator:"eq",value:e})).map((e=>e.state()))}async delete(e){const t=await this.find(e,!1);if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(this.key(e)),s}},se=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;const n=s.state();return this.cache.set(e,n),n}async add(e){await this.collection.create(e),this.cache.set(e.id,e)}async update(e,t){const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;await s.update(t);const n=s.state();return this.cache.set(e,n),n}async delete(e){const t=await this.collection.find({field:"id",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async list(){const e=await this.collection.list({limit:100,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return e}},ne=class{cache;maxSize;constructor(e){this.cache=new Map,this.maxSize=e}get(e){const t=this.cache.get(e);return void 0!==t&&(this.cache.delete(e),this.cache.set(e,t)),t}set(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.maxSize){const e=this.cache.keys().next().value;void 0!==e&&this.cache.delete(e)}this.cache.set(e,t)}has(e){return this.cache.has(e)}delete(e){this.cache.delete(e)}clear(){this.cache.clear()}},re=(e={})=>({id:t(),label:"New Conversation",role:"assistant-default",topics:[],preferences:[],metadata:{created:(new Date).toString(),updated:(new Date).toString()},...e,head:e.head?e.head:void 0}),ie=(e={},s)=>({id:e.id??t(),version:e.version??0,session:e.session??s?.id??t(),actor:"user",blocks:[{id:t(),type:"text",content:"Hello, world!"}],timestamp:(new Date).toString(),role:s?.role??"default",...e,parent:e.parent?e.parent:void 0}),oe=(e={})=>({id:e.id??t(),settings:k({language:"en-US",defaultRole:void 0,prompt:void 0},e.settings),project:k({id:t(),name:"Unnamed Project"},e.project),index:k({roles:{},preferences:{},context:{},sessions:{},topics:{},blobs:{},tools:{},extensions:{}},e.index)});function ae(e,t,s){const n=new Set([...Object.keys(e??{}),...Object.keys(t??{}),...Object.keys(s??{})]),r={};for(const i of n){const n=e?.[i]??{},o=t?.[i]??{},a=s?.[i]??{};r[i]={temperature:a.temperature??o.temperature??n.temperature,tokens:{max:a.tokens?.max??o.tokens?.max??n.tokens?.max,stops:a.tokens?.stops??o.tokens?.stops??n.tokens?.stops,thought:a.tokens?.thought??o.tokens?.thought??n.tokens?.thought}}}return r}function ce(e,s,n){return{id:t(),session:e,version:0,actor:s,blocks:n,timestamp:(new Date).toISOString()}}var de=class{constructor(e,t,s){this.contextRegistry=e,this.retriever=t,this.summarizer=s}async build(e,s,n={}){const r=[],{resolved:i}=function(e){const t=[],s=new Map;for(const n of e)for(const e of n.topics){const r=s.get(e);if(!r){s.set(e,n);continue}const i=new Date(r.timestamp).getTime(),o=new Date(n.timestamp).getTime();o>i?(t.push({topic:e,kept:n.id,dropped:r.id}),s.set(e,n)):i>o&&t.push({topic:e,kept:r.id,dropped:n.id})}const n=new Map,r=new Map;for(const t of e)r.set(t.id,t.topics.length);for(const e of t)n.set(e.dropped,(n.get(e.dropped)??0)+1);const i=new Set;for(const t of e){const e=n.get(t.id)??0,s=r.get(t.id)??0;s>0&&e>=s&&i.add(t.id)}return{resolved:e.filter((e=>!i.has(e.id))),conflicts:Array.from(new Map(t.map((e=>[`${e.topic}:${e.dropped}`,e]))).values())}}(e.preferences),o=function(e,t=3){return e.filter((e=>"user"===e.actor)).slice(-t).flatMap((e=>e.blocks.filter((e=>"text"===e.type)).map((e=>e.text)).filter(Boolean)))}(e.transcript),a=this.retriever.rank({entries:e.context,recentMessages:o,topics:e.topics,config:n.retrieverConfig}),c=[],d=[];for(const e of a){const t=this.contextRegistry.get(e.content.kind);if(!t){r.push(`No ContextDefinition found for kind: ${e.content.kind}`);continue}const s=t.render(e),n=Array.isArray(s)?s:[s];"system"===t.target?c.push({label:`context:${e.content.kind}:${e.key}`,content:n.map((t=>"text"===t.type?t.text:`[${e.content.kind}] ${JSON.stringify(t,null,2)}`)).join("\n"),position:"after:context"}):d.push(...n)}let l=e.transcript;if(n.summarize&&this.summarizer&&l.length>0){const s=2e3;try{const n=await this.summarizer.summarize(l,s),r=[];n.summary&&r.push(ce(e.id,"system",[{id:t(),type:"summary",text:n.summary}])),l=[...r,...n.remaining]}catch(e){r.push(`Summarizer failed: ${e instanceof Error?e.message:String(e)}`)}}const u=[];d.length>0&&u.push(ce(e.id,"user",d));const p=function(e,s){const n=[];let r=null,i=!1;for(const o of e)"user"===o.actor&&o.role&&(i&&o.role!==r&&n.push(ce(s,"system",[{id:t(),type:"role:transition",previousRole:r??void 0,newRole:o.role}])),r=o.role,i=!0),n.push(o);return n}(l,e.id),h=[...u,...p],m=function(e,t){const s=new Map;for(const t of e)if("blob"===t.content.kind){const{sha256:e,mediaType:n,sizeBytes:r,filename:i,previewUrl:o}=t.content;s.has(e)||s.set(e,{sha256:e,mediaType:n,sizeBytes:r,filename:i,previewUrl:o})}for(const e of t)for(const t of e.blocks)if("image"===t.type||"document"===t.type){const e=t.ref;e&&!s.has(e.sha256)&&s.set(e.sha256,e)}return s}(a,h);return y({session:e.id,model:e.model,system:{persona:e.role.persona,instructions:e.instructions,preferences:i,context:[],extensions:c},transcript:h,blobs:m,role:e.role,constraints:ae(e.constraints.role,e.constraints.session,e.constraints.turn),warnings:r})}},le=class{constructor(e){this.contextRegistry=e}rank(e){const{entries:t,recentMessages:s,config:n={}}=e,r=n.minScore??0,i=n.freshnessHalfLifeDays??30,o=n.recentMessageWindow??3;if(0===s.length)return[...t].sort(((e,t)=>this.freshnessWeight(t.timestamp,i)-this.freshnessWeight(e.timestamp,i)));const a=this.tokenize(s.slice(-o).join(" "));return t.map((e=>{const t=function(e,t){const s=t.get(e.content.kind);return s?s.toString(e):""}(e,this.contextRegistry);return{entry:e,score:.7*this.jaccardSimilarity(a,this.tokenize(t))+.3*this.freshnessWeight(e.timestamp,i)}})).filter((e=>e.score>r)).sort(((e,t)=>t.score-e.score)).map((e=>e.entry))}tokenize(e){return new Set(e.toLowerCase().replace(/[^\w\s]/g," ").split(/\s+/).filter((e=>e.length>2)))}jaccardSimilarity(e,t){if(0===e.size&&0===t.size)return 0;let s=0;for(const n of e)t.has(n)&&s++;const n=e.size+t.size-s;return 0===n?0:s/n}freshnessWeight(e,t){const s=(Date.now()-new Date(e).getTime())/864e5;return Math.pow(.5,s/t)}},ue=class{bytes=new Map;records=new Map;async storeBytes(e,t){this.bytes.has(e)||this.bytes.set(e,t)}async loadBytes(e){return this.bytes.get(e)??null}async hasBytes(e){return this.bytes.has(e)}async deleteBytes(e){this.bytes.delete(e)}async saveRecord(e){this.records.set(e.sha256,{...e})}async loadRecord(e){return this.records.get(e)??null}async deleteRecord(e){this.records.delete(e)}async listRecords(){return Array.from(this.records.values()).map((e=>({...e})))}async exportAllBytes(){return Array.from(this.bytes.entries()).map((([e,t])=>[e,new Uint8Array(t)]))}async registerBlob(e,t){this.bytes.has(e.sha256)||this.bytes.set(e.sha256,t),this.records.set(e.sha256,{...e})}},pe="blob_bytes",he="blob_records";function me(e){return new Promise(((t,s)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>s(e.error)}))}function fe(e){return new Promise(((t,s)=>{e.oncomplete=()=>t(),e.onerror=()=>s(e.error),e.onabort=()=>s(new Error("Transaction aborted"))}))}var ye=class{dbName;db=null;constructor(e={}){this.dbName=e.dbName??"aiworkspace-blobs"}async open(){this.db||(this.db=await new Promise(((e,t)=>{const s=indexedDB.open(this.dbName,1);s.onupgradeneeded=e=>{const t=e.target.result;this.createSchema(t)},s.onsuccess=()=>e(s.result),s.onerror=()=>t(s.error),s.onblocked=()=>t(new Error(`[IndexedDBBlobStorage] Database "${this.dbName}" blocked.`))})),this.db.onversionchange=()=>{this.db?.close(),this.db=null})}createSchema(e){e.objectStoreNames.contains(pe)||e.createObjectStore(pe,{keyPath:"sha256"}),e.objectStoreNames.contains(he)||e.createObjectStore(he,{keyPath:"sha256"})}close(){this.db?.close(),this.db=null}async deleteDatabase(){this.close(),await new Promise(((e,t)=>{const s=indexedDB.deleteDatabase(this.dbName);s.onsuccess=()=>e(),s.onerror=()=>t(s.error)}))}getDB(){if(!this.db)throw new Error("[IndexedDBBlobStorage] Database not open. Call open() first.");return this.db}readTx(...e){return this.getDB().transaction(e,"readonly")}writeTx(...e){return this.getDB().transaction(e,"readwrite")}async storeBytes(e,t){const s=this.readTx(pe);if(await me(s.objectStore(pe).get(e)))return;const n=this.writeTx(pe);n.objectStore(pe).put({sha256:e,data:t}),await fe(n)}async loadBytes(e){const t=this.readTx(pe),s=await me(t.objectStore(pe).get(e));return s?.data??null}async hasBytes(e){const t=this.readTx(pe);return await me(t.objectStore(pe).count(e))>0}async deleteBytes(e){const t=this.writeTx(pe);t.objectStore(pe).delete(e),await fe(t)}async saveRecord(e){const t=this.writeTx(he);t.objectStore(he).put(e),await fe(t)}async loadRecord(e){const t=this.readTx(he);return await me(t.objectStore(he).get(e))??null}async deleteRecord(e){const t=this.writeTx(he);t.objectStore(he).delete(e),await fe(t)}async listRecords(){return me(this.readTx(he).objectStore(he).getAll())}async exportAllBytes(){const e=this.readTx(pe);return(await me(e.objectStore(pe).getAll())).map((({sha256:e,data:t})=>[e,t]))}async registerBlob(e,t){await new Promise(((s,n)=>{const r=this.getDB().transaction([pe,he],"readwrite"),i=r.objectStore(pe),o=r.objectStore(he),a=i.count(e.sha256);a.onsuccess=()=>{0===a.result&&i.put({sha256:e.sha256,data:t}),o.put(e)},a.onerror=()=>n(a.error),r.oncomplete=()=>s(),r.onerror=()=>n(r.error),r.onabort=()=>n(new Error("registerBlob transaction aborted"))}))}},ge={};((e,t)=>{for(var s in t)n(e,s,{get:t[s],enumerable:!0})})(ge,{GOOGLE_MODELS:()=>be,GoogleGenAIAdapter:()=>Se,mapBlockToPart:()=>ve,mapTurnToContent:()=>xe,mappings:()=>we,parseModelResponse:()=>ke});var we={text:{to:e=>({text:e.text}),from:e=>({id:s(),type:"text",text:e.text})},summary:{to:e=>({text:`[Summary]: ${e.text}`}),from:e=>({id:s(),type:"summary",text:e.text})},thinking:{to:e=>({text:e.thinking}),from:e=>({id:s(),type:"thinking",thinking:e.thinking})},"tool:use":{to:e=>({functionCall:{name:e.name,args:e.input}}),from:e=>({id:s(),type:"tool:use",name:e.functionCall?.name??e.name,input:e.functionCall?.args??e.input??{}})},"tool:result":{to:e=>({functionResponse:{name:e.useId,response:{result:e.content}}}),from:e=>({id:s(),type:"tool:result",useId:e.useId,content:e.content,isError:e.isError})},"role:transition":{to:e=>({text:`[Role transition: ${e.previousRole??"none"} → ${e.newRole}]`}),from:e=>({id:s(),type:"role:transition",previousRole:e.previousRole,newRole:e.newRole})}},be=[{provider:"google",name:"gemini-3.1-pro-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:2,output:12,cache:{read:.2,write:4.5}}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-3-flash-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.5,output:3,cache:{read:.05,write:1}}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-3.1-flash-lite-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.25,output:1.5,cache:{read:.025,write:1}}}],capacity:[{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-2.5-pro",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:1.25,output:10,cache:{read:.125,write:4.5}}}],capacity:[{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-2.5-flash",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.3,output:2.5,cache:{read:.03,write:1}}}],capacity:[{unit:"call",max:4e3,period:60},{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-2.5-flash-lite",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.1,output:.4,cache:{read:.01,write:1}}}],capacity:[{unit:"call",max:4e3,period:60},{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-3-pro-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:2,output:12,cache:{read:.2,write:4.5}}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-2.5-flash-image",window:{size:4096,out:0},feature:{vision:!1,tools:!1,json:!1,cache:!1,streaming:!1,thinking:!1},pricing:[{unit:"image",scale:0,cost:{input:.02,output:0}}],capacity:[{unit:"call",max:100,period:60}]},{provider:"google",name:"gemini-2.5-flash-live-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.5,output:3}}],capacity:[{unit:"concurrent",max:10,period:0}]},{provider:"google",name:"gemini-3.1-flash-live-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.5,output:3}}],capacity:[{unit:"concurrent",max:10,period:0}]},{provider:"google",name:"gemini-2.5-computer-use-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:1.25,output:10}}],capacity:[{unit:"call",max:200,period:60},{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-embedding-001",window:{size:2048,out:0},feature:{vision:!1,tools:!1,json:!1,cache:!1,streaming:!1,thinking:!1},pricing:[{unit:"token",scale:6,cost:{input:.5,output:0}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-embedding-2",window:{size:8192,out:0},feature:{vision:!1,tools:!1,json:!1,cache:!1,streaming:!1,thinking:!1},pricing:[{unit:"token",scale:6,cost:{input:.3,output:0}}],capacity:[{unit:"token",max:1e6,period:60}]}];function ke(e,s){const n=e.candidates?.[0];if(!n?.content?.parts)return g({code:"BACKEND_ERROR",reason:"No valid content parts in response"});const r=[];let i;for(const e of n.content.parts)if(e.thought)r.push((o=e.text??"",{id:t(),type:"thinking",thinking:o}));else if(e.text){i=e;break}var o;if(!i)return g({code:"BACKEND_ERROR",reason:"Response missing JSON part"});const a=function(e){try{const t=JSON.parse(e);return t.blocks&&Array.isArray(t.blocks)?y(t.blocks):g({code:"BACKEND_ERROR",reason:'Invalid response: missing or malformed "blocks" array'})}catch(e){return g({code:"BACKEND_ERROR",reason:`Failed to parse response JSON: ${e instanceof Error?e.message:String(e)}`})}}(i.text);if(!a.ok)return a;for(const e of a.value){const t=s.parse(e,Se.provider());t&&r.push(t)}return y(r)}async function xe(e,t,s){const n="assistant"===e.actor?"model":"user",r=[];for(const n of e.blocks){if("image"===n.type||"document"===n.type){const e=n.ref;if(!e)continue;const s=await _e(e,t);s&&r.push(s);continue}const e=ve(n,s);e&&r.push(e)}return{role:n,parts:r}}function ve(e,t){const s=t.get(e.type);if(!s)throw new Error(`[GoogleGenAIAdapter] mapBlockToPart: block type "${e.type}" is not registered. Register it via registry.register() before use.`);const n=s.mappings?.[Se.provider()];if(!n)throw new Error(`[GoogleGenAIAdapter] mapBlockToPart: no "${Se.provider()}" mapping for block type "${e.type}". Add a mapping via registry.update("${e.type}", { mappings: { ${Se.provider()}: { to, from } } }).`);return n.to(e)}async function _e(e,t){const s=await t(e,Se.provider());if(!s.ok||!s.value)return null;const{value:n}=s;return"remote"===n.kind?{fileData:{fileUri:n.fileId,mimeType:n.mediaType}}:{inlineData:{data:v(n.data),mimeType:n.mediaType}}}function Oe(e){return Math.ceil(e.length/4)}var Se=class e{constructor(e,t,s={model:"gemini-2.5-flash"}){this.client=e,this.services=t,this._models=t.models;const n=this._models.get(s.model);if(!n)throw new Error(`Could not get model: ${s.model} profile in registry.`);this.model=n,this.registerGeminiMappings()}model;_models;registerGeminiMappings(){const t=this.services.blockRegistry;for(const[s,n]of Object.entries(we))t.update(s,{mappings:{[e.provider()]:n}})}async status(t){return{provider:e.provider(),model:this.model.name,ready:!0,window:this.model.window,feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.1,output:.4}}],rate:{load:0,capacity:[{unit:"call",max:1e3,period:60},{unit:"token",max:4e6,period:60}]}}}async resolve(e){const{prompt:s}=e,{assembler:n,blockRegistry:r,blobResolver:i}=this.services,o=s.model&&this._models.get(s.model)||this.model,a=n.build(s,[{label:"block-architecture",content:r.description(),position:"after:instructions"}]),c=n.join(a),d={role:"system",parts:[{text:c}]},l=s.constraints[o.name]??{tokens:{}},u=await Promise.all(s.transcript.map((e=>xe(e,i,r)))),p=r.schema(),h={model:o.name,contents:u,config:{systemInstruction:d,thinkingConfig:{includeThoughts:!0},responseMimeType:"application/json",responseSchema:p,...void 0!==l.temperature&&{temperature:l.temperature},...void 0!==l.tokens.max&&{maxOutputTokens:l.tokens.max},...l.tokens.stops?.length&&{stopSequences:l.tokens.stops},...void 0!==l.tokens.thought&&{thinkingConfig:{includeThoughts:!0,thinkingBudget:l.tokens.thought}}}},m=u.flatMap((e=>e.parts??[])).map((e=>e.text??"")).join(""),f=Oe(c),w=Oe(m),b=f+w,k=this;return{model:o.name,instructions:a,transcript:s.transcript,context:s.system.context,preferences:s.system.preferences,constraints:l,tokens:{breakdown:{system:f,transcript:w},total:b,source:"estimated",output:l.tokens.max??o.window.out,remaining:o.window.size-b},async execute(){let e;try{e=await k.client.models.generateContent(h)}catch(e){return g({code:"BACKEND_ERROR",reason:e instanceof Error?e.message:String(e)})}const t=ke(e,k.services.blockRegistry);if(!t.ok)return t;const n=t.value,r=new L("assistant",s.session);for(const e of n)r.addBlock(e);return y({turn:r.build(),effects:[]})},async*executeStream(){let e;try{e=await k.client.models.generateContentStream(h)}catch(e){const n=e instanceof Error?e.message:String(e),r=new L("assistant",s.session);return r.addBlock({id:t(),type:"text",text:`[Stream error: ${n}]`}),void(yield{turn:r.build(),effects:[]})}const n=[];for await(const s of e){const e=s.candidates?.[0];if(e?.content?.parts)for(const s of e.content.parts)s.thought||s.text&&(n.push(s.text),yield{blocks:[{id:t(),type:"text",text:s.text}]})}const r=n.join(""),i=new L("assistant",s.session);i.addBlock({id:t(),type:"text",text:r}),yield{turn:i.build(),effects:[]}}}}static provider(){return"google"}static models(){return be}};async function Te(t){const{blobStorage:s,eventBus:n=e(),getWorkspace:i,setWorkspace:o,processor:a,guard:c,toolRegistry:d,models:l=[],extensions:u=[],extensionReducers:m={},extensionMiddleware:f=[],extensionIndexers:y=[],extensionStores:g,extensionSchemas:w=[]}=t,b=p(t.db),k=[...w,...u.flatMap((e=>e.schemas??[]))],x={...m,...u.reduce(((e,t)=>({...e,...t.reducers})),{})},v=[...f,...u.flatMap((e=>e.middleware??[]))],_=[...y,...u.flatMap((e=>e.indexers??[]))],O=u.flatMap((e=>e.blocks??[]));await b.open(k);const N={workspace:await b.collection(h.WORKSPACE),role:await b.collection(h.ROLE),preference:await b.collection(h.PREFERENCE),context:await b.collection(h.CONTEXT),session:await b.collection(h.SESSION),topic:await b.collection(h.TOPIC),turn:await b.collection(h.TURN)},R=new H(s,new ne(200),n),D=new P,I={workspaceStore:new se(N.workspace,new ne(1)),roles:new Z(N.role,new ne(100)),preferences:new Q(N.preference,new ne(500)),context:new X(N.context,new ne(500),D),topics:new T(N.topic,new ne(100)),sessions:new ee(N.session,new ne(50)),turns:new te(N.turn,new ne(50)),blobs:R,tools:d,db:b,indexers:[...r,..._]};if(g){const e=g(I);Object.assign(I,e)}await Promise.all(u.map((async e=>{if(e.stores){const t=await e.stores(I);Object.assign(I,t)}})));const j=new S({ctx:I,getWorkspace:i,updateWorkspace:async e=>{if(await o(e),e?.id||e?.settings||e?.project){const e=i();await I.workspaceStore.update(e.id,{id:e.id,settings:e.settings,project:e.project})}},guard:c,bus:n});Object.entries($).forEach((([e,t])=>{j.register(e,t)})),Object.entries(x).forEach((([e,t])=>{j.register(e,t)})),j.use(E),v.forEach((e=>{j.use(e)}));const A=new Y(j,a),B=new F;O.forEach((e=>B.register(e))),u.forEach((e=>{e.contexts&&e.contexts.forEach((e=>{if(D.register(e),e.store){const t=e.store(I);I.context.registerDelegate(e.kind,t)}}))}));const q=new U(l),z={assembler:new C,processor:a,blobResolver:I.blobs.resolve.bind(I.blobs),blockRegistry:B,contextRegistry:D,models:q},M=async e=>{await j.dispatch({type:"workspace:sync",payload:void 0,timestamp:(new Date).toISOString()});let t=i();t.id&&""!==t.id&&"00000000-0000-0000-0000-000000000000"!==t.id||(await j.dispatch({type:"workspace:create",payload:e.workspace,timestamp:(new Date).toISOString()}),t=i());const s=[];if(e.roles)for(const n of e.roles)t.index.roles[n.name]||(await j.dispatch({type:"role:add",payload:n,timestamp:(new Date).toISOString()}),s.push(n.name));return e.workspace.settings.defaultRole&&t.settings.defaultRole!==e.workspace.settings.defaultRole&&await j.dispatch({type:"workspace:sync",payload:{settings:{...t.settings,defaultRole:e.workspace.settings.defaultRole}},timestamp:(new Date).toISOString()}),{workspace:i(),roles:s}};if(t.bootstrap){const e=i();if(!e||!e.index){const e=oe({id:t.bootstrap.workspace.id,settings:t.bootstrap.workspace.settings,project:t.bootstrap.workspace.project});await o(e)}await M(t.bootstrap)}return{manager:j,sessions:A,ctx:I,services:z,bootstrap:M}}export{h as COLLECTIONS,de as DefaultPromptBuilder,C as DefaultSystemPromptAssembler,K as EMPTY_SYSTEM_ROLE,ge as GoogleAdapter,ye as IndexedDBBlobStorage,le as JaccardContextRetriever,ne as LRUCache,ue as MemoryBlobStorage,G as Session,Y as SessionManager,L as TurnBuilder,W as TurnTree,S as WorkspaceManager,v as bufferToBase64,x as computeSHA256,q as createDefaultAssembler,re as createEmptySession,ie as createEmptyTurn,oe as createEmptyWorkspace,Te as createWorkspace,p as createWorkspaceDatabase,b as del,g as error,O as getExtension,k as merge,w as omitNullUndefined,_ as shortHash,y as success};
|
|
1
|
+
import{createEventBus as e}from"@asaidimu/utils-events";import{v7 as t,v4 as s}from"uuid";var n=Object.defineProperty,r=[async e=>{const t=await e.workspaceStore.list();if(0===t.length)return{};const s=t[0];return{id:s.id,settings:s.settings,project:s.project}},async e=>{const t=await e.roles.list(),s={};for(const n of t)s[n.name]=e.roles.summarize(n);return{index:{roles:s}}},async e=>{const t=await e.preferences.list(),s={};for(const n of t)s[n.id]=e.preferences.summarize(n);return{index:{preferences:s}}},async e=>{const t=await e.context.list(),s={};for(const n of t)s[n.key]=e.context.summarize(n);return{index:{context:s}}},async e=>{const t=await e.sessions.list(),s={};for(const n of t)s[n.id]=e.sessions.summarize(n);return{index:{sessions:s}}},async e=>{const t=await e.topics.list(),s={};for(const n of t)s[n.name]=e.topics.summarize(n);return{index:{topics:s}}},async e=>({index:{blobs:await e.blobs.getAllRecords()}})],i=[{name:"workspace",version:"1.0.0",description:"Workspace root containing global settings and project metadata.",fields:{id:{name:"id",type:"string",required:!0},settings:{name:"settings",type:"record",required:!0},project:{name:"project",type:"record",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"}],constraints:[],migrations:[]},{name:"role",version:"1.0.0",description:"AI persona with a system prompt and associated preference defaults.",fields:{name:{name:"name",type:"string",required:!0},label:{name:"label",type:"string",required:!0},description:{name:"description",type:"string",required:!1},persona:{name:"persona",type:"string",required:!0},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"},topics:{name:"topics",type:"array",required:!1},constraints:{name:"constraints",type:"record",required:!1}},indexes:[{name:"by_name",fields:["name"],type:"unique"},{name:"by_label",fields:["label"],type:"normal"}],constraints:[],migrations:[]},{name:"preference",version:"1.0.0",description:"A user behavioural instruction, scoped to zero or more topics.",fields:{id:{name:"id",type:"string",required:!0},content:{name:"content",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},timestamp:{name:"timestamp",type:"string",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"context",version:"1.0.0",description:"Injected background knowledge, scoped to topics. Content is a discriminated union.",fields:{key:{name:"key",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},content:{name:"content",type:"record",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},metadata:{name:"metadata",type:"record",required:!1}},indexes:[{name:"by_key",fields:["key"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"session",version:"1.0.0",description:"Session metadata. The head field tracks the current tip of the turn DAG.",fields:{id:{name:"id",type:"string",required:!0},label:{name:"label",type:"string",required:!0},role:{name:"role",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"},metadata:{name:"metadata",type:"record",required:!1},head:{name:"head",type:"record",required:!1},constraints:{name:"constraints",type:"record",required:!1}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_role",fields:["role"],type:"normal"}],constraints:[],migrations:[]},{name:"turn",version:"1.0.0",description:["A single message in a session transcript, stored as a flat document.","The DAG is reconstructed in memory by TurnTree.buildNodeGraph() at session open time."].join(" "),fields:{id:{name:"id",type:"string",required:!0},session:{name:"session",type:"string",required:!0},version:{name:"version",type:"number",required:!0},actor:{name:"actor",type:"enum",required:!0,values:["user","assistant","tool"]},blocks:{name:"blocks",type:"array",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},role:{name:"role",type:"string",required:!1},model:{name:"model",type:"string",required:!1},parent:{name:"parent",type:"record",required:!1},constraints:{name:"constraints",type:"record",required:!1},metadata:{name:"metadata",type:"record",required:!1}},indexes:[{name:"by_session",fields:["session"],type:"normal"},{name:"by_session_parent",fields:["session","parent"],type:"composite"},{name:"by_session_id_ver",fields:["session","id","version"],type:"composite",unique:!0}],constraints:[],migrations:[]},{name:"topic",version:"1.0.0",description:"A categorization for context and preferences, used for retrieval.",fields:{name:{name:"name",type:"string",required:!0},label:{name:"label",type:"string",required:!1},description:{name:"description",type:"string",required:!1},metadata:{name:"metadata",type:"record",required:!1},created:{name:"created",type:"string",required:!0},updated:{name:"updated",type:"string",required:!0}},indexes:[{name:"by_name",fields:["name"],type:"unique"}],constraints:[],migrations:[]}],o=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},a=class extends o{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},c=class extends o{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},d=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const s=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await s;let n;await Promise.race([s.then((()=>clearTimeout(n))),new Promise(((s,r)=>{n=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),r(new a("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},l=class{mutex=new d({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,s="Operation timed out"){if(null==t)return e;let n;return Promise.race([e.then((e=>(clearTimeout(n),e))),new Promise(((e,r)=>{n=setTimeout((()=>r(new a(s))),t)}))])}},u=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new d({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new c};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,n=null;try{if(this._done)throw new c;n=await e(),this._lastValue=n,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:n,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}};function p(e){const t=new l({retry:!0,throws:!0}),s=new l({retry:!0,throws:!0});return{open:async(s=[])=>(await t.do((async()=>{const t=[...i,...s];await e.setupCollections(t)}))).value,collection:async t=>e.collection(t),close:async()=>(await s.do((()=>{e.close()}))).value,database:()=>e}}var h={WORKSPACE:"workspace",ROLE:"role",PREFERENCE:"preference",CONTEXT:"context",SESSION:"session",TURN:"turn",BLOB:"blob",TOPIC:"topic"},m=Symbol.for("delete"),f=e=>Array.isArray(e)?[...e]:{...e};function y(e){return{ok:!0,value:e}}function g(e){return{ok:!1,error:e}}function w(e){return Object.fromEntries(Object.entries(e).filter((([e,t])=>null!=t)))}function b(){return m}var k=function(e){const t=e?.deleteMarker||m;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const n={};for(const[r,i]of Object.entries(e))if(i!==t)if("object"==typeof i&&null!==i){const e=s(i);void 0!==e&&(n[r]=e)}else n[r]=i;return n}return e===t?void 0:e}return function(e,n){if("object"!=typeof e||null===e)return"object"==typeof n&&null!==n?s(n):n===t?{}:n;if("object"!=typeof n||null===n)return e;const r=f(e),i=[{target:r,source:n}];for(;i.length>0;){const{target:e,source:s}=i.pop();for(const n of Object.keys(s)){const r=s[n];if(r!==t)if(Array.isArray(r))e[n]=r;else if("object"==typeof r&&null!==r){const t=n in e&&"object"==typeof e[n]&&null!==e[n]?e[n]:{};e[n]=f(t),i.push({target:e[n],source:r})}else e[n]=r;else delete e[n]}}return r}}({deleteMarker:m});async function x(e){const t=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join("")}function v(e){if("undefined"!=typeof Buffer)return Buffer.from(e).toString("base64");const t=[];for(let s=0;s<e.length;s+=32768){const n=e.subarray(s,s+32768);t.push(String.fromCharCode.apply(null,Array.from(n)))}return btoa(t.join(""))}function _(e,t=4){let s=0;for(let t=0;t<e.length;t++)s=(s<<5)-s+e.charCodeAt(t),s|=0;return Math.abs(s).toString(36).padEnd(t,"0").slice(0,t)}function O(e,t){return e.extensions[t]}var S=class{registry=new Map;middlewares=[];serializer=new u;bus;_getWorkspace;updateWorkspace;guard;_ctx;constructor(e){this._ctx=e.ctx,this._getWorkspace=e.getWorkspace,this.updateWorkspace=e.updateWorkspace,this.guard=e.guard,this.bus=e.bus}register(e,t){return this.registry.set(e,t),this}use(e){return this.middlewares.push(e),this}workspace(){return this._getWorkspace()}async dispatch(e){const t=await this.serializer.do((async()=>{if(this.guard){const t=await this.guard.authenticate({type:"command",payload:e});if(!t.ok)return g(t.error)}const t=this.registry.get(e.type);if(!t)return g({code:"INVALID_COMMAND",reason:`No reducer registered for command type: ${e.type}`});const s=this._getWorkspace(),n=await t({workspace:s,...this._ctx},e.payload);if(!n.ok)return n;let r=n.value;for(const t of this.middlewares){const n=await t({workspace:s,command:e,patch:r,...this._ctx});r=k(r,n)}return await this.updateWorkspace(r),this.bus.emit({name:"workspace:changed",payload:r}),"workspace:sync"===e.type&&this.bus.emit({name:"workspace:synced",payload:void 0}),y(r)}));if(t.error)throw t.error;return t.value}subscribe(e,t){return this.bus.subscribe(e,t)}ctx(){return{workspace:this._getWorkspace(),...this._ctx}}},T=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;const n=s.state();return this.cache.set(e,n),n}async add(e){await this.collection.create(e),this.cache.set(e.name,e)}async update(e,t){const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;await s.update(t);const n=s.state();return this.cache.set(e,n),n}async delete(e){const t=await this.collection.find({field:"name",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async getMany(e){if(0===e.length)return[];const t=[],s=[];for(const n of e){const e=this.cache.get(n);e?t.push(e):s.push(n)}if(s.length>0){const e=await this.collection.filter({operator:"or",conditions:s.map((e=>({field:"name",operator:"eq",value:e})))});for(const s of e){const e=s.state();this.cache.set(e.name,e),t.push(e)}}return t}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}referencedBy(e,t){for(const s in t.roles)if(t.roles[s].topics?.includes(e))return!0;for(const s in t.sessions)if(t.sessions[s].topics?.includes(e))return!0;for(const s in t.context)if(t.context[s].topics?.includes(e))return!0;for(const s in t.preferences)if(t.preferences[s].topics?.includes(e))return!0;return!1}summarize(e){return{topic:e.name,contextKeys:[],preferences:[],metadata:{created:e.created,updated:e.updated,entries:0}}}};function N(e,t,s,n,r,i){const o={};for(const a of t){let t=e[a];if(!t){if("add"!==r||!i)continue;t={topic:a,contextKeys:[],preferences:[],metadata:{created:(new Date).toISOString(),updated:(new Date).toISOString(),entries:0}},i.add({name:a,created:t.metadata.created,updated:t.metadata.updated})}const c=t[n],d=c.includes(s);if("add"!==r||d){if("remove"===r&&d){const e=Math.max(0,(t.metadata.entries||0)-1);o[a]={...t,[n]:c.filter((e=>e!==s)),metadata:{...t.metadata,updated:(new Date).toISOString(),entries:e}}}}else o[a]={...t,[n]:[...c,s],metadata:{...t.metadata,updated:(new Date).toISOString(),entries:(t.metadata.entries||0)+1}}}return{index:{topics:o}}}function R(e,t,s,n){return N(e,t,s,"contextKeys","add",n)}function D(e,t,s){return N(e,t,s,"contextKeys","remove")}function I(e,t,s,n){return N(e,t,s,"preferences","add",n)}function j(e,t,s){return N(e,t,s,"preferences","remove")}var E=async e=>{if(!e.patch)return;const{workspace:t,patch:s}=e,n=t.index.topics;let r={};const i=e=>{const t=e?.index?.topics;t&&(r=k(r,t))};if(s.index?.context)for(const[r,o]of Object.entries(s.index.context)){const s=t.index.context[r];if(void 0===o&&s)i(D(n,s.topics,s.key));else if(s||!o){if(s&&o){const t=s.topics??[],r=o.topics??t,a=r.filter((e=>!t.includes(e))),c=t.filter((e=>!r.includes(e)));c.length&&i(D(n,c,s.key)),a.length&&i(R(n,a,s.key,e.topics))}}else i(R(n,o.topics??[],o.key,e.topics))}if(s.index?.preferences)for(const[r,o]of Object.entries(s.index.preferences)){const s=t.index.preferences[r];if(void 0===o&&s)i(j(n,s.topics,s.id));else if(s||!o){if(s&&o){const t=s.topics??[],r=o.topics??t,a=r.filter((e=>!t.includes(e))),c=t.filter((e=>!r.includes(e)));c.length&&i(j(n,c,s.id)),a.length&&i(I(n,a,s.id,e.topics))}}else i(I(n,o.topics??[],o.id,e.topics))}return Object.keys(r).length?{index:{topics:r}}:{}},A="\n# WORKSPACE OPERATING SYSTEM\nYou are operating within a structured workspace. Your output MUST be a JSON object matching the provided schema.\nYour entire response MUST be valid JSON. Nothing else.\n".trim();function B(e){if(!e||"append"===e)return{placement:"append",label:null};if("prepend"===e)return{placement:"prepend",label:null};const[t,...s]=e.split(":");return("before"===t||"after"===t)&&s.length>0?{placement:t,label:s.join(":")}:(console.warn(`[SystemPromptAssembler] Unrecognised position "${e}", defaulting to "append".`),{placement:"append",label:null})}var C=class{build(e,t=[]){const s=[...e.system.extensions||[],...t],n=[];var r,i,o;n.push({label:"operating-system",content:A}),e.role.persona&&n.push({label:"persona",content:(r=e.role.persona,`# Persona\n${r}`)}),e.system.preferences.length>0&&n.push({label:"preferences",content:(i=e.system.preferences,`# User Preferences\n${i.map((e=>`- ${e.content}`)).join("\n")}`),metadata:{count:e.system.preferences.length}}),e.system.context.length>0&&n.push({label:"context",content:(o=e.system.context,`# Context\n${o.map((e=>{switch(e.content.kind){case"text":return`[${e.key}] ${e.content.value}`;case"json":return`[${e.key}] JSON: ${JSON.stringify(e.content.value)}`;case"blob":return`[${e.key}] Blob: ${e.content.filename??"unnamed"} (${e.content.mediaType}, ${e.content.sizeBytes} bytes)`;case"remote":return`[${e.key}] Remote: ${e.content.uri}`;default:return`[${e.key}] Unsupported context type`}})).join("\n")}`),metadata:{count:e.system.context.length}}),e.system.instructions&&n.push({label:"instructions",content:`# Instructions\n${e.system.instructions}`});const a=[...n],c=[];for(const e of s){const{position:t,...s}=e,n=B(t);if("prepend"===n.placement){c.push(s);continue}if("append"===n.placement){a.push(s);continue}const r=a.findIndex((e=>e.label===n.label));if(-1===r){console.warn(`[SystemPromptAssembler] Anchor target "${n.label}" not found in sections. Extension "${e.label}" will be appended.`),a.push(s);continue}const i="before"===n.placement?r:r+1;a.splice(i,0,s)}return[...c,...a]}join(e){return e.map((e=>e.content)).join("\n\n---\n\n")}};function q(){return new C}var U={"workspace:create":async function(e,t){const{workspaceStore:s}=e,{id:n,settings:r,project:i}=t,o=await s.get(n);return o?y({id:o.id,settings:o.settings,project:o.project}):(await s.add({id:n,settings:r,project:i}),y({id:n,settings:r,project:i,index:{roles:{},preferences:{},context:{},sessions:{},topics:{},blobs:{},tools:{},extensions:{}}}))},"workspace:sync":async function(e,t){let s={};for(const t of e.indexers){const n=await t(e);s=k(s,n)}return t&&(t.id&&(s.id=t.id),t.settings&&(s.settings=k(s.settings||{},t.settings)),t.project&&(s.project=k(s.project||{},t.project))),y(s)},"role:add":async function(e,t){const{workspace:s,roles:n}=e,r=t;return s.index.roles[r.name]?g({code:"DUPLICATE_KEY",resource:"Role",key:r.name}):(await n.add(r),y({index:{roles:{[r.name]:n.summarize(r)}}}))},"role:update":async function(e,t){const{workspace:s,roles:n}=e,{name:r,...i}=t;if(!s.index.roles[r])return g({code:"NOT_FOUND",resource:"Role",id:r});const o=await n.update(r,i);return o?y({index:{roles:{[r]:n.summarize(o)}}}):g({code:"BACKEND_ERROR",reason:`Failed to update role ${r} in store.`})},"role:delete":async function(e,t){const{workspace:s,roles:n}=e,{name:r}=t;return s.index.roles[r]?await n.delete(r)?y({index:{roles:{[r]:m}}}):g({code:"BACKEND_ERROR",reason:`Failed to delete role ${r} from store.`}):g({code:"NOT_FOUND",resource:"Role",id:r})},"preference:add":async function(e,t){const{workspace:s,preferences:n}=e,r=t;return s.index.preferences[r.id]?g({code:"DUPLICATE_KEY",resource:"Preference",key:r.id}):(await n.add(r),y({index:{preferences:{[r.id]:n.summarize(r)}}}))},"preference:update":async function(e,t){const{workspace:s,preferences:n}=e,{id:r,...i}=t;if(!s.index.preferences[r])return g({code:"NOT_FOUND",resource:"Preference",id:r});const o=await n.update(r,i);return o?y({index:{preferences:{[r]:n.summarize(o)}}}):g({code:"BACKEND_ERROR",reason:`Failed to update preference ${r} in store.`})},"preference:delete":async function(e,t){const{workspace:s,preferences:n}=e,{id:r}=t;return s.index.preferences[r]?await n.delete(r)?y({index:{preferences:{[r]:m}}}):g({code:"BACKEND_ERROR",reason:`Failed to delete preference ${r} from store.`}):g({code:"NOT_FOUND",resource:"Preference",id:r})},"context:add":async function(e,t){const{workspace:s,context:n}=e,r=t;return s.index.context[r.key]?g({code:"DUPLICATE_KEY",resource:"Context",key:r.key}):(await n.add(r),y({index:{context:{[r.key]:n.summarize(r)}}}))},"context:update":async function(e,t){const{workspace:s,context:n}=e,{key:r,...i}=t,o=s.index.context[r];if(!o)return g({code:"NOT_FOUND",resource:"Context",id:r});const a=await n.update(r,i,o.kind);return a?y({index:{context:{[r]:n.summarize(a)}}}):g({code:"BACKEND_ERROR",reason:`Failed to update context ${r} in store.`})},"context:delete":async function(e,t){const{workspace:s,context:n}=e,{key:r}=t,i=s.index.context[r];return i?await n.delete(r,i.kind)?y({index:{context:{[r]:m}}}):g({code:"BACKEND_ERROR",reason:`Failed to delete context ${r} from store.`}):g({code:"NOT_FOUND",resource:"Context",id:r})},"topic:add":async function(e,t){const{workspace:s,topics:n}=e,r=t;return s.index.topics[r.name]?g({code:"DUPLICATE_KEY",resource:"Topic",key:r.name}):(await n.add(r),y({index:{topics:{[r.name]:n.summarize(r)}}}))},"topic:update":async function(e,t){const{workspace:s,topics:n}=e,{name:r,...i}=t;if(!s.index.topics[r])return g({code:"NOT_FOUND",resource:"Topic",id:r});const o=await n.update(r,i);return o?y({index:{topics:{[r]:{metadata:{updated:o.updated}}}}}):g({code:"BACKEND_ERROR",reason:`Failed to update topic ${r} in store.`})},"topic:delete":async function(e,t){const{workspace:s,topics:n,roles:r,sessions:i}=e,{name:o,cascade:a}=t;if(!s.index.topics[o])return g({code:"NOT_FOUND",resource:"Topic",id:o});if(n.referencedBy(o,s.index)&&!a)return g({code:"INVALID_COMMAND",reason:`Topic '${o}' is referenced by other entities. Use 'cascade: true' to force deletion.`});if(a){for(const e in s.index.roles){const t=s.index.roles[e];if(t.topics?.includes(o)){const t=await r.get(e);t&&await r.update(e,{topics:t.topics.filter((e=>e!==o))})}}for(const e in s.index.sessions){const t=s.index.sessions[e];t.topics?.includes(o)&&await i.update(e,{topics:t.topics.filter((e=>e!==o))})}}return await n.delete(o)?y({index:{topics:{[o]:m}}}):g({code:"BACKEND_ERROR",reason:`Failed to delete topic ${o} from store.`})},"topic:merge":async function(e,t){const{workspace:s,topics:n,roles:r,sessions:i}=e,{source:o,target:a}=t;if(!s.index.topics[o]||!s.index.topics[a])return g({code:"NOT_FOUND",resource:"Topic",id:s.index.topics[o]?a:o});for(const e in s.index.roles){const t=s.index.roles[e];if(t.topics?.includes(o)){const t=await r.get(e);if(t){const s=t.topics.filter((e=>e!==o));s.includes(a)||s.push(a),await r.update(e,{topics:s})}}}for(const e in s.index.sessions){const t=s.index.sessions[e];if(t.topics?.includes(o)){const s=t.topics.filter((e=>e!==o));s.includes(a)||s.push(a),await i.update(e,{topics:s})}}return await n.delete(o),y({index:{topics:{[o]:m}}})},"session:create":async function(e,t){const{workspace:s,sessions:n}=e,r=t;return s.index.sessions[r.id]?g({code:"DUPLICATE_KEY",resource:"Session",key:r.id}):(await n.add(r),y({index:{sessions:{[r.id]:n.summarize(r)}}}))},"session:update":async function(e,t){const{workspace:s,sessions:n}=e,{sessionId:r,...i}=t;if(!s.index.sessions[r])return g({code:"NOT_FOUND",resource:"Session",id:r});const o=await n.update(r,i);return o?y({index:{sessions:{[r]:n.summarize(o)}}}):g({code:"BACKEND_ERROR",reason:`Failed to update session ${r} in store.`})},"session:fork":async function(e,t){const{workspace:s,sessions:n}=e,{sessionId:r,newSessionId:i,label:o}=t,a=s.index.sessions[r];if(!a)return g({code:"NOT_FOUND",resource:"Session",id:r});const c={...a,id:i,label:o||`Fork of ${a.label}`,role:t.role?t.role:a.role,topics:t.topics?t.topics:a.topics};return await n.add(c),y({index:{sessions:{[i]:n.summarize(c)}}})},"session:delete":async function(e,t){const{workspace:s,sessions:n}=e,{sessionId:r}=t;return s.index.sessions[r]?(await n.delete(r),y({index:{sessions:{[r]:m}}})):g({code:"NOT_FOUND",resource:"Session",id:r})},"session:role:switch":async function(e,t){const{workspace:s,sessions:n}=e,{sessionId:r,roleName:i}=t;return s.index.sessions[r]?(await n.update(r,{role:i}),y({index:{sessions:{[r]:{role:i}}}})):g({code:"NOT_FOUND",resource:"Session",id:r})},"session:topics:add":async function(e,t){const{workspace:s,sessions:n}=e,{sessionId:r,topics:i}=t,o=s.index.sessions[r];if(!o)return g({code:"NOT_FOUND",resource:"Session",id:r});const a=Array.from(new Set([...o.topics,...i]));return await n.update(r,{topics:a}),y({index:{sessions:{[r]:{topics:a}}}})},"session:preferences:override":async function(e,t){const{workspace:s,sessions:n}=e,{sessionId:r,preferences:i}=t;return s.index.sessions[r]?(await n.update(r,{preferences:i}),y({index:{sessions:{[r]:{preferences:i}}}})):g({code:"NOT_FOUND",resource:"Session",id:r})},"turn:add":async function(e,t){const{workspace:s,sessions:n,turns:r}=e,{sessionId:i,turn:o}=t;if(!s.index.sessions[i])return g({code:"NOT_FOUND",resource:"Session",id:i});await r.add(o);const a={id:o.id,version:o.version};return await n.update(i,{head:a}),y({index:{sessions:{[i]:{head:a}}}})},"turn:update":async function(e,t){const{workspace:s,sessions:n,turns:r}=e,{sessionId:i,turn:o}=t;if(!s.index.sessions[i])return g({code:"NOT_FOUND",resource:"Session",id:i});const{id:a,session:c,version:d,...l}=o;await r.update({id:a,session:c,version:d},l);const u={id:o.id,version:o.version};return await n.update(i,{head:u}),y({index:{sessions:{[i]:{head:u}}}})},"turn:edit":async function(e,t){const{workspace:s,sessions:n,turns:r}=e,{sessionId:i,turnId:o,newBlocks:a,newVersion:c,roleSnapshot:d,modelSnapshot:l}=t,u=s.index.sessions[i];if(!u)return g({code:"NOT_FOUND",resource:"Session",id:i});const p=u.head;let h={};if(p&&p.id===o){const e=await r.get({id:p.id,version:p.version,session:i});e&&(h={...e})}const m={...h,id:o,version:c,blocks:a,role:d??h.role,model:l??h.model,timestamp:(new Date).toISOString(),parent:h.parent,actor:h.actor||"assistant",session:i};if(await r.add(m),u.head?.id===o){const e={id:o,version:c};return await n.update(i,{head:e}),y({index:{sessions:{[i]:{head:e}}}})}return y({})},"turn:branch":async function(e,t){const{workspace:s,sessions:n,turns:r}=e,{sessionId:i,turn:o}=t;if(!s.index.sessions[i])return g({code:"NOT_FOUND",resource:"Session",id:i});await r.add(o);const a={id:o.id,version:o.version};return await n.update(i,{head:a}),y({index:{sessions:{[i]:{head:a}}}})},"turn:delete":async function(e,t){const{workspace:s,sessions:n,turns:r}=e,{sessionId:i,turnId:o,newHead:a}=t;return s.index.sessions[i]?(await r.delete({session:i,id:o,version:t.version}),a?(await n.update(i,{head:a}),y({index:{sessions:{[i]:{head:a}}}})):y({})):g({code:"NOT_FOUND",resource:"Session",id:i})},"blob:register":async function(e,t){const{blobs:s}=e,n=await s.register(t.data,t.mediaType,t.filename);if(!n.ok)return n;const r=await s.getRecord(n.value.sha256);return r?y({index:{blobs:{[r.sha256]:r}}}):g({code:"BACKEND_ERROR",reason:`Failed to retrieve registered blob record for ${n.value.sha256}`})},"blob:retain":async function(e,t){const{blobs:s}=e,n=await s.retain(t.sha256);if(!n.ok)return n;const r=await s.getRecord(t.sha256);return y({index:{blobs:{[t.sha256]:r}}})},"blob:release":async function(e,t){const{blobs:s}=e,n=await s.release(t.sha256);if(!n.ok)return n;const r=await s.getRecord(t.sha256);return y({index:{blobs:{[t.sha256]:r||m}}})},"blob:purge":async function(e,t){const{blobs:s}=e,n=await s.purge(t.sha256);return n.ok?y({index:{blobs:{[t.sha256]:m}}}):n},"blob:record_remote_id":async function(e,t){const{blobs:s}=e,{sha256:n,providerId:r,fileId:i,timestamp:o}=t,a=await s.recordRemoteId(n,r,i,o);if(!a.ok)return a;const c=await s.getRecord(n);return y({index:{blobs:{[n]:c}}})},"tool:call":async function(e,t){return y({})}},$=class{profiles;constructor(e=[]){this.profiles=new Map;for(const t of e)this.profiles.set(t.name,t)}get(e){return this.profiles.get(e)}list(e){const t=Array.from(this.profiles.values());return e?t.filter((t=>t.provider===e)):t}register(e){this.profiles.set(e.name,e)}},z=[{type:"text",emittable:!0,description:["## Block: `text`","Primary communication block. Use for all conversational responses, explanations, and prose.","A response may contain multiple `text` blocks interleaved with other block types."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["text"]},text:{type:"string",description:"The raw markdown or plain text content of the response."}},required:["type","text"]}},{type:"summary",emittable:!0,description:["## Block: `summary`","Context compression block. Replaces older conversation history with a concise digest."].join("\n"),rules:["Only emit when explicitly instructed by the system to summarise.","Never emit more than one summary block per turn.","Preserve key decisions, outcomes, and unresolved questions.","Do not summarise the current turn — only prior history."],schema:{type:"object",properties:{type:{type:"string",enum:["summary"]},text:{type:"string",description:"A concise summary replacing older conversation context."}},required:["type","text"]}},{type:"thinking",emittable:!1,description:["## Block: `thinking`","Internal chain-of-thought produced by the model before its final response.","Injected by the workspace from provider reasoning tokens — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["thinking"]},thinking:{type:"string",description:"The internal reasoning text produced before the final response."}},required:["type","thinking"]}},{type:"tool:use",emittable:!1,description:["## Block: `tool:use`","Captures a model request to execute a registered tool.","Constructed by the workspace from the provider native function-call response — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["tool:use"]},name:{type:"string",description:"The exact registered name of the tool to execute."},input:{type:"object",description:"The parameter arguments for the tool execution.",additionalProperties:!0}},required:["type","name","input"]}},{type:"tool:result",emittable:!1,description:["## Block: `tool:result`","Contains the output of a tool execution, including any errors.","Injected by the workspace after a tool runs — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["tool:result"]},useId:{type:"string",description:"The UUID of the ToolUseBlock that triggered this execution."},content:{oneOf:[{type:"string"},{type:"object",additionalProperties:!0}],description:"The serialized output of the tool, or a structured JSON response."},isError:{type:"boolean",description:"True if the tool execution resulted in an error."}},required:["type","useId","content"]}},{type:"image",emittable:!1,description:["## Block: `image`","An image asset attached to a turn, resolved from the workspace blob store.","Constructed by the workspace from user uploads — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["image"]},altText:{type:"string",description:"Accessible description of the image content."}},required:["type"]}},{type:"document",emittable:!1,description:["## Block: `document`","A document asset (PDF, DOCX, etc.) attached to a turn, resolved from the workspace blob store.","Constructed by the workspace from user uploads — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["document"]},title:{type:"string",description:"Human-readable title or filename of the document."}},required:["type"]}},{type:"role:transition",emittable:!1,description:["## Block: `role:transition`","Marks that the active session persona has switched from one role to another.","Emitted by the workspace when the active persona changes — never emit it yourself."].join("\n"),rules:[],schema:{type:"object",properties:{type:{type:"string",enum:["role:transition"]},previousRole:{type:"string",description:"The name of the role the session is leaving."},newRole:{type:"string",description:"The name of the role the session is adopting."}},required:["type","newRole"]}}];function M(e,t){let s=e.filter((e=>e.emittable));if(!t)return s;if(t.only&&t.only.length>0){const e=new Set(t.only);return s.filter((t=>e.has(t.type)))}if(t.exclude&&t.exclude.length>0){const e=new Set(t.exclude);return s.filter((t=>!e.has(t.type)))}return s}var F=class{store=new Map;constructor(){for(const e of z)this.store.set(e.type,e)}register(e){if(this.store.has(e.type))throw new Error(`[BlockRegistry] Block type "${e.type}" is already registered. Use update() to modify it.`);this.store.set(e.type,{...e,emittable:!0,rules:[]})}unregister(e){if(!this.store.has(e))throw new Error(`[BlockRegistry] Cannot unregister unknown block type "${e}".`);this.store.delete(e)}update(e,t){const s=this.store.get(e);s?this.store.set(e,{...s,...t,type:e}):this.store.set(e,{emittable:!0,rules:[],...t,type:e})}get(e){return this.store.get(e)}list(){return Array.from(this.store.values())}isType(e,t){return e.type===t}guard(e){return t=>t.type===e}schema(e){return{type:"object",description:"The model's structured response, containing an ordered sequence of content blocks.",properties:{blocks:{type:"array",description:"An ordered array of content blocks comprising the model's response.",items:{anyOf:M(Array.from(this.store.values()),e).map((e=>e.schema))}}},required:["blocks"]}}description(e){return["# BLOCK TYPES & USAGE RULES","","Your response MUST be a JSON object with a `blocks` array.","Each element of `blocks` must be one of the following types:","",M(Array.from(this.store.values()),e).map((e=>{const t=[e.description];return e.rules.length>0&&(t.push("**Rules:**"),t.push(...e.rules.map((e=>`- ${e}`)))),t.join("\n")})).join("\n\n"),"","## GLOBAL CONSTRAINTS","","- Output must be **valid JSON only** — no prose before or after the JSON object.","- Responses may contain multiple blocks. Blocks are rendered in order.","- **Do NOT generate IDs.** The workspace is solely responsible for block ID assignment.","- Do not infer or invent fields not defined in the block schemas above."].join("\n")}rules(e){const t=M(Array.from(this.store.values()),e);return Object.fromEntries(t.map((e=>[e.type,[...e.rules]])))}setRules(e,t){const s=this.store.get(e);if(!s)throw new Error(`[BlockRegistry] Cannot set rules on unknown block type "${e}".`);this.store.set(e,{...s,rules:t})}parse(e,s){const n=this.store.get(e.type);if(!n)return console.warn(`[BlockRegistry] parse() received unknown block type "${e.type}". Returning null.`),null;if(s&&n.mappings?.[s])return n.mappings[s].from(e);const{id:r,...i}=e;return{id:t(),...i}}create(e,s){if(!this.store.has(e))throw new Error(`[BlockRegistry] Cannot create block of unknown type "${e}".`);return{...s,id:t(),type:e}}clone(e,s){return{...structuredClone(e),...s,id:t()}}},P=class{store=new Map;constructor(){this.registerDefaults()}registerDefaults(){this.register({kind:"text",target:"system",render:e=>({id:e.key,type:"text",text:e.content.value}),toString:e=>e.content.value,summarize:e=>({key:e.key,kind:"text",topics:e.topics,timestamp:e.timestamp,preview:e.content.value.slice(0,100)})}),this.register({kind:"json",target:"system",render:e=>({id:e.key,type:"text",text:JSON.stringify(e.content.value,null,2)}),toString:e=>JSON.stringify(e.content.value),summarize:e=>({key:e.key,kind:"json",topics:e.topics,timestamp:e.timestamp,preview:"JSON Data"})}),this.register({kind:"blob",target:"transcript",render:e=>{const{sha256:t,mediaType:s,sizeBytes:n,filename:r}=e.content,i={sha256:t,mediaType:s,sizeBytes:n,filename:r};return s.startsWith("image/")?{id:e.key,type:"image",ref:i}:{id:e.key,type:"document",ref:i,title:r}},toString:e=>e.content.filename||"unnamed blob",summarize:e=>({key:e.key,kind:"blob",topics:e.topics,timestamp:e.timestamp,mime:e.content.mediaType,size:e.content.sizeBytes,preview:e.content.filename})})}register(e){if(this.store.has(e.kind))throw new Error(`[ContextRegistry] Context kind "${e.kind}" is already registered.`);this.store.set(e.kind,e)}get(e){return this.store.get(e)}list(){return Array.from(this.store.values())}},K="__system__",W=class{constructor(e,s,n){this._actor=e,this._turn=n?JSON.parse(JSON.stringify(n)):{id:t(),session:s,version:0,actor:this._actor,blocks:[],timestamp:(new Date).toISOString(),role:void 0,model:void 0}}_turn;addText(e){const s={id:t(),type:"text",text:e};return this._turn.blocks.push(s),this}addImage(e,s){const n={id:t(),type:"image",ref:e,altText:s};return this._turn.blocks.push(n),this}addDocument(e,s){const n={id:t(),type:"document",ref:e,title:s};return this._turn.blocks.push(n),this}addToolUse(e,s){const n={id:t(),type:"tool:use",name:e,input:s};return this._turn.blocks.push(n),this}addToolResult(e,s,n){const r={id:t(),type:"tool:result",useId:e,content:s,isError:n};return this._turn.blocks.push(r),this}addSummary(e){const s={id:t(),type:"summary",text:e};return this._turn.blocks.push(s),this}addRoleTransition(e,s){const n={id:t(),type:"role:transition",previousRole:e,newRole:s};return this._turn.blocks.push(n),this}addThinking(e){const s={id:t(),type:"thinking",thinking:e};return this._turn.blocks.push(s),this}addBlock(e){return e.id||(e.id=t()),this._turn.blocks.push(e),this}deleteBlock(e){return this._turn.blocks=this._turn.blocks.filter((t=>t.id!==e)),this}editTextBlock(e,t){const s=this._turn.blocks.findIndex((t=>t.id===e));if(-1===s)throw new Error(`Block with ID ${e} not found.`);const n=this._turn.blocks[s];if("text"!==n.type)throw new Error(`Block with ID ${e} is not a TextBlock.`);return this._turn.blocks[s]={...n,text:t},this}withId(e){return this._turn.id=e,this}withVersion(e){return this._turn.version=e,this}withTimestamp(e){return this._turn.timestamp=e,this}withParent(e){return this._turn.parent=e,this}withRoleSnapshot(e){return this._turn.role=e,this}withRole(e){return this._turn.role=e,this}withModel(e){return this._turn.model=e,this}build(){return JSON.parse(JSON.stringify(this._turn))}},V=class{constructor(e,t){this.turnStore=e,this.sessionStore=t}async loadAllTurns(e){return this.turnStore.listBySession(e)}async loadHead(e){const t=await this.sessionStore.get(e);return t?.head??null}},L=class e{constructor(e,t){this.nodes=e,this._head=t}static async build(t,s){const[n,r]=await Promise.all([s.loadAllTurns(t),s.loadHead(t)]),i=function(e,t){const s=function(e,t){if(!t)return new Set;const s=new Map;for(const t of e)s.set(`${t.id}:${t.version}`,t);const n=new Set;let r=t;for(;r;){const e=`${r.id}:${r.version}`;if(n.has(e))break;n.add(e);const t=s.get(e);if(!t)break;r=t.parent}return n}(e,t),n={},r={};for(const t of e){n[t.id]||(n[t.id]={id:t.id,versions:{},activeVersion:t.version,actor:t.actor,blocks:t.blocks,timestamp:t.timestamp,roleSnapshot:t.role,modelSnapshot:t.model,parent:t.parent,children:{}},r[t.id]=new Set);const e=n[t.id];e.versions[t.version]=t;const i=s.has(`${t.id}:${t.version}`),o=s.has(`${t.id}:${e.activeVersion}`);if(i&&(!o||t.version>=e.activeVersion)&&(e.activeVersion=t.version,e.blocks=t.blocks,e.timestamp=t.timestamp,e.roleSnapshot=t.role,e.modelSnapshot=t.model,e.parent=t.parent),t.parent){const e=`${t.parent.id}:${t.parent.version}`;if(r[t.parent.id]||(r[t.parent.id]=new Set),!r[t.parent.id].has(e+":"+t.id)){r[t.parent.id].add(e+":"+t.id),n[t.parent.id]||(n[t.parent.id]={id:t.parent.id,versions:{},activeVersion:t.parent.version,actor:"user",blocks:[],timestamp:"",roleSnapshot:void 0,modelSnapshot:void 0,children:{}});const s=n[t.parent.id];s.children[t.parent.version]||(s.children[t.parent.version]=[]),s.children[t.parent.version].push(t.id)}}}return n}(n,r);return new e(i,r)}head(){return this._head}chain(){return this._head?this.chainFrom(this._head.id):[]}chainFrom(e){const t=[];let s=e;for(;s;){const e=this.nodes[s];if(!e)break;t.push(e),s=e.parent?.id??null}return t.reverse()}getTurnSiblings(e){const t=this.nodes[e];if(!t)return[];if(!t.parent)return Object.values(this.nodes).filter((e=>!e.parent));const s=this.nodes[t.parent.id];if(!s)return[t];const n=s.children[t.parent.version];return n?n.map((e=>this.nodes[e])).filter((e=>!!e)):[t]}branchInfo(e){const t=this.nodes[e];if(!t)return{versions:[],currentIndex:-1,total:0,hasPrev:!1,hasNext:!1};const s=Object.keys(t.versions).map(Number).sort(((e,t)=>e-t)),n=s.indexOf(t.activeVersion);return{versions:s,currentIndex:n,total:s.length,hasPrev:n>0,hasNext:n<s.length-1}}graph(){return{...this.nodes}}};var J=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;const n=s.state();return this.cache.set(e,n),n}async add(e){await this.collection.create(e),this.cache.set(e.id,e)}async update(e,t){const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;await s.update(t);const n=s.state();return this.cache.set(e,n),n}async delete(e){const t=await this.collection.find({field:"id",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async list(){const e=await this.collection.list({limit:100,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return e}},G=class{cache;maxSize;constructor(e){this.cache=new Map,this.maxSize=e}get(e){const t=this.cache.get(e);return void 0!==t&&(this.cache.delete(e),this.cache.set(e,t)),t}set(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.maxSize){const e=this.cache.keys().next().value;void 0!==e&&this.cache.delete(e)}this.cache.set(e,t)}has(e){return this.cache.has(e)}delete(e){this.cache.delete(e)}clear(){this.cache.clear()}},Y=class{constructor(e){this.db=e}async list(){const e=p(this.db);await e.open();const t=await e.collection(h.WORKSPACE);return new J(t,new G(100)).list()}async delete(e){const t=p(this.db);await t.open();const s=await t.collection(h.WORKSPACE);return new J(s,new G(1)).delete(e)}async purge(){this.db.clear()}},H=class{constructor(e){this.manager=e}get workspace(){return this.manager.workspace()}roles(){return this.manager.ctx().roles.list()}role(e){return this.manager.ctx().roles.get(e)}async createRole(e,t,s,n,r=[]){if(this.workspace.index.roles[e])return g({code:"DUPLICATE_KEY",resource:"role",key:e});const i={name:e,label:t,description:n,persona:s,preferences:r,topics:[]};return this.manager.dispatch({type:"role:add",payload:i,timestamp:(new Date).toISOString()})}async updateRole(e,t){return this.workspace.index.roles[e]?this.manager.dispatch({type:"role:update",payload:{name:e,...t},timestamp:(new Date).toISOString()}):g({code:"NOT_FOUND",resource:"role",id:e})}async deleteRole(e){const t=this.workspace;if(!t.index.roles[e])return g({code:"NOT_FOUND",resource:"role",id:e});return Object.values(t.index.sessions).some((t=>t.role===e))?g({code:"INVALID_COMMAND",reason:`Cannot delete role "${e}" — it is still referenced by one or more sessions`}):this.manager.dispatch({type:"role:delete",payload:{name:e},timestamp:(new Date).toISOString()})}async addPreference(e,t){const s={id:crypto.randomUUID(),content:e,topics:t,timestamp:(new Date).toISOString()};return this.manager.dispatch({type:"preference:add",payload:s,timestamp:s.timestamp})}preferences(){return this.manager.ctx().preferences.list()}async addContext(e,t,s,n){const r={key:e,topics:s,content:t,timestamp:(new Date).toISOString(),metadata:n};return this.manager.dispatch({type:"context:add",payload:r,timestamp:r.timestamp})}context(){return this.manager.ctx().context.list()}async registerBlob(e,t,s){const n=await this.manager.dispatch({type:"blob:register",payload:{data:e,mediaType:t,filename:s},timestamp:(new Date).toISOString()});if(!n.ok)return g(n.error);const r=n.value,i=r?.index?.blobs;if(!i)return g({code:"BACKEND_ERROR",reason:"Blob registration succeeded but no blobs patch returned"});const o=Object.keys(i)[0];if(!o)return g({code:"BACKEND_ERROR",reason:"No SHA256 in patch"});const a=i[o];if(!a)return g({code:"BACKEND_ERROR",reason:"Blob record missing"});return y({sha256:o,ref:{sha256:o,mediaType:a.mediaType,sizeBytes:a.sizeBytes,filename:a.filename,previewUrl:a.previewUrl}})}},X=class e{constructor(e,t,s,n){this._id=e,this.manager=t,this.processor=s,this.turnRepository=n,this.workspace=new H(t),this.unsubscribe=t.subscribe("workspace:synced",(()=>this.sync()))}workspace;_role=void 0;_preferences=[];tree;unsubscribe;static async create(t,s,n){s.ctx().workspace;const r=new V(s.ctx().turns,s.ctx().sessions),i=new e(t,s,n,r);return await i.sync(),i}async sync(){await this._setRole(),await this._setPreference(),await this.refreshTurnTree()}close(){this.unsubscribe?.()}async _setRole(){const e=this.meta(),t=await this.manager.ctx().roles.get(e.role);t&&(this._role=t)}async _setPreference(){const e=this.meta();this._preferences=await this.manager.ctx().preferences.load(e.preferences)}id(){return this._id}ws(){return this.manager.workspace()}meta(){return this.ws().index.sessions[this._id]}label(){return this.meta()?.label}role(){return this._role}topics(){return this.meta()?.topics??[]}preferences(){return this._preferences}head(){return this.meta()?.head??null}turns(){return this.tree.chain()}async siblings(e){return this.tree.getTurnSiblings(e)}async branchInfo(e){return this.tree.branchInfo(e)}async getTurn(e){return this.tree.graph()[e]}async rename(e){return this.meta()?this.dispatch({type:"session:update",payload:{sessionId:this._id,label:e},timestamp:(new Date).toISOString()}):g({code:"NOT_FOUND",resource:"session",id:this._id})}async setTopics(e){return this.meta()?this.dispatch({type:"session:update",payload:{sessionId:this._id,topics:e},timestamp:(new Date).toISOString()}):g({code:"NOT_FOUND",resource:"session",id:this._id})}async setModel(e){return this.meta()?this.updateMetadata({model:e}):g({code:"NOT_FOUND",resource:"session",id:this._id})}async updateMetadata(e){const t=this.meta();if(!t)return g({code:"NOT_FOUND",resource:"session",id:this._id});const s={...t.metadata||{},...e};return this.dispatch({type:"session:update",payload:{sessionId:this._id,metadata:s},timestamp:(new Date).toISOString()})}async addTopics(e){return this.meta()?this.dispatch({type:"session:topics:add",payload:{sessionId:this._id,topics:e},timestamp:(new Date).toISOString()}):g({code:"NOT_FOUND",resource:"session",id:this._id})}async setPreferences(e){if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});const t=await this.dispatch({type:"session:preferences:override",payload:{sessionId:this._id,preferences:e},timestamp:(new Date).toISOString()});return t.ok&&await this._setPreference(),t}async fork(e,t,s,n){return this.meta()?this.dispatch({type:"session:fork",payload:{sessionId:this._id,newSessionId:e,label:t,role:s,topics:n},timestamp:(new Date).toISOString()}):g({code:"NOT_FOUND",resource:"session",id:this._id})}async dispatch(e){return this.manager.dispatch(e)}async switchRole(e){const t=this.ws();if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});if(e!==K&&!t.index.roles[e])return g({code:"NOT_FOUND",resource:"role",id:e});const s=await this.dispatch({type:"session:update",payload:{sessionId:this._id,role:e},timestamp:(new Date).toISOString()});return s.ok&&await this._setRole(),s}async addTurn(e){if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});const t=this.meta(),s={...e,session:this._id,version:e.version??0,parent:e.parent??this.head()??void 0,role:e.role??t?.role,model:e.model??t?.metadata?.model},n=await this.dispatch({type:"turn:add",payload:{sessionId:this._id,turn:s},timestamp:s.timestamp});return n.ok&&await this.refreshTurnTree(),n}async recordUserTurn(e){return this.meta()?this.addTurn(e):g({code:"NOT_FOUND",resource:"session",id:this._id})}async recordAssistantTurn(e,t){const s=this.ws();if(!s)return g({code:"NOT_FOUND",resource:"workspace",id:"current"});if(!s.index.sessions[this._id])return g({code:"NOT_FOUND",resource:"session",id:this._id});const n=this.processor.process(e,this._id);let r={};const i=[];let o;for(const e of n){const t=await this.manager.dispatch(e);if(t.ok)r=k(r,t.value);else{if("PERMISSION_DENIED"!==t.error.code||e.synthetic){o=t.error;break}{const t=this.describeCommand(e);i.push({cmd:e,description:t})}}}e.metadata=o?{...e.metadata,status:"unsuccessful",error:o}:{...e.metadata,status:"success"};const a=await this.addTurn(e);if(!a.ok)return a;if(r=k(r,a.value),t&&i.length>0){const e=this.buildDenialTurn(i),t=await this.addTurn(e);t.ok&&(r=k(r,t.value))}return o?g(o):y(r)}buildDenialTurn(e){const t=new W("user",this._id);for(const s of e)t.addText(`[System] User denied: ${s.description}.`);return t.build()}describeCommand(e){return"tool:call"===e.type?`tool execution: ${e.payload.tool}`:`command: ${e.type}`}async editTurn(e,t,s,n){if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});const r=this.tree.graph()[e];if(!r)return g({code:"NOT_FOUND",resource:"turn",id:e});const i=r.versions[r.activeVersion],o=r.activeVersion+1,a=await this.dispatch({type:"turn:edit",payload:{sessionId:this._id,turnId:e,newBlocks:t,roleSnapshot:s??i.role,modelSnapshot:n??i.model,newVersion:o},timestamp:(new Date).toISOString()});return a.ok&&(await this.dispatch({type:"session:update",payload:{sessionId:this._id,head:{id:e,version:o}},timestamp:(new Date).toISOString()}),await this.refreshTurnTree()),a}async branch(e){if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});if(!e.parent)return g({code:"INVALID_COMMAND",reason:"branch requires turn.parent to be set"});const t=await this.dispatch({type:"turn:branch",payload:{sessionId:this._id,turn:{...e,session:this._id}},timestamp:e.timestamp});return t.ok&&await this.refreshTurnTree(),t}async deleteTurn(e,t,s){if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});const n=this.tree.graph();if(!n[e]?.versions[t])return g({code:"NOT_FOUND",resource:"turn version",id:`${e}:${t}`});const r=await this.dispatch({type:"turn:delete",payload:{sessionId:this._id,turnId:e,version:t,newHead:s},timestamp:(new Date).toISOString()});return r.ok&&await this.refreshTurnTree(),r}async updateTurnStatus(e,t){const s=this.tree.graph()[e];if(!s)return g({code:"NOT_FOUND",resource:"turn",id:e});const n=s.versions[s.activeVersion],r={...n,metadata:{...n.metadata,status:t.ok?"success":"unsuccessful",error:t.ok?void 0:t.error}},i=await this.dispatch({type:"turn:update",payload:{sessionId:this._id,turn:r},timestamp:(new Date).toISOString()});return i.ok&&await this.refreshTurnTree(),i}async switchVersionLeft(e){return this.switchVersion(e,-1)}async switchVersionRight(e){return this.switchVersion(e,1)}async switchVersion(e,t){if(!this.ws())return g({code:"NOT_FOUND",resource:"workspace",id:"current"});if(!this.meta())return g({code:"NOT_FOUND",resource:"session",id:this._id});const s=this.tree.graph()[e];if(!s)return g({code:"NOT_FOUND",resource:"turn",id:e});const n=Object.keys(s.versions).map(Number).sort(((e,t)=>e-t)),r=n.indexOf(s.activeVersion);if(-1===r)return g({code:"INVALID_COMMAND",reason:"Active version not found"});const i=r+t;if(i<0||i>=n.length)return g({code:"INVALID_COMMAND",reason:`No ${t<0?"previous":"next"} version available for turn ${e}`});const o=n[i],a=this.findSubtreeTip(this.tree.graph(),e,o),c=await this.dispatch({type:"session:update",payload:{sessionId:this._id,head:a},timestamp:(new Date).toISOString()});return c.ok&&await this.refreshTurnTree(),c}async snapshot(e){const t=this,s=t.meta();if(!s)return;const n=t.ws(),r=t._role;if(!r)return;const i=await t.manager.ctx().context.getByTopics(n.index,s.topics),o=Array.from(new Set([...r.preferences,...s.preferences])),a=o.length>0?await t.manager.ctx().preferences.load(o):t._preferences,c=(e?t.tree.chainFrom(e):t.tree.chain()).map((e=>e.versions[e.activeVersion])).filter((e=>!!e)),d=[...c].reverse().find((e=>"user"===e.actor));return{id:t._id,meta:s,role:r,preferences:a,context:i,model:s.metadata?.model,transcript:c,topics:s.topics,instructions:n.settings?.prompt,constraints:{role:r.constraints,session:s.constraints,turn:d?.constraints}}}async refreshTurnTree(){this.tree=await L.build(this._id,this.turnRepository)}findSubtreeTip(e,t,s){let n=t,r=s;for(;;){const t=e[n];if(!t)break;const s=t.children[r];if(!s||0===s.length)break;const i=s[0],o=e[i];if(!o)break;n=i,r=o.activeVersion}return{id:n,version:r}}},Q=class{constructor(e,t){this.manager=e,this.processor=t}openOnce=new Map;async open(e){let t=this.openOnce.get(e);t||(t=new l,this.openOnce.set(e,t));const s=await t.do((async()=>{if(!this.manager.workspace().index.sessions[e])throw new Error(`Session ${e} not found in workspace index`);return X.create(e,this.manager,this.processor)}));if(s.error)throw s.error;return s.value}close(e){this.openOnce.delete(e)}async delete(e){const t=await this.manager.dispatch({type:"session:delete",payload:{sessionId:e},timestamp:(new Date).toISOString()});if(t.ok)return this.close(e),t.value=void 0,t;throw t.error}async has(e){return!this.manager.workspace().index.sessions[e]}async create(e){const s=t(),n=await this.manager.dispatch({type:"session:create",payload:{id:s,label:e.label,role:e.role,topics:e.topics,preferences:e.preferences??[],metadata:{created:(new Date).toISOString()}},timestamp:(new Date).toISOString()});if(n.ok)return this.open(s);throw n.error}list(){return Object.values(this.manager.workspace().index.sessions)}metadata(e){return this.manager.workspace().index.sessions[e]}},Z=class{constructor(e,t,s){this.storage=e,this.cache=t,this.bus=s}async register(e,t,s){const n=await x(e),r=await this.getRecord(n);if(r){const e={...r,refCount:r.refCount+1,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(e),this.cache.set(n,e),y(this.reference(e))}const i={sha256:n,mediaType:t,sizeBytes:e.byteLength,filename:s,refCount:1,remoteIds:{},createdAt:(new Date).toISOString(),lastUsedAt:(new Date).toISOString()};return this.storage.registerBlob?await this.storage.registerBlob(i,e):(await this.storage.storeBytes(n,e),await this.storage.saveRecord(i)),this.cache.set(n,i),this.bus.emit({name:"blobs:changed",payload:{sha256:n,record:i}}),y(this.reference(i))}async retain(e){const t=await this.getRecord(e);if(!t)return g({code:"NOT_FOUND",resource:"blob",id:e});const s={...t,refCount:t.refCount+1,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(s),this.cache.set(e,s),y(void 0)}async release(e){const t=await this.getRecord(e);if(!t)return g({code:"NOT_FOUND",resource:"blob",id:e});const s=Math.max(0,t.refCount-1),n={...t,refCount:s,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(n),this.cache.set(e,n),y(void 0)}async purge(e){return await this.storage.deleteBytes(e),await this.storage.deleteRecord(e),this.cache.delete(e),this.bus.emit({name:"blobs:changed",payload:{sha256:e}}),y(void 0)}async recordRemoteId(e,t,s,n){const r=await this.getRecord(e);if(!r)return g({code:"NOT_FOUND",resource:"blob",id:e});const i={...r,remoteIds:{...r.remoteIds,[t]:{id:s,timestamp:n||(new Date).toISOString()}},lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(i),this.cache.set(e,i),this.bus.emit({name:"blobs:changed",payload:{sha256:e,record:i}}),y(void 0)}async getRecord(e){const t=this.cache.get(e);if(t)return t;const s=await this.storage.loadRecord(e);return s&&this.cache.set(e,s),s}async getAllRecords(){const e=await this.storage.listRecords(),t={};for(const s of e)t[s.sha256]=s,this.cache.set(s.sha256,s);return t}reference(e){return{sha256:e.sha256,mediaType:e.mediaType,sizeBytes:e.sizeBytes,filename:e.filename}}async resolve(e,t){const s=await this.getRecord(e.sha256);if(!s)return y(null);if(t){const e=s.remoteIds[t];if(e)return y({kind:"remote",sha256:s.sha256,mediaType:s.mediaType,fileId:e.id,providerId:t,timestamp:e.timestamp});const n=await this.storage.loadBytes(s.sha256);return y(n?{kind:"inline",sha256:s.sha256,mediaType:s.mediaType,data:n}:null)}const n=await this.storage.loadBytes(s.sha256);return y(n?{kind:"inline",sha256:s.sha256,mediaType:s.mediaType,data:n}:null)}async resolveMany(e,t){const s=new Map;for(const n of e){const e=await this.resolve(n,t);if(!e.ok)return g(e.error);if(null===e.value)return g({code:"BLOB_ERROR",reason:`Unable to resolve blob ${n.sha256}${t?` with adapter ${t}`:""}`});s.set(n.sha256,e.value)}return y(s)}},ee=class{constructor(e,t,s){this.collection=e,this.cache=t,this.registry=s}delegates=new Map;registerDelegate(e,t){this.delegates.set(e,t)}async get(e,t){const s=this.cache.get(e);if(s)return s;if(t){const s=this.delegates.get(t);if(s){const t=await s.get(e);return t&&this.cache.set(e,t),t}}const n=await this.collection.find({field:"key",operator:"eq",value:e});if(!n)return null;const r=n.state();return this.cache.set(e,r),r}async add(e){const t=this.delegates.get(e.content.kind);t?await t.add(e):await this.collection.create(e),this.cache.set(e.key,e)}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"}),t=((await e.next()).value||[]).map((e=>e.state()));for(const e of this.delegates.values()){const s=await e.list();t.push(...s)}return t}async update(e,t,s){if(s){const n=this.delegates.get(s);if(n){const s=await n.update(e,t);return s&&this.cache.set(e,s),s}}const n=await this.collection.find({field:"key",operator:"eq",value:e});if(!n)return null;await n.update(t);const r=n.state();return this.cache.set(e,r),r}async delete(e,t){if(t){const s=this.delegates.get(t);if(s){const t=await s.delete(e);return t&&this.cache.delete(e),t}}const s=await this.collection.find({field:"key",operator:"eq",value:e});if(!s)return!1;const n=await s.delete();return n&&this.cache.delete(e),n}async getByTopics(e,t){const s=new Map;for(const n of t){const t=e.topics[n];t&&t.contextKeys.forEach((t=>{const n=e.context[t],r=n?.kind||"unknown";s.has(r)||s.set(r,new Set),s.get(r).add(t)}))}if(0===s.size)return[];const n=[],r=[];for(const[e,t]of s.entries()){if(this.delegates.get(e))for(const s of t){const t=await this.get(s,e);t&&n.push(t)}else t.forEach((e=>r.push(e)))}if(r.length>0){const e=[];for(const t of r){const s=this.cache.get(t);s?n.push(s):e.push(t)}if(e.length>0){const t=await this.collection.filter({operator:"or",conditions:e.map((e=>({field:"key",operator:"eq",value:e})))});for(const e of t){const t=e.state();this.cache.set(t.key,t),n.push(t)}}}return n.sort(((e,t)=>new Date(t.timestamp).getTime()-new Date(e.timestamp).getTime()))}summarize(e){const t=this.registry?.get(e.content.kind);return t?t.summarize(e):{kind:e.content.kind,key:e.key,topics:e.topics,timestamp:e.timestamp,metadata:e.metadata}}},te=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;const n=s.state();return this.cache.set(e,n),n}async add(e){await this.collection.create(e),this.cache.set(e.id,e)}async update(e,t){const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;await s.update(t);const n=s.state();return this.cache.set(e,n),n}async delete(e){const t=await this.collection.find({field:"id",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async load(e){if(0===e.length)return[];const t=[],s=[];for(const n of e){const e=this.cache.get(n);e?s.push(e):t.push(n)}if(t.length>0){const e=await this.collection.filter({operator:"or",conditions:t.map((e=>({field:"id",operator:"eq",value:e})))});for(const t of e){const e=t.state();this.cache.set(e.id,e),s.push(e)}}return s}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return{id:e.id,topics:e.topics,timestamp:e.timestamp,snippet:e.content.slice(0,100)}}},se=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;const n=s.state();return this.cache.set(e,n),n}async add(e){await this.collection.create(e),this.cache.set(e.name,e)}async update(e,t){const s=await this.collection.find({field:"name",operator:"eq",value:e});if(!s)return null;await s.update(t);const n=s.state();return this.cache.set(e,n),n}async delete(e){const t=await this.collection.find({field:"name",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return{name:e.name,label:e.label,description:e.description,preferences:e.preferences?.length??0,topics:e.topics??[],constraints:e.constraints}}},ne=class{constructor(e,t){this.collection=e,this.cache=t}async get(e){const t=this.cache.get(e);if(t)return t;const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;const n=s.state();return this.cache.set(e,n),n}async add(e){await this.collection.create(e),this.cache.set(e.id,e)}async update(e,t){const s=await this.collection.find({field:"id",operator:"eq",value:e});if(!s)return null;await s.update(t);const n=s.state();return this.cache.set(e,n),n}async delete(e){const t=await this.collection.find({field:"id",operator:"eq",value:e});if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(e),s}async list(){const e=await this.collection.list({limit:1e3,type:"cursor",direction:"forward"});return((await e.next()).value||[]).map((e=>e.state()))}summarize(e){return e}},re=class{constructor(e,t){this.collection=e,this.cache=t}key({id:e,session:t,version:s}){return`${t}:${s}:${e}`}async find({id:e,session:t,version:s},n=!0){const r=this.key({id:e,session:t,version:s});this.cache.get(r)&&this.cache.get(r);const i=await this.collection.find({operator:"and",conditions:[{field:"id",operator:"eq",value:e},{field:"session",operator:"eq",value:t},{field:"version",operator:"eq",value:s}]});return i?(n&&this.cache.set(r,i),i):null}async get(e){return this.find(e)}async add(e){const t=await this.collection.create(e);this.cache.set(this.key(e),t)}async update(e,t){const s=await this.find(e);return s?(await s.update(t),s.state()):null}async listBySession(e){return(await this.collection.filter({field:"session",operator:"eq",value:e})).map((e=>e.state()))}async delete(e){const t=await this.find(e,!1);if(!t)return!1;const s=await t.delete();return s&&this.cache.delete(this.key(e)),s}},ie=(e={})=>({id:t(),label:"New Conversation",role:"assistant-default",topics:[],preferences:[],metadata:{created:(new Date).toString(),updated:(new Date).toString()},...e,head:e.head?e.head:void 0}),oe=(e={},s)=>({id:e.id??t(),version:e.version??0,session:e.session??s?.id??t(),actor:"user",blocks:[{id:t(),type:"text",text:"Hello, world!"}],timestamp:(new Date).toString(),role:s?.role,...e,parent:e.parent?e.parent:void 0}),ae=(e={})=>({id:e.id??t(),settings:k({language:"en-US",defaultRole:void 0,prompt:void 0},e.settings),project:k({id:t(),name:"Unnamed Project"},e.project),index:k({roles:{},preferences:{},context:{},sessions:{},topics:{},blobs:{},tools:{},extensions:{}},e.index)});function ce(e,t,s){const n=new Set([...Object.keys(e??{}),...Object.keys(t??{}),...Object.keys(s??{})]),r={};for(const i of n){const n=e?.[i]??{},o=t?.[i]??{},a=s?.[i]??{};r[i]={temperature:a.temperature??o.temperature??n.temperature,tokens:{max:a.tokens?.max??o.tokens?.max??n.tokens?.max,stops:a.tokens?.stops??o.tokens?.stops??n.tokens?.stops,thought:a.tokens?.thought??o.tokens?.thought??n.tokens?.thought}}}return r}function de(e,s,n){return{id:t(),session:e,version:0,actor:s,blocks:n,timestamp:(new Date).toISOString()}}var le=class{constructor(e,t,s){this.contextRegistry=e,this.retriever=t,this.summarizer=s}async build(e,s,n={}){const r=[],{resolved:i}=function(e){const t=[],s=new Map;for(const n of e)for(const e of n.topics){const r=s.get(e);if(!r){s.set(e,n);continue}const i=new Date(r.timestamp).getTime(),o=new Date(n.timestamp).getTime();o>i?(t.push({topic:e,kept:n.id,dropped:r.id}),s.set(e,n)):i>o&&t.push({topic:e,kept:r.id,dropped:n.id})}const n=new Map,r=new Map;for(const t of e)r.set(t.id,t.topics.length);for(const e of t)n.set(e.dropped,(n.get(e.dropped)??0)+1);const i=new Set;for(const t of e){const e=n.get(t.id)??0,s=r.get(t.id)??0;s>0&&e>=s&&i.add(t.id)}return{resolved:e.filter((e=>!i.has(e.id))),conflicts:Array.from(new Map(t.map((e=>[`${e.topic}:${e.dropped}`,e]))).values())}}(e.preferences),o=function(e,t=3){return e.filter((e=>"user"===e.actor)).slice(-t).flatMap((e=>e.blocks.filter((e=>"text"===e.type)).map((e=>e.text)).filter(Boolean)))}(e.transcript),a=this.retriever.rank({entries:e.context,recentMessages:o,topics:e.topics,config:n.retrieverConfig}),c=[],d=[];for(const e of a){const t=this.contextRegistry.get(e.content.kind);if(!t){r.push(`No ContextDefinition found for kind: ${e.content.kind}`);continue}const s=t.render(e),n=Array.isArray(s)?s:[s];"system"===t.target?c.push({label:`context:${e.content.kind}:${e.key}`,content:n.map((t=>"text"===t.type?t.text:`[${e.content.kind}] ${JSON.stringify(t,null,2)}`)).join("\n"),position:"after:context"}):d.push(...n)}let l=e.transcript;if(n.summarize&&this.summarizer&&l.length>0){const s=2e3;try{const n=await this.summarizer.summarize(l,s),r=[];n.summary&&r.push(de(e.id,"system",[{id:t(),type:"summary",text:n.summary}])),l=[...r,...n.remaining]}catch(e){r.push(`Summarizer failed: ${e instanceof Error?e.message:String(e)}`)}}const u=[];d.length>0&&u.push(de(e.id,"user",d));const p=function(e,s){const n=[];let r=null,i=!1;for(const o of e)"user"===o.actor&&o.role&&(i&&o.role!==r&&n.push(de(s,"system",[{id:t(),type:"role:transition",previousRole:r??void 0,newRole:o.role}])),r=o.role,i=!0),n.push(o);return n}(l,e.id),h=[...u,...p],m=function(e,t){const s=new Map;for(const t of e)if("blob"===t.content.kind){const{sha256:e,mediaType:n,sizeBytes:r,filename:i,previewUrl:o}=t.content;s.has(e)||s.set(e,{sha256:e,mediaType:n,sizeBytes:r,filename:i,previewUrl:o})}for(const e of t)for(const t of e.blocks)if("image"===t.type||"document"===t.type){const e=t.ref;e&&!s.has(e.sha256)&&s.set(e.sha256,e)}return s}(a,h);return y({session:e.id,model:e.model,system:{persona:e.role.persona,instructions:e.instructions,preferences:i,context:[],extensions:c},transcript:h,blobs:m,role:e.role,constraints:ce(e.constraints.role,e.constraints.session,e.constraints.turn),warnings:r})}},ue=class{constructor(e){this.contextRegistry=e}rank(e){const{entries:t,recentMessages:s,config:n={}}=e,r=n.minScore??0,i=n.freshnessHalfLifeDays??30,o=n.recentMessageWindow??3;if(0===s.length)return[...t].sort(((e,t)=>this.freshnessWeight(t.timestamp,i)-this.freshnessWeight(e.timestamp,i)));const a=this.tokenize(s.slice(-o).join(" "));return t.map((e=>{const t=function(e,t){const s=t.get(e.content.kind);return s?s.toString(e):""}(e,this.contextRegistry);return{entry:e,score:.7*this.jaccardSimilarity(a,this.tokenize(t))+.3*this.freshnessWeight(e.timestamp,i)}})).filter((e=>e.score>r)).sort(((e,t)=>t.score-e.score)).map((e=>e.entry))}tokenize(e){return new Set(e.toLowerCase().replace(/[^\w\s]/g," ").split(/\s+/).filter((e=>e.length>2)))}jaccardSimilarity(e,t){if(0===e.size&&0===t.size)return 0;let s=0;for(const n of e)t.has(n)&&s++;const n=e.size+t.size-s;return 0===n?0:s/n}freshnessWeight(e,t){const s=(Date.now()-new Date(e).getTime())/864e5;return Math.pow(.5,s/t)}},pe=class{bytes=new Map;records=new Map;async storeBytes(e,t){this.bytes.has(e)||this.bytes.set(e,t)}async loadBytes(e){return this.bytes.get(e)??null}async hasBytes(e){return this.bytes.has(e)}async deleteBytes(e){this.bytes.delete(e)}async saveRecord(e){this.records.set(e.sha256,{...e})}async loadRecord(e){return this.records.get(e)??null}async deleteRecord(e){this.records.delete(e)}async listRecords(){return Array.from(this.records.values()).map((e=>({...e})))}async exportAllBytes(){return Array.from(this.bytes.entries()).map((([e,t])=>[e,new Uint8Array(t)]))}async registerBlob(e,t){this.bytes.has(e.sha256)||this.bytes.set(e.sha256,t),this.records.set(e.sha256,{...e})}},he="blob_bytes",me="blob_records";function fe(e){return new Promise(((t,s)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>s(e.error)}))}function ye(e){return new Promise(((t,s)=>{e.oncomplete=()=>t(),e.onerror=()=>s(e.error),e.onabort=()=>s(new Error("Transaction aborted"))}))}var ge=class{dbName;db=null;constructor(e={}){this.dbName=e.dbName??"aiworkspace-blobs"}async open(){this.db||(this.db=await new Promise(((e,t)=>{const s=indexedDB.open(this.dbName,1);s.onupgradeneeded=e=>{const t=e.target.result;this.createSchema(t)},s.onsuccess=()=>e(s.result),s.onerror=()=>t(s.error),s.onblocked=()=>t(new Error(`[IndexedDBBlobStorage] Database "${this.dbName}" blocked.`))})),this.db.onversionchange=()=>{this.db?.close(),this.db=null})}createSchema(e){e.objectStoreNames.contains(he)||e.createObjectStore(he,{keyPath:"sha256"}),e.objectStoreNames.contains(me)||e.createObjectStore(me,{keyPath:"sha256"})}close(){this.db?.close(),this.db=null}async deleteDatabase(){this.close(),await new Promise(((e,t)=>{const s=indexedDB.deleteDatabase(this.dbName);s.onsuccess=()=>e(),s.onerror=()=>t(s.error)}))}getDB(){if(!this.db)throw new Error("[IndexedDBBlobStorage] Database not open. Call open() first.");return this.db}readTx(...e){return this.getDB().transaction(e,"readonly")}writeTx(...e){return this.getDB().transaction(e,"readwrite")}async storeBytes(e,t){const s=this.readTx(he);if(await fe(s.objectStore(he).get(e)))return;const n=this.writeTx(he);n.objectStore(he).put({sha256:e,data:t}),await ye(n)}async loadBytes(e){const t=this.readTx(he),s=await fe(t.objectStore(he).get(e));return s?.data??null}async hasBytes(e){const t=this.readTx(he);return await fe(t.objectStore(he).count(e))>0}async deleteBytes(e){const t=this.writeTx(he);t.objectStore(he).delete(e),await ye(t)}async saveRecord(e){const t=this.writeTx(me);t.objectStore(me).put(e),await ye(t)}async loadRecord(e){const t=this.readTx(me);return await fe(t.objectStore(me).get(e))??null}async deleteRecord(e){const t=this.writeTx(me);t.objectStore(me).delete(e),await ye(t)}async listRecords(){return fe(this.readTx(me).objectStore(me).getAll())}async exportAllBytes(){const e=this.readTx(he);return(await fe(e.objectStore(he).getAll())).map((({sha256:e,data:t})=>[e,t]))}async registerBlob(e,t){await new Promise(((s,n)=>{const r=this.getDB().transaction([he,me],"readwrite"),i=r.objectStore(he),o=r.objectStore(me),a=i.count(e.sha256);a.onsuccess=()=>{0===a.result&&i.put({sha256:e.sha256,data:t}),o.put(e)},a.onerror=()=>n(a.error),r.oncomplete=()=>s(),r.onerror=()=>n(r.error),r.onabort=()=>n(new Error("registerBlob transaction aborted"))}))}},we={};((e,t)=>{for(var s in t)n(e,s,{get:t[s],enumerable:!0})})(we,{GOOGLE_MODELS:()=>ke,GoogleGenAIAdapter:()=>Ne,mapBlockToPart:()=>Oe,mapTurnToContent:()=>_e,mappings:()=>be,parseModelResponse:()=>ve});var be={text:{to:e=>({text:e.text}),from:e=>({id:s(),type:"text",text:e.text})},summary:{to:e=>({text:`[Summary]: ${e.text}`}),from:e=>({id:s(),type:"summary",text:e.text})},thinking:{to:e=>({text:e.thinking}),from:e=>({id:s(),type:"thinking",thinking:e.thinking})},"tool:use":{to:e=>({functionCall:{name:e.name,args:e.input}}),from:e=>({id:s(),type:"tool:use",name:e.functionCall?.name??e.name,input:e.functionCall?.args??e.input??{}})},"tool:result":{to:e=>({functionResponse:{name:e.useId,response:{result:e.content}}}),from:e=>({id:s(),type:"tool:result",useId:e.useId,content:e.content,isError:e.isError})},"role:transition":{to:e=>({text:`[Role transition: ${e.previousRole??"none"} → ${e.newRole}]`}),from:e=>({id:s(),type:"role:transition",previousRole:e.previousRole,newRole:e.newRole})}},ke=[{provider:"google",name:"gemini-3.1-pro-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:2,output:12,cache:{read:.2,write:4.5}}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-3-flash-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.5,output:3,cache:{read:.05,write:1}}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-3.1-flash-lite-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.25,output:1.5,cache:{read:.025,write:1}}}],capacity:[{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-2.5-pro",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:1.25,output:10,cache:{read:.125,write:4.5}}}],capacity:[{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-2.5-flash",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.3,output:2.5,cache:{read:.03,write:1}}}],capacity:[{unit:"call",max:4e3,period:60},{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-2.5-flash-lite",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.1,output:.4,cache:{read:.01,write:1}}}],capacity:[{unit:"call",max:4e3,period:60},{unit:"token",max:4e6,period:60}]},{provider:"google",name:"gemini-3-pro-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!0,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:2,output:12,cache:{read:.2,write:4.5}}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-2.5-flash-image",window:{size:4096,out:0},feature:{vision:!1,tools:!1,json:!1,cache:!1,streaming:!1,thinking:!1},pricing:[{unit:"image",scale:0,cost:{input:.02,output:0}}],capacity:[{unit:"call",max:100,period:60}]},{provider:"google",name:"gemini-2.5-flash-live-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.5,output:3}}],capacity:[{unit:"concurrent",max:10,period:0}]},{provider:"google",name:"gemini-3.1-flash-live-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.5,output:3}}],capacity:[{unit:"concurrent",max:10,period:0}]},{provider:"google",name:"gemini-2.5-computer-use-preview",window:{size:1048576,out:65536},feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:1.25,output:10}}],capacity:[{unit:"call",max:200,period:60},{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-embedding-001",window:{size:2048,out:0},feature:{vision:!1,tools:!1,json:!1,cache:!1,streaming:!1,thinking:!1},pricing:[{unit:"token",scale:6,cost:{input:.5,output:0}}],capacity:[{unit:"token",max:1e6,period:60}]},{provider:"google",name:"gemini-embedding-2",window:{size:8192,out:0},feature:{vision:!1,tools:!1,json:!1,cache:!1,streaming:!1,thinking:!1},pricing:[{unit:"token",scale:6,cost:{input:.3,output:0}}],capacity:[{unit:"token",max:1e6,period:60}]}];function xe(e){let t=e;return(t.match(/```/g)||[]).length%2!=0&&(t+="\n```"),t.includes('\\"')&&!t.includes('"')&&(t=t.replace(/\\"/g,'"')),t}function ve(e,s){const n=e.candidates?.[0];if(!n?.content?.parts)return g({code:"BACKEND_ERROR",reason:"No valid content parts in response"});const r=[];let i;for(const e of n.content.parts)if(e.thought)r.push((o=e.text??"",{id:t(),type:"thinking",thinking:o}));else if(e.text){i=e;break}var o;if(!i)return r.length>0?y(r):g({code:"BACKEND_ERROR",reason:"Response missing JSON part"});const a=function(e){try{const t=JSON.parse(e);return t.blocks&&Array.isArray(t.blocks)?y(t.blocks):g({code:"BACKEND_ERROR",reason:'Invalid response: missing or malformed "blocks" array'})}catch(e){return g({code:"BACKEND_ERROR",reason:`Failed to parse response JSON: ${e instanceof Error?e.message:String(e)}`})}}(i.text);if(!a.ok)return r.push(function(e){return{id:t(),type:"text",text:xe(e)}}(i.text)),y(r);for(const e of a.value){const t=s.parse(e,Ne.provider());t&&r.push(t)}return y(r)}async function _e(e,t,s){const n="assistant"===e.actor?"model":"user",r=[];for(const n of e.blocks){if("image"===n.type||"document"===n.type){const e=n.ref;if(!e)continue;const s=await Se(e,t);s&&r.push(s);continue}const e=Oe(n,s);e&&r.push(e)}return{role:n,parts:r}}function Oe(e,t){const s=t.get(e.type);if(!s)throw new Error(`[GoogleGenAIAdapter] mapBlockToPart: block type "${e.type}" is not registered. Register it via registry.register() before use.`);const n=s.mappings?.[Ne.provider()];if(!n)throw new Error(`[GoogleGenAIAdapter] mapBlockToPart: no "${Ne.provider()}" mapping for block type "${e.type}". Add a mapping via registry.update("${e.type}", { mappings: { ${Ne.provider()}: { to, from } } }).`);return n.to(e)}async function Se(e,t){const s=await t(e,Ne.provider());if(!s.ok||!s.value)return null;const{value:n}=s;return"remote"===n.kind?{fileData:{fileUri:n.fileId,mimeType:n.mediaType}}:{inlineData:{data:v(n.data),mimeType:n.mediaType}}}function Te(e){return Math.ceil(e.length/4)}var Ne=class e{constructor(e,t,s={model:"gemini-2.5-flash"}){this.client=e,this.services=t,this._models=t.models;const n=this._models.get(s.model);if(!n)throw new Error(`Could not get model: ${s.model} profile in registry.`);this.model=n,this.registerGeminiMappings()}model;_models;registerGeminiMappings(){const t=this.services.blockRegistry;for(const[s,n]of Object.entries(be))t.update(s,{mappings:{[e.provider()]:n}})}async status(t){return{provider:e.provider(),model:this.model.name,ready:!0,window:this.model.window,feature:{vision:!0,tools:!0,json:!0,cache:!1,streaming:!0,thinking:!0},pricing:[{unit:"token",scale:6,cost:{input:.1,output:.4}}],rate:{load:0,capacity:[{unit:"call",max:1e3,period:60},{unit:"token",max:4e6,period:60}]}}}async resolve(e){const{prompt:s}=e,{assembler:n,blockRegistry:r,blobResolver:i}=this.services,o=s.model&&this._models.get(s.model)||this.model,a=n.build(s,[{label:"block-architecture",content:r.description(),position:"after:instructions"}]),c=n.join(a),d={role:"system",parts:[{text:c}]},l=s.constraints[o.name]??{tokens:{}},u=await Promise.all(s.transcript.map((e=>_e(e,i,r)))),p=r.schema(),h={model:o.name,contents:u,config:{systemInstruction:d,thinkingConfig:{includeThoughts:!0},responseMimeType:"application/json",responseSchema:p,...void 0!==l.temperature&&{temperature:l.temperature},...void 0!==l.tokens.max&&{maxOutputTokens:l.tokens.max},...l.tokens.stops?.length&&{stopSequences:l.tokens.stops},...void 0!==l.tokens.thought&&{thinkingConfig:{includeThoughts:!0,thinkingBudget:l.tokens.thought}}}},m=u.flatMap((e=>e.parts??[])).map((e=>e.text??"")).join(""),f=Te(c),w=Te(m),b=f+w,k=this;return{model:o.name,instructions:a,transcript:s.transcript,context:s.system.context,preferences:s.system.preferences,constraints:l,tokens:{breakdown:{system:f,transcript:w},total:b,source:"estimated",output:l.tokens.max??o.window.out,remaining:o.window.size-b},async execute(){let e;try{e=await k.client.models.generateContent(h)}catch(e){return g({code:"BACKEND_ERROR",reason:e instanceof Error?e.message:String(e)})}const t=ve(e,k.services.blockRegistry);if(!t.ok)return t;const n=t.value,r=new W("assistant",s.session);for(const e of n)r.addBlock(e);return y({turn:r.build(),effects:[]})},async*executeStream(){let e;try{e=await k.client.models.generateContentStream(h)}catch(e){const n=e instanceof Error?e.message:String(e),r=new W("assistant",s.session);return r.addBlock({id:t(),type:"text",text:`[Stream error: ${n}]`}),void(yield{turn:r.build(),effects:[]})}const n=[];for await(const s of e){const e=s.candidates?.[0];if(e?.content?.parts)for(const s of e.content.parts)s.thought||s.text&&(n.push(s.text),yield{blocks:[{id:t(),type:"text",text:s.text}]})}const r=n.join(""),i=new W("assistant",s.session);i.addBlock({id:t(),type:"text",text:r}),yield{turn:i.build(),effects:[]}}}}static provider(){return"google"}static models(){return ke}};async function Re(t){const{blobStorage:s,eventBus:n=e(),getWorkspace:i,setWorkspace:o,processor:a,guard:c,toolRegistry:d,models:l=[],extensions:u=[],extensionReducers:m={},extensionMiddleware:f=[],extensionIndexers:y=[],extensionStores:g,extensionSchemas:w=[]}=t,b=p(t.db),k=[...w,...u.flatMap((e=>e.schemas??[]))],x={...m,...u.reduce(((e,t)=>({...e,...t.reducers})),{})},v=[...f,...u.flatMap((e=>e.middleware??[]))],_=[...y,...u.flatMap((e=>e.indexers??[]))],O=u.flatMap((e=>e.blocks??[]));await b.open(k);const N={workspace:await b.collection(h.WORKSPACE),role:await b.collection(h.ROLE),preference:await b.collection(h.PREFERENCE),context:await b.collection(h.CONTEXT),session:await b.collection(h.SESSION),topic:await b.collection(h.TOPIC),turn:await b.collection(h.TURN)},R=new Z(s,new G(200),n),D=new P,I={workspaceStore:new J(N.workspace,new G(1)),roles:new se(N.role,new G(100)),preferences:new te(N.preference,new G(500)),context:new ee(N.context,new G(500),D),topics:new T(N.topic,new G(100)),sessions:new ne(N.session,new G(50)),turns:new re(N.turn,new G(50)),blobs:R,tools:d,db:b,indexers:[...r,..._]};if(g){const e=g(I);Object.assign(I,e)}await Promise.all(u.map((async e=>{if(e.stores){const t=await e.stores(I);Object.assign(I,t)}})));const j=new S({ctx:I,getWorkspace:i,updateWorkspace:async e=>{if(await o(e),e?.id||e?.settings||e?.project){const e=i();await I.workspaceStore.update(e.id,{id:e.id,settings:e.settings,project:e.project})}},guard:c,bus:n});Object.entries(U).forEach((([e,t])=>{j.register(e,t)})),Object.entries(x).forEach((([e,t])=>{j.register(e,t)})),j.use(E),v.forEach((e=>{j.use(e)}));const A=new Q(j,a),B=new F;O.forEach((e=>B.register(e))),u.forEach((e=>{e.contexts&&e.contexts.forEach((e=>{if(D.register(e),e.store){const t=e.store(I);I.context.registerDelegate(e.kind,t)}}))}));const q=new $(l),z={assembler:new C,processor:a,blobResolver:I.blobs.resolve.bind(I.blobs),blockRegistry:B,contextRegistry:D,models:q},M=async e=>{await j.dispatch({type:"workspace:sync",payload:void 0,timestamp:(new Date).toISOString()});let t=i();await j.dispatch({type:"workspace:create",payload:e.workspace,timestamp:(new Date).toISOString()}),t=i();const s=[];if(e.roles)for(const n of e.roles)t.index.roles[n.name]||(await j.dispatch({type:"role:add",payload:n,timestamp:(new Date).toISOString()}),s.push(n.name));return e.workspace.settings.defaultRole&&t.settings.defaultRole!==e.workspace.settings.defaultRole&&await j.dispatch({type:"workspace:sync",payload:{settings:{...t.settings,defaultRole:e.workspace.settings.defaultRole}},timestamp:(new Date).toISOString()}),{workspace:i(),roles:s}};if(t.bootstrap){const e=i();if(!e||!e.index){const e=ae({id:t.bootstrap.workspace.id,settings:t.bootstrap.workspace.settings,project:t.bootstrap.workspace.project});await o(e)}await M(t.bootstrap)}return{manager:j,sessions:A,ctx:I,services:z,bootstrap:M}}export{h as COLLECTIONS,le as DefaultPromptBuilder,C as DefaultSystemPromptAssembler,K as EMPTY_SYSTEM_ROLE,we as GoogleAdapter,ge as IndexedDBBlobStorage,ue as JaccardContextRetriever,G as LRUCache,pe as MemoryBlobStorage,X as Session,Q as SessionManager,W as TurnBuilder,L as TurnTree,H as WorkspaceApi,S as WorkspaceManager,Y as WorkspaceRegistry,v as bufferToBase64,x as computeSHA256,q as createDefaultAssembler,ie as createEmptySession,oe as createEmptyTurn,ae as createEmptyWorkspace,Re as createWorkspace,p as createWorkspaceDatabase,b as del,g as error,O as getExtension,k as merge,w as omitNullUndefined,_ as shortHash,y as success};
|