langfun 0.0.2.dev20240208__tar.gz → 0.0.2.dev20240210__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 (99) hide show
  1. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/PKG-INFO +2 -2
  2. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/__init__.py +2 -0
  3. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/python/correction.py +1 -1
  4. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/concurrent.py +3 -2
  5. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/eval/base.py +55 -22
  6. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/eval/base_test.py +8 -9
  7. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/language_model.py +2 -0
  8. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/structured/prompting.py +5 -8
  9. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/structured/prompting_test.py +39 -42
  10. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun.egg-info/PKG-INFO +2 -2
  11. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun.egg-info/requires.txt +1 -1
  12. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/LICENSE +0 -0
  13. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/README.md +0 -0
  14. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/__init__.py +0 -0
  15. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/__init__.py +0 -0
  16. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/python/__init__.py +0 -0
  17. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/python/correction_test.py +0 -0
  18. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/python/errors.py +0 -0
  19. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/python/errors_test.py +0 -0
  20. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/python/execution.py +0 -0
  21. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/python/execution_test.py +0 -0
  22. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/python/generation.py +0 -0
  23. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/python/generation_test.py +0 -0
  24. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/python/parsing.py +0 -0
  25. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/python/parsing_test.py +0 -0
  26. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/python/permissions.py +0 -0
  27. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/coding/python/permissions_test.py +0 -0
  28. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/component.py +0 -0
  29. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/component_test.py +0 -0
  30. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/concurrent_test.py +0 -0
  31. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/console.py +0 -0
  32. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/console_test.py +0 -0
  33. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/eval/__init__.py +0 -0
  34. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/eval/matching.py +0 -0
  35. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/eval/matching_test.py +0 -0
  36. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/eval/scoring.py +0 -0
  37. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/eval/scoring_test.py +0 -0
  38. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/langfunc.py +0 -0
  39. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/langfunc_test.py +0 -0
  40. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/language_model_test.py +0 -0
  41. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/llms/__init__.py +0 -0
  42. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/llms/cache/__init__.py +0 -0
  43. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/llms/cache/base.py +0 -0
  44. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/llms/cache/in_memory.py +0 -0
  45. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/llms/cache/in_memory_test.py +0 -0
  46. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/llms/fake.py +0 -0
  47. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/llms/fake_test.py +0 -0
  48. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/llms/gemini.py +0 -0
  49. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/llms/gemini_test.py +0 -0
  50. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/llms/llama_cpp.py +0 -0
  51. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/llms/llama_cpp_test.py +0 -0
  52. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/llms/openai.py +0 -0
  53. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/llms/openai_test.py +0 -0
  54. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/memories/__init__.py +0 -0
  55. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/memories/conversation_history.py +0 -0
  56. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/memories/conversation_history_test.py +0 -0
  57. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/memory.py +0 -0
  58. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/message.py +0 -0
  59. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/message_test.py +0 -0
  60. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/modalities/__init__.py +0 -0
  61. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/modalities/image.py +0 -0
  62. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/modalities/image_test.py +0 -0
  63. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/modality.py +0 -0
  64. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/modality_test.py +0 -0
  65. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/natural_language.py +0 -0
  66. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/natural_language_test.py +0 -0
  67. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/sampling.py +0 -0
  68. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/sampling_test.py +0 -0
  69. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/structured/__init__.py +0 -0
  70. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/structured/completion.py +0 -0
  71. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/structured/completion_test.py +0 -0
  72. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/structured/description.py +0 -0
  73. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/structured/description_test.py +0 -0
  74. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/structured/mapping.py +0 -0
  75. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/structured/mapping_test.py +0 -0
  76. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/structured/parsing.py +0 -0
  77. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/structured/parsing_test.py +0 -0
  78. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/structured/schema.py +0 -0
  79. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/structured/schema_test.py +0 -0
  80. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/subscription.py +0 -0
  81. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/subscription_test.py +0 -0
  82. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/template.py +0 -0
  83. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/template_test.py +0 -0
  84. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/templates/__init__.py +0 -0
  85. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/templates/completion.py +0 -0
  86. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/templates/completion_test.py +0 -0
  87. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/templates/conversation.py +0 -0
  88. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/templates/conversation_test.py +0 -0
  89. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/templates/demonstration.py +0 -0
  90. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/templates/demonstration_test.py +0 -0
  91. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/templates/selfplay.py +0 -0
  92. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/templates/selfplay_test.py +0 -0
  93. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/text_formatting.py +0 -0
  94. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun/core/text_formatting_test.py +0 -0
  95. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun.egg-info/SOURCES.txt +0 -0
  96. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun.egg-info/dependency_links.txt +0 -0
  97. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/langfun.egg-info/top_level.txt +0 -0
  98. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/setup.cfg +0 -0
  99. {langfun-0.0.2.dev20240208 → langfun-0.0.2.dev20240210}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langfun
