deepline 0.1.62 → 0.1.64
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/index.js +702 -339
- package/dist/cli/index.mjs +727 -348
- package/dist/index.d.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +77 -51
- package/dist/index.mjs +77 -51
- package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +9 -10
- package/dist/repo/apps/play-runner-workers/src/entry.ts +55 -0
- package/dist/repo/apps/play-runner-workers/src/runtime/dataset-handles.ts +36 -27
- package/dist/repo/apps/play-runner-workers/src/runtime/tool-http-errors.ts +5 -2
- package/dist/repo/sdk/src/client.ts +71 -63
- package/dist/repo/sdk/src/errors.ts +5 -1
- package/dist/repo/sdk/src/http.ts +25 -17
- package/dist/repo/sdk/src/plays/local-file-discovery.ts +93 -24
- package/dist/repo/sdk/src/release.ts +2 -2
- package/dist/repo/sdk/src/tool-output.ts +40 -20
- package/dist/repo/shared_libs/play-runtime/batch-runtime.ts +10 -3
- package/dist/repo/shared_libs/play-runtime/batching-types.ts +15 -4
- package/dist/repo/shared_libs/play-runtime/coordinator-headers.ts +2 -1
- package/dist/repo/shared_libs/play-runtime/dedup-backend.ts +0 -0
- package/dist/repo/shared_libs/play-runtime/default-batch-strategies.ts +3 -4
- package/dist/repo/shared_libs/play-runtime/run-failure.ts +1 -3
- package/dist/repo/shared_libs/play-runtime/step-lifecycle-tracker.ts +4 -1
- package/dist/repo/shared_libs/play-runtime/tool-batch-executor.ts +4 -1
- package/dist/repo/shared_libs/play-runtime/tool-result.ts +28 -15
- package/dist/repo/shared_libs/plays/dataset.ts +10 -11
- package/package.json +1 -1
|
@@ -50,10 +50,10 @@ export type SdkRelease = {
|
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
export const SDK_RELEASE = {
|
|
53
|
-
version: '0.1.
|
|
53
|
+
version: '0.1.64',
|
|
54
54
|
apiContract: '2026-05-play-bootstrap-dataset-summary',
|
|
55
55
|
supportPolicy: {
|
|
56
|
-
latest: '0.1.
|
|
56
|
+
latest: '0.1.64',
|
|
57
57
|
minimumSupported: '0.1.53',
|
|
58
58
|
deprecatedBelow: '0.1.53',
|
|
59
59
|
},
|
|
@@ -86,7 +86,9 @@ function normalizeScalarString(value: unknown): string | null {
|
|
|
86
86
|
*/
|
|
87
87
|
function getByDottedPath(root: unknown, dottedPath: string): unknown {
|
|
88
88
|
let current = root;
|
|
89
|
-
for (const segment of String(dottedPath || '')
|
|
89
|
+
for (const segment of String(dottedPath || '')
|
|
90
|
+
.split('.')
|
|
91
|
+
.filter(Boolean)) {
|
|
90
92
|
if (!isPlainObject(current) || !(segment in current)) {
|
|
91
93
|
return null;
|
|
92
94
|
}
|
|
@@ -111,8 +113,12 @@ function normalizeRows(value: unknown): Array<Record<string, unknown>> | null {
|
|
|
111
113
|
* Generate candidate root objects to search for lists.
|
|
112
114
|
* Tries: raw payload → V2 toolResponse.raw → legacy payload.output.body → legacy payload.result → legacy payload.result.data.
|
|
113
115
|
*/
|
|
114
|
-
function candidateRoots(
|
|
115
|
-
|
|
116
|
+
function candidateRoots(
|
|
117
|
+
payload: unknown,
|
|
118
|
+
): Array<{ path: string | null; value: unknown }> {
|
|
119
|
+
const roots: Array<{ path: string | null; value: unknown }> = [
|
|
120
|
+
{ path: null, value: payload },
|
|
121
|
+
];
|
|
116
122
|
if (isPlainObject(payload) && isPlainObject(payload.toolResponse)) {
|
|
117
123
|
roots.push({ path: 'toolResponse', value: payload.toolResponse });
|
|
118
124
|
if (Object.prototype.hasOwnProperty.call(payload.toolResponse, 'raw')) {
|
|
@@ -150,7 +156,10 @@ function findBestArrayCandidate(
|
|
|
150
156
|
if (depth > 5) return null;
|
|
151
157
|
|
|
152
158
|
const directRows = normalizeRows(value);
|
|
153
|
-
const hasObjectRow =
|
|
159
|
+
const hasObjectRow =
|
|
160
|
+
directRows?.some((row) =>
|
|
161
|
+
Object.keys(row).some((key) => key !== 'value'),
|
|
162
|
+
) ?? false;
|
|
154
163
|
let best: { path: string; rows: Array<Record<string, unknown>> } | null =
|
|
155
164
|
directRows && directRows.length > 0 && hasObjectRow
|
|
156
165
|
? { path: pathPrefix, rows: directRows }
|
|
@@ -220,7 +229,10 @@ export function tryConvertToList(
|
|
|
220
229
|
options?: { listExtractorPaths?: string[] },
|
|
221
230
|
): ListConversionResult | null {
|
|
222
231
|
const listExtractorPaths = Array.isArray(options?.listExtractorPaths)
|
|
223
|
-
? options?.listExtractorPaths.filter(
|
|
232
|
+
? options?.listExtractorPaths.filter(
|
|
233
|
+
(entry): entry is string =>
|
|
234
|
+
typeof entry === 'string' && entry.trim().length > 0,
|
|
235
|
+
)
|
|
224
236
|
: [];
|
|
225
237
|
|
|
226
238
|
if (listExtractorPaths.length > 0) {
|
|
@@ -229,7 +241,9 @@ export function tryConvertToList(
|
|
|
229
241
|
const resolved = getByDottedPath(root.value, extractorPath);
|
|
230
242
|
const rows = normalizeRows(resolved);
|
|
231
243
|
if (rows && rows.length > 0) {
|
|
232
|
-
const sourcePath = root.path
|
|
244
|
+
const sourcePath = root.path
|
|
245
|
+
? `${root.path}.${extractorPath}`
|
|
246
|
+
: extractorPath;
|
|
233
247
|
return { rows, strategy: 'configured_paths', sourcePath };
|
|
234
248
|
}
|
|
235
249
|
}
|
|
@@ -322,11 +336,14 @@ export function writeCsvOutputFile(
|
|
|
322
336
|
}
|
|
323
337
|
|
|
324
338
|
const escapeCell = (value: unknown): string => {
|
|
325
|
-
const normalized =
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
339
|
+
const normalized =
|
|
340
|
+
value == null
|
|
341
|
+
? ''
|
|
342
|
+
: typeof value === 'string' ||
|
|
343
|
+
typeof value === 'number' ||
|
|
344
|
+
typeof value === 'boolean'
|
|
345
|
+
? String(value)
|
|
346
|
+
: JSON.stringify(value);
|
|
330
347
|
if (/[",\n]/.test(normalized)) {
|
|
331
348
|
return `"${normalized.replace(/"/g, '""')}"`;
|
|
332
349
|
}
|
|
@@ -345,7 +362,8 @@ export function writeCsvOutputFile(
|
|
|
345
362
|
const preview = [
|
|
346
363
|
previewColumns.join(','),
|
|
347
364
|
...previewRows.map((row) =>
|
|
348
|
-
previewColumns.map((column) => escapeCell(row[column])).join(',')
|
|
365
|
+
previewColumns.map((column) => escapeCell(row[column])).join(','),
|
|
366
|
+
),
|
|
349
367
|
].join('\n');
|
|
350
368
|
|
|
351
369
|
return {
|
|
@@ -378,14 +396,16 @@ export function extractSummaryFields(payload: unknown): Record<string, Scalar> {
|
|
|
378
396
|
const candidates = candidateRoots(payload);
|
|
379
397
|
for (const candidate of candidates) {
|
|
380
398
|
if (!isPlainObject(candidate.value)) continue;
|
|
381
|
-
const summaryEntries = Object.entries(candidate.value).filter(
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
399
|
+
const summaryEntries = Object.entries(candidate.value).filter(
|
|
400
|
+
([, value]) => {
|
|
401
|
+
return (
|
|
402
|
+
value == null ||
|
|
403
|
+
typeof value === 'string' ||
|
|
404
|
+
typeof value === 'number' ||
|
|
405
|
+
typeof value === 'boolean'
|
|
406
|
+
);
|
|
407
|
+
},
|
|
408
|
+
);
|
|
389
409
|
if (summaryEntries.length === 0) continue;
|
|
390
410
|
return Object.fromEntries(summaryEntries) as Record<string, Scalar>;
|
|
391
411
|
}
|
|
@@ -132,7 +132,9 @@ export function compileRequestsWithStrategy<TRequest>(input: {
|
|
|
132
132
|
export async function executeWaterfallProviders<TRequest, TResult>(input: {
|
|
133
133
|
providers: string[];
|
|
134
134
|
getPendingRequests: () => TRequest[];
|
|
135
|
-
getCachedResults: (
|
|
135
|
+
getCachedResults: (
|
|
136
|
+
provider: string,
|
|
137
|
+
) => Array<ChunkExecutionResult<TRequest, TResult>> | null;
|
|
136
138
|
storeCachedResults: (
|
|
137
139
|
provider: string,
|
|
138
140
|
results: Array<ChunkExecutionResult<TRequest, TResult>>,
|
|
@@ -177,6 +179,11 @@ export async function executeWaterfallProviders<TRequest, TResult>(input: {
|
|
|
177
179
|
}
|
|
178
180
|
}
|
|
179
181
|
|
|
180
|
-
export function resolveWaterfallToolId(
|
|
181
|
-
|
|
182
|
+
export function resolveWaterfallToolId(
|
|
183
|
+
provider: string,
|
|
184
|
+
toolName: string,
|
|
185
|
+
): string {
|
|
186
|
+
return toolName.startsWith(`${provider}_`)
|
|
187
|
+
? toolName
|
|
188
|
+
: `${provider}_${toolName}`;
|
|
182
189
|
}
|
|
@@ -10,7 +10,10 @@ export type BatchCompileItem<TSingle extends object> = {
|
|
|
10
10
|
payload: TSingle;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
export type BatchCompileResult<
|
|
13
|
+
export type BatchCompileResult<
|
|
14
|
+
TBatch extends object,
|
|
15
|
+
TSingle extends object,
|
|
16
|
+
> = {
|
|
14
17
|
batchOperation: string;
|
|
15
18
|
batchPayload: TBatch;
|
|
16
19
|
items: Array<BatchCompileItem<TSingle>>;
|
|
@@ -58,7 +61,10 @@ export type AnyBatchOperationStrategy = {
|
|
|
58
61
|
batchOperation: string;
|
|
59
62
|
kind: BatchStrategyKind;
|
|
60
63
|
maxBatchSize: number;
|
|
61
|
-
canBatchWith(
|
|
64
|
+
canBatchWith(
|
|
65
|
+
left: Record<string, unknown>,
|
|
66
|
+
right: Record<string, unknown>,
|
|
67
|
+
): boolean;
|
|
62
68
|
toBucketKey(payload: Record<string, unknown>): string;
|
|
63
69
|
toItemKey(payload: Record<string, unknown>): string;
|
|
64
70
|
compile(payloads: Record<string, unknown>[]): {
|
|
@@ -81,8 +87,13 @@ export type AnyBatchOperationStrategy = {
|
|
|
81
87
|
|
|
82
88
|
export type BatchStrategyMap = Record<string, AnyBatchOperationStrategy>;
|
|
83
89
|
|
|
84
|
-
type StrictBatchOperationStrategy =
|
|
85
|
-
|
|
90
|
+
type StrictBatchOperationStrategy = BatchOperationStrategy<
|
|
91
|
+
Record<string, unknown>,
|
|
92
|
+
Record<string, unknown>,
|
|
93
|
+
object,
|
|
94
|
+
unknown,
|
|
95
|
+
unknown
|
|
96
|
+
>;
|
|
86
97
|
|
|
87
98
|
export function defineBatchStrategyMap<
|
|
88
99
|
TStrategies extends Record<string, StrictBatchOperationStrategy>,
|
|
@@ -31,7 +31,8 @@ function resolveInternalCoordinatorToken(): string | null {
|
|
|
31
31
|
// Read lazily so the helper is safe to import in environments without
|
|
32
32
|
// env access (e.g. workerd build-time bundling).
|
|
33
33
|
const fromEnv =
|
|
34
|
-
(typeof process !== 'undefined' &&
|
|
34
|
+
(typeof process !== 'undefined' &&
|
|
35
|
+
process?.env?.DEEPLINE_INTERNAL_TOKEN?.trim()) ||
|
|
35
36
|
null;
|
|
36
37
|
if (fromEnv) return fromEnv;
|
|
37
38
|
if (!warnedAboutMissingInternalToken) {
|
|
Binary file
|
|
@@ -109,10 +109,9 @@ const testRateLimitBatchStrategy: BatchOperationStrategy<
|
|
|
109
109
|
},
|
|
110
110
|
};
|
|
111
111
|
|
|
112
|
-
export const DEFAULT_PLAY_RUNTIME_BATCH_STRATEGIES =
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
});
|
|
112
|
+
export const DEFAULT_PLAY_RUNTIME_BATCH_STRATEGIES = defineBatchStrategyMap({
|
|
113
|
+
test_rate_limit: testRateLimitBatchStrategy,
|
|
114
|
+
});
|
|
116
115
|
|
|
117
116
|
export function getDefaultPlayRuntimeBatchStrategy(
|
|
118
117
|
operation: string | null | undefined,
|
|
@@ -27,9 +27,7 @@ export function isCloudflareDurableObjectCodeUpdatedError(
|
|
|
27
27
|
);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export function normalizePlayRunFailure(
|
|
31
|
-
error: unknown,
|
|
32
|
-
): PlayRunFailureDetails {
|
|
30
|
+
export function normalizePlayRunFailure(error: unknown): PlayRunFailureDetails {
|
|
33
31
|
const cause = toErrorText(error);
|
|
34
32
|
if (isCloudflareDurableObjectCodeUpdatedError(cause)) {
|
|
35
33
|
return {
|
|
@@ -24,7 +24,10 @@ export class PlayStepLifecycleTracker {
|
|
|
24
24
|
|
|
25
25
|
constructor(
|
|
26
26
|
private readonly nodes: readonly PlayStepLifecycleNode[],
|
|
27
|
-
private readonly getProgress: () => Record<
|
|
27
|
+
private readonly getProgress: () => Record<
|
|
28
|
+
string,
|
|
29
|
+
PlayStepLifecycleProgress
|
|
30
|
+
>,
|
|
28
31
|
private readonly emit: (event: PlayStepLifecycleEvent) => void,
|
|
29
32
|
private readonly now: () => number = Date.now,
|
|
30
33
|
) {}
|
|
@@ -55,7 +55,10 @@ export function createToolBatchExecutor(
|
|
|
55
55
|
): ToolBatchExecutor {
|
|
56
56
|
return {
|
|
57
57
|
async executeToolBatch(request) {
|
|
58
|
-
const providerBatchSize = Math.max(
|
|
58
|
+
const providerBatchSize = Math.max(
|
|
59
|
+
1,
|
|
60
|
+
Math.floor(request.providerBatchSize),
|
|
61
|
+
);
|
|
59
62
|
const batches = chunkToolBatchItems(request.items, providerBatchSize);
|
|
60
63
|
const results: ToolBatchItemResult[] = [];
|
|
61
64
|
for (let batchIndex = 0; batchIndex < batches.length; batchIndex += 1) {
|
|
@@ -454,19 +454,14 @@ function deriveListKeys(input: {
|
|
|
454
454
|
}
|
|
455
455
|
|
|
456
456
|
const listPrefix = input.listPath.replace(/\[\d+\]$/, '');
|
|
457
|
-
for (const [target, paths] of Object.entries(
|
|
458
|
-
input.targetGetters ?? {},
|
|
459
|
-
)) {
|
|
457
|
+
for (const [target, paths] of Object.entries(input.targetGetters ?? {})) {
|
|
460
458
|
for (const rawPath of paths) {
|
|
461
459
|
const path = String(rawPath || '')
|
|
462
460
|
.trim()
|
|
463
461
|
.replace(/^\./, '');
|
|
464
462
|
if (!path) continue;
|
|
465
463
|
const firstRow = input.rows[0];
|
|
466
|
-
if (
|
|
467
|
-
firstRow &&
|
|
468
|
-
Object.prototype.hasOwnProperty.call(firstRow, path)
|
|
469
|
-
) {
|
|
464
|
+
if (firstRow && Object.prototype.hasOwnProperty.call(firstRow, path)) {
|
|
470
465
|
keys[target] = path;
|
|
471
466
|
break;
|
|
472
467
|
}
|
|
@@ -514,21 +509,20 @@ function buildTargets(
|
|
|
514
509
|
for (const [target, descriptor] of Object.entries(extractors ?? {})) {
|
|
515
510
|
const fromExtractor = findFirstTargetByPath(result, descriptor.paths);
|
|
516
511
|
if (!fromExtractor) continue;
|
|
512
|
+
const transformed = coerceToEnum(
|
|
513
|
+
applyExtractorTransforms(fromExtractor.value, descriptor),
|
|
514
|
+
descriptor,
|
|
515
|
+
);
|
|
516
|
+
const override = findExtractorOverride(result, descriptor);
|
|
517
517
|
targets[target] = {
|
|
518
518
|
path: fromExtractor.path,
|
|
519
|
-
value:
|
|
520
|
-
applyExtractorTransforms(fromExtractor.value, descriptor),
|
|
521
|
-
descriptor,
|
|
522
|
-
),
|
|
519
|
+
value: override?.value ?? transformed,
|
|
523
520
|
};
|
|
524
521
|
}
|
|
525
522
|
const metadataTargets = new Set(Object.keys(targetGetters ?? {}));
|
|
526
523
|
for (const target of metadataTargets) {
|
|
527
524
|
if (targets[target]) continue;
|
|
528
|
-
const fromMetadata = findFirstTargetByPath(
|
|
529
|
-
result,
|
|
530
|
-
targetGetters?.[target],
|
|
531
|
-
);
|
|
525
|
+
const fromMetadata = findFirstTargetByPath(result, targetGetters?.[target]);
|
|
532
526
|
if (fromMetadata) {
|
|
533
527
|
targets[target] = fromMetadata;
|
|
534
528
|
continue;
|
|
@@ -547,6 +541,25 @@ function buildTargets(
|
|
|
547
541
|
return targets;
|
|
548
542
|
}
|
|
549
543
|
|
|
544
|
+
function findExtractorOverride(
|
|
545
|
+
result: unknown,
|
|
546
|
+
descriptor: ToolResultExtractorDescriptor,
|
|
547
|
+
): { value: string | number | boolean | null } | null {
|
|
548
|
+
for (const override of descriptor.overrides ?? []) {
|
|
549
|
+
const expected = Object.prototype.hasOwnProperty.call(override, 'equals')
|
|
550
|
+
? override.equals
|
|
551
|
+
: true;
|
|
552
|
+
for (const path of override.paths) {
|
|
553
|
+
const match = findFirstTargetByPath(result, [path]);
|
|
554
|
+
if (!match) continue;
|
|
555
|
+
if (match.value === expected) {
|
|
556
|
+
return { value: override.value };
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
return null;
|
|
561
|
+
}
|
|
562
|
+
|
|
550
563
|
function buildLists(
|
|
551
564
|
resolved: Record<string, { path: string; rows: Record<string, unknown>[] }>,
|
|
552
565
|
metadata: ToolResultMetadataInput,
|
|
@@ -172,8 +172,8 @@ function inferPreviewColumns<T>(rows: readonly T[]): string[] | undefined {
|
|
|
172
172
|
export function isPlayDataset<T>(value: unknown): value is PlayDataset<T> {
|
|
173
173
|
return Boolean(
|
|
174
174
|
value &&
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
typeof value === 'object' &&
|
|
176
|
+
(value as Record<PropertyKey, unknown>)[PLAY_DATASET_BRAND] === true,
|
|
177
177
|
);
|
|
178
178
|
}
|
|
179
179
|
|
|
@@ -182,13 +182,13 @@ export function isSerializedPlayDataset<T>(
|
|
|
182
182
|
): value is SerializedPlayDataset<T> {
|
|
183
183
|
return Boolean(
|
|
184
184
|
value &&
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
185
|
+
typeof value === 'object' &&
|
|
186
|
+
!Array.isArray(value) &&
|
|
187
|
+
(value as Record<string, unknown>).kind === 'dataset' &&
|
|
188
|
+
typeof (value as Record<string, unknown>).datasetKind === 'string' &&
|
|
189
|
+
typeof (value as Record<string, unknown>).datasetId === 'string' &&
|
|
190
|
+
typeof (value as Record<string, unknown>).count === 'number' &&
|
|
191
|
+
Array.isArray((value as Record<string, unknown>).preview),
|
|
192
192
|
);
|
|
193
193
|
}
|
|
194
194
|
|
|
@@ -506,8 +506,7 @@ export function createPlayDataset<T>(
|
|
|
506
506
|
tableNamespace: metadata?.tableNamespace ?? null,
|
|
507
507
|
resolvers: {
|
|
508
508
|
count: async () => materializedRows.length,
|
|
509
|
-
peek: async (limit) =>
|
|
510
|
-
materializedRows.slice(0, Math.max(0, limit)),
|
|
509
|
+
peek: async (limit) => materializedRows.slice(0, Math.max(0, limit)),
|
|
511
510
|
materialize: async (limit) =>
|
|
512
511
|
limit === undefined
|
|
513
512
|
? [...materializedRows]
|