@camerontaylor/paseo-client 0.11.0-beta.3.fork.1 → 0.11.1-fork.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -39,7 +39,10 @@ export declare const DEFAULT_CLIENT_CAPABILITIES: {
39
39
  timeline_notifications: true;
40
40
  plugin_timeline_items: true;
41
41
  workspace_setup_blocked: true;
42
+ durable_agent_queue: true;
43
+ durable_voice_input_v1: true;
42
44
  explicit_event_subscriptions: true;
45
+ companion_stream_port_v1: true;
43
46
  };
44
47
  /** Calling releases demand; ready waits for membership, or local attachment on broadcast hosts. */
45
48
  export type TimelineSubscription = (() => void) & {
@@ -112,6 +112,10 @@ export const DEFAULT_CLIENT_CAPABILITIES = {
112
112
  [CLIENT_CAPS.timelineNotifications]: true,
113
113
  [CLIENT_CAPS.pluginTimelineItems]: true,
114
114
  [CLIENT_CAPS.workspaceSetupBlocked]: true,
115
+ [CLIENT_CAPS.durableAgentQueue]: true,
116
+ [CLIENT_CAPS.durableVoiceInputV1]: true,
115
117
  [CLIENT_CAPS.explicitEventSubscriptions]: true,
118
+ // COMPAT(companionStreamPortV1): added in v0.11.0-beta.3-fork, remove after 2027-04-01.
119
+ [CLIENT_CAPS.companionStreamPortV1]: true,
116
120
  };
117
121
  //# sourceMappingURL=index.js.map
@@ -1,12 +1,12 @@
1
1
  import { type TimelineMessage } from "./timeline-subscription/index.js";
2
2
  import { type OwnedSubscription, type TimelineSubscription } from "./connection/index.js";
3
- import type { CreationSnapshot } from "@camerontaylor/paseo-protocol/messages";
3
+ import type { AgentQueueSnapshot, CreationSnapshot } from "@camerontaylor/paseo-protocol/messages";
4
4
  import type { z } from "zod";
5
5
  import type { SessionEventSubscription } from "@camerontaylor/paseo-protocol/messages";
6
6
  import type { ClientCapability } from "@camerontaylor/paseo-protocol/client-capabilities";
7
7
  import type { AgentAttentionNotificationPayload } from "@camerontaylor/paseo-protocol/agent-attention-notification";
8
- import { AgentRefreshedStatusPayloadSchema, CheckoutRenameBranchResponseSchema, CheckoutBaseRefSetResponseSchema, RenameTerminalResponseSchema, RestartRequestedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, DaemonUpdateResponseSchema, type ActiveTurnBehavior, type ServerInfoStatusPayload } from "@camerontaylor/paseo-protocol/messages";
9
- import type { AgentStreamEventPayload, AgentSnapshotPayload, ProjectPlacementPayload, AgentPermissionResolvedMessage, CreateAgentRequestMessage, CreatePaseoWorktreeRequest, FileDownloadTokenResponse, FileUploadResponse, FileExplorerResponse, FileVersion, FileWriteResult, FetchAgentTimelineResponseMessage, AgentForkContextResponseMessage, GitSetupOptions, CheckoutStatusResponse, CheckoutCommit, ParsedDiffFile, CheckoutCommitResponse, CheckoutMergeResponse, CheckoutMergeFromBaseResponse, CheckoutPullResponse, CheckoutPushResponse, CheckoutRefreshResponse, CheckoutPrCreateResponse, CheckoutPrMergeResponse, CheckoutPrMergeMethod, CheckoutForgeSetAutoMergeResponse, CheckoutGithubSetAutoMergeResponse, CheckoutForgeGetCheckDetailsResponse, CheckoutGithubGetCheckDetailsResponse, CheckoutPrStatusResponse, PullRequestTimelineResponse, CheckoutSwitchBranchResponse, StashSaveResponse, StashPopResponse, StashListResponse, ValidateBranchResponse, BranchSuggestionsResponse, ForgeSearchResponse, ForgeSearchRequest, GitHubSearchResponse, GitHubSearchRequest, DirectorySuggestionsResponse, PaseoWorktreeListResponse, PaseoWorktreeArchiveResponse, ProjectIconSource, ProjectIconResponse, ProjectIconGetResponse, ProjectAddResponse, ProjectCreateDirectoryResponse, OpenProjectResponseMessage, WorkspaceGithubSearchRepositoriesResponse, ProjectGithubCloneProtocol, ProjectGithubCloneResponse, ArchiveWorkspaceResponseMessage, WorkspaceSetupStatusResponseMessage, ListCommandsResponse, ListProviderFeaturesResponseMessage, ListProviderModelsResponseMessage, ListProviderModesResponseMessage, ListAvailableProvidersResponse, GetProvidersSnapshotResponseMessage, RefreshProvidersSnapshotResponseMessage, ProviderDiagnosticResponseMessage, ProviderUsageListResponseMessage, UsageListReportsResponseMessage, DaemonGetStatusResponse, DaemonGetPairingOfferResponse, DaemonConfigReloadResponse, DiagnosticsResponse, AgentRewindResponseMessage, ListTerminalsResponse, CreateTerminalResponse, SubscribeTerminalResponse, SubscribeTerminalRequest, CloseItemsResponse, KillTerminalResponse, CaptureTerminalResponse, TerminalInput, SessionInboundMessage, SessionOutboundMessage, SendAgentMessageRequest, PaseoConfigRaw, PaseoConfigRevision, WorkspaceCreateRequest, WorkspaceRecoveryState, PluginListItem, PluginLogEntry, PluginSourceStatusItem, PluginSourceUpdateItem, PluginUpdateSelection, PluginUpdateProposal, PluginUpdatePreview, PluginUpdateResult, AgentSkillSelection, AgentSkillsStatus, AgentSkillsSaveResult } from "@camerontaylor/paseo-protocol/messages";
8
+ import { AgentRefreshedStatusPayloadSchema, CheckoutRenameBranchResponseSchema, CheckoutBaseRefSetResponseSchema, RenameTerminalResponseSchema, RestartRequestedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, DaemonUpdateResponseSchema, type ActiveTurnBehavior, type AgentAttachmentWire, type QueuedAgentDeliveryIntent, type QueuedComposerAttachment, type ServerInfoStatusPayload } from "@camerontaylor/paseo-protocol/messages";
9
+ import type { AgentStreamEventPayload, AgentSnapshotPayload, ProjectPlacementPayload, AgentPermissionResolvedMessage, CreateAgentRequestMessage, CreatePaseoWorktreeRequest, FileDownloadTokenResponse, FileUploadResponse, FileExplorerResponse, FileVersion, FileWriteResult, FetchAgentTimelineResponseMessage, AgentForkContextResponseMessage, GitSetupOptions, CheckoutStatusResponse, CheckoutCommit, ParsedDiffFile, CheckoutCommitResponse, CheckoutMergeResponse, CheckoutMergeFromBaseResponse, CheckoutPullResponse, CheckoutPushResponse, CheckoutRefreshResponse, CheckoutPrCreateResponse, CheckoutPrMergeResponse, CheckoutPrMergeMethod, CheckoutForgeSetAutoMergeResponse, CheckoutGithubSetAutoMergeResponse, CheckoutForgeGetCheckDetailsResponse, CheckoutGithubGetCheckDetailsResponse, CheckoutPrStatusResponse, PullRequestTimelineResponse, CheckoutSwitchBranchResponse, StashSaveResponse, StashPopResponse, StashListResponse, ValidateBranchResponse, BranchSuggestionsResponse, ForgeSearchResponse, ForgeSearchRequest, GitHubSearchResponse, GitHubSearchRequest, DirectorySuggestionsResponse, PaseoWorktreeListResponse, PaseoWorktreeArchiveResponse, ProjectIconSource, ProjectIconResponse, ProjectIconGetResponse, ProjectAddResponse, ProjectCreateDirectoryResponse, OpenProjectResponseMessage, WorkspaceGithubSearchRepositoriesResponse, ProjectGithubCloneProtocol, ProjectGithubCloneResponse, ArchiveWorkspaceResponseMessage, WorkspaceSetupStatusResponseMessage, ListCommandsResponse, ListProviderFeaturesResponseMessage, ListProviderModelsResponseMessage, ListProviderModesResponseMessage, ListAvailableProvidersResponse, GetProvidersSnapshotResponseMessage, RefreshProvidersSnapshotResponseMessage, ProviderDiagnosticResponseMessage, ProviderUsageListResponseMessage, UsageReportEntry, DaemonGetStatusResponse, DaemonGetPairingOfferResponse, DaemonConfigReloadResponse, DiagnosticsResponse, AgentRewindResponseMessage, ListTerminalsResponse, CreateTerminalResponse, SubscribeTerminalResponse, SubscribeTerminalRequest, CloseItemsResponse, KillTerminalResponse, CaptureTerminalResponse, TerminalInput, SessionInboundMessage, SessionOutboundMessage, SendAgentMessageRequest, PaseoConfigRaw, PaseoConfigRevision, WorkspaceCreateRequest, WorkspaceRecoveryState, PluginListItem, PluginLogEntry, PluginSourceStatusItem, PluginSourceUpdateItem, PluginUpdateSelection, PluginUpdateProposal, PluginUpdatePreview, PluginUpdateResult, AgentSkillSelection, AgentSkillsStatus, AgentSkillsSaveResult } from "@camerontaylor/paseo-protocol/messages";
10
10
  import type { AgentPermissionRequest, AgentPermissionResponse, AgentPersistenceHandle, AgentProviderNotice, AgentProvider, AgentSessionConfig } from "@camerontaylor/paseo-protocol/agent-types";
11
11
  import type { AgentConfigApply, MutableDaemonConfig, MutableDaemonConfigPatch } from "@camerontaylor/paseo-protocol/messages";
12
12
  import { type DaemonTransportFactory, type WebSocketFactory } from "./daemon-client-transport.js";
@@ -266,7 +266,10 @@ type GetProvidersSnapshotPayload = GetProvidersSnapshotResponseMessage["payload"
266
266
  type RefreshProvidersSnapshotPayload = RefreshProvidersSnapshotResponseMessage["payload"];
267
267
  type ProviderDiagnosticPayload = ProviderDiagnosticResponseMessage["payload"];
268
268
  type ProviderUsageListPayload = ProviderUsageListResponseMessage["payload"];
269
- type UsageListReportsPayload = UsageListReportsResponseMessage["payload"];
269
+ interface UsageListReportsPayload {
270
+ requestId: string;
271
+ reports: UsageReportEntry[];
272
+ }
270
273
  type DaemonStatusPayload = DaemonGetStatusResponse["payload"];
271
274
  type DaemonPairingOfferPayload = DaemonGetPairingOfferResponse["payload"];
272
275
  type DiagnosticsPayload = DiagnosticsResponse["payload"];
@@ -589,6 +592,11 @@ export declare class DaemonConnectionError extends Error {
589
592
  constructor(message: string, code?: "DAEMON_CONNECTION_LOST" | "DAEMON_REQUEST_TIMEOUT");
590
593
  }
591
594
  export declare function supportsUsageReports(features: ServerInfoStatusPayload["features"]): boolean;
595
+ /** Identifies the voice attachment a voice message belongs to. */
596
+ export interface VoiceTransport {
597
+ attachmentId: string;
598
+ generation: string;
599
+ }
592
600
  export declare class DaemonClient {
593
601
  private config;
594
602
  private readonly providerSnapshotUpdates;
@@ -830,6 +838,26 @@ export declare class DaemonClient {
830
838
  name?: string;
831
839
  labels?: Record<string, string>;
832
840
  }): Promise<void>;
841
+ updateCompanionEntry(input: {
842
+ agentId: string;
843
+ entryId?: string;
844
+ action: "update_status" | "add_pin" | "remove_pin" | "add_q_and_a";
845
+ status?: "open" | "reviewed" | "done";
846
+ text?: string;
847
+ answerText?: string;
848
+ sourceId?: string;
849
+ }): Promise<void>;
850
+ /**
851
+ * Backfills an agent's artifact feed from files already on disk. Needed for
852
+ * agents whose work predates the artifact feed, whose feeds are otherwise
853
+ * permanently empty.
854
+ */
855
+ scanAgentArtifacts(agentId: string, options?: {
856
+ limit?: number;
857
+ }): Promise<{
858
+ addedOrUpdated: number;
859
+ total: number;
860
+ }>;
833
861
  renameProject(projectId: string, customName: string | null, requestId?: string): Promise<{
834
862
  customName: string | null;
835
863
  }>;
@@ -882,6 +910,53 @@ export declare class DaemonClient {
882
910
  buildAgentForkContext(agentId: string, options?: AgentForkContextOptions): Promise<AgentForkContextPayload>;
883
911
  sendAgentMessage(agentId: string, text: string, options?: SendMessageOptions): Promise<void>;
884
912
  sendMessage(agentId: string, text: string, options?: SendMessageOptions): Promise<void>;
913
+ /**
914
+ * Admits a prompt into the durable queue with an explicit delivery intent.
915
+ * `itemId` comes from the caller so an optimistic local row and the stored
916
+ * item share an id, which makes a reconnect retry of the same enqueue a
917
+ * daemon-side no-op instead of a duplicate.
918
+ */
919
+ enqueueAgentMessage(input: {
920
+ agentId: string;
921
+ itemId: string;
922
+ text: string;
923
+ intent: QueuedAgentDeliveryIntent;
924
+ images?: Array<{
925
+ data: string;
926
+ mimeType: string;
927
+ }>;
928
+ attachments?: AgentAttachmentWire[];
929
+ composerAttachments?: QueuedComposerAttachment[];
930
+ }): Promise<AgentQueueSnapshot>;
931
+ updateQueuedAgentMessage(input: {
932
+ agentId: string;
933
+ itemId: string;
934
+ text: string;
935
+ expectedRevision: number;
936
+ images?: Array<{
937
+ data: string;
938
+ mimeType: string;
939
+ }>;
940
+ attachments?: AgentAttachmentWire[];
941
+ composerAttachments?: QueuedComposerAttachment[];
942
+ }): Promise<AgentQueueSnapshot>;
943
+ reorderQueuedAgentMessages(agentId: string, itemIds: string[], expectedRevision: number): Promise<AgentQueueSnapshot>;
944
+ deleteQueuedAgentMessage(agentId: string, itemId: string, expectedRevision: number): Promise<AgentQueueSnapshot>;
945
+ retryQueuedAgentMessage(agentId: string, itemId: string, expectedRevision: number): Promise<AgentQueueSnapshot>;
946
+ sendQueuedAgentMessageNow(agentId: string, itemId: string, expectedRevision: number): Promise<AgentQueueSnapshot>;
947
+ listQueuedAgentMessages(agentId: string): Promise<AgentQueueSnapshot>;
948
+ /**
949
+ * Fetches the image bytes of one queued item. A device that did not queue the
950
+ * item has no local copy, so pulling it back into the composer would
951
+ * otherwise drop the images.
952
+ */
953
+ getQueuedAgentMessageImages(agentId: string, itemId: string): Promise<Array<{
954
+ id: string;
955
+ mimeType: string;
956
+ fileName?: string | null;
957
+ data: string;
958
+ }>>;
959
+ private requireAgentQueuePayload;
885
960
  rewindAgent(agentId: string, messageId: string, mode: "conversation" | "files" | "both"): Promise<AgentRewindResponseMessage["payload"]>;
886
961
  cancelAgent(agentId: string): Promise<void>;
887
962
  setAgentMode(agentId: string, modeId: string): Promise<AgentProviderNotice | null>;
@@ -901,8 +976,23 @@ export declare class DaemonClient {
901
976
  }): Promise<RestartRequestedStatusPayload>;
902
977
  shutdownServer(options?: ShutdownServerOptions): Promise<ShutdownRequestedStatusPayload>;
903
978
  updateDaemon(requestId?: string): Promise<DaemonUpdateResponse["payload"]>;
904
- setVoiceMode(enabled: boolean, agentId?: string): Promise<SetVoiceModePayload>;
905
- sendVoiceAudioChunk(audio: string, format: string, isLast?: boolean): Promise<void>;
979
+ setVoiceMode(enabled: boolean, agentId?: string, input?: {
980
+ /** Voice attachment identity; the host binds its transport generation to it. */
981
+ attachmentId?: string;
982
+ /** Supplied when an existing attachment reclaims itself after a reconnect. */
983
+ generation?: string;
984
+ }): Promise<SetVoiceModePayload>;
985
+ /** Reads this attachment's delivery receipts so the panel can show truthful state. */
986
+ readVoiceInputReceipts(input: {
987
+ agentId: string;
988
+ attachmentId: string;
989
+ generation: string;
990
+ after?: string;
991
+ limit?: number;
992
+ }): Promise<Extract<SessionOutboundMessage, {
993
+ type: "voice.input.receipts.read.response";
994
+ }>["payload"]>;
995
+ sendVoiceAudioChunk(audio: string, format: string, isLast?: boolean, transport?: VoiceTransport): Promise<void>;
906
996
  startDictationStream(dictationId: string, format: string): Promise<void>;
907
997
  sendDictationStreamChunk(dictationId: string, seq: number, audio: string, format: string): void;
908
998
  finishDictationStream(dictationId: string, finalSeq: number): Promise<{
@@ -910,8 +1000,8 @@ export declare class DaemonClient {
910
1000
  text: string;
911
1001
  }>;
912
1002
  cancelDictationStream(dictationId: string): void;
913
- abortRequest(): Promise<void>;
914
- audioPlayed(id: string): Promise<void>;
1003
+ abortRequest(transport?: VoiceTransport): Promise<void>;
1004
+ audioPlayed(id: string, error?: string, transport?: VoiceTransport): Promise<void>;
915
1005
  getCheckoutStatus(cwd: string, options?: {
916
1006
  requestId?: string;
917
1007
  }): Promise<CheckoutStatusPayload>;
@@ -1192,10 +1282,11 @@ export declare class DaemonClient {
1192
1282
  requestId?: string;
1193
1283
  }): Promise<ProviderUsageListPayload>;
1194
1284
  listUsageReports(options?: {
1285
+ agentId?: string;
1195
1286
  requestId?: string;
1196
1287
  forceRefresh?: boolean;
1197
1288
  reportIds?: string[];
1198
- }): Promise<UsageListReportsPayload>;
1289
+ }, onReport?: (report: UsageReportEntry) => void): Promise<UsageListReportsPayload>;
1199
1290
  listCommands(options: ListCommandsOptions): Promise<ListCommandsPayload>;
