@ellipsis-dev/sdk 0.15.1 → 0.17.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.
@@ -0,0 +1,208 @@
1
+ // src/stream/index.ts
2
+ var SESSION_STREAM_PROTOCOL_VERSION = 3;
3
+ var WS_CLOSE_NORMAL = 1e3;
4
+ var WS_CLOSE_GOING_AWAY = 1001;
5
+ var WS_CLOSE_UNSUPPORTED_PROTOCOL_VERSION = 1002;
6
+ var WS_CLOSE_NO_PROTOCOL = 1003;
7
+ var WS_CLOSE_AUTH_FAILED = 1008;
8
+ var WS_CLOSE_SERVER_ERROR = 1011;
9
+ var WS_CLOSE_OVER_CAPACITY = 1013;
10
+ function sessionStatusWord(session) {
11
+ return session.surface?.status ?? session.status;
12
+ }
13
+ var StreamUnavailableError = class extends Error {
14
+ constructor(message) {
15
+ super(message);
16
+ this.name = "StreamUnavailableError";
17
+ }
18
+ };
19
+ var StreamAuthError = class extends Error {
20
+ constructor(message) {
21
+ super(message);
22
+ this.name = "StreamAuthError";
23
+ }
24
+ };
25
+ function streamQuery(afterSeq) {
26
+ const base = `protocol=${SESSION_STREAM_PROTOCOL_VERSION}`;
27
+ return afterSeq > 0 ? `${base}&after_seq=${afterSeq}` : base;
28
+ }
29
+ var HEARTBEAT_TIMEOUT_MS = 45e3;
30
+ var DEFAULT_MAX_RECONNECTS = 5;
31
+ function classifyCloseCode(code) {
32
+ switch (code) {
33
+ case WS_CLOSE_NORMAL:
34
+ return "normal";
35
+ case WS_CLOSE_AUTH_FAILED:
36
+ case 4401:
37
+ // dashboard ticket door: bad/expired ticket
38
+ case 4403:
39
+ return "auth";
40
+ case WS_CLOSE_UNSUPPORTED_PROTOCOL_VERSION:
41
+ case WS_CLOSE_NO_PROTOCOL:
42
+ return "unsupported";
43
+ default:
44
+ return "retry";
45
+ }
46
+ }
47
+ function nextReconnectDelayMs(attempt) {
48
+ const base = 500;
49
+ const max = 8e3;
50
+ return Math.min(max, base * 2 ** Math.max(0, attempt - 1));
51
+ }
52
+ function decideReconnect(params) {
53
+ const { closeKind, everReceivedFrame, attempt, maxReconnects } = params;
54
+ if (closeKind === "auth") return { action: "fail-auth" };
55
+ if (closeKind === "unsupported") return { action: "fallback" };
56
+ const cap = everReceivedFrame ? maxReconnects : Math.min(2, maxReconnects);
57
+ if (attempt >= cap) return { action: "fallback" };
58
+ return { action: "reconnect", delayMs: nextReconnectDelayMs(attempt) };
59
+ }
60
+ function connectOnce(sock, emit, signal) {
61
+ return new Promise((resolve) => {
62
+ let settled = false;
63
+ let heartbeat;
64
+ const finish = (result) => {
65
+ if (settled) return;
66
+ settled = true;
67
+ if (heartbeat) clearTimeout(heartbeat);
68
+ if (signal) signal.removeEventListener("abort", onAbort);
69
+ sock.close();
70
+ resolve(result);
71
+ };
72
+ const onAbort = () => finish({ kind: "aborted" });
73
+ const bumpHeartbeat = () => {
74
+ if (heartbeat) clearTimeout(heartbeat);
75
+ heartbeat = setTimeout(
76
+ () => finish({ kind: "error", err: new Error("heartbeat timeout") }),
77
+ HEARTBEAT_TIMEOUT_MS
78
+ );
79
+ };
80
+ if (signal) {
81
+ if (signal.aborted) {
82
+ finish({ kind: "aborted" });
83
+ return;
84
+ }
85
+ signal.addEventListener("abort", onAbort);
86
+ }
87
+ sock.onOpen(() => bumpHeartbeat());
88
+ sock.onMessage((data) => {
89
+ bumpHeartbeat();
90
+ let frame;
91
+ try {
92
+ frame = JSON.parse(data);
93
+ } catch {
94
+ return;
95
+ }
96
+ emit(frame);
97
+ if (frame.type === "done") {
98
+ finish({ kind: "done" });
99
+ } else if (frame.type === "error") {
100
+ finish({
101
+ kind: "frameError",
102
+ message: frame.message ?? "stream error"
103
+ });
104
+ }
105
+ });
106
+ sock.onClose((code) => finish({ kind: "closed", code }));
107
+ sock.onError((err) => finish({ kind: "error", err }));
108
+ });
109
+ }
110
+ function sleep(ms, signal) {
111
+ return new Promise((resolve) => {
112
+ const timer = setTimeout(resolve, ms);
113
+ signal?.addEventListener(
114
+ "abort",
115
+ () => {
116
+ clearTimeout(timer);
117
+ resolve();
118
+ },
119
+ { once: true }
120
+ );
121
+ });
122
+ }
123
+ async function streamSession(opts) {
124
+ const maxReconnects = opts.maxReconnects ?? DEFAULT_MAX_RECONNECTS;
125
+ let afterSeq = opts.afterSeq ?? 0;
126
+ let everReceivedFrame = false;
127
+ let attempt = 0;
128
+ let lastStatusWord = "";
129
+ let lastExitStatus = null;
130
+ const emit = (frame) => {
131
+ everReceivedFrame = true;
132
+ attempt = 0;
133
+ if (frame.type === "records_append") {
134
+ const records = frame.records;
135
+ for (const record of records) {
136
+ if (typeof record.feed_seq === "number") {
137
+ afterSeq = Math.max(afterSeq, record.feed_seq);
138
+ }
139
+ }
140
+ } else if (frame.type === "snapshot" || frame.type === "session") {
141
+ const session = frame.session;
142
+ lastStatusWord = sessionStatusWord(session);
143
+ lastExitStatus = session.exit_status ?? null;
144
+ }
145
+ opts.onFrame(frame);
146
+ };
147
+ for (; ; ) {
148
+ if (opts.signal?.aborted) return { type: "aborted" };
149
+ let res;
150
+ try {
151
+ const sock = await opts.openSocket({
152
+ sessionId: opts.sessionId,
153
+ afterSeq,
154
+ query: streamQuery(afterSeq)
155
+ });
156
+ res = await connectOnce(sock, emit, opts.signal);
157
+ } catch (err) {
158
+ res = {
159
+ kind: "error",
160
+ err: err instanceof Error ? err : new Error(String(err))
161
+ };
162
+ }
163
+ if (res.kind === "done") {
164
+ return {
165
+ type: "done",
166
+ status: lastStatusWord,
167
+ exitStatus: lastExitStatus
168
+ };
169
+ }
170
+ if (res.kind === "frameError")
171
+ return { type: "error", message: res.message };
172
+ if (res.kind === "aborted") return { type: "aborted" };
173
+ attempt++;
174
+ const decision = decideReconnect({
175
+ closeKind: res.kind === "closed" ? classifyCloseCode(res.code) : void 0,
176
+ everReceivedFrame,
177
+ attempt,
178
+ maxReconnects
179
+ });
180
+ if (decision.action === "fail-auth") {
181
+ throw new StreamAuthError("not authorized to stream this session");
182
+ }
183
+ if (decision.action === "fallback") {
184
+ const why = res.kind === "error" ? res.err.message : `stream closed (code ${res.code})`;
185
+ throw new StreamUnavailableError(why);
186
+ }
187
+ await sleep(decision.delayMs ?? 0, opts.signal);
188
+ }
189
+ }
190
+
191
+ export {
192
+ SESSION_STREAM_PROTOCOL_VERSION,
193
+ WS_CLOSE_NORMAL,
194
+ WS_CLOSE_GOING_AWAY,
195
+ WS_CLOSE_UNSUPPORTED_PROTOCOL_VERSION,
196
+ WS_CLOSE_NO_PROTOCOL,
197
+ WS_CLOSE_AUTH_FAILED,
198
+ WS_CLOSE_SERVER_ERROR,
199
+ WS_CLOSE_OVER_CAPACITY,
200
+ sessionStatusWord,
201
+ StreamUnavailableError,
202
+ StreamAuthError,
203
+ streamQuery,
204
+ classifyCloseCode,
205
+ nextReconnectDelayMs,
206
+ decideReconnect,
207
+ streamSession
208
+ };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { c as components } from './types-D9g-eZui.js';
2
- export { A as AgentConfigSource, a as AttributionType, B as BudgetSource, C as ClaudeSessionRecord, b as CodexEvent, d as CodexItem, e as CodexSessionRecord, f as CreateReviewRequest, D as DeltaFrame, g as DoneFrame, E as ErrorFrame, F as Finding, G as GithubAccountSnippet, h as GithubAccountType, H as Harness, i as HeartbeatFrame, L as LifecycleSessionRecord, P as ParentKind, j as PromptBlockedReason, R as RecordsAppendFrame, k as ResolvedReviewScope, l as Review, m as ReviewConfiguration, n as ReviewCounters, o as ReviewFinding, p as ReviewRequester, q as ReviewScope, r as ReviewScopeKind, s as ReviewStage, t as ReviewedCommit, u as ReviewsListResponse, S as SdkAssistantRecord, v as SdkContentBlock, w as SdkRateLimitRecord, x as SdkRecord, y as SdkResultRecord, z as SdkSystemRecord, I as SdkUserRecord, J as SendSessionMessageRequest, K as Session, M as SessionExecution, N as SessionExecutionsListResponse, O as SessionExitStatus, Q as SessionFrame, T as SessionLiveness, U as SessionMessage, V as SessionMessageResponse, W as SessionMessageStatus, X as SessionPr, Y as SessionPrompting, Z as SessionRecord, _ as SessionRecordsListResponse, $ as SessionResponse, a0 as SessionSource, a1 as SessionState, a2 as SessionStatus, a3 as SessionStreamFrame, a4 as SessionSurface, a5 as SessionsListResponse, a6 as SnapshotFrame, a7 as StreamFrame, a8 as TokensInfo, a9 as paths } from './types-D9g-eZui.js';
1
+ import { c as components } from './types--VF0yCc1.js';
2
+ export { A as AgentConfigSource, a as AttributionType, B as BudgetSource, C as ClaudeSessionRecord, b as CodexEvent, d as CodexItem, e as CodexSessionRecord, f as CreateReviewRequest, D as DeltaFrame, g as DoneFrame, E as ErrorFrame, F as Finding, G as GithubAccountSnippet, h as GithubAccountType, H as Harness, i as HeartbeatFrame, L as LifecycleSessionRecord, P as ParentKind, j as PromptBlockedReason, R as RecordsAppendFrame, k as ResolvedReviewScope, l as Review, m as ReviewConfiguration, n as ReviewCounters, o as ReviewFinding, p as ReviewRequester, q as ReviewScope, r as ReviewScopeKind, s as ReviewStage, t as ReviewedCommit, u as ReviewsListResponse, S as SdkAssistantRecord, v as SdkContentBlock, w as SdkRateLimitRecord, x as SdkRecord, y as SdkResultRecord, z as SdkSystemRecord, I as SdkUserRecord, J as SendSessionMessageRequest, K as Session, M as SessionExecution, N as SessionExecutionsListResponse, O as SessionExitStatus, Q as SessionFrame, T as SessionGit, U as SessionLiveness, V as SessionMessage, W as SessionMessageResponse, X as SessionMessageStatus, Y as SessionPrompting, Z as SessionRecord, _ as SessionRecordsListResponse, $ as SessionResponse, a0 as SessionSource, a1 as SessionState, a2 as SessionStatus, a3 as SessionStreamFrame, a4 as SessionSurface, a5 as SessionsListResponse, a6 as SnapshotFrame, a7 as StreamFrame, a8 as TokensInfo, a9 as paths } from './types--VF0yCc1.js';
3
3
 