3
- Version: 0.0.2.dev20240208
3
+ Version: 0.0.2.dev20240210
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.dev20240109
27
+ Requires-Dist: pyglove>=0.4.5.dev20240201
28
28
  Requires-Dist: requests>=2.31.0
29
29
  Requires-Dist: termcolor==1.1.0
30
30
  Requires-Dist: tqdm>=4.64.1
@@ -109,6 +109,8 @@ from langfun.core.memory import Memory
109
109
  # Utility for console output.
110
110
  from langfun.core import console
111
111
 
112
+ # Import internal modules.
113
+
112
114
  # pylint: enable=g-import-not-at-top
113
115
  # pylint: enable=g-importing-member
114
116
  # pylint: enable=g-bad-import-order
@@ -83,7 +83,7 @@ def run_with_correction(
83
83
  # pylint: disable=g-import-not-at-top
84
84
  # pytype: disable=import-error
85
85
  from langfun.core.structured import prompting
86
- # pytype: disable=import-error
86
+ # pytype: enable=import-error
87
87
  # pylint: enable=g-import-not-at-top
88
88
 
89
89
  code = remove_docstrings(code)
@@ -538,11 +538,12 @@ def concurrent_map(
538
538
  An iterator of (input, output, error).
539
539
 
540
540
  Raises:
541
- Exception: Erros that are not in `silence_on_errors` or `retry_on_errors`,
541
+ Exception: Errors that are not in `silence_on_errors` or `retry_on_errors`,
542
542
  or retry on such errors has reached max attempts.
543
543
  TimeoutError: Any item timed out while TimeoutError is not silenced via
544
544
  `silence_on_errors`.
545
545
  """
546
+ # Internal usage logging.
546
547
 
547
548
  if retry_on_errors:
548
549
  func = with_retry(
@@ -683,7 +684,7 @@ def concurrent_map(
683
684
  class ExecutorPool:
684
685
  """A pool of managed executors.
685
686
 
686
- Managed executors are used for controlling the parallism of execution based
687
+ Managed executors are used for controlling the parallelism of execution based
687
688
  on resource id. This design is to honor overall rate limit of LMs globally
688
689
  (with current process).
689
690
  """
@@ -211,6 +211,8 @@ class Evaluable(lf.Component):
211
211
  **kwargs,
212
212
  ) -> Union['Summary', pg.Dict]:
213
213
  """Run the evaluation, which fills and returns the result."""
214
+ # Internal usage logging.
215
+
214
216
  if dryrun:
215
217
  self.dryrun(filter=filter, verbose=False, debug=debug)
216
218
 
@@ -582,8 +584,22 @@ class Suite(Evaluable):
582
584
 
583
585
  children: Annotated[list[Evaluable], 'Child evaluation sets or suites.']
584
586
 
587
+ __kwargs__: Annotated[
588
+ Any,
589
+ (
590
+ 'Wildcard keyword arguments for `__init__` that can be accessed from '
591
+ 'parent suite if the argument is absent from current evaluation set.'
592
+ ),
593
+ ]
594
+
585
595
  def _on_bound(self):
586
596
  super()._on_bound()
597
+ overrides = {
598
+ k: v for k, v in self.sym_init_args.items()
599
+ if k not in ('id', 'children')
600
+ }
601
+ for child in self.children:
602
+ child.rebind(overrides, notify_parents=False)
587
603
  self.__dict__.pop('hash', None)
588
604
 
589
605
  @functools.cached_property
@@ -618,7 +634,7 @@ class Evaluation(Evaluable):
618
634
 
619
635
  method: Annotated[
620
636
  Literal['call', 'query', 'complete'], 'Method for symbolic prompting.'
621
- ]
637
+ ] = lf.contextual(default='query')
622
638
 
623
639
  prompt: Annotated[
624
640
  lf.Template,
@@ -626,7 +642,7 @@ class Evaluation(Evaluable):
626
642
  'Template for rendering the template. Example object could be '
627
643
  'accessed via `example`.'
628
644
  ),
629
- ]
645
+ ] = lf.contextual()
630
646
 
631
647
  schema_fn: pg.typing.Annotated[
632
648
  pg.typing.Functor().noneable(),
@@ -660,9 +676,11 @@ class Evaluation(Evaluable):
660
676
  ```
661
677
  """)
662
678
  ),