1200
1291
  listCommands(agentId: string, requestId?: string): Promise<ListCommandsPayload>;
1201
1292
  listCommands(agentId: string, options?: LegacyListCommandsOptions): Promise<ListCommandsPayload>;
@@ -1770,6 +1770,41 @@ export class DaemonClient {
1770
1770
  throw new Error(payload.error ?? "updateAgent rejected");
1771
1771
  }
1772
1772
  }
1773
+ async updateCompanionEntry(input) {
1774
+ const payload = await this.sendNamespacedCorrelatedSessionRequest({
1775
+ message: {
1776
+ type: "agent.companion.update_entry.request",
1777
+ agentId: input.agentId,
1778
+ entryId: input.entryId,
1779
+ action: input.action,
1780
+ status: input.status,
1781
+ text: input.text,
1782
+ answerText: input.answerText,
1783
+ sourceId: input.sourceId,
1784
+ },
1785
+ });
1786
+ if (!payload.accepted) {
1787
+ throw new Error(payload.error ?? "updateCompanionEntry rejected");
1788
+ }
1789
+ }
1790
+ /**
1791
+ * Backfills an agent's artifact feed from files already on disk. Needed for
1792
+ * agents whose work predates the artifact feed, whose feeds are otherwise
1793
+ * permanently empty.
1794
+ */
1795
+ async scanAgentArtifacts(agentId, options) {
1796
+ const payload = await this.sendNamespacedCorrelatedSessionRequest({
1797
+ message: {
1798
+ type: "agent.artifacts.scan.request",
1799
+ agentId,
1800
+ ...(options?.limit !== undefined ? { limit: options.limit } : {}),
1801
+ },
1802
+ });
1803
+ if (!payload.accepted) {
1804
+ throw new Error(payload.error ?? "scanAgentArtifacts rejected");
1805
+ }
1806
+ return { addedOrUpdated: payload.addedOrUpdated, total: payload.total };
1807
+ }
1773
1808
  async renameProject(projectId, customName, requestId) {
1774
1809
  const payload = await this.sendCorrelatedSessionRequest({
1775
1810
  requestId,
@@ -2210,6 +2245,96 @@ export class DaemonClient {
2210
2245
  async sendMessage(agentId, text, options) {
2211
2246
  await this.sendAgentMessage(agentId, text, options);
2212
2247
  }
2248
+ // ==========================================================================
2249
+ // Durable agent message queue — see docs/queue-mirroring.md.
2250
+ // Gated on server_info.features.durableAgentQueueV1; callers must check the
2251
+ // flag before reaching any of these. Mutations are revision-checked: a stale
2252
+ // expectedRevision is rejected with the `queue_revision_conflict` code
2253
+ // instead of overwriting another device's edit.
2254
+ // ==========================================================================
2255
+ /**
2256
+ * Admits a prompt into the durable queue with an explicit delivery intent.
2257
+ * `itemId` comes from the caller so an optimistic local row and the stored
2258
+ * item share an id, which makes a reconnect retry of the same enqueue a
2259
+ * daemon-side no-op instead of a duplicate.
2260
+ */
2261
+ async enqueueAgentMessage(input) {
2262
+ return this.requireAgentQueuePayload(await this.sendNamespacedCorrelatedSessionRequest({
2263
+ message: {
2264
+ type: "agent.queue.enqueue.request",
2265
+ agentId: input.agentId,
2266
+ itemId: input.itemId,
2267
+ text: input.text,
2268
+ intent: input.intent,
2269
+ ...(input.images?.length ? { images: input.images } : {}),
2270
+ ...(input.attachments?.length ? { attachments: input.attachments } : {}),
2271
+ ...(input.composerAttachments?.length
2272
+ ? { composerAttachments: input.composerAttachments }
2273
+ : {}),
2274
+ },
2275
+ }));
2276
+ }
2277
+ async updateQueuedAgentMessage(input) {
2278
+ return this.requireAgentQueuePayload(await this.sendNamespacedCorrelatedSessionRequest({
2279
+ message: {
2280
+ type: "agent.queue.update.request",
2281
+ agentId: input.agentId,
2282
+ itemId: input.itemId,
2283
+ text: input.text,
2284
+ expectedRevision: input.expectedRevision,
2285
+ ...(input.images?.length ? { images: input.images } : {}),
2286
+ ...(input.attachments?.length ? { attachments: input.attachments } : {}),
2287
+ ...(input.composerAttachments?.length
2288
+ ? { composerAttachments: input.composerAttachments }
2289
+ : {}),
2290
+ },
2291
+ }));
2292
+ }
2293
+ async reorderQueuedAgentMessages(agentId, itemIds, expectedRevision) {
2294
+ return this.requireAgentQueuePayload(await this.sendNamespacedCorrelatedSessionRequest({
2295
+ message: { type: "agent.queue.reorder.request", agentId, itemIds, expectedRevision },
2296
+ }));
2297
+ }
2298
+ async deleteQueuedAgentMessage(agentId, itemId, expectedRevision) {
2299
+ return this.requireAgentQueuePayload(await this.sendNamespacedCorrelatedSessionRequest({
2300
+ message: { type: "agent.queue.delete.request", agentId, itemId, expectedRevision },
2301
+ }));
2302
+ }
2303
+ async retryQueuedAgentMessage(agentId, itemId, expectedRevision) {
2304
+ return this.requireAgentQueuePayload(await this.sendNamespacedCorrelatedSessionRequest({
2305
+ message: { type: "agent.queue.retry.request", agentId, itemId, expectedRevision },
2306
+ }));
2307
+ }
2308
+ async sendQueuedAgentMessageNow(agentId, itemId, expectedRevision) {
2309
+ return this.requireAgentQueuePayload(await this.sendNamespacedCorrelatedSessionRequest({
2310
+ message: { type: "agent.queue.send_now.request", agentId, itemId, expectedRevision },
2311
+ }));
2312
+ }
2313
+ async listQueuedAgentMessages(agentId) {
2314
+ return this.requireAgentQueuePayload(await this.sendNamespacedCorrelatedSessionRequest({
2315
+ message: { type: "agent.queue.list.request", agentId },
2316
+ }));
2317
+ }
2318
+ /**
2319
+ * Fetches the image bytes of one queued item. A device that did not queue the
2320
+ * item has no local copy, so pulling it back into the composer would
2321
+ * otherwise drop the images.
2322
+ */
2323
+ async getQueuedAgentMessageImages(agentId, itemId) {
2324
+ const payload = await this.sendNamespacedCorrelatedSessionRequest({
2325
+ message: { type: "agent.queue.get_item_images.request", agentId, itemId },
2326
+ });
2327
+ if (payload.error) {
2328
+ throw new Error(payload.error);
2329
+ }
2330
+ return payload.images;
2331
+ }
2332
+ requireAgentQueuePayload(payload) {
2333
+ if (!payload.queue) {
2334
+ throw new Error(payload.error ?? "Agent queue request rejected");
2335
+ }
2336
+ return payload.queue;
2337
+ }
2213
2338
  async rewindAgent(agentId, messageId, mode) {
2214
2339
  const requestId = this.createRequestId();
2215
2340
  const message = SessionInboundMessageSchema.parse({
@@ -2483,12 +2608,14 @@ export class DaemonClient {
2483
2608
  // ============================================================================
2484
2609
  // Audio / Voice
2485
2610
  // ============================================================================
2486
- async setVoiceMode(enabled, agentId) {
2611
+ async setVoiceMode(enabled, agentId, input) {
2487
2612
  const requestId = this.createRequestId();
2488
2613
  const message = SessionInboundMessageSchema.parse({
2489
2614
  type: "set_voice_mode",
2490
2615
  enabled,
2491
2616
  ...(agentId ? { agentId } : {}),
2617
+ ...(input?.attachmentId ? { attachmentId: input.attachmentId } : {}),
2618
+ ...(input?.generation ? { generation: input.generation } : {}),
2492
2619
  requestId,
2493
2620
  });
2494
2621
  const response = await this.sendRequest({
@@ -2512,8 +2639,28 @@ export class DaemonClient {
2512
2639
  }
2513
2640
  return response;
2514
2641
  }
2515
- async sendVoiceAudioChunk(audio, format, isLast = false) {
2516
- this.sendSessionMessage({ type: "voice_audio_chunk", audio, format, isLast });
2642
+ /** Reads this attachment's delivery receipts so the panel can show truthful state. */
2643
+ async readVoiceInputReceipts(input) {
2644
+ const requestId = this.createRequestId();
2645
+ const response = await this.sendRequest({
2646
+ requestId,
2647
+ message: { type: "voice.input.receipts.read.request", requestId, ...input },
2648
+ select: (msg) => msg.type === "voice.input.receipts.read.response" && msg.payload.requestId === requestId
2649
+ ? msg.payload
2650
+ : null,
2651
+ });
2652
+ if (response.error)
2653
+ throw new Error(response.error);
2654
+ return response;
2655
+ }
2656
+ async sendVoiceAudioChunk(audio, format, isLast = false, transport) {
2657
+ this.sendSessionMessage({
2658
+ type: "voice_audio_chunk",
2659
+ audio,
2660
+ format,
2661
+ isLast,
2662
+ ...transport,
2663
+ });
2517
2664
  }
2518
2665
  async startDictationStream(dictationId, format) {
2519
2666
  const ack = this.waitForWithCancel((msg) => {
@@ -2674,11 +2821,16 @@ export class DaemonClient {
2674
2821
  cancelDictationStream(dictationId) {
2675
2822
  this.sendSessionMessageStrict({ type: "dictation_stream_cancel", dictationId });
2676
2823
  }
2677
- async abortRequest() {
2678
- this.sendSessionMessage({ type: "abort_request" });
2824
+ async abortRequest(transport) {
2825
+ this.sendSessionMessage({ type: "abort_request", ...transport });
2679
2826
  }
2680
- async audioPlayed(id) {
2681
- this.sendSessionMessage({ type: "audio_played", id });
2827
+ async audioPlayed(id, error, transport) {
2828
+ this.sendSessionMessageStrict({
2829
+ type: "audio_played",
2830
+ id,
2831
+ ...(error !== undefined ? { error } : {}),
2832
+ ...transport,
2833
+ });
2682
2834
  }
2683
2835
  // ============================================================================
2684
2836
  // Git Operations
@@ -3580,13 +3732,17 @@ export class DaemonClient {
3580
3732
  },
3581
3733
  });
3582
3734
  }
3583
- async listUsageReports(options) {
3735
+ async listUsageReports(options, onReport) {
3584
3736
  const features = this.getLastServerInfoMessage()?.features;
3585
3737
  if (!supportsUsageReports(features)) {
3586
3738
  throw new Error("Update the host to see usage.");
3587
3739
  }
3740
+ if (options?.agentId !== undefined && options.reportIds !== undefined)
3741
+ throw new Error("agentId and reportIds cannot be combined");
3588
3742
  // COMPAT(providerUsageList): added in v0.1.98, remove after 2027-03-26.
3589
3743
  if (features?.usageSources !== true) {
3744
+ if (options?.agentId !== undefined)
3745
+ return { requestId: this.createRequestId(options.requestId), reports: [] };
3590
3746
  // Released hosts serve a five-minute cache and have no forceRefresh option.
3591
3747
  const payload = await this.listProviderUsage({ requestId: options?.requestId });
3592
3748
  return {
@@ -3627,14 +3783,54 @@ export class DaemonClient {
3627
3783
  }),
3628
3784
  };
3629
3785
  }
3630
- return this.sendNamespacedCorrelatedSessionRequest({
3631
- requestId: options?.requestId,
3632
- message: {
3633
- type: "usage.list_reports.request",
3634
- forceRefresh: options?.forceRefresh,
3635
- reportIds: options?.reportIds,
3636
- },
3786
+ const requestId = this.createRequestId(options?.requestId);
3787
+ const reports = [];
3788
+ let active = true;
3789
+ const unsubscribe = this.subscribeRawMessages((message) => {
3790
+ if (!active ||
3791
+ !("payload" in message) ||
3792
+ !("requestId" in message.payload) ||
3793
+ message.payload.requestId !== requestId)
3794
+ return;
3795
+ if (message.type === "usage.list_reports.response" || message.type === "rpc_error") {
3796
+ active = false;
3797
+ return;
3798
+ }
3799
+ if (message.type !== "usage.list_reports.update")
3800
+ return;
3801
+ reports.push(message.payload.report);
3802
+ onReport?.(message.payload.report);
3637
3803
  });
3804
+ try {
3805
+ const response = await this.sendRequest({
3806
+ requestId,
3807
+ message: {
3808
+ type: "usage.list_reports.request",
3809
+ streaming: features?.usageReportsStreaming === true ? true : undefined,
3810
+ requestId,
3811
+ forceRefresh: options?.forceRefresh,
3812
+ reportIds: options?.reportIds,
3813
+ agentId: options?.agentId,
3814
+ },
3815
+ select: (message) => message.type === "usage.list_reports.response" && message.payload.requestId === requestId
3816
+ ? message.payload
3817
+ : null,
3818
+ });
3819
+ if (response.error != null)
3820
+ throw new Error(response.error);
3821
+ // COMPAT(usageReportsStreaming): added in v0.11.1, remove after 2027-04-08 once all hosts advertise usageReportsStreaming.
3822
+ // beta.3 sends reports only; beta.4 through 0.11.1 send updates only.
3823
+ if (response.reports !== undefined) {
3824
+ if (reports.length === 0)
3825
+ response.reports.forEach((report) => onReport?.(report));
3826
+ return { requestId, reports: response.reports };
3827
+ }
3828
+ return { requestId, reports };
3829
+ }
3830
+ finally {
3831
+ active = false;
3832
+ unsubscribe();
3833
+ }
3638
3834
  }
3639
3835
  async listCommands(input, legacyOptions) {
3640
3836
  const options = normalizeListCommandsOptions(input, legacyOptions);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camerontaylor/paseo-client",
3
- "version": "0.11.0-beta.3.fork.1",
3
+ "version": "0.11.1-fork.2",
4
4
  "description": "Paseo client SDK package",
5
5
  "files": [
6
6
  "dist",
@@ -39,8 +39,8 @@
39
39
  "test": "vitest run"
40
40
  },
41
41
  "dependencies": {
42
- "@camerontaylor/paseo-protocol": "0.11.0-beta.3.fork.1",
43
- "@camerontaylor/paseo-relay": "0.11.0-beta.3.fork.1",
42
+ "@camerontaylor/paseo-protocol": "0.11.1-fork.2",
43
+ "@camerontaylor/paseo-relay": "0.11.1-fork.2",
44
44
  "zod": "^4.4.3"
45
45
  },
46
46
  "devDependencies": {