@scenario-labs/sdk 2.4.0 → 2.6.0

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.
Files changed (91) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/client.d.mts +1 -1
  3. package/client.d.mts.map +1 -1
  4. package/client.d.ts +1 -1
  5. package/client.d.ts.map +1 -1
  6. package/lib/workflow_converter.d.mts +4 -0
  7. package/lib/workflow_converter.d.mts.map +1 -1
  8. package/lib/workflow_converter.d.ts +4 -0
  9. package/lib/workflow_converter.d.ts.map +1 -1
  10. package/lib/workflow_converter.js +64 -34
  11. package/lib/workflow_converter.js.map +1 -1
  12. package/lib/workflow_converter.mjs +64 -34
  13. package/lib/workflow_converter.mjs.map +1 -1
  14. package/package.json +1 -1
  15. package/resources/assets/assets.d.mts +269 -31
  16. package/resources/assets/assets.d.mts.map +1 -1
  17. package/resources/assets/assets.d.ts +269 -31
  18. package/resources/assets/assets.d.ts.map +1 -1
  19. package/resources/assets/assets.js.map +1 -1
  20. package/resources/assets/assets.mjs.map +1 -1
  21. package/resources/generate.d.mts +159 -51
  22. package/resources/generate.d.mts.map +1 -1
  23. package/resources/generate.d.ts +159 -51
  24. package/resources/generate.d.ts.map +1 -1
  25. package/resources/generate.js +1 -5
  26. package/resources/generate.js.map +1 -1
  27. package/resources/generate.mjs +1 -5
  28. package/resources/generate.mjs.map +1 -1
  29. package/resources/index.d.mts +1 -1
  30. package/resources/index.d.mts.map +1 -1
  31. package/resources/index.d.ts +1 -1
  32. package/resources/index.d.ts.map +1 -1
  33. package/resources/jobs.d.mts +30 -12
  34. package/resources/jobs.d.mts.map +1 -1
  35. package/resources/jobs.d.ts +30 -12
  36. package/resources/jobs.d.ts.map +1 -1
  37. package/resources/models/description.d.mts +62 -4
  38. package/resources/models/description.d.mts.map +1 -1
  39. package/resources/models/description.d.ts +62 -4
  40. package/resources/models/description.d.ts.map +1 -1
  41. package/resources/models/examples.d.mts +94 -64
  42. package/resources/models/examples.d.mts.map +1 -1
  43. package/resources/models/examples.d.ts +94 -64
  44. package/resources/models/examples.d.ts.map +1 -1
  45. package/resources/models/models.d.mts +239 -295
  46. package/resources/models/models.d.mts.map +1 -1
  47. package/resources/models/models.d.ts +239 -295
  48. package/resources/models/models.d.ts.map +1 -1
  49. package/resources/models/models.js.map +1 -1
  50. package/resources/models/models.mjs.map +1 -1
  51. package/resources/models/train.d.mts +92 -110
  52. package/resources/models/train.d.mts.map +1 -1
  53. package/resources/models/train.d.ts +92 -110
  54. package/resources/models/train.d.ts.map +1 -1
  55. package/resources/search.d.mts +2 -2
  56. package/resources/search.d.ts +2 -2
  57. package/resources/uploads.d.mts +2 -3
  58. package/resources/uploads.d.mts.map +1 -1
  59. package/resources/uploads.d.ts +2 -3
  60. package/resources/uploads.d.ts.map +1 -1
  61. package/resources/usages.d.mts +44 -15
  62. package/resources/usages.d.mts.map +1 -1
  63. package/resources/usages.d.ts +44 -15
  64. package/resources/usages.d.ts.map +1 -1
  65. package/resources/workflows.d.mts +63 -45
  66. package/resources/workflows.d.mts.map +1 -1
  67. package/resources/workflows.d.ts +63 -45
  68. package/resources/workflows.d.ts.map +1 -1
  69. package/resources/workflows.js +4 -4
  70. package/resources/workflows.js.map +1 -1
  71. package/resources/workflows.mjs +4 -4
  72. package/resources/workflows.mjs.map +1 -1
  73. package/src/client.ts +1 -1
  74. package/src/lib/workflow_converter.ts +96 -35
  75. package/src/resources/assets/assets.ts +300 -62
  76. package/src/resources/generate.ts +159 -129
  77. package/src/resources/index.ts +1 -1
  78. package/src/resources/jobs.ts +27 -37
  79. package/src/resources/models/description.ts +70 -12
  80. package/src/resources/models/examples.ts +100 -88
  81. package/src/resources/models/models.ts +228 -385
  82. package/src/resources/models/train.ts +89 -139
  83. package/src/resources/search.ts +2 -2
  84. package/src/resources/uploads.ts +2 -3
  85. package/src/resources/usages.ts +47 -20
  86. package/src/resources/workflows.ts +48 -157
  87. package/src/version.ts +1 -1
  88. package/version.d.mts +1 -1
  89. package/version.d.ts +1 -1
  90. package/version.js +1 -1
  91. package/version.mjs +1 -1
