langfun 0.1.2.dev202510290805__tar.gz → 0.1.2.dev202510310805__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 (203) hide show
  1. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/PKG-INFO +1 -1
  2. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/agentic/action.py +31 -3
  3. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/agentic/action_test.py +25 -0
  4. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/gemini.py +3 -3
  5. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/__init__.py +4 -0
  6. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/base_sandbox.py +41 -239
  7. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/base_test.py +15 -25
  8. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/interface.py +112 -4
  9. langfun-0.1.2.dev202510310805/langfun/env/interface_test.py +122 -0
  10. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/load_balancers_test.py +17 -0
  11. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/test_utils.py +6 -6
  12. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun.egg-info/PKG-INFO +1 -1
  13. langfun-0.1.2.dev202510290805/langfun/env/interface_test.py +0 -44
  14. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/LICENSE +0 -0
  15. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/README.md +0 -0
  16. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/__init__.py +0 -0
  17. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/assistant/capabilities/gui/__init__.py +0 -0
  18. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/assistant/capabilities/gui/bounding_box_parser.py +0 -0
  19. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/assistant/capabilities/gui/bounding_box_parser_test.py +0 -0
  20. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/assistant/capabilities/gui/drawing.py +0 -0
  21. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/assistant/capabilities/gui/drawing_test.py +0 -0
  22. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/assistant/capabilities/gui/location.py +0 -0
  23. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/assistant/capabilities/gui/location_test.py +0 -0
  24. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/__init__.py +0 -0
  25. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/agentic/__init__.py +0 -0
  26. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/agentic/action_eval.py +0 -0
  27. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/agentic/action_eval_test.py +0 -0
  28. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/async_support.py +0 -0
  29. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/async_support_test.py +0 -0
  30. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/coding/__init__.py +0 -0
  31. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/coding/python/__init__.py +0 -0
  32. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/coding/python/correction.py +0 -0
  33. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/coding/python/correction_test.py +0 -0
  34. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/coding/python/execution.py +0 -0
  35. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/coding/python/execution_test.py +0 -0
  36. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/coding/python/generation.py +0 -0
  37. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/coding/python/generation_test.py +0 -0
  38. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/coding/python/parsing.py +0 -0
  39. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/coding/python/parsing_test.py +0 -0
  40. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/coding/python/sandboxing.py +0 -0
  41. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/coding/python/sandboxing_test.py +0 -0
  42. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/component.py +0 -0
  43. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/component_test.py +0 -0
  44. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/concurrent.py +0 -0
  45. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/concurrent_test.py +0 -0
  46. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/console.py +0 -0
  47. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/console_test.py +0 -0
  48. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/data/__init__.py +0 -0
  49. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/data/conversion/__init__.py +0 -0
  50. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/data/conversion/anthropic.py +0 -0
  51. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/data/conversion/anthropic_test.py +0 -0
  52. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/data/conversion/gemini.py +0 -0
  53. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/data/conversion/gemini_test.py +0 -0
  54. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/data/conversion/openai.py +0 -0
  55. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/data/conversion/openai_test.py +0 -0
  56. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/__init__.py +0 -0
  57. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/base.py +0 -0
  58. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/base_test.py +0 -0
  59. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/matching.py +0 -0
  60. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/matching_test.py +0 -0
  61. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/patching.py +0 -0
  62. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/patching_test.py +0 -0
  63. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/scoring.py +0 -0
  64. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/scoring_test.py +0 -0
  65. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/__init__.py +0 -0
  66. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/checkpointing.py +0 -0
  67. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/checkpointing_test.py +0 -0
  68. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/eval_test_helper.py +0 -0
  69. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/evaluation.py +0 -0
  70. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/evaluation_test.py +0 -0
  71. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/example.py +0 -0
  72. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/example_test.py +0 -0
  73. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/experiment.py +0 -0
  74. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/experiment_test.py +0 -0
  75. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/metric_values.py +0 -0
  76. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/metric_values_test.py +0 -0
  77. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/metrics.py +0 -0
  78. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/metrics_test.py +0 -0
  79. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/progress.py +0 -0
  80. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/progress_test.py +0 -0
  81. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/progress_tracking.py +0 -0
  82. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/progress_tracking_test.py +0 -0
  83. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/reporting.py +0 -0
  84. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/reporting_test.py +0 -0
  85. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/runners.py +0 -0
  86. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/eval/v2/runners_test.py +0 -0
  87. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/langfunc.py +0 -0
  88. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/langfunc_test.py +0 -0
  89. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/language_model.py +0 -0
  90. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/language_model_test.py +0 -0
  91. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/__init__.py +0 -0
  92. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/anthropic.py +0 -0
  93. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/anthropic_test.py +0 -0
  94. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/azure_openai.py +0 -0
  95. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/azure_openai_test.py +0 -0
  96. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/cache/__init__.py +0 -0
  97. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/cache/base.py +0 -0
  98. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/cache/in_memory.py +0 -0
  99. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/cache/in_memory_test.py +0 -0
  100. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/compositional.py +0 -0
  101. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/compositional_test.py +0 -0
  102. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/deepseek.py +0 -0
  103. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/deepseek_test.py +0 -0
  104. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/fake.py +0 -0
  105. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/fake_test.py +0 -0
  106. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/gemini_test.py +0 -0
  107. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/google_genai.py +0 -0
  108. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/google_genai_test.py +0 -0
  109. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/groq.py +0 -0
  110. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/groq_test.py +0 -0
  111. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/llama_cpp.py +0 -0
  112. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/llama_cpp_test.py +0 -0
  113. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/openai.py +0 -0
  114. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/openai_compatible.py +0 -0
  115. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/openai_compatible_test.py +0 -0
  116. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/openai_test.py +0 -0
  117. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/rest.py +0 -0
  118. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/rest_test.py +0 -0
  119. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/vertexai.py +0 -0
  120. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/llms/vertexai_test.py +0 -0
  121. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/logging.py +0 -0
  122. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/logging_test.py +0 -0
  123. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/mcp/__init__.py +0 -0
  124. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/mcp/client.py +0 -0
  125. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/mcp/client_test.py +0 -0
  126. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/mcp/session.py +0 -0
  127. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/mcp/session_test.py +0 -0
  128. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/mcp/testing/simple_mcp_client.py +0 -0
  129. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/mcp/testing/simple_mcp_server.py +0 -0
  130. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/mcp/tool.py +0 -0
  131. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/mcp/tool_test.py +0 -0
  132. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/memories/__init__.py +0 -0
  133. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/memories/conversation_history.py +0 -0
  134. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/memories/conversation_history_test.py +0 -0
  135. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/memory.py +0 -0
  136. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/message.py +0 -0
  137. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/message_test.py +0 -0
  138. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/modalities/__init__.py +0 -0
  139. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/modalities/audio.py +0 -0
  140. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/modalities/audio_test.py +0 -0
  141. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/modalities/image.py +0 -0
  142. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/modalities/image_test.py +0 -0
  143. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/modalities/mime.py +0 -0
  144. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/modalities/mime_test.py +0 -0
  145. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/modalities/pdf.py +0 -0
  146. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/modalities/pdf_test.py +0 -0
  147. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/modalities/video.py +0 -0
  148. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/modalities/video_test.py +0 -0
  149. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/modality.py +0 -0
  150. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/modality_test.py +0 -0
  151. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/natural_language.py +0 -0
  152. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/natural_language_test.py +0 -0
  153. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/sampling.py +0 -0
  154. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/sampling_test.py +0 -0
  155. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/__init__.py +0 -0
  156. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/completion.py +0 -0
  157. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/completion_test.py +0 -0
  158. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/description.py +0 -0
  159. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/description_test.py +0 -0
  160. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/function_generation.py +0 -0
  161. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/function_generation_test.py +0 -0
  162. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/mapping.py +0 -0
  163. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/mapping_test.py +0 -0
  164. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/parsing.py +0 -0
  165. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/parsing_test.py +0 -0
  166. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/querying.py +0 -0
  167. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/querying_test.py +0 -0
  168. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/schema.py +0 -0
  169. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/schema_generation.py +0 -0
  170. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/schema_generation_test.py +0 -0
  171. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/schema_test.py +0 -0
  172. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/scoring.py +0 -0
  173. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/scoring_test.py +0 -0
  174. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/tokenization.py +0 -0
  175. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/structured/tokenization_test.py +0 -0
  176. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/subscription.py +0 -0
  177. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/subscription_test.py +0 -0
  178. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/template.py +0 -0
  179. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/template_test.py +0 -0
  180. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/templates/__init__.py +0 -0
  181. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/templates/completion.py +0 -0
  182. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/templates/completion_test.py +0 -0
  183. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/templates/conversation.py +0 -0
  184. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/templates/conversation_test.py +0 -0
  185. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/templates/demonstration.py +0 -0
  186. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/templates/demonstration_test.py +0 -0
  187. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/templates/selfplay.py +0 -0
  188. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/core/templates/selfplay_test.py +0 -0
  189. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/base_environment.py +0 -0
  190. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/base_feature.py +0 -0
  191. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/event_handlers/__init__.py +0 -0
  192. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/event_handlers/base.py +0 -0
  193. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/event_handlers/event_logger.py +0 -0
  194. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/event_handlers/event_logger_test.py +0 -0
  195. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/event_handlers/metric_writer.py +0 -0
  196. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/event_handlers/metric_writer_test.py +0 -0
  197. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun/env/load_balancers.py +0 -0
  198. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun.egg-info/SOURCES.txt +0 -0
  199. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun.egg-info/dependency_links.txt +0 -0
  200. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun.egg-info/requires.txt +0 -0
  201. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/langfun.egg-info/top_level.txt +0 -0
  202. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/setup.cfg +0 -0
  203. {langfun-0.1.2.dev202510290805 → langfun-0.1.2.dev202510310805}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langfun
