deepline 0.1.150 → 0.1.151
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/bundling-sources/apps/play-runner-workers/src/entry.ts +157 -140
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/csv-rows.ts +2 -19
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/row-isolation.ts +5 -53
- package/dist/bundling-sources/sdk/src/config.ts +2 -2
- package/dist/bundling-sources/sdk/src/release.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +100 -158
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durability-store.ts +54 -0
- package/dist/bundling-sources/shared_libs/play-runtime/map-row-outcome.ts +167 -0
- package/dist/bundling-sources/shared_libs/play-runtime/pacing.ts +79 -0
- package/dist/bundling-sources/shared_libs/play-runtime/row-isolation.ts +39 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +19 -86
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-row-transition.ts +90 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-session.ts +43 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +142 -11
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +3 -2
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +20 -23
- package/dist/cli/index.js +35 -3
- package/dist/cli/index.mjs +35 -3
- package/dist/index.js +3 -3
- package/dist/index.mjs +3 -3
- package/dist/plays/bundle-play-file.mjs +22 -19
- package/package.json +1 -1
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
import {
|
|
2
|
+
isHardBillingToolHttpError,
|
|
3
|
+
normalizeToolHttpErrorMessage,
|
|
4
|
+
type ToolHttpError,
|
|
5
|
+
} from './tool-http-errors';
|
|
6
|
+
|
|
7
|
+
export const TOOL_EXECUTE_TRANSIENT_HTTP_MAX_ATTEMPTS = 2;
|
|
2
8
|
export const TOOL_EXECUTE_RATE_LIMIT_MAX_ATTEMPTS = 8;
|
|
3
9
|
export const TOOL_EXECUTE_TRANSPORT_MAX_ATTEMPTS = 3;
|
|
4
10
|
export const TOOL_EXECUTE_TRANSPORT_RETRY_DELAY_MS = 1_000;
|
|
11
|
+
export const TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS = 1_000;
|
|
12
|
+
export const TOOL_EXECUTE_RETRY_DELAY_MAX_MS = 5_000;
|
|
5
13
|
|
|
6
14
|
export type ToolExecuteHttpRetryDecision = {
|
|
7
15
|
retryable: boolean;
|
|
@@ -9,15 +17,33 @@ export type ToolExecuteHttpRetryDecision = {
|
|
|
9
17
|
reason:
|
|
10
18
|
| 'rate_limit'
|
|
11
19
|
| 'retry_safe_transient_5xx'
|
|
12
|
-
| 'hard_billing_error'
|
|
13
20
|
| 'unsafe_transient_5xx'
|
|
21
|
+
| 'hard_billing_error'
|
|
14
22
|
| 'non_retryable_status';
|
|
15
23
|
};
|
|
16
24
|
|
|
17
|
-
export
|
|
18
|
-
|
|
25
|
+
export type ToolExecuteHttpFailureOutcome = ToolExecuteHttpRetryDecision & {
|
|
26
|
+
error: ToolHttpError;
|
|
27
|
+
shouldRetry: boolean;
|
|
28
|
+
isRateLimit: boolean;
|
|
29
|
+
fate: 'retry' | 'settle_row_failure' | 'fail_run';
|
|
30
|
+
retryDelayMs: number;
|
|
31
|
+
backpressureDelayMs: number | null;
|
|
32
|
+
chargeRetryBudget: boolean;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type ToolExecuteHttpFailureAttemptTracker = {
|
|
36
|
+
next(input: {
|
|
37
|
+
toolId: string;
|
|
38
|
+
status: number;
|
|
39
|
+
transientHttpRetrySafe?: boolean;
|
|
40
|
+
}): number;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
function decideToolExecuteHttpRetry(input: {
|
|
19
44
|
status: number;
|
|
20
45
|
hardBillingFailure?: boolean;
|
|
46
|
+
transientHttpRetrySafe?: boolean;
|
|
21
47
|
}): ToolExecuteHttpRetryDecision {
|
|
22
48
|
if (input.status === 429) {
|
|
23
49
|
if (input.hardBillingFailure) {
|
|
@@ -34,17 +60,17 @@ export function decideToolExecuteHttpRetry(input: {
|
|
|
34
60
|
};
|
|
35
61
|
}
|
|
36
62
|
if (input.status >= 500 && input.status < 600) {
|
|
37
|
-
if (input.
|
|
63
|
+
if (!input.transientHttpRetrySafe) {
|
|
38
64
|
return {
|
|
39
|
-
retryable:
|
|
40
|
-
attemptCap:
|
|
41
|
-
reason: '
|
|
65
|
+
retryable: false,
|
|
66
|
+
attemptCap: 1,
|
|
67
|
+
reason: 'unsafe_transient_5xx',
|
|
42
68
|
};
|
|
43
69
|
}
|
|
44
70
|
return {
|
|
45
|
-
retryable:
|
|
46
|
-
attemptCap:
|
|
47
|
-
reason: '
|
|
71
|
+
retryable: true,
|
|
72
|
+
attemptCap: TOOL_EXECUTE_TRANSIENT_HTTP_MAX_ATTEMPTS,
|
|
73
|
+
reason: 'retry_safe_transient_5xx',
|
|
48
74
|
};
|
|
49
75
|
}
|
|
50
76
|
return {
|
|
@@ -53,3 +79,108 @@ export function decideToolExecuteHttpRetry(input: {
|
|
|
53
79
|
reason: 'non_retryable_status',
|
|
54
80
|
};
|
|
55
81
|
}
|
|
82
|
+
|
|
83
|
+
export function createToolExecuteHttpFailureAttemptTracker(): ToolExecuteHttpFailureAttemptTracker {
|
|
84
|
+
const attemptsByReason: Record<
|
|
85
|
+
ToolExecuteHttpRetryDecision['reason'],
|
|
86
|
+
number
|
|
87
|
+
> = {
|
|
88
|
+
rate_limit: 0,
|
|
89
|
+
retry_safe_transient_5xx: 0,
|
|
90
|
+
unsafe_transient_5xx: 0,
|
|
91
|
+
hard_billing_error: 0,
|
|
92
|
+
non_retryable_status: 0,
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
next(input) {
|
|
97
|
+
const decision = decideToolExecuteHttpRetry({
|
|
98
|
+
status: input.status,
|
|
99
|
+
transientHttpRetrySafe: input.transientHttpRetrySafe === true,
|
|
100
|
+
});
|
|
101
|
+
attemptsByReason[decision.reason] += 1;
|
|
102
|
+
return attemptsByReason[decision.reason];
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function parseToolExecuteRetryAfterMs(
|
|
108
|
+
header: string | null | undefined,
|
|
109
|
+
nowMs = Date.now(),
|
|
110
|
+
): number {
|
|
111
|
+
if (!header) return TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS;
|
|
112
|
+
const seconds = Number(header);
|
|
113
|
+
if (Number.isFinite(seconds) && seconds > 0) {
|
|
114
|
+
return Math.ceil(seconds * 1000);
|
|
115
|
+
}
|
|
116
|
+
const retryAt = Date.parse(header);
|
|
117
|
+
if (Number.isFinite(retryAt)) {
|
|
118
|
+
return Math.max(1, retryAt - nowMs);
|
|
119
|
+
}
|
|
120
|
+
return TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function classifyToolExecuteHttpFailure(input: {
|
|
124
|
+
toolId: string;
|
|
125
|
+
status: number;
|
|
126
|
+
attempt: number;
|
|
127
|
+
bodyText: string;
|
|
128
|
+
retryAfterHeader?: string | null;
|
|
129
|
+
transientHttpRetrySafe?: boolean;
|
|
130
|
+
nowMs?: number;
|
|
131
|
+
}): ToolExecuteHttpFailureOutcome {
|
|
132
|
+
const transientHttpRetrySafe = input.transientHttpRetrySafe === true;
|
|
133
|
+
const initialRetryDecision = decideToolExecuteHttpRetry({
|
|
134
|
+
status: input.status,
|
|
135
|
+
transientHttpRetrySafe,
|
|
136
|
+
});
|
|
137
|
+
const error = normalizeToolHttpErrorMessage({
|
|
138
|
+
toolId: input.toolId,
|
|
139
|
+
status: input.status,
|
|
140
|
+
attempt: input.attempt,
|
|
141
|
+
maxAttempts: initialRetryDecision.attemptCap,
|
|
142
|
+
bodyText: input.bodyText,
|
|
143
|
+
});
|
|
144
|
+
const retryDecision = decideToolExecuteHttpRetry({
|
|
145
|
+
status: input.status,
|
|
146
|
+
hardBillingFailure: isHardBillingToolHttpError(error),
|
|
147
|
+
transientHttpRetrySafe,
|
|
148
|
+
});
|
|
149
|
+
const shouldRetry =
|
|
150
|
+
retryDecision.retryable && input.attempt < retryDecision.attemptCap;
|
|
151
|
+
const retryAfterMs = parseToolExecuteRetryAfterMs(
|
|
152
|
+
input.retryAfterHeader,
|
|
153
|
+
input.nowMs,
|
|
154
|
+
);
|
|
155
|
+
const retryDelayMs =
|
|
156
|
+
input.status === 429
|
|
157
|
+
? Math.min(
|
|
158
|
+
TOOL_EXECUTE_RETRY_DELAY_MAX_MS,
|
|
159
|
+
Math.max(
|
|
160
|
+
retryAfterMs,
|
|
161
|
+
TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS * input.attempt,
|
|
162
|
+
),
|
|
163
|
+
)
|
|
164
|
+
: retryAfterMs > 0
|
|
165
|
+
? Math.min(TOOL_EXECUTE_RETRY_DELAY_MAX_MS, retryAfterMs)
|
|
166
|
+
: TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS;
|
|
167
|
+
return {
|
|
168
|
+
...retryDecision,
|
|
169
|
+
error,
|
|
170
|
+
shouldRetry,
|
|
171
|
+
isRateLimit: input.status === 429,
|
|
172
|
+
fate: shouldRetry
|
|
173
|
+
? 'retry'
|
|
174
|
+
: retryDecision.reason === 'hard_billing_error'
|
|
175
|
+
? 'fail_run'
|
|
176
|
+
: 'settle_row_failure',
|
|
177
|
+
retryDelayMs,
|
|
178
|
+
backpressureDelayMs:
|
|
179
|
+
input.status === 429
|
|
180
|
+
? retryAfterMs > 0
|
|
181
|
+
? retryAfterMs
|
|
182
|
+
: TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS
|
|
183
|
+
: null,
|
|
184
|
+
chargeRetryBudget: shouldRetry,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
@@ -240,8 +240,9 @@ export function isHardBillingToolHttpError(error: unknown): boolean {
|
|
|
240
240
|
|
|
241
241
|
/**
|
|
242
242
|
* A tool call that ultimately failed with HTTP 429 — provider or
|
|
243
|
-
* Deepline-internal rate-limit pushback
|
|
244
|
-
*
|
|
243
|
+
* Deepline-internal rate-limit pushback. While the local retry budget is
|
|
244
|
+
* active it feeds provider pacing; after exhaustion it becomes a row-scoped
|
|
245
|
+
* Map Row Outcome unless the payload is a hard Deepline billing failure.
|
|
245
246
|
*/
|
|
246
247
|
export function isRateLimitToolHttpError(error: unknown): boolean {
|
|
247
248
|
return error instanceof ToolHttpError && error.status === 429;
|
|
@@ -1513,18 +1513,28 @@ async function computeWorkersHarnessFingerprintWithAdapter(
|
|
|
1513
1513
|
hash: sha256(contents),
|
|
1514
1514
|
});
|
|
1515
1515
|
};
|
|
1516
|
-
const
|
|
1516
|
+
const collectTsFilesRecursive = async (
|
|
1517
1517
|
rootDir: string,
|
|
1518
1518
|
parts: Array<{ name: string; hash: string }>,
|
|
1519
1519
|
) => {
|
|
1520
1520
|
if (!(await fileExists(rootDir))) return;
|
|
1521
|
-
const
|
|
1522
|
-
const
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1521
|
+
const filePaths: string[] = [];
|
|
1522
|
+
const visitDir = async (dir: string) => {
|
|
1523
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
1524
|
+
for (const entry of entries) {
|
|
1525
|
+
const childPath = join(dir, entry.name);
|
|
1526
|
+
if (entry.isDirectory()) {
|
|
1527
|
+
await visitDir(childPath);
|
|
1528
|
+
continue;
|
|
1529
|
+
}
|
|
1530
|
+
if (entry.isFile() && /\.[cm]?ts$/.test(entry.name)) {
|
|
1531
|
+
filePaths.push(childPath);
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
};
|
|
1535
|
+
await visitDir(rootDir);
|
|
1536
|
+
for (const filePath of filePaths.sort()) {
|
|
1537
|
+
await addFilePart(parts, rootDir, filePath);
|
|
1528
1538
|
}
|
|
1529
1539
|
};
|
|
1530
1540
|
const collectIntegrationBatchingFiles = async (
|
|
@@ -1554,26 +1564,13 @@ async function computeWorkersHarnessFingerprintWithAdapter(
|
|
|
1554
1564
|
}
|
|
1555
1565
|
};
|
|
1556
1566
|
|
|
1557
|
-
const entries = await readdir(adapter.workersHarnessFilesDir, {
|
|
1558
|
-
withFileTypes: true,
|
|
1559
|
-
});
|
|
1560
|
-
const tsFiles = entries
|
|
1561
|
-
.filter((e) => e.isFile() && /\.[cm]?ts$/.test(e.name))
|
|
1562
|
-
.map((e) => e.name)
|
|
1563
|
-
.sort();
|
|
1564
1567
|
const parts: Array<{ name: string; hash: string }> = [];
|
|
1565
|
-
|
|
1566
|
-
await addFilePart(
|
|
1567
|
-
parts,
|
|
1568
|
-
adapter.workersHarnessFilesDir,
|
|
1569
|
-
join(adapter.workersHarnessFilesDir, name),
|
|
1570
|
-
);
|
|
1571
|
-
}
|
|
1568
|
+
await collectTsFilesRecursive(adapter.workersHarnessFilesDir, parts);
|
|
1572
1569
|
for (const dir of adapter.workersRuntimeFingerprintDirs ?? []) {
|
|
1573
1570
|
if (basename(dir) === 'integrations') {
|
|
1574
1571
|
await collectIntegrationBatchingFiles(dir, parts);
|
|
1575
1572
|
} else {
|
|
1576
|
-
await
|
|
1573
|
+
await collectTsFilesRecursive(dir, parts);
|
|
1577
1574
|
}
|
|
1578
1575
|
}
|
|
1579
1576
|
return sha256(JSON.stringify(parts));
|
package/dist/cli/index.js
CHANGED
|
@@ -420,7 +420,7 @@ function loadProjectEnvCandidates(startDir = process.cwd()) {
|
|
|
420
420
|
}));
|
|
421
421
|
}
|
|
422
422
|
function normalizeBaseUrl(baseUrl) {
|
|
423
|
-
const trimmed = baseUrl
|
|
423
|
+
const trimmed = baseUrl?.trim().replace(/\/+$/, "") ?? "";
|
|
424
424
|
if (!trimmed) return "";
|
|
425
425
|
try {
|
|
426
426
|
const parsed = new URL(trimmed);
|
|
@@ -655,10 +655,10 @@ var SDK_RELEASE = {
|
|
|
655
655
|
// the SDK enrich generator's one-second stale policy.
|
|
656
656
|
// 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
|
|
657
657
|
// 0.1.111 ships dataset-native tool list getters and result row datasets.
|
|
658
|
-
version: "0.1.
|
|
658
|
+
version: "0.1.151",
|
|
659
659
|
apiContract: "2026-06-dataset-handle-results-hard-cutover",
|
|
660
660
|
supportPolicy: {
|
|
661
|
-
latest: "0.1.
|
|
661
|
+
latest: "0.1.151",
|
|
662
662
|
minimumSupported: "0.1.53",
|
|
663
663
|
deprecatedBelow: "0.1.53",
|
|
664
664
|
commandMinimumSupported: [
|
|
@@ -10790,6 +10790,23 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
10790
10790
|
},
|
|
10791
10791
|
Math.max(1, input2.waitTimeoutMs)
|
|
10792
10792
|
);
|
|
10793
|
+
const fetchKnownTerminalStatus = async () => {
|
|
10794
|
+
if (!lastKnownWorkflowId) {
|
|
10795
|
+
return null;
|
|
10796
|
+
}
|
|
10797
|
+
let refreshed;
|
|
10798
|
+
try {
|
|
10799
|
+
refreshed = await input2.client.getPlayStatus(lastKnownWorkflowId, {
|
|
10800
|
+
billing: false
|
|
10801
|
+
});
|
|
10802
|
+
} catch (error) {
|
|
10803
|
+
if (isTransientPlayStreamError(error)) {
|
|
10804
|
+
return null;
|
|
10805
|
+
}
|
|
10806
|
+
throw error;
|
|
10807
|
+
}
|
|
10808
|
+
return TERMINAL_PLAY_STATUSES2.has(refreshed.status) ? { ...refreshed, dashboardUrl } : null;
|
|
10809
|
+
};
|
|
10793
10810
|
try {
|
|
10794
10811
|
for await (const event of input2.client.startPlayRunStream(input2.request, {
|
|
10795
10812
|
signal: controller.signal
|
|
@@ -10885,6 +10902,21 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
10885
10902
|
}
|
|
10886
10903
|
} catch (error) {
|
|
10887
10904
|
if (timedOut) {
|
|
10905
|
+
const terminal = await fetchKnownTerminalStatus();
|
|
10906
|
+
if (terminal) {
|
|
10907
|
+
recordCliTrace({
|
|
10908
|
+
phase: "cli.play_start_stream_timeout_status_reconcile",
|
|
10909
|
+
ms: Date.now() - startedAt,
|
|
10910
|
+
ok: true,
|
|
10911
|
+
playName: input2.playName,
|
|
10912
|
+
workflowId: lastKnownWorkflowId,
|
|
10913
|
+
eventCount,
|
|
10914
|
+
firstRunIdMs,
|
|
10915
|
+
lastPhase,
|
|
10916
|
+
status: terminal.status
|
|
10917
|
+
});
|
|
10918
|
+
return terminal;
|
|
10919
|
+
}
|
|
10888
10920
|
assertPlayWaitNotTimedOut({
|
|
10889
10921
|
workflowId: lastKnownWorkflowId,
|
|
10890
10922
|
startedAt,
|
package/dist/cli/index.mjs
CHANGED
|
@@ -405,7 +405,7 @@ function loadProjectEnvCandidates(startDir = process.cwd()) {
|
|
|
405
405
|
}));
|
|
406
406
|
}
|
|
407
407
|
function normalizeBaseUrl(baseUrl) {
|
|
408
|
-
const trimmed = baseUrl
|
|
408
|
+
const trimmed = baseUrl?.trim().replace(/\/+$/, "") ?? "";
|
|
409
409
|
if (!trimmed) return "";
|
|
410
410
|
try {
|
|
411
411
|
const parsed = new URL(trimmed);
|
|
@@ -640,10 +640,10 @@ var SDK_RELEASE = {
|
|
|
640
640
|
// the SDK enrich generator's one-second stale policy.
|
|
641
641
|
// 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
|
|
642
642
|
// 0.1.111 ships dataset-native tool list getters and result row datasets.
|
|
643
|
-
version: "0.1.
|
|
643
|
+
version: "0.1.151",
|
|
644
644
|
apiContract: "2026-06-dataset-handle-results-hard-cutover",
|
|
645
645
|
supportPolicy: {
|
|
646
|
-
latest: "0.1.
|
|
646
|
+
latest: "0.1.151",
|
|
647
647
|
minimumSupported: "0.1.53",
|
|
648
648
|
deprecatedBelow: "0.1.53",
|
|
649
649
|
commandMinimumSupported: [
|
|
@@ -10807,6 +10807,23 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
10807
10807
|
},
|
|
10808
10808
|
Math.max(1, input2.waitTimeoutMs)
|
|
10809
10809
|
);
|
|
10810
|
+
const fetchKnownTerminalStatus = async () => {
|
|
10811
|
+
if (!lastKnownWorkflowId) {
|
|
10812
|
+
return null;
|
|
10813
|
+
}
|
|
10814
|
+
let refreshed;
|
|
10815
|
+
try {
|
|
10816
|
+
refreshed = await input2.client.getPlayStatus(lastKnownWorkflowId, {
|
|
10817
|
+
billing: false
|
|
10818
|
+
});
|
|
10819
|
+
} catch (error) {
|
|
10820
|
+
if (isTransientPlayStreamError(error)) {
|
|
10821
|
+
return null;
|
|
10822
|
+
}
|
|
10823
|
+
throw error;
|
|
10824
|
+
}
|
|
10825
|
+
return TERMINAL_PLAY_STATUSES2.has(refreshed.status) ? { ...refreshed, dashboardUrl } : null;
|
|
10826
|
+
};
|
|
10810
10827
|
try {
|
|
10811
10828
|
for await (const event of input2.client.startPlayRunStream(input2.request, {
|
|
10812
10829
|
signal: controller.signal
|
|
@@ -10902,6 +10919,21 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
|
|
|
10902
10919
|
}
|
|
10903
10920
|
} catch (error) {
|
|
10904
10921
|
if (timedOut) {
|
|
10922
|
+
const terminal = await fetchKnownTerminalStatus();
|
|
10923
|
+
if (terminal) {
|
|
10924
|
+
recordCliTrace({
|
|
10925
|
+
phase: "cli.play_start_stream_timeout_status_reconcile",
|
|
10926
|
+
ms: Date.now() - startedAt,
|
|
10927
|
+
ok: true,
|
|
10928
|
+
playName: input2.playName,
|
|
10929
|
+
workflowId: lastKnownWorkflowId,
|
|
10930
|
+
eventCount,
|
|
10931
|
+
firstRunIdMs,
|
|
10932
|
+
lastPhase,
|
|
10933
|
+
status: terminal.status
|
|
10934
|
+
});
|
|
10935
|
+
return terminal;
|
|
10936
|
+
}
|
|
10905
10937
|
assertPlayWaitNotTimedOut({
|
|
10906
10938
|
workflowId: lastKnownWorkflowId,
|
|
10907
10939
|
startedAt,
|
package/dist/index.js
CHANGED
|
@@ -308,7 +308,7 @@ function loadProjectEnvCandidates(startDir = process.cwd()) {
|
|
|
308
308
|
}));
|
|
309
309
|
}
|
|
310
310
|
function normalizeBaseUrl(baseUrl) {
|
|
311
|
-
const trimmed = baseUrl
|
|
311
|
+
const trimmed = baseUrl?.trim().replace(/\/+$/, "") ?? "";
|
|
312
312
|
if (!trimmed) return "";
|
|
313
313
|
try {
|
|
314
314
|
const parsed = new URL(trimmed);
|
|
@@ -419,10 +419,10 @@ var SDK_RELEASE = {
|
|
|
419
419
|
// the SDK enrich generator's one-second stale policy.
|
|
420
420
|
// 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
|
|
421
421
|
// 0.1.111 ships dataset-native tool list getters and result row datasets.
|
|
422
|
-
version: "0.1.
|
|
422
|
+
version: "0.1.151",
|
|
423
423
|
apiContract: "2026-06-dataset-handle-results-hard-cutover",
|
|
424
424
|
supportPolicy: {
|
|
425
|
-
latest: "0.1.
|
|
425
|
+
latest: "0.1.151",
|
|
426
426
|
minimumSupported: "0.1.53",
|
|
427
427
|
deprecatedBelow: "0.1.53",
|
|
428
428
|
commandMinimumSupported: [
|
package/dist/index.mjs
CHANGED
|
@@ -238,7 +238,7 @@ function loadProjectEnvCandidates(startDir = process.cwd()) {
|
|
|
238
238
|
}));
|
|
239
239
|
}
|
|
240
240
|
function normalizeBaseUrl(baseUrl) {
|
|
241
|
-
const trimmed = baseUrl
|
|
241
|
+
const trimmed = baseUrl?.trim().replace(/\/+$/, "") ?? "";
|
|
242
242
|
if (!trimmed) return "";
|
|
243
243
|
try {
|
|
244
244
|
const parsed = new URL(trimmed);
|
|
@@ -349,10 +349,10 @@ var SDK_RELEASE = {
|
|
|
349
349
|
// the SDK enrich generator's one-second stale policy.
|
|
350
350
|
// 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
|
|
351
351
|
// 0.1.111 ships dataset-native tool list getters and result row datasets.
|
|
352
|
-
version: "0.1.
|
|
352
|
+
version: "0.1.151",
|
|
353
353
|
apiContract: "2026-06-dataset-handle-results-hard-cutover",
|
|
354
354
|
supportPolicy: {
|
|
355
|
-
latest: "0.1.
|
|
355
|
+
latest: "0.1.151",
|
|
356
356
|
minimumSupported: "0.1.53",
|
|
357
357
|
deprecatedBelow: "0.1.53",
|
|
358
358
|
commandMinimumSupported: [
|
|
@@ -1120,19 +1120,32 @@ async function computeWorkersHarnessFingerprintWithAdapter(adapter) {
|
|
|
1120
1120
|
hash: sha256(contents)
|
|
1121
1121
|
});
|
|
1122
1122
|
};
|
|
1123
|
-
const
|
|
1123
|
+
const collectTsFilesRecursive = async (rootDir, parts2) => {
|
|
1124
1124
|
if (!await fileExists(rootDir)) return;
|
|
1125
|
-
const
|
|
1126
|
-
const
|
|
1127
|
-
|
|
1128
|
-
|
|
1125
|
+
const filePaths = [];
|
|
1126
|
+
const visitDir = async (dir) => {
|
|
1127
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
1128
|
+
for (const entry of entries) {
|
|
1129
|
+
const childPath = join(dir, entry.name);
|
|
1130
|
+
if (entry.isDirectory()) {
|
|
1131
|
+
await visitDir(childPath);
|
|
1132
|
+
continue;
|
|
1133
|
+
}
|
|
1134
|
+
if (entry.isFile() && /\.[cm]?ts$/.test(entry.name)) {
|
|
1135
|
+
filePaths.push(childPath);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
};
|
|
1139
|
+
await visitDir(rootDir);
|
|
1140
|
+
for (const filePath of filePaths.sort()) {
|
|
1141
|
+
await addFilePart(parts2, rootDir, filePath);
|
|
1129
1142
|
}
|
|
1130
1143
|
};
|
|
1131
1144
|
const collectIntegrationBatchingFiles = async (rootDir, parts2) => {
|
|
1132
1145
|
if (!await fileExists(rootDir)) return;
|
|
1133
|
-
const
|
|
1146
|
+
const entries = await readdir(rootDir, { withFileTypes: true });
|
|
1134
1147
|
const filePaths = [];
|
|
1135
|
-
for (const entry of
|
|
1148
|
+
for (const entry of entries) {
|
|
1136
1149
|
if (entry.isFile() && (entry.name === "play-runtime-batching-registry.ts" || /^batching.*\.ts$/.test(entry.name))) {
|
|
1137
1150
|
filePaths.push(join(rootDir, entry.name));
|
|
1138
1151
|
}
|
|
@@ -1147,23 +1160,13 @@ async function computeWorkersHarnessFingerprintWithAdapter(adapter) {
|
|
|
1147
1160
|
await addFilePart(parts2, rootDir, filePath);
|
|
1148
1161
|
}
|
|
1149
1162
|
};
|
|
1150
|
-
const entries = await readdir(adapter.workersHarnessFilesDir, {
|
|
1151
|
-
withFileTypes: true
|
|
1152
|
-
});
|
|
1153
|
-
const tsFiles = entries.filter((e) => e.isFile() && /\.[cm]?ts$/.test(e.name)).map((e) => e.name).sort();
|
|
1154
1163
|
const parts = [];
|
|
1155
|
-
|
|
1156
|
-
await addFilePart(
|
|
1157
|
-
parts,
|
|
1158
|
-
adapter.workersHarnessFilesDir,
|
|
1159
|
-
join(adapter.workersHarnessFilesDir, name)
|
|
1160
|
-
);
|
|
1161
|
-
}
|
|
1164
|
+
await collectTsFilesRecursive(adapter.workersHarnessFilesDir, parts);
|
|
1162
1165
|
for (const dir of adapter.workersRuntimeFingerprintDirs ?? []) {
|
|
1163
1166
|
if (basename(dir) === "integrations") {
|
|
1164
1167
|
await collectIntegrationBatchingFiles(dir, parts);
|
|
1165
1168
|
} else {
|
|
1166
|
-
await
|
|
1169
|
+
await collectTsFilesRecursive(dir, parts);
|
|
1167
1170
|
}
|
|
1168
1171
|
}
|
|
1169
1172
|
return sha256(JSON.stringify(parts));
|