@scenario-labs/sdk 2.4.0 → 2.5.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 +28 -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 +3 -0
  7. package/lib/workflow_converter.d.mts.map +1 -1
  8. package/lib/workflow_converter.d.ts +3 -0
  9. package/lib/workflow_converter.d.ts.map +1 -1
  10. package/lib/workflow_converter.js +62 -34
  11. package/lib/workflow_converter.js.map +1 -1
  12. package/lib/workflow_converter.mjs +62 -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 +157 -51
  22. package/resources/generate.d.mts.map +1 -1
  23. package/resources/generate.d.ts +157 -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 +91 -35
  75. package/src/resources/assets/assets.ts +300 -62
  76. package/src/resources/generate.ts +157 -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,13 @@ 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
+ value?: string;
61
+ };
56
62
  }
57
63
  | { id: string; type: 'forEach'; data: NodeCommonData }
58
64
  | { id: string; type: 'forEachEnd'; data: NodeCommonData & { parentNodeId?: string } }
@@ -561,6 +567,50 @@ function getOutputHandleVarName(targetNodeId: string, handleName: string): strin
561
567
  return ['output', 'allOutputs'].includes(handleName) ? targetNodeId : `${targetNodeId}_${handleName}`;
562
568
  }
563
569
 
570
+ function getIsSliceAssetsItemsSourceHandle(nodeId: string, sourceHandle: string | null | undefined): boolean {
571
+ return sourceHandle === `${nodeId}-source-items` || sourceHandle === `${nodeId}-source-assets`;
572
+ }
573
+
574
+ /**
575
+ * Builds the concat variables and flow inputs for a list-concatenating node
576
+ * (groupItems, sliceAssets in randomize mode) from its incoming edges.
577
+ * `getVarName` maps a target node id + output handle name to the variable name,
578
+ * which differs between callers.
579
+ */
580
+ function collectConcatVarsAndInputs(
581
+ edges: WorkflowEditorEdge[],
582
+ ctx: SourceRefContext,
583
+ getVarName: (targetNodeId: string, handleName: string) => string,
584
+ ): { variables: ConcatVariable[]; flowInputs: WorkflowEditorFlowInput[] } {
585
+ const { nodes, inputNodeIds } = ctx;
586
+ const variables: ConcatVariable[] = [];
587
+ const flowInputs: WorkflowEditorFlowInput[] = [];
588
+
589
+ for (const edge of edges) {
590
+ const targetNode = nodes.find((n) => n.id === edge.target);
591
+ if (!targetNode) continue;
592
+ const ref = getSourceRef(edge, ctx);
593
+ if (!ref) continue;
594
+ const outHandle = targetNode.data.outputHandles?.find((h) => h.id === edge.targetHandle);
595
+ const outHandleName = outHandle?.name ?? 'output';
596
+ const varName = getVarName(targetNode.id, outHandleName);
597
+ const isArr =
598
+ (targetNode.type === 'asset' && !!(targetNode.data as { isMultiple?: boolean }).isMultiple) ||
599
+ targetNode.type === 'groupItems' ||
600
+ targetNode.type === 'sliceAssets' ||
601
+ outHandleName === 'allOutputs';
602
+ const isRequired =
603
+ inputNodeIds.includes(targetNode.id) ?
604
+ (targetNode.type === 'asset' && !!(targetNode.data as { isRequired?: boolean }).isRequired) ||
605
+ ['firstFrame', 'lastFrame'].includes(outHandleName)
606
+ : true;
607
+ variables.push({ name: varName, isArray: isArr, isRequired });
608
+ flowInputs.push({ name: varName, type: isArr ? 'file_array' : 'file', ref });
609
+ }
610
+
611
+ return { variables, flowInputs };
612
+ }
613
+
564
614
  function setOrPushFlowInput(
565
615
  flowInputs: WorkflowEditorFlowInput[],
566
616
  existingIndex: number,
@@ -1522,32 +1572,12 @@ export function convertWorkflowEditorToFlow(
1522
1572
  // GroupItems -> array concatenation
1523
1573
  // ------------------------------------
1524
1574
  } else if (node.type === 'groupItems') {
1525
- const flowInputs: WorkflowEditorFlowInput[] = [];
1526
- const variables: ConcatVariable[] = [];
1527
1575
  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
- }
1576
+ const { variables, flowInputs } = collectConcatVarsAndInputs(
1577
+ incomingEdges.filter((e) => e.sourceHandle !== conditionalHandleId),
1578
+ ctx,
1579
+ (targetNodeId, handleName) => `${targetNodeId}_${handleName}`,
1580
+ );
1551
1581
 
1552
1582
  const orderedValues = convertValueToList((node.data as { value?: string }).value ?? '');
1553
1583
  variables.sort((a, b) => orderedValues.indexOf(a.name) - orderedValues.indexOf(b.name));
@@ -1561,20 +1591,46 @@ export function convertWorkflowEditorToFlow(
1561
1591
  });
