langfun 0.0.2.dev20240325__tar.gz → 0.0.2.dev20240329__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.dev20240325 → langfun-0.0.2.dev20240329}/PKG-INFO +2 -2
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/eval/base.py +39 -18
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/eval/base_test.py +4 -9
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/eval/matching_test.py +2 -4
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/eval/scoring_test.py +1 -2
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/schema.py +21 -20
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/schema_generation.py +2 -3
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/schema_test.py +38 -21
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun.egg-info/PKG-INFO +2 -2
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun.egg-info/requires.txt +1 -1
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/LICENSE +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/README.md +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/__init__.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/__init__.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/__init__.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/__init__.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/correction.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/correction_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/errors.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/errors_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/execution.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/execution_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/generation.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/generation_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/parsing.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/parsing_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/permissions.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/permissions_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/component.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/component_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/concurrent.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/concurrent_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/console.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/console_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/eval/__init__.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/eval/matching.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/eval/scoring.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/langfunc.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/langfunc_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/language_model.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/language_model_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/__init__.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/cache/__init__.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/cache/base.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/cache/in_memory.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/cache/in_memory_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/fake.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/fake_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/gemini.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/gemini_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/llama_cpp.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/llama_cpp_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/openai.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/openai_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/memories/__init__.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/memories/conversation_history.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/memories/conversation_history_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/memory.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/message.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/message_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/modalities/__init__.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/modalities/image.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/modalities/image_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/modalities/mime.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/modalities/mime_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/modalities/video.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/modalities/video_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/modality.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/modality_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/natural_language.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/natural_language_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/sampling.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/sampling_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/__init__.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/completion.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/completion_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/description.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/description_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/mapping.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/mapping_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/parsing.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/parsing_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/prompting.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/prompting_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/schema_generation_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/scoring.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/scoring_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/subscription.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/subscription_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/template.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/template_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/__init__.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/completion.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/completion_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/conversation.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/conversation_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/demonstration.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/demonstration_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/selfplay.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/selfplay_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/text_formatting.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/text_formatting_test.py +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun.egg-info/SOURCES.txt +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun.egg-info/dependency_links.txt +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun.egg-info/top_level.txt +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/setup.cfg +0 -0
- {langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/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.dev20240329
|
4
4
|
Summary: Langfun: Language as Functions.
|
5
5
|
Home-page: https://github.com/google/langfun
|
6
6
|
Author: Langfun Authors
|
@@ -24,7 +24,7 @@ License-File: LICENSE
|
|
24
24
|
Requires-Dist: google-generativeai>=0.3.2
|
25
25
|
Requires-Dist: jinja2>=3.1.2
|
26
26
|
Requires-Dist: openai==0.27.2
|
27
|
-
Requires-Dist: pyglove>=0.4.5.
|
27
|
+
Requires-Dist: pyglove>=0.4.5.dev20240323
|
28
28
|
Requires-Dist: python-magic>=0.4.27
|
29
29
|
Requires-Dist: requests>=2.31.0
|
30
30
|
Requires-Dist: termcolor==1.1.0
|
@@ -27,6 +27,7 @@ import time
|
|
27
27
|
from typing import Annotated, Any, Callable, Iterator, Literal, Optional, Sequence, Type, Union
|
28
28
|
|
29
29
|
import langfun.core as lf
|
30
|
+
import langfun.core.coding as lf_coding
|
30
31
|
from langfun.core.llms.cache import in_memory
|
31
32
|
import langfun.core.structured as lf_structured
|
32
33
|
import pyglove as pg
|
@@ -41,14 +42,6 @@ class Evaluable(lf.Component):
|
|
41
42
|
INDEX_HTML = 'index.html'
|
42
43
|
SUMMARY_HTML = 'summary.html'
|
43
44
|
|
44
|
-
id: Annotated[
|
45
|
-
str,
|
46
|
-
(
|
47
|
-
'The ID of the evaluation, which should be unique across all '
|
48
|
-
'evaluations.'
|
49
|
-
),
|
50
|
-
]
|
51
|
-
|
52
45
|
root_dir: Annotated[
|
53
46
|
str | None,
|
54
47
|
(
|
@@ -61,6 +54,18 @@ class Evaluable(lf.Component):
|
|
61
54
|
int, 'Number of decimals when reporting precision.'
|
62
55
|
] = lf.contextual(default=1)
|
63
56
|
|
57
|
+
@property
|
58
|
+
@abc.abstractmethod
|
59
|
+
def id(self) -> str:
|
60
|
+
"""Returns the ID of the task.
|
61
|
+
|
62
|
+
Returns:
|
63
|
+
Evaluation task ID. Different evaluation task should have their unique
|
64
|
+
task IDs, for each task will be stored in sub-directoreis identified by
|
65
|
+
their IDs. For suites, the ID could be an empty string as they will not
|
66
|
+
produce sub-directories
|
67
|
+
"""
|
68
|
+
|
64
69
|
@property
|
65
70
|
def dir(self) -> str | None:
|
66
71
|
"""Returns the directory for saving results and details."""
|
@@ -578,12 +583,15 @@ class _LeafNode:
|
|
578
583
|
progress_bar: int | None = None
|
579
584
|
|
580
585
|
|
581
|
-
@pg.use_init_args(['
|
586
|
+
@pg.use_init_args(['children'])
|
582
587
|
class Suite(Evaluable):
|
583
588
|
"""Evaluation suite."""
|
584
589
|
|
585
590
|
children: Annotated[list[Evaluable], 'Child evaluation sets or suites.']
|
586
591
|
|
592
|
+
# Use empty ID as suite is just a container of child evaluations.
|
593
|
+
id: str = ''
|
594
|
+
|
587
595
|
__kwargs__: Annotated[
|
588
596
|
Any,
|
589
597
|
(
|
@@ -841,8 +849,10 @@ class Evaluation(Evaluable):
|
|
841
849
|
kwargs['evaluation'] = self
|
842
850
|
return self.schema_fn(**kwargs)
|
843
851
|
|
844
|
-
def _formalize_schema(self, annotation) -> lf_structured.Schema:
|
852
|
+
def _formalize_schema(self, annotation) -> lf_structured.Schema | None:
|
845
853
|
"""Formalizes schema from annotation."""
|
854
|
+
if annotation in (str, None):
|
855
|
+
return None
|
846
856
|
if self.method == 'complete':
|
847
857
|
if not hasattr(annotation, '__schema__'):
|
848
858
|
raise TypeError(
|
@@ -883,6 +893,14 @@ class Evaluation(Evaluable):
|
|
883
893
|
completion_examples.append(ex)
|
884
894
|
return completion_examples
|
885
895
|
|
896
|
+
@property
|
897
|
+
def id(self) -> str:
|
898
|
+
"""Returns the ID of this evaluation."""
|
899
|
+
id_prefix = self.__class__.__name__
|
900
|
+
if not self.is_deterministic:
|
901
|
+
return id_prefix
|
902
|
+
return f'{id_prefix}@{self.hash}'
|
903
|
+
|
886
904
|
@functools.cached_property
|
887
905
|
def children(self) -> list['Evaluation']:
|
888
906
|
"""Returns the trials as child evaluations if this evaluation is a space."""
|
@@ -892,7 +910,6 @@ class Evaluation(Evaluable):
|
|
892
910
|
for i, child in enumerate(pg.iter(self)):
|
893
911
|
child.sym_setparent(self)
|
894
912
|
child.sym_setpath(self.sym_path + f'children[{i}]')
|
895
|
-
child.rebind(id=f'{self.id}@{child.hash}', skip_notification=True)
|
896
913
|
children.append(child)
|
897
914
|
return children
|
898
915
|
|
@@ -1004,7 +1021,11 @@ class Evaluation(Evaluable):
|
|
1004
1021
|
self._reset()
|
1005
1022
|
|
1006
1023
|
def _process(example: Any):
|
1007
|
-
|
1024
|
+
# NOTE(daiyip): set the `input` symbol of the globals to None, so LLM
|
1025
|
+
# generated code with calls to `input` will raise an error, thus not
|
1026
|
+
# blocking the evaluation.
|
1027
|
+
with lf_coding.context(input=None):
|
1028
|
+
return self.process(example, **(self.additional_args or {}))
|
1008
1029
|
|
1009
1030
|
try:
|
1010
1031
|
for example, message, error in lf.concurrent_map(
|
@@ -1015,10 +1036,7 @@ class Evaluation(Evaluable):
|
|
1015
1036
|
status_fn=self._status,
|
1016
1037
|
):
|
1017
1038
|
if error is not None:
|
1018
|
-
|
1019
|
-
self._failures.append((example, str(error)))
|
1020
|
-
except Exception as e: # pylint: disable=broad-exception-caught
|
1021
|
-
self._failures.append((example, str(e)))
|
1039
|
+
self._failures.append((example, str(error)))
|
1022
1040
|
else:
|
1023
1041
|
output = message.text if self.schema is None else message.result
|
1024
1042
|
self.audit(example, output, message)
|
@@ -1521,9 +1539,12 @@ class Summary(pg.Object):
|
|
1521
1539
|
pivot_field = pivot_field or self.pivot_field
|
1522
1540
|
s = io.StringIO()
|
1523
1541
|
s.write('<html><body>')
|
1524
|
-
for task in self.tasks():
|
1542
|
+
for task in sorted(self.tasks(), key=lambda cls: cls.__name__):
|
1543
|
+
table_id = task.__name__.lower()
|
1525
1544
|
s.write('<div>')
|
1526
|
-
s.write(f'<
|
1545
|
+
s.write(f'<a id="{table_id}"')
|
1546
|
+
s.write(f'<h2><a href="#{table_id}">{task.__name__}</a></h2>')
|
1547
|
+
s.write('</a>')
|
1527
1548
|
table = Summary.Table.from_evaluations(
|
1528
1549
|
self.select(task=task).evaluations, pivot_field
|
1529
1550
|
)
|
@@ -70,8 +70,7 @@ def eval_set(
|
|
70
70
|
"""Creates an evaluation object for testing."""
|
71
71
|
tmp_dir = tempfile.gettempdir()
|
72
72
|
return cls(
|
73
|
-
|
74
|
-
root_dir=tmp_dir,
|
73
|
+
root_dir=os.path.join(tmp_dir, eval_id),
|
75
74
|
inputs=base.as_inputs([
|
76
75
|
pg.Dict(question='Compute 1 + 1'),
|
77
76
|
pg.Dict(question='Compute 1 + 2'),
|
@@ -210,7 +209,7 @@ class EvaluationTest(unittest.TestCase):
|
|
210
209
|
s.result,
|
211
210
|
dict(
|
212
211
|
experiment_setup=dict(
|
213
|
-
id='
|
212
|
+
id='Evaluation@17915dc6',
|
214
213
|
dir=s.dir,
|
215
214
|
model='StaticSequence',
|
216
215
|
prompt_template='{{example.question}}',
|
@@ -302,7 +301,6 @@ class EvaluationTest(unittest.TestCase):
|
|
302
301
|
'3',
|
303
302
|
])
|
304
303
|
s = base.Evaluation(
|
305
|
-
id='search_space_test',
|
306
304
|
root_dir=tempfile.gettempdir(),
|
307
305
|
inputs=base.as_inputs([
|
308
306
|
pg.Dict(question='Compute 1 + 1'),
|
@@ -439,7 +437,6 @@ class SuiteTest(unittest.TestCase):
|
|
439
437
|
'3',
|
440
438
|
] * 5)
|
441
439
|
s = base.Suite(
|
442
|
-
'suite_run_test',
|
443
440
|
[
|
444
441
|
eval_set('run_test_1', 'query', schema_fn=answer_schema()),
|
445
442
|
# A suite of search space. Two of the sub-experiments are identical,
|
@@ -548,7 +545,6 @@ class SummaryTest(unittest.TestCase):
|
|
548
545
|
def _eval_set(self, root_dir):
|
549
546
|
return base.Suite(id='select_test', children=[
|
550
547
|
TaskA(
|
551
|
-
id='task_a',
|
552
548
|
inputs=base.as_inputs([
|
553
549
|
pg.Dict(question='Compute 1 + 1'),
|
554
550
|
]),
|
@@ -569,7 +565,6 @@ class SummaryTest(unittest.TestCase):
|
|
569
565
|
max_workers=1,
|
570
566
|
),
|
571
567
|
TaskB(
|
572
|
-
id='task_b',
|
573
568
|
inputs=base.as_inputs([
|
574
569
|
pg.Dict(question='Compute 1 + 1'),
|
575
570
|
]),
|
@@ -650,10 +645,10 @@ class SummaryTest(unittest.TestCase):
|
|
650
645
|
len(base.Summary.from_dirs(root_dir)), 2 * 2 * 2 * 2 + 2 * 1 * 1 * 2
|
651
646
|
)
|
652
647
|
self.assertEqual(
|
653
|
-
len(base.Summary.from_dirs(root_dir, '
|
648
|
+
len(base.Summary.from_dirs(root_dir, 'TaskB')), 2 * 1 * 1 * 2
|
654
649
|
)
|
655
650
|
self.assertEqual(
|
656
|
-
len(base.Summary.from_dirs(root_dir, ('
|
651
|
+
len(base.Summary.from_dirs(root_dir, ('TaskA'))), 2 * 2 * 2 * 2
|
657
652
|
)
|
658
653
|
|
659
654
|
def test_monitor(self):
|
@@ -65,10 +65,8 @@ def eval_set(
|
|
65
65
|
use_cache: bool = True,
|
66
66
|
):
|
67
67
|
"""Creates an evaluation object for testing."""
|
68
|
-
tmp_dir = tempfile.gettempdir()
|
69
68
|
return MyTask(
|
70
|
-
|
71
|
-
root_dir=tmp_dir,
|
69
|
+
root_dir=os.path.join(tempfile.gettempdir(), eval_id),
|
72
70
|
inputs=base.as_inputs([
|
73
71
|
pg.Dict(question='Compute 1 + 1', groundtruth=2),
|
74
72
|
pg.Dict(question='Compute 1 + 2', groundtruth=3),
|
@@ -105,7 +103,7 @@ class MatchingTest(unittest.TestCase):
|
|
105
103
|
s.result,
|
106
104
|
dict(
|
107
105
|
experiment_setup=dict(
|
108
|
-
id='
|
106
|
+
id='MyTask@3d87f97f',
|
109
107
|
dir=s.dir,
|
110
108
|
model='StaticSequence',
|
111
109
|
prompt_template='{{example.question}}',
|
@@ -43,7 +43,6 @@ def constrained_by_upperbound(upper_bound: int):
|
|
43
43
|
|
44
44
|
|
45
45
|
class ConstraintFollowing(scoring.Scoring):
|
46
|
-
id = 'constraint_following'
|
47
46
|
inputs = constrained_by_upperbound(1)
|
48
47
|
prompt = '{{example}}'
|
49
48
|
method = 'query'
|
@@ -82,7 +81,7 @@ class ScoringTest(unittest.TestCase):
|
|
82
81
|
s.result,
|
83
82
|
dict(
|
84
83
|
experiment_setup=dict(
|
85
|
-
id='
|
84
|
+
id='ConstraintFollowing@9e51bb9e',
|
86
85
|
dir=s.dir,
|
87
86
|
model='StaticSequence',
|
88
87
|
prompt_template='{{example}}',
|
@@ -55,10 +55,6 @@ def parse_value_spec(value) -> pg.typing.ValueSpec:
|
|
55
55
|
),
|
56
56
|
):
|
57
57
|
raise ValueError(f'Unsupported schema specification: {v}')
|
58
|
-
if isinstance(spec, pg.typing.Object) and not issubclass(
|
59
|
-
spec.cls, pg.Symbolic
|
60
|
-
):
|
61
|
-
raise ValueError(f'{v} must be a symbolic class to be parsable.')
|
62
58
|
return spec
|
63
59
|
|
64
60
|
return _parse_node(value)
|
@@ -208,7 +204,9 @@ def class_dependencies(
|
|
208
204
|
if isinstance(value_or_spec, Schema):
|
209
205
|
return value_or_spec.class_dependencies(include_subclasses)
|
210
206
|
|
211
|
-
if
|
207
|
+
if inspect.isclass(value_or_spec) or isinstance(
|
208
|
+
value_or_spec, pg.typing.ValueSpec
|
209
|
+
):
|
212
210
|
value_or_spec = (value_or_spec,)
|
213
211
|
|
214
212
|
if isinstance(value_or_spec, tuple):
|
@@ -216,7 +214,7 @@ def class_dependencies(
|
|
216
214
|
for v in value_or_spec:
|
217
215
|
if isinstance(v, pg.typing.ValueSpec):
|
218
216
|
value_specs.append(v)
|
219
|
-
elif inspect.isclass(v)
|
217
|
+
elif inspect.isclass(v):
|
220
218
|
value_specs.append(pg.typing.Object(v))
|
221
219
|
else:
|
222
220
|
raise TypeError(f'Unsupported spec type: {v!r}')
|
@@ -235,23 +233,20 @@ def class_dependencies(
|
|
235
233
|
|
236
234
|
def _fill_dependencies(vs: pg.typing.ValueSpec, include_subclasses: bool):
|
237
235
|
if isinstance(vs, pg.typing.Object):
|
238
|
-
if
|
236
|
+
if vs.cls not in seen:
|
239
237
|
seen.add(vs.cls)
|
240
238
|
|
241
239
|
# Add base classes as dependencies.
|
242
240
|
for base_cls in vs.cls.__bases__:
|
243
241
|
# We only keep track of user-defined symbolic classes.
|
244
|
-
if
|
245
|
-
base_cls, pg.Object
|
246
|
-
) and not base_cls.__module__.startswith('pyglove'):
|
242
|
+
if base_cls is not object and base_cls is not pg.Object:
|
247
243
|
_fill_dependencies(
|
248
244
|
pg.typing.Object(base_cls), include_subclasses=False
|
249
245
|
)
|
250
246
|
|
251
247
|
# Add members as dependencies.
|
252
|
-
|
253
|
-
|
254
|
-
_fill_dependencies(field.value, include_subclasses)
|
248
|
+
for field in _pg_schema(vs.cls).values():
|
249
|
+
_fill_dependencies(field.value, include_subclasses)
|
255
250
|
_add_dependency(vs.cls)
|
256
251
|
|
257
252
|
# Check subclasses if available.
|
@@ -364,17 +359,13 @@ def class_definition(
|
|
364
359
|
) -> str:
|
365
360
|
"""Returns the Python class definition."""
|
366
361
|
out = io.StringIO()
|
367
|
-
|
368
|
-
raise TypeError(
|
369
|
-
'Classes must be `pg.Object` subclasses to be used as schema. '
|
370
|
-
f'Encountered: {cls}.'
|
371
|
-
)
|
372
|
-
schema = cls.__schema__
|
362
|
+
schema = _pg_schema(cls)
|
373
363
|
eligible_bases = []
|
374
364
|
for base_cls in cls.__bases__:
|
375
|
-
if
|
365
|
+
if base_cls is not object:
|
376
366
|
if include_pg_object_as_base or base_cls is not pg.Object:
|
377
367
|
eligible_bases.append(base_cls.__name__)
|
368
|
+
|
378
369
|
if eligible_bases:
|
379
370
|
base_cls_str = ', '.join(eligible_bases)
|
380
371
|
out.write(f'class {cls.__name__}({base_cls_str}):\n')
|
@@ -839,3 +830,13 @@ class Unknown(pg.Object, pg.typing.CustomTyping):
|
|
839
830
|
|
840
831
|
|
841
832
|
UNKNOWN = Unknown()
|
833
|
+
|
834
|
+
|
835
|
+
def _pg_schema(cls: Type[Any]) -> pg.Schema:
|
836
|
+
"""Returns PyGlove schema for the constructor of a class."""
|
837
|
+
schema = getattr(cls, '__schema__', None)
|
838
|
+
if schema is None:
|
839
|
+
schema = pg.symbolic.callable_schema(
|
840
|
+
cls.__init__, auto_typing=True, auto_doc=True, remove_self=True
|
841
|
+
)
|
842
|
+
return schema
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/schema_generation.py
RENAMED
@@ -143,14 +143,14 @@ def generate_class(
|
|
143
143
|
|
144
144
|
|
145
145
|
def classgen_example(
|
146
|
-
|
146
|
+
prompt: str | pg.Symbolic, cls: Type[Any]
|
147
147
|
) -> mapping.MappingExample:
|
148
148
|
"""Creates a class generation example."""
|
149
149
|
if isinstance(prompt, lf.Template):
|
150
150
|
prompt = prompt.render()
|
151
151
|
return mapping.MappingExample(
|
152
152
|
input=prompt,
|
153
|
-
context=
|
153
|
+
context=cls.__name__,
|
154
154
|
output=cls,
|
155
155
|
)
|
156
156
|
|
@@ -168,7 +168,6 @@ def default_classgen_examples() -> list[mapping.MappingExample]:
|
|
168
168
|
|
169
169
|
return [
|
170
170
|
classgen_example(
|
171
|
-
'Solution',
|
172
171
|
'How to evaluate an arithmetic expression?',
|
173
172
|
Solution,
|
174
173
|
)
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/schema_test.py
RENAMED
@@ -13,6 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
"""Tests for structured parsing."""
|
15
15
|
|
16
|
+
import dataclasses
|
16
17
|
import inspect
|
17
18
|
import typing
|
18
19
|
import unittest
|
@@ -101,12 +102,7 @@ class SchemaTest(unittest.TestCase):
|
|
101
102
|
|
102
103
|
self.assert_unsupported_annotation(typing.Type[int])
|
103
104
|
self.assert_unsupported_annotation(typing.Union[int, str, bool])
|
104
|
-
|
105
|
-
class X:
|
106
|
-
pass
|
107
|
-
|
108
|
-
# X must be a symbolic type to be parsable.
|
109
|
-
self.assert_unsupported_annotation(X)
|
105
|
+
self.assert_unsupported_annotation(typing.Any)
|
110
106
|
|
111
107
|
def test_schema_dict(self):
|
112
108
|
schema = schema_lib.Schema([{'x': Itinerary}])
|
@@ -150,6 +146,25 @@ class SchemaTest(unittest.TestCase):
|
|
150
146
|
schema = schema_lib.Schema([B])
|
151
147
|
self.assertEqual(schema.class_dependencies(), [Foo, A, Bar, X, B])
|
152
148
|
|
149
|
+
def test_class_dependencies_non_pyglove(self):
|
150
|
+
class Baz:
|
151
|
+
def __init__(self, x: int):
|
152
|
+
pass
|
153
|
+
|
154
|
+
@dataclasses.dataclass(frozen=True)
|
155
|
+
class AA:
|
156
|
+
foo: tuple[Baz, int]
|
157
|
+
|
158
|
+
class XX(pg.Object):
|
159
|
+
pass
|
160
|
+
|
161
|
+
@dataclasses.dataclass(frozen=True)
|
162
|
+
class BB(AA):
|
163
|
+
foo2: Baz | XX
|
164
|
+
|
165
|
+
schema = schema_lib.Schema([AA])
|
166
|
+
self.assertEqual(schema.class_dependencies(), [Baz, AA, XX, BB])
|
167
|
+
|
153
168
|
def test_schema_repr(self):
|
154
169
|
schema = schema_lib.Schema([{'x': Itinerary}])
|
155
170
|
self.assertEqual(
|
@@ -440,13 +455,6 @@ class SchemaPythonReprTest(unittest.TestCase):
|
|
440
455
|
'class A(Object):\n pass\n',
|
441
456
|
)
|
442
457
|
|
443
|
-
class B:
|
444
|
-
pass
|
445
|
-
|
446
|
-
with self.assertRaisesRegex(
|
447
|
-
TypeError, 'Classes must be `pg.Object` subclasses.*'):
|
448
|
-
schema_lib.class_definition(B)
|
449
|
-
|
450
458
|
class C(pg.Object):
|
451
459
|
x: str
|
452
460
|
__kwargs__: typing.Any
|
@@ -459,9 +467,12 @@ class SchemaPythonReprTest(unittest.TestCase):
|
|
459
467
|
class Foo(pg.Object):
|
460
468
|
x: int
|
461
469
|
|
462
|
-
|
470
|
+
@dataclasses.dataclass(frozen=True)
|
471
|
+
class Bar:
|
472
|
+
"""Class Bar."""
|
463
473
|
y: str
|
464
474
|
|
475
|
+
@dataclasses.dataclass(frozen=True)
|
465
476
|
class Baz(Bar): # pylint: disable=unused-variable
|
466
477
|
pass
|
467
478
|
|
@@ -475,7 +486,7 @@ class SchemaPythonReprTest(unittest.TestCase):
|
|
475
486
|
schema = schema_lib.Schema([B])
|
476
487
|
self.assertEqual(
|
477
488
|
schema_lib.SchemaPythonRepr().class_definitions(schema),
|
478
|
-
inspect.cleandoc(
|
489
|
+
inspect.cleandoc('''
|
479
490
|
class Foo:
|
480
491
|
x: int
|
481
492
|
|
@@ -483,16 +494,18 @@ class SchemaPythonReprTest(unittest.TestCase):
|
|
483
494
|
foo: Foo
|
484
495
|
|
485
496
|
class Bar:
|
497
|
+
"""Class Bar."""
|
486
498
|
y: str
|
487
499
|
|
488
500
|
class Baz(Bar):
|
501
|
+
"""Baz(y: str)"""
|
489
502
|
y: str
|
490
503
|
|
491
504
|
class B(A):
|
492
505
|
foo: Foo
|
493
506
|
bar: Bar
|
494
507
|
foo2: Foo
|
495
|
-
|
508
|
+
''') + '\n',
|
496
509
|
)
|
497
510
|
|
498
511
|
self.assertEqual(
|
@@ -501,7 +514,7 @@ class SchemaPythonReprTest(unittest.TestCase):
|
|
501
514
|
|
502
515
|
self.assertEqual(
|
503
516
|
schema_lib.SchemaPythonRepr().repr(schema),
|
504
|
-
inspect.cleandoc(
|
517
|
+
inspect.cleandoc('''
|
505
518
|
list[B]
|
506
519
|
|
507
520
|
```python
|
@@ -512,9 +525,11 @@ class SchemaPythonReprTest(unittest.TestCase):
|
|
512
525
|
foo: Foo
|
513
526
|
|
514
527
|
class Bar:
|
528
|
+
"""Class Bar."""
|
515
529
|
y: str
|
516
530
|
|
517
531
|
class Baz(Bar):
|
532
|
+
"""Baz(y: str)"""
|
518
533
|
y: str
|
519
534
|
|
520
535
|
class B(A):
|
@@ -522,7 +537,7 @@ class SchemaPythonReprTest(unittest.TestCase):
|
|
522
537
|
bar: Bar
|
523
538
|
foo2: Foo
|
524
539
|
```
|
525
|
-
|
540
|
+
'''),
|
526
541
|
)
|
527
542
|
self.assertEqual(
|
528
543
|
schema_lib.SchemaPythonRepr().repr(
|
@@ -531,24 +546,26 @@ class SchemaPythonReprTest(unittest.TestCase):
|
|
531
546
|
include_pg_object_as_base=True,
|
532
547
|
markdown=False,
|
533
548
|
),
|
534
|
-
inspect.cleandoc(
|
549
|
+
inspect.cleandoc('''
|
535
550
|
class Foo(Object):
|
536
551
|
x: int
|
537
552
|
|
538
553
|
class A(Object):
|
539
554
|
foo: Foo
|
540
555
|
|
541
|
-
class Bar
|
556
|
+
class Bar:
|
557
|
+
"""Class Bar."""
|
542
558
|
y: str
|
543
559
|
|
544
560
|
class Baz(Bar):
|
561
|
+
"""Baz(y: str)"""
|
545
562
|
y: str
|
546
563
|
|
547
564
|
class B(A):
|
548
565
|
foo: Foo
|
549
566
|
bar: Bar
|
550
567
|
foo2: Foo
|
551
|
-
|
568
|
+
'''),
|
552
569
|
)
|
553
570
|
|
554
571
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: langfun
|
3
|
-
Version: 0.0.2.
|
3
|
+
Version: 0.0.2.dev20240329
|
4
4
|
Summary: Langfun: Language as Functions.
|
5
5
|
Home-page: https://github.com/google/langfun
|
6
6
|
Author: Langfun Authors
|
@@ -24,7 +24,7 @@ License-File: LICENSE
|
|
24
24
|
Requires-Dist: google-generativeai>=0.3.2
|
25
25
|
Requires-Dist: jinja2>=3.1.2
|
26
26
|
Requires-Dist: openai==0.27.2
|
27
|
-
Requires-Dist: pyglove>=0.4.5.
|
27
|
+
Requires-Dist: pyglove>=0.4.5.dev20240323
|
28
28
|
Requires-Dist: python-magic>=0.4.27
|
29
29
|
Requires-Dist: requests>=2.31.0
|
30
30
|
Requires-Dist: termcolor==1.1.0
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/__init__.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/correction.py
RENAMED
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/errors.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/errors_test.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/execution.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/execution_test.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/generation.py
RENAMED
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/parsing.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/parsing_test.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/coding/python/permissions.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/cache/in_memory.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/llms/cache/in_memory_test.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/modalities/image_test.py
RENAMED
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/modalities/mime_test.py
RENAMED
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/modalities/video_test.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/natural_language_test.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/completion.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/completion_test.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/description.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/description_test.py
RENAMED
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/mapping_test.py
RENAMED
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/parsing_test.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/prompting.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/prompting_test.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/structured/scoring_test.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/completion.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/completion_test.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/conversation.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/conversation_test.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/demonstration.py
RENAMED
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/demonstration_test.py
RENAMED
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/templates/selfplay_test.py
RENAMED
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun/core/text_formatting_test.py
RENAMED
File without changes
|
File without changes
|
{langfun-0.0.2.dev20240325 → langfun-0.0.2.dev20240329}/langfun.egg-info/dependency_links.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|