langfun 0.1.2.dev202410170804__py3-none-any.whl → 0.1.2.dev202410190803__py3-none-any.whl

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.
langfun/core/message.py CHANGED
@@ -14,8 +14,9 @@
14
14
  """Messages that are exchanged between users and agents."""
15
15
 
16
16
  import contextlib
17
+ import functools
17
18
  import io
18
- from typing import Annotated, Any, Optional, Sequence, Union
19
+ from typing import Annotated, Any, Optional, Union
19
20
 
20
21
  from langfun.core import modality
21
22
  from langfun.core import natural_language
@@ -506,53 +507,70 @@ class Message(natural_language.NaturalLanguageFormattable, pg.Object):
506
507
  v = self.metadata[key]
507
508
  return v.value if isinstance(v, pg.Ref) else v
508
509
 
509
- # pytype: disable=annotation-type-mismatch
510
510
  def _html_tree_view_content(
511
511
  self,
512
512
  *,
513
513
  view: pg.views.HtmlTreeView,
514
514
  root_path: pg.KeyPath,
515
- source_tag: str | Sequence[str] | None = pg.View.PresetArgValue(
516
- ('lm-input', 'lm-output')
517
- ),
518
- include_message_metadata: bool = pg.View.PresetArgValue(True),
519
- collapse_modalities_in_text: bool = pg.View.PresetArgValue(True),
520
- collapse_llm_usage: bool = pg.View.PresetArgValue(False),
521
- collapse_message_result_level: int | None = pg.View.PresetArgValue(1),
522
- collapse_message_metadata_level: int | None = pg.View.PresetArgValue(0),
523
- collapse_source_message_level: int | None = pg.View.PresetArgValue(1),
524
- collapse_level: int | None = pg.View.PresetArgValue(1),
515
+ collapse_level: int | None = None,
516
+ extra_flags: dict[str, Any] | None = None,
525
517
  **kwargs,
526
518
  ) -> pg.Html:
527
- # pytype: enable=annotation-type-mismatch
528
519
  """Returns the HTML representation of the message.
529
520
 
530
521
  Args:
531
522
  view: The HTML tree view.
532
523
  root_path: The root path of the message.
533
- source_tag: tags to filter source messages. If None, the entire
534
- source chain will be included.
535
- include_message_metadata: Whether to include the metadata of the message.
536
- collapse_modalities_in_text: Whether to collapse the modalities in the
537
- message text.
538
- collapse_llm_usage: Whether to collapse the usage in the message.
539
- collapse_message_result_level: The level to collapse the result in the
540
- message.
541
- collapse_message_metadata_level: The level to collapse the metadata in the
542
- message.
543
- collapse_source_message_level: The level to collapse the source in the
544
- message.
545
524
  collapse_level: The global collapse level.
546
- **kwargs: Other keyword arguments.
525
+ extra_flags: Extra flags to control the rendering.
526
+ - source_tag: tags to filter source messages. If None, the entire
527
+ source chain will be included.
528
+ - include_message_metadata: Whether to include the metadata of the
529
+ message.
530
+ - collapse_modalities_in_text: Whether to collapse the modalities in the
531
+ message text.
532
+ - collapse_llm_usage: Whether to collapse the usage in the message.
533
+ - collapse_message_result_level: The level to collapse the result in the
534
+ message.
535
+ - collapse_message_metadata_level: The level to collapse the metadata in
536
+ the message.
537
+ - collapse_source_message_level: The level to collapse the source in the
538
+ message.
539
+ - collapse_level: The global collapse level.
540
+ **kwargs: Omitted keyword arguments.
547
541
 
548
542
  Returns:
549
543
  The HTML representation of the message content.
550
544
  """
545
+ extra_flags = extra_flags if extra_flags is not None else {}
546
+
547
+ include_message_metadata: bool = extra_flags.get(
548
+ 'include_message_metadata', True
549
+ )
550
+ source_tag: str | tuple[str, ...] | None = extra_flags.get(
551
+ 'source_tag', ('lm-input', 'lm-output')
552
+ )
553
+ collapse_modalities_in_text: bool = extra_flags.get(
554
+ 'collapse_modalities_in_text', True
555
+ )
556
+ collapse_llm_usage: bool = extra_flags.get(
557
+ 'collapse_llm_usage', False
558
+ )
559
+ collapse_message_result_level: int | None = extra_flags.get(
560
+ 'collapse_message_result_level', 1
561
+ )
562
+ collapse_message_metadata_level: int | None = extra_flags.get(
563
+ 'collapse_message_metadata_level', 1
564
+ )
565
+ collapse_source_message_level: int | None = extra_flags.get(
566
+ 'collapse_source_message_level', 1
567
+ )
568
+ passthrough_kwargs = view.get_passthrough_kwargs(**kwargs)
551
569
  def render_tags():
552
570
  return pg.Html.element(
553
571
  'div',
554
572
  [pg.Html.element('span', [tag]) for tag in self.tags],
555
- css_class=['message-tags'],
573
+ css_classes=['message-tags'],
556
574
  )
557
575
 
558
576
  def render_message_text():
@@ -573,12 +591,16 @@ class Message(natural_language.NaturalLanguageFormattable, pg.Object):
573
591
  chunk,
574
592
  name=chunk.referred_name,
575
593
  root_path=child_path,
576
- collapse_level=child_path.depth + (
594
+ collapse_level=(
577
595
  0 if collapse_modalities_in_text else 1
578
- )
596
+ ),
597
+ extra_flags=dict(
598
+ display_modality_when_hover=True,
599
+ ),
600
+ **passthrough_kwargs,
579
601
  )
580
602
  ],
