langfun 0.1.2.dev202510150805__tar.gz → 0.1.2.dev202510170805__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.dev202510150805 → langfun-0.1.2.dev202510170805}/PKG-INFO +3 -1
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/__init__.py +5 -1
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/agentic/__init__.py +4 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/agentic/action.py +278 -89
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/agentic/action_test.py +33 -5
- langfun-0.1.2.dev202510170805/langfun/core/async_support.py +98 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/async_support_test.py +23 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/concurrent_test.py +8 -2
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/progress_tracking_test.py +3 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/querying.py +12 -12
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/querying_test.py +4 -4
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun.egg-info/PKG-INFO +3 -1
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun.egg-info/requires.txt +2 -0
- langfun-0.1.2.dev202510150805/langfun/core/async_support.py +0 -28
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/LICENSE +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/README.md +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/assistant/capabilities/gui/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/assistant/capabilities/gui/bounding_box_parser.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/assistant/capabilities/gui/bounding_box_parser_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/assistant/capabilities/gui/drawing.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/assistant/capabilities/gui/drawing_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/assistant/capabilities/gui/location.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/assistant/capabilities/gui/location_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/agentic/action_eval.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/agentic/action_eval_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/coding/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/coding/python/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/coding/python/correction.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/coding/python/correction_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/coding/python/execution.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/coding/python/execution_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/coding/python/generation.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/coding/python/generation_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/coding/python/parsing.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/coding/python/parsing_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/coding/python/sandboxing.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/coding/python/sandboxing_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/component.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/component_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/concurrent.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/console.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/console_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/data/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/data/conversion/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/data/conversion/anthropic.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/data/conversion/anthropic_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/data/conversion/gemini.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/data/conversion/gemini_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/data/conversion/openai.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/data/conversion/openai_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/base.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/base_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/matching.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/matching_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/patching.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/patching_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/scoring.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/scoring_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/checkpointing.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/checkpointing_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/eval_test_helper.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/evaluation.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/evaluation_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/example.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/example_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/experiment.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/experiment_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/metric_values.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/metric_values_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/metrics.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/metrics_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/progress.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/progress_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/progress_tracking.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/reporting.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/reporting_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/runners.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/eval/v2/runners_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/langfunc.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/langfunc_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/language_model.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/language_model_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/anthropic.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/anthropic_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/azure_openai.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/azure_openai_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/cache/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/cache/base.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/cache/in_memory.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/cache/in_memory_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/compositional.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/compositional_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/deepseek.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/deepseek_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/fake.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/fake_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/gemini.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/gemini_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/google_genai.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/google_genai_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/groq.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/groq_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/llama_cpp.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/llama_cpp_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/openai.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/openai_compatible.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/openai_compatible_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/openai_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/rest.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/rest_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/vertexai.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/llms/vertexai_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/logging.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/logging_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/memories/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/memories/conversation_history.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/memories/conversation_history_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/memory.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/message.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/message_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/modalities/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/modalities/audio.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/modalities/audio_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/modalities/image.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/modalities/image_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/modalities/mime.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/modalities/mime_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/modalities/pdf.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/modalities/pdf_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/modalities/video.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/modalities/video_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/modality.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/modality_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/natural_language.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/natural_language_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/sampling.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/sampling_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/completion.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/completion_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/description.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/description_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/function_generation.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/function_generation_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/mapping.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/mapping_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/parsing.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/parsing_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/schema.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/schema_generation.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/schema_generation_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/schema_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/scoring.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/scoring_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/tokenization.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/structured/tokenization_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/subscription.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/subscription_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/template.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/template_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/templates/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/templates/completion.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/templates/completion_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/templates/conversation.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/templates/conversation_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/templates/demonstration.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/templates/demonstration_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/templates/selfplay.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/templates/selfplay_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/base_environment.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/base_feature.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/base_sandbox.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/base_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/event_handlers/__init__.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/event_handlers/base.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/event_handlers/event_logger.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/event_handlers/event_logger_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/event_handlers/metric_writer.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/event_handlers/metric_writer_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/interface.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/interface_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/load_balancers.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/load_balancers_test.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/env/test_utils.py +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun.egg-info/SOURCES.txt +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun.egg-info/dependency_links.txt +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun.egg-info/top_level.txt +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/setup.cfg +0 -0
- {langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langfun
|
|
3
|
-
Version: 0.1.2.
|
|
3
|
+
Version: 0.1.2.dev202510170805
|
|
4
4
|
Summary: Langfun: Language as Functions.
|
|
5
5
|
Home-page: https://github.com/google/langfun
|
|
6
6
|
Author: Langfun Authors
|
|
@@ -21,11 +21,13 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
21
21
|
Classifier: Topic :: Software Development :: Libraries
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
|
+
Requires-Dist: anyio>=4.7.0
|
|
24
25
|
Requires-Dist: jinja2>=3.1.2
|
|
25
26
|
Requires-Dist: puremagic>=1.20
|
|
26
27
|
Requires-Dist: pyglove>=0.4.5.dev202507140812
|
|
27
28
|
Requires-Dist: requests>=2.31.0
|
|
28
29
|
Provides-Extra: all
|
|
30
|
+
Requires-Dist: anyio>=4.7.0; extra == "all"
|
|
29
31
|
Requires-Dist: jinja2>=3.1.2; extra == "all"
|
|
30
32
|
Requires-Dist: puremagic>=1.20; extra == "all"
|
|
31
33
|
Requires-Dist: pyglove>=0.4.5.dev202507140812; extra == "all"
|
|
@@ -40,9 +40,13 @@ from langfun.core.component import context
|
|
|
40
40
|
as_context = context
|
|
41
41
|
use_context = context
|
|
42
42
|
|
|
43
|
-
#
|
|
43
|
+
# Support for async IO.
|
|
44
44
|
from langfun.core.async_support import invoke_async
|
|
45
45
|
|
|
46
|
+
# Adaptors for async function/context manager to sync versions.
|
|
47
|
+
from langfun.core.async_support import invoke_sync
|
|
48
|
+
from langfun.core.async_support import sync_context_manager
|
|
49
|
+
|
|
46
50
|
# Shortcut function for overriding components attributes, usually for
|
|
47
51
|
# override settings.
|
|
48
52
|
from langfun.core.component import use_settings
|
{langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/agentic/__init__.py
RENAMED
|
@@ -26,6 +26,10 @@ from langfun.core.agentic.action import ExecutionTrace
|
|
|
26
26
|
from langfun.core.agentic.action import ParallelExecutions
|
|
27
27
|
from langfun.core.agentic.action import Session
|
|
28
28
|
|
|
29
|
+
from langfun.core.agentic.action import SessionEventHandler
|
|
30
|
+
from langfun.core.agentic.action import SessionEventHandlerChain
|
|
31
|
+
from langfun.core.agentic.action import SessionLogging
|
|
32
|
+
|
|
29
33
|
from langfun.core.agentic.action_eval import ActionEval
|
|
30
34
|
from langfun.core.agentic.action_eval import ActionEvalV1
|
|
31
35
|
|
{langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/agentic/action.py
RENAMED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
import abc
|
|
17
17
|
import contextlib
|
|
18
|
+
import dataclasses
|
|
18
19
|
import functools
|
|
19
20
|
import threading
|
|
20
21
|
import time
|
|
@@ -1161,26 +1162,271 @@ class RootAction(Action):
|
|
|
1161
1162
|
raise NotImplementedError('Shall not be called.')
|
|
1162
1163
|
|
|
1163
1164
|
|
|
1165
|
+
class SessionEventHandler:
|
|
1166
|
+
"""Interface for handling session events."""
|
|
1167
|
+
|
|
1168
|
+
def on_session_start(
|
|
1169
|
+
self,
|
|
1170
|
+
session: 'Session'
|
|
1171
|
+
) -> None:
|
|
1172
|
+
"""Called when a session starts."""
|
|
1173
|
+
|
|
1174
|
+
def on_session_end(
|
|
1175
|
+
self,
|
|
1176
|
+
session: 'Session'
|
|
1177
|
+
) -> None:
|
|
1178
|
+
"""Called when a session ends."""
|
|
1179
|
+
|
|
1180
|
+
def on_action_start(
|
|
1181
|
+
self,
|
|
1182
|
+
session: 'Session',
|
|
1183
|
+
action: ActionInvocation
|
|
1184
|
+
) -> None:
|
|
1185
|
+
"""Called when an action starts."""
|
|
1186
|
+
|
|
1187
|
+
def on_action_end(
|
|
1188
|
+
self,
|
|
1189
|
+
session: 'Session',
|
|
1190
|
+
action: ActionInvocation
|
|
1191
|
+
) -> None:
|
|
1192
|
+
"""Called when an action ends."""
|
|
1193
|
+
|
|
1194
|
+
def on_action_progress(
|
|
1195
|
+
self,
|
|
1196
|
+
session: 'Session',
|
|
1197
|
+
action: ActionInvocation,
|
|
1198
|
+
title: str,
|
|
1199
|
+
**kwargs
|
|
1200
|
+
) -> None:
|
|
1201
|
+
"""Called when an action progress is updated."""
|
|
1202
|
+
|
|
1203
|
+
def on_query_start(
|
|
1204
|
+
self,
|
|
1205
|
+
session: 'Session',
|
|
1206
|
+
action: ActionInvocation,
|
|
1207
|
+
query: lf_structured.QueryInvocation,
|
|
1208
|
+
) -> None:
|
|
1209
|
+
"""Called when a query starts."""
|
|
1210
|
+
|
|
1211
|
+
def on_query_end(
|
|
1212
|
+
self,
|
|
1213
|
+
session: 'Session',
|
|
1214
|
+
action: ActionInvocation,
|
|
1215
|
+
query: lf_structured.QueryInvocation,
|
|
1216
|
+
) -> None:
|
|
1217
|
+
"""Called when a query ends."""
|
|
1218
|
+
|
|
1219
|
+
|
|
1220
|
+
@dataclasses.dataclass
|
|
1221
|
+
class SessionEventHandlerChain(SessionEventHandler):
|
|
1222
|
+
"""A session event handler that chains multiple event handlers."""
|
|
1223
|
+
|
|
1224
|
+
handlers: list[SessionEventHandler]
|
|
1225
|
+
|
|
1226
|
+
def on_session_start(self, session: 'Session') -> None:
|
|
1227
|
+
"""Called when a session starts."""
|
|
1228
|
+
for handler in self.handlers:
|
|
1229
|
+
handler.on_session_start(session)
|
|
1230
|
+
|
|
1231
|
+
def on_session_end(self, session: 'Session') -> None:
|
|
1232
|
+
"""Called when a session ends."""
|
|
1233
|
+
for handler in self.handlers:
|
|
1234
|
+
handler.on_session_end(session)
|
|
1235
|
+
|
|
1236
|
+
def on_action_start(
|
|
1237
|
+
self,
|
|
1238
|
+
session: 'Session',
|
|
1239
|
+
action: ActionInvocation) -> None:
|
|
1240
|
+
"""Called when an action starts."""
|
|
1241
|
+
for handler in self.handlers:
|
|
1242
|
+
handler.on_action_start(session, action)
|
|
1243
|
+
|
|
1244
|
+
def on_action_end(
|
|
1245
|
+
self,
|
|
1246
|
+
session: 'Session',
|
|
1247
|
+
action: ActionInvocation) -> None:
|
|
1248
|
+
"""Called when an action ends."""
|
|
1249
|
+
for handler in self.handlers:
|
|
1250
|
+
handler.on_action_end(session, action)
|
|
1251
|
+
|
|
1252
|
+
def on_action_progress(
|
|
1253
|
+
self,
|
|
1254
|
+
session: 'Session',
|
|
1255
|
+
action: ActionInvocation,
|
|
1256
|
+
title: str,
|
|
1257
|
+
**kwargs
|
|
1258
|
+
) -> None:
|
|
1259
|
+
"""Called when an action progress is updated."""
|
|
1260
|
+
for handler in self.handlers:
|
|
1261
|
+
handler.on_action_progress(session, action, title, **kwargs)
|
|
1262
|
+
|
|
1263
|
+
def on_query_start(
|
|
1264
|
+
self,
|
|
1265
|
+
session: 'Session',
|
|
1266
|
+
action: ActionInvocation,
|
|
1267
|
+
query: lf_structured.QueryInvocation,
|
|
1268
|
+
) -> None:
|
|
1269
|
+
"""Called when a query starts."""
|
|
1270
|
+
for handler in self.handlers:
|
|
1271
|
+
handler.on_query_start(session, action, query)
|
|
1272
|
+
|
|
1273
|
+
def on_query_end(
|
|
1274
|
+
self,
|
|
1275
|
+
session: 'Session',
|
|
1276
|
+
action: ActionInvocation,
|
|
1277
|
+
query: lf_structured.QueryInvocation,
|
|
1278
|
+
) -> None:
|
|
1279
|
+
"""Called when a query ends."""
|
|
1280
|
+
for handler in self.handlers:
|
|
1281
|
+
handler.on_query_end(session, action, query)
|
|
1282
|
+
|
|
1283
|
+
|
|
1284
|
+
@dataclasses.dataclass
|
|
1285
|
+
class SessionLogging(SessionEventHandler):
|
|
1286
|
+
"""An event handler that logs Session events."""
|
|
1287
|
+
|
|
1288
|
+
verbose: bool = False
|
|
1289
|
+
|
|
1290
|
+
def on_session_end(self, session: 'Session'):
|
|
1291
|
+
if session.has_error:
|
|
1292
|
+
session.error(
|
|
1293
|
+
f'Trajectory failed in {session.elapse:.2f} seconds.',
|
|
1294
|
+
error=session.final_error,
|
|
1295
|
+
metadata=session.root.metadata,
|
|
1296
|
+
keep=True,
|
|
1297
|
+
)
|
|
1298
|
+
elif self.verbose:
|
|
1299
|
+
session.info(
|
|
1300
|
+
f'Trajectory succeeded in {session.elapse:.2f} seconds.',
|
|
1301
|
+
result=session.final_result,
|
|
1302
|
+
metadata=session.root.metadata,
|
|
1303
|
+
keep=False,
|
|
1304
|
+
)
|
|
1305
|
+
|
|
1306
|
+
def on_action_start(
|
|
1307
|
+
self,
|
|
1308
|
+
session: 'Session',
|
|
1309
|
+
action: ActionInvocation
|
|
1310
|
+
) -> None:
|
|
1311
|
+
if self.verbose:
|
|
1312
|
+
session.info(
|
|
1313
|
+
'Action execution started.',
|
|
1314
|
+
action=action.action,
|
|
1315
|
+
keep=False,
|
|
1316
|
+
)
|
|
1317
|
+
|
|
1318
|
+
def on_action_end(
|
|
1319
|
+
self,
|
|
1320
|
+
session: 'Session',
|
|
1321
|
+
action: ActionInvocation
|
|
1322
|
+
) -> None:
|
|
1323
|
+
if action.has_error:
|
|
1324
|
+
session.warning(
|
|
1325
|
+
(
|
|
1326
|
+
f'Action execution failed in '
|
|
1327
|
+
f'{action.execution.elapse:.2f} seconds.'
|
|
1328
|
+
),
|
|
1329
|
+
action=action.action,
|
|
1330
|
+
error=action.error,
|
|
1331
|
+
keep=True,
|
|
1332
|
+
)
|
|
1333
|
+
elif self.verbose:
|
|
1334
|
+
session.info(
|
|
1335
|
+
(
|
|
1336
|
+
f'Action execution succeeded in '
|
|
1337
|
+
f'{action.execution.elapse:.2f} seconds.'
|
|
1338
|
+
),
|
|
1339
|
+
action=action.action,
|
|
1340
|
+
result=action.result,
|
|
1341
|
+
keep=False,
|
|
1342
|
+
)
|
|
1343
|
+
|
|
1344
|
+
def on_query_start(
|
|
1345
|
+
self,
|
|
1346
|
+
session: 'Session',
|
|
1347
|
+
action: ActionInvocation,
|
|
1348
|
+
query: lf_structured.QueryInvocation,
|
|
1349
|
+
) -> None:
|
|
1350
|
+
if self.verbose:
|
|
1351
|
+
session.info(
|
|
1352
|
+
'Querying LLM started.',
|
|
1353
|
+
lm=query.lm.model_id,
|
|
1354
|
+
output_type=(
|
|
1355
|
+
lf_structured.annotation(query.schema.spec)
|
|
1356
|
+
if query.schema is not None else None
|
|
1357
|
+
),
|
|
1358
|
+
keep=False,
|
|
1359
|
+
)
|
|
1360
|
+
|
|
1361
|
+
def on_query_end(
|
|
1362
|
+
self,
|
|
1363
|
+
session: 'Session',
|
|
1364
|
+
action: ActionInvocation,
|
|
1365
|
+
query: lf_structured.QueryInvocation,
|
|
1366
|
+
) -> None:
|
|
1367
|
+
if query.has_error:
|
|
1368
|
+
session.warning(
|
|
1369
|
+
(
|
|
1370
|
+
f'Querying LLM failed in '
|
|
1371
|
+
f'{time.time() - query.start_time:.2f} seconds.'
|
|
1372
|
+
),
|
|
1373
|
+
lm=query.lm.model_id,
|
|
1374
|
+
output_type=(
|
|
1375
|
+
lf_structured.annotation(query.schema.spec)
|
|
1376
|
+
if query.schema is not None else None
|
|
1377
|
+
),
|
|
1378
|
+
error=query.error,
|
|
1379
|
+
keep=True,
|
|
1380
|
+
)
|
|
1381
|
+
elif self.verbose:
|
|
1382
|
+
session.info(
|
|
1383
|
+
(
|
|
1384
|
+
f'Querying LLM succeeded in '
|
|
1385
|
+
f'{time.time() - query.start_time:.2f} seconds.'
|
|
1386
|
+
),
|
|
1387
|
+
lm=query.lm.model_id,
|
|
1388
|
+
output_type=(
|
|
1389
|
+
lf_structured.annotation(query.schema.spec)
|
|
1390
|
+
if query.schema is not None else None
|
|
1391
|
+
),
|
|
1392
|
+
keep=False,
|
|
1393
|
+
)
|
|
1394
|
+
|
|
1395
|
+
|
|
1164
1396
|
class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
1165
1397
|
"""Session for performing an agentic task."""
|
|
1166
1398
|
|
|
1167
1399
|
root: Annotated[
|
|
1168
1400
|
ActionInvocation,
|
|
1169
1401
|
'The root action invocation of the session.'
|
|
1170
|
-
]
|
|
1402
|
+
]
|
|
1171
1403
|
|
|
1172
1404
|
id: Annotated[
|
|
1173
1405
|
str | None,
|
|
1174
|
-
'An optional identifier for the
|
|
1175
|
-
]
|
|
1406
|
+
'An optional identifier for the session, which will be used for logging.'
|
|
1407
|
+
]
|
|
1176
1408
|
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1409
|
+
event_handler: Annotated[
|
|
1410
|
+
SessionEventHandler,
|
|
1411
|
+
'Event handler for the session.'
|
|
1412
|
+
]
|
|
1413
|
+
|
|
1414
|
+
@pg.explicit_method_override
|
|
1415
|
+
def __init__(
|
|
1416
|
+
self,
|
|
1417
|
+
id: str | None = None, # pylint: disable=redefined-builtin
|
|
1418
|
+
*,
|
|
1419
|
+
verbose: bool = False,
|
|
1420
|
+
event_handler: SessionEventHandler | None = None,
|
|
1421
|
+
root: ActionInvocation | None = None,
|
|
1422
|
+
**kwargs
|
|
1423
|
+
):
|
|
1424
|
+
super().__init__(
|
|
1425
|
+
id=id,
|
|
1426
|
+
root=root or ActionInvocation(RootAction()),
|
|
1427
|
+
event_handler=event_handler or SessionLogging(verbose=verbose),
|
|
1428
|
+
**kwargs
|
|
1429
|
+
)
|
|
1184
1430
|
|
|
1185
1431
|
#
|
|
1186
1432
|
# Shortcut methods for accessing the root action invocation.
|
|
@@ -1271,6 +1517,7 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
|
1271
1517
|
def start(self) -> None:
|
|
1272
1518
|
"""Starts the session."""
|
|
1273
1519
|
self.root.execution.start()
|
|
1520
|
+
self.event_handler.on_session_start(self)
|
|
1274
1521
|
|
|
1275
1522
|
def end(
|
|
1276
1523
|
self,
|
|
@@ -1279,21 +1526,8 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
|
1279
1526
|
metadata: dict[str, Any] | None = None,
|
|
1280
1527
|
) -> None:
|
|
1281
1528
|
"""Ends the session."""
|
|
1282
|
-
if error is not None:
|
|
1283
|
-
self.error(
|
|
1284
|
-
f'Trajectory failed in {self.elapse:.2f} seconds.',
|
|
1285
|
-
error=error,
|
|
1286
|
-
metadata=metadata,
|
|
1287
|
-
keep=True,
|
|
1288
|
-
)
|
|
1289
|
-
elif self.verbose:
|
|
1290
|
-
self.info(
|
|
1291
|
-
f'Trajectory succeeded in {self.elapse:.2f} seconds.',
|
|
1292
|
-
result=result,
|
|
1293
|
-
metadata=metadata,
|
|
1294
|
-
keep=False,
|
|
1295
|
-
)
|
|
1296
1529
|
self.root.end(result, error, metadata)
|
|
1530
|
+
self.event_handler.on_session_end(self)
|
|
1297
1531
|
|
|
1298
1532
|
def check_execution_time(self) -> None:
|
|
1299
1533
|
"""Checks the execution time of the current action."""
|
|
@@ -1312,6 +1546,20 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
|
1312
1546
|
'seconds.'
|
|
1313
1547
|
)
|
|
1314
1548
|
|
|
1549
|
+
def update_progress(self, title: str, **kwargs: Any) -> None:
|
|
1550
|
+
"""Update the progress of current action's execution.
|
|
1551
|
+
|
|
1552
|
+
Args:
|
|
1553
|
+
title: The title of the progress update.
|
|
1554
|
+
**kwargs: Additional keyword arguments to pass to the event handler.
|
|
1555
|
+
"""
|
|
1556
|
+
self.event_handler.on_action_progress(
|
|
1557
|
+
self,
|
|
1558
|
+
self._current_action,
|
|
1559
|
+
title,
|
|
1560
|
+
**kwargs
|
|
1561
|
+
)
|
|
1562
|
+
|
|
1315
1563
|
def __enter__(self):
|
|
1316
1564
|
"""Enters the session."""
|
|
1317
1565
|
self.start()
|
|
@@ -1371,34 +1619,10 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
|
1371
1619
|
self._current_execution = invocation.execution
|
|
1372
1620
|
# Start the execution of the current action.
|
|
1373
1621
|
self._current_action.start()
|
|
1374
|
-
|
|
1375
|
-
self.info(
|
|
1376
|
-
'Action execution started.',
|
|
1377
|
-
action=invocation.action,
|
|
1378
|
-
keep=False,
|
|
1379
|
-
)
|
|
1622
|
+
self.event_handler.on_action_start(self, self._current_action)
|
|
1380
1623
|
yield invocation
|
|
1381
1624
|
finally:
|
|
1382
|
-
|
|
1383
|
-
self.warning(
|
|
1384
|
-
(
|
|
1385
|
-
f'Action execution failed in '
|
|
1386
|
-
f'{invocation.execution.elapse:.2f} seconds.'
|
|
1387
|
-
),
|
|
1388
|
-
action=invocation.action,
|
|
1389
|
-
error=invocation.error,
|
|
1390
|
-
keep=True,
|
|
1391
|
-
)
|
|
1392
|
-
elif self.verbose:
|
|
1393
|
-
self.info(
|
|
1394
|
-
(
|
|
1395
|
-
f'Action execution succeeded in '
|
|
1396
|
-
f'{invocation.execution.elapse:.2f} seconds.'
|
|
1397
|
-
),
|
|
1398
|
-
action=invocation.action,
|
|
1399
|
-
result=invocation.result,
|
|
1400
|
-
keep=False,
|
|
1401
|
-
)
|
|
1625
|
+
self.event_handler.on_action_end(self, self._current_action)
|
|
1402
1626
|
self._current_execution = parent_execution
|
|
1403
1627
|
self._current_action = parent_action
|
|
1404
1628
|
|
|
@@ -1446,51 +1670,16 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
|
1446
1670
|
skip_notification=False, raise_on_no_change=False
|
|
1447
1671
|
)
|
|
1448
1672
|
execution.append(invocation)
|
|
1449
|
-
|
|
1450
|
-
self.info(
|
|
1451
|
-
'Querying LLM started.',
|
|
1452
|
-
lm=invocation.lm.model_id,
|
|
1453
|
-
output_type=(
|
|
1454
|
-
lf_structured.annotation(invocation.schema.spec)
|
|
1455
|
-
if invocation.schema is not None else None
|
|
1456
|
-
),
|
|
1457
|
-
keep=False,
|
|
1458
|
-
)
|
|
1673
|
+
self.event_handler.on_query_start(self, self._current_action, invocation)
|
|
1459
1674
|
|
|
1460
1675
|
def _query_end(invocation: lf_structured.QueryInvocation):
|
|
1461
1676
|
self._current_execution.merge_usage_summary(invocation.usage_summary)
|
|
1462
|
-
|
|
1463
|
-
self.warning(
|
|
1464
|
-
(
|
|
1465
|
-
f'Querying LLM failed in '
|
|
1466
|
-
f'{time.time() - invocation.start_time:.2f} seconds.'
|
|
1467
|
-
),
|
|
1468
|
-
lm=invocation.lm.model_id,
|
|
1469
|
-
output_type=(
|
|
1470
|
-
lf_structured.annotation(invocation.schema.spec)
|
|
1471
|
-
if invocation.schema is not None else None
|
|
1472
|
-
),
|
|
1473
|
-
error=invocation.error,
|
|
1474
|
-
keep=True,
|
|
1475
|
-
)
|
|
1476
|
-
elif self.verbose:
|
|
1477
|
-
self.info(
|
|
1478
|
-
(
|
|
1479
|
-
f'Querying LLM succeeded in '
|
|
1480
|
-
f'{time.time() - invocation.start_time:.2f} seconds.'
|
|
1481
|
-
),
|
|
1482
|
-
lm=invocation.lm.model_id,
|
|
1483
|
-
output_type=(
|
|
1484
|
-
lf_structured.annotation(invocation.schema.spec)
|
|
1485
|
-
if invocation.schema is not None else None
|
|
1486
|
-
),
|
|
1487
|
-
keep=False,
|
|
1488
|
-
)
|
|
1677
|
+
self.event_handler.on_query_end(self, self._current_action, invocation)
|
|
1489
1678
|
|
|
1490
1679
|
with self.track_phase(phase), lf_structured.track_queries(
|
|
1491
1680
|
include_child_scopes=False,
|
|
1492
|
-
|
|
1493
|
-
|
|
1681
|
+
start_callback=_query_start,
|
|
1682
|
+
end_callback=_query_end,
|
|
1494
1683
|
) as queries:
|
|
1495
1684
|
try:
|
|
1496
1685
|
yield queries
|
{langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/agentic/action_test.py
RENAMED
|
@@ -34,6 +34,7 @@ class Bar(action_lib.Action):
|
|
|
34
34
|
time.sleep(self.simulate_execution_time)
|
|
35
35
|
session.query('bar', lm=lm)
|
|
36
36
|
session.add_metadata(note='bar')
|
|
37
|
+
session.update_progress('Query completed')
|
|
37
38
|
if self.simulate_action_error:
|
|
38
39
|
raise ValueError('Bar error')
|
|
39
40
|
return 2 + pg.contextual_value('baz', 0)
|
|
@@ -128,7 +129,7 @@ class SessionTest(unittest.TestCase):
|
|
|
128
129
|
self.assertIsNone(foo.result)
|
|
129
130
|
self.assertIsNone(foo.metadata)
|
|
130
131
|
|
|
131
|
-
session = action_lib.Session(id='agent@1')
|
|
132
|
+
session = action_lib.Session(id='agent@1', verbose=True)
|
|
132
133
|
self.assertEqual(session.id, 'agent@1')
|
|
133
134
|
self.assertFalse(session.has_started)
|
|
134
135
|
self.assertFalse(session.has_stopped)
|
|
@@ -137,7 +138,7 @@ class SessionTest(unittest.TestCase):
|
|
|
137
138
|
_ = session.to_html()
|
|
138
139
|
|
|
139
140
|
with session:
|
|
140
|
-
result = foo(session, lm=lm
|
|
141
|
+
result = foo(session, lm=lm)
|
|
141
142
|
|
|
142
143
|
self.assertTrue(session.has_started)
|
|
143
144
|
self.assertTrue(session.has_stopped)
|
|
@@ -375,7 +376,7 @@ class SessionTest(unittest.TestCase):
|
|
|
375
376
|
self.assertFalse(session.has_stopped)
|
|
376
377
|
|
|
377
378
|
session.start()
|
|
378
|
-
result = foo(session, lm=lm
|
|
379
|
+
result = foo(session, lm=lm)
|
|
379
380
|
session.end(result)
|
|
380
381
|
|
|
381
382
|
self.assertTrue(session.has_started)
|
|
@@ -395,7 +396,7 @@ class SessionTest(unittest.TestCase):
|
|
|
395
396
|
session = action_lib.Session(id='agent@1')
|
|
396
397
|
with self.assertRaisesRegex(ValueError, 'Bar error'):
|
|
397
398
|
with session:
|
|
398
|
-
foo(session, lm=lm
|
|
399
|
+
foo(session, lm=lm)
|
|
399
400
|
self.assertTrue(session.has_started)
|
|
400
401
|
self.assertTrue(session.has_stopped)
|
|
401
402
|
self.assertTrue(session.has_error)
|
|
@@ -408,7 +409,7 @@ class SessionTest(unittest.TestCase):
|
|
|
408
409
|
foo = Foo(1, simulate_action_error=True)
|
|
409
410
|
session = action_lib.Session(id='agent@1')
|
|
410
411
|
with self.assertRaisesRegex(ValueError, 'Please call `Session.start'):
|
|
411
|
-
foo(session, lm=lm
|
|
412
|
+
foo(session, lm=lm)
|
|
412
413
|
|
|
413
414
|
def test_succeed_with_multiple_actions(self):
|
|
414
415
|
lm = fake.StaticResponse('lm response')
|
|
@@ -489,6 +490,33 @@ class SessionTest(unittest.TestCase):
|
|
|
489
490
|
):
|
|
490
491
|
foo(lm=lm, max_execution_time=1.0)
|
|
491
492
|
|
|
493
|
+
def test_event_handler(self):
|
|
494
|
+
|
|
495
|
+
class MyActionHandler(pg.Object, action_lib.SessionEventHandler):
|
|
496
|
+
def _on_bound(self):
|
|
497
|
+
super()._on_bound()
|
|
498
|
+
self.progresses = []
|
|
499
|
+
|
|
500
|
+
def on_action_progress(self, session, action, title, **kwargs):
|
|
501
|
+
self.progresses.append((action.id, title))
|
|
502
|
+
|
|
503
|
+
handler = MyActionHandler()
|
|
504
|
+
session = action_lib.Session(
|
|
505
|
+
id='agent@1',
|
|
506
|
+
event_handler=action_lib.SessionEventHandlerChain(
|
|
507
|
+
handlers=[handler, action_lib.SessionLogging()]
|
|
508
|
+
)
|
|
509
|
+
)
|
|
510
|
+
bar = Bar()
|
|
511
|
+
with session:
|
|
512
|
+
bar(session, lm=fake.StaticResponse('lm response'))
|
|
513
|
+
session.update_progress('Trajectory completed')
|
|
514
|
+
|
|
515
|
+
self.assertEqual(handler.progresses, [
|
|
516
|
+
('agent@1:/a1', 'Query completed'),
|
|
517
|
+
('agent@1:', 'Trajectory completed'),
|
|
518
|
+
])
|
|
519
|
+
|
|
492
520
|
def test_log(self):
|
|
493
521
|
session = action_lib.Session()
|
|
494
522
|
session.debug('hi', x=1, y=2)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Copyright 2025 The Langfun Authors
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
"""Utility for async IO in Langfun."""
|
|
15
|
+
|
|
16
|
+
import asyncio
|
|
17
|
+
import contextlib
|
|
18
|
+
from typing import Any, Awaitable, Callable, Iterator
|
|
19
|
+
import anyio
|
|
20
|
+
import pyglove as pg
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
async def invoke_async(
|
|
24
|
+
sync_callable: Callable[..., Any], *args, **kwargs
|
|
25
|
+
) -> Any:
|
|
26
|
+
"""Invokes a callable asynchronously with `lf.context` manager enabled."""
|
|
27
|
+
return await asyncio.to_thread(
|
|
28
|
+
# Enable `lf.context` manager for async calls.
|
|
29
|
+
pg.with_contextual_override(sync_callable), *args, **kwargs
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def invoke_sync(
|
|
34
|
+
async_callable: Callable[..., Awaitable[Any]],
|
|
35
|
+
*args,
|
|
36
|
+
**kwargs
|
|
37
|
+
) -> Any:
|
|
38
|
+
"""Invokes a async callable synchronously."""
|
|
39
|
+
async def _invoke():
|
|
40
|
+
return await async_callable(*args, **kwargs)
|
|
41
|
+
invoke_fn = pg.with_contextual_override(_invoke)
|
|
42
|
+
blocking_portal = pg.utils.thread_local_get('__blocking_portal__', None)
|
|
43
|
+
if blocking_portal is None:
|
|
44
|
+
return anyio.run(invoke_fn)
|
|
45
|
+
return blocking_portal.call(invoke_fn)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@contextlib.contextmanager
|
|
49
|
+
def sync_context_manager(
|
|
50
|
+
async_context_manager: contextlib.AbstractAsyncContextManager[Any]
|
|
51
|
+
) -> Iterator[Any]:
|
|
52
|
+
"""Adapts an async context manager to a sync context manager.
|
|
53
|
+
|
|
54
|
+
sync_context_manager installs a blocking portal in current thread to run the
|
|
55
|
+
async context manager in a blocking way. It's useful for running async code in
|
|
56
|
+
sync context managers, e.g. `sync_context_manager` can be nested and share the
|
|
57
|
+
same event loop.
|
|
58
|
+
|
|
59
|
+
Example:
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
@contextlib.asynccontextmanager
|
|
63
|
+
async def foo(x):
|
|
64
|
+
try:
|
|
65
|
+
yield x
|
|
66
|
+
finally:
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
with lf.sync_context_manager(foo(x)) as x
|
|
70
|
+
with lf.sync_context_manager(foo(y)) as y:
|
|
71
|
+
...
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
async_context_manager: The async context manager to adapt.
|
|
76
|
+
|
|
77
|
+
Yields:
|
|
78
|
+
The value yielded by the async context manager.
|
|
79
|
+
"""
|
|
80
|
+
blocking_portal = pg.utils.thread_local_get('__blocking_portal__', None)
|
|
81
|
+
portal_exit_stack = None
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
if blocking_portal is None:
|
|
85
|
+
portal_exit_stack = contextlib.ExitStack()
|
|
86
|
+
blocking_portal = portal_exit_stack.enter_context(
|
|
87
|
+
anyio.from_thread.start_blocking_portal()
|
|
88
|
+
)
|
|
89
|
+
pg.utils.thread_local_set('__blocking_portal__', blocking_portal)
|
|
90
|
+
context_manager = blocking_portal.wrap_async_context_manager(
|
|
91
|
+
async_context_manager
|
|
92
|
+
)
|
|
93
|
+
with context_manager as value:
|
|
94
|
+
yield value
|
|
95
|
+
finally:
|
|
96
|
+
if portal_exit_stack is not None:
|
|
97
|
+
portal_exit_stack.close()
|
|
98
|
+
pg.utils.thread_local_del('__blocking_portal__')
|
{langfun-0.1.2.dev202510150805 → langfun-0.1.2.dev202510170805}/langfun/core/async_support_test.py
RENAMED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
import asyncio
|
|
16
|
+
import contextlib
|
|
16
17
|
import time
|
|
17
18
|
import unittest
|
|
18
19
|
|
|
@@ -34,6 +35,28 @@ class AsyncSupportTest(unittest.TestCase):
|
|
|
34
35
|
with pg.contextual_override(z=3):
|
|
35
36
|
self.assertEqual(asyncio.run(r), 6)
|
|
36
37
|
|
|
38
|
+
def test_invoke_sync(self):
|
|
39
|
+
@contextlib.asynccontextmanager
|
|
40
|
+
async def bar(x):
|
|
41
|
+
try:
|
|
42
|
+
yield x
|
|
43
|
+
finally:
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
async def foo(x, *, y):
|
|
47
|
+
time.sleep(2)
|
|
48
|
+
return x + y + pg.contextual_value('z', 0)
|
|
49
|
+
|
|
50
|
+
with pg.contextual_override(z=3):
|
|
51
|
+
with async_support.sync_context_manager(bar(1)) as x:
|
|
52
|
+
self.assertEqual(x, 1)
|
|
53
|
+
with async_support.sync_context_manager(bar(2)) as y:
|
|
54
|
+
self.assertEqual(y, 2)
|
|
55
|
+
self.assertEqual(async_support.invoke_sync(foo, 1, y=2), 6)
|
|
56
|
+
|
|
57
|
+
with pg.contextual_override(z=2):
|
|
58
|
+
self.assertEqual(async_support.invoke_sync(foo, 1, y=2), 5)
|
|
59
|
+
|
|
37
60
|
|
|
38
61
|
if __name__ == '__main__':
|
|
39
62
|
unittest.main()
|