@@ -52,7 +52,14 @@ export type WorkflowEditorNode =
52
52
  | {
53
53
  id: string;
54
54
  type: 'sliceAssets';
55
- data: NodeCommonData & { from?: number | string; count?: number | string };
55
+ data: NodeCommonData & {
56
+ from?: number | string;
57
+ count?: number | string;
58
+ isRandomize?: boolean;
59
+ randomSeed?: string;
60
+ isSeedLocked?: boolean;
61
+ value?: string;
62
+ };
56
63
  }
57
64
  | { id: string; type: 'forEach'; data: NodeCommonData }
58
65
  | { id: string; type: 'forEachEnd'; data: NodeCommonData & { parentNodeId?: string } }
@@ -561,6 +568,50 @@ function getOutputHandleVarName(targetNodeId: string, handleName: string): strin
561
568
  return ['output', 'allOutputs'].includes(handleName) ? targetNodeId : `${targetNodeId}_${handleName}`;
562
569
  }
563
570
 
571
+ function getIsSliceAssetsItemsSourceHandle(nodeId: string, sourceHandle: string | null | undefined): boolean {
572
+ return sourceHandle === `${nodeId}-source-items` || sourceHandle === `${nodeId}-source-assets`;
573
+ }
574
+
575
+ /**
576
+ * Builds the concat variables and flow inputs for a list-concatenating node
577
+ * (groupItems, sliceAssets in randomize mode) from its incoming edges.
578
+ * `getVarName` maps a target node id + output handle name to the variable name,
579
+ * which differs between callers.
580
+ */
581
+ function collectConcatVarsAndInputs(
582
+ edges: WorkflowEditorEdge[],
583
+ ctx: SourceRefContext,
584
+ getVarName: (targetNodeId: string, handleName: string) => string,
585
+ ): { variables: ConcatVariable[]; flowInputs: WorkflowEditorFlowInput[] } {
586
+ const { nodes, inputNodeIds } = ctx;
587
+ const variables: ConcatVariable[] = [];
588
+ const flowInputs: WorkflowEditorFlowInput[] = [];
589
+
590
+ for (const edge of edges) {
591
+ const targetNode = nodes.find((n) => n.id === edge.target);
592
+ if (!targetNode) continue;
593
+ const ref = getSourceRef(edge, ctx);
594
+ if (!ref) continue;
595
+ const outHandle = targetNode.data.outputHandles?.find((h) => h.id === edge.targetHandle);
596
+ const outHandleName = outHandle?.name ?? 'output';
597
+ const varName = getVarName(targetNode.id, outHandleName);
598
+ const isArr =
599
+ (targetNode.type === 'asset' && !!(targetNode.data as { isMultiple?: boolean }).isMultiple) ||
600
+ targetNode.type === 'groupItems' ||
601
+ targetNode.type === 'sliceAssets' ||
602
+ outHandleName === 'allOutputs';
603
+ const isRequired =
604
+ inputNodeIds.includes(targetNode.id) ?
605
+ (targetNode.type === 'asset' && !!(targetNode.data as { isRequired?: boolean }).isRequired) ||
606
+ ['firstFrame', 'lastFrame'].includes(outHandleName)
607
+ : true;
608
+ variables.push({ name: varName, isArray: isArr, isRequired });
609
+ flowInputs.push({ name: varName, type: isArr ? 'file_array' : 'file', ref });
610
+ }
611
+
612
+ return { variables, flowInputs };
613
+ }
614
+
564
615
  function setOrPushFlowInput(
565
616
  flowInputs: WorkflowEditorFlowInput[],
566
617
  existingIndex: number,
@@ -1522,32 +1573,12 @@ export function convertWorkflowEditorToFlow(
1522
1573
  // GroupItems -> array concatenation
1523
1574
  // ------------------------------------
1524
1575
  } else if (node.type === 'groupItems') {
1525
- const flowInputs: WorkflowEditorFlowInput[] = [];
1526
- const variables: ConcatVariable[] = [];
1527
1576
  const conditionalHandleId = getConditionalInputHandleId(node.id);
1528
-
1529
- for (const edge of incomingEdges) {
1530
- if (edge.sourceHandle === conditionalHandleId) continue;
1531
- const targetNode = nodes.find((n) => n.id === edge.target);
1532
- if (!targetNode) continue;
1533
- const ref = getSourceRef(edge, ctx);
1534
- if (!ref) continue;
1535
- const outHandle = targetNode.data.outputHandles?.find((h) => h.id === edge.targetHandle);
1536
- const outHandleName = outHandle?.name ?? 'output';
1537
- const varName = `${targetNode.id}_${outHandleName}`;
1538
- const isArr =
1539
- (targetNode.type === 'asset' && !!(targetNode.data as { isMultiple?: boolean }).isMultiple) ||
1540
- targetNode.type === 'groupItems' ||
1541
- targetNode.type === 'sliceAssets' ||
1542
- outHandleName === 'allOutputs';
1543
- const isRequired =
1544
- inputNodeIds.includes(targetNode.id) ?
1545
- (targetNode.type === 'asset' && !!(targetNode.data as { isRequired?: boolean }).isRequired) ||
1546
- ['firstFrame', 'lastFrame'].includes(outHandleName)
1547
- : true;
1548
- variables.push({ name: varName, isArray: isArr, isRequired });
1549
- flowInputs.push({ name: varName, type: isArr ? 'file_array' : 'file', ref });
1550
- }
1577
+ const { variables, flowInputs } = collectConcatVarsAndInputs(
1578
+ incomingEdges.filter((e) => e.sourceHandle !== conditionalHandleId),
1579
+ ctx,
1580
+ (targetNodeId, handleName) => `${targetNodeId}_${handleName}`,
1581
+ );
1551
1582
 
1552
1583
  const orderedValues = convertValueToList((node.data as { value?: string }).value ?? '');
1553
1584
  variables.sort((a, b) => orderedValues.indexOf(a.name) - orderedValues.indexOf(b.name));
@@ -1561,20 +1592,50 @@ export function convertWorkflowEditorToFlow(
1561
1592
  });
1562
1593
 
1563
1594
  // ------------------------------------
1564
- // SliceAssets -> slice(list, from, from+count)
1595
+ // SliceAssets -> slice(list, from, from+count) or randomSample(list, count, seed)
1565
1596
  // ------------------------------------
1566
1597
  } else if (node.type === 'sliceAssets') {
1567
- const assetsEdge = incomingEdges.find((e) => e.sourceHandle === `${node.id}-source-assets`);
1568
- if (!assetsEdge) {
1569
- flow.push({ id: flowId, type: 'transform', logic: { transform: '[]' } });
1598
+ const sliceData = node.data as {
1599
+ from?: number | string;
1600
+ count?: number | string;
1601
+ isRandomize?: boolean;
1602
+ randomSeed?: string;
1603
+ isSeedLocked?: boolean;
1604
+ };
1605
+ const conditionalHandleId = getConditionalInputHandleId(node.id);
1606
+ const itemsEdges = incomingEdges.filter(
1607
+ (e) =>
1608
+ e.sourceHandle !== conditionalHandleId &&
1609
+ getIsSliceAssetsItemsSourceHandle(node.id, e.sourceHandle),
1610
+ );
1611
+
1612
+ if (sliceData.isRandomize) {
1613
+ const { variables, flowInputs } = collectConcatVarsAndInputs(itemsEdges, ctx, getOutputHandleVarName);
1614
+ flowInputs.push(...collectConditionalConnectionInputs(incomingEdges, node.id, ctx));
1615
+
1616
+ const count = Math.max(1, parseInt(String(sliceData.count ?? ''), 10) || 1);
1617
+ const listExpr = buildConcatArrayTransform(variables);
1618
+ const transform =
1619
+ sliceData.isSeedLocked === true ?
1620
+ `randomSample(${listExpr}, ${count}, ${parseInt(String(sliceData.randomSeed ?? ''), 10) || 0})`
1621
+ : `randomSample(${listExpr}, ${count})`;
1622
+
1623
+ flow.push({
1624
+ id: flowId,
1625
+ type: 'transform',
1626
+ logic: { transform },
1627
+ inputs: flowInputs.length > 0 ? flowInputs : undefined,
1628
+ });
1570
1629
  } else {
1571
- const targetNode = nodes.find((n) => n.id === assetsEdge.target);
1572
- if (targetNode) {
1573
- const ref = getSourceRef(assetsEdge, ctx);
1574
- if (ref) {
1630
+ const assetsEdge = itemsEdges[0];
1631
+ if (!assetsEdge) {
1632
+ flow.push({ id: flowId, type: 'transform', logic: { transform: '[]' } });
1633
+ } else {
1634
+ const targetNode = nodes.find((n) => n.id === assetsEdge.target);
1635
+ const ref = targetNode ? getSourceRef(assetsEdge, ctx) : undefined;
1636
+ if (targetNode && ref) {
1575
1637
  const outHandle = targetNode.data.outputHandles?.find((h) => h.id === assetsEdge.targetHandle);
1576
1638
  const varName = getOutputHandleVarName(targetNode.id, outHandle?.name ?? 'output');
1577
- const sliceData = node.data as { from?: number | string; count?: number | string };
1578
1639
  const from = parseInt(String(sliceData.from ?? ''), 10) || 0;
1579
1640
  const count = parseInt(String(sliceData.count ?? ''), 10) || 0;
1580
1641
  const transform =