langfun 0.1.2.dev202509220805__tar.gz → 0.1.2.dev202509240805__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.

Potentially problematic release.


This version of langfun might be problematic. Click here for more details.

Files changed (189) hide show
  1. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/PKG-INFO +1 -1
  2. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/env/__init__.py +0 -1
  3. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/env/base_environment.py +126 -66
  4. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/env/base_feature.py +79 -40
  5. langfun-0.1.2.dev202509240805/langfun/env/base_sandbox.py +964 -0
  6. langfun-0.1.2.dev202509240805/langfun/env/base_test.py +1604 -0
  7. langfun-0.1.2.dev202509240805/langfun/env/interface.py +971 -0
  8. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/env/load_balancers.py +4 -4
  9. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/env/load_balancers_test.py +32 -57
  10. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun.egg-info/PKG-INFO +1 -1
  11. langfun-0.1.2.dev202509220805/langfun/env/base_sandbox.py +0 -458
  12. langfun-0.1.2.dev202509220805/langfun/env/base_test.py +0 -795
  13. langfun-0.1.2.dev202509220805/langfun/env/interface.py +0 -843
  14. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/LICENSE +0 -0
  15. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/README.md +0 -0
  16. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/__init__.py +0 -0
  17. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/__init__.py +0 -0
  18. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/bounding_box_parser.py +0 -0
  19. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/bounding_box_parser_test.py +0 -0
  20. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/drawing.py +0 -0
  21. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/drawing_test.py +0 -0
  22. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/location.py +0 -0
  23. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/location_test.py +0 -0
  24. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/__init__.py +0 -0
  25. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/agentic/__init__.py +0 -0
  26. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/agentic/action.py +0 -0
  27. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/agentic/action_eval.py +0 -0
  28. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/agentic/action_eval_test.py +0 -0
  29. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/agentic/action_test.py +0 -0
  30. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/async_support.py +0 -0
  31. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/async_support_test.py +0 -0
  32. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/__init__.py +0 -0
  33. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/__init__.py +0 -0
  34. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/correction.py +0 -0
  35. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/correction_test.py +0 -0
  36. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/execution.py +0 -0
  37. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/execution_test.py +0 -0
  38. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/generation.py +0 -0
  39. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/generation_test.py +0 -0
  40. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/parsing.py +0 -0
  41. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/parsing_test.py +0 -0
  42. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/sandboxing.py +0 -0
  43. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/sandboxing_test.py +0 -0
  44. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/component.py +0 -0
  45. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/component_test.py +0 -0
  46. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/concurrent.py +0 -0
  47. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/concurrent_test.py +0 -0
  48. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/console.py +0 -0
  49. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/console_test.py +0 -0
  50. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/__init__.py +0 -0
  51. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/__init__.py +0 -0
  52. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/anthropic.py +0 -0
  53. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/anthropic_test.py +0 -0
  54. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/gemini.py +0 -0
  55. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/gemini_test.py +0 -0
  56. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/openai.py +0 -0
  57. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/openai_test.py +0 -0
  58. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/__init__.py +0 -0
  59. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/base.py +0 -0
  60. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/base_test.py +0 -0
  61. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/matching.py +0 -0
  62. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/matching_test.py +0 -0
  63. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/patching.py +0 -0
  64. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/patching_test.py +0 -0
  65. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/scoring.py +0 -0
  66. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/scoring_test.py +0 -0
  67. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/__init__.py +0 -0
  68. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/checkpointing.py +0 -0
  69. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/checkpointing_test.py +0 -0
  70. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/eval_test_helper.py +0 -0
  71. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/evaluation.py +0 -0
  72. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/evaluation_test.py +0 -0
  73. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/example.py +0 -0
  74. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/example_test.py +0 -0
  75. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/experiment.py +0 -0
  76. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/experiment_test.py +0 -0
  77. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/metric_values.py +0 -0
  78. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/metric_values_test.py +0 -0
  79. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/metrics.py +0 -0
  80. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/metrics_test.py +0 -0
  81. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/progress.py +0 -0
  82. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/progress_test.py +0 -0
  83. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/progress_tracking.py +0 -0
  84. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/progress_tracking_test.py +0 -0
  85. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/reporting.py +0 -0
  86. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/reporting_test.py +0 -0
  87. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/runners.py +0 -0
  88. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/runners_test.py +0 -0
  89. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/langfunc.py +0 -0
  90. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/langfunc_test.py +0 -0
  91. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/language_model.py +0 -0
  92. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/language_model_test.py +0 -0
  93. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/__init__.py +0 -0
  94. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/anthropic.py +0 -0
  95. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/anthropic_test.py +0 -0
  96. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/azure_openai.py +0 -0
  97. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/azure_openai_test.py +0 -0
  98. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/cache/__init__.py +0 -0
  99. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/cache/base.py +0 -0
  100. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/cache/in_memory.py +0 -0
  101. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/cache/in_memory_test.py +0 -0
  102. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/compositional.py +0 -0
  103. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/compositional_test.py +0 -0
  104. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/deepseek.py +0 -0
  105. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/deepseek_test.py +0 -0
  106. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/fake.py +0 -0
  107. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/fake_test.py +0 -0
  108. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/gemini.py +0 -0
  109. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/gemini_test.py +0 -0
  110. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/google_genai.py +0 -0
  111. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/google_genai_test.py +0 -0
  112. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/groq.py +0 -0
  113. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/groq_test.py +0 -0
  114. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/llama_cpp.py +0 -0
  115. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/llama_cpp_test.py +0 -0
  116. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/openai.py +0 -0
  117. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/openai_compatible.py +0 -0
  118. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/openai_compatible_test.py +0 -0
  119. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/openai_test.py +0 -0
  120. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/rest.py +0 -0
  121. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/rest_test.py +0 -0
  122. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/vertexai.py +0 -0
  123. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/vertexai_test.py +0 -0
  124. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/logging.py +0 -0
  125. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/logging_test.py +0 -0
  126. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/memories/__init__.py +0 -0
  127. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/memories/conversation_history.py +0 -0
  128. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/memories/conversation_history_test.py +0 -0
  129. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/memory.py +0 -0
  130. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/message.py +0 -0
  131. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/message_test.py +0 -0
  132. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/__init__.py +0 -0
  133. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/audio.py +0 -0
  134. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/audio_test.py +0 -0
  135. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/image.py +0 -0
  136. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/image_test.py +0 -0
  137. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/mime.py +0 -0
  138. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/mime_test.py +0 -0
  139. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/pdf.py +0 -0
  140. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/pdf_test.py +0 -0
  141. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/video.py +0 -0
  142. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/video_test.py +0 -0
  143. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modality.py +0 -0
  144. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modality_test.py +0 -0
  145. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/natural_language.py +0 -0
  146. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/natural_language_test.py +0 -0
  147. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/sampling.py +0 -0
  148. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/sampling_test.py +0 -0
  149. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/__init__.py +0 -0
  150. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/completion.py +0 -0
  151. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/completion_test.py +0 -0
  152. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/description.py +0 -0
  153. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/description_test.py +0 -0
  154. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/function_generation.py +0 -0
  155. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/function_generation_test.py +0 -0
  156. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/mapping.py +0 -0
  157. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/mapping_test.py +0 -0
  158. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/parsing.py +0 -0
  159. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/parsing_test.py +0 -0
  160. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/querying.py +0 -0
  161. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/querying_test.py +0 -0
  162. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/schema.py +0 -0
  163. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/schema_generation.py +0 -0
  164. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/schema_generation_test.py +0 -0
  165. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/schema_test.py +0 -0
  166. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/scoring.py +0 -0
  167. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/scoring_test.py +0 -0
  168. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/tokenization.py +0 -0
  169. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/tokenization_test.py +0 -0
  170. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/subscription.py +0 -0
  171. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/subscription_test.py +0 -0
  172. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/template.py +0 -0
  173. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/template_test.py +0 -0
  174. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/__init__.py +0 -0
  175. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/completion.py +0 -0
  176. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/completion_test.py +0 -0
  177. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/conversation.py +0 -0
  178. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/conversation_test.py +0 -0
  179. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/demonstration.py +0 -0
  180. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/demonstration_test.py +0 -0
  181. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/selfplay.py +0 -0
  182. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/selfplay_test.py +0 -0
  183. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/env/interface_test.py +0 -0
  184. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun.egg-info/SOURCES.txt +0 -0
  185. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun.egg-info/dependency_links.txt +0 -0
  186. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun.egg-info/requires.txt +0 -0
  187. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun.egg-info/top_level.txt +0 -0
  188. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/setup.cfg +0 -0
  189. {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langfun
3
- Version: 0.1.2.dev202509220805
3
+ Version: 0.1.2.dev202509240805
4
4
  Summary: Langfun: Language as Functions.
5
5
  Home-page: https://github.com/google/langfun
6
6
  Author: Langfun Authors
@@ -27,7 +27,6 @@ from langfun.env.interface import SandboxStateError
27
27
  from langfun.env.interface import Environment
28
28
  from langfun.env.interface import Sandbox
29
29
  from langfun.env.interface import Feature
30
- from langfun.env.interface import call_with_event
31
30
 
32
31
  from langfun.env.base_environment import BaseEnvironment
33
32
  from langfun.env.base_sandbox import BaseSandbox
@@ -19,16 +19,19 @@ environments that handles pooling, load balancing, and maintenance.
19
19
  Note that:
20
20
  - Environments do not have to inherit from this class, especially if features
21
21
  like pooling or load balancing are not needed.
22
- - `BaseEnvironment` is not required to work with `BaseSandbox`.
22
+ - `BaseEnvironment` is coupled with `BaseSandbox`.
23
23
  """
24
24
 
25
25
  import abc
26
26
  import functools
27
+ import random
27
28
  import threading
28
29
  import time
29
30
  from typing import Annotated, Any
31
+ import uuid
30
32
 
31
33
  import langfun.core as lf
34
+ from langfun.env import base_sandbox
32
35
  from langfun.env import interface
33
36
  from langfun.env import load_balancers
34
37
  import pyglove as pg
@@ -66,6 +69,16 @@ class BaseEnvironment(interface.Environment):
66
69
  )
67
70
  ] = load_balancers.RoundRobin()
68
71
 
72
+ proactive_session_setup: Annotated[
73
+ bool,
74
+ (
75
+ 'If True, all sandboxes will perform setup work before a user '
76
+ 'session is started. This is useful for features that need to '
77
+ 'perform heavy setup work, which could block the user thread for a '
78
+ 'long time.'
79
+ )
80
+ ] = True
81
+
69
82
  outage_grace_period: Annotated[
70
83
  float,
71
84
  (
@@ -100,13 +113,24 @@ class BaseEnvironment(interface.Environment):
100
113
  )
101
114
  ] = 256
102
115
 
116
+ random_seed: Annotated[
117
+ int | None,
118
+ (
119
+ 'The random seed for generating session IDs with reproducibility. '
120
+ 'If None, no seed will be used.'
121
+ )
122
+ ] = None
123
+
103
124
  def _on_bound(self) -> None:
104
125
  super()._on_bound()
105
126
 
106
- self._alive = False
127
+ self._status = self.Status.CREATED
107
128
  self._start_time = None
108
129
  self._sandbox_pool = []
109
130
  self._next_pooled_sandbox_id = 0
131
+ self._random = (
132
+ random if self.random_seed is None else random.Random(self.random_seed)
133
+ )
110
134
 
111
135
  self._maintenance_thread = None
112
136
  self._offline_start_time = None
@@ -119,13 +143,16 @@ class BaseEnvironment(interface.Environment):
119
143
  def _create_sandbox(
120
144
  self,
121
145
  sandbox_id: str,
122
- reusable: bool
123
- ) -> interface.Sandbox:
146
+ reusable: bool,
147
+ proactive_session_setup: bool,
148
+ ) -> base_sandbox.BaseSandbox:
124
149
  """Creates a sandbox with the given identifier.
125
150
 
126
151
  Args:
127
152
  sandbox_id: The identifier for the sandbox.
128
153
  reusable: Whether the sandbox is reusable across user sessions.
154
+ proactive_session_setup: Whether the sandbox performs session setup work
155
+ before a user session is started.
129
156
 
130
157
  Returns:
131
158
  The created sandbox.
@@ -135,32 +162,28 @@ class BaseEnvironment(interface.Environment):
135
162
  interface.SandboxStateError: If sandbox cannot be started.
136
163
  """
137
164
 
165
+ def new_session_id(self) -> str:
166
+ """Generates a random session ID."""
167
+ suffix = uuid.UUID(
168
+ bytes=bytes(bytes(self._random.getrandbits(8) for _ in range(16))),
169
+ version=4
170
+ ).hex[:7]
171
+ return f'session-{suffix}'
172
+
138
173
  #
139
174
  # Subclasses can override:
140
175
  #
141
176
 
142
177
  def stats(self) -> dict[str, Any]:
143
178
  """Returns the stats of the environment."""
144
- num_busy = 0
145
- num_free = 0
146
- num_dead = 0
147
-
179
+ stats_dict = {
180
+ status.value: 0
181
+ for status in interface.Sandbox.Status
182
+ }
148
183
  for sandbox in self._sandbox_pool:
149
- if sandbox.is_alive:
150
- if sandbox.is_busy:
151
- num_busy += 1
152
- else:
153
- num_free += 1
154
- else:
155
- num_dead += 1
156
-
184
+ stats_dict[sandbox.status.value] += 1
157
185
  return {
158
- 'sandbox': {
159
- 'num_total': len(self._sandbox_pool),
160
- 'num_busy': num_busy,
161
- 'num_free': num_free,
162
- 'num_dead': num_dead,
163
- },
186
+ 'sandbox': stats_dict,
164
187
  }
165
188
 
166
189
  def _start(self) -> None:
@@ -169,7 +192,9 @@ class BaseEnvironment(interface.Environment):
169
192
  self._sandbox_pool = [
170
193
  sandbox
171
194
  for _, sandbox, _ in lf.concurrent_map(
172
- lambda i: self._bring_up_sandbox_with_retry(sandbox_id=str(i)),
195
+ lambda i: self._bring_up_sandbox_with_retry(
196
+ sandbox_id=str(i), shutdown_env_upon_outage=False
197
+ ),
173
198
  range(self.min_pool_size),
174
199
  silence_on_errors=None,
175
200
  max_workers=min(
@@ -179,7 +204,6 @@ class BaseEnvironment(interface.Environment):
179
204
  )
180
205
  ]
181
206
  self._next_sandbox_id = len(self._sandbox_pool)
182
- self._alive = True
183
207
  self._maintenance_thread = threading.Thread(
184
208
  target=self._maintenance_loop, daemon=True
185
209
  )
@@ -193,7 +217,7 @@ class BaseEnvironment(interface.Environment):
193
217
  self._maintenance_thread.join()
194
218
  self._maintenance_thread = None
195
219
 
196
- def _shutdown_sandbox(sandbox: interface.Sandbox) -> None:
220
+ def _shutdown_sandbox(sandbox: base_sandbox.BaseSandbox) -> None:
197
221
  sandbox.shutdown()
198
222
 
199
223
  if self._sandbox_pool:
@@ -215,7 +239,7 @@ class BaseEnvironment(interface.Environment):
215
239
  #
216
240
 
217
241
  @property
218
- def sandbox_pool(self) -> list[interface.Sandbox]:
242
+ def sandbox_pool(self) -> list[base_sandbox.BaseSandbox]:
219
243
  """Returns the sandbox pool."""
220
244
  return self._sandbox_pool
221
245
 
@@ -230,9 +254,13 @@ class BaseEnvironment(interface.Environment):
230
254
  return self.min_pool_size > 0
231
255
 
232
256
  @property
233
- def is_alive(self) -> bool:
234
- """Returns whether the environment is alive."""
235
- return self._alive
257
+ def status(self) -> interface.Environment.Status:
258
+ """Returns whether the environment is online."""
259
+ return self._status
260
+
261
+ def _set_status(self, status: interface.Environment.Status) -> None:
262
+ """Sets the status of the environment."""
263
+ self._status = status
236
264
 
237
265
  @property
238
266
  def min_pool_size(self) -> int:
@@ -270,48 +298,56 @@ class BaseEnvironment(interface.Environment):
270
298
  Raises:
271
299
  interface.EnvironmentOutageError: If the environment is out of service.
272
300
  """
273
- assert not self._alive
274
- def _start_impl():
301
+ assert self._status == self.Status.CREATED, (
302
+ f'Environment {self.id} cannot be started because '
303
+ f'it is in {self._status.value!r} status.'
304
+ )
305
+
306
+ try:
275
307
  with pg.timeit('env.start') as t:
276
308
  self._start()
277
- self._start_time = time.time()
309
+ self._start_time = time.time()
278
310
  pg.logging.info(
279
311
  '[%s]: %s started in %.2f seconds.',
280
312
  self.id, self.__class__.__name__, t.elapse
281
313
  )
282
- interface.call_with_event(
283
- _start_impl, self.on_start,
284
- )
314
+ self._set_status(self.Status.ONLINE)
315
+ self.on_start()
316
+ except BaseException as e:
317
+ self.on_start(error=e)
318
+ self.shutdown()
319
+ raise e
285
320
 
286
321
  def shutdown(self) -> None:
287
322
  """Shuts down the environment.
288
323
 
289
324
  This method should not raise any exceptions.
290
325
  """
291
- if not self._alive:
326
+ if self._status in (
327
+ self.Status.SHUTTING_DOWN,
328
+ self.Status.OFFLINE,
329
+ ):
292
330
  return
293
331
 
294
- self._alive = False
295
- def _shutdown_impl():
296
- pg.logging.info(
297
- '[%s]: Shutting down %s...', self.id, self.__class__.__name__
298
- )
332
+ self._set_status(self.Status.SHUTTING_DOWN)
333
+
334
+ try:
299
335
  with pg.timeit('env.shutdown') as t:
300
336
  self._shutdown()
337
+ self.on_shutdown()
301
338
  pg.logging.info(
302
339
  '[%s]: %s shutdown in %.2f seconds.',
303
340
  self.id, self.__class__.__name__, t.elapse
304
341
  )
305
-
306
- interface.call_with_event(
307
- _shutdown_impl, self.on_shutdown,
308
- )
342
+ except BaseException as e: # pylint: disable=broad-except
343
+ self.on_shutdown(error=e)
344
+ raise e
309
345
 
310
346
  #
311
347
  # Environment operations.
312
348
  #
313
349
 
314
- def acquire(self) -> interface.Sandbox:
350
+ def acquire(self) -> base_sandbox.BaseSandbox:
315
351
  """Acquires a sandbox from the environment.
316
352
 
317
353
  Returns:
@@ -324,7 +360,7 @@ class BaseEnvironment(interface.Environment):
324
360
  the grace period has passed.
325
361
  """
326
362
 
327
- if not self._alive:
363
+ if not self.is_online:
328
364
  raise interface.EnvironmentOutageError(
329
365
  f'Environment {self.id} is not alive.',
330
366
  environment=self,
@@ -334,7 +370,7 @@ class BaseEnvironment(interface.Environment):
334
370
  if not self.enable_pooling:
335
371
  return self._bring_up_sandbox_with_retry(
336
372
  sandbox_id=str(self._increment_sandbox_id()),
337
- set_pending=True,
373
+ set_acquired=True,
338
374
  )
339
375
 
340
376
  allocation_start_time = time.time()
@@ -352,13 +388,9 @@ class BaseEnvironment(interface.Environment):
352
388
  time.sleep(1)
353
389
  else:
354
390
  try:
355
- sandbox = self._create_sandbox(
356
- sandbox_id=str(self._increment_sandbox_id()),
357
- reusable=self.enable_pooling,
391
+ sandbox = self._bring_up_sandbox(
392
+ sandbox_id=str(self._increment_sandbox_id()), set_acquired=True,
358
393
  )
359
- sandbox.start()
360
- sandbox.set_pending()
361
-
362
394
  # Append is atomic and does not require locking.
363
395
  self._sandbox_pool.append(sandbox)
364
396
  self._offline_start_time = None
@@ -368,17 +400,35 @@ class BaseEnvironment(interface.Environment):
368
400
  ) as ex:
369
401
  self._report_outage_or_wait(ex)
370
402
 
403
+ def _bring_up_sandbox(
404
+ self,
405
+ sandbox_id: str,
406
+ set_acquired: bool = False,
407
+ ) -> base_sandbox.BaseSandbox:
408
+ """Brings up a new sandbox."""
409
+ sandbox = self._create_sandbox(
410
+ sandbox_id=sandbox_id,
411
+ reusable=self.enable_pooling,
412
+ proactive_session_setup=self.proactive_session_setup,
413
+ )
414
+ for handler in self.event_handlers:
415
+ sandbox.add_event_handler(handler)
416
+ sandbox.start()
417
+ if set_acquired:
418
+ sandbox.set_acquired()
419
+ return sandbox
420
+
371
421
  def _bring_up_sandbox_with_retry(
372
422
  self,
373
423
  sandbox_id: str,
374
- set_pending: bool = False,
424
+ set_acquired: bool = False,
375
425
  shutdown_env_upon_outage: bool = True,
376
- ) -> interface.Sandbox:
426
+ ) -> base_sandbox.BaseSandbox:
377
427
  """Brings up a new sandbox with retry until grace period is passed.
378
428
 
379
429
  Args:
380
430
  sandbox_id: The ID of the sandbox to bring up.
381
- set_pending: Whether to mark the sandbox as pending.
431
+ set_acquired: If True, the sandbox will be marked as acquired.
382
432
  shutdown_env_upon_outage: Whether to shutdown the environment when the
383
433
  outage grace period is passed.
384
434
 
@@ -391,14 +441,9 @@ class BaseEnvironment(interface.Environment):
391
441
  """
392
442
  while True:
393
443
  try:
394
- sandbox = self._create_sandbox(
395
- sandbox_id=sandbox_id,
396
- reusable=self.enable_pooling
444
+ return self._bring_up_sandbox(
445
+ sandbox_id=sandbox_id, set_acquired=set_acquired
397
446
  )
398
- sandbox.start()
399
- if set_pending:
400
- sandbox.set_pending()
401
- return sandbox
402
447
  except (interface.EnvironmentError, interface.SandboxStateError) as e:
403
448
  self._report_outage_or_wait(e, shutdown_env_upon_outage)
404
449
 
@@ -435,7 +480,7 @@ class BaseEnvironment(interface.Environment):
435
480
  '[%s]: %s maintenance thread started.', self.id, self.__class__.__name__
436
481
  )
437
482
  stats_report_time = time.time()
438
- while self._alive:
483
+ while self._status not in (self.Status.SHUTTING_DOWN, self.Status.OFFLINE):
439
484
  if time.time() - stats_report_time > self.stats_report_interval:
440
485
  pg.logging.info(
441
486
  '[%s] %s stats: %s.',
@@ -444,7 +489,8 @@ class BaseEnvironment(interface.Environment):
444
489
  stats_report_time = time.time()
445
490
 
446
491
  dead_pool_indices = [
447
- i for i, s in enumerate(self._sandbox_pool) if not s.is_alive
492
+ i for i, s in enumerate(self._sandbox_pool)
493
+ if s.status == interface.Sandbox.Status.OFFLINE
448
494
  ]
449
495
  if dead_pool_indices and not self._replace_dead_sandboxes(
450
496
  dead_pool_indices
@@ -489,3 +535,17 @@ class BaseEnvironment(interface.Environment):
489
535
  ),
490
536
  )
491
537
  ])
