langfun 0.1.1.dev20240820__tar.gz → 0.1.1.dev20240821__tar.gz

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.
Files changed (130) hide show
  1. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/PKG-INFO +1 -1
  2. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/repr_utils.py +2 -1
  3. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/repr_utils_test.py +4 -1
  4. langfun-0.1.1.dev20240821/langfun/core/structured/scoring.py +181 -0
  5. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/scoring_test.py +24 -0
  6. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun.egg-info/PKG-INFO +1 -1
  7. langfun-0.1.1.dev20240820/langfun/core/structured/scoring.py +0 -95
  8. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/LICENSE +0 -0
  9. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/README.md +0 -0
  10. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/__init__.py +0 -0
  11. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/__init__.py +0 -0
  12. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/__init__.py +0 -0
  13. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/python/__init__.py +0 -0
  14. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/python/correction.py +0 -0
  15. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/python/correction_test.py +0 -0
  16. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/python/errors.py +0 -0
  17. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/python/errors_test.py +0 -0
  18. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/python/execution.py +0 -0
  19. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/python/execution_test.py +0 -0
  20. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/python/generation.py +0 -0
  21. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/python/generation_test.py +0 -0
  22. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/python/parsing.py +0 -0
  23. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/python/parsing_test.py +0 -0
  24. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/python/permissions.py +0 -0
  25. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/coding/python/permissions_test.py +0 -0
  26. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/component.py +0 -0
  27. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/component_test.py +0 -0
  28. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/concurrent.py +0 -0
  29. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/concurrent_test.py +0 -0
  30. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/console.py +0 -0
  31. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/console_test.py +0 -0
  32. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/eval/__init__.py +0 -0
  33. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/eval/base.py +0 -0
  34. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/eval/base_test.py +0 -0
  35. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/eval/matching.py +0 -0
  36. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/eval/matching_test.py +0 -0
  37. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/eval/patching.py +0 -0
  38. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/eval/patching_test.py +0 -0
  39. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/eval/scoring.py +0 -0
  40. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/eval/scoring_test.py +0 -0
  41. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/langfunc.py +0 -0
  42. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/langfunc_test.py +0 -0
  43. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/language_model.py +0 -0
  44. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/language_model_test.py +0 -0
  45. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/__init__.py +0 -0
  46. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/anthropic.py +0 -0
  47. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/anthropic_test.py +0 -0
  48. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/cache/__init__.py +0 -0
  49. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/cache/base.py +0 -0
  50. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/cache/in_memory.py +0 -0
  51. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/cache/in_memory_test.py +0 -0
  52. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/fake.py +0 -0
  53. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/fake_test.py +0 -0
  54. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/google_genai.py +0 -0
  55. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/google_genai_test.py +0 -0
  56. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/groq.py +0 -0
  57. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/groq_test.py +0 -0
  58. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/llama_cpp.py +0 -0
  59. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/llama_cpp_test.py +0 -0
  60. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/openai.py +0 -0
  61. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/openai_test.py +0 -0
  62. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/rest.py +0 -0
  63. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/rest_test.py +0 -0
  64. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/vertexai.py +0 -0
  65. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/llms/vertexai_test.py +0 -0
  66. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/logging.py +0 -0
  67. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/logging_test.py +0 -0
  68. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/memories/__init__.py +0 -0
  69. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/memories/conversation_history.py +0 -0
  70. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/memories/conversation_history_test.py +0 -0
  71. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/memory.py +0 -0
  72. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/message.py +0 -0
  73. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/message_test.py +0 -0
  74. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modalities/__init__.py +0 -0
  75. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modalities/audio.py +0 -0
  76. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modalities/audio_test.py +0 -0
  77. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modalities/image.py +0 -0
  78. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modalities/image_test.py +0 -0
  79. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modalities/mime.py +0 -0
  80. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modalities/mime_test.py +0 -0
  81. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modalities/ms_office.py +0 -0
  82. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modalities/ms_office_test.py +0 -0
  83. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modalities/pdf.py +0 -0
  84. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modalities/pdf_test.py +0 -0
  85. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modalities/video.py +0 -0
  86. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modalities/video_test.py +0 -0
  87. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modality.py +0 -0
  88. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/modality_test.py +0 -0
  89. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/natural_language.py +0 -0
  90. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/natural_language_test.py +0 -0
  91. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/sampling.py +0 -0
  92. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/sampling_test.py +0 -0
  93. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/__init__.py +0 -0
  94. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/completion.py +0 -0
  95. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/completion_test.py +0 -0
  96. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/description.py +0 -0
  97. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/description_test.py +0 -0
  98. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/function_generation.py +0 -0
  99. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/function_generation_test.py +0 -0
  100. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/mapping.py +0 -0
  101. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/mapping_test.py +0 -0
  102. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/parsing.py +0 -0
  103. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/parsing_test.py +0 -0
  104. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/prompting.py +0 -0
  105. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/prompting_test.py +0 -0
  106. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/schema.py +0 -0
  107. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/schema_generation.py +0 -0
  108. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/schema_generation_test.py +0 -0
  109. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/structured/schema_test.py +0 -0
  110. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/subscription.py +0 -0
  111. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/subscription_test.py +0 -0
  112. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/template.py +0 -0
  113. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/template_test.py +0 -0
  114. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/templates/__init__.py +0 -0
  115. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/templates/completion.py +0 -0
  116. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/templates/completion_test.py +0 -0
  117. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/templates/conversation.py +0 -0
  118. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/templates/conversation_test.py +0 -0
  119. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/templates/demonstration.py +0 -0
  120. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/templates/demonstration_test.py +0 -0
  121. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/templates/selfplay.py +0 -0
  122. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/templates/selfplay_test.py +0 -0
  123. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/text_formatting.py +0 -0
  124. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun/core/text_formatting_test.py +0 -0
  125. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun.egg-info/SOURCES.txt +0 -0
  126. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun.egg-info/dependency_links.txt +0 -0
  127. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun.egg-info/requires.txt +0 -0
  128. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/langfun.egg-info/top_level.txt +0 -0
  129. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/setup.cfg +0 -0
  130. {langfun-0.1.1.dev20240820 → langfun-0.1.1.dev20240821}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langfun
