@granular-software/sdk 0.4.57 → 0.4.59

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.
@@ -1,19 +1,23 @@
1
- import { bM as WSClientOptions, a2 as GranularQuotaProgress, T as ToolWithHandler, f as PublishToolsResult, aO as Job, g as ToolHandler, I as InstanceToolHandler, aY as ConversationMessageInput, aZ as ConversationAppendResult, aB as EffectInfo, P as Prompt, aA as ToolInfo, aD as EffectsChangedEvent, aC as ToolsChangedEvent, D as DomainState, y as GranularOptions, ci as EnvironmentImporter, B as RecordUserOptions, U as User, H as OpenEnvironmentOptions, af as EnvironmentData, ac as BuildPolicy, cf as EnvironmentSetupSummary, W as ConversationSessionListOptions, Q as ConversationSessionInfo, L as CreateSessionOptions, bW as RecordObjectOptions, c1 as RecordObjectResult, c3 as RecordObjectsOptions, ca as RecordImport, c6 as RecordImportStatus, c9 as RecordImportItem, cb as EnvironmentRecordImportSummary, aM as EnvironmentFeedbackRecord, c as SessionHeapSnapshot, bA as SessionDocumentResult, bB as SessionCollectionListOptions, bD as SessionCollectionListResult, a_ as SessionConversationMessage, a$ as SessionTimelineEvent, bC as SessionJobListOptions, bt as SessionJobRecord, b8 as SessionArtifactListOptions, b7 as SessionArtifactRecord, b9 as SessionArtifactValidationResult, bb as SessionArtifactExecutionOptions, ba as SessionArtifactExecutionResult, bc as SessionArtifactApprovalOptions, bm as RecordManualActionInput, bo as ManualActionRecordResult, bp as ManualActionListOptions, bn as ManualActionOccurrence, br as ManualActionSuggestionOptions, bq as ManualActionSuggestion, bf as ArtifactApprovalTaskListOptions, be as ArtifactApprovalTask, bg as ArtifactApprovalDecisionInput, bh as ArtifactApprovalDecisionResult, b3 as SessionFileRecord, bs as SessionFileUploadOptions, S as SessionHeapEntry, b as SessionHeapList, bw as SessionHeapVariable, d as SessionTranscriptEntry, cM as GraphQLResult, by as RecordSearchOptions, bx as RecordSearchResult, bz as RecordMentionInput, bV as DefineRelationshipOptions, bU as RelationshipInfo, bT as ModelRef, cL as ManifestContent, b_ as EnvironmentStateUpdateInput, bY as EnvironmentStateTarget, c0 as EnvironmentStateProxy, c5 as RecordImportOptions, bI as UserEnvironmentStateOptions, bH as UserEnvironmentState, bJ as MarkUserEnvironmentReadOptions, J as AdoptEnvironmentOptions, K as ConnectOptions, cd as RunEnvironmentImporterOptions, l as OpenAIUsageSpendEvent, G as GranularSpendContext, o as RecordOpenAIUsageSpendResult, a5 as SandboxListResponse, a3 as Sandbox, a4 as CreateSandboxData, cO as DeleteResponse, a7 as PermissionProfile, a8 as CreatePermissionProfileData, ag as CreateEnvironmentData, cP as StreamEvent, cQ as StreamSubscription, cR as StreamStats, F as Subject, ab as AssignmentListResponse } from './spend-DpRRCrAr.js';
1
+ import { cN as WSClientOptions, Y as SessionFeedApi, a$ as GranularQuotaProgress, T as ToolWithHandler, g as PublishToolsResult, bP as Job, h as ToolHandler, I as InstanceToolHandler, bS as UserMessageInput, bT as UserMessageAppendResult, bC as EffectInfo, P as Prompt, bB as ToolInfo, bE as EffectsChangedEvent, bD as ToolsChangedEvent, D as DomainState, $ as FeedListTransport, aI as GranularOptions, dj as EnvironmentImporter, aL as RecordUserOptions, aK as User, aN as OpenEnvironmentOptions, bc as EnvironmentData, b9 as BuildPolicy, dg as EnvironmentSetupSummary, aT as ConversationSessionListOptions, aR as ConversationSessionInfo, aQ as CreateSessionOptions, cX as RecordObjectOptions, d2 as RecordObjectResult, d4 as RecordObjectsOptions, db as RecordImport, d7 as RecordImportStatus, da as RecordImportItem, dc as EnvironmentRecordImportSummary, bN as EnvironmentFeedbackRecord, d as SessionHeapSnapshot, cB as SessionDocumentResult, bU as AssistantReplyPublicationInput, bV as AssistantReplyPublicationResult, cC as SessionCollectionListOptions, cE as SessionCollectionListResult, bY as SessionTimelineEvent, cD as SessionJobListOptions, cu as SessionJobRecord, c5 as SessionArtifactListOptions, c4 as SessionArtifactRecord, c7 as SessionArtifactRelationshipOptionsInput, c9 as SessionArtifactRelationshipOptionsResult, ca as SessionArtifactRelationshipCreateInput, c6 as SessionArtifactValidationResult, cc as SessionArtifactExecutionOptions, cb as SessionArtifactExecutionResult, cd as SessionArtifactApprovalOptions, cn as RecordManualActionInput, cp as ManualActionRecordResult, cq as ManualActionListOptions, co as ManualActionOccurrence, cs as ManualActionSuggestionOptions, cr as ManualActionSuggestion, cg as ArtifactApprovalTaskListOptions, cf as ArtifactApprovalTask, ch as ArtifactApprovalDecisionInput, ci as ArtifactApprovalDecisionResult, c0 as SessionFileRecord, ct as SessionFileUploadOptions, S as SessionHeapEntry, b as SessionHeapList, cx as SessionHeapVariable, e as SessionTranscriptEntry, dO as GraphQLResult, cz as RecordSearchOptions, cy as RecordSearchResult, cA as RecordMentionInput, cW as DefineRelationshipOptions, cV as RelationshipInfo, cU as ModelRef, dN as ManifestContent, c$ as EnvironmentStateUpdateInput, cZ as EnvironmentStateTarget, d1 as EnvironmentStateProxy, d6 as RecordImportOptions, cJ as UserEnvironmentStateOptions, cI as UserEnvironmentState, cK as MarkUserEnvironmentReadOptions, aO as AdoptEnvironmentOptions, aP as ConnectOptions, de as RunEnvironmentImporterOptions, au as OpenAIUsageSpendEvent, at as GranularSpendContext, aw as RecordOpenAIUsageSpendResult, b2 as SandboxListResponse, b0 as Sandbox, b1 as CreateSandboxData, dQ as DeleteResponse, b4 as PermissionProfile, b5 as CreatePermissionProfileData, bd as CreateEnvironmentData, dR as StreamEvent, dS as StreamSubscription, dT as StreamStats, aM as Subject, b8 as AssignmentListResponse } from './spend-3DNM1u9N.js';
2
2
  import * as Automerge from '@automerge/automerge';
