deepline 0.1.167 → 0.1.169
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/coordinator-entry.ts +317 -26
- package/dist/bundling-sources/apps/play-runner-workers/src/dedup-do.ts +99 -6
- package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +219 -73
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/map-chunk-plan.ts +119 -33
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-receipts.ts +2 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/workflow-instance-create.ts +3 -0
- package/dist/bundling-sources/sdk/src/client.ts +29 -1
- package/dist/bundling-sources/sdk/src/release.ts +2 -2
- package/dist/bundling-sources/sdk/src/types.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-data-plane/column-names.ts +50 -8
- package/dist/bundling-sources/shared_libs/play-data-plane/sheet-contract.ts +40 -1
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +1 -0
- package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +202 -45
- package/dist/cli/index.js +70 -113
- package/dist/cli/index.mjs +70 -113
- package/dist/{compiler-manifest-VhtM9n24.d.mts → compiler-manifest-OwORQ07f.d.mts} +1 -0
- package/dist/{compiler-manifest-VhtM9n24.d.ts → compiler-manifest-OwORQ07f.d.ts} +1 -0
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +26 -5
- package/dist/index.mjs +26 -5
- package/dist/plays/bundle-play-file.d.mts +2 -2
- package/dist/plays/bundle-play-file.d.ts +2 -2
- package/package.json +1 -1
|
@@ -14,9 +14,10 @@ import {
|
|
|
14
14
|
|
|
15
15
|
export const CACHE_ENABLED_SIMPLE_MAP_CHUNK_SIZE = 10_000;
|
|
16
16
|
export { TOOL_CALLING_MAP_CHUNK_SIZE };
|
|
17
|
-
// Cloudflare
|
|
18
|
-
//
|
|
19
|
-
|
|
17
|
+
// Paid Cloudflare Workers support a much higher configured subrequest limit.
|
|
18
|
+
// Keep a large buffer for coordinator/storage calls around row-level unbatched
|
|
19
|
+
// tool RPCs, but avoid pathological one-row chunks for provider waterfalls.
|
|
20
|
+
export const UNBATCHED_TOOL_SUBREQUESTS_PER_CHUNK_BUDGET = 500;
|
|
20
21
|
// Fresh unbatched tool calls use one RUNTIME_API integration execute RPC and
|
|
21
22
|
// one HARNESS durable-receipt completion RPC. Batch-cap rows by both.
|
|
22
23
|
export const SUBREQUESTS_PER_UNBATCHED_TOOL_CALL = 2;
|
|
@@ -46,6 +47,10 @@ type ChunkSizingPlan = {
|
|
|
46
47
|
|
|
47
48
|
type MapToolStats = [totalToolCount: number, unbatchedToolCount: number];
|
|
48
49
|
|
|
50
|
+
function fieldRoot(field: string | null | undefined): string {
|
|
51
|
+
return String(field ?? '').split('.', 1)[0] ?? '';
|
|
52
|
+
}
|
|
53
|
+
|
|
49
54
|
function declarationBelongsToMapOutput(
|
|
50
55
|
declaration: { field?: string | null },
|
|
51
56
|
outputFields: readonly string[],
|
|
@@ -76,39 +81,124 @@ function countToolSubsteps(
|
|
|
76
81
|
let unbatchedToolCount = 0;
|
|
77
82
|
|
|
78
83
|
for (const substep of substeps) {
|
|
79
|
-
|
|
84
|
+
const [nestedTotal, nestedUnbatched] = countToolSubstep(substep);
|
|
85
|
+
totalToolCount += nestedTotal;
|
|
86
|
+
unbatchedToolCount += nestedUnbatched;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return [totalToolCount, unbatchedToolCount];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function countToolSubstep(substep: PlayStaticSubstep): MapToolStats {
|
|
93
|
+
if (substep.type === 'tool') {
|
|
94
|
+
return [1, isUnbatchedTool(substep.toolId) ? 1 : 0];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (substep.type === 'waterfall') {
|
|
98
|
+
let totalToolCount = 0;
|
|
99
|
+
let unbatchedToolCount = 0;
|
|
100
|
+
for (const step of substep.steps ?? []) {
|
|
101
|
+
if (!step.toolId) continue;
|
|
80
102
|
totalToolCount += 1;
|
|
81
|
-
if (isUnbatchedTool(
|
|
103
|
+
if (isUnbatchedTool(step.toolId)) {
|
|
82
104
|
unbatchedToolCount += 1;
|
|
83
105
|
}
|
|
84
|
-
continue;
|
|
85
106
|
}
|
|
107
|
+
return [totalToolCount, unbatchedToolCount];
|
|
108
|
+
}
|
|
86
109
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
totalToolCount += 1;
|
|
91
|
-
if (isUnbatchedTool(step.toolId)) {
|
|
92
|
-
unbatchedToolCount += 1;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
110
|
+
if (substep.type === 'step_suite') {
|
|
111
|
+
return countStepSuiteTools(substep);
|
|
112
|
+
}
|
|
97
113
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
substep.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
114
|
+
if (substep.type === 'control_flow') {
|
|
115
|
+
if (substep.kind === 'conditional' && substep.branches?.length) {
|
|
116
|
+
const branchStats = substep.branches.map((branch) =>
|
|
117
|
+
countToolSubsteps(branch.steps),
|
|
118
|
+
);
|
|
119
|
+
return branchStats.reduce<MapToolStats>(
|
|
120
|
+
([totalMax, unbatchedMax], [total, unbatched]) => [
|
|
121
|
+
Math.max(totalMax, total),
|
|
122
|
+
Math.max(unbatchedMax, unbatched),
|
|
123
|
+
],
|
|
124
|
+
[0, 0],
|
|
105
125
|
);
|
|
106
|
-
totalToolCount += nestedTotal;
|
|
107
|
-
unbatchedToolCount += nestedUnbatched;
|
|
108
126
|
}
|
|
127
|
+
return countToolSubsteps(substep.steps);
|
|
109
128
|
}
|
|
110
129
|
|
|
111
|
-
|
|
130
|
+
if (substep.type === 'dataset') {
|
|
131
|
+
return countToolSubsteps(substep.steps ?? []);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return [0, 0];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function countStepSuiteTools(
|
|
138
|
+
substep: Extract<PlayStaticSubstep, { type: 'step_suite' }>,
|
|
139
|
+
): MapToolStats {
|
|
140
|
+
const childStats = substep.steps.map((step) => ({
|
|
141
|
+
step,
|
|
142
|
+
stats: countToolSubstep(step),
|
|
143
|
+
}));
|
|
144
|
+
const conditionalChildren = childStats.filter(
|
|
145
|
+
({ step }) =>
|
|
146
|
+
step.conditional ||
|
|
147
|
+
(step.type === 'control_flow' && step.kind === 'conditional'),
|
|
148
|
+
);
|
|
149
|
+
if (
|
|
150
|
+
conditionalChildren.length === 0 ||
|
|
151
|
+
conditionalChildren.length < childStats.length / 2
|
|
152
|
+
) {
|
|
153
|
+
return childStats.reduce<MapToolStats>(
|
|
154
|
+
([totalSum, unbatchedSum], { stats: [total, unbatched] }) => [
|
|
155
|
+
totalSum + total,
|
|
156
|
+
unbatchedSum + unbatched,
|
|
157
|
+
],
|
|
158
|
+
[0, 0],
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const suiteRoot = fieldRoot(substep.field);
|
|
163
|
+
const sameRoot = childStats.every(({ step }) => {
|
|
164
|
+
if (!('field' in step)) return true;
|
|
165
|
+
return fieldRoot(step.field) === suiteRoot;
|
|
166
|
+
});
|
|
167
|
+
if (!sameRoot) {
|
|
168
|
+
return childStats.reduce<MapToolStats>(
|
|
169
|
+
([totalSum, unbatchedSum], { stats: [total, unbatched] }) => [
|
|
170
|
+
totalSum + total,
|
|
171
|
+
unbatchedSum + unbatched,
|
|
172
|
+
],
|
|
173
|
+
[0, 0],
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const unconditionalStats = childStats
|
|
178
|
+
.filter(
|
|
179
|
+
({ step }) =>
|
|
180
|
+
!step.conditional &&
|
|
181
|
+
!(step.type === 'control_flow' && step.kind === 'conditional'),
|
|
182
|
+
)
|
|
183
|
+
.reduce<MapToolStats>(
|
|
184
|
+
([totalSum, unbatchedSum], { stats: [total, unbatched] }) => [
|
|
185
|
+
totalSum + total,
|
|
186
|
+
unbatchedSum + unbatched,
|
|
187
|
+
],
|
|
188
|
+
[0, 0],
|
|
189
|
+
);
|
|
190
|
+
const conditionalStats = conditionalChildren.reduce<MapToolStats>(
|
|
191
|
+
([totalSum, unbatchedSum], { stats: [total, unbatched] }) => [
|
|
192
|
+
totalSum + total,
|
|
193
|
+
unbatchedSum + unbatched,
|
|
194
|
+
],
|
|
195
|
+
[0, 0],
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
return [
|
|
199
|
+
unconditionalStats[0] + conditionalStats[0],
|
|
200
|
+
unconditionalStats[1] + conditionalStats[1],
|
|
201
|
+
];
|
|
112
202
|
}
|
|
113
203
|
|
|
114
204
|
function countProducerTools(
|
|
@@ -125,13 +215,9 @@ function countProducerTools(
|
|
|
125
215
|
}
|
|
126
216
|
}
|
|
127
217
|
if (producer.substep.type === 'waterfall') {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (isUnbatchedTool(step.toolId)) {
|
|
132
|
-
unbatchedToolCount += 1;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
218
|
+
const [nestedTotal, nestedUnbatched] = countToolSubstep(producer.substep);
|
|
219
|
+
totalToolCount += nestedTotal;
|
|
220
|
+
unbatchedToolCount += nestedUnbatched;
|
|
135
221
|
}
|
|
136
222
|
if (producer.steps?.length) {
|
|
137
223
|
const [nestedTotal, nestedUnbatched] = countProducerTools(producer.steps);
|
|
@@ -22,6 +22,8 @@ export type WorkerToolReceiptGroupPlan<TRequest> = {
|
|
|
22
22
|
export function canReclaimTimedOutWorkerToolReceipt(input: {
|
|
23
23
|
ownerRunId?: string | null;
|
|
24
24
|
currentRunId: string;
|
|
25
|
+
updatedAt?: string | null;
|
|
26
|
+
nowMs?: number;
|
|
25
27
|
}): boolean {
|
|
26
28
|
const currentRunId = input.currentRunId.trim();
|
|
27
29
|
return Boolean(currentRunId);
|
|
@@ -19,11 +19,13 @@ export async function createOrAttachWorkflowInstance<
|
|
|
19
19
|
>(input: {
|
|
20
20
|
create: () => Promise<T>;
|
|
21
21
|
getExisting: () => Promise<T>;
|
|
22
|
+
onCreateFailure?: (error: unknown) => Promise<void>;
|
|
22
23
|
}): Promise<WorkflowInstanceCreateResult<T>> {
|
|
23
24
|
try {
|
|
24
25
|
return { instance: await input.create(), startMode: 'created' };
|
|
25
26
|
} catch (error) {
|
|
26
27
|
if (!isWorkflowInstanceAlreadyExistsError(error)) {
|
|
28
|
+
await input.onCreateFailure?.(error);
|
|
27
29
|
throw error;
|
|
28
30
|
}
|
|
29
31
|
try {
|
|
@@ -32,6 +34,7 @@ export async function createOrAttachWorkflowInstance<
|
|
|
32
34
|
startMode: 'reattached_existing',
|
|
33
35
|
};
|
|
34
36
|
} catch (attachError) {
|
|
37
|
+
await input.onCreateFailure?.(attachError);
|
|
35
38
|
const message =
|
|
36
39
|
attachError instanceof Error
|
|
37
40
|
? attachError.message
|
|
@@ -91,6 +91,23 @@ const REGISTER_PLAY_ARTIFACTS_COMPILE_CONCURRENCY = 3;
|
|
|
91
91
|
const REGISTER_PLAY_ARTIFACTS_MAX_BATCH_COUNT = 3;
|
|
92
92
|
const REGISTER_PLAY_ARTIFACTS_MAX_BATCH_BYTES = 2_500_000;
|
|
93
93
|
|
|
94
|
+
function normalizePlayRunIntegrationMode(
|
|
95
|
+
value: unknown,
|
|
96
|
+
): 'live' | 'eval_stub' | 'fixture' | undefined {
|
|
97
|
+
if (value === 'live' || value === 'eval_stub' || value === 'fixture') {
|
|
98
|
+
return value;
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function resolvePlayRunIntegrationMode(
|
|
104
|
+
request: StartPlayRunRequest,
|
|
105
|
+
): 'live' | 'eval_stub' | 'fixture' | undefined {
|
|
106
|
+
return normalizePlayRunIntegrationMode(
|
|
107
|
+
request.integrationMode ?? process.env.DEEPLINE_EVAL_INTEGRATION_MODE,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
94
111
|
function sleep(ms: number): Promise<void> {
|
|
95
112
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
96
113
|
}
|
|
@@ -1238,6 +1255,7 @@ export class DeeplineClient {
|
|
|
1238
1255
|
* ```
|
|
1239
1256
|
*/
|
|
1240
1257
|
async startPlayRun(request: StartPlayRunRequest): Promise<PlayRunStart> {
|
|
1258
|
+
const integrationMode = resolvePlayRunIntegrationMode(request);
|
|
1241
1259
|
const response = await this.http.post<Record<string, unknown>>(
|
|
1242
1260
|
'/api/v2/plays/run',
|
|
1243
1261
|
{
|
|
@@ -1279,6 +1297,7 @@ export class DeeplineClient {
|
|
|
1279
1297
|
// defaults to workers_edge; tests and runtime probes that want a
|
|
1280
1298
|
// different profile pass `request.profile` explicitly.
|
|
1281
1299
|
...(request.profile ? { profile: request.profile } : {}),
|
|
1300
|
+
...(integrationMode ? { integrationMode } : {}),
|
|
1282
1301
|
},
|
|
1283
1302
|
);
|
|
1284
1303
|
return normalizePlayRunStart(response);
|
|
@@ -1299,6 +1318,7 @@ export class DeeplineClient {
|
|
|
1299
1318
|
request: StartPlayRunRequest,
|
|
1300
1319
|
options?: { signal?: AbortSignal },
|
|
1301
1320
|
): AsyncGenerator<PlayLiveEvent> {
|
|
1321
|
+
const integrationMode = resolvePlayRunIntegrationMode(request);
|
|
1302
1322
|
const body = {
|
|
1303
1323
|
...(request.name ? { name: request.name } : {}),
|
|
1304
1324
|
...(request.revisionId ? { revisionId: request.revisionId } : {}),
|
|
@@ -1335,6 +1355,7 @@ export class DeeplineClient {
|
|
|
1335
1355
|
? { waitForCompletionMs: request.waitForCompletionMs }
|
|
1336
1356
|
: {}),
|
|
1337
1357
|
...(request.profile ? { profile: request.profile } : {}),
|
|
1358
|
+
...(integrationMode ? { integrationMode } : {}),
|
|
1338
1359
|
};
|
|
1339
1360
|
for await (const event of this.http.streamSse<PlayLiveEvent>(
|
|
1340
1361
|
'/api/v2/plays/run?stream=true',
|
|
@@ -1538,8 +1559,15 @@ export class DeeplineClient {
|
|
|
1538
1559
|
sourceFiles?: Record<string, string>;
|
|
1539
1560
|
description?: string;
|
|
1540
1561
|
artifact: Record<string, unknown>;
|
|
1562
|
+
integrationMode?: 'live' | 'eval_stub' | 'fixture';
|
|
1541
1563
|
}): Promise<PlayCheckResult> {
|
|
1542
|
-
|
|
1564
|
+
const integrationMode = normalizePlayRunIntegrationMode(
|
|
1565
|
+
input.integrationMode ?? process.env.DEEPLINE_EVAL_INTEGRATION_MODE,
|
|
1566
|
+
);
|
|
1567
|
+
return this.http.post('/api/v2/plays/check', {
|
|
1568
|
+
...input,
|
|
1569
|
+
...(integrationMode ? { integrationMode } : {}),
|
|
1570
|
+
});
|
|
1543
1571
|
}
|
|
1544
1572
|
|
|
1545
1573
|
/**
|
|
@@ -104,10 +104,10 @@ export const SDK_RELEASE = {
|
|
|
104
104
|
// 0.1.111 ships dataset-native tool list getters and result row datasets.
|
|
105
105
|
// 0.1.154 removes the short-lived generated enrich StepOptions recompute
|
|
106
106
|
// fields shipped in 0.1.153.
|
|
107
|
-
version: '0.1.
|
|
107
|
+
version: '0.1.169',
|
|
108
108
|
apiContract: '2026-06-dataset-handle-results-hard-cutover',
|
|
109
109
|
supportPolicy: {
|
|
110
|
-
latest: '0.1.
|
|
110
|
+
latest: '0.1.169',
|
|
111
111
|
minimumSupported: '0.1.53',
|
|
112
112
|
deprecatedBelow: '0.1.53',
|
|
113
113
|
commandMinimumSupported: [
|
|
@@ -919,6 +919,7 @@ export interface PlayRunStart {
|
|
|
919
919
|
export interface PlayCheckResult {
|
|
920
920
|
valid: boolean;
|
|
921
921
|
errors: string[];
|
|
922
|
+
warnings?: string[];
|
|
922
923
|
staticPipeline?: Record<string, unknown> | null;
|
|
923
924
|
toolGetterHints?: PlayCheckToolGetterHint[];
|
|
924
925
|
artifactHash?: string | null;
|
|
@@ -1005,6 +1006,8 @@ export interface StartPlayRunRequest {
|
|
|
1005
1006
|
* should leave this unset.
|
|
1006
1007
|
*/
|
|
1007
1008
|
profile?: string;
|
|
1009
|
+
/** Optional per-run provider execution mode for eval/smoke runs. */
|
|
1010
|
+
integrationMode?: 'live' | 'eval_stub' | 'fixture';
|
|
1008
1011
|
}
|
|
1009
1012
|
|
|
1010
1013
|
/**
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* JSONB columns so logical names such as `_metadata` and `person.email` do not
|
|
6
|
-
* drift between writer and reader paths.
|
|
7
|
-
*/
|
|
8
|
-
export function sqlSafePlayColumnName(id: string): string {
|
|
1
|
+
const POSTGRES_IDENTIFIER_MAX_BYTES = 63;
|
|
2
|
+
const HASH_SUFFIX_LENGTH = 10;
|
|
3
|
+
|
|
4
|
+
function normalizePlayColumnName(id: string): string {
|
|
9
5
|
const normalized = id
|
|
10
6
|
.trim()
|
|
11
7
|
.replace(/\.+/g, '__')
|
|
@@ -15,3 +11,49 @@ export function sqlSafePlayColumnName(id: string): string {
|
|
|
15
11
|
const safe = normalized || 'column';
|
|
16
12
|
return /^[A-Za-z_]/.test(safe) ? safe : `c_${safe}`;
|
|
17
13
|
}
|
|
14
|
+
|
|
15
|
+
function stableHexSuffix(value: string): string {
|
|
16
|
+
let primary = 0x811c9dc5;
|
|
17
|
+
let secondary = 0x811c9dc5 ^ value.length;
|
|
18
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
19
|
+
const code = value.charCodeAt(index);
|
|
20
|
+
primary = Math.imul(primary ^ code, 0x01000193) >>> 0;
|
|
21
|
+
secondary = Math.imul(secondary ^ (code + index), 0x01000193) >>> 0;
|
|
22
|
+
}
|
|
23
|
+
return `${primary.toString(16).padStart(8, '0')}${secondary
|
|
24
|
+
.toString(16)
|
|
25
|
+
.padStart(8, '0')}`.slice(0, HASH_SUFFIX_LENGTH);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* SQL-safe physical column name for a play-authored logical field id.
|
|
30
|
+
*
|
|
31
|
+
* Runtime Sheet adapters must use this when they create or discover physical
|
|
32
|
+
* JSONB columns so logical names such as `_metadata` and `person.email` do not
|
|
33
|
+
* drift between writer and reader paths.
|
|
34
|
+
*/
|
|
35
|
+
export function sqlSafePlayColumnName(id: string): string {
|
|
36
|
+
const prefixed = normalizePlayColumnName(id);
|
|
37
|
+
if (prefixed.length <= POSTGRES_IDENTIFIER_MAX_BYTES) {
|
|
38
|
+
return prefixed;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const hash = stableHexSuffix(prefixed);
|
|
42
|
+
const maxPrefixLength =
|
|
43
|
+
POSTGRES_IDENTIFIER_MAX_BYTES - HASH_SUFFIX_LENGTH - 1;
|
|
44
|
+
const prefix = prefixed
|
|
45
|
+
.slice(0, maxPrefixLength)
|
|
46
|
+
.replace(/_+$/g, '')
|
|
47
|
+
.slice(0, maxPrefixLength);
|
|
48
|
+
return `${prefix}_${hash}`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function legacyPostgresTruncatedPlayColumnName(
|
|
52
|
+
id: string,
|
|
53
|
+
): string | null {
|
|
54
|
+
const prefixed = normalizePlayColumnName(id);
|
|
55
|
+
if (prefixed.length <= POSTGRES_IDENTIFIER_MAX_BYTES) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return prefixed.slice(0, POSTGRES_IDENTIFIER_MAX_BYTES);
|
|
59
|
+
}
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import type { PlaySheetContract } from '../plays/static-pipeline';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
legacyPostgresTruncatedPlayColumnName,
|
|
4
|
+
sqlSafePlayColumnName,
|
|
5
|
+
} from './column-names';
|
|
3
6
|
|
|
4
7
|
export type PhysicalSheetColumnProjection = {
|
|
5
8
|
sqlName: string;
|
|
6
9
|
fieldName: string;
|
|
7
10
|
};
|
|
8
11
|
|
|
12
|
+
export type LegacyPhysicalSheetColumnBackfill = {
|
|
13
|
+
sqlName: string;
|
|
14
|
+
legacySqlName: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
9
17
|
const RUNTIME_SHEET_SYSTEM_FIELDS = new Set([
|
|
10
18
|
'_key',
|
|
11
19
|
'_status',
|
|
@@ -58,6 +66,37 @@ export function physicalSheetColumnNames(
|
|
|
58
66
|
);
|
|
59
67
|
}
|
|
60
68
|
|
|
69
|
+
export function legacyPhysicalSheetColumnBackfills(
|
|
70
|
+
sheetContract: PlaySheetContract | null | undefined,
|
|
71
|
+
): LegacyPhysicalSheetColumnBackfill[] {
|
|
72
|
+
if (!sheetContract) {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
const seen = new Set<string>();
|
|
76
|
+
const backfills: LegacyPhysicalSheetColumnBackfill[] = [];
|
|
77
|
+
for (const column of sheetContract.columns) {
|
|
78
|
+
const sqlName = column.sqlName.trim();
|
|
79
|
+
if (!sqlName || sqlName.startsWith('_')) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const candidates = [
|
|
83
|
+
typeof column.field === 'string' ? column.field : null,
|
|
84
|
+
column.id,
|
|
85
|
+
];
|
|
86
|
+
for (const candidate of candidates) {
|
|
87
|
+
if (!candidate) continue;
|
|
88
|
+
const legacySqlName = legacyPostgresTruncatedPlayColumnName(candidate);
|
|
89
|
+
const key = legacySqlName ? `${sqlName}:${legacySqlName}` : '';
|
|
90
|
+
if (!legacySqlName || legacySqlName === sqlName || seen.has(key)) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
seen.add(key);
|
|
94
|
+
backfills.push({ sqlName, legacySqlName });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return backfills;
|
|
98
|
+
}
|
|
99
|
+
|
|
61
100
|
export function physicalSheetColumnFieldLookup(
|
|
62
101
|
sheetContract: PlaySheetContract | null | undefined,
|
|
63
102
|
): Map<string, string> {
|
|
@@ -230,6 +230,7 @@ type RuntimeApiRequest =
|
|
|
230
230
|
export type WorkerRuntimeApiContext = {
|
|
231
231
|
baseUrl: string;
|
|
232
232
|
executorToken: string;
|
|
233
|
+
integrationMode?: 'live' | 'eval_stub' | 'fixture' | null;
|
|
233
234
|
vercelProtectionBypassToken?: string | null;
|
|
234
235
|
fetch?: typeof fetch;
|
|
235
236
|
};
|
|
@@ -4850,6 +4850,9 @@ export class PlayContextImpl {
|
|
|
4850
4850
|
body: JSON.stringify({
|
|
4851
4851
|
payload: input,
|
|
4852
4852
|
metadata: { parent_run_id: this.#options.runId },
|
|
4853
|
+
...(this.#options.integrationMode
|
|
4854
|
+
? { integration_mode: this.#options.integrationMode }
|
|
4855
|
+
: {}),
|
|
4853
4856
|
}),
|
|
4854
4857
|
});
|
|
4855
4858
|
} catch (error) {
|
|
@@ -388,6 +388,8 @@ export interface ContextOptions {
|
|
|
388
388
|
executorToken?: string;
|
|
389
389
|
baseUrl?: string;
|
|
390
390
|
vercelProtectionBypassToken?: string | null;
|
|
391
|
+
/** Optional per-run integration execution mode for provider calls. */
|
|
392
|
+
integrationMode?: 'live' | 'eval_stub' | 'fixture';
|
|
391
393
|
orgId?: string;
|
|
392
394
|
userEmail?: string;
|
|
393
395
|
playName?: string;
|
|
@@ -83,6 +83,7 @@ type RuntimeApiContext = {
|
|
|
83
83
|
playName?: string | null;
|
|
84
84
|
runId?: string | null;
|
|
85
85
|
userEmail?: string | null;
|
|
86
|
+
integrationMode?: 'live' | 'eval_stub' | 'fixture' | null;
|
|
86
87
|
dbSessionStrategy?: 'preloaded' | 'sandbox_public_key' | null;
|
|
87
88
|
preloadedDbSessions?: PreloadedRuntimeDbSession[] | null;
|
|
88
89
|
vercelProtectionBypassToken?: string | null;
|
|
@@ -1512,6 +1513,7 @@ function mapRuntimeWorkReceiptRow(raw: Record<string, unknown>): WorkReceipt {
|
|
|
1512
1513
|
output: raw.output == null ? null : raw.output,
|
|
1513
1514
|
error: raw.error == null ? null : String(raw.error),
|
|
1514
1515
|
runId: raw.run_id == null ? null : String(raw.run_id),
|
|
1516
|
+
updatedAt: raw.updated_at == null ? null : String(raw.updated_at),
|
|
1515
1517
|
};
|
|
1516
1518
|
}
|
|
1517
1519
|
|
|
@@ -124,6 +124,8 @@ export type PlaySchedulerSubmitInput = {
|
|
|
124
124
|
dynamicWorkerCode?: string | null;
|
|
125
125
|
executorToken: string;
|
|
126
126
|
baseUrl: string;
|
|
127
|
+
/** Optional per-run provider execution mode. Defaults to server policy when omitted. */
|
|
128
|
+
integrationMode?: 'live' | 'eval_stub' | 'fixture';
|
|
127
129
|
orgId: string;
|
|
128
130
|
userEmail: string;
|
|
129
131
|
userId?: string | null;
|