UNPKG

assistant-cloud

Version:

Cloud integration for assistant-ui

132 lines • 6.45 kB
import type { ReadonlyJSONObject } from "assistant-stream/utils"; import type { AssistantCloud } from "./AssistantCloud.js"; import type { CloudMessage, CloudMessageRun } from "./AssistantCloudThreadMessages.js"; import type { CloudRunEndReason } from "./AssistantCloudThreadRuns.js"; /** How a write relates to the message's run: `running` opens or renews its lease, a reason ends it. */ export type CloudMessageRunPhase = "running" | CloudRunEndReason; /** How long a running lease may go without a heartbeat before its message reads as stale. */ export declare const DEFAULT_RUN_STALE_AFTER_MS = 30000; export type CloudMessagePersistenceOptions = { /** * Milliseconds without a heartbeat after which a running lease reads as * stale, which is what a run whose tab went away looks like. Default * 30 000. The server never expires a run: a late run that beats again * reads as running again, and its writes still land. */ staleAfter?: number | undefined; }; /** Where a listed message's run stands for a reader: still beating, or quiet for longer than `staleAfter`. */ export type CloudRunState = { status: "in-progress"; staleInMs: number; } | { status: "stale"; }; /** * Appends, updates and loads cloud messages while mapping local ids to cloud * ids and chaining parent_id. A parent that is still being created is awaited, * so concurrent appends land under the right parent. A parent whose create * failed is created again before its child, and a child whose parent still * cannot be created is stored as a root. * * A message appended as running holds a run lease, renewed by heartbeats on * the server's interval until a write with an end reason ends it. Heartbeats * keep running while the page is in the background. The server never * expires a lease; readers show a run as stale once it has gone `staleAfter` * without a beat, and a late run keeps writing its own message. A lease that * is lost (ended elsewhere or refused) is final: the message gets no further * writes from this persistence. */ export declare class CloudMessagePersistence { private idMapping; private failedAppends; /** Every message this persistence opened a lease for; a repeated append of one writes its row instead of storing another. */ private runs; private runWrites; /** Writes waiting on an in-flight create, chained so they apply in append order. */ private pendingWrites; /** The deletes each write waiting on an in-flight create saw start; each resolves to whether it deleted the message. */ private waiters; private getCloud; private staleAfter; constructor(cloud: AssistantCloud, options?: CloudMessagePersistenceOptions); constructor(getCloud: () => AssistantCloud, options?: CloudMessagePersistenceOptions); /** * Reads a listed message's run against `staleAfter`; `sinceReadMs` is the * time since the list was read. Undefined for no run or an ended one. */ runStateOf(run: CloudMessageRun | undefined, sinceReadMs?: number): CloudRunState | undefined; /** * Persist a message to the cloud. * * @param threadId - Remote thread ID * @param messageId - Local message ID (used for tracking) * @param parentId - Local parent message ID (or null for first message) * @param format - Message format (e.g., "aui/v0", "ai-sdk/v6") * @param content - Message content (format-specific) * @param run - `running` stores the message with an open run lease that is * kept alive by heartbeats until a write with an end reason closes it. * Once the lease is lost (it was ended elsewhere or the server refused * it), later writes for the message are dropped. */ append(threadId: string, messageId: string, parentId: string | null, format: string, content: ReadonlyJSONObject, run?: CloudMessageRunPhase): Promise<void>; private resolveParentId; /** * Update an already-persisted message in the cloud. */ update(threadId: string, messageId: string, _format: string, content: ReadonlyJSONObject, run?: CloudMessageRunPhase): Promise<void>; private writeRun; /** * Moves a stored message's id mapping and run lease to a new local id, for * runtimes that swap a placeholder's id once the backend names the message. */ rename(from: string, to: string): Promise<void>; /** Whether a run lease this persistence opened for the message is still held. */ hasOpenRun(messageId: string): boolean; private openRun; private scheduleHeartbeat; private heartbeat; /** The lease is gone for good: stop heartbeating and drop every later write for the message. */ private loseRun; private closeRun; /** * Delete mapped messages from the cloud and clear their local ID mappings. */ delete(threadId: string, messageIds: string[]): Promise<void>; private deleteMessages; /** * Check if a message has been persisted (or is currently being persisted). */ isPersisted(messageId: string): boolean; /** * Get the remote ID for a local message ID (resolved). * Returns undefined if not persisted. */ getRemoteId(messageId: string): Promise<string | undefined>; getResolvedRemoteId(messageId: string): string | undefined; record(localId: string, remoteId: string): void; /** * Load messages from the cloud and populate the ID mapping. * * The list endpoint caps a response at 200 rows, so pages are followed by * message ID cursor until a short page and concatenated in server order. * * The ID mapping is populated so that `isPersisted()` returns true for * loaded messages, preventing re-persistence of already-stored messages. * * A loaded ID that an append already maps keeps the remote ID from that append, and falls back to the loaded ID if the append fails. * * @param threadId - Remote thread ID * @param format - Optional format filter * @returns Array of cloud messages */ load(threadId: string, format?: string): Promise<CloudMessage[]>; /** * Reset the ID mapping (call when switching threads). * * Pending `load()` and `append()` calls are not cancelled and still settle * normally, but their results no longer populate the ID mapping. */ reset(): void; } //# sourceMappingURL=CloudMessagePersistence.d.ts.map