581
- css_class=['modality-in-text'],
603
+ css_classes=['modality-in-text'],
582
604
  )
583
605
  )
584
606
  referred_chunks[chunk.referred_name] = chunk
@@ -596,14 +618,15 @@ class Message(natural_language.NaturalLanguageFormattable, pg.Object):
596
618
  self.result,
597
619
  name='result',
598
620
  root_path=child_path,
599
- collapse_level=view.max_collapse_level(
600
- collapse_level,
621
+ collapse_level=view.get_collapse_level(
622
+ (collapse_level, -1),
601
623
  collapse_message_result_level,
602
- child_path,
603
- )
624
+ ),
625
+ extra_flags=extra_flags,
626
+ **passthrough_kwargs,
604
627
  )
605
628
  ],
606
- css_class=['message-result'],
629
+ css_classes=['message-result'],
607
630
  )
608
631
 
609
632
  def render_usage():
@@ -616,15 +639,19 @@ class Message(natural_language.NaturalLanguageFormattable, pg.Object):
616
639
  view.render(
617
640
  self.usage,
618
641
  name='llm usage',
642
+ key_style='label',
619
643
  root_path=child_path,
620
- collapse_level=view.max_collapse_level(
621
- collapse_level,
644
+ collapse_level=view.get_collapse_level(
645
+ (collapse_level, -1),
622
646
  0 if collapse_llm_usage else 1,
623
- child_path,
624
- )
647
+ ),
648
+ extra_flags=extra_flags,
649
+ **view.get_passthrough_kwargs(
650
+ remove=['key_style'], **kwargs
651
+ ),
625
652
  )
626
653
  ],
627
- css_class=['message-usage'],
654
+ css_classes=['message-usage'],
628
655
  )
629
656
 
630
657
  def render_source_message():
@@ -635,21 +662,22 @@ class Message(natural_language.NaturalLanguageFormattable, pg.Object):
635
662
  source = source.source
636
663
  if source is not None:
637
664
  child_path = root_path + 'source'
665
+ child_extra_flags = extra_flags.copy()
666
+ child_extra_flags['collapse_source_message_level'] = (
667
+ view.get_collapse_level(
668
+ (collapse_source_message_level, -1), 0,
669
+ )
670
+ )
638
671
  return view.render(
639
672
  self.source,
640
673
  name='source',
641
674
  root_path=child_path,
642
- include_metadata=include_message_metadata,
643
- collapse_level=view.max_collapse_level(
644
- collapse_level,
675
+ collapse_level=view.get_collapse_level(
676
+ (collapse_level, -1),
645
677
  collapse_source_message_level,
646
- child_path
647
678
  ),
648
- collapse_source_level=max(0, collapse_source_message_level - 1),
649
- collapse_modalities=collapse_modalities_in_text,
650
- collapse_usage=collapse_llm_usage,
651
- collapse_metadata_level=collapse_message_metadata_level,
652
- collapse_result_level=collapse_message_result_level,
679
+ extra_flags=child_extra_flags,
680
+ **passthrough_kwargs,
653
681
  )
654
682
  return None
655
683
 
@@ -662,17 +690,20 @@ class Message(natural_language.NaturalLanguageFormattable, pg.Object):
662
690
  [
663
691
  view.render(
664
692
  self.metadata,
665
- css_class=['message-metadata'],
693
+ css_classes=['message-metadata'],
694
+ exclude_keys=['usage', 'result'],
666
695
  name='metadata',
667
696
  root_path=child_path,
668
- collapse_level=view.max_collapse_level(
669
- collapse_level,
697
+ collapse_level=view.get_collapse_level(
698
+ (collapse_level, -1),
670
699
  collapse_message_metadata_level,
671
- child_path,
672
- )
700
+ ),
701
+ **view.get_passthrough_kwargs(
702
+ remove=['exclude_keys'], **kwargs
703
+ ),
673
704
  )
674
705
  ],
675
- css_class=['message-metadata'],
706
+ css_classes=['message-metadata'],
676
707
  )
677
708
 
678
709
  return pg.Html.element(
@@ -685,18 +716,30 @@ class Message(natural_language.NaturalLanguageFormattable, pg.Object):
685
716
  render_metadata(),
686
717
  render_source_message(),
687
718
  ],
688
- css_class=['complex_value'],
719
+ css_classes=['complex_value'],
720
+ )
721
+
722
+ @classmethod
723
+ @functools.cache
724
+ def _html_tree_view_config(cls) -> dict[str, Any]:
725
+ return pg.views.HtmlTreeView.get_kwargs(
726
+ super()._html_tree_view_config(),
727
+ dict(
728
+ css_classes=['lf-message'],
729
+ )
689
730
  )
690
731
 
