@finalai/agents 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of @finalai/agents might be problematic. Click here for more details.

Files changed (153) hide show
  1. package/README.md +30 -0
  2. package/dist/modules/agent-client/acp-frames.d.mts +19 -0
  3. package/dist/modules/agent-client/acp-frames.mjs +49 -0
  4. package/dist/modules/agent-client/acp-frames.mjs.map +7 -0
  5. package/dist/modules/agent-client/acp.d.mts +43 -0
  6. package/dist/modules/agent-client/acp.mjs +76 -0
  7. package/dist/modules/agent-client/acp.mjs.map +7 -0
  8. package/dist/modules/agent-client/async-queue.d.mts +10 -0
  9. package/dist/modules/agent-client/async-queue.mjs +66 -0
  10. package/dist/modules/agent-client/async-queue.mjs.map +7 -0
  11. package/dist/modules/agent-client/build.d.mts +107 -0
  12. package/dist/modules/agent-client/build.mjs +222 -0
  13. package/dist/modules/agent-client/build.mjs.map +7 -0
  14. package/dist/modules/agent-client/client.d.mts +111 -0
  15. package/dist/modules/agent-client/client.mjs +198 -0
  16. package/dist/modules/agent-client/client.mjs.map +7 -0
  17. package/dist/modules/agent-client/collection-events.d.mts +35 -0
  18. package/dist/modules/agent-client/collection-events.mjs +142 -0
  19. package/dist/modules/agent-client/collection-events.mjs.map +7 -0
  20. package/dist/modules/agent-client/config-options.d.mts +24 -0
  21. package/dist/modules/agent-client/config-options.mjs +49 -0
  22. package/dist/modules/agent-client/config-options.mjs.map +7 -0
  23. package/dist/modules/agent-client/context.d.mts +31 -0
  24. package/dist/modules/agent-client/context.mjs +11 -0
  25. package/dist/modules/agent-client/context.mjs.map +7 -0
  26. package/dist/modules/agent-client/conversations.d.mts +385 -0
  27. package/dist/modules/agent-client/conversations.mjs +1156 -0
  28. package/dist/modules/agent-client/conversations.mjs.map +7 -0
  29. package/dist/modules/agent-client/errors.d.mts +85 -0
  30. package/dist/modules/agent-client/errors.mjs +94 -0
  31. package/dist/modules/agent-client/errors.mjs.map +7 -0
  32. package/dist/modules/agent-client/event-stream.d.mts +14 -0
  33. package/dist/modules/agent-client/event-stream.mjs +89 -0
  34. package/dist/modules/agent-client/event-stream.mjs.map +7 -0
  35. package/dist/modules/agent-client/frame-stream.d.mts +51 -0
  36. package/dist/modules/agent-client/frame-stream.mjs +333 -0
  37. package/dist/modules/agent-client/frame-stream.mjs.map +7 -0
  38. package/dist/modules/agent-client/http.d.mts +68 -0
  39. package/dist/modules/agent-client/http.mjs +168 -0
  40. package/dist/modules/agent-client/http.mjs.map +7 -0
  41. package/dist/modules/agent-client/index.d.mts +17 -0
  42. package/dist/modules/agent-client/index.mjs +86 -0
  43. package/dist/modules/agent-client/index.mjs.map +7 -0
  44. package/dist/modules/agent-client/live-stream.d.mts +18 -0
  45. package/dist/modules/agent-client/live-stream.mjs +94 -0
  46. package/dist/modules/agent-client/live-stream.mjs.map +7 -0
  47. package/dist/modules/agent-client/realtime.d.mts +72 -0
  48. package/dist/modules/agent-client/realtime.mjs +186 -0
  49. package/dist/modules/agent-client/realtime.mjs.map +7 -0
  50. package/dist/modules/agent-client/sandbox-uri.d.mts +19 -0
  51. package/dist/modules/agent-client/sandbox-uri.mjs +43 -0
  52. package/dist/modules/agent-client/sandbox-uri.mjs.map +7 -0
  53. package/dist/modules/agent-client/sessions.d.mts +124 -0
  54. package/dist/modules/agent-client/sessions.mjs +350 -0
  55. package/dist/modules/agent-client/sessions.mjs.map +7 -0
  56. package/dist/modules/agent-client/test-fakes.d.mts +40 -0
  57. package/dist/modules/agent-client/test-fakes.mjs +94 -0
  58. package/dist/modules/agent-client/test-fakes.mjs.map +7 -0
  59. package/dist/modules/authoring/approval.d.mts +1 -0
  60. package/dist/modules/authoring/approval.mjs +2 -0
  61. package/dist/modules/authoring/approval.mjs.map +7 -0
  62. package/dist/modules/authoring/channels.d.mts +1 -0
  63. package/dist/modules/authoring/channels.mjs +2 -0
  64. package/dist/modules/authoring/channels.mjs.map +7 -0
  65. package/dist/modules/authoring/final-channel.d.mts +1 -0
  66. package/dist/modules/authoring/final-channel.mjs +2 -0
  67. package/dist/modules/authoring/final-channel.mjs.map +7 -0
  68. package/dist/modules/authoring/hooks.d.mts +1 -0
  69. package/dist/modules/authoring/hooks.mjs +2 -0
  70. package/dist/modules/authoring/hooks.mjs.map +7 -0
  71. package/dist/modules/authoring/index.d.mts +1 -0
  72. package/dist/modules/authoring/index.mjs +2 -0
  73. package/dist/modules/authoring/index.mjs.map +7 -0
  74. package/dist/modules/authoring/instructions.d.mts +1 -0
  75. package/dist/modules/authoring/instructions.mjs +2 -0
  76. package/dist/modules/authoring/instructions.mjs.map +7 -0
  77. package/dist/modules/authoring/providers.d.mts +2 -0
  78. package/dist/modules/authoring/providers.mjs +1 -0
  79. package/dist/modules/authoring/providers.mjs.map +7 -0
  80. package/dist/modules/authoring/tools.d.mts +1 -0
  81. package/dist/modules/authoring/tools.mjs +2 -0
  82. package/dist/modules/authoring/tools.mjs.map +7 -0
  83. package/dist/modules/cli/build.d.mts +22 -0
  84. package/dist/modules/cli/build.mjs +77 -0
  85. package/dist/modules/cli/build.mjs.map +7 -0
  86. package/dist/modules/cli/channel-socket.d.mts +9 -0
  87. package/dist/modules/cli/channel-socket.mjs +114 -0
  88. package/dist/modules/cli/channel-socket.mjs.map +7 -0
  89. package/dist/modules/cli/cli.d.mts +16 -0
  90. package/dist/modules/cli/cli.mjs +151 -0
  91. package/dist/modules/cli/cli.mjs.map +7 -0
  92. package/dist/modules/cli/conformance.d.mts +36 -0
  93. package/dist/modules/cli/conformance.mjs +220 -0
  94. package/dist/modules/cli/conformance.mjs.map +7 -0
  95. package/dist/modules/cli/dev.d.mts +24 -0
  96. package/dist/modules/cli/dev.mjs +263 -0
  97. package/dist/modules/cli/dev.mjs.map +7 -0
  98. package/dist/modules/cli/files.d.mts +18 -0
  99. package/dist/modules/cli/files.mjs +66 -0
  100. package/dist/modules/cli/files.mjs.map +7 -0
  101. package/dist/modules/cli/harness-descriptions.d.mts +20 -0
  102. package/dist/modules/cli/harness-descriptions.mjs +70 -0
  103. package/dist/modules/cli/harness-descriptions.mjs.map +7 -0
  104. package/dist/modules/cli/main.d.mts +2 -0
  105. package/dist/modules/cli/main.mjs +20 -0
  106. package/dist/modules/cli/main.mjs.map +7 -0
  107. package/dist/modules/cli/output.d.mts +14 -0
  108. package/dist/modules/cli/output.mjs +94 -0
  109. package/dist/modules/cli/output.mjs.map +7 -0
  110. package/dist/modules/cli/publish.d.mts +14 -0
  111. package/dist/modules/cli/publish.mjs +89 -0
  112. package/dist/modules/cli/publish.mjs.map +7 -0
  113. package/dist/modules/compile.d.mts +3 -0
  114. package/dist/modules/compile.mjs +62 -0
  115. package/dist/modules/compile.mjs.map +7 -0
  116. package/dist/modules/harnesses.d.mts +1 -0
  117. package/dist/modules/harnesses.mjs +2 -0
  118. package/dist/modules/harnesses.mjs.map +7 -0
  119. package/dist/modules/index.browser.d.mts +4 -0
  120. package/dist/modules/index.browser.mjs +8 -0
  121. package/dist/modules/index.browser.mjs.map +7 -0
  122. package/dist/modules/index.d.mts +3 -0
  123. package/dist/modules/index.mjs +6 -0
  124. package/dist/modules/index.mjs.map +7 -0
  125. package/dist/modules/models.d.mts +1 -0
  126. package/dist/modules/models.mjs +2 -0
  127. package/dist/modules/models.mjs.map +7 -0
  128. package/dist/modules/public.d.mts +6 -0
  129. package/dist/modules/public.mjs +68 -0
  130. package/dist/modules/public.mjs.map +7 -0
  131. package/dist/modules/sandboxes.d.mts +1 -0
  132. package/dist/modules/sandboxes.mjs +2 -0
  133. package/dist/modules/sandboxes.mjs.map +7 -0
  134. package/examples/custom-harness/README.md +16 -0
  135. package/examples/custom-harness/agent.ts +154 -0
  136. package/examples/custom-sandbox/README.md +12 -0
  137. package/examples/custom-sandbox/agent.ts +14 -0
  138. package/examples/custom-sandbox/sandbox.ts +22 -0
  139. package/examples/release-scout/README.md +11 -0
  140. package/examples/release-scout/agent/agent.ts +22 -0
  141. package/examples/release-scout/agent/channels/github-signature.ts +27 -0
  142. package/examples/release-scout/agent/channels/github.ts +38 -0
  143. package/examples/release-scout/agent/connections/linear.ts +9 -0
  144. package/examples/release-scout/agent/hooks/audit.ts +24 -0
  145. package/examples/release-scout/agent/instructions/org-context.ts +26 -0
  146. package/examples/release-scout/agent/instructions.md +2 -0
  147. package/examples/release-scout/agent/sandbox.ts +20 -0
  148. package/examples/release-scout/agent/schedules/daily-digest.md +7 -0
  149. package/examples/release-scout/agent/skills/triage/SKILL.md +8 -0
  150. package/examples/release-scout/agent/skills/triage/checklist.md +3 -0
  151. package/examples/release-scout/agent/tools/lookup_release_notes.ts +24 -0
  152. package/examples/release-scout/client.ts +123 -0
  153. package/package.json +126 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/agent-client/conversations.ts"],
