deepline 0.2.13 → 0.2.15
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/sdk/src/index.ts +3 -0
- package/dist/bundling-sources/sdk/src/play.ts +150 -691
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/child-execution-strategy.ts +7 -1
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +249 -51
- package/dist/bundling-sources/shared_libs/play-runtime/csv-rename.ts +10 -6
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +32 -51
- package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +11 -22
- package/dist/bundling-sources/shared_libs/play-runtime/durable-call-policy.ts +34 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-call-execution.ts +2 -1
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger-projection-contract.ts +95 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +11 -6
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-store-adapter.ts +38 -9
- package/dist/bundling-sources/shared_libs/play-runtime/secret-capability.ts +23 -15
- package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +3 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +2222 -0
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +3 -2
- package/dist/bundling-sources/shared_libs/plays/compiler-manifest.ts +2 -0
- package/dist/bundling-sources/shared_libs/plays/contracts.ts +16 -0
- package/dist/bundling-sources/shared_libs/plays/input-contract-definition.ts +28 -0
- package/dist/bundling-sources/shared_libs/plays/input-contract.ts +3 -3
- package/dist/cli/index.js +5074 -829
- package/dist/cli/index.mjs +5019 -759
- package/dist/compiler-manifest-xFkbJX2B.d.mts +2517 -0
- package/dist/compiler-manifest-xFkbJX2B.d.ts +2517 -0
- package/dist/index.d.mts +36 -1011
- package/dist/index.d.ts +36 -1011
- package/dist/index.js +25 -7
- package/dist/index.mjs +25 -7
- package/dist/plays/bundle-play-file.d.mts +5 -8
- package/dist/plays/bundle-play-file.d.ts +5 -8
- package/dist/plays/bundle-play-file.mjs +3844 -3
- package/package.json +1 -1
- package/dist/bundling-sources/shared_libs/plays/source-metadata.ts +0 -240
- package/dist/tool-execution-error-4-rhemLQ.d.mts +0 -446
- package/dist/tool-execution-error-4-rhemLQ.d.ts +0 -446
|
@@ -160,7 +160,7 @@ export const SDK_RELEASE = {
|
|
|
160
160
|
// 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
|
|
161
161
|
// exposed storage-dependent synchronous access. This deliberate minor
|
|
162
162
|
// release keeps lazy paging semantics independent of row residency.
|
|
163
|
-
version: '0.2.
|
|
163
|
+
version: '0.2.15',
|
|
164
164
|
contracts: {
|
|
165
165
|
api: {
|
|
166
166
|
name: 'sdk-http-api',
|
|
@@ -36,6 +36,12 @@ export function ctxRunPlayInlineOnlyMessage(
|
|
|
36
36
|
childPlayName: string,
|
|
37
37
|
reason: CtxRunPlayInlineOnlyReason,
|
|
38
38
|
): string {
|
|
39
|
+
const contractPath =
|
|
40
|
+
reason === 'explicit_timeout'
|
|
41
|
+
? 'ctx.runPlay.options.timeoutMs'
|
|
42
|
+
: reason === 'explicit_child_workflow'
|
|
43
|
+
? 'ctx.runPlay.options.execution'
|
|
44
|
+
: 'ctx.runPlay';
|
|
39
45
|
const detail: Record<CtxRunPlayInlineOnlyReason, string> = {
|
|
40
46
|
missing_static_contract: 'its static contract could not be resolved',
|
|
41
47
|
dataset_child: 'it uses ctx.dataset(), ctx.csv(), or a Runtime Sheet',
|
|
@@ -59,7 +65,7 @@ export function ctxRunPlayInlineOnlyMessage(
|
|
|
59
65
|
'Remove execution: "child-workflow" for a scalar lookup, or trigger the child as a top-level play when it needs its own lifecycle.',
|
|
60
66
|
};
|
|
61
67
|
return (
|
|
62
|
-
`${CTX_RUN_PLAY_INLINE_ONLY}: ctx.runPlay("${childPlayName}") can only call a scalar, per-record play; ` +
|
|
68
|
+
`${CTX_RUN_PLAY_INLINE_ONLY}: [play_authoring_run_play_option_invalid path=${contractPath}] ctx.runPlay("${childPlayName}") can only call a scalar, per-record play; ` +
|
|
63
69
|
`${detail[reason]}. ${nextStep[reason]}`
|
|
64
70
|
);
|
|
65
71
|
}
|
|
@@ -142,7 +142,17 @@ import {
|
|
|
142
142
|
buildDurableToolCallCacheKey,
|
|
143
143
|
buildDurableToolProviderIdempotencyKey,
|
|
144
144
|
buildDurableToolReceiptPrefix,
|
|
145
|
+
resolveDurableCallCachePolicy,
|
|
145
146
|
} from './durable-call-cache';
|
|
147
|
+
import {
|
|
148
|
+
PLAY_AUTHORING_CONTRACT_EDITION,
|
|
149
|
+
normalizePlayAuthoringCustomerDbStatement,
|
|
150
|
+
validateOptionalPlayAuthoringField,
|
|
151
|
+
validatePlayAuthoringField,
|
|
152
|
+
type PlayAuthoringContractEdition,
|
|
153
|
+
type PlaySqlQuery,
|
|
154
|
+
type PlayAuthoringRuntimeContext,
|
|
155
|
+
} from '../plays/authoring-contract';
|
|
146
156
|
import {
|
|
147
157
|
RuntimeReceiptLeaseLostError,
|
|
148
158
|
RuntimeReceiptWaitTimeoutError,
|
|
@@ -236,7 +246,7 @@ import {
|
|
|
236
246
|
import type {
|
|
237
247
|
CsvOptions,
|
|
238
248
|
RowState,
|
|
239
|
-
|
|
249
|
+
RuntimeDatasetOptions,
|
|
240
250
|
ToolCallRequest,
|
|
241
251
|
ToolBatchResult,
|
|
242
252
|
ContextOptions,
|
|
@@ -248,7 +258,7 @@ import type {
|
|
|
248
258
|
MapFieldDefinition,
|
|
249
259
|
MapFieldResolver,
|
|
250
260
|
ToolCallOptions,
|
|
251
|
-
|
|
261
|
+
RuntimeStepOptions,
|
|
252
262
|
FetchOptions,
|
|
253
263
|
ResolvedPlayExecution,
|
|
254
264
|
PlayFetchResponse,
|
|
@@ -304,6 +314,8 @@ type InlineCompositionStore = {
|
|
|
304
314
|
staticPipeline: ContextOptions['staticPipeline'];
|
|
305
315
|
/** Immutable error contract pinned by the child play artifact. */
|
|
306
316
|
toolErrorSchemaVersion: ToolExecutionErrorSchemaVersion;
|
|
317
|
+
/** Immutable authoring semantics pinned by the child play artifact. */
|
|
318
|
+
authoringContractEdition: PlayAuthoringContractEdition;
|
|
307
319
|
};
|
|
308
320
|
const inlineCompositionContext =
|
|
309
321
|
new AsyncLocalStorage<InlineCompositionStore>();
|
|
@@ -575,13 +587,21 @@ export async function reconcileNodeRuntimeMapResultsWithPersistedSheet(input: {
|
|
|
575
587
|
export function resolveToolRuntimeTimeoutMs(
|
|
576
588
|
toolId: string,
|
|
577
589
|
requestedTimeoutMs?: number,
|
|
590
|
+
authoringContractEdition: PlayAuthoringContractEdition = PLAY_AUTHORING_CONTRACT_EDITION,
|
|
578
591
|
): number | undefined {
|
|
579
|
-
if (
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
592
|
+
if (requestedTimeoutMs !== undefined) {
|
|
593
|
+
if (authoringContractEdition >= 2) {
|
|
594
|
+
validatePlayAuthoringField(
|
|
595
|
+
'ctx.tools.execute.timeoutMs',
|
|
596
|
+
requestedTimeoutMs,
|
|
597
|
+
);
|
|
598
|
+
return requestedTimeoutMs;
|
|
599
|
+
}
|
|
600
|
+
// Edition 1 rounded positive finite values and treated every other value
|
|
601
|
+
// as omitted. Preserve that behavior for already-published artifacts.
|
|
602
|
+
if (Number.isFinite(requestedTimeoutMs) && requestedTimeoutMs > 0) {
|
|
603
|
+
return Math.max(1, Math.ceil(requestedTimeoutMs));
|
|
604
|
+
}
|
|
585
605
|
}
|
|
586
606
|
const normalized = toolId.trim().toLowerCase();
|
|
587
607
|
// Long-inference tools keep their explicit 15-minute budget. Every other tool
|
|
@@ -1135,7 +1155,7 @@ class RuntimeDatasetBuilder<T extends Record<string, unknown>> {
|
|
|
1135
1155
|
private readonly builder: StepProgramDatasetBuilder<
|
|
1136
1156
|
RuntimeStepProgramStep,
|
|
1137
1157
|
RuntimeStepProgramStep['resolver'],
|
|
1138
|
-
|
|
1158
|
+
RuntimeDatasetOptions<T>,
|
|
1139
1159
|
Promise<PlayDataset<Record<string, unknown>>>
|
|
1140
1160
|
>;
|
|
1141
1161
|
|
|
@@ -1181,7 +1201,7 @@ class RuntimeDatasetBuilder<T extends Record<string, unknown>> {
|
|
|
1181
1201
|
}
|
|
1182
1202
|
|
|
1183
1203
|
run(
|
|
1184
|
-
options?:
|
|
1204
|
+
options?: RuntimeDatasetOptions<T>,
|
|
1185
1205
|
): Promise<PlayDataset<Record<string, unknown>>> {
|
|
1186
1206
|
return this.builder.run(options);
|
|
1187
1207
|
}
|
|
@@ -1288,7 +1308,20 @@ function createPacingResolver(
|
|
|
1288
1308
|
};
|
|
1289
1309
|
}
|
|
1290
1310
|
|
|
1291
|
-
|
|
1311
|
+
type ScalarPlayAuthoringRuntimeContext = Pick<
|
|
1312
|
+
PlayAuthoringRuntimeContext,
|
|
1313
|
+
| 'tools'
|
|
1314
|
+
| 'customerDb'
|
|
1315
|
+
| 'tool'
|
|
1316
|
+
| 'step'
|
|
1317
|
+
| 'fetch'
|
|
1318
|
+
| 'secrets'
|
|
1319
|
+
| 'runPlay'
|
|
1320
|
+
| 'log'
|
|
1321
|
+
| 'sleep'
|
|
1322
|
+
>;
|
|
1323
|
+
|
|
1324
|
+
export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
1292
1325
|
private rowStates = new Map<number, RowState>();
|
|
1293
1326
|
private toolCallQueue: ToolCallRequest[] = [];
|
|
1294
1327
|
private pendingRuntimeToolOwnershipAssertions: Array<{
|
|
@@ -1423,7 +1456,7 @@ export class PlayContextImpl {
|
|
|
1423
1456
|
input: Record<string, unknown>;
|
|
1424
1457
|
description?: string;
|
|
1425
1458
|
force?: boolean;
|
|
1426
|
-
staleAfterSeconds?: number;
|
|
1459
|
+
staleAfterSeconds?: number | null;
|
|
1427
1460
|
timeoutMs?: number;
|
|
1428
1461
|
receiptWaitMs?: number;
|
|
1429
1462
|
}): Promise<TOutput> => {
|
|
@@ -1432,20 +1465,37 @@ export class PlayContextImpl {
|
|
|
1432
1465
|
'ctx.tools.execute requires a request object: ctx.tools.execute({ id, tool, input, description }).',
|
|
1433
1466
|
);
|
|
1434
1467
|
}
|
|
1468
|
+
validatePlayAuthoringField('ctx.tools.execute.id', request.id);
|
|
1469
|
+
validatePlayAuthoringField('ctx.tools.execute.tool', request.tool);
|
|
1470
|
+
validatePlayAuthoringField('ctx.tools.execute.input', request.input);
|
|
1471
|
+
if (request.description !== undefined) {
|
|
1472
|
+
validatePlayAuthoringField(
|
|
1473
|
+
'ctx.tools.execute.description',
|
|
1474
|
+
request.description,
|
|
1475
|
+
);
|
|
1476
|
+
}
|
|
1477
|
+
if (request.force !== undefined) {
|
|
1478
|
+
validatePlayAuthoringField('ctx.tools.execute.force', request.force);
|
|
1479
|
+
}
|
|
1480
|
+
assertNoSecretTaint(request.input, 'ctx.tools.execute input');
|
|
1435
1481
|
if (
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
typeof request.tool !== 'string' ||
|
|
1439
|
-
!request.tool.trim() ||
|
|
1440
|
-
!request.input ||
|
|
1441
|
-
typeof request.input !== 'object' ||
|
|
1442
|
-
Array.isArray(request.input)
|
|
1482
|
+
request.timeoutMs !== undefined &&
|
|
1483
|
+
this.currentAuthoringContractEdition >= 2
|
|
1443
1484
|
) {
|
|
1444
|
-
|
|
1445
|
-
'ctx.tools.execute
|
|
1485
|
+
validatePlayAuthoringField(
|
|
1486
|
+
'ctx.tools.execute.timeoutMs',
|
|
1487
|
+
request.timeoutMs,
|
|
1488
|
+
);
|
|
1489
|
+
}
|
|
1490
|
+
if (
|
|
1491
|
+
request.receiptWaitMs !== undefined &&
|
|
1492
|
+
this.currentAuthoringContractEdition >= 2
|
|
1493
|
+
) {
|
|
1494
|
+
validatePlayAuthoringField(
|
|
1495
|
+
'ctx.tools.execute.receiptWaitMs',
|
|
1496
|
+
request.receiptWaitMs,
|
|
1446
1497
|
);
|
|
1447
1498
|
}
|
|
1448
|
-
assertNoSecretTaint(request.input, 'ctx.tools.execute input');
|
|
1449
1499
|
const force =
|
|
1450
1500
|
request.force === true ||
|
|
1451
1501
|
toolExecutionOverrides.getStore()?.force === true;
|
|
@@ -1478,19 +1528,55 @@ export class PlayContextImpl {
|
|
|
1478
1528
|
},
|
|
1479
1529
|
};
|
|
1480
1530
|
|
|
1531
|
+
async tool<TOutput = unknown>(
|
|
1532
|
+
key: string,
|
|
1533
|
+
toolId: string,
|
|
1534
|
+
input: Record<string, unknown>,
|
|
1535
|
+
options?: { description?: string },
|
|
1536
|
+
): Promise<ToolExecuteResult<TOutput>> {
|
|
1537
|
+
validatePlayAuthoringField('ctx.tool.key', key);
|
|
1538
|
+
validatePlayAuthoringField('ctx.tool.tool', toolId);
|
|
1539
|
+
validatePlayAuthoringField('ctx.tool.input', input);
|
|
1540
|
+
if (options?.description !== undefined) {
|
|
1541
|
+
validatePlayAuthoringField(
|
|
1542
|
+
'ctx.tool.options.description',
|
|
1543
|
+
options.description,
|
|
1544
|
+
);
|
|
1545
|
+
}
|
|
1546
|
+
return (await this.tools.execute<ToolExecuteResult<TOutput>>({
|
|
1547
|
+
id: key,
|
|
1548
|
+
tool: toolId,
|
|
1549
|
+
input,
|
|
1550
|
+
...(options?.description ? { description: options.description } : {}),
|
|
1551
|
+
})) as ToolExecuteResult<TOutput>;
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1481
1554
|
async __deeplineRunWithForcedTools<T>(run: () => Promise<T>): Promise<T> {
|
|
1482
1555
|
return await toolExecutionOverrides.run({ force: true }, run);
|
|
1483
1556
|
}
|
|
1484
1557
|
readonly customerDb = {
|
|
1485
1558
|
query: async <TRow extends object = Record<string, unknown>>(
|
|
1486
|
-
statement: string,
|
|
1559
|
+
statement: PlaySqlQuery | string,
|
|
1487
1560
|
options?: { maxRows?: number; timeoutMs?: number },
|
|
1488
1561
|
): Promise<TRow[]> => {
|
|
1562
|
+
const sql = normalizePlayAuthoringCustomerDbStatement(statement);
|
|
1563
|
+
if (options?.maxRows !== undefined) {
|
|
1564
|
+
validatePlayAuthoringField(
|
|
1565
|
+
'ctx.customerDb.query.options.maxRows',
|
|
1566
|
+
options.maxRows,
|
|
1567
|
+
);
|
|
1568
|
+
}
|
|
1569
|
+
if (options?.timeoutMs !== undefined) {
|
|
1570
|
+
validatePlayAuthoringField(
|
|
1571
|
+
'ctx.customerDb.query.options.timeoutMs',
|
|
1572
|
+
options.timeoutMs,
|
|
1573
|
+
);
|
|
1574
|
+
}
|
|
1489
1575
|
const result = (await this.tools.execute({
|
|
1490
1576
|
id: `customer_db_query_${this.customerDbQueryIndex++}`,
|
|
1491
1577
|
tool: 'query_customer_db',
|
|
1492
1578
|
input: {
|
|
1493
|
-
sql
|
|
1579
|
+
sql,
|
|
1494
1580
|
...(options?.maxRows !== undefined
|
|
1495
1581
|
? { max_rows: options.maxRows }
|
|
1496
1582
|
: {}),
|
|
@@ -1681,6 +1767,14 @@ export class PlayContextImpl {
|
|
|
1681
1767
|
);
|
|
1682
1768
|
}
|
|
1683
1769
|
|
|
1770
|
+
private get currentAuthoringContractEdition(): PlayAuthoringContractEdition {
|
|
1771
|
+
return (
|
|
1772
|
+
this.activeInlineComposition?.authoringContractEdition ??
|
|
1773
|
+
this.#options.authoringContractEdition ??
|
|
1774
|
+
PLAY_AUTHORING_CONTRACT_EDITION
|
|
1775
|
+
);
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1684
1778
|
private recordPlayCallStep(input: {
|
|
1685
1779
|
playId: string;
|
|
1686
1780
|
execution?: 'inline';
|
|
@@ -3137,6 +3231,14 @@ export class PlayContextImpl {
|
|
|
3137
3231
|
execute: (context: { leaseId: string | null }) => Promise<T>;
|
|
3138
3232
|
},
|
|
3139
3233
|
): Promise<T> {
|
|
3234
|
+
const stalePolicy = resolveDurableCallCachePolicy(
|
|
3235
|
+
opts.staleAfterSeconds,
|
|
3236
|
+
operation === 'step'
|
|
3237
|
+
? 'ctx.step.staleAfterSeconds'
|
|
3238
|
+
: operation === 'fetch'
|
|
3239
|
+
? 'ctx.fetch.staleAfterSeconds'
|
|
3240
|
+
: 'ctx.tools.execute.staleAfterSeconds',
|
|
3241
|
+
);
|
|
3140
3242
|
const receiptKey =
|
|
3141
3243
|
opts.receiptKey?.trim() ||
|
|
3142
3244
|
durableCtxKey({
|
|
@@ -3145,7 +3247,7 @@ export class PlayContextImpl {
|
|
|
3145
3247
|
operation,
|
|
3146
3248
|
id,
|
|
3147
3249
|
semanticKey: opts.semanticKey,
|
|
3148
|
-
staleAfterSeconds:
|
|
3250
|
+
staleAfterSeconds: stalePolicy.staleAfterSeconds,
|
|
3149
3251
|
});
|
|
3150
3252
|
return await executeWithDurableRuntimeReceipt<T>({
|
|
3151
3253
|
operation,
|
|
@@ -3153,7 +3255,7 @@ export class PlayContextImpl {
|
|
|
3153
3255
|
runId: this.currentReceiptOwnerRunId,
|
|
3154
3256
|
receiptKey,
|
|
3155
3257
|
store: this.durableReceiptExecutionStore(),
|
|
3156
|
-
force: opts.force,
|
|
3258
|
+
force: opts.force === true || stalePolicy.forceRefresh,
|
|
3157
3259
|
repairRunningReceiptForSameRun: opts.repairRunningReceiptForSameRun,
|
|
3158
3260
|
repairRunningReceiptForSameRunAfterWaitTimeout:
|
|
3159
3261
|
opts.repairRunningReceiptForSameRunAfterWaitTimeout,
|
|
@@ -3483,15 +3585,20 @@ export class PlayContextImpl {
|
|
|
3483
3585
|
forceFailedRefresh: boolean;
|
|
3484
3586
|
staleAfterSeconds?: number | null;
|
|
3485
3587
|
} {
|
|
3588
|
+
const stalePolicy = resolveDurableCallCachePolicy(
|
|
3589
|
+
options?.staleAfterSeconds,
|
|
3590
|
+
);
|
|
3486
3591
|
return {
|
|
3487
3592
|
force:
|
|
3488
3593
|
options?.force === true ||
|
|
3594
|
+
stalePolicy.forceRefresh ||
|
|
3489
3595
|
this.#options.cachePolicy?.forceToolRefresh === true,
|
|
3490
3596
|
forceFailedRefresh:
|
|
3491
3597
|
options?.force === true ||
|
|
3598
|
+
stalePolicy.forceRefresh ||
|
|
3492
3599
|
this.#options.cachePolicy?.forceToolRefresh === true ||
|
|
3493
3600
|
this.#options.cachePolicy?.forceFailedToolRefresh === true,
|
|
3494
|
-
staleAfterSeconds:
|
|
3601
|
+
staleAfterSeconds: stalePolicy.staleAfterSeconds,
|
|
3495
3602
|
};
|
|
3496
3603
|
}
|
|
3497
3604
|
|
|
@@ -4024,10 +4131,19 @@ export class PlayContextImpl {
|
|
|
4024
4131
|
|
|
4025
4132
|
async csv(
|
|
4026
4133
|
path: string,
|
|
4027
|
-
|
|
4134
|
+
options?: CsvOptions,
|
|
4028
4135
|
): Promise<PlayDataset<Record<string, unknown>>> {
|
|
4029
4136
|
this.assertInlineChildContract('dataset_child');
|
|
4030
|
-
|
|
4137
|
+
if (options) {
|
|
4138
|
+
for (const [field, value] of [
|
|
4139
|
+
['ctx.csv.options.description', options.description],
|
|
4140
|
+
['ctx.csv.options.columns', options.columns],
|
|
4141
|
+
['ctx.csv.options.rename', options.rename],
|
|
4142
|
+
['ctx.csv.options.required', options.required],
|
|
4143
|
+
] as const) {
|
|
4144
|
+
validateOptionalPlayAuthoringField(field, value);
|
|
4145
|
+
}
|
|
4146
|
+
}
|
|
4031
4147
|
// In cloud mode, CSV data is passed in — path is just a label
|
|
4032
4148
|
// The activity loads the actual data before creating the ctx
|
|
4033
4149
|
throw new Error(
|
|
@@ -4044,7 +4160,7 @@ export class PlayContextImpl {
|
|
|
4044
4160
|
key: string,
|
|
4045
4161
|
items: PlayDatasetInput<T>,
|
|
4046
4162
|
input: RuntimeStepProgram,
|
|
4047
|
-
options?:
|
|
4163
|
+
options?: RuntimeDatasetOptions<T>,
|
|
4048
4164
|
): Promise<PlayDataset<Record<string, unknown>>>;
|
|
4049
4165
|
dataset<
|
|
4050
4166
|
T extends Record<string, unknown>,
|
|
@@ -4053,7 +4169,7 @@ export class PlayContextImpl {
|
|
|
4053
4169
|
key: string,
|
|
4054
4170
|
items: PlayDatasetInput<T>,
|
|
4055
4171
|
input?: MapFieldDefinition<T, TColumns> | RuntimeStepProgram,
|
|
4056
|
-
options?:
|
|
4172
|
+
options?: RuntimeDatasetOptions<T>,
|
|
4057
4173
|
): RuntimeDatasetBuilder<T> | Promise<PlayDataset<Record<string, unknown>>> {
|
|
4058
4174
|
this.assertInlineChildContract('dataset_child');
|
|
4059
4175
|
if (rowContext.getStore()) {
|
|
@@ -4082,7 +4198,7 @@ export class PlayContextImpl {
|
|
|
4082
4198
|
key: string,
|
|
4083
4199
|
items: PlayDatasetInput<T>,
|
|
4084
4200
|
input: RuntimeStepProgram,
|
|
4085
|
-
options?:
|
|
4201
|
+
options?: RuntimeDatasetOptions<T>,
|
|
4086
4202
|
): never;
|
|
4087
4203
|
map<T extends Record<string, unknown>>(
|
|
4088
4204
|
_key: string,
|
|
@@ -4090,7 +4206,7 @@ export class PlayContextImpl {
|
|
|
4090
4206
|
_input?:
|
|
4091
4207
|
| MapFieldDefinition<T, Record<string, unknown>>
|
|
4092
4208
|
| RuntimeStepProgram,
|
|
4093
|
-
_options?:
|
|
4209
|
+
_options?: RuntimeDatasetOptions<T>,
|
|
4094
4210
|
): never {
|
|
4095
4211
|
void _key;
|
|
4096
4212
|
void _items;
|
|
@@ -4103,7 +4219,7 @@ export class PlayContextImpl {
|
|
|
4103
4219
|
key: string,
|
|
4104
4220
|
items: PlayDatasetInput<T>,
|
|
4105
4221
|
program: RuntimeStepProgram,
|
|
4106
|
-
options?:
|
|
4222
|
+
options?: RuntimeDatasetOptions<T>,
|
|
4107
4223
|
): Promise<PlayDataset<Record<string, unknown>>> {
|
|
4108
4224
|
const definition = this.stepProgramToMapDefinition(program);
|
|
4109
4225
|
return this.runMapDefinition(key, items, definition, options);
|
|
@@ -4117,7 +4233,11 @@ export class PlayContextImpl {
|
|
|
4117
4233
|
if (!isRuntimeStepProgram(program)) {
|
|
4118
4234
|
throw new Error('ctx.runSteps(program, input) requires steps().');
|
|
4119
4235
|
}
|
|
4120
|
-
if (options?.description) {
|
|
4236
|
+
if (options?.description !== undefined) {
|
|
4237
|
+
validatePlayAuthoringField(
|
|
4238
|
+
'ctx.runSteps.options.description',
|
|
4239
|
+
options.description,
|
|
4240
|
+
);
|
|
4121
4241
|
this.log(options.description);
|
|
4122
4242
|
}
|
|
4123
4243
|
return (await this.executeStepProgram(program, input, 0, [], {
|
|
@@ -4132,13 +4252,28 @@ export class PlayContextImpl {
|
|
|
4132
4252
|
key: string,
|
|
4133
4253
|
items: PlayDatasetInput<T>,
|
|
4134
4254
|
input: MapFieldDefinition<T, TColumns>,
|
|
4135
|
-
options?:
|
|
4255
|
+
options?: RuntimeDatasetOptions<T>,
|
|
4136
4256
|
): Promise<PlayDataset<Record<string, unknown>>> {
|
|
4137
4257
|
if (rowContext.getStore()) {
|
|
4138
4258
|
throw new Error(
|
|
4139
4259
|
'Nested ctx.dataset() is not supported. Flatten your columns into one dataset, or keep custom per-row logic inside a single column.',
|
|
4140
4260
|
);
|
|
4141
4261
|
}
|
|
4262
|
+
validatePlayAuthoringField('ctx.dataset.key', key);
|
|
4263
|
+
if (options) {
|
|
4264
|
+
validateOptionalPlayAuthoringField(
|
|
4265
|
+
'ctx.dataset.run.description',
|
|
4266
|
+
options.description,
|
|
4267
|
+
);
|
|
4268
|
+
validateOptionalPlayAuthoringField(
|
|
4269
|
+
'ctx.dataset.run.onRowError',
|
|
4270
|
+
options.onRowError,
|
|
4271
|
+
);
|
|
4272
|
+
validateOptionalPlayAuthoringField('ctx.dataset.run.mode', options.mode);
|
|
4273
|
+
if (options.key !== undefined) {
|
|
4274
|
+
validatePlayAuthoringField('ctx.dataset.run.key', options.key);
|
|
4275
|
+
}
|
|
4276
|
+
}
|
|
4142
4277
|
const normalizedMapKey = this.normalizeContextKey(key, 'map');
|
|
4143
4278
|
|
|
4144
4279
|
const normalizedMapNamespace = normalizeTableNamespace(normalizedMapKey);
|
|
@@ -6946,6 +7081,33 @@ export class PlayContextImpl {
|
|
|
6946
7081
|
input: Record<string, unknown>,
|
|
6947
7082
|
options?: ToolCallOptions,
|
|
6948
7083
|
): Promise<unknown> {
|
|
7084
|
+
if (options?.description !== undefined) {
|
|
7085
|
+
validatePlayAuthoringField(
|
|
7086
|
+
'ctx.tools.execute.description',
|
|
7087
|
+
options.description,
|
|
7088
|
+
);
|
|
7089
|
+
}
|
|
7090
|
+
if (options?.force !== undefined) {
|
|
7091
|
+
validatePlayAuthoringField('ctx.tools.execute.force', options.force);
|
|
7092
|
+
}
|
|
7093
|
+
if (
|
|
7094
|
+
options?.timeoutMs !== undefined &&
|
|
7095
|
+
this.currentAuthoringContractEdition >= 2
|
|
7096
|
+
) {
|
|
7097
|
+
validatePlayAuthoringField(
|
|
7098
|
+
'ctx.tools.execute.timeoutMs',
|
|
7099
|
+
options.timeoutMs,
|
|
7100
|
+
);
|
|
7101
|
+
}
|
|
7102
|
+
if (
|
|
7103
|
+
options?.receiptWaitMs !== undefined &&
|
|
7104
|
+
this.currentAuthoringContractEdition >= 2
|
|
7105
|
+
) {
|
|
7106
|
+
validatePlayAuthoringField(
|
|
7107
|
+
'ctx.tools.execute.receiptWaitMs',
|
|
7108
|
+
options.receiptWaitMs,
|
|
7109
|
+
);
|
|
7110
|
+
}
|
|
6949
7111
|
const executionScope = this.currentExecutionScope;
|
|
6950
7112
|
const normalizedKey = this.normalizeContextKey(key, 'tool');
|
|
6951
7113
|
const toolCachePolicy = this.effectiveToolCallCachePolicy(options);
|
|
@@ -7052,7 +7214,11 @@ export class PlayContextImpl {
|
|
|
7052
7214
|
logicalCallId,
|
|
7053
7215
|
})
|
|
7054
7216
|
: physicalDirectKey,
|
|
7055
|
-
timeoutMs: resolveToolRuntimeTimeoutMs(
|
|
7217
|
+
timeoutMs: resolveToolRuntimeTimeoutMs(
|
|
7218
|
+
toolId,
|
|
7219
|
+
options?.timeoutMs,
|
|
7220
|
+
this.currentAuthoringContractEdition,
|
|
7221
|
+
),
|
|
7056
7222
|
...(directReceiptLeaseId &&
|
|
7057
7223
|
(this.#options.heartbeatRuntimeStepReceipts ||
|
|
7058
7224
|
this.#options.getRuntimeStepReceipt ||
|
|
@@ -7154,6 +7320,7 @@ export class PlayContextImpl {
|
|
|
7154
7320
|
const timeoutMs = resolveToolRuntimeTimeoutMs(
|
|
7155
7321
|
toolId,
|
|
7156
7322
|
options?.timeoutMs,
|
|
7323
|
+
this.currentAuthoringContractEdition,
|
|
7157
7324
|
);
|
|
7158
7325
|
this.enqueueToolCall({
|
|
7159
7326
|
callId,
|
|
@@ -7168,7 +7335,7 @@ export class PlayContextImpl {
|
|
|
7168
7335
|
toolId,
|
|
7169
7336
|
input,
|
|
7170
7337
|
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
7171
|
-
...(
|
|
7338
|
+
...(options?.receiptWaitMs !== undefined
|
|
7172
7339
|
? { receiptWaitMs: options.receiptWaitMs }
|
|
7173
7340
|
: {}),
|
|
7174
7341
|
tableNamespace: store.tableNamespace,
|
|
@@ -7205,8 +7372,11 @@ export class PlayContextImpl {
|
|
|
7205
7372
|
toolRetryPolicy?.requiresExecutionFence === true,
|
|
7206
7373
|
executionLockTtlMs: Math.min(
|
|
7207
7374
|
600_000,
|
|
7208
|
-
resolveToolRuntimeTimeoutMs(
|
|
7209
|
-
|
|
7375
|
+
resolveToolRuntimeTimeoutMs(
|
|
7376
|
+
toolId,
|
|
7377
|
+
options?.timeoutMs,
|
|
7378
|
+
this.currentAuthoringContractEdition,
|
|
7379
|
+
) ?? 300_000,
|
|
7210
7380
|
),
|
|
7211
7381
|
staleAfterSeconds: toolCachePolicy.staleAfterSeconds,
|
|
7212
7382
|
onClaimedResult: (output, receiptKey) =>
|
|
@@ -7228,7 +7398,7 @@ export class PlayContextImpl {
|
|
|
7228
7398
|
execute: ({ leaseId }) => executeTool({ leaseId }),
|
|
7229
7399
|
runningReceiptWaitMaxAttempts:
|
|
7230
7400
|
resolveRuntimeToolReceiptWaitMaxAttempts(
|
|
7231
|
-
|
|
7401
|
+
options?.receiptWaitMs !== undefined
|
|
7232
7402
|
? { max_wait_ms: options.receiptWaitMs }
|
|
7233
7403
|
: input,
|
|
7234
7404
|
),
|
|
@@ -7382,8 +7552,6 @@ export class PlayContextImpl {
|
|
|
7382
7552
|
input: Record<string, unknown>,
|
|
7383
7553
|
options?: PlayCallOptions,
|
|
7384
7554
|
): Promise<TOutput> {
|
|
7385
|
-
assertNoSecretTaint(input, 'ctx.runPlay input');
|
|
7386
|
-
const normalizedKey = this.normalizeContextKey(key, 'runPlay');
|
|
7387
7555
|
if (
|
|
7388
7556
|
arguments.length === 3 &&
|
|
7389
7557
|
typeof playRef === 'object' &&
|
|
@@ -7396,13 +7564,26 @@ export class PlayContextImpl {
|
|
|
7396
7564
|
const resolvedName =
|
|
7397
7565
|
typeof playRef === 'string'
|
|
7398
7566
|
? playRef
|
|
7399
|
-
: typeof playRef.playName === 'string'
|
|
7567
|
+
: playRef && typeof playRef.playName === 'string'
|
|
7400
7568
|
? playRef.playName
|
|
7401
|
-
:
|
|
7569
|
+
: playRef && typeof playRef.name === 'string'
|
|
7570
|
+
? playRef.name
|
|
7571
|
+
: '';
|
|
7402
7572
|
|
|
7403
7573
|
if (!resolvedName.trim()) {
|
|
7404
7574
|
throw new Error('ctx.runPlay(...) requires a resolvable play name.');
|
|
7405
7575
|
}
|
|
7576
|
+
validatePlayAuthoringField('ctx.runPlay.playRef', playRef);
|
|
7577
|
+
validatePlayAuthoringField('ctx.runPlay.input', input);
|
|
7578
|
+
assertNoSecretTaint(input, 'ctx.runPlay input');
|
|
7579
|
+
validatePlayAuthoringField('ctx.runPlay.key', key);
|
|
7580
|
+
if (options?.description !== undefined) {
|
|
7581
|
+
validatePlayAuthoringField(
|
|
7582
|
+
'ctx.runPlay.options.description',
|
|
7583
|
+
options.description,
|
|
7584
|
+
);
|
|
7585
|
+
}
|
|
7586
|
+
const normalizedKey = this.normalizeContextKey(key, 'runPlay');
|
|
7406
7587
|
if (!this.#options.resolvePlay) {
|
|
7407
7588
|
throw new Error(
|
|
7408
7589
|
'ctx.runPlay(...) is unavailable because no play resolver was configured.',
|
|
@@ -7414,11 +7595,13 @@ export class PlayContextImpl {
|
|
|
7414
7595
|
`Unable to resolve play "${resolvedName}" for ctx.runPlay(...).`,
|
|
7415
7596
|
);
|
|
7416
7597
|
}
|
|
7417
|
-
const
|
|
7598
|
+
const childCompatibility = normalizePlayContractCompatibility(
|
|
7418
7599
|
resolvedPlay.contractSnapshot?.compatibility ??
|
|
7419
7600
|
resolvedPlay.artifact?.compatibility ??
|
|
7420
7601
|
buildPlayContractCompatibility(),
|
|
7421
|
-
)
|
|
7602
|
+
);
|
|
7603
|
+
const childToolErrorSchemaVersion =
|
|
7604
|
+
childCompatibility.toolErrorSchemaVersion;
|
|
7422
7605
|
const childExecutionDecision = resolveChildExecutionStrategy({
|
|
7423
7606
|
pipeline: resolvedPlay.staticPipeline,
|
|
7424
7607
|
timeoutMs: options?.timeoutMs,
|
|
@@ -7490,6 +7673,8 @@ export class PlayContextImpl {
|
|
|
7490
7673
|
playName: resolvedName,
|
|
7491
7674
|
staticPipeline: resolvedPlay.staticPipeline ?? null,
|
|
7492
7675
|
toolErrorSchemaVersion: childToolErrorSchemaVersion,
|
|
7676
|
+
authoringContractEdition:
|
|
7677
|
+
childCompatibility.authoringContractEdition,
|
|
7493
7678
|
},
|
|
7494
7679
|
() => this.executeResolvedPlay(resolvedPlay, this, input),
|
|
7495
7680
|
);
|
|
@@ -7671,8 +7856,11 @@ export class PlayContextImpl {
|
|
|
7671
7856
|
|
|
7672
7857
|
async sleep(ms: number): Promise<void> {
|
|
7673
7858
|
this.assertInlineChildContract('suspending_child');
|
|
7859
|
+
const delayMs =
|
|
7860
|
+
this.currentAuthoringContractEdition >= 2
|
|
7861
|
+
? (validatePlayAuthoringField('ctx.sleep.ms', ms), ms)
|
|
7862
|
+
: Math.max(0, Math.round(ms));
|
|
7674
7863
|
if (this.#options.durableBoundaries) {
|
|
7675
|
-
const delayMs = Math.max(0, Math.round(ms));
|
|
7676
7864
|
const boundaryId = this.durableBoundaryId(
|
|
7677
7865
|
`sleep-${this.sleepBoundaryIndex}-${delayMs}`,
|
|
7678
7866
|
);
|
|
@@ -7695,7 +7883,7 @@ export class PlayContextImpl {
|
|
|
7695
7883
|
delayMs,
|
|
7696
7884
|
});
|
|
7697
7885
|
}
|
|
7698
|
-
return new Promise((resolve) => setTimeout(resolve,
|
|
7886
|
+
return new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
7699
7887
|
}
|
|
7700
7888
|
|
|
7701
7889
|
async fetch(
|
|
@@ -7704,6 +7892,7 @@ export class PlayContextImpl {
|
|
|
7704
7892
|
init: SecretAwareRequestInit = {},
|
|
7705
7893
|
options?: FetchOptions,
|
|
7706
7894
|
): Promise<PlayFetchResponse> {
|
|
7895
|
+
validatePlayAuthoringField('ctx.fetch.key', key);
|
|
7707
7896
|
const normalizedKey = this.normalizeContextKey(key, 'fetch');
|
|
7708
7897
|
const rowStore = rowContext.getStore();
|
|
7709
7898
|
const rowFetchScope = rowStore
|
|
@@ -7890,8 +8079,13 @@ export class PlayContextImpl {
|
|
|
7890
8079
|
async step<T>(
|
|
7891
8080
|
key: string,
|
|
7892
8081
|
run: () => T | Promise<T>,
|
|
7893
|
-
options?:
|
|
8082
|
+
options?: RuntimeStepOptions,
|
|
7894
8083
|
): Promise<T> {
|
|
8084
|
+
validatePlayAuthoringField('ctx.step.id', key);
|
|
8085
|
+
validateOptionalPlayAuthoringField(
|
|
8086
|
+
'ctx.step.semanticKey',
|
|
8087
|
+
options?.semanticKey,
|
|
8088
|
+
);
|
|
7895
8089
|
const normalizedKey = this.normalizeContextKey(key, 'step');
|
|
7896
8090
|
if (!normalizedKey.trim()) {
|
|
7897
8091
|
throw new Error('ctx.step(key, fn) requires a non-empty stable step id.');
|
|
@@ -9207,7 +9401,11 @@ export class PlayContextImpl {
|
|
|
9207
9401
|
this.#options.executionGatewayBaseUrl?.trim() || this.#options.baseUrl;
|
|
9208
9402
|
const url = `${executionBaseUrl.replace(/\/$/, '')}/api/v2/integrations/${encodeURIComponent(toolId)}/${executeSuffix}`;
|
|
9209
9403
|
const toolErrorSchemaVersion = this.currentToolErrorSchemaVersion;
|
|
9210
|
-
const timeoutMs = resolveToolRuntimeTimeoutMs(
|
|
9404
|
+
const timeoutMs = resolveToolRuntimeTimeoutMs(
|
|
9405
|
+
toolId,
|
|
9406
|
+
options?.timeoutMs,
|
|
9407
|
+
this.currentAuthoringContractEdition,
|
|
9408
|
+
);
|
|
9211
9409
|
const provider = toolId.split(/[._]/)[0]?.trim() || 'provider';
|
|
9212
9410
|
const activityId = `provider:${toolId}`;
|
|
9213
9411
|
let retryActivityEmitted = false;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import type {
|
|
2
|
+
PlayAuthoringCsvOptions,
|
|
3
|
+
PlayAuthoringCsvRenameMap,
|
|
4
|
+
} from '../plays/authoring-contract';
|
|
2
5
|
|
|
3
|
-
export type
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
export type CsvRenameMap = PlayAuthoringCsvRenameMap;
|
|
7
|
+
|
|
8
|
+
export type CsvRenameOptions = Pick<
|
|
9
|
+
PlayAuthoringCsvOptions,
|
|
10
|
+
'columns' | 'rename' | 'required'
|
|
11
|
+
>;
|
|
8
12
|
|
|
9
13
|
const CSV_PROJECTED_FIELDS = Symbol.for('deepline.play.csv.projected_fields');
|
|
10
14
|
const CSV_PROJECTED_FIELDS_KEY = '__deeplineCsvProjectedFields';
|