@trops/dash-core 0.1.640 → 0.1.641

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -47440,45 +47440,85 @@ function widgetSubscription(workspace, widget, event) {
47440
47440
  * otherwise they show as typed.
47441
47441
  */
47442
47442
  function describeSubscription(sub, catalog) {
47443
+ var botCatalog = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
47443
47444
  var eventType = sub && sub.eventType;
47444
- var _iterator2 = _createForOfIteratorHelper$m(catalog || []),
47445
- _step2;
47445
+ // Bot subscriptions resolve against the bot catalog; `kind` lets the form
47446
+ // say "bot missing" instead of "widget missing".
47447
+ if (sub && sub.source && sub.source.kind === "bot") {
47448
+ var _iterator2 = _createForOfIteratorHelper$m(botCatalog || []),
47449
+ _step2;
47450
+ try {
47451
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
47452
+ var b = _step2.value;
47453
+ var _iterator3 = _createForOfIteratorHelper$m(b.events),
47454
+ _step3;
47455
+ try {
47456
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
47457
+ var ev = _step3.value;
47458
+ var s = botSubscription(b, ev);
47459
+ if (s.eventType === eventType) {
47460
+ return {
47461
+ label: s.label,
47462
+ missing: false,
47463
+ kind: "bot"
47464
+ };
47465
+ }
47466
+ }
47467
+ } catch (err) {
47468
+ _iterator3.e(err);
47469
+ } finally {
47470
+ _iterator3.f();
47471
+ }
47472
+ }
47473
+ } catch (err) {
47474
+ _iterator2.e(err);
47475
+ } finally {
47476
+ _iterator2.f();
47477
+ }
47478
+ return {
47479
+ label: sub.label || eventType,
47480
+ missing: true,
47481
+ kind: "bot"
47482
+ };
47483
+ }
47484
+ var _iterator4 = _createForOfIteratorHelper$m(catalog || []),
47485
+ _step4;
47446
47486
  try {
47447
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
47448
- var ws = _step2.value;
47449
- var _iterator3 = _createForOfIteratorHelper$m(ws.widgets),
47450
- _step3;
47487
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
47488
+ var ws = _step4.value;
47489
+ var _iterator5 = _createForOfIteratorHelper$m(ws.widgets),
47490
+ _step5;
47451
47491
  try {
47452
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
47453
- var w = _step3.value;
47454
- var _iterator4 = _createForOfIteratorHelper$m(w.events),
47455
- _step4;
47492
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
47493
+ var w = _step5.value;
47494
+ var _iterator6 = _createForOfIteratorHelper$m(w.events),
47495
+ _step6;
47456
47496
  try {
47457
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
47458
- var ev = _step4.value;
47459
- if (formatEventString(w.ref, w.instanceId, ev) === eventType) {
47497
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
47498
+ var _ev = _step6.value;
47499
+ if (formatEventString(w.ref, w.instanceId, _ev) === eventType) {
47460
47500
  return {
47461
- label: widgetSubscription(ws, w, ev).label,
47501
+ label: widgetSubscription(ws, w, _ev).label,
47462
47502
  missing: false
47463
47503
  };
47464
47504
  }
47465
47505
  }
47466
47506
  } catch (err) {
47467
- _iterator4.e(err);
47507
+ _iterator6.e(err);
47468
47508
  } finally {
47469
- _iterator4.f();
47509
+ _iterator6.f();
47470
47510
  }
47471
47511
  }
47472
47512
  } catch (err) {
47473
- _iterator3.e(err);
47513
+ _iterator5.e(err);
47474
47514
  } finally {
47475
- _iterator3.f();
47515
+ _iterator5.f();
47476
47516
  }
47477
47517
  }
47478
47518
  } catch (err) {
47479
- _iterator2.e(err);
47519
+ _iterator4.e(err);
47480
47520
  } finally {
47481
- _iterator2.f();
47521
+ _iterator4.f();
47482
47522
  }