538
+
539
+ #
540
+ # Event handlers subclasses can override.
541
+ #
542
+
543
+ def on_start(self, error: BaseException | None = None) -> None:
544
+ """Called when the environment is started."""
545
+ for handler in self.event_handlers:
546
+ handler.on_environment_start(self, error)
547
+
548
+ def on_shutdown(self, error: BaseException | None = None) -> None:
549
+ """Called when the environment is shutdown."""
550
+ for handler in self.event_handlers:
551
+ handler.on_environment_shutdown(self, error)
@@ -23,7 +23,7 @@ the `Environment` and `Sandbox` interfaces directly.
23
23
  """
24
24
 
25
25
  import functools
26
- from typing import Annotated
26
+ from typing import Annotated, Callable
27
27
 
28
28
  from langfun.env import interface
29
29
  import pyglove as pg
@@ -53,22 +53,16 @@ class BaseFeature(interface.Feature):
53
53
  NOTE: always call super()._teardown() at the end of the implementation.
54
54
  """
55
55
 
56
- def _setup_session(self, session_id: str) -> None:
56
+ def _setup_session(self) -> None:
57
57
  """Subclasses can override this for custom setup session.
58
58
 
59
- Args:
60
- session_id: The session ID.
61
-
62
59
  NOTE: always call super()._setup_session() at the beginning of the
63
60
  implementation.
64
61
  """
