@agimon-ai/po-plan 0.0.0-alpha.73 → 0.0.0-alpha.75

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.
@@ -1,7 +1,7 @@
1
- import { createApiClient, defineActivityGroup, defineFill, defineNativePlugin, nativeApiTransport, sessionApiAddress } from "@agimon-ai/po-core/native";
1
+ import { createApiClient, defineActivityGroup, defineFill, defineNativePlugin, defineToolRenderer, nativeApiTransport, sessionApiAddress } from "@agimon-ai/po-core/native";
2
2
  import { View } from "react-native-unistyles/components/native/View";
3
3
  import { Text } from "react-native-unistyles/components/native/Text";
4
- import { Button, ListRow, Markdown, SegmentedControl, Textarea, fontOf } from "@agimon-ai/po-native-components";
4
+ import { Button, ListRow, Markdown, MessageItem, MessageItemBody, MessageItemHeader, SegmentedControl, Textarea, fontOf, toolTone } from "@agimon-ai/po-native-components";
5
5
  import { StyleSheet } from "react-native-unistyles";
6
6
  import { ScrollView } from "react-native-unistyles/components/native/ScrollView";
7
7
  import { useEffect, useState } from "react";
@@ -45,7 +45,7 @@ function parsePlanStatus(raw) {
45
45
  }
46
46
  //#endregion
47
47
  //#region src/extensions/workspaces/sessions/(frontend)/activity-group/plan.native.ts
