teamshift 0.1.2 → 0.1.4
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/cli.js +5 -0
- package/dist/run.js +30 -2
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -151,6 +151,11 @@ async function run(args) {
|
|
|
151
151
|
const serial = outcomes.reduce((sum, outcome) => sum + outcome.elapsedMs, 0);
|
|
152
152
|
console.log(`\n${outcomes.length} run(s) · ${money(total)} total · ${duration(Date.now() - startedAt)} wall clock ` +
|
|
153
153
|
`(${duration(serial)} if run one at a time)`);
|
|
154
|
+
for (const outcome of outcomes) {
|
|
155
|
+
if (!outcome.error)
|
|
156
|
+
continue;
|
|
157
|
+
console.error(`\n${outcome.status} · ${outcome.runId ?? 'not dispatched'}\n${outcome.error}`);
|
|
158
|
+
}
|
|
154
159
|
for (const outcome of outcomes) {
|
|
155
160
|
if (outcome.output === null || outcome.output === undefined)
|
|
156
161
|
continue;
|
package/dist/run.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ApiError } from './api.js';
|
|
1
2
|
import { isTerminal } from './format.js';
|
|
2
3
|
const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
3
4
|
export class RunPollingTimeoutError extends Error {
|
|
@@ -9,6 +10,24 @@ export class RunPollingTimeoutError extends Error {
|
|
|
9
10
|
this.latest = latest;
|
|
10
11
|
}
|
|
11
12
|
}
|
|
13
|
+
const RETRYABLE_RESULT_STATUSES = new Set([404, 409, 502, 503]);
|
|
14
|
+
/** Wait for terminal reconciliation and object-storage visibility to converge. */
|
|
15
|
+
export async function waitForRunResult(client, runId, options = {}) {
|
|
16
|
+
const { intervalMs = 1000, timeoutMs = 30_000, now = Date.now, sleep = defaultSleep } = options;
|
|
17
|
+
const startedAt = now();
|
|
18
|
+
for (;;) {
|
|
19
|
+
try {
|
|
20
|
+
return await client.getRunResult(runId);
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (!(error instanceof ApiError) || !RETRYABLE_RESULT_STATUSES.has(error.status))
|
|
24
|
+
throw error;
|
|
25
|
+
if (now() - startedAt >= timeoutMs)
|
|
26
|
+
throw error;
|
|
27
|
+
await sleep(intervalMs);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
12
31
|
/** Poll one run to a terminal status, or give up at the timeout. */
|
|
13
32
|
export async function waitForRun(client, runId, options = {}) {
|
|
14
33
|
const { intervalMs = 2000, timeoutMs = 900_000, now = Date.now, sleep = defaultSleep } = options;
|
|
@@ -46,17 +65,26 @@ export async function runBatch(client, kind, id, prompts, options = {}) {
|
|
|
46
65
|
let runId = null;
|
|
47
66
|
try {
|
|
48
67
|
runId = await client.startRun(kind, id, prompt);
|
|
49
|
-
|
|
68
|
+
let summary = await waitForRun(client, runId, { ...pollOptions, now });
|
|
50
69
|
let output = null;
|
|
51
70
|
let resultError;
|
|
52
71
|
if (summary.status === 'completed') {
|
|
53
72
|
try {
|
|
54
|
-
const result = await client
|
|
73
|
+
const result = await waitForRunResult(client, runId);
|
|
55
74
|
output = result.text ?? result.document;
|
|
56
75
|
}
|
|
57
76
|
catch (error) {
|
|
58
77
|
resultError = `result unavailable: ${error instanceof Error ? error.message : String(error)}`;
|
|
59
78
|
}
|
|
79
|
+
try {
|
|
80
|
+
// Refresh even when the deliverable read failed: reconciliation may
|
|
81
|
+
// still have replaced the dispatch-time estimate with the real cost.
|
|
82
|
+
summary = await client.getRun(runId);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Keep the terminal summary already obtained; a secondary read must
|
|
86
|
+
// not erase a completed deliverable or its actionable result error.
|
|
87
|
+
}
|
|
60
88
|
}
|
|
61
89
|
else {
|
|
62
90
|
resultError = `run ended with status ${summary.status ?? 'unknown'}`;
|
package/package.json
CHANGED