langfun 0.1.2.dev202510240805__py3-none-any.whl → 0.1.2.dev202510260804__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.
Potentially problematic release.
This version of langfun might be problematic. Click here for more details.
- langfun/core/concurrent_test.py +1 -0
- langfun/core/data/conversion/anthropic_test.py +8 -6
- langfun/core/data/conversion/gemini_test.py +12 -9
- langfun/core/data/conversion/openai.py +134 -30
- langfun/core/data/conversion/openai_test.py +161 -17
- langfun/core/eval/v2/progress_tracking_test.py +3 -0
- langfun/core/langfunc_test.py +4 -2
- langfun/core/language_model.py +6 -6
- langfun/core/language_model_test.py +9 -3
- langfun/core/llms/__init__.py +2 -1
- langfun/core/llms/cache/base.py +3 -1
- langfun/core/llms/cache/in_memory_test.py +14 -4
- langfun/core/llms/deepseek.py +1 -1
- langfun/core/llms/groq.py +1 -1
- langfun/core/llms/llama_cpp.py +1 -1
- langfun/core/llms/openai.py +7 -2
- langfun/core/llms/openai_compatible.py +134 -27
- langfun/core/llms/openai_compatible_test.py +207 -20
- langfun/core/llms/openai_test.py +0 -2
- langfun/core/llms/vertexai.py +2 -2
- langfun/core/message.py +78 -44
- langfun/core/message_test.py +56 -81
- langfun/core/modalities/__init__.py +8 -0
- langfun/core/modalities/mime.py +9 -0
- langfun/core/modality.py +104 -27
- langfun/core/modality_test.py +42 -12
- langfun/core/sampling_test.py +20 -4
- langfun/core/structured/completion.py +2 -7
- langfun/core/structured/completion_test.py +23 -43
- langfun/core/structured/mapping.py +4 -13
- langfun/core/structured/querying.py +13 -11
- langfun/core/structured/querying_test.py +65 -29
- langfun/core/template.py +39 -13
- langfun/core/template_test.py +83 -17
- langfun/env/event_handlers/metric_writer_test.py +3 -3
- langfun/env/load_balancers_test.py +2 -2
- {langfun-0.1.2.dev202510240805.dist-info → langfun-0.1.2.dev202510260804.dist-info}/METADATA +1 -1
- {langfun-0.1.2.dev202510240805.dist-info → langfun-0.1.2.dev202510260804.dist-info}/RECORD +41 -41
- {langfun-0.1.2.dev202510240805.dist-info → langfun-0.1.2.dev202510260804.dist-info}/WHEEL +0 -0
- {langfun-0.1.2.dev202510240805.dist-info → langfun-0.1.2.dev202510260804.dist-info}/licenses/LICENSE +0 -0
- {langfun-0.1.2.dev202510240805.dist-info → langfun-0.1.2.dev202510260804.dist-info}/top_level.txt +0 -0
langfun/core/message.py
CHANGED
|
@@ -20,7 +20,7 @@ import contextlib
|
|
|
20
20
|
import functools
|
|
21
21
|
import inspect
|
|
22
22
|
import io
|
|
23
|
-
from typing import Annotated, Any, ClassVar, Optional, Type, Union
|
|
23
|
+
from typing import Annotated, Any, Callable, ClassVar, Optional, Type, Union
|
|
24
24
|
|
|
25
25
|
from langfun.core import modality
|
|
26
26
|
from langfun.core import natural_language
|
|
@@ -86,6 +86,11 @@ class Message(
|
|
|
86
86
|
|
|
87
87
|
sender: Annotated[str, 'The sender of the message.']
|
|
88
88
|
|
|
89
|
+
referred_modalities: Annotated[
|
|
90
|
+
dict[str, pg.Ref[modality.Modality]],
|
|
91
|
+
'The modality objects referred in the message.'
|
|
92
|
+
] = pg.Dict()
|
|
93
|
+
|
|
89
94
|
metadata: Annotated[
|
|
90
95
|
dict[str, Any],
|
|
91
96
|
(
|
|
@@ -111,6 +116,11 @@ class Message(
|
|
|
111
116
|
*,
|
|
112
117
|
# Default sender is specified in subclasses.
|
|
113
118
|
sender: str | pg.object_utils.MissingValue = pg.MISSING_VALUE,
|
|
119
|
+
referred_modalities: (
|
|
120
|
+
list[modality.Modality]
|
|
121
|
+
| dict[str, modality.Modality]
|
|
122
|
+
| None
|
|
123
|
+
) = None,
|
|
114
124
|
metadata: dict[str, Any] | None = None,
|
|
115
125
|
tags: list[str] | None = None,
|
|
116
126
|
source: Optional['Message'] = None,
|
|
@@ -125,6 +135,7 @@ class Message(
|
|
|
125
135
|
Args:
|
|
126
136
|
text: The text in the message.
|
|
127
137
|
sender: The sender name of the message.
|
|
138
|
+
referred_modalities: The modality objects referred in the message.
|
|
128
139
|
metadata: Structured meta-data associated with this message.
|
|
129
140
|
tags: Tags for the message.
|
|
130
141
|
source: The source message of the current message.
|
|
@@ -138,9 +149,13 @@ class Message(
|
|
|
138
149
|
"""
|
|
139
150
|
metadata = metadata or {}
|
|
140
151
|
metadata.update(kwargs)
|
|
152
|
+
if isinstance(referred_modalities, list):
|
|
153
|
+
referred_modalities = {m.id: pg.Ref(m) for m in referred_modalities}
|
|
154
|
+
|
|
141
155
|
super().__init__(
|
|
142
156
|
text=text,
|
|
143
157
|
metadata=metadata,
|
|
158
|
+
referred_modalities=referred_modalities or {},
|
|
144
159
|
tags=tags or [],
|
|
145
160
|
sender=sender,
|
|
146
161
|
allow_partial=allow_partial,
|
|
@@ -186,7 +201,7 @@ class Message(
|
|
|
186
201
|
A message created from the value.
|
|
187
202
|
"""
|
|
188
203
|
if isinstance(value, modality.Modality):
|
|
189
|
-
return cls('<<[[
|
|
204
|
+
return cls(f'<<[[{value.id}]]>>', referred_modalities=[value])
|
|
190
205
|
if isinstance(value, Message):
|
|
191
206
|
return value
|
|
192
207
|
if isinstance(value, str):
|
|
@@ -280,8 +295,7 @@ class Message(
|
|
|
280
295
|
if key_path == Message.PATH_TEXT:
|
|
281
296
|
return self.text
|
|
282
297
|
else:
|
|
283
|
-
|
|
284
|
-
return v.value if isinstance(v, pg.Ref) else v
|
|
298
|
+
return self.metadata.sym_get(key_path, default, use_inferred=True)
|
|
285
299
|
|
|
286
300
|
#
|
|
287
301
|
# API for accessing the structured result and error.
|
|
@@ -361,43 +375,53 @@ class Message(
|
|
|
361
375
|
# API for supporting modalities.
|
|
362
376
|
#
|
|
363
377
|
|
|
378
|
+
def modalities(
|
|
379
|
+
self,
|
|
380
|
+
filter: ( # pylint: disable=redefined-builtin
|
|
381
|
+
Type[modality.Modality]
|
|
382
|
+
| Callable[[modality.Modality], bool]
|
|
383
|
+
| None
|
|
384
|
+
) = None # pylint: disable=bad-whitespace
|
|
385
|
+
) -> list[modality.Modality]:
|
|
386
|
+
"""Returns the modality objects referred in the message."""
|
|
387
|
+
if inspect.isclass(filter) and issubclass(filter, modality.Modality):
|
|
388
|
+
filter_fn = lambda v: isinstance(v, filter) # pytype: disable=wrong-arg-types
|
|
389
|
+
elif filter is None:
|
|
390
|
+
filter_fn = lambda v: True
|
|
391
|
+
else:
|
|
392
|
+
filter_fn = filter
|
|
393
|
+
return [v for v in self.referred_modalities.values() if filter_fn(v)]
|
|
394
|
+
|
|
364
395
|
@property
|
|
365
|
-
def
|
|
366
|
-
"""Returns
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
396
|
+
def images(self) -> list[modality.Modality]:
|
|
397
|
+
"""Returns the image objects referred in the message."""
|
|
398
|
+
assert False, 'Overridden in core/modalities/__init__.py'
|
|
399
|
+
|
|
400
|
+
@property
|
|
401
|
+
def videos(self) -> list[modality.Modality]:
|
|
402
|
+
"""Returns the video objects referred in the message."""
|
|
403
|
+
assert False, 'Overridden in core/modalities/__init__.py'
|
|
404
|
+
|
|
405
|
+
@property
|
|
406
|
+
def audios(self) -> list[modality.Modality]:
|
|
407
|
+
"""Returns the audio objects referred in the message."""
|
|
408
|
+
assert False, 'Overridden in core/modalities/__init__.py'
|
|
373
409
|
|
|
374
410
|
def get_modality(
|
|
375
|
-
self,
|
|
411
|
+
self,
|
|
412
|
+
var_name: str,
|
|
413
|
+
default: Any = None
|
|
376
414
|
) -> modality.Modality | None:
|
|
377
415
|
"""Gets the modality object referred in the message.
|
|
378
416
|
|
|
379
417
|
Args:
|
|
380
418
|
var_name: The referred variable name for the modality object.
|
|
381
419
|
default: default value.
|
|
382
|
-
from_message_chain: If True, the look up will be performed from the
|
|
383
|
-
message chain. Otherwise it will be performed in current message.
|
|
384
420
|
|
|
385
421
|
Returns:
|
|
386
422
|
A modality object if found, otherwise None.
|
|
387
423
|
"""
|
|
388
|
-
|
|
389
|
-
if isinstance(obj, modality.Modality):
|
|
390
|
-
return obj
|
|
391
|
-
elif obj is None and self.source is not None:
|
|
392
|
-
return self.source.get_modality(var_name, default, from_message_chain)
|
|
393
|
-
return default
|
|
394
|
-
|
|
395
|
-
def referred_modalities(self) -> dict[str, modality.Modality]:
|
|
396
|
-
"""Returns modality objects attached on this message."""
|
|
397
|
-
chunks = self.chunk()
|
|
398
|
-
return {
|
|
399
|
-
m.referred_name: m for m in chunks if isinstance(m, modality.Modality)
|
|
400
|
-
}
|
|
424
|
+
return self.referred_modalities.get(var_name, default)
|
|
401
425
|
|
|
402
426
|
def chunk(self, text: str | None = None) -> list[str | modality.Modality]:
|
|
403
427
|
"""Chunk a message into a list of str or modality objects."""
|
|
@@ -425,10 +449,15 @@ class Message(
|
|
|
425
449
|
|
|
426
450
|
var_name = text[var_start:ref_end].strip()
|
|
427
451
|
var_value = self.get_modality(var_name)
|
|
428
|
-
if var_value is
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
452
|
+
if var_value is None:
|
|
453
|
+
raise ValueError(
|
|
454
|
+
f'Unknown modality reference: {var_name!r}. '
|
|
455
|
+
'Please make sure the modality object is present in '
|
|
456
|
+
f'`referred_modalities` when creating {self.__class__.__name__}.'
|
|
457
|
+
)
|
|
458
|
+
add_text_chunk(text[chunk_start:ref_start].strip(' '))
|
|
459
|
+
chunks.append(var_value)
|
|
460
|
+
chunk_start = ref_end + len(modality.Modality.REF_END)
|
|
432
461
|
return chunks
|
|
433
462
|
|
|
434
463
|
@classmethod
|
|
@@ -437,8 +466,8 @@ class Message(
|
|
|
437
466
|
) -> 'Message':
|
|
438
467
|
"""Assembly a message from a list of string or modality objects."""
|
|
439
468
|
fused_text = io.StringIO()
|
|
440
|
-
ref_index = 0
|
|
441
469
|
metadata = dict()
|
|
470
|
+
referred_modalities = dict()
|
|
442
471
|
last_char = None
|
|
443
472
|
for i, chunk in enumerate(chunks):
|
|
444
473
|
if i > 0 and last_char not in ('\t', ' ', '\n', None):
|
|
@@ -451,14 +480,16 @@ class Message(
|
|
|
451
480
|
last_char = None
|
|
452
481
|
else:
|
|
453
482
|
assert isinstance(chunk, modality.Modality), chunk
|
|
454
|
-
|
|
455
|
-
fused_text.write(modality.Modality.text_marker(var_name))
|
|
483
|
+
fused_text.write(modality.Modality.text_marker(chunk.id))
|
|
456
484
|
last_char = modality.Modality.REF_END[-1]
|
|
457
485
|
# Make a reference if the chunk is already owned by another object
|
|
458
486
|
# to avoid copy.
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
487
|
+
referred_modalities[chunk.id] = pg.Ref(chunk)
|
|
488
|
+
return cls(
|
|
489
|
+
fused_text.getvalue().strip(),
|
|
490
|
+
referred_modalities=referred_modalities,
|
|
491
|
+
metadata=metadata,
|
|
492
|
+
)
|
|
462
493
|
|
|
463
494
|
#
|
|
464
495
|
# Tagging
|
|
@@ -551,6 +582,11 @@ class Message(
|
|
|
551
582
|
#
|
|
552
583
|
|
|
553
584
|
def natural_language_format(self) -> str:
|
|
585
|
+
"""Returns the natural language format representation."""
|
|
586
|
+
# Propagate the modality references to parent context if any.
|
|
587
|
+
if capture_context := modality.get_modality_capture_context():
|
|
588
|
+
for v in self.referred_modalities.values():
|
|
589
|
+
capture_context.capture(v)
|
|
554
590
|
return self.text
|
|
555
591
|
|
|
556
592
|
def __eq__(self, other: Any) -> bool:
|
|
@@ -568,8 +604,7 @@ class Message(
|
|
|
568
604
|
def __getattr__(self, key: str) -> Any:
|
|
569
605
|
if key not in self.metadata:
|
|
570
606
|
raise AttributeError(key)
|
|
571
|
-
|
|
572
|
-
return v.value if isinstance(v, pg.Ref) else v
|
|
607
|
+
return self.metadata[key]
|
|
573
608
|
|
|
574
609
|
def _html_tree_view_content(
|
|
575
610
|
self,
|
|
@@ -646,15 +681,14 @@ class Message(
|
|
|
646
681
|
s.write(s.escape(chunk))
|
|
647
682
|
else:
|
|
648
683
|
assert isinstance(chunk, modality.Modality), chunk
|
|
649
|
-
child_path = pg.KeyPath(['metadata', chunk.referred_name], root_path)
|
|
650
684
|
s.write(
|
|
651
685
|
pg.Html.element(
|
|
652
686
|
'div',
|
|
653
687
|
[
|
|
654
688
|
view.render(
|
|
655
689
|
chunk,
|
|
656
|
-
name=chunk.
|
|
657
|
-
root_path=
|
|
690
|
+
name=chunk.id,
|
|
691
|
+
root_path=chunk.sym_path,
|
|
658
692
|
collapse_level=(
|
|
659
693
|
0 if collapse_modalities_in_text else 1
|
|
660
694
|
),
|
|
@@ -667,7 +701,7 @@ class Message(
|
|
|
667
701
|
css_classes=['modality-in-text'],
|
|
668
702
|
)
|
|
669
703
|
)
|
|
670
|
-
referred_chunks[chunk.
|
|
704
|
+
referred_chunks[chunk.id] = chunk
|
|
671
705
|
s.write('</div>')
|
|
672
706
|
return s
|
|
673
707
|
|
langfun/core/message_test.py
CHANGED
|
@@ -60,10 +60,19 @@ class MessageTest(unittest.TestCase):
|
|
|
60
60
|
self.assertTrue(
|
|
61
61
|
pg.eq(message.UserMessage.from_value('hi'), message.UserMessage('hi'))
|
|
62
62
|
)
|
|
63
|
+
foo = CustomModality('foo')
|
|
63
64
|
self.assertTrue(
|
|
64
65
|
pg.eq(
|
|
65
|
-
message.UserMessage.from_value(
|
|
66
|
-
message.UserMessage('<<[[
|
|
66
|
+
message.UserMessage.from_value(foo),
|
|
67
|
+
message.UserMessage(f'<<[[{foo.id}]]>>', referred_modalities=[foo]),
|
|
68
|
+
)
|
|
69
|
+
)
|
|
70
|
+
self.assertTrue(
|
|
71
|
+
pg.eq(
|
|
72
|
+
message.UserMessage.from_value(foo),
|
|
73
|
+
message.UserMessage(
|
|
74
|
+
f'<<[[{foo.id}]]>>', referred_modalities={foo.id: foo}
|
|
75
|
+
),
|
|
67
76
|
)
|
|
68
77
|
)
|
|
69
78
|
m = message.UserMessage('hi')
|
|
@@ -224,76 +233,39 @@ class MessageTest(unittest.TestCase):
|
|
|
224
233
|
self.assertEqual(str(m), m.text)
|
|
225
234
|
|
|
226
235
|
def test_get_modality(self):
|
|
236
|
+
foo = CustomModality('foo')
|
|
237
|
+
bar = CustomModality('bar')
|
|
227
238
|
m1 = message.UserMessage(
|
|
228
|
-
'hi
|
|
229
|
-
|
|
230
|
-
|
|
239
|
+
'hi',
|
|
240
|
+
referred_modalities={
|
|
241
|
+
foo.id: foo,
|
|
242
|
+
bar.id: pg.Ref(bar),
|
|
243
|
+
},
|
|
231
244
|
)
|
|
232
|
-
self.assertIs(m1.get_modality(
|
|
233
|
-
self.assertIs(m1.get_modality(
|
|
245
|
+
self.assertIs(m1.get_modality(foo.id), foo)
|
|
246
|
+
self.assertIs(m1.get_modality(bar.id), bar)
|
|
234
247
|
self.assertIsNone(m1.get_modality('video'))
|
|
248
|
+
self.assertEqual(len(m1.modalities()), 2)
|
|
249
|
+
self.assertEqual(len(m1.modalities(CustomModality)), 2)
|
|
235
250
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
# We could get the modality object even it's not directly used by current
|
|
239
|
-
# message.
|
|
240
|
-
self.assertIs(m2.get_modality('x.img2'), m1.x.img2)
|
|
241
|
-
self.assertIsNone(m2.get_modality('video'))
|
|
242
|
-
|
|
243
|
-
m3 = message.AIMessage(
|
|
244
|
-
'This is the {{output_image}} based on {{x.img2}}',
|
|
245
|
-
output_image=CustomModality('bar'),
|
|
246
|
-
source=m2,
|
|
247
|
-
)
|
|
248
|
-
self.assertIs(m3.get_modality('x.img2'), m1.x.img2)
|
|
249
|
-
self.assertIs(m3.get_modality('output_image'), m3.output_image)
|
|
250
|
-
self.assertIsNone(m3.get_modality('video'))
|
|
251
|
-
|
|
252
|
-
def test_referred_modalities(self):
|
|
253
|
-
m1 = message.UserMessage(
|
|
254
|
-
'hi, this is a <<[[img1]]>> and <<[[x.img2]]>>',
|
|
255
|
-
img1=CustomModality('foo'),
|
|
256
|
-
x=dict(img2=CustomModality('bar')),
|
|
257
|
-
)
|
|
258
|
-
m2 = message.SystemMessage('class Question:\n image={{img1}}', source=m1)
|
|
259
|
-
m3 = message.AIMessage(
|
|
260
|
-
(
|
|
261
|
-
'This is the <<[[output_image]]>> based on <<[[x.img2]]>>, '
|
|
262
|
-
'{{unknown_var}}'
|
|
263
|
-
),
|
|
264
|
-
output_image=CustomModality('bar'),
|
|
265
|
-
source=m2,
|
|
266
|
-
)
|
|
267
|
-
self.assertEqual(
|
|
268
|
-
m3.referred_modalities(),
|
|
269
|
-
{
|
|
270
|
-
'output_image': m3.output_image,
|
|
271
|
-
'x.img2': m1.x.img2,
|
|
272
|
-
},
|
|
273
|
-
)
|
|
251
|
+
class MyModality(modality.Modality):
|
|
252
|
+
pass
|
|
274
253
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
'hi, this is a <<[[img1]]>> and <<[[x.img2]]>>',
|
|
278
|
-
img1=CustomModality('foo'),
|
|
279
|
-
x=dict(img2=CustomModality('bar')),
|
|
280
|
-
)
|
|
281
|
-
self.assertEqual(
|
|
282
|
-
m.text_with_modality_hash,
|
|
283
|
-
(
|
|
284
|
-
'hi, this is a <<[[img1]]>> and <<[[x.img2]]>>'
|
|
285
|
-
'<img1>acbd18db</img1><x.img2>37b51d19</x.img2>'
|
|
286
|
-
)
|
|
287
|
-
)
|
|
254
|
+
self.assertEqual(len(m1.modalities(MyModality)), 0)
|
|
255
|
+
self.assertEqual(len(m1.modalities(lambda x: x.content == 'foo')), 1)
|
|
288
256
|
|
|
289
257
|
def test_chunking(self):
|
|
258
|
+
foo = CustomModality('foo')
|
|
259
|
+
bar = CustomModality('bar')
|
|
290
260
|
m = message.UserMessage(
|
|
291
|
-
inspect.cleandoc("""
|
|
292
|
-
Hi, this is <<[[
|
|
293
|
-
<<[[
|
|
261
|
+
inspect.cleandoc(f"""
|
|
262
|
+
Hi, this is <<[[{foo.id}]]>> and this is {{b}}.
|
|
263
|
+
<<[[{bar.id}]]>> something else
|
|
294
264
|
"""),
|
|
295
|
-
|
|
296
|
-
|
|
265
|
+
referred_modalities={
|
|
266
|
+
foo.id: pg.Ref(foo),
|
|
267
|
+
bar.id: pg.Ref(bar),
|
|
268
|
+
},
|
|
297
269
|
)
|
|
298
270
|
chunks = m.chunk()
|
|
299
271
|
self.assertTrue(
|
|
@@ -301,10 +273,10 @@ class MessageTest(unittest.TestCase):
|
|
|
301
273
|
chunks,
|
|
302
274
|
[
|
|
303
275
|
'Hi, this is',
|
|
304
|
-
|
|
305
|
-
'and this is {
|
|
306
|
-
|
|
307
|
-
'
|
|
276
|
+
foo,
|
|
277
|
+
'and this is {b}.\n',
|
|
278
|
+
bar,
|
|
279
|
+
'something else',
|
|
308
280
|
],
|
|
309
281
|
)
|
|
310
282
|
)
|
|
@@ -312,15 +284,17 @@ class MessageTest(unittest.TestCase):
|
|
|
312
284
|
pg.eq(
|
|
313
285
|
message.AIMessage.from_chunks(chunks),
|
|
314
286
|
message.AIMessage(
|
|
315
|
-
|
|
316
|
-
Hi, this is <<[[
|
|
317
|
-
<<[[
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
287
|
+
(
|
|
288
|
+
f'Hi, this is <<[[{foo.id}]]>> and this '
|
|
289
|
+
f'is {{b}}.\n<<[[{bar.id}]]>> '
|
|
290
|
+
'something else'
|
|
291
|
+
),
|
|
292
|
+
referred_modalities=[foo, bar],
|
|
321
293
|
),
|
|
322
294
|
)
|
|
323
295
|
)
|
|
296
|
+
with self.assertRaisesRegex(ValueError, 'Unknown modality reference'):
|
|
297
|
+
message.UserMessage('<<[[abc]]>>').chunk()
|
|
324
298
|
|
|
325
299
|
def assert_html_content(self, html, expected):
|
|
326
300
|
expected = inspect.cleandoc(expected).strip()
|
|
@@ -404,25 +378,26 @@ class MessageTest(unittest.TestCase):
|
|
|
404
378
|
<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>
|
|
405
379
|
"""
|
|
406
380
|
)
|
|
381
|
+
image = CustomModality('bird')
|
|
407
382
|
self.assert_html_content(
|
|
408
383
|
message.UserMessage(
|
|
409
|
-
'what is this <<[[image]]>>',
|
|
384
|
+
f'what is this <<[[{image.id}]]>>',
|
|
410
385
|
tags=['lm-input'],
|
|
411
|
-
image
|
|
386
|
+
referred_modalities=[image],
|
|
412
387
|
).to_html(
|
|
413
388
|
enable_summary_tooltip=False,
|
|
414
389
|
extra_flags=dict(include_message_metadata=False)
|
|
415
390
|
),
|
|
416
391
|
"""
|
|
417
|
-
<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">
|
|
392
|
+
<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">custom_modality:abaecf8c<span class="tooltip"></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">content</span></div><div class="summary-title">str</div></summary><span class="simple-value str">'bird'</span></details></div></details></div></div></div></details>
|
|
418
393
|
"""
|
|
419
394
|
)
|
|
420
395
|
|
|
421
396
|
def test_html_ai_message(self):
|
|
422
397
|
image = CustomModality('foo')
|
|
423
398
|
user_message = message.UserMessage(
|
|
424
|
-
'What is in this image? <<[[image]]>> this is a test',
|
|
425
|
-
|
|
399
|
+
f'What is in this image? <<[[{image.id}]]>> this is a test',
|
|
400
|
+
referred_modalities=[image],
|
|
426
401
|
source=message.UserMessage('User input'),
|
|
427
402
|
tags=['lm-input']
|
|
428
403
|
)
|
|
@@ -438,7 +413,7 @@ class MessageTest(unittest.TestCase):
|
|
|
438
413
|
self.assert_html_content(
|
|
439
414
|
ai_message.to_html(enable_summary_tooltip=False),
|
|
440
415
|
"""
|
|
441
|
-
<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><tr><td><span class="object-key str">retry_stats</span><span class="tooltip">metadata.usage.retry_stats</span></td><td><details class="pyglove retry-stats"><summary><div class="summary-title">RetryStats(...)</div></summary><div class="complex-value retry-stats"><table><tr><td><span class="object-key str">num_occurences</span><span class="tooltip">metadata.usage.retry_stats.num_occurences</span></td><td><span class="simple-value int">0</span></td></tr><tr><td><span class="object-key str">total_wait_interval</span><span class="tooltip">metadata.usage.retry_stats.total_wait_interval</span></td><td><span class="simple-value float">0.0</span></td></tr><tr><td><span class="object-key str">total_call_interval</span><span class="tooltip">metadata.usage.retry_stats.total_call_interval</span></td><td><span class="simple-value float">0.0</span></td></tr><tr><td><span class="object-key str">errors</span><span class="tooltip">metadata.usage.retry_stats.errors</span></td><td><details class="pyglove dict"><summary><div class="summary-title">Dict(...)</div></summary><div class="complex-value dict"><span class="empty-container"></span></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str">completion_tokens_details</span><span class="tooltip">metadata.usage.completion_tokens_details</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">
|
|
416
|
+
<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><tr><td><span class="object-key str">retry_stats</span><span class="tooltip">metadata.usage.retry_stats</span></td><td><details class="pyglove retry-stats"><summary><div class="summary-title">RetryStats(...)</div></summary><div class="complex-value retry-stats"><table><tr><td><span class="object-key str">num_occurences</span><span class="tooltip">metadata.usage.retry_stats.num_occurences</span></td><td><span class="simple-value int">0</span></td></tr><tr><td><span class="object-key str">total_wait_interval</span><span class="tooltip">metadata.usage.retry_stats.total_wait_interval</span></td><td><span class="simple-value float">0.0</span></td></tr><tr><td><span class="object-key str">total_call_interval</span><span class="tooltip">metadata.usage.retry_stats.total_call_interval</span></td><td><span class="simple-value float">0.0</span></td></tr><tr><td><span class="object-key str">errors</span><span class="tooltip">metadata.usage.retry_stats.errors</span></td><td><details class="pyglove dict"><summary><div class="summary-title">Dict(...)</div></summary><div class="complex-value dict"><span class="empty-container"></span></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str">completion_tokens_details</span><span class="tooltip">metadata.usage.completion_tokens_details</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">custom_modality:acbd18db<span class="tooltip"></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">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"><span class="empty-container"></span></div></details></div></div></details></div></details>
|
|
442
417
|
"""
|
|
443
418
|
)
|
|
444
419
|
self.assert_html_content(
|
|
@@ -455,7 +430,7 @@ class MessageTest(unittest.TestCase):
|
|
|
455
430
|
),
|
|
456
431
|
),
|
|
457
432
|
"""
|
|
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 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><tr><td><span class="object-key str">retry_stats</span><span class="tooltip">metadata.usage.retry_stats</span></td><td><details class="pyglove retry-stats"><summary><div class="summary-title">RetryStats(...)</div></summary><div class="complex-value retry-stats"><table><tr><td><span class="object-key str">num_occurences</span><span class="tooltip">metadata.usage.retry_stats.num_occurences</span></td><td><span class="simple-value int">0</span></td></tr><tr><td><span class="object-key str">total_wait_interval</span><span class="tooltip">metadata.usage.retry_stats.total_wait_interval</span></td><td><span class="simple-value float">0.0</span></td></tr><tr><td><span class="object-key str">total_call_interval</span><span class="tooltip">metadata.usage.retry_stats.total_call_interval</span></td><td><span class="simple-value float">0.0</span></td></tr><tr><td><span class="object-key str">errors</span><span class="tooltip">metadata.usage.retry_stats.errors</span></td><td><details class="pyglove dict"><summary><div class="summary-title">Dict(...)</div></summary><div class="complex-value dict"><span class="empty-container"></span></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str">completion_tokens_details</span><span class="tooltip">metadata.usage.completion_tokens_details</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">
|
|
433
|
+
<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><tr><td><span class="object-key str">retry_stats</span><span class="tooltip">metadata.usage.retry_stats</span></td><td><details class="pyglove retry-stats"><summary><div class="summary-title">RetryStats(...)</div></summary><div class="complex-value retry-stats"><table><tr><td><span class="object-key str">num_occurences</span><span class="tooltip">metadata.usage.retry_stats.num_occurences</span></td><td><span class="simple-value int">0</span></td></tr><tr><td><span class="object-key str">total_wait_interval</span><span class="tooltip">metadata.usage.retry_stats.total_wait_interval</span></td><td><span class="simple-value float">0.0</span></td></tr><tr><td><span class="object-key str">total_call_interval</span><span class="tooltip">metadata.usage.retry_stats.total_call_interval</span></td><td><span class="simple-value float">0.0</span></td></tr><tr><td><span class="object-key str">errors</span><span class="tooltip">metadata.usage.retry_stats.errors</span></td><td><details class="pyglove dict"><summary><div class="summary-title">Dict(...)</div></summary><div class="complex-value dict"><span class="empty-container"></span></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str">completion_tokens_details</span><span class="tooltip">metadata.usage.completion_tokens_details</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">custom_modality:acbd18db<span class="tooltip"></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">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"><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.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>
|
|
459
434
|
"""
|
|
460
435
|
)
|
|
461
436
|
self.assert_html_content(
|
|
@@ -472,7 +447,7 @@ class MessageTest(unittest.TestCase):
|
|
|
472
447
|
),
|
|
473
448
|
),
|
|
474
449
|
"""
|
|
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 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><tr><td><span class="object-key str">retry_stats</span><span class="tooltip">metadata.usage.retry_stats</span></td><td><details class="pyglove retry-stats"><summary><div class="summary-title">RetryStats(...)</div></summary><div class="complex-value retry-stats"><table><tr><td><span class="object-key str">num_occurences</span><span class="tooltip">metadata.usage.retry_stats.num_occurences</span></td><td><span class="simple-value int">0</span></td></tr><tr><td><span class="object-key str">total_wait_interval</span><span class="tooltip">metadata.usage.retry_stats.total_wait_interval</span></td><td><span class="simple-value float">0.0</span></td></tr><tr><td><span class="object-key str">total_call_interval</span><span class="tooltip">metadata.usage.retry_stats.total_call_interval</span></td><td><span class="simple-value float">0.0</span></td></tr><tr><td><span class="object-key str">errors</span><span class="tooltip">metadata.usage.retry_stats.errors</span></td><td><details class="pyglove dict"><summary><div class="summary-title">Dict(...)</div></summary><div class="complex-value dict"><span class="empty-container"></span></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str">completion_tokens_details</span><span class="tooltip">metadata.usage.completion_tokens_details</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">
|
|
450
|
+
<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><tr><td><span class="object-key str">retry_stats</span><span class="tooltip">metadata.usage.retry_stats</span></td><td><details class="pyglove retry-stats"><summary><div class="summary-title">RetryStats(...)</div></summary><div class="complex-value retry-stats"><table><tr><td><span class="object-key str">num_occurences</span><span class="tooltip">metadata.usage.retry_stats.num_occurences</span></td><td><span class="simple-value int">0</span></td></tr><tr><td><span class="object-key str">total_wait_interval</span><span class="tooltip">metadata.usage.retry_stats.total_wait_interval</span></td><td><span class="simple-value float">0.0</span></td></tr><tr><td><span class="object-key str">total_call_interval</span><span class="tooltip">metadata.usage.retry_stats.total_call_interval</span></td><td><span class="simple-value float">0.0</span></td></tr><tr><td><span class="object-key str">errors</span><span class="tooltip">metadata.usage.retry_stats.errors</span></td><td><details class="pyglove dict"><summary><div class="summary-title">Dict(...)</div></summary><div class="complex-value dict"><span class="empty-container"></span></div></details></td></tr></table></div></details></td></tr><tr><td><span class="object-key str">completion_tokens_details</span><span class="tooltip">metadata.usage.completion_tokens_details</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">custom_modality:acbd18db<span class="tooltip"></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">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"><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.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>
|
|
476
451
|
"""
|
|
477
452
|
)
|
|
478
453
|
|
|
@@ -24,6 +24,14 @@ from langfun.core.modalities.image import Image
|
|
|
24
24
|
from langfun.core.modalities.pdf import PDF
|
|
25
25
|
from langfun.core.modalities.video import Video
|
|
26
26
|
|
|
27
|
+
from langfun.core import message as _message_lib
|
|
28
|
+
|
|
29
|
+
# Override the `images`, `videos` and `audios` properties of `Message` to
|
|
30
|
+
# return the modalities of the corresponding types.
|
|
31
|
+
_message_lib.Message.images = property(lambda self: self.modalities(Image))
|
|
32
|
+
_message_lib.Message.videos = property(lambda self: self.modalities(Video))
|
|
33
|
+
_message_lib.Message.audios = property(lambda self: self.modalities(Audio))
|
|
34
|
+
|
|
27
35
|
# pylint: enable=g-import-not-at-top
|
|
28
36
|
# pylint: enable=g-bad-import-order
|
|
29
37
|
# pylint: enable=g-importing-member
|