663
- ]
679
+ ] = lf.contextual()
664
680
 
665
- lm: Annotated[lf.LanguageModel, 'Language model to use for evaluation.']
681
+ lm: Annotated[lf.LanguageModel, 'Language model to use for evaluation.'] = (
682
+ lf.contextual()
683
+ )
666
684
 
667
685
  parsing_lm: Annotated[
668
686
  lf.LanguageModel | None,
@@ -670,7 +688,7 @@ class Evaluation(Evaluable):
670
688
  'Language model for parsing. Applicable only when method is set'
671
689
  'to `call`. If None, `lm` will also be used for parsing. '
672
690
  ),
673
- ] = None
691
+ ] = lf.contextual(default=None)
674
692
 
675
693
  completion_prompt_field: Annotated[
676
694
  str | None,
@@ -680,8 +698,8 @@ class Evaluation(Evaluable):
680
698
  'the class, instead the prompt will be passed as the first argument '
681
699
  'of the input object to complete. Applicable only when `method` is '
682
700
  'set to `complete`.'
683
- )
684
- ] = None
701
+ ),
702
+ ] = lf.contextual(default=None)
685
703
 
686
704
  autofix: Annotated[
687
705
  int,
@@ -690,7 +708,7 @@ class Evaluation(Evaluable):
690
708
  'generated code for the output structure. If 0, autofix will be '
691
709
  'disabled.'
692
710
  ),
693
- ] = 0
711
+ ] = lf.contextual(default=0)
694
712
 
695
713
  autofix_lm: Annotated[
696
714
  lf.LanguageModel | None,
@@ -698,14 +716,16 @@ class Evaluation(Evaluable):
698
716
  'Language model for autofix. If None, `lm` will also be used for '
699
717
  'autofix.'
700
718
  ),
701
- ] = None
719
+ ] = lf.contextual(default=None)
702
720
 
703
721
  additional_args: Annotated[
704
722
  dict[str, Any] | None,
705
- 'Additional kwargs that will be passed to `self.process`'
706
- ] = None
723
+ 'Additional kwargs that will be passed to `self.process`',
724
+ ] = lf.contextual(default=None)
707
725
 
708
- use_cache: Annotated[bool, 'If True, LM cache will be enabled.'] = True
726
+ use_cache: Annotated[bool, 'If True, LM cache will be enabled.'] = (
727
+ lf.contextual(default=True)
728
+ )
709
729
 
