@pipelex/mthds-ui 0.9.0 → 0.11.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.
@@ -16,8 +16,10 @@ import {
16
16
  getPipeBlueprint,
17
17
  resolveConceptRef,
18
18
  stuffDigestFromId,
19
+ toolbarOrientation,
20
+ toolbarSide,
19
21
  validateGraphSpec
20
- } from "../../chunk-WNSV4E7G.js";
22
+ } from "../../chunk-R34J4GFM.js";
21
23
  import {
22
24
  __spreadProps,
23
25
  __spreadValues
@@ -823,9 +825,6 @@ function PipeLLMSection({
823
825
  )
824
826
  ] });
825
827
  }
826
- function LLMExecutionData(_props) {
827
- return null;
828
- }
829
828
 
830
829
  // src/graph/react/detail/sections/PipeImgGenDetail.tsx
831
830
  import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
@@ -870,9 +869,6 @@ function PipeImgGenSection({
870
869
  )
871
870
  ] });
872
871
  }
873
- function ImgGenExecutionData(_props) {
874
- return null;
875
- }
876
872
 
877
873
  // src/graph/react/detail/sections/PipeExtractDetail.tsx
878
874
  import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
@@ -893,9 +889,6 @@ function PipeExtractSection({
893
889
  /* @__PURE__ */ jsx6(KV, { label: "Image Variable", value: blueprint.image_stuff_name })
894
890
  ] });
895
891
  }
896
- function ExtractExecutionData(_props) {
897
- return null;
898
- }
899
892
 
900
893
  // src/graph/react/detail/sections/PipeSearchDetail.tsx
901
894
  import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
@@ -924,12 +917,46 @@ function PipeSearchSection({
924
917
  blueprint.exclude_domains && blueprint.exclude_domains.length > 0 && /* @__PURE__ */ jsx7(KV, { label: "Exclude Domains", value: blueprint.exclude_domains.join(", ") })
925
918
  ] });
926
919
  }