48
- var plan_native_default = defineActivityGroup({
48
+ var plan_native_default$1 = defineActivityGroup({
49
49
  name: "plan",
50
50
  keys: "p e",
51
51
  statusKey: PLAN_STATUS_KEY,
@@ -194,11 +194,11 @@ function PlanPanel({ sessionId, statuses, closeTransientTab, fileTabFor, openTra
194
194
  }
195
195
  };
196
196
  return /* @__PURE__ */ jsxs(ScrollView, {
197
- contentContainerStyle: styles$1.panel,
197
+ contentContainerStyle: styles$2.panel,
198
198
  testID: "plan-panel",
199
199
  children: [
200
200
  /* @__PURE__ */ jsx(Text, {
201
- style: styles$1.title,
201
+ style: styles$2.title,
202
202
  children: detail?.title ?? "plan"
203
203
  }),
204
204
  /* @__PURE__ */ jsx(SegmentedControl, {
@@ -214,19 +214,19 @@ function PlanPanel({ sessionId, statuses, closeTransientTab, fileTabFor, openTra
214
214
  onValueChange: setView
215
215
  }),
216
216
  sessionId === null ? /* @__PURE__ */ jsx(Text, {
217
- style: styles$1.meta,
217
+ style: styles$2.meta,
218
218
  children: "Select a session."
219
219
  }) : loading && !detail ? /* @__PURE__ */ jsx(Text, {
220
- style: styles$1.meta,
220
+ style: styles$2.meta,
221
221
  children: "reading this session's plan…"
222
222
  }) : null,
223
223
  error ? /* @__PURE__ */ jsx(Text, {
224
224
  accessibilityRole: "alert",
225
- style: styles$1.error,
225
+ style: styles$2.error,
226
226
  children: error
227
227
  }) : null,
228
228
  detail ? detail.unavailable ? /* @__PURE__ */ jsx(Text, {
229
- style: styles$1.meta,
229
+ style: styles$2.meta,
230
230
  children: detail.reason ?? "this plan cannot be shown"
231
231
  }) : view === "preview" ? /* @__PURE__ */ jsx(Markdown, {
232
232
  text: draft ?? detail.content,
@@ -242,7 +242,7 @@ function PlanPanel({ sessionId, statuses, closeTransientTab, fileTabFor, openTra
242
242
  numberOfLines: 12
243
243
  }),
244
244
  /* @__PURE__ */ jsxs(View, {
245
- style: styles$1.actions,
245
+ style: styles$2.actions,
246
246
  children: [/* @__PURE__ */ jsx(Button, {
247
247
  variant: "primary",
248
248
  disabled: draft === void 0 || saving,
@@ -255,13 +255,13 @@ function PlanPanel({ sessionId, statuses, closeTransientTab, fileTabFor, openTra
255
255
  }) : null]
256
256
  }),
257
257
  note ? /* @__PURE__ */ jsx(Text, {
258
- style: note === "saved" ? styles$1.success : styles$1.error,
258
+ style: note === "saved" ? styles$2.success : styles$2.error,
259
259
  children: note
260
260
  }) : null
261
261
  ] }) : null,
262
262
  detail ? /* @__PURE__ */ jsx(Text, {
263
263
  selectable: true,
264
- style: styles$1.path,
264
+ style: styles$2.path,
265
265
  children: detail.path
266
266
  }) : null,
267
267
  /* @__PURE__ */ jsx(Button, {
@@ -279,7 +279,7 @@ function planTab() {
279
279
  panel: PlanPanel
280
280
  };
281
281
  }
282
- const styles$1 = StyleSheet.create((theme) => ({
282
+ const styles$2 = StyleSheet.create((theme) => ({
283
283
  panel: {
284
284
  padding: theme.spacing(4),
285
285
  gap: theme.spacing(3),
@@ -328,7 +328,7 @@ const styles$1 = StyleSheet.create((theme) => ({
328
328
  function PlanActivitySection({ sessionId, statuses, openTransientTab }) {
329
329
  const view = parsePlanStatus(statuses[PLAN_STATUS_KEY]);
330
330
  if (!view) return /* @__PURE__ */ jsx(Text, {
331
- style: styles.meta,
331
+ style: styles$1.meta,
332
332
  children: "no plan written yet"
333
333
  });
334
334
  return /* @__PURE__ */ jsxs(View, {
@@ -341,12 +341,12 @@ function PlanActivitySection({ sessionId, statuses, openTransientTab }) {
341
341
  if (sessionId !== null) openTransientTab(planTab());
342
342
  }
343
343
  }), /* @__PURE__ */ jsx(Text, {
344
- style: styles.meta,
344
+ style: styles$1.meta,
345
345
  children: "open to read or edit; the agent reads what you save."
346
346
  })]
347
347
  });
348
348
  }
349
- const styles = StyleSheet.create((theme) => ({ meta: {
349
+ const styles$1 = StyleSheet.create((theme) => ({ meta: {
350
350
  fontFamily: fontOf(theme.fontFamily.sans),
351
351
  fontSize: theme.fontSize.sm,
352
352
  lineHeight: theme.lineHeight.sm,
@@ -361,6 +361,411 @@ var Plan_activity_plan_native_default = defineFill({
361
361
  component: PlanActivitySection
362
362
  });
363
363
  //#endregion
364
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_lib/planToolRender.ts
365
+ const COLLAPSED_BODY_LINES = 12;
366
+ const PREVIEW_LENGTH = 72;
367
+ const EVIDENCE_LISTS = [
368
+ ["logs", "log"],
369
+ ["correlatedTraceEvidence", "trace"],
370
+ ["processOutput", "process output"],
371
+ ["browserConsoleEvidence", "console entry"],
372
+ ["correlationIds", "correlation id"],
373
+ ["timestamps", "timestamp"],
374
+ ["verifiedFacts", "verified fact"],
375
+ ["hypotheses", "hypothesis"],
376
+ ["unavailableEvidence", "unavailable item"]
377
+ ];
378
+ const PACKET_LISTS = [
379
+ ["goal", "goal"],
380
+ ["constraints", "constraint"],
381
+ ["decisions", "decision"],
382
+ ["verifiedFindings", "verified finding"],
383
+ ["inferredFindings", "inferred finding"],
384
+ ["unresolvedQuestions", "open question"]
385
+ ];
386
+ function asRecord(value) {
387
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
388
+ }
389
+ function inlineText(value) {
390
+ let normalized = "";
391
+ for (const character of value) {
392
+ const code = character.codePointAt(0) ?? 0;
393
+ normalized += code <= 31 || code === 127 ? " " : character;
394
+ }
395
+ return normalized.replace(/\s+/gu, " ").trim();
396
+ }
397
+ function readString(record, key) {
398
+ const value = record?.[key];
399
+ return typeof value === "string" ? inlineText(value) || void 0 : void 0;
400
+ }
401
+ function readNumber(record, key) {
402
+ const value = record?.[key];
403
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
404
+ }
405
+ function listLength(record, key) {
406
+ const value = record[key];
407
+ return Array.isArray(value) ? value.length : 0;
408
+ }
409
+ function plural(count, singular) {
410
+ if (count === 1) return singular;
411
+ if (singular.endsWith("y")) return `${singular.slice(0, -1)}ies`;
412
+ return `${singular}s`;
413
+ }
414
+ function preview(value) {
415
+ if (!value) return void 0;
416
+ return value.length > PREVIEW_LENGTH ? `${value.slice(0, 69)}…` : value;
417
+ }
418
+ function countMetadata(args, lists) {
419
+ return lists.flatMap(([key, label]) => {
420
+ const count = listLength(args, key);
421
+ return count > 0 ? [`${count} ${plural(count, label)}`] : [];
422
+ });
423
+ }
424
+ function line(text, tone, extra = {}) {
425
+ return {
426
+ text,
427
+ tone,
428
+ ...extra
429
+ };
430
+ }
431
+ function outputText(result) {
432
+ if (!result) return "";
433
+ return result.content.flatMap((item) => {
434
+ const record = asRecord(item);
435
+ return record?.type === "text" && typeof record.text === "string" ? [record.text] : [];
436
+ }).join("\n");
437
+ }
438
+ function bodyLines(text, expanded) {
439
+ const all = text.split("\n").map((entry) => entry.trimEnd()).filter((entry) => entry.length > 0);
440
+ const shown = expanded ? all : all.slice(0, COLLAPSED_BODY_LINES);
441
+ const lines = shown.map((entry) => line(entry, "text"));
442
+ if (all.length > shown.length) lines.push(line(`… ${all.length - shown.length} more lines`, "dim"));
443
+ return lines;
444
+ }
445
+ /** The header beside the tool name: what the call is for and how much it carries. */
446
+ function planCallSummary(toolName, args) {
447
+ if (toolName === "record_debug_evidence") {
448
+ const issue = preview(readString(args, "issue"));
449
+ return {
450
+ action: "record evidence",
451
+ ...issue ? { detail: issue } : {},
452
+ metadata: countMetadata(args, EVIDENCE_LISTS)
453
+ };
454
+ }
455
+ if (toolName === "run_fable_plan") {
456
+ const metadata = countMetadata(args, PACKET_LISTS);
457
+ if (readString(args, "currentPlan")) metadata.push("with current plan");
458
+ return {
459
+ action: "fable draft",
460
+ metadata
461
+ };
462
+ }
463
+ if (toolName === "write_plan") return {
464
+ action: "save plan",
465
+ metadata: []
466
+ };
467
+ const decision = readString(args, "decision");
468
+ return {
469
+ action: decision ? `decide ${decision}` : "request approval",
470
+ metadata: []
471
+ };
472
+ }
473
+ function evidenceLines(args, result, options) {
474
+ const lines = [asRecord(result?.details)?.recorded === true ? line("✓ evidence recorded as planning context", "success") : line(`○ ${inlineText(outputText(result)) || "not recorded"}`, "muted")];
475
+ if (!options.expanded) return lines;
476
+ for (const [key, label] of [
477
+ ["issue", "issue"],
478
+ ["expectedBehavior", "expected"],
479
+ ["reproductionAttempt", "reproduction"],
480
+ ["actualBehavior", "actual"]
481
+ ]) {
482
+ const value = readString(args, key);
483
+ if (value) lines.push(line(`${label} ${value}`, "text", { label }));
484
+ }
485
+ for (const [key, label] of EVIDENCE_LISTS) {
486
+ const raw = args[key];
487
+ const items = Array.isArray(raw) ? raw.filter((item) => typeof item === "string") : [];
488
+ if (items.length === 0) continue;
489
+ lines.push(line(plural(items.length, label), "hi", { bold: true }));
490
+ lines.push(...items.map((item) => line(inlineText(item), "text", { indent: true })));
491
+ }
492
+ return lines;
493
+ }
494
+ function fableLines(result, options) {
495
+ const details = asRecord(result?.details);
496
+ const text = outputText(result);
497
+ if (details?.started !== true) {
498
+ const code = readString(details, "errorCode");
499
+ return [line(`○ ${inlineText(text) || "fable planning did not start"}${code ? ` · ${code}` : ""}`, "muted")];
500
+ }
501
+ const status = readString(details, "status") ?? "unknown";
502
+ const draft = typeof details?.draft === "string" ? details.draft : void 0;
503
+ const code = readString(details, "errorCode");
504
+ if (!draft) return [line(`✗ fable planning ${status}${code ? ` · ${code}` : ""}`, "error")];
505
+ const finished = status === "completed";
506
+ return [line(`${finished ? "✓" : "!"} fable draft · ${status}${code ? ` · ${code}` : ""}`, finished ? "success" : "warning", { bold: true }), ...bodyLines(draft, options.expanded)];
507
+ }
508
+ function writeLines(result, options) {
509
+ const details = asRecord(result?.details);
510
+ const path = readString(details, "path");
511
+ if (options.isPartial) return [line(`◐ ${readString(details, "phase") ?? "checking"}${path ? ` ${path}` : ""}`, "warning")];
512
+ const duration = readNumber(details, "durationMs");
513
+ if (details?.written === true) return [line(`✓ wrote ${path ?? "the plan"}${duration === void 0 ? "" : ` · ${duration}ms`}`, "success")];
514
+ const lines = [line(`○ ${inlineText(outputText(result)) || "plan not written"}`, "muted")];
515
+ if (path) lines.push(line(`path ${path}`, "dim"));
516
+ return lines;
517
+ }
518
+ function completeLines(result) {
519
+ const text = inlineText(outputText(result));
520
+ if (asRecord(result?.details)?.exited === true) return [line(`✓ plan mode exited${text ? ` · ${text}` : ""}`, "success")];
521
+ return [line(`○ staying in plan mode${text ? ` · ${text}` : ""}`, "muted")];
522
+ }
523
+ /** Why a plan tool call failed, as the tool said it on one line; empty when it said nothing. */
524
+ function planFailureReason(result) {
525
+ return inlineText(outputText(result));
526
+ }
527
+ /** The body of a plan tool card: the outcome line, plus the carried detail once expanded. */
528
+ function planResultLines(toolName, args, result, options) {
529
+ if (options.isError) return [line(`✗ ${planFailureReason(result) || `${toolName} failed`}`, "error")];
530
+ if (toolName === "record_debug_evidence") return evidenceLines(args, result, options);
531
+ if (toolName === "run_fable_plan") {
532
+ if (options.isPartial) return [line("◐ drafting with the local Fable broker", "warning")];
533
+ return fableLines(result, options);
534
+ }
535
+ if (toolName === "write_plan") return writeLines(result, options);
536
+ if (options.isPartial) return [line("◐ waiting for the review decision", "warning")];
537
+ return completeLines(result);
538
+ }
539
+ //#endregion
540
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_components/PlanToolMessage.native.tsx
541
+ /**
542
+ * The plan tools' timeline item on native, as the web's: the plan action as
543
+ * the title, the issue and what the packet carries beside it on one line, and
544
+ * the outcome line in the body (shown collapsed too, as the web does), with
545
+ * the recorded evidence or the Fable draft once expanded. A failure shows only the tool's reason; the edge and icon say it failed.
546
+ */
547
+ function PlanToolMessage({ toolName, args, result, running, isError }) {
548
+ const summary = planCallSummary(toolName, args);
549
+ const collapsed = planResultLines(toolName, args, result, {
550
+ expanded: false,
551
+ isError,
552
+ isPartial: running
553
+ });
554
+ const full = planResultLines(toolName, args, result, {
555
+ expanded: true,
556
+ isError,
557
+ isPartial: running
558
+ });
559
+ const reason = isError ? planFailureReason(result) : "";
560
+ const primary = summary.detail;
561
+ const secondary = summary.metadata;
562
+ return /* @__PURE__ */ jsx(MessageItem, {
563
+ tone: toolTone({
564
+ running,
565
+ isError
566
+ }),
567
+ expandable: !isError && full.length > collapsed.length,
568
+ children: ({ expanded }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MessageItemHeader, {
569
+ title: summary.action,
570
+ children: /* @__PURE__ */ jsxs(View, {
571
+ testID: `tool-call-${toolName}`,
572
+ style: styles.summary,
573
+ children: [primary !== void 0 ? /* @__PURE__ */ jsx(Text, {
574
+ numberOfLines: 1,
575
+ style: [styles.sans, styles.primary],
576
+ children: primary
577
+ }) : null, secondary.length > 0 ? /* @__PURE__ */ jsx(Text, {
578
+ numberOfLines: 1,
579
+ style: [styles.sans, styles.secondary],
580
+ children: primary !== void 0 ? `· ${secondary.join(" · ")}` : secondary.join(" · ")
581
+ }) : null]
582
+ })
583
+ }), isError ? reason.length > 0 ? /* @__PURE__ */ jsx(MessageItemBody, {
584
+ testID: `tool-result-${toolName}`,
585
+ children: /* @__PURE__ */ jsx(Text, {
586
+ selectable: true,
587
+ style: [styles.sans, styles.error],
588
+ children: reason
589
+ })
590
+ }) : null : expanded && toolName === "record_debug_evidence" && full.length > 1 ? /* @__PURE__ */ jsx(MessageItemBody, {
591
+ testID: `tool-result-${toolName}`,
592
+ children: /* @__PURE__ */ jsx(EvidenceBody, { lines: full })
593
+ }) : (expanded ? full : collapsed).length > 0 ? /* @__PURE__ */ jsx(MessageItemBody, {
594
+ testID: `tool-result-${toolName}`,
595
+ children: /* @__PURE__ */ jsx(View, {
596
+ style: styles.lines,
597
+ children: (expanded ? full : collapsed).map((entry, index) => /* @__PURE__ */ jsx(ToneLine, { entry }, `${String(index)}-${entry.text}`))
598
+ })
599
+ }) : null] })
600
+ });
601
+ }
602
+ function ToneLine({ entry }) {
603
+ return /* @__PURE__ */ jsx(Text, {
604
+ selectable: true,
605
+ style: [
606
+ styles.sans,
607
+ TONE_STYLE[entry.tone],
608
+ entry.bold === true ? styles.bold : null,
609
+ entry.indent === true ? styles.indent : null
610
+ ],
611
+ children: entry.text
612
+ });
613
+ }
614
+ function evidenceGroups(lines) {
615
+ const groups = [];
616
+ for (const entry of lines) if (entry.bold === true) groups.push({
617
+ label: entry.text,
618
+ values: []
619
+ });
620
+ else if (entry.indent === true && groups.length > 0) groups[groups.length - 1]?.values.push(entry.text);
621
+ else if (entry.label !== void 0) groups.push({
622
+ label: entry.label,
623
+ values: [entry.text.slice(entry.label.length).trimStart()]
624
+ });
625
+ else groups.push({
626
+ label: entry.text,
627
+ values: []
628
+ });
629
+ return groups;
630
+ }
631
+ /** The expanded evidence: the outcome line, then each label over its values, set apart from the outcome. */
632
+ function EvidenceBody({ lines }) {
633
+ const [status, ...facts] = lines;
634
+ return /* @__PURE__ */ jsxs(View, {
635
+ style: styles.evidence,
636
+ children: [status !== void 0 ? /* @__PURE__ */ jsx(ToneLine, { entry: status }) : null, /* @__PURE__ */ jsx(View, {
637
+ style: styles.facts,
638
+ children: evidenceGroups(facts).map((group) => /* @__PURE__ */ jsxs(View, {
639
+ style: styles.group,
640
+ children: [/* @__PURE__ */ jsx(Text, {
641
+ style: styles.label,
642
+ children: group.label
643
+ }), group.values.map((value, index) => /* @__PURE__ */ jsx(Text, {
644
+ selectable: true,
645
+ style: [styles.sans, styles.text],
646
+ children: value
647
+ }, `${String(index)}-${value}`))]
648
+ }, group.label))
649
+ })]
650
+ });
651
+ }
652
+ const styles = StyleSheet.create((theme) => ({
653
+ summary: {
654
+ flex: 1,
655
+ flexDirection: "row",
656
+ alignItems: "center",
657
+ gap: theme.spacing(2),
658
+ minWidth: 0,
659
+ uni__dependencies: [0]
660
+ },
661
+ sans: {
662
+ fontFamily: fontOf(theme.fontFamily.sans),
663
+ fontSize: theme.fontSize.base,
664
+ lineHeight: theme.lineHeight.base,
665
+ uni__dependencies: [0]
666
+ },
667
+ primary: {
668
+ flexShrink: 0,
669
+ maxWidth: "70%",
670
+ color: theme.colors.text,
671
+ uni__dependencies: [0]
672
+ },
673
+ secondary: {
674
+ flexShrink: 1,
675
+ color: theme.colors.faint,
676
+ uni__dependencies: [0]
677
+ },
678
+ lines: {
679
+ gap: theme.spacing(.5),
680
+ uni__dependencies: [0]
681
+ },
682
+ evidence: {
683
+ gap: theme.spacing(3),
684
+ uni__dependencies: [0]
685
+ },
686
+ facts: {
687
+ gap: theme.spacing(3),
688
+ paddingTop: theme.spacing(3),
689
+ borderTopWidth: 1,
690
+ borderTopColor: theme.colors["border-soft"],
691
+ uni__dependencies: [0]
692
+ },
693
+ group: {
694
+ gap: theme.spacing(.5),
695
+ uni__dependencies: [0]
696
+ },
697
+ label: {
698
+ fontFamily: fontOf(theme.fontFamily.sans),
699
+ fontSize: theme.fontSize.sm,
700
+ lineHeight: theme.lineHeight.sm,
701
+ fontWeight: theme.fontWeight.semibold,
702
+ color: theme.colors.dim,
703
+ uni__dependencies: [0]
704
+ },
705
+ bold: {
706
+ fontWeight: theme.fontWeight.semibold,
707
+ uni__dependencies: [0]
708
+ },
709
+ indent: {
710
+ paddingLeft: theme.spacing(4),
711
+ uni__dependencies: [0]
712
+ },
713
+ error: {
714
+ color: theme.colors.red,
715
+ uni__dependencies: [0]
716
+ },
717
+ hi: {
718
+ color: theme.colors.hi,
719
+ uni__dependencies: [0]
720
+ },
721
+ text: {
722
+ color: theme.colors.text,
723
+ uni__dependencies: [0]
724
+ },
725
+ dim: {
726
+ color: theme.colors.dim,
727
+ uni__dependencies: [0]
728
+ },
729
+ muted: {
730
+ color: theme.colors.faint,
731
+ uni__dependencies: [0]
732
+ },
733
+ success: {
734
+ color: theme.colors.green,
735
+ uni__dependencies: [0]
736
+ },
737
+ warning: {
738
+ color: theme.colors.yellow,
739
+ uni__dependencies: [0]
740
+ },
741
+ accent: {
742
+ color: theme.colors.blue,
743
+ uni__dependencies: [0]
744
+ }
745
+ }));
746
+ /** The line tones of the web's MessageLines, drawn with the same theme tokens. */
747
+ const TONE_STYLE = {
748
+ hi: styles.hi,
749
+ text: styles.text,
750
+ dim: styles.dim,
751
+ muted: styles.muted,
752
+ success: styles.success,
753
+ error: styles.error,
754
+ warning: styles.warning,
755
+ accent: styles.accent
756
+ };
757
+ //#endregion
758
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/plan.native.tsx
759
+ var plan_native_default = defineToolRenderer({
760
+ tools: [
761
+ "record_debug_evidence",
762
+ "run_fable_plan",
763
+ "write_plan",
764
+ "complete_plan"
765
+ ],
766
+ message: PlanToolMessage
767
+ });
768
+ //#endregion
364
769
  //#region generated/native.ts
365
770
  const via = (identity, value) => value === void 0 ? void 0 : {
366
771
  ...identity,
@@ -370,13 +775,16 @@ const nativePlugin = defineNativePlugin({
370
775
  id: "plan",
371
776
  session: {
372
777
  get activityGroups() {
373
- return [via({ name: "plan" }, plan_native_default)];
778
+ return [via({ name: "plan" }, plan_native_default$1)];
374
779
  },
375
780
  get fills() {
376
781
  return [via({
377
782
  slot: "activity.plan",
378
783
  id: "plan"
379
784
  }, Plan_activity_plan_native_default)];
785
+ },
786
+ get toolRenderers() {
787
+ return [via({ tools: ["plan"] }, plan_native_default)];
380
788
  }
381
789
  }
382
790
  });