4
4
  interface CursorResponse {
5
5
  has_more: boolean;
@@ -75,23 +75,15 @@ declare class EllipsisAgentsConfigs {
75
75
  /**
76
76
  * Create Agent Config
77
77
  *
78
- * Create an agent config.
78
+ * Create an agent config, managed through the API: no file, live
79
+ * immediately. To put its definition in a repository instead, create
80
+ * it here and then POST /v1/agents/configs/{config_id}/link.
79
81
  *
80
- * Name a repository and Ellipsis opens a pull request adding the
81
- * config file to agents/ there; the agent goes live when it
82
- * merges. Omit it and the agent is created here, with no file,
83
- * live immediately — and every file reference in it must name the
84
- * repository it lives in.
85
- *
86
- * Accepts an inline config or a gallery template slug. 409 when
87
- * another live agent already holds the name.
82
+ * 409 when another live agent already holds the name.
88
83
  */
89
- create(options?: {
90
- config?: S['AgentConfig'] | null;
91
- path?: string | null;
92
- repository?: string | null;
93
- template_id?: string | null;
94
- }): Promise<S['CreateAgentConfigResponse']>;
84
+ create(options: {
85
+ config: S['AgentConfig'];
86
+ }): Promise<S['AgentConfigResponse']>;
95
87
  /**
96
88
  * Delete Agent Config
97
89
  *
@@ -350,6 +342,97 @@ declare class EllipsisAuth {
350
342
  readonly cli: EllipsisAuthCli;
351
343
  constructor(transport: Transport);
352
344
  }
345
+ declare class EllipsisEnvironmentsDefaults {
346
+ private readonly transport;
347
+ constructor(transport: Transport);
348
+ /**
349
+ * Delete Environment Default
350
+ *
351
+ * Clear a default environment.
352
+ *
353
+ * Addressed by rung: the account rung (repository omitted) or a
354
+ * repository rung. Refused for sandbox tokens.
355
+ */
356
+ delete(options?: {
357
+ repository?: string | null;
358
+ }): Promise<void>;
359
+ /**
360
+ * List Environment Defaults
361
+ *
362
+ * Get the default environments.
363
+ *
364
+ * The account-wide default and the per-repository defaults, as
365
+ * environment ids. Repo rungs are keyed "owner/name".
366
+ */
367
+ list(): Promise<S['EnvironmentDefaults']>;
368
+ /**
369
+ * Put Environment Default
370
+ *
371
+ * Set a default environment.
372
+ *
373
+ * Addressed by rung: the account rung (repository omitted) or a
374
+ * repository rung ("owner/name"); the environment by id or name.
375
+ * Returns the full resulting ladder. Refused for sandbox tokens.
376
+ */
377
+ set(options: {
378
+ environment: string;
379
+ repository?: string | null;
380
+ }): Promise<S['EnvironmentDefaults']>;
381
+ }
382
+ declare class EllipsisEnvironments {
383
+ private readonly transport;
384
+ readonly defaults: EllipsisEnvironmentsDefaults;
385
+ constructor(transport: Transport);
386
+ /**
387
+ * Create Environment
388
+ *
389
+ * Create an environment, managed through the API: no file, live
390
+ * immediately. To define it in a repository instead, commit a
391
+ * `kind: environment` YAML under an agents directory.
392
+ *
393
+ * 409 when another live environment already holds the name.
394
+ */
395
+ create(options: {
396
+ environment: S['EnvironmentConfig'];
397
+ }): Promise<S['EnvironmentResponse']>;
398
+ /**
399
+ * Delete Environment
400
+ *
401
+ * Delete an environment, by id or by name.
402
+ *
403
+ * Always succeeds, even while agents still reference it — their next
404
+ * session start fails with a clear error naming the missing
405
+ * environment. Past sessions remain readable. Only for environments
406
+ * managed through this API — delete the file to remove one defined
407
+ * by a repository.
408
+ */
409
+ delete(environment_id: string): Promise<void>;
410
+ /**
411
+ * Get Environment
412
+ *
413
+ * Return one saved environment, by id or by name.
414
+ */
415
+ get(environment_id: string): Promise<S['EnvironmentResponse']>;
416
+ /**
417
+ * List Environments
418
+ *
419
+ * List saved environments.
420
+ */
421
+ list(): Promise<S['EnvironmentsListResponse']>;
422
+ /**
423
+ * Update Environment
424
+ *
425
+ * Replace an environment's definition, by id or by name.
426
+ *
427
+ * The whole definition is replaced, live at once — future sessions
428
+ * resolve the new body; running sessions keep the one frozen at
429
+ * their start. Only for environments managed through this API: one
430
+ * defined by a repository file is a 409.
431
+ */
432
+ update(environment_id: string, options: {
433
+ environment: S['EnvironmentConfig'];
434
+ }): Promise<S['EnvironmentResponse']>;
435
+ }
353
436
  declare class EllipsisFiles {
354
437
  private readonly transport;
355
438
  constructor(transport: Transport);
@@ -790,8 +873,7 @@ declare class EllipsisSessions {
790
873
  */
791
874
  replay(session_id: string, options?: {
792
875
  config_id?: string | null;
793
- config_override?: Record<string, unknown> | null;
794
- config_override_yaml?: string | null;
876
+ override?: Record<string, unknown> | null;
795
877
  prompt?: string | null;
796
878
  }): Promise<S['SessionResponse']>;
797
879
  /**
@@ -839,25 +921,25 @@ declare class EllipsisSessions {
839
921
  *
840
922
  * Start a cloud agent session.
841
923
  *
842
- * Provide at most one of config_id (an id or an agent name),
843
- * config, or
844
- * template_id; with none, the account's default-config ladder
845
- * resolves the config. 400 when idle_start is combined with
846
- * prompt or input. 422 when the agent declares an
847
- * input schema and the request's input is absent or invalid.
924
+ * Provide at most one of config_id (an id or an agent name) or
925
+ * config; with neither, the account's default-config ladder
926
+ * resolves the config. `prompt` is the first message; omit it and
927
+ * the session starts idle, waiting for one. 400 when
928
+ * interactive=false and there is no prompt or input. 422 when the
929
+ * agent declares an input schema and the request's input is absent
930
+ * or invalid.
848
931
  */
849
932
  start(options?: {
850
933
  config?: S['AgentConfig'] | null;
851
934
  config_id?: string | null;
852
- config_override?: Record<string, unknown> | null;
853
- config_override_yaml?: string | null;
935
+ environment?: string | null;
854
936
  force_rebuild?: boolean;
855
- idle_start?: boolean;
856
937
  input?: Record<string, unknown> | null;
938
+ interactive?: boolean;
857
939
  metadata?: Record<string, string>;
940
+ override?: Record<string, unknown> | null;
858
941
  prompt?: string | null;
859
942
  repository?: string | null;
860
- template_id?: string | null;
861
943
  }): Promise<S['SessionResponse']>;
862
944
  /**
863
945
  * Stop Agent Session
@@ -879,6 +961,7 @@ declare class Ellipsis {
879
961
  readonly alerts: EllipsisAlerts;
880
962
  readonly analytics: EllipsisAnalytics;
881
963
  readonly auth: EllipsisAuth;
964
+ readonly environments: EllipsisEnvironments;
882
965
  readonly files: EllipsisFiles;
883
966
  readonly integrations: EllipsisIntegrations;
884
967
  readonly memories: EllipsisMemories;
package/dist/index.js CHANGED
@@ -249,20 +249,15 @@ var EllipsisAgentsConfigs = class {
249
249
  /**
250
250
  * Create Agent Config
251
251
  *
252
- * Create an agent config.
252
+ * Create an agent config, managed through the API: no file, live
253
+ * immediately. To put its definition in a repository instead, create
254
+ * it here and then POST /v1/agents/configs/{config_id}/link.
253
255
  *
254
- * Name a repository and Ellipsis opens a pull request adding the
255
- * config file to agents/ there; the agent goes live when it
256
- * merges. Omit it and the agent is created here, with no file,
257
- * live immediately — and every file reference in it must name the
258
- * repository it lives in.
259
- *
260
- * Accepts an inline config or a gallery template slug. 409 when
261
- * another live agent already holds the name.
256
+ * 409 when another live agent already holds the name.
262
257
  */
263
- async create(options = {}) {
258
+ async create(options) {
264
259
  const path = "/v1/agents/configs";
265
- const body = buildBody({ config: options.config, path: options.path, repository: options.repository, template_id: options.template_id });
260
+ const body = buildBody({ config: options.config });
266
261
  return await this.transport.request("POST", path, { body });
267
262
  }
268
263
  /**
@@ -571,6 +566,121 @@ var EllipsisAuth = class {
571
566
  transport;
572
567
  cli;
573
568
  };
569
+ var EllipsisEnvironmentsDefaults = class {
570
+ constructor(transport) {
571
+ this.transport = transport;
572
+ }
573
+ transport;
574
+ /**
575
+ * Delete Environment Default
576
+ *
577
+ * Clear a default environment.
578
+ *
579
+ * Addressed by rung: the account rung (repository omitted) or a
580
+ * repository rung. Refused for sandbox tokens.
581
+ */
582
+ async delete(options = {}) {
583
+ const path = "/v1/environments/defaults";
584
+ const query = buildQuery({ repository: options.repository });
585
+ await this.transport.request("DELETE", path, { query });
586
+ }
587
+ /**
588
+ * List Environment Defaults
589
+ *
590
+ * Get the default environments.
591
+ *
592
+ * The account-wide default and the per-repository defaults, as
593
+ * environment ids. Repo rungs are keyed "owner/name".
594
+ */
595
+ async list() {
596
+ const path = "/v1/environments/defaults";
597
+ return await this.transport.request("GET", path);
598
+ }
599
+ /**
600
+ * Put Environment Default
601
+ *
602
+ * Set a default environment.
603
+ *
604
+ * Addressed by rung: the account rung (repository omitted) or a
605
+ * repository rung ("owner/name"); the environment by id or name.
606
+ * Returns the full resulting ladder. Refused for sandbox tokens.
607
+ */
608
+ async set(options) {
609
+ const path = "/v1/environments/defaults";
610
+ const body = buildBody({ environment: options.environment, repository: options.repository });
611
+ return await this.transport.request("PUT", path, { body });
612
+ }
613
+ };
614
+ var EllipsisEnvironments = class {
615
+ constructor(transport) {
616
+ this.transport = transport;
617
+ this.defaults = new EllipsisEnvironmentsDefaults(transport);
618
+ }
619
+ transport;
620
+ defaults;
621
+ /**
622
+ * Create Environment
623
+ *
624
+ * Create an environment, managed through the API: no file, live
625
+ * immediately. To define it in a repository instead, commit a
626
+ * `kind: environment` YAML under an agents directory.
627
+ *
628
+ * 409 when another live environment already holds the name.
629
+ */
630
+ async create(options) {
631
+ const path = "/v1/environments";
632
+ const body = buildBody({ environment: options.environment });
633
+ return await this.transport.request("POST", path, { body });
634
+ }
635
+ /**
636
+ * Delete Environment
637
+ *
638
+ * Delete an environment, by id or by name.
639
+ *
640
+ * Always succeeds, even while agents still reference it — their next
641
+ * session start fails with a clear error naming the missing
642
+ * environment. Past sessions remain readable. Only for environments
643
+ * managed through this API — delete the file to remove one defined
644
+ * by a repository.
645
+ */
646
+ async delete(environment_id) {
647
+ const path = `/v1/environments/${enc(environment_id)}`;
648
+ await this.transport.request("DELETE", path);
649
+ }
650
+ /**
651
+ * Get Environment
652
+ *
653
+ * Return one saved environment, by id or by name.
654
+ */
655
+ async get(environment_id) {
656
+ const path = `/v1/environments/${enc(environment_id)}`;
657
+ return await this.transport.request("GET", path);
658
+ }
659
+ /**
660
+ * List Environments
661
+ *
662
+ * List saved environments.
663
+ */
664
+ async list() {
665
+ const path = "/v1/environments";
666
+ return await this.transport.request("GET", path);
667
+ }
668
+ /**
669
+ * Update Environment
670
+ *
671
+ * Replace an environment's definition, by id or by name.
672
+ *
673
+ * The whole definition is replaced, live at once — future sessions
674
+ * resolve the new body; running sessions keep the one frozen at
675
+ * their start. Only for environments managed through this API: one
676
+ * defined by a repository file is a 409.
677
+ */
678
+ async update(environment_id, options) {
679
+ const path = `/v1/environments/${enc(environment_id)}`;
680
+ const body = buildBody({ environment: options.environment });
681
+ return await this.transport.request("PUT", path, { body });
682
+ }
683
+ };
574
684
  var EllipsisFiles = class {
575
685
  constructor(transport) {
576
686
  this.transport = transport;
@@ -1107,7 +1217,7 @@ var EllipsisSessions = class {
1107
1217
  */
1108
1218
  async replay(session_id, options = {}) {
1109
1219
  const path = `/v1/sessions/${enc(session_id)}/replay`;
1110
- const body = buildBody({ config_id: options.config_id, config_override: options.config_override, config_override_yaml: options.config_override_yaml, prompt: options.prompt });
1220
+ const body = buildBody({ config_id: options.config_id, override: options.override, prompt: options.prompt });
1111
1221
  return await this.transport.request("POST", path, { body });
1112
1222
  }
1113
1223
  /**
@@ -1148,16 +1258,17 @@ var EllipsisSessions = class {
1148
1258
  *
1149
1259
  * Start a cloud agent session.
1150
1260
  *
1151
- * Provide at most one of config_id (an id or an agent name),
1152
- * config, or
1153
- * template_id; with none, the account's default-config ladder
1154
- * resolves the config. 400 when idle_start is combined with
1155
- * prompt or input. 422 when the agent declares an
1156
- * input schema and the request's input is absent or invalid.
1261
+ * Provide at most one of config_id (an id or an agent name) or
1262
+ * config; with neither, the account's default-config ladder
1263
+ * resolves the config. `prompt` is the first message; omit it and
1264
+ * the session starts idle, waiting for one. 400 when
1265
+ * interactive=false and there is no prompt or input. 422 when the
1266
+ * agent declares an input schema and the request's input is absent
1267
+ * or invalid.
1157
1268
  */
1158
1269
  async start(options = {}) {
1159
1270
  const path = "/v1/sessions";
1160
- const body = buildBody({ config: options.config, config_id: options.config_id, config_override: options.config_override, config_override_yaml: options.config_override_yaml, force_rebuild: options.force_rebuild, idle_start: options.idle_start, input: options.input, metadata: options.metadata, prompt: options.prompt, repository: options.repository, template_id: options.template_id });
1271
+ const body = buildBody({ config: options.config, config_id: options.config_id, environment: options.environment, force_rebuild: options.force_rebuild, input: options.input, interactive: options.interactive, metadata: options.metadata, override: options.override, prompt: options.prompt, repository: options.repository });
1161
1272
  return await this.transport.request("POST", path, { body });
1162
1273
  }
1163
1274
  /**
@@ -1190,6 +1301,7 @@ var Ellipsis = class {
1190
1301
  alerts;
1191
1302
  analytics;
1192
1303
  auth;
1304
+ environments;
1193
1305
  files;
1194
1306
  integrations;
1195
1307
  memories;
@@ -1203,6 +1315,7 @@ var Ellipsis = class {
1203
1315
  this.alerts = new EllipsisAlerts(this.transport);
1204
1316
  this.analytics = new EllipsisAnalytics(this.transport);
1205
1317
  this.auth = new EllipsisAuth(this.transport);
1318
+ this.environments = new EllipsisEnvironments(this.transport);
1206
1319
  this.files = new EllipsisFiles(this.transport);
1207
1320
  this.integrations = new EllipsisIntegrations(this.transport);
1208
1321
  this.memories = new EllipsisMemories(this.transport);
@@ -1,4 +1,4 @@
1
- import { Z as SessionRecord, aa as CodexFileChangeItem, b as CodexEvent, ab as CodexMcpToolCallItem, x as SdkRecord, K as Session, U as SessionMessage, a7 as StreamFrame } from '../types-D9g-eZui.js';
1
+ import { Z as SessionRecord, aa as CodexFileChangeItem, b as CodexEvent, ab as CodexMcpToolCallItem, x as SdkRecord, K as Session, V as SessionMessage, a7 as StreamFrame } from '../types--VF0yCc1.js';
2
2
 
3
3
  interface ChatToolNode {
4
4
  key: string;
@@ -42,9 +42,46 @@ interface ChatTurn {
42
42
  costUsd: number | null;
43
43
  tokens: number | null;
44
44
  resumed: boolean;
45
+ isError: boolean;
45
46
  }
46
47
  declare function groupRecordsToChatTurns(records: readonly SessionRecord[]): ChatTurn[];
47
48
 
49
+ type RecordSlice = {
50
+ feed_seq: number;
51
+ source: string;
52
+ record_type: string;
53
+ payload: Record<string, unknown>;
54
+ session_message_id?: string | null;
55
+ };
56
+ declare function recordSlice(records: readonly SessionRecord[]): readonly RecordSlice[];
57
+ declare function humanDuration(seconds: number): string;
58
+ declare function sessionLogText(recordType: string, payload: Record<string, unknown>): string | null;
59
+ declare function awaitingAgentPhase(records: readonly RecordSlice[]): 'boot' | 'turn' | null;
60
+ declare function deliveredUnechoedSends(records: readonly RecordSlice[]): {
61
+ id: string;
62
+ body: string;
63
+ cancelled: boolean;
64
+ }[];
65
+ type SandboxLogKind = 'step' | 'output' | 'done' | 'failed';
66
+ type SandboxLogLine = {
67
+ key: string;
68
+ kind: SandboxLogKind;
69
+ text: string;
70
+ };
71
+ type SandboxState = {
72
+ headline: string;
73
+ done: boolean;
74
+ readySeconds: number | null;
75
+ sandboxDone: boolean;
76
+ configName: string | null;
77
+ configCommitSha: string | null;
78
+ log: SandboxLogLine[];
79
+ };
80
+ declare function hookPhrase(step: string): string;
81
+ declare function deriveSandboxState(records: readonly RecordSlice[], minFeedSeq: number): SandboxState | null;
82
+ declare function sandboxSummary(sandbox: SandboxState | null): string;
83
+ declare function lastLines(log: readonly SandboxLogLine[], max: number): SandboxLogLine[];
84
+
48
85
  declare function sandboxOutputStep(payload: Record<string, unknown>): string;
49
86
  declare function sandboxOutputLines(payload: Record<string, unknown>): string[];
50
87
  declare function sandboxOutputLine(payload: Record<string, unknown>): string | null;
@@ -104,6 +141,12 @@ interface SessionTranscriptSnapshot {
104
141
  lastEventAt: number | null;
105
142
  conversationOver: boolean;
106
143
  }
144
+ declare function seedTranscriptStore(store: SessionTranscriptStore, seed: {
145
+ session: Session;
146
+ records: readonly SessionRecord[];
147
+ messages?: readonly SessionMessage[] | null;
148
+ earliestFeedSeq?: number | null;
149
+ }): void;
107
150
  declare function emptySessionTranscriptSnapshot(): SessionTranscriptSnapshot;
108
151
  declare class SessionTranscriptStore {
109
152
  private snapshot;
@@ -122,4 +165,4 @@ declare class SessionTranscriptStore {
122
165
  ingest: (rawFrame: StreamFrame) => void;
123
166
  }
124
167
 
125
- export { type ChatNode, type ChatToolNode, type ChatTurn, type EventToItemsOptions, type ItemKind, type SessionTranscriptSnapshot, SessionTranscriptStore, StreamFrame, type TranscriptItem, cacheTierLabel, clampLines, codexChangedPaths, codexEventToItems, codexMcpToolName, collapseToolRuns, emptySessionTranscriptSnapshot, eventToItems, foldCosts, formatDuration, groupRecordsToChatTurns, isConnectVisibleRecord, isConversationOver, lifecycleText, oneLine, pendingToolCalls, recordToItems, resultCostUsd, sandboxOutputLine, sandboxOutputLines, sandboxOutputStep, sandboxPhaseLabel, statusActivityText, summarizeToolInput, toolResultText };
168
+ export { type ChatNode, type ChatToolNode, type ChatTurn, type EventToItemsOptions, type ItemKind, type RecordSlice, type SandboxLogKind, type SandboxLogLine, type SandboxState, type SessionTranscriptSnapshot, SessionTranscriptStore, StreamFrame, type TranscriptItem, awaitingAgentPhase, cacheTierLabel, clampLines, codexChangedPaths, codexEventToItems, codexMcpToolName, collapseToolRuns, deliveredUnechoedSends, deriveSandboxState, emptySessionTranscriptSnapshot, eventToItems, foldCosts, formatDuration, groupRecordsToChatTurns, hookPhrase, humanDuration, isConnectVisibleRecord, isConversationOver, lastLines, lifecycleText, oneLine, pendingToolCalls, recordSlice, recordToItems, resultCostUsd, sandboxOutputLine, sandboxOutputLines, sandboxOutputStep, sandboxPhaseLabel, sandboxSummary, seedTranscriptStore, sessionLogText, statusActivityText, summarizeToolInput, toolResultText };