deepline 0.1.145 → 0.1.147
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 +205 -75
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/dataset-handles.ts +8 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/output-datasets.ts +363 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/result-dataset-persistence.ts +50 -0
- package/dist/bundling-sources/sdk/src/release.ts +54 -21
- package/dist/bundling-sources/sdk/src/tool-output.ts +18 -7
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result-types.ts +2 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +81 -5
- package/dist/cli/index.js +371 -41
- package/dist/cli/index.mjs +383 -53
- package/dist/index.d.mts +91 -89
- package/dist/index.d.ts +91 -89
- package/dist/index.js +545 -31
- package/dist/index.mjs +546 -32
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -418,10 +418,11 @@ var SDK_RELEASE = {
|
|
|
418
418
|
// 0.1.108 ships explicit dataset column/tool recompute policy and removes
|
|
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
|
-
|
|
422
|
-
|
|
421
|
+
// 0.1.111 ships dataset-native tool list getters and result row datasets.
|
|
422
|
+
version: "0.1.147",
|
|
423
|
+
apiContract: "2026-06-dataset-handle-results-hard-cutover",
|
|
423
424
|
supportPolicy: {
|
|
424
|
-
latest: "0.1.
|
|
425
|
+
latest: "0.1.147",
|
|
425
426
|
minimumSupported: "0.1.53",
|
|
426
427
|
deprecatedBelow: "0.1.53",
|
|
427
428
|
commandMinimumSupported: [
|
|
@@ -432,52 +433,79 @@ var SDK_RELEASE = {
|
|
|
432
433
|
},
|
|
433
434
|
{
|
|
434
435
|
command: "plays",
|
|
435
|
-
minimumSupported: "0.1.
|
|
436
|
-
reason: "Play file commands now
|
|
436
|
+
minimumSupported: "0.1.111",
|
|
437
|
+
reason: "Play file commands now use dataset-native list getters and result row datasets."
|
|
437
438
|
},
|
|
438
439
|
{
|
|
439
440
|
command: "plays run",
|
|
440
|
-
minimumSupported: "0.1.
|
|
441
|
-
reason: "Play
|
|
441
|
+
minimumSupported: "0.1.111",
|
|
442
|
+
reason: "Play run results now promote row-shaped outputs into dataset handles for safe export."
|
|
442
443
|
},
|
|
443
444
|
{
|
|
444
445
|
command: "run",
|
|
445
446
|
displayCommand: "plays run",
|
|
446
|
-
minimumSupported: "0.1.
|
|
447
|
-
reason: "Play
|
|
447
|
+
minimumSupported: "0.1.111",
|
|
448
|
+
reason: "Play run results now promote row-shaped outputs into dataset handles for safe export."
|
|
448
449
|
},
|
|
449
450
|
{
|
|
450
451
|
command: "plays check",
|
|
451
|
-
minimumSupported: "0.1.
|
|
452
|
-
reason: "Play file
|
|
452
|
+
minimumSupported: "0.1.111",
|
|
453
|
+
reason: "Play file checks now validate dataset-native list getter authoring."
|
|
453
454
|
},
|
|
454
455
|
{
|
|
455
456
|
command: "check",
|
|
456
457
|
displayCommand: "plays check",
|
|
457
|
-
minimumSupported: "0.1.
|
|
458
|
-
reason: "Play file
|
|
458
|
+
minimumSupported: "0.1.111",
|
|
459
|
+
reason: "Play file checks now validate dataset-native list getter authoring."
|
|
459
460
|
},
|
|
460
461
|
{
|
|
461
462
|
command: "plays publish",
|
|
462
|
-
minimumSupported: "0.1.
|
|
463
|
-
reason: "
|
|
463
|
+
minimumSupported: "0.1.111",
|
|
464
|
+
reason: "Published play artifacts now target dataset-native list getters and result row datasets."
|
|
464
465
|
},
|
|
465
466
|
{
|
|
466
467
|
command: "publish",
|
|
467
468
|
displayCommand: "plays publish",
|
|
468
|
-
minimumSupported: "0.1.
|
|
469
|
-
reason: "
|
|
469
|
+
minimumSupported: "0.1.111",
|
|
470
|
+
reason: "Published play artifacts now target dataset-native list getters and result row datasets."
|
|
470
471
|
},
|
|
471
472
|
{
|
|
472
473
|
command: "plays set-live",
|
|
473
|
-
minimumSupported: "0.1.
|
|
474
|
-
reason: "
|
|
474
|
+
minimumSupported: "0.1.111",
|
|
475
|
+
reason: "Published play artifacts now target dataset-native list getters and result row datasets."
|
|
475
476
|
},
|
|
476
477
|
{
|
|
477
478
|
command: "set-live",
|
|
478
479
|
displayCommand: "plays set-live",
|
|
479
|
-
minimumSupported: "0.1.
|
|
480
|
-
reason: "
|
|
480
|
+
minimumSupported: "0.1.111",
|
|
481
|
+
reason: "Published play artifacts now target dataset-native list getters and result row datasets."
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
command: "runs",
|
|
485
|
+
minimumSupported: "0.1.111",
|
|
486
|
+
reason: "Run result rows now render as dataset handles with explicit export commands."
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
command: "runs get",
|
|
490
|
+
minimumSupported: "0.1.111",
|
|
491
|
+
reason: "Run result rows now render as dataset handles with explicit export commands."
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
command: "get",
|
|
495
|
+
displayCommand: "runs get",
|
|
496
|
+
minimumSupported: "0.1.111",
|
|
497
|
+
reason: "Run result rows now render as dataset handles with explicit export commands."
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
command: "runs export",
|
|
501
|
+
minimumSupported: "0.1.111",
|
|
502
|
+
reason: "Run result row datasets now use the dataset-handle export contract."
|
|
503
|
+
},
|
|
504
|
+
{
|
|
505
|
+
command: "export",
|
|
506
|
+
displayCommand: "runs export",
|
|
507
|
+
minimumSupported: "0.1.111",
|
|
508
|
+
reason: "Run result row datasets now use the dataset-handle export contract."
|
|
481
509
|
}
|
|
482
510
|
],
|
|
483
511
|
autoUpdatePatchLag: 2
|
|
@@ -3973,6 +4001,420 @@ function isDeeplineExtractorTarget(value) {
|
|
|
3973
4001
|
return value in DEEPLINE_EXTRACTOR_TARGET_DEFINITIONS;
|
|
3974
4002
|
}
|
|
3975
4003
|
|
|
4004
|
+
// ../shared_libs/plays/dataset.ts
|
|
4005
|
+
var PLAY_DATASET_BRAND = /* @__PURE__ */ Symbol.for("deepline.play.dataset");
|
|
4006
|
+
var NODE_INSPECT_CUSTOM = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
|
|
4007
|
+
var DEFAULT_MATERIALIZE_LIMIT = 1e4;
|
|
4008
|
+
function resolveMaterializeLimitCap() {
|
|
4009
|
+
const raw = process.env.DEEPLINE_PLAY_DATASET_MATERIALIZE_LIMIT;
|
|
4010
|
+
const parsed = raw ? Number(raw) : NaN;
|
|
4011
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
4012
|
+
return Math.floor(parsed);
|
|
4013
|
+
}
|
|
4014
|
+
return DEFAULT_MATERIALIZE_LIMIT;
|
|
4015
|
+
}
|
|
4016
|
+
function inferPreviewColumns(rows) {
|
|
4017
|
+
const columns = /* @__PURE__ */ new Set();
|
|
4018
|
+
for (const row of rows) {
|
|
4019
|
+
if (!row || typeof row !== "object" || Array.isArray(row)) {
|
|
4020
|
+
continue;
|
|
4021
|
+
}
|
|
4022
|
+
for (const key of Object.keys(row)) {
|
|
4023
|
+
columns.add(key);
|
|
4024
|
+
}
|
|
4025
|
+
}
|
|
4026
|
+
return columns.size > 0 ? [...columns] : void 0;
|
|
4027
|
+
}
|
|
4028
|
+
var DeferredPlayDataset = class {
|
|
4029
|
+
[PLAY_DATASET_BRAND] = true;
|
|
4030
|
+
datasetKind;
|
|
4031
|
+
datasetId;
|
|
4032
|
+
backing;
|
|
4033
|
+
sourceLabel;
|
|
4034
|
+
tableNamespace;
|
|
4035
|
+
previewRows;
|
|
4036
|
+
previewColumns;
|
|
4037
|
+
workProgress;
|
|
4038
|
+
cachedCount;
|
|
4039
|
+
resolvers;
|
|
4040
|
+
constructor(input) {
|
|
4041
|
+
this.datasetKind = input.datasetKind;
|
|
4042
|
+
this.datasetId = input.datasetId;
|
|
4043
|
+
this.cachedCount = input.count;
|
|
4044
|
+
this.backing = input.backing;
|
|
4045
|
+
this.previewRows = input.previewRows;
|
|
4046
|
+
this.previewColumns = inferPreviewColumns(this.previewRows);
|
|
4047
|
+
this.sourceLabel = input.sourceLabel ?? null;
|
|
4048
|
+
this.tableNamespace = input.tableNamespace ?? null;
|
|
4049
|
+
this.workProgress = input.workProgress;
|
|
4050
|
+
this.resolvers = input.resolvers;
|
|
4051
|
+
}
|
|
4052
|
+
async count() {
|
|
4053
|
+
this.cachedCount = await this.resolvers.count();
|
|
4054
|
+
return this.cachedCount;
|
|
4055
|
+
}
|
|
4056
|
+
async peek(limit = 10) {
|
|
4057
|
+
if (limit <= this.previewRows.length) {
|
|
4058
|
+
return this.previewRows.slice(0, Math.max(0, limit));
|
|
4059
|
+
}
|
|
4060
|
+
return await this.resolvers.peek(limit);
|
|
4061
|
+
}
|
|
4062
|
+
map(mapper, options) {
|
|
4063
|
+
return createTransformedPlayDataset(this, { kind: "map", mapper }, options);
|
|
4064
|
+
}
|
|
4065
|
+
filter(predicate, options) {
|
|
4066
|
+
return createTransformedPlayDataset(
|
|
4067
|
+
this,
|
|
4068
|
+
{ kind: "filter", predicate },
|
|
4069
|
+
options
|
|
4070
|
+
);
|
|
4071
|
+
}
|
|
4072
|
+
slice(start, end, options) {
|
|
4073
|
+
return createTransformedPlayDataset(
|
|
4074
|
+
this,
|
|
4075
|
+
{ kind: "slice", start, end },
|
|
4076
|
+
options
|
|
4077
|
+
);
|
|
4078
|
+
}
|
|
4079
|
+
take(limit, options) {
|
|
4080
|
+
return this.slice(0, limit, options);
|
|
4081
|
+
}
|
|
4082
|
+
async materialize(limit) {
|
|
4083
|
+
const requestedLimit = limit !== void 0 ? Math.max(0, Math.floor(limit)) : void 0;
|
|
4084
|
+
const cap = resolveMaterializeLimitCap();
|
|
4085
|
+
if (requestedLimit !== void 0) {
|
|
4086
|
+
if (requestedLimit > cap) {
|
|
4087
|
+
throw new Error(
|
|
4088
|
+
`PlayDataset.materialize(${requestedLimit}) exceeds the hard limit of ${cap} rows. Return the dataset handle instead, or request a smaller bounded slice.`
|
|
4089
|
+
);
|
|
4090
|
+
}
|
|
4091
|
+
return await this.resolvers.materialize(requestedLimit);
|
|
4092
|
+
}
|
|
4093
|
+
const count = await this.count();
|
|
4094
|
+
if (count > cap) {
|
|
4095
|
+
throw new Error(
|
|
4096
|
+
`PlayDataset.materialize() refuses to load ${count} rows into memory. The hard limit is ${cap}. Return the dataset handle instead or call materialize(limit).`
|
|
4097
|
+
);
|
|
4098
|
+
}
|
|
4099
|
+
return await this.resolvers.materialize();
|
|
4100
|
+
}
|
|
4101
|
+
async *[Symbol.asyncIterator]() {
|
|
4102
|
+
for await (const row of this.resolvers.iterate()) {
|
|
4103
|
+
yield row;
|
|
4104
|
+
}
|
|
4105
|
+
}
|
|
4106
|
+
toJSON() {
|
|
4107
|
+
return {
|
|
4108
|
+
kind: "dataset",
|
|
4109
|
+
datasetKind: this.datasetKind,
|
|
4110
|
+
datasetId: this.datasetId,
|
|
4111
|
+
count: this.cachedCount,
|
|
4112
|
+
...this.backing ? { backing: this.backing } : {},
|
|
4113
|
+
...this.sourceLabel ? { sourceLabel: this.sourceLabel } : {},
|
|
4114
|
+
...this.tableNamespace ? { tableNamespace: this.tableNamespace } : {},
|
|
4115
|
+
...this.previewColumns ? { columns: this.previewColumns } : {},
|
|
4116
|
+
...this.workProgress ? { _metadata: { workProgress: this.workProgress } } : {},
|
|
4117
|
+
preview: [...this.previewRows]
|
|
4118
|
+
};
|
|
4119
|
+
}
|
|
4120
|
+
[NODE_INSPECT_CUSTOM]() {
|
|
4121
|
+
return this.toJSON();
|
|
4122
|
+
}
|
|
4123
|
+
};
|
|
4124
|
+
function normalizeSliceBounds(input) {
|
|
4125
|
+
const count = Math.max(0, Math.floor(input.count));
|
|
4126
|
+
const rawStart = input.start ?? 0;
|
|
4127
|
+
const rawEnd = input.end ?? count;
|
|
4128
|
+
const startInteger = Number.isFinite(rawStart) ? Math.trunc(rawStart) : 0;
|
|
4129
|
+
const endInteger = Number.isFinite(rawEnd) ? Math.trunc(rawEnd) : count;
|
|
4130
|
+
const start = startInteger < 0 ? Math.max(count + startInteger, 0) : Math.min(startInteger, count);
|
|
4131
|
+
const end = endInteger < 0 ? Math.max(count + endInteger, 0) : Math.min(endInteger, count);
|
|
4132
|
+
return { start, end: Math.max(start, end) };
|
|
4133
|
+
}
|
|
4134
|
+
function transformDatasetId(input) {
|
|
4135
|
+
const key = input.key?.trim();
|
|
4136
|
+
return key ? `${input.source.datasetId}:${input.kind}:${key}` : `${input.source.datasetId}:${input.kind}`;
|
|
4137
|
+
}
|
|
4138
|
+
function createTransformedPlayDataset(source, transform, options) {
|
|
4139
|
+
const sourceLabel = options?.sourceLabel ?? `${source.sourceLabel ?? source.tableNamespace ?? source.datasetId}.${transform.kind}`;
|
|
4140
|
+
const iterate = async function* () {
|
|
4141
|
+
if (transform.kind === "slice") {
|
|
4142
|
+
const bounds = normalizeSliceBounds({
|
|
4143
|
+
start: transform.start,
|
|
4144
|
+
end: transform.end,
|
|
4145
|
+
count: await source.count()
|
|
4146
|
+
});
|
|
4147
|
+
let index = 0;
|
|
4148
|
+
for await (const row of source) {
|
|
4149
|
+
if (index >= bounds.end) break;
|
|
4150
|
+
if (index >= bounds.start) {
|
|
4151
|
+
yield row;
|
|
4152
|
+
}
|
|
4153
|
+
index += 1;
|
|
4154
|
+
}
|
|
4155
|
+
return;
|
|
4156
|
+
}
|
|
4157
|
+
let inputIndex = 0;
|
|
4158
|
+
let outputIndex = 0;
|
|
4159
|
+
for await (const row of source) {
|
|
4160
|
+
if (transform.kind === "filter") {
|
|
4161
|
+
if (await transform.predicate(row, inputIndex)) {
|
|
4162
|
+
yield row;
|
|
4163
|
+
outputIndex += 1;
|
|
4164
|
+
}
|
|
4165
|
+
} else {
|
|
4166
|
+
yield await transform.mapper(row, outputIndex);
|
|
4167
|
+
outputIndex += 1;
|
|
4168
|
+
}
|
|
4169
|
+
inputIndex += 1;
|
|
4170
|
+
}
|
|
4171
|
+
};
|
|
4172
|
+
const collect = async (limit) => {
|
|
4173
|
+
const rows = [];
|
|
4174
|
+
const boundedLimit = limit === void 0 ? void 0 : Math.max(0, Math.floor(limit));
|
|
4175
|
+
if (boundedLimit === 0) return rows;
|
|
4176
|
+
for await (const row of iterate()) {
|
|
4177
|
+
rows.push(row);
|
|
4178
|
+
if (boundedLimit !== void 0 && rows.length >= boundedLimit) break;
|
|
4179
|
+
}
|
|
4180
|
+
return rows;
|
|
4181
|
+
};
|
|
4182
|
+
const count = async () => {
|
|
4183
|
+
if (transform.kind === "map") return await source.count();
|
|
4184
|
+
if (transform.kind === "slice") {
|
|
4185
|
+
const bounds = normalizeSliceBounds({
|
|
4186
|
+
start: transform.start,
|
|
4187
|
+
end: transform.end,
|
|
4188
|
+
count: await source.count()
|
|
4189
|
+
});
|
|
4190
|
+
return Math.max(0, bounds.end - bounds.start);
|
|
4191
|
+
}
|
|
4192
|
+
let total = 0;
|
|
4193
|
+
for await (const _row of iterate()) {
|
|
4194
|
+
void _row;
|
|
4195
|
+
total += 1;
|
|
4196
|
+
}
|
|
4197
|
+
return total;
|
|
4198
|
+
};
|
|
4199
|
+
return createDeferredPlayDataset({
|
|
4200
|
+
datasetKind: source.datasetKind,
|
|
4201
|
+
datasetId: transformDatasetId({
|
|
4202
|
+
source,
|
|
4203
|
+
kind: transform.kind,
|
|
4204
|
+
key: options?.key
|
|
4205
|
+
}),
|
|
4206
|
+
count: 0,
|
|
4207
|
+
backing: source.backing,
|
|
4208
|
+
sourceLabel,
|
|
4209
|
+
tableNamespace: options?.key ?? null,
|
|
4210
|
+
resolvers: {
|
|
4211
|
+
count,
|
|
4212
|
+
peek: async (limit) => collect(limit),
|
|
4213
|
+
materialize: async (limit) => collect(limit),
|
|
4214
|
+
iterate: () => ({
|
|
4215
|
+
async *[Symbol.asyncIterator]() {
|
|
4216
|
+
yield* iterate();
|
|
4217
|
+
}
|
|
4218
|
+
})
|
|
4219
|
+
}
|
|
4220
|
+
});
|
|
4221
|
+
}
|
|
4222
|
+
function createDeferredPlayDataset(input) {
|
|
4223
|
+
return new DeferredPlayDataset({
|
|
4224
|
+
...input,
|
|
4225
|
+
previewRows: input.previewRows ?? []
|
|
4226
|
+
});
|
|
4227
|
+
}
|
|
4228
|
+
function createPlayDataset(rows, metadata) {
|
|
4229
|
+
const materializedRows = [...rows];
|
|
4230
|
+
return createDeferredPlayDataset({
|
|
4231
|
+
datasetKind: metadata?.kind ?? "map",
|
|
4232
|
+
datasetId: metadata?.datasetId ?? `${metadata?.kind ?? "map"}:${metadata?.tableNamespace ?? metadata?.sourceLabel ?? "inline"}`,
|
|
4233
|
+
count: materializedRows.length,
|
|
4234
|
+
previewRows: materializedRows.slice(0, 5),
|
|
4235
|
+
sourceLabel: metadata?.sourceLabel ?? null,
|
|
4236
|
+
tableNamespace: metadata?.tableNamespace ?? null,
|
|
4237
|
+
resolvers: {
|
|
4238
|
+
count: async () => materializedRows.length,
|
|
4239
|
+
peek: async (limit) => materializedRows.slice(0, Math.max(0, limit)),
|
|
4240
|
+
materialize: async (limit) => limit === void 0 ? [...materializedRows] : materializedRows.slice(0, Math.max(0, limit)),
|
|
4241
|
+
iterate: () => ({
|
|
4242
|
+
async *[Symbol.asyncIterator]() {
|
|
4243
|
+
for (const row of materializedRows) {
|
|
4244
|
+
yield row;
|
|
4245
|
+
}
|
|
4246
|
+
}
|
|
4247
|
+
})
|
|
4248
|
+
}
|
|
4249
|
+
});
|
|
4250
|
+
}
|
|
4251
|
+
|
|
4252
|
+
// ../shared_libs/plays/row-identity.ts
|
|
4253
|
+
var POSTGRES_IDENTIFIER_MAX_LENGTH = 63;
|
|
4254
|
+
var MAP_KEY_NAMESPACE_MAX_LENGTH = POSTGRES_IDENTIFIER_MAX_LENGTH;
|
|
4255
|
+
var SHA256_INITIAL_HASH = [
|
|
4256
|
+
1779033703,
|
|
4257
|
+
3144134277,
|
|
4258
|
+
1013904242,
|
|
4259
|
+
2773480762,
|
|
4260
|
+
1359893119,
|
|
4261
|
+
2600822924,
|
|
4262
|
+
528734635,
|
|
4263
|
+
1541459225
|
|
4264
|
+
];
|
|
4265
|
+
var SHA256_ROUND_CONSTANTS = [
|
|
4266
|
+
1116352408,
|
|
4267
|
+
1899447441,
|
|
4268
|
+
3049323471,
|
|
4269
|
+
3921009573,
|
|
4270
|
+
961987163,
|
|
4271
|
+
1508970993,
|
|
4272
|
+
2453635748,
|
|
4273
|
+
2870763221,
|
|
4274
|
+
3624381080,
|
|
4275
|
+
310598401,
|
|
4276
|
+
607225278,
|
|
4277
|
+
1426881987,
|
|
4278
|
+
1925078388,
|
|
4279
|
+
2162078206,
|
|
4280
|
+
2614888103,
|
|
4281
|
+
3248222580,
|
|
4282
|
+
3835390401,
|
|
4283
|
+
4022224774,
|
|
4284
|
+
264347078,
|
|
4285
|
+
604807628,
|
|
4286
|
+
770255983,
|
|
4287
|
+
1249150122,
|
|
4288
|
+
1555081692,
|
|
4289
|
+
1996064986,
|
|
4290
|
+
2554220882,
|
|
4291
|
+
2821834349,
|
|
4292
|
+
2952996808,
|
|
4293
|
+
3210313671,
|
|
4294
|
+
3336571891,
|
|
4295
|
+
3584528711,
|
|
4296
|
+
113926993,
|
|
4297
|
+
338241895,
|
|
4298
|
+
666307205,
|
|
4299
|
+
773529912,
|
|
4300
|
+
1294757372,
|
|
4301
|
+
1396182291,
|
|
4302
|
+
1695183700,
|
|
4303
|
+
1986661051,
|
|
4304
|
+
2177026350,
|
|
4305
|
+
2456956037,
|
|
4306
|
+
2730485921,
|
|
4307
|
+
2820302411,
|
|
4308
|
+
3259730800,
|
|
4309
|
+
3345764771,
|
|
4310
|
+
3516065817,
|
|
4311
|
+
3600352804,
|
|
4312
|
+
4094571909,
|
|
4313
|
+
275423344,
|
|
4314
|
+
430227734,
|
|
4315
|
+
506948616,
|
|
4316
|
+
659060556,
|
|
4317
|
+
883997877,
|
|
4318
|
+
958139571,
|
|
4319
|
+
1322822218,
|
|
4320
|
+
1537002063,
|
|
4321
|
+
1747873779,
|
|
4322
|
+
1955562222,
|
|
4323
|
+
2024104815,
|
|
4324
|
+
2227730452,
|
|
4325
|
+
2361852424,
|
|
4326
|
+
2428436474,
|
|
4327
|
+
2756734187,
|
|
4328
|
+
3204031479,
|
|
4329
|
+
3329325298
|
|
4330
|
+
];
|
|
4331
|
+
function rightRotate32(value, bits) {
|
|
4332
|
+
return value >>> bits | value << 32 - bits;
|
|
4333
|
+
}
|
|
4334
|
+
function sha256Hex(input) {
|
|
4335
|
+
const bytes = Array.from(new TextEncoder().encode(input));
|
|
4336
|
+
const bitLength = bytes.length * 8;
|
|
4337
|
+
bytes.push(128);
|
|
4338
|
+
while (bytes.length % 64 !== 56) {
|
|
4339
|
+
bytes.push(0);
|
|
4340
|
+
}
|
|
4341
|
+
const highBits = Math.floor(bitLength / 4294967296);
|
|
4342
|
+
const lowBits = bitLength >>> 0;
|
|
4343
|
+
bytes.push(
|
|
4344
|
+
highBits >>> 24 & 255,
|
|
4345
|
+
highBits >>> 16 & 255,
|
|
4346
|
+
highBits >>> 8 & 255,
|
|
4347
|
+
highBits & 255,
|
|
4348
|
+
lowBits >>> 24 & 255,
|
|
4349
|
+
lowBits >>> 16 & 255,
|
|
4350
|
+
lowBits >>> 8 & 255,
|
|
4351
|
+
lowBits & 255
|
|
4352
|
+
);
|
|
4353
|
+
const hash = [...SHA256_INITIAL_HASH];
|
|
4354
|
+
const words = new Array(64).fill(0);
|
|
4355
|
+
for (let offset = 0; offset < bytes.length; offset += 64) {
|
|
4356
|
+
for (let index = 0; index < 16; index += 1) {
|
|
4357
|
+
const wordOffset = offset + index * 4;
|
|
4358
|
+
words[index] = (bytes[wordOffset] ?? 0) << 24 | (bytes[wordOffset + 1] ?? 0) << 16 | (bytes[wordOffset + 2] ?? 0) << 8 | (bytes[wordOffset + 3] ?? 0);
|
|
4359
|
+
}
|
|
4360
|
+
for (let index = 16; index < 64; index += 1) {
|
|
4361
|
+
const s0 = rightRotate32(words[index - 15], 7) ^ rightRotate32(words[index - 15], 18) ^ words[index - 15] >>> 3;
|
|
4362
|
+
const s1 = rightRotate32(words[index - 2], 17) ^ rightRotate32(words[index - 2], 19) ^ words[index - 2] >>> 10;
|
|
4363
|
+
words[index] = words[index - 16] + s0 + words[index - 7] + s1 >>> 0;
|
|
4364
|
+
}
|
|
4365
|
+
let [a, b, c, d, e, f, g, h] = hash;
|
|
4366
|
+
for (let index = 0; index < 64; index += 1) {
|
|
4367
|
+
const s1 = rightRotate32(e, 6) ^ rightRotate32(e, 11) ^ rightRotate32(e, 25);
|
|
4368
|
+
const ch = e & f ^ ~e & g;
|
|
4369
|
+
const temp1 = h + s1 + ch + SHA256_ROUND_CONSTANTS[index] + words[index] >>> 0;
|
|
4370
|
+
const s0 = rightRotate32(a, 2) ^ rightRotate32(a, 13) ^ rightRotate32(a, 22);
|
|
4371
|
+
const maj = a & b ^ a & c ^ b & c;
|
|
4372
|
+
const temp2 = s0 + maj >>> 0;
|
|
4373
|
+
h = g;
|
|
4374
|
+
g = f;
|
|
4375
|
+
f = e;
|
|
4376
|
+
e = d + temp1 >>> 0;
|
|
4377
|
+
d = c;
|
|
4378
|
+
c = b;
|
|
4379
|
+
b = a;
|
|
4380
|
+
a = temp1 + temp2 >>> 0;
|
|
4381
|
+
}
|
|
4382
|
+
hash[0] = hash[0] + a >>> 0;
|
|
4383
|
+
hash[1] = hash[1] + b >>> 0;
|
|
4384
|
+
hash[2] = hash[2] + c >>> 0;
|
|
4385
|
+
hash[3] = hash[3] + d >>> 0;
|
|
4386
|
+
hash[4] = hash[4] + e >>> 0;
|
|
4387
|
+
hash[5] = hash[5] + f >>> 0;
|
|
4388
|
+
hash[6] = hash[6] + g >>> 0;
|
|
4389
|
+
hash[7] = hash[7] + h >>> 0;
|
|
4390
|
+
}
|
|
4391
|
+
return hash.map((word) => word.toString(16).padStart(8, "0")).join("");
|
|
4392
|
+
}
|
|
4393
|
+
function sanitizeIdentifierPart(value) {
|
|
4394
|
+
return value.trim().replace(/[^a-z0-9]+/gi, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
4395
|
+
}
|
|
4396
|
+
function validateIdentifierPart(rawValue, label, maxLength) {
|
|
4397
|
+
const sanitized = sanitizeIdentifierPart(rawValue);
|
|
4398
|
+
if (!sanitized) {
|
|
4399
|
+
throw new Error(
|
|
4400
|
+
`${label} must contain at least one letter or number after normalization. Use only letters, numbers, underscores, or hyphens.`
|
|
4401
|
+
);
|
|
4402
|
+
}
|
|
4403
|
+
if (sanitized.length > maxLength) {
|
|
4404
|
+
throw new Error(
|
|
4405
|
+
`${label} is too long after normalization (${sanitized.length}/${maxLength}). Shorten it to ${maxLength} characters or fewer. Normalized value: "${sanitized}".`
|
|
4406
|
+
);
|
|
4407
|
+
}
|
|
4408
|
+
return sanitized;
|
|
4409
|
+
}
|
|
4410
|
+
function normalizeTableNamespace(value) {
|
|
4411
|
+
return validateIdentifierPart(
|
|
4412
|
+
value,
|
|
4413
|
+
"ctx.dataset() key",
|
|
4414
|
+
MAP_KEY_NAMESPACE_MAX_LENGTH
|
|
4415
|
+
);
|
|
4416
|
+
}
|
|
4417
|
+
|
|
3976
4418
|
// ../shared_libs/play-runtime/tool-result.ts
|
|
3977
4419
|
var TARGET_FALLBACK_KEYS = {
|
|
3978
4420
|
email: [/^email$/i, /^address$/i, /email/i],
|
|
@@ -4320,17 +4762,31 @@ function resolveListRows(result, listExtractorPaths) {
|
|
|
4320
4762
|
);
|
|
4321
4763
|
let resolvedPath = null;
|
|
4322
4764
|
let rows = null;
|
|
4765
|
+
let emptyMatch = null;
|
|
4323
4766
|
for (const candidate of candidates) {
|
|
4324
4767
|
rows = normalizeRows(getAtPath(result, candidate));
|
|
4325
|
-
if (rows) {
|
|
4768
|
+
if (!rows) {
|
|
4769
|
+
continue;
|
|
4770
|
+
}
|
|
4771
|
+
if (rows.length > 0) {
|
|
4326
4772
|
resolvedPath = candidate;
|
|
4327
4773
|
break;
|
|
4328
4774
|
}
|
|
4775
|
+
emptyMatch ??= { path: candidate, rows };
|
|
4776
|
+
}
|
|
4777
|
+
if (!rows && emptyMatch) {
|
|
4778
|
+
resolvedPath = emptyMatch.path;
|
|
4779
|
+
rows = emptyMatch.rows;
|
|
4329
4780
|
}
|
|
4330
4781
|
if (!rows) continue;
|
|
4331
4782
|
const storedPath = resolvedPath ?? path;
|
|
4332
4783
|
const name = storedPath.split(".").filter(Boolean).at(-1)?.replace(/\[\d+\]$/, "");
|
|
4333
|
-
|
|
4784
|
+
const listName = name || storedPath;
|
|
4785
|
+
const existing = lists[listName];
|
|
4786
|
+
if (existing?.rows.length && rows.length === 0) {
|
|
4787
|
+
continue;
|
|
4788
|
+
}
|
|
4789
|
+
lists[listName] = { path: storedPath, rows };
|
|
4334
4790
|
}
|
|
4335
4791
|
return lists;
|
|
4336
4792
|
}
|
|
@@ -4478,10 +4934,24 @@ function buildExtractedAccessors(targets) {
|
|
|
4478
4934
|
})
|
|
4479
4935
|
);
|
|
4480
4936
|
}
|
|
4481
|
-
function buildListAccessors(resolved, lists) {
|
|
4937
|
+
function buildListAccessors(resolved, lists, toolId, executionDiscriminator) {
|
|
4482
4938
|
return Object.fromEntries(
|
|
4483
4939
|
Object.entries(lists).map(([name, metadata]) => {
|
|
4484
4940
|
const rows = resolved[name]?.rows ?? [];
|
|
4941
|
+
const datasetDiscriminator = `${executionDiscriminator}:${listRowsFingerprint(rows)}`;
|
|
4942
|
+
const dataset = createPlayDataset(rows, {
|
|
4943
|
+
kind: "csv",
|
|
4944
|
+
sourceLabel: metadata.path,
|
|
4945
|
+
tableNamespace: listTableNamespace(
|
|
4946
|
+
toolId,
|
|
4947
|
+
name,
|
|
4948
|
+
metadata.path,
|
|
4949
|
+
datasetDiscriminator
|
|
4950
|
+
),
|
|
4951
|
+
datasetId: `tool-list:${sha256Hex(
|
|
4952
|
+
`${toolId}:${metadata.path}:${datasetDiscriminator}`
|
|
4953
|
+
)}`
|
|
4954
|
+
});
|
|
4485
4955
|
const accessor = {
|
|
4486
4956
|
path: metadata.path,
|
|
4487
4957
|
count: metadata.count,
|
|
@@ -4489,7 +4959,7 @@ function buildListAccessors(resolved, lists) {
|
|
|
4489
4959
|
};
|
|
4490
4960
|
Object.defineProperty(accessor, "get", {
|
|
4491
4961
|
value() {
|
|
4492
|
-
return
|
|
4962
|
+
return dataset;
|
|
4493
4963
|
},
|
|
4494
4964
|
enumerable: false
|
|
4495
4965
|
});
|
|
@@ -4497,6 +4967,37 @@ function buildListAccessors(resolved, lists) {
|
|
|
4497
4967
|
})
|
|
4498
4968
|
);
|
|
4499
4969
|
}
|
|
4970
|
+
function listRowsFingerprint(rows) {
|
|
4971
|
+
try {
|
|
4972
|
+
return sha256Hex(
|
|
4973
|
+
JSON.stringify(
|
|
4974
|
+
{
|
|
4975
|
+
count: rows.length,
|
|
4976
|
+
rows
|
|
4977
|
+
},
|
|
4978
|
+
(_key, value) => typeof value === "bigint" ? value.toString() : value
|
|
4979
|
+
)
|
|
4980
|
+
).slice(0, 12);
|
|
4981
|
+
} catch {
|
|
4982
|
+
return sha256Hex(String(rows.length)).slice(0, 12);
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
4985
|
+
function listTableNamespace(toolId, name, path, discriminator) {
|
|
4986
|
+
const raw = `${toolId}_${name || path || "rows"}_${sha256Hex(discriminator).slice(0, 10)}`;
|
|
4987
|
+
try {
|
|
4988
|
+
return normalizeTableNamespace(raw);
|
|
4989
|
+
} catch {
|
|
4990
|
+
const hash = sha256Hex(raw).slice(0, 10);
|
|
4991
|
+
const leaf = name || path.split(".").filter(Boolean).at(-1) || "rows";
|
|
4992
|
+
let prefix = "rows";
|
|
4993
|
+
try {
|
|
4994
|
+
prefix = normalizeTableNamespace(leaf).slice(0, 52) || "rows";
|
|
4995
|
+
} catch {
|
|
4996
|
+
prefix = "rows";
|
|
4997
|
+
}
|
|
4998
|
+
return normalizeTableNamespace(`${prefix}_${hash}`);
|
|
4999
|
+
}
|
|
5000
|
+
}
|
|
4500
5001
|
function createToolExecuteResult(input) {
|
|
4501
5002
|
const result = toResultEnvelope(input.result);
|
|
4502
5003
|
const resultRoot = {
|
|
@@ -4527,7 +5028,12 @@ function createToolExecuteResult(input) {
|
|
|
4527
5028
|
...result.meta ? { meta: result.meta } : {}
|
|
4528
5029
|
};
|
|
4529
5030
|
const extractedValues = buildExtractedAccessors(targets);
|
|
4530
|
-
const extractedLists = buildListAccessors(
|
|
5031
|
+
const extractedLists = buildListAccessors(
|
|
5032
|
+
resolvedLists,
|
|
5033
|
+
lists,
|
|
5034
|
+
input.metadata.toolId,
|
|
5035
|
+
input.jobId ?? input.execution.cacheKey ?? "inline"
|
|
5036
|
+
);
|
|
4531
5037
|
const wrapper = {
|
|
4532
5038
|
status: input.status,
|
|
4533
5039
|
...input.jobId ? { job_id: input.jobId } : {},
|
|
@@ -5138,16 +5644,24 @@ function tryConvertToList(payload, options) {
|
|
|
5138
5644
|
(entry) => typeof entry === "string" && entry.trim().length > 0
|
|
5139
5645
|
) : [];
|
|
5140
5646
|
if (listExtractorPaths.length > 0) {
|
|
5647
|
+
let emptyMatch = null;
|
|
5141
5648
|
for (const root of candidateRoots(payload)) {
|
|
5142
5649
|
for (const extractorPath of listExtractorPaths) {
|
|
5143
5650
|
const resolved = getByDottedPath(root.value, extractorPath);
|
|
5144
5651
|
const rows = normalizeRows2(resolved);
|
|
5145
|
-
if (rows
|
|
5146
|
-
|
|
5652
|
+
if (!rows) {
|
|
5653
|
+
continue;
|
|
5654
|
+
}
|
|
5655
|
+
const sourcePath = root.path ? `${root.path}.${extractorPath}` : extractorPath;
|
|
5656
|
+
if (rows.length > 0) {
|
|
5147
5657
|
return { rows, strategy: "configured_paths", sourcePath };
|
|
5148
5658
|
}
|
|
5659
|
+
emptyMatch ??= { rows, strategy: "configured_paths", sourcePath };
|
|
5149
5660
|
}
|
|
5150
5661
|
}
|
|
5662
|
+
if (emptyMatch) {
|
|
5663
|
+
return emptyMatch;
|
|
5664
|
+
}
|
|
5151
5665
|
}
|
|
5152
5666
|
for (const root of candidateRoots(payload)) {
|
|
5153
5667
|
const candidate = findBestArrayCandidate(root.value, root.path ?? "");
|
|
@@ -5171,9 +5685,9 @@ function writeJsonOutputFile(payload, stem) {
|
|
|
5171
5685
|
(0, import_node_fs3.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
5172
5686
|
return outputPath;
|
|
5173
5687
|
}
|
|
5174
|
-
function writeCsvOutputFile(rows, stem) {
|
|
5175
|
-
const
|
|
5176
|
-
|
|
5688
|
+
function writeCsvOutputFile(rows, stem, options) {
|
|
5689
|
+
const outputPath = options?.outPath ? options.outPath : (0, import_node_path3.join)(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
|
|
5690
|
+
(0, import_node_fs3.mkdirSync)((0, import_node_path3.dirname)(outputPath), { recursive: true });
|
|
5177
5691
|
const seen = /* @__PURE__ */ new Set();
|
|
5178
5692
|
const columns = [];
|
|
5179
5693
|
for (const row of rows) {
|