691
- def _html_style(self) -> list[str]:
692
- return super()._html_style() + [
732
+ @classmethod
733
+ @functools.cache
734
+ def _html_tree_view_css_styles(cls) -> list[str]:
735
+ return super()._html_tree_view_css_styles() + [
693
736
  """
694
737
  /* Langfun Message styles.*/
695
738
  [class^="message-"] > details {
696
739
  margin: 0px 0px 5px 0px;
697
740
  border: 1px solid #EEE;
698
741
  }
699
- details.lf-message > summary > .summary_title::after {
742
+ .lf-message.summary-title::after {
700
743
  content: ' 💬';
701
744
  }
702
745
  details.pyglove.ai-message {
@@ -739,12 +782,12 @@ class Message(natural_language.NaturalLanguageFormattable, pg.Object):
739
782
  margin: 0px 5px 0px 5px;
740
783
  }
741
784
  .message-result {
742
- color: purple;
785
+ color: dodgerblue;
743
786
  }
744
787
  .message-usage {
745
788
  color: orange;
746
789
  }
747
- .message-usage .object_key.str {
790
+ .message-usage .object-key.str {
748
791
  border: 1px solid orange;
749
792
  background-color: orange;
750
793
  color: white;
@@ -752,9 +795,6 @@ class Message(natural_language.NaturalLanguageFormattable, pg.Object):
752
795
  """
753
796
  ]
754
797
 
755
- def _html_element_class(self) -> list[str]:
756
- return super()._html_element_class() + ['lf-message']
757
-
758
798
 
759
799
  #
760
800
  # Messages of different roles.
@@ -345,13 +345,80 @@ class MessageTest(unittest.TestCase):
345
345
  print(actual)
346
346
  self.assertEqual(actual, expected)
347
347
 
348
+ def test_html_style(self):
349
+ self.assertIn(
350
+ inspect.cleandoc(
351
+ """
352
+ /* Langfun Message styles.*/
353
+ [class^="message-"] > details {
354
+ margin: 0px 0px 5px 0px;
355
+ border: 1px solid #EEE;
356
+ }
357
+ .lf-message.summary-title::after {
358
+ content: ' 💬';
359
+ }
360
+ details.pyglove.ai-message {
361
+ border: 1px solid blue;
362
+ color: blue;
363
+ }
364
+ details.pyglove.user-message {
365
+ border: 1px solid green;
366
+ color: green;
367
+ }
368
+ .message-tags {
369
+ margin: 5px 0px 5px 0px;
370
+ font-size: .8em;
371
+ }
372
+ .message-tags > span {
373
+ border-radius: 5px;
374
+ background-color: #CCC;
375
+ padding: 3px;
376
+ margin: 0px 2px 0px 2px;
377
+ color: white;
378
+ }
379
+ .message-text {
380
+ padding: 20px;
381
+ margin: 10px 5px 10px 5px;
382
+ font-style: italic;
383
+ font-size: 1.1em;
384
+ white-space: pre-wrap;
385
+ border: 1px solid #EEE;
386
+ border-radius: 5px;
387
+ background-color: #EEE;
388
+ }
389
+ .modality-in-text {
390
+ display: inline-block;
391
+ }
392
+ .modality-in-text > details {
393
+ display: inline-block;
394
+ font-size: 0.8em;
395
+ border: 0;
396
+ background-color: #A6F1A6;
397
+ margin: 0px 5px 0px 5px;
398
+ }
399
+ .message-result {
400
+ color: dodgerblue;
401
+ }
402
+ .message-usage {
403
+ color: orange;
404
+ }
405
+ .message-usage .object-key.str {
406
+ border: 1px solid orange;
407
+ background-color: orange;
408
+ color: white;
409
+ }
410
+ """
411
+ ),
412
+ message.UserMessage('hi').to_html().style_section,
413
+ )
414
+
348
415
  def test_html_user_message(self):
349
416
  self.assert_html_content(
350
417
  message.UserMessage(
351
418
  'what is a <div>'
352
419
  ).to_html(enable_summary_tooltip=False),
353
420
  """
354
- <details open class="pyglove user-message lf-message"><summary><div class="summary_title">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"></div><div class="message-text">what is a &lt;div&gt;</div><div class="message-metadata"><details class="pyglove dict"><summary><div class="summary_name">metadata</div><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict message-metadata"><span class="empty_container"></span></div></details></div></div></details>
421
+ <details open class="pyglove user-message lf-message"><summary><div class="summary-title lf-message">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"></div><div class="message-text">what is a &lt;div&gt;</div><div class="message-metadata"><details open class="pyglove dict message-metadata"><summary><div class="summary-name message-metadata">metadata<span class="tooltip message-metadata">metadata</span></div><div class="summary-title message-metadata">Dict(...)</div></summary><div class="complex-value dict"><span class="empty-container"></span></div></details></div></div></details>
355
422
  """
356
423
  )
357
424
  self.assert_html_content(
@@ -359,9 +426,12 @@ class MessageTest(unittest.TestCase):
359
426
  'what is this <<[[image]]>>',
360
427
  tags=['lm-input'],
361
428
  image=CustomModality('bird')
362
- ).to_html(enable_summary_tooltip=False, include_message_metadata=False),
429
+ ).to_html(
430
+ enable_summary_tooltip=False,
431
+ extra_flags=dict(include_message_metadata=False)
432
+ ),
363
433
  """
364
- <details open class="pyglove user-message lf-message"><summary><div class="summary_title">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>lm-input</span></div><div class="message-text">what is this<div class="modality-in-text"><details class="pyglove custom-modality"><summary><div class="summary_name">image</div><div class="summary_title">CustomModality(...)</div></summary><div class="complex_value custom-modality"><table><tr><td><span class="object_key str">content</span><span class="tooltip key-path">metadata.image.content</span></td><td><div><span class="simple_value str">&#x27;bird&#x27;</span></div></td></tr></table></div></details></div></div></div></details>
434
+ <details open class="pyglove user-message lf-message"><summary><div class="summary-title lf-message">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>lm-input</span></div><div class="message-text">what is this<div class="modality-in-text"><details class="pyglove custom-modality"><summary><div class="summary-name">image<span class="tooltip">metadata.image</span></div><div class="summary-title">CustomModality(...)</div></summary><div class="complex-value custom-modality"><details open class="pyglove str"><summary><div class="summary-name">content<span class="tooltip">metadata.image.content</span></div><div class="summary-title">str</div></summary><span class="simple-value str">&#x27;bird&#x27;</span></details></div></details></div></div></div></details>
365
435
  """
366
436
  )
367
437
 