3
- Version: 0.1.2.dev202510290805
3
+ Version: 0.1.2.dev202510310805
4
4
  Summary: Langfun: Language as Functions.
5
5
  Home-page: https://github.com/google/langfun
6
6
  Author: Langfun Authors
@@ -538,6 +538,18 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
538
538
  remove_class=['not-started'],
539
539
  )
540
540
 
541
+ def remove(self, item: TracedItem) -> None:
542
+ """Removes an item from the sequence."""
543
+ index = self.items.index(item)
544
+ if index == -1:
545
+ raise ValueError(f'Item not found in execution trace: {item!r}')
546
+
547
+ with pg.notify_on_change(False):
548
+ self.items.pop(index)
549
+
550
+ if self._tab_control is not None:
551
+ self._tab_control.remove(index)
552
+
541
553
  def extend(self, items: Iterable[TracedItem]) -> None:
542
554
  """Extends the sequence with a list of items."""
543
555
  for item in items:
@@ -1648,13 +1660,20 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
1648
1660
  @contextlib.contextmanager
1649
1661
  def track_queries(
1650
1662
  self,
1651
- phase: str | None = None
1663
+ phase: str | None = None,
1664
+ track_if: Callable[
1665
+ [lf_structured.QueryInvocation],
1666
+ bool
1667
+ ] | None = None,
1652
1668
  ) -> Iterator[list[lf_structured.QueryInvocation]]:
