langfun 0.1.2.dev202410140804__py3-none-any.whl → 0.1.2.dev202410180804__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/component.py +48 -0
- langfun/core/component_test.py +48 -0
- langfun/core/logging.py +39 -28
- langfun/core/logging_test.py +21 -5
- langfun/core/message.py +104 -64
- langfun/core/message_test.py +101 -11
- langfun/core/modalities/mime.py +32 -20
- langfun/core/modalities/mime_test.py +8 -4
- langfun/core/structured/mapping.py +46 -29
- langfun/core/structured/mapping_test.py +11 -5
- langfun/core/structured/schema.py +1 -1
- langfun/core/template.py +36 -49
- langfun/core/template_test.py +39 -1
- {langfun-0.1.2.dev202410140804.dist-info → langfun-0.1.2.dev202410180804.dist-info}/METADATA +1 -1
- {langfun-0.1.2.dev202410140804.dist-info → langfun-0.1.2.dev202410180804.dist-info}/RECORD +18 -18
- {langfun-0.1.2.dev202410140804.dist-info → langfun-0.1.2.dev202410180804.dist-info}/WHEEL +1 -1
- {langfun-0.1.2.dev202410140804.dist-info → langfun-0.1.2.dev202410180804.dist-info}/LICENSE +0 -0
- {langfun-0.1.2.dev202410140804.dist-info → langfun-0.1.2.dev202410180804.dist-info}/top_level.txt +0 -0
langfun/core/message_test.py
CHANGED
@@ -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="
|
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 <div></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(
|
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="
|
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">'bird'</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="
|
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">'foo'</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">'foo'</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">'foo'</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">'foo'</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
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
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="
|
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">'foo'</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">'foo'</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
|
|
langfun/core/modalities/mime.py
CHANGED
@@ -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
|
186
|
+
def _html_tree_view(
|
187
187
|
self,
|
188
188
|
view: pg.views.HtmlTreeView,
|
189
|
-
|
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
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
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
|
-
|
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
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
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:
|
@@ -92,14 +92,16 @@ class CustomMimeTest(unittest.TestCase):
|
|
92
92
|
enable_key_tooltip=False,
|
93
93
|
),
|
94
94
|
"""
|
95
|
-
<details open class="pyglove custom"><summary><div class="
|
95
|
+
<details open class="pyglove custom"><summary><div class="summary-title">Custom(...)</div></summary><embed type="text/plain" src="data:text/plain;base64,Zm9v"/></details>
|
96
96
|
"""
|
97
97
|
)
|
98
98
|
self.assert_html_content(
|
99
99
|
mime.Custom('text/plain', b'foo').to_html(
|
100
100
|
enable_summary_tooltip=False,
|
101
101
|
enable_key_tooltip=False,
|
102
|
-
|
102
|
+
extra_flags=dict(
|
103
|
+
raw_mime_content=True,
|
104
|
+
)
|
103
105
|
),
|
104
106
|
"""
|
105
107
|
<embed type="text/plain" src="data:text/plain;base64,Zm9v"/>
|
@@ -109,10 +111,12 @@ class CustomMimeTest(unittest.TestCase):
|
|
109
111
|
mime.Custom('text/plain', b'foo').to_html(
|
110
112
|
enable_summary_tooltip=False,
|
111
113
|
enable_key_tooltip=False,
|
112
|
-
|
114
|
+
extra_flags=dict(
|
115
|
+
display_modality_when_hover=True,
|
116
|
+
)
|
113
117
|
),
|
114
118
|
"""
|
115
|
-
<details open class="pyglove custom"><summary><div class="
|
119
|
+
<details open class="pyglove custom"><summary><div class="summary-title">Custom(...)</div><span class="tooltip"><embed type="text/plain" src="data:text/plain;base64,Zm9v"/></span></summary><embed type="text/plain" src="data:text/plain;base64,Zm9v"/></details>
|
116
120
|
"""
|
117
121
|
)
|
118
122
|
|
@@ -13,6 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
"""The base of symbolic mapping methods."""
|
15
15
|
|
16
|
+
import functools
|
16
17
|
import io
|
17
18
|
from typing import Annotated, Any, Callable
|
18
19
|
import langfun.core as lf
|
@@ -183,43 +184,59 @@ class MappingExample(lf.NaturalLanguageFormattable, lf.Component):
|
|
183
184
|
result.write(lf.colored(str(self.metadata), color='cyan'))
|
184
185
|
return result.getvalue().strip()
|
185
186
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
root_path: pg.KeyPath,
|
192
|
-
**kwargs,
|
193
|
-
):
|
194
|
-
def render_value(value, **kwargs):
|
187
|
+
@classmethod
|
188
|
+
@functools.cache
|
189
|
+
def _html_tree_view_config(cls) -> dict[str, Any]:
|
190
|
+
|
191
|
+
def render_value(view, *, value, **kwargs):
|
195
192
|
if isinstance(value, lf.Template):
|
196
193
|
# Make a shallow copy to make sure modalities are rooted by
|
197
194
|
# the input.
|
198
195
|
value = value.clone().render()
|
196
|
+
if value is None:
|
197
|
+
return None
|
199
198
|
return view.render(value, **kwargs)
|
200
199
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
200
|
+
return pg.views.HtmlTreeView.get_kwargs(
|
201
|
+
super()._html_tree_view_config(),
|
202
|
+
dict(
|
203
|
+
include_keys=['input', 'output', 'context', 'schema', 'metadata'],
|
204
|
+
extra_flags=dict(
|
205
|
+
render_value_fn=render_value,
|
206
|
+
),
|
207
|
+
child_config=dict(
|
208
|
+
input=dict(
|
209
|
+
collapse_level=1,
|
210
|
+
),
|
211
|
+
output=dict(
|
212
|
+
css_classes=['lf-example-output'],
|
213
|
+
collapse_level=1,
|
214
|
+
),
|
215
|
+
schema=dict(
|
216
|
+
css_classes=['lf-example-schema'],
|
217
|
+
collapse_level=1,
|
218
|
+
),
|
219
|
+
metadata=dict(
|
220
|
+
css_classes=['lf-example-metadata'],
|
221
|
+
collapse_level=1,
|
222
|
+
),
|
223
|
+
),
|
224
|
+
)
|
219
225
|
)
|
220
226
|
|
221
|
-
|
222
|
-
|
227
|
+
@classmethod
|
228
|
+
@functools.cache
|
229
|
+
def _html_tree_view_css_styles(cls) -> list[str]:
|
230
|
+
return super()._html_tree_view_css_styles() + [
|
231
|
+
"""
|
232
|
+
.lf-example-output {
|
233
|
+
color: dodgerblue;
|
234
|
+
}
|
235
|
+
.lf-example-schema {
|
236
|
+
color: blue;
|
237
|
+
}
|
238
|
+
"""
|
239
|
+
]
|
223
240
|
|
224
241
|
|
225
242
|
class Mapping(lf.LangFunc):
|
@@ -194,15 +194,18 @@ class MappingExampleTest(unittest.TestCase):
|
|
194
194
|
)
|
195
195
|
self.assert_html_content(
|
196
196
|
example.to_html(
|
197
|
-
enable_summary_tooltip=False,
|
197
|
+
enable_summary_tooltip=False,
|
198
|
+
extra_flags=dict(
|
199
|
+
include_message_metadata=False
|
200
|
+
)
|
198
201
|
),
|
199
202
|
"""
|
200
|
-
<details open class="pyglove mapping-example"><summary><div class="
|
203
|
+
<details open class="pyglove mapping-example"><summary><div class="summary-title">MappingExample(...)</div></summary><div class="complex-value mapping-example"><details open class="pyglove user-message lf-message"><summary><div class="summary-name lf-message">input<span class="tooltip lf-message">input</span></div><div class="summary-title lf-message">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>rendered</span></div><div class="message-text">1 + 2 = ?</div></div></details><details open class="pyglove answer lf-example-output"><summary><div class="summary-name lf-example-output">output<span class="tooltip lf-example-output">output</span></div><div class="summary-title lf-example-output">Answer(...)</div></summary><div class="complex-value answer"><details open class="pyglove int"><summary><div class="summary-name">answer<span class="tooltip">output.answer</span></div><div class="summary-title">int</div></summary><span class="simple-value int">3</span></details></div></details><details open class="pyglove str"><summary><div class="summary-name">context<span class="tooltip">context</span></div><div class="summary-title">str</div></summary><span class="simple-value str">'compute 1 + 1'</span></details><details open class="pyglove schema lf-example-schema"><summary><div class="summary-name lf-example-schema">schema<span class="tooltip lf-example-schema">schema</span></div><div class="summary-title lf-example-schema">Schema(...)</div></summary><div class="lf-schema-definition">Answer
|
201
204
|
|
202
205
|
```python
|
203
206
|
class Answer:
|
204
207
|
answer: int
|
205
|
-
```</div></details
|
208
|
+
```</div></details><details open class="pyglove dict lf-example-metadata"><summary><div class="summary-name lf-example-metadata">metadata<span class="tooltip lf-example-metadata">metadata</span></div><div class="summary-title lf-example-metadata">Dict(...)</div></summary><div class="complex-value dict"><details open class="pyglove str"><summary><div class="summary-name">foo<span class="tooltip">metadata.foo</span></div><div class="summary-title">str</div></summary><span class="simple-value str">'bar'</span></details></div></details></div></details>
|
206
209
|
"""
|
207
210
|
)
|
208
211
|
|
@@ -212,10 +215,13 @@ class MappingExampleTest(unittest.TestCase):
|
|
212
215
|
)
|
213
216
|
self.assert_html_content(
|
214
217
|
example.to_html(
|
215
|
-
enable_summary_tooltip=False,
|
218
|
+
enable_summary_tooltip=False,
|
219
|
+
extra_flags=dict(
|
220
|
+
include_message_metadata=False
|
221
|
+
)
|
216
222
|
),
|
217
223
|
"""
|
218
|
-
<details open class="pyglove mapping-example"><summary><div class="
|
224
|
+
<details open class="pyglove mapping-example"><summary><div class="summary-title">MappingExample(...)</div></summary><div class="complex-value mapping-example"><details open class="pyglove user-message lf-message"><summary><div class="summary-name lf-message">input<span class="tooltip lf-message">input</span></div><div class="summary-title lf-message">UserMessage(...)</div></summary><div class="complex_value"><div class="message-tags"><span>rendered</span></div><div class="message-text">1 + 2 = ?</div></div></details><details open class="pyglove answer lf-example-output"><summary><div class="summary-name lf-example-output">output<span class="tooltip lf-example-output">output</span></div><div class="summary-title lf-example-output">Answer(...)</div></summary><div class="complex-value answer"><details open class="pyglove int"><summary><div class="summary-name">answer<span class="tooltip">output.answer</span></div><div class="summary-title">int</div></summary><span class="simple-value int">3</span></details></div></details><details open class="pyglove contextual-attribute lf-example-schema"><summary><div class="summary-name lf-example-schema">schema<span class="tooltip lf-example-schema">schema</span></div><div class="summary-title lf-example-schema">ContextualAttribute(...)</div></summary><span class="simple-value none-type">None</span></details><details open class="pyglove dict lf-example-metadata"><summary><div class="summary-name lf-example-metadata">metadata<span class="tooltip lf-example-metadata">metadata</span></div><div class="summary-title lf-example-metadata">Dict(...)</div></summary><div class="complex-value dict"><span class="empty-container"></span></div></details></div></details>
|
219
225
|
"""
|
220
226
|
)
|
221
227
|
|
@@ -199,7 +199,7 @@ class Schema(lf.NaturalLanguageFormattable, pg.Object):
|
|
199
199
|
return pg.Html.element(
|
200
200
|
'div',
|
201
201
|
[self.schema_str(protocol='python')],
|
202
|
-
|
202
|
+
css_classes=['lf-schema-definition']
|
203
203
|
).add_style(
|
204
204
|
"""
|
205
205
|
.lf-schema-definition {
|