927
- function SearchExecutionData(_props) {
928
- return null;
920
+
921
+ // src/graph/react/detail/sections/llmChoice.ts
922
+ var LLM_CHOICE_LABEL_KEYS = ["model", "llm_handle", "handle", "llm_name", "name"];
923
+ function nonEmptyString(value) {
924
+ if (typeof value !== "string") return void 0;
925
+ const trimmed = value.trim();
926
+ return trimmed.length > 0 ? trimmed : void 0;
927
+ }
928
+ function labelFromLlmChoice(choice) {
929
+ if (typeof choice === "string") return nonEmptyString(choice);
930
+ if (choice && typeof choice === "object") {
931
+ for (const key of LLM_CHOICE_LABEL_KEYS) {
932
+ const label = nonEmptyString(choice[key]);
933
+ if (label) return label;
934
+ }
935
+ }
936
+ return void 0;
929
937
  }
930
938
 
931
- // src/graph/react/detail/sections/PipeComposeDetail.tsx
939
+ // src/graph/react/detail/sections/PipeStructureDetail.tsx
932
940
  import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
941
+ function PipeStructureSection({
942
+ blueprint,
943
+ executionData
944
+ }) {
945
+ const resolvedModel = executionData == null ? void 0 : executionData.resolved_model;
946
+ const isMultipleOutput = executionData == null ? void 0 : executionData.is_multiple_output;
947
+ const renderedUser = executionData == null ? void 0 : executionData.rendered_user_prompt;
948
+ const modelDisplay = resolvedModel || labelFromLlmChoice(blueprint.llm_choice);
949
+ return /* @__PURE__ */ jsxs8(Fragment5, { children: [
950
+ /* @__PURE__ */ jsx8(KV, { label: "Model", value: modelDisplay }),
951
+ /* @__PURE__ */ jsx8(KV, { label: "Text Variable", value: blueprint.text_input_name }),
952
+ /* @__PURE__ */ jsx8(KV, { label: "Multiple Output", value: isMultipleOutput }),
953
+ /* @__PURE__ */ jsx8(KV, { label: "Output Multiplicity", value: blueprint.output_multiplicity }),
954
+ /* @__PURE__ */ jsx8(PromptToggle, { label: "Prompt", templateText: void 0, renderedText: renderedUser })
955
+ ] });
956
+ }
957
+
958
+ // src/graph/react/detail/sections/PipeComposeDetail.tsx
959
+ import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
933
960
  function formatLeafField(field) {
934
961
  var _a, _b;
935
962
  switch (field.method) {
@@ -950,9 +977,9 @@ function isLongValue(text) {
950
977
  return text.length > LONG_VALUE_THRESHOLD_CHARS || text.includes("\n");
951
978
  }
952
979
  function FieldBlock({ label, value }) {
953
- return /* @__PURE__ */ jsxs8("div", { className: "detail-field-block", children: [
954
- /* @__PURE__ */ jsx8("div", { className: "detail-field-block-label", children: label }),
955
- /* @__PURE__ */ jsx8("div", { className: "detail-field-block-value", children: value })
980
+ return /* @__PURE__ */ jsxs9("div", { className: "detail-field-block", children: [
981
+ /* @__PURE__ */ jsx9("div", { className: "detail-field-block-label", children: label }),
982
+ /* @__PURE__ */ jsx9("div", { className: "detail-field-block-value", children: value })
956
983
  ] });
957
984
  }
958
985
  function ConstructFieldsBlock({
@@ -973,18 +1000,18 @@ function ConstructFieldsBlock({
973
1000
  }
974
1001
  }
975
1002
  const indentStyle = depth > 0 ? { paddingLeft: depth * 12 } : void 0;
976
- return /* @__PURE__ */ jsxs8(Fragment5, { children: [
1003
+ return /* @__PURE__ */ jsxs9(Fragment6, { children: [
977
1004
  leafFields.map(([name, field]) => {
978
1005
  const display = formatLeafField(field);
979
1006
  if (isLongValue(display)) {
980
- return /* @__PURE__ */ jsx8("div", { style: indentStyle, children: /* @__PURE__ */ jsx8(FieldBlock, { label: name, value: display }) }, name);
1007
+ return /* @__PURE__ */ jsx9("div", { style: indentStyle, children: /* @__PURE__ */ jsx9(FieldBlock, { label: name, value: display }) }, name);
981
1008
  }
982
- return /* @__PURE__ */ jsx8("div", { style: indentStyle, children: /* @__PURE__ */ jsx8(KV, { label: name, value: display }) }, name);
1009
+ return /* @__PURE__ */ jsx9("div", { style: indentStyle, children: /* @__PURE__ */ jsx9(KV, { label: name, value: display }) }, name);
983
1010
  }),
984
1011
  templateFields.map(([name, field]) => {
985
1012
  var _a, _b;
986
1013
  const renderedForField = (_a = fieldResolutions == null ? void 0 : fieldResolutions[name]) == null ? void 0 : _a.rendered;
987
- return /* @__PURE__ */ jsx8("div", { style: indentStyle, children: /* @__PURE__ */ jsx8(
1014
+ return /* @__PURE__ */ jsx9("div", { style: indentStyle, children: /* @__PURE__ */ jsx9(
988
1015
  PromptToggle,
989
1016
  {
990
1017
  label: `Template \u2014 ${name}`,
@@ -995,15 +1022,15 @@ function ConstructFieldsBlock({
995
1022
  }),
996
1023
  nestedFields.map(([name, field]) => {
997
1024
  if (!field.nested) return null;
998
- return /* @__PURE__ */ jsxs8("div", { children: [
999
- /* @__PURE__ */ jsxs8(
1025
+ return /* @__PURE__ */ jsxs9("div", { children: [
1026
+ /* @__PURE__ */ jsxs9(
1000
1027
  "div",
1001
1028
  {
1002
1029
  className: "detail-nested-header",
1003
1030
  style: depth > 0 ? { paddingLeft: depth * 12 } : void 0,
1004
1031
  children: [
1005
- /* @__PURE__ */ jsx8("span", { className: "detail-nested-header-name", children: name }),
1006
- /* @__PURE__ */ jsxs8("span", { className: "detail-nested-header-meta", children: [
1032
+ /* @__PURE__ */ jsx9("span", { className: "detail-nested-header-name", children: name }),
1033
+ /* @__PURE__ */ jsxs9("span", { className: "detail-nested-header-meta", children: [
1007
1034
  "nested \xB7 ",
1008
1035
  Object.keys(field.nested.fields).length,
1009
1036
  " field",
@@ -1012,7 +1039,7 @@ function ConstructFieldsBlock({
1012
1039
  ]
1013
1040
  }
1014
1041
  ),
1015
- /* @__PURE__ */ jsx8(
1042
+ /* @__PURE__ */ jsx9(
1016
1043
  ConstructFieldsBlock,
1017
1044
  {
1018
1045
  blueprint: field.nested,
@@ -1034,11 +1061,11 @@ function PipeComposeSection({
1034
1061
  const fieldResolutions = (_a = executionData == null ? void 0 : executionData.fields) != null ? _a : null;
1035
1062
  const constructBlueprint = blueprint.construct_blueprint;
1036
1063
  const hasConstruct = constructBlueprint !== null && Object.keys(constructBlueprint.fields).length > 0;
1037
- return /* @__PURE__ */ jsxs8(Fragment5, { children: [
1038
- /* @__PURE__ */ jsx8(KV, { label: "Mode", value: composeMode || (hasConstruct ? "construct" : "template") }),
1039
- /* @__PURE__ */ jsx8(KV, { label: "Category", value: blueprint.category }),
1040
- /* @__PURE__ */ jsx8(KV, { label: "Templating Style", value: blueprint.templating_style }),
1041
- blueprint.template && /* @__PURE__ */ jsx8(
1064
+ return /* @__PURE__ */ jsxs9(Fragment6, { children: [
1065
+ /* @__PURE__ */ jsx9(KV, { label: "Mode", value: composeMode || (hasConstruct ? "construct" : "template") }),
1066
+ /* @__PURE__ */ jsx9(KV, { label: "Category", value: blueprint.category }),
1067
+ /* @__PURE__ */ jsx9(KV, { label: "Templating Style", value: blueprint.templating_style }),
1068
+ blueprint.template && /* @__PURE__ */ jsx9(
1042
1069
  PromptToggle,
1043
1070
  {
1044
1071
  label: "Template",
@@ -1046,9 +1073,9 @@ function PipeComposeSection({
1046
1073
  renderedText
1047
1074
  }
1048
1075
  ),
1049
- hasConstruct && /* @__PURE__ */ jsxs8(Fragment5, { children: [
1050
- /* @__PURE__ */ jsx8("div", { className: "detail-section-label", children: "FIELDS" }),
1051
- /* @__PURE__ */ jsx8(
1076
+ hasConstruct && /* @__PURE__ */ jsxs9(Fragment6, { children: [
1077
+ /* @__PURE__ */ jsx9("div", { className: "detail-section-label", children: "FIELDS" }),
1078
+ /* @__PURE__ */ jsx9(
1052
1079
  ConstructFieldsBlock,
1053
1080
  {
1054
1081
  blueprint: constructBlueprint,
@@ -1059,31 +1086,28 @@ function PipeComposeSection({
1059
1086
  ] })
1060
1087
  ] });
1061
1088
  }
1062
- function ComposeExecutionData(_props) {
1063
- return null;
1064
- }
1065
1089
 
1066
1090
  // src/graph/react/detail/sections/PipeConditionDetail.tsx
1067
- import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1091
+ import { Fragment as Fragment7, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1068
1092
  function PipeConditionSection({
1069
1093
  blueprint,
1070
1094
  executionData
1071
1095
  }) {
1072
1096
  const evaluatedExpression = executionData == null ? void 0 : executionData.evaluated_expression;
1073
1097
  const selectedOutcome = executionData == null ? void 0 : executionData.selected_outcome;
1074
- return /* @__PURE__ */ jsxs9(Fragment6, { children: [
1075
- /* @__PURE__ */ jsx9(PromptBlock, { label: "Expression", text: blueprint.expression }),
1076
- evaluatedExpression && /* @__PURE__ */ jsx9(KV, { label: "Expression Result", value: evaluatedExpression }),
1077
- /* @__PURE__ */ jsxs9("div", { children: [
1078
- /* @__PURE__ */ jsx9("div", { className: "detail-section-label", children: "Outcomes" }),
1079
- Object.entries(blueprint.outcome_map).map(([outcome, pipeCode]) => /* @__PURE__ */ jsxs9(
1098
+ return /* @__PURE__ */ jsxs10(Fragment7, { children: [
1099
+ /* @__PURE__ */ jsx10(PromptBlock, { label: "Expression", text: blueprint.expression }),
1100
+ evaluatedExpression && /* @__PURE__ */ jsx10(KV, { label: "Expression Result", value: evaluatedExpression }),
1101
+ /* @__PURE__ */ jsxs10("div", { children: [
1102
+ /* @__PURE__ */ jsx10("div", { className: "detail-section-label", children: "Outcomes" }),
1103
+ Object.entries(blueprint.outcome_map).map(([outcome, pipeCode]) => /* @__PURE__ */ jsxs10(
1080
1104
  "div",
1081
1105
  {
1082
1106
  className: "detail-kv-row",
1083
1107
  style: selectedOutcome === pipeCode ? { background: "rgba(80,250,123,0.08)" } : void 0,
1084
1108
  children: [
1085
- /* @__PURE__ */ jsx9("span", { className: "detail-kv-key", children: outcome }),
1086
- /* @__PURE__ */ jsx9(
1109
+ /* @__PURE__ */ jsx10("span", { className: "detail-kv-key", children: outcome }),
1110
+ /* @__PURE__ */ jsx10(
1087
1111
  "span",
1088
1112
  {
1089
1113
  className: "detail-kv-value",
@@ -1095,83 +1119,89 @@ function PipeConditionSection({
1095
1119
  },
1096
1120
  outcome
1097
1121
  )),
1098
- /* @__PURE__ */ jsxs9("div", { className: "detail-kv-row", children: [
1099
- /* @__PURE__ */ jsx9("span", { className: "detail-kv-key", children: "default" }),
1100
- /* @__PURE__ */ jsx9("span", { className: "detail-kv-value", children: blueprint.default_outcome })
1122
+ /* @__PURE__ */ jsxs10("div", { className: "detail-kv-row", children: [
1123
+ /* @__PURE__ */ jsx10("span", { className: "detail-kv-key", children: "default" }),
1124
+ /* @__PURE__ */ jsx10("span", { className: "detail-kv-value", children: blueprint.default_outcome })
1101
1125
  ] })
1102
1126
  ] }),
1103
- /* @__PURE__ */ jsx9(KV, { label: "Alias Expression To", value: blueprint.add_alias_from_expression_to })
1127
+ /* @__PURE__ */ jsx10(KV, { label: "Alias Expression To", value: blueprint.add_alias_from_expression_to })
1104
1128
  ] });
1105
1129
  }
1106
- function ConditionExecutionData(_props) {
1107
- return null;
1108
- }
1109
1130
 
1110
1131
  // src/graph/react/detail/sections/PipeSequenceDetail.tsx
1111
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1132
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1112
1133
  function PipeSequenceSection({
1113
1134
  blueprint
1114
1135
  }) {
1115
- return /* @__PURE__ */ jsxs10("div", { children: [
1116
- /* @__PURE__ */ jsx10("div", { className: "detail-section-label", children: "Steps" }),
1117
- /* @__PURE__ */ jsx10("div", { className: "detail-steps-list", children: blueprint.sequential_sub_pipes.map((step, idx) => /* @__PURE__ */ jsxs10("div", { className: "detail-step-item", children: [
1118
- /* @__PURE__ */ jsx10("span", { className: "detail-step-index", children: idx + 1 }),
1119
- /* @__PURE__ */ jsx10("span", { className: "detail-step-code", children: step.pipe_code }),
1120
- step.output_name && /* @__PURE__ */ jsxs10("span", { className: "detail-io-concept", children: [
1136
+ return /* @__PURE__ */ jsxs11("div", { children: [
1137
+ /* @__PURE__ */ jsx11("div", { className: "detail-section-label", children: "Steps" }),
1138
+ /* @__PURE__ */ jsx11("div", { className: "detail-steps-list", children: blueprint.sequential_sub_pipes.map((step, idx) => /* @__PURE__ */ jsxs11("div", { className: "detail-step-item", children: [
1139
+ /* @__PURE__ */ jsx11("span", { className: "detail-step-index", children: idx + 1 }),
1140
+ /* @__PURE__ */ jsx11("span", { className: "detail-step-code", children: step.pipe_code }),
1141
+ step.output_name && /* @__PURE__ */ jsxs11("span", { className: "detail-io-concept", children: [
1121
1142
  "-> ",
1122
1143
  step.output_name
1123
1144
  ] })
1124
1145
  ] }, idx)) })
1125
1146
  ] });
1126
1147
  }
1127
- function SequenceExecutionData(_props) {
1128
- return null;
1129
- }
1130
1148
 
1131
1149
  // src/graph/react/detail/sections/PipeParallelDetail.tsx
1132
- import { Fragment as Fragment7, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1150
+ import { Fragment as Fragment8, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1133
1151
  function PipeParallelSection({
1134
1152
  blueprint
1135
1153
  }) {
1136
- return /* @__PURE__ */ jsxs11(Fragment7, { children: [
1137
- /* @__PURE__ */ jsxs11("div", { children: [
1138
- /* @__PURE__ */ jsx11("div", { className: "detail-section-label", children: "Branches" }),
1139
- /* @__PURE__ */ jsx11("div", { className: "detail-steps-list", children: blueprint.parallel_sub_pipes.map((branch, idx) => /* @__PURE__ */ jsxs11("div", { className: "detail-step-item", children: [
1140
- /* @__PURE__ */ jsx11("span", { className: "detail-step-code", children: branch.pipe_code }),
1141
- branch.output_name && /* @__PURE__ */ jsxs11("span", { className: "detail-io-concept", children: [
1154
+ return /* @__PURE__ */ jsxs12(Fragment8, { children: [
1155
+ /* @__PURE__ */ jsxs12("div", { children: [
1156
+ /* @__PURE__ */ jsx12("div", { className: "detail-section-label", children: "Branches" }),
1157
+ /* @__PURE__ */ jsx12("div", { className: "detail-steps-list", children: blueprint.parallel_sub_pipes.map((branch, idx) => /* @__PURE__ */ jsxs12("div", { className: "detail-step-item", children: [
1158
+ /* @__PURE__ */ jsx12("span", { className: "detail-step-code", children: branch.pipe_code }),
1159
+ branch.output_name && /* @__PURE__ */ jsxs12("span", { className: "detail-io-concept", children: [
1142
1160
  "-> ",
1143
1161
  branch.output_name
1144
1162
  ] })
1145
1163
  ] }, idx)) })
1146
1164
  ] }),
1147
- /* @__PURE__ */ jsx11(KV, { label: "Add Each Output", value: blueprint.add_each_output }),
1148
- /* @__PURE__ */ jsx11(KV, { label: "Combined Output", value: blueprint.combined_output })
1165
+ /* @__PURE__ */ jsx12(KV, { label: "Add Each Output", value: blueprint.add_each_output }),
1166
+ /* @__PURE__ */ jsx12(KV, { label: "Combined Output", value: blueprint.combined_output })
1149
1167
  ] });
1150
1168
  }
1151
- function ParallelExecutionData(_props) {
1152
- return null;
1153
- }
1154
1169
 
1155
1170
  // src/graph/react/detail/sections/PipeBatchDetail.tsx
1156
- import { Fragment as Fragment8, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1171
+ import { Fragment as Fragment9, jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
1157
1172
  function PipeBatchSection({
1158
1173
  blueprint,
1159
1174
  executionData
1160
1175
  }) {
1161
1176
  const itemCount = executionData == null ? void 0 : executionData.item_count;
1162
- return /* @__PURE__ */ jsxs12(Fragment8, { children: [
1163
- /* @__PURE__ */ jsx12(KV, { label: "Branch Pipe", value: blueprint.branch_pipe_code }),
1164
- /* @__PURE__ */ jsx12(KV, { label: "Input List Variable", value: blueprint.batch_params.input_list_stuff_name }),
1165
- /* @__PURE__ */ jsx12(KV, { label: "Input Item Variable", value: blueprint.batch_params.input_item_stuff_name }),
1166
- itemCount != null && /* @__PURE__ */ jsx12(KV, { label: "Items Processed", value: itemCount })
1177
+ return /* @__PURE__ */ jsxs13(Fragment9, { children: [
1178
+ /* @__PURE__ */ jsx13(KV, { label: "Branch Pipe", value: blueprint.branch_pipe_code }),
1179
+ /* @__PURE__ */ jsx13(KV, { label: "Input List Variable", value: blueprint.batch_params.input_list_stuff_name }),
1180
+ /* @__PURE__ */ jsx13(KV, { label: "Input Item Variable", value: blueprint.batch_params.input_item_stuff_name }),
1181
+ itemCount != null && /* @__PURE__ */ jsx13(KV, { label: "Items Processed", value: itemCount })
1167
1182
  ] });
1168
1183
  }
1169
- function BatchExecutionData(_props) {
1170
- return null;
1184
+
1185
+ // src/graph/react/detail/sections/executionData.ts
1186
+ var MERGED_EXECUTION_DATA_TYPES = /* @__PURE__ */ new Set([
1187
+ "PipeLLM",
1188
+ "PipeImgGen",
1189
+ "PipeExtract",
1190
+ "PipeSearch",
1191
+ "PipeStructure",
1192
+ "PipeCompose",
1193
+ "PipeSequence",
1194
+ "PipeParallel",
1195
+ "PipeCondition",
1196
+ "PipeBatch"
1197
+ ]);
1198
+ function shouldDumpExecutionData(pipeType, hasBlueprint) {
1199
+ if (MERGED_EXECUTION_DATA_TYPES.has(pipeType)) return !hasBlueprint;
1200
+ return true;
1171
1201
  }
1172
1202
 
1173
1203
  // src/graph/react/detail/PipeDetailPanel.tsx
1174
- import { Fragment as Fragment9, jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
1204
+ import { Fragment as Fragment10, jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
1175
1205
  var PIPE_TYPE_BADGES = {
1176
1206
  PipeLLM: "LLM",
1177
1207
  PipeExtract: "Extract",
@@ -1179,6 +1209,7 @@ var PIPE_TYPE_BADGES = {
1179
1209
  PipeImgGen: "ImgGen",
1180
1210
  PipeSearch: "Search",
1181
1211
  PipeFunc: "Func",
1212
+ PipeStructure: "Structure",
1182
1213
  PipeSignature: "Signature",
1183
1214
  PipeSequence: "Seq",
1184
1215
  PipeParallel: "Par",
@@ -1220,17 +1251,17 @@ function PipeDetailPanel({ node, spec, onConceptClick }) {
1220
1251
  const inputs = (_c = (_b = node.io) == null ? void 0 : _b.inputs) != null ? _c : [];
1221
1252
  const outputs = (_e = (_d = node.io) == null ? void 0 : _d.outputs) != null ? _e : [];
1222
1253
  const description = (_f = blueprint == null ? void 0 : blueprint.description) != null ? _f : node.description;
1223
- return /* @__PURE__ */ jsxs13(Fragment9, { children: [
1224
- /* @__PURE__ */ jsxs13("div", { className: "detail-sticky-header", children: [
1225
- /* @__PURE__ */ jsxs13("div", { className: "detail-header", children: [
1226
- /* @__PURE__ */ jsx13(
1254
+ return /* @__PURE__ */ jsxs14(Fragment10, { children: [
1255
+ /* @__PURE__ */ jsxs14("div", { className: "detail-sticky-header", children: [
1256
+ /* @__PURE__ */ jsxs14("div", { className: "detail-header", children: [
1257
+ /* @__PURE__ */ jsx14(
1227
1258
  "span",
1228
1259
  {
1229
1260
  className: `detail-badge ${isController ? "detail-badge--controller" : "detail-badge--operator"}`,
1230
1261
  children: badge
1231
1262
  }
1232
1263
  ),
1233
- /* @__PURE__ */ jsx13(
1264
+ /* @__PURE__ */ jsx14(
1234
1265
  "span",
1235
1266
  {
1236
1267
  className: `detail-pipe-code ${isController ? "detail-pipe-code--controller" : ""}`,
@@ -1238,56 +1269,63 @@ function PipeDetailPanel({ node, spec, onConceptClick }) {
1238
1269
  }
1239
1270
  )
1240
1271
  ] }),
1241
- /* @__PURE__ */ jsxs13("div", { className: "detail-status", children: [
1242
- /* @__PURE__ */ jsx13("span", { className: "detail-status-dot", style: { background: statusColor } }),
1243
- /* @__PURE__ */ jsx13("span", { className: "detail-status-label", style: { color: statusColor }, children: status }),
1244
- ((_g = node.timing) == null ? void 0 : _g.duration) != null && /* @__PURE__ */ jsx13("span", { className: "detail-duration", children: formatDuration(node.timing.duration) })
1272
+ /* @__PURE__ */ jsxs14("div", { className: "detail-status", children: [
1273
+ /* @__PURE__ */ jsx14("span", { className: "detail-status-dot", style: { background: statusColor } }),
1274
+ /* @__PURE__ */ jsx14("span", { className: "detail-status-label", style: { color: statusColor }, children: status }),
1275
+ ((_g = node.timing) == null ? void 0 : _g.duration) != null && /* @__PURE__ */ jsx14("span", { className: "detail-duration", children: formatDuration(node.timing.duration) })
1245
1276
  ] }),
1246
- description && /* @__PURE__ */ jsx13("div", { className: "detail-description", children: description }),
1247
- inputs.length > 0 && /* @__PURE__ */ jsxs13("div", { children: [
1248
- /* @__PURE__ */ jsx13("div", { className: "detail-section-label", children: "Inputs" }),
1249
- /* @__PURE__ */ jsx13("div", { className: "detail-io-list", children: inputs.map((input, idx) => /* @__PURE__ */ jsxs13(
1277
+ description && /* @__PURE__ */ jsx14("div", { className: "detail-description", children: description }),
1278
+ inputs.length > 0 && /* @__PURE__ */ jsxs14("div", { children: [
1279
+ /* @__PURE__ */ jsx14("div", { className: "detail-section-label", children: "Inputs" }),
1280
+ /* @__PURE__ */ jsx14("div", { className: "detail-io-list", children: inputs.map((input, idx) => /* @__PURE__ */ jsxs14(
1250
1281
  "div",
1251
1282
  {
1252
1283
  className: "detail-io-pill",
1253
1284
  style: { cursor: input.concept && onConceptClick ? "pointer" : void 0 },
1254
1285
  onClick: () => input.concept && (onConceptClick == null ? void 0 : onConceptClick(input.concept)),
1255
1286
  children: [
1256
- /* @__PURE__ */ jsx13("span", { className: "detail-io-name", children: input.name }),
1257
- input.concept && /* @__PURE__ */ jsx13("span", { className: "detail-io-concept", children: input.concept })
1287
+ /* @__PURE__ */ jsx14("span", { className: "detail-io-name", children: input.name }),
1288
+ input.concept && /* @__PURE__ */ jsx14("span", { className: "detail-io-concept", children: input.concept })
1258
1289
  ]
1259
1290
  },
1260
1291
  idx
1261
1292
  )) })
1262
1293
  ] }),
1263
- outputs.length > 0 && /* @__PURE__ */ jsxs13("div", { children: [
1264
- /* @__PURE__ */ jsx13("div", { className: "detail-section-label", children: "Output" }),
1265
- /* @__PURE__ */ jsx13("div", { className: "detail-io-list", children: outputs.map((output, idx) => /* @__PURE__ */ jsxs13(
1294
+ outputs.length > 0 && /* @__PURE__ */ jsxs14("div", { children: [
1295
+ /* @__PURE__ */ jsx14("div", { className: "detail-section-label", children: "Output" }),
1296
+ /* @__PURE__ */ jsx14("div", { className: "detail-io-list", children: outputs.map((output, idx) => /* @__PURE__ */ jsxs14(
1266
1297
  "div",
1267
1298
  {
1268
1299
  className: "detail-io-pill",
1269
1300
  style: { cursor: output.concept && onConceptClick ? "pointer" : void 0 },
1270
1301
  onClick: () => output.concept && (onConceptClick == null ? void 0 : onConceptClick(output.concept)),
1271
1302
  children: [
1272
- /* @__PURE__ */ jsx13("span", { className: "detail-io-name", children: output.name }),
1273
- output.concept && /* @__PURE__ */ jsx13("span", { className: "detail-io-concept", children: output.concept })
1303
+ /* @__PURE__ */ jsx14("span", { className: "detail-io-name", children: output.name }),
1304
+ output.concept && /* @__PURE__ */ jsx14("span", { className: "detail-io-concept", children: output.concept })
1274
1305
  ]
1275
1306
  },
1276
1307
  idx
1277
1308
  )) })
1278
1309
  ] }),
1279
- (inputs.length > 0 || outputs.length > 0) && /* @__PURE__ */ jsx13("div", { style: { borderTop: "1px solid rgba(255,255,255,0.06)", margin: "4px 0" } })
1310
+ (inputs.length > 0 || outputs.length > 0) && /* @__PURE__ */ jsx14("div", { style: { borderTop: "1px solid rgba(255,255,255,0.06)", margin: "4px 0" } })
1280
1311
  ] }),
1281
- blueprint && /* @__PURE__ */ jsx13(BlueprintSection, { blueprint, executionData: node.execution_data }),
1282
- node.execution_data && Object.keys(node.execution_data).length > 0 && /* @__PURE__ */ jsx13(ExecutionDataSection, { executionData: node.execution_data, pipeType }),
1283
- node.error && /* @__PURE__ */ jsxs13("div", { className: "detail-error", children: [
1284
- /* @__PURE__ */ jsx13("div", { className: "detail-error-type", children: node.error.error_type }),
1285
- /* @__PURE__ */ jsx13("div", { className: "detail-error-message", children: node.error.message }),
1286
- node.error.stack && /* @__PURE__ */ jsx13("div", { className: "detail-error-stack", children: node.error.stack })
1312
+ blueprint && /* @__PURE__ */ jsx14(BlueprintSection, { blueprint, executionData: node.execution_data }),
1313
+ node.execution_data && Object.keys(node.execution_data).length > 0 && /* @__PURE__ */ jsx14(
1314
+ ExecutionDataSection,
1315
+ {
1316
+ executionData: node.execution_data,
1317
+ pipeType,
1318
+ hasBlueprint: !!blueprint
1319
+ }
1320
+ ),
1321
+ node.error && /* @__PURE__ */ jsxs14("div", { className: "detail-error", children: [
1322
+ /* @__PURE__ */ jsx14("div", { className: "detail-error-type", children: node.error.error_type }),
1323
+ /* @__PURE__ */ jsx14("div", { className: "detail-error-message", children: node.error.message }),
1324
+ node.error.stack && /* @__PURE__ */ jsx14("div", { className: "detail-error-stack", children: node.error.stack })
1287
1325
  ] }),
1288
- node.metrics && Object.keys(node.metrics).length > 0 && /* @__PURE__ */ jsxs13("div", { children: [
1289
- /* @__PURE__ */ jsx13("div", { className: "detail-section-label", children: "Metrics" }),
1290
- Object.entries(node.metrics).map(([key, value]) => /* @__PURE__ */ jsx13(
1326
+ node.metrics && Object.keys(node.metrics).length > 0 && /* @__PURE__ */ jsxs14("div", { children: [
1327
+ /* @__PURE__ */ jsx14("div", { className: "detail-section-label", children: "Metrics" }),
1328
+ Object.entries(node.metrics).map(([key, value]) => /* @__PURE__ */ jsx14(
1291
1329
  KV,
1292
1330
  {
1293
1331
  label: key,
@@ -1296,17 +1334,17 @@ function PipeDetailPanel({ node, spec, onConceptClick }) {
1296
1334
  key
1297
1335
  ))
1298
1336
  ] }),
1299
- node.tags && Object.keys(node.tags).length > 0 && /* @__PURE__ */ jsxs13("div", { children: [
1300
- /* @__PURE__ */ jsx13("div", { className: "detail-section-label", children: "Tags" }),
1301
- /* @__PURE__ */ jsx13("div", { className: "detail-tags", children: Object.entries(node.tags).map(([key, value]) => /* @__PURE__ */ jsxs13("span", { className: "detail-tag", children: [
1302
- /* @__PURE__ */ jsxs13("span", { className: "detail-tag-key", children: [
1337
+ node.tags && Object.keys(node.tags).length > 0 && /* @__PURE__ */ jsxs14("div", { children: [
1338
+ /* @__PURE__ */ jsx14("div", { className: "detail-section-label", children: "Tags" }),
1339
+ /* @__PURE__ */ jsx14("div", { className: "detail-tags", children: Object.entries(node.tags).map(([key, value]) => /* @__PURE__ */ jsxs14("span", { className: "detail-tag", children: [
1340
+ /* @__PURE__ */ jsxs14("span", { className: "detail-tag-key", children: [
1303
1341
  key,
1304
1342
  ": "
1305
1343
  ] }),
1306
- /* @__PURE__ */ jsx13("span", { className: "detail-tag-value", children: value })
1344
+ /* @__PURE__ */ jsx14("span", { className: "detail-tag-value", children: value })
1307
1345
  ] }, key)) })
1308
1346
  ] }),
1309
- !blueprint && /* @__PURE__ */ jsx13("div", { className: "detail-not-available", children: "Blueprint not available" })
1347
+ !blueprint && /* @__PURE__ */ jsx14("div", { className: "detail-not-available", children: "Blueprint not available" })
1310
1348
  ] });
1311
1349
  }
1312
1350
  function BlueprintSection({
@@ -1315,70 +1353,53 @@ function BlueprintSection({
1315
1353
  }) {
1316
1354
  switch (blueprint.type) {
1317
1355
  case "PipeLLM":
1318
- return /* @__PURE__ */ jsx13(PipeLLMSection, { blueprint, executionData });
1356
+ return /* @__PURE__ */ jsx14(PipeLLMSection, { blueprint, executionData });
1319
1357
  case "PipeImgGen":
1320
- return /* @__PURE__ */ jsx13(PipeImgGenSection, { blueprint, executionData });
1358
+ return /* @__PURE__ */ jsx14(PipeImgGenSection, { blueprint, executionData });
1321
1359
  case "PipeCompose":
1322
- return /* @__PURE__ */ jsx13(PipeComposeSection, { blueprint, executionData });
1360
+ return /* @__PURE__ */ jsx14(PipeComposeSection, { blueprint, executionData });
1323
1361
  case "PipeExtract":
1324
- return /* @__PURE__ */ jsx13(PipeExtractSection, { blueprint, executionData });
1362
+ return /* @__PURE__ */ jsx14(PipeExtractSection, { blueprint, executionData });
1325
1363
  case "PipeSearch":
1326
- return /* @__PURE__ */ jsx13(PipeSearchSection, { blueprint, executionData });
1364
+ return /* @__PURE__ */ jsx14(PipeSearchSection, { blueprint, executionData });
1365
+ case "PipeStructure":
1366
+ return /* @__PURE__ */ jsx14(PipeStructureSection, { blueprint, executionData });
1327
1367
  case "PipeSequence":
1328
- return /* @__PURE__ */ jsx13(PipeSequenceSection, { blueprint, executionData });
1368
+ return /* @__PURE__ */ jsx14(PipeSequenceSection, { blueprint, executionData });
1329
1369
  case "PipeParallel":
1330
- return /* @__PURE__ */ jsx13(PipeParallelSection, { blueprint, executionData });
1370
+ return /* @__PURE__ */ jsx14(PipeParallelSection, { blueprint, executionData });
1331
1371
  case "PipeCondition":
1332
- return /* @__PURE__ */ jsx13(PipeConditionSection, { blueprint, executionData });
1372
+ return /* @__PURE__ */ jsx14(PipeConditionSection, { blueprint, executionData });
1333
1373
  case "PipeBatch":
1334
- return /* @__PURE__ */ jsx13(PipeBatchSection, { blueprint, executionData });
1374
+ return /* @__PURE__ */ jsx14(PipeBatchSection, { blueprint, executionData });
1335
1375
  case "PipeFunc":
1336
1376
  return null;
1337
1377
  case "PipeSignature":
1338
- return /* @__PURE__ */ jsx13("div", { className: "detail-not-available", children: "Signature stub \u2014 declared but not yet implemented." });
1378
+ return /* @__PURE__ */ jsx14("div", { className: "detail-not-available", children: "Signature stub \u2014 declared but not yet implemented." });
1339
1379
  default:
1340
1380
  return null;
1341
1381
  }
1342
1382
  }
1343
1383
  function ExecutionDataSection({
1344
1384
  executionData,
1345
- pipeType
1385
+ pipeType,
1386
+ hasBlueprint
1346
1387
  }) {
1347
- switch (pipeType) {
1348
- case "PipeLLM":
1349
- return /* @__PURE__ */ jsx13(LLMExecutionData, { data: executionData });
1350
- case "PipeImgGen":
1351
- return /* @__PURE__ */ jsx13(ImgGenExecutionData, { data: executionData });
1352
- case "PipeExtract":
1353
- return /* @__PURE__ */ jsx13(ExtractExecutionData, { data: executionData });
1354
- case "PipeSearch":
1355
- return /* @__PURE__ */ jsx13(SearchExecutionData, { data: executionData });
1356
- case "PipeCompose":
1357
- return /* @__PURE__ */ jsx13(ComposeExecutionData, { data: executionData });
1358
- case "PipeCondition":
1359
- return /* @__PURE__ */ jsx13(ConditionExecutionData, { data: executionData });
1360
- case "PipeSequence":
1361
- return /* @__PURE__ */ jsx13(SequenceExecutionData, { data: executionData });
1362
- case "PipeParallel":
1363
- return /* @__PURE__ */ jsx13(ParallelExecutionData, { data: executionData });
1364
- case "PipeBatch":
1365
- return /* @__PURE__ */ jsx13(BatchExecutionData, { data: executionData });
1366
- default:
1367
- return /* @__PURE__ */ jsx13(GenericExecutionData, { data: executionData });
1368
- }
1388
+ if (!shouldDumpExecutionData(pipeType, hasBlueprint)) return null;
1389
+ return /* @__PURE__ */ jsx14(GenericExecutionData, { data: executionData });
1369
1390
  }
1370
1391
  function GenericExecutionData({ data }) {
1371
1392
  const entries = Object.entries(data);
1372
1393
  if (entries.length === 0) return null;
1373
- return /* @__PURE__ */ jsxs13(Fragment9, { children: [
1374
- /* @__PURE__ */ jsx13("div", { className: "detail-section-label", children: "Execution" }),
1375
- entries.map(([key, value]) => /* @__PURE__ */ jsx13(KV, { label: key, value: String(value) }, key))
1394
+ return /* @__PURE__ */ jsxs14(Fragment10, { children: [
1395
+ /* @__PURE__ */ jsx14("div", { className: "detail-section-label", children: "Execution" }),
1396
+ entries.map(([key, value]) => /* @__PURE__ */ jsx14(KV, { label: key, value: String(value) }, key))
1376
1397
  ] });
1377
1398
  }
1378
1399
 
1379
1400
  // src/graph/react/detail/ConceptDetailPanel.tsx
1380
1401
  import React7 from "react";
1381
- import { Fragment as Fragment10, jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
1402
+ import { Fragment as Fragment11, jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
1382
1403
  function ConceptDetailPanel({
1383
1404
  concept,
1384
1405
  ioData,
@@ -1389,17 +1410,17 @@ function ConceptDetailPanel({
1389
1410
  instanceKey
1390
1411
  }) {
1391
1412
  var _a;
1392
- return /* @__PURE__ */ jsxs14(Fragment10, { children: [
1393
- /* @__PURE__ */ jsxs14("div", { className: "detail-header", children: [
1394
- /* @__PURE__ */ jsx14("span", { className: "detail-concept-code", children: concept.code }),
1395
- /* @__PURE__ */ jsx14("span", { className: "detail-concept-domain", children: concept.domain_code })
1413
+ return /* @__PURE__ */ jsxs15(Fragment11, { children: [
1414
+ /* @__PURE__ */ jsxs15("div", { className: "detail-header", children: [
1415
+ /* @__PURE__ */ jsx15("span", { className: "detail-concept-code", children: concept.code }),
1416
+ /* @__PURE__ */ jsx15("span", { className: "detail-concept-domain", children: concept.domain_code })
1396
1417
  ] }),
1397
- concept.description && /* @__PURE__ */ jsx14("div", { className: "detail-description", children: concept.description }),
1398
- concept.refines && /* @__PURE__ */ jsxs14("div", { className: "detail-refines", children: [
1418
+ concept.description && /* @__PURE__ */ jsx15("div", { className: "detail-description", children: concept.description }),
1419
+ concept.refines && /* @__PURE__ */ jsxs15("div", { className: "detail-refines", children: [
1399
1420
  "refines ",
1400
- /* @__PURE__ */ jsx14("span", { className: "detail-refines-code", children: concept.refines })
1421
+ /* @__PURE__ */ jsx15("span", { className: "detail-refines-code", children: concept.refines })
1401
1422
  ] }),
1402
- /* @__PURE__ */ jsx14(
1423
+ /* @__PURE__ */ jsx15(
1403
1424
  ConceptBody,
1404
1425
  {
1405
1426
  concept,
@@ -1426,10 +1447,10 @@ function ConceptBody({
1426
1447
  const baseId = React7.useId();
1427
1448
  const tabId = (tab) => `${baseId}-tab-${tab}`;
1428
1449
  const panelId = (tab) => `${baseId}-tabpanel-${tab}`;
1429
- const structure = concept.json_schema ? /* @__PURE__ */ jsxs14("div", { children: [
1430
- /* @__PURE__ */ jsx14("div", { className: "detail-section-label", children: "Structure" }),
1431
- /* @__PURE__ */ jsx14(SchemaTable, { schema: concept.json_schema, isDryRun })
1432
- ] }) : /* @__PURE__ */ jsx14("div", { className: "detail-not-available", children: "Schema not available" });
1450
+ const structure = concept.json_schema ? /* @__PURE__ */ jsxs15("div", { children: [
1451
+ /* @__PURE__ */ jsx15("div", { className: "detail-section-label", children: "Structure" }),
1452
+ /* @__PURE__ */ jsx15(SchemaTable, { schema: concept.json_schema, isDryRun })
1453
+ ] }) : /* @__PURE__ */ jsx15("div", { className: "detail-not-available", children: "Schema not available" });
1433
1454
  if (!hasData) return structure;
1434
1455
  const onTabKeyDown = (event) => {
1435
1456
  var _a;
@@ -1452,7 +1473,7 @@ function ConceptBody({
1452
1473
  setActiveTab(next);
1453
1474
  (_a = document.getElementById(tabId(next))) == null ? void 0 : _a.focus();
1454
1475
  };
1455
- const renderTab = (tab, label) => /* @__PURE__ */ jsx14(
1476
+ const renderTab = (tab, label) => /* @__PURE__ */ jsx15(
1456
1477
  "button",
1457
1478
  {
1458
1479
  type: "button",
@@ -1467,12 +1488,12 @@ function ConceptBody({
1467
1488
  children: label
1468
1489
  }
1469
1490
  );
1470
- return /* @__PURE__ */ jsxs14(Fragment10, { children: [
1471
- /* @__PURE__ */ jsxs14("div", { className: "detail-tabs", role: "tablist", "aria-label": "Concept views", children: [
1491
+ return /* @__PURE__ */ jsxs15(Fragment11, { children: [
1492
+ /* @__PURE__ */ jsxs15("div", { className: "detail-tabs", role: "tablist", "aria-label": "Concept views", children: [
1472
1493
  renderTab("data", "Data"),
1473
1494
  renderTab("structure", "Structure")
1474
1495
  ] }),
1475
- /* @__PURE__ */ jsx14("div", { role: "tabpanel", id: panelId(activeTab), "aria-labelledby": tabId(activeTab), children: activeTab === "data" ? /* @__PURE__ */ jsx14(
1496
+ /* @__PURE__ */ jsx15("div", { role: "tabpanel", id: panelId(activeTab), "aria-labelledby": tabId(activeTab), children: activeTab === "data" ? /* @__PURE__ */ jsx15(
1476
1497
  StuffViewer,
1477
1498
  {
1478
1499
  stuff: toStuffViewerData(ioData),
@@ -1491,42 +1512,43 @@ function SchemaTable({
1491
1512
  const properties = schema.properties;
1492
1513
  const required = new Set((_a = schema.required) != null ? _a : []);
1493
1514
  if (!properties || Object.keys(properties).length === 0) {
1494
- return /* @__PURE__ */ jsx14("div", { className: "detail-not-available", children: "No fields defined" });
1515
+ return /* @__PURE__ */ jsx15("div", { className: "detail-not-available", children: "No fields defined" });
1495
1516
  }
1496
1517
  const fields = Object.entries(properties);
1497
1518
  const visibleFields = isDryRun ? fields.filter(([name]) => required.has(name)) : fields;
1498
- return /* @__PURE__ */ jsxs14("table", { className: "detail-schema-table", children: [
1499
- /* @__PURE__ */ jsx14("thead", { children: /* @__PURE__ */ jsxs14("tr", { children: [
1500
- /* @__PURE__ */ jsx14("th", { children: "Field" }),
1501
- /* @__PURE__ */ jsx14("th", { children: "Type" }),
1502
- /* @__PURE__ */ jsx14("th", {}),
1503
- /* @__PURE__ */ jsx14("th", { children: "Description" })
1519
+ return /* @__PURE__ */ jsxs15("table", { className: "detail-schema-table", children: [
1520
+ /* @__PURE__ */ jsx15("thead", { children: /* @__PURE__ */ jsxs15("tr", { children: [
1521
+ /* @__PURE__ */ jsx15("th", { children: "Field" }),
1522
+ /* @__PURE__ */ jsx15("th", { children: "Type" }),
1523
+ /* @__PURE__ */ jsx15("th", {}),
1524
+ /* @__PURE__ */ jsx15("th", { children: "Description" })
1504
1525
  ] }) }),
1505
- /* @__PURE__ */ jsx14("tbody", { children: visibleFields.map(([fieldName, fieldSchema]) => {
1526
+ /* @__PURE__ */ jsx15("tbody", { children: visibleFields.map(([fieldName, fieldSchema]) => {
1506
1527
  var _a2;
1507
- return /* @__PURE__ */ jsxs14("tr", { children: [
1508
- /* @__PURE__ */ jsx14("td", { className: "detail-schema-field", children: fieldName }),
1509
- /* @__PURE__ */ jsx14("td", { className: "detail-schema-type", children: extractType(fieldSchema) }),
1510
- /* @__PURE__ */ jsx14("td", { children: required.has(fieldName) && /* @__PURE__ */ jsx14("span", { className: "detail-schema-required", children: "req" }) }),
1511
- /* @__PURE__ */ jsx14("td", { children: (_a2 = fieldSchema.description) != null ? _a2 : "" })
1528
+ return /* @__PURE__ */ jsxs15("tr", { children: [
1529
+ /* @__PURE__ */ jsx15("td", { className: "detail-schema-field", children: fieldName }),
1530
+ /* @__PURE__ */ jsx15("td", { className: "detail-schema-type", children: extractType(fieldSchema) }),
1531
+ /* @__PURE__ */ jsx15("td", { children: required.has(fieldName) && /* @__PURE__ */ jsx15("span", { className: "detail-schema-required", children: "req" }) }),
1532
+ /* @__PURE__ */ jsx15("td", { children: (_a2 = fieldSchema.description) != null ? _a2 : "" })
1512
1533
  ] }, fieldName);
1513
1534
  }) })
1514
1535
  ] });
1515
1536
  }
1516
1537
  function extractType(schema) {
1517
1538
  var _a;
1518
- if (schema.type) return String(schema.type);
1539
+ if (typeof schema.type === "string") return schema.type;
1540
+ if (Array.isArray(schema.type)) return schema.type.join(" | ");
1519
1541
  if (schema.anyOf) return "union";
1520
1542
  if (schema.allOf) return "all";
1521
- if (schema.$ref) {
1522
- const ref = String(schema.$ref);
1543
+ if (typeof schema.$ref === "string") {
1544
+ const ref = schema.$ref;
1523
1545
  return (_a = ref.split("/").pop()) != null ? _a : "(unresolved type)";
1524
1546
  }
1525
1547
  return "(unresolved type)";
1526
1548
  }
1527
1549
  function toStuffViewerData(ioData) {
1528
1550
  var _a;
1529
- if ("digest" in ioData) return ioData;
1551
+ if (isStuffViewerData(ioData)) return ioData;
1530
1552
  return {
1531
1553
  digest: (_a = ioData.digest) != null ? _a : "",
1532
1554
  name: ioData.name,
@@ -1537,6 +1559,9 @@ function toStuffViewerData(ioData) {
1537
1559
  dataHtml: ioData.data_html
1538
1560
  };
1539
1561
  }
1562
+ function isStuffViewerData(ioData) {
1563
+ return "contentType" in ioData || "dataText" in ioData || "dataHtml" in ioData;
1564
+ }
1540
1565
 
1541
1566
  // src/graph/react/rfTypes.ts
1542
1567
  function toAppNodes(nodes) {
@@ -1571,10 +1596,10 @@ function toAppEdges(edges) {
1571
1596
  }
1572
1597
 
1573
1598
  // src/graph/react/viewer/renderLabel.tsx
1574
- import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
1599
+ import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
1575
1600
  function renderLabel(desc) {
1576
1601
  if (desc.kind === "pipe") {
1577
- return /* @__PURE__ */ jsx15(
1602
+ return /* @__PURE__ */ jsx16(
1578
1603
  "div",
1579
1604
  {
1580
1605
  style: {
@@ -1588,7 +1613,7 @@ function renderLabel(desc) {
1588
1613
  minWidth: 0
1589
1614
  },
1590
1615
  title: desc.label,
1591
- children: /* @__PURE__ */ jsx15(
1616
+ children: /* @__PURE__ */ jsx16(
1592
1617
  "span",
1593
1618
  {
1594
1619
  style: {
@@ -1607,7 +1632,7 @@ function renderLabel(desc) {
1607
1632
  }
1608
1633
  );
1609
1634
  }
1610
- return /* @__PURE__ */ jsxs15(
1635
+ return /* @__PURE__ */ jsxs16(
1611
1636
  "div",
1612
1637
  {
1613
1638
  style: {
@@ -1623,7 +1648,7 @@ function renderLabel(desc) {
1623
1648
  },
1624
1649
  title: desc.concept ? `${desc.label}: ${desc.concept}` : desc.label,
1625
1650
  children: [
1626
- /* @__PURE__ */ jsx15(
1651
+ /* @__PURE__ */ jsx16(
1627
1652
  "span",
1628
1653
  {
1629
1654
  style: {
@@ -1639,7 +1664,7 @@ function renderLabel(desc) {
1639
1664
  children: desc.label
1640
1665
  }
1641
1666
  ),
1642
- desc.concept && /* @__PURE__ */ jsx15(
1667
+ desc.concept && /* @__PURE__ */ jsx16(
1643
1668
  "span",
1644
1669
  {
1645
1670
  style: {
@@ -1669,8 +1694,10 @@ function hydrateLabels(nodes) {
1669
1694
  }
1670
1695
 
1671
1696
  // src/graph/react/viewer/GraphToolbar.tsx
1672
- import { Fragment as Fragment11, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
1673
- var ARROW_RIGHT_ICON = /* @__PURE__ */ jsxs16(
1697
+ import { Panel } from "@xyflow/react";
1698
+ import { Fragment as Fragment12, jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
1699
+ var REACTFLOW_PANEL_MARGIN = 15;
1700
+ var ARROW_RIGHT_ICON = /* @__PURE__ */ jsxs17(
1674
1701
  "svg",
1675
1702
  {
1676
1703
  viewBox: "0 0 24 24",
@@ -1682,12 +1709,12 @@ var ARROW_RIGHT_ICON = /* @__PURE__ */ jsxs16(
1682
1709
  strokeLinecap: "round",
1683
1710
  strokeLinejoin: "round",
1684
1711
  children: [
1685
- /* @__PURE__ */ jsx16("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
1686
- /* @__PURE__ */ jsx16("polyline", { points: "12 5 19 12 12 19" })
1712
+ /* @__PURE__ */ jsx17("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
1713
+ /* @__PURE__ */ jsx17("polyline", { points: "12 5 19 12 12 19" })
1687
1714
  ]
1688
1715
  }
1689
1716
  );
1690
- var ARROW_DOWN_ICON = /* @__PURE__ */ jsxs16(
1717
+ var ARROW_DOWN_ICON = /* @__PURE__ */ jsxs17(
1691
1718
  "svg",
1692
1719
  {
1693
1720
  viewBox: "0 0 24 24",
@@ -1699,12 +1726,12 @@ var ARROW_DOWN_ICON = /* @__PURE__ */ jsxs16(
1699
1726
  strokeLinecap: "round",
1700
1727
  strokeLinejoin: "round",
1701
1728
  children: [
1702
- /* @__PURE__ */ jsx16("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
1703
- /* @__PURE__ */ jsx16("polyline", { points: "19 12 12 19 5 12" })
1729
+ /* @__PURE__ */ jsx17("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
1730
+ /* @__PURE__ */ jsx17("polyline", { points: "19 12 12 19 5 12" })
1704
1731
  ]
1705
1732
  }
1706
1733
  );
1707
- var MINUS_ICON = /* @__PURE__ */ jsx16(
1734
+ var MINUS_ICON = /* @__PURE__ */ jsx17(
1708
1735
  "svg",
1709
1736
  {
1710
1737
  viewBox: "0 0 24 24",
@@ -1715,10 +1742,10 @@ var MINUS_ICON = /* @__PURE__ */ jsx16(
1715
1742
  strokeWidth: "2",
1716
1743
  strokeLinecap: "round",
1717
1744
  strokeLinejoin: "round",
1718
- children: /* @__PURE__ */ jsx16("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
1745
+ children: /* @__PURE__ */ jsx17("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
1719
1746
  }
1720
1747
  );
1721
- var PLUS_ICON = /* @__PURE__ */ jsxs16(
1748
+ var PLUS_ICON = /* @__PURE__ */ jsxs17(
1722
1749
  "svg",
1723
1750
  {
1724
1751
  viewBox: "0 0 24 24",
@@ -1730,12 +1757,12 @@ var PLUS_ICON = /* @__PURE__ */ jsxs16(
1730
1757
  strokeLinecap: "round",
1731
1758
  strokeLinejoin: "round",
1732
1759
  children: [
1733
- /* @__PURE__ */ jsx16("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
1734
- /* @__PURE__ */ jsx16("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
1760
+ /* @__PURE__ */ jsx17("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
1761
+ /* @__PURE__ */ jsx17("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
1735
1762
  ]
1736
1763
  }
1737
1764
  );
1738
- var FIT_VIEW_ICON = /* @__PURE__ */ jsxs16(
1765
+ var FIT_VIEW_ICON = /* @__PURE__ */ jsxs17(
1739
1766
  "svg",
1740
1767
  {
1741
1768
  viewBox: "0 0 24 24",
@@ -1747,14 +1774,14 @@ var FIT_VIEW_ICON = /* @__PURE__ */ jsxs16(
1747
1774
  strokeLinecap: "round",
1748
1775
  strokeLinejoin: "round",
1749
1776
  children: [
1750
- /* @__PURE__ */ jsx16("polyline", { points: "15 3 21 3 21 9" }),
1751
- /* @__PURE__ */ jsx16("polyline", { points: "9 21 3 21 3 15" }),
1752
- /* @__PURE__ */ jsx16("line", { x1: "21", y1: "3", x2: "14", y2: "10" }),
1753
- /* @__PURE__ */ jsx16("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
1777
+ /* @__PURE__ */ jsx17("polyline", { points: "15 3 21 3 21 9" }),
1778
+ /* @__PURE__ */ jsx17("polyline", { points: "9 21 3 21 3 15" }),
1779
+ /* @__PURE__ */ jsx17("line", { x1: "21", y1: "3", x2: "14", y2: "10" }),
1780
+ /* @__PURE__ */ jsx17("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
1754
1781
  ]
1755
1782
  }
1756
1783
  );
1757
- var BOXES_ICON = /* @__PURE__ */ jsxs16(
1784
+ var BOXES_ICON = /* @__PURE__ */ jsxs17(
1758
1785
  "svg",
1759
1786
  {
1760
1787
  viewBox: "0 0 24 24",
@@ -1766,22 +1793,22 @@ var BOXES_ICON = /* @__PURE__ */ jsxs16(
1766
1793
  strokeLinecap: "round",
1767
1794
  strokeLinejoin: "round",
1768
1795
  children: [
1769
- /* @__PURE__ */ jsx16("path", { d: "M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" }),
1770
- /* @__PURE__ */ jsx16("path", { d: "m7 16.5-4.74-2.85" }),
1771
- /* @__PURE__ */ jsx16("path", { d: "m7 16.5 5-3" }),
1772
- /* @__PURE__ */ jsx16("path", { d: "M7 16.5v5.17" }),
1773
- /* @__PURE__ */ jsx16("path", { d: "M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" }),
1774
- /* @__PURE__ */ jsx16("path", { d: "m17 16.5-5-3" }),
1775
- /* @__PURE__ */ jsx16("path", { d: "m17 16.5 4.74-2.85" }),
1776
- /* @__PURE__ */ jsx16("path", { d: "M17 16.5v5.17" }),
1777
- /* @__PURE__ */ jsx16("path", { d: "M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" }),
1778
- /* @__PURE__ */ jsx16("path", { d: "M12 8 7.26 5.15" }),
1779
- /* @__PURE__ */ jsx16("path", { d: "m12 8 4.74-2.85" }),
1780
- /* @__PURE__ */ jsx16("path", { d: "M12 13.5V8" })
1796
+ /* @__PURE__ */ jsx17("path", { d: "M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" }),
1797
+ /* @__PURE__ */ jsx17("path", { d: "m7 16.5-4.74-2.85" }),
1798
+ /* @__PURE__ */ jsx17("path", { d: "m7 16.5 5-3" }),
1799
+ /* @__PURE__ */ jsx17("path", { d: "M7 16.5v5.17" }),
1800
+ /* @__PURE__ */ jsx17("path", { d: "M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" }),
1801
+ /* @__PURE__ */ jsx17("path", { d: "m17 16.5-5-3" }),
1802
+ /* @__PURE__ */ jsx17("path", { d: "m17 16.5 4.74-2.85" }),
1803
+ /* @__PURE__ */ jsx17("path", { d: "M17 16.5v5.17" }),
1804
+ /* @__PURE__ */ jsx17("path", { d: "M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" }),
1805
+ /* @__PURE__ */ jsx17("path", { d: "M12 8 7.26 5.15" }),
1806
+ /* @__PURE__ */ jsx17("path", { d: "m12 8 4.74-2.85" }),
1807
+ /* @__PURE__ */ jsx17("path", { d: "M12 13.5V8" })
1781
1808
  ]
1782
1809
  }
1783
1810
  );
1784
- var FOLD_ALL_ICON = /* @__PURE__ */ jsxs16(
1811
+ var FOLD_ALL_ICON = /* @__PURE__ */ jsxs17(
1785
1812
  "svg",
1786
1813
  {
1787
1814
  viewBox: "0 0 24 24",
@@ -1793,15 +1820,15 @@ var FOLD_ALL_ICON = /* @__PURE__ */ jsxs16(
1793
1820
  strokeLinecap: "round",
1794
1821
  strokeLinejoin: "round",
1795
1822
  children: [
1796
- /* @__PURE__ */ jsx16("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2" }),
1797
- /* @__PURE__ */ jsx16("polyline", { points: "2 2 6 6 2 6" }),
1798
- /* @__PURE__ */ jsx16("polyline", { points: "22 2 18 6 22 6" }),
1799
- /* @__PURE__ */ jsx16("polyline", { points: "2 22 6 18 2 18" }),
1800
- /* @__PURE__ */ jsx16("polyline", { points: "22 22 18 18 22 18" })
1823
+ /* @__PURE__ */ jsx17("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2" }),
1824
+ /* @__PURE__ */ jsx17("polyline", { points: "2 2 6 6 2 6" }),
1825
+ /* @__PURE__ */ jsx17("polyline", { points: "22 2 18 6 22 6" }),
1826
+ /* @__PURE__ */ jsx17("polyline", { points: "2 22 6 18 2 18" }),
1827
+ /* @__PURE__ */ jsx17("polyline", { points: "22 22 18 18 22 18" })
1801
1828
  ]
1802
1829
  }
1803
1830
  );
1804
- var EXPAND_ALL_ICON = /* @__PURE__ */ jsxs16(
1831
+ var EXPAND_ALL_ICON = /* @__PURE__ */ jsxs17(
1805
1832
  "svg",
1806
1833
  {
1807
1834
  viewBox: "0 0 24 24",
@@ -1813,15 +1840,15 @@ var EXPAND_ALL_ICON = /* @__PURE__ */ jsxs16(
1813
1840
  strokeLinecap: "round",
1814
1841
  strokeLinejoin: "round",
1815
1842
  children: [
1816
- /* @__PURE__ */ jsx16("rect", { x: "9", y: "9", width: "6", height: "6", rx: "1" }),
1817
- /* @__PURE__ */ jsx16("polyline", { points: "3 3 7 7 3 7" }),
1818
- /* @__PURE__ */ jsx16("polyline", { points: "21 3 17 7 21 7" }),
1819
- /* @__PURE__ */ jsx16("polyline", { points: "3 21 7 17 3 17" }),
1820
- /* @__PURE__ */ jsx16("polyline", { points: "21 21 17 17 21 17" })
1843
+ /* @__PURE__ */ jsx17("rect", { x: "9", y: "9", width: "6", height: "6", rx: "1" }),
1844
+ /* @__PURE__ */ jsx17("polyline", { points: "3 3 7 7 3 7" }),
1845
+ /* @__PURE__ */ jsx17("polyline", { points: "21 3 17 7 21 7" }),
1846
+ /* @__PURE__ */ jsx17("polyline", { points: "3 21 7 17 3 17" }),
1847
+ /* @__PURE__ */ jsx17("polyline", { points: "21 21 17 17 21 17" })
1821
1848
  ]
1822
1849
  }
1823
1850
  );
1824
- var SUN_ICON = /* @__PURE__ */ jsxs16(
1851
+ var SUN_ICON = /* @__PURE__ */ jsxs17(
1825
1852
  "svg",
1826
1853
  {
1827
1854
  viewBox: "0 0 24 24",
@@ -1833,19 +1860,19 @@ var SUN_ICON = /* @__PURE__ */ jsxs16(
1833
1860
  strokeLinecap: "round",
1834
1861
  strokeLinejoin: "round",
1835
1862
  children: [
1836
- /* @__PURE__ */ jsx16("circle", { cx: "12", cy: "12", r: "4" }),
1837
- /* @__PURE__ */ jsx16("line", { x1: "12", y1: "2", x2: "12", y2: "4" }),
1838
- /* @__PURE__ */ jsx16("line", { x1: "12", y1: "20", x2: "12", y2: "22" }),
1839
- /* @__PURE__ */ jsx16("line", { x1: "4.93", y1: "4.93", x2: "6.34", y2: "6.34" }),
1840
- /* @__PURE__ */ jsx16("line", { x1: "17.66", y1: "17.66", x2: "19.07", y2: "19.07" }),
1841
- /* @__PURE__ */ jsx16("line", { x1: "2", y1: "12", x2: "4", y2: "12" }),
1842
- /* @__PURE__ */ jsx16("line", { x1: "20", y1: "12", x2: "22", y2: "12" }),
1843
- /* @__PURE__ */ jsx16("line", { x1: "4.93", y1: "19.07", x2: "6.34", y2: "17.66" }),
1844
- /* @__PURE__ */ jsx16("line", { x1: "17.66", y1: "6.34", x2: "19.07", y2: "4.93" })
1863
+ /* @__PURE__ */ jsx17("circle", { cx: "12", cy: "12", r: "4" }),
1864
+ /* @__PURE__ */ jsx17("line", { x1: "12", y1: "2", x2: "12", y2: "4" }),
1865
+ /* @__PURE__ */ jsx17("line", { x1: "12", y1: "20", x2: "12", y2: "22" }),
1866
+ /* @__PURE__ */ jsx17("line", { x1: "4.93", y1: "4.93", x2: "6.34", y2: "6.34" }),
1867
+ /* @__PURE__ */ jsx17("line", { x1: "17.66", y1: "17.66", x2: "19.07", y2: "19.07" }),
1868
+ /* @__PURE__ */ jsx17("line", { x1: "2", y1: "12", x2: "4", y2: "12" }),
1869
+ /* @__PURE__ */ jsx17("line", { x1: "20", y1: "12", x2: "22", y2: "12" }),
1870
+ /* @__PURE__ */ jsx17("line", { x1: "4.93", y1: "19.07", x2: "6.34", y2: "17.66" }),
1871
+ /* @__PURE__ */ jsx17("line", { x1: "17.66", y1: "6.34", x2: "19.07", y2: "4.93" })
1845
1872
  ]
1846
1873
  }
1847
1874
  );
1848
- var MOON_ICON = /* @__PURE__ */ jsx16(
1875
+ var MOON_ICON = /* @__PURE__ */ jsx17(
1849
1876
  "svg",
1850
1877
  {
1851
1878
  viewBox: "0 0 24 24",
@@ -1856,10 +1883,10 @@ var MOON_ICON = /* @__PURE__ */ jsx16(
1856
1883
  strokeWidth: "2",
1857
1884
  strokeLinecap: "round",
1858
1885
  strokeLinejoin: "round",
1859
- children: /* @__PURE__ */ jsx16("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })
1886
+ children: /* @__PURE__ */ jsx17("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })
1860
1887
  }
1861
1888
  );
1862
- var MONITOR_ICON = /* @__PURE__ */ jsxs16(
1889
+ var MONITOR_ICON = /* @__PURE__ */ jsxs17(
1863
1890
  "svg",
1864
1891
  {
1865
1892
  viewBox: "0 0 24 24",
@@ -1871,9 +1898,9 @@ var MONITOR_ICON = /* @__PURE__ */ jsxs16(
1871
1898
  strokeLinecap: "round",
1872
1899
  strokeLinejoin: "round",
1873
1900
  children: [
1874
- /* @__PURE__ */ jsx16("rect", { x: "2", y: "3", width: "20", height: "14", rx: "2" }),
1875
- /* @__PURE__ */ jsx16("line", { x1: "8", y1: "21", x2: "16", y2: "21" }),
1876
- /* @__PURE__ */ jsx16("line", { x1: "12", y1: "17", x2: "12", y2: "21" })
1901
+ /* @__PURE__ */ jsx17("rect", { x: "2", y: "3", width: "20", height: "14", rx: "2" }),
1902
+ /* @__PURE__ */ jsx17("line", { x1: "8", y1: "21", x2: "16", y2: "21" }),
1903
+ /* @__PURE__ */ jsx17("line", { x1: "12", y1: "17", x2: "12", y2: "21" })
1877
1904
  ]
1878
1905
  }
1879
1906
  );
@@ -1914,17 +1941,21 @@ function GraphToolbar({
1914
1941
  expandAllDisabled = false,
1915
1942
  themeMode,
1916
1943
  onThemeModeChange,
1917
- rightOffset = 0
1944
+ rightOffset = 0,
1945
+ position
1918
1946
  }) {
1919
1947
  const themeToggleEnabled = themeMode !== void 0 && onThemeModeChange !== void 0;
1948
+ const orientation = toolbarOrientation(position);
1949
+ const dodgesDetailPanel = toolbarSide(position) === "right" && rightOffset > 0;
1950
+ const panelStyle = dodgesDetailPanel ? { marginRight: REACTFLOW_PANEL_MARGIN + rightOffset } : void 0;
1920
1951
  const isVertical = direction === GRAPH_DIRECTION.TB || direction === GRAPH_DIRECTION.BT;
1921
1952
  const directionLabel = isVertical ? "Switch to horizontal layout" : "Switch to vertical layout";
1922
1953
  const controllersLabel = showControllers ? "Hide pipe controllers" : "Show pipe controllers \u2014 groups pipes by their controlling pipe";
1923
1954
  const foldAllSection = onFoldAll || onExpandAll;
1924
1955
  const foldAllTitle = foldAllDisabled ? "Fold all controllers (nothing to fold)" : "Fold all controllers";
1925
1956
  const expandAllTitle = expandAllDisabled ? "Expand all controllers (nothing to expand)" : "Expand all controllers";
1926
- return /* @__PURE__ */ jsxs16("div", { className: "graph-toolbar", style: { right: `${rightOffset + 8}px` }, children: [
1927
- onFoldAll && /* @__PURE__ */ jsx16(
1957
+ return /* @__PURE__ */ jsx17(Panel, { position, className: "graph-toolbar-panel", style: panelStyle, children: /* @__PURE__ */ jsxs17("div", { className: `graph-toolbar graph-toolbar--${orientation}`, children: [
1958
+ onFoldAll && /* @__PURE__ */ jsx17(
1928
1959
  "button",
1929
1960
  {
1930
1961
  type: "button",
@@ -1936,7 +1967,7 @@ function GraphToolbar({
1936
1967
  children: FOLD_ALL_ICON
1937
1968
  }
1938
1969
  ),
1939
- onExpandAll && /* @__PURE__ */ jsx16(
1970
+ onExpandAll && /* @__PURE__ */ jsx17(
1940
1971
  "button",
1941
1972
  {
1942
1973
  type: "button",
@@ -1948,8 +1979,8 @@ function GraphToolbar({
1948
1979
  children: EXPAND_ALL_ICON
1949
1980
  }
1950
1981
  ),
1951
- foldAllSection && /* @__PURE__ */ jsx16("div", { className: "graph-toolbar-separator" }),
1952
- /* @__PURE__ */ jsx16(
1982
+ foldAllSection && /* @__PURE__ */ jsx17("div", { className: "graph-toolbar-separator" }),
1983
+ /* @__PURE__ */ jsx17(
1953
1984
  "button",
1954
1985
  {
1955
1986
  type: "button",
@@ -1960,7 +1991,7 @@ function GraphToolbar({
1960
1991
  children: BOXES_ICON
1961
1992
  }
1962
1993
  ),
1963
- /* @__PURE__ */ jsx16(
1994
+ /* @__PURE__ */ jsx17(
1964
1995
  "button",
1965
1996
  {
1966
1997
  type: "button",
@@ -1971,8 +2002,8 @@ function GraphToolbar({
1971
2002
  children: isVertical ? ARROW_RIGHT_ICON : ARROW_DOWN_ICON
1972
2003
  }
1973
2004
  ),
1974
- (onZoomOut || onZoomIn || onFitView) && /* @__PURE__ */ jsx16("div", { className: "graph-toolbar-separator" }),
1975
- onZoomOut && /* @__PURE__ */ jsx16(
2005
+ (onZoomOut || onZoomIn || onFitView) && /* @__PURE__ */ jsx17("div", { className: "graph-toolbar-separator" }),
2006
+ onZoomOut && /* @__PURE__ */ jsx17(
1976
2007
  "button",
1977
2008
  {
1978
2009
  type: "button",
@@ -1983,7 +2014,7 @@ function GraphToolbar({
1983
2014
  children: MINUS_ICON
1984
2015
  }
1985
2016
  ),
1986
- onZoomIn && /* @__PURE__ */ jsx16(
2017
+ onZoomIn && /* @__PURE__ */ jsx17(
1987
2018
  "button",
1988
2019
  {
1989
2020
  type: "button",
@@ -1994,7 +2025,7 @@ function GraphToolbar({
1994
2025
  children: PLUS_ICON
1995
2026
  }
1996
2027
  ),
1997
- onFitView && /* @__PURE__ */ jsx16(
2028
+ onFitView && /* @__PURE__ */ jsx17(
1998
2029
  "button",
1999
2030
  {
2000
2031
  type: "button",
@@ -2005,9 +2036,9 @@ function GraphToolbar({
2005
2036
  children: FIT_VIEW_ICON
2006
2037
  }
2007
2038
  ),
2008
- themeToggleEnabled && /* @__PURE__ */ jsxs16(Fragment11, { children: [
2009
- /* @__PURE__ */ jsx16("div", { className: "graph-toolbar-separator" }),
2010
- /* @__PURE__ */ jsx16(
2039
+ themeToggleEnabled && /* @__PURE__ */ jsxs17(Fragment12, { children: [
2040
+ /* @__PURE__ */ jsx17("div", { className: "graph-toolbar-separator" }),
2041
+ /* @__PURE__ */ jsx17(
2011
2042
  "button",
2012
2043
  {
2013
2044
  type: "button",
@@ -2019,11 +2050,11 @@ function GraphToolbar({
2019
2050
  }
2020
2051
  )
2021
2052
  ] })
2022
- ] });
2053
+ ] }) });
2023
2054
  }
2024
2055
 
2025
2056
  // src/graph/react/nodes/controller/ControllerGroupNode.tsx
2026
- import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
2057
+ import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
2027
2058
  var CONTROLLER_CONFIG = {
2028
2059
  PipeSequence: { badge: "Sequence", icon: "\u2192" },
2029
2060
  PipeParallel: { badge: "Parallel", icon: "//" },
@@ -2045,12 +2076,12 @@ function ControllerGroupNode({ data }) {
2045
2076
  const modifier = getControllerModifier(data.pipeType);
2046
2077
  const isCollapsible = (data.pipeType === "PipeParallel" || data.pipeType === "PipeBatch") && ((_a = data.childCount) != null ? _a : 0) > MAX_VISIBLE_CONTROLLER_CHILDREN;
2047
2078
  const hiddenCount = isCollapsible ? ((_b = data.childCount) != null ? _b : 0) - MAX_VISIBLE_CONTROLLER_CHILDREN : 0;
2048
- return /* @__PURE__ */ jsxs17("div", { className: `controller-group-node ${modifier}`, children: [
2049
- /* @__PURE__ */ jsxs17("div", { className: "controller-group-header", children: [
2050
- /* @__PURE__ */ jsx17("span", { className: "controller-group-icon", children: config.icon }),
2051
- /* @__PURE__ */ jsx17("span", { className: "controller-group-badge", children: config.badge }),
2052
- data.label && /* @__PURE__ */ jsx17("span", { className: "controller-group-label", children: data.label }),
2053
- data.onToggleFold && /* @__PURE__ */ jsx17(
2079
+ return /* @__PURE__ */ jsxs18("div", { className: `controller-group-node ${modifier}`, children: [
2080
+ /* @__PURE__ */ jsxs18("div", { className: "controller-group-header", children: [
2081
+ /* @__PURE__ */ jsx18("span", { className: "controller-group-icon", children: config.icon }),
2082
+ /* @__PURE__ */ jsx18("span", { className: "controller-group-badge", children: config.badge }),
2083
+ data.label && /* @__PURE__ */ jsx18("span", { className: "controller-group-label", children: data.label }),
2084
+ data.onToggleFold && /* @__PURE__ */ jsx18(
2054
2085
  "button",
2055
2086
  {
2056
2087
  type: "button",
@@ -2066,7 +2097,7 @@ function ControllerGroupNode({ data }) {
2066
2097
  }
2067
2098
  )
2068
2099
  ] }),
2069
- isCollapsible && /* @__PURE__ */ jsx17(
2100
+ isCollapsible && /* @__PURE__ */ jsx18(
2070
2101
  "button",
2071
2102
  {
2072
2103
  className: "controller-group-collapse",
@@ -2087,7 +2118,7 @@ import { Handle, Position } from "@xyflow/react";
2087
2118
 
2088
2119
  // src/graph/react/nodes/pipe/PipeCardBase.tsx
2089
2120
  import { useState as useState2 } from "react";
2090
- import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
2121
+ import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
2091
2122
  var PIPE_TYPE_BADGES2 = {
2092
2123
  PipeLLM: "LLM",
2093
2124
  PipeExtract: "Extract",
@@ -2095,6 +2126,7 @@ var PIPE_TYPE_BADGES2 = {
2095
2126
  PipeImgGen: "ImgGen",
2096
2127
  PipeSearch: "Search",
2097
2128
  PipeFunc: "Func",
2129
+ PipeStructure: "Structure",
2098
2130
  PipeSignature: "Signature",
2099
2131
  PipeSequence: "Sequence",
2100
2132
  PipeParallel: "Parallel",
@@ -2136,17 +2168,17 @@ function PipeCardBase({ data, children }) {
2136
2168
  const controllerClass = isController ? " pipe-card--controller" : "";
2137
2169
  const signatureClass = isSignature ? " pipe-card--signature" : "";
2138
2170
  const badgeClass = isController ? "pipe-card-badge pipe-card-badge--controller" : isSignature ? "pipe-card-badge pipe-card-badge--signature" : "pipe-card-badge";
2139
- return /* @__PURE__ */ jsxs18("div", { className: `pipe-card ${dirClass}${controllerClass}${signatureClass}`, children: [
2140
- /* @__PURE__ */ jsxs18("div", { className: "pipe-card-header", children: [
2141
- /* @__PURE__ */ jsx18("span", { className: badgeClass, children: badge }),
2142
- /* @__PURE__ */ jsx18("span", { className: "pipe-card-code", title: data.pipeCode, children: data.pipeCode }),
2143
- /* @__PURE__ */ jsx18(
2171
+ return /* @__PURE__ */ jsxs19("div", { className: `pipe-card ${dirClass}${controllerClass}${signatureClass}`, children: [
2172
+ /* @__PURE__ */ jsxs19("div", { className: "pipe-card-header", children: [
2173
+ /* @__PURE__ */ jsx19("span", { className: badgeClass, children: badge }),
2174
+ /* @__PURE__ */ jsx19("span", { className: "pipe-card-code", title: data.pipeCode, children: data.pipeCode }),
2175
+ /* @__PURE__ */ jsx19(
2144
2176
  "span",
2145
2177
  {
2146
2178
  className: "pipe-card-status",
2147
2179
  style: { color: statusConfig.color },
2148
2180
  title: statusConfig.label,
2149
- children: /* @__PURE__ */ jsx18(
2181
+ children: /* @__PURE__ */ jsx19(
2150
2182
  "span",
2151
2183
  {
2152
2184
  className: `pipe-card-status-dot ${isRunning ? "pipe-card-status-dot--pulse" : ""}`,
@@ -2155,7 +2187,7 @@ function PipeCardBase({ data, children }) {
2155
2187
  )
2156
2188
  }
2157
2189
  ),
2158
- data.onExpand && /* @__PURE__ */ jsx18(
2190
+ data.onExpand && /* @__PURE__ */ jsx19(
2159
2191
  "button",
2160
2192
  {
2161
2193
  type: "button",
@@ -2171,23 +2203,23 @@ function PipeCardBase({ data, children }) {
2171
2203
  }
2172
2204
  )
2173
2205
  ] }),
2174
- data.description && /* @__PURE__ */ jsx18("span", { className: "pipe-card-description", title: data.description, children: data.description }),
2175
- data.inputs.length > 0 && /* @__PURE__ */ jsxs18("div", { className: "pipe-card-io", children: [
2176
- /* @__PURE__ */ jsx18("span", { className: "pipe-card-io-label", children: "INPUTS" }),
2177
- /* @__PURE__ */ jsxs18("div", { className: "pipe-card-io-pills", children: [
2178
- visibleInputs.map((input) => /* @__PURE__ */ jsxs18(
2206
+ data.description && /* @__PURE__ */ jsx19("span", { className: "pipe-card-description", title: data.description, children: data.description }),
2207
+ data.inputs.length > 0 && /* @__PURE__ */ jsxs19("div", { className: "pipe-card-io", children: [
2208
+ /* @__PURE__ */ jsx19("span", { className: "pipe-card-io-label", children: "INPUTS" }),
2209
+ /* @__PURE__ */ jsxs19("div", { className: "pipe-card-io-pills", children: [
2210
+ visibleInputs.map((input) => /* @__PURE__ */ jsxs19(
2179
2211
  "span",
2180
2212
  {
2181
2213
  className: "pipe-card-io-pill",
2182
2214
  title: `${input.name}: ${input.concept}`,
2183
2215
  children: [
2184
- /* @__PURE__ */ jsx18("span", { className: "pipe-card-io-pill-name", children: input.name }),
2185
- /* @__PURE__ */ jsx18("span", { className: "pipe-card-io-pill-concept", children: input.concept })
2216
+ /* @__PURE__ */ jsx19("span", { className: "pipe-card-io-pill-name", children: input.name }),
2217
+ /* @__PURE__ */ jsx19("span", { className: "pipe-card-io-pill-concept", children: input.concept })
2186
2218
  ]
2187
2219
  },
2188
2220
  input.name
2189
2221
  )),
2190
- hasMany && /* @__PURE__ */ jsx18(
2222
+ hasMany && /* @__PURE__ */ jsx19(
2191
2223
  "button",
2192
2224
  {
2193
2225
  className: "pipe-card-io-more",
@@ -2200,16 +2232,16 @@ function PipeCardBase({ data, children }) {
2200
2232
  )
2201
2233
  ] })
2202
2234
  ] }),
2203
- data.outputs.length > 0 && /* @__PURE__ */ jsxs18("div", { className: "pipe-card-io", children: [
2204
- /* @__PURE__ */ jsx18("span", { className: "pipe-card-io-label", children: "OUTPUT" }),
2205
- /* @__PURE__ */ jsx18("div", { className: "pipe-card-io-pills", children: data.outputs.map((output) => /* @__PURE__ */ jsxs18(
2235
+ data.outputs.length > 0 && /* @__PURE__ */ jsxs19("div", { className: "pipe-card-io", children: [
2236
+ /* @__PURE__ */ jsx19("span", { className: "pipe-card-io-label", children: "OUTPUT" }),
2237
+ /* @__PURE__ */ jsx19("div", { className: "pipe-card-io-pills", children: data.outputs.map((output) => /* @__PURE__ */ jsxs19(
2206
2238
  "span",
2207
2239
  {
2208
2240
  className: "pipe-card-io-pill",
2209
2241
  title: `${output.name}: ${output.concept}`,
2210
2242
  children: [
2211
- /* @__PURE__ */ jsx18("span", { className: "pipe-card-io-pill-name", children: output.name }),
2212
- /* @__PURE__ */ jsx18("span", { className: "pipe-card-io-pill-concept", children: output.concept })
2243
+ /* @__PURE__ */ jsx19("span", { className: "pipe-card-io-pill-name", children: output.name }),
2244
+ /* @__PURE__ */ jsx19("span", { className: "pipe-card-io-pill-concept", children: output.concept })
2213
2245
  ]
2214
2246
  },
2215
2247
  output.name
@@ -2227,6 +2259,7 @@ var PIPE_CARD_REGISTRY = {
2227
2259
  PipeImgGen: PipeCardBase,
2228
2260
  PipeSearch: PipeCardBase,
2229
2261
  PipeFunc: PipeCardBase,
2262
+ PipeStructure: PipeCardBase,
2230
2263
  PipeSignature: PipeCardBase,
2231
2264
  PipeSequence: PipeCardBase,
2232
2265
  PipeParallel: PipeCardBase,
@@ -2238,11 +2271,11 @@ function getPipeCardComponent(pipeType) {
2238
2271
  }
2239
2272
 
2240
2273
  // src/graph/react/nodes/pipe/PipeCardNode.tsx
2241
- import { Fragment as Fragment12, jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
2274
+ import { Fragment as Fragment13, jsx as jsx20, jsxs as jsxs20 } from "react/jsx-runtime";
2242
2275
  function PipeCardNode({ data }) {
2243
2276
  var _a;
2244
2277
  const Card = (_a = getPipeCardComponent(data.pipeType)) != null ? _a : PipeCardBase;
2245
- return /* @__PURE__ */ jsx19(Card, { data });
2278
+ return /* @__PURE__ */ jsx20(Card, { data });
2246
2279
  }
2247
2280
  function PipeCardRFNode({
2248
2281
  data,
@@ -2251,15 +2284,15 @@ function PipeCardRFNode({
2251
2284
  }) {
2252
2285
  const payload = data.pipeCardData;
2253
2286
  if (!payload) return null;
2254
- return /* @__PURE__ */ jsxs19(Fragment12, { children: [
2255
- /* @__PURE__ */ jsx19(Handle, { type: "target", position: targetPosition }),
2256
- /* @__PURE__ */ jsx19(PipeCardNode, { data: payload }),
2257
- /* @__PURE__ */ jsx19(Handle, { type: "source", position: sourcePosition })
2287
+ return /* @__PURE__ */ jsxs20(Fragment13, { children: [
2288
+ /* @__PURE__ */ jsx20(Handle, { type: "target", position: targetPosition }),
2289
+ /* @__PURE__ */ jsx20(PipeCardNode, { data: payload }),
2290
+ /* @__PURE__ */ jsx20(Handle, { type: "source", position: sourcePosition })
2258
2291
  ] });
2259
2292
  }
2260
2293
 
2261
2294
  // src/graph/react/viewer/GraphViewer.tsx
2262
- import { Fragment as Fragment13, jsx as jsx20, jsxs as jsxs20 } from "react/jsx-runtime";
2295
+ import { Fragment as Fragment14, jsx as jsx21, jsxs as jsxs21 } from "react/jsx-runtime";
2263
2296
  var nodeTypes = __spreadProps(__spreadValues({}, controllerNodeTypes), {
2264
2297
  pipeCard: PipeCardRFNode
2265
2298
  });
@@ -2272,7 +2305,7 @@ function StuffNodeDetail({
2272
2305
  onOpenExternally
2273
2306
  }) {
2274
2307
  const conceptInfo = stuffData.concept && graphspec ? resolveConceptRef(graphspec, stuffData.concept) : void 0;
2275
- return /* @__PURE__ */ jsx20(Fragment13, { children: conceptInfo ? /* @__PURE__ */ jsx20(
2308
+ return /* @__PURE__ */ jsx21(Fragment14, { children: conceptInfo ? /* @__PURE__ */ jsx21(
2276
2309
  ConceptDetailPanel,
2277
2310
  {
2278
2311
  concept: conceptInfo,
@@ -2284,7 +2317,7 @@ function StuffNodeDetail({
2284
2317
  }
2285
2318
  ) : (
2286
2319
  /* Fallback: just show the StuffViewer if no concept info */
2287
- /* @__PURE__ */ jsx20(
2320
+ /* @__PURE__ */ jsx21(
2288
2321
  StuffViewer,
2289
2322
  {
2290
2323
  stuff: stuffData,
@@ -2306,6 +2339,10 @@ function resolveExternalThemeMode(themeProp, configTheme) {
2306
2339
  function resolveActiveTheme(mode, systemTheme) {
2307
2340
  return mode === GRAPH_THEME_MODE.SYSTEM ? systemTheme : mode;
2308
2341
  }
2342
+ function resolveToolbarPosition(positionProp, configPosition) {
2343
+ var _a;
2344
+ return (_a = positionProp != null ? positionProp : configPosition) != null ? _a : DEFAULT_GRAPH_CONFIG.toolbarPosition;
2345
+ }
2309
2346
  function cloneCachedNodes(nodes) {
2310
2347
  return nodes.map((n) => __spreadProps(__spreadValues({}, n), {
2311
2348
  position: __spreadValues({}, n.position),
@@ -2339,6 +2376,7 @@ function GraphViewer(props) {
2339
2376
  initialFoldMode,
2340
2377
  hideToolbar = false,
2341
2378
  theme: themeProp,
2379
+ toolbarPosition: toolbarPositionProp,
2342
2380
  systemTheme: systemThemeProp,
2343
2381
  showThemeToggle = true,
2344
2382
  onThemeChange,
@@ -2483,7 +2521,7 @@ function GraphViewer(props) {
2483
2521
  React9.useEffect(() => {
2484
2522
  if (!initialDataRef.current) return;
2485
2523
  let cancelled = false;
2486
- (async () => {
2524
+ void (async () => {
2487
2525
  try {
2488
2526
  const data = initialDataRef.current;
2489
2527
  if (!data) return;
@@ -2521,7 +2559,7 @@ function GraphViewer(props) {
2521
2559
  setEdges(toAppEdges(withControllers.edges));
2522
2560
  setTimeout(() => {
2523
2561
  if (!cancelled && reactFlowRef.current) {
2524
- reactFlowRef.current.fitView({ padding: 0.1 });
2562
+ void reactFlowRef.current.fitView({ padding: 0.1 });
2525
2563
  }
2526
2564
  }, 50);
2527
2565
  } catch (err) {
@@ -2593,7 +2631,7 @@ function GraphViewer(props) {
2593
2631
  _analysis: folded.analysis,
2594
2632
  _graphspec: graphspec
2595
2633
  };
2596
- (async () => {
2634
+ void (async () => {
2597
2635
  try {
2598
2636
  const currentDirection = directionRef.current;
2599
2637
  const currentLayoutConfig = layoutConfigRef.current;
@@ -2638,13 +2676,13 @@ function GraphViewer(props) {
2638
2676
  setEdges(toAppEdges(withControllers.edges));
2639
2677
  setTimeout(() => {
2640
2678
  if (!cancelled && reactFlowRef.current) {
2641
- reactFlowRef.current.fitView({ padding: 0.1 });
2679
+ void reactFlowRef.current.fitView({ padding: 0.1 });
2642
2680
  if (initialZoomRef.current !== void 0 && initialZoomRef.current !== null) {
2643
- reactFlowRef.current.zoomTo(initialZoomRef.current);
2681
+ void reactFlowRef.current.zoomTo(initialZoomRef.current);
2644
2682
  }
2645
2683
  if (panToTopRef.current) {
2646
2684
  const vp = reactFlowRef.current.getViewport();
2647
- reactFlowRef.current.setViewport({ x: vp.x, y: 20, zoom: vp.zoom });
2685
+ void reactFlowRef.current.setViewport({ x: vp.x, y: 20, zoom: vp.zoom });
2648
2686
  }
2649
2687
  }
2650
2688
  }, 100);
@@ -2689,7 +2727,7 @@ function GraphViewer(props) {
2689
2727
  _analysis: folded.analysis,
2690
2728
  _graphspec: currentGraphspec
2691
2729
  };
2692
- (async () => {
2730
+ void (async () => {
2693
2731
  try {
2694
2732
  const layouted = await getLayoutedElements(
2695
2733
  folded.nodes,
@@ -2725,7 +2763,7 @@ function GraphViewer(props) {
2725
2763
  setEdges(toAppEdges(withControllers.edges));
2726
2764
  setTimeout(() => {
2727
2765
  if (!cancelled && reactFlowRef.current) {
2728
- reactFlowRef.current.fitView({ padding: 0.1 });
2766
+ void reactFlowRef.current.fitView({ padding: 0.1 });
2729
2767
  }
2730
2768
  }, 50);
2731
2769
  } catch (err) {
@@ -2820,6 +2858,10 @@ function GraphViewer(props) {
2820
2858
  );
2821
2859
  const selectedSpecNode = (detailSelection == null ? void 0 : detailSelection.kind) === "pipe" && graphspec ? graphspec.nodes.find((n) => n.pipe_code === detailSelection.nodeData.pipeCode) : void 0;
2822
2860
  const detailOpen = detailSelection !== null || conceptOverride !== null;
2861
+ const effectiveToolbarPosition = resolveToolbarPosition(
2862
+ toolbarPositionProp,
2863
+ config.toolbarPosition
2864
+ );
2823
2865
  const rawAnalysis = (_c = rawGraphDataRef.current) == null ? void 0 : _c.analysis;
2824
2866
  const allControllerIds = rawAnalysis == null ? void 0 : rawAnalysis.controllerNodeIds;
2825
2867
  const foldAllProps = React9.useMemo(() => {
@@ -2838,13 +2880,13 @@ function GraphViewer(props) {
2838
2880
  expandAllDisabled: foldedControllers.size === 0
2839
2881
  };
2840
2882
  }, [showControllers, allControllerIds, foldedControllers]);
2841
- return /* @__PURE__ */ jsxs20(
2883
+ return /* @__PURE__ */ jsxs21(
2842
2884
  "div",
2843
2885
  {
2844
2886
  ref: containerRef,
2845
2887
  className: `react-flow-container react-flow-container--theme-${resolvedTheme} react-flow-container--mode-${mode}`,
2846
2888
  children: [
2847
- /* @__PURE__ */ jsx20(
2889
+ /* @__PURE__ */ jsxs21(
2848
2890
  ReactFlow,
2849
2891
  {
2850
2892
  nodes,
@@ -2862,18 +2904,49 @@ function GraphViewer(props) {
2862
2904
  minZoom: 0.1,
2863
2905
  proOptions: { hideAttribution: true },
2864
2906
  panActivationKeyCode: null,
2865
- children: /* @__PURE__ */ jsx20(
2866
- Background,
2867
- {
2868
- variant: BackgroundVariant.Dots,
2869
- gap: 20,
2870
- size: 1,
2871
- color: "var(--color-bg-dots)"
2872
- }
2873
- )
2907
+ children: [
2908
+ /* @__PURE__ */ jsx21(
2909
+ Background,
2910
+ {
2911
+ variant: BackgroundVariant.Dots,
2912
+ gap: 20,
2913
+ size: 1,
2914
+ color: "var(--color-bg-dots)"
2915
+ }
2916
+ ),
2917
+ !hideToolbar && /* @__PURE__ */ jsx21(
2918
+ GraphToolbar,
2919
+ {
2920
+ direction,
2921
+ onDirectionChange: setDirection,
2922
+ showControllers,
2923
+ onShowControllersChange: setShowControllers,
2924
+ onZoomIn: () => {
2925
+ var _a2;
2926
+ void ((_a2 = reactFlowRef.current) == null ? void 0 : _a2.zoomIn());
2927
+ },
2928
+ onZoomOut: () => {
2929
+ var _a2;
2930
+ void ((_a2 = reactFlowRef.current) == null ? void 0 : _a2.zoomOut());
2931
+ },
2932
+ onFitView: () => {
2933
+ var _a2;
2934
+ void ((_a2 = reactFlowRef.current) == null ? void 0 : _a2.fitView({ padding: 0.1 }));
2935
+ },
2936
+ onFoldAll: foldAllProps.onFoldAll,
2937
+ onExpandAll: foldAllProps.onExpandAll,
2938
+ foldAllDisabled: foldAllProps.foldAllDisabled,
2939
+ expandAllDisabled: foldAllProps.expandAllDisabled,
2940
+ themeMode: showThemeToggle ? mode : void 0,
2941
+ onThemeModeChange: showThemeToggle ? setMode : void 0,
2942
+ rightOffset: detailOpen ? panelWidth : 0,
2943
+ position: effectiveToolbarPosition
2944
+ }
2945
+ )
2946
+ ]
2874
2947
  }
2875
2948
  ),
2876
- /* @__PURE__ */ jsxs20(
2949
+ /* @__PURE__ */ jsxs21(
2877
2950
  DetailPanel,
2878
2951
  {
2879
2952
  isOpen: detailOpen,
@@ -2882,14 +2955,14 @@ function GraphViewer(props) {
2882
2955
  isDragging: isPanelDragging,
2883
2956
  onResizeHandleMouseDown: onResizeMouseDown,
2884
2957
  children: [
2885
- conceptOverride ? /* @__PURE__ */ jsx20(ConceptDetailPanel, { concept: conceptOverride }) : selectedSpecNode && graphspec ? /* @__PURE__ */ jsx20(
2958
+ conceptOverride ? /* @__PURE__ */ jsx21(ConceptDetailPanel, { concept: conceptOverride }) : selectedSpecNode && graphspec ? /* @__PURE__ */ jsx21(
2886
2959
  PipeDetailPanel,
2887
2960
  {
2888
2961
  node: selectedSpecNode,
2889
2962
  spec: graphspec,
2890
2963
  onConceptClick: handleConceptClick
2891
2964
  }
2892
- ) : (detailSelection == null ? void 0 : detailSelection.stuffData) ? /* @__PURE__ */ jsx20(
2965
+ ) : (detailSelection == null ? void 0 : detailSelection.stuffData) ? /* @__PURE__ */ jsx21(
2893
2966
  StuffNodeDetail,
2894
2967
  {
2895
2968
  nodeId: detailSelection.nodeId,
@@ -2903,34 +2976,6 @@ function GraphViewer(props) {
2903
2976
  renderDetailExtra && detailSelection && !conceptOverride && renderDetailExtra(detailSelection.nodeId, detailSelection.nodeData)
2904
2977
  ]
2905
2978
  }
2906
- ),
2907
- !hideToolbar && /* @__PURE__ */ jsx20(
2908
- GraphToolbar,
2909
- {
2910
- direction,
2911
- onDirectionChange: setDirection,
2912
- showControllers,
2913
- onShowControllersChange: setShowControllers,
2914
- onZoomIn: () => {
2915
- var _a2;
2916
- return (_a2 = reactFlowRef.current) == null ? void 0 : _a2.zoomIn();
2917
- },
2918
- onZoomOut: () => {
2919
- var _a2;
2920
- return (_a2 = reactFlowRef.current) == null ? void 0 : _a2.zoomOut();
2921
- },
2922
- onFitView: () => {
2923
- var _a2;
2924
- return (_a2 = reactFlowRef.current) == null ? void 0 : _a2.fitView({ padding: 0.1 });
2925
- },
2926
- onFoldAll: foldAllProps.onFoldAll,
2927
- onExpandAll: foldAllProps.onExpandAll,
2928
- foldAllDisabled: foldAllProps.foldAllDisabled,
2929
- expandAllDisabled: foldAllProps.expandAllDisabled,
2930
- themeMode: showThemeToggle ? mode : void 0,
2931
- onThemeModeChange: showThemeToggle ? setMode : void 0,
2932
- rightOffset: detailOpen ? panelWidth : 0
2933
- }
2934
2979
  )
2935
2980
  ]
2936
2981
  }