@neta-art/cohub 1.5.0 → 1.6.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.
@@ -148,6 +148,11 @@ export declare class SessionClient {
148
148
  rename(title: string | null, customFetch?: Fetch): Promise<{
149
149
  session: SessionRecord;
150
150
  }>;
151
+ abort(optionsOrFetch?: {
152
+ turnId?: string | null;
153
+ } | Fetch, customFetch?: Fetch): Promise<{
154
+ ok: true;
155
+ }>;
151
156
  subscribe(handlers: SessionSubscriptionHandlers): () => void;
152
157
  on(type: SessionEventName, handler: (event: WebsocketEventPayload) => void): () => void;
153
158
  }
@@ -425,6 +425,16 @@ export class SessionClient {
425
425
  fetch: customFetch,
426
426
  });
427
427
  }
428
+ abort(optionsOrFetch, customFetch) {
429
+ const options = typeof optionsOrFetch === "function" ? undefined : optionsOrFetch;
430
+ const fetch = typeof optionsOrFetch === "function" ? optionsOrFetch : customFetch;
431
+ return this.transport.request(`/api/sessions/${this.id}/abort`, {
432
+ method: "POST",
433
+ headers: { "Content-Type": "application/json" },
434
+ body: JSON.stringify({ turnId: options?.turnId ?? null }),
435
+ fetch,
436
+ });
437
+ }
428
438
  subscribe(handlers) {
429
439
  return this.realtime.subscribe(handlers);
430
440
  }
@@ -1,6 +1,6 @@
1
1
  import type { ContentBlock } from "@neta-art/cohub-protocol/core";
2
2
  import type { RealtimePatchOperation, SessionTurnPatchEvent } from "@neta-art/cohub-protocol/realtime";
3
- export type SessionPatchStatus = "idle" | "pending" | "streaming" | "completed" | "failed";
3
+ export type SessionPatchStatus = "idle" | "pending" | "streaming" | "completed" | "failed" | "interrupted";
4
4
  export type SessionPatchState = {
5
5
  spaceId: string | null;
6
6
  sessionId: string;
@@ -50,6 +50,7 @@ export declare class SessionPatchReducer {
50
50
  }): SessionPatchState;
51
51
  complete(input: SessionPatchKeyInput): SessionPatchState;
52
52
  fail(input: SessionPatchKeyInput): SessionPatchState;
53
+ interrupt(input: SessionPatchKeyInput): SessionPatchState;
53
54
  reset(input: SessionPatchKeyInput): void;
54
55
  applySnapshot(input: SessionPatchSnapshotInput): SessionPatchApplyResult;
55
56
  resetAll(): void;
@@ -1,6 +1,8 @@
1
1
  const blockSubPathPattern = /^\/message\/content\/blocks\/(\d+)\/(.+)$/;
2
2
  const blockPathPattern = /^\/message\/content\/blocks\/(\d+)$/;
3
3
  const blockMetaPathPattern = /^\/message\/content\/blocks\/(\d+)\/_meta$/;
