deepline 0.3.274 → 0.3.276
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/client.ts +148 -19
- package/dist/bundling-sources/sdk/src/index.ts +3 -0
- package/dist/bundling-sources/sdk/src/play.ts +4 -10
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/runs/log-cursor.ts +35 -0
- package/dist/bundling-sources/sdk/src/types.ts +10 -3
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +12 -26
- package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +7 -3
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +15 -7
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +18 -18
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +1 -0
- package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +7 -4
- package/dist/bundling-sources/shared_libs/plays/table-csv.ts +152 -0
- package/dist/cli/index.js +411 -284
- package/dist/cli/index.mjs +411 -284
- package/dist/{client-2rIHKJiq.d.mts → client-C0EhEIQO.d.mts} +78 -13
- package/dist/{client-D6fRwhnE.d.ts → client-HxPrGPbv.d.ts} +78 -13
- package/dist/index.d.mts +6 -12
- package/dist/index.d.ts +6 -12
- package/dist/index.js +87 -9
- package/dist/index.mjs +87 -9
- package/dist/install-integrity.json +4 -2
- package/dist/plays/run-request.d.mts +1 -1
- package/dist/plays/run-request.d.ts +1 -1
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -1985,18 +1985,18 @@ function playInputExampleArgs(schema) {
|
|
|
1985
1985
|
if (!schema) return " --input '@<input.json>'";
|
|
1986
1986
|
if (schema.$ref || schema.allOf) return " --input '@<input.json>'";
|
|
1987
1987
|
const csv = schema.csvInput;
|
|
1988
|
-
const
|
|
1988
|
+
const csvField2 = typeof csv?.inputField === "string" ? csv.inputField : null;
|
|
1989
1989
|
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
1990
|
-
const csvOnlyRequired = required.every((key) => key ===
|
|
1990
|
+
const csvOnlyRequired = required.every((key) => key === csvField2);
|
|
1991
1991
|
const alternatives = schema.oneOf ?? schema.anyOf;
|
|
1992
1992
|
const hasCsvAlternative = Array.isArray(alternatives) && alternatives.some((branch) => {
|
|
1993
1993
|
if (!branch || typeof branch !== "object") return false;
|
|
1994
1994
|
const keys = branch.required;
|
|
1995
|
-
return Array.isArray(keys) && keys.includes(
|
|
1995
|
+
return Array.isArray(keys) && keys.includes(csvField2) && keys.every((key) => key === csvField2);
|
|
1996
1996
|
});
|
|
1997
|
-
if (
|
|
1998
|
-
if (
|
|
1999
|
-
const value = JSON.stringify({ [
|
|
1997
|
+
if (csvField2 && csvOnlyRequired && (!alternatives || hasCsvAlternative)) {
|
|
1998
|
+
if (csvField2 === "csv") return " --csv '<contacts.csv>'";
|
|
1999
|
+
const value = JSON.stringify({ [csvField2]: "<contacts.csv>" });
|
|
2000
2000
|
return ` --input '${value.replace(/'/g, "'\\''")}'`;
|
|
2001
2001
|
}
|
|
2002
2002
|
if (Array.isArray(schema.required) && !required.length && !csv && !alternatives) {
|
|
@@ -3507,7 +3507,7 @@ var SDK_RELEASE = {
|
|
|
3507
3507
|
// getters keep their established compatibility behavior.
|
|
3508
3508
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
3509
3509
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
3510
|
-
version: "0.3.
|
|
3510
|
+
version: "0.3.276",
|
|
3511
3511
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
3512
3512
|
packageCapabilities: {
|
|
3513
3513
|
updatePreferences: 1
|
|
@@ -6210,6 +6210,28 @@ async function* watchRunEvents(options) {
|
|
|
6210
6210
|
}
|
|
6211
6211
|
}
|
|
6212
6212
|
|
|
6213
|
+
// src/runs/log-cursor.ts
|
|
6214
|
+
var RUN_LOGS_CURSOR_PREFIX = "before:";
|
|
6215
|
+
function encodeRunLogsCursor(beforeSequence) {
|
|
6216
|
+
return `${RUN_LOGS_CURSOR_PREFIX}${beforeSequence}`;
|
|
6217
|
+
}
|
|
6218
|
+
function isRunLogsCursor(value) {
|
|
6219
|
+
return value.startsWith(RUN_LOGS_CURSOR_PREFIX);
|
|
6220
|
+
}
|
|
6221
|
+
function parseRunLogsCursor(value) {
|
|
6222
|
+
const raw = isRunLogsCursor(value) ? value.slice(RUN_LOGS_CURSOR_PREFIX.length) : "";
|
|
6223
|
+
const parsed = /^[1-9]\d*$/.test(raw) ? Number(raw) : NaN;
|
|
6224
|
+
if (!Number.isSafeInteger(parsed)) {
|
|
6225
|
+
throw Object.assign(
|
|
6226
|
+
new Error(
|
|
6227
|
+
`Invalid run log cursor ${JSON.stringify(value)}. Pass the nextCursor value from a previous deepline runs logs result.`
|
|
6228
|
+
),
|
|
6229
|
+
{ exitCode: 2 }
|
|
6230
|
+
);
|
|
6231
|
+
}
|
|
6232
|
+
return parsed;
|
|
6233
|
+
}
|
|
6234
|
+
|
|
6213
6235
|
// src/types.ts
|
|
6214
6236
|
function isStopAllPlayRunsDryRunResult(result) {
|
|
6215
6237
|
return "dryRun" in result && result.dryRun === true;
|
|
@@ -7160,6 +7182,7 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
7160
7182
|
status: (runId) => this.getRunLifecycleStatus(runId),
|
|
7161
7183
|
list: (options2) => this.listRuns(options2),
|
|
7162
7184
|
listPage: (options2) => this.listRunsPage(options2),
|
|
7185
|
+
history: (options2) => this.getRunsHistory(options2),
|
|
7163
7186
|
watch: (runId, options2) => this.watchRunToTerminal(runId, options2),
|
|
7164
7187
|
tail: (runId, options2) => this.tailRun(runId, options2),
|
|
7165
7188
|
logs: (runId, options2) => this.getRunLogs(runId, options2),
|
|
@@ -8237,11 +8260,21 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8237
8260
|
if (options?.full === true) {
|
|
8238
8261
|
params.set("full", "true");
|
|
8239
8262
|
}
|
|
8263
|
+
if (options?.configuration === true) {
|
|
8264
|
+
params.set("include", "configuration");
|
|
8265
|
+
}
|
|
8240
8266
|
const query = params.size > 0 ? `?${params.toString()}` : "";
|
|
8241
8267
|
const response = await this.http.get(
|
|
8242
8268
|
`/api/v2/runs/${encodeURIComponent(runId)}${query}`,
|
|
8243
8269
|
{ headers: { "x-deepline-run-status": "1" } }
|
|
8244
8270
|
);
|
|
8271
|
+
if (options?.configuration === true && !Object.hasOwn(response, "contract")) {
|
|
8272
|
+
throw new DeeplineError(
|
|
8273
|
+
"This server does not support recorded configuration reads.",
|
|
8274
|
+
void 0,
|
|
8275
|
+
"RUN_CONFIGURATION_UNAVAILABLE"
|
|
8276
|
+
);
|
|
8277
|
+
}
|
|
8245
8278
|
const status = normalizePlayStatus(response);
|
|
8246
8279
|
if (options?.failedLogs !== true || status.status !== "failed") {
|
|
8247
8280
|
return status;
|
|
@@ -8329,6 +8362,33 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8329
8362
|
async listRuns(options) {
|
|
8330
8363
|
return (await this.listRunsPage(options)).runs;
|
|
8331
8364
|
}
|
|
8365
|
+
/** The same tenant-scoped run history searched by the dashboard and CLI. */
|
|
8366
|
+
async getRunsHistory(options = {}) {
|
|
8367
|
+
const params = new URLSearchParams();
|
|
8368
|
+
const search = options.search?.trim();
|
|
8369
|
+
if (search && search.length > 200) {
|
|
8370
|
+
throw new Error("Run search must be at most 200 characters.");
|
|
8371
|
+
}
|
|
8372
|
+
if (options.type && options.type !== "all" && !search) {
|
|
8373
|
+
throw new Error("runs.history options.type requires options.search.");
|
|
8374
|
+
}
|
|
8375
|
+
if (search) params.set("search", search);
|
|
8376
|
+
if (search && options.type) params.set("type", options.type);
|
|
8377
|
+
if (options.cursor) params.set("cursor", options.cursor);
|
|
8378
|
+
if (options.orgId) params.set("orgId", options.orgId);
|
|
8379
|
+
if (options.limit !== void 0) {
|
|
8380
|
+
if (!Number.isSafeInteger(options.limit) || options.limit < 1) {
|
|
8381
|
+
throw new Error(
|
|
8382
|
+
"runs.history options.limit must be a positive integer."
|
|
8383
|
+
);
|
|
8384
|
+
}
|
|
8385
|
+
params.set("limit", String(options.limit));
|
|
8386
|
+
}
|
|
8387
|
+
return this.http.get(
|
|
8388
|
+
`/api/v2/dashboard/runs-history?${params.toString()}`,
|
|
8389
|
+
{ signal: options.signal }
|
|
8390
|
+
);
|
|
8391
|
+
}
|
|
8332
8392
|
/** Read one run page without discarding server pagination metadata. */
|
|
8333
8393
|
async listRunsPage(options) {
|
|
8334
8394
|
const playName = options.play?.trim();
|
|
@@ -8435,6 +8495,13 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8435
8495
|
"INVALID_RUN_LOG_VIEW"
|
|
8436
8496
|
);
|
|
8437
8497
|
}
|
|
8498
|
+
if (options?.cursor !== void 0 && options.failed === true) {
|
|
8499
|
+
throw new DeeplineError(
|
|
8500
|
+
"runs.logs cannot combine failed with cursor.",
|
|
8501
|
+
void 0,
|
|
8502
|
+
"INVALID_RUN_LOG_VIEW"
|
|
8503
|
+
);
|
|
8504
|
+
}
|
|
8438
8505
|
if (options?.failed === true) {
|
|
8439
8506
|
const requestedLimit = typeof options.limit === "number" && Number.isFinite(options.limit) && options.limit > 0 ? Math.trunc(options.limit) : RUNS_FAILED_LOG_LIMIT;
|
|
8440
8507
|
const failedLimit = Math.min(RUNS_FAILED_LOG_LIMIT, requestedLimit);
|
|
@@ -8460,6 +8527,7 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8460
8527
|
...page.logsTruncated ? { logsTruncated: true } : {}
|
|
8461
8528
|
};
|
|
8462
8529
|
}
|
|
8530
|
+
const beforeSequence = options?.cursor !== void 0 ? parseRunLogsCursor(options.cursor) : null;
|
|
8463
8531
|
const limit = options?.all ? Number.MAX_SAFE_INTEGER : typeof options?.limit === "number" && Number.isFinite(options.limit) && options.limit > 0 ? Math.trunc(options.limit) : 200;
|
|
8464
8532
|
const fetchPage = (afterSeq2, pageLimit) => this.http.get(
|
|
8465
8533
|
`/api/v2/runs/${encodeURIComponent(runId)}/logs?afterSeq=${afterSeq2}&limit=${pageLimit}`,
|
|
@@ -8467,24 +8535,33 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8467
8535
|
);
|
|
8468
8536
|
const probe = await fetchPage(0, 1);
|
|
8469
8537
|
const lastStoredSeq = probe.lastStoredSeq;
|
|
8470
|
-
|
|
8538
|
+
const oldestStoredSeq = probe.entries[0]?.seq ?? null;
|
|
8539
|
+
const upperSeq = beforeSequence === null ? Number.POSITIVE_INFINITY : Math.min(beforeSequence - 1, lastStoredSeq);
|
|
8540
|
+
const windowEndSeq = Math.min(upperSeq, lastStoredSeq);
|
|
8541
|
+
let afterSeq = options?.all ? 0 : Math.max(0, windowEndSeq - limit);
|
|
8471
8542
|
const entries = [];
|
|
8472
|
-
while (entries.length < limit) {
|
|
8543
|
+
while (entries.length < limit && afterSeq < upperSeq) {
|
|
8473
8544
|
const page = await fetchPage(
|
|
8474
8545
|
afterSeq,
|
|
8475
|
-
Math.min(
|
|
8546
|
+
Math.min(
|
|
8547
|
+
RUN_LOGS_PAGE_LIMIT,
|
|
8548
|
+
limit - entries.length,
|
|
8549
|
+
upperSeq - afterSeq
|
|
8550
|
+
)
|
|
8476
8551
|
);
|
|
8477
|
-
|
|
8552
|
+
const inWindow = page.entries.filter((entry) => entry.seq <= upperSeq);
|
|
8553
|
+
if (inWindow.length === 0) {
|
|
8478
8554
|
break;
|
|
8479
8555
|
}
|
|
8480
|
-
entries.push(...
|
|
8481
|
-
afterSeq =
|
|
8482
|
-
if (!page.hasMore) {
|
|
8556
|
+
entries.push(...inWindow);
|
|
8557
|
+
afterSeq = inWindow[inWindow.length - 1].seq;
|
|
8558
|
+
if (!page.hasMore || inWindow.length < page.entries.length) {
|
|
8483
8559
|
break;
|
|
8484
8560
|
}
|
|
8485
8561
|
}
|
|
8486
8562
|
const firstSequence = entries.length > 0 ? entries[0].seq : null;
|
|
8487
8563
|
const lastSequence = entries.length > 0 ? entries[entries.length - 1].seq : null;
|
|
8564
|
+
const olderLinesExist = firstSequence !== null && oldestStoredSeq !== null && firstSequence > oldestStoredSeq;
|
|
8488
8565
|
return {
|
|
8489
8566
|
runId: probe.runId,
|
|
8490
8567
|
totalCount: probe.totalLogCount,
|
|
@@ -8492,7 +8569,8 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8492
8569
|
firstSequence,
|
|
8493
8570
|
lastSequence,
|
|
8494
8571
|
truncated: entries.length < probe.totalLogCount,
|
|
8495
|
-
hasMore:
|
|
8572
|
+
hasMore: olderLinesExist,
|
|
8573
|
+
nextCursor: olderLinesExist ? encodeRunLogsCursor(firstSequence) : null,
|
|
8496
8574
|
entries: entries.map((entry) => entry.line),
|
|
8497
8575
|
view: options?.all ? "all" : "tail",
|
|
8498
8576
|
...probe.logsTruncated ? { logsTruncated: true } : {}
|
|
@@ -10469,6 +10547,7 @@ var ROOTS = {
|
|
|
10469
10547
|
check: "kind target checked scope name exportName valid stage issues inputSchema outputSchema recognized triggers runtimeLimit limits featureFlags sourceHash artifactHash graphHash toolGetterHints exports actions diagnostics reference origin ownerType activeScheduledPlays command_context",
|
|
10470
10548
|
run: "schemaVersion kind run datasets actions apiVersion dashboardUrl progress rowOutcomes steps errors error warnings result resultState execution command_context diagnostics",
|
|
10471
10549
|
get: "schemaVersion kind run runStatus steps failures errorDetails rowOutcomes warnings failedLogs datasets result resultState actions diagnostics command_context",
|
|
10550
|
+
config: "runId contract command_context",
|
|
10472
10551
|
export: "runId datasets csv_path json_path format source rowCount columns notice metadata_path actions command_context"
|
|
10473
10552
|
};
|
|
10474
10553
|
function parseJsonFields(args, surface) {
|
|
@@ -15690,205 +15769,73 @@ function registerPlayTriggerConfigCommands(plays) {
|
|
|
15690
15769
|
import { createHash as createHash4, randomUUID as randomUUID4 } from "crypto";
|
|
15691
15770
|
|
|
15692
15771
|
// src/cli/run-logs-help.ts
|
|
15693
|
-
var
|
|
15694
|
-
"run.created":
|
|
15695
|
-
|
|
15696
|
-
|
|
15697
|
-
|
|
15698
|
-
"run.
|
|
15699
|
-
|
|
15700
|
-
|
|
15701
|
-
|
|
15702
|
-
"
|
|
15703
|
-
|
|
15704
|
-
|
|
15705
|
-
|
|
15706
|
-
"
|
|
15707
|
-
"
|
|
15708
|
-
|
|
15709
|
-
|
|
15710
|
-
|
|
15711
|
-
"
|
|
15712
|
-
|
|
15713
|
-
|
|
15714
|
-
|
|
15715
|
-
|
|
15716
|
-
|
|
15717
|
-
|
|
15718
|
-
|
|
15719
|
-
|
|
15720
|
-
"run
|
|
15721
|
-
|
|
15722
|
-
|
|
15723
|
-
|
|
15724
|
-
|
|
15725
|
-
|
|
15726
|
-
|
|
15727
|
-
},
|
|
15728
|
-
"step.progress": {
|
|
15729
|
-
emittedBy: "Managed step execution",
|
|
15730
|
-
payloadFields: ["stepId", "label", "kind", "status", "progress"]
|
|
15731
|
-
},
|
|
15732
|
-
"step.completed": {
|
|
15733
|
-
emittedBy: "Managed step execution",
|
|
15734
|
-
payloadFields: ["stepId", "label", "kind", "artifactTableNamespace"]
|
|
15735
|
-
},
|
|
15736
|
-
"step.failed": {
|
|
15737
|
-
emittedBy: "Managed step execution",
|
|
15738
|
-
payloadFields: [
|
|
15739
|
-
"stepId",
|
|
15740
|
-
"label",
|
|
15741
|
-
"kind",
|
|
15742
|
-
"error",
|
|
15743
|
-
"artifactTableNamespace"
|
|
15744
|
-
]
|
|
15745
|
-
},
|
|
15746
|
-
"step.skipped": {
|
|
15747
|
-
emittedBy: "Managed step execution",
|
|
15748
|
-
payloadFields: ["stepId", "label", "kind", "artifactTableNamespace"]
|
|
15749
|
-
},
|
|
15750
|
-
"log.appended": {
|
|
15751
|
-
emittedBy: "ctx.log and runtime/coordinator messages",
|
|
15752
|
-
payloadFields: [
|
|
15753
|
-
"lines",
|
|
15754
|
-
"lineContexts",
|
|
15755
|
-
"producerAttempt",
|
|
15756
|
-
"channelOffset",
|
|
15757
|
-
"logsTruncated"
|
|
15758
|
-
]
|
|
15759
|
-
},
|
|
15760
|
-
"dataset.lifecycle": {
|
|
15761
|
-
emittedBy: "Managed dataset storage",
|
|
15762
|
-
payloadFields: [
|
|
15763
|
-
"datasetId",
|
|
15764
|
-
"path",
|
|
15765
|
-
"tableNamespace",
|
|
15766
|
-
"phase",
|
|
15767
|
-
"persistedRows",
|
|
15768
|
-
"succeededRows",
|
|
15769
|
-
"failedRows",
|
|
15770
|
-
"complete",
|
|
15771
|
-
"bornFrom"
|
|
15772
|
-
]
|
|
15772
|
+
var KIND_DESCRIPTIONS = {
|
|
15773
|
+
"run.created": "Run accepted.",
|
|
15774
|
+
"run.started": "Execution started.",
|
|
15775
|
+
"run.waiting": "Run waiting.",
|
|
15776
|
+
"run.resumed": "Execution resumed.",
|
|
15777
|
+
"run.completed": "Run succeeded.",
|
|
15778
|
+
"run.failed": "Run failed.",
|
|
15779
|
+
"run.cancelled": "Run cancelled.",
|
|
15780
|
+
"step.started": "Step started.",
|
|
15781
|
+
"step.progress": "Progress update.",
|
|
15782
|
+
"step.completed": "Step succeeded.",
|
|
15783
|
+
"step.failed": "Step failed.",
|
|
15784
|
+
"step.skipped": "Step skipped.",
|
|
15785
|
+
"log.appended": "Text log line.",
|
|
15786
|
+
"dataset.lifecycle": "Dataset registered, available or failed.",
|
|
15787
|
+
"activity.observed": "Provider or workflow activity.",
|
|
15788
|
+
"work.counters": "Call, request and rate-limit totals.",
|
|
15789
|
+
"receipt.completed": "Saved work result: succeeded.",
|
|
15790
|
+
"receipt.failed": "Saved work result: failed.",
|
|
15791
|
+
"receipt.skipped": "Saved work result: skipped.",
|
|
15792
|
+
"runtime.event": "Other event."
|
|
15793
|
+
};
|
|
15794
|
+
var RUN_LOGS_KIND_HELP = RUN_EVENT_SEARCH_KIND_VALUES.map((kind) => ({
|
|
15795
|
+
kind,
|
|
15796
|
+
description: KIND_DESCRIPTIONS[kind]
|
|
15797
|
+
}));
|
|
15798
|
+
var READ_EXAMPLES = [
|
|
15799
|
+
"deepline runs logs '<run-id>'",
|
|
15800
|
+
"deepline runs logs '<run-id>' --out run.log"
|
|
15801
|
+
];
|
|
15802
|
+
var FILTER_EXAMPLES = [
|
|
15803
|
+
{
|
|
15804
|
+
label: "Failed work with saved details",
|
|
15805
|
+
command: `deepline runs logs --kind receipt.failed --where '$.status == "failed"' --payloads --json`
|
|
15773
15806
|
},
|
|
15774
|
-
|
|
15775
|
-
|
|
15776
|
-
|
|
15807
|
+
{
|
|
15808
|
+
label: "One failed step",
|
|
15809
|
+
command: `deepline runs logs --kind step.failed --where '$.stepId == "company-lookup"' --payloads --json`
|
|
15777
15810
|
},
|
|
15778
|
-
"work.counters": {
|
|
15779
|
-
emittedBy: "Runtime work accounting",
|
|
15780
|
-
payloadFields: [
|
|
15781
|
-
"attempt",
|
|
15782
|
-
"invocationSeq",
|
|
15783
|
-
"segmentId",
|
|
15784
|
-
"logicalCalls",
|
|
15785
|
-
"providerRequests",
|
|
15786
|
-
"provider429s",
|
|
15787
|
-
"final"
|
|
15788
|
-
]
|
|
15789
|
-
}
|
|
15790
|
-
};
|
|
15791
|
-
var RUN_LOGS_KIND_HELP = [
|
|
15792
|
-
...Object.entries(RUN_EVENT_KIND_CATALOG).map(([kind, descriptor]) => ({
|
|
15793
|
-
kind,
|
|
15794
|
-
description: descriptor.description,
|
|
15795
|
-
...EVENT_DETAILS[kind]
|
|
15796
|
-
})),
|
|
15797
|
-
...Object.entries(RUN_RECEIPT_SEARCH_KIND_CATALOG).map(
|
|
15798
|
-
([kind, descriptor]) => ({
|
|
15799
|
-
kind,
|
|
15800
|
-
description: descriptor.description,
|
|
15801
|
-
emittedBy: "Durable work receipt settlement",
|
|
15802
|
-
payloadFields: ["status", "output", "error", "errorPayload"]
|
|
15803
|
-
})
|
|
15804
|
-
),
|
|
15805
15811
|
{
|
|
15806
|
-
|
|
15807
|
-
|
|
15808
|
-
|
|
15809
|
-
payloadFields: []
|
|
15810
|
-
}
|
|
15811
|
-
];
|
|
15812
|
-
var SECTIONS = [
|
|
15812
|
+
label: "Provider and operation",
|
|
15813
|
+
command: `deepline runs logs --kind activity.observed --where '$.provider == "apollo" && $.operation == "company_lookup"' --json`
|
|
15814
|
+
},
|
|
15813
15815
|
{
|
|
15814
|
-
|
|
15815
|
-
|
|
15816
|
-
"These commands read existing evidence; they do not start a run or execute a provider. Replace <run-id>, <play-name> and other angle-bracket values with identifiers returned by the CLI.",
|
|
15817
|
-
"Text logs: runs logs <run-id> returns the last 200 retained lines by default. --out writes the full retained stream to a local file. --log-level filters text severity; debug includes all retained levels. --failed reads only a terminal-failed run\u2019s last 20 retained lines and reports retention limitations.",
|
|
15818
|
-
"Event search: omit the run ID, or add any of --since, --until, --play, --kind, --where, --payloads, --cursor, --runtime-namespace or --runtime-backend. A supplied run ID then narrows the search. --limit and --json alone do not switch a run\u2019s text logs to event search. Text-only flags --out, --failed and --log-level cannot be combined with event search.",
|
|
15819
|
-
"Current status and returned output selectors: runs get <run-id> --json. Live observation: runs watch <run-id>. Dataset rows: runs export <run-id> --dataset <returned-selector> --out rows.csv. A referenced tool response: runs receipt <run-id> --key <returned-receipt-key> --json. Read each command\u2019s --help for its options."
|
|
15820
|
-
],
|
|
15821
|
-
commands: [
|
|
15822
|
-
"deepline runs logs <run-id> --json",
|
|
15823
|
-
"deepline runs logs <run-id> --out run.log --json",
|
|
15824
|
-
"deepline runs logs --kind run.failed --json",
|
|
15825
|
-
"deepline runs logs --kind step.failed --payloads --json",
|
|
15826
|
-
"deepline runs logs --kind receipt.failed --payloads --json"
|
|
15827
|
-
]
|
|
15816
|
+
label: "Failed dataset",
|
|
15817
|
+
command: `deepline runs logs --kind dataset.lifecycle --where '$.datasetId == "companies" && $.phase == "failed"' --payloads --json`
|
|
15828
15818
|
},
|
|
15829
15819
|
{
|
|
15830
|
-
|
|
15831
|
-
|
|
15832
|
-
"Search defaults to the last hour, newest first. Use explicit ISO UTC --since and --until values for reproducible queries; the maximum lookback is seven days. Default page size is 100 events; --limit accepts 1\u2013200. With --payloads, default and maximum are 10 events, with 16 MiB total payload data.",
|
|
15833
|
-
"JSON returns events[], returnedCount, since, until, nextCursor and next.logs. Run the returned next.logs command to continue with the same filters and UTC window; nextCursor is opaque. A bounded page or an empty result does not establish whole-run coverage or application health."
|
|
15834
|
-
],
|
|
15835
|
-
commands: [
|
|
15836
|
-
"deepline runs logs <run-id> --kind log.appended --json",
|
|
15837
|
-
"deepline runs logs --play <play-name> --since <UTC-start> --until <UTC-end> --json"
|
|
15838
|
-
]
|
|
15820
|
+
label: "String log context",
|
|
15821
|
+
command: `deepline runs logs --kind log.appended --where '$.context.companyId == "acme_123"' --json`
|
|
15839
15822
|
},
|
|
15840
15823
|
{
|
|
15841
|
-
|
|
15842
|
-
|
|
15843
|
-
"Identity strings: orgId, runId, playName, runtimeScope. These come from authenticated execution state; filters only narrow your authorized organization/runtime. Preview reads require the existing runtime credential and an authorized --runtime-namespace; --runtime-backend selects daytona or modal.",
|
|
15844
|
-
"Event string: kind. Optional strings: source, stepId, stepKind, status, datasetId, phase, provider, operation. Optional positive integer: producerAttempt. These fields exist only when recorded; inspect a returned event before filtering on an optional field.",
|
|
15845
|
-
'stepId/stepKind describe recorded step work; datasetId/phase describe dataset lifecycle (registered, available, failed). provider/operation appear on typed provider activity.observed events, not every receipt or provider call. status is the recorded status or activity state when present: run.completed and step.completed do not imply status == "completed". Select lifecycle outcomes with --kind.',
|
|
15846
|
-
"context.<key> matches an authored flat scalar log field: string, number or boolean. Context cannot override event identity. Missing fields do not match. --where supports only $.field == literal predicates joined with &&, at most eight predicates and 512 bytes. No OR, ranges, wildcards, nested payload paths or text search. Time uses --since/--until; level and message are not --where fields.",
|
|
15847
|
-
'Wrap the entire predicate in single shell quotes so $ and && reach the CLI unchanged. Inside it, strings use double quotes; numbers and booleans are unquoted. Types must match: 2 differs from "2", false differs from "false". Examples use illustrative recorded values; use your own step IDs, dataset IDs, provider/operation names and authored context. The context examples assume ctx.log recorded companyId: "acme_123", attempt: 2 and cached: false.'
|
|
15848
|
-
],
|
|
15849
|
-
commands: [
|
|
15850
|
-
"# Failed retained work with its stored error/result",
|
|
15851
|
-
`deepline runs logs --kind receipt.failed --where '$.status == "failed"' --payloads --json`,
|
|
15852
|
-
"# Failure details for one named step",
|
|
15853
|
-
`deepline runs logs --kind step.failed --where '$.stepId == "company-lookup"' --payloads --json`,
|
|
15854
|
-
"# Typed provider observations matching both fields",
|
|
15855
|
-
`deepline runs logs --kind activity.observed --where '$.provider == "apollo" && $.operation == "company_lookup"' --json`,
|
|
15856
|
-
"# Failed lifecycle transitions for one dataset",
|
|
15857
|
-
`deepline runs logs --kind dataset.lifecycle --where '$.datasetId == "companies" && $.phase == "failed"' --payloads --json`,
|
|
15858
|
-
"# Authored string context on log lines",
|
|
15859
|
-
`deepline runs logs --kind log.appended --where '$.context.companyId == "acme_123"' --json`,
|
|
15860
|
-
"# Authored number and boolean context, both required to match",
|
|
15861
|
-
"deepline runs logs --kind log.appended --where '$.context.attempt == 2 && $.context.cached == false' --json",
|
|
15862
|
-
"# Known producer identity within one run",
|
|
15863
|
-
`deepline runs logs <run-id> --where '$.source == "worker" && $.producerAttempt == 1' --json`
|
|
15864
|
-
]
|
|
15824
|
+
label: "Number and boolean log context",
|
|
15825
|
+
command: "deepline runs logs --kind log.appended --where '$.context.attempt == 2 && $.context.cached == false' --json"
|
|
15865
15826
|
},
|
|
15866
15827
|
{
|
|
15867
|
-
|
|
15868
|
-
|
|
15869
|
-
"Search events include eventId, occurredAt, ingestedAt, kind, runId, playName, level and message. The CLI puts indexed fields directly on each events[] entry; SDK/API responses keep them under searchDoc. Log search message is a preview (up to 2,048 characters); use text logs or --out for full retained lines.",
|
|
15870
|
-
"--payloads adds eventPayload for stored canonical events: lifecycle, step details/errors, activity observations, dataset transitions and work counters. Receipt matches instead hydrate payload with status, output, error and errorPayload. An event without a receipt does not promise a tool response; retained payloads may be unavailable. Neither --where nor event search indexes request/response bodies.",
|
|
15871
|
-
"Search does not expose a receipt key or storage reference. To retrieve a specific retained tool response with runs receipt, use the receipt key returned in the run\u2019s exported evidence or tool execution metadata. For full row data, follow runs get output/export actions; dataset.lifecycle contains metadata, not all dataset rows.",
|
|
15872
|
-
"The catalog lists known searchable kinds, including receipt outcomes and the runtime.event fallback. Use the exact dotted name with --kind. Future stored kinds can also be queried; this list is not a CLI validation allowlist. Events are observations, not a count of billed provider calls.",
|
|
15873
|
-
"Catalog payload fields are possible producer fields, not required fields or --where paths. Canonical eventPayload uses type for the dotted event kind; its kind field, when present on a step, becomes indexed stepKind. Indexed log entries describe individual lines rather than reproducing the original lines batch.",
|
|
15874
|
-
"Canonical event envelopes carry runId, type, occurredAt (producer milliseconds), source, optional seq and optional producer-owned payload. Search occurredAt/ingestedAt are UTC timestamp strings. source identifies the recorded producer; producerAttempt is present only when known.",
|
|
15875
|
-
"activity.observed stores observation with activityId, stepId, target, state and observedAt. Targets describe provider, dataset, lease, runner, step or capacity work. State kinds are active, queued, waiting, retrying, scheduled, completed or failed; retry/wait detail stays in the payload. work.counters contains aggregate logicalCalls, providerRequests and provider429s, not per-call responses."
|
|
15876
|
-
],
|
|
15877
|
-
commands: []
|
|
15828
|
+
label: "One run and step",
|
|
15829
|
+
command: `deepline runs logs '<run-id>' --where '$.stepId == "company-lookup"' --json`
|
|
15878
15830
|
}
|
|
15879
15831
|
];
|
|
15880
|
-
|
|
15881
|
-
"Event/log/receipt search shares the PlanetScale index. New runs marked runEventStore=planet_scale retain accepted event/log history in PlanetScale; Convex keeps current run/control state and eligible saved-Play rollup facts. Older unmarked runs retain their existing readers. No backfill is implied.",
|
|
15882
|
-
"Search retention is seven days; receipt payload retention is independent. Logs reflect accepted, retained lines: runtime sampling and truncation can omit original console output. Read returned retention/sampling warnings; an export contains the full retained stream, not suppressed lines."
|
|
15883
|
-
];
|
|
15884
|
-
function wrapParagraph(text, indent2 = 2) {
|
|
15832
|
+
function wrapParagraph(text) {
|
|
15885
15833
|
const lines = [];
|
|
15886
|
-
|
|
15887
|
-
let line = padding;
|
|
15834
|
+
let line = " ";
|
|
15888
15835
|
for (const word of text.split(" ")) {
|
|
15889
15836
|
if (line.length + word.length > 80 && line.trim()) {
|
|
15890
15837
|
lines.push(line.trimEnd());
|
|
15891
|
-
line =
|
|
15838
|
+
line = " ";
|
|
15892
15839
|
}
|
|
15893
15840
|
line += `${word} `;
|
|
15894
15841
|
}
|
|
@@ -15896,34 +15843,36 @@ function wrapParagraph(text, indent2 = 2) {
|
|
|
15896
15843
|
return lines.join("\n");
|
|
15897
15844
|
}
|
|
15898
15845
|
function renderRunLogsHelp() {
|
|
15899
|
-
const section = ({
|
|
15900
|
-
title,
|
|
15901
|
-
paragraphs,
|
|
15902
|
-
commands
|
|
15903
|
-
}) => [
|
|
15904
|
-
`${title}:`,
|
|
15905
|
-
...paragraphs.flatMap((paragraph) => [wrapParagraph(paragraph), ""]),
|
|
15906
|
-
...commands.length ? [" Common commands:", ...commands.map((command) => ` ${command}`)] : [],
|
|
15907
|
-
""
|
|
15908
|
-
];
|
|
15909
15846
|
return [
|
|
15910
15847
|
"",
|
|
15911
|
-
|
|
15912
|
-
|
|
15913
|
-
|
|
15914
|
-
|
|
15915
|
-
|
|
15916
|
-
|
|
15917
|
-
|
|
15918
|
-
|
|
15919
|
-
|
|
15920
|
-
|
|
15921
|
-
]
|
|
15848
|
+
"Examples:",
|
|
15849
|
+
` ${READ_EXAMPLES[0]}`,
|
|
15850
|
+
" deepline runs logs --kind run.failed --json",
|
|
15851
|
+
...[FILTER_EXAMPLES[1], FILTER_EXAMPLES[2], FILTER_EXAMPLES[5]].map(
|
|
15852
|
+
({ command }) => ` ${command}`
|
|
15853
|
+
),
|
|
15854
|
+
"",
|
|
15855
|
+
"Event kinds:",
|
|
15856
|
+
...RUN_LOGS_KIND_HELP.map(
|
|
15857
|
+
({ kind, description }) => ` ${kind.padEnd(20)} ${description}`
|
|
15922
15858
|
),
|
|
15923
15859
|
"",
|
|
15924
|
-
|
|
15925
|
-
|
|
15926
|
-
|
|
15860
|
+
"Filters:",
|
|
15861
|
+
...[
|
|
15862
|
+
"Use $.field == value; combine matches with &&.",
|
|
15863
|
+
"Quote the whole filter with single shell quotes. Strings use double quotes; numbers and booleans are unquoted.",
|
|
15864
|
+
"Missing fields do not match. Maximum eight matches and 512 bytes per filter."
|
|
15865
|
+
].map((note) => wrapParagraph(note)),
|
|
15866
|
+
"",
|
|
15867
|
+
"Search:",
|
|
15868
|
+
...[
|
|
15869
|
+
"A run ID alone reads text logs. Omit it or add a search flag to search events; a supplied run ID narrows the search.",
|
|
15870
|
+
"Defaults to the last hour; maximum lookback is seven days. Follow next.logs for events; use nextCursor with --cursor for older text logs.",
|
|
15871
|
+
"--payloads returns available details or saved results: up to 10 events and 16 MiB.",
|
|
15872
|
+
"--out, --failed and --log-level apply to text logs and cannot be combined with event search."
|
|
15873
|
+
].map((note) => wrapParagraph(note)),
|
|
15874
|
+
"",
|
|
15875
|
+
"More examples: https://deepline.com/docs/sdk-v2/run-events"
|
|
15927
15876
|
].join("\n");
|
|
15928
15877
|
}
|
|
15929
15878
|
|
|
@@ -18599,24 +18548,31 @@ includes nextCommand when another page is available.
|
|
|
18599
18548
|
|
|
18600
18549
|
// src/cli/commands/plays/run-history.ts
|
|
18601
18550
|
async function handleRunsHistory(options) {
|
|
18602
|
-
|
|
18603
|
-
if (options.
|
|
18604
|
-
|
|
18551
|
+
let limit;
|
|
18552
|
+
if (options.type && !["all", "plays", "monitors"].includes(options.type)) {
|
|
18553
|
+
throw new Error("--type must be all, plays or monitors.");
|
|
18554
|
+
}
|
|
18605
18555
|
if (options.limit !== void 0) {
|
|
18606
|
-
|
|
18556
|
+
limit = Number(options.limit);
|
|
18607
18557
|
if (!/^\d+$/.test(options.limit) || !Number.isSafeInteger(limit) || limit < 1) {
|
|
18608
18558
|
throw new Error("--limit must be a positive integer.");
|
|
18609
18559
|
}
|
|
18610
|
-
query.set("limit", String(limit));
|
|
18611
18560
|
}
|
|
18612
|
-
const
|
|
18613
|
-
|
|
18614
|
-
|
|
18615
|
-
|
|
18561
|
+
const page = await new DeeplineClient().runs.history({
|
|
18562
|
+
cursor: options.cursor,
|
|
18563
|
+
orgId: options.org,
|
|
18564
|
+
search: options.search,
|
|
18565
|
+
type: options.type,
|
|
18566
|
+
limit
|
|
18567
|
+
});
|
|
18616
18568
|
const lines = page.runs.map(
|
|
18617
18569
|
(run) => `${run.workflowName} \xB7 ${run.status} \xB7 ${run.runId}`
|
|
18618
18570
|
);
|
|
18619
|
-
if (lines.length === 0)
|
|
18571
|
+
if (lines.length === 0) {
|
|
18572
|
+
lines.push(
|
|
18573
|
+
options.search && page.hasMore ? "No matches in this page; continue searching with the next cursor." : "No runs found on this page."
|
|
18574
|
+
);
|
|
18575
|
+
}
|
|
18620
18576
|
if (page.hasMore) lines.push(`Next cursor: ${page.nextCursor}`);
|
|
18621
18577
|
printCommandEnvelope(
|
|
18622
18578
|
{ ...page, render: { sections: [{ title: "Run history", lines }] } },
|
|
@@ -18628,6 +18584,12 @@ function registerRunHistoryCommand(runs) {
|
|
|
18628
18584
|
"--cursor <cursor>",
|
|
18629
18585
|
"Opaque nextCursor returned by the previous page"
|
|
18630
18586
|
).option("--limit <count>", "Maximum runs on this page").option(
|
|
18587
|
+
"--search <text>",
|
|
18588
|
+
"Search Play/workflow names, run IDs and statuses"
|
|
18589
|
+
).option(
|
|
18590
|
+
"--type <type>",
|
|
18591
|
+
"Search all, plays or monitors (requires --search)"
|
|
18592
|
+
).option(
|
|
18631
18593
|
"--org <id>",
|
|
18632
18594
|
"Workspace ID (must match the authenticated workspace)"
|
|
18633
18595
|
).option("--json", "Emit JSON output. Also automatic when stdout is piped").addHelpText(
|
|
@@ -24357,6 +24319,63 @@ var SDK_TYPES_ENTRY_FILE = HAS_SOURCE_BUNDLING_SOURCES ? SDK_ENTRY_FILE : resolv
|
|
|
24357
24319
|
import { writeFileSync as writeFileSync9 } from "fs";
|
|
24358
24320
|
import { resolve as resolve10 } from "path";
|
|
24359
24321
|
|
|
24322
|
+
// ../plays/table-csv.ts
|
|
24323
|
+
var TABLE_EXPORT_ERROR_COLUMN = "_error";
|
|
24324
|
+
var UNRECORDED_FAILURE_REASON = "Row failed without a recorded reason.";
|
|
24325
|
+
function tableCellText(value) {
|
|
24326
|
+
if (value === null || value === void 0) return "";
|
|
24327
|
+
if (typeof value === "string") return value;
|
|
24328
|
+
if (typeof value === "number" || typeof value === "bigint" || typeof value === "boolean")
|
|
24329
|
+
return String(value);
|
|
24330
|
+
if (value instanceof Date) return value.toISOString();
|
|
24331
|
+
if (typeof value === "symbol" || typeof value === "function") return "";
|
|
24332
|
+
try {
|
|
24333
|
+
return JSON.stringify(
|
|
24334
|
+
value,
|
|
24335
|
+
(_key, nested) => typeof nested === "bigint" ? nested.toString() : nested
|
|
24336
|
+
) ?? "";
|
|
24337
|
+
} catch {
|
|
24338
|
+
return String(value);
|
|
24339
|
+
}
|
|
24340
|
+
}
|
|
24341
|
+
function csvField(value) {
|
|
24342
|
+
const text = tableCellText(value);
|
|
24343
|
+
return /[",\r\n]/.test(text) ? `"${text.replaceAll('"', '""')}"` : text;
|
|
24344
|
+
}
|
|
24345
|
+
function csvRecord(values) {
|
|
24346
|
+
return `${values.map(csvField).join(",")}
|
|
24347
|
+
`;
|
|
24348
|
+
}
|
|
24349
|
+
function isFailedRow(row) {
|
|
24350
|
+
return row.status === "failed";
|
|
24351
|
+
}
|
|
24352
|
+
function tableExportHasFailedRows(rows) {
|
|
24353
|
+
for (const row of rows) if (isFailedRow(row)) return true;
|
|
24354
|
+
return false;
|
|
24355
|
+
}
|
|
24356
|
+
function tableExportErrorCell(row) {
|
|
24357
|
+
if (!isFailedRow(row)) return "";
|
|
24358
|
+
const reason = typeof row.error === "string" ? row.error.trim() : "";
|
|
24359
|
+
return reason || UNRECORDED_FAILURE_REASON;
|
|
24360
|
+
}
|
|
24361
|
+
function tableExportColumns(columns, withError) {
|
|
24362
|
+
if (!withError) return [...columns];
|
|
24363
|
+
return [
|
|
24364
|
+
...columns.filter((column) => column !== TABLE_EXPORT_ERROR_COLUMN),
|
|
24365
|
+
TABLE_EXPORT_ERROR_COLUMN
|
|
24366
|
+
];
|
|
24367
|
+
}
|
|
24368
|
+
function tableExportCells(row, columns, withError) {
|
|
24369
|
+
return tableExportColumns(columns, withError).map(
|
|
24370
|
+
(column) => column === TABLE_EXPORT_ERROR_COLUMN && withError ? tableExportErrorCell(row) : Object.hasOwn(row.data, column) ? row.data[column] : void 0
|
|
24371
|
+
);
|
|
24372
|
+
}
|
|
24373
|
+
function tableCsvText(header, records) {
|
|
24374
|
+
let text = csvRecord(header);
|
|
24375
|
+
for (const record5 of records) text += csvRecord(record5);
|
|
24376
|
+
return text;
|
|
24377
|
+
}
|
|
24378
|
+
|
|
24360
24379
|
// src/cli/run-dataset-order.ts
|
|
24361
24380
|
function underscoreKeysLast(keys) {
|
|
24362
24381
|
return [...keys].sort(
|
|
@@ -24405,9 +24424,13 @@ var RunDatasetCsv = class _RunDatasetCsv {
|
|
|
24405
24424
|
}
|
|
24406
24425
|
write(outPath) {
|
|
24407
24426
|
const absolutePath = resolve10(outPath);
|
|
24427
|
+
const { rows, columns } = this.#projection;
|
|
24408
24428
|
writeFileSync9(
|
|
24409
24429
|
absolutePath,
|
|
24410
|
-
|
|
24430
|
+
tableCsvText(
|
|
24431
|
+
columns,
|
|
24432
|
+
rows.map((data) => tableExportCells({ data }, columns, false))
|
|
24433
|
+
),
|
|
24411
24434
|
"utf-8"
|
|
24412
24435
|
);
|
|
24413
24436
|
return absolutePath;
|
|
@@ -32003,7 +32026,20 @@ async function fetchBackingDatasetRows(input2) {
|
|
|
32003
32026
|
}
|
|
32004
32027
|
offset += page.rows.length;
|
|
32005
32028
|
}
|
|
32006
|
-
const
|
|
32029
|
+
const withError = tableExportHasFailedRows(
|
|
32030
|
+
sheetRows.filter(
|
|
32031
|
+
(row) => Boolean(row) && typeof row === "object" && !Array.isArray(row)
|
|
32032
|
+
)
|
|
32033
|
+
);
|
|
32034
|
+
const rows = sheetRows.map((row) => {
|
|
32035
|
+
const data = exportableSheetRow(row);
|
|
32036
|
+
return data && withError ? {
|
|
32037
|
+
...data,
|
|
32038
|
+
[TABLE_EXPORT_ERROR_COLUMN]: tableExportErrorCell(
|
|
32039
|
+
row
|
|
32040
|
+
)
|
|
32041
|
+
} : data;
|
|
32042
|
+
}).filter((row) => Boolean(row));
|
|
32007
32043
|
const hasCompleteSettledPrefix = acceptsSettledRowsAsCompleteExport(input2.status) && settledTotal !== null && // A zero-row run-scoped read is not a settled export when the returned
|
|
32008
32044
|
// Dataset Handle advertised rows. That shape is the replay/reuse case:
|
|
32009
32045
|
// the rows belong to another writer (or the projection has not caught up)
|
|
@@ -33985,9 +34021,12 @@ function renderRunOverviewText(overview, extras = {}) {
|
|
|
33985
34021
|
${renderCommandEnvelopeText({ render: { sections, actions: actions2 } })}`;
|
|
33986
34022
|
}
|
|
33987
34023
|
async function handleRunGet(args) {
|
|
33988
|
-
const selection = parseJsonFields(
|
|
34024
|
+
const selection = parseJsonFields(
|
|
34025
|
+
args,
|
|
34026
|
+
args.includes("--config") ? "config" : "get"
|
|
34027
|
+
);
|
|
33989
34028
|
args = selection.args;
|
|
33990
|
-
const usage2 = "Usage: deepline runs get <run-id> [--json] [--full] [--input] [--log-failed]";
|
|
34029
|
+
const usage2 = "Usage: deepline runs get <run-id> [--json] [--full] [--input] [--config] [--log-failed]";
|
|
33991
34030
|
let runId;
|
|
33992
34031
|
try {
|
|
33993
34032
|
runId = parseRunIdPositional(args, usage2);
|
|
@@ -33996,6 +34035,25 @@ async function handleRunGet(args) {
|
|
|
33996
34035
|
return 1;
|
|
33997
34036
|
}
|
|
33998
34037
|
const client2 = new DeeplineClient();
|
|
34038
|
+
if (args.includes("--config")) {
|
|
34039
|
+
if (args.some((arg) => ["--input", "--full", "--log-failed"].includes(arg))) {
|
|
34040
|
+
console.error(
|
|
34041
|
+
"--config cannot be combined with --input, --full or --log-failed."
|
|
34042
|
+
);
|
|
34043
|
+
return 1;
|
|
34044
|
+
}
|
|
34045
|
+
const status2 = await client2.runs.get(runId, { configuration: true });
|
|
34046
|
+
if (!Object.hasOwn(status2, "contract")) {
|
|
34047
|
+
throw new Error(
|
|
34048
|
+
"This server does not support recorded configuration reads."
|
|
34049
|
+
);
|
|
34050
|
+
}
|
|
34051
|
+
printCommandEnvelope(
|
|
34052
|
+
{ runId, contract: status2.contract ?? null },
|
|
34053
|
+
{ json: true, fields: selection.fields }
|
|
34054
|
+
);
|
|
34055
|
+
return 0;
|
|
34056
|
+
}
|
|
33999
34057
|
if (args.includes("--input")) {
|
|
34000
34058
|
const input2 = await client2.getRunInput(runId);
|
|
34001
34059
|
printCommandEnvelope(input2, { json: true });
|
|
@@ -34501,15 +34559,17 @@ async function handleRunLogs(args) {
|
|
|
34501
34559
|
"--play",
|
|
34502
34560
|
"--kind",
|
|
34503
34561
|
"--where",
|
|
34504
|
-
"--cursor",
|
|
34505
34562
|
"--payloads",
|
|
34506
34563
|
"--runtime-namespace",
|
|
34507
34564
|
"--runtime-backend"
|
|
34508
34565
|
]);
|
|
34509
|
-
|
|
34566
|
+
const cursorIndex = args.indexOf("--cursor");
|
|
34567
|
+
const cursorValue = cursorIndex >= 0 ? args[cursorIndex + 1] : void 0;
|
|
34568
|
+
const continuesEventSearch = cursorIndex >= 0 && !(cursorValue && isRunLogsCursor(cursorValue));
|
|
34569
|
+
if (!args[0] || args[0].startsWith("--") || continuesEventSearch || args.some((arg) => searchFlags.has(arg))) {
|
|
34510
34570
|
return handleRunEventSearch(args);
|
|
34511
34571
|
}
|
|
34512
|
-
const usage2 = "Usage: deepline runs logs <run-id> [--limit 200] [--failed] [--out run.log] [--log-level debug|info|warn|error] [--json]";
|
|
34572
|
+
const usage2 = "Usage: deepline runs logs <run-id> [--limit 200] [--cursor before:<seq>] [--failed] [--out run.log] [--log-level debug|info|warn|error] [--json]";
|
|
34513
34573
|
let runId;
|
|
34514
34574
|
try {
|
|
34515
34575
|
runId = parseRunIdPositional(args, usage2);
|
|
@@ -34519,6 +34579,7 @@ async function handleRunLogs(args) {
|
|
|
34519
34579
|
}
|
|
34520
34580
|
let limit = 200;
|
|
34521
34581
|
let outPath = null;
|
|
34582
|
+
let cursor;
|
|
34522
34583
|
let logLevel = "debug";
|
|
34523
34584
|
let hasExplicitLogLevel = false;
|
|
34524
34585
|
let usesDebugAlias = false;
|
|
@@ -34557,6 +34618,10 @@ async function handleRunLogs(args) {
|
|
|
34557
34618
|
outPath = resolve13(args[++index]);
|
|
34558
34619
|
continue;
|
|
34559
34620
|
}
|
|
34621
|
+
if (arg === "--cursor" && args[index + 1]) {
|
|
34622
|
+
cursor = args[++index];
|
|
34623
|
+
continue;
|
|
34624
|
+
}
|
|
34560
34625
|
if (arg.startsWith("--")) {
|
|
34561
34626
|
console.error(`${arg} is not supported by deepline runs logs.`);
|
|
34562
34627
|
return 1;
|
|
@@ -34575,6 +34640,12 @@ async function handleRunLogs(args) {
|
|
|
34575
34640
|
);
|
|
34576
34641
|
return 1;
|
|
34577
34642
|
}
|
|
34643
|
+
if (cursor !== void 0 && (failed || outPath)) {
|
|
34644
|
+
console.error(
|
|
34645
|
+
"--cursor pages the bounded log tail; it cannot be combined with --failed or --out."
|
|
34646
|
+
);
|
|
34647
|
+
return 1;
|
|
34648
|
+
}
|
|
34578
34649
|
const client2 = new DeeplineClient();
|
|
34579
34650
|
if (outPath) {
|
|
34580
34651
|
const result2 = await client2.runs.logs(runId, { all: true });
|
|
@@ -34608,19 +34679,25 @@ async function handleRunLogs(args) {
|
|
|
34608
34679
|
return 0;
|
|
34609
34680
|
}
|
|
34610
34681
|
const result = await client2.runs.logs(runId, {
|
|
34611
|
-
...failed ? { limit, failed: true } : { all: logLevel !== "debug", limit }
|
|
34612
|
-
|
|
34613
|
-
|
|
34614
|
-
|
|
34615
|
-
|
|
34616
|
-
|
|
34617
|
-
|
|
34682
|
+
...failed ? { limit, failed: true } : { all: logLevel !== "debug", limit },
|
|
34683
|
+
...cursor !== void 0 ? { cursor } : {}
|
|
34684
|
+
});
|
|
34685
|
+
const page = failed ? {
|
|
34686
|
+
entries: result.entries,
|
|
34687
|
+
firstSequence: result.firstSequence,
|
|
34688
|
+
lastSequence: result.lastSequence,
|
|
34689
|
+
truncated: result.truncated,
|
|
34690
|
+
hasMore: result.hasMore,
|
|
34691
|
+
nextCursor: void 0
|
|
34692
|
+
} : selectRunLogTailPage(result, logLevel, limit);
|
|
34693
|
+
const entries = page.entries;
|
|
34694
|
+
const nextPage = page.nextCursor ? `deepline runs logs ${result.runId} --limit ${limit}${logLevel === "debug" ? "" : ` --log-level ${logLevel}`} --cursor ${page.nextCursor} --json` : null;
|
|
34618
34695
|
const filteredResult = {
|
|
34619
34696
|
...result,
|
|
34620
34697
|
entries,
|
|
34621
34698
|
returnedCount: entries.length,
|
|
34622
|
-
truncated:
|
|
34623
|
-
hasMore:
|
|
34699
|
+
truncated: page.truncated,
|
|
34700
|
+
hasMore: page.hasMore,
|
|
34624
34701
|
view: failed ? result.view : "tail",
|
|
34625
34702
|
next: {
|
|
34626
34703
|
...result.next ?? {},
|
|
@@ -34633,10 +34710,11 @@ async function handleRunLogs(args) {
|
|
|
34633
34710
|
runId: result.runId,
|
|
34634
34711
|
totalCount: result.totalCount,
|
|
34635
34712
|
returnedCount: entries.length,
|
|
34636
|
-
firstSequence:
|
|
34637
|
-
lastSequence:
|
|
34713
|
+
firstSequence: page.firstSequence,
|
|
34714
|
+
lastSequence: page.lastSequence,
|
|
34638
34715
|
truncated: filteredResult.truncated,
|
|
34639
34716
|
hasMore: filteredResult.hasMore,
|
|
34717
|
+
...page.nextCursor !== void 0 ? { nextCursor: page.nextCursor } : {},
|
|
34640
34718
|
logLevel,
|
|
34641
34719
|
...result.logsTruncated ? { logsTruncated: true } : {},
|
|
34642
34720
|
entries,
|
|
@@ -34645,6 +34723,7 @@ async function handleRunLogs(args) {
|
|
|
34645
34723
|
...result.warning ? { warning: result.warning } : {},
|
|
34646
34724
|
next: {
|
|
34647
34725
|
...result.next ?? {},
|
|
34726
|
+
...nextPage ? { page: nextPage } : {},
|
|
34648
34727
|
export: `deepline runs logs ${result.runId} --out run.log --log-level ${logLevel} --json`
|
|
34649
34728
|
},
|
|
34650
34729
|
render: { sections: [{ title: "run logs", lines: entries }] }
|
|
@@ -34656,6 +34735,37 @@ async function handleRunLogs(args) {
|
|
|
34656
34735
|
);
|
|
34657
34736
|
return 0;
|
|
34658
34737
|
}
|
|
34738
|
+
function selectRunLogTailPage(result, logLevel, limit) {
|
|
34739
|
+
if (logLevel === "debug") {
|
|
34740
|
+
return {
|
|
34741
|
+
entries: [...result.entries],
|
|
34742
|
+
firstSequence: result.firstSequence,
|
|
34743
|
+
lastSequence: result.lastSequence,
|
|
34744
|
+
truncated: result.truncated,
|
|
34745
|
+
hasMore: result.hasMore,
|
|
34746
|
+
nextCursor: result.nextCursor ?? null
|
|
34747
|
+
};
|
|
34748
|
+
}
|
|
34749
|
+
const first = result.firstSequence;
|
|
34750
|
+
if (result.entries.length > 0 && (first === null || result.lastSequence === null || result.lastSequence - first + 1 !== result.entries.length)) {
|
|
34751
|
+
throw new Error(
|
|
34752
|
+
`Run log window is not contiguous (sequences ${first}..${result.lastSequence} for ${result.entries.length} lines); cannot page by severity.`
|
|
34753
|
+
);
|
|
34754
|
+
}
|
|
34755
|
+
const matching = result.entries.map((line, index) => ({ line, seq: first + index })).filter(
|
|
34756
|
+
(entry) => logLevelReaches(classifyLogLine(entry.line).level, logLevel)
|
|
34757
|
+
);
|
|
34758
|
+
const selected = matching.slice(-limit);
|
|
34759
|
+
const olderMatchesExist = matching.length > selected.length;
|
|
34760
|
+
return {
|
|
34761
|
+
entries: selected.map((entry) => entry.line),
|
|
34762
|
+
firstSequence: selected[0]?.seq ?? null,
|
|
34763
|
+
lastSequence: selected.at(-1)?.seq ?? null,
|
|
34764
|
+
truncated: result.truncated || olderMatchesExist,
|
|
34765
|
+
hasMore: olderMatchesExist,
|
|
34766
|
+
nextCursor: olderMatchesExist ? encodeRunLogsCursor(selected[0].seq) : null
|
|
34767
|
+
};
|
|
34768
|
+
}
|
|
34659
34769
|
async function handleRunEventSearch(args) {
|
|
34660
34770
|
const usage2 = "Usage: deepline runs logs [run-id] [--since ISO] [--until ISO] [--play name] [--kind kind] [--where jsonpath] [--payloads] [--cursor token] [--limit 100] [--json]";
|
|
34661
34771
|
const values = {};
|
|
@@ -34821,6 +34931,14 @@ function buildRunLogsText(result) {
|
|
|
34821
34931
|
}
|
|
34822
34932
|
return `${lines.join("\n")}${lines.length > 0 ? "\n" : ""}`;
|
|
34823
34933
|
}
|
|
34934
|
+
function resolveRunStopState(result) {
|
|
34935
|
+
if (result.state) return result.state;
|
|
34936
|
+
if (result.cancelling === true) return "cancelling";
|
|
34937
|
+
if (result.stopped === false || result.staleSchedulerState === true) {
|
|
34938
|
+
return "failed";
|
|
34939
|
+
}
|
|
34940
|
+
return "stopped";
|
|
34941
|
+
}
|
|
34824
34942
|
async function handleRunStop(args) {
|
|
34825
34943
|
const usage2 = 'Usage: deepline runs stop <run-id> [--reason "text"] [--json]';
|
|
34826
34944
|
let runId;
|
|
@@ -34839,15 +34957,25 @@ async function handleRunStop(args) {
|
|
|
34839
34957
|
}
|
|
34840
34958
|
const client2 = new DeeplineClient();
|
|
34841
34959
|
const result = await client2.runs.stop(runId, { reason });
|
|
34842
|
-
|
|
34960
|
+
const state = resolveRunStopState(result);
|
|
34961
|
+
const hitlCleanupIncomplete = state === "cancelling" && result.hitlCancellationPending === true;
|
|
34962
|
+
if (state === "cancelling" && !hitlCleanupIncomplete) {
|
|
34963
|
+
const {
|
|
34964
|
+
error: _legacyError,
|
|
34965
|
+
staleSchedulerState: _legacyStale,
|
|
34966
|
+
...cancelling
|
|
34967
|
+
} = result;
|
|
34843
34968
|
const lines2 = [
|
|
34844
|
-
`
|
|
34969
|
+
`Cancelling run ${result.runId || runId}; sandbox cleanup and the final run update are pending.`,
|
|
34845
34970
|
...result.hitlCancelledCount > 0 ? [`cancelled HITL waits: ${result.hitlCancelledCount}`] : [],
|
|
34846
34971
|
`inspect: deepline runs get ${runId} --full --json`
|
|
34847
34972
|
];
|
|
34848
34973
|
printCommandEnvelope(
|
|
34849
34974
|
{
|
|
34850
|
-
...
|
|
34975
|
+
...cancelling,
|
|
34976
|
+
state,
|
|
34977
|
+
stopped: false,
|
|
34978
|
+
cancelling: true,
|
|
34851
34979
|
render: {
|
|
34852
34980
|
sections: [
|
|
34853
34981
|
{
|
|
@@ -34861,9 +34989,8 @@ async function handleRunStop(args) {
|
|
|
34861
34989
|
);
|
|
34862
34990
|
return 0;
|
|
34863
34991
|
}
|
|
34864
|
-
|
|
34865
|
-
|
|
34866
|
-
const detail = typeof result.error === "string" && result.error.trim() ? result.error.trim() : result.staleSchedulerState === true ? "scheduler state for the run is stale" : "the server did not confirm the stop";
|
|
34992
|
+
if (state === "failed" || hitlCleanupIncomplete) {
|
|
34993
|
+
const detail = typeof result.error === "string" && result.error.trim() ? result.error.trim() : hitlCleanupIncomplete ? "cancellation is queued, but HITL cleanup is still pending" : result.staleSchedulerState === true ? "scheduler state for the run is stale" : "the server did not confirm the stop";
|
|
34867
34994
|
const lines2 = [
|
|
34868
34995
|
`Failed to stop run ${runId}: ${detail}.`,
|
|
34869
34996
|
...result.hitlCancelledCount > 0 ? [`cancelled HITL waits: ${result.hitlCancelledCount}`] : [],
|
|
@@ -36884,15 +37011,15 @@ Examples:
|
|
|
36884
37011
|
...options.json ? ["--json"] : []
|
|
36885
37012
|
]);
|
|
36886
37013
|
});
|
|
36887
|
-
const runs = program.command("runs").description("Inspect,
|
|
37014
|
+
const runs = program.command("runs").description("Inspect, watch, stop, and export play runs.").addHelpText(
|
|
36888
37015
|
"after",
|
|
36889
37016
|
`
|
|
36890
37017
|
Concepts:
|
|
36891
37018
|
A run is one execution instance of a play. It has status, progress, logs,
|
|
36892
37019
|
returned result, dataset previews, recovery metadata, and optional dataset export.
|
|
36893
37020
|
plays run starts NEW work and follows it by default; --no-wait returns immediately.
|
|
36894
|
-
runs
|
|
36895
|
-
Use
|
|
37021
|
+
runs watch attaches to EXISTING work and follows progress without starting a run.
|
|
37022
|
+
Use watch after a disconnect or --no-wait; do not launch again to reconnect.
|
|
36896
37023
|
get reads the current overview once. logs fetches persisted log history.
|
|
36897
37024
|
stop requests cancellation. rerun starts new work and may spend credits.
|
|
36898
37025
|
|
|
@@ -36906,14 +37033,15 @@ Retrieve results:
|
|
|
36906
37033
|
not JSON rows. For a JSON row file, use --format json --out results.json.
|
|
36907
37034
|
|
|
36908
37035
|
Follow existing work:
|
|
36909
|
-
deepline runs
|
|
36910
|
-
|
|
36911
|
-
|
|
37036
|
+
deepline runs watch <run-id>
|
|
37037
|
+
watch --json waits for one terminal JSON document; --jsonl streams live events.
|
|
37038
|
+
runs tail is an alias of runs watch.
|
|
36912
37039
|
|
|
36913
37040
|
More options:
|
|
36914
37041
|
deepline runs get -h
|
|
36915
37042
|
deepline runs children -h
|
|
36916
37043
|
deepline runs tail -h
|
|
37044
|
+
deepline runs watch -h
|
|
36917
37045
|
deepline runs export -h
|
|
36918
37046
|
deepline plays -h
|
|
36919
37047
|
|
|
@@ -36960,6 +37088,7 @@ Notes:
|
|
|
36960
37088
|
Run activity and status evidence retain provider cooldown and call progress.
|
|
36961
37089
|
Use --input only when you intentionally need the original payload; it can
|
|
36962
37090
|
contain customer data and is never included in ordinary status output.
|
|
37091
|
+
--config reads only the recorded graph and source; it never uses current Play code.
|
|
36963
37092
|
--json run.status,datasets.name,actions selects fields without flattening.
|
|
36964
37093
|
Selection changes stdout only, not the server query. Optional missing paths
|
|
36965
37094
|
are omitted; array positions are preserved. --json diagnostics needs --full.
|
|
@@ -36971,6 +37100,7 @@ Examples:
|
|
|
36971
37100
|
deepline runs get play/my-play/run/20260501t000000-000 --log-failed --json
|
|
36972
37101
|
deepline runs get play/my-play/run/20260501t000000-000 --full --json
|
|
36973
37102
|
deepline runs get play/my-play/run/20260501t000000-000 --input
|
|
37103
|
+
deepline runs get play/my-play/run/20260501t000000-000 --config --json
|
|
36974
37104
|
`
|
|
36975
37105
|
).option(
|
|
36976
37106
|
"--json [fields]",
|
|
@@ -36981,6 +37111,9 @@ Examples:
|
|
|
36981
37111
|
).option(
|
|
36982
37112
|
"--input",
|
|
36983
37113
|
"Explicitly print the original retained input JSON (may contain customer data)"
|
|
37114
|
+
).option(
|
|
37115
|
+
"--config",
|
|
37116
|
+
"Explicitly print the recorded configuration, without full results"
|
|
36984
37117
|
).option(
|
|
36985
37118
|
"--log-failed",
|
|
36986
37119
|
"Attach a bounded terminal-failure log window for failed runs"
|
|
@@ -36990,6 +37123,7 @@ Examples:
|
|
|
36990
37123
|
...jsonFieldArgs(options.json),
|
|
36991
37124
|
...options.full ? ["--full"] : [],
|
|
36992
37125
|
...options.input ? ["--input"] : [],
|
|
37126
|
+
...options.config ? ["--config"] : [],
|
|
36993
37127
|
...options.logFailed ? ["--log-failed"] : []
|
|
36994
37128
|
]);
|
|
36995
37129
|
});
|
|
@@ -37130,15 +37264,7 @@ Examples:
|
|
|
37130
37264
|
...options.logLevel ? ["--log-level", options.logLevel] : []
|
|
37131
37265
|
]);
|
|
37132
37266
|
});
|
|
37133
|
-
runs.command("logs [runId]").description(
|
|
37134
|
-
"Fetch one run\u2019s logs or search recent runtime events across runs."
|
|
37135
|
-
).addHelpText("after", renderRunLogsHelp()).option(
|
|
37136
|
-
"--limit <count>",
|
|
37137
|
-
"Text tail: default 200; search: default 100, max 200 (10 with --payloads)"
|
|
37138
|
-
).option("--out <path>", "Write the full retained log stream to a file").option("--failed", "Show the bounded terminal-failure log window").option(
|
|
37139
|
-
"--log-level <level>",
|
|
37140
|
-
"Minimum severity: debug (default), info, warn, or error"
|
|
37141
|
-
).addOption(
|
|
37267
|
+
runs.command("logs [runId]").description("Read a run\u2019s logs or search recent events.").addHelpText("after", renderRunLogsHelp()).option("--limit <count>", "Maximum results: logs 200; events 100, max 200").option("--out <path>", "Save the full available text log").option("--failed", "Last 20 lines of a failed run").option("--log-level <level>", "debug (default), info, warn or error").addOption(
|
|
37142
37268
|
new Option3(
|
|
37143
37269
|
"--logs",
|
|
37144
37270
|
"Compatibility alias for --log-level debug"
|
|
@@ -37148,19 +37274,20 @@ Examples:
|
|
|
37148
37274
|
"--debug",
|
|
37149
37275
|
"Compatibility alias for --log-level debug"
|
|
37150
37276
|
).hideHelp()
|
|
37151
|
-
).option("--json", "
|
|
37152
|
-
"--
|
|
37153
|
-
"
|
|
37154
|
-
).
|
|
37155
|
-
|
|
37156
|
-
|
|
37157
|
-
|
|
37158
|
-
|
|
37159
|
-
|
|
37160
|
-
|
|
37161
|
-
|
|
37162
|
-
|
|
37163
|
-
|
|
37277
|
+
).option("--json", "JSON output; automatic when piped").option("--since <timestamp>", "Search from this UTC time").option("--until <timestamp>", "Search before this UTC time").option("--play <name>", "Filter by Play").option("--kind <kind>", "Filter by event kind").option("--where <filter>", "Match event fields; examples below").option("--payloads", "Include available details or saved results").option(
|
|
37278
|
+
"--cursor <token>",
|
|
37279
|
+
"Continue to older logs or the next events page"
|
|
37280
|
+
).addOption(
|
|
37281
|
+
new Option3(
|
|
37282
|
+
"--runtime-namespace <name>",
|
|
37283
|
+
"Search an explicitly authorized Preview namespace"
|
|
37284
|
+
).hideHelp()
|
|
37285
|
+
).addOption(
|
|
37286
|
+
new Option3(
|
|
37287
|
+
"--runtime-backend <backend>",
|
|
37288
|
+
"Preview backend: daytona or modal"
|
|
37289
|
+
).hideHelp()
|
|
37290
|
+
).action(async (runId, options) => {
|
|
37164
37291
|
process.exitCode = await handleRunLogs([
|
|
37165
37292
|
...runId ? [runId] : [],
|
|
37166
37293
|
...options.limit ? ["--limit", options.limit] : [],
|