@parcha/agentrun-jev 0.1.0-beta.17 → 0.1.0-beta.18
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/README.md +1 -1
- package/dist/index.js +27 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Optional [TypeSafe Jev](https://docs.typesafe.ai/) support for AgentRun DSL. Jev answers focused questions with typed values and probability distributions. The workflow decides how to use them.
|
|
4
4
|
|
|
5
|
-
Beta
|
|
5
|
+
Beta, on npm under the `beta` dist-tag (`npm view @parcha/agentrun-jev dist-tags`). Requires Node.js 22.19 or later.
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
8
|
npm install @parcha/agentrun-dsl@beta @parcha/agentrun-jev@beta
|
package/dist/index.js
CHANGED
|
@@ -82,6 +82,16 @@ function wait(ms, signal, error) {
|
|
|
82
82
|
abort();
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
|
+
/** A server's Retry-After in milliseconds from now, given as delta-seconds or an HTTP date; undefined when absent or unparseable. */
|
|
86
|
+
function retryAfterMs(headers) {
|
|
87
|
+
const value = headers instanceof Headers ? headers.get("retry-after")?.trim() : undefined;
|
|
88
|
+
if (!value)
|
|
89
|
+
return undefined;
|
|
90
|
+
if (/^\d+$/.test(value))
|
|
91
|
+
return Number(value) * 1000;
|
|
92
|
+
const date = Date.parse(value);
|
|
93
|
+
return Number.isNaN(date) ? undefined : Math.max(0, date - Date.now());
|
|
94
|
+
}
|
|
85
95
|
export function createJevRunner(options = {}) {
|
|
86
96
|
const timeoutMs = options.timeoutMs === null ? null : (options.timeoutMs ?? 30_000);
|
|
87
97
|
const maxStateBytes = options.maxStateBytes ?? null;
|
|
@@ -200,6 +210,8 @@ export function createJevRunner(options = {}) {
|
|
|
200
210
|
body = JSON.stringify({ ...JSON.parse(body), assets: assetDigests });
|
|
201
211
|
}
|
|
202
212
|
const headers = carriesImage || hasBox ? { [IMAGE_HEADER]: "true" } : undefined;
|
|
213
|
+
// The first attempt that failed in a way the server may have billed (a lost answer, a 408, a 5xx). A later 429 does not make the call free: the give-up reports this one.
|
|
214
|
+
let billable;
|
|
203
215
|
for (attempt = 1;; attempt++) {
|
|
204
216
|
if (signal.aborted)
|
|
205
217
|
throw abortError();
|
|
@@ -214,10 +226,23 @@ export function createJevRunner(options = {}) {
|
|
|
214
226
|
throw abortError();
|
|
215
227
|
const status = error instanceof APIError ? error.status : undefined;
|
|
216
228
|
const retryable = status === 408 || status === 429 || (status !== undefined && status >= 500 && status <= 599) || error instanceof APIConnectionError;
|
|
229
|
+
if (retryable && status !== 429 && billable === undefined)
|
|
230
|
+
billable = status === undefined ? {} : { status };
|
|
217
231
|
if (retryable && attempt < maxAttempts) {
|
|
218
|
-
|
|
219
|
-
|
|
232
|
+
const backoff = Math.min(retryMaxMs, retryBaseMs * 2 ** (attempt - 1));
|
|
233
|
+
const asked = error instanceof APIError && (status === 429 || status === 503) ? retryAfterMs(error.headers) : undefined;
|
|
234
|
+
const delay = asked === undefined ? backoff : Math.max(asked, backoff);
|
|
235
|
+
// A server's wait is kept in full or the loop gives up now: it never runs past the deadline, or past the longest timer when there is none, so no
|
|
236
|
+
// retry is sent with no time left to answer (a request that times out has a cost no one knows).
|
|
237
|
+
const left = timeoutMs === null ? 2_147_483_647 : timeoutMs - (Date.now() - started);
|
|
238
|
+
if (asked === undefined || delay < left) {
|
|
239
|
+
await wait(delay, signal, abortError);
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
220
242
|
}
|
|
243
|
+
// HTTP 429 means every attempt was refused unanswered; after one that may have been billed, the give-up names that one instead.
|
|
244
|
+
if (status === 429 && billable)
|
|
245
|
+
throw billable.status === undefined ? new JevError("connection", "Jev transport failed.", attempt) : new JevError("http", `Jev returned HTTP ${billable.status}.`, attempt, billable.status);
|
|
221
246
|
if (status !== undefined) {
|
|
222
247
|
const safeStatus = Number.isInteger(status) && status >= 100 && status <= 599 ? status : undefined;
|
|
223
248
|
const capacity = error instanceof APIError && record(error.body) && record(error.body.detail)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parcha/agentrun-jev",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.18",
|
|
4
4
|
"description": "Optional Jev system one decisions for AgentRun workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"test": "node --test test/*.test.mjs"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@parcha/agentrun-dsl": "0.1.0-beta.
|
|
30
|
+
"@parcha/agentrun-dsl": "0.1.0-beta.18",
|
|
31
31
|
"@typesafe-ai/sdk": "0.7.0"
|
|
32
32
|
},
|
|
33
33
|
"repository": {
|