@beanx/cathygo-protocol 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -390,6 +390,28 @@ type CathyGOTransport = {
390
390
  isOpen(): boolean;
391
391
  };
392
392
 
393
+ declare class SessionEventCursorStore {
394
+ private readonly cursors;
395
+ getAfterSeq(sessionId: string): number;
396
+ observeEvent(event: LearningTurnEvent): void;
397
+ setAfterSeq(sessionId: string, seq: number): void;
398
+ clear(): void;
399
+ }
400
+ type SessionSubscriptionClient = {
401
+ getSession(sessionId: string): Promise<ConversationDetail>;
402
+ subscribeSession(sessionId: string, afterSeq: number): Promise<void>;
403
+ };
404
+ declare class SessionSubscriptionManager {
405
+ private readonly client;
406
+ readonly cursorStore: SessionEventCursorStore;
407
+ private activeSessionId;
408
+ constructor(client: SessionSubscriptionClient, cursorStore: SessionEventCursorStore);
409
+ get activeSession(): string | null;
410
+ activateSession(sessionId: string, afterSeq?: number): Promise<ConversationDetail>;
411
+ deactivate(): void;
412
+ markActive(sessionId: string): void;
413
+ }
414
+
393
415
  declare class CathyGOClientError extends Error {
394
416
  readonly code?: string | undefined;
395
417
  constructor(message: string, code?: string | undefined);
@@ -405,7 +427,8 @@ declare class CathyGOProtocolClient {
405
427
  private turnHandlers;
406
428
  private attachmentRelayProgressHandlers;
407
429
  private lastConnect?;
408
- private lastEventSeq;
430
+ private readonly cursorStore;
431
+ private readonly subscriptionManager;
409
432
  private connectOptions;
410
433
  private callbacks;
411
434
  constructor(transport: CathyGOTransport, options: CathyGOProtocolClientOptions);
@@ -427,6 +450,11 @@ declare class CathyGOProtocolClient {
427
450
  attachment_relay_max_file_bytes?: number;
428
451
  attachment_relay_progress_min_interval_ms?: number;
429
452
  } | undefined;
453
+ getSessionEventCursorStore(): SessionEventCursorStore;
454
+ getLastEventSeq(sessionId: string): number;
455
+ getActiveSubscriptionSessionId(): string | null;
456
+ activateSession(sessionId: string, afterSeq?: number): Promise<ConversationDetail>;
457
+ deactivateSessionSubscription(): void;
430
458
  createSession(metadata?: Record<string, unknown>): Promise<string>;
431
459
  listSessions(limit?: number): Promise<ConversationSummary[]>;
432
460
  getSession(sessionId: string): Promise<ConversationDetail>;
@@ -469,4 +497,4 @@ declare function photoQuestionTurnInput(text: string, attachments: GatewayAttach
469
497
  declare function capabilityForTurn(attachments: GatewayAttachment[]): LearningCapability;
470
498
  declare function learningTurnInput(text: string, attachments: GatewayAttachment[]): TurnInput;
471
499
 
472
- export { type AgentActivity, type AgentPresenceEvent, type AttachmentCommitBlob, type AttachmentCommitParams, type AttachmentInput, type AttachmentRelayProgress, type AttachmentRelayProgressEvent, type AttachmentRelayProgressHandler, type BeanXAccountRuntimeConfig, CathyGOClientError, type CathyGOClientRole, type CathyGOConnectOptions, type CathyGOConnectResult, type CathyGODeviceContext, type CathyGOFrame, type CathyGOIncomingFrame, CathyGOProtocolClient, type CathyGOProtocolClientCallbacks, type CathyGOProtocolClientOptions, type CathyGORequest, type CathyGOResponse, type CathyGOTransport, type CathyGOTransportEventHandler, type CathyGOTransportFrameHandler, type ConversationDetail, type ConversationMessage, type ConversationMessagePart, type ConversationSummary, type GatewayAgentProfile, type GatewayAttachment, type GatewayModelConfig, type GatewayModelConfigUpdate, type GatewayModelOption, type GatewayModelStatus, type GatewayVisibleSettings, type LearningCapability, type LearningTurnEvent, type LearningTurnEventHandler, type LearningTurnEventPayload, type ListResponse, type MessagePartInput, type MultimodalTurnInput, type SameSessionPolicy, type SessionInputOptions, type SessionInputResult, type SessionRuntimeSnapshot, type SessionStopResult, type SettingsItem, type SettingsItemKind, type SettingsSection, type TextTurnInput, type TurnInput, type UploadAttachmentViaRelayOptions, type UploadScope, capabilityForTurn, connectPayload, isAttachmentRelayProgressEvent, isLearningTurnEvent, learningTurnInput, parseConnectPayload, photoQuestionTurnInput, settingsFromPayload, textTurnInput, uploadAttachmentViaRelay };
500
+ export { type AgentActivity, type AgentPresenceEvent, type AttachmentCommitBlob, type AttachmentCommitParams, type AttachmentInput, type AttachmentRelayProgress, type AttachmentRelayProgressEvent, type AttachmentRelayProgressHandler, type BeanXAccountRuntimeConfig, CathyGOClientError, type CathyGOClientRole, type CathyGOConnectOptions, type CathyGOConnectResult, type CathyGODeviceContext, type CathyGOFrame, type CathyGOIncomingFrame, CathyGOProtocolClient, type CathyGOProtocolClientCallbacks, type CathyGOProtocolClientOptions, type CathyGORequest, type CathyGOResponse, type CathyGOTransport, type CathyGOTransportEventHandler, type CathyGOTransportFrameHandler, type ConversationDetail, type ConversationMessage, type ConversationMessagePart, type ConversationSummary, type GatewayAgentProfile, type GatewayAttachment, type GatewayModelConfig, type GatewayModelConfigUpdate, type GatewayModelOption, type GatewayModelStatus, type GatewayVisibleSettings, type LearningCapability, type LearningTurnEvent, type LearningTurnEventHandler, type LearningTurnEventPayload, type ListResponse, type MessagePartInput, type MultimodalTurnInput, type SameSessionPolicy, SessionEventCursorStore, type SessionInputOptions, type SessionInputResult, type SessionRuntimeSnapshot, type SessionStopResult, type SessionSubscriptionClient, SessionSubscriptionManager, type SettingsItem, type SettingsItemKind, type SettingsSection, type TextTurnInput, type TurnInput, type UploadAttachmentViaRelayOptions, type UploadScope, capabilityForTurn, connectPayload, isAttachmentRelayProgressEvent, isLearningTurnEvent, learningTurnInput, parseConnectPayload, photoQuestionTurnInput, settingsFromPayload, textTurnInput, uploadAttachmentViaRelay };
package/dist/index.js CHANGED
@@ -1,3 +1,58 @@
1
+ // src/session-subscription.ts
2
+ var SessionEventCursorStore = class {
3
+ cursors = /* @__PURE__ */ new Map();
4
+ getAfterSeq(sessionId) {
5
+ return this.cursors.get(sessionId) ?? 0;
6
+ }
7
+ observeEvent(event) {
8
+ const sessionId = sessionIdFromEvent(event);
9
+ if (!sessionId || !event.seq || event.seq <= 0) return;
10
+ const current = this.cursors.get(sessionId) ?? 0;
11
+ if (event.seq > current) {
12
+ this.cursors.set(sessionId, event.seq);
13
+ }
14
+ }
15
+ setAfterSeq(sessionId, seq) {
16
+ if (seq > 0) {
17
+ this.cursors.set(sessionId, seq);
18
+ }
19
+ }
20
+ clear() {
21
+ this.cursors.clear();
22
+ }
23
+ };
24
+ var SessionSubscriptionManager = class {
25
+ constructor(client, cursorStore) {
26
+ this.client = client;
27
+ this.cursorStore = cursorStore;
28
+ }
29
+ client;
30
+ cursorStore;
31
+ activeSessionId = null;
32
+ get activeSession() {
33
+ return this.activeSessionId;
34
+ }
35
+ async activateSession(sessionId, afterSeq) {
36
+ this.activeSessionId = sessionId;
37
+ const detail = await this.client.getSession(sessionId);
38
+ const snapshotSeq = detail.runtime?.last_event_seq ?? detail.session.runtime?.last_event_seq ?? 0;
39
+ const subscribeFrom = afterSeq ?? snapshotSeq;
40
+ await this.client.subscribeSession(sessionId, subscribeFrom);
41
+ return detail;
42
+ }
43
+ deactivate() {
44
+ this.activeSessionId = null;
45
+ }
46
+ markActive(sessionId) {
47
+ this.activeSessionId = sessionId;
48
+ }
49
+ };
50
+ function sessionIdFromEvent(event) {
51
+ const sessionId = event.payload.session_id;
52
+ if (typeof sessionId !== "string" || !sessionId.trim()) return void 0;
53
+ return sessionId.trim();
54
+ }
55
+
1
56
  // src/client.ts
2
57
  var CathyGOClientError = class extends Error {
3
58
  constructor(message, code) {
@@ -12,6 +67,7 @@ var CathyGOProtocolClient = class {
12
67
  this.transport = transport;
13
68
  this.connectOptions = options.connect;
14
69
  this.callbacks = options.callbacks ?? {};
70
+ this.subscriptionManager = new SessionSubscriptionManager(this, this.cursorStore);
15
71
  this.transport.onFrame((frame) => this.handleFrame(frame));
16
72
  this.transport.onClose?.(() => {
17
73
  this.rejectPending("CathyGO socket closed");
@@ -28,7 +84,8 @@ var CathyGOProtocolClient = class {
28
84
  turnHandlers = /* @__PURE__ */ new Set();
29
85
  attachmentRelayProgressHandlers = /* @__PURE__ */ new Set();
30
86
  lastConnect;
31
- lastEventSeq = 0;
87
+ cursorStore = new SessionEventCursorStore();
88
+ subscriptionManager;
32
89
  connectOptions;
33
90
  callbacks;
34
91
  updateConnectOptions(patch) {
@@ -69,7 +126,8 @@ var CathyGOProtocolClient = class {
69
126
  disconnect() {
70
127
  this.transport.close();
71
128
  this.lastConnect = void 0;
72
- this.lastEventSeq = 0;
129
+ this.cursorStore.clear();
130
+ this.subscriptionManager.deactivate();
73
131
  this.rejectPending("CathyGO socket closed");
74
132
  }
75
133
  isConnected() {
@@ -78,6 +136,21 @@ var CathyGOProtocolClient = class {
78
136
  getLimits() {
79
137
  return this.lastConnect?.limits;
80
138
  }
139
+ getSessionEventCursorStore() {
140
+ return this.cursorStore;
141
+ }
142
+ getLastEventSeq(sessionId) {
143
+ return this.cursorStore.getAfterSeq(sessionId);
144
+ }
145
+ getActiveSubscriptionSessionId() {
146
+ return this.subscriptionManager.activeSession;
147
+ }
148
+ async activateSession(sessionId, afterSeq) {
149
+ return this.subscriptionManager.activateSession(sessionId, afterSeq);
150
+ }
151
+ deactivateSessionSubscription() {
152
+ this.subscriptionManager.deactivate();
153
+ }
81
154
  async createSession(metadata = {}) {
82
155
  const payload = await this.request("session.create", { metadata });
83
156
  return String(payload.session_id ?? "");
@@ -109,9 +182,11 @@ var CathyGOProtocolClient = class {
109
182
  return turnStartResultFromPayload(payload, sessionId);
110
183
  }
111
184
  async subscribeSession(sessionId, afterSeq) {
185
+ this.subscriptionManager.markActive(sessionId);
186
+ const resolvedAfterSeq = afterSeq ?? this.cursorStore.getAfterSeq(sessionId);
112
187
  await this.request("session.subscribe", {
113
188
  session_id: sessionId,
114
- after_seq: afterSeq ?? this.lastEventSeq
189
+ after_seq: resolvedAfterSeq
115
190
  });
116
191
  }
117
192
  async stopSession(sessionId) {
@@ -124,12 +199,7 @@ var CathyGOProtocolClient = class {
124
199
  };
125
200
  }
126
201
  async resumeSession(sessionId, afterSeq) {
127
- const detail = await this.getSession(sessionId);
128
- await this.subscribeSession(
129
- sessionId,
130
- afterSeq ?? detail.runtime?.last_event_seq ?? detail.session.runtime?.last_event_seq
131
- );
132
- return detail;
202
+ return this.subscriptionManager.activateSession(sessionId, afterSeq);
133
203
  }
134
204
  async regenerateSession(sessionId) {
135
205
  const payload = await this.request("session.regenerate", { session_id: sessionId });
@@ -202,9 +272,7 @@ var CathyGOProtocolClient = class {
202
272
  }
203
273
  }
204
274
  if (isLearningTurnEvent(frame)) {
205
- if (typeof frame.seq === "number" && frame.seq > this.lastEventSeq) {
206
- this.lastEventSeq = frame.seq;
207
- }
275
+ this.cursorStore.observeEvent(frame);
208
276
  this.callbacks.onTurnEvent?.(frame);
209
277
  for (const handler of this.turnHandlers) {
210
278
  handler(frame);
@@ -461,6 +529,8 @@ function learningTurnInput(text, attachments) {
461
529
  export {
462
530
  CathyGOClientError,
463
531
  CathyGOProtocolClient,
532
+ SessionEventCursorStore,
533
+ SessionSubscriptionManager,
464
534
  capabilityForTurn,
465
535
  connectPayload,
466
536
  isAttachmentRelayProgressEvent,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beanx/cathygo-protocol",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"