4
+ "sourcesContent": ["import {\n ProcessInspectionOperation,\n processInspectionRequestSchema,\n processInspectionResultSchema,\n type ProcessInspectionRequestIface,\n type ProcessInspectionResultIface,\n} from '@finalai/agent-protocol';\nimport {\n agentRealtimeFrameSchema,\n AgentRealtimeFrameType,\n AgentRealtimeKind,\n agentRealtimeTopics,\n AgentSessionState,\n attachmentDownloadSchema,\n attachmentUploadSchema,\n cancelConversationRequestSchema,\n conversationLinkListSchema,\n conversationLinkSchema,\n conversationListSchema,\n conversationMessageSchema,\n conversationMessagesPageSchema,\n conversationSandboxListSchema,\n conversationSandboxSchema,\n conversationScheduleListSchema,\n conversationScheduleSchema,\n conversationSchema,\n createAttachmentUploadRequestSchema,\n createConversationLinkRequestSchema,\n createConversationRequestSchema,\n createConversationScheduleRequestSchema,\n createDirectConversationRequestSchema,\n decisionsPageSchema,\n markReadRequestSchema,\n messageDeliveriesSchema,\n MessageStreamingState,\n MessageThreadFilter,\n okResponseSchema,\n parseAgentRealtimeEvent,\n participantInputSchema,\n ParticipantKind,\n participantListSchema,\n participantSchema,\n PendingEventState,\n pendingRequestListSchema,\n postConversationEventRequestSchema,\n pushDeliveryOpenResponseSchema,\n reactionRequestSchema,\n reactionsResponseSchema,\n readStateSchema,\n removeParticipantRequestSchema,\n respondPendingRequestSchema,\n respondPendingResponseSchema,\n sandboxDirectorySchema,\n sandboxEditorAuthorizationSchema,\n sandboxEditorSessionSchema,\n sandboxFileSchema,\n sandboxPathSchema,\n sandboxPreviewOptionsSchema,\n sandboxPreviewSchema,\n sandboxSearchSchema,\n searchMessagesPageSchema,\n sendMessageRequestSchema,\n sendMessageResponseSchema,\n sessionSchema,\n typingRequestSchema,\n updateConversationRequestSchema,\n updateConversationScheduleRequestSchema,\n updateParticipantRequestSchema,\n type AgentRealtimeEvent,\n type AgentRealtimeEventOf,\n type AgentSessionIface,\n type AgentTurnPolicy,\n type AttachmentDownloadIface,\n type AttachmentUploadIface,\n type ContentInput,\n type ConversationIface,\n type ConversationKind,\n type ConversationLinkIface,\n type ConversationListIface,\n type ConversationMessageIface,\n type ConversationMessagesPageIface,\n type ConversationSandboxIface,\n type ConversationScheduleIface,\n type CreateConversationScheduleRequestIface,\n type DecisionsPageIface,\n type MessageDeliveryIface,\n type ParticipantIface,\n type ParticipantInput,\n type PendingRequestIface,\n type PostConversationEventRequestIface,\n type ReactionIface,\n type ReadStateIface,\n type RespondPendingResponseIface,\n type SandboxDirectoryIface,\n type SandboxEditorSessionIface,\n type SandboxFileIface,\n type SandboxPathIface,\n type SandboxPreviewType,\n type SandboxSearchIface,\n type SearchMessagesPageIface,\n type UpdateConversationRequestIface,\n type UpdateConversationScheduleRequestIface,\n type UpdateParticipantRequestIface,\n type WireFallback,\n} from '@finalai/agent-protocol/agent-platform';\nimport { createAsyncQueue, failOnAbort } from \"./async-queue.mjs\";\nimport {\n streamCollectionEvents,\n type CollectionEvent,\n type CollectionEventsOptionsIface,\n} from \"./collection-events.mjs\";\nimport {\n ClientCollection,\n encodePath,\n type ClientContextIface,\n type EnumInput,\n type SignalOptionsIface,\n} from \"./context.mjs\";\nimport {\n clientError,\n ClientErrorCode,\n isRetryableClientError,\n isTerminalRealtimeError,\n realtimeSubscriptionError,\n} from \"./errors.mjs\";\nimport { errorFromResponse, HttpMethod, type HttpRequestArgsIface } from \"./http.mjs\";\nimport type { RealtimeTransportFrameIface } from \"./realtime.mjs\";\nimport { outcomeOf, type RespondArgs } from \"./sessions.mjs\";\n\nexport interface SandboxFileContentArgsIface {\n snapshotId?: string;\n bindingId: string;\n path: string;\n download?: boolean;\n /** One HTTP byte range, for example `bytes=1024-2047`. */\n range?: string;\n}\n\nexport interface SandboxFileContentRequestIface {\n url: string;\n /** Supply these to native download/media clients; never put bearer tokens in URLs. */\n headers: Record<string, string>;\n credentials: RequestCredentials;\n}\n\nexport interface ConversationEventMetaIface {\n topic: string;\n cursor: string | null;\n createdAt: string | null;\n /** True for messages the SDK fetched over HTTP to fill a realtime gap. */\n replayed: boolean;\n}\n\n/** A realtime event of the conversation topic, flattened (`event.message`, `event.pending`). */\nexport type ConversationEvent = AgentRealtimeEvent & ConversationEventMetaIface;\n\nexport interface ConversationEventsOptionsIface extends SignalOptionsIface {\n /** Keep streaming; false ends once the subscription is current. Defaults to true. */\n follow?: boolean;\n /** Also replay messages (thread replies included) after this conversation seq when the subscription opens. */\n afterSeq?: number;\n /** Gateway cursor to resume the topic after. */\n afterCursor?: string;\n /**\n * Messages the caller already has (an earlier stream or page). On the first\n * subscription the stream recovers everything created or updated since the\n * newest of them, thread replies included, and skips the versions given, so\n * a client resuming a conversation it rendered before is left with no gap.\n */\n resumeFrom?: readonly ConversationMessageIface[];\n /**\n * Called on every resubscribe (after the first) and resync, as the stream\n * starts recovering messages. State that messages cannot reconstruct, such\n * as whether an agent's turn ended without a reply, is the caller's to re-read.\n */\n onResubscribed?: () => void;\n /**\n * Also recover what only realtime carries (default true). On every\n * (re)subscribe, resync and fallback poll the stream re-reads the open\n * permission and elicitation requests of the conversation's agent sessions\n * and emits replayed `acp.pending` events: `created` for an open request it\n * has not emitted, `resolved` for one it emitted open that no longer is. And\n * for every turn it saw start whose session is no longer running, it emits a\n * replayed `conversation.turn.ended` (stop reason null). Turns that started\n * and ended while it was away arrive only as messages.\n */\n recoverTransient?: boolean;\n // While the realtime transport reports errors, a following stream polls the\n // same recovery every `timing.pollIntervalMs` until it is subscribed again.\n // Without `resumeFrom` or `afterSeq`, the stream reads the newest message when it is\n // called and, once subscribed, recovers every change after it (thread replies included),\n // so nothing posted while the subscription registers is lost.\n}\n\nexport interface SendMessageOptionsIface extends SignalOptionsIface {\n clientMessageId?: string;\n replyTo?: string;\n threadRootId?: string;\n /** Ids of earlier messages in the conversation to quote, in order. */\n quotes?: string[];\n /** Mentioned participant ids. */\n mentions?: string[];\n attachmentIds?: string[];\n /** When the person submitted, for the prompt-to-inference trace; defaults to now. */\n clientSubmittedAtMs?: number;\n}\n\nexport type ParticipantCreateInput =\n | { user: string }\n | {\n agent: string;\n routingMode?: EnumInput<\n NonNullable<Extract<ParticipantInput, { agent: string }>['routingMode']>\n >;\n }\n | { apiKeyPrincipal: string };\n\nexport interface SentMessageIface {\n message: ConversationMessageIface;\n messageId: string;\n seq: number;\n /** One entry per agent participant the message was routed to. */\n deliveries: MessageDeliveryIface[];\n}\n\nexport interface ListMessagesOptionsIface extends SignalOptionsIface {\n before?: number;\n after?: number;\n limit?: number;\n /** Thread root message id, or `MessageThreadFilter.All` for the timeline plus every thread. */\n thread?: string;\n /** ISO instant: messages created or updated after it (the first page of a change scan). */\n updatedAfter?: string;\n /** A previous page's `nextUpdatedCursor`: continue the change scan after it. */\n updatedCursor?: string;\n}\n\nexport interface UploadAttachmentArgsIface extends SignalOptionsIface {\n name: string;\n contentType: string;\n data: Blob | ArrayBuffer;\n}\n\nexport interface ConversationHandleIface {\n /** Durable accepted prompt receipts for a message, including queued deliveries once admitted. */\n deliveries: (\n args: { messageId: string },\n options?: SignalOptionsIface,\n ) => Promise<MessageDeliveryIface[]>;\n\n id: string;\n info: (options?: SignalOptionsIface) => Promise<ConversationIface>;\n send: (content: ContentInput, options?: SendMessageOptionsIface) => Promise<SentMessageIface>;\n events: (options?: ConversationEventsOptionsIface) => AsyncIterableIterator<ConversationEvent>;\n messages: (options?: ListMessagesOptionsIface) => Promise<ConversationMessagesPageIface>;\n /** One message by id (`GET /v1/conversations/:id/messages/:messageId`), e.g. a thread root. */\n message: (\n args: { messageId: string },\n options?: SignalOptionsIface,\n ) => Promise<ConversationMessageIface>;\n react: (\n args: { messageId: string; emoji: string },\n options?: SignalOptionsIface,\n ) => Promise<ReactionIface[]>;\n unreact: (\n args: { messageId: string; emoji: string },\n options?: SignalOptionsIface,\n ) => Promise<ReactionIface[]>;\n recordPushOpen: (\n args: { deliveryId: string },\n options?: SignalOptionsIface,\n ) => Promise<{ recorded: boolean }>;\n markRead: (args: { throughSeq: number }, options?: SignalOptionsIface) => Promise<ReadStateIface>;\n /**\n * Marks a thread read through one of its replies' seq and follows it\n * (`POST \u2026/threads/:rootId/read`); the conversation's own unread count\n * moves with `markRead`.\n */\n markThreadRead: (\n args: { rootId: string; throughSeq: number },\n options?: SignalOptionsIface,\n ) => Promise<void>;\n /**\n * Tells the other members the caller is typing (`POST \u2026/typing`), realtime\n * only. A `true` lapses on its own after a few seconds, so composers repeat\n * it while typing continues and send `false` when the draft is sent or cleared.\n */\n typing: (args: { typing: boolean }, options?: SignalOptionsIface) => Promise<void>;\n /**\n * Posts something that happened outside the conversation (`POST \u2026/events`):\n * a message from the source's system participant (a Goal, a tool, a\n * webhook), routed like one. The same `eventId` from the same source posts once.\n */\n postEvent: (\n event: PostConversationEventRequestIface,\n options?: SignalOptionsIface,\n ) => Promise<SentMessageIface>;\n respond: (\n args: RespondArgs,\n options?: SignalOptionsIface,\n ) => Promise<RespondPendingResponseIface>;\n /** Stops the agents' running turns in this conversation. */\n cancel: (\n options?: SignalOptionsIface & { reason?: string; throughMessageSeq?: number },\n ) => Promise<void>;\n participants: (options?: SignalOptionsIface) => Promise<ParticipantIface[]>;\n /**\n * Each agent participant's session state, read now: whether a turn is\n * running in it. What a client re-reads when it may have missed a\n * `conversation.turn.ended` (`events()` reconciles the turns it saw itself).\n */\n turns: (options?: SignalOptionsIface) => Promise<ConversationAgentTurnIface[]>;\n addParticipant: (\n participant: ParticipantCreateInput,\n options?: SignalOptionsIface,\n ) => Promise<ParticipantIface>;\n /**\n * Changes an agent's routing mode (owners and admins) or a person's role\n * (owners, groups only; the last owner cannot step down). One field per call.\n */\n updateParticipant: (\n args: { participantId: string } & Omit<\n UpdateParticipantRequestIface,\n 'routingMode' | 'role'\n > & {\n routingMode?: EnumInput<NonNullable<UpdateParticipantRequestIface['routingMode']>>;\n role?: EnumInput<NonNullable<UpdateParticipantRequestIface['role']>>;\n },\n options?: SignalOptionsIface,\n ) => Promise<ParticipantIface>;\n removeParticipant: (\n args: { participantId: string },\n options?: SignalOptionsIface,\n ) => Promise<void>;\n update: (\n patch: UpdateConversationRequestIface,\n options?: SignalOptionsIface,\n ) => Promise<ConversationIface>;\n delete: (args: { messageId: string }, options?: SignalOptionsIface) => Promise<void>;\n uploadAttachment: (args: UploadAttachmentArgsIface) => Promise<AttachmentUploadIface>;\n /**\n * A fresh presigned download URL for one attachment\n * (`GET /v1/conversations/:id/attachments/:attachmentId`). URLs on messages\n * expire; resolve through this before opening one that may be stale.\n */\n attachmentUrl: (\n args: { attachmentId: string },\n options?: SignalOptionsIface,\n ) => Promise<AttachmentDownloadIface>;\n /**\n * The conversation's sandboxes (the computer tile): status, capabilities and\n * whether a preview is available (`GET /v1/conversations/:id/sandboxes`).\n * Never starts a parked sandbox.\n */\n sandboxes: (options?: SignalOptionsIface) => Promise<ConversationSandboxIface[]>;\n /** One directory of a running sandbox, confined to its workspace (`\u2026/sandboxes/:bindingId/files`). */\n sandboxFiles: (\n args: { bindingId: string; path?: string; snapshotId?: string },\n options?: SignalOptionsIface,\n ) => Promise<SandboxDirectoryIface>;\n /** Resolves a file or directory without waking its sandbox. */\n sandboxPath: (\n args: { bindingId: string; path?: string; snapshotId?: string },\n options?: SignalOptionsIface,\n ) => Promise<SandboxPathIface>;\n /** Bounded recursive path search; truncated signals incomplete traversal. */\n searchSandboxFiles: (\n args: { bindingId: string; path?: string; query: string; limit?: number },\n options?: SignalOptionsIface,\n ) => Promise<SandboxSearchIface>;\n /** A byte range of a file in a running sandbox, at most 1 MiB (`\u2026/sandboxes/:bindingId/file`). */\n sandboxFile: (\n args: {\n bindingId: string;\n path: string;\n offset?: number;\n length?: number;\n snapshotId?: string;\n },\n options?: SignalOptionsIface,\n ) => Promise<SandboxFileIface>;\n inspectSandboxProcesses(\n args: { bindingId: string; request: ProcessInspectionRequestIface },\n options?: SignalOptionsIface,\n ): Promise<ProcessInspectionResultIface>;\n /** Opens a provider editor for an existing workspace, with write authorization. */\n openSandboxEditor(\n args: { bindingId: string },\n options?: SignalOptionsIface,\n ): Promise<SandboxEditorSessionIface>;\n refreshSandboxEditor(\n args: { bindingId: string; editorId: string; authorizationId: string },\n options?: SignalOptionsIface,\n ): Promise<SandboxEditorSessionIface>;\n closeSandboxEditor(\n args: { bindingId: string; editorId: string; authorizationId: string },\n options?: SignalOptionsIface & { keepalive?: boolean },\n ): Promise<void>;\n /** Raw streaming bytes (`\u2026/file/content`). The caller consumes or cancels the response body. */\n sandboxFileContent: (\n args: SandboxFileContentArgsIface,\n options?: SignalOptionsIface,\n ) => Promise<Response>;\n /**\n * An authenticated request for a browser/native media or download client.\n * Cookie clients can use the URL directly; bearer clients must supply headers.\n * Every request rechecks membership and confinement; never wakes the sandbox.\n */\n sandboxFileContentRequest: (\n args: SandboxFileContentArgsIface,\n ) => Promise<SandboxFileContentRequestIface>;\n /** A short-lived screen preview of a running sandbox; 404 when it serves none (`\u2026/preview`). */\n sandboxPreview: (\n args: { bindingId: string; viewOnly?: boolean },\n options?: SignalOptionsIface,\n ) => Promise<SandboxPreviewType>;\n /** Starts a parked sandbox (conversation owners and admins; `POST \u2026/wake`). */\n wakeSandbox: (\n args: { bindingId: string },\n options?: SignalOptionsIface,\n ) => Promise<ConversationSandboxIface>;\n /** The conversation's runtime schedules: reminders and recurring checks (`GET \u2026/schedules`). */\n schedules: (options?: SignalOptionsIface) => Promise<ConversationScheduleIface[]>;\n /**\n * Creates a schedule owned by one agent participant (`POST \u2026/schedules`).\n * Agents create their own; people need to be conversation owners or admins.\n */\n createSchedule: (\n args: CreateConversationScheduleRequestIface,\n options?: SignalOptionsIface,\n ) => Promise<ConversationScheduleIface>;\n /** Changes a schedule (its agent, or conversation owners and admins; `PATCH \u2026/schedules/:id`). */\n updateSchedule: (\n args: { scheduleId: string } & UpdateConversationScheduleRequestIface,\n options?: SignalOptionsIface,\n ) => Promise<ConversationScheduleIface>;\n /** Deletes a schedule (`DELETE \u2026/schedules/:id`). */\n deleteSchedule: (args: { scheduleId: string }, options?: SignalOptionsIface) => Promise<void>;\n /**\n * The conversations this one handed work to, with what their agents are\n * doing (`GET \u2026/links`). Their replies and waits arrive here as messages.\n */\n links: (options?: SignalOptionsIface) => Promise<ConversationLinkIface[]>;\n /** Conversations receiving this conversation\u2019s delegated results. */\n parentLinks: (options?: SignalOptionsIface) => Promise<ConversationLinkIface[]>;\n /**\n * Links another conversation the caller belongs to (`POST \u2026/links`); linking\n * it again returns the same link. Links never form a cycle.\n */\n link: (\n args: { conversationId: string },\n options?: SignalOptionsIface,\n ) => Promise<ConversationLinkIface>;\n /** Removes a link (`DELETE \u2026/links/:linkId`); both conversations remain. */\n unlink: (args: { linkId: string }, options?: SignalOptionsIface) => Promise<void>;\n}\n\nexport interface ConversationAgentTurnIface {\n participantId: string;\n sessionId: string;\n state: AgentSessionState | WireFallback;\n /** A turn is running or waiting on a pending request. */\n running: boolean;\n}\n\n/** Session states in which a turn is open. */\nexport const TURN_OPEN_SESSION_STATES: ReadonlySet<AgentSessionState | WireFallback> = new Set([\n AgentSessionState.Running,\n AgentSessionState.RequiresAction,\n]);\n\nexport interface OpenedConversationIface extends ConversationHandleIface {\n conversation: ConversationIface;\n}\n\nexport interface CreateConversationArgsIface extends SignalOptionsIface {\n kind: EnumInput<ConversationKind>;\n title?: string;\n participants: ParticipantCreateInput[];\n turnPolicy?: EnumInput<AgentTurnPolicy>;\n}\n\nexport interface ConversationsApiIface {\n list: (\n options?: SignalOptionsIface & { cursor?: string; limit?: number; includeArchived?: boolean },\n ) => Promise<ConversationListIface>;\n /** Finds or creates the caller's direct conversation with an agent. */\n direct: (args: { agent: string } & SignalOptionsIface) => Promise<OpenedConversationIface>;\n /** Finds or creates the caller's Home conversation. */\n home: (options?: SignalOptionsIface) => Promise<OpenedConversationIface>;\n create: (args: CreateConversationArgsIface) => Promise<OpenedConversationIface>;\n /** I/O-free handle. */\n get: (conversationId: string) => ConversationHandleIface;\n /** Full-text search over the caller's conversations (or one), newest first. */\n search: (\n args: {\n q: string;\n conversationId?: string;\n cursor?: string;\n limit?: number;\n } & SignalOptionsIface,\n ) => Promise<SearchMessagesPageIface>;\n /**\n * The caller's conversation list topic (`user.collection:<userId>:conversations`):\n * `conversation.list.changed` and `conversation.updated` events, and a\n * `collection.resync` whenever `list()` must be re-read (on every\n * subscription, resync and while realtime is down).\n */\n listEvents: (options?: CollectionEventsOptionsIface) => AsyncIterableIterator<CollectionEvent>;\n /** Everything awaiting the caller's answer across conversations. */\n decisions: (\n options?: SignalOptionsIface & { cursor?: string; limit?: number },\n ) => Promise<DecisionsPageIface>;\n}\n\nconst conversationPath = (conversationId: string, suffix = ''): string =>\n `/v1/conversations/${encodePath(conversationId)}${suffix}`;\n\nconst messagePath = (conversationId: string, messageId: string, suffix = ''): string =>\n conversationPath(conversationId, `/messages/${encodePath(messageId)}${suffix}`);\n\ninterface ConversationStreamArgsIface {\n context: ClientContextIface;\n conversationId: string;\n options: ConversationEventsOptionsIface | undefined;\n listMessages: (options: ListMessagesOptionsIface) => Promise<ConversationMessagesPageIface>;\n listParticipants: (options: SignalOptionsIface) => Promise<ParticipantIface[]>;\n getSession: (sessionId: string, options: SignalOptionsIface) => Promise<AgentSessionIface>;\n sessionPending: (\n sessionId: string,\n options: SignalOptionsIface,\n ) => Promise<PendingRequestIface[]>;\n}\n\n// Bounds on the ids a stream remembers to dedupe transient events.\nconst MAX_REMEMBERED = 4096;\n\n// `GET /v1/sessions/:id/pending` returns at most this many open requests; a\n// list that long may be truncated, so absence from it proves nothing.\nconst SESSION_PENDING_LIMIT = 200;\n\nconst remember = <Key, Value>(map: Map<Key, Value>, key: Key, value: Value): void => {\n map.delete(key);\n map.set(key, value);\n if (map.size > MAX_REMEMBERED) {\n const oldest = map.keys().next();\n if (oldest.done !== true) map.delete(oldest.value);\n }\n};\n\ntype TurnStartedEventIface = AgentRealtimeEventOf<AgentRealtimeKind.TurnStarted>;\n\nconst isTransientEvent = (event: AgentRealtimeEvent): boolean =>\n event.kind === AgentRealtimeKind.AcpPending ||\n event.kind === AgentRealtimeKind.TurnStarted ||\n event.kind === AgentRealtimeKind.TurnEnded;\n\nconst REPLAY_PAGE = 100;\n/**\n * Every recovery rescans this far behind the newest change seen: `updated_at`\n * is a transaction's start time, so a slow write (a lock wait) can commit\n * after newer changes were delivered.\n */\nexport const RECOVERY_SKEW_MS = 30_000;\n\nconst stampOf = (message: ConversationMessageIface): number =>\n Math.max(\n ...[message.updatedAt, message.deletedAt, message.createdAt].map((value) =>\n value == null ? 0 : Date.parse(value) || 0,\n ),\n );\n\n/** The newest copy of a message the stream has emitted (or the caller already had). */\nexport interface MessageVersionIface {\n /** The server's per-message change counter: a total order when both copies carry it. */\n revision: number | null;\n /** `updatedAt` in ms; distinct changes can share a millisecond. */\n updatedAt: number | null;\n /** Newest of updatedAt/deletedAt/createdAt, for messages without `updatedAt`. */\n stamp: number;\n deleted: boolean;\n final: boolean;\n fingerprint: string;\n}\n\nconst isoMs = (value: string | null): number | null => {\n if (value == null) return null;\n const ms = Date.parse(value);\n return Number.isNaN(ms) ? null : ms;\n};\n\nexport const messageVersionOf = (message: ConversationMessageIface): MessageVersionIface => ({\n revision: message.revision,\n updatedAt: isoMs(message.updatedAt),\n stamp: stampOf(message),\n deleted: message.deletedAt != null,\n final: message.streaming?.state === MessageStreamingState.Final,\n fingerprint: JSON.stringify([\n message.deletedAt,\n message.streaming?.state ?? null,\n message.body,\n message.reactions,\n ]),\n});\n\n/**\n * Whether `incoming` is newer than the copy already emitted; older or equal\n * copies are dropped. A deletion is never undone. `revision` orders copies\n * when both carry it. Otherwise `updatedAt` does, where a finalized reply\n * beats a streaming copy from the same millisecond; without either, a later\n * change time wins, a finalized reply is never undone by a copy at the same\n * time, and equal times fall back to content.\n */\nexport const isNewerMessageVersion = (\n incoming: MessageVersionIface,\n current: MessageVersionIface | undefined,\n): boolean => {\n if (current == null) return true;\n if (current.deleted && !incoming.deleted) return false;\n if (incoming.revision != null && current.revision != null) {\n return incoming.revision > current.revision;\n }\n if (incoming.updatedAt != null && current.updatedAt != null) {\n if (incoming.updatedAt !== current.updatedAt) return incoming.updatedAt > current.updatedAt;\n return incoming.final && !current.final;\n }\n if (incoming.stamp !== current.stamp) return incoming.stamp > current.stamp;\n if (current.final && !incoming.final) return false;\n return incoming.fingerprint !== current.fingerprint;\n};\n\ninterface PendingLiveIface {\n event: AgentRealtimeEvent;\n meta: ConversationEventMetaIface;\n // A transient event whose state was recorded when it arrived (or was recovered);\n // released as is.\n noted: boolean;\n}\n\n/**\n * Live conversation events. On every resubscribe or resync the stream\n * recovers what changed while it was away: messages created *or updated*\n * (including thread replies), scanned in the server's (updated_at, id) order.\n * The first scan starts at the newest change seen minus a skew; every scan\n * ends on the server's change cursor, and the next scan resumes from it, so\n * messages that share an update time are never skipped between pages.\n * Live events that arrive during recovery are held and released after it,\n * and message events are deduped by id and version, so a reconnect neither\n * loses nor repeats a message.\n */\nconst streamConversationEvents = (\n args: ConversationStreamArgsIface,\n): AsyncIterableIterator<ConversationEvent> => {\n const topic = agentRealtimeTopics.conversation(args.conversationId);\n const follow = args.options?.follow ?? true;\n const controller = new AbortController();\n const signal = AbortSignal.any([\n controller.signal,\n args.context.closeSignal,\n ...(args.options?.signal == null ? [] : [args.options.signal]),\n ]);\n const versions = new Map<string, MessageVersionIface>();\n let newestStamp: number | null = null;\n const subscribedAt = Date.now();\n let recoveryFloor: number | null = null;\n let subscribedOnce = false;\n let recovering = 0;\n let recovery: Promise<void> = Promise.resolve();\n const held: PendingLiveIface[] = [];\n const recoverTransientState = args.options?.recoverTransient ?? true;\n // Transient events emitted so far, so live and recovered copies are emitted once.\n // `noted` orders each entry against recovery snapshots (see recoverTransient).\n let transientClock = 0;\n const pendingSeen = new Map<\n string,\n { state: PendingEventState; pending: PendingRequestIface; noted: number }\n >();\n const runningTurns = new Map<string, { turn: TurnStartedEventIface; noted: number }>();\n const endedTurns = new Map<string, true>();\n // The realtime transport reported a retryable error and has not resubscribed since.\n let degraded = false;\n let pollTimer: ReturnType<typeof setTimeout> | null = null;\n const clearPoll = (): void => {\n if (pollTimer != null) clearTimeout(pollTimer);\n pollTimer = null;\n };\n let unsubscribe: (() => void) | null = null;\n let detachAbort: () => void = () => {};\n let detachClose: () => void = () => {};\n const queue = createAsyncQueue<ConversationEvent>(() => {\n controller.abort();\n held.length = 0;\n clearPoll();\n unsubscribe?.();\n detachAbort();\n detachClose();\n });\n const resumeFrom = args.options?.resumeFrom ?? [];\n // Taken when `events()` is called, before subscribing; see recoverFromAnchor.\n const anchor =\n resumeFrom.length === 0 && args.options?.afterSeq == null\n ? args.listMessages({ limit: 1, thread: MessageThreadFilter.All, signal })\n : null;\n // A failed anchor read surfaces through the recovery that awaits it.\n anchor?.catch(() => {});\n for (const message of resumeFrom) {\n versions.set(message.id, messageVersionOf(message));\n newestStamp = Math.max(newestStamp ?? 0, stampOf(message));\n }\n\n /** Emits a message event only when it is newer than every copy of that message emitted so far. */\n const emitMessage = (\n message: ConversationMessageIface,\n meta: ConversationEventMetaIface,\n live: AgentRealtimeEvent | null,\n ): void => {\n const version = messageVersionOf(message);\n const previous = versions.get(message.id);\n if (!isNewerMessageVersion(version, previous)) return;\n versions.set(message.id, version);\n newestStamp = Math.max(newestStamp ?? 0, stampOf(message));\n if (live != null) {\n queue.push({ ...live, ...meta });\n return;\n }\n queue.push(\n previous == null\n ? { kind: AgentRealtimeKind.MessageCreated, message, ...meta }\n : { kind: AgentRealtimeKind.MessageUpdated, message, ...meta },\n );\n };\n\n /** Records a pending event; false when an equal or newer state was already emitted. */\n const notePending = (\n pending: PendingRequestIface,\n state: PendingEventState | WireFallback,\n ): boolean => {\n const seen = pendingSeen.get(pending.id);\n if (state === PendingEventState.Resolved) {\n if (seen?.state === PendingEventState.Resolved) return false;\n transientClock += 1;\n remember(pendingSeen, pending.id, { state, pending, noted: transientClock });\n return true;\n }\n if (state === PendingEventState.Created) {\n if (seen != null) return false;\n transientClock += 1;\n remember(pendingSeen, pending.id, { state, pending, noted: transientClock });\n return true;\n }\n return true;\n };\n\n /** Records a pending or turn event's state; false when it repeats one already emitted. */\n const noteTransient = (event: AgentRealtimeEvent): boolean => {\n if (event.kind === AgentRealtimeKind.AcpPending) return notePending(event.pending, event.state);\n if (event.kind === AgentRealtimeKind.TurnStarted) {\n if (!endedTurns.has(event.turnId)) {\n transientClock += 1;\n remember(runningTurns, event.turnId, { turn: event, noted: transientClock });\n }\n return true;\n }\n if (event.kind === AgentRealtimeKind.TurnEnded) {\n if (endedTurns.has(event.turnId)) return false;\n remember(endedTurns, event.turnId, true);\n runningTurns.delete(event.turnId);\n }\n return true;\n };\n\n const emitLive = (event: AgentRealtimeEvent, meta: ConversationEventMetaIface): void => {\n if (\n event.kind === AgentRealtimeKind.MessageCreated ||\n event.kind === AgentRealtimeKind.MessageUpdated\n ) {\n emitMessage(event.message, meta, event);\n return;\n }\n if (event.kind === AgentRealtimeKind.MessageDeleted) {\n // A deletion outranks every copy up to its time, so a held or replayed older copy cannot restore it.\n const current = versions.get(event.messageId);\n if (current?.deleted === true) return;\n const deletedAt = isoMs(event.deletedAt) ?? current?.stamp ?? 0;\n versions.set(event.messageId, {\n revision: current?.revision ?? null,\n updatedAt: Math.max(current?.updatedAt ?? 0, deletedAt),\n stamp: Math.max(current?.stamp ?? 0, deletedAt),\n deleted: true,\n final: current?.final ?? false,\n fingerprint: current?.fingerprint ?? '',\n });\n }\n if (!noteTransient(event)) return;\n queue.push({ ...event, ...meta });\n };\n\n const replayed = (message: ConversationMessageIface): ConversationEventMetaIface => ({\n topic,\n cursor: null,\n createdAt: message.updatedAt ?? message.createdAt,\n replayed: true,\n });\n\n const emitPage = (messages: ConversationMessageIface[]): void => {\n for (const message of [...messages].sort((left, right) => left.seq - right.seq)) {\n emitMessage(message, replayed(message), null);\n }\n };\n\n /**\n * One change scan, paged by the server's cursor. Every scan starts over from\n * the oldest writer active before the preceding scan (or the newest change\n * minus the skew for older servers), never from the last scan\u2019s cursor:\n * `updated_at` is the writing transaction's start time, so a change can\n * commit after a later one was already seen. Revision ordering drops the\n * repeats the overlap brings back.\n */\n const recoverChanges = async (): Promise<void> => {\n const since = Math.max(\n 0,\n Math.min(newestStamp ?? subscribedAt, recoveryFloor ?? Infinity) - RECOVERY_SKEW_MS,\n );\n let position: { updatedCursor: string } | { updatedAfter: string } = {\n updatedAfter: new Date(since).toISOString(),\n };\n let nextFloor: number | null = null;\n for (;;) {\n const page = await args.listMessages({\n ...position,\n thread: MessageThreadFilter.All,\n limit: REPLAY_PAGE,\n signal,\n });\n if (nextFloor == null && page.recoverySince != null) {\n const stamp = Date.parse(page.recoverySince);\n if (Number.isFinite(stamp)) nextFloor = stamp;\n }\n emitPage(page.messages);\n const next = page.nextUpdatedCursor;\n if (next == null || !page.hasMoreAfter || page.messages.length === 0) {\n recoveryFloor = nextFloor ?? recoveryFloor;\n return;\n }\n position = { updatedCursor: next };\n }\n };\n\n /**\n * With nothing to resume from, the stream anchors on the newest message at\n * the moment `events()` was called and, once subscribed, recovers every\n * change after it. So a message posted between a caller's first page and the\n * gateway registering the subscription still arrives (marked `replayed`).\n */\n const recoverFromAnchor = async (anchor: Promise<ConversationMessagesPageIface>) => {\n const page = await anchor;\n if (page.recoverySince != null) {\n const stamp = Date.parse(page.recoverySince);\n if (Number.isFinite(stamp)) recoveryFloor = stamp;\n }\n const newest = page.messages.reduce<ConversationMessageIface | null>(\n (best, message) => (best == null || message.seq > best.seq ? message : best),\n null,\n );\n if (newest != null && !versions.has(newest.id)) {\n versions.set(newest.id, messageVersionOf(newest));\n newestStamp = Math.max(newestStamp ?? 0, stampOf(newest));\n }\n await recoverChanges();\n };\n\n const recoverAfterSeq = async (afterSeq: number): Promise<void> => {\n let cursor = afterSeq;\n for (;;) {\n const page = await args.listMessages({\n after: cursor,\n thread: MessageThreadFilter.All,\n limit: REPLAY_PAGE,\n signal,\n });\n emitPage(page.messages);\n const next = Math.max(cursor, ...page.messages.map((message) => message.seq));\n if (!page.hasMoreAfter || next === cursor) return;\n cursor = next;\n }\n };\n\n const recoveredMeta = (): ConversationEventMetaIface => ({\n topic,\n cursor: null,\n createdAt: null,\n replayed: true,\n });\n\n /** A read that recovery may skip: retryable failures retry the recovery, others drop the read. */\n const optional = async <Value>(read: () => Promise<Value>): Promise<Value | null> => {\n try {\n return await read();\n } catch (cause) {\n if (isRetryableClientError(cause)) throw cause;\n return null;\n }\n };\n\n // Recovery runs while live events are held: a recovered transient event joins\n // them, so it is released after every live event that arrived before it.\n const emitRecovered = (event: AgentRealtimeEvent): void => {\n held.push({ event, meta: recoveredMeta(), noted: true });\n };\n\n /**\n * Re-reads what only realtime carries (see `recoverTransient`): the open\n * pending requests and turn state of every agent participant's session.\n * Live transient events held during recovery record their state on arrival,\n * so the snapshot settles what was recorded before it was requested, and\n * never a turn or request that arrived live after it.\n */\n const recoverTransient = async (): Promise<void> => {\n if (!recoverTransientState) return;\n const asOf = transientClock;\n const participants = await optional(() => args.listParticipants({ signal }));\n const current =\n participants == null\n ? null\n : new Set(\n participants.flatMap((participant) =>\n participant.kind === ParticipantKind.Agent &&\n participant.sessionId != null &&\n participant.leftAt == null\n ? [participant.sessionId]\n : [],\n ),\n );\n // Sessions the stream holds open state for, including ones whose agent has since left.\n const remembered = new Set([\n ...[...pendingSeen.values()].flatMap((seen) =>\n seen.state === PendingEventState.Created ? [seen.pending.sessionId] : [],\n ),\n ...[...runningTurns.values()].map((entry) => entry.turn.sessionId),\n ]);\n const checked = await Promise.all(\n [...new Set([...(current ?? []), ...remembered])].map(async (sessionId) => {\n const [session, open] = await Promise.all([\n optional(() => args.getSession(sessionId, { signal })),\n optional(() => args.sessionPending(sessionId, { signal })),\n ]);\n // An agent that left: its session is closed, and may no longer be readable.\n const departed = current != null && !current.has(sessionId);\n return {\n sessionId,\n running:\n session == null\n ? departed\n ? false\n : null\n : TURN_OPEN_SESSION_STATES.has(session.state),\n open: open ?? (departed ? [] : null),\n };\n }),\n );\n for (const { sessionId, running, open } of checked) {\n if (open != null) {\n const complete = open.length < SESSION_PENDING_LIMIT;\n const openIds = new Set(open.map((pending) => pending.id));\n for (const pending of open) {\n if (notePending(pending, PendingEventState.Created))\n emitRecovered({\n kind: AgentRealtimeKind.AcpPending,\n pending,\n state: PendingEventState.Created,\n });\n }\n for (const seen of [...pendingSeen.values()]) {\n if (\n !complete ||\n seen.state !== PendingEventState.Created ||\n seen.noted > asOf ||\n seen.pending.sessionId !== sessionId ||\n openIds.has(seen.pending.id)\n )\n continue;\n notePending(seen.pending, PendingEventState.Resolved);\n emitRecovered({\n kind: AgentRealtimeKind.AcpPending,\n pending: seen.pending,\n state: PendingEventState.Resolved,\n });\n }\n }\n if (running !== false) continue;\n for (const { turn, noted } of [...runningTurns.values()]) {\n if (turn.sessionId !== sessionId || noted > asOf) continue;\n runningTurns.delete(turn.turnId);\n remember(endedTurns, turn.turnId, true);\n emitRecovered({\n kind: AgentRealtimeKind.TurnEnded,\n conversationId: turn.conversationId,\n participantId: turn.participantId,\n sessionId: turn.sessionId,\n turnId: turn.turnId,\n stopReason: null,\n });\n }\n }\n };\n\n /** Runs a recovery while holding live events; the cursor is captured now, not when it runs. */\n const scheduleRecovery = (run: () => Promise<void>): void => {\n recovering += 1;\n recovery = recovery\n .then(async () => {\n let delay = 250;\n while (!queue.closed()) {\n try {\n await run();\n return;\n } catch (cause) {\n if (!follow || !isRetryableClientError(cause)) throw cause;\n await new Promise<void>((resolve) => {\n const done = () => {\n clearTimeout(timer);\n signal.removeEventListener('abort', done);\n resolve();\n };\n const timer = setTimeout(done, delay);\n if (signal.aborted) done();\n else signal.addEventListener('abort', done, { once: true });\n });\n delay = Math.min(delay * 2, 30_000);\n }\n }\n })\n .then(() => {\n recovering -= 1;\n if (recovering > 0) return;\n for (const entry of held.splice(0)) {\n if (entry.noted) queue.push({ ...entry.event, ...entry.meta });\n else emitLive(entry.event, entry.meta);\n }\n })\n .catch((cause) => queue.fail(cause));\n };\n\n // Reads the newest change when it runs, after any recovery queued before it.\n let newestRecoveryPending = false;\n let newestRecoveryRequested = false;\n const recoverFromNewest = (): void => {\n newestRecoveryRequested = true;\n if (newestRecoveryPending) return;\n newestRecoveryPending = true;\n scheduleRecovery(async () => {\n do {\n newestRecoveryRequested = false;\n await recoverChanges();\n await recoverTransient();\n } while (newestRecoveryRequested && !queue.closed());\n newestRecoveryPending = false;\n });\n };\n\n let initialRecoveryStarted = false;\n /** What the first subscription (or, while realtime is down, the first poll) recovers. */\n const startInitialRecovery = (): void => {\n if (initialRecoveryStarted) return;\n initialRecoveryStarted = true;\n const afterSeq = args.options?.afterSeq;\n if (afterSeq != null) scheduleRecovery(() => recoverAfterSeq(afterSeq));\n if (resumeFrom.length > 0) recoverFromNewest();\n if (anchor != null)\n scheduleRecovery(async () => {\n try {\n await recoverFromAnchor(anchor);\n } catch (cause) {\n if (!isRetryableClientError(cause)) throw cause;\n // A later anchor could hide messages written during the outage.\n await recoverChanges();\n }\n });\n // recoverFromNewest recovers transient state itself.\n if (resumeFrom.length === 0) scheduleRecovery(recoverTransient);\n };\n\n // HTTP polling while the realtime transport reports errors.\n const poll = (): void => {\n pollTimer = null;\n if (!degraded || queue.closed()) return;\n if (initialRecoveryStarted) recoverFromNewest();\n else startInitialRecovery();\n void recovery.then(() => {\n if (!degraded || queue.closed() || pollTimer != null) return;\n pollTimer = setTimeout(poll, args.context.timing.conversationPollIntervalMs);\n });\n };\n\n const onFrame = (raw: RealtimeTransportFrameIface): void => {\n const frame = agentRealtimeFrameSchema.safeParse(raw);\n if (!frame.success || queue.closed()) return;\n switch (frame.data.type) {\n case AgentRealtimeFrameType.Event: {\n const envelope = frame.data;\n const entry = {\n event: parseAgentRealtimeEvent(envelope),\n meta: {\n topic: envelope.topic,\n cursor: envelope.cursor,\n createdAt: envelope.createdAt,\n replayed: false,\n },\n };\n if (recovering > 0) {\n // Ending explicitly preserves transient events; a caller can reopen and recover messages.\n if (held.length >= 1024) {\n queue.fail(\n clientError({\n code: ClientErrorCode.Network,\n status: 0,\n message: 'Conversation recovery buffer is full; reconnect from the last message.',\n }),\n );\n return;\n }\n // Transient events record their state now, so recovery reconciles them.\n if (isTransientEvent(entry.event)) {\n if (noteTransient(entry.event)) held.push({ ...entry, noted: true });\n } else held.push({ ...entry, noted: false });\n } else emitLive(entry.event, entry.meta);\n return;\n }\n case AgentRealtimeFrameType.Subscribed: {\n degraded = false;\n clearPoll();\n if (!subscribedOnce) {\n subscribedOnce = true;\n // Polls during an outage before the first subscription already ran the initial recovery.\n if (initialRecoveryStarted) recoverFromNewest();\n else startInitialRecovery();\n } else {\n recoverFromNewest();\n args.options?.onResubscribed?.();\n }\n if (!follow) void recovery.then(() => queue.end());\n return;\n }\n case AgentRealtimeFrameType.ResyncRequired:\n recoverFromNewest();\n args.options?.onResubscribed?.();\n return;\n case AgentRealtimeFrameType.Error:\n if (isTerminalRealtimeError(frame.data)) {\n queue.fail(\n realtimeSubscriptionError({\n topic: frame.data.topic ?? topic,\n code: frame.data.code ?? 'unknown',\n message: frame.data.message ?? 'Realtime subscription was refused',\n }),\n );\n return;\n }\n // Retryable: the transport resubscribes (and its `subscribed` runs recovery);\n // meanwhile the stream recovers over HTTP. A non-following stream ends once\n // that recovery is current.\n if (!follow) {\n if (subscribedOnce) return;\n subscribedOnce = true;\n startInitialRecovery();\n void recovery.then(() => queue.end());\n return;\n }\n if (!degraded) {\n degraded = true;\n poll();\n }\n return;\n default:\n return;\n }\n };\n\n detachAbort = failOnAbort(queue, signal);\n detachClose = failOnAbort(queue, args.context.closeSignal);\n if (!queue.closed()) {\n const subscribeOptions =\n args.options?.afterCursor == null ? undefined : { afterCursor: args.options.afterCursor };\n const stop = args.context.realtime().subscribe(topic, onFrame, subscribeOptions);\n if (queue.closed()) stop();\n else unsubscribe = stop;\n }\n return queue.iterator;\n};\n\nexport const createConversationHandle = (\n context: ClientContextIface,\n conversationId: string,\n): ConversationHandleIface => {\n const { http } = context;\n\n const sandboxFileContentRequest = async (\n args: SandboxFileContentArgsIface,\n ): Promise<SandboxFileContentRequestIface> => {\n if (args.path.length === 0 || args.path.length > 4096 || args.path.includes('\\0')) {\n throw clientError({\n message: 'Invalid sandbox file path',\n status: 0,\n code: ClientErrorCode.InvalidRequest,\n });\n }\n const target = http.url(\n conversationPath(conversationId, `/sandboxes/${encodePath(args.bindingId)}/file/content`),\n );\n target.searchParams.set('path', args.path);\n if (args.snapshotId != null) target.searchParams.set('snapshotId', args.snapshotId);\n if (args.download != null) target.searchParams.set('download', String(args.download));\n const headers = await http.headers();\n if (args.range != null) headers.range = args.range;\n return {\n url: target.toString(),\n headers,\n credentials: http.usesCookies ? 'include' : 'omit',\n };\n };\n\n const listMessages = (options: ListMessagesOptionsIface = {}) =>\n http.request({\n method: HttpMethod.Get,\n path: conversationPath(conversationId, '/messages'),\n query: {\n before: options.before,\n after: options.after,\n limit: options.limit,\n thread: options.thread,\n updatedAfter: options.updatedAfter,\n updatedCursor: options.updatedCursor,\n },\n response: conversationMessagesPageSchema,\n signal: options.signal,\n });\n\n const listParticipants = async (options: SignalOptionsIface) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: conversationPath(conversationId, '/participants'),\n response: participantListSchema,\n signal: options.signal,\n })\n ).participants;\n\n const getSession = (sessionId: string, options: SignalOptionsIface) =>\n http.request({\n method: HttpMethod.Get,\n path: `/v1/sessions/${encodePath(sessionId)}`,\n response: sessionSchema,\n signal: options.signal,\n });\n\n const sessionPending = async (sessionId: string, options: SignalOptionsIface) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: `/v1/sessions/${encodePath(sessionId)}/pending`,\n response: pendingRequestListSchema,\n signal: options.signal,\n })\n ).pending;\n\n const reaction = async (args: {\n method: HttpMethod;\n messageId: string;\n emoji: string;\n signal?: AbortSignal;\n }): Promise<ReactionIface[]> =>\n (\n await http.request({\n method: args.method,\n path: messagePath(conversationId, args.messageId, '/reactions'),\n body: { schema: reactionRequestSchema, value: { emoji: args.emoji } },\n response: reactionsResponseSchema,\n signal: args.signal,\n })\n ).reactions;\n\n return {\n id: conversationId,\n info: (options) =>\n http.request({\n method: HttpMethod.Get,\n path: conversationPath(conversationId),\n response: conversationSchema,\n signal: options?.signal,\n }),\n send: async (content, options) => {\n const sent = await http.request({\n method: HttpMethod.Post,\n path: conversationPath(conversationId, '/messages'),\n body: {\n schema: sendMessageRequestSchema,\n value: {\n content,\n clientMessageId: options?.clientMessageId ?? context.newKey(),\n replyTo: options?.replyTo,\n threadRootId: options?.threadRootId,\n quotes: options?.quotes,\n mentions: options?.mentions,\n attachmentIds: options?.attachmentIds,\n clientSubmittedAtMs: options?.clientSubmittedAtMs ?? context.now(),\n },\n },\n response: sendMessageResponseSchema,\n signal: options?.signal,\n });\n return {\n message: sent.message,\n messageId: sent.message.id,\n seq: sent.message.seq,\n deliveries: sent.deliveries,\n };\n },\n events: (options) =>\n streamConversationEvents({\n context,\n conversationId,\n options,\n listMessages,\n listParticipants,\n getSession,\n sessionPending,\n }),\n messages: (options) => listMessages(options),\n deliveries: async (args, options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: `${messagePath(conversationId, args.messageId)}/deliveries`,\n response: messageDeliveriesSchema,\n signal: options?.signal,\n })\n ).deliveries,\n message: (args, options) =>\n http.request({\n method: HttpMethod.Get,\n path: messagePath(conversationId, args.messageId),\n response: conversationMessageSchema,\n signal: options?.signal,\n }),\n react: (args, options) =>\n reaction({ method: HttpMethod.Post, ...args, signal: options?.signal }),\n unreact: (args, options) =>\n reaction({ method: HttpMethod.Delete, ...args, signal: options?.signal }),\n markThreadRead: async ({ rootId, throughSeq }, options) => {\n await http.request({\n method: HttpMethod.Post,\n path: conversationPath(conversationId, `/threads/${encodePath(rootId)}/read`),\n body: { schema: markReadRequestSchema, value: { throughSeq } },\n response: okResponseSchema,\n signal: options?.signal,\n });\n },\n postEvent: async (event, options) => {\n const sent = await http.request({\n method: HttpMethod.Post,\n path: conversationPath(conversationId, '/events'),\n body: { schema: postConversationEventRequestSchema, value: event },\n response: sendMessageResponseSchema,\n signal: options?.signal,\n });\n return {\n message: sent.message,\n messageId: sent.message.id,\n seq: sent.message.seq,\n deliveries: sent.deliveries,\n };\n },\n typing: async (args, options) => {\n await http.request({\n method: HttpMethod.Post,\n path: conversationPath(conversationId, '/typing'),\n body: { schema: typingRequestSchema, value: args },\n response: okResponseSchema,\n signal: options?.signal,\n });\n },\n recordPushOpen: (args, options) =>\n http.request({\n method: HttpMethod.Post,\n path: conversationPath(\n conversationId,\n `/push-deliveries/${encodeURIComponent(args.deliveryId)}/open`,\n ),\n response: pushDeliveryOpenResponseSchema,\n signal: options?.signal,\n }),\n markRead: (args, options) =>\n http.request({\n method: HttpMethod.Post,\n path: conversationPath(conversationId, '/read'),\n body: { schema: markReadRequestSchema, value: args },\n response: readStateSchema,\n signal: options?.signal,\n }),\n respond: (args, options) =>\n http.request({\n method: HttpMethod.Post,\n path: conversationPath(conversationId, '/respond'),\n body: {\n schema: respondPendingRequestSchema,\n value: { pendingId: args.pendingId, outcome: outcomeOf(args) },\n },\n response: respondPendingResponseSchema,\n signal: options?.signal,\n context: { pendingId: args.pendingId },\n }),\n cancel: async (options) => {\n await http.request({\n method: HttpMethod.Post,\n path: conversationPath(conversationId, '/cancel'),\n body: {\n schema: cancelConversationRequestSchema,\n value: { reason: options?.reason, throughMessageSeq: options?.throughMessageSeq },\n },\n response: okResponseSchema,\n signal: options?.signal,\n });\n },\n participants: (options) => listParticipants({ signal: options?.signal }),\n turns: async (options) => {\n const participants = await listParticipants({ signal: options?.signal });\n return Promise.all(\n participants.flatMap((participant) => {\n const sessionId = participant.sessionId;\n if (participant.kind !== ParticipantKind.Agent || sessionId == null) return [];\n return [\n getSession(sessionId, { signal: options?.signal }).then(\n (session): ConversationAgentTurnIface => ({\n participantId: participant.id,\n sessionId,\n state: session.state,\n running: TURN_OPEN_SESSION_STATES.has(session.state),\n }),\n ),\n ];\n }),\n );\n },\n addParticipant: (participant, options) =>\n http.request({\n method: HttpMethod.Post,\n path: conversationPath(conversationId, '/participants'),\n body: { schema: participantInputSchema, value: participant },\n response: participantSchema,\n signal: options?.signal,\n }),\n updateParticipant: ({ participantId, ...patch }, options) =>\n http.request({\n method: HttpMethod.Patch,\n path: conversationPath(conversationId, `/participants/${encodePath(participantId)}`),\n body: { schema: updateParticipantRequestSchema, value: patch },\n response: participantSchema,\n signal: options?.signal,\n }),\n removeParticipant: async (args, options) => {\n await http.request({\n method: HttpMethod.Delete,\n path: conversationPath(conversationId, '/participants'),\n body: { schema: removeParticipantRequestSchema, value: args },\n response: okResponseSchema,\n signal: options?.signal,\n });\n },\n update: (patch, options) =>\n http.request({\n method: HttpMethod.Patch,\n path: conversationPath(conversationId),\n body: { schema: updateConversationRequestSchema, value: patch },\n response: conversationSchema,\n signal: options?.signal,\n }),\n delete: async (args, options) => {\n await http.request({\n method: HttpMethod.Delete,\n path: messagePath(conversationId, args.messageId),\n response: okResponseSchema,\n signal: options?.signal,\n });\n },\n links: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: conversationPath(conversationId, '/links'),\n response: conversationLinkListSchema,\n signal: options?.signal,\n })\n ).links,\n parentLinks: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: conversationPath(conversationId, '/parent-links'),\n response: conversationLinkListSchema,\n signal: options?.signal,\n })\n ).links,\n link: (args, options) =>\n http.request({\n method: HttpMethod.Post,\n path: conversationPath(conversationId, '/links'),\n body: { schema: createConversationLinkRequestSchema, value: args },\n response: conversationLinkSchema,\n signal: options?.signal,\n }),\n unlink: async (args, options) => {\n await http.request({\n method: HttpMethod.Delete,\n path: conversationPath(conversationId, `/links/${encodePath(args.linkId)}`),\n response: okResponseSchema,\n signal: options?.signal,\n });\n },\n attachmentUrl: (args, options) =>\n http.request({\n method: HttpMethod.Get,\n path: conversationPath(conversationId, `/attachments/${encodePath(args.attachmentId)}`),\n response: attachmentDownloadSchema,\n signal: options?.signal,\n }),\n sandboxes: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: conversationPath(conversationId, '/sandboxes'),\n response: conversationSandboxListSchema,\n signal: options?.signal,\n })\n ).sandboxes,\n sandboxFiles: (args, options) =>\n http.request({\n method: HttpMethod.Get,\n path: conversationPath(conversationId, `/sandboxes/${encodePath(args.bindingId)}/files`),\n query: { path: args.path, snapshotId: args.snapshotId },\n response: sandboxDirectorySchema,\n signal: options?.signal,\n }),\n sandboxPath: (args, options) =>\n http.request({\n method: HttpMethod.Get,\n path: conversationPath(conversationId, `/sandboxes/${encodePath(args.bindingId)}/path`),\n query: { path: args.path, snapshotId: args.snapshotId },\n response: sandboxPathSchema,\n signal: options?.signal,\n }),\n searchSandboxFiles: (args, options) =>\n http.request({\n method: HttpMethod.Get,\n path: conversationPath(\n conversationId,\n `/sandboxes/${encodePath(args.bindingId)}/files/search`,\n ),\n query: { path: args.path, query: args.query, limit: args.limit },\n response: sandboxSearchSchema,\n signal: options?.signal,\n }),\n sandboxFile: (args, options) =>\n http.request({\n method: HttpMethod.Get,\n path: conversationPath(conversationId, `/sandboxes/${encodePath(args.bindingId)}/file`),\n query: {\n path: args.path,\n offset: args.offset,\n length: args.length,\n snapshotId: args.snapshotId,\n },\n response: sandboxFileSchema,\n signal: options?.signal,\n }),\n sandboxFileContentRequest,\n openSandboxEditor: (args, options) =>\n http.request({\n method: HttpMethod.Post,\n path: conversationPath(conversationId, `/sandboxes/${encodePath(args.bindingId)}/editor`),\n response: sandboxEditorSessionSchema,\n signal: options?.signal,\n }),\n refreshSandboxEditor: (args, options) =>\n http.request({\n method: HttpMethod.Post,\n path: conversationPath(\n conversationId,\n `/sandboxes/${encodePath(args.bindingId)}/editor/${encodePath(args.editorId)}/refresh`,\n ),\n body: {\n schema: sandboxEditorAuthorizationSchema,\n value: { authorizationId: args.authorizationId },\n },\n response: sandboxEditorSessionSchema,\n signal: options?.signal,\n }),\n closeSandboxEditor: async (args, options) => {\n await http.request({\n method: HttpMethod.Delete,\n path: conversationPath(\n conversationId,\n `/sandboxes/${encodePath(args.bindingId)}/editor/${encodePath(args.editorId)}`,\n ),\n body: {\n schema: sandboxEditorAuthorizationSchema,\n value: { authorizationId: args.authorizationId },\n },\n response: okResponseSchema,\n signal: options?.signal,\n keepalive: options?.keepalive,\n });\n },\n sandboxFileContent: async (args, options) => {\n const request = await sandboxFileContentRequest(args);\n let response: Response;\n try {\n response = await http.fetch(request.url, {\n method: HttpMethod.Get,\n headers: request.headers,\n credentials: request.credentials,\n signal: options?.signal,\n });\n } catch (cause) {\n if (options?.signal?.aborted === true) throw cause;\n throw clientError({\n message: 'Sandbox file request failed',\n status: 0,\n code: ClientErrorCode.Network,\n cause,\n });\n }\n if (!response.ok) {\n let text: string;\n try {\n text = await response.text();\n } catch (cause) {\n if (options?.signal?.aborted === true) throw cause;\n throw clientError({\n message: 'Sandbox file response failed',\n status: 0,\n code: ClientErrorCode.Network,\n cause,\n });\n }\n throw errorFromResponse({ status: response.status, text, context: undefined });\n }\n return response;\n },\n inspectSandboxProcesses: (args, options) => {\n const request = processInspectionRequestSchema.parse(args.request);\n const { operation } = request;\n const suffix =\n operation === ProcessInspectionOperation.Available\n ? '/available'\n : 'processId' in request\n ? '/' + encodePath(request.processId)\n : '';\n const query: NonNullable<HttpRequestArgsIface<ProcessInspectionResultIface>['query']> = {};\n if ('bootId' in request) query.bootId = request.bootId;\n if ('cursor' in request) query.cursor = request.cursor;\n if ('limit' in request) query.limit = request.limit;\n return http.request({\n method: operation === ProcessInspectionOperation.Stop ? HttpMethod.Delete : HttpMethod.Get,\n path: conversationPath(\n conversationId,\n `/sandboxes/${encodePath(args.bindingId)}/processes${suffix}`,\n ),\n query,\n response: processInspectionResultSchema,\n signal: options?.signal,\n });\n },\n sandboxPreview: (args, options) => {\n const request: HttpRequestArgsIface<SandboxPreviewType> = {\n method: args.viewOnly === false ? HttpMethod.Post : HttpMethod.Get,\n path: conversationPath(conversationId, `/sandboxes/${encodePath(args.bindingId)}/preview`),\n response: sandboxPreviewSchema,\n signal: options?.signal,\n };\n if (args.viewOnly === false)\n request.body = { schema: sandboxPreviewOptionsSchema, value: { viewOnly: false } };\n return http.request(request);\n },\n wakeSandbox: (args, options) =>\n http.request({\n method: HttpMethod.Post,\n path: conversationPath(conversationId, `/sandboxes/${encodePath(args.bindingId)}/wake`),\n response: conversationSandboxSchema,\n signal: options?.signal,\n }),\n schedules: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: conversationPath(conversationId, '/schedules'),\n response: conversationScheduleListSchema,\n signal: options?.signal,\n })\n ).schedules,\n createSchedule: (args, options) =>\n http.request({\n method: HttpMethod.Post,\n path: conversationPath(conversationId, '/schedules'),\n body: { schema: createConversationScheduleRequestSchema, value: args },\n response: conversationScheduleSchema,\n signal: options?.signal,\n }),\n updateSchedule: ({ scheduleId, ...patch }, options) =>\n http.request({\n method: HttpMethod.Patch,\n path: conversationPath(conversationId, `/schedules/${encodePath(scheduleId)}`),\n body: { schema: updateConversationScheduleRequestSchema, value: patch },\n response: conversationScheduleSchema,\n signal: options?.signal,\n }),\n deleteSchedule: async (args, options) => {\n await http.request({\n method: HttpMethod.Delete,\n path: conversationPath(conversationId, `/schedules/${encodePath(args.scheduleId)}`),\n response: okResponseSchema,\n signal: options?.signal,\n });\n },\n uploadAttachment: async (args) => {\n const sizeBytes = 'byteLength' in args.data ? args.data.byteLength : args.data.size;\n const upload = await http.request({\n method: HttpMethod.Post,\n path: conversationPath(conversationId, '/attachments'),\n body: {\n schema: createAttachmentUploadRequestSchema,\n value: { name: args.name, contentType: args.contentType, sizeBytes },\n },\n response: attachmentUploadSchema,\n signal: args.signal,\n });\n // Presigned upload: storage authenticates the URL, so it gets only the headers the\n // presign requires, through storageFetch, never the API fetch or its credentials.\n const response = await context.storageFetch(upload.uploadUrl, {\n method: upload.method,\n headers: { 'content-type': args.contentType, ...upload.headers },\n body: args.data,\n signal: args.signal,\n credentials: 'omit',\n });\n if (!response.ok) {\n throw clientError({\n message: `Attachment upload failed with status ${response.status}`,\n status: response.status,\n code: ClientErrorCode.UploadFailed,\n body: await response.text(),\n });\n }\n return upload;\n },\n };\n};\n\nexport const createConversationsApi = (context: ClientContextIface): ConversationsApiIface => {\n const opened = (conversation: ConversationIface): OpenedConversationIface => ({\n ...createConversationHandle(context, conversation.id),\n conversation,\n });\n return {\n list: (options) =>\n context.http.request({\n method: HttpMethod.Get,\n path: '/v1/conversations',\n query: {\n cursor: options?.cursor,\n limit: options?.limit,\n includeArchived: options?.includeArchived,\n },\n response: conversationListSchema,\n signal: options?.signal,\n }),\n direct: async (args) =>\n opened(\n await context.http.request({\n method: HttpMethod.Post,\n path: '/v1/conversations/direct',\n body: { schema: createDirectConversationRequestSchema, value: { agent: args.agent } },\n response: conversationSchema,\n signal: args.signal,\n }),\n ),\n home: async (options) =>\n opened(\n await context.http.request({\n method: HttpMethod.Get,\n path: '/v1/conversations/home',\n response: conversationSchema,\n signal: options?.signal,\n }),\n ),\n create: async (args) =>\n opened(\n await context.http.request({\n method: HttpMethod.Post,\n path: '/v1/conversations',\n body: {\n schema: createConversationRequestSchema,\n value: {\n kind: args.kind,\n title: args.title,\n participants: args.participants,\n turnPolicy: args.turnPolicy,\n },\n },\n response: conversationSchema,\n signal: args.signal,\n }),\n ),\n get: (conversationId) => createConversationHandle(context, conversationId),\n search: (args) =>\n context.http.request({\n method: HttpMethod.Get,\n path: '/v1/conversations/search',\n query: {\n q: args.q,\n conversationId: args.conversationId,\n cursor: args.cursor,\n limit: args.limit,\n },\n response: searchMessagesPageSchema,\n signal: args.signal,\n }),\n listEvents: (options) =>\n streamCollectionEvents({\n context,\n topicFor: agentRealtimeTopics.userConversations,\n collection: ClientCollection.Conversations,\n options,\n }),\n decisions: (options) =>\n context.http.request({\n method: HttpMethod.Get,\n path: '/v1/decisions',\n query: { cursor: options?.cursor, limit: options?.limit },\n response: decisionsPageSchema,\n signal: options?.signal,\n }),\n };\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["anchor"]
7
+ }
@@ -0,0 +1,85 @@
1
+ import type { JsonValue } from '@finalai/agent-protocol';
2
+ export declare enum AgentClientErrorName {
3
+ Client = "ClientError",
4
+ PendingRequest = "PendingRequestError",
5
+ TurnRejected = "TurnRejectedError",
6
+ RealtimeSubscription = "RealtimeSubscriptionError"
7
+ }
8
+ export declare enum PendingRequestErrorReason {
9
+ NotFound = "not_found",
10
+ NotInAudience = "not_in_audience",
11
+ AlreadyResolved = "already_resolved",
12
+ Expired = "expired"
13
+ }
14
+ /** Codes the SDK itself assigns when no HTTP error body applies. */
15
+ export declare enum ClientErrorCode {
16
+ Network = "network_error",
17
+ InvalidRequest = "invalid_request",
18
+ InvalidResponse = "invalid_response",
19
+ UploadFailed = "upload_failed",
20
+ NotFound = "not_found",
21
+ Closed = "client_closed",
22
+ /** The runtime's fetch cannot stream a response body (Streamable HTTP). */
23
+ StreamUnsupported = "stream_unsupported",
24
+ Unknown = "unknown"
25
+ }
26
+ interface ErrorFieldsIface {
27
+ /** HTTP status; 0 when no response arrived or the SDK rejected the call locally. */
28
+ status: number;
29
+ code: string;
30
+ body: JsonValue | null;
31
+ }
32
+ export interface ClientErrorIface extends Error, ErrorFieldsIface {
33
+ name: AgentClientErrorName.Client;
34
+ }
35
+ /** Answering a pending request outside your audience, already resolved, expired, or unknown. */
36
+ export interface PendingRequestErrorIface extends Error, ErrorFieldsIface {
37
+ name: AgentClientErrorName.PendingRequest;
38
+ pendingId: string | null;
39
+ reason: PendingRequestErrorReason;
40
+ }
41
+ /** The session is not accepting prompts; `state` is its ACP/session state. */
42
+ export interface TurnRejectedErrorIface extends Error, ErrorFieldsIface {
43
+ name: AgentClientErrorName.TurnRejected;
44
+ sessionId: string | null;
45
+ state: string | null;
46
+ }
47
+ /** The realtime gateway refused a topic for good (no access, unknown topic, subscription limit). */
48
+ export interface RealtimeSubscriptionErrorIface extends Error, ErrorFieldsIface {
49
+ name: AgentClientErrorName.RealtimeSubscription;
50
+ topic: string;
51
+ }
52
+ export type AgentClientError = ClientErrorIface | PendingRequestErrorIface | TurnRejectedErrorIface | RealtimeSubscriptionErrorIface;
53
+ export interface ClientErrorArgsIface {
54
+ message: string;
55
+ status: number;
56
+ code: string;
57
+ body?: JsonValue | null;
58
+ cause?: unknown;
59
+ }
60
+ export declare const clientError: (args: ClientErrorArgsIface) => ClientErrorIface;
61
+ export declare const pendingRequestError: (args: ClientErrorArgsIface & {
62
+ pendingId: string | null;
63
+ reason: PendingRequestErrorReason;
64
+ }) => PendingRequestErrorIface;
65
+ export declare const turnRejectedError: (args: ClientErrorArgsIface & {
66
+ sessionId: string | null;
67
+ state: string | null;
68
+ }) => TurnRejectedErrorIface;
69
+ export declare const realtimeSubscriptionError: (args: {
70
+ topic: string;
71
+ code: string;
72
+ message: string;
73
+ }) => RealtimeSubscriptionErrorIface;
74
+ /** Whether a realtime error frame ends the subscription: explicit, or by a known terminal code. */
75
+ export declare const isTerminalRealtimeError: (frame: {
76
+ code: string | null;
77
+ retryable: boolean | null;
78
+ }) => boolean;
79
+ /** True for every SDK error (ClientError, PendingRequestError, TurnRejectedError). */
80
+ export declare const isClientError: (cause: unknown) => cause is AgentClientError;
81
+ export declare const isPendingRequestError: (cause: unknown) => cause is PendingRequestErrorIface;
82
+ export declare const isTurnRejectedError: (cause: unknown) => cause is TurnRejectedErrorIface;
83
+ export declare const isRealtimeSubscriptionError: (cause: unknown) => cause is RealtimeSubscriptionErrorIface;
84
+ export declare const isRetryableClientError: (cause: unknown) => boolean;
85
+ export {};
@@ -0,0 +1,94 @@
1
+ import * as z from "zod";
2
+ var AgentClientErrorName = /* @__PURE__ */ ((AgentClientErrorName2) => {
3
+ AgentClientErrorName2["Client"] = "ClientError";
4
+ AgentClientErrorName2["PendingRequest"] = "PendingRequestError";
5
+ AgentClientErrorName2["TurnRejected"] = "TurnRejectedError";
6
+ AgentClientErrorName2["RealtimeSubscription"] = "RealtimeSubscriptionError";
7
+ return AgentClientErrorName2;
8
+ })(AgentClientErrorName || {});
9
+ var PendingRequestErrorReason = /* @__PURE__ */ ((PendingRequestErrorReason2) => {
10
+ PendingRequestErrorReason2["NotFound"] = "not_found";
11
+ PendingRequestErrorReason2["NotInAudience"] = "not_in_audience";
12
+ PendingRequestErrorReason2["AlreadyResolved"] = "already_resolved";
13
+ PendingRequestErrorReason2["Expired"] = "expired";
14
+ return PendingRequestErrorReason2;
15
+ })(PendingRequestErrorReason || {});
16
+ var ClientErrorCode = /* @__PURE__ */ ((ClientErrorCode2) => {
17
+ ClientErrorCode2["Network"] = "network_error";
18
+ ClientErrorCode2["InvalidRequest"] = "invalid_request";
19
+ ClientErrorCode2["InvalidResponse"] = "invalid_response";
20
+ ClientErrorCode2["UploadFailed"] = "upload_failed";
21
+ ClientErrorCode2["NotFound"] = "not_found";
22
+ ClientErrorCode2["Closed"] = "client_closed";
23
+ ClientErrorCode2["StreamUnsupported"] = "stream_unsupported";
24
+ ClientErrorCode2["Unknown"] = "unknown";
25
+ return ClientErrorCode2;
26
+ })(ClientErrorCode || {});
27
+ const baseError = (args) => args.cause === void 0 ? new Error(args.message) : new Error(args.message, { cause: args.cause });
28
+ const clientError = (args) => Object.assign(baseError(args), {
29
+ name: "ClientError" /* Client */,
30
+ status: args.status,
31
+ code: args.code,
32
+ body: args.body ?? null
33
+ });
34
+ const pendingRequestError = (args) => Object.assign(baseError(args), {
35
+ name: "PendingRequestError" /* PendingRequest */,
36
+ status: args.status,
37
+ code: args.code,
38
+ body: args.body ?? null,
39
+ pendingId: args.pendingId,
40
+ reason: args.reason
41
+ });
42
+ const turnRejectedError = (args) => Object.assign(baseError(args), {
43
+ name: "TurnRejectedError" /* TurnRejected */,
44
+ status: args.status,
45
+ code: args.code,
46
+ body: args.body ?? null,
47
+ sessionId: args.sessionId,
48
+ state: args.state
49
+ });
50
+ const realtimeStatusByCode = /* @__PURE__ */ new Map([
51
+ ["unauthorized", 401],
52
+ ["forbidden", 403],
53
+ ["not_found", 404],
54
+ ["too_many_subscriptions", 429]
55
+ ]);
56
+ const realtimeSubscriptionError = (args) => Object.assign(new Error(args.message), {
57
+ name: "RealtimeSubscriptionError" /* RealtimeSubscription */,
58
+ status: realtimeStatusByCode.get(args.code) ?? 0,
59
+ code: args.code,
60
+ body: null,
61
+ topic: args.topic
62
+ });
63
+ const isTerminalRealtimeError = (frame) => frame.retryable === false || frame.retryable == null && realtimeStatusByCode.has(frame.code ?? "");
64
+ const errorIdentitySchema = z.object({
65
+ name: z.nativeEnum(AgentClientErrorName),
66
+ status: z.number(),
67
+ code: z.string(),
68
+ message: z.string()
69
+ });
70
+ const errorNameOf = (cause) => {
71
+ const parsed = errorIdentitySchema.safeParse(cause);
72
+ return parsed.success ? parsed.data.name : null;
73
+ };
74
+ const isClientError = (cause) => errorNameOf(cause) != null;
75
+ const isPendingRequestError = (cause) => errorNameOf(cause) === "PendingRequestError" /* PendingRequest */;
76
+ const isTurnRejectedError = (cause) => errorNameOf(cause) === "TurnRejectedError" /* TurnRejected */;
77
+ const isRealtimeSubscriptionError = (cause) => errorNameOf(cause) === "RealtimeSubscriptionError" /* RealtimeSubscription */;
78
+ const isRetryableClientError = (cause) => isClientError(cause) && (cause.code === "network_error" /* Network */ || cause.status === 429 || cause.status >= 500);
79
+ export {
80
+ AgentClientErrorName,
81
+ ClientErrorCode,
82
+ PendingRequestErrorReason,
83
+ clientError,
84
+ isClientError,
85
+ isPendingRequestError,
86
+ isRealtimeSubscriptionError,
87
+ isRetryableClientError,
88
+ isTerminalRealtimeError,
89
+ isTurnRejectedError,
90
+ pendingRequestError,
91
+ realtimeSubscriptionError,
92
+ turnRejectedError
93
+ };
94
+ //# sourceMappingURL=errors.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/agent-client/errors.ts"],
4
+ "sourcesContent": ["import type { JsonValue } from '@finalai/agent-protocol';\nimport * as z from 'zod';\n\n// Errors are plain `Error` objects with a discriminating `name` (no classes):\n// narrow with the `is*Error` guards, never `instanceof`.\n\nexport enum AgentClientErrorName {\n Client = 'ClientError',\n PendingRequest = 'PendingRequestError',\n TurnRejected = 'TurnRejectedError',\n RealtimeSubscription = 'RealtimeSubscriptionError',\n}\n\nexport enum PendingRequestErrorReason {\n NotFound = 'not_found',\n NotInAudience = 'not_in_audience',\n AlreadyResolved = 'already_resolved',\n Expired = 'expired',\n}\n\n/** Codes the SDK itself assigns when no HTTP error body applies. */\nexport enum ClientErrorCode {\n Network = 'network_error',\n InvalidRequest = 'invalid_request',\n InvalidResponse = 'invalid_response',\n UploadFailed = 'upload_failed',\n NotFound = 'not_found',\n Closed = 'client_closed',\n /** The runtime's fetch cannot stream a response body (Streamable HTTP). */\n StreamUnsupported = 'stream_unsupported',\n Unknown = 'unknown',\n}\n\ninterface ErrorFieldsIface {\n /** HTTP status; 0 when no response arrived or the SDK rejected the call locally. */\n status: number;\n code: string;\n body: JsonValue | null;\n}\n\nexport interface ClientErrorIface extends Error, ErrorFieldsIface {\n name: AgentClientErrorName.Client;\n}\n\n/** Answering a pending request outside your audience, already resolved, expired, or unknown. */\nexport interface PendingRequestErrorIface extends Error, ErrorFieldsIface {\n name: AgentClientErrorName.PendingRequest;\n pendingId: string | null;\n reason: PendingRequestErrorReason;\n}\n\n/** The session is not accepting prompts; `state` is its ACP/session state. */\nexport interface TurnRejectedErrorIface extends Error, ErrorFieldsIface {\n name: AgentClientErrorName.TurnRejected;\n sessionId: string | null;\n state: string | null;\n}\n\n/** The realtime gateway refused a topic for good (no access, unknown topic, subscription limit). */\nexport interface RealtimeSubscriptionErrorIface extends Error, ErrorFieldsIface {\n name: AgentClientErrorName.RealtimeSubscription;\n topic: string;\n}\n\nexport type AgentClientError =\n | ClientErrorIface\n | PendingRequestErrorIface\n | TurnRejectedErrorIface\n | RealtimeSubscriptionErrorIface;\n\ntype ErrorBaseKey = 'message' | 'stack' | 'cause';\n\nexport interface ClientErrorArgsIface {\n message: string;\n status: number;\n code: string;\n body?: JsonValue | null;\n cause?: unknown;\n}\n\nconst baseError = (args: ClientErrorArgsIface): Error =>\n args.cause === undefined\n ? new Error(args.message)\n : new Error(args.message, { cause: args.cause });\n\nexport const clientError = (args: ClientErrorArgsIface): ClientErrorIface =>\n Object.assign(baseError(args), {\n name: AgentClientErrorName.Client,\n status: args.status,\n code: args.code,\n body: args.body ?? null,\n } satisfies Omit<ClientErrorIface, ErrorBaseKey>);\n\nexport const pendingRequestError = (\n args: ClientErrorArgsIface & { pendingId: string | null; reason: PendingRequestErrorReason },\n): PendingRequestErrorIface =>\n Object.assign(baseError(args), {\n name: AgentClientErrorName.PendingRequest,\n status: args.status,\n code: args.code,\n body: args.body ?? null,\n pendingId: args.pendingId,\n reason: args.reason,\n } satisfies Omit<PendingRequestErrorIface, ErrorBaseKey>);\n\nexport const turnRejectedError = (\n args: ClientErrorArgsIface & { sessionId: string | null; state: string | null },\n): TurnRejectedErrorIface =>\n Object.assign(baseError(args), {\n name: AgentClientErrorName.TurnRejected,\n status: args.status,\n code: args.code,\n body: args.body ?? null,\n sessionId: args.sessionId,\n state: args.state,\n } satisfies Omit<TurnRejectedErrorIface, ErrorBaseKey>);\n\n// Gateway codes map onto the HTTP statuses callers already branch on.\nconst realtimeStatusByCode = new Map<string, number>([\n ['unauthorized', 401],\n ['forbidden', 403],\n ['not_found', 404],\n ['too_many_subscriptions', 429],\n]);\n\nexport const realtimeSubscriptionError = (args: {\n topic: string;\n code: string;\n message: string;\n}): RealtimeSubscriptionErrorIface =>\n Object.assign(new Error(args.message), {\n name: AgentClientErrorName.RealtimeSubscription,\n status: realtimeStatusByCode.get(args.code) ?? 0,\n code: args.code,\n body: null,\n topic: args.topic,\n } satisfies Omit<RealtimeSubscriptionErrorIface, ErrorBaseKey>);\n\n/** Whether a realtime error frame ends the subscription: explicit, or by a known terminal code. */\nexport const isTerminalRealtimeError = (frame: {\n code: string | null;\n retryable: boolean | null;\n}): boolean =>\n frame.retryable === false ||\n (frame.retryable == null && realtimeStatusByCode.has(frame.code ?? ''));\n\nconst errorIdentitySchema = z.object({\n name: z.nativeEnum(AgentClientErrorName),\n status: z.number(),\n code: z.string(),\n message: z.string(),\n});\n\nconst errorNameOf = (cause: unknown): AgentClientErrorName | null => {\n const parsed = errorIdentitySchema.safeParse(cause);\n return parsed.success ? parsed.data.name : null;\n};\n\n/** True for every SDK error (ClientError, PendingRequestError, TurnRejectedError). */\nexport const isClientError = (cause: unknown): cause is AgentClientError =>\n errorNameOf(cause) != null;\n\nexport const isPendingRequestError = (cause: unknown): cause is PendingRequestErrorIface =>\n errorNameOf(cause) === AgentClientErrorName.PendingRequest;\n\nexport const isTurnRejectedError = (cause: unknown): cause is TurnRejectedErrorIface =>\n errorNameOf(cause) === AgentClientErrorName.TurnRejected;\n\nexport const isRealtimeSubscriptionError = (\n cause: unknown,\n): cause is RealtimeSubscriptionErrorIface =>\n errorNameOf(cause) === AgentClientErrorName.RealtimeSubscription;\n\nexport const isRetryableClientError = (cause: unknown): boolean =>\n isClientError(cause) &&\n (cause.code === ClientErrorCode.Network || cause.status === 429 || cause.status >= 500);\n"],
5
+ "mappings": "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",
6
+ "names": ["AgentClientErrorName", "PendingRequestErrorReason", "ClientErrorCode"]
7
+ }
@@ -0,0 +1,14 @@
1
+ import { type HttpIface, type QueryValue } from "./http.mjs";
2
+ export interface ServerSentEventIface {
3
+ event: string;
4
+ data: string;
5
+ id: string | null;
6
+ }
7
+ /** Parses `text/event-stream` chunks into events; comment lines (keepalives) are skipped. */
8
+ export declare const createEventStreamParser: () => (chunk: string) => ServerSentEventIface[];
9
+ export declare function streamServerSentEvents(args: {
10
+ http: HttpIface;
11
+ path: string;
12
+ query?: Record<string, QueryValue>;
13
+ signal: AbortSignal;
14
+ }): AsyncGenerator<ServerSentEventIface>;
@@ -0,0 +1,89 @@
1
+ import { clientError, ClientErrorCode, isClientError } from "./errors.mjs";
2
+ import { errorFromResponse } from "./http.mjs";
3
+ const createEventStreamParser = () => {
4
+ let buffer = "";
5
+ let event = "message";
6
+ let data = [];
7
+ let id = null;
8
+ const dispatch = (out) => {
9
+ if (data.length > 0) out.push({ event, data: data.join("\n"), id });
10
+ event = "message";
11
+ data = [];
12
+ id = null;
13
+ };
14
+ return (chunk) => {
15
+ buffer += chunk;
16
+ const out = [];
17
+ for (let end = buffer.search(/\r\n|\r|\n/); end >= 0; end = buffer.search(/\r\n|\r|\n/)) {
18
+ const line = buffer.slice(0, end);
19
+ buffer = buffer.slice(buffer.startsWith("\r\n", end) ? end + 2 : end + 1);
20
+ if (line.length === 0) {
21
+ dispatch(out);
22
+ continue;
23
+ }
24
+ if (line.startsWith(":")) continue;
25
+ const colon = line.indexOf(":");
26
+ const field = colon < 0 ? line : line.slice(0, colon);
27
+ const raw = colon < 0 ? "" : line.slice(colon + 1);
28
+ const value = raw.startsWith(" ") ? raw.slice(1) : raw;
29
+ if (field === "event") event = value;
30
+ else if (field === "data") data.push(value);
31
+ else if (field === "id") id = value;
32
+ }
33
+ return out;
34
+ };
35
+ };
36
+ async function* streamServerSentEvents(args) {
37
+ const target = args.http.url(args.path);
38
+ for (const [key, value] of Object.entries(args.query ?? {})) {
39
+ if (value !== void 0) target.searchParams.set(key, String(value));
40
+ }
41
+ let reader = null;
42
+ try {
43
+ const response = await args.http.fetch(target.toString(), {
44
+ method: "GET",
45
+ headers: { accept: "text/event-stream", ...await args.http.headers() },
46
+ signal: args.signal,
47
+ credentials: args.http.usesCookies ? "include" : void 0
48
+ });
49
+ if (!response.ok) {
50
+ throw errorFromResponse({
51
+ status: response.status,
52
+ text: await response.text(),
53
+ context: {}
54
+ });
55
+ }
56
+ const body = response.body;
57
+ if (body == null) {
58
+ throw clientError({
59
+ message: `${args.path} cannot be streamed by this fetch`,
60
+ status: response.status,
61
+ code: ClientErrorCode.StreamUnsupported
62
+ });
63
+ }
64
+ reader = body.getReader();
65
+ const decoder = new TextDecoder();
66
+ const parse = createEventStreamParser();
67
+ for (; ; ) {
68
+ const chunk = await reader.read();
69
+ if (chunk.done) return;
70
+ for (const event of parse(decoder.decode(chunk.value, { stream: true }))) yield event;
71
+ }
72
+ } catch (cause) {
73
+ if (args.signal.aborted || isClientError(cause)) throw cause;
74
+ throw clientError({
75
+ message: `Network stream from ${args.path} failed`,
76
+ status: 0,
77
+ code: ClientErrorCode.Network,
78
+ cause
79
+ });
80
+ } finally {
81
+ await reader?.cancel().catch(() => void 0);
82
+ reader?.releaseLock();
83
+ }
84
+ }
85
+ export {
86
+ createEventStreamParser,
87
+ streamServerSentEvents
88
+ };
89
+ //# sourceMappingURL=event-stream.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/agent-client/event-stream.ts"],
4
+ "sourcesContent": ["import { clientError, ClientErrorCode, isClientError } from \"./errors.mjs\";\nimport { errorFromResponse, type HttpIface, type QueryValue } from \"./http.mjs\";\n\n// Server-sent events over the API's fetch: the Streamable HTTP transport the\n// SDK falls back to when the realtime gateway is unreachable. Runtimes whose\n// fetch cannot stream a response body fail with `stream_unsupported`, and the\n// caller falls back further, to replay polling.\n\nexport interface ServerSentEventIface {\n event: string;\n data: string;\n id: string | null;\n}\n\n/** Parses `text/event-stream` chunks into events; comment lines (keepalives) are skipped. */\nexport const createEventStreamParser = () => {\n let buffer = '';\n let event = 'message';\n let data: string[] = [];\n let id: string | null = null;\n const dispatch = (out: ServerSentEventIface[]): void => {\n if (data.length > 0) out.push({ event, data: data.join('\\n'), id });\n event = 'message';\n data = [];\n id = null;\n };\n return (chunk: string): ServerSentEventIface[] => {\n buffer += chunk;\n const out: ServerSentEventIface[] = [];\n for (let end = buffer.search(/\\r\\n|\\r|\\n/); end >= 0; end = buffer.search(/\\r\\n|\\r|\\n/)) {\n const line = buffer.slice(0, end);\n buffer = buffer.slice(buffer.startsWith('\\r\\n', end) ? end + 2 : end + 1);\n if (line.length === 0) {\n dispatch(out);\n continue;\n }\n if (line.startsWith(':')) continue;\n const colon = line.indexOf(':');\n const field = colon < 0 ? line : line.slice(0, colon);\n const raw = colon < 0 ? '' : line.slice(colon + 1);\n const value = raw.startsWith(' ') ? raw.slice(1) : raw;\n if (field === 'event') event = value;\n else if (field === 'data') data.push(value);\n else if (field === 'id') id = value;\n }\n return out;\n };\n};\n\nexport async function* streamServerSentEvents(args: {\n http: HttpIface;\n path: string;\n query?: Record<string, QueryValue>;\n signal: AbortSignal;\n}): AsyncGenerator<ServerSentEventIface> {\n const target = args.http.url(args.path);\n for (const [key, value] of Object.entries(args.query ?? {})) {\n if (value !== undefined) target.searchParams.set(key, String(value));\n }\n let reader: ReadableStreamDefaultReader<Uint8Array> | null = null;\n try {\n const response = await args.http.fetch(target.toString(), {\n method: 'GET',\n headers: { accept: 'text/event-stream', ...(await args.http.headers()) },\n signal: args.signal,\n credentials: args.http.usesCookies ? 'include' : undefined,\n });\n if (!response.ok) {\n throw errorFromResponse({\n status: response.status,\n text: await response.text(),\n context: {},\n });\n }\n const body = response.body;\n if (body == null) {\n throw clientError({\n message: `${args.path} cannot be streamed by this fetch`,\n status: response.status,\n code: ClientErrorCode.StreamUnsupported,\n });\n }\n reader = body.getReader();\n const decoder = new TextDecoder();\n const parse = createEventStreamParser();\n for (;;) {\n const chunk = await reader.read();\n if (chunk.done) return;\n for (const event of parse(decoder.decode(chunk.value, { stream: true }))) yield event;\n }\n } catch (cause) {\n if (args.signal.aborted || isClientError(cause)) throw cause;\n throw clientError({\n message: `Network stream from ${args.path} failed`,\n status: 0,\n code: ClientErrorCode.Network,\n cause,\n });\n } finally {\n await reader?.cancel().catch(() => undefined);\n reader?.releaseLock();\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,51 @@
1
+ import { type AcpFrameEventIface, type PendingRequestIface, type SessionFramesPageIface } from '@finalai/agent-protocol/agent-platform';
2
+ import type { RealtimeTransportIface } from "./realtime.mjs";
3
+ export interface StreamTimingIface {
4
+ sleep: (ms: number) => Promise<void>;
5
+ /** Delays between replay attempts while a gap stays open. */
6
+ gapRetryDelaysMs: number[];
7
+ /** Replay polling, and Streamable HTTP reconnects, while the realtime transport reports errors. */
8
+ pollIntervalMs: number;
9
+ /** Conversation recovery polling (`events()`) while the realtime transport reports errors. */
10
+ conversationPollIntervalMs: number;
11
+ replayPageSize: number;
12
+ /**
13
+ * How long a live request frame waits for its `acp.pending` event before the
14
+ * open requests are read, once per entry; then it is yielded without one.
15
+ */
16
+ pendingJoinDelaysMs: number[];
17
+ }
18
+ export declare const defaultStreamTiming: StreamTimingIface;
19
+ export interface FrameReplayArgsIface {
20
+ fromSeq: number;
21
+ limit: number;
22
+ signal?: AbortSignal;
23
+ }
24
+ export interface SessionFrameStreamArgsIface {
25
+ sessionId: string;
26
+ fromSeq: number;
27
+ /** Keep streaming live frames after replay catches up. */
28
+ follow: boolean;
29
+ replay: (args: FrameReplayArgsIface) => Promise<SessionFramesPageIface>;
30
+ transport: RealtimeTransportIface;
31
+ timing: StreamTimingIface;
32
+ /** The session's open pending requests, to join live request frames with. */
33
+ pending?: (signal?: AbortSignal) => Promise<PendingRequestIface[]>;
34
+ /** Frames from `fromSeq` over Streamable HTTP, followed live. */
35
+ httpStream?: (args: {
36
+ fromSeq: number;
37
+ signal: AbortSignal;
38
+ }) => AsyncIterable<AcpFrameEventIface>;
39
+ signal?: AbortSignal;
40
+ /** The client's close signal: ends the stream like `signal`. */
41
+ closeSignal?: AbortSignal;
42
+ /** Return true to end the stream after yielding this frame. */
43
+ until?: (event: AcpFrameEventIface) => boolean;
44
+ /** A durable terminal receipt, including turns that ended without an ACP echo. */
45
+ terminal?: (signal: AbortSignal) => Promise<{
46
+ throughSeq: number;
47
+ } | null>;
48
+ }
49
+ /** Whether a frame is an agent request the session holds as a pending request. */
50
+ export declare const isPendingRequestFrame: (event: AcpFrameEventIface) => boolean;
51
+ export declare const streamSessionFrames: (args: SessionFrameStreamArgsIface) => AsyncIterableIterator<AcpFrameEventIface>;