710
730
  max_workers: Annotated[
711
731
  int, 'Max workers to run the evaluation in parallel.'
@@ -744,7 +764,11 @@ class Evaluation(Evaluable):
744
764
  @functools.cached_property
745
765
  def examples(self):
746
766
  """Returns examples for evaluation."""
747
- return self.inputs()
767
+ kwargs = {}
768
+ # Allow inputs to be dependent on current evaluation.
769
+ if 'evaluation' in self.inputs.__signature__.arg_names:
770
+ kwargs['evaluation'] = self
771
+ return self.inputs(**kwargs)
748
772
 
749
773
  @property
750
774
  def num_examples(self) -> int:
@@ -784,7 +808,12 @@ class Evaluation(Evaluable):
784
808
  if self.schema_fn is None:
785
809
  return None
786
810
 
787
- schema = self.schema_fn()
811
+ kwargs = {}
812
+ # Allow schema to be a function based on current evaluation.
813
+ if 'evaluation' in self.schema_fn.__signature__.arg_names:
814
+ kwargs['evaluation'] = self
815
+
816
+ schema = self._call_schema_fn()
788
817
  fewshot_examples = None
789
818
  if isinstance(schema, tuple):
790
819
  schema, fewshot_examples = schema
@@ -798,13 +827,20 @@ class Evaluation(Evaluable):
798
827
  if self.schema_fn is None:
799
828
  return None
800
829
 
801
- schema = self.schema_fn()
830
+ schema = self._call_schema_fn()
802
831
  fewshot_examples = None
803
832
  if isinstance(schema, tuple):
804
833
  schema, fewshot_examples = schema
805
834
  self.__dict__['schema'] = self._formalize_schema(schema)
806
835
  return self._maybe_adjust_examples_for_completion(fewshot_examples)
807
836
 
837
+ def _call_schema_fn(self):
838
+ kwargs = {}
839
+ # Allow schema to be a function based on current evaluation.
840
+ if 'evaluation' in self.schema_fn.__signature__.arg_names:
841
+ kwargs['evaluation'] = self
842
+ return self.schema_fn(**kwargs)
843
+
808
844
  def _formalize_schema(self, annotation) -> lf_structured.Schema:
809
845
  """Formalizes schema from annotation."""
810
846
  if self.method == 'complete':
@@ -854,9 +890,9 @@ class Evaluation(Evaluable):
854
890
  return []
855
891
  children = []
856
892
  for i, child in enumerate(pg.iter(self)):
857
- child.rebind(id=f'{self.id}@{child.hash}', skip_notification=True)
858
893
  child.sym_setparent(self)
859
894
  child.sym_setpath(self.sym_path + f'children[{i}]')
895
+ child.rebind(id=f'{self.id}@{child.hash}', skip_notification=True)
860
896
  children.append(child)
861
897
  return children
862
898
 
@@ -873,9 +909,6 @@ class Evaluation(Evaluable):
873
909
 
874
910
  def _on_bound(self):
875
911
  super()._on_bound()
876
- if self.method != 'call' and self.schema_fn is None:
877
- raise ValueError(
878
- f'`schema_fn` must be specified for method {self.method!r}')
879
912
  self.__dict__.pop('hash', None)
880
913
  self.__dict__.pop('children', None)
881
914
  self.__dict__.pop('examples', None)
@@ -1442,11 +1475,11 @@ class Summary(pg.Object):
1442
1475
  cols = set()
1443
1476
  nonpivot_values = collections.defaultdict(set)
1444
1477
  for e in evaluations:
1445
- for k, v in e.sym_init_args.items():
1478
+ for k in e.sym_init_args:
1446
1479
  if pivot_field == k:
1447
- cols.add(SymbolicComparable(v))
1480
+ cols.add(SymbolicComparable(e.sym_inferred(k)))
1448
1481
  elif k not in ('id', 'groundtruth'):
1449
- nonpivot_values[k].add(SymbolicComparable(v))
1482
+ nonpivot_values[k].add(SymbolicComparable(e.sym_inferred(k)))
1450
1483
 
1451
1484
  cols = sorted(cols)
1452
1485
 
@@ -42,7 +42,8 @@ def answer_schema():
42
42
 
43
43
 
44
44
  @pg.functor
45
- def answer_schema_with_fewshot_examples():
45
+ def answer_schema_with_fewshot_examples(evaluation):
46
+ del evaluation
46
47
  return Solution, [
47
48
  lf_structured.MappingExample(
48
49
  input='The result of one plus two',
@@ -61,7 +62,7 @@ def eval_set(
61
62
  eval_id: str,
62
63
  method: str,
63
64
  schema_fn,
64
- lm: lf.LanguageModel,
65
+ lm: lf.LanguageModel = pg.MISSING_VALUE,
65
66
  use_cache: bool = True,
66
67
  cls: Type[base.Evaluation] = base.Evaluation,
67
68
  **kwargs,
@@ -170,8 +171,6 @@ class EvaluationTest(unittest.TestCase):
170
171
  )
171
172
 
172
173
  def test_bad_init(self):
173
- with self.assertRaisesRegex(ValueError, '.*'):
174
- eval_set('bad_init1', 'complete', None, lm=fake.StaticResponse('hi'))
175
174
 
176
175
  @pg.functor()
177
176
  def _bad_completion_schema():
@@ -438,18 +437,18 @@ class SuiteTest(unittest.TestCase):
438
437
  lm = fake.StaticSequence([
439
438
  'Solution(final_answer=2)',
440
439
  '3',
441
- ])
440
+ ] * 5)
442
441
  s = base.Suite(
443
442
  'suite_run_test',
444
443
  [
445
- eval_set('run_test_1', 'query', schema_fn=answer_schema(), lm=lm),
444
+ eval_set('run_test_1', 'query', schema_fn=answer_schema()),
446
445
  # A suite of search space. Two of the sub-experiments are identical,
447
446
  # thus the result of run_test_2 would include only two keys.
448
447
  eval_set('run_test_2',
449
448
  pg.oneof(['call', 'query']),
450
- schema_fn=pg.oneof([answer_schema(), answer_schema()]),
451
- lm=lm),
449
+ schema_fn=pg.oneof([answer_schema(), answer_schema()])),
452
450
  ],
451
+ lm=lm
453
452
  )