@@ -385,21 +455,41 @@ class MessageTest(unittest.TestCase):
385
455
  self.assert_html_content(
386
456
  ai_message.to_html(enable_summary_tooltip=False),
387
457
  """
388
- <details open class="pyglove ai-message lf-message"><summary><div class="summary_title">AIMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>lm-response</span><span>lm-output</span></div><div class="message-text">My name is Gemini</div><div class="message-result"><details open class="pyglove dict"><summary><div class="summary_name">result</div><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">x</span><span class="tooltip key-path">metadata.result.x</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">y</span><span class="tooltip key-path">metadata.result.y</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">z</span><span class="tooltip key-path">metadata.result.z</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">a</span><span class="tooltip key-path">metadata.result.z.a</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">List(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">metadata.result.z.a[0]</span></td><td><div><span class="simple_value int">12</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">metadata.result.z.a[1]</span></td><td><div><span class="simple_value int">323</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div></details></div><div class="message-usage"><details open class="pyglove lm-sampling-usage"><summary><div class="summary_name">llm usage</div><div class="summary_title">LMSamplingUsage(...)</div></summary><div class="complex_value lm-sampling-usage"><table><tr><td><span class="object_key str">prompt_tokens</span><span class="tooltip key-path">metadata.usage.prompt_tokens</span></td><td><div><span class="simple_value int">10</span></div></td></tr><tr><td><span class="object_key str">completion_tokens</span><span class="tooltip key-path">metadata.usage.completion_tokens</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">total_tokens</span><span class="tooltip key-path">metadata.usage.total_tokens</span></td><td><div><span class="simple_value int">12</span></div></td></tr><tr><td><span class="object_key str">num_requests</span><span class="tooltip key-path">metadata.usage.num_requests</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">estimated_cost</span><span class="tooltip key-path">metadata.usage.estimated_cost</span></td><td><div><span class="simple_value none-type">None</span></div></td></tr></table></div></details></div><div class="message-metadata"><details class="pyglove dict"><summary><div class="summary_name">metadata</div><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict message-metadata"><table><tr><td><span class="object_key str">result</span><span class="tooltip key-path">metadata.result</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict message-metadata"><table><tr><td><span class="object_key str">x</span><span class="tooltip key-path">metadata.result.x</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">y</span><span class="tooltip key-path">metadata.result.y</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">z</span><span class="tooltip key-path">metadata.result.z</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict message-metadata"><table><tr><td><span class="object_key str">a</span><span class="tooltip key-path">metadata.result.z.a</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">List(...)</div></summary><div class="complex_value list message-metadata"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">metadata.result.z.a[0]</span></td><td><div><span class="simple_value int">12</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">metadata.result.z.a[1]</span></td><td><div><span class="simple_value int">323</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key str">usage</span><span class="tooltip key-path">metadata.usage</span></td><td><div><details class="pyglove lm-sampling-usage"><summary><div class="summary_title">LMSamplingUsage(...)</div></summary><div class="complex_value lm-sampling-usage message-metadata"><table><tr><td><span class="object_key str">prompt_tokens</span><span class="tooltip key-path">metadata.usage.prompt_tokens</span></td><td><div><span class="simple_value int">10</span></div></td></tr><tr><td><span class="object_key str">completion_tokens</span><span class="tooltip key-path">metadata.usage.completion_tokens</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">total_tokens</span><span class="tooltip key-path">metadata.usage.total_tokens</span></td><td><div><span class="simple_value int">12</span></div></td></tr><tr><td><span class="object_key str">num_requests</span><span class="tooltip key-path">metadata.usage.num_requests</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">estimated_cost</span><span class="tooltip key-path">metadata.usage.estimated_cost</span></td><td><div><span class="simple_value none-type">None</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div><details open class="pyglove user-message lf-message"><summary><div class="summary_name">source</div><div class="summary_title">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>lm-input</span></div><div class="message-text">What is in this image?<div class="modality-in-text"><details class="pyglove custom-modality"><summary><div class="summary_name">image</div><div class="summary_title">CustomModality(...)</div></summary><div class="complex_value custom-modality"><table><tr><td><span class="object_key str">content</span><span class="tooltip key-path">source.metadata.image.content</span></td><td><div><span class="simple_value str">&#x27;foo&#x27;</span></div></td></tr></table></div></details></div>this is a test</div><div class="message-metadata"><details class="pyglove dict"><summary><div class="summary_name">metadata</div><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict message-metadata"><table><tr><td><span class="object_key str">image</span><span class="tooltip key-path">source.metadata.image</span></td><td><div><details class="pyglove custom-modality"><summary><div class="summary_title">CustomModality(...)</div></summary><div class="complex_value custom-modality message-metadata"><table><tr><td><span class="object_key str">content</span><span class="tooltip key-path">source.metadata.image.content</span></td><td><div><span class="simple_value str">&#x27;foo&#x27;</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></div></details></div></details>
458
+ <details open class="pyglove ai-message lf-message"><summary><div class="summary-title lf-message">AIMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>lm-response</span><span>lm-output</span></div><div class="message-text">My name is Gemini</div><div class="message-result"><details open class="pyglove dict"><summary><div class="summary-name">result<span class="tooltip">metadata.result</span></div><div class="summary-title">Dict(...)</div></summary><div class="complex-value dict"><details open class="pyglove int"><summary><div class="summary-name">x<span class="tooltip">metadata.result.x</span></div><div class="summary-title">int</div></summary><span class="simple-value int">1</span></details><details open class="pyglove int"><summary><div class="summary-name">y<span class="tooltip">metadata.result.y</span></div><div class="summary-title">int</div></summary><span class="simple-value int">2</span></details><details class="pyglove dict"><summary><div class="summary-name">z<span class="tooltip">metadata.result.z</span></div><div class="summary-title">Dict(...)</div></summary><div class="complex-value dict"><details class="pyglove list"><summary><div class="summary-name">a<span class="tooltip">metadata.result.z.a</span></div><div class="summary-title">List(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">metadata.result.z.a[0]</span></td><td><span class="simple-value int">12</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">metadata.result.z.a[1]</span></td><td><span class="simple-value int">323</span></td></tr></table></div></details></div></details></div></details></div><div class="message-usage"><details open class="pyglove lm-sampling-usage"><summary><div class="summary-name">llm usage<span class="tooltip">metadata.usage</span></div><div class="summary-title">LMSamplingUsage(...)</div></summary><div class="complex-value lm-sampling-usage"><table><tr><td><span class="object-key str">prompt_tokens</span><span class="tooltip">metadata.usage.prompt_tokens</span></td><td><span class="simple-value int">10</span></td></tr><tr><td><span class="object-key str">completion_tokens</span><span class="tooltip">metadata.usage.completion_tokens</span></td><td><span class="simple-value int">2</span></td></tr><tr><td><span class="object-key str">total_tokens</span><span class="tooltip">metadata.usage.total_tokens</span></td><td><span class="simple-value int">12</span></td></tr><tr><td><span class="object-key str">num_requests</span><span class="tooltip">metadata.usage.num_requests</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key str">estimated_cost</span><span class="tooltip">metadata.usage.estimated_cost</span></td><td><span class="simple-value none-type">None</span></td></tr></table></div></details></div><div class="message-metadata"><details open class="pyglove dict message-metadata"><summary><div class="summary-name message-metadata">metadata<span class="tooltip message-metadata">metadata</span></div><div class="summary-title message-metadata">Dict(...)</div></summary><div class="complex-value dict"><span class="empty-container"></span></div></details></div><details open class="pyglove user-message lf-message"><summary><div class="summary-name lf-message">source<span class="tooltip lf-message">source</span></div><div class="summary-title lf-message">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>lm-input</span></div><div class="message-text">What is in this image?<div class="modality-in-text"><details class="pyglove custom-modality"><summary><div class="summary-name">image<span class="tooltip">source.metadata.image</span></div><div class="summary-title">CustomModality(...)</div></summary><div class="complex-value custom-modality"><details open class="pyglove str"><summary><div class="summary-name">content<span class="tooltip">source.metadata.image.content</span></div><div class="summary-title">str</div></summary><span class="simple-value str">&#x27;foo&#x27;</span></details></div></details></div>this is a test</div><div class="message-metadata"><details open class="pyglove dict message-metadata"><summary><div class="summary-name message-metadata">metadata<span class="tooltip message-metadata">source.metadata</span></div><div class="summary-title message-metadata">Dict(...)</div></summary><div class="complex-value dict"><details class="pyglove custom-modality"><summary><div class="summary-name">image<span class="tooltip">source.metadata.image</span></div><div class="summary-title">CustomModality(...)</div></summary><div class="complex-value custom-modality"><details open class="pyglove str"><summary><div class="summary-name">content<span class="tooltip">source.metadata.image.content</span></div><div class="summary-title">str</div></summary><span class="simple-value str">&#x27;foo&#x27;</span></details></div></details></div></details></div></div></details></div></details>
459
+ """
460
+ )
461
+ self.assert_html_content(
462
+ ai_message.to_html(
463
+ key_style='label',
464
+ enable_summary_tooltip=False,
465
+ extra_flags=dict(
466
+ collapse_modalities_in_text=False,
467
+ collapse_llm_usage=True,
468
+ collapse_message_result_level=0,
469
+ collapse_message_metadata_level=0,
470
+ collapse_source_message_level=0,
471
+ source_tag=None,
472
+ ),
473
+ ),
474
+ """
475
+ <details open class="pyglove ai-message lf-message"><summary><div class="summary-title lf-message">AIMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>lm-response</span><span>lm-output</span></div><div class="message-text">My name is Gemini</div><div class="message-result"><details class="pyglove dict"><summary><div class="summary-name">result<span class="tooltip">metadata.result</span></div><div class="summary-title">Dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str">x</span><span class="tooltip">metadata.result.x</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key str">y</span><span class="tooltip">metadata.result.y</span></td><td><span class="simple-value int">2</span></td></tr><tr><td><span class="object-key str">z</span><span class="tooltip">metadata.result.z</span></td><td><details class="pyglove dict"><summary><div class="summary-title">Dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str">a</span><span class="tooltip">metadata.result.z.a</span></td><td><details class="pyglove list"><summary><div class="summary-title">List(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">metadata.result.z.a[0]</span></td><td><span class="simple-value int">12</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">metadata.result.z.a[1]</span></td><td><span class="simple-value int">323</span></td></tr></table></div></details></td></tr></table></div></details></td></tr></table></div></details></div><div class="message-usage"><details class="pyglove lm-sampling-usage"><summary><div class="summary-name">llm usage<span class="tooltip">metadata.usage</span></div><div class="summary-title">LMSamplingUsage(...)</div></summary><div class="complex-value lm-sampling-usage"><table><tr><td><span class="object-key str">prompt_tokens</span><span class="tooltip">metadata.usage.prompt_tokens</span></td><td><span class="simple-value int">10</span></td></tr><tr><td><span class="object-key str">completion_tokens</span><span class="tooltip">metadata.usage.completion_tokens</span></td><td><span class="simple-value int">2</span></td></tr><tr><td><span class="object-key str">total_tokens</span><span class="tooltip">metadata.usage.total_tokens</span></td><td><span class="simple-value int">12</span></td></tr><tr><td><span class="object-key str">num_requests</span><span class="tooltip">metadata.usage.num_requests</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key str">estimated_cost</span><span class="tooltip">metadata.usage.estimated_cost</span></td><td><span class="simple-value none-type">None</span></td></tr></table></div></details></div><div class="message-metadata"><details class="pyglove dict message-metadata"><summary><div class="summary-name message-metadata">metadata<span class="tooltip message-metadata">metadata</span></div><div class="summary-title message-metadata">Dict(...)</div></summary><div class="complex-value dict"><span class="empty-container"></span></div></details></div><details class="pyglove user-message lf-message"><summary><div class="summary-name lf-message">source<span class="tooltip lf-message">source</span></div><div class="summary-title lf-message">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>lm-input</span></div><div class="message-text">What is in this image?<div class="modality-in-text"><details open class="pyglove custom-modality"><summary><div class="summary-name">image<span class="tooltip">source.metadata.image</span></div><div class="summary-title">CustomModality(...)</div></summary><div class="complex-value custom-modality"><table><tr><td><span class="object-key str">content</span><span class="tooltip">source.metadata.image.content</span></td><td><span class="simple-value str">&#x27;foo&#x27;</span></td></tr></table></div></details></div>this is a test</div><div class="message-metadata"><details class="pyglove dict message-metadata"><summary><div class="summary-name message-metadata">metadata<span class="tooltip message-metadata">source.metadata</span></div><div class="summary-title message-metadata">Dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str">image</span><span class="tooltip">source.metadata.image</span></td><td><details class="pyglove custom-modality"><summary><div class="summary-title">CustomModality(...)</div></summary><div class="complex-value custom-modality"><table><tr><td><span class="object-key str">content</span><span class="tooltip">source.metadata.image.content</span></td><td><span class="simple-value str">&#x27;foo&#x27;</span></td></tr></table></div></details></td></tr></table></div></details></div><details class="pyglove user-message lf-message"><summary><div class="summary-name lf-message">source<span class="tooltip lf-message">source.source</span></div><div class="summary-title lf-message">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"></div><div class="message-text">User input</div><div class="message-metadata"><details class="pyglove dict message-metadata"><summary><div class="summary-name message-metadata">metadata<span class="tooltip message-metadata">source.source.metadata</span></div><div class="summary-title message-metadata">Dict(...)</div></summary><div class="complex-value dict"><span class="empty-container"></span></div></details></div></div></details></div></details></div></details>
389
476
  """
390
477
  )
