deepline 0.1.11 → 0.1.19
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/README.md +18 -10
- package/dist/cli/index.js +1795 -1052
- package/dist/cli/index.mjs +1795 -1053
- package/dist/index.d.mts +427 -308
- package/dist/index.d.ts +427 -308
- package/dist/index.js +391 -326
- package/dist/index.mjs +391 -325
- package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +88 -22
- package/dist/repo/apps/play-runner-workers/src/entry.ts +804 -1253
- package/dist/repo/sdk/src/client.ts +287 -47
- package/dist/repo/sdk/src/config.ts +125 -8
- package/dist/repo/sdk/src/http.ts +10 -2
- package/dist/repo/sdk/src/index.ts +7 -16
- package/dist/repo/sdk/src/play.ts +105 -140
- package/dist/repo/sdk/src/plays/bundle-play-file.ts +23 -6
- package/dist/repo/sdk/src/plays/local-file-discovery.ts +207 -160
- package/dist/repo/sdk/src/tool-output.ts +0 -146
- package/dist/repo/sdk/src/types.ts +27 -0
- package/dist/repo/sdk/src/version.ts +2 -2
- package/dist/repo/sdk/src/worker-play-entry.ts +3 -0
- package/dist/repo/shared_libs/play-runtime/csv-rename.ts +180 -0
- package/dist/repo/shared_libs/play-runtime/tool-result.ts +250 -133
- package/dist/repo/shared_libs/plays/bundling/index.ts +274 -234
- package/dist/repo/shared_libs/plays/dataset.ts +29 -1
- package/package.json +5 -4
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/index.mjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/repo/apps/play-runner-workers/src/runtime/README.md +0 -21
- package/dist/repo/apps/play-runner-workers/src/runtime/batching.ts +0 -177
- package/dist/repo/apps/play-runner-workers/src/runtime/execution-plan.ts +0 -52
- package/dist/repo/apps/play-runner-workers/src/runtime/tool-batch.ts +0 -100
- package/dist/repo/apps/play-runner-workers/src/runtime/tool-result.ts +0 -184
- package/dist/repo/sdk/src/cli/commands/auth.ts +0 -500
- package/dist/repo/sdk/src/cli/commands/billing.ts +0 -188
- package/dist/repo/sdk/src/cli/commands/csv.ts +0 -123
- package/dist/repo/sdk/src/cli/commands/db.ts +0 -119
- package/dist/repo/sdk/src/cli/commands/feedback.ts +0 -40
- package/dist/repo/sdk/src/cli/commands/org.ts +0 -117
- package/dist/repo/sdk/src/cli/commands/play.ts +0 -3307
- package/dist/repo/sdk/src/cli/commands/tools.ts +0 -687
- package/dist/repo/sdk/src/cli/dataset-stats.ts +0 -341
- package/dist/repo/sdk/src/cli/index.ts +0 -148
- package/dist/repo/sdk/src/cli/progress.ts +0 -149
- package/dist/repo/sdk/src/cli/skills-sync.ts +0 -141
- package/dist/repo/sdk/src/cli/trace.ts +0 -61
- package/dist/repo/sdk/src/cli/utils.ts +0 -145
- package/dist/repo/sdk/src/compat.ts +0 -77
- package/dist/repo/shared_libs/observability/node-tracing.ts +0 -129
- package/dist/repo/shared_libs/observability/tracing.ts +0 -98
- package/dist/repo/shared_libs/play-runtime/context.ts +0 -3999
- package/dist/repo/shared_libs/play-runtime/ctx-contract.ts +0 -250
- package/dist/repo/shared_libs/play-runtime/ctx-types.ts +0 -713
- package/dist/repo/shared_libs/play-runtime/dataset-id.ts +0 -10
- package/dist/repo/shared_libs/play-runtime/db-session-crypto.ts +0 -304
- package/dist/repo/shared_libs/play-runtime/db-session.ts +0 -462
- package/dist/repo/shared_libs/play-runtime/live-events.ts +0 -214
- package/dist/repo/shared_libs/play-runtime/live-state-contract.ts +0 -50
- package/dist/repo/shared_libs/play-runtime/map-execution-frame.ts +0 -114
- package/dist/repo/shared_libs/play-runtime/map-row-identity.ts +0 -158
- package/dist/repo/shared_libs/play-runtime/progress-emitter.ts +0 -172
- package/dist/repo/shared_libs/play-runtime/protocol.ts +0 -121
- package/dist/repo/shared_libs/play-runtime/public-play-contract.ts +0 -42
- package/dist/repo/shared_libs/play-runtime/result-normalization.ts +0 -33
- package/dist/repo/shared_libs/play-runtime/runtime-api.ts +0 -1873
- package/dist/repo/shared_libs/play-runtime/runtime-constraints.ts +0 -2
- package/dist/repo/shared_libs/play-runtime/runtime-pg-driver-neon-serverless.ts +0 -201
- package/dist/repo/shared_libs/play-runtime/runtime-pg-driver-pg.ts +0 -48
- package/dist/repo/shared_libs/play-runtime/runtime-pg-driver.ts +0 -84
- package/dist/repo/shared_libs/play-runtime/static-pipeline-types.ts +0 -147
- package/dist/repo/shared_libs/play-runtime/suspension.ts +0 -68
- package/dist/repo/shared_libs/play-runtime/tracing.ts +0 -31
- package/dist/repo/shared_libs/play-runtime/waterfall-replay.ts +0 -75
- package/dist/repo/shared_libs/play-runtime/worker-api-types.ts +0 -140
- package/dist/repo/shared_libs/plays/artifact-transport.ts +0 -14
- package/dist/repo/shared_libs/plays/artifact-types.ts +0 -49
- package/dist/repo/shared_libs/plays/compiler-manifest.ts +0 -186
- package/dist/repo/shared_libs/plays/definition.ts +0 -264
- package/dist/repo/shared_libs/plays/file-refs.ts +0 -11
- package/dist/repo/shared_libs/plays/rate-limit-scheduler.ts +0 -206
- package/dist/repo/shared_libs/plays/resolve-static-pipeline.ts +0 -164
- package/dist/repo/shared_libs/plays/runtime-validation.ts +0 -415
- package/dist/repo/shared_libs/temporal/constants.ts +0 -39
- package/dist/repo/shared_libs/temporal/preview-config.ts +0 -153
package/dist/index.mjs
CHANGED
|
@@ -42,6 +42,10 @@ var ConfigError = class extends DeeplineError {
|
|
|
42
42
|
var PROD_URL = "https://code.deepline.com";
|
|
43
43
|
var DEFAULT_TIMEOUT = 6e4;
|
|
44
44
|
var DEFAULT_MAX_RETRIES = 3;
|
|
45
|
+
var ACTIVE_DEEPLINE_ENV_FILE = ".env.deepline";
|
|
46
|
+
function projectEnvStartDir() {
|
|
47
|
+
return process.env.DEEPLINE_PROJECT_ENV_DIR?.trim() || process.cwd();
|
|
48
|
+
}
|
|
45
49
|
function baseUrlSlug(baseUrl) {
|
|
46
50
|
let url;
|
|
47
51
|
try {
|
|
@@ -77,16 +81,52 @@ function parseEnvFile(filePath) {
|
|
|
77
81
|
}
|
|
78
82
|
return env;
|
|
79
83
|
}
|
|
80
|
-
function
|
|
84
|
+
function findNearestEnvFile(names, startDir = process.cwd()) {
|
|
81
85
|
let current = resolve(startDir);
|
|
82
86
|
while (true) {
|
|
83
|
-
const
|
|
84
|
-
|
|
87
|
+
for (const name of names) {
|
|
88
|
+
const filePath = join(current, name);
|
|
89
|
+
if (existsSync(filePath)) return filePath;
|
|
90
|
+
}
|
|
85
91
|
const parent = dirname(current);
|
|
86
|
-
if (parent === current) return
|
|
92
|
+
if (parent === current) return null;
|
|
87
93
|
current = parent;
|
|
88
94
|
}
|
|
89
95
|
}
|
|
96
|
+
function findNearestEnv(names, startDir = process.cwd()) {
|
|
97
|
+
const filePath = findNearestEnvFile(names, startDir);
|
|
98
|
+
return filePath ? parseEnvFile(filePath) : {};
|
|
99
|
+
}
|
|
100
|
+
function findNearestWorktreeEnv(startDir = process.cwd()) {
|
|
101
|
+
return findNearestEnv([".env.worktree"], startDir);
|
|
102
|
+
}
|
|
103
|
+
function resolveProfileEnvFileNames() {
|
|
104
|
+
const explicitProfile = process.env.DEEPLINE_ENV_PROFILE?.trim() || process.env.DEEPLINE_PROFILE?.trim() || "";
|
|
105
|
+
const names = [];
|
|
106
|
+
if (explicitProfile) names.push(`.env.deepline.${explicitProfile}`);
|
|
107
|
+
const nodeEnv = process.env.NODE_ENV?.trim();
|
|
108
|
+
if (nodeEnv === "production") names.push(".env.deepline.prod");
|
|
109
|
+
else if (nodeEnv === "staging") names.push(".env.deepline.staging");
|
|
110
|
+
names.push(ACTIVE_DEEPLINE_ENV_FILE);
|
|
111
|
+
return names;
|
|
112
|
+
}
|
|
113
|
+
function resolveProjectAppEnvFileNames() {
|
|
114
|
+
const nodeEnv = process.env.NODE_ENV?.trim();
|
|
115
|
+
const names = [];
|
|
116
|
+
if (nodeEnv === "production") names.push(".env.prod");
|
|
117
|
+
if (nodeEnv === "staging") names.push(".env.staging");
|
|
118
|
+
names.push(".env.local", ".env");
|
|
119
|
+
return names;
|
|
120
|
+
}
|
|
121
|
+
function resolveBaseUrlFromEnvValues(env) {
|
|
122
|
+
return env.DEEPLINE_ORIGIN_URL?.trim() || env.DEEPLINE_API_BASE_URL?.trim() || "";
|
|
123
|
+
}
|
|
124
|
+
function loadProjectDeeplineEnv() {
|
|
125
|
+
return findNearestEnv(resolveProfileEnvFileNames(), projectEnvStartDir());
|
|
126
|
+
}
|
|
127
|
+
function loadProjectAppEnv() {
|
|
128
|
+
return findNearestEnv(resolveProjectAppEnvFileNames(), projectEnvStartDir());
|
|
129
|
+
}
|
|
90
130
|
function normalizeWorktreeBaseUrl(baseUrl, worktreeEnv = findNearestWorktreeEnv()) {
|
|
91
131
|
const trimmed = baseUrl.trim().replace(/\/$/, "");
|
|
92
132
|
if (!trimmed) return trimmed;
|
|
@@ -123,6 +163,10 @@ function autoDetectBaseUrl() {
|
|
|
123
163
|
if (envOrigin) return normalizeWorktreeBaseUrl(envOrigin);
|
|
124
164
|
const envBase = process.env.DEEPLINE_API_BASE_URL?.trim();
|
|
125
165
|
if (envBase) return normalizeWorktreeBaseUrl(envBase);
|
|
166
|
+
const projectDeeplineBaseUrl = resolveBaseUrlFromEnvValues(loadProjectDeeplineEnv());
|
|
167
|
+
if (projectDeeplineBaseUrl) return normalizeWorktreeBaseUrl(projectDeeplineBaseUrl);
|
|
168
|
+
const projectAppBaseUrl = resolveBaseUrlFromEnvValues(loadProjectAppEnv());
|
|
169
|
+
if (projectAppBaseUrl) return normalizeWorktreeBaseUrl(projectAppBaseUrl);
|
|
126
170
|
const worktreeBaseUrl = resolveWorktreeBaseUrl();
|
|
127
171
|
if (worktreeBaseUrl) return worktreeBaseUrl;
|
|
128
172
|
const globalEnv = loadGlobalCliEnv();
|
|
@@ -134,7 +178,9 @@ function resolveConfig(options) {
|
|
|
134
178
|
const requestedBaseUrl = options?.baseUrl?.trim() || autoDetectBaseUrl();
|
|
135
179
|
const baseUrl = normalizeWorktreeBaseUrl(requestedBaseUrl);
|
|
136
180
|
const cliEnv = loadCliEnv(baseUrl);
|
|
137
|
-
const
|
|
181
|
+
const projectDeeplineEnv = loadProjectDeeplineEnv();
|
|
182
|
+
const projectAppEnv = loadProjectAppEnv();
|
|
183
|
+
const apiKey = options?.apiKey?.trim() || process.env.DEEPLINE_API_KEY?.trim() || projectDeeplineEnv.DEEPLINE_API_KEY || projectAppEnv.DEEPLINE_API_KEY || cliEnv.DEEPLINE_API_KEY || "";
|
|
138
184
|
if (!apiKey) {
|
|
139
185
|
throw new ConfigError(
|
|
140
186
|
`No API key found. Set DEEPLINE_API_KEY env var, pass apiKey option, or run: deepline auth register`
|
|
@@ -149,8 +195,8 @@ function resolveConfig(options) {
|
|
|
149
195
|
}
|
|
150
196
|
|
|
151
197
|
// src/version.ts
|
|
152
|
-
var SDK_VERSION = "0.1.
|
|
153
|
-
var SDK_API_CONTRACT = "2026-
|
|
198
|
+
var SDK_VERSION = "0.1.19";
|
|
199
|
+
var SDK_API_CONTRACT = "2026-05-runs-v2";
|
|
154
200
|
|
|
155
201
|
// ../shared_libs/play-runtime/coordinator-headers.ts
|
|
156
202
|
var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
|
|
@@ -343,8 +389,12 @@ var HttpClient = class {
|
|
|
343
389
|
* @param path - API path
|
|
344
390
|
* @param body - Request body (will be JSON-serialized)
|
|
345
391
|
*/
|
|
346
|
-
async post(path, body) {
|
|
347
|
-
return this.request(path, {
|
|
392
|
+
async post(path, body, headers) {
|
|
393
|
+
return this.request(path, {
|
|
394
|
+
method: "POST",
|
|
395
|
+
body,
|
|
396
|
+
headers
|
|
397
|
+
});
|
|
348
398
|
}
|
|
349
399
|
/**
|
|
350
400
|
* Send a DELETE request.
|
|
@@ -424,6 +474,10 @@ function sleep(ms) {
|
|
|
424
474
|
|
|
425
475
|
// src/client.ts
|
|
426
476
|
var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
477
|
+
var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
|
|
478
|
+
function isRecord(value) {
|
|
479
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
480
|
+
}
|
|
427
481
|
function normalizePlayStatus(raw) {
|
|
428
482
|
const status = typeof raw.status === "string" ? raw.status : typeof raw.temporalStatus === "string" ? mapLegacyTemporalStatus(raw.temporalStatus) : "running";
|
|
429
483
|
const runId = typeof raw.runId === "string" ? raw.runId : typeof raw.workflowId === "string" ? raw.workflowId : "";
|
|
@@ -453,6 +507,7 @@ function mapLegacyTemporalStatus(status) {
|
|
|
453
507
|
var DeeplineClient = class {
|
|
454
508
|
http;
|
|
455
509
|
config;
|
|
510
|
+
runs;
|
|
456
511
|
/**
|
|
457
512
|
* @param options - Optional overrides for API key, base URL, timeout, and retries.
|
|
458
513
|
* @throws {@link ConfigError} if no API key can be resolved from any source.
|
|
@@ -460,6 +515,13 @@ var DeeplineClient = class {
|
|
|
460
515
|
constructor(options) {
|
|
461
516
|
this.config = resolveConfig(options);
|
|
462
517
|
this.http = new HttpClient(this.config);
|
|
518
|
+
this.runs = {
|
|
519
|
+
get: (runId) => this.getRunStatus(runId),
|
|
520
|
+
list: (options2) => this.listRuns(options2),
|
|
521
|
+
tail: (runId, options2) => this.tailRun(runId, options2),
|
|
522
|
+
logs: (runId, options2) => this.getRunLogs(runId, options2),
|
|
523
|
+
stop: (runId, options2) => this.stopRun(runId, options2)
|
|
524
|
+
};
|
|
463
525
|
}
|
|
464
526
|
/** The resolved base URL this client is targeting (e.g. `"http://localhost:3000"`). */
|
|
465
527
|
get baseUrl() {
|
|
@@ -476,12 +538,27 @@ var DeeplineClient = class {
|
|
|
476
538
|
).filter((field) => Boolean(field?.name)) : [];
|
|
477
539
|
return fields.length > 0 ? { fields } : schema;
|
|
478
540
|
}
|
|
479
|
-
|
|
480
|
-
|
|
541
|
+
schemaMetadata(schema, key) {
|
|
542
|
+
if (!isRecord(schema)) return null;
|
|
543
|
+
const value = schema[key];
|
|
544
|
+
return isRecord(value) ? value : null;
|
|
545
|
+
}
|
|
546
|
+
playRunCommand(play, options) {
|
|
547
|
+
const target = play.reference || play.name;
|
|
548
|
+
if (options?.csvInput) {
|
|
549
|
+
const inputField = typeof options.csvInput.inputField === "string" && options.csvInput.inputField.trim() ? options.csvInput.inputField.trim() : "csv";
|
|
550
|
+
return `deepline plays run ${target} --${inputField} leads.csv --watch`;
|
|
551
|
+
}
|
|
552
|
+
return `deepline plays run ${target} --input '{...}' --watch`;
|
|
481
553
|
}
|
|
482
554
|
summarizePlayListItem(play, options) {
|
|
483
555
|
const aliases = play.aliases?.length ? play.aliases : [play.name];
|
|
484
|
-
const
|
|
556
|
+
const csvInput = this.schemaMetadata(play.inputSchema, "csvInput");
|
|
557
|
+
const rowOutputSchema = this.schemaMetadata(
|
|
558
|
+
play.outputSchema,
|
|
559
|
+
"rowOutputSchema"
|
|
560
|
+
);
|
|
561
|
+
const runCommand = this.playRunCommand(play, { csvInput });
|
|
485
562
|
return {
|
|
486
563
|
name: play.name,
|
|
487
564
|
...play.reference ? { reference: play.reference } : {},
|
|
@@ -493,6 +570,8 @@ var DeeplineClient = class {
|
|
|
493
570
|
aliases,
|
|
494
571
|
inputSchema: options?.compact ? this.compactSchema(play.inputSchema) : play.inputSchema ?? null,
|
|
495
572
|
outputSchema: options?.compact ? this.compactSchema(play.outputSchema) : play.outputSchema ?? null,
|
|
573
|
+
...csvInput ? { csvInput } : {},
|
|
574
|
+
...rowOutputSchema ? { rowOutputSchema } : {},
|
|
496
575
|
runCommand,
|
|
497
576
|
examples: [runCommand],
|
|
498
577
|
currentPublishedVersion: play.currentPublishedVersion ?? null,
|
|
@@ -531,6 +610,31 @@ var DeeplineClient = class {
|
|
|
531
610
|
);
|
|
532
611
|
return res.tools;
|
|
533
612
|
}
|
|
613
|
+
/**
|
|
614
|
+
* Search available tools using Deepline's ranked backend search.
|
|
615
|
+
*
|
|
616
|
+
* This is the same discovery surface used by the legacy CLI: it ranks across
|
|
617
|
+
* tool metadata, categories, agent guidance, and input schema fields.
|
|
618
|
+
*/
|
|
619
|
+
async searchTools(options = {}) {
|
|
620
|
+
const params = new URLSearchParams();
|
|
621
|
+
const query = options.query?.trim() ?? "";
|
|
622
|
+
params.set("q", query);
|
|
623
|
+
params.set(
|
|
624
|
+
"include_search_debug",
|
|
625
|
+
options.includeSearchDebug ? "true" : "false"
|
|
626
|
+
);
|
|
627
|
+
params.set("search_mode", options.searchMode ?? "v2");
|
|
628
|
+
if (options.categories?.trim()) {
|
|
629
|
+
params.set("categories", options.categories.trim());
|
|
630
|
+
}
|
|
631
|
+
if (options.searchTerms?.trim()) {
|
|
632
|
+
params.set("search_terms", options.searchTerms.trim());
|
|
633
|
+
}
|
|
634
|
+
return this.http.get(
|
|
635
|
+
`/api/v2/integrations/list?${params.toString()}`
|
|
636
|
+
);
|
|
637
|
+
}
|
|
534
638
|
/**
|
|
535
639
|
* Get detailed metadata for a single tool.
|
|
536
640
|
*
|
|
@@ -559,55 +663,24 @@ var DeeplineClient = class {
|
|
|
559
663
|
);
|
|
560
664
|
}
|
|
561
665
|
/**
|
|
562
|
-
* Execute a tool and return the
|
|
563
|
-
*
|
|
564
|
-
* Sends the input payload to the tool and returns the `.result` field from the
|
|
565
|
-
* response. For the full response envelope (including job_id, credits, etc.),
|
|
566
|
-
* use {@link executeToolRaw}.
|
|
666
|
+
* Execute a tool and return the standard execution envelope.
|
|
567
667
|
*
|
|
568
|
-
*
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
* @example
|
|
574
|
-
* ```typescript
|
|
575
|
-
* const company = await client.executeTool('test_company_search', {
|
|
576
|
-
* domain: 'stripe.com',
|
|
577
|
-
* });
|
|
578
|
-
* console.log(company); // { name: "Stripe", industry: "Financial Services", ... }
|
|
579
|
-
* ```
|
|
580
|
-
*/
|
|
581
|
-
async executeTool(toolId, input) {
|
|
582
|
-
const res = await this.http.post(
|
|
583
|
-
`/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
|
|
584
|
-
{ payload: input }
|
|
585
|
-
);
|
|
586
|
-
return res.result ?? res;
|
|
587
|
-
}
|
|
588
|
-
/**
|
|
589
|
-
* Execute a tool and return the full response envelope.
|
|
590
|
-
*
|
|
591
|
-
* Unlike {@link executeTool}, this returns the complete API response including
|
|
592
|
-
* `job_id`, `status`, `credits`, and the raw `result` object.
|
|
593
|
-
*
|
|
594
|
-
* @param toolId - Tool identifier
|
|
595
|
-
* @param input - Tool-specific input parameters
|
|
596
|
-
* @returns Full response with job metadata and result
|
|
597
|
-
*
|
|
598
|
-
* @example
|
|
599
|
-
* ```typescript
|
|
600
|
-
* const raw = await client.executeToolRaw('test_company_search', { domain: 'stripe.com' });
|
|
601
|
-
* console.log(`Job: ${raw.job_id}, Credits: ${raw.credits}`);
|
|
602
|
-
* console.log(`Result:`, raw.result);
|
|
603
|
-
* ```
|
|
668
|
+
* The `result.data` field contains the provider payload. `result.meta`
|
|
669
|
+
* contains provider/upstream metadata such as HTTP status or paging details.
|
|
670
|
+
* Top-level fields such as `status`, `job_id`, and `billing` describe the
|
|
671
|
+
* Deepline execution.
|
|
604
672
|
*/
|
|
605
|
-
async
|
|
673
|
+
async executeTool(toolId, input, options) {
|
|
674
|
+
const headers = options?.includeToolMetadata ? { [INCLUDE_TOOL_METADATA_HEADER]: "true" } : void 0;
|
|
606
675
|
return this.http.post(
|
|
607
676
|
`/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
|
|
608
|
-
{ payload: input }
|
|
677
|
+
{ payload: input },
|
|
678
|
+
headers
|
|
609
679
|
);
|
|
610
680
|
}
|
|
681
|
+
async executeToolRaw(toolId, input, options) {
|
|
682
|
+
return this.executeTool(toolId, input, options);
|
|
683
|
+
}
|
|
611
684
|
async queryCustomerDb(input) {
|
|
612
685
|
return this.http.post("/api/v2/db/query", {
|
|
613
686
|
sql: input.sql,
|
|
@@ -656,6 +729,7 @@ var DeeplineClient = class {
|
|
|
656
729
|
...request.revisionId ? { revisionId: request.revisionId } : {},
|
|
657
730
|
...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
|
|
658
731
|
...request.sourceCode ? { sourceCode: request.sourceCode } : {},
|
|
732
|
+
...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
|
|
659
733
|
..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
|
|
660
734
|
...request.artifactHash ? { artifactHash: request.artifactHash } : {},
|
|
661
735
|
...request.graphHash ? { graphHash: request.graphHash } : {},
|
|
@@ -680,6 +754,7 @@ var DeeplineClient = class {
|
|
|
680
754
|
...request.revisionId ? { revisionId: request.revisionId } : {},
|
|
681
755
|
...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
|
|
682
756
|
...request.sourceCode ? { sourceCode: request.sourceCode } : {},
|
|
757
|
+
...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
|
|
683
758
|
..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
|
|
684
759
|
...request.artifactHash ? { artifactHash: request.artifactHash } : {},
|
|
685
760
|
...request.graphHash ? { graphHash: request.graphHash } : {},
|
|
@@ -716,6 +791,7 @@ var DeeplineClient = class {
|
|
|
716
791
|
const compilerManifest = input.compilerManifest ?? await this.compilePlayManifest({
|
|
717
792
|
name: input.name,
|
|
718
793
|
sourceCode: input.sourceCode,
|
|
794
|
+
sourceFiles: input.sourceFiles,
|
|
719
795
|
artifact: input.artifact
|
|
720
796
|
});
|
|
721
797
|
return this.http.post("/api/v2/plays/artifacts", {
|
|
@@ -730,6 +806,7 @@ var DeeplineClient = class {
|
|
|
730
806
|
compilerManifest: artifact.compilerManifest ?? await this.compilePlayManifest({
|
|
731
807
|
name: artifact.name,
|
|
732
808
|
sourceCode: artifact.sourceCode,
|
|
809
|
+
sourceFiles: artifact.sourceFiles,
|
|
733
810
|
artifact: artifact.artifact
|
|
734
811
|
})
|
|
735
812
|
}))
|
|
@@ -756,11 +833,13 @@ var DeeplineClient = class {
|
|
|
756
833
|
const compilerManifest = input.compilerManifest ?? await this.compilePlayManifest({
|
|
757
834
|
name: input.name,
|
|
758
835
|
sourceCode: input.sourceCode,
|
|
836
|
+
sourceFiles: input.sourceFiles,
|
|
759
837
|
artifact: input.artifact
|
|
760
838
|
});
|
|
761
839
|
const registeredArtifact = await this.registerPlayArtifact({
|
|
762
840
|
name: input.name,
|
|
763
841
|
sourceCode: input.sourceCode,
|
|
842
|
+
sourceFiles: input.sourceFiles,
|
|
764
843
|
artifact: input.artifact,
|
|
765
844
|
compilerManifest,
|
|
766
845
|
publish: false
|
|
@@ -820,11 +899,13 @@ var DeeplineClient = class {
|
|
|
820
899
|
const compilerManifest = options?.compilerManifest ?? await this.compilePlayManifest({
|
|
821
900
|
name,
|
|
822
901
|
sourceCode,
|
|
902
|
+
sourceFiles: options?.sourceFiles,
|
|
823
903
|
artifact
|
|
824
904
|
});
|
|
825
905
|
const registeredArtifact = await this.registerPlayArtifact({
|
|
826
906
|
name,
|
|
827
907
|
sourceCode,
|
|
908
|
+
sourceFiles: options?.sourceFiles,
|
|
828
909
|
artifact,
|
|
829
910
|
compilerManifest,
|
|
830
911
|
publish: false
|
|
@@ -1008,6 +1089,112 @@ var DeeplineClient = class {
|
|
|
1008
1089
|
);
|
|
1009
1090
|
return response.runs ?? [];
|
|
1010
1091
|
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Get a run by id using the public runs resource model.
|
|
1094
|
+
*
|
|
1095
|
+
* This is the SDK equivalent of:
|
|
1096
|
+
*
|
|
1097
|
+
* ```bash
|
|
1098
|
+
* deepline runs get <run-id> --json
|
|
1099
|
+
* ```
|
|
1100
|
+
*/
|
|
1101
|
+
async getRunStatus(runId) {
|
|
1102
|
+
const response = await this.http.get(
|
|
1103
|
+
`/api/v2/runs/${encodeURIComponent(runId)}`
|
|
1104
|
+
);
|
|
1105
|
+
return normalizePlayStatus(response);
|
|
1106
|
+
}
|
|
1107
|
+
/**
|
|
1108
|
+
* List play runs using the public runs resource model.
|
|
1109
|
+
*
|
|
1110
|
+
* This is the SDK equivalent of:
|
|
1111
|
+
*
|
|
1112
|
+
* ```bash
|
|
1113
|
+
* deepline runs list --play <play-name> --status failed --json
|
|
1114
|
+
* ```
|
|
1115
|
+
*/
|
|
1116
|
+
async listRuns(options) {
|
|
1117
|
+
const playName = options.play.trim();
|
|
1118
|
+
if (!playName) {
|
|
1119
|
+
throw new Error("runs.list requires options.play.");
|
|
1120
|
+
}
|
|
1121
|
+
const params = new URLSearchParams({ play: playName });
|
|
1122
|
+
const status = options.status?.trim();
|
|
1123
|
+
if (status) {
|
|
1124
|
+
params.set("status", status);
|
|
1125
|
+
}
|
|
1126
|
+
const response = await this.http.get(
|
|
1127
|
+
`/api/v2/runs?${params.toString()}`
|
|
1128
|
+
);
|
|
1129
|
+
return response.runs ?? [];
|
|
1130
|
+
}
|
|
1131
|
+
/**
|
|
1132
|
+
* Fetch the lightweight tail status for a run using the public runs resource model.
|
|
1133
|
+
*
|
|
1134
|
+
* This is the SDK equivalent of:
|
|
1135
|
+
*
|
|
1136
|
+
* ```bash
|
|
1137
|
+
* deepline runs tail <run-id> --json
|
|
1138
|
+
* ```
|
|
1139
|
+
*/
|
|
1140
|
+
async tailRun(runId, options) {
|
|
1141
|
+
const afterLogIndex = typeof options?.afterLogIndex === "number" ? options.afterLogIndex : typeof options?.cursor === "number" ? options.cursor : typeof options?.cursor === "string" && options.cursor.trim() ? Number(options.cursor) : void 0;
|
|
1142
|
+
const params = new URLSearchParams();
|
|
1143
|
+
if (Number.isFinite(afterLogIndex)) {
|
|
1144
|
+
params.set("afterLogIndex", String(Number(afterLogIndex)));
|
|
1145
|
+
}
|
|
1146
|
+
if (typeof options?.waitMs === "number") {
|
|
1147
|
+
params.set("waitMs", String(options.waitMs));
|
|
1148
|
+
}
|
|
1149
|
+
if (options?.terminalOnly) {
|
|
1150
|
+
params.set("terminalOnly", "true");
|
|
1151
|
+
}
|
|
1152
|
+
const suffix = params.toString() ? `?${params.toString()}` : "";
|
|
1153
|
+
const response = await this.http.get(
|
|
1154
|
+
`/api/v2/runs/${encodeURIComponent(runId)}/tail${suffix}`
|
|
1155
|
+
);
|
|
1156
|
+
return normalizePlayStatus(response);
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Fetch persisted logs for a run using the public runs resource model.
|
|
1160
|
+
*
|
|
1161
|
+
* This is the SDK equivalent of:
|
|
1162
|
+
*
|
|
1163
|
+
* ```bash
|
|
1164
|
+
* deepline runs logs <run-id> --limit 200 --json
|
|
1165
|
+
* ```
|
|
1166
|
+
*/
|
|
1167
|
+
async getRunLogs(runId, options) {
|
|
1168
|
+
const status = await this.getRunStatus(runId);
|
|
1169
|
+
const logs = status.progress?.logs ?? [];
|
|
1170
|
+
const limit = typeof options?.limit === "number" && Number.isFinite(options.limit) ? Math.max(0, Math.trunc(options.limit)) : 200;
|
|
1171
|
+
const entries = logs.slice(Math.max(0, logs.length - limit));
|
|
1172
|
+
return {
|
|
1173
|
+
runId: status.runId,
|
|
1174
|
+
totalCount: logs.length,
|
|
1175
|
+
returnedCount: entries.length,
|
|
1176
|
+
firstSequence: logs.length === 0 ? null : logs.length - entries.length + 1,
|
|
1177
|
+
lastSequence: logs.length === 0 ? null : logs.length,
|
|
1178
|
+
truncated: logs.length > entries.length,
|
|
1179
|
+
hasMore: logs.length > entries.length,
|
|
1180
|
+
entries
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Stop a run by id using the public runs resource model.
|
|
1185
|
+
*
|
|
1186
|
+
* This is the SDK equivalent of:
|
|
1187
|
+
*
|
|
1188
|
+
* ```bash
|
|
1189
|
+
* deepline runs stop <run-id> --reason "stale lock" --json
|
|
1190
|
+
* ```
|
|
1191
|
+
*/
|
|
1192
|
+
async stopRun(runId, options) {
|
|
1193
|
+
return this.http.post(
|
|
1194
|
+
`/api/v2/runs/${encodeURIComponent(runId)}/stop`,
|
|
1195
|
+
options?.reason ? { reason: options.reason } : {}
|
|
1196
|
+
);
|
|
1197
|
+
}
|
|
1011
1198
|
async listPlays() {
|
|
1012
1199
|
const response = await this.http.get(
|
|
1013
1200
|
"/api/v2/plays"
|
|
@@ -1224,258 +1411,6 @@ var DeeplineClient = class {
|
|
|
1224
1411
|
}
|
|
1225
1412
|
};
|
|
1226
1413
|
|
|
1227
|
-
// src/tool-output.ts
|
|
1228
|
-
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
1229
|
-
import { homedir as homedir2 } from "os";
|
|
1230
|
-
import { join as join2 } from "path";
|
|
1231
|
-
function isPlainObject(value) {
|
|
1232
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1233
|
-
}
|
|
1234
|
-
var EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1235
|
-
var PHONE_KEY_PATTERN = /(^|[_-])(phone|mobile|cell|telephone|tel)([_-]|$)|phone|mobile|telephone/i;
|
|
1236
|
-
function normalizeScalarString(value) {
|
|
1237
|
-
if (typeof value === "string") {
|
|
1238
|
-
const trimmed = value.trim();
|
|
1239
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
1240
|
-
}
|
|
1241
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
1242
|
-
return String(value);
|
|
1243
|
-
}
|
|
1244
|
-
return null;
|
|
1245
|
-
}
|
|
1246
|
-
function looksLikeEmail(value) {
|
|
1247
|
-
const candidate = normalizeScalarString(value);
|
|
1248
|
-
if (!candidate || !EMAIL_PATTERN.test(candidate)) return null;
|
|
1249
|
-
return candidate;
|
|
1250
|
-
}
|
|
1251
|
-
function looksLikePhone(value) {
|
|
1252
|
-
const candidate = normalizeScalarString(value);
|
|
1253
|
-
if (!candidate) return null;
|
|
1254
|
-
const digits = candidate.replace(/\D/g, "");
|
|
1255
|
-
if (digits.length < 7 || digits.length > 16) return null;
|
|
1256
|
-
return candidate;
|
|
1257
|
-
}
|
|
1258
|
-
function findEmail(value, depth = 0) {
|
|
1259
|
-
if (depth > 6) return null;
|
|
1260
|
-
const direct = looksLikeEmail(value);
|
|
1261
|
-
if (direct) return direct;
|
|
1262
|
-
if (Array.isArray(value)) {
|
|
1263
|
-
for (const entry of value) {
|
|
1264
|
-
const nested = findEmail(entry, depth + 1);
|
|
1265
|
-
if (nested) return nested;
|
|
1266
|
-
}
|
|
1267
|
-
return null;
|
|
1268
|
-
}
|
|
1269
|
-
if (!isPlainObject(value)) return null;
|
|
1270
|
-
for (const [key, child] of Object.entries(value)) {
|
|
1271
|
-
if (/email/i.test(key)) {
|
|
1272
|
-
const keyed = looksLikeEmail(child);
|
|
1273
|
-
if (keyed) return keyed;
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
for (const child of Object.values(value)) {
|
|
1277
|
-
const nested = findEmail(child, depth + 1);
|
|
1278
|
-
if (nested) return nested;
|
|
1279
|
-
}
|
|
1280
|
-
return null;
|
|
1281
|
-
}
|
|
1282
|
-
function findPhone(value, depth = 0) {
|
|
1283
|
-
if (depth > 6) return null;
|
|
1284
|
-
if (Array.isArray(value)) {
|
|
1285
|
-
for (const entry of value) {
|
|
1286
|
-
const nested = findPhone(entry, depth + 1);
|
|
1287
|
-
if (nested) return nested;
|
|
1288
|
-
}
|
|
1289
|
-
return null;
|
|
1290
|
-
}
|
|
1291
|
-
if (!isPlainObject(value)) return null;
|
|
1292
|
-
for (const [key, child] of Object.entries(value)) {
|
|
1293
|
-
if (PHONE_KEY_PATTERN.test(key)) {
|
|
1294
|
-
const keyed = looksLikePhone(child);
|
|
1295
|
-
if (keyed) return keyed;
|
|
1296
|
-
}
|
|
1297
|
-
}
|
|
1298
|
-
for (const child of Object.values(value)) {
|
|
1299
|
-
const nested = findPhone(child, depth + 1);
|
|
1300
|
-
if (nested) return nested;
|
|
1301
|
-
}
|
|
1302
|
-
return null;
|
|
1303
|
-
}
|
|
1304
|
-
function normalizeListExtractorPaths(paths) {
|
|
1305
|
-
if (!Array.isArray(paths)) return [];
|
|
1306
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1307
|
-
const normalized = [];
|
|
1308
|
-
for (const rawPath of paths) {
|
|
1309
|
-
if (typeof rawPath !== "string") continue;
|
|
1310
|
-
const path = rawPath.trim();
|
|
1311
|
-
if (!path) continue;
|
|
1312
|
-
for (const candidate of [path, path.replace(/^result\./, "")]) {
|
|
1313
|
-
if (!candidate || seen.has(candidate)) continue;
|
|
1314
|
-
seen.add(candidate);
|
|
1315
|
-
normalized.push(candidate);
|
|
1316
|
-
}
|
|
1317
|
-
}
|
|
1318
|
-
return normalized;
|
|
1319
|
-
}
|
|
1320
|
-
var DeeplineToolCallResult = class {
|
|
1321
|
-
constructor(value, options) {
|
|
1322
|
-
this.value = value;
|
|
1323
|
-
this.listExtractorPaths = normalizeListExtractorPaths(
|
|
1324
|
-
options?.listExtractorPaths
|
|
1325
|
-
);
|
|
1326
|
-
}
|
|
1327
|
-
value;
|
|
1328
|
-
listExtractorPaths;
|
|
1329
|
-
getEmail() {
|
|
1330
|
-
return findEmail(this.value);
|
|
1331
|
-
}
|
|
1332
|
-
getPhone() {
|
|
1333
|
-
return findPhone(this.value);
|
|
1334
|
-
}
|
|
1335
|
-
tryList(options) {
|
|
1336
|
-
const explicitPaths = normalizeListExtractorPaths(options?.listExtractorPaths);
|
|
1337
|
-
return tryConvertToList(this.value, {
|
|
1338
|
-
listExtractorPaths: explicitPaths.length > 0 ? explicitPaths : this.listExtractorPaths
|
|
1339
|
-
})?.rows ?? null;
|
|
1340
|
-
}
|
|
1341
|
-
};
|
|
1342
|
-
function createToolCallResult(value, options) {
|
|
1343
|
-
return new DeeplineToolCallResult(value, options);
|
|
1344
|
-
}
|
|
1345
|
-
function getByDottedPath(root, dottedPath) {
|
|
1346
|
-
let current = root;
|
|
1347
|
-
for (const segment of String(dottedPath || "").split(".").filter(Boolean)) {
|
|
1348
|
-
if (!isPlainObject(current) || !(segment in current)) {
|
|
1349
|
-
return null;
|
|
1350
|
-
}
|
|
1351
|
-
current = current[segment];
|
|
1352
|
-
}
|
|
1353
|
-
return current;
|
|
1354
|
-
}
|
|
1355
|
-
function normalizeRows(value) {
|
|
1356
|
-
if (!Array.isArray(value)) return null;
|
|
1357
|
-
return value.map((entry) => {
|
|
1358
|
-
if (isPlainObject(entry)) return entry;
|
|
1359
|
-
return { value: entry };
|
|
1360
|
-
});
|
|
1361
|
-
}
|
|
1362
|
-
function candidateRoots(payload) {
|
|
1363
|
-
const roots = [{ path: null, value: payload }];
|
|
1364
|
-
if (isPlainObject(payload) && isPlainObject(payload.result)) {
|
|
1365
|
-
roots.push({ path: "result", value: payload.result });
|
|
1366
|
-
if (isPlainObject(payload.result.data)) {
|
|
1367
|
-
roots.push({ path: "result.data", value: payload.result.data });
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
|
-
return roots;
|
|
1371
|
-
}
|
|
1372
|
-
function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
|
|
1373
|
-
if (depth > 5) return null;
|
|
1374
|
-
const directRows = normalizeRows(value);
|
|
1375
|
-
const hasObjectRow = directRows?.some((row) => Object.keys(row).some((key) => key !== "value")) ?? false;
|
|
1376
|
-
let best = directRows && directRows.length > 0 && hasObjectRow ? { path: pathPrefix, rows: directRows } : null;
|
|
1377
|
-
if (!isPlainObject(value)) {
|
|
1378
|
-
return best;
|
|
1379
|
-
}
|
|
1380
|
-
for (const [key, child] of Object.entries(value)) {
|
|
1381
|
-
const childPath = pathPrefix ? `${pathPrefix}.${key}` : key;
|
|
1382
|
-
const candidate = findBestArrayCandidate(child, childPath, depth + 1);
|
|
1383
|
-
if (!candidate) continue;
|
|
1384
|
-
if (!best || candidate.rows.length > best.rows.length) {
|
|
1385
|
-
best = candidate;
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
return best;
|
|
1389
|
-
}
|
|
1390
|
-
function tryConvertToList(payload, options) {
|
|
1391
|
-
const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
|
|
1392
|
-
if (listExtractorPaths.length > 0) {
|
|
1393
|
-
for (const root of candidateRoots(payload)) {
|
|
1394
|
-
for (const extractorPath of listExtractorPaths) {
|
|
1395
|
-
const resolved = getByDottedPath(root.value, extractorPath);
|
|
1396
|
-
const rows = normalizeRows(resolved);
|
|
1397
|
-
if (rows && rows.length > 0) {
|
|
1398
|
-
const sourcePath = root.path ? `${root.path}.${extractorPath}` : extractorPath;
|
|
1399
|
-
return { rows, strategy: "configured_paths", sourcePath };
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
}
|
|
1404
|
-
for (const root of candidateRoots(payload)) {
|
|
1405
|
-
const candidate = findBestArrayCandidate(root.value, root.path ?? "");
|
|
1406
|
-
if (!candidate || candidate.rows.length === 0) continue;
|
|
1407
|
-
return {
|
|
1408
|
-
rows: candidate.rows,
|
|
1409
|
-
strategy: "auto_detected",
|
|
1410
|
-
sourcePath: candidate.path || root.path
|
|
1411
|
-
};
|
|
1412
|
-
}
|
|
1413
|
-
return null;
|
|
1414
|
-
}
|
|
1415
|
-
function ensureOutputDir() {
|
|
1416
|
-
const outputDir = join2(homedir2(), ".local", "share", "deepline", "data");
|
|
1417
|
-
mkdirSync2(outputDir, { recursive: true });
|
|
1418
|
-
return outputDir;
|
|
1419
|
-
}
|
|
1420
|
-
function writeJsonOutputFile(payload, stem) {
|
|
1421
|
-
const outputDir = ensureOutputDir();
|
|
1422
|
-
const outputPath = join2(outputDir, `${stem}_${Date.now()}.json`);
|
|
1423
|
-
writeFileSync2(outputPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
1424
|
-
return outputPath;
|
|
1425
|
-
}
|
|
1426
|
-
function writeCsvOutputFile(rows, stem) {
|
|
1427
|
-
const outputDir = ensureOutputDir();
|
|
1428
|
-
const outputPath = join2(outputDir, `${stem}_${Date.now()}.csv`);
|
|
1429
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1430
|
-
const columns = [];
|
|
1431
|
-
for (const row of rows) {
|
|
1432
|
-
for (const key of Object.keys(row)) {
|
|
1433
|
-
if (!seen.has(key)) {
|
|
1434
|
-
seen.add(key);
|
|
1435
|
-
columns.push(key);
|
|
1436
|
-
}
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
const escapeCell = (value) => {
|
|
1440
|
-
const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
|
|
1441
|
-
if (/[",\n]/.test(normalized)) {
|
|
1442
|
-
return `"${normalized.replace(/"/g, '""')}"`;
|
|
1443
|
-
}
|
|
1444
|
-
return normalized;
|
|
1445
|
-
};
|
|
1446
|
-
const lines = [];
|
|
1447
|
-
lines.push(columns.map(escapeCell).join(","));
|
|
1448
|
-
for (const row of rows) {
|
|
1449
|
-
lines.push(columns.map((column) => escapeCell(row[column])).join(","));
|
|
1450
|
-
}
|
|
1451
|
-
writeFileSync2(outputPath, `${lines.join("\n")}
|
|
1452
|
-
`, "utf-8");
|
|
1453
|
-
const previewRows = rows.slice(0, 5);
|
|
1454
|
-
const previewColumns = columns.slice(0, 5);
|
|
1455
|
-
const preview = [
|
|
1456
|
-
previewColumns.join(","),
|
|
1457
|
-
...previewRows.map((row) => previewColumns.map((column) => escapeCell(row[column])).join(","))
|
|
1458
|
-
].join("\n");
|
|
1459
|
-
return {
|
|
1460
|
-
path: outputPath,
|
|
1461
|
-
rowCount: rows.length,
|
|
1462
|
-
columns,
|
|
1463
|
-
preview
|
|
1464
|
-
};
|
|
1465
|
-
}
|
|
1466
|
-
function extractSummaryFields(payload) {
|
|
1467
|
-
const candidates = candidateRoots(payload);
|
|
1468
|
-
for (const candidate of candidates) {
|
|
1469
|
-
if (!isPlainObject(candidate.value)) continue;
|
|
1470
|
-
const summaryEntries = Object.entries(candidate.value).filter(([, value]) => {
|
|
1471
|
-
return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
1472
|
-
});
|
|
1473
|
-
if (summaryEntries.length === 0) continue;
|
|
1474
|
-
return Object.fromEntries(summaryEntries);
|
|
1475
|
-
}
|
|
1476
|
-
return {};
|
|
1477
|
-
}
|
|
1478
|
-
|
|
1479
1414
|
// src/play.ts
|
|
1480
1415
|
var DeeplineConditionalStepResolver = class _DeeplineConditionalStepResolver {
|
|
1481
1416
|
constructor(when2, run, elseValue) {
|
|
@@ -1614,12 +1549,8 @@ var DeeplineContext = class {
|
|
|
1614
1549
|
* ```typescript
|
|
1615
1550
|
* const tools = await ctx.tools.list();
|
|
1616
1551
|
* const meta = await ctx.tools.get('apollo_people_search');
|
|
1617
|
-
* const
|
|
1618
|
-
*
|
|
1619
|
-
* input: { domain: 'stripe.com' },
|
|
1620
|
-
* });
|
|
1621
|
-
* const rows = result.tryList({ listExtractorPaths: ['people'] });
|
|
1622
|
-
* const email = result.getEmail();
|
|
1552
|
+
* const companyLookup = await ctx.tools.execute('test_company_search', { domain: 'stripe.com' });
|
|
1553
|
+
* const company = companyLookup.result.data;
|
|
1623
1554
|
* ```
|
|
1624
1555
|
*/
|
|
1625
1556
|
get tools() {
|
|
@@ -1628,16 +1559,12 @@ var DeeplineContext = class {
|
|
|
1628
1559
|
list: () => this.client.listTools(),
|
|
1629
1560
|
/** Get detailed metadata for a tool. */
|
|
1630
1561
|
get: (toolId) => this.client.getTool(toolId),
|
|
1631
|
-
/** Execute a tool and return
|
|
1632
|
-
execute: async (
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
return createToolCallResult(value, {
|
|
1638
|
-
listExtractorPaths: metadata.listExtractorPaths ?? []
|
|
1639
|
-
});
|
|
1640
|
-
}
|
|
1562
|
+
/** Execute a tool and return the standard execution envelope. */
|
|
1563
|
+
execute: async (toolId, input) => this.client.executeTool(
|
|
1564
|
+
toolId,
|
|
1565
|
+
input,
|
|
1566
|
+
{ includeToolMetadata: true }
|
|
1567
|
+
)
|
|
1641
1568
|
};
|
|
1642
1569
|
}
|
|
1643
1570
|
get plays() {
|
|
@@ -1840,6 +1767,147 @@ function getDefinedPlayMetadata(value) {
|
|
|
1840
1767
|
}
|
|
1841
1768
|
return candidate;
|
|
1842
1769
|
}
|
|
1770
|
+
|
|
1771
|
+
// src/tool-output.ts
|
|
1772
|
+
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
1773
|
+
import { homedir as homedir2 } from "os";
|
|
1774
|
+
import { join as join2 } from "path";
|
|
1775
|
+
function isPlainObject(value) {
|
|
1776
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1777
|
+
}
|
|
1778
|
+
function getByDottedPath(root, dottedPath) {
|
|
1779
|
+
let current = root;
|
|
1780
|
+
for (const segment of String(dottedPath || "").split(".").filter(Boolean)) {
|
|
1781
|
+
if (!isPlainObject(current) || !(segment in current)) {
|
|
1782
|
+
return null;
|
|
1783
|
+
}
|
|
1784
|
+
current = current[segment];
|
|
1785
|
+
}
|
|
1786
|
+
return current;
|
|
1787
|
+
}
|
|
1788
|
+
function normalizeRows(value) {
|
|
1789
|
+
if (!Array.isArray(value)) return null;
|
|
1790
|
+
return value.map((entry) => {
|
|
1791
|
+
if (isPlainObject(entry)) return entry;
|
|
1792
|
+
return { value: entry };
|
|
1793
|
+
});
|
|
1794
|
+
}
|
|
1795
|
+
function candidateRoots(payload) {
|
|
1796
|
+
const roots = [{ path: null, value: payload }];
|
|
1797
|
+
if (isPlainObject(payload) && isPlainObject(payload.result)) {
|
|
1798
|
+
roots.push({ path: "result", value: payload.result });
|
|
1799
|
+
if (isPlainObject(payload.result.data)) {
|
|
1800
|
+
roots.push({ path: "result.data", value: payload.result.data });
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
return roots;
|
|
1804
|
+
}
|
|
1805
|
+
function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
|
|
1806
|
+
if (depth > 5) return null;
|
|
1807
|
+
const directRows = normalizeRows(value);
|
|
1808
|
+
const hasObjectRow = directRows?.some((row) => Object.keys(row).some((key) => key !== "value")) ?? false;
|
|
1809
|
+
let best = directRows && directRows.length > 0 && hasObjectRow ? { path: pathPrefix, rows: directRows } : null;
|
|
1810
|
+
if (!isPlainObject(value)) {
|
|
1811
|
+
return best;
|
|
1812
|
+
}
|
|
1813
|
+
for (const [key, child] of Object.entries(value)) {
|
|
1814
|
+
const childPath = pathPrefix ? `${pathPrefix}.${key}` : key;
|
|
1815
|
+
const candidate = findBestArrayCandidate(child, childPath, depth + 1);
|
|
1816
|
+
if (!candidate) continue;
|
|
1817
|
+
if (!best || candidate.rows.length > best.rows.length) {
|
|
1818
|
+
best = candidate;
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
return best;
|
|
1822
|
+
}
|
|
1823
|
+
function tryConvertToList(payload, options) {
|
|
1824
|
+
const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
|
|
1825
|
+
if (listExtractorPaths.length > 0) {
|
|
1826
|
+
for (const root of candidateRoots(payload)) {
|
|
1827
|
+
for (const extractorPath of listExtractorPaths) {
|
|
1828
|
+
const resolved = getByDottedPath(root.value, extractorPath);
|
|
1829
|
+
const rows = normalizeRows(resolved);
|
|
1830
|
+
if (rows && rows.length > 0) {
|
|
1831
|
+
const sourcePath = root.path ? `${root.path}.${extractorPath}` : extractorPath;
|
|
1832
|
+
return { rows, strategy: "configured_paths", sourcePath };
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
for (const root of candidateRoots(payload)) {
|
|
1838
|
+
const candidate = findBestArrayCandidate(root.value, root.path ?? "");
|
|
1839
|
+
if (!candidate || candidate.rows.length === 0) continue;
|
|
1840
|
+
return {
|
|
1841
|
+
rows: candidate.rows,
|
|
1842
|
+
strategy: "auto_detected",
|
|
1843
|
+
sourcePath: candidate.path || root.path
|
|
1844
|
+
};
|
|
1845
|
+
}
|
|
1846
|
+
return null;
|
|
1847
|
+
}
|
|
1848
|
+
function ensureOutputDir() {
|
|
1849
|
+
const outputDir = join2(homedir2(), ".local", "share", "deepline", "data");
|
|
1850
|
+
mkdirSync2(outputDir, { recursive: true });
|
|
1851
|
+
return outputDir;
|
|
1852
|
+
}
|
|
1853
|
+
function writeJsonOutputFile(payload, stem) {
|
|
1854
|
+
const outputDir = ensureOutputDir();
|
|
1855
|
+
const outputPath = join2(outputDir, `${stem}_${Date.now()}.json`);
|
|
1856
|
+
writeFileSync2(outputPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
1857
|
+
return outputPath;
|
|
1858
|
+
}
|
|
1859
|
+
function writeCsvOutputFile(rows, stem) {
|
|
1860
|
+
const outputDir = ensureOutputDir();
|
|
1861
|
+
const outputPath = join2(outputDir, `${stem}_${Date.now()}.csv`);
|
|
1862
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1863
|
+
const columns = [];
|
|
1864
|
+
for (const row of rows) {
|
|
1865
|
+
for (const key of Object.keys(row)) {
|
|
1866
|
+
if (!seen.has(key)) {
|
|
1867
|
+
seen.add(key);
|
|
1868
|
+
columns.push(key);
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
const escapeCell = (value) => {
|
|
1873
|
+
const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
|
|
1874
|
+
if (/[",\n]/.test(normalized)) {
|
|
1875
|
+
return `"${normalized.replace(/"/g, '""')}"`;
|
|
1876
|
+
}
|
|
1877
|
+
return normalized;
|
|
1878
|
+
};
|
|
1879
|
+
const lines = [];
|
|
1880
|
+
lines.push(columns.map(escapeCell).join(","));
|
|
1881
|
+
for (const row of rows) {
|
|
1882
|
+
lines.push(columns.map((column) => escapeCell(row[column])).join(","));
|
|
1883
|
+
}
|
|
1884
|
+
writeFileSync2(outputPath, `${lines.join("\n")}
|
|
1885
|
+
`, "utf-8");
|
|
1886
|
+
const previewRows = rows.slice(0, 5);
|
|
1887
|
+
const previewColumns = columns.slice(0, 5);
|
|
1888
|
+
const preview = [
|
|
1889
|
+
previewColumns.join(","),
|
|
1890
|
+
...previewRows.map((row) => previewColumns.map((column) => escapeCell(row[column])).join(","))
|
|
1891
|
+
].join("\n");
|
|
1892
|
+
return {
|
|
1893
|
+
path: outputPath,
|
|
1894
|
+
rowCount: rows.length,
|
|
1895
|
+
columns,
|
|
1896
|
+
preview
|
|
1897
|
+
};
|
|
1898
|
+
}
|
|
1899
|
+
function extractSummaryFields(payload) {
|
|
1900
|
+
const candidates = candidateRoots(payload);
|
|
1901
|
+
for (const candidate of candidates) {
|
|
1902
|
+
if (!isPlainObject(candidate.value)) continue;
|
|
1903
|
+
const summaryEntries = Object.entries(candidate.value).filter(([, value]) => {
|
|
1904
|
+
return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
1905
|
+
});
|
|
1906
|
+
if (summaryEntries.length === 0) continue;
|
|
1907
|
+
return Object.fromEntries(summaryEntries);
|
|
1908
|
+
}
|
|
1909
|
+
return {};
|
|
1910
|
+
}
|
|
1843
1911
|
export {
|
|
1844
1912
|
AuthError,
|
|
1845
1913
|
ConfigError,
|
|
@@ -1851,7 +1919,6 @@ export {
|
|
|
1851
1919
|
RateLimitError,
|
|
1852
1920
|
SDK_API_CONTRACT,
|
|
1853
1921
|
SDK_VERSION,
|
|
1854
|
-
createToolCallResult,
|
|
1855
1922
|
defineInput,
|
|
1856
1923
|
definePlay,
|
|
1857
1924
|
defineWorkflow,
|
|
@@ -1864,4 +1931,3 @@ export {
|
|
|
1864
1931
|
writeCsvOutputFile,
|
|
1865
1932
|
writeJsonOutputFile
|
|
1866
1933
|
};
|
|
1867
|
-
//# sourceMappingURL=index.mjs.map
|