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.
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/PKG-INFO +1 -1
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/env/__init__.py +0 -1
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/env/base_environment.py +126 -66
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/env/base_feature.py +79 -40
- langfun-0.1.2.dev202509240805/langfun/env/base_sandbox.py +964 -0
- langfun-0.1.2.dev202509240805/langfun/env/base_test.py +1604 -0
- langfun-0.1.2.dev202509240805/langfun/env/interface.py +971 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/env/load_balancers.py +4 -4
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/env/load_balancers_test.py +32 -57
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun.egg-info/PKG-INFO +1 -1
- langfun-0.1.2.dev202509220805/langfun/env/base_sandbox.py +0 -458
- langfun-0.1.2.dev202509220805/langfun/env/base_test.py +0 -795
- langfun-0.1.2.dev202509220805/langfun/env/interface.py +0 -843
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/LICENSE +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/README.md +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/bounding_box_parser.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/bounding_box_parser_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/drawing.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/drawing_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/location.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/assistant/capabilities/gui/location_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/agentic/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/agentic/action.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/agentic/action_eval.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/agentic/action_eval_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/agentic/action_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/async_support.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/async_support_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/correction.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/correction_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/execution.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/execution_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/generation.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/generation_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/parsing.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/parsing_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/sandboxing.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/coding/python/sandboxing_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/component.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/component_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/concurrent.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/concurrent_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/console.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/console_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/anthropic.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/anthropic_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/gemini.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/gemini_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/openai.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/data/conversion/openai_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/base.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/base_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/matching.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/matching_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/patching.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/patching_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/scoring.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/scoring_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/checkpointing.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/checkpointing_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/eval_test_helper.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/evaluation.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/evaluation_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/example.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/example_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/experiment.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/experiment_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/metric_values.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/metric_values_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/metrics.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/metrics_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/progress.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/progress_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/progress_tracking.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/progress_tracking_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/reporting.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/reporting_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/runners.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/eval/v2/runners_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/langfunc.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/langfunc_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/language_model.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/language_model_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/anthropic.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/anthropic_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/azure_openai.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/azure_openai_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/cache/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/cache/base.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/cache/in_memory.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/cache/in_memory_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/compositional.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/compositional_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/deepseek.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/deepseek_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/fake.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/fake_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/gemini.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/gemini_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/google_genai.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/google_genai_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/groq.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/groq_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/llama_cpp.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/llama_cpp_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/openai.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/openai_compatible.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/openai_compatible_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/openai_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/rest.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/rest_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/vertexai.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/llms/vertexai_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/logging.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/logging_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/memories/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/memories/conversation_history.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/memories/conversation_history_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/memory.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/message.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/message_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/audio.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/audio_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/image.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/image_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/mime.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/mime_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/pdf.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/pdf_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/video.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modalities/video_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modality.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/modality_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/natural_language.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/natural_language_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/sampling.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/sampling_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/completion.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/completion_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/description.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/description_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/function_generation.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/function_generation_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/mapping.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/mapping_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/parsing.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/parsing_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/querying.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/querying_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/schema.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/schema_generation.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/schema_generation_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/schema_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/scoring.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/scoring_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/tokenization.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/structured/tokenization_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/subscription.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/subscription_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/template.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/template_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/__init__.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/completion.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/completion_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/conversation.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/conversation_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/demonstration.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/demonstration_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/selfplay.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/core/templates/selfplay_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/env/interface_test.py +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun.egg-info/SOURCES.txt +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun.egg-info/dependency_links.txt +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun.egg-info/requires.txt +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun.egg-info/top_level.txt +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/setup.cfg +0 -0
- {langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/setup.py +0 -0
|
@@ -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
|
{langfun-0.1.2.dev202509220805 → langfun-0.1.2.dev202509240805}/langfun/env/base_environment.py
RENAMED
|
@@ -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
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
-
|
|
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(
|
|
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:
|
|
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[
|
|
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
|
|
234
|
-
"""Returns whether the environment is
|
|
235
|
-
return self.
|
|
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
|
|
274
|
-
|
|
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
|
-
|
|
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
|
-
|
|
283
|
-
|
|
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
|
|
326
|
+
if self._status in (
|
|
327
|
+
self.Status.SHUTTING_DOWN,
|
|
328
|
+
self.Status.OFFLINE,
|
|
329
|
+
):
|
|
292
330
|
return
|
|
293
331
|
|
|
294
|
-
self.
|
|
295
|
-
|
|
296
|
-
|
|
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
|
-
|
|
307
|
-
|
|
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) ->
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
424
|
+
set_acquired: bool = False,
|
|
375
425
|
shutdown_env_upon_outage: bool = True,
|
|
376
|
-
) ->
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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)
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
135
|
+
def setup_session(self) -> None:
|
|
139
136
|
"""Sets up the feature for a user session."""
|
|
140
|
-
|
|
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
|
|
139
|
+
def teardown_session(self) -> None:
|
|
148
140
|
"""Teardowns the feature for a user session."""
|
|
149
|
-
|
|
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
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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
|
)
|