ag2 0.10.2__py3-none-any.whl
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.
- ag2-0.10.2.dist-info/METADATA +819 -0
- ag2-0.10.2.dist-info/RECORD +423 -0
- ag2-0.10.2.dist-info/WHEEL +4 -0
- ag2-0.10.2.dist-info/licenses/LICENSE +201 -0
- ag2-0.10.2.dist-info/licenses/NOTICE.md +19 -0
- autogen/__init__.py +88 -0
- autogen/_website/__init__.py +3 -0
- autogen/_website/generate_api_references.py +426 -0
- autogen/_website/generate_mkdocs.py +1216 -0
- autogen/_website/notebook_processor.py +475 -0
- autogen/_website/process_notebooks.py +656 -0
- autogen/_website/utils.py +413 -0
- autogen/a2a/__init__.py +36 -0
- autogen/a2a/agent_executor.py +86 -0
- autogen/a2a/client.py +357 -0
- autogen/a2a/errors.py +18 -0
- autogen/a2a/httpx_client_factory.py +79 -0
- autogen/a2a/server.py +221 -0
- autogen/a2a/utils.py +207 -0
- autogen/agentchat/__init__.py +47 -0
- autogen/agentchat/agent.py +180 -0
- autogen/agentchat/assistant_agent.py +86 -0
- autogen/agentchat/chat.py +325 -0
- autogen/agentchat/contrib/__init__.py +5 -0
- autogen/agentchat/contrib/agent_eval/README.md +7 -0
- autogen/agentchat/contrib/agent_eval/agent_eval.py +108 -0
- autogen/agentchat/contrib/agent_eval/criterion.py +43 -0
- autogen/agentchat/contrib/agent_eval/critic_agent.py +44 -0
- autogen/agentchat/contrib/agent_eval/quantifier_agent.py +39 -0
- autogen/agentchat/contrib/agent_eval/subcritic_agent.py +45 -0
- autogen/agentchat/contrib/agent_eval/task.py +42 -0
- autogen/agentchat/contrib/agent_optimizer.py +432 -0
- autogen/agentchat/contrib/capabilities/__init__.py +5 -0
- autogen/agentchat/contrib/capabilities/agent_capability.py +20 -0
- autogen/agentchat/contrib/capabilities/generate_images.py +301 -0
- autogen/agentchat/contrib/capabilities/teachability.py +393 -0
- autogen/agentchat/contrib/capabilities/text_compressors.py +66 -0
- autogen/agentchat/contrib/capabilities/tools_capability.py +22 -0
- autogen/agentchat/contrib/capabilities/transform_messages.py +93 -0
- autogen/agentchat/contrib/capabilities/transforms.py +578 -0
- autogen/agentchat/contrib/capabilities/transforms_util.py +122 -0
- autogen/agentchat/contrib/capabilities/vision_capability.py +215 -0
- autogen/agentchat/contrib/captainagent/__init__.py +9 -0
- autogen/agentchat/contrib/captainagent/agent_builder.py +790 -0
- autogen/agentchat/contrib/captainagent/captainagent.py +514 -0
- autogen/agentchat/contrib/captainagent/tool_retriever.py +334 -0
- autogen/agentchat/contrib/captainagent/tools/README.md +44 -0
- autogen/agentchat/contrib/captainagent/tools/__init__.py +5 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_correlation.py +40 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_skewness_and_kurtosis.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_iqr.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_zscore.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/explore_csv.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/shapiro_wilk_test.py +30 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_download.py +27 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_search.py +53 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_image.py +53 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_text.py +38 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_wikipedia_text.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_youtube_caption.py +34 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/image_qa.py +60 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/optical_character_recognition.py +61 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/perform_web_search.py +47 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/scrape_wikipedia_tables.py +33 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/transcribe_audio_file.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/youtube_download.py +35 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_circle_area_from_diameter.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_day_of_the_week.py +18 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_fraction_sum.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_matrix_power.py +31 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_reflected_point.py +16 -0
- autogen/agentchat/contrib/captainagent/tools/math/complex_numbers_product.py +25 -0
- autogen/agentchat/contrib/captainagent/tools/math/compute_currency_conversion.py +23 -0
- autogen/agentchat/contrib/captainagent/tools/math/count_distinct_permutations.py +27 -0
- autogen/agentchat/contrib/captainagent/tools/math/evaluate_expression.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/math/find_continuity_point.py +34 -0
- autogen/agentchat/contrib/captainagent/tools/math/fraction_to_mixed_numbers.py +39 -0
- autogen/agentchat/contrib/captainagent/tools/math/modular_inverse_sum.py +23 -0
- autogen/agentchat/contrib/captainagent/tools/math/simplify_mixed_numbers.py +36 -0
- autogen/agentchat/contrib/captainagent/tools/math/sum_of_digit_factorials.py +15 -0
- autogen/agentchat/contrib/captainagent/tools/math/sum_of_primes_below.py +15 -0
- autogen/agentchat/contrib/captainagent/tools/requirements.txt +10 -0
- autogen/agentchat/contrib/captainagent/tools/tool_description.tsv +34 -0
- autogen/agentchat/contrib/gpt_assistant_agent.py +526 -0
- autogen/agentchat/contrib/graph_rag/__init__.py +9 -0
- autogen/agentchat/contrib/graph_rag/document.py +29 -0
- autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +167 -0
- autogen/agentchat/contrib/graph_rag/falkor_graph_rag_capability.py +103 -0
- autogen/agentchat/contrib/graph_rag/graph_query_engine.py +53 -0
- autogen/agentchat/contrib/graph_rag/graph_rag_capability.py +63 -0
- autogen/agentchat/contrib/graph_rag/neo4j_graph_query_engine.py +263 -0
- autogen/agentchat/contrib/graph_rag/neo4j_graph_rag_capability.py +83 -0
- autogen/agentchat/contrib/graph_rag/neo4j_native_graph_query_engine.py +210 -0
- autogen/agentchat/contrib/graph_rag/neo4j_native_graph_rag_capability.py +93 -0
- autogen/agentchat/contrib/img_utils.py +397 -0
- autogen/agentchat/contrib/llamaindex_conversable_agent.py +117 -0
- autogen/agentchat/contrib/llava_agent.py +189 -0
- autogen/agentchat/contrib/math_user_proxy_agent.py +464 -0
- autogen/agentchat/contrib/multimodal_conversable_agent.py +125 -0
- autogen/agentchat/contrib/qdrant_retrieve_user_proxy_agent.py +325 -0
- autogen/agentchat/contrib/rag/__init__.py +10 -0
- autogen/agentchat/contrib/rag/chromadb_query_engine.py +268 -0
- autogen/agentchat/contrib/rag/llamaindex_query_engine.py +195 -0
- autogen/agentchat/contrib/rag/mongodb_query_engine.py +319 -0
- autogen/agentchat/contrib/rag/query_engine.py +76 -0
- autogen/agentchat/contrib/retrieve_assistant_agent.py +59 -0
- autogen/agentchat/contrib/retrieve_user_proxy_agent.py +704 -0
- autogen/agentchat/contrib/society_of_mind_agent.py +200 -0
- autogen/agentchat/contrib/swarm_agent.py +1404 -0
- autogen/agentchat/contrib/text_analyzer_agent.py +79 -0
- autogen/agentchat/contrib/vectordb/__init__.py +5 -0
- autogen/agentchat/contrib/vectordb/base.py +224 -0
- autogen/agentchat/contrib/vectordb/chromadb.py +316 -0
- autogen/agentchat/contrib/vectordb/couchbase.py +405 -0
- autogen/agentchat/contrib/vectordb/mongodb.py +551 -0
- autogen/agentchat/contrib/vectordb/pgvectordb.py +927 -0
- autogen/agentchat/contrib/vectordb/qdrant.py +320 -0
- autogen/agentchat/contrib/vectordb/utils.py +126 -0
- autogen/agentchat/contrib/web_surfer.py +304 -0
- autogen/agentchat/conversable_agent.py +4307 -0
- autogen/agentchat/group/__init__.py +67 -0
- autogen/agentchat/group/available_condition.py +91 -0
- autogen/agentchat/group/context_condition.py +77 -0
- autogen/agentchat/group/context_expression.py +238 -0
- autogen/agentchat/group/context_str.py +39 -0
- autogen/agentchat/group/context_variables.py +182 -0
- autogen/agentchat/group/events/transition_events.py +111 -0
- autogen/agentchat/group/group_tool_executor.py +324 -0
- autogen/agentchat/group/group_utils.py +659 -0
- autogen/agentchat/group/guardrails.py +179 -0
- autogen/agentchat/group/handoffs.py +303 -0
- autogen/agentchat/group/llm_condition.py +93 -0
- autogen/agentchat/group/multi_agent_chat.py +291 -0
- autogen/agentchat/group/on_condition.py +55 -0
- autogen/agentchat/group/on_context_condition.py +51 -0
- autogen/agentchat/group/patterns/__init__.py +18 -0
- autogen/agentchat/group/patterns/auto.py +160 -0
- autogen/agentchat/group/patterns/manual.py +177 -0
- autogen/agentchat/group/patterns/pattern.py +295 -0
- autogen/agentchat/group/patterns/random.py +106 -0
- autogen/agentchat/group/patterns/round_robin.py +117 -0
- autogen/agentchat/group/reply_result.py +24 -0
- autogen/agentchat/group/safeguards/__init__.py +21 -0
- autogen/agentchat/group/safeguards/api.py +241 -0
- autogen/agentchat/group/safeguards/enforcer.py +1158 -0
- autogen/agentchat/group/safeguards/events.py +140 -0
- autogen/agentchat/group/safeguards/validator.py +435 -0
- autogen/agentchat/group/speaker_selection_result.py +41 -0
- autogen/agentchat/group/targets/__init__.py +4 -0
- autogen/agentchat/group/targets/function_target.py +245 -0
- autogen/agentchat/group/targets/group_chat_target.py +133 -0
- autogen/agentchat/group/targets/group_manager_target.py +151 -0
- autogen/agentchat/group/targets/transition_target.py +424 -0
- autogen/agentchat/group/targets/transition_utils.py +6 -0
- autogen/agentchat/groupchat.py +1832 -0
- autogen/agentchat/realtime/__init__.py +3 -0
- autogen/agentchat/realtime/experimental/__init__.py +20 -0
- autogen/agentchat/realtime/experimental/audio_adapters/__init__.py +8 -0
- autogen/agentchat/realtime/experimental/audio_adapters/twilio_audio_adapter.py +148 -0
- autogen/agentchat/realtime/experimental/audio_adapters/websocket_audio_adapter.py +139 -0
- autogen/agentchat/realtime/experimental/audio_observer.py +42 -0
- autogen/agentchat/realtime/experimental/clients/__init__.py +15 -0
- autogen/agentchat/realtime/experimental/clients/gemini/__init__.py +7 -0
- autogen/agentchat/realtime/experimental/clients/gemini/client.py +274 -0
- autogen/agentchat/realtime/experimental/clients/oai/__init__.py +8 -0
- autogen/agentchat/realtime/experimental/clients/oai/base_client.py +220 -0
- autogen/agentchat/realtime/experimental/clients/oai/rtc_client.py +243 -0
- autogen/agentchat/realtime/experimental/clients/oai/utils.py +48 -0
- autogen/agentchat/realtime/experimental/clients/realtime_client.py +191 -0
- autogen/agentchat/realtime/experimental/function_observer.py +84 -0
- autogen/agentchat/realtime/experimental/realtime_agent.py +158 -0
- autogen/agentchat/realtime/experimental/realtime_events.py +42 -0
- autogen/agentchat/realtime/experimental/realtime_observer.py +100 -0
- autogen/agentchat/realtime/experimental/realtime_swarm.py +533 -0
- autogen/agentchat/realtime/experimental/websockets.py +21 -0
- autogen/agentchat/realtime_agent/__init__.py +21 -0
- autogen/agentchat/user_proxy_agent.py +114 -0
- autogen/agentchat/utils.py +206 -0
- autogen/agents/__init__.py +3 -0
- autogen/agents/contrib/__init__.py +10 -0
- autogen/agents/contrib/time/__init__.py +8 -0
- autogen/agents/contrib/time/time_reply_agent.py +74 -0
- autogen/agents/contrib/time/time_tool_agent.py +52 -0
- autogen/agents/experimental/__init__.py +27 -0
- autogen/agents/experimental/deep_research/__init__.py +7 -0
- autogen/agents/experimental/deep_research/deep_research.py +52 -0
- autogen/agents/experimental/discord/__init__.py +7 -0
- autogen/agents/experimental/discord/discord.py +66 -0
- autogen/agents/experimental/document_agent/__init__.py +19 -0
- autogen/agents/experimental/document_agent/chroma_query_engine.py +301 -0
- autogen/agents/experimental/document_agent/docling_doc_ingest_agent.py +113 -0
- autogen/agents/experimental/document_agent/document_agent.py +643 -0
- autogen/agents/experimental/document_agent/document_conditions.py +50 -0
- autogen/agents/experimental/document_agent/document_utils.py +376 -0
- autogen/agents/experimental/document_agent/inmemory_query_engine.py +214 -0
- autogen/agents/experimental/document_agent/parser_utils.py +134 -0
- autogen/agents/experimental/document_agent/url_utils.py +417 -0
- autogen/agents/experimental/reasoning/__init__.py +7 -0
- autogen/agents/experimental/reasoning/reasoning_agent.py +1178 -0
- autogen/agents/experimental/slack/__init__.py +7 -0
- autogen/agents/experimental/slack/slack.py +73 -0
- autogen/agents/experimental/telegram/__init__.py +7 -0
- autogen/agents/experimental/telegram/telegram.py +76 -0
- autogen/agents/experimental/websurfer/__init__.py +7 -0
- autogen/agents/experimental/websurfer/websurfer.py +70 -0
- autogen/agents/experimental/wikipedia/__init__.py +7 -0
- autogen/agents/experimental/wikipedia/wikipedia.py +88 -0
- autogen/browser_utils.py +309 -0
- autogen/cache/__init__.py +10 -0
- autogen/cache/abstract_cache_base.py +71 -0
- autogen/cache/cache.py +203 -0
- autogen/cache/cache_factory.py +88 -0
- autogen/cache/cosmos_db_cache.py +144 -0
- autogen/cache/disk_cache.py +97 -0
- autogen/cache/in_memory_cache.py +54 -0
- autogen/cache/redis_cache.py +119 -0
- autogen/code_utils.py +598 -0
- autogen/coding/__init__.py +30 -0
- autogen/coding/base.py +120 -0
- autogen/coding/docker_commandline_code_executor.py +283 -0
- autogen/coding/factory.py +56 -0
- autogen/coding/func_with_reqs.py +203 -0
- autogen/coding/jupyter/__init__.py +23 -0
- autogen/coding/jupyter/base.py +36 -0
- autogen/coding/jupyter/docker_jupyter_server.py +160 -0
- autogen/coding/jupyter/embedded_ipython_code_executor.py +182 -0
- autogen/coding/jupyter/import_utils.py +82 -0
- autogen/coding/jupyter/jupyter_client.py +224 -0
- autogen/coding/jupyter/jupyter_code_executor.py +154 -0
- autogen/coding/jupyter/local_jupyter_server.py +164 -0
- autogen/coding/local_commandline_code_executor.py +341 -0
- autogen/coding/markdown_code_extractor.py +44 -0
- autogen/coding/utils.py +55 -0
- autogen/coding/yepcode_code_executor.py +197 -0
- autogen/doc_utils.py +35 -0
- autogen/environments/__init__.py +10 -0
- autogen/environments/docker_python_environment.py +365 -0
- autogen/environments/python_environment.py +125 -0
- autogen/environments/system_python_environment.py +85 -0
- autogen/environments/venv_python_environment.py +220 -0
- autogen/environments/working_directory.py +74 -0
- autogen/events/__init__.py +7 -0
- autogen/events/agent_events.py +1016 -0
- autogen/events/base_event.py +100 -0
- autogen/events/client_events.py +168 -0
- autogen/events/helpers.py +44 -0
- autogen/events/print_event.py +45 -0
- autogen/exception_utils.py +73 -0
- autogen/extensions/__init__.py +5 -0
- autogen/fast_depends/__init__.py +16 -0
- autogen/fast_depends/_compat.py +75 -0
- autogen/fast_depends/core/__init__.py +14 -0
- autogen/fast_depends/core/build.py +206 -0
- autogen/fast_depends/core/model.py +527 -0
- autogen/fast_depends/dependencies/__init__.py +15 -0
- autogen/fast_depends/dependencies/model.py +30 -0
- autogen/fast_depends/dependencies/provider.py +40 -0
- autogen/fast_depends/library/__init__.py +10 -0
- autogen/fast_depends/library/model.py +46 -0
- autogen/fast_depends/py.typed +6 -0
- autogen/fast_depends/schema.py +66 -0
- autogen/fast_depends/use.py +272 -0
- autogen/fast_depends/utils.py +177 -0
- autogen/formatting_utils.py +83 -0
- autogen/function_utils.py +13 -0
- autogen/graph_utils.py +173 -0
- autogen/import_utils.py +539 -0
- autogen/interop/__init__.py +22 -0
- autogen/interop/crewai/__init__.py +7 -0
- autogen/interop/crewai/crewai.py +88 -0
- autogen/interop/interoperability.py +71 -0
- autogen/interop/interoperable.py +46 -0
- autogen/interop/langchain/__init__.py +8 -0
- autogen/interop/langchain/langchain_chat_model_factory.py +156 -0
- autogen/interop/langchain/langchain_tool.py +78 -0
- autogen/interop/litellm/__init__.py +7 -0
- autogen/interop/litellm/litellm_config_factory.py +178 -0
- autogen/interop/pydantic_ai/__init__.py +7 -0
- autogen/interop/pydantic_ai/pydantic_ai.py +172 -0
- autogen/interop/registry.py +70 -0
- autogen/io/__init__.py +15 -0
- autogen/io/base.py +151 -0
- autogen/io/console.py +56 -0
- autogen/io/processors/__init__.py +12 -0
- autogen/io/processors/base.py +21 -0
- autogen/io/processors/console_event_processor.py +61 -0
- autogen/io/run_response.py +294 -0
- autogen/io/thread_io_stream.py +63 -0
- autogen/io/websockets.py +214 -0
- autogen/json_utils.py +42 -0
- autogen/llm_clients/MIGRATION_TO_V2.md +782 -0
- autogen/llm_clients/__init__.py +77 -0
- autogen/llm_clients/client_v2.py +122 -0
- autogen/llm_clients/models/__init__.py +55 -0
- autogen/llm_clients/models/content_blocks.py +389 -0
- autogen/llm_clients/models/unified_message.py +145 -0
- autogen/llm_clients/models/unified_response.py +83 -0
- autogen/llm_clients/openai_completions_client.py +444 -0
- autogen/llm_config/__init__.py +11 -0
- autogen/llm_config/client.py +59 -0
- autogen/llm_config/config.py +461 -0
- autogen/llm_config/entry.py +169 -0
- autogen/llm_config/types.py +37 -0
- autogen/llm_config/utils.py +223 -0
- autogen/logger/__init__.py +11 -0
- autogen/logger/base_logger.py +129 -0
- autogen/logger/file_logger.py +262 -0
- autogen/logger/logger_factory.py +42 -0
- autogen/logger/logger_utils.py +57 -0
- autogen/logger/sqlite_logger.py +524 -0
- autogen/math_utils.py +338 -0
- autogen/mcp/__init__.py +7 -0
- autogen/mcp/__main__.py +78 -0
- autogen/mcp/helpers.py +45 -0
- autogen/mcp/mcp_client.py +349 -0
- autogen/mcp/mcp_proxy/__init__.py +19 -0
- autogen/mcp/mcp_proxy/fastapi_code_generator_helpers.py +62 -0
- autogen/mcp/mcp_proxy/mcp_proxy.py +577 -0
- autogen/mcp/mcp_proxy/operation_grouping.py +166 -0
- autogen/mcp/mcp_proxy/operation_renaming.py +110 -0
- autogen/mcp/mcp_proxy/patch_fastapi_code_generator.py +98 -0
- autogen/mcp/mcp_proxy/security.py +399 -0
- autogen/mcp/mcp_proxy/security_schema_visitor.py +37 -0
- autogen/messages/__init__.py +7 -0
- autogen/messages/agent_messages.py +946 -0
- autogen/messages/base_message.py +108 -0
- autogen/messages/client_messages.py +172 -0
- autogen/messages/print_message.py +48 -0
- autogen/oai/__init__.py +61 -0
- autogen/oai/anthropic.py +1516 -0
- autogen/oai/bedrock.py +800 -0
- autogen/oai/cerebras.py +302 -0
- autogen/oai/client.py +1658 -0
- autogen/oai/client_utils.py +196 -0
- autogen/oai/cohere.py +494 -0
- autogen/oai/gemini.py +1045 -0
- autogen/oai/gemini_types.py +156 -0
- autogen/oai/groq.py +319 -0
- autogen/oai/mistral.py +311 -0
- autogen/oai/oai_models/__init__.py +23 -0
- autogen/oai/oai_models/_models.py +16 -0
- autogen/oai/oai_models/chat_completion.py +86 -0
- autogen/oai/oai_models/chat_completion_audio.py +32 -0
- autogen/oai/oai_models/chat_completion_message.py +97 -0
- autogen/oai/oai_models/chat_completion_message_tool_call.py +60 -0
- autogen/oai/oai_models/chat_completion_token_logprob.py +62 -0
- autogen/oai/oai_models/completion_usage.py +59 -0
- autogen/oai/ollama.py +657 -0
- autogen/oai/openai_responses.py +451 -0
- autogen/oai/openai_utils.py +897 -0
- autogen/oai/together.py +387 -0
- autogen/remote/__init__.py +18 -0
- autogen/remote/agent.py +199 -0
- autogen/remote/agent_service.py +197 -0
- autogen/remote/errors.py +17 -0
- autogen/remote/httpx_client_factory.py +131 -0
- autogen/remote/protocol.py +37 -0
- autogen/remote/retry.py +102 -0
- autogen/remote/runtime.py +96 -0
- autogen/retrieve_utils.py +490 -0
- autogen/runtime_logging.py +161 -0
- autogen/testing/__init__.py +12 -0
- autogen/testing/messages.py +45 -0
- autogen/testing/test_agent.py +111 -0
- autogen/token_count_utils.py +280 -0
- autogen/tools/__init__.py +20 -0
- autogen/tools/contrib/__init__.py +9 -0
- autogen/tools/contrib/time/__init__.py +7 -0
- autogen/tools/contrib/time/time.py +40 -0
- autogen/tools/dependency_injection.py +249 -0
- autogen/tools/experimental/__init__.py +54 -0
- autogen/tools/experimental/browser_use/__init__.py +7 -0
- autogen/tools/experimental/browser_use/browser_use.py +154 -0
- autogen/tools/experimental/code_execution/__init__.py +7 -0
- autogen/tools/experimental/code_execution/python_code_execution.py +86 -0
- autogen/tools/experimental/crawl4ai/__init__.py +7 -0
- autogen/tools/experimental/crawl4ai/crawl4ai.py +150 -0
- autogen/tools/experimental/deep_research/__init__.py +7 -0
- autogen/tools/experimental/deep_research/deep_research.py +329 -0
- autogen/tools/experimental/duckduckgo/__init__.py +7 -0
- autogen/tools/experimental/duckduckgo/duckduckgo_search.py +103 -0
- autogen/tools/experimental/firecrawl/__init__.py +7 -0
- autogen/tools/experimental/firecrawl/firecrawl_tool.py +836 -0
- autogen/tools/experimental/google/__init__.py +14 -0
- autogen/tools/experimental/google/authentication/__init__.py +11 -0
- autogen/tools/experimental/google/authentication/credentials_hosted_provider.py +43 -0
- autogen/tools/experimental/google/authentication/credentials_local_provider.py +91 -0
- autogen/tools/experimental/google/authentication/credentials_provider.py +35 -0
- autogen/tools/experimental/google/drive/__init__.py +9 -0
- autogen/tools/experimental/google/drive/drive_functions.py +124 -0
- autogen/tools/experimental/google/drive/toolkit.py +88 -0
- autogen/tools/experimental/google/model.py +17 -0
- autogen/tools/experimental/google/toolkit_protocol.py +19 -0
- autogen/tools/experimental/google_search/__init__.py +8 -0
- autogen/tools/experimental/google_search/google_search.py +93 -0
- autogen/tools/experimental/google_search/youtube_search.py +181 -0
- autogen/tools/experimental/messageplatform/__init__.py +17 -0
- autogen/tools/experimental/messageplatform/discord/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/discord/discord.py +284 -0
- autogen/tools/experimental/messageplatform/slack/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/slack/slack.py +385 -0
- autogen/tools/experimental/messageplatform/telegram/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/telegram/telegram.py +271 -0
- autogen/tools/experimental/perplexity/__init__.py +7 -0
- autogen/tools/experimental/perplexity/perplexity_search.py +249 -0
- autogen/tools/experimental/reliable/__init__.py +10 -0
- autogen/tools/experimental/reliable/reliable.py +1311 -0
- autogen/tools/experimental/searxng/__init__.py +7 -0
- autogen/tools/experimental/searxng/searxng_search.py +142 -0
- autogen/tools/experimental/tavily/__init__.py +7 -0
- autogen/tools/experimental/tavily/tavily_search.py +176 -0
- autogen/tools/experimental/web_search_preview/__init__.py +7 -0
- autogen/tools/experimental/web_search_preview/web_search_preview.py +120 -0
- autogen/tools/experimental/wikipedia/__init__.py +7 -0
- autogen/tools/experimental/wikipedia/wikipedia.py +284 -0
- autogen/tools/function_utils.py +412 -0
- autogen/tools/tool.py +188 -0
- autogen/tools/toolkit.py +86 -0
- autogen/types.py +29 -0
- autogen/version.py +7 -0
- templates/client_template/main.jinja2 +72 -0
- templates/config_template/config.jinja2 +7 -0
- templates/main.jinja2 +61 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
import enum
|
|
6
|
+
import warnings
|
|
7
|
+
from typing import Any, Optional, TypeVar, Union, get_args, get_origin
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel as BaseModel
|
|
10
|
+
from pydantic import ConfigDict, Field, alias_generators
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _remove_extra_fields(model: Any, response: dict[str, object]) -> None:
|
|
14
|
+
"""Removes extra fields from the response that are not in the model.
|
|
15
|
+
|
|
16
|
+
Mutates the response in place.
|
|
17
|
+
"""
|
|
18
|
+
key_values = list(response.items())
|
|
19
|
+
|
|
20
|
+
for key, value in key_values:
|
|
21
|
+
# Need to convert to snake case to match model fields names
|
|
22
|
+
# ex: UsageMetadata
|
|
23
|
+
alias_map = {field_info.alias: key for key, field_info in model.model_fields.items()}
|
|
24
|
+
|
|
25
|
+
if key not in model.model_fields and key not in alias_map:
|
|
26
|
+
response.pop(key)
|
|
27
|
+
continue
|
|
28
|
+
|
|
29
|
+
key = alias_map.get(key, key)
|
|
30
|
+
|
|
31
|
+
annotation = model.model_fields[key].annotation
|
|
32
|
+
|
|
33
|
+
# Get the BaseModel if Optional
|
|
34
|
+
if get_origin(annotation) is Union:
|
|
35
|
+
annotation = get_args(annotation)[0]
|
|
36
|
+
|
|
37
|
+
# if dict, assume BaseModel but also check that field type is not dict
|
|
38
|
+
# example: FunctionCall.args
|
|
39
|
+
if isinstance(value, dict) and get_origin(annotation) is not dict:
|
|
40
|
+
_remove_extra_fields(annotation, value)
|
|
41
|
+
elif isinstance(value, list):
|
|
42
|
+
for item in value:
|
|
43
|
+
# assume a list of dict is list of BaseModel
|
|
44
|
+
if isinstance(item, dict):
|
|
45
|
+
_remove_extra_fields(get_args(annotation)[0], item)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
T = TypeVar("T", bound="BaseModel")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class CommonBaseModel(BaseModel):
|
|
52
|
+
model_config = ConfigDict(
|
|
53
|
+
alias_generator=alias_generators.to_camel,
|
|
54
|
+
populate_by_name=True,
|
|
55
|
+
from_attributes=True,
|
|
56
|
+
protected_namespaces=(),
|
|
57
|
+
extra="forbid",
|
|
58
|
+
# This allows us to use arbitrary types in the model. E.g. PIL.Image.
|
|
59
|
+
arbitrary_types_allowed=True,
|
|
60
|
+
ser_json_bytes="base64",
|
|
61
|
+
val_json_bytes="base64",
|
|
62
|
+
ignored_types=(TypeVar,),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def _from_response(cls: type[T], *, response: dict[str, object], kwargs: dict[str, object]) -> T:
|
|
67
|
+
# To maintain forward compatibility, we need to remove extra fields from
|
|
68
|
+
# the response.
|
|
69
|
+
# We will provide another mechanism to allow users to access these fields.
|
|
70
|
+
_remove_extra_fields(cls, response)
|
|
71
|
+
validated_response = cls.model_validate(response)
|
|
72
|
+
return validated_response
|
|
73
|
+
|
|
74
|
+
def to_json_dict(self) -> dict[str, object]:
|
|
75
|
+
return self.model_dump(exclude_none=True, mode="json")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class CaseInSensitiveEnum(str, enum.Enum):
|
|
79
|
+
"""Case insensitive enum."""
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
def _missing_(cls, value: Any) -> Optional["CaseInSensitiveEnum"]:
|
|
83
|
+
try:
|
|
84
|
+
return cls[value.upper()] # Try to access directly with uppercase
|
|
85
|
+
except KeyError:
|
|
86
|
+
try:
|
|
87
|
+
return cls[value.lower()] # Try to access directly with lowercase
|
|
88
|
+
except KeyError:
|
|
89
|
+
warnings.warn(f"{value} is not a valid {cls.__name__}")
|
|
90
|
+
try:
|
|
91
|
+
# Creating a enum instance based on the value
|
|
92
|
+
# We need to use super() to avoid infinite recursion.
|
|
93
|
+
unknown_enum_val = super().__new__(cls, value)
|
|
94
|
+
unknown_enum_val._name_ = str(value) # pylint: disable=protected-access
|
|
95
|
+
unknown_enum_val._value_ = value # pylint: disable=protected-access
|
|
96
|
+
return unknown_enum_val
|
|
97
|
+
except: # noqa: E722
|
|
98
|
+
return None
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class FunctionCallingConfigMode(CaseInSensitiveEnum):
|
|
102
|
+
"""Config for the function calling config mode."""
|
|
103
|
+
|
|
104
|
+
MODE_UNSPECIFIED = "MODE_UNSPECIFIED"
|
|
105
|
+
AUTO = "AUTO"
|
|
106
|
+
ANY = "ANY"
|
|
107
|
+
NONE = "NONE"
|
|
108
|
+
VALIDATED = "VALIDATED"
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class LatLng(CommonBaseModel):
|
|
112
|
+
"""An object that represents a latitude/longitude pair.
|
|
113
|
+
|
|
114
|
+
This is expressed as a pair of doubles to represent degrees latitude and
|
|
115
|
+
degrees longitude. Unless specified otherwise, this object must conform to the
|
|
116
|
+
<a href="https://en.wikipedia.org/wiki/World_Geodetic_System#1984_version">
|
|
117
|
+
WGS84 standard</a>. Values must be within normalized ranges.
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
latitude: float | None = Field(
|
|
121
|
+
default=None,
|
|
122
|
+
description="""The latitude in degrees. It must be in the range [-90.0, +90.0].""",
|
|
123
|
+
)
|
|
124
|
+
longitude: float | None = Field(
|
|
125
|
+
default=None,
|
|
126
|
+
description="""The longitude in degrees. It must be in the range [-180.0, +180.0]""",
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class FunctionCallingConfig(CommonBaseModel):
|
|
131
|
+
"""Function calling config."""
|
|
132
|
+
|
|
133
|
+
mode: FunctionCallingConfigMode | None = Field(default=None, description="""Optional. Function calling mode.""")
|
|
134
|
+
allowed_function_names: list[str] | None = Field(
|
|
135
|
+
default=None,
|
|
136
|
+
description="""Optional. Function names to call. Only set when the Mode is ANY. Function names should match [FunctionDeclaration.name]. With mode set to ANY, model will predict a function call from the set of function names provided.""",
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class RetrievalConfig(CommonBaseModel):
|
|
141
|
+
"""Retrieval config."""
|
|
142
|
+
|
|
143
|
+
lat_lng: LatLng | None = Field(default=None, description="""Optional. The location of the user.""")
|
|
144
|
+
language_code: str | None = Field(default=None, description="""The language code of the user.""")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class ToolConfig(CommonBaseModel):
|
|
148
|
+
"""Tool config.
|
|
149
|
+
|
|
150
|
+
This config is shared for all tools provided in the request.
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
function_calling_config: FunctionCallingConfig | None = Field(
|
|
154
|
+
default=None, description="""Optional. Function calling config."""
|
|
155
|
+
)
|
|
156
|
+
retrieval_config: RetrievalConfig | None = Field(default=None, description="""Optional. Retrieval config.""")
|
autogen/oai/groq.py
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
#
|
|
5
|
+
# Portions derived from https://github.com/microsoft/autogen are under the MIT License.
|
|
6
|
+
# SPDX-License-Identifier: MIT
|
|
7
|
+
"""Create an OpenAI-compatible client using Groq's API.
|
|
8
|
+
|
|
9
|
+
Example:
|
|
10
|
+
```python
|
|
11
|
+
llm_config = {
|
|
12
|
+
"config_list": [{"api_type": "groq", "model": "mixtral-8x7b-32768", "api_key": os.environ.get("GROQ_API_KEY")}]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
agent = autogen.AssistantAgent("my_agent", llm_config=llm_config)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Install Groq's python library using: pip install --upgrade groq
|
|
19
|
+
|
|
20
|
+
Resources:
|
|
21
|
+
- https://console.groq.com/docs/quickstart
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
import copy
|
|
27
|
+
import os
|
|
28
|
+
import time
|
|
29
|
+
import warnings
|
|
30
|
+
from typing import Any, Literal
|
|
31
|
+
|
|
32
|
+
from pydantic import Field
|
|
33
|
+
from typing_extensions import Unpack
|
|
34
|
+
|
|
35
|
+
from ..import_utils import optional_import_block, require_optional_import
|
|
36
|
+
from ..llm_config.entry import LLMConfigEntry, LLMConfigEntryDict
|
|
37
|
+
from .client_utils import should_hide_tools, validate_parameter
|
|
38
|
+
from .oai_models import ChatCompletion, ChatCompletionMessage, ChatCompletionMessageToolCall, Choice, CompletionUsage
|
|
39
|
+
|
|
40
|
+
with optional_import_block():
|
|
41
|
+
from groq import Groq, Stream
|
|
42
|
+
|
|
43
|
+
# Cost per thousand tokens - Input / Output (NOTE: Convert $/Million to $/K)
|
|
44
|
+
GROQ_PRICING_1K = {
|
|
45
|
+
"llama3-70b-8192": (0.00059, 0.00079),
|
|
46
|
+
"mixtral-8x7b-32768": (0.00024, 0.00024),
|
|
47
|
+
"llama3-8b-8192": (0.00005, 0.00008),
|
|
48
|
+
"gemma-7b-it": (0.00007, 0.00007),
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class GroqEntryDict(LLMConfigEntryDict, total=False):
|
|
53
|
+
api_type: Literal["groq"]
|
|
54
|
+
|
|
55
|
+
frequency_penalty: float
|
|
56
|
+
presence_penalty: float
|
|
57
|
+
seed: int
|
|
58
|
+
stream: bool
|
|
59
|
+
hide_tools: Literal["if_all_run", "if_any_run", "never"]
|
|
60
|
+
tool_choice: Literal["none", "auto", "required"] | None
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class GroqLLMConfigEntry(LLMConfigEntry):
|
|
64
|
+
api_type: Literal["groq"] = "groq"
|
|
65
|
+
|
|
66
|
+
frequency_penalty: float = Field(default=None, ge=-2, le=2)
|
|
67
|
+
presence_penalty: float = Field(default=None, ge=-2, le=2)
|
|
68
|
+
seed: int = Field(default=None)
|
|
69
|
+
stream: bool = Field(default=False)
|
|
70
|
+
hide_tools: Literal["if_all_run", "if_any_run", "never"] = "never"
|
|
71
|
+
tool_choice: Literal["none", "auto", "required"] | None = None
|
|
72
|
+
|
|
73
|
+
def create_client(self):
|
|
74
|
+
raise NotImplementedError("GroqLLMConfigEntry.create_client is not implemented.")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class GroqClient:
|
|
78
|
+
"""Client for Groq's API."""
|
|
79
|
+
|
|
80
|
+
RESPONSE_USAGE_KEYS: list[str] = ["prompt_tokens", "completion_tokens", "total_tokens", "cost", "model"]
|
|
81
|
+
|
|
82
|
+
def __init__(self, **kwargs: Unpack[GroqEntryDict]):
|
|
83
|
+
"""Requires api_key or environment variable to be set
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
**kwargs: Additional parameters to pass to the Groq API
|
|
87
|
+
"""
|
|
88
|
+
# Ensure we have the api_key upon instantiation
|
|
89
|
+
self.api_key = kwargs.get("api_key")
|
|
90
|
+
if not self.api_key:
|
|
91
|
+
self.api_key = os.getenv("GROQ_API_KEY")
|
|
92
|
+
|
|
93
|
+
assert self.api_key, (
|
|
94
|
+
"Please include the api_key in your config list entry for Groq or set the GROQ_API_KEY env variable."
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
if "response_format" in kwargs and kwargs["response_format"] is not None:
|
|
98
|
+
warnings.warn("response_format is not supported for Groq API, it will be ignored.", UserWarning)
|
|
99
|
+
self.base_url = kwargs.get("base_url")
|
|
100
|
+
|
|
101
|
+
def message_retrieval(self, response) -> list:
|
|
102
|
+
"""Retrieve and return a list of strings or a list of Choice.Message from the response.
|
|
103
|
+
|
|
104
|
+
NOTE: if a list of Choice.Message is returned, it currently needs to contain the fields of OpenAI's ChatCompletion Message object,
|
|
105
|
+
since that is expected for function or tool calling in the rest of the codebase at the moment, unless a custom agent is being used.
|
|
106
|
+
"""
|
|
107
|
+
return [choice.message for choice in response.choices]
|
|
108
|
+
|
|
109
|
+
def cost(self, response) -> float:
|
|
110
|
+
return response.cost
|
|
111
|
+
|
|
112
|
+
@staticmethod
|
|
113
|
+
def get_usage(response) -> dict:
|
|
114
|
+
"""Return usage summary of the response using RESPONSE_USAGE_KEYS."""
|
|
115
|
+
# ... # pragma: no cover
|
|
116
|
+
return {
|
|
117
|
+
"prompt_tokens": response.usage.prompt_tokens,
|
|
118
|
+
"completion_tokens": response.usage.completion_tokens,
|
|
119
|
+
"total_tokens": response.usage.total_tokens,
|
|
120
|
+
"cost": response.cost,
|
|
121
|
+
"model": response.model,
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
def parse_params(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
125
|
+
"""Loads the parameters for Groq API from the passed in parameters and returns a validated set. Checks types, ranges, and sets defaults"""
|
|
126
|
+
groq_params = {}
|
|
127
|
+
|
|
128
|
+
# Check that we have what we need to use Groq's API
|
|
129
|
+
# We won't enforce the available models as they are likely to change
|
|
130
|
+
groq_params["model"] = params.get("model")
|
|
131
|
+
assert groq_params["model"], (
|
|
132
|
+
"Please specify the 'model' in your config list entry to nominate the Groq model to use."
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
# Validate allowed Groq parameters
|
|
136
|
+
# https://console.groq.com/docs/api-reference#chat
|
|
137
|
+
groq_params["frequency_penalty"] = validate_parameter(
|
|
138
|
+
params, "frequency_penalty", (int, float), True, None, (-2, 2), None
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
groq_params["max_tokens"] = validate_parameter(params, "max_tokens", int, True, None, (0, None), None)
|
|
142
|
+
groq_params["temperature"] = validate_parameter(params, "temperature", (int, float), True, 1, (0, 2), None)
|
|
143
|
+
groq_params["top_p"] = validate_parameter(params, "top_p", (int, float), True, None, None, None)
|
|
144
|
+
|
|
145
|
+
groq_params["presence_penalty"] = validate_parameter(
|
|
146
|
+
params, "presence_penalty", (int, float), True, None, (-2, 2), None
|
|
147
|
+
)
|
|
148
|
+
groq_params["seed"] = validate_parameter(params, "seed", int, True, None, None, None)
|
|
149
|
+
groq_params["stream"] = validate_parameter(params, "stream", bool, True, False, None, None)
|
|
150
|
+
|
|
151
|
+
if "tool_choice" in params:
|
|
152
|
+
groq_params["tool_choice"] = validate_parameter(
|
|
153
|
+
params, "tool_choice", str, True, None, None, ["none", "auto", "required"]
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
# Groq parameters not supported by their models yet, ignoring
|
|
157
|
+
# logit_bias, logprobs, top_logprobs
|
|
158
|
+
|
|
159
|
+
# Groq parameters we are ignoring:
|
|
160
|
+
# n (must be 1), response_format (to enforce JSON but needs prompting as well), user,
|
|
161
|
+
# parallel_tool_calls (defaults to True), stop
|
|
162
|
+
# function_call (deprecated), functions (deprecated)
|
|
163
|
+
# tool_choice (none if no tools, auto if there are tools)
|
|
164
|
+
|
|
165
|
+
return groq_params
|
|
166
|
+
|
|
167
|
+
@require_optional_import("groq", "groq")
|
|
168
|
+
def create(self, params: dict) -> ChatCompletion:
|
|
169
|
+
messages = params.get("messages", [])
|
|
170
|
+
|
|
171
|
+
# Convert AG2 messages to Groq messages
|
|
172
|
+
groq_messages = oai_messages_to_groq_messages(messages)
|
|
173
|
+
|
|
174
|
+
# Parse parameters to the Groq API's parameters
|
|
175
|
+
groq_params = self.parse_params(params)
|
|
176
|
+
|
|
177
|
+
# Add tools to the call if we have them and aren't hiding them
|
|
178
|
+
if "tools" in params:
|
|
179
|
+
hide_tools = validate_parameter(
|
|
180
|
+
params, "hide_tools", str, False, "never", None, ["if_all_run", "if_any_run", "never"]
|
|
181
|
+
)
|
|
182
|
+
if not should_hide_tools(groq_messages, params["tools"], hide_tools):
|
|
183
|
+
groq_params["tools"] = params["tools"]
|
|
184
|
+
|
|
185
|
+
groq_params["messages"] = groq_messages
|
|
186
|
+
|
|
187
|
+
# We use chat model by default, and set max_retries to 5 (in line with typical retries loop)
|
|
188
|
+
client = Groq(api_key=self.api_key, max_retries=5, base_url=self.base_url)
|
|
189
|
+
|
|
190
|
+
# Token counts will be returned
|
|
191
|
+
prompt_tokens = 0
|
|
192
|
+
completion_tokens = 0
|
|
193
|
+
total_tokens = 0
|
|
194
|
+
|
|
195
|
+
# Streaming tool call recommendations
|
|
196
|
+
streaming_tool_calls = []
|
|
197
|
+
|
|
198
|
+
ans = None
|
|
199
|
+
response = client.chat.completions.create(**groq_params)
|
|
200
|
+
if groq_params["stream"]:
|
|
201
|
+
# Read in the chunks as they stream, taking in tool_calls which may be across
|
|
202
|
+
# multiple chunks if more than one suggested
|
|
203
|
+
ans = ""
|
|
204
|
+
for chunk in response:
|
|
205
|
+
ans = ans + (chunk.choices[0].delta.content or "")
|
|
206
|
+
|
|
207
|
+
if chunk.choices[0].delta.tool_calls:
|
|
208
|
+
# We have a tool call recommendation
|
|
209
|
+
for tool_call in chunk.choices[0].delta.tool_calls:
|
|
210
|
+
streaming_tool_calls.append(
|
|
211
|
+
ChatCompletionMessageToolCall(
|
|
212
|
+
id=tool_call.id,
|
|
213
|
+
function={
|
|
214
|
+
"name": tool_call.function.name,
|
|
215
|
+
"arguments": tool_call.function.arguments,
|
|
216
|
+
},
|
|
217
|
+
type="function",
|
|
218
|
+
)
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
if chunk.choices[0].finish_reason:
|
|
222
|
+
prompt_tokens = chunk.x_groq.usage.prompt_tokens
|
|
223
|
+
completion_tokens = chunk.x_groq.usage.completion_tokens
|
|
224
|
+
total_tokens = chunk.x_groq.usage.total_tokens
|
|
225
|
+
else:
|
|
226
|
+
# Non-streaming finished
|
|
227
|
+
ans: str = response.choices[0].message.content
|
|
228
|
+
prompt_tokens = response.usage.prompt_tokens
|
|
229
|
+
completion_tokens = response.usage.completion_tokens
|
|
230
|
+
total_tokens = response.usage.total_tokens
|
|
231
|
+
|
|
232
|
+
if response is not None:
|
|
233
|
+
if isinstance(response, Stream):
|
|
234
|
+
# Streaming response
|
|
235
|
+
if chunk.choices[0].finish_reason == "tool_calls":
|
|
236
|
+
groq_finish = "tool_calls"
|
|
237
|
+
tool_calls = streaming_tool_calls
|
|
238
|
+
else:
|
|
239
|
+
groq_finish = "stop"
|
|
240
|
+
tool_calls = None
|
|
241
|
+
|
|
242
|
+
response_content = ans
|
|
243
|
+
response_id = chunk.id
|
|
244
|
+
else:
|
|
245
|
+
# Non-streaming response
|
|
246
|
+
# If we have tool calls as the response, populate completed tool calls for our return OAI response
|
|
247
|
+
if response.choices[0].finish_reason == "tool_calls":
|
|
248
|
+
groq_finish = "tool_calls"
|
|
249
|
+
tool_calls = []
|
|
250
|
+
for tool_call in response.choices[0].message.tool_calls:
|
|
251
|
+
tool_calls.append(
|
|
252
|
+
ChatCompletionMessageToolCall(
|
|
253
|
+
id=tool_call.id,
|
|
254
|
+
function={"name": tool_call.function.name, "arguments": tool_call.function.arguments},
|
|
255
|
+
type="function",
|
|
256
|
+
)
|
|
257
|
+
)
|
|
258
|
+
else:
|
|
259
|
+
groq_finish = "stop"
|
|
260
|
+
tool_calls = None
|
|
261
|
+
|
|
262
|
+
response_content = response.choices[0].message.content
|
|
263
|
+
response_id = response.id
|
|
264
|
+
else:
|
|
265
|
+
raise RuntimeError("Failed to get response from Groq after retrying 5 times.")
|
|
266
|
+
|
|
267
|
+
# 3. convert output
|
|
268
|
+
message = ChatCompletionMessage(
|
|
269
|
+
role="assistant",
|
|
270
|
+
content=response_content,
|
|
271
|
+
function_call=None,
|
|
272
|
+
tool_calls=tool_calls,
|
|
273
|
+
)
|
|
274
|
+
choices = [Choice(finish_reason=groq_finish, index=0, message=message)]
|
|
275
|
+
|
|
276
|
+
response_oai = ChatCompletion(
|
|
277
|
+
id=response_id,
|
|
278
|
+
model=groq_params["model"],
|
|
279
|
+
created=int(time.time()),
|
|
280
|
+
object="chat.completion",
|
|
281
|
+
choices=choices,
|
|
282
|
+
usage=CompletionUsage(
|
|
283
|
+
prompt_tokens=prompt_tokens,
|
|
284
|
+
completion_tokens=completion_tokens,
|
|
285
|
+
total_tokens=total_tokens,
|
|
286
|
+
),
|
|
287
|
+
cost=calculate_groq_cost(prompt_tokens, completion_tokens, groq_params["model"]),
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
return response_oai
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def oai_messages_to_groq_messages(messages: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
294
|
+
"""Convert messages from OAI format to Groq's format.
|
|
295
|
+
We correct for any specific role orders and types.
|
|
296
|
+
"""
|
|
297
|
+
groq_messages = copy.deepcopy(messages)
|
|
298
|
+
|
|
299
|
+
# Remove the name field
|
|
300
|
+
for message in groq_messages:
|
|
301
|
+
if "name" in message:
|
|
302
|
+
message.pop("name", None)
|
|
303
|
+
|
|
304
|
+
return groq_messages
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def calculate_groq_cost(input_tokens: int, output_tokens: int, model: str) -> float:
|
|
308
|
+
"""Calculate the cost of the completion using the Groq pricing."""
|
|
309
|
+
total = 0.0
|
|
310
|
+
|
|
311
|
+
if model in GROQ_PRICING_1K:
|
|
312
|
+
input_cost_per_k, output_cost_per_k = GROQ_PRICING_1K[model]
|
|
313
|
+
input_cost = (input_tokens / 1000) * input_cost_per_k
|
|
314
|
+
output_cost = (output_tokens / 1000) * output_cost_per_k
|
|
315
|
+
total = input_cost + output_cost
|
|
316
|
+
else:
|
|
317
|
+
warnings.warn(f"Cost calculation not available for model {model}", UserWarning)
|
|
318
|
+
|
|
319
|
+
return total
|