1653
1669
  """Tracks `lf.query` made within the context.
1654
1670
 
1655
1671
  Args:
1656
1672
  phase: The name of a new phase to track the queries in. If not provided,
1657
1673
  the queries will be tracked in the parent phase.
1674
+ track_if: A function that takes a `lf_structured.QueryInvocation` and
1675
+ returns True if the query should be included in the result. If None,
1676
+ all queries (including failed queries) will be included.
1658
1677
 
1659
1678
  Yields:
1660
1679
  A list of `lf.QueryInvocation` objects, each for a single `lf.query`
@@ -1673,6 +1692,11 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
1673
1692
  self.event_handler.on_query_start(self, self._current_action, invocation)
1674
1693
 
1675
1694
  def _query_end(invocation: lf_structured.QueryInvocation):
1695
+ if track_if is not None and not track_if(invocation):
1696
+ self._current_execution.remove(invocation)
1697
+ # Even if the query is not included in the execution trace, we still
1698
+ # count the usage summary to the current execution and trigger the
1699
+ # event handler to log the query.
1676
1700
  self._current_execution.merge_usage_summary(invocation.usage_summary)
1677
1701
  self.event_handler.on_query_end(self, self._current_action, invocation)
1678
1702
 
@@ -1705,8 +1729,9 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
1705
1729
  *,
1706
1730
  lm: lf.LanguageModel,
1707
1731
  examples: list[lf_structured.MappingExample] | None = None,
1732
+ track_if: Callable[[lf_structured.QueryInvocation], bool] | None = None,
1708
1733
  **kwargs
1709
- ) -> Any:
1734
+ ) -> Any:
1710
1735
  """Calls `lf.query` and associates it with the current invocation.
1711
1736
 
1712
1737
  The following code are equivalent:
@@ -1731,12 +1756,15 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
1731
1756
  default: The default value to return if the query fails.
1732
1757
  lm: The language model to use for the query.
1733
1758
  examples: The examples to use for the query.
1759
+ track_if: A function that takes a `lf_structured.QueryInvocation`
1760
+ and returns True if the query should be tracked.
1761
+ If None, all queries (including failed queries) will be tracked.
1734
1762
  **kwargs: Additional keyword arguments to pass to `lf.query`.
1735
1763
 
1736
1764
  Returns:
1737
1765
  The result of the query.