454
453
  # Test for persistent hash.
455
454
  self.assertEqual(s.hash, '7285e52b')
@@ -482,7 +481,7 @@ class SuiteTest(unittest.TestCase):
482
481
  schema_fn='answer_schema()',
483
482
  ),
484
483
  cache_stats=dict(
485
- use_cache=True, num_queries=3, num_hits=0, num_updates=2
484
+ use_cache=True, num_queries=4, num_hits=0, num_updates=4
486
485
  ),
487
486
  metrics=dict(total=2, failures=2, failure_rate=1.0),
488
487
  ),
@@ -288,6 +288,8 @@ class LanguageModel(component.Component):
288
288
  **kwargs,
289
289
  ) -> list[LMSamplingResult]:
290
290
  """Samples one or multiple prompts."""
291
+ # Internal usage logging.
292
+
291
293
  prompts = [message_lib.UserMessage.from_value(p) for p in prompts]
292
294
 
293
295
  with component.context(override_attrs=True, **kwargs):
@@ -26,7 +26,7 @@ class QueryStructure(mapping.Mapping):
26
26
  """Query an object out from a natural language text."""
27
27
 
28
28
  context_title = 'CONTEXT'
29
- input_title = 'USER_REQUEST'
29
+ input_title = 'INPUT_OBJECT'
30
30
 
31
31
  # Mark schema as required.
32
32
  schema: pg.typing.Annotated[
@@ -65,11 +65,6 @@ class QueryStructurePython(QueryStructure):
65
65
  preamble = """
66
66
  Please respond to the last {{ input_title }} with {{ output_title }} according to {{ schema_title }}.
67
67
 
68
- INSTRUCTIONS:
69
- 1. Only respond with the required {{ output_title }} encapsulated with python markdown as illustrated by the given example.
70
- 2. Don't add any comments in the response.
71
- 3. {{ output_title }} must strictly follow the {{ schema_title }}.
72
-
73
68
  {{ input_title }}:
74
69
  1 + 1 =
75
70
 
@@ -87,8 +82,8 @@ class QueryStructurePython(QueryStructure):
87
82
  ```
88
83
  """
89
84
  protocol = 'python'
90
- schema_title = 'RESULT_TYPE'
91
- output_title = 'RESULT_OBJECT'
85
+ schema_title = 'OUTPUT_TYPE'
86
+ output_title = 'OUTPUT_OBJECT'
92
87
 
93
88
 
94
89
  def _query_structure_cls(
@@ -174,6 +169,8 @@ def query(
174
169
  Returns:
175
170
  The result based on the schema.
176
171
  """
172
+ # Internal usage logging.
173
+
177
174
  # When `lf.query` is used for symbolic completion, schema is automatically
178
175
  # inferred when it is None.
179
176
  if isinstance(prompt, pg.Symbolic) and prompt.sym_partial and schema is None:
@@ -115,7 +115,14 @@ class QueryTest(unittest.TestCase):
115
115
  x=1,
116
116
  y=2,
117
117
  lm=lm.clone(),
118
- expected_snippet='\n\nUSER_REQUEST:\n What is 1 + 2?\n\n',
118
+ expected_snippet=(
119
+ 'Please respond to the last INPUT_OBJECT with OUTPUT_OBJECT'
120
+ ' according to OUTPUT_TYPE.\n\nINPUT_OBJECT:\n 1 + 1'
121
+ ' =\n\nOUTPUT_TYPE:\n Answer\n\n ```python\n class Answer:\n '
122
+ ' final_answer: int\n ```\n\nOUTPUT_OBJECT:\n ```python\n '
123
+ ' Answer(final_answer=2)\n ```\n\nINPUT_OBJECT:\n What is 1 +'
124
+ ' 2?\n\nOUTPUT_TYPE:\n int\n\nOUTPUT_OBJECT:'
125
+ ),
119
126
  )
120
127
 
121
128
  def test_str_to_str_render(self):
@@ -139,7 +146,7 @@ class QueryTest(unittest.TestCase):
139
146
  y=2,
140
147
  lm=lm.clone(),
141
148
  expected_snippet=(
142
- '\n\nUSER_REQUEST:\n ```python\n [\n 1\n ]\n ```\n\n'
149
+ '\n\nINPUT_OBJECT:\n ```python\n [\n 1\n ]\n ```\n\n'
143
150
  ),
144
151
  )
145
152
 
@@ -155,7 +162,7 @@ class QueryTest(unittest.TestCase):
155
162
  modalities.Image.from_bytes(b'mock_image'),
156
163
  int,
157
164
  lm=lm,
158
- expected_snippet='\n\nUSER_REQUEST:\n {{input}}\n\n',
165
+ expected_snippet='\n\nINPUT_OBJECT:\n {{input}}\n\n',
159
166
  expected_modalities=1,
160
167
  )
161
168
 
@@ -207,7 +214,7 @@ class QueryTest(unittest.TestCase):
207
214
  list[str],
208
215
  lm=lm,
209
216
  expected_snippet=inspect.cleandoc("""
210
- USER_REQUEST:
217
+ INPUT_OBJECT:
211
218
  ```python
212
219
  [
213
220
  ModalityRef(
@@ -238,17 +245,12 @@ class QueryStructurePythonTest(unittest.TestCase):
238
245
  self.assertEqual(
239
246
  l.render().text,
240
247
  inspect.cleandoc("""
241
- Please respond to the last USER_REQUEST with RESULT_OBJECT according to RESULT_TYPE.
242
-
243
- INSTRUCTIONS:
244
- 1. Only respond with the required RESULT_OBJECT encapsulated with python markdown as illustrated by the given example.
245
- 2. Don't add any comments in the response.
246
- 3. RESULT_OBJECT must strictly follow the RESULT_TYPE.
248
+ Please respond to the last INPUT_OBJECT with OUTPUT_OBJECT according to OUTPUT_TYPE.
247
249
 
248
- USER_REQUEST:
250
+ INPUT_OBJECT:
249
251
  1 + 1 =
250
252
 
251
- RESULT_TYPE:
253
+ OUTPUT_TYPE:
252
254
  Answer
253
255
 
254
256
  ```python
@@ -256,18 +258,18 @@ class QueryStructurePythonTest(unittest.TestCase):
256
258
  final_answer: int
257
259
  ```
258
260
 
259
- RESULT_OBJECT:
261
+ OUTPUT_OBJECT:
260
262
  ```python
261
263
  Answer(final_answer=2)
262
264
  ```
263
265
 
264
- USER_REQUEST:
266
+ INPUT_OBJECT:
265
267
  Compute 12 / 6 + 2.
266
268
 
267
- RESULT_TYPE:
269
+ OUTPUT_TYPE:
268
270
  int
269
271
 
270
- RESULT_OBJECT:
272
+ OUTPUT_OBJECT:
271
273
  """),
272
274
  )
273
275
 
@@ -287,17 +289,12 @@ class QueryStructurePythonTest(unittest.TestCase):
287
289
  self.assertEqual(
288
290
  l.render().text,
289
291
  inspect.cleandoc("""
290
- Please respond to the last USER_REQUEST with RESULT_OBJECT according to RESULT_TYPE.
291
-
292
- INSTRUCTIONS:
293
- 1. Only respond with the required RESULT_OBJECT encapsulated with python markdown as illustrated by the given example.
294
- 2. Don't add any comments in the response.
295
- 3. RESULT_OBJECT must strictly follow the RESULT_TYPE.
292
+ Please respond to the last INPUT_OBJECT with OUTPUT_OBJECT according to OUTPUT_TYPE.
296
293
 
297
- USER_REQUEST:
294
+ INPUT_OBJECT:
298
295
  1 + 1 =
299
296
 
300
- RESULT_TYPE:
297
+ OUTPUT_TYPE:
301
298
  Answer
302
299
 
303
300
  ```python
@@ -305,41 +302,41 @@ class QueryStructurePythonTest(unittest.TestCase):
305
302
  final_answer: int
306
303
  ```
307
304
 
308
- RESULT_OBJECT:
305
+ OUTPUT_OBJECT:
309
306
  ```python
310
307
  Answer(final_answer=2)
311
308
  ```
312
309
 
313
- USER_REQUEST:
310
+ INPUT_OBJECT:
314
311
  What is the answer of 1 plus 1?
315
312
 
316
- RESULT_TYPE:
313
+ OUTPUT_TYPE:
317
314
  int
318
315
 
319
- RESULT_OBJECT:
316
+ OUTPUT_OBJECT:
320
317
  ```python
321
318
  2
322
319
  ```
323
320
 
324
- USER_REQUEST:
321
+ INPUT_OBJECT:
325
322
  Compute the value of 3 + (2 * 6).
326
323
 
327
- RESULT_TYPE:
324
+ OUTPUT_TYPE:
328
325
  int
329
326
 
330
- RESULT_OBJECT:
327
+ OUTPUT_OBJECT:
331
328
  ```python
332
329
  15
333
330
  ```
334
331
 
335
332
 
336
- USER_REQUEST:
333
+ INPUT_OBJECT:
337
334
  Compute 12 / 6 + 2.
338
335
 
339
- RESULT_TYPE:
336
+ OUTPUT_TYPE:
340
337
  int
341
338
 
342
- RESULT_OBJECT:
339
+ OUTPUT_OBJECT:
343
340
  """),
344
341
  )
345
342
 
@@ -445,13 +442,13 @@ class QueryStructureJsonTest(unittest.TestCase):
445
442
  self.assertEqual(
446
443
  l.render().text,
447
444
  inspect.cleandoc("""
448
- Please respond to the last USER_REQUEST with JSON according to SCHEMA:
445
+ Please respond to the last INPUT_OBJECT with JSON according to SCHEMA:
449
446
 
450
447
  INSTRUCTIONS:
451
448
  1. If the schema has `_type`, carry it over to the JSON output.
452
449
  2. If a field from the schema cannot be extracted from the response, use null as the JSON value.
453
450
 
454
- USER_REQUEST:
451
+ INPUT_OBJECT:
455
452
  1 + 1 =
456
453
 
457
454
  SCHEMA:
@@ -460,7 +457,7 @@ class QueryStructureJsonTest(unittest.TestCase):
460
457
  JSON:
461
458
  {"result": {"_type": "langfun.core.structured.prompting.Answer", "final_answer": 2}}
462
459
 
463
- USER_REQUEST:
460
+ INPUT_OBJECT:
464
461
  Compute 12 / 6 + 2.
465
462
 
466
463
  SCHEMA:
@@ -482,13 +479,13 @@ class QueryStructureJsonTest(unittest.TestCase):
482
479
  self.assertEqual(
483
480
  l.render().text,
484
481
  inspect.cleandoc("""
485
- Please respond to the last USER_REQUEST with JSON according to SCHEMA:
482
+ Please respond to the last INPUT_OBJECT with JSON according to SCHEMA:
486
483
 
487
484
  INSTRUCTIONS:
488
485
  1. If the schema has `_type`, carry it over to the JSON output.
489
486
  2. If a field from the schema cannot be extracted from the response, use null as the JSON value.
490
487
 
491
- USER_REQUEST:
488
+ INPUT_OBJECT:
492
489
  1 + 1 =
493
490
 
494
491
  SCHEMA:
@@ -497,7 +494,7 @@ class QueryStructureJsonTest(unittest.TestCase):
497
494
  JSON:
498
495
  {"result": {"_type": "langfun.core.structured.prompting.Answer", "final_answer": 2}}
499
496
 
500
- USER_REQUEST:
497
+ INPUT_OBJECT:
501
498
  What is the answer of 1 plus 1?
502
499
 
503
500
  SCHEMA:
@@ -506,7 +503,7 @@ class QueryStructureJsonTest(unittest.TestCase):
506
503
  JSON:
507
504
  {"result": 2}
508
505
 
509
- USER_REQUEST:
506
+ INPUT_OBJECT:
510
507
  Compute the value of 3 + (2 * 6).
511
508
 
512
509
  SCHEMA:
@@ -516,7 +513,7 @@ class QueryStructureJsonTest(unittest.TestCase):
516
513
  {"result": 15}
517
514
 
518
515
 
519
- USER_REQUEST:
516
+ INPUT_OBJECT:
520
517
  Compute 12 / 6 + 2.
521
518
 
522
519
  SCHEMA:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langfun
3
- Version: 0.0.2.dev20240208
3
+ Version: 0.0.2.dev20240210
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.dev20240109
27
+ Requires-Dist: pyglove>=0.4.5.dev20240201
28
28
  Requires-Dist: requests>=2.31.0
29
29
  Requires-Dist: termcolor==1.1.0
30
30
  Requires-Dist: tqdm>=4.64.1
@@ -1,7 +1,7 @@
1
1
  google-generativeai>=0.3.2
2
2
  jinja2>=3.1.2
3
3
  openai==0.27.2
4
- pyglove>=0.4.5.dev20240109
4
+ pyglove>=0.4.5.dev20240201
5
5
  requests>=2.31.0
6
6
  termcolor==1.1.0
7
7
  tqdm>=4.64.1