deepline 0.1.227 → 0.1.228
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 +63 -32
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/ledger-event-batches.ts +81 -0
- package/dist/bundling-sources/sdk/src/client.ts +24 -2
- package/dist/bundling-sources/sdk/src/play.ts +2 -2
- package/dist/bundling-sources/sdk/src/release.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +315 -16
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +49 -17
- package/dist/bundling-sources/shared_libs/play-runtime/live-state-contract.ts +3 -9
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +26 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-lifecycle-policy.ts +5 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +44 -9
- package/dist/bundling-sources/shared_libs/play-runtime/transport-error-diagnostics.ts +63 -0
- package/dist/cli/index.js +78 -11
- package/dist/cli/index.mjs +78 -11
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +14 -5
- package/dist/index.mjs +14 -5
- package/package.json +1 -1
|
@@ -140,6 +140,11 @@ import type {
|
|
|
140
140
|
PlayRunLedgerStepProgress,
|
|
141
141
|
PlayRunLedgerStepStatus,
|
|
142
142
|
} from '../../../shared_libs/play-runtime/run-ledger';
|
|
143
|
+
import {
|
|
144
|
+
MAX_LEDGER_LOG_LINE_LENGTH,
|
|
145
|
+
MAX_LEDGER_LOG_LINES_PER_EVENT,
|
|
146
|
+
} from '../../../shared_libs/play-runtime/ledger-safe-payload';
|
|
147
|
+
import { partitionWorkerLedgerEvents } from './runtime/ledger-event-batches';
|
|
143
148
|
import type { PlayHarnessRpc } from '../../play-harness-worker/src/rpc-types';
|
|
144
149
|
import {
|
|
145
150
|
createCsvDatasetHandle,
|
|
@@ -7778,7 +7783,10 @@ async function executeRunRequest(
|
|
|
7778
7783
|
let ledgerFlushQueueDepth = 0;
|
|
7779
7784
|
|
|
7780
7785
|
const appendRunLogLine = (line: string) => {
|
|
7781
|
-
const trimmed = redactSecretsFromLogString(line.trim())
|
|
7786
|
+
const trimmed = redactSecretsFromLogString(line.trim()).slice(
|
|
7787
|
+
0,
|
|
7788
|
+
MAX_LEDGER_LOG_LINE_LENGTH,
|
|
7789
|
+
);
|
|
7782
7790
|
if (!trimmed) return;
|
|
7783
7791
|
workBudgetMeter.count('log');
|
|
7784
7792
|
totalEmittedLogLines += 1;
|
|
@@ -7861,17 +7869,27 @@ async function executeRunRequest(
|
|
|
7861
7869
|
pendingLedgerEvents = [];
|
|
7862
7870
|
|
|
7863
7871
|
if (pendingRunLogLines.length > 0) {
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7872
|
+
const channelOffset = totalEmittedLogLines - pendingRunLogLines.length;
|
|
7873
|
+
for (
|
|
7874
|
+
let start = 0;
|
|
7875
|
+
start < pendingRunLogLines.length;
|
|
7876
|
+
start += MAX_LEDGER_LOG_LINES_PER_EVENT
|
|
7877
|
+
) {
|
|
7878
|
+
events.push({
|
|
7879
|
+
type: 'log.appended',
|
|
7880
|
+
runId: req.runId,
|
|
7881
|
+
source: 'worker',
|
|
7882
|
+
occurredAt,
|
|
7883
|
+
lines: pendingRunLogLines.slice(
|
|
7884
|
+
start,
|
|
7885
|
+
start + MAX_LEDGER_LOG_LINES_PER_EVENT,
|
|
7886
|
+
),
|
|
7887
|
+
// Positional cursor: pendingRunLogLines always holds the LAST
|
|
7888
|
+
// pending lines emitted on this channel, so the offset of its first
|
|
7889
|
+
// line is total-emitted minus pending length.
|
|
7890
|
+
channelOffset: channelOffset + start,
|
|
7891
|
+
});
|
|
7892
|
+
}
|
|
7875
7893
|
pendingRunLogLines = [];
|
|
7876
7894
|
}
|
|
7877
7895
|
|
|
@@ -7956,19 +7974,26 @@ async function executeRunRequest(
|
|
|
7956
7974
|
ledgerFlushInFlight = ledgerFlushInFlight
|
|
7957
7975
|
.catch(() => undefined)
|
|
7958
7976
|
.then(async () => {
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
7977
|
+
const batches = partitionWorkerLedgerEvents(events);
|
|
7978
|
+
for (let index = 0; index < batches.length; index += 1) {
|
|
7979
|
+
try {
|
|
7980
|
+
await postRuntimeApi(req.baseUrl, req.executorToken, {
|
|
7981
|
+
action: 'append_run_events',
|
|
7982
|
+
playId: req.runId,
|
|
7983
|
+
events: batches[index]!,
|
|
7984
|
+
});
|
|
7985
|
+
} catch {
|
|
7986
|
+
pendingLedgerEvents = [
|
|
7987
|
+
...batches.slice(index).flat(),
|
|
7988
|
+
...pendingLedgerEvents,
|
|
7989
|
+
];
|
|
7990
|
+
throw new Error('runtime run-ledger append failed');
|
|
7991
|
+
}
|
|
7970
7992
|
}
|
|
7971
7993
|
})
|
|
7994
|
+
.finally(() => {
|
|
7995
|
+
ledgerFlushQueueDepth = Math.max(0, ledgerFlushQueueDepth - 1);
|
|
7996
|
+
})
|
|
7972
7997
|
.catch(() => undefined);
|
|
7973
7998
|
return force ? ledgerFlushInFlight : Promise.resolve();
|
|
7974
7999
|
};
|
|
@@ -7988,15 +8013,21 @@ async function executeRunRequest(
|
|
|
7988
8013
|
]);
|
|
7989
8014
|
const events = [...drainPendingLedgerEvents(now), terminalEvent];
|
|
7990
8015
|
if (events.length === 0) return;
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
|
|
7999
|
-
|
|
8016
|
+
const batches = partitionWorkerLedgerEvents(events);
|
|
8017
|
+
for (let index = 0; index < batches.length; index += 1) {
|
|
8018
|
+
try {
|
|
8019
|
+
await postRuntimeApi(req.baseUrl, req.executorToken, {
|
|
8020
|
+
action: 'append_run_events',
|
|
8021
|
+
playId: req.runId,
|
|
8022
|
+
events: batches[index]!,
|
|
8023
|
+
});
|
|
8024
|
+
} catch (error) {
|
|
8025
|
+
pendingLedgerEvents = [
|
|
8026
|
+
...batches.slice(index).flat(),
|
|
8027
|
+
...pendingLedgerEvents,
|
|
8028
|
+
];
|
|
8029
|
+
throw error;
|
|
8030
|
+
}
|
|
8000
8031
|
}
|
|
8001
8032
|
};
|
|
8002
8033
|
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MAX_LEDGER_LOG_LINE_LENGTH,
|
|
3
|
+
MAX_LEDGER_LOG_LINES_PER_EVENT,
|
|
4
|
+
} from '../../../../shared_libs/play-runtime/ledger-safe-payload';
|
|
5
|
+
import type { PlayRunLedgerEvent } from '../../../../shared_libs/play-runtime/run-ledger';
|
|
6
|
+
|
|
7
|
+
/** Keep a Worker-to-runtime append comfortably below the API and Convex limits. */
|
|
8
|
+
export const WORKER_LEDGER_EVENT_BATCH_MAX_BYTES = 128 * 1024;
|
|
9
|
+
export const WORKER_LEDGER_EVENTS_PER_APPEND_MAX = 100;
|
|
10
|
+
|
|
11
|
+
const encoder = new TextEncoder();
|
|
12
|
+
|
|
13
|
+
function encodedJsonBytes(value: unknown): number {
|
|
14
|
+
return encoder.encode(JSON.stringify(value)).length;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function splitLogEvent(
|
|
18
|
+
event: Extract<PlayRunLedgerEvent, { type: 'log.appended' }>,
|
|
19
|
+
): PlayRunLedgerEvent[] {
|
|
20
|
+
const events: PlayRunLedgerEvent[] = [];
|
|
21
|
+
const lines = event.lines.map((line) =>
|
|
22
|
+
line.slice(0, MAX_LEDGER_LOG_LINE_LENGTH),
|
|
23
|
+
);
|
|
24
|
+
let start = 0;
|
|
25
|
+
while (start < lines.length) {
|
|
26
|
+
let end = start;
|
|
27
|
+
let bytes = encodedJsonBytes({ ...event, lines: [] });
|
|
28
|
+
while (end < lines.length && end - start < MAX_LEDGER_LOG_LINES_PER_EVENT) {
|
|
29
|
+
const lineBytes = encodedJsonBytes(lines[end]!);
|
|
30
|
+
if (
|
|
31
|
+
end > start &&
|
|
32
|
+
bytes + lineBytes + 1 > WORKER_LEDGER_EVENT_BATCH_MAX_BYTES
|
|
33
|
+
) {
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
bytes += lineBytes + 1;
|
|
37
|
+
end += 1;
|
|
38
|
+
}
|
|
39
|
+
events.push({
|
|
40
|
+
...event,
|
|
41
|
+
lines: lines.slice(start, end),
|
|
42
|
+
...(typeof event.channelOffset === 'number'
|
|
43
|
+
? { channelOffset: event.channelOffset + start }
|
|
44
|
+
: {}),
|
|
45
|
+
});
|
|
46
|
+
start = end;
|
|
47
|
+
}
|
|
48
|
+
return events;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Partition ledger delivery without dropping positional log lines. The worker
|
|
53
|
+
* retries only unacknowledged batches, so each batch must be independently
|
|
54
|
+
* valid for the app-runtime and Convex boundaries.
|
|
55
|
+
*/
|
|
56
|
+
export function partitionWorkerLedgerEvents(
|
|
57
|
+
events: readonly PlayRunLedgerEvent[],
|
|
58
|
+
): PlayRunLedgerEvent[][] {
|
|
59
|
+
const batches: PlayRunLedgerEvent[][] = [];
|
|
60
|
+
let batch: PlayRunLedgerEvent[] = [];
|
|
61
|
+
let batchBytes = 2;
|
|
62
|
+
|
|
63
|
+
for (const event of events.flatMap((event) =>
|
|
64
|
+
event.type === 'log.appended' ? splitLogEvent(event) : [event],
|
|
65
|
+
)) {
|
|
66
|
+
const eventBytes = encodedJsonBytes(event);
|
|
67
|
+
if (
|
|
68
|
+
batch.length > 0 &&
|
|
69
|
+
(batch.length >= WORKER_LEDGER_EVENTS_PER_APPEND_MAX ||
|
|
70
|
+
batchBytes + eventBytes + 1 > WORKER_LEDGER_EVENT_BATCH_MAX_BYTES)
|
|
71
|
+
) {
|
|
72
|
+
batches.push(batch);
|
|
73
|
+
batch = [];
|
|
74
|
+
batchBytes = 2;
|
|
75
|
+
}
|
|
76
|
+
batch.push(event);
|
|
77
|
+
batchBytes += eventBytes + 1;
|
|
78
|
+
}
|
|
79
|
+
if (batch.length > 0) batches.push(batch);
|
|
80
|
+
return batches;
|
|
81
|
+
}
|
|
@@ -243,8 +243,30 @@ type ExecuteToolRawOptions = {
|
|
|
243
243
|
maxRetries?: number;
|
|
244
244
|
};
|
|
245
245
|
|
|
246
|
-
|
|
246
|
+
/**
|
|
247
|
+
* The server launches the Apify run, polls it for `payload.timeoutMs`, then
|
|
248
|
+
* reads its dataset before replying. Keep the client request alive through
|
|
249
|
+
* that final hand-off so a pollable run id is never lost to the SDK default
|
|
250
|
+
* timeout.
|
|
251
|
+
*/
|
|
252
|
+
const APIFY_SYNC_DEFAULT_TIMEOUT_MS = 300_000;
|
|
253
|
+
const APIFY_SYNC_RESPONSE_GRACE_MS = 90_000;
|
|
254
|
+
|
|
255
|
+
function resolveToolExecuteTimeoutMs(
|
|
256
|
+
toolId: string,
|
|
257
|
+
input: Record<string, unknown>,
|
|
258
|
+
): number | undefined {
|
|
247
259
|
const normalized = toolId.trim().toLowerCase();
|
|
260
|
+
if (normalized === 'apify_run_actor_sync') {
|
|
261
|
+
const requestedTimeoutMs = input.timeoutMs ?? APIFY_SYNC_DEFAULT_TIMEOUT_MS;
|
|
262
|
+
if (
|
|
263
|
+
typeof requestedTimeoutMs === 'number' &&
|
|
264
|
+
Number.isFinite(requestedTimeoutMs) &&
|
|
265
|
+
requestedTimeoutMs > 0
|
|
266
|
+
) {
|
|
267
|
+
return Math.floor(requestedTimeoutMs) + APIFY_SYNC_RESPONSE_GRACE_MS;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
248
270
|
return normalized === 'deeplineagent' ||
|
|
249
271
|
normalized === 'deeplineagent_deeplineagent' ||
|
|
250
272
|
normalized === 'ai_inference' ||
|
|
@@ -1417,7 +1439,7 @@ export class DeeplineClient {
|
|
|
1417
1439
|
headers,
|
|
1418
1440
|
{
|
|
1419
1441
|
forbiddenAsApiError: true,
|
|
1420
|
-
timeout: options?.timeout ?? resolveToolExecuteTimeoutMs(toolId),
|
|
1442
|
+
timeout: options?.timeout ?? resolveToolExecuteTimeoutMs(toolId, input),
|
|
1421
1443
|
maxRetries: options?.maxRetries ?? 0,
|
|
1422
1444
|
exactUrlOnly: true,
|
|
1423
1445
|
},
|
|
@@ -161,7 +161,7 @@ export interface PlayCallOptions {
|
|
|
161
161
|
* sqlListeners: [
|
|
162
162
|
* {
|
|
163
163
|
* id: 'jobs',
|
|
164
|
-
* tool: '
|
|
164
|
+
* tool: 'deepline_native.company_radar',
|
|
165
165
|
* stream: 'company_job_openings',
|
|
166
166
|
* operations: ['INSERT'],
|
|
167
167
|
* },
|
|
@@ -237,7 +237,7 @@ export type SqlListenerWhere = {
|
|
|
237
237
|
export type SqlListenerDeclaration = {
|
|
238
238
|
/** Short id unique inside this play. Deepline stores it as playName.id. */
|
|
239
239
|
id: string;
|
|
240
|
-
/** Modeled monitor tool id, for example "
|
|
240
|
+
/** Modeled monitor tool id, for example "deepline_native.company_radar". */
|
|
241
241
|
tool: string;
|
|
242
242
|
/** Stream key exposed by the modeled monitor tool, for example "company_job_openings". */
|
|
243
243
|
stream: string;
|
|
@@ -108,10 +108,10 @@ export const SDK_RELEASE = {
|
|
|
108
108
|
// 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
|
|
109
109
|
// 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
|
|
110
110
|
// automatically without blocking their current command.
|
|
111
|
-
version: '0.1.
|
|
111
|
+
version: '0.1.228',
|
|
112
112
|
apiContract: '2026-06-dataset-handle-results-hard-cutover',
|
|
113
113
|
supportPolicy: {
|
|
114
|
-
latest: '0.1.
|
|
114
|
+
latest: '0.1.228',
|
|
115
115
|
minimumSupported: '0.1.53',
|
|
116
116
|
deprecatedBelow: '0.1.219',
|
|
117
117
|
commandMinimumSupported: [
|