@synsci/sdk 2.0.66 → 2.0.67-test.33756594889

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.
@@ -1135,27 +1135,6 @@ export type Config = {
1135
1135
  url?: string;
1136
1136
  };
1137
1137
  experimental?: {
1138
- hook?: {
1139
- file_edited?: {
1140
- [key: string]: Array<{
1141
- command: Array<string>;
1142
- environment?: {
1143
- [key: string]: string;
1144
- };
1145
- }>;
1146
- };
1147
- session_completed?: Array<{
1148
- command: Array<string>;
1149
- environment?: {
1150
- [key: string]: string;
1151
- };
1152
- }>;
1153
- };
1154
- /**
1155
- * Number of retries for chat completions on failure
1156
- */
1157
- chatMaxRetries?: number;
1158
- disable_paste_summary?: boolean;
1159
1138
  /**
1160
1139
  * Enable the batch tool
1161
1140
  */
@@ -213,10 +213,11 @@ export type UserMessage = {
213
213
  epoch: string;
214
214
  } | {
215
215
  type: "continuation";
216
- kind: "output" | "contract" | "review" | "review-summary" | "compaction" | "task";
216
+ kind: "output" | "contract" | "review" | "review-summary" | "compaction" | "task" | "context";
217
217
  text: string;
218
218
  epoch: string;
219
219
  transaction: string;
220
+ routing?: string;
220
221
  progress?: string;
221
222
  repair?: boolean;
222
223
  } | {
@@ -227,6 +228,10 @@ export type UserMessage = {
227
228
  focus?: string;
228
229
  handoffFile?: string;
229
230
  trigger?: "proactive" | "overflow" | "manual";
231
+ recovery?: {
232
+ type: "preflight";
233
+ continuationID: string;
234
+ };
230
235
  before?: number;
231
236
  headTokens?: number;
232
237
  continuationID?: string;
@@ -256,6 +261,12 @@ export type ProviderAuthError = {
256
261
  message: string;
257
262
  };
258
263
  };
264
+ export type MessageContextWindowError = {
265
+ name: "MessageContextWindowError";
266
+ data: {
267
+ message: string;
268
+ };
269
+ };
259
270
  export type UnknownError = {
260
271
  name: "UnknownError";
261
272
  data: {
@@ -297,7 +308,7 @@ export type AssistantMessage = {
297
308
  created: number;
298
309
  completed?: number;
299
310
  };
300
- error?: ProviderAuthError | UnknownError | MessageOutputLengthError | MessageAbortedError | ApiError;
311
+ error?: ProviderAuthError | MessageContextWindowError | UnknownError | MessageOutputLengthError | MessageAbortedError | ApiError;
301
312
  parentID: string;
302
313
  modelID: string;
303
314
  providerID: string;
@@ -865,7 +876,7 @@ export type EventSessionError = {
865
876
  type: "session.error";
866
877
  properties: {
867
878
  sessionID?: string;
868
- error?: ProviderAuthError | UnknownError | MessageOutputLengthError | MessageAbortedError | ApiError;
879
+ error?: ProviderAuthError | MessageContextWindowError | UnknownError | MessageOutputLengthError | MessageAbortedError | ApiError;
869
880
  };
870
881
  };
871
882
  export type EventSkillUpdated = {
@@ -1846,27 +1857,6 @@ export type Config = {
1846
1857
  tailTokens?: number;
1847
1858
  };
1848
1859
  experimental?: {
1849
- hook?: {
1850
- file_edited?: {
1851
- [key: string]: Array<{
1852
- command: Array<string>;
1853
- environment?: {
1854
- [key: string]: string;
1855
- };
1856
- }>;
1857
- };
1858
- session_completed?: Array<{
1859
- command: Array<string>;
1860
- environment?: {
1861
- [key: string]: string;
1862
- };
1863
- }>;
1864
- };
1865
- /**
1866
- * Number of retries for chat completions on failure
1867
- */
1868
- chatMaxRetries?: number;
1869
- disable_paste_summary?: boolean;
1870
1860
  /**
1871
1861
  * Enable the batch tool
1872
1862
  */
@@ -15,7 +15,11 @@ export type OpenScienceRuntimeConfig = OpenScienceClientConfig & {
15
15
  directory?: string;
16
16
  projectID?: string;
17
17
  project?: string;
18
- /** Delay before reconnecting an event stream that ended without an error. */
18
+ /**
19
+ * Base delay before reconnecting an event stream. It doubles (capped at
20
+ * 30 s) while connections fail or close without delivering any event, and
21
+ * resets once events arrive.
22
+ */
19
23
  runtimeReconnectDelayMs?: number;
20
24
  };
21
25
  /**
@@ -62,6 +62,7 @@ export class OpenScienceRuntime {
62
62
  let failures = 0;
63
63
  while (!signal?.aborted) {
64
64
  let connectionError;
65
+ let delivered = false;
65
66
  const result = await this.#client.runtime.subscribe(parameters, {
66
67
  signal,
67
68
  throwOnError: true,
@@ -76,6 +77,7 @@ export class OpenScienceRuntime {
76
77
  for await (const event of result.stream) {
77
78
  lastSequence = event.sequence;
78
79
  failures = 0;
80
+ delivered = true;
79
81
  yield event;
80
82
  }
81
83
  if (signal?.aborted)
@@ -86,11 +88,13 @@ export class OpenScienceRuntime {
86
88
  throw new RuntimeEventCursorError(connectionError.message);
87
89
  if (status !== undefined && status >= 400 && status < 500)
88
90
  throw connectionError;
89
- failures += 1;
90
91
  }
91
- const delay = connectionError
92
- ? Math.min(this.#reconnectDelay * 2 ** Math.max(0, failures - 1), 30_000)
93
- : this.#reconnectDelay;
92
+ // A clean close that delivered nothing looks exactly like a server that
93
+ // keeps dropping the stream, so it backs off like an error instead of
94
+ // reconnecting at the base delay forever.
95
+ if (connectionError || !delivered)
96
+ failures += 1;
97
+ const delay = Math.min(this.#reconnectDelay * 2 ** Math.max(0, failures - 1), 30_000);
94
98
  await waitForReconnect(delay, signal);
95
99
  }
96
100
  }
@@ -114,6 +114,41 @@ describe("OpenScienceRuntime", () => {
114
114
  assert.equal(requests[0]?.headers.get("Last-Event-ID"), "0");
115
115
  assert.equal(requests[1]?.headers.get("Last-Event-ID"), "1");
116
116
  });
117
+ test("backs off after empty clean closes and resets once events arrive", async () => {
118
+ const times = [];
119
+ const controller = new AbortController();
120
+ const event = {
121
+ sequence: 1,
122
+ sessionID: "ses_empty",
123
+ runID: "run_empty",
124
+ type: "runtime.accepted",
125
+ properties: { effort: "normal" },
126
+ time: 1,
127
+ };
128
+ const runtime = createOpenScienceRuntime({
129
+ baseUrl: "http://runtime.test",
130
+ runtimeReconnectDelayMs: 20,
131
+ fetch: async () => {
132
+ times.push(Date.now());
133
+ if (times.length === 6)
134
+ controller.abort();
135
+ const body = times.length === 5 ? `id: 1\nevent: runtime.accepted\ndata: ${JSON.stringify(event)}\n\n` : "";
136
+ return new Response(body, { headers: { "content-type": "text/event-stream" } });
137
+ },
138
+ });
139
+ const received = [];
140
+ for await (const item of runtime.events({ sessionID: "ses_empty", signal: controller.signal })) {
141
+ received.push(item);
142
+ }
143
+ assert.equal(received.length, 1);
144
+ assert.equal(times.length, 6);
145
+ const gaps = times.slice(1).map((time, index) => time - (times[index] ?? time));
146
+ // Four empty closes wait 20, 40, 80, and 160 ms; the delivered event on
147
+ // the fifth connection resets the next wait to the 20 ms base.
148
+ assert.ok((gaps[3] ?? 0) >= 150, `fourth reconnect waited ${gaps[3]}ms`);
149
+ assert.ok((gaps[0] ?? 0) + (gaps[1] ?? 0) + (gaps[2] ?? 0) + (gaps[3] ?? 0) >= 280, `empty closes waited ${gaps}`);
150
+ assert.ok((gaps[4] ?? 0) < 200, `reconnect after a delivered event waited ${gaps[4]}ms`);
151
+ });
117
152
  test("surfaces a retained-window conflict without retrying forever", async () => {
118
153
  let calls = 0;
119
154
  const runtime = createOpenScienceRuntime({
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@synsci/sdk",
4
- "version": "2.0.66",
4
+ "version": "2.0.67-test.33756594889",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "scripts": {