@ellipsis-dev/sdk 0.36.0 → 0.37.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.
package/dist/index.js CHANGED
@@ -29,14 +29,12 @@ var Page = class {
29
29
  };
30
30
 
31
31
  // src/core/sessionHandle.ts
32
- var FINAL_TURN_STATUSES = /* @__PURE__ */ new Set([
33
- "completed",
34
- "failed",
35
- "stopped",
36
- "cancelled"
32
+ var SETTLED_SESSION_STATUSES = /* @__PURE__ */ new Set([
33
+ "idle",
34
+ "closed"
37
35
  ]);
38
- function isTurnFinal(status) {
39
- return FINAL_TURN_STATUSES.has(status);
36
+ function isSessionSettled(status) {
37
+ return SETTLED_SESSION_STATUSES.has(status);
40
38
  }
41
39
  var DEFAULT_POLL_INTERVAL_MS = 3e3;
42
40
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
@@ -45,50 +43,55 @@ var SessionHandle = class {
45
43
  this.sessions = sessions;
46
44
  this.id = session.id;
47
45
  this.session = session;
48
- this.turnId = session.turn?.id ?? null;
49
46
  }
50
47
  sessions;
51
48
  id;
52
49
  // The latest session snapshot this handle saw.
53
50
  session;
54
- // The turn `wait()` waits on: the session's turn after `run()`, then the
55
- // turn each `send()` creates. Null until the session has a message.
56
- turnId;
51
+ // The message `wait()` waits on: the last one sent through `send()`, else
52
+ // the session's latest message.
53
+ messageId = null;
57
54
  async refresh() {
58
55
  this.session = (await this.sessions.get(this.id)).session;
59
56
  return this.session;
60
57
  }
61
- // Poll until the awaited turn reaches a final status (completed, failed,
62
- // stopped, cancelled) or the conversation closes, and return that turn.
63
- // Returns null at once when the session has no turn to wait on.
58
+ // Poll until the session is idle or closed, then return how the awaited
59
+ // message ended: its `message_ended` record's payload. Null when the
60
+ // session has no message.
64
61
  async wait(options = {}) {
65
62
  const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
66
63
  const deadline = options.timeoutMs == null ? null : Date.now() + options.timeoutMs;
67
64
  for (; ; ) {
68
65
  const session = await this.refresh();
69
- const turnId = this.turnId;
70
- if (turnId == null) return null;
71
- const turn = session.turn?.id === turnId ? session.turn : (await this.sessions.turns.get(this.id, turnId)).turn;
72
- if (isTurnFinal(turn.status) || session.conversation.state === "closed")
73
- return turn;
66
+ if (isSessionSettled(session.status)) break;
74
67
  if (deadline != null && Date.now() >= deadline) {
75
68
  throw new Error(
76
- `turn ${turnId} of session ${this.id} not final after ${options.timeoutMs}ms`
69
+ `session ${this.id} not settled after ${options.timeoutMs}ms`
77
70
  );
78
71
  }
79
72
  await sleep(pollIntervalMs);
80
73
  }
74
+ let ended = null;
75
+ const page = await this.sessions.records(this.id, {
76
+ message_id: this.messageId
77
+ });
78
+ for await (const record of page) {
79
+ if (record.kind !== "platform" || record.record_type !== "message_ended")
80
+ continue;
81
+ if (this.messageId == null || record.message_id === this.messageId)
82
+ ended = record.payload;
83
+ }
84
+ return ended;
81
85
  }
82
- // Post a message into the session. The returned turn is the one that will
83
- // answer it, and the one `wait()` waits on from now. `images` ride the
84
- // message as content blocks the model sees on that turn.
86
+ // Send a message to the session; `wait()` then waits for it to be
87
+ // answered. `images` ride the message as content blocks the model sees.
85
88
  async send(message, options = {}) {
86
89
  const response = await this.sessions.sendMessage(this.id, {
87
90
  message,
88
91
  images: options.images,
89
92
  idempotency_key: options.idempotencyKey
90
93
  });
91
- this.turnId = response.turn.id;
94
+ this.messageId = response.message.id;
92
95
  return response;
93
96
  }
94
97
  async stop() {
@@ -1714,58 +1717,11 @@ var EllipsisSecrets = class {
1714
1717
  return await this.transport.request("PUT", path, { body });
1715
1718
  }
1716
1719
  };
1717
- var EllipsisSessionsTurns = class {
1718
- constructor(transport) {
1719
- this.transport = transport;
1720
- }
1721
- transport;
1722
- /**
1723
- * Get Session Turn
1724
- *
1725
- * Return one turn.
1726
- *
1727
- * Poll this after sending a message: the message is answered when
1728
- * the turn's status is completed, failed, stopped, or cancelled.
1729
- *
1730
- * Required permissions: read:sessions.
1731
- * API key: Supported.
1732
- * CLI user token: Supported.
1733
- * Session token: Requires the ellipsis:api scope and the required grants in the token's permissions.ellipsis configuration.
1734
- * Higher permission levels include lower levels: read < write < delete.
1735
- * Grant match patterns can further restrict access to individual resources.
1736
- */
1737
- async get(session_id, id) {
1738
- const path = `/v1/sessions/${enc(session_id)}/turns/${enc(id)}`;
1739
- return await this.transport.request("GET", path);
1740
- }
1741
- /**
1742
- * Get Session Turns
1743
- *
1744
- * Return the session's turns and messages, oldest first.
1745
- *
1746
- * One turn per message: pending until the agent starts on it,
1747
- * running while it works, then completed, failed, stopped, or
1748
- * cancelled.
1749
- *
1750
- * Required permissions: read:sessions.
1751
- * API key: Supported.
1752
- * CLI user token: Supported.
1753
- * Session token: Requires the ellipsis:api scope and the required grants in the token's permissions.ellipsis configuration.
1754
- * Higher permission levels include lower levels: read < write < delete.
1755
- * Grant match patterns can further restrict access to individual resources.
1756
- */
1757
- async list(id) {
1758
- const path = `/v1/sessions/${enc(id)}/turns`;
1759
- return await this.transport.request("GET", path);
1760
- }
1761
- };
1762
1720
  var EllipsisSessions = class {
1763
1721
  constructor(transport) {
1764
1722
  this.transport = transport;
1765
- this.turns = new EllipsisSessionsTurns(transport);
1766
1723
  }
1767
1724
  transport;
1768
- turns;
1769
1725
  /**
1770
1726
  * Get Session Analytics
1771
1727
  *
@@ -1908,8 +1864,7 @@ var EllipsisSessions = class {
1908
1864
  * List cloud agent sessions, newest first.
1909
1865
  *
1910
1866
  * Optionally filtered by agent (id or name), source, service, handler, time
1911
- * window, attributed author, repository, and whether the session is
1912
- * still going.
1867
+ * window, attributed author, repository, and status.
1913
1868
  *
1914
1869
  * Required permissions: read:sessions.
1915
1870
  * API key: Supported.
@@ -1920,7 +1875,7 @@ var EllipsisSessions = class {
1920
1875
  */
1921
1876
  async list(options = {}) {
1922
1877
  const path = "/v1/sessions";
1923
- const query = buildQuery({ agent: options.agent, source: options.source, service: options.service, handler: options.handler, days: options.days, start: options.start, end: options.end, limit: options.limit, cursor: options.cursor, author_id: options.author_id, repo: options.repo, unfinished: options.unfinished });
1878
+ const query = buildQuery({ agent: options.agent, source: options.source, service: options.service, handler: options.handler, days: options.days, start: options.start, end: options.end, limit: options.limit, cursor: options.cursor, author_id: options.author_id, repo: options.repo, status: options.status });
1924
1879
  const response = await this.transport.request("GET", path, { query });
1925
1880
  return new Page(
1926
1881
  response,
@@ -1967,7 +1922,7 @@ var EllipsisSessions = class {
1967
1922
  */
1968
1923
  async records(id, options = {}) {
1969
1924
  const path = `/v1/sessions/${enc(id)}/records`;
1970
- const query = buildQuery({ cursor: options.cursor, limit: options.limit });
1925
+ const query = buildQuery({ cursor: options.cursor, limit: options.limit, message_id: options.message_id });
1971
1926
  const response = await this.transport.request("GET", path, { query });
1972
1927
  return new Page(
1973
1928
  response,
@@ -1996,8 +1951,9 @@ var EllipsisSessions = class {
1996
1951
  * Send a message to a session.
1997
1952
  *
1998
1953
  * 409 for mention, non-interactive, closed, and out-of-budget
1999
- * sessions. Returns the created message and its turn; a retried send
2000
- * with the same idempotency_key returns the original ones.
1954
+ * sessions. Returns the created message; a retried send with the
1955
+ * same idempotency_key returns the original one. The message is
1956
+ * answered once the session's status is `idle` or `closed`.
2001
1957
  *
2002
1958
  * Required permissions: write:sessions.
2003
1959
  * API key: Supported.
@@ -2058,11 +2014,11 @@ var EllipsisSessions = class {
2058
2014
  /**
2059
2015
  * Stop Session
2060
2016
  *
2061
- * Stop the turn in progress and return the session.
2017
+ * Stop the session's work and return it.
2062
2018
  *
2063
- * The turn ends `stopped`; the conversation stays open. 409 when no
2064
- * turn is queued, preparing, or running. The stopping user is recorded only
2065
- * when the caller's credential maps to a GitHub account.
2019
+ * The running message ends `stopped` and every queued message is
2020
+ * cancelled, so the session goes `idle` (or `closed` when it was
2021
+ * not interactive). 409 when the session is idle or closed already.
2066
2022
  *
2067
2023
  * Required permissions: write:sessions.
2068
2024
  * API key: Supported.
@@ -2600,5 +2556,5 @@ export {
2600
2556
  Transport,
2601
2557
  TransportError,
2602
2558
  UnprocessableError,
2603
- isTurnFinal
2559
+ isSessionSettled
2604
2560
  };
@@ -1,14 +1,13 @@
1
- import { s as CodexAgentMessage, cO as SessionRecord, N as CodexFileChangeItem, L as CodexEvent, _ as CodexMcpToolCallItem, cb as SdkRecord, co as Session, cH as SessionMessage, d4 as StreamFrame } from '../types-CbePyY-S.js';
1
+ import { s as CodexAgentMessage, cQ as SessionRecord, N as CodexFileChangeItem, L as CodexEvent, _ as CodexMcpToolCallItem, ce as SdkRecord, cr as Session, d1 as StreamFrame } from '../types-BXbnHOQe.js';
2
2
 
3
3
  type WorkPhase = 'queued' | 'preparing' | 'starting' | 'working';
4
- interface TurnTiming {
5
- id: string;
4
+ interface MessageTiming {
6
5
  startedAt: string | null;
7
6
  completedAt: string | null;
8
7
  }
9
8
  interface MessageProgress {
10
9
  phase: WorkPhase | null;
11
- turns: TurnTiming[];
10
+ timing: MessageTiming;
12
11
  }
13
12
 
14
13
  interface ChatToolNode {
@@ -50,7 +49,6 @@ type ChatNode = {
50
49
  interface ChatTurn {
51
50
  key: string;
52
51
  messageId?: string;
53
- turnId?: string;
54
52
  role: 'assistant' | 'user' | 'lifecycle';
55
53
  nodes: ChatNode[];
56
54
  startedAt: string | null;
@@ -70,10 +68,6 @@ declare function groupRecordsToChatTurns(records: readonly SessionRecord[], sess
70
68
  prompt?: string | null;
71
69
  } | null;
72
70
  created_at: string;
73
- turn?: {
74
- id: string;
75
- index: number;
76
- } | null;
77
71
  } | null): ChatTurn[];
78
72
 
79
73
  type RecordSlice = {
@@ -81,8 +75,7 @@ type RecordSlice = {
81
75
  source: string;
82
76
  record_type: string;
83
77
  payload: Record<string, unknown>;
84
- turn_id?: string | null;
85
- session_message_id?: string | null;
78
+ message_id?: string | null;
86
79
  };
87
80
  declare function recordSlice(records: readonly SessionRecord[]): readonly RecordSlice[];
88
81
  declare function humanDuration(seconds: number): string;
@@ -214,13 +207,13 @@ interface ToolActivity {
214
207
  declare function toolActivities(item: TranscriptItem): ToolActivity[];
215
208
  declare function activitySummary(activities: readonly ToolActivity[]): string;
216
209
 
217
- declare function environmentOutputStep(payload: Record<string, unknown>): string;
218
- declare function environmentOutputLines(payload: Record<string, unknown>): string[];
219
- declare function environmentOutputLine(payload: Record<string, unknown>): string | null;
210
+ declare function environmentOutputStep(source: object): string;
211
+ declare function environmentOutputLines(source: object): string[];
212
+ declare function environmentOutputLine(source: object): string | null;
220
213
  declare function cacheTierLabel(tier: unknown): string | null;
221
214
  declare function environmentPhaseLabel(phase: unknown): string;
222
- declare function turnEndedText(payload: Record<string, unknown>): string | null;
223
- declare function lifecycleText(recordType: string, payload: Record<string, unknown>): string | null;
215
+ declare function messageEndedText(source: object): string | null;
216
+ declare function lifecycleText(recordType: string, source: object): string | null;
224
217
 
225
218
  declare function claudePayload(record: SessionRecord): SdkRecord | null;
226
219
 
@@ -231,9 +224,7 @@ declare function isConversationOver(session: Session): boolean;
231
224
  interface SessionTranscriptSnapshot {
232
225
  session: Session | null;
233
226
  records: readonly SessionRecord[];
234
- messages: readonly SessionMessage[];
235
227
  acknowledgedMessageIds: ReadonlySet<string>;
236
- historyTruncated: boolean;
237
228
  liveText: string;
238
229
  liveSummary: string;
239
230
  liveOutputTokens: number | null;
@@ -243,27 +234,22 @@ interface SessionTranscriptSnapshot {
243
234
  declare function seedTranscriptStore(store: SessionTranscriptStore, seed: {
244
235
  session: Session;
245
236
  records: readonly SessionRecord[];
246
- messages?: readonly SessionMessage[] | null;
247
- earliestFeedSeq?: number | null;
248
237
  }): void;
249
238
  declare function emptySessionTranscriptSnapshot(): SessionTranscriptSnapshot;
250
239
  declare class SessionTranscriptStore {
251
240
  private snapshot;
252
241
  private listeners;
253
242
  private acknowledged;
254
- private inbox;
255
243
  private cursorSeq;
256
244
  private turnsFor;
257
245
  private turnsSession;
258
246
  private turnsCache;
259
- private summaryTurnId;
247
+ private summaryMessageId;
260
248
  get cursor(): number;
261
249
  subscribe: (listener: () => void) => (() => void);
262
250
  getSnapshot: () => SessionTranscriptSnapshot;
263
251
  chatTurns: () => ChatTurn[];
264
- private pendingMessages;
265
- private applyMessageRecord;
266
252
  ingest: (rawFrame: StreamFrame) => void;
267
253
  }
268
254
 
269
- export { BRANCH_GLYPH, type ChatNode, type ChatToolNode, type ChatTurn, type EntryBody, type EnvironmentLogKind, type EnvironmentLogLine, type EnvironmentState, type EventToItemsOptions, type ItemKind, LIVE_GLYPH, type LedgerEntry, type MessageProgress, type PlacedItem, type RecordSlice, type SessionTranscriptSnapshot, SessionTranscriptStore, StreamFrame, type ToolActivity, type TranscriptItem, type TurnTiming, USER_BAR, type WorkPhase, activitySummary, awaitingAgentPhase, cacheTierLabel, chatTurnsToItems, clampLines, claudePayload, codexChangedPaths, codexEventToItems, codexMcpToolName, codexSubagentThreads, collapseToolRuns, deliveredUnechoedSends, deriveEnvironmentState, emptySessionTranscriptSnapshot, entryBody, entrySeconds, environmentOutputLine, environmentOutputLines, environmentOutputStep, environmentPhaseLabel, environmentSummary, eventToItems, foldCosts, foldGutter, foldRun, formatDuration, groupRecordsToChatTurns, gutterFor, hookPhrase, humanDuration, isCodexSubagentRecord, isConnectVisibleRecord, isConversationOver, isFoldable, isToolActivity, isToolFold, isWorkFold, lastLines, layOutItems, lifecycleText, oneLine, pendingToolCalls, reasoningSummaryTitle, recordSlice, recordToItems, resultCostUsd, seedTranscriptStore, sessionLogText, splitLedger, startupHeadline, startupSettled, statusActivityText, summarizeToolInput, tailLines, toolActivities, toolResultText, toolRunMembers, turnEndedText };
255
+ export { BRANCH_GLYPH, type ChatNode, type ChatToolNode, type ChatTurn, type EntryBody, type EnvironmentLogKind, type EnvironmentLogLine, type EnvironmentState, type EventToItemsOptions, type ItemKind, LIVE_GLYPH, type LedgerEntry, type MessageProgress, type MessageTiming, type PlacedItem, type RecordSlice, type SessionTranscriptSnapshot, SessionTranscriptStore, StreamFrame, type ToolActivity, type TranscriptItem, USER_BAR, type WorkPhase, activitySummary, awaitingAgentPhase, cacheTierLabel, chatTurnsToItems, clampLines, claudePayload, codexChangedPaths, codexEventToItems, codexMcpToolName, codexSubagentThreads, collapseToolRuns, deliveredUnechoedSends, deriveEnvironmentState, emptySessionTranscriptSnapshot, entryBody, entrySeconds, environmentOutputLine, environmentOutputLines, environmentOutputStep, environmentPhaseLabel, environmentSummary, eventToItems, foldCosts, foldGutter, foldRun, formatDuration, groupRecordsToChatTurns, gutterFor, hookPhrase, humanDuration, isCodexSubagentRecord, isConnectVisibleRecord, isConversationOver, isFoldable, isToolActivity, isToolFold, isWorkFold, lastLines, layOutItems, lifecycleText, messageEndedText, oneLine, pendingToolCalls, reasoningSummaryTitle, recordSlice, recordToItems, resultCostUsd, seedTranscriptStore, sessionLogText, splitLedger, startupHeadline, startupSettled, statusActivityText, summarizeToolInput, tailLines, toolActivities, toolResultText, toolRunMembers };