langfun 0.0.2.dev20240104__tar.gz → 0.0.2.dev20240106__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.
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/PKG-INFO +2 -2
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/correction.py +1 -1
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/generation.py +14 -11
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/eval/base.py +12 -14
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/eval/base_test.py +13 -13
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/natural_language.py +7 -10
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/natural_language_test.py +3 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/__init__.py +0 -7
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/completion.py +75 -50
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/completion_test.py +29 -36
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/description.py +17 -14
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/description_test.py +19 -9
- langfun-0.0.2.dev20240106/langfun/core/structured/mapping.py +335 -0
- langfun-0.0.2.dev20240106/langfun/core/structured/mapping_test.py +125 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/parsing.py +33 -33
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/parsing_test.py +30 -26
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/prompting.py +34 -41
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/prompting_test.py +16 -16
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/schema.py +18 -3
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/schema_test.py +27 -1
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/template.py +13 -2
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/template_test.py +2 -2
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun.egg-info/PKG-INFO +2 -2
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun.egg-info/requires.txt +1 -1
- langfun-0.0.2.dev20240104/langfun/core/structured/mapping.py +0 -445
- langfun-0.0.2.dev20240104/langfun/core/structured/mapping_test.py +0 -166
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/LICENSE +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/README.md +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/__init__.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/__init__.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/__init__.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/__init__.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/correction_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/errors.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/errors_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/execution.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/execution_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/generation_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/parsing.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/parsing_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/permissions.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/permissions_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/component.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/component_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/concurrent.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/concurrent_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/console.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/console_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/eval/__init__.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/eval/matching.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/eval/matching_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/eval/scoring.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/eval/scoring_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/langfunc.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/langfunc_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/language_model.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/language_model_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/llms/__init__.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/llms/cache/__init__.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/llms/cache/base.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/llms/cache/in_memory.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/llms/cache/in_memory_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/llms/fake.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/llms/fake_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/llms/llama_cpp.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/llms/llama_cpp_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/llms/openai.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/llms/openai_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/memories/__init__.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/memories/conversation_history.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/memories/conversation_history_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/memory.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/message.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/message_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/modalities/__init__.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/modalities/image.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/modalities/image_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/modality.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/modality_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/sampling.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/sampling_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/subscription.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/subscription_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/templates/__init__.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/templates/completion.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/templates/completion_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/templates/conversation.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/templates/conversation_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/templates/demonstration.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/templates/demonstration_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/templates/selfplay.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/templates/selfplay_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/text_formatting.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/text_formatting_test.py +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun.egg-info/SOURCES.txt +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun.egg-info/dependency_links.txt +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun.egg-info/top_level.txt +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/setup.cfg +0 -0
- {langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/setup.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: langfun
|
3
|
-
Version: 0.0.2.
|
3
|
+
Version: 0.0.2.dev20240106
|
4
4
|
Summary: Langfun: Language as Functions.
|
5
5
|
Home-page: https://github.com/google/langfun
|
6
6
|
Author: Langfun Authors
|
@@ -23,7 +23,7 @@ Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
24
24
|
Requires-Dist: jinja2>=3.1.2
|
25
25
|
Requires-Dist: openai==0.27.2
|
26
|
-
Requires-Dist: pyglove>=0.4.
|
26
|
+
Requires-Dist: pyglove>=0.4.5.dev20240105
|
27
27
|
Requires-Dist: requests>=2.31.0
|
28
28
|
Requires-Dist: termcolor==1.1.0
|
29
29
|
Requires-Dist: tqdm>=4.64.1
|
{langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/correction.py
RENAMED
@@ -107,7 +107,7 @@ def run_with_correction(
|
|
107
107
|
|
108
108
|
examples = examples or DEFAULT_CODE_CORRECTION_EXAMPLES
|
109
109
|
examples = [ # pylint: disable=g-complex-comprehension
|
110
|
-
completion.
|
110
|
+
completion.mapping.MappingExample(
|
111
111
|
CodeCorrection.partial(ex.latest_code, ex.correction_history),
|
112
112
|
ex,
|
113
113
|
)
|
{langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/coding/python/generation.py
RENAMED
@@ -21,12 +21,12 @@ import pyglove as pg
|
|
21
21
|
|
22
22
|
|
23
23
|
class PythonCode(pg.Object):
|
24
|
-
"""Symbolic class for Python code.
|
24
|
+
"""Symbolic class for Python code.
|
25
25
|
|
26
|
-
source
|
27
|
-
|
28
|
-
|
29
|
-
]
|
26
|
+
The source code will be directly passed into eval() for execution. The value
|
27
|
+
of the last expression of the source will be returned.
|
28
|
+
"""
|
29
|
+
source: Annotated[str, 'Source code.']
|
30
30
|
|
31
31
|
_TLS_AUTO_RUN = '__auto_run__'
|
32
32
|
|
@@ -135,18 +135,21 @@ class PythonCode(pg.Object):
|
|
135
135
|
global_vars=global_vars,
|
136
136
|
sandbox=sandbox,
|
137
137
|
timeout=timeout,
|
138
|
-
outputs_intermediate=True
|
138
|
+
outputs_intermediate=True,
|
139
|
+
)
|
139
140
|
|
140
141
|
|
141
142
|
class PythonFunction(pg.Object):
|
142
|
-
"""Generated Python function via source code.
|
143
|
+
"""Generated Python function via source code.
|
144
|
+
|
145
|
+
The source code will be directly passed into eval() for execution and the
|
146
|
+
output of the function will be returned.
|
147
|
+
"""
|
148
|
+
|
143
149
|
name: str
|
144
150
|
args: dict[str, str]
|
145
151
|
returns: str
|
146
|
-
source: Annotated[
|
147
|
-
str,
|
148
|
-
'Source code for the Python function. '
|
149
|
-
]
|
152
|
+
source: Annotated[str, 'Source code for the Python function. ']
|
150
153
|
|
151
154
|
def _on_bound(self):
|
152
155
|
super()._on_bound()
|
@@ -634,7 +634,8 @@ class Evaluation(Evaluable):
|
|
634
634
|
'examples will be used for parsing. For "query" and "complete", it '
|
635
635
|
'must be provided, and the fewshot examples will be used directly '
|
636
636
|
'for prompting. Here are the example code on how the '
|
637
|
-
'functors should be defined:'
|
637
|
+
'functors should be defined:'
|
638
|
+
+ inspect.cleandoc("""
|
638
639
|
```
|
639
640
|
@pg.functor()
|
640
641
|
def solution():
|
@@ -648,9 +649,9 @@ class Evaluation(Evaluable):
|
|
648
649
|
final_answer: int
|
649
650
|
return Solution, [
|
650
651
|
lf.structured.MappingExample(
|
651
|
-
|
652
|
-
|
653
|
-
|
652
|
+
input='Compute 1 + 2',
|
653
|
+
output=Solution(3),
|
654
|
+
schema=Solution)
|
654
655
|
]
|
655
656
|
```
|
656
657
|
""")
|
@@ -832,16 +833,13 @@ class Evaluation(Evaluable):
|
|
832
833
|
|
833
834
|
completion_examples = []
|
834
835
|
for ex in fewshot_examples:
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
right=example_cls(ex.nl_context, **init_args),
|
843
|
-
)
|
844
|
-
)
|
836
|
+
example_cls = ex.output.__class__
|
837
|
+
self._maybe_adjust_schema_for_completion(example_cls)
|
838
|
+
ex = lf.structured.MappingExample(
|
839
|
+
context=ex.context,
|
840
|
+
input=example_cls.partial(ex.input),
|
841
|
+
output=example_cls(ex.input, **ex.output.sym_init_args),
|
842
|
+
)
|
845
843
|
completion_examples.append(ex)
|
846
844
|
return completion_examples
|
847
845
|
|
@@ -45,9 +45,9 @@ def answer_schema():
|
|
45
45
|
def answer_schema_with_fewshot_examples():
|
46
46
|
return Solution, [
|
47
47
|
lf_structured.MappingExample(
|
48
|
-
|
48
|
+
input='The result of one plus two',
|
49
|
+
output=Solution(3),
|
49
50
|
schema=Solution,
|
50
|
-
value=Solution(3)
|
51
51
|
)
|
52
52
|
]
|
53
53
|
|
@@ -120,10 +120,11 @@ class EvaluationTest(unittest.TestCase):
|
|
120
120
|
s.fewshot_examples,
|
121
121
|
[
|
122
122
|
lf_structured.MappingExample(
|
123
|
-
|
123
|
+
input='The result of one plus two',
|
124
|
+
output=Solution(3),
|
124
125
|
schema=Solution,
|
125
|
-
|
126
|
-
]
|
126
|
+
)
|
127
|
+
],
|
127
128
|
)
|
128
129
|
)
|
129
130
|
|
@@ -137,9 +138,9 @@ class EvaluationTest(unittest.TestCase):
|
|
137
138
|
|
138
139
|
return Solution1, [
|
139
140
|
lf.structured.MappingExample(
|
140
|
-
|
141
|
+
input='The result of one plus two',
|
142
|
+
output=Solution1(3),
|
141
143
|
schema=Solution1,
|
142
|
-
value=Solution1(3)
|
143
144
|
)
|
144
145
|
]
|
145
146
|
|
@@ -159,13 +160,12 @@ class EvaluationTest(unittest.TestCase):
|
|
159
160
|
fewshot_examples,
|
160
161
|
[
|
161
162
|
lf.structured.MappingExample(
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
)
|
163
|
+
input=solution_cls.partial(
|
164
|
+
question='The result of one plus two'
|
165
|
+
),
|
166
|
+
output=solution_cls('The result of one plus two', 3),
|
167
167
|
)
|
168
|
-
]
|
168
|
+
],
|
169
169
|
)
|
170
170
|
)
|
171
171
|
|
@@ -26,16 +26,13 @@ class NaturalLanguageFormattable(pg.Formattable):
|
|
26
26
|
|
27
27
|
def format(
|
28
28
|
self,
|
29
|
-
|
30
|
-
|
31
|
-
root_indent: int = 0,
|
29
|
+
*args,
|
30
|
+
natural_language: bool = False,
|
32
31
|
**kwargs
|
33
32
|
) -> str:
|
34
|
-
if
|
35
|
-
# For `repr(x)`, which returns the symbolic representation of
|
36
|
-
# current object.
|
37
|
-
return super().format(compact, verbose, root_indent, **kwargs)
|
38
|
-
else:
|
39
|
-
# For `str(x)`, which returns the natural language representation of
|
40
|
-
# current object.
|
33
|
+
if natural_language:
|
41
34
|
return self.natural_language_format()
|
35
|
+
return super().format(*args, **kwargs)
|
36
|
+
|
37
|
+
def __str__(self):
|
38
|
+
return self.natural_language_format()
|
{langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/natural_language_test.py
RENAMED
@@ -16,6 +16,7 @@ import unittest
|
|
16
16
|
|
17
17
|
from langfun.core import component
|
18
18
|
from langfun.core import natural_language as nl
|
19
|
+
import pyglove as pg
|
19
20
|
|
20
21
|
|
21
22
|
class NaturalLanguageFormattableTest(unittest.TestCase):
|
@@ -31,6 +32,8 @@ class NaturalLanguageFormattableTest(unittest.TestCase):
|
|
31
32
|
|
32
33
|
a = A(1, 'abc')
|
33
34
|
self.assertEqual(repr(a), 'A(x=1, y=\'abc\')')
|
35
|
+
with pg.object_utils.repr_format(natural_language=True):
|
36
|
+
self.assertEqual(repr(a), "A simple object with 1 and 'abc'.")
|
34
37
|
self.assertEqual(str(a), "A simple object with 1 and 'abc'.")
|
35
38
|
|
36
39
|
|
@@ -47,11 +47,6 @@ from langfun.core.structured.schema import value_repr
|
|
47
47
|
from langfun.core.structured.mapping import Mapping
|
48
48
|
from langfun.core.structured.mapping import MappingExample
|
49
49
|
|
50
|
-
# Mappings of between different forms of content.
|
51
|
-
from langfun.core.structured.mapping import NaturalLanguageToStructure
|
52
|
-
from langfun.core.structured.mapping import StructureToNaturalLanguage
|
53
|
-
from langfun.core.structured.mapping import StructureToStructure
|
54
|
-
|
55
50
|
from langfun.core.structured.parsing import ParseStructure
|
56
51
|
from langfun.core.structured.parsing import ParseStructureJson
|
57
52
|
from langfun.core.structured.parsing import ParseStructurePython
|
@@ -74,8 +69,6 @@ from langfun.core.structured.completion import complete
|
|
74
69
|
from langfun.core.structured.parsing import DEFAULT_PARSE_EXAMPLES
|
75
70
|
from langfun.core.structured.description import DEFAULT_DESCRIBE_EXAMPLES
|
76
71
|
|
77
|
-
from langfun.core.structured.completion import completion_example
|
78
|
-
|
79
72
|
# Default examples.
|
80
73
|
|
81
74
|
|
{langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/completion.py
RENAMED
@@ -11,9 +11,9 @@
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
|
-
"""
|
14
|
+
"""Symbolic completion."""
|
15
15
|
|
16
|
-
from typing import Any
|
16
|
+
from typing import Annotated, Any, Type
|
17
17
|
|
18
18
|
import langfun.core as lf
|
19
19
|
from langfun.core.structured import mapping
|
@@ -21,53 +21,37 @@ from langfun.core.structured import schema as schema_lib
|
|
21
21
|
import pyglove as pg
|
22
22
|
|
23
23
|
|
24
|
-
class CompleteStructure(mapping.
|
24
|
+
class CompleteStructure(mapping.Mapping):
|
25
25
|
"""Complete structure by filling the missing fields."""
|
26
26
|
|
27
|
+
input: Annotated[
|
28
|
+
pg.Symbolic, 'A symbolic object with `lf.MISSING` values to complete.'
|
29
|
+
] = lf.contextual()
|
30
|
+
|
27
31
|
mapping_template = lf.Template("""
|
28
|
-
{{
|
29
|
-
{{
|
32
|
+
{{ input_title }}:
|
33
|
+
{{ example.input_repr() | indent(2, True) }}
|
30
34
|
|
31
|
-
{%- if missing_type_dependencies(example.
|
35
|
+
{%- if missing_type_dependencies(example.input) %}
|
32
36
|
|
33
|
-
{{
|
34
|
-
{{
|
37
|
+
{{ schema_title }}:
|
38
|
+
{{ class_defs_repr(example.input) | indent(2, True) }}
|
35
39
|
{%- endif %}
|
36
|
-
{%- if has_modalities(example.
|
40
|
+
{%- if has_modalities(example.input) %}
|
37
41
|
|
38
42
|
{{ modality_refs_title }}:
|
39
|
-
{{
|
43
|
+
{{ modality_refs_repr(example.input) | indent(2, True) }}
|
40
44
|
{%- endif %}
|
41
45
|
|
42
|
-
{{
|
43
|
-
{%- if example.
|
44
|
-
{{
|
46
|
+
{{ output_title }}:
|
47
|
+
{%- if example.has_output %}
|
48
|
+
{{ example.output_repr() | indent(2, True) }}
|
45
49
|
{% endif -%}
|
46
50
|
""")
|
47
51
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
nl_context=None,
|
52
|
-
nl_text=None,
|
53
|
-
schema=self.input_value.__class__,
|
54
|
-
value=mapping.Pair(
|
55
|
-
left=pg.Ref(self.input_value), right=schema_lib.MISSING
|
56
|
-
),
|
57
|
-
)
|
58
|
-
|
59
|
-
def _on_bound(self):
|
60
|
-
super()._on_bound()
|
61
|
-
if self.examples:
|
62
|
-
for example in self.examples:
|
63
|
-
if not isinstance(example.value, mapping.Pair):
|
64
|
-
raise ValueError(
|
65
|
-
'The value of example must be a `lf.structured.Pair` object. '
|
66
|
-
f'Encountered: { example.value }.'
|
67
|
-
)
|
68
|
-
|
69
|
-
input_value_title = 'INPUT_OBJECT'
|
70
|
-
output_value_title = 'OUTPUT_OBJECT'
|
52
|
+
input_title = 'INPUT_OBJECT'
|
53
|
+
output_title = 'OUTPUT_OBJECT'
|
54
|
+
schema_title = 'CLASS_DEFINITIONS'
|
71
55
|
|
72
56
|
preamble = lf.LangFunc(
|
73
57
|
"""
|
@@ -77,7 +61,7 @@ class CompleteStructure(mapping.StructureToStructure):
|
|
77
61
|
1. Each MISSING field contains a Python annotation, please fill the value based on the annotation.
|
78
62
|
2. Classes for the MISSING fields are defined under CLASS_DEFINITIONS.
|
79
63
|
|
80
|
-
{{
|
64
|
+
{{input_title}}:
|
81
65
|
```python
|
82
66
|
Answer(
|
83
67
|
question='1 + 1 =',
|
@@ -85,7 +69,7 @@ class CompleteStructure(mapping.StructureToStructure):
|
|
85
69
|
)
|
86
70
|
```
|
87
71
|
|
88
|
-
{{
|
72
|
+
{{output_title}}:
|
89
73
|
```python
|
90
74
|
Answer(
|
91
75
|
question='1 + 1 =',
|
@@ -93,16 +77,62 @@ class CompleteStructure(mapping.StructureToStructure):
|
|
93
77
|
)
|
94
78
|
```
|
95
79
|
""",
|
96
|
-
|
97
|
-
|
80
|
+
input_title=input_title,
|
81
|
+
output_title=output_title,
|
98
82
|
)
|
99
83
|
|
100
|
-
|
101
|
-
|
102
|
-
|
84
|
+
@property
|
85
|
+
def mapping_request(self) -> mapping.MappingExample:
|
86
|
+
"""Returns a MappingExample as the mapping request."""
|
87
|
+
return mapping.MappingExample(
|
88
|
+
input=pg.Ref(self.input),
|
89
|
+
# Use the schema of input object.
|
90
|
+
schema=pg.Ref(schema_lib.Schema.from_value(self.input.__class__)),
|
91
|
+
context=self.context,
|
92
|
+
)
|
93
|
+
|
94
|
+
def transform_input(self, lm_input: lf.Message) -> lf.Message:
|
95
|
+
if not pg.contains(self.input, type=schema_lib.Missing):
|
96
|
+
raise ValueError(
|
97
|
+
'The input of `lf.complete` must contain a least one '
|
98
|
+
f'missing value. Encountered: {self.input}.'
|
99
|
+
)
|
100
|
+
|
101
|
+
# Find modalities to fill the input message.
|
102
|
+
modalities = self.modalities(self.input)
|
103
|
+
modalities.update(
|
104
|
+
self.modalities(self.examples, root_path=pg.KeyPath('examples'))
|
105
|
+
)
|
106
|
+
if modalities:
|
107
|
+
lm_input.metadata.update(pg.object_utils.canonicalize(modalities))
|
108
|
+
return lm_input
|
109
|
+
|
110
|
+
def missing_type_dependencies(self, value: Any) -> list[Type[Any]]:
|
111
|
+
value_specs = tuple(
|
112
|
+
[v.value_spec for v in schema_lib.Missing.find_missing(value).values()]
|
113
|
+
)
|
114
|
+
return schema_lib.class_dependencies(value_specs, include_subclasses=True)
|
115
|
+
|
116
|
+
def class_defs_repr(self, value: Any) -> str | None:
|
117
|
+
return schema_lib.class_definitions(
|
118
|
+
self.missing_type_dependencies(value), markdown=True
|
119
|
+
)
|
120
|
+
|
121
|
+
def postprocess_result(self, result: Any) -> Any:
|
122
|
+
"""Postprocess result."""
|
123
|
+
# Try restore modality objects from the input value to output value.
|
124
|
+
modalities = self.modalities(self.input)
|
125
|
+
if modalities:
|
126
|
+
result.rebind(modalities)
|
127
|
+
return result
|
103
128
|
|
104
129
|
def globals(self):
|
105
130
|
context = super().globals()
|
131
|
+
|
132
|
+
# Add class dependencies from the input value to the globals.
|
133
|
+
classes = schema_lib.class_dependencies(self.input)
|
134
|
+
context.update({cls.__name__: cls for cls in classes})
|
135
|
+
|
106
136
|
# NOTE(daiyip): since `lf.complete` could have fields of Any type, which
|
107
137
|
# could be user provided objects. For LLMs to restores these objects, we
|
108
138
|
# need to expose their types to the code evaluation context.
|
@@ -117,15 +147,10 @@ class CompleteStructure(mapping.StructureToStructure):
|
|
117
147
|
if isinstance(v, pg.Object):
|
118
148
|
cls = v.__class__
|
119
149
|
context[cls.__name__] = cls
|
120
|
-
pg.traverse(self.
|
150
|
+
pg.traverse(self.input, _visit)
|
121
151
|
return context
|
122
152
|
|
123
153
|
|
124
|
-
def completion_example(left: Any, right: Any) -> mapping.MappingExample:
|
125
|
-
"""Makes a mapping example for completion."""
|
126
|
-
return mapping.MappingExample(value=mapping.Pair(left=left, right=right))
|
127
|
-
|
128
|
-
|
129
154
|
def complete(
|
130
155
|
input_value: pg.Symbolic,
|
131
156
|
default: Any = lf.RAISE_IF_HAS_ERROR,
|
@@ -200,5 +225,5 @@ def complete(
|
|
200
225
|
context.update(kwargs)
|
201
226
|
|
202
227
|
with t.override(**context):
|
203
|
-
output = t(
|
228
|
+
output = t(input=schema_lib.mark_missing(input_value))
|
204
229
|
return output if returns_message else output.result
|
{langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/completion_test.py
RENAMED
@@ -59,7 +59,7 @@ class CompleteStructureTest(unittest.TestCase):
|
|
59
59
|
)
|
60
60
|
)
|
61
61
|
self.assertEqual(
|
62
|
-
l.render(
|
62
|
+
l.render(input=input_value).text,
|
63
63
|
inspect.cleandoc("""
|
64
64
|
Please generate the OUTPUT_OBJECT by completing the MISSING fields from the last INPUT_OBJECT.
|
65
65
|
|
@@ -133,7 +133,7 @@ class CompleteStructureTest(unittest.TestCase):
|
|
133
133
|
)
|
134
134
|
)
|
135
135
|
self.assertEqual(
|
136
|
-
l.render(
|
136
|
+
l.render(input=input_value).text,
|
137
137
|
inspect.cleandoc("""
|
138
138
|
Please generate the OUTPUT_OBJECT by completing the MISSING fields from the last INPUT_OBJECT.
|
139
139
|
|
@@ -213,7 +213,7 @@ class CompleteStructureTest(unittest.TestCase):
|
|
213
213
|
)
|
214
214
|
)
|
215
215
|
self.assertEqual(
|
216
|
-
l.render(
|
216
|
+
l.render(input=input_value).text,
|
217
217
|
inspect.cleandoc("""
|
218
218
|
Please generate the OUTPUT_OBJECT by completing the MISSING fields from the last INPUT_OBJECT.
|
219
219
|
|
@@ -410,15 +410,13 @@ class CompleteStructureTest(unittest.TestCase):
|
|
410
410
|
l = completion.CompleteStructure(
|
411
411
|
examples=[
|
412
412
|
mapping.MappingExample(
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
),
|
421
|
-
)
|
413
|
+
input=Animal.partial(
|
414
|
+
modalities.Image.from_bytes(b'image_of_rabbit')
|
415
|
+
),
|
416
|
+
output=Animal(
|
417
|
+
modalities.Image.from_bytes(b'image_of_rabbit'),
|
418
|
+
'rabbit',
|
419
|
+
),
|
422
420
|
)
|
423
421
|
]
|
424
422
|
)
|
@@ -427,7 +425,8 @@ class CompleteStructureTest(unittest.TestCase):
|
|
427
425
|
modalities.Image.from_bytes(b'image_of_elephant'),
|
428
426
|
)
|
429
427
|
)
|
430
|
-
lm_input = l.render(
|
428
|
+
lm_input = l.render(input=input_value)
|
429
|
+
self.maxDiff = None
|
431
430
|
self.assertEqual(
|
432
431
|
lm_input.text,
|
433
432
|
inspect.cleandoc("""
|
@@ -463,9 +462,9 @@ class CompleteStructureTest(unittest.TestCase):
|
|
463
462
|
)
|
464
463
|
```
|
465
464
|
|
466
|
-
|
465
|
+
MODALITY_REFERENCES:
|
467
466
|
{
|
468
|
-
'image': {{examples[0].
|
467
|
+
'image': {{examples[0].input.image}}
|
469
468
|
}
|
470
469
|
|
471
470
|
OUTPUT_OBJECT:
|
@@ -489,7 +488,7 @@ class CompleteStructureTest(unittest.TestCase):
|
|
489
488
|
)
|
490
489
|
```
|
491
490
|
|
492
|
-
|
491
|
+
MODALITY_REFERENCES:
|
493
492
|
{
|
494
493
|
'image': {{image}}
|
495
494
|
}
|
@@ -504,28 +503,20 @@ class CompleteStructureTest(unittest.TestCase):
|
|
504
503
|
'image': lm_input.get('image'),
|
505
504
|
},
|
506
505
|
{
|
507
|
-
'examples': [
|
508
|
-
{
|
509
|
-
'
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
'right': {
|
516
|
-
'image': modalities.Image.from_bytes(
|
517
|
-
b'image_of_rabbit'
|
518
|
-
)
|
519
|
-
},
|
520
|
-
}
|
521
|
-
}
|
522
|
-
],
|
506
|
+
'examples': [{
|
507
|
+
'input': {
|
508
|
+
'image': modalities.Image.from_bytes(b'image_of_rabbit')
|
509
|
+
},
|
510
|
+
'output': {
|
511
|
+
'image': modalities.Image.from_bytes(b'image_of_rabbit')
|
512
|
+
},
|
513
|
+
}],
|
523
514
|
'image': modalities.Image.from_bytes(b'image_of_elephant'),
|
524
515
|
},
|
525
516
|
)
|
526
517
|
)
|
527
518
|
lm_output = l(
|
528
|
-
|
519
|
+
input=input_value,
|
529
520
|
lm=fake.StaticResponse(inspect.cleandoc("""
|
530
521
|
```python
|
531
522
|
Animal(
|
@@ -595,9 +586,11 @@ class CompleteStructureTest(unittest.TestCase):
|
|
595
586
|
with self.assertRaises(IndexError):
|
596
587
|
completion.complete(Activity.partial(), lm=lm)
|
597
588
|
|
598
|
-
def
|
599
|
-
with self.assertRaisesRegex(
|
600
|
-
|
589
|
+
def test_bad_call(self):
|
590
|
+
with self.assertRaisesRegex(
|
591
|
+
ValueError, '.*must contain a least .* missing'
|
592
|
+
):
|
593
|
+
completion.complete(Activity('foo'), lm=fake.StaticResponse(''))
|
601
594
|
|
602
595
|
def test_bad_transform(self):
|
603
596
|
with lf.context(
|
{langfun-0.0.2.dev20240104 → langfun-0.0.2.dev20240106}/langfun/core/structured/description.py
RENAMED
@@ -11,7 +11,7 @@
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
|
-
"""
|
14
|
+
"""Symbolic description."""
|
15
15
|
|
16
16
|
import inspect
|
17
17
|
from typing import Any, Literal
|
@@ -22,11 +22,15 @@ import pyglove as pg
|
|
22
22
|
|
23
23
|
|
24
24
|
@pg.use_init_args(['examples'])
|
25
|
-
class DescribeStructure(mapping.
|
25
|
+
class DescribeStructure(mapping.Mapping):
|
26
26
|
"""Describe a structured value in natural language."""
|
27
27
|
|
28
|
+
input_title = 'PYTHON_OBJECT'
|
29
|
+
context_title = 'CONTEXT_FOR_DESCRIPTION'
|
30
|
+
output_title = 'NATURAL_LANGUAGE_TEXT'
|
31
|
+
|
28
32
|
preamble = """
|
29
|
-
Please help describe {{
|
33
|
+
Please help describe {{ input_title }} in natural language.
|
30
34
|
|
31
35
|
INSTRUCTIONS:
|
32
36
|
1. Do not add details which are not present in the object.
|
@@ -103,7 +107,7 @@ def describe(
|
|
103
107
|
if lm is not None:
|
104
108
|
kwargs['lm'] = lm
|
105
109
|
return DescribeStructure(examples)(
|
106
|
-
|
110
|
+
input=value, context=context, **kwargs
|
107
111
|
).text
|
108
112
|
|
109
113
|
|
@@ -130,16 +134,8 @@ class _Country(pg.Object):
|
|
130
134
|
|
131
135
|
DEFAULT_DESCRIBE_EXAMPLES: list[mapping.MappingExample] = [
|
132
136
|
mapping.MappingExample(
|
133
|
-
|
134
|
-
|
135
|
-
The United States of America is a country primarily located in North America
|
136
|
-
consisting of fifty states. It shares land borders with Canada to its north
|
137
|
-
and with Mexico to its south and has maritime borders with the Bahamas, Cuba,
|
138
|
-
Russia, and other nations. With a population of over 333 million. The national
|
139
|
-
capital of the United States is Washington, D.C.
|
140
|
-
"""),
|
141
|
-
schema=None,
|
142
|
-
value=_Country(
|
137
|
+
context='Brief intro to United States',
|
138
|
+
input=_Country(
|
143
139
|
name='The United States of America',
|
144
140
|
continents=['North America'],
|
145
141
|
num_states=50,
|
@@ -154,5 +150,12 @@ DEFAULT_DESCRIBE_EXAMPLES: list[mapping.MappingExample] = [
|
|
154
150
|
capital='Washington, D.C',
|
155
151
|
president=None,
|
156
152
|
),
|
153
|
+
output=inspect.cleandoc("""
|
154
|
+
The United States of America is a country primarily located in North America
|
155
|
+
consisting of fifty states. It shares land borders with Canada to its north
|
156
|
+
and with Mexico to its south and has maritime borders with the Bahamas, Cuba,
|
157
|
+
Russia, and other nations. With a population of over 333 million. The national
|
158
|
+
capital of the United States is Washington, D.C.
|
159
|
+
"""),
|
157
160
|
),
|
158
161
|
]
|