47483
47523
  if (sub && sub.source) {
47484
47524
  return {
@@ -47492,8 +47532,122 @@ function describeSubscription(sub, catalog) {
47492
47532
  };
47493
47533
  }
47494
47534
 
47535
+ /**
47536
+ * Events other bots publish (bot:<ref>[<botId>].<event>, PRD US-010), for the
47537
+ * "Another bot" side of the picker. Derived from each bot's settings — never
47538
+ * hand-declared: Completed, Failed, and one `tool.<providerType>.<tool>` per
47539
+ * tool the bot may use (the provider's tools, narrowed by the bot's
47540
+ * selection). Providers with no known type or tool list are skipped.
47541
+ *
47542
+ * @param {Array<object>} bots
47543
+ * @param {Array<{name, type, tools}>} toolSources bots.listToolSources()
47544
+ * @param {string} [excludeBotId] the bot being edited — can't trigger itself
47545
+ */
47546
+ function buildBotEventCatalog(bots, toolSources) {
47547
+ var excludeBotId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
47548
+ if (!Array.isArray(bots)) return [];
47549
+ var sources = Array.isArray(toolSources) ? toolSources : [];
47550
+ var out = [];
47551
+ var _iterator7 = _createForOfIteratorHelper$m(bots),
47552
+ _step7;
47553
+ try {
47554
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
47555
+ var bot = _step7.value;
47556
+ if (!bot || !bot.id || !bot.ref || bot.id === excludeBotId) continue;
47557
+ var events = [{
47558
+ event: "completed",
47559
+ label: "Completed"
47560
+ }, {
47561
+ event: "failed",
47562
+ label: "Failed"
47563
+ }];
47564
+ var _iterator8 = _createForOfIteratorHelper$m(bot.mcpServers || []),
47565
+ _step8;
47566
+ try {
47567
+ var _loop = function _loop() {
47568
+ var provider = _step8.value;
47569
+ var src = sources.find(function (s) {
47570
+ return s && s.name === provider;
47571
+ });
47572
+ if (!src || !src.type || !Array.isArray(src.tools)) return 1; // continue
47573
+ var sel = bot.toolSelections && bot.toolSelections[provider];
47574
+ var tools = Array.isArray(sel) ? src.tools.filter(function (t) {
47575
+ return sel.includes(t);
47576
+ }) : src.tools;
47577
+ var _iterator9 = _createForOfIteratorHelper$m(tools),
47578
+ _step9;
47579
+ try {
47580
+ for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
47581
+ var tool = _step9.value;
47582
+ events.push({
47583
+ event: "tool.".concat(src.type, ".").concat(tool),
47584
+ label: "".concat(provider, " \u203A ").concat(tool)
47585
+ });
47586
+ }
47587
+ } catch (err) {
47588
+ _iterator9.e(err);
47589
+ } finally {
47590
+ _iterator9.f();
47591
+ }
47592
+ };
47593
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
47594
+ if (_loop()) continue;
47595
+ }
47596
+ } catch (err) {
47597
+ _iterator8.e(err);
47598
+ } finally {
47599
+ _iterator8.f();
47600
+ }
47601
+ out.push({
47602
+ botId: bot.id,
47603
+ ref: bot.ref,
47604
+ name: bot.name || bot.id,
47605
+ events: events
47606
+ });
47607
+ }
47608
+ } catch (err) {
47609
+ _iterator7.e(err);
47610
+ } finally {
47611
+ _iterator7.f();
47612
+ }
47613
+ return out;
47614
+ }
47615
+
47616
+ /** A subscription to one bot event, picked from the bot catalog. */
47617
+ function botSubscription(botEntry, ev) {
47618
+ return {
47619
+ eventType: "bot:".concat(botEntry.ref, "[").concat(botEntry.botId, "].").concat(ev.event),
47620
+ source: {
47621
+ kind: "bot",
47622
+ ref: botEntry.ref,
47623
+ instanceId: botEntry.botId,
47624
+ event: ev.event
47625
+ },
47626
+ label: "".concat(botEntry.name, " \u203A ").concat(ev.label)
47627
+ };
47628
+ }
47629
+
47495
47630
  function ownKeys$t(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
47496
47631
  function _objectSpread$t(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$t(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$t(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
47632
+ var EVENT_FROM_OPTIONS = [{
47633
+ value: "widget",
47634
+ label: "A dashboard widget"
47635
+ }, {
47636
+ value: "bot",
47637
+ label: "Another bot"
47638
+ }];
47639
+
47640
+ /**
47641
+ * BotDetail — create/edit form for a Bot Factory bot (Settings → Bots).
47642
+ *
47643
+ * Built for a non-technical user: Providers (the user's Dash MCP providers —
47644
+ * what the bot can use), the AI model, and the schedule are all
47645
+ * pick-from-a-list, never free text. "Provider" always means a Dash provider;
47646
+ * the LLM choice is labelled "Model source". The raw cron lives behind an "Advanced"
47647
+ * toggle for power users. All inputs are @trops/dash-react primitives.
47648
+ */
47649
+
47650
+ // Friendly, Title-case provider labels for the dropdown.
47497
47651
  var PROVIDER_LABELS = {
47498
47652
  anthropic: "Anthropic",
47499
47653
  openai: "OpenAI",
@@ -47599,6 +47753,8 @@ var BotDetail = function BotDetail(_ref) {
47599
47753
  workspaces = _ref$workspaces === void 0 ? EMPTY_LIST : _ref$workspaces,
47600
47754
  _ref$getWidgetConfig = _ref.getWidgetConfig,
47601
47755
  getWidgetConfig = _ref$getWidgetConfig === void 0 ? null : _ref$getWidgetConfig,
47756
+ _ref$bots = _ref.bots,
47757
+ bots = _ref$bots === void 0 ? EMPTY_LIST : _ref$bots,
47602
47758
  onSave = _ref.onSave,
47603
47759
  onCancel = _ref.onCancel,
47604
47760
  onDelete = _ref.onDelete;
@@ -47754,26 +47910,34 @@ var BotDetail = function BotDetail(_ref) {
47754
47910
  var eventCatalog = useMemo(function () {
47755
47911
  return buildWidgetEventCatalog(workspaces, getWidgetConfig);
47756
47912
  }, [workspaces, getWidgetConfig]);
47757
- var _useState39 = useState(""),
47913
+ var _useState39 = useState("widget"),
47758
47914
  _useState40 = _slicedToArray(_useState39, 2),
47759
- pickWorkspace = _useState40[0],
47760
- setPickWorkspace = _useState40[1];
47915
+ pickFrom = _useState40[0],
47916
+ setPickFrom = _useState40[1];
47761
47917
  var _useState41 = useState(""),
47762
47918
  _useState42 = _slicedToArray(_useState41, 2),
47763
- pickWidget = _useState42[0],
47764
- setPickWidget = _useState42[1];
47919
+ pickWorkspace = _useState42[0],
47920
+ setPickWorkspace = _useState42[1];
47765
47921
  var _useState43 = useState(""),
47766
47922
  _useState44 = _slicedToArray(_useState43, 2),
47767
- pickEvent = _useState44[0],
47768
- setPickEvent = _useState44[1];
47769
- var _useState45 = useState(false),
47923
+ pickWidget = _useState44[0],
47924
+ setPickWidget = _useState44[1];
47925
+ var _useState45 = useState(""),
47770
47926
  _useState46 = _slicedToArray(_useState45, 2),
47771
- saving = _useState46[0],
47772
- setSaving = _useState46[1];
47773
- var _useState47 = useState(null),
47927
+ pickBot = _useState46[0],
47928
+ setPickBot = _useState46[1];
47929
+ var _useState47 = useState(""),
47774
47930
  _useState48 = _slicedToArray(_useState47, 2),
47775
- error = _useState48[0],
47776
- setError = _useState48[1];
47931
+ pickEvent = _useState48[0],
47932
+ setPickEvent = _useState48[1];
47933
+ var _useState49 = useState(false),
47934
+ _useState50 = _slicedToArray(_useState49, 2),
47935
+ saving = _useState50[0],
47936
+ setSaving = _useState50[1];
47937
+ var _useState51 = useState(null),
47938
+ _useState52 = _slicedToArray(_useState51, 2),
47939
+ error = _useState52[0],
47940
+ setError = _useState52[1];
47777
47941
 
47778
47942
  // Discover the user's configured MCP providers — running or not. The bot
47779
47943
  // starts any that aren't running when it runs.
@@ -47895,9 +48059,22 @@ var BotDetail = function BotDetail(_ref) {
47895
48059
  var pickedWidget = pickedWs ? pickedWs.widgets.find(function (w) {
47896
48060
  return "".concat(w.ref, "|").concat(w.instanceId) === pickWidget;
47897
48061
  }) : null;
48062
+
48063
+ // Other bots' events, derived from their providers + tools (this bot
48064
+ // excluded — it can't trigger itself).
48065
+ var botCatalog = useMemo(function () {
48066
+ return buildBotEventCatalog(bots, toolSources, (bot === null || bot === void 0 ? void 0 : bot.id) || null);
48067
+ }, [bots, toolSources, bot === null || bot === void 0 ? void 0 : bot.id]);
48068
+ var pickedBot = botCatalog.find(function (b) {
48069
+ return b.botId === pickBot;
48070
+ }) || null;
48071
+ var pickedBotEvent = pickedBot ? pickedBot.events.find(function (e) {
48072
+ return e.event === pickEvent;
48073
+ }) || null : null;
48074
+ var canAddEvent = pickFrom === "bot" ? !!pickedBotEvent : !!(pickedWidget && pickEvent);
47898
48075
  var addSubscription = function addSubscription() {
47899
- if (!pickedWs || !pickedWidget || !pickEvent) return;
47900
- var sub = widgetSubscription(pickedWs, pickedWidget, pickEvent);
48076
+ if (!canAddEvent) return;
48077
+ var sub = pickFrom === "bot" ? botSubscription(pickedBot, pickedBotEvent) : widgetSubscription(pickedWs, pickedWidget, pickEvent);
47901
48078
  setSubscriptions(function (prev) {
47902
48079
  return prev.some(function (s) {
47903
48080
  return s.eventType === sub.eventType;
@@ -48180,16 +48357,17 @@ var BotDetail = function BotDetail(_ref) {
48180
48357
  }), subscriptions.length ? /*#__PURE__*/jsx("div", {
48181
48358
  className: "flex flex-col gap-1",
48182
48359
  children: subscriptions.map(function (sub) {
48183
- var _describeSubscription = describeSubscription(sub, eventCatalog),
48360
+ var _describeSubscription = describeSubscription(sub, eventCatalog, botCatalog),
48184
48361
  label = _describeSubscription.label,
48185
- missing = _describeSubscription.missing;
48362
+ missing = _describeSubscription.missing,
48363
+ kind = _describeSubscription.kind;
48186
48364
  return /*#__PURE__*/jsxs("div", {
48187
48365
  className: "flex flex-row items-center justify-between gap-2",
48188
48366
  children: [/*#__PURE__*/jsxs("span", {
48189
48367
  className: "text-sm",
48190
48368
  children: [label, missing ? /*#__PURE__*/jsxs("span", {
48191
48369
  className: "text-xs opacity-60",
48192
- children: [" ", "(widget missing)"]
48370
+ children: [" ", "(", kind === "bot" ? "bot" : "widget", " missing)"]
48193
48371
  }) : null]
48194
48372
  }), /*#__PURE__*/jsx(Button3, {
48195
48373
  title: "Remove",
@@ -48204,7 +48382,51 @@ var BotDetail = function BotDetail(_ref) {
48204
48382
  }) : /*#__PURE__*/jsx("span", {
48205
48383
  className: "text-xs opacity-50",
48206
48384
  children: "This bot doesn't run on any events yet."
48207
- }), eventCatalog.length ? /*#__PURE__*/jsxs("div", {
48385
+ }), /*#__PURE__*/jsx(SelectInput, {
48386
+ label: "From",
48387
+ value: pickFrom,
48388
+ onChange: function onChange(v) {
48389
+ setPickFrom(v);
48390
+ setPickEvent("");
48391
+ },
48392
+ options: EVENT_FROM_OPTIONS
48393
+ }), pickFrom === "bot" ? botCatalog.length ? /*#__PURE__*/jsxs("div", {
48394
+ className: "flex flex-col gap-2",
48395
+ children: [/*#__PURE__*/jsx(SelectInput, {
48396
+ label: "Bot",
48397
+ value: pickBot,
48398
+ onChange: function onChange(v) {
48399
+ setPickBot(v);
48400
+ setPickEvent("");
48401
+ },
48402
+ placeholder: "Choose a bot\u2026",
48403
+ options: botCatalog.map(function (b) {
48404
+ return {
48405
+ value: b.botId,
48406
+ label: b.name
48407
+ };
48408
+ })
48409
+ }), /*#__PURE__*/jsx(SelectInput, {
48410
+ label: "Event",
48411
+ value: pickEvent,
48412
+ onChange: setPickEvent,
48413
+ placeholder: "Choose an event\u2026",
48414
+ options: (pickedBot ? pickedBot.events : []).map(function (e) {
48415
+ return {
48416
+ value: e.event,
48417
+ label: e.label
48418
+ };
48419
+ })
48420
+ }), /*#__PURE__*/jsx(Button, {
48421
+ title: "Add event",
48422
+ onClick: addSubscription,
48423
+ size: "sm",
48424
+ disabled: !canAddEvent
48425
+ })]
48426
+ }) : /*#__PURE__*/jsx("span", {
48427
+ className: "text-xs opacity-50",
48428
+ children: "No other bots yet. Create another bot to trigger this one when it finishes or uses a tool."
48429
+ }) : eventCatalog.length ? /*#__PURE__*/jsxs("div", {
48208
48430
  className: "flex flex-col gap-2",
48209
48431
  children: [/*#__PURE__*/jsx(SelectInput, {
48210
48432
  label: "Dashboard",
@@ -48464,6 +48686,7 @@ var BotsSection = function BotsSection(_ref) {
48464
48686
  providers: providers,
48465
48687
  workspaces: workspaces,
48466
48688
  getWidgetConfig: getWidgetConfig,
48689
+ bots: bots,
48467
48690
  onSave: handleSave,
48468
48691
  onCancel: function onCancel() {
48469
48692
  return setIsCreating(false);
@@ -48475,6 +48698,7 @@ var BotsSection = function BotsSection(_ref) {
48475
48698
  providers: providers,
48476
48699
  workspaces: workspaces,
48477
48700
  getWidgetConfig: getWidgetConfig,
48701
+ bots: bots,
48478
48702
  onSave: handleSave,
48479
48703
  onDelete: function onDelete() {
48480
48704
  return setDeleteTarget(selected.id);