1738
1766
  """
1739
- with self.track_queries():
1767
+ with self.track_queries(track_if=track_if):
1740
1768
  return lf_structured.query(
1741
1769
  prompt,
1742
1770
  schema=schema,
@@ -530,6 +530,31 @@ class SessionTest(unittest.TestCase):
530
530
  self.assertIn('agent@', session.id)
531
531
  self.assertIsInstance(session.as_message(), lf.AIMessage)
532
532
 
533
+ def test_query_with_track_if(self):
534
+ lm = fake.StaticResponse('lm response')
535
+ session = action_lib.Session()
536
+
537
+ # Render session to trigger javascript updates to the HTML when
538
+ # operating on the session.
539
+ _ = session.to_html()
540
+ with session:
541
+ # This query will succeed.
542
+ session.query(
543
+ 'prompt1',
544
+ schema=None,
545
+ lm=lm,
546
+ track_if=lambda q: not q.has_error,
547
+ default=None)
548
+ # This query will fail during parsing.
549
+ session.query(
550
+ 'prompt2',
551
+ schema=int,
552
+ lm=lm,
553
+ track_if=lambda q: not q.has_error,
554
+ default=None)
555
+ self.assertEqual(len(session.root.queries), 1)
556
+ self.assertIsNone(session.root.queries[0].error)
557
+
533
558
 
534
559
  if __name__ == '__main__':
535
560
  unittest.main()
@@ -830,9 +830,9 @@ class Gemini(rest.REST):
830
830
  )
831
831
 
832
832
  def _error(self, status_code: int, content: str) -> lf.LMError:
833
- if (
834
- status_code == 400
835
- and b'exceeds the maximum number of tokens' in content
833
+ if status_code == 400 and (
834
+ b'exceeds the maximum number of tokens' in content
835
+ or b'Reduce the input token count and try again.' in content
836
836
  ):
837
837
  return lf.ContextLimitError(f'{status_code}: {content}')
838
838
  return super()._error(status_code, content)
@@ -24,6 +24,10 @@ from langfun.env.interface import Environment
24
24
  from langfun.env.interface import Sandbox
25
25
  from langfun.env.interface import Feature
26
26
 
27
+ # Decorators for sandbox/feature methods.
28
+ from langfun.env.interface import treat_as_sandbox_state_error
29
+ from langfun.env.interface import log_sandbox_activity
30
+
27
31
  from langfun.env.base_environment import BaseEnvironment
28
32
  from langfun.env.base_sandbox import BaseSandbox
29
33
  from langfun.env.base_feature import BaseFeature
@@ -26,7 +26,7 @@ import contextlib
26
26
  import functools
27
27
  import threading
28
28
  import time
29
- from typing import Annotated, Any, Callable, Iterator, Sequence, Type
29
+ from typing import Annotated, Any, Iterator
30
30
 
31
31
  from langfun.env import interface
32
32
  from langfun.env.event_handlers import base as event_handler_base
@@ -100,10 +100,9 @@ class BaseSandbox(interface.Sandbox):
100
100
  self._status = status
101
101
  self._status_start_time = time.time()
102
102
 
103
- def report_maybe_state_error(self, e: BaseException | None) -> None:
103
+ def report_state_error(self, e: interface.SandboxStateError) -> None:
104
104
  """Reports sandbox state errors."""
105
- if (isinstance(e, interface.SandboxStateError)
106
- and e not in self._state_errors):
105
+ if e not in self._state_errors:
107
106
  self._state_errors.append(e)
108
107
 
109
108
  def _setup_features(self) -> None:
@@ -141,7 +140,8 @@ class BaseSandbox(interface.Sandbox):
141
140
  try:
142
141
  feature.teardown()
143
142
  except BaseException as e: # pylint: disable=broad-except
144
- self.report_maybe_state_error(e)
143
+ if isinstance(e, interface.SandboxStateError):
144
+ self.report_state_error(e)
145
145
  errors[feature.name] = e
146
146
  if errors:
147
147
  return interface.FeatureTeardownError(sandbox=self, errors=errors)
@@ -175,7 +175,8 @@ class BaseSandbox(interface.Sandbox):
175
175
  try:
176
176
  feature.teardown_session()
177
177
  except BaseException as e: # pylint: disable=broad-except
178
- self.report_maybe_state_error(e)
178
+ if isinstance(e, interface.SandboxStateError):
179
+ self.report_state_error(e)
179
180
  feature_teardown_errors[name] = e
180
181
 
181
182
  return interface.SessionTeardownError(
@@ -277,28 +278,6 @@ class BaseSandbox(interface.Sandbox):
277
278
  """Returns the features in the sandbox."""
278
279
  return self._features
279
280
 
280
- def _enter_service_call(self) -> bool:
281
- """Enters a service call.
282
-
283
- Returns:
284
- True if the service call is at the top of the call stack.
285
- """
286
- v = getattr(self._tls_state, 'service_call_depth', None)
287
- if v is None:
288
- v = 0
289
- setattr(self._tls_state, 'service_call_depth', v + 1)
290
- return v == 0
291
-
292
- def _exit_service_call(self) -> bool:
293
- """Exits a service call.
294
-
295
- Returns:
296
- True if the service call is at the top of the call stack.
297
- """
298
- v = getattr(self._tls_state, 'service_call_depth')
299
- setattr(self._tls_state, 'service_call_depth', v - 1)
300
- return v == 1
301
-
302
281
  #
303
282
  # Sandbox start/shutdown.
304
283
  #
@@ -369,7 +348,8 @@ class BaseSandbox(interface.Sandbox):
369
348
  '[%s]: Sandbox failed to start in %.2f seconds: %s',
370
349
  self.id, duration, e
371
350
  )
372
- self.report_maybe_state_error(e)
351
+ if isinstance(e, interface.SandboxStateError):
352
+ self.report_state_error(e)
373
353
  self.on_start(duration, e)
374
354
  self.shutdown()
375
355
  raise e
@@ -442,7 +422,8 @@ class BaseSandbox(interface.Sandbox):
442
422
  shutdown_error = None
443
423
  except BaseException as e: # pylint: disable=broad-except
444
424
  shutdown_error = e
445
- self.report_maybe_state_error(e)
425
+ if isinstance(e, interface.SandboxStateError):
426
+ self.report_state_error(e)
446
427
  self._set_status(interface.Sandbox.Status.OFFLINE)
447
428
  pg.logging.error(
448
429
  '[%s]: Sandbox shutdown with error: %s',
@@ -540,7 +521,8 @@ class BaseSandbox(interface.Sandbox):
540
521
  self._set_status(self.Status.IN_SESSION)
541
522
  self.on_session_start(session_id, time.time() - self._session_start_time)
542
523
  except BaseException as e: # pylint: disable=broad-except
543
- self.report_maybe_state_error(e)
524
+ if isinstance(e, interface.SandboxStateError):
525
+ self.report_state_error(e)
544
526
  self.on_session_start(
545
527
  session_id, time.time() - self._session_start_time, e
546
528
  )
@@ -626,7 +608,8 @@ class BaseSandbox(interface.Sandbox):
626
608
  self.id,
627
609
  e
628
610
  )
629
- self.report_maybe_state_error(e)
611
+ if isinstance(e, interface.SandboxStateError):
612
+ self.report_state_error(e)
630
613
  self.shutdown()
631
614
 
632
615
  # End session before setting up the next session.
@@ -677,6 +660,30 @@ class BaseSandbox(interface.Sandbox):
677
660
  and end_session_error.has_non_sandbox_state_error):
678
661
  raise end_session_error # pylint: disable=raising-bad-type
679
662
 
663
+ @contextlib.contextmanager
664
+ def track_activity(
665
+ self,
666
+ name: str,
667
+ feature: interface.Feature | None = None,
668
+ **kwargs: Any
669
+ ) -> Iterator[None]:
670
+ """Tracks an activity for the sandbox."""
671
+ start_time = time.time()
672
+ error = None
673
+ try:
674
+ yield None
675
+ except BaseException as e: # pylint: disable=broad-except
676
+ error = e
677
+ raise
678
+ finally:
679
+ self.on_activity(
680
+ name=name,
681
+ feature=feature,
682
+ duration=time.time() - start_time,
683
+ error=error,
684
+ **kwargs
685
+ )
686
+
680
687
  #
681
688
  # Housekeeping.
682
689
  #
@@ -722,7 +729,7 @@ class BaseSandbox(interface.Sandbox):
722
729
  str(e)
723
730
  )
724
731
  self._housekeep_counter += 1
725
- self.report_maybe_state_error(e)
732
+ self.report_state_error(e)
726
733
  self.on_housekeep(time.time() - housekeep_start, e)
727
734
  self.shutdown()
728
735
  break
@@ -744,7 +751,7 @@ class BaseSandbox(interface.Sandbox):
744
751
  feature.name,
745
752
  e,
746
753
  )
747
- self.report_maybe_state_error(e)
754
+ self.report_state_error(e)
748
755
  self._housekeep_counter += 1
749
756
  self.on_housekeep(time.time() - housekeep_start, e)
750
757
  self.shutdown()
@@ -917,208 +924,3 @@ class BaseSandbox(interface.Sandbox):
917
924
  handler.on_session_end(
918
925
  self.environment, self, session_id, duration, lifetime, error
919
926
  )
920
-
921
-
922
- #
923
- # Sandbox service decorator.
924
- #
925
-
926
-
927
- def sandbox_service(
928
- critical_errors: Sequence[
929
- Type[BaseException] | tuple[Type[BaseException], str]
930
- ] | None = None
931
- ) -> Callable[..., Any]:
932
- """Decorator for Sandbox/Feature methods exposed as sandbox services.
933
-
934
- This decorator will catch errors and map to `SandboxStateError` if the
935
- error matches any of the critical errors. Consequently, the sandbox will be
936
- shutdown automatically when the error is raised.
937
-
938
- Example:
939
-
940
- ```
941
- with env:
942
- with env.sandbox() as sb:
943
- try:
944
- sb.test_feature.do_something_with_non_state_error()
945
- except ValueError:
946
- # sandbox will not be shutdown.
947
- pass
948
-
949
- try:
950
- sb.test_feature.do_something_with_state_error()
951
- except ValueError:
952
- assert sb.state == sb.Status.OFFLINE
953
- ```
954
-
955
- If the decorated method returns a context manager, a wrapper context manager
956
- will be returned, which will end the session when exiting the context.
957
-
958
- Example:
959
-
960
- ```
961
- with env:
962
- with env.test_feature.do_something_with_context_manager() as result:
963
- # sandbox will be alive during the whole context manager cycle.
964
- ```
965
-
966
- For sandbox service methods, an optional `session_id` argument can be passed
967
- to create a new session for the service call, even its signature does not
968
- contain a `session_id` argument.
969
-
970
- Args:
971
- critical_errors: A sequence of exception types or tuples of exception type
972
- and error messages (described in regular expression), when matched, treat
973
- the sandbox as in a bad state, which will trigger a shutdown.
974
-
975
- Returns:
976
- The decorator function.
977
- """
978
- critical_errors = critical_errors or []
979
-
980
- def decorator(func):
981
- signature = pg.typing.get_signature(func)
982
- if 'session_id' in signature.arg_names:
983
- raise ValueError(
984
- '`session_id` should not be used as argument for sandbox '
985
- 'service method. Please use `self.session_id` instead.'
986
- )
987
-
988
- def to_kwargs(*args, **kwargs):
989
- num_non_self_args = len(signature.arg_names) - 1
990
- if len(args) > num_non_self_args:
991
- assert signature.varargs is not None, (signature, args)
992
- kwargs[signature.varargs.name] = tuple(args[num_non_self_args:])
993
- args = args[:num_non_self_args]
994
- for i in range(len(args)):
995
- # The first argument is `self`.
996
- kwargs[signature.arg_names[i + 1]] = args[i]
997
- return kwargs
998
-
999
- @functools.wraps(func)
1000
- def method_wrapper(self, *args, **kwargs) -> Any:
1001
- """Helper function to safely execute logics in the sandbox."""
1002
-
1003
- assert isinstance(self, (BaseSandbox, interface.Feature)), self
1004
- sandbox = self.sandbox if isinstance(self, interface.Feature) else self
1005
-
1006
- # We count the service call stack depth so we could shutdown the sandbox
1007
- # at the top upon sandbox state error.
1008
- sandbox._enter_service_call() # pylint: disable=protected-access
1009
-
1010
- # When a capability is directly accessed from the environment,
1011
- # we create a new session for the capability call. This
1012
- # prevents the sandbox from being reused for other feature calls.
1013
- if sandbox.status == interface.Sandbox.Status.ACQUIRED:
1014
- new_session = True
1015
- new_session_id = kwargs.get('session_id')
1016
- if new_session_id is None:
1017
- new_session_id = sandbox.environment.new_session_id()
1018
-
1019
- # If it's a feature method called from the environment, start a new
1020
- # session for the feature call.
1021
- sandbox.start_session(new_session_id)
1022
- else:
1023
- new_session = False
1024
-
1025
- kwargs.pop('session_id', None)
1026
- result = None
1027
- error = None
1028
- start_time = time.time()
1029
-
1030
- try:
1031
- # Execute the service function.
1032
- result = func(self, *args, **kwargs)
1033
-
1034
- # If the result is a context manager, wrap it with a context manager
1035
- # to end the session when exiting.
1036
- if isinstance(result, contextlib.AbstractContextManager):
1037
- return _service_context_manager_wrapper(
1038
- service=result,
1039
- sandbox_or_feature=self,
1040
- sandbox=sandbox,
1041
- name=func.__name__,
1042
- kwargs=to_kwargs(*args, **kwargs),
1043
- start_time=start_time,
1044
- new_session=new_session
1045
- )
1046
-
1047
- # Otherwise, return the result and end the session in the finally block.
1048
- return result
1049
- except BaseException as e:
1050
- error = e
1051
- sandbox.report_maybe_state_error(e)
1052
- if pg.match_error(e, critical_errors):
1053
- state_error = interface.SandboxStateError(
1054
- 'Sandbox encountered an unexpected error executing '
1055
- f'`{func.__name__}` (args={args!r}, kwargs={kwargs!r}): {e}',
1056
- sandbox=self
1057
- )
1058
- sandbox.report_maybe_state_error(state_error)
1059
- raise state_error from e
1060
- raise
1061
- finally:
1062
- is_topmost_call = sandbox._exit_service_call() # pylint: disable=protected-access
1063
- if not isinstance(result, contextlib.AbstractContextManager):
1064
- self.on_activity(
1065
- name=func.__name__,
1066
- duration=time.time() - start_time,
1067
- error=error,
1068
- **to_kwargs(*args, **kwargs),
1069
- )
1070
- if new_session:
1071
- assert is_topmost_call
1072
-
1073
- # End the session if it's from a feature method and the result
1074
- # is not a context manager.
1075
- sandbox.end_session()
1076
-
1077
- # Shutdown the sandbox if it is at the top of the service call stack and
1078
- # has state errors.
1079
- if (is_topmost_call
1080
- and sandbox.state_errors
1081
- # Sandbox service method might be called during shutting down, in
1082
- # that case we don't want to shutdown the sandbox again.
1083
- and not sandbox.is_shutting_down):
1084
- sandbox.shutdown()
1085
-
1086
- return method_wrapper
1087
- return decorator
1088
-
1089
-
1090
- @contextlib.contextmanager
1091
- def _service_context_manager_wrapper(
1092
- service: contextlib.AbstractContextManager[Any],
1093
- sandbox_or_feature: BaseSandbox | interface.Feature,
1094
- sandbox: interface.Sandbox,
1095
- name: str,
1096
- kwargs: dict[str, Any],
1097
- new_session: bool,
1098
- start_time: float,
1099
- ) -> Iterator[Any]:
1100
- """Context manager wrapper for ending a sandbox session when exiting."""
1101
- error = None
1102
- sandbox._enter_service_call() # pylint: disable=protected-access
1103
-
1104
- try:
1105
- with service as result:
1106
- yield result
1107
- except BaseException as e:
1108
- error = e
1109
- sandbox.report_maybe_state_error(error)
1110
- raise
1111
- finally:
1112
- sandbox_or_feature.on_activity(
1113
- name=name,
1114
- error=error,
1115
- duration=time.time() - start_time,
1116
- **kwargs,
1117
- )
1118
- is_topmost_call = sandbox._exit_service_call() # pylint: disable=protected-access
1119
-
1120
- if new_session:
1121
- assert is_topmost_call
1122
- sandbox.end_session()
1123
- elif isinstance(error, interface.SandboxStateError):
1124
- sandbox.shutdown()
@@ -15,7 +15,6 @@ import time
15
15
  from typing import Any
16
16
  import unittest
17
17
 
18
- from langfun.env import base_sandbox
19
18
  from langfun.env import interface
20
19
  from langfun.env import test_utils
21
20
  from langfun.env.event_handlers import base as event_handler_base
@@ -460,10 +459,11 @@ class EnvironmentTests(unittest.TestCase):
460
459
  simulate_setup_error=interface.SandboxStateError,
461
460
  skip_notification=True
462
461
  )
463
- with env.sandbox() as sb:
464
- with self.assertRaises(interface.SandboxStateError):
462
+ with self.assertRaises(interface.SandboxStateError):
463
+ with env.sandbox() as sb:
465
464
  sb.shell('bad command', raise_error=interface.SandboxStateError)
466
465
  self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
466
+ self.assertEqual(len(sb.state_errors), 1)
467
467
  sb_offline_time = time.time()
468
468
  while time.time() - sb_offline_time < 10:
469
469
  if not env.is_online:
@@ -1250,12 +1250,11 @@ class SandboxStatusTests(unittest.TestCase):
1250
1250
  },
1251
1251
  )
1252
1252
  with env:
1253
- with env.sandbox(session_id='session1') as sb:
1254
- with self.assertRaises(interface.SandboxStateError):
1253
+ with self.assertRaises(interface.SandboxStateError):
1254
+ with env.sandbox(session_id='session1') as sb:
1255
1255
  sb.shell('echo foo', raise_error=RuntimeError)
1256
- self.assertEqual(len(sb.state_errors), 1)
1257
- self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
1258
- sb.shell('echo bar')
1256
+ self.assertEqual(len(sb.state_errors), 1)
1257
+ self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
1259
1258
  self.assertEqual(
1260
1259
  self.event_handler.logs,
1261
1260
  [
@@ -1282,7 +1281,6 @@ class SandboxStatusTests(unittest.TestCase):
1282
1281
  '[testing-env/test_image:0:0/feature1] feature teardown',
1283
1282
  '[testing-env/test_image:0:0] shutting_down -> offline',
1284
1283
  '[testing-env/test_image:0:0] sandbox shutdown',
1285
- '[testing-env/test_image:0:0] shell: echo bar',
1286
1284
  # pylint: enable=line-too-long
1287
1285
  ]
1288
1286
  )
@@ -1306,11 +1304,6 @@ class SandboxActivityTests(unittest.TestCase):
1306
1304
  r'test_feature-session-[0-9a-f]{7}'
1307
1305
  )
1308
1306
 
1309
- with self.assertRaisesRegex(ValueError, '`session_id` should not be used'):
1310
- @base_sandbox.sandbox_service()
1311
- def foo(session_id: str):
1312
- del session_id
1313
-
1314
1307
  def test_ping_error(self):
1315
1308
  env = TestingEnvironment(
1316
1309
  features={'test_feature': TestingFeature(housekeep_interval=0)},
@@ -1487,10 +1480,11 @@ class SandboxServiceTests(unittest.TestCase):
1487
1480
 
1488
1481
  def test_service_call_from_feature_with_error(self):
1489
1482
  with self.env:
1490
- with self.env.sandbox(session_id='session1') as sb:
1491
- with self.assertRaises(interface.SandboxStateError):
1483
+ with self.assertRaises(interface.SandboxStateError):
1484
+ with self.env.sandbox(session_id='session1') as sb:
1492
1485
  sb.test_feature.bad_shell_call()
1493
- self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
1486
+ self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
1487
+ self.assertEqual(len(sb.state_errors), 1)
1494
1488
 
1495
1489
  self.assertEqual(
1496
1490
  self.event_handler.logs,
@@ -1584,7 +1578,6 @@ class SandboxServiceTests(unittest.TestCase):
1584
1578
  '[testing-env/test_image:0/session1] shell: "test_feature" setup session',
1585
1579
  "[testing-env/test_image:0] session 'session1' started",
1586
1580
  '[testing-env/test_image:0/session1] shell: hello',
1587
- '[testing-env/test_image:0/session1/test_feature] test_feature.my_service: None',
1588
1581
  '[testing-env/test_image:0/session1] shell: foo',
1589
1582
  '[testing-env/test_image:0/session1] shell: "test_feature" teardown session',
1590
1583
  "[testing-env/test_image:0] session 'session1' ended",
@@ -1598,11 +1591,12 @@ class SandboxServiceTests(unittest.TestCase):
1598
1591
 
1599
1592
  def test_service_context_manager_from_feature_with_error(self):
1600
1593
  with self.env:
1601
- with self.env.sandbox(session_id='session1') as sb:
1602
- with self.assertRaises(interface.SandboxStateError):
1594
+ with self.assertRaises(interface.SandboxStateError):
1595
+ with self.env.sandbox(session_id='session1') as sb:
1603
1596
  with sb.test_feature.my_service() as service:
1604
1597
  service.do('hello', raise_error=interface.SandboxStateError)
1605
- self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
1598
+ self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
1599
+ self.assertEqual(len(sb.state_errors), 1)
1606
1600
  self.assertEqual(
1607
1601
  self.event_handler.logs,
1608
1602
  [
@@ -1614,7 +1608,6 @@ class SandboxServiceTests(unittest.TestCase):
1614
1608
  '[testing-env/test_image:0/session1] shell: "test_feature" setup session',
1615
1609
  "[testing-env/test_image:0] session 'session1' started",
1616
1610
  '[testing-env/test_image:0/session1] shell: hello with SandboxStateError',
1617
- '[testing-env/test_image:0/session1/test_feature] test_feature.my_service: None with SandboxStateError',
1618
1611
  '[testing-env/test_image:0/session1] shell: "test_feature" teardown session',
1619
1612
  "[testing-env/test_image:0] session 'session1' ended with SandboxStateError",
1620
1613
  '[testing-env/test_image:0] shell: "test_feature" teardown',
@@ -1645,7 +1638,6 @@ class SandboxServiceTests(unittest.TestCase):
1645
1638
  '[testing-env/test_image:0/session1] shell: "test_feature" setup session',
1646
1639
  "[testing-env/test_image:0] session 'session1' started",
1647
1640
  '[testing-env/test_image:0/session1] shell: foo',
1648
- '[testing-env/test_image:0/session1/test_feature] test_feature.my_service: None',
1649
1641
  '[testing-env/test_image:0/session1] shell: "test_feature" teardown session',
1650
1642
  "[testing-env/test_image:0] session 'session1' ended",
1651
1643
  '[testing-env/test_image:0] shell: "test_feature" teardown',
@@ -1657,7 +1649,6 @@ class SandboxServiceTests(unittest.TestCase):
1657
1649
  '[testing-env/test_image:1/test_feature-session-2291d8c] shell: "test_feature" setup session',
1658
1650
  "[testing-env/test_image:1] session 'test_feature-session-2291d8c' started",
1659
1651
  '[testing-env/test_image:1/test_feature-session-2291d8c] shell: bar',
1660
- '[testing-env/test_image:1/test_feature-session-2291d8c/test_feature] test_feature.my_service: None',
1661
1652
  '[testing-env/test_image:1/test_feature-session-2291d8c] shell: "test_feature" teardown session',
1662
1653
  "[testing-env/test_image:1] session 'test_feature-session-2291d8c' ended",
1663
1654
  '[testing-env/test_image:1] shell: "test_feature" teardown',
@@ -1685,7 +1676,6 @@ class SandboxServiceTests(unittest.TestCase):
1685
1676
  '[testing-env/test_image:0/test_feature-session-2291d8c] shell: "test_feature" setup session',
1686
1677
  "[testing-env/test_image:0] session 'test_feature-session-2291d8c' started",
1687
1678
  '[testing-env/test_image:0/test_feature-session-2291d8c] shell: hello with SandboxStateError',
1688
- '[testing-env/test_image:0/test_feature-session-2291d8c/test_feature] test_feature.my_service: None with SandboxStateError',
1689
1679
  '[testing-env/test_image:0/test_feature-session-2291d8c] shell: "test_feature" teardown session',
1690
1680
  "[testing-env/test_image:0] session 'test_feature-session-2291d8c' ended with SandboxStateError",
1691
1681
  '[testing-env/test_image:0] shell: "test_feature" teardown',