3
3
  import { Doc } from '@automerge/automerge/slim';
4
4
 
5
+ interface CanonicalDocumentQuarantine {
6
+ documentEpoch: number;
7
+ documentRevision: number;
8
+ error: Error;
9
+ }
5
10
  declare class WSClient {
6
11
  private ws;
7
12
  private url;
8
13
  private sessionId;
9
14
  private token;
10
15
  private messageQueue;
11
- private syncHandlers;
12
16
  private rpcHandlers;
13
17
  private eventHandlers;
18
+ private canonicalDocumentQuarantineHandlers;
14
19
  private nextRpcId;
15
20
  doc: Automerge.Doc<Record<string, unknown>>;
16
- private syncState;
17
21
  private reconnectTimer;
18
22
  private tokenRefreshTimer;
19
23
  private isExplicitlyDisconnected;
@@ -21,6 +25,8 @@ declare class WSClient {
21
25
  private connectPromise;
22
26
  private connectionEpoch;
23
27
  private cancelConnectAttempt;
28
+ private documentRepairRequired;
29
+ private canonicalDocumentActivated;
24
30
  private options;
25
31
  constructor(options: WSClientOptions);
26
32
  get currentSessionId(): string;
@@ -39,12 +45,25 @@ declare class WSClient {
39
45
  connect(options?: {
40
46
  signal?: AbortSignal;
41
47
  }): Promise<void>;
48
+ /**
49
+ * Mark the current transport as unusable and schedule the normal reconnect
50
+ * path. Browser WebSockets can remain in OPEN state after a proxy/worker
51
+ * restart, so a timed-out heartbeat must revoke the stale socket explicitly.
52
+ */
53
+ reportTransportFailure(reason?: unknown): void;
42
54
  private connectAttempt;
43
55
  private normalizeReason;
44
56
  private rejectPending;
45
57
  private emitReconnectErrorMessage;
46
58
  private scheduleReconnectAttempt;
47
59
  private buildDisconnectError;
60
+ private decodeDocumentBytes;
61
+ private rememberCanonicalActivation;
62
+ private canAcceptDocumentReplacement;
63
+ private exposeCanonicalQuarantine;
64
+ private canonicalReplacementError;
65
+ private assertIncrementalDocumentIsSafe;
66
+ private requireDocumentResync;
48
67
  private handleDisconnect;
49
68
  private handleMessage;
50
69
  /**
@@ -62,6 +81,13 @@ declare class WSClient {
62
81
  * @param {Function} handler - Event handler
63
82
  */
64
83
  on(event: string, handler: (params: unknown) => void): void;
84
+ /**
85
+ * Subscribe to rejected canonical replacement metadata without exposing the
86
+ * malformed document through the public sync stream.
87
+ *
88
+ * @internal Session uses this to quarantine only its feed projection.
89
+ */
90
+ onCanonicalDocumentQuarantine(handler: (quarantine: CanonicalDocumentQuarantine) => void): () => void;
65
91
  /**
66
92
  * Register an RPC handler for incoming server requests
67
93
  * @param {string} method - RPC method name
@@ -93,7 +119,6 @@ declare class Session {
93
119
  private clientId;
94
120
  private initialQuota;
95
121
  private jobsMap;
96
- private pendingAgentMessagesByJobId;
97
122
  private eventListeners;
98
123
  private toolHandlers;
99
124
  /** Tracks which tools are instance methods (className set, not static) */
@@ -110,12 +135,22 @@ declare class Session {
110
135
  private domainPackagePartCache;
111
136
  private domainPackagePartPromises;
112
137
  private domainPackageFetchQueue;
138
+ private readonly feedController;
139
+ readonly feed: SessionFeedApi;
113
140
  constructor(client: WSClient, clientId?: string, options?: {
114
141
  initialQuota?: GranularQuotaProgress | null;
115
142
  });
116
143
  private extractDomainRevisionFromDoc;
117
- private buildLegacyEffectContext;
118
- private stringifyConversationValue;
144
+ /**
145
+ * Prompt delivery is deliberately event-driven while a socket is live, but
146
+ * an existing session can be attached from a fresh tab/client after the
147
+ * event was originally sent. Rebuild that client's prompt cache from the
148
+ * canonical document on every sync so an open durable prompt remains
149
+ * actionable after reconnect without manufacturing a second prompt.
150
+ */
151
+ private reconcilePromptCacheFromCanonicalDocument;
152
+ private buildDirectedInvocationEffectContext;
153
+ private createDirectedInvocationFeedbackContext;
119
154
  get document(): Doc<Record<string, unknown>>;
120
155
  get quota(): GranularQuotaProgress | null;
121
156
  getQuota(): GranularQuotaProgress | null;
@@ -195,7 +230,7 @@ declare class Session {
195
230
  * Respond to a prompt request from the sandbox
196
231
  */
197
232
  answerPrompt(promptId: string, answer: unknown): Promise<void>;
198
- appendConversationMessage(input: ConversationMessageInput): Promise<ConversationAppendResult>;
233
+ appendUserMessage(input: UserMessageInput): Promise<UserMessageAppendResult>;
199
234
  /**
200
235
  * Get the current list of available effects.
201
236
  * Consolidates effect declarations and live availability for the session.
@@ -252,6 +287,8 @@ declare class Session {
252
287
  * Close the session and disconnect from the sandbox
253
288
  */
254
289
  disconnect(): Promise<void>;
290
+ /** Stop feed repair work without detaching a reconnectable transport. */
291
+ protected disposeSessionFeed(): void;
255
292
  /**
256
293
  * Subscribe to session events
257
294
  */
@@ -260,6 +297,7 @@ declare class Session {
260
297
  * Unsubscribe from session events
261
298
  */
262
299
  off(event: string, handler: (data: unknown) => void): void;
300
+ protected setFeedListTransport(transport: FeedListTransport | null): void;
263
301
  private setupToolInvokeHandler;
264
302
  private setupEventHandlers;
265
303
  protected emit(event: string, data: unknown): void;
@@ -270,6 +308,7 @@ declare class Session {
270
308
  }
271
309
 
272
310
  type SessionFileUploadBody = Blob | ArrayBuffer | Uint8Array | string;
311
+ type SessionDataHeaders = any;
273
312
  type EnvironmentImporterHandler = (importer: EnvironmentImporter) => Promise<void> | void;
274
313
  /**
275
314
  * Environment is the sessionless handle for one resolved ontology environment.
@@ -330,11 +369,11 @@ declare class Environment {
330
369
  }) => Promise<EnvironmentSession>;
331
370
  close: (sessionId: string, session?: EnvironmentSession | null) => Promise<void>;
332
371
  state: (options?: UserEnvironmentStateOptions) => Promise<UserEnvironmentState>;
333
- markRead: (options: MarkUserEnvironmentReadOptions) => Promise<UserEnvironmentState["readAtBySessionId"]>;
372
+ markRead: (options: MarkUserEnvironmentReadOptions) => Promise<UserEnvironmentState["readThroughSequenceBySessionId"]>;
334
373
  };
335
374
  get userEnvironmentState(): {
336
375
  get: (options?: UserEnvironmentStateOptions) => Promise<UserEnvironmentState>;
337
- markRead: (options: MarkUserEnvironmentReadOptions) => Promise<UserEnvironmentState["readAtBySessionId"]>;
376
+ markRead: (options: MarkUserEnvironmentReadOptions) => Promise<UserEnvironmentState["readThroughSequenceBySessionId"]>;
338
377
  };
339
378
  get data(): {
340
379
  record: (record: RecordObjectOptions) => Promise<RecordObjectResult>;
@@ -387,7 +426,7 @@ declare class Environment {
387
426
  listSessions(status?: ConversationSessionListOptions["status"]): Promise<ConversationSessionInfo[]>;
388
427
  listSessions(options?: Omit<ConversationSessionListOptions, "environmentId" | "sandboxId" | "subjectId">): Promise<ConversationSessionInfo[]>;
389
428
  getUserEnvironmentState(options?: UserEnvironmentStateOptions): Promise<UserEnvironmentState>;
390
- markUserEnvironmentSessionsRead(options: MarkUserEnvironmentReadOptions): Promise<UserEnvironmentState["readAtBySessionId"]>;
429
+ markUserEnvironmentSessionsRead(options: MarkUserEnvironmentReadOptions): Promise<UserEnvironmentState["readThroughSequenceBySessionId"]>;
391
430
  createSession(options?: CreateSessionOptions): Promise<EnvironmentSession>;
392
431
  connectSession(sessionId: string, options?: {
393
432
  clientId?: string;
@@ -697,6 +736,9 @@ declare class Environment {
697
736
  declare class EnvironmentSession extends Session {
698
737
  readonly environment: Environment;
699
738
  private readonly sessionDataRoutePrefix;
739
+ private readonly sessionDataHeaders;
740
+ private heartbeatTimer;
741
+ private heartbeatInFlight;
700
742
  /** The last known graph container status, updated by checkReadiness() or on heartbeat */
701
743
  graphContainerStatus: {
702
744
  lastKeepAliveAt: number;
@@ -704,8 +746,32 @@ declare class EnvironmentSession extends Session {
704
746
  } | null;
705
747
  constructor(client: WSClient, environment: Environment, clientId: string, options?: {
706
748
  sessionDataRoutePrefix?: string;
749
+ /**
750
+ * Browser-only request metadata forwarded with session-data mutations.
751
+ * This lets a session direct a frontend effect to the exact Dock client
752
+ * that initiated a user action when multiple tabs are connected.
753
+ */
754
+ sessionDataHeaders?: SessionDataHeaders;
707
755
  initialQuota?: GranularQuotaProgress | null;
708
756
  });
757
+ /**
758
+ * Keep the browser session transport observable from the client side.
759
+ * A worker/proxy restart can leave a browser WebSocket appearing OPEN even
760
+ * though the server-side Durable Object has already closed its peer. The
761
+ * heartbeat gives the SDK a bounded failure signal so it can revoke that
762
+ * stale socket and use WSClient's normal reconnect path.
763
+ */
764
+ private startHeartbeat;
765
+ private stopHeartbeat;
766
+ hello(): Promise<{
767
+ ok: boolean;
768
+ environmentId?: string;
769
+ docId?: string;
770
+ graphContainerStatus?: {
771
+ lastKeepAliveAt: number;
772
+ status: "warming" | "hot" | "unknown";
773
+ };
774
+ }>;
709
775
  get environmentId(): string;
710
776
  get sandboxId(): string;
711
777
  get ontologyId(): string;
@@ -739,17 +805,21 @@ declare class EnvironmentSession extends Session {
739
805
  private buildSessionDataUrl;
740
806
  private sessionDataFetch;
741
807
  private sessionDataRequest;
742
- private collectAllSessionItems;
743
808
  /**
744
809
  * Fetch the live session document from the runtime DO.
745
810
  *
746
- * For history and saved artifacts, prefer the collection APIs on
747
- * `messages`, `timeline`, `jobs`, and `heap`.
811
+ * For presentation history use `feed.list()` or `transcript.list()`.
812
+ * Timeline and job collections are diagnostic/execution data only.
748
813
  */
749
814
  getDocument(): Promise<SessionDocumentResult>;
750
- get messages(): {
751
- list: (options?: SessionCollectionListOptions) => Promise<SessionCollectionListResult<SessionConversationMessage>>;
752
- };
815
+ /**
816
+ * Publish one terminal assistant reply from a trusted server integration.
817
+ *
818
+ * This uses the API-key-authenticated HTTP session boundary. Delegated
819
+ * browser sessions cannot use it and never receive assistant feed-authoring
820
+ * capability through their WebSocket.
821
+ */
822
+ publishAssistantReply(input: AssistantReplyPublicationInput): Promise<AssistantReplyPublicationResult>;
753
823
  get timeline(): {
754
824
  list: (options?: SessionCollectionListOptions) => Promise<SessionCollectionListResult<SessionTimelineEvent>>;
755
825
  };
@@ -765,11 +835,14 @@ declare class EnvironmentSession extends Session {
765
835
  create: (artifact: Partial<SessionArtifactRecord> & {
766
836
  label: string;
767
837
  }) => Promise<SessionArtifactRecord>;
838
+ acceptSuggestion: (sequence: number) => Promise<SessionArtifactRecord>;
768
839
  updateInputs: (artifactId: string, patch: {
769
840
  inputValues?: Record<string, unknown>;
770
841
  relationships?: Record<string, string | string[] | null>;
771
842
  expectedUpdatedAt?: number;
772
843
  }) => Promise<SessionArtifactRecord>;
844
+ relationshipOptions: (artifactId: string, input: SessionArtifactRelationshipOptionsInput) => Promise<SessionArtifactRelationshipOptionsResult>;
845
+ relationshipCreate: (artifactId: string, input: SessionArtifactRelationshipCreateInput) => Promise<SessionArtifactRecord>;
773
846
  validate: (artifactId: string) => Promise<SessionArtifactValidationResult>;
774
847
  execute: (artifactId: string, options: SessionArtifactExecutionOptions) => Promise<SessionArtifactExecutionResult>;
775
848
  approve: (artifactId: string, options: SessionArtifactApprovalOptions) => Promise<SessionArtifactExecutionResult>;
@@ -1031,7 +1104,7 @@ declare class Granular {
1031
1104
  }): Promise<UserEnvironmentState>;
1032
1105
  markUserEnvironmentSessionsRead(options: MarkUserEnvironmentReadOptions & {
1033
1106
  environmentId: string;
1034
- }): Promise<UserEnvironmentState["readAtBySessionId"]>;
1107
+ }): Promise<UserEnvironmentState["readThroughSequenceBySessionId"]>;
1035
1108
  private normalizeConversationSession;
1036
1109
  private normalizeUserEnvironmentState;
1037
1110
  private static coerceIsoDate;
@@ -1057,10 +1130,7 @@ declare class Granular {
1057
1130
  recordOpenAIUsageSpend(usage: OpenAIUsageSpendEvent, context?: GranularSpendContext | null, options?: {
1058
1131
  metadata?: Record<string, unknown> | null;
1059
1132
  }): Promise<RecordOpenAIUsageSpendResult>;
1060
- /**
1061
- * Mark a session closed in the control plane. If `environment` is the connected handle for that
1062
- * `sessionId`, disconnects the WebSocket so the runtime tears down cleanly.
1063
- */
1133
+ /** End a session through the runtime, or disconnect its connected handle. */
1064
1134
  closeSession(sessionId: string, environment?: EnvironmentSession | null): Promise<void>;
1065
1135
  /**
1066
1136
  * Re-open a closed session in the index and connect to its existing runtime document.
@@ -1,19 +1,23 @@
1
- import { bM as WSClientOptions, a2 as GranularQuotaProgress, T as ToolWithHandler, f as PublishToolsResult, aO as Job, g as ToolHandler, I as InstanceToolHandler, aY as ConversationMessageInput, aZ as ConversationAppendResult, aB as EffectInfo, P as Prompt, aA as ToolInfo, aD as EffectsChangedEvent, aC as ToolsChangedEvent, D as DomainState, y as GranularOptions, ci as EnvironmentImporter, B as RecordUserOptions, U as User, H as OpenEnvironmentOptions, af as EnvironmentData, ac as BuildPolicy, cf as EnvironmentSetupSummary, W as ConversationSessionListOptions, Q as ConversationSessionInfo, L as CreateSessionOptions, bW as RecordObjectOptions, c1 as RecordObjectResult, c3 as RecordObjectsOptions, ca as RecordImport, c6 as RecordImportStatus, c9 as RecordImportItem, cb as EnvironmentRecordImportSummary, aM as EnvironmentFeedbackRecord, c as SessionHeapSnapshot, bA as SessionDocumentResult, bB as SessionCollectionListOptions, bD as SessionCollectionListResult, a_ as SessionConversationMessage, a$ as SessionTimelineEvent, bC as SessionJobListOptions, bt as SessionJobRecord, b8 as SessionArtifactListOptions, b7 as SessionArtifactRecord, b9 as SessionArtifactValidationResult, bb as SessionArtifactExecutionOptions, ba as SessionArtifactExecutionResult, bc as SessionArtifactApprovalOptions, bm as RecordManualActionInput, bo as ManualActionRecordResult, bp as ManualActionListOptions, bn as ManualActionOccurrence, br as ManualActionSuggestionOptions, bq as ManualActionSuggestion, bf as ArtifactApprovalTaskListOptions, be as ArtifactApprovalTask, bg as ArtifactApprovalDecisionInput, bh as ArtifactApprovalDecisionResult, b3 as SessionFileRecord, bs as SessionFileUploadOptions, S as SessionHeapEntry, b as SessionHeapList, bw as SessionHeapVariable, d as SessionTranscriptEntry, cM as GraphQLResult, by as RecordSearchOptions, bx as RecordSearchResult, bz as RecordMentionInput, bV as DefineRelationshipOptions, bU as RelationshipInfo, bT as ModelRef, cL as ManifestContent, b_ as EnvironmentStateUpdateInput, bY as EnvironmentStateTarget, c0 as EnvironmentStateProxy, c5 as RecordImportOptions, bI as UserEnvironmentStateOptions, bH as UserEnvironmentState, bJ as MarkUserEnvironmentReadOptions, J as AdoptEnvironmentOptions, K as ConnectOptions, cd as RunEnvironmentImporterOptions, l as OpenAIUsageSpendEvent, G as GranularSpendContext, o as RecordOpenAIUsageSpendResult, a5 as SandboxListResponse, a3 as Sandbox, a4 as CreateSandboxData, cO as DeleteResponse, a7 as PermissionProfile, a8 as CreatePermissionProfileData, ag as CreateEnvironmentData, cP as StreamEvent, cQ as StreamSubscription, cR as StreamStats, F as Subject, ab as AssignmentListResponse } from './spend-DpRRCrAr.mjs';
1
+ import { cN as WSClientOptions, Y as SessionFeedApi, a$ as GranularQuotaProgress, T as ToolWithHandler, g as PublishToolsResult, bP as Job, h as ToolHandler, I as InstanceToolHandler, bS as UserMessageInput, bT as UserMessageAppendResult, bC as EffectInfo, P as Prompt, bB as ToolInfo, bE as EffectsChangedEvent, bD as ToolsChangedEvent, D as DomainState, $ as FeedListTransport, aI as GranularOptions, dj as EnvironmentImporter, aL as RecordUserOptions, aK as User, aN as OpenEnvironmentOptions, bc as EnvironmentData, b9 as BuildPolicy, dg as EnvironmentSetupSummary, aT as ConversationSessionListOptions, aR as ConversationSessionInfo, aQ as CreateSessionOptions, cX as RecordObjectOptions, d2 as RecordObjectResult, d4 as RecordObjectsOptions, db as RecordImport, d7 as RecordImportStatus, da as RecordImportItem, dc as EnvironmentRecordImportSummary, bN as EnvironmentFeedbackRecord, d as SessionHeapSnapshot, cB as SessionDocumentResult, bU as AssistantReplyPublicationInput, bV as AssistantReplyPublicationResult, cC as SessionCollectionListOptions, cE as SessionCollectionListResult, bY as SessionTimelineEvent, cD as SessionJobListOptions, cu as SessionJobRecord, c5 as SessionArtifactListOptions, c4 as SessionArtifactRecord, c7 as SessionArtifactRelationshipOptionsInput, c9 as SessionArtifactRelationshipOptionsResult, ca as SessionArtifactRelationshipCreateInput, c6 as SessionArtifactValidationResult, cc as SessionArtifactExecutionOptions, cb as SessionArtifactExecutionResult, cd as SessionArtifactApprovalOptions, cn as RecordManualActionInput, cp as ManualActionRecordResult, cq as ManualActionListOptions, co as ManualActionOccurrence, cs as ManualActionSuggestionOptions, cr as ManualActionSuggestion, cg as ArtifactApprovalTaskListOptions, cf as ArtifactApprovalTask, ch as ArtifactApprovalDecisionInput, ci as ArtifactApprovalDecisionResult, c0 as SessionFileRecord, ct as SessionFileUploadOptions, S as SessionHeapEntry, b as SessionHeapList, cx as SessionHeapVariable, e as SessionTranscriptEntry, dO as GraphQLResult, cz as RecordSearchOptions, cy as RecordSearchResult, cA as RecordMentionInput, cW as DefineRelationshipOptions, cV as RelationshipInfo, cU as ModelRef, dN as ManifestContent, c$ as EnvironmentStateUpdateInput, cZ as EnvironmentStateTarget, d1 as EnvironmentStateProxy, d6 as RecordImportOptions, cJ as UserEnvironmentStateOptions, cI as UserEnvironmentState, cK as MarkUserEnvironmentReadOptions, aO as AdoptEnvironmentOptions, aP as ConnectOptions, de as RunEnvironmentImporterOptions, au as OpenAIUsageSpendEvent, at as GranularSpendContext, aw as RecordOpenAIUsageSpendResult, b2 as SandboxListResponse, b0 as Sandbox, b1 as CreateSandboxData, dQ as DeleteResponse, b4 as PermissionProfile, b5 as CreatePermissionProfileData, bd as CreateEnvironmentData, dR as StreamEvent, dS as StreamSubscription, dT as StreamStats, aM as Subject, b8 as AssignmentListResponse } from './spend-3DNM1u9N.mjs';
2
2
  import * as Automerge from '@automerge/automerge';
3
3
  import { Doc } from '@automerge/automerge/slim';
4
4
 
5
+ interface CanonicalDocumentQuarantine {
6
+ documentEpoch: number;
7
+ documentRevision: number;
8
+ error: Error;
9
+ }
5
10
  declare class WSClient {
6
11
  private ws;
7
12
  private url;
8
13
  private sessionId;
9
14
  private token;
10
15
  private messageQueue;
11
- private syncHandlers;
12
16
  private rpcHandlers;
13
17
  private eventHandlers;
18
+ private canonicalDocumentQuarantineHandlers;
14
19
  private nextRpcId;
15
20
  doc: Automerge.Doc<Record<string, unknown>>;
16
- private syncState;
17
21
  private reconnectTimer;
18
22
  private tokenRefreshTimer;
19
23
  private isExplicitlyDisconnected;
@@ -21,6 +25,8 @@ declare class WSClient {
21
25
  private connectPromise;
22
26
  private connectionEpoch;
23
27
  private cancelConnectAttempt;
28
+ private documentRepairRequired;
29
+ private canonicalDocumentActivated;
24
30
  private options;
25
31
  constructor(options: WSClientOptions);
26
32
  get currentSessionId(): string;
@@ -39,12 +45,25 @@ declare class WSClient {
39
45
  connect(options?: {
40
46
  signal?: AbortSignal;
41
47
  }): Promise<void>;
48
+ /**
49
+ * Mark the current transport as unusable and schedule the normal reconnect
50
+ * path. Browser WebSockets can remain in OPEN state after a proxy/worker
51
+ * restart, so a timed-out heartbeat must revoke the stale socket explicitly.
52
+ */
53
+ reportTransportFailure(reason?: unknown): void;
42
54
  private connectAttempt;
43
55
  private normalizeReason;
44
56
  private rejectPending;
45
57
  private emitReconnectErrorMessage;
46
58
  private scheduleReconnectAttempt;
47
59
  private buildDisconnectError;
60
+ private decodeDocumentBytes;
61
+ private rememberCanonicalActivation;
62
+ private canAcceptDocumentReplacement;
63
+ private exposeCanonicalQuarantine;
64
+ private canonicalReplacementError;
65
+ private assertIncrementalDocumentIsSafe;
66
+ private requireDocumentResync;
48
67
  private handleDisconnect;
49
68
  private handleMessage;
50
69
  /**
@@ -62,6 +81,13 @@ declare class WSClient {
62
81
  * @param {Function} handler - Event handler
63
82
  */
64
83
  on(event: string, handler: (params: unknown) => void): void;
84
+ /**
85
+ * Subscribe to rejected canonical replacement metadata without exposing the
86
+ * malformed document through the public sync stream.
87
+ *
88
+ * @internal Session uses this to quarantine only its feed projection.
89
+ */
90
+ onCanonicalDocumentQuarantine(handler: (quarantine: CanonicalDocumentQuarantine) => void): () => void;
65
91
  /**
66
92
  * Register an RPC handler for incoming server requests
67
93
  * @param {string} method - RPC method name
@@ -93,7 +119,6 @@ declare class Session {
93
119
  private clientId;
94
120
  private initialQuota;
95
121
  private jobsMap;
96
- private pendingAgentMessagesByJobId;
97
122
  private eventListeners;
98
123
  private toolHandlers;
99
124
  /** Tracks which tools are instance methods (className set, not static) */
@@ -110,12 +135,22 @@ declare class Session {
110
135
  private domainPackagePartCache;
111
136
  private domainPackagePartPromises;
112
137
  private domainPackageFetchQueue;
138
+ private readonly feedController;
139
+ readonly feed: SessionFeedApi;
113
140
  constructor(client: WSClient, clientId?: string, options?: {
114
141
  initialQuota?: GranularQuotaProgress | null;
115
142
  });
116
143
  private extractDomainRevisionFromDoc;
117
- private buildLegacyEffectContext;
118
- private stringifyConversationValue;
144
+ /**
145
+ * Prompt delivery is deliberately event-driven while a socket is live, but
146
+ * an existing session can be attached from a fresh tab/client after the
147
+ * event was originally sent. Rebuild that client's prompt cache from the
148
+ * canonical document on every sync so an open durable prompt remains
149
+ * actionable after reconnect without manufacturing a second prompt.
150
+ */
151
+ private reconcilePromptCacheFromCanonicalDocument;
152
+ private buildDirectedInvocationEffectContext;
153
+ private createDirectedInvocationFeedbackContext;
119
154
  get document(): Doc<Record<string, unknown>>;
120
155
  get quota(): GranularQuotaProgress | null;
121
156
  getQuota(): GranularQuotaProgress | null;
@@ -195,7 +230,7 @@ declare class Session {
195
230
  * Respond to a prompt request from the sandbox
196
231
  */
197
232
  answerPrompt(promptId: string, answer: unknown): Promise<void>;
198
- appendConversationMessage(input: ConversationMessageInput): Promise<ConversationAppendResult>;
233
+ appendUserMessage(input: UserMessageInput): Promise<UserMessageAppendResult>;
199
234
  /**
200
235
  * Get the current list of available effects.
201
236
  * Consolidates effect declarations and live availability for the session.
@@ -252,6 +287,8 @@ declare class Session {
252
287
  * Close the session and disconnect from the sandbox
253
288
  */
254
289
  disconnect(): Promise<void>;
290
+ /** Stop feed repair work without detaching a reconnectable transport. */
291
+ protected disposeSessionFeed(): void;
255
292
  /**
256
293
  * Subscribe to session events
257
294
  */
@@ -260,6 +297,7 @@ declare class Session {
260
297
  * Unsubscribe from session events
261
298
  */
262
299
  off(event: string, handler: (data: unknown) => void): void;
300
+ protected setFeedListTransport(transport: FeedListTransport | null): void;
263
301
  private setupToolInvokeHandler;
264
302
  private setupEventHandlers;
265
303
  protected emit(event: string, data: unknown): void;
@@ -270,6 +308,7 @@ declare class Session {
270
308
  }
271
309
 
272
310
  type SessionFileUploadBody = Blob | ArrayBuffer | Uint8Array | string;
311
+ type SessionDataHeaders = any;
273
312
  type EnvironmentImporterHandler = (importer: EnvironmentImporter) => Promise<void> | void;
274
313
  /**
275
314
  * Environment is the sessionless handle for one resolved ontology environment.
@@ -330,11 +369,11 @@ declare class Environment {
330
369
  }) => Promise<EnvironmentSession>;
331
370
  close: (sessionId: string, session?: EnvironmentSession | null) => Promise<void>;
332
371
  state: (options?: UserEnvironmentStateOptions) => Promise<UserEnvironmentState>;
333
- markRead: (options: MarkUserEnvironmentReadOptions) => Promise<UserEnvironmentState["readAtBySessionId"]>;
372
+ markRead: (options: MarkUserEnvironmentReadOptions) => Promise<UserEnvironmentState["readThroughSequenceBySessionId"]>;
334
373
  };
335
374
  get userEnvironmentState(): {
336
375
  get: (options?: UserEnvironmentStateOptions) => Promise<UserEnvironmentState>;
337
- markRead: (options: MarkUserEnvironmentReadOptions) => Promise<UserEnvironmentState["readAtBySessionId"]>;
376
+ markRead: (options: MarkUserEnvironmentReadOptions) => Promise<UserEnvironmentState["readThroughSequenceBySessionId"]>;
338
377
  };
339
378
  get data(): {
340
379
  record: (record: RecordObjectOptions) => Promise<RecordObjectResult>;
@@ -387,7 +426,7 @@ declare class Environment {
387
426
  listSessions(status?: ConversationSessionListOptions["status"]): Promise<ConversationSessionInfo[]>;
388
427
  listSessions(options?: Omit<ConversationSessionListOptions, "environmentId" | "sandboxId" | "subjectId">): Promise<ConversationSessionInfo[]>;
389
428
  getUserEnvironmentState(options?: UserEnvironmentStateOptions): Promise<UserEnvironmentState>;
390
- markUserEnvironmentSessionsRead(options: MarkUserEnvironmentReadOptions): Promise<UserEnvironmentState["readAtBySessionId"]>;
429
+ markUserEnvironmentSessionsRead(options: MarkUserEnvironmentReadOptions): Promise<UserEnvironmentState["readThroughSequenceBySessionId"]>;
391
430
  createSession(options?: CreateSessionOptions): Promise<EnvironmentSession>;
392
431
  connectSession(sessionId: string, options?: {
393
432
  clientId?: string;
@@ -697,6 +736,9 @@ declare class Environment {
697
736
  declare class EnvironmentSession extends Session {
698
737
  readonly environment: Environment;
699
738
  private readonly sessionDataRoutePrefix;
739
+ private readonly sessionDataHeaders;
740
+ private heartbeatTimer;
741
+ private heartbeatInFlight;
700
742
  /** The last known graph container status, updated by checkReadiness() or on heartbeat */
701
743
  graphContainerStatus: {
702
744
  lastKeepAliveAt: number;
@@ -704,8 +746,32 @@ declare class EnvironmentSession extends Session {
704
746
  } | null;
705
747
  constructor(client: WSClient, environment: Environment, clientId: string, options?: {
706
748
  sessionDataRoutePrefix?: string;
749
+ /**
750
+ * Browser-only request metadata forwarded with session-data mutations.
751
+ * This lets a session direct a frontend effect to the exact Dock client
752
+ * that initiated a user action when multiple tabs are connected.
753
+ */
754
+ sessionDataHeaders?: SessionDataHeaders;
707
755
  initialQuota?: GranularQuotaProgress | null;
708
756
  });
757
+ /**
758
+ * Keep the browser session transport observable from the client side.
759
+ * A worker/proxy restart can leave a browser WebSocket appearing OPEN even
760
+ * though the server-side Durable Object has already closed its peer. The
761
+ * heartbeat gives the SDK a bounded failure signal so it can revoke that
762
+ * stale socket and use WSClient's normal reconnect path.
763
+ */
764
+ private startHeartbeat;
765
+ private stopHeartbeat;
766
+ hello(): Promise<{
767
+ ok: boolean;
768
+ environmentId?: string;
769
+ docId?: string;
770
+ graphContainerStatus?: {
771
+ lastKeepAliveAt: number;
772
+ status: "warming" | "hot" | "unknown";
773
+ };
774
+ }>;
709
775
  get environmentId(): string;
710
776
  get sandboxId(): string;
711
777
  get ontologyId(): string;
@@ -739,17 +805,21 @@ declare class EnvironmentSession extends Session {
739
805
  private buildSessionDataUrl;
740
806
  private sessionDataFetch;
741
807
  private sessionDataRequest;
742
- private collectAllSessionItems;
743
808
  /**
744
809
  * Fetch the live session document from the runtime DO.
745
810
  *
746
- * For history and saved artifacts, prefer the collection APIs on
747
- * `messages`, `timeline`, `jobs`, and `heap`.
811
+ * For presentation history use `feed.list()` or `transcript.list()`.
812
+ * Timeline and job collections are diagnostic/execution data only.
748
813
  */
749
814
  getDocument(): Promise<SessionDocumentResult>;
750
- get messages(): {
751
- list: (options?: SessionCollectionListOptions) => Promise<SessionCollectionListResult<SessionConversationMessage>>;
752
- };
815
+ /**
816
+ * Publish one terminal assistant reply from a trusted server integration.
817
+ *
818
+ * This uses the API-key-authenticated HTTP session boundary. Delegated
819
+ * browser sessions cannot use it and never receive assistant feed-authoring
820
+ * capability through their WebSocket.
821
+ */
822
+ publishAssistantReply(input: AssistantReplyPublicationInput): Promise<AssistantReplyPublicationResult>;
753
823
  get timeline(): {
754
824
  list: (options?: SessionCollectionListOptions) => Promise<SessionCollectionListResult<SessionTimelineEvent>>;
755
825
  };
@@ -765,11 +835,14 @@ declare class EnvironmentSession extends Session {
765
835
  create: (artifact: Partial<SessionArtifactRecord> & {
766
836
  label: string;
767
837
  }) => Promise<SessionArtifactRecord>;
838
+ acceptSuggestion: (sequence: number) => Promise<SessionArtifactRecord>;
768
839
  updateInputs: (artifactId: string, patch: {
769
840
  inputValues?: Record<string, unknown>;
770
841
  relationships?: Record<string, string | string[] | null>;
771
842
  expectedUpdatedAt?: number;
772
843
  }) => Promise<SessionArtifactRecord>;
844
+ relationshipOptions: (artifactId: string, input: SessionArtifactRelationshipOptionsInput) => Promise<SessionArtifactRelationshipOptionsResult>;
845
+ relationshipCreate: (artifactId: string, input: SessionArtifactRelationshipCreateInput) => Promise<SessionArtifactRecord>;
773
846
  validate: (artifactId: string) => Promise<SessionArtifactValidationResult>;
774
847
  execute: (artifactId: string, options: SessionArtifactExecutionOptions) => Promise<SessionArtifactExecutionResult>;
775
848
  approve: (artifactId: string, options: SessionArtifactApprovalOptions) => Promise<SessionArtifactExecutionResult>;
@@ -1031,7 +1104,7 @@ declare class Granular {
1031
1104
  }): Promise<UserEnvironmentState>;
1032
1105
  markUserEnvironmentSessionsRead(options: MarkUserEnvironmentReadOptions & {
1033
1106
  environmentId: string;
1034
- }): Promise<UserEnvironmentState["readAtBySessionId"]>;
1107
+ }): Promise<UserEnvironmentState["readThroughSequenceBySessionId"]>;
1035
1108
  private normalizeConversationSession;
1036
1109
  private normalizeUserEnvironmentState;
1037
1110
  private static coerceIsoDate;
@@ -1057,10 +1130,7 @@ declare class Granular {
1057
1130
  recordOpenAIUsageSpend(usage: OpenAIUsageSpendEvent, context?: GranularSpendContext | null, options?: {
1058
1131
  metadata?: Record<string, unknown> | null;
1059
1132
  }): Promise<RecordOpenAIUsageSpendResult>;
1060
- /**
1061
- * Mark a session closed in the control plane. If `environment` is the connected handle for that
1062
- * `sessionId`, disconnects the WebSocket so the runtime tears down cleanly.
1063
- */
1133
+ /** End a session through the runtime, or disconnect its connected handle. */
1064
1134
  closeSession(sessionId: string, environment?: EnvironmentSession | null): Promise<void>;
1065
1135
  /**
1066
1136
  * Re-open a closed session in the index and connect to its existing runtime document.