1562
1592
 
1563
1593
  // ------------------------------------
1564
- // SliceAssets -> slice(list, from, from+count)
1594
+ // SliceAssets -> slice(list, from, from+count) or randomSample(list, count, seed)
1565
1595
  // ------------------------------------
1566
1596
  } 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: '[]' } });
1597
+ const sliceData = node.data as {
1598
+ from?: number | string;
1599
+ count?: number | string;
1600
+ isRandomize?: boolean;
1601
+ randomSeed?: string;
1602
+ };
1603
+ const conditionalHandleId = getConditionalInputHandleId(node.id);
1604
+ const itemsEdges = incomingEdges.filter(
1605
+ (e) =>
1606
+ e.sourceHandle !== conditionalHandleId &&
1607
+ getIsSliceAssetsItemsSourceHandle(node.id, e.sourceHandle),
1608
+ );
1609
+
1610
+ if (sliceData.isRandomize) {
1611
+ const { variables, flowInputs } = collectConcatVarsAndInputs(itemsEdges, ctx, getOutputHandleVarName);
1612
+ flowInputs.push(...collectConditionalConnectionInputs(incomingEdges, node.id, ctx));
1613
+
1614
+ const count = Math.max(1, parseInt(String(sliceData.count ?? ''), 10) || 1);
1615
+ const seed = parseInt(String(sliceData.randomSeed ?? ''), 10) || 0;
1616
+ const transform = `randomSample(${buildConcatArrayTransform(variables)}, ${count}, ${seed})`;
1617
+
1618
+ flow.push({
1619
+ id: flowId,
1620
+ type: 'transform',
1621
+ logic: { transform },
1622
+ inputs: flowInputs.length > 0 ? flowInputs : undefined,
1623
+ });
1570
1624
  } else {
1571
- const targetNode = nodes.find((n) => n.id === assetsEdge.target);
1572
- if (targetNode) {
1573
- const ref = getSourceRef(assetsEdge, ctx);
1574
- if (ref) {
1625
+ const assetsEdge = itemsEdges[0];
1626
+ if (!assetsEdge) {
1627
+ flow.push({ id: flowId, type: 'transform', logic: { transform: '[]' } });
1628
+ } else {
1629
+ const targetNode = nodes.find((n) => n.id === assetsEdge.target);
1630
+ const ref = targetNode ? getSourceRef(assetsEdge, ctx) : undefined;
1631
+ if (targetNode && ref) {
1575
1632
  const outHandle = targetNode.data.outputHandles?.find((h) => h.id === assetsEdge.targetHandle);
1576
1633
  const varName = getOutputHandleVarName(targetNode.id, outHandle?.name ?? 'output');
1577
- const sliceData = node.data as { from?: number | string; count?: number | string };
1578
1634
  const from = parseInt(String(sliceData.from ?? ''), 10) || 0;
1579
1635
  const count = parseInt(String(sliceData.count ?? ''), 10) || 0;
1580
1636
  const transform =