391
478
  self.assert_html_content(
392
479
  ai_message.to_html(
480
+ key_style='label',
393
481
  enable_summary_tooltip=False,
394
- collapse_modalities_in_text=False,
395
- collapse_llm_usage=True,
396
- collapse_message_result_level=0,
397
- collapse_message_metadata_level=0,
398
- collapse_source_message_level=0,
399
- source_tag=None,
482
+ extra_flags=dict(
483
+ collapse_modalities_in_text=True,
484
+ collapse_llm_usage=False,
485
+ collapse_message_result_level=1,
486
+ collapse_message_metadata_level=1,
487
+ collapse_source_message_level=2,
488
+ source_tag=None,
489
+ ),
400
490
  ),
401
491
  """
402
- <details open class="pyglove ai-message lf-message"><summary><div class="summary_title">AIMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>lm-response</span><span>lm-output</span></div><div class="message-text">My name is Gemini</div><div class="message-result"><details class="pyglove dict"><summary><div class="summary_name">result</div><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">x</span><span class="tooltip key-path">metadata.result.x</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">y</span><span class="tooltip key-path">metadata.result.y</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">z</span><span class="tooltip key-path">metadata.result.z</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict"><table><tr><td><span class="object_key str">a</span><span class="tooltip key-path">metadata.result.z.a</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">List(...)</div></summary><div class="complex_value list"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">metadata.result.z.a[0]</span></td><td><div><span class="simple_value int">12</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">metadata.result.z.a[1]</span></td><td><div><span class="simple_value int">323</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div></details></div><div class="message-usage"><details class="pyglove lm-sampling-usage"><summary><div class="summary_name">llm usage</div><div class="summary_title">LMSamplingUsage(...)</div></summary><div class="complex_value lm-sampling-usage"><table><tr><td><span class="object_key str">prompt_tokens</span><span class="tooltip key-path">metadata.usage.prompt_tokens</span></td><td><div><span class="simple_value int">10</span></div></td></tr><tr><td><span class="object_key str">completion_tokens</span><span class="tooltip key-path">metadata.usage.completion_tokens</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">total_tokens</span><span class="tooltip key-path">metadata.usage.total_tokens</span></td><td><div><span class="simple_value int">12</span></div></td></tr><tr><td><span class="object_key str">num_requests</span><span class="tooltip key-path">metadata.usage.num_requests</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">estimated_cost</span><span class="tooltip key-path">metadata.usage.estimated_cost</span></td><td><div><span class="simple_value none-type">None</span></div></td></tr></table></div></details></div><div class="message-metadata"><details class="pyglove dict"><summary><div class="summary_name">metadata</div><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict message-metadata"><table><tr><td><span class="object_key str">result</span><span class="tooltip key-path">metadata.result</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict message-metadata"><table><tr><td><span class="object_key str">x</span><span class="tooltip key-path">metadata.result.x</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">y</span><span class="tooltip key-path">metadata.result.y</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">z</span><span class="tooltip key-path">metadata.result.z</span></td><td><div><details class="pyglove dict"><summary><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict message-metadata"><table><tr><td><span class="object_key str">a</span><span class="tooltip key-path">metadata.result.z.a</span></td><td><div><details class="pyglove list"><summary><div class="summary_title">List(...)</div></summary><div class="complex_value list message-metadata"><table><tr><td><span class="object_key int">0</span><span class="tooltip key-path">metadata.result.z.a[0]</span></td><td><div><span class="simple_value int">12</span></div></td></tr><tr><td><span class="object_key int">1</span><span class="tooltip key-path">metadata.result.z.a[1]</span></td><td><div><span class="simple_value int">323</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr></table></div></details></div></td></tr><tr><td><span class="object_key str">usage</span><span class="tooltip key-path">metadata.usage</span></td><td><div><details class="pyglove lm-sampling-usage"><summary><div class="summary_title">LMSamplingUsage(...)</div></summary><div class="complex_value lm-sampling-usage message-metadata"><table><tr><td><span class="object_key str">prompt_tokens</span><span class="tooltip key-path">metadata.usage.prompt_tokens</span></td><td><div><span class="simple_value int">10</span></div></td></tr><tr><td><span class="object_key str">completion_tokens</span><span class="tooltip key-path">metadata.usage.completion_tokens</span></td><td><div><span class="simple_value int">2</span></div></td></tr><tr><td><span class="object_key str">total_tokens</span><span class="tooltip key-path">metadata.usage.total_tokens</span></td><td><div><span class="simple_value int">12</span></div></td></tr><tr><td><span class="object_key str">num_requests</span><span class="tooltip key-path">metadata.usage.num_requests</span></td><td><div><span class="simple_value int">1</span></div></td></tr><tr><td><span class="object_key str">estimated_cost</span><span class="tooltip key-path">metadata.usage.estimated_cost</span></td><td><div><span class="simple_value none-type">None</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div><details class="pyglove user-message lf-message"><summary><div class="summary_name">source</div><div class="summary_title">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>lm-input</span></div><div class="message-text">What is in this image?<div class="modality-in-text"><details open class="pyglove custom-modality"><summary><div class="summary_name">image</div><div class="summary_title">CustomModality(...)</div></summary><div class="complex_value custom-modality"><table><tr><td><span class="object_key str">content</span><span class="tooltip key-path">source.metadata.image.content</span></td><td><div><span class="simple_value str">&#x27;foo&#x27;</span></div></td></tr></table></div></details></div>this is a test</div><div class="message-metadata"><details class="pyglove dict"><summary><div class="summary_name">metadata</div><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict message-metadata"><table><tr><td><span class="object_key str">image</span><span class="tooltip key-path">source.metadata.image</span></td><td><div><details class="pyglove custom-modality"><summary><div class="summary_title">CustomModality(...)</div></summary><div class="complex_value custom-modality message-metadata"><table><tr><td><span class="object_key str">content</span><span class="tooltip key-path">source.metadata.image.content</span></td><td><div><span class="simple_value str">&#x27;foo&#x27;</span></div></td></tr></table></div></details></div></td></tr></table></div></details></div><details class="pyglove user-message lf-message"><summary><div class="summary_name">source</div><div class="summary_title">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"></div><div class="message-text">User input</div><div class="message-metadata"><details class="pyglove dict"><summary><div class="summary_name">metadata</div><div class="summary_title">Dict(...)</div></summary><div class="complex_value dict message-metadata"><span class="empty_container"></span></div></details></div></div></details></div></details></div></details>
492
+ <details open class="pyglove ai-message lf-message"><summary><div class="summary-title lf-message">AIMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>lm-response</span><span>lm-output</span></div><div class="message-text">My name is Gemini</div><div class="message-result"><details open class="pyglove dict"><summary><div class="summary-name">result<span class="tooltip">metadata.result</span></div><div class="summary-title">Dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str">x</span><span class="tooltip">metadata.result.x</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key str">y</span><span class="tooltip">metadata.result.y</span></td><td><span class="simple-value int">2</span></td></tr><tr><td><span class="object-key str">z</span><span class="tooltip">metadata.result.z</span></td><td><details class="pyglove dict"><summary><div class="summary-title">Dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str">a</span><span class="tooltip">metadata.result.z.a</span></td><td><details class="pyglove list"><summary><div class="summary-title">List(...)</div></summary><div class="complex-value list"><table><tr><td><span class="object-key int">0</span><span class="tooltip">metadata.result.z.a[0]</span></td><td><span class="simple-value int">12</span></td></tr><tr><td><span class="object-key int">1</span><span class="tooltip">metadata.result.z.a[1]</span></td><td><span class="simple-value int">323</span></td></tr></table></div></details></td></tr></table></div></details></td></tr></table></div></details></div><div class="message-usage"><details open class="pyglove lm-sampling-usage"><summary><div class="summary-name">llm usage<span class="tooltip">metadata.usage</span></div><div class="summary-title">LMSamplingUsage(...)</div></summary><div class="complex-value lm-sampling-usage"><table><tr><td><span class="object-key str">prompt_tokens</span><span class="tooltip">metadata.usage.prompt_tokens</span></td><td><span class="simple-value int">10</span></td></tr><tr><td><span class="object-key str">completion_tokens</span><span class="tooltip">metadata.usage.completion_tokens</span></td><td><span class="simple-value int">2</span></td></tr><tr><td><span class="object-key str">total_tokens</span><span class="tooltip">metadata.usage.total_tokens</span></td><td><span class="simple-value int">12</span></td></tr><tr><td><span class="object-key str">num_requests</span><span class="tooltip">metadata.usage.num_requests</span></td><td><span class="simple-value int">1</span></td></tr><tr><td><span class="object-key str">estimated_cost</span><span class="tooltip">metadata.usage.estimated_cost</span></td><td><span class="simple-value none-type">None</span></td></tr></table></div></details></div><div class="message-metadata"><details open class="pyglove dict message-metadata"><summary><div class="summary-name message-metadata">metadata<span class="tooltip message-metadata">metadata</span></div><div class="summary-title message-metadata">Dict(...)</div></summary><div class="complex-value dict"><span class="empty-container"></span></div></details></div><details open class="pyglove user-message lf-message"><summary><div class="summary-name lf-message">source<span class="tooltip lf-message">source</span></div><div class="summary-title lf-message">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>lm-input</span></div><div class="message-text">What is in this image?<div class="modality-in-text"><details class="pyglove custom-modality"><summary><div class="summary-name">image<span class="tooltip">source.metadata.image</span></div><div class="summary-title">CustomModality(...)</div></summary><div class="complex-value custom-modality"><table><tr><td><span class="object-key str">content</span><span class="tooltip">source.metadata.image.content</span></td><td><span class="simple-value str">&#x27;foo&#x27;</span></td></tr></table></div></details></div>this is a test</div><div class="message-metadata"><details open class="pyglove dict message-metadata"><summary><div class="summary-name message-metadata">metadata<span class="tooltip message-metadata">source.metadata</span></div><div class="summary-title message-metadata">Dict(...)</div></summary><div class="complex-value dict"><table><tr><td><span class="object-key str">image</span><span class="tooltip">source.metadata.image</span></td><td><details class="pyglove custom-modality"><summary><div class="summary-title">CustomModality(...)</div></summary><div class="complex-value custom-modality"><table><tr><td><span class="object-key str">content</span><span class="tooltip">source.metadata.image.content</span></td><td><span class="simple-value str">&#x27;foo&#x27;</span></td></tr></table></div></details></td></tr></table></div></details></div><details open class="pyglove user-message lf-message"><summary><div class="summary-name lf-message">source<span class="tooltip lf-message">source.source</span></div><div class="summary-title lf-message">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"></div><div class="message-text">User input</div><div class="message-metadata"><details open class="pyglove dict message-metadata"><summary><div class="summary-name message-metadata">metadata<span class="tooltip message-metadata">source.source.metadata</span></div><div class="summary-title message-metadata">Dict(...)</div></summary><div class="complex-value dict"><span class="empty-container"></span></div></details></div></div></details></div></details></div></details>
403
493
  """
404
494
  )