65
62
 
66
- def _teardown_session(self, session_id: str) -> None:
63
+ def _teardown_session(self) -> None:
67
64
  """Subclasses can override this for custom teardown session.
68
65
 
69
- Args:
70
- session_id: The session ID.
71
-
72
66
  NOTE: always call super()._teardown_session() at the end of the
73
67
  implementation.
74
68
  """
@@ -114,44 +108,37 @@ class BaseFeature(interface.Feature):
114
108
  # Setup and teardown of the feature.
115
109
  #
116
110
 
111
+ def _do(
112
+ self,
113
+ action: Callable[[], None],
114
+ event_handler: Callable[..., None],
115
+ ) -> None:
116
+ """Triggers an event handler."""
117
+ error = None
118
+ try:
119
+ action()
120
+ except BaseException as e: # pylint: disable=broad-except
121
+ error = e
122
+ raise
123
+ finally:
124
+ event_handler(error=error)
125
+
117
126
  def setup(self, sandbox: interface.Sandbox) -> None:
118
127
  """Sets up the feature."""
119
128
  self._sandbox = sandbox
120
- interface.call_with_event(
121
- action=self._setup,
122
- event_handler=self.on_setup,
123
- )
129
+ self._do(self._setup, self.on_setup)
124
130
 
125
131
  def teardown(self) -> None:
126
132
  """Tears down the feature."""
127
- # If a sandbox is down during setting up, feature.shutdown might be called
128
- # before the feature is setup. In this case, we don't need to teardown the
129
- # feature.
130
- if self._sandbox is None:
131
- return
132
-
133
- interface.call_with_event(
134
- action=self._teardown,
135
- event_handler=self.on_teardown,
136
- )
133
+ self._do(self._teardown, event_handler=self.on_teardown)
137
134
 
138
- def setup_session(self, session_id: str) -> None:
135
+ def setup_session(self) -> None:
139
136
  """Sets up the feature for a user session."""
140
- interface.call_with_event(
141
- action=self._setup_session,
142
- event_handler=self.on_session_setup,
143
- action_kwargs={'session_id': session_id},
144
- event_handler_kwargs={'session_id': session_id},
145
- )
137
+ self._do(self._setup_session, event_handler=self.on_setup_session)
146
138
 
147
- def teardown_session(self, session_id: str) -> None:
139
+ def teardown_session(self) -> None:
148
140
  """Teardowns the feature for a user session."""
149
- interface.call_with_event(
150
- action=self._teardown_session,
151
- event_handler=self.on_session_teardown,
152
- action_kwargs={'session_id': session_id},
153
- event_handler_kwargs={'session_id': session_id},
154
- )
141
+ self._do(self._teardown_session, self.on_teardown_session)
155
142
 
156
143
  #
157
144
  # Housekeeping.
@@ -159,7 +146,59 @@ class BaseFeature(interface.Feature):
159
146
 
160
147
  def housekeep(self) -> None:
161
148
  """Performs housekeeping for the feature."""
162
- interface.call_with_event(
163
- action=self._housekeep,
164
- event_handler=self.on_housekeep,
149
+ self._do(self._housekeep, self.on_housekeep)
150
+
151
+ #
152
+ # Event handlers subclasses can override.
153
+ #
154
+
155
+ def on_setup(
156
+ self,
157
+ error: BaseException | None = None
158
+ ) -> None:
159
+ """Called when the feature is setup."""
160
+ self.sandbox.on_feature_setup(self, error)
161
+
162
+ def on_teardown(
163
+ self,
164
+ error: BaseException | None = None
165
+ ) -> None:
166
+ """Called when the feature is teardown."""
167
+ self.sandbox.on_feature_teardown(self, error)
168
+
169
+ def on_housekeep(
170
+ self,
171
+ error: BaseException | None = None
172
+ ) -> None:
173
+ """Called when the feature has done housekeeping."""
174
+ self.sandbox.on_feature_housekeep(self, error)
175
+
176
+ def on_setup_session(
177
+ self,
178
+ error: BaseException | None = None,
179
+ ) -> None:
180
+ """Called when the feature is setup for a user session."""
181
+ self.sandbox.on_feature_setup_session(self, error)
182
+
183
+ def on_teardown_session(
184
+ self,
185
+ error: BaseException | None = None,
186
+ ) -> None:
187
+ """Called when the feature is teardown for a user session."""
188
+ self.sandbox.on_feature_teardown_session(self, error)
189
+
190
+ def on_session_activity(
191
+ self,
192
+ session_id: str,
193
+ name: str,
194
+ error: BaseException | None,
195
+ **kwargs
196
+ ) -> None:
197
+ """Called when a sandbox activity is performed."""
198
+ self.sandbox.on_session_activity(
199
+ session_id=session_id,
200
+ name=name,
201
+ feature=self,
202
+ error=error,
203
+ **kwargs
165
204
  )