@synsci/sdk 2.0.65 → 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
|
*/
|
package/dist/src/v2/runtime.d.ts
CHANGED
|
@@ -15,7 +15,11 @@ export type OpenScienceRuntimeConfig = OpenScienceClientConfig & {
|
|
|
15
15
|
directory?: string;
|
|
16
16
|
projectID?: string;
|
|
17
17
|
project?: string;
|
|
18
|
-
/**
|
|
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
|
/**
|
package/dist/src/v2/runtime.js
CHANGED
|
@@ -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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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({
|