3
- Version: 0.1.1.dev20240820
3
+ Version: 0.1.1.dev20240821
4
4
  Summary: Langfun: Language as Functions.
5
5
  Home-page: https://github.com/google/langfun
6
6
  Author: Langfun Authors
@@ -15,6 +15,7 @@
15
15
 
16
16
  import collections
17
17
  import contextlib
18
+ import html
18
19
  import io
19
20
  from typing import Any, Callable, Iterator
20
21
 
@@ -126,7 +127,7 @@ def html_repr(
126
127
  if hasattr(v, '_repr_html_'):
127
128
  cs = v._repr_html_() # pylint: disable=protected-access
128
129
  else:
129
- cs = f'<span style="white-space: pre-wrap">{str(v)}</span>'
130
+ cs = f'<span style="white-space: pre-wrap">{html.escape(str(v))}</span>'
130
131
 
131
132
  key_color, key_bg_color, value_color, value_bg_color = item_color(k, v)
132
133
  key_span = html_round_text(
@@ -63,9 +63,12 @@ class SharingContentTest(unittest.TestCase):
63
63
  class Foo(pg.Object):
64
64
  x: int
65
65
 
66
- html = repr_utils.html_repr({'foo': pg.Ref(Foo(1))})
66
+ html = repr_utils.html_repr(
67
+ {'foo': pg.Ref(Foo(1)), 'bar': '<lf_image>'}
68
+ )
67
69
  self.assertIn('foo</span>', html)
68
70
  self.assertNotIn('Ref', html)
71
+ self.assertIn('&lt;lf_image&gt;', html)
69
72
 
70
73
 
71
74
  if __name__ == '__main__':
@@ -0,0 +1,181 @@
1
+ # Copyright 2023 The Langfun Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Scoring the output objects based on their inputs."""
15
+
16
+ from typing import Any, Type, Union
17
+
18
+ import langfun.core as lf
19
+ from langfun.core.structured import mapping
20
+ from langfun.core.structured import prompting
21
+ from langfun.core.structured import schema as schema_lib
22
+ import pyglove as pg
23
+
24
+
25
+ def score(
26
+ prompt: Union[str, pg.Symbolic] | list[str | pg.Symbolic],
27
+ completions: list[str | pg.Symbolic],
28
+ schema: Union[
29
+ schema_lib.Schema, Type[Any], list[Type[Any]], dict[str, Any], None
30
+ ] = None,
31
+ *,
32
+ lm: lf.LanguageModel | None = None,
33
+ examples: list[mapping.MappingExample] | None = None,
34
+ protocol: schema_lib.SchemaProtocol = 'python',
35
+ return_scoring_results: bool = False,
36
+ **kwargs,
37
+ ) -> list[float] | list[lf.LMScoringResult]:
38
+ """Scores the outputs based on the prompt.
39
+
40
+ Examples:
41
+ ```
42
+ # Example 1: Scoring text output based on the user prompt.
43
+ scores = lf.score('{{x}} + {{y}} =', ['1', '2', '3'], lm=lm, x=1, y=2)
44
+ assert len(scores) == 3
45
+
46
+ # Example 2: Scoring int output based on the formulated OOP prompt.
47
+ scores = lf.score('1 + 1 =', [1, 2, 3], lm=lm)
48
+ assert len(scores) == 3
49
+
50
+ class Answer(pg.Object):
51
+ result: int
52
+
53
+ # Example 3: Scoring object output based on the formulated OOP prompt.
54
+ scores = lf.score('1 + 1 =', [Answer(1), Answer(2), Answer(3)], lm=lm)
55
+ assert len(scores) == 3
56
+
57
+ # Example 4: Scoring object field value based on the formulated OOP prompt
58
+ # and the generated tokens before the first `pg.oneof`.
59
+ scores = lf.score('1 + 1 =', [Answer(pg.oneof([1, 2, 3]))], lm=lm)
60
+ assert len(scores) == 3
61
+
62
+ # Example 5: Scoring multiple prompt/completion pairs.
63
+ scores = lf.score(
64
+ ['1 + 1=', '2 + 3='],
65
+ ['2', '4'],
66
+ lm=lm
67
+ )
68
+ assert len(scores) == 2
69
+ ```
70
+
71
+ Args:
72
+ prompt: The prompt(s) based on which each completion will be scored.
73
+ completions: A list of strings or symbolic objects as the output.
74
+ schema: The schema as the output type. If None, it will be inferred from
75
+ the completions.
76
+ lm: The language model used for scoring.
77
+ examples: Fewshot exemplars used together with the prompt in getting the
78
+ completions.
79
+ protocol: The protocol for formulating the prompt based on objects.
80
+ return_scoring_results: If True, returns a list of `lf.LMScoringResult`,
81
+ otherwise returns a list of floats as the scores of each completion.
82
+ **kwargs: Keyword arguments that are referred by the prompt.
83
+
84
+ Returns:
85
+ A list of floats or `lf.LMScoringResult` as the score of each completion.
86
+ """
87
+ if not completions:
88
+ raise ValueError('`completions` must not be empty.')
89
+
90
+ if schema is None:
91
+ for c in completions:
92
+ if schema is None:
93
+ schema = type(c)
94
+ elif schema is not type(c):
95
+ raise ValueError(
96
+ '`schema` cannot be inferred from completions of different types: '
97
+ f'{[type(c) for c in completions]}.'
98
+ )
99
+
100
+ if isinstance(prompt, list):
101
+ prompts = []
102
+ for p in prompt:
103
+ prompts.append(
104
+ prompting.query_prompt(
105
+ p,
106
+ schema,
107
+ examples=examples,
108
+ protocol=protocol,
109
+ **kwargs,
110
+ )
111
+ )
112
+ input_message = prompts
113
+ else:
114
+ input_message = prompting.query_prompt(
115
+ prompt,
116
+ schema,
117
+ examples=examples,
118
+ protocol=protocol,
119
+ **kwargs,
120
+ )
121
+ if lm is None:
122
+ lm_override = lf.get_contextual_override('lm')
123
+ if lm_override is None:
124
+ raise ValueError('`lm` must be specified or provided from `lf.context`.')
125
+ lm = lm_override.value
126
+
127
+ completion_reprs = []
128
+ for c in completions:
129
+ if isinstance(c, mapping.MappingError):
130
+ completion_reprs.append(c.lm_response)
131
+ else:
132
+ rep = mapping.MappingExample.value_repr(
133
+ c, protocol=protocol, compact=False, verbose=False
134
+ )
135
+
136
+ # NOTE(daiyip): supporting scenario of scoring object field with
137
+ # `pg.oneof`.
138
+ oneof_pos = rep.find('OneOf(')
139
+ if oneof_pos == -1:
140
+ completion_reprs.append(rep)
141
+ else:
142
+ assert protocol == 'python', protocol
143
+ if isinstance(input_message, list):
144
+ raise ValueError(
145
+ 'Scoring on object fields using `pg.oneof` must share the '
146
+ f'same prompt. Encountered: {prompt}'
147
+ )
148
+ input_message.text += '\n' + rep[:oneof_pos]
149
+ oneof = _get_first_oneof(c)
150
+ for v in oneof.candidates:
151
+ completion_reprs.append(
152
+ pg.format(
153
+ v,
154
+ python_format=True,
155
+ compact=False,
156
+ verbose=False,
157
+ root_indent=oneof.sym_path.depth
158
+ )
159
+ )
160
+
161
+ results = lm.score(
162
+ input_message,
163
+ completion_reprs,
164
+ )
165
+ if return_scoring_results:
166
+ return results
167
+ return [r.score for r in results]
168
+
169
+
170
+ def _get_first_oneof(value: Any) -> pg.hyper.OneOf:
171
+ """Gets the first pg.oneof from a symbolic object."""
172
+ oneofs = []
173
+ def select_oneofs(k, v, p):
174
+ del k, p
175
+ if isinstance(v, pg.hyper.OneOf):
176
+ oneofs.append(v)
177
+ return pg.TraverseAction.CONTINUE
178
+ return pg.TraverseAction.ENTER
179
+ pg.traverse(value, select_oneofs)
180
+ assert oneofs
181
+ return oneofs[0]
@@ -16,6 +16,11 @@ import unittest
16
16
  import langfun.core as lf
17
17
  from langfun.core.llms import fake
18
18
  from langfun.core.structured import scoring
19
+ import pyglove as pg
20
+
21
+
22
+ class Answer(pg.Object):
23
+ result: int
19
24
 
20
25
 
21
26
  class ScoringTest(unittest.TestCase):
@@ -32,9 +37,28 @@ class ScoringTest(unittest.TestCase):
32
37
  with self.assertRaisesRegex(ValueError, '`lm` must be specified'):
33
38
  scoring.score('hi', [1, 2])
34
39
 
40
+ with self.assertRaisesRegex(
41
+ ValueError,
42
+ 'Scoring on object fields using `pg.oneof` must share the same prompt',
43
+ ):
44
+ scoring.score(
45
+ ['1 + 1=', '2 + 3='],
46
+ [Answer(pg.oneof([1, 2, 3]))],
47
+ lm=fake.Echo(),
48
+ )
49
+
35
50
  def test_score(self):
36
51
  self.assertEqual(scoring.score('hi', [1, 2], lm=fake.Echo()), [0.0, -1.0])
37
52
 
53
+ def test_score_on_field_values(self):
54
+ self.assertEqual(
55
+ scoring.score(
56
+ '1 + 1=',
57
+ [Answer(pg.oneof([1, 2, 3]))], lm=fake.Echo()
58
+ ),
59
+ [0.0, -1.0, -2.0]
60
+ )
61
+
38
62
  def test_score_returning_scoring_results(self):
39
63
  self.assertEqual(scoring.score(
40
64
  'hi', [1, 2], lm=fake.Echo(), return_scoring_results=True),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langfun
3
- Version: 0.1.1.dev20240820
3
+ Version: 0.1.1.dev20240821
4
4
  Summary: Langfun: Language as Functions.
5
5
  Home-page: https://github.com/google/langfun
6
6
  Author: Langfun Authors
@@ -1,95 +0,0 @@
1
- # Copyright 2023 The Langfun Authors
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
- """Scoring the output objects based on their inputs."""
15
-
16
- from typing import Any, Type, Union
17
-
18
- import langfun.core as lf
19
- from langfun.core.structured import mapping
20
- from langfun.core.structured import prompting
21
- from langfun.core.structured import schema as schema_lib
22
- import pyglove as pg
23
-
24
-
25
- def score(
26
- prompt: Union[str, pg.Symbolic] | list[str | pg.Symbolic],
27
- completions: list[str | pg.Symbolic],
28
- schema: Union[
29
- schema_lib.Schema, Type[Any], list[Type[Any]], dict[str, Any], None
30
- ] = None,
31
- *,
32
- lm: lf.LanguageModel | None = None,
33
- examples: list[mapping.MappingExample] | None = None,
34
- protocol: schema_lib.SchemaProtocol = 'python',
35
- return_scoring_results: bool = False,
36
- **kwargs,
37
- ) -> list[float] | list[lf.LMScoringResult]:
38
- """Scores the outputs based on the prompt."""
39
- if not completions:
40
- raise ValueError('`completions` must not be empty.')
41
-
42
- if schema is None:
43
- for c in completions:
44
- if schema is None:
45
- schema = type(c)
46
- elif schema is not type(c):
47
- raise ValueError(
48
- '`schema` cannot be inferred from completions of different types: '
49
- f'{[type(c) for c in completions]}.'
50
- )
51
-
52
- if isinstance(prompt, list):
53
- prompts = []
54
- for p in prompt:
55
- prompts.append(
56
- prompting.query_prompt(
57
- p,
58
- schema,
59
- examples=examples,
60
- protocol=protocol,
61
- **kwargs,
62
- )
63
- )
64
- input_message = prompts
65
- else:
66
- input_message = prompting.query_prompt(
67
- prompt,
68
- schema,
69
- examples=examples,
70
- protocol=protocol,
71
- **kwargs,
72
- )
73
- if lm is None:
74
- lm_override = lf.get_contextual_override('lm')
75
- if lm_override is None:
76
- raise ValueError('`lm` must be specified or provided from `lf.context`.')
77
- lm = lm_override.value
78
-
79
- completion_reprs = []
80
- for c in completions:
81
- if isinstance(c, mapping.MappingError):
82
- rep = c.lm_response
83
- else:
84
- rep = mapping.MappingExample.value_repr(
85
- c, protocol=protocol, compact=False, verbose=False
86
- )
87
- completion_reprs.append(rep)
88
-
89
- results = lm.score(
90
- input_message,
91
- completion_reprs,
92
- )
93
- if return_scoring_results:
94
- return results
95
- return [r.score for r in results]