4
+ const TERMINAL_PATCH_STATUSES = new Set(["completed", "failed", "interrupted"]);
5
+ const isTerminalPatchStatus = (status) => TERMINAL_PATCH_STATUSES.has(status);
4
6
  const createIdleState = (input) => ({
5
7
  spaceId: input.spaceId ?? null,
6
8
  sessionId: input.sessionId,
@@ -305,6 +307,19 @@ export class SessionPatchReducer {
305
307
  this.states.set(this.key(input), state);
306
308
  return state;
307
309
  }
310
+ interrupt(input) {
311
+ const current = this.get(input);
312
+ const state = {
313
+ ...current,
314
+ turnId: input.turnId ?? current.turnId,
315
+ status: "interrupted",
316
+ contentBlocks: [],
317
+ anchorUserMessageId: null,
318
+ appendPath: null,
319
+ };
320
+ this.states.set(this.key(input), state);
321
+ return state;
322
+ }
308
323
  reset(input) {
309
324
  this.states.delete(this.key(input));
310
325
  }
@@ -313,7 +328,8 @@ export class SessionPatchReducer {
313
328
  const inputTurnId = input.turnId ?? null;
314
329
  const currentTurnId = current.turnId;
315
330
  const isDifferentKnownTurn = Boolean(currentTurnId && inputTurnId && currentTurnId !== inputTurnId);
316
- if (!isDifferentKnownTurn && input.seq < current.patchSeq) {
331
+ const isTerminalSameTurn = isTerminalPatchStatus(current.status) && Boolean(currentTurnId) && currentTurnId === inputTurnId;
332
+ if (isTerminalSameTurn || (!isDifferentKnownTurn && input.seq < current.patchSeq)) {
317
333
  return { applied: false, reason: "duplicate", state: current };
318
334
  }
319
335
  const state = {
@@ -356,7 +372,7 @@ export class SessionPatchReducer {
356
372
  currentTurnId === inputTurnId &&
357
373
  input.baseSeq === 0 &&
358
374
  input.seq >= currentSeq);
359
- const isTerminalSameTurn = (current.status === "completed" || current.status === "failed") &&
375
+ const isTerminalSameTurn = isTerminalPatchStatus(current.status) &&
360
376
  Boolean(currentTurnId) &&
361
377
  currentTurnId === inputTurnId;
362
378
  if (isTerminalSameTurn) {
package/dist/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { SessionBindingRecord as ProtocolSessionBindingRecord, SessionRecord as ProtocolSessionRecord, SessionTurnIndexItem, SessionTurnRecord } from "@neta-art/cohub-protocol/model";
2
2
  import type { ChannelConfig } from "@neta-art/cohub-protocol/gateway";
3
- import type { ContentBlock } from "@neta-art/cohub-protocol/core";
3
+ import type { ContentBlock, Usage } from "@neta-art/cohub-protocol/core";
4
4
  import type { MessageRecord } from "@neta-art/cohub-protocol/model";
5
5
  export type { ChannelConfig, DiscordChannelConfig, } from "@neta-art/cohub-protocol/gateway";
6
6
  export type ApiError = {
@@ -226,6 +226,18 @@ export type SessionTurnStreamSnapshotResponse = {
226
226
  messageId: string | null;
227
227
  messageOrdinal: number | null;
228
228
  content: ContentBlock[];
229
+ id?: string;
230
+ sessionId?: string;
231
+ role?: "user" | "assistant" | "system";
232
+ text?: string | null;
233
+ provider?: string | null;
234
+ model?: string | null;
235
+ stopReason?: string | null;
236
+ errorMessage?: string | null;
237
+ usage?: Usage | null;
238
+ toolCallsObjectKey?: string | null;
239
+ meta?: Record<string, unknown> | null;
240
+ createdAt?: string;
229
241
  }>;
230
242
  updatedAt: number;
231
243
  } | null;
package/dist/websocket.js CHANGED
@@ -473,10 +473,12 @@ export class WebsocketClient {
473
473
  }
474
474
  const buffer = this.patchStreamBuffers.get(key);
475
475
  if (!buffer) {
476
- this.patchStreamBuffers.set(key, {
477
- nextSeq: payload.baseSeq,
476
+ const newBuffer = {
477
+ nextSeq: payload.baseSeq + 1,
478
478
  pending: new Map([[payload.seq, envelope]]),
479
- });
479
+ };
480
+ this.patchStreamBuffers.set(key, newBuffer);
481
+ this.flushPatchStreamBuffer(newBuffer);
480
482
  return;
481
483
  }
482
484
  if (payload.seq < buffer.nextSeq)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neta-art/cohub",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Cohub SDK for spaces, sessions, checkpoints, and realtime agent collaboration.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -44,7 +44,7 @@
44
44
  "README.md"
45
45
  ],
46
46
  "dependencies": {
47
- "@neta-art/cohub-protocol": "1.3.0"
47
+ "@neta-art/cohub-protocol": "1.4.0"
48
48
  },
49
49
  "devDependencies": {
50
50
  "typescript": "^6.0.3"