405
495
 
@@ -15,7 +15,7 @@
15
15
 
16
16
  import base64
17
17
  import functools
18
- from typing import Annotated, Iterable, Type, Union
18
+ from typing import Annotated, Any, Iterable, Type, Union
19
19
  import langfun.core as lf
20
20
  import pyglove as pg
21
21
  import requests
@@ -183,35 +183,47 @@ class Mime(lf.Modality):
183
183
  **kwargs) -> str:
184
184
  return self._raw_html()
185
185
 
186
- def _html_tree_view_render(
186
+ def _html_tree_view(
187
187
  self,
188
188
  view: pg.views.HtmlTreeView,
189
- raw_mime_content: bool = pg.View.PresetArgValue(False), # pytype: disable=annotation-type-mismatch
190
- display_modality_when_hover: bool = pg.View.PresetArgValue(False), # pytype: disable=annotation-type-mismatch
189
+ extra_flags: dict[str, Any] | None = None,
191
190
  **kwargs
192
191
  ):
192
+ extra_flags = extra_flags if extra_flags is not None else {}
193
+ raw_mime_content = extra_flags.get('raw_mime_content', False)
194
+ display_modality_when_hover = extra_flags.get(
195
+ 'display_modality_when_hover', False
196
+ )
193
197
  if raw_mime_content:
194
- return pg.Html(self._raw_html())
195
- else:
196
- if display_modality_when_hover:
197
- kwargs.update(
198
- display_modality_when_hover=True,
199
- enable_summary_tooltip=True,
200
- )
201
- return super()._html_tree_view_render(view=view, **kwargs)
202
-
203
- def _html_tree_view_tooltip(
198
+ kwargs['enable_summary'] = False
199
+ elif display_modality_when_hover:
200
+ kwargs.update(
201
+ enable_summary=True,
202
+ enable_summary_tooltip=True,
203
+ )
204
+ return super()._html_tree_view(
205
+ view=view, extra_flags=extra_flags, **kwargs
206
+ )
207
+
208
+ def _html_tree_view_summary(
204
209
  self,
205
210
  *,
206
211
  view: pg.views.HtmlTreeView,
207
- content: pg.Html | str | None = None,
208
- display_modality_when_hover: bool = pg.View.PresetArgValue(False), # pytype: disable=annotation-type-mismatch
212
+ extra_flags: dict[str, Any] | None = None,
209
213
  **kwargs
210
214
  ):
211
- if content is None and display_modality_when_hover:
212
- content = self._raw_html()
213
- return super()._html_tree_view_tooltip(
214
- view=view, content=content, **kwargs
215
+ extra_flags = extra_flags or {}
216
+ if extra_flags.get('display_modality_when_hover', False):
217
+ def summary_tooltip(*args, content: str | None = None, **kwargs):
218
+ del content
219
+ return view.tooltip(*args, content=self._raw_html(), **kwargs)
220
+ else:
221
+ summary_tooltip = None
222
+ return super()._html_tree_view_summary(
223
+ view=view,
224
+ summary_tooltip_fn=summary_tooltip,
225
+ extra_flags=extra_flags,
226
+ **kwargs
215
227
  )
216
228
 
217
229
  def _raw_html(self) -> str: