deepline 0.1.36 → 0.1.38

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.
@@ -193,8 +193,8 @@ function resolveConfig(options) {
193
193
  }
194
194
 
195
195
  // src/version.ts
196
- var SDK_VERSION = "0.1.36";
197
- var SDK_API_CONTRACT = "2026-05-v2-tool-response";
196
+ var SDK_VERSION = "0.1.38";
197
+ var SDK_API_CONTRACT = "2026-05-v2-tool-response-play-guardrails";
198
198
 
199
199
  // ../shared_libs/play-runtime/coordinator-headers.ts
200
200
  var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
@@ -7478,6 +7478,126 @@ function shouldUseLocalOnlyPlayCheck() {
7478
7478
  const value = process.env.DEEPLINE_PLAY_CHECK_LOCAL_ONLY?.trim().toLowerCase();
7479
7479
  return value === "1" || value === "true" || value === "yes" || value === "on";
7480
7480
  }
7481
+ function isRecord3(value) {
7482
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
7483
+ }
7484
+ function stringValue(value) {
7485
+ return typeof value === "string" ? value.trim() : "";
7486
+ }
7487
+ function asArray(value) {
7488
+ return Array.isArray(value) ? value : [];
7489
+ }
7490
+ function extractionEntries(value) {
7491
+ if (Array.isArray(value)) return value.filter(isRecord3);
7492
+ if (!isRecord3(value)) return [];
7493
+ return Object.entries(value).map(
7494
+ ([name, entry]) => isRecord3(entry) ? { name, ...entry } : { name }
7495
+ );
7496
+ }
7497
+ function firstRawPath(entry) {
7498
+ const details = isRecord3(entry.details) ? entry.details : {};
7499
+ const paths = [
7500
+ ...asArray(details.rawToolOutputPaths),
7501
+ ...asArray(details.raw_tool_output_paths),
7502
+ ...asArray(details.candidatePaths),
7503
+ ...asArray(details.candidate_paths)
7504
+ ].map(stringValue).filter(Boolean);
7505
+ return paths[0];
7506
+ }
7507
+ function checkHintExpression(value) {
7508
+ return stringValue(value).replace(/^toolExecutionResult\./, "result.");
7509
+ }
7510
+ function checkHintRawPath(value) {
7511
+ return value?.replace(/^toolResponse\./, "result.toolResponse.");
7512
+ }
7513
+ function collectStaticPipelineToolIds(staticPipeline) {
7514
+ const seen = /* @__PURE__ */ new Set();
7515
+ const visitPipeline = (pipeline) => {
7516
+ if (!isRecord3(pipeline)) return;
7517
+ for (const step of [
7518
+ ...asArray(pipeline.stages),
7519
+ ...asArray(pipeline.substeps)
7520
+ ]) {
7521
+ if (!isRecord3(step)) continue;
7522
+ if (step.type === "tool") {
7523
+ const toolId = stringValue(step.toolId) || stringValue(step.tool);
7524
+ if (toolId) seen.add(toolId);
7525
+ }
7526
+ if (step.type === "play_call") {
7527
+ visitPipeline(step.pipeline);
7528
+ }
7529
+ }
7530
+ };
7531
+ visitPipeline(staticPipeline);
7532
+ return [...seen].sort();
7533
+ }
7534
+ function toolGetterHintFromMetadata(toolId, tool) {
7535
+ const usageGuidance = isRecord3(tool.usageGuidance) ? tool.usageGuidance : {};
7536
+ const resultGuidance = isRecord3(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord3(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
7537
+ const toolResponse = isRecord3(resultGuidance.toolResponse) ? resultGuidance.toolResponse : isRecord3(resultGuidance.tool_response) ? resultGuidance.tool_response : {};
7538
+ const lists = extractionEntries(
7539
+ resultGuidance.extractedLists ?? resultGuidance.extracted_lists
7540
+ ).map((entry) => ({
7541
+ name: stringValue(entry.name),
7542
+ expression: checkHintExpression(entry.expression),
7543
+ raw: checkHintRawPath(firstRawPath(entry))
7544
+ })).filter((entry) => entry.name && entry.expression);
7545
+ const values = extractionEntries(
7546
+ resultGuidance.extractedValues ?? resultGuidance.extracted_values
7547
+ ).map((entry) => ({
7548
+ name: stringValue(entry.name),
7549
+ expression: checkHintExpression(entry.expression),
7550
+ raw: checkHintRawPath(firstRawPath(entry))
7551
+ })).filter((entry) => entry.name && entry.expression);
7552
+ return {
7553
+ toolId,
7554
+ lists,
7555
+ values,
7556
+ raw: checkHintExpression(toolResponse.raw) || "result.toolResponse.raw"
7557
+ };
7558
+ }
7559
+ async function buildToolGetterHints(client, staticPipeline) {
7560
+ const toolIds = collectStaticPipelineToolIds(staticPipeline);
7561
+ return Promise.all(
7562
+ toolIds.map(async (toolId) => {
7563
+ try {
7564
+ const tool = await client.getTool(toolId);
7565
+ return toolGetterHintFromMetadata(toolId, tool);
7566
+ } catch (error) {
7567
+ return {
7568
+ toolId,
7569
+ lists: [],
7570
+ values: [],
7571
+ raw: "result.toolResponse.raw",
7572
+ unavailable: error instanceof Error ? error.message : String(error)
7573
+ };
7574
+ }
7575
+ })
7576
+ );
7577
+ }
7578
+ function printToolGetterHints(hints) {
7579
+ if (!hints?.length) return;
7580
+ console.log(" Tool result getter hints:");
7581
+ for (const hint of hints) {
7582
+ console.log(` ${hint.toolId} output:`);
7583
+ if (hint.lists.length) {
7584
+ for (const entry of hint.lists) {
7585
+ const raw = entry.raw ? ` (raw: ${entry.raw})` : "";
7586
+ console.log(` - list ${entry.name}: ${entry.expression}${raw}`);
7587
+ }
7588
+ }
7589
+ if (hint.values.length) {
7590
+ const valueNames = hint.values.map((entry) => entry.name).join(", ");
7591
+ console.log(` - values: ${valueNames}`);
7592
+ for (const entry of hint.values) {
7593
+ const raw = entry.raw ? ` (raw: ${entry.raw})` : "";
7594
+ console.log(` ${entry.name}: ${entry.expression}${raw}`);
7595
+ }
7596
+ }
7597
+ if (hint.raw) console.log(` - raw: ${hint.raw}`);
7598
+ if (hint.unavailable) console.log(` - warning: ${hint.unavailable}`);
7599
+ }
7600
+ }
7481
7601
  async function handlePlayCheck(args) {
7482
7602
  const options = parsePlayCheckOptions(args);
7483
7603
  if (!isFileTarget(options.target)) {
@@ -7508,6 +7628,7 @@ async function handlePlayCheck(args) {
7508
7628
  valid: true,
7509
7629
  errors: [],
7510
7630
  staticPipeline: graph.root.compilerManifest?.staticPipeline ?? null,
7631
+ toolGetterHints: [],
7511
7632
  artifactHash: graph.root.artifact.artifactHash,
7512
7633
  graphHash: graph.root.artifact.graphHash
7513
7634
  };
@@ -7517,6 +7638,7 @@ async function handlePlayCheck(args) {
7517
7638
  } else {
7518
7639
  console.log(`\u2713 ${playName} passed local play check`);
7519
7640
  console.log(` artifact: ${result2.artifactHash.slice(0, 12)}`);
7641
+ printToolGetterHints(result2.toolGetterHints);
7520
7642
  }
7521
7643
  return 0;
7522
7644
  }
@@ -7527,21 +7649,27 @@ async function handlePlayCheck(args) {
7527
7649
  sourceFiles: graph.root.sourceFiles,
7528
7650
  artifact: graph.root.artifact
7529
7651
  });
7652
+ const enrichedResult = {
7653
+ ...result,
7654
+ toolGetterHints: result.toolGetterHints ?? await buildToolGetterHints(client, result.staticPipeline)
7655
+ };
7530
7656
  if (options.jsonOutput) {
7531
- process.stdout.write(`${JSON.stringify({ name: playName, ...result })}
7657
+ process.stdout.write(`${JSON.stringify({ name: playName, ...enrichedResult })}
7532
7658
  `);
7533
- } else if (result.valid) {
7659
+ } else if (enrichedResult.valid) {
7534
7660
  console.log(`\u2713 ${playName} passed cloud play check`);
7535
- if (result.artifactHash) {
7536
- console.log(` artifact: ${result.artifactHash.slice(0, 12)}`);
7661
+ if (enrichedResult.artifactHash) {
7662
+ console.log(` artifact: ${enrichedResult.artifactHash.slice(0, 12)}`);
7537
7663
  }
7664
+ printToolGetterHints(enrichedResult.toolGetterHints);
7538
7665
  } else {
7539
7666
  console.error(`\u2717 ${playName} failed cloud play check`);
7540
- for (const error of result.errors) {
7667
+ for (const error of enrichedResult.errors) {
7541
7668
  console.error(` ${error}`);
7542
7669
  }
7670
+ printToolGetterHints(enrichedResult.toolGetterHints);
7543
7671
  }
7544
- return result.valid ? 0 : 1;
7672
+ return enrichedResult.valid ? 0 : 1;
7545
7673
  }
7546
7674
  async function handleFileBackedRun(options) {
7547
7675
  if (options.target.kind !== "file") {
@@ -8644,7 +8772,7 @@ Pass-through input flags:
8644
8772
  ...options.logs ? ["--logs"] : [],
8645
8773
  ...options.tailTimeoutMs ? ["--tail-timeout-ms", options.tailTimeoutMs] : [],
8646
8774
  ...options.force ? ["--force"] : [],
8647
- ...options.open === false ? ["--no-open"] : [],
8775
+ ...options.noOpen || options.open === false ? ["--no-open"] : [],
8648
8776
  ...options.json ? ["--json"] : [],
8649
8777
  ...passthroughArgs
8650
8778
  ]);
@@ -9100,6 +9228,15 @@ function extractSummaryFields(payload) {
9100
9228
 
9101
9229
  // src/cli/commands/tools.ts
9102
9230
  function toListedTool(tool) {
9231
+ if (isPlayLikeTool(tool)) {
9232
+ const playReference = playReferenceForTool(tool);
9233
+ return {
9234
+ ...tool,
9235
+ id: tool.toolId,
9236
+ type: "play",
9237
+ executeCommand: `deepline plays run ${playReference} --input '{...}' --watch`
9238
+ };
9239
+ }
9103
9240
  return {
9104
9241
  ...tool,
9105
9242
  id: tool.toolId,
@@ -9138,11 +9275,12 @@ async function searchTools(queryInput, options = {}) {
9138
9275
  searchMode: options.searchMode,
9139
9276
  includeSearchDebug: options.includeSearchDebug
9140
9277
  });
9141
- const items = result.tools.map(toListedTool);
9278
+ const items = result.tools.filter((tool) => !isPlayLikeTool(tool)).map(toListedTool);
9142
9279
  const envelope = {
9143
9280
  ...result,
9144
9281
  tools: items,
9145
9282
  count: items.length,
9283
+ omitted_plays_hint: "Use `deepline plays search <query> --json` for prebuilt and org-owned plays.",
9146
9284
  render: {
9147
9285
  sections: [
9148
9286
  {
@@ -9155,6 +9293,10 @@ async function searchTools(queryInput, options = {}) {
9155
9293
  ...item.inputSchema ? [" inputSchema: yes"] : []
9156
9294
  ];
9157
9295
  })
9296
+ },
9297
+ {
9298
+ title: "plays",
9299
+ lines: ["For prebuilt or org-owned workflows, run: deepline plays search <query>"]
9158
9300
  }
9159
9301
  ]
9160
9302
  }
@@ -9173,13 +9315,36 @@ async function findPlayForToolId(client, toolId) {
9173
9315
  const plays = await client.searchPlays({ query: requested, compact: true });
9174
9316
  return plays.find((play) => playIdentifiers(play).includes(requested)) ?? null;
9175
9317
  }
9176
- function printPlayAliasToolError(toolId, play) {
9318
+ function playAliasToolErrorMessage(toolId, play) {
9177
9319
  const playName = play.reference ?? play.name;
9178
- console.error(
9179
- `${toolId} is a play, not a tool.
9320
+ return `${toolId} is a play, not a tool.
9180
9321
  Use: deepline plays run ${playName} --input '{...}' --watch
9181
- Inspect its schema with: deepline plays describe ${playName} --json`
9182
- );
9322
+ Inspect its schema with: deepline plays describe ${playName} --json`;
9323
+ }
9324
+ function printPlayAliasToolError(toolId, play) {
9325
+ console.error(playAliasToolErrorMessage(toolId, play));
9326
+ }
9327
+ function isPlayLikeTool(tool) {
9328
+ const record = tool;
9329
+ if (record.isPlay === true || record.is_play === true) return true;
9330
+ const playExpansion = recordField(record, "playExpansion", "play_expansion");
9331
+ if (Object.keys(playExpansion).length > 0) return true;
9332
+ const toolId = typeof record.toolId === "string" ? record.toolId : "";
9333
+ return toolId.endsWith("_waterfall");
9334
+ }
9335
+ function playReferenceForTool(tool) {
9336
+ const record = tool;
9337
+ const toolId = typeof record.toolId === "string" ? record.toolId : "play";
9338
+ return `prebuilt/${toolId.replace(/_/g, "-")}`;
9339
+ }
9340
+ function playLikeToolExecuteErrorMessage(toolId) {
9341
+ const playReference = `prebuilt/${toolId.replace(/_/g, "-")}`;
9342
+ return `${toolId} is a workflow/play entry, not an atomic provider tool.
9343
+ Use: deepline plays run ${playReference} --input '{...}' --watch
9344
+ Or search provider tools only with: deepline tools search "<query>" --json`;
9345
+ }
9346
+ function printPlayLikeToolExecuteError(toolId) {
9347
+ console.error(playLikeToolExecuteErrorMessage(toolId));
9183
9348
  }
9184
9349
  function registerToolsCommands(program) {
9185
9350
  const tools = program.command("tools").description("Search, describe, and execute atomic provider tools.").addHelpText(
@@ -9354,7 +9519,7 @@ function printToolDetails(tool, requestedToolId) {
9354
9519
  const operation = typeof tool.operation === "string" ? tool.operation : "";
9355
9520
  const displayBase = operation && operation.startsWith(`${tool.provider}_`) ? operation.slice(String(tool.provider).length + 1) : operation ? `${tool.provider} ${operation}`.trim() : toolId;
9356
9521
  const displayName = titleCase(displayBase || String(tool.displayName || toolId));
9357
- const cost = isRecord3(tool.cost) ? tool.cost : null;
9522
+ const cost = isRecord4(tool.cost) ? tool.cost : null;
9358
9523
  const deeplineCredits = numberField(tool, "deeplineCreditsPerPricingUnit", "deepline_credits_per_pricing_unit");
9359
9524
  const deeplineUsdPerPricingUnit = numberField(tool, "deeplineUsdPerPricingUnit", "deepline_usd_per_pricing_unit");
9360
9525
  const deeplineUsdPerCredit = numberField(tool, "deeplineUsdPerCredit", "deepline_usd_per_credit");
@@ -9404,7 +9569,7 @@ function printToolDetails(tool, requestedToolId) {
9404
9569
  if (stepContributions.length) {
9405
9570
  console.log(" step contributions:");
9406
9571
  for (const item of stepContributions) {
9407
- if (!isRecord3(item)) continue;
9572
+ if (!isRecord4(item)) continue;
9408
9573
  const stepTool = typeof item.tool === "string" ? item.tool.trim() : "";
9409
9574
  const low = typeof item.lowCredits === "number" ? item.lowCredits : null;
9410
9575
  const high = typeof item.highCredits === "number" ? item.highCredits : null;
@@ -9444,7 +9609,7 @@ function printToolDetails(tool, requestedToolId) {
9444
9609
  }
9445
9610
  const toolExecutionResult = recordField(usageGuidance, "toolExecutionResult");
9446
9611
  const extractedValues = arrayField(toolExecutionResult, "extractedValues", "extracted_values");
9447
- const targets = extractedValues.map((entry) => isRecord3(entry) && typeof entry.name === "string" ? entry.name : "").filter(Boolean).sort();
9612
+ const targets = extractedValues.map((entry) => isRecord4(entry) && typeof entry.name === "string" ? entry.name : "").filter(Boolean).sort();
9448
9613
  if (targets.length) {
9449
9614
  console.log(` - Built-in extract targets: ${targets.join(", ")}`);
9450
9615
  }
@@ -9485,7 +9650,7 @@ function printExtractions(label, entries) {
9485
9650
  if (!entries.length) return;
9486
9651
  console.log(` ${label}:`);
9487
9652
  for (const entry of entries) {
9488
- if (!isRecord3(entry)) continue;
9653
+ if (!isRecord4(entry)) continue;
9489
9654
  const name = stringField(entry, "name");
9490
9655
  const expression = stringField(entry, "expression");
9491
9656
  const details = recordField(entry, "details");
@@ -9525,12 +9690,12 @@ function printToolCost(input) {
9525
9690
  return false;
9526
9691
  }
9527
9692
  function toolInputFieldsForDisplay(inputSchema) {
9528
- if (Array.isArray(inputSchema.fields)) return inputSchema.fields.filter(isRecord3);
9529
- const jsonSchema = isRecord3(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
9530
- const properties = isRecord3(jsonSchema.properties) ? jsonSchema.properties : {};
9693
+ if (Array.isArray(inputSchema.fields)) return inputSchema.fields.filter(isRecord4);
9694
+ const jsonSchema = isRecord4(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
9695
+ const properties = isRecord4(jsonSchema.properties) ? jsonSchema.properties : {};
9531
9696
  const required = Array.isArray(jsonSchema.required) ? new Set(jsonSchema.required.map(String)) : /* @__PURE__ */ new Set();
9532
9697
  return Object.entries(properties).map(([name, value]) => {
9533
- const property = isRecord3(value) ? value : {};
9698
+ const property = isRecord4(value) ? value : {};
9534
9699
  return {
9535
9700
  name,
9536
9701
  type: typeof property.type === "string" ? property.type : "unknown",
@@ -9557,15 +9722,15 @@ function printJsonPreview(label, payload) {
9557
9722
  }
9558
9723
  function samplePayload(samples, key) {
9559
9724
  const entry = samples[key];
9560
- if (!isRecord3(entry)) return void 0;
9725
+ if (!isRecord4(entry)) return void 0;
9561
9726
  return Object.prototype.hasOwnProperty.call(entry, "payload") ? entry.payload : entry;
9562
9727
  }
9563
9728
  function commandEnvelopeFromRawResponse(rawResponse) {
9564
- return isRecord3(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
9729
+ return isRecord4(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
9565
9730
  }
9566
9731
  function listExtractorPathsFromUsageGuidance(tool) {
9567
9732
  const toolExecutionResult = tool.usageGuidance?.toolExecutionResult;
9568
- const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord3(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
9733
+ const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord4(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
9569
9734
  return extractedLists.flatMap((entry) => {
9570
9735
  const paths = entry.details?.candidatePaths ?? entry.details?.rawToolOutputPaths;
9571
9736
  if (!Array.isArray(paths)) return [];
@@ -9592,7 +9757,7 @@ function formatDecimal(value) {
9592
9757
  function formatUsd(value) {
9593
9758
  return `$${formatDecimal(value)}`;
9594
9759
  }
9595
- function isRecord3(value) {
9760
+ function isRecord4(value) {
9596
9761
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
9597
9762
  }
9598
9763
  function stringField(source, ...keys) {
@@ -9619,7 +9784,7 @@ function arrayField(source, ...keys) {
9619
9784
  function recordField(source, ...keys) {
9620
9785
  for (const key of keys) {
9621
9786
  const value = source[key];
9622
- if (isRecord3(value)) return value;
9787
+ if (isRecord4(value)) return value;
9623
9788
  }
9624
9789
  return {};
9625
9790
  }
@@ -9717,8 +9882,11 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
9717
9882
  // .step('phone_waterfall', (row, rowCtx) => rowCtx.runPlay('contact_phone', 'contact-to-phone', { first_name: String(row.first_name ?? ''), last_name: String(row.last_name ?? ''), email: String(row.email ?? '') }, { description: 'Resolve phone.' }))
9718
9883
  // ctx.map is idempotent by map key + row key; reruns reuse completed rows.
9719
9884
  const enrichedData = await ctx
9720
- .map('enriched_data', rows, { key: ${rowKey} })
9721
- .run({ description: 'Enrich seeded rows.' });
9885
+ .map('enriched_data', rows)
9886
+ .run({
9887
+ key: ${rowKey},
9888
+ description: 'Enrich seeded rows.',
9889
+ });
9722
9890
 
9723
9891
  return {
9724
9892
  rows: enrichedData,
@@ -9748,7 +9916,7 @@ function buildToolExecuteBaseEnvelope(input) {
9748
9916
  kind: summaryEntries.length > 0 ? "object" : "raw",
9749
9917
  summary: input.summary
9750
9918
  };
9751
- const envelopeHasCanonicalOutput = isRecord3(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
9919
+ const envelopeHasCanonicalOutput = isRecord4(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
9752
9920
  const inspectCommand = `deepline tools execute ${input.toolId} --input ${shellQuote(JSON.stringify(input.params))} --json`;
9753
9921
  const actions = input.listConversion ? [
9754
9922
  {
@@ -9808,7 +9976,11 @@ async function executeTool(args) {
9808
9976
  } catch (error) {
9809
9977
  const play = await findPlayForToolId(client, parsed.toolId);
9810
9978
  if (play) {
9811
- printPlayAliasToolError(parsed.toolId, play);
9979
+ if (argsWantJson(args)) {
9980
+ printJsonError(new Error(playAliasToolErrorMessage(parsed.toolId, play)));
9981
+ } else {
9982
+ printPlayAliasToolError(parsed.toolId, play);
9983
+ }
9812
9984
  return 2;
9813
9985
  }
9814
9986
  if (error instanceof DeeplineError) {
@@ -9816,6 +9988,14 @@ async function executeTool(args) {
9816
9988
  }
9817
9989
  throw error;
9818
9990
  }
9991
+ if (isPlayLikeTool(metadata)) {
9992
+ if (argsWantJson(args)) {
9993
+ printJsonError(new Error(playLikeToolExecuteErrorMessage(parsed.toolId)));
9994
+ } else {
9995
+ printPlayLikeToolExecuteError(parsed.toolId);
9996
+ }
9997
+ return 2;
9998
+ }
9819
9999
  const rawResponse = await client.executeTool(parsed.toolId, parsed.params);
9820
10000
  const listConversion = tryConvertToList(rawResponse, {
9821
10001
  listExtractorPaths: listExtractorPathsFromUsageGuidance(metadata)
@@ -9838,7 +10018,7 @@ async function executeTool(args) {
9838
10018
  {
9839
10019
  ...baseEnvelope,
9840
10020
  local: {
9841
- ...isRecord3(baseEnvelope.local) ? baseEnvelope.local : {},
10021
+ ...isRecord4(baseEnvelope.local) ? baseEnvelope.local : {},
9842
10022
  payload_file: jsonPath
9843
10023
  }
9844
10024
  },
@@ -10436,9 +10616,15 @@ Notes:
10436
10616
 
10437
10617
  Examples:
10438
10618
  deepline version
10619
+ deepline version --json
10439
10620
  deepline --version
10440
10621
  `
10441
- ).action(() => {
10622
+ ).option("--json", "Emit JSON output").action((options) => {
10623
+ if (options.json) {
10624
+ process.stdout.write(`${JSON.stringify({ version: SDK_VERSION })}
10625
+ `);
10626
+ return;
10627
+ }
10442
10628
  process.stdout.write(`deepline ${SDK_VERSION}
10443
10629
  `);
10444
10630
  });
package/dist/index.d.mts CHANGED
@@ -745,9 +745,25 @@ interface PlayCheckResult {
745
745
  valid: boolean;
746
746
  errors: string[];
747
747
  staticPipeline?: Record<string, unknown> | null;
748
+ toolGetterHints?: PlayCheckToolGetterHint[];
748
749
  artifactHash?: string | null;
749
750
  graphHash?: string | null;
750
751
  }
752
+ interface PlayCheckToolGetterHint {
753
+ toolId: string;
754
+ lists: Array<{
755
+ name: string;
756
+ expression: string;
757
+ raw?: string;
758
+ }>;
759
+ values: Array<{
760
+ name: string;
761
+ expression: string;
762
+ raw?: string;
763
+ }>;
764
+ raw?: string;
765
+ unavailable?: string;
766
+ }
751
767
  /**
752
768
  * Request body for starting a play run via {@link DeeplineClient.startPlayRun}.
753
769
  *
@@ -1477,8 +1493,8 @@ declare class DeeplineClient {
1477
1493
  }>;
1478
1494
  }
1479
1495
 
1480
- declare const SDK_VERSION = "0.1.36";
1481
- declare const SDK_API_CONTRACT = "2026-05-v2-tool-response";
1496
+ declare const SDK_VERSION = "0.1.38";
1497
+ declare const SDK_API_CONTRACT = "2026-05-v2-tool-response-play-guardrails";
1482
1498
 
1483
1499
  /**
1484
1500
  * Base error class for all Deepline SDK errors.
package/dist/index.d.ts CHANGED
@@ -745,9 +745,25 @@ interface PlayCheckResult {
745
745
  valid: boolean;
746
746
  errors: string[];
747
747
  staticPipeline?: Record<string, unknown> | null;
748
+ toolGetterHints?: PlayCheckToolGetterHint[];
748
749
  artifactHash?: string | null;
749
750
  graphHash?: string | null;
750
751
  }
752
+ interface PlayCheckToolGetterHint {
753
+ toolId: string;
754
+ lists: Array<{
755
+ name: string;
756
+ expression: string;
757
+ raw?: string;
758
+ }>;
759
+ values: Array<{
760
+ name: string;
761
+ expression: string;
762
+ raw?: string;
763
+ }>;
764
+ raw?: string;
765
+ unavailable?: string;
766
+ }
751
767
  /**
752
768
  * Request body for starting a play run via {@link DeeplineClient.startPlayRun}.
753
769
  *
@@ -1477,8 +1493,8 @@ declare class DeeplineClient {
1477
1493
  }>;
1478
1494
  }
1479
1495
 
1480
- declare const SDK_VERSION = "0.1.36";
1481
- declare const SDK_API_CONTRACT = "2026-05-v2-tool-response";
1496
+ declare const SDK_VERSION = "0.1.38";
1497
+ declare const SDK_API_CONTRACT = "2026-05-v2-tool-response-play-guardrails";
1482
1498
 
1483
1499
  /**
1484
1500
  * Base error class for all Deepline SDK errors.
package/dist/index.js CHANGED
@@ -215,8 +215,8 @@ function resolveConfig(options) {
215
215
  }
216
216
 
217
217
  // src/version.ts
218
- var SDK_VERSION = "0.1.36";
219
- var SDK_API_CONTRACT = "2026-05-v2-tool-response";
218
+ var SDK_VERSION = "0.1.38";
219
+ var SDK_API_CONTRACT = "2026-05-v2-tool-response-play-guardrails";
220
220
 
221
221
  // ../shared_libs/play-runtime/coordinator-headers.ts
222
222
  var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
@@ -1891,9 +1891,8 @@ function buildTargets(result, resultIdentityGetters) {
1891
1891
  }
1892
1892
  return targets;
1893
1893
  }
1894
- function buildLists(result, metadata) {
1894
+ function buildLists(resolved, metadata) {
1895
1895
  const lists = {};
1896
- const resolved = resolveListRows(result, metadata.listExtractorPaths);
1897
1896
  for (const [name, list] of Object.entries(resolved)) {
1898
1897
  lists[name] = {
1899
1898
  path: list.path,
@@ -1928,9 +1927,10 @@ function buildExtractedAccessors(targets) {
1928
1927
  })
1929
1928
  );
1930
1929
  }
1931
- function buildListAccessors(result, lists) {
1930
+ function buildListAccessors(resolved, lists) {
1932
1931
  return Object.fromEntries(
1933
1932
  Object.entries(lists).map(([name, metadata]) => {
1933
+ const rows = resolved[name]?.rows ?? [];
1934
1934
  const accessor = {
1935
1935
  path: metadata.path,
1936
1936
  count: metadata.count,
@@ -1938,7 +1938,7 @@ function buildListAccessors(result, lists) {
1938
1938
  };
1939
1939
  Object.defineProperty(accessor, "get", {
1940
1940
  value() {
1941
- return normalizeRows(getAtPath(result, metadata.path)) ?? [];
1941
+ return rows;
1942
1942
  },
1943
1943
  enumerable: false
1944
1944
  });
@@ -1958,7 +1958,11 @@ function createToolExecuteResult(input) {
1958
1958
  resultRoot,
1959
1959
  input.metadata.resultIdentityGetters
1960
1960
  );
1961
- const lists = buildLists(resultRoot, input.metadata);
1961
+ const resolvedLists = resolveListRows(
1962
+ resultRoot,
1963
+ input.metadata.listExtractorPaths
1964
+ );
1965
+ const lists = buildLists(resolvedLists, input.metadata);
1962
1966
  const metadata = {
1963
1967
  toolId: input.metadata.toolId,
1964
1968
  execution: input.execution,
@@ -1970,7 +1974,7 @@ function createToolExecuteResult(input) {
1970
1974
  ...result.meta ? { meta: result.meta } : {}
1971
1975
  };
1972
1976
  const extractedValues = buildExtractedAccessors(targets);
1973
- const extractedLists = buildListAccessors(resultRoot, lists);
1977
+ const extractedLists = buildListAccessors(resolvedLists, lists);
1974
1978
  const wrapper = {
1975
1979
  status: input.status,
1976
1980
  ...input.jobId ? { job_id: input.jobId } : {},
package/dist/index.mjs CHANGED
@@ -169,8 +169,8 @@ function resolveConfig(options) {
169
169
  }
170
170
 
171
171
  // src/version.ts
172
- var SDK_VERSION = "0.1.36";
173
- var SDK_API_CONTRACT = "2026-05-v2-tool-response";
172
+ var SDK_VERSION = "0.1.38";
173
+ var SDK_API_CONTRACT = "2026-05-v2-tool-response-play-guardrails";
174
174
 
175
175
  // ../shared_libs/play-runtime/coordinator-headers.ts
176
176
  var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
@@ -1845,9 +1845,8 @@ function buildTargets(result, resultIdentityGetters) {
1845
1845
  }
1846
1846
  return targets;
1847
1847
  }
1848
- function buildLists(result, metadata) {
1848
+ function buildLists(resolved, metadata) {
1849
1849
  const lists = {};
1850
- const resolved = resolveListRows(result, metadata.listExtractorPaths);
1851
1850
  for (const [name, list] of Object.entries(resolved)) {
1852
1851
  lists[name] = {
1853
1852
  path: list.path,
@@ -1882,9 +1881,10 @@ function buildExtractedAccessors(targets) {
1882
1881
  })
1883
1882
  );
1884
1883
  }
1885
- function buildListAccessors(result, lists) {
1884
+ function buildListAccessors(resolved, lists) {
1886
1885
  return Object.fromEntries(
1887
1886
  Object.entries(lists).map(([name, metadata]) => {
1887
+ const rows = resolved[name]?.rows ?? [];
1888
1888
  const accessor = {
1889
1889
  path: metadata.path,
1890
1890
  count: metadata.count,
@@ -1892,7 +1892,7 @@ function buildListAccessors(result, lists) {
1892
1892
  };
1893
1893
  Object.defineProperty(accessor, "get", {
1894
1894
  value() {
1895
- return normalizeRows(getAtPath(result, metadata.path)) ?? [];
1895
+ return rows;
1896
1896
  },
1897
1897
  enumerable: false
1898
1898
  });
@@ -1912,7 +1912,11 @@ function createToolExecuteResult(input) {
1912
1912
  resultRoot,
1913
1913
  input.metadata.resultIdentityGetters
1914
1914
  );
1915
- const lists = buildLists(resultRoot, input.metadata);
1915
+ const resolvedLists = resolveListRows(
1916
+ resultRoot,
1917
+ input.metadata.listExtractorPaths
1918
+ );
1919
+ const lists = buildLists(resolvedLists, input.metadata);
1916
1920
  const metadata = {
1917
1921
  toolId: input.metadata.toolId,
1918
1922
  execution: input.execution,
@@ -1924,7 +1928,7 @@ function createToolExecuteResult(input) {
1924
1928
  ...result.meta ? { meta: result.meta } : {}
1925
1929
  };
1926
1930
  const extractedValues = buildExtractedAccessors(targets);
1927
- const extractedLists = buildListAccessors(resultRoot, lists);
1931
+ const extractedLists = buildListAccessors(resolvedLists, lists);
1928
1932
  const wrapper = {
1929
1933
  status: input.status,
1930
1934
  ...input.jobId ? { job_id: input.jobId } : {},