camel-ai 0.2.65__py3-none-any.whl → 0.2.83a6__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.
Potentially problematic release.
This version of camel-ai might be problematic. Click here for more details.
- camel/__init__.py +3 -3
- camel/agents/__init__.py +2 -2
- camel/agents/_types.py +9 -4
- camel/agents/_utils.py +40 -2
- camel/agents/base.py +2 -2
- camel/agents/chat_agent.py +5107 -995
- camel/agents/critic_agent.py +2 -2
- camel/agents/deductive_reasoner_agent.py +56 -56
- camel/agents/embodied_agent.py +2 -2
- camel/agents/knowledge_graph_agent.py +20 -20
- camel/agents/mcp_agent.py +35 -36
- camel/agents/multi_hop_generator_agent.py +3 -3
- camel/agents/programmed_agent_instruction.py +2 -2
- camel/agents/repo_agent.py +4 -3
- camel/agents/role_assignment_agent.py +2 -2
- camel/agents/search_agent.py +2 -2
- camel/agents/task_agent.py +2 -2
- camel/agents/tool_agents/__init__.py +2 -2
- camel/agents/tool_agents/base.py +2 -2
- camel/agents/tool_agents/hugging_face_tool_agent.py +3 -3
- camel/benchmarks/__init__.py +2 -2
- camel/benchmarks/apibank.py +5 -5
- camel/benchmarks/apibench.py +2 -2
- camel/benchmarks/base.py +2 -2
- camel/benchmarks/browsecomp.py +44 -33
- camel/benchmarks/gaia.py +17 -13
- camel/benchmarks/mock_website/README.md +1 -3
- camel/benchmarks/mock_website/mock_web.py +2 -2
- camel/benchmarks/mock_website/requirements.txt +1 -1
- camel/benchmarks/mock_website/shopping_mall/app.py +2 -2
- camel/benchmarks/mock_website/task.json +1 -1
- camel/benchmarks/nexus.py +3 -3
- camel/benchmarks/ragbench.py +2 -2
- camel/bots/__init__.py +2 -2
- camel/bots/discord/__init__.py +2 -2
- camel/bots/discord/discord_app.py +2 -2
- camel/bots/discord/discord_installation.py +2 -2
- camel/bots/discord/discord_store.py +3 -3
- camel/bots/slack/__init__.py +2 -2
- camel/bots/slack/models.py +4 -4
- camel/bots/slack/slack_app.py +2 -2
- camel/bots/telegram_bot.py +2 -2
- camel/configs/__init__.py +29 -2
- camel/configs/aihubmix_config.py +90 -0
- camel/configs/aiml_config.py +2 -2
- camel/configs/amd_config.py +70 -0
- camel/configs/anthropic_config.py +2 -2
- camel/configs/base_config.py +2 -2
- camel/configs/bedrock_config.py +5 -3
- camel/configs/cerebras_config.py +98 -0
- camel/configs/cohere_config.py +2 -2
- camel/configs/cometapi_config.py +106 -0
- camel/configs/crynux_config.py +2 -2
- camel/configs/deepseek_config.py +9 -8
- camel/configs/function_gemma_config.py +59 -0
- camel/configs/gemini_config.py +6 -4
- camel/configs/groq_config.py +6 -4
- camel/configs/internlm_config.py +6 -4
- camel/configs/litellm_config.py +2 -2
- camel/configs/lmstudio_config.py +6 -4
- camel/configs/minimax_config.py +95 -0
- camel/configs/mistral_config.py +2 -2
- camel/configs/modelscope_config.py +5 -3
- camel/configs/moonshot_config.py +2 -2
- camel/configs/nebius_config.py +105 -0
- camel/configs/netmind_config.py +2 -2
- camel/configs/novita_config.py +2 -2
- camel/configs/nvidia_config.py +2 -2
- camel/configs/ollama_config.py +2 -2
- camel/configs/openai_config.py +5 -3
- camel/configs/openrouter_config.py +6 -4
- camel/configs/ppio_config.py +2 -2
- camel/configs/qianfan_config.py +85 -0
- camel/configs/qwen_config.py +2 -2
- camel/configs/reka_config.py +2 -2
- camel/configs/samba_config.py +6 -4
- camel/configs/sglang_config.py +2 -2
- camel/configs/siliconflow_config.py +2 -2
- camel/configs/togetherai_config.py +2 -2
- camel/configs/vllm_config.py +4 -2
- camel/configs/watsonx_config.py +2 -2
- camel/configs/yi_config.py +6 -4
- camel/configs/zhipuai_config.py +6 -4
- camel/data_collectors/__init__.py +2 -2
- camel/data_collectors/alpaca_collector.py +18 -9
- camel/data_collectors/base.py +2 -2
- camel/data_collectors/sharegpt_collector.py +2 -2
- camel/datagen/__init__.py +2 -2
- camel/datagen/cot_datagen.py +3 -3
- camel/datagen/evol_instruct/__init__.py +2 -2
- camel/datagen/evol_instruct/evol_instruct.py +2 -2
- camel/datagen/evol_instruct/scorer.py +12 -12
- camel/datagen/evol_instruct/templates.py +16 -16
- camel/datagen/self_improving_cot.py +5 -5
- camel/datagen/self_instruct/__init__.py +2 -2
- camel/datagen/self_instruct/filter/__init__.py +2 -2
- camel/datagen/self_instruct/filter/filter_function.py +2 -2
- camel/datagen/self_instruct/filter/filter_registry.py +2 -2
- camel/datagen/self_instruct/filter/instruction_filter.py +2 -2
- camel/datagen/self_instruct/self_instruct.py +2 -2
- camel/datagen/self_instruct/templates.py +47 -47
- camel/datagen/source2synth/__init__.py +2 -2
- camel/datagen/source2synth/data_processor.py +2 -2
- camel/datagen/source2synth/models.py +2 -2
- camel/datagen/source2synth/user_data_processor_config.py +2 -2
- camel/datahubs/__init__.py +2 -2
- camel/datahubs/base.py +2 -2
- camel/datahubs/huggingface.py +2 -2
- camel/datahubs/models.py +2 -2
- camel/datasets/__init__.py +2 -2
- camel/datasets/base_generator.py +41 -12
- camel/datasets/few_shot_generator.py +18 -18
- camel/datasets/models.py +2 -2
- camel/datasets/self_instruct_generator.py +2 -2
- camel/datasets/static_dataset.py +2 -2
- camel/embeddings/__init__.py +2 -2
- camel/embeddings/azure_embedding.py +2 -2
- camel/embeddings/base.py +2 -2
- camel/embeddings/gemini_embedding.py +2 -2
- camel/embeddings/jina_embedding.py +2 -2
- camel/embeddings/mistral_embedding.py +2 -2
- camel/embeddings/openai_compatible_embedding.py +2 -2
- camel/embeddings/openai_embedding.py +2 -2
- camel/embeddings/sentence_transformers_embeddings.py +2 -2
- camel/embeddings/together_embedding.py +2 -2
- camel/embeddings/vlm_embedding.py +2 -2
- camel/environments/__init__.py +14 -2
- camel/environments/models.py +2 -2
- camel/environments/multi_step.py +2 -2
- camel/environments/rlcards_env.py +860 -0
- camel/environments/single_step.py +30 -5
- camel/environments/tic_tac_toe.py +3 -3
- camel/extractors/__init__.py +2 -2
- camel/extractors/base.py +2 -2
- camel/extractors/python_strategies.py +2 -2
- camel/generators.py +2 -2
- camel/human.py +2 -2
- camel/interpreters/__init__.py +4 -2
- camel/interpreters/base.py +2 -2
- camel/interpreters/docker/Dockerfile +14 -24
- camel/interpreters/docker_interpreter.py +5 -4
- camel/interpreters/e2b_interpreter.py +36 -3
- camel/interpreters/internal_python_interpreter.py +53 -4
- camel/interpreters/interpreter_error.py +2 -2
- camel/interpreters/ipython_interpreter.py +2 -2
- camel/interpreters/microsandbox_interpreter.py +395 -0
- camel/interpreters/subprocess_interpreter.py +2 -2
- camel/loaders/__init__.py +13 -4
- camel/loaders/apify_reader.py +2 -2
- camel/loaders/base_io.py +2 -2
- camel/loaders/base_loader.py +85 -0
- camel/loaders/chunkr_reader.py +11 -2
- camel/loaders/crawl4ai_reader.py +2 -2
- camel/loaders/firecrawl_reader.py +6 -6
- camel/loaders/jina_url_reader.py +2 -2
- camel/loaders/markitdown.py +2 -2
- camel/loaders/mineru_extractor.py +2 -2
- camel/loaders/mistral_reader.py +2 -2
- camel/loaders/scrapegraph_reader.py +2 -2
- camel/loaders/unstructured_io.py +2 -2
- camel/logger.py +5 -5
- camel/memories/__init__.py +2 -2
- camel/memories/agent_memories.py +86 -3
- camel/memories/base.py +36 -2
- camel/memories/blocks/__init__.py +2 -2
- camel/memories/blocks/chat_history_block.py +125 -7
- camel/memories/blocks/vectordb_block.py +10 -3
- camel/memories/context_creators/__init__.py +2 -2
- camel/memories/context_creators/score_based.py +109 -230
- camel/memories/records.py +90 -10
- camel/messages/__init__.py +2 -2
- camel/messages/base.py +178 -43
- camel/messages/conversion/__init__.py +2 -2
- camel/messages/conversion/alpaca.py +2 -2
- camel/messages/conversion/conversation_models.py +2 -2
- camel/messages/conversion/sharegpt/__init__.py +2 -2
- camel/messages/conversion/sharegpt/function_call_formatter.py +2 -2
- camel/messages/conversion/sharegpt/hermes/__init__.py +2 -2
- camel/messages/conversion/sharegpt/hermes/hermes_function_formatter.py +2 -2
- camel/messages/func_message.py +54 -17
- camel/models/__init__.py +18 -2
- camel/models/_utils.py +3 -3
- camel/models/aihubmix_model.py +83 -0
- camel/models/aiml_model.py +11 -18
- camel/models/amd_model.py +101 -0
- camel/models/anthropic_model.py +127 -20
- camel/models/aws_bedrock_model.py +12 -35
- camel/models/azure_openai_model.py +214 -115
- camel/models/base_audio_model.py +5 -3
- camel/models/base_model.py +378 -31
- camel/models/cerebras_model.py +83 -0
- camel/models/cohere_model.py +18 -49
- camel/models/cometapi_model.py +83 -0
- camel/models/crynux_model.py +11 -18
- camel/models/deepseek_model.py +20 -84
- camel/models/fish_audio_model.py +8 -2
- camel/models/function_gemma_model.py +889 -0
- camel/models/gemini_model.py +391 -52
- camel/models/groq_model.py +11 -19
- camel/models/internlm_model.py +11 -18
- camel/models/litellm_model.py +57 -49
- camel/models/lmstudio_model.py +17 -20
- camel/models/minimax_model.py +83 -0
- camel/models/mistral_model.py +20 -47
- camel/models/model_factory.py +39 -3
- camel/models/model_manager.py +26 -8
- camel/models/modelscope_model.py +13 -193
- camel/models/moonshot_model.py +183 -21
- camel/models/nebius_model.py +83 -0
- camel/models/nemotron_model.py +19 -9
- camel/models/netmind_model.py +11 -18
- camel/models/novita_model.py +11 -18
- camel/models/nvidia_model.py +11 -18
- camel/models/ollama_model.py +14 -21
- camel/models/openai_audio_models.py +2 -2
- camel/models/openai_compatible_model.py +190 -71
- camel/models/openai_model.py +192 -86
- camel/models/openrouter_model.py +11 -19
- camel/models/ppio_model.py +11 -18
- camel/models/qianfan_model.py +89 -0
- camel/models/qwen_model.py +13 -193
- camel/models/reka_model.py +23 -49
- camel/models/reward/__init__.py +2 -2
- camel/models/reward/base_reward_model.py +2 -2
- camel/models/reward/evaluator.py +2 -2
- camel/models/reward/nemotron_model.py +2 -2
- camel/models/reward/skywork_model.py +2 -2
- camel/models/samba_model.py +50 -75
- camel/models/sglang_model.py +90 -68
- camel/models/siliconflow_model.py +12 -35
- camel/models/stub_model.py +10 -7
- camel/models/togetherai_model.py +11 -18
- camel/models/vllm_model.py +10 -18
- camel/models/volcano_model.py +158 -19
- camel/models/watsonx_model.py +9 -47
- camel/models/yi_model.py +11 -18
- camel/models/zhipuai_model.py +70 -18
- camel/parsers/__init__.py +18 -0
- camel/parsers/mcp_tool_call_parser.py +176 -0
- camel/personas/__init__.py +2 -2
- camel/personas/persona.py +2 -2
- camel/personas/persona_hub.py +2 -2
- camel/prompts/__init__.py +2 -2
- camel/prompts/ai_society.py +2 -2
- camel/prompts/base.py +2 -2
- camel/prompts/code.py +2 -2
- camel/prompts/evaluation.py +2 -2
- camel/prompts/generate_text_embedding_data.py +2 -2
- camel/prompts/image_craft.py +2 -2
- camel/prompts/misalignment.py +2 -2
- camel/prompts/multi_condition_image_craft.py +2 -2
- camel/prompts/object_recognition.py +2 -2
- camel/prompts/persona_hub.py +3 -3
- camel/prompts/prompt_templates.py +2 -2
- camel/prompts/role_description_prompt_template.py +2 -2
- camel/prompts/solution_extraction.py +8 -8
- camel/prompts/task_prompt_template.py +2 -2
- camel/prompts/translation.py +2 -2
- camel/prompts/video_description_prompt.py +3 -3
- camel/responses/__init__.py +2 -2
- camel/responses/agent_responses.py +2 -2
- camel/retrievers/__init__.py +2 -2
- camel/retrievers/auto_retriever.py +3 -2
- camel/retrievers/base.py +2 -2
- camel/retrievers/bm25_retriever.py +2 -2
- camel/retrievers/cohere_rerank_retriever.py +2 -2
- camel/retrievers/hybrid_retrival.py +2 -2
- camel/retrievers/vector_retriever.py +2 -2
- camel/runtimes/Dockerfile.multi-toolkit +90 -0
- camel/runtimes/__init__.py +2 -2
- camel/runtimes/api.py +79 -23
- camel/runtimes/base.py +2 -2
- camel/runtimes/configs.py +13 -13
- camel/runtimes/daytona_runtime.py +17 -18
- camel/runtimes/docker_runtime.py +12 -12
- camel/runtimes/llm_guard_runtime.py +26 -26
- camel/runtimes/remote_http_runtime.py +11 -11
- camel/runtimes/ubuntu_docker_runtime.py +2 -2
- camel/runtimes/utils/__init__.py +2 -2
- camel/runtimes/utils/function_risk_toolkit.py +2 -2
- camel/runtimes/utils/ignore_risk_toolkit.py +2 -2
- camel/schemas/__init__.py +2 -2
- camel/schemas/base.py +2 -2
- camel/schemas/openai_converter.py +3 -3
- camel/schemas/outlines_converter.py +2 -2
- camel/services/agent_openapi_server.py +380 -0
- camel/societies/__init__.py +4 -2
- camel/societies/babyagi_playing.py +2 -2
- camel/societies/role_playing.py +201 -80
- camel/societies/workforce/__init__.py +10 -3
- camel/societies/workforce/base.py +2 -2
- camel/societies/workforce/events.py +145 -0
- camel/societies/workforce/prompts.py +259 -33
- camel/societies/workforce/role_playing_worker.py +88 -31
- camel/societies/workforce/single_agent_worker.py +638 -40
- camel/societies/workforce/structured_output_handler.py +512 -0
- camel/societies/workforce/task_channel.py +182 -38
- camel/societies/workforce/utils.py +780 -65
- camel/societies/workforce/worker.py +92 -26
- camel/societies/workforce/workflow_memory_manager.py +1746 -0
- camel/societies/workforce/workforce.py +5354 -372
- camel/societies/workforce/workforce_callback.py +103 -0
- camel/societies/workforce/workforce_logger.py +647 -0
- camel/societies/workforce/workforce_metrics.py +33 -0
- camel/storages/__init__.py +6 -2
- camel/storages/graph_storages/__init__.py +2 -2
- camel/storages/graph_storages/base.py +2 -2
- camel/storages/graph_storages/graph_element.py +2 -2
- camel/storages/graph_storages/nebula_graph.py +4 -4
- camel/storages/graph_storages/neo4j_graph.py +7 -7
- camel/storages/key_value_storages/__init__.py +2 -2
- camel/storages/key_value_storages/base.py +2 -2
- camel/storages/key_value_storages/in_memory.py +2 -2
- camel/storages/key_value_storages/json.py +17 -4
- camel/storages/key_value_storages/mem0_cloud.py +50 -49
- camel/storages/key_value_storages/redis.py +2 -2
- camel/storages/object_storages/__init__.py +2 -2
- camel/storages/object_storages/amazon_s3.py +2 -2
- camel/storages/object_storages/azure_blob.py +2 -2
- camel/storages/object_storages/base.py +2 -2
- camel/storages/object_storages/google_cloud.py +3 -3
- camel/storages/vectordb_storages/__init__.py +8 -2
- camel/storages/vectordb_storages/base.py +2 -2
- camel/storages/vectordb_storages/chroma.py +731 -0
- camel/storages/vectordb_storages/faiss.py +2 -2
- camel/storages/vectordb_storages/milvus.py +2 -2
- camel/storages/vectordb_storages/oceanbase.py +15 -15
- camel/storages/vectordb_storages/pgvector.py +349 -0
- camel/storages/vectordb_storages/qdrant.py +6 -6
- camel/storages/vectordb_storages/surreal.py +372 -0
- camel/storages/vectordb_storages/tidb.py +11 -8
- camel/storages/vectordb_storages/weaviate.py +2 -2
- camel/tasks/__init__.py +2 -2
- camel/tasks/task.py +348 -26
- camel/tasks/task_prompt.py +3 -3
- camel/terminators/__init__.py +2 -2
- camel/terminators/base.py +2 -2
- camel/terminators/response_terminator.py +2 -2
- camel/terminators/token_limit_terminator.py +2 -2
- camel/toolkits/__init__.py +57 -10
- camel/toolkits/aci_toolkit.py +66 -21
- camel/toolkits/arxiv_toolkit.py +8 -8
- camel/toolkits/ask_news_toolkit.py +2 -2
- camel/toolkits/async_browser_toolkit.py +4 -4
- camel/toolkits/audio_analysis_toolkit.py +3 -3
- camel/toolkits/base.py +106 -6
- camel/toolkits/bohrium_toolkit.py +2 -2
- camel/toolkits/browser_toolkit.py +34 -21
- camel/toolkits/browser_toolkit_commons.py +4 -4
- camel/toolkits/code_execution.py +31 -4
- camel/toolkits/context_summarizer_toolkit.py +684 -0
- camel/toolkits/craw4ai_toolkit.py +93 -0
- camel/toolkits/dappier_toolkit.py +12 -8
- camel/toolkits/data_commons_toolkit.py +2 -2
- camel/toolkits/dingtalk.py +1135 -0
- camel/toolkits/earth_science_toolkit.py +5367 -0
- camel/toolkits/edgeone_pages_mcp_toolkit.py +49 -0
- camel/toolkits/excel_toolkit.py +905 -71
- camel/toolkits/file_toolkit.py +1402 -0
- camel/toolkits/function_tool.py +205 -27
- camel/toolkits/github_toolkit.py +109 -22
- camel/toolkits/gmail_toolkit.py +1839 -0
- camel/toolkits/google_calendar_toolkit.py +40 -6
- camel/toolkits/google_drive_mcp_toolkit.py +54 -0
- camel/toolkits/google_maps_toolkit.py +2 -2
- camel/toolkits/google_scholar_toolkit.py +2 -2
- camel/toolkits/human_toolkit.py +36 -12
- camel/toolkits/hybrid_browser_toolkit/__init__.py +18 -0
- camel/toolkits/hybrid_browser_toolkit/config_loader.py +185 -0
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +246 -0
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +1958 -0
- camel/toolkits/hybrid_browser_toolkit/installer.py +203 -0
- camel/toolkits/hybrid_browser_toolkit/ts/package-lock.json +4589 -0
- camel/toolkits/hybrid_browser_toolkit/ts/package.json +33 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/browser-scripts.js +125 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/browser-session.ts +1940 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/config-loader.ts +233 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/hybrid-browser-toolkit.ts +589 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/index.ts +7 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/parent-child-filter.ts +226 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/snapshot-parser.ts +219 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/som-screenshot-injected.ts +543 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/types.ts +129 -0
- camel/toolkits/hybrid_browser_toolkit/ts/tsconfig.json +27 -0
- camel/toolkits/hybrid_browser_toolkit/ts/websocket-server.js +325 -0
- camel/toolkits/hybrid_browser_toolkit/ws_wrapper.py +1037 -0
- camel/toolkits/hybrid_browser_toolkit_py/__init__.py +17 -0
- camel/toolkits/hybrid_browser_toolkit_py/actions.py +575 -0
- camel/toolkits/hybrid_browser_toolkit_py/agent.py +311 -0
- camel/toolkits/hybrid_browser_toolkit_py/browser_session.py +787 -0
- camel/toolkits/hybrid_browser_toolkit_py/config_loader.py +490 -0
- camel/toolkits/hybrid_browser_toolkit_py/hybrid_browser_toolkit.py +2390 -0
- camel/toolkits/hybrid_browser_toolkit_py/snapshot.py +233 -0
- camel/toolkits/hybrid_browser_toolkit_py/stealth_script.js +0 -0
- camel/toolkits/hybrid_browser_toolkit_py/unified_analyzer.js +1043 -0
- camel/toolkits/image_analysis_toolkit.py +3 -6
- camel/toolkits/image_generation_toolkit.py +390 -0
- camel/toolkits/jina_reranker_toolkit.py +5 -6
- camel/toolkits/klavis_toolkit.py +7 -3
- camel/toolkits/linkedin_toolkit.py +2 -2
- camel/toolkits/markitdown_toolkit.py +104 -0
- camel/toolkits/math_toolkit.py +66 -12
- camel/toolkits/mcp_toolkit.py +412 -36
- camel/toolkits/memory_toolkit.py +7 -3
- camel/toolkits/meshy_toolkit.py +2 -2
- camel/toolkits/message_agent_toolkit.py +608 -0
- camel/toolkits/message_integration.py +728 -0
- camel/toolkits/microsoft_outlook_mail_toolkit.py +1885 -0
- camel/toolkits/mineru_toolkit.py +2 -2
- camel/toolkits/minimax_mcp_toolkit.py +195 -0
- camel/toolkits/networkx_toolkit.py +2 -2
- camel/toolkits/note_taking_toolkit.py +277 -0
- camel/toolkits/notion_mcp_toolkit.py +224 -0
- camel/toolkits/notion_toolkit.py +2 -2
- camel/toolkits/open_api_specs/biztoc/__init__.py +2 -2
- camel/toolkits/open_api_specs/biztoc/ai-plugin.json +1 -1
- camel/toolkits/open_api_specs/coursera/__init__.py +2 -2
- camel/toolkits/open_api_specs/create_qr_code/__init__.py +2 -2
- camel/toolkits/open_api_specs/klarna/__init__.py +2 -2
- camel/toolkits/open_api_specs/nasa_apod/__init__.py +2 -2
- camel/toolkits/open_api_specs/outschool/__init__.py +2 -2
- camel/toolkits/open_api_specs/outschool/ai-plugin.json +1 -1
- camel/toolkits/open_api_specs/outschool/openapi.yaml +1 -1
- camel/toolkits/open_api_specs/outschool/paths/__init__.py +2 -2
- camel/toolkits/open_api_specs/outschool/paths/get_classes.py +2 -2
- camel/toolkits/open_api_specs/outschool/paths/search_teachers.py +2 -2
- camel/toolkits/open_api_specs/security_config.py +2 -2
- camel/toolkits/open_api_specs/speak/__init__.py +2 -2
- camel/toolkits/open_api_specs/web_scraper/__init__.py +2 -2
- camel/toolkits/open_api_specs/web_scraper/ai-plugin.json +1 -1
- camel/toolkits/open_api_specs/web_scraper/paths/__init__.py +2 -2
- camel/toolkits/open_api_specs/web_scraper/paths/scraper.py +2 -2
- camel/toolkits/open_api_toolkit.py +2 -2
- camel/toolkits/openbb_toolkit.py +7 -3
- camel/toolkits/origene_mcp_toolkit.py +56 -0
- camel/toolkits/page_script.js +53 -53
- camel/toolkits/playwright_mcp_toolkit.py +13 -31
- camel/toolkits/pptx_toolkit.py +36 -23
- camel/toolkits/pubmed_toolkit.py +2 -2
- camel/toolkits/pulse_mcp_search_toolkit.py +2 -2
- camel/toolkits/pyautogui_toolkit.py +2 -2
- camel/toolkits/reddit_toolkit.py +2 -2
- camel/toolkits/resend_toolkit.py +168 -0
- camel/toolkits/retrieval_toolkit.py +2 -2
- camel/toolkits/screenshot_toolkit.py +213 -0
- camel/toolkits/search_toolkit.py +606 -156
- camel/toolkits/searxng_toolkit.py +2 -2
- camel/toolkits/semantic_scholar_toolkit.py +2 -2
- camel/toolkits/slack_toolkit.py +108 -58
- camel/toolkits/sql_toolkit.py +712 -0
- camel/toolkits/stripe_toolkit.py +2 -2
- camel/toolkits/sympy_toolkit.py +3 -3
- camel/toolkits/task_planning_toolkit.py +5 -5
- camel/toolkits/terminal_toolkit/__init__.py +18 -0
- camel/toolkits/terminal_toolkit/terminal_toolkit.py +1281 -0
- camel/toolkits/terminal_toolkit/utils.py +659 -0
- camel/toolkits/thinking_toolkit.py +3 -3
- camel/toolkits/twitter_toolkit.py +2 -2
- camel/toolkits/vertex_ai_veo_toolkit.py +590 -0
- camel/toolkits/video_analysis_toolkit.py +109 -29
- camel/toolkits/video_download_toolkit.py +19 -16
- camel/toolkits/weather_toolkit.py +2 -2
- camel/toolkits/web_deploy_toolkit.py +1219 -0
- camel/toolkits/wechat_official_toolkit.py +483 -0
- camel/toolkits/whatsapp_toolkit.py +2 -2
- camel/toolkits/wolfram_alpha_toolkit.py +2 -2
- camel/toolkits/zapier_toolkit.py +7 -3
- camel/types/__init__.py +4 -4
- camel/types/agents/__init__.py +2 -2
- camel/types/agents/tool_calling_record.py +6 -3
- camel/types/enums.py +381 -41
- camel/types/mcp_registries.py +2 -2
- camel/types/openai_types.py +4 -4
- camel/types/unified_model_type.py +46 -10
- camel/utils/__init__.py +5 -2
- camel/utils/agent_context.py +41 -0
- camel/utils/async_func.py +2 -2
- camel/utils/chunker/__init__.py +2 -2
- camel/utils/chunker/base.py +2 -2
- camel/utils/chunker/code_chunker.py +2 -2
- camel/utils/chunker/uio_chunker.py +2 -2
- camel/utils/commons.py +38 -7
- camel/utils/constants.py +5 -2
- camel/utils/context_utils.py +1134 -0
- camel/utils/deduplication.py +2 -2
- camel/utils/filename.py +2 -2
- camel/utils/langfuse.py +18 -10
- camel/utils/mcp.py +140 -6
- camel/utils/mcp_client.py +48 -38
- camel/utils/message_summarizer.py +148 -0
- camel/utils/response_format.py +2 -2
- camel/utils/token_counting.py +45 -22
- camel/utils/tool_result.py +44 -0
- camel/verifiers/__init__.py +2 -2
- camel/verifiers/base.py +2 -2
- camel/verifiers/math_verifier.py +2 -2
- camel/verifiers/models.py +2 -2
- camel/verifiers/physics_verifier.py +2 -2
- camel/verifiers/python_verifier.py +2 -2
- {camel_ai-0.2.65.dist-info → camel_ai-0.2.83a6.dist-info}/METADATA +355 -117
- camel_ai-0.2.83a6.dist-info/RECORD +511 -0
- {camel_ai-0.2.65.dist-info → camel_ai-0.2.83a6.dist-info}/WHEEL +1 -1
- {camel_ai-0.2.65.dist-info → camel_ai-0.2.83a6.dist-info}/licenses/LICENSE +1 -1
- camel/loaders/pandas_reader.py +0 -368
- camel/toolkits/dalle_toolkit.py +0 -175
- camel/toolkits/file_write_toolkit.py +0 -444
- camel/toolkits/openai_agent_toolkit.py +0 -135
- camel/toolkits/terminal_toolkit.py +0 -1037
- camel_ai-0.2.65.dist-info/RECORD +0 -426
camel/models/base_model.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ========= Copyright 2023-
|
|
1
|
+
# ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
2
2
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
3
|
# you may not use this file except in compliance with the License.
|
|
4
4
|
# You may obtain a copy of the License at
|
|
@@ -10,15 +10,31 @@
|
|
|
10
10
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
11
|
# See the License for the specific language governing permissions and
|
|
12
12
|
# limitations under the License.
|
|
13
|
-
# ========= Copyright 2023-
|
|
13
|
+
# ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
14
14
|
import abc
|
|
15
|
+
import inspect
|
|
16
|
+
import os
|
|
15
17
|
import re
|
|
16
18
|
from abc import ABC, abstractmethod
|
|
17
|
-
from typing import
|
|
19
|
+
from typing import (
|
|
20
|
+
Any,
|
|
21
|
+
AsyncGenerator,
|
|
22
|
+
Dict,
|
|
23
|
+
Generator,
|
|
24
|
+
List,
|
|
25
|
+
Optional,
|
|
26
|
+
Type,
|
|
27
|
+
Union,
|
|
28
|
+
)
|
|
18
29
|
|
|
19
30
|
from openai import AsyncStream, Stream
|
|
31
|
+
from openai.lib.streaming.chat import (
|
|
32
|
+
AsyncChatCompletionStreamManager,
|
|
33
|
+
ChatCompletionStreamManager,
|
|
34
|
+
)
|
|
20
35
|
from pydantic import BaseModel
|
|
21
36
|
|
|
37
|
+
from camel.logger import get_logger as camel_get_logger
|
|
22
38
|
from camel.messages import OpenAIMessage
|
|
23
39
|
from camel.types import (
|
|
24
40
|
ChatCompletion,
|
|
@@ -27,7 +43,153 @@ from camel.types import (
|
|
|
27
43
|
ParsedChatCompletion,
|
|
28
44
|
UnifiedModelType,
|
|
29
45
|
)
|
|
30
|
-
from camel.utils import
|
|
46
|
+
from camel.utils import (
|
|
47
|
+
BaseTokenCounter,
|
|
48
|
+
Constants,
|
|
49
|
+
get_current_agent_session_id,
|
|
50
|
+
update_langfuse_trace,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
if os.environ.get("TRACEROOT_ENABLED", "False").lower() == "true":
|
|
54
|
+
try:
|
|
55
|
+
from traceroot import get_logger # type: ignore[import]
|
|
56
|
+
from traceroot import trace as observe # type: ignore[import]
|
|
57
|
+
|
|
58
|
+
logger = get_logger('base_model')
|
|
59
|
+
except ImportError:
|
|
60
|
+
from camel.utils import observe
|
|
61
|
+
|
|
62
|
+
logger = camel_get_logger('base_model')
|
|
63
|
+
else:
|
|
64
|
+
from camel.utils import observe
|
|
65
|
+
|
|
66
|
+
logger = camel_get_logger('base_model')
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class _StreamLogger:
|
|
70
|
+
r"""Base for stream logging wrappers."""
|
|
71
|
+
|
|
72
|
+
def __init__(self, log_path: Optional[str], log_enabled: bool):
|
|
73
|
+
self._log_path = log_path
|
|
74
|
+
self._log_enabled = log_enabled
|
|
75
|
+
self._id = self._model = self._content = ""
|
|
76
|
+
self._finish_reason: Optional[str] = None
|
|
77
|
+
self._usage: Optional[Dict[str, Any]] = None
|
|
78
|
+
self._logged = False
|
|
79
|
+
|
|
80
|
+
def _collect(self, chunk: ChatCompletionChunk) -> None:
|
|
81
|
+
self._id = self._id or getattr(chunk, 'id', '')
|
|
82
|
+
self._model = self._model or getattr(chunk, 'model', '')
|
|
83
|
+
if chunk.usage:
|
|
84
|
+
u = chunk.usage
|
|
85
|
+
self._usage = (
|
|
86
|
+
u.model_dump() if hasattr(u, 'model_dump') else u.dict()
|
|
87
|
+
)
|
|
88
|
+
if chunk.choices:
|
|
89
|
+
choice = chunk.choices[0]
|
|
90
|
+
if choice.delta and choice.delta.content:
|
|
91
|
+
self._content += choice.delta.content
|
|
92
|
+
if choice.finish_reason:
|
|
93
|
+
self._finish_reason = choice.finish_reason
|
|
94
|
+
|
|
95
|
+
def _log(self) -> None:
|
|
96
|
+
if self._logged or not self._log_enabled or not self._log_path:
|
|
97
|
+
return
|
|
98
|
+
self._logged = True
|
|
99
|
+
import json
|
|
100
|
+
from datetime import datetime
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
with open(self._log_path, "r+") as f:
|
|
104
|
+
data = json.load(f)
|
|
105
|
+
data["response_timestamp"] = datetime.now().isoformat()
|
|
106
|
+
data["response"] = {
|
|
107
|
+
"id": self._id,
|
|
108
|
+
"model": self._model,
|
|
109
|
+
"content": self._content,
|
|
110
|
+
"finish_reason": self._finish_reason,
|
|
111
|
+
"usage": self._usage,
|
|
112
|
+
"streaming": True,
|
|
113
|
+
}
|
|
114
|
+
f.seek(0)
|
|
115
|
+
json.dump(data, f, indent=4)
|
|
116
|
+
f.truncate()
|
|
117
|
+
except Exception:
|
|
118
|
+
pass
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class _SyncStreamWrapper(_StreamLogger):
|
|
122
|
+
r"""Sync stream wrapper with logging."""
|
|
123
|
+
|
|
124
|
+
def __init__(
|
|
125
|
+
self,
|
|
126
|
+
stream: Union[
|
|
127
|
+
Stream[ChatCompletionChunk],
|
|
128
|
+
Generator[ChatCompletionChunk, None, None],
|
|
129
|
+
],
|
|
130
|
+
log_path: Optional[str],
|
|
131
|
+
log_enabled: bool,
|
|
132
|
+
):
|
|
133
|
+
super().__init__(log_path, log_enabled)
|
|
134
|
+
self._stream = stream
|
|
135
|
+
|
|
136
|
+
def __iter__(self):
|
|
137
|
+
return self
|
|
138
|
+
|
|
139
|
+
def __next__(self) -> ChatCompletionChunk:
|
|
140
|
+
try:
|
|
141
|
+
chunk = next(self._stream)
|
|
142
|
+
self._collect(chunk)
|
|
143
|
+
return chunk
|
|
144
|
+
except StopIteration:
|
|
145
|
+
self._log()
|
|
146
|
+
raise
|
|
147
|
+
|
|
148
|
+
def __enter__(self):
|
|
149
|
+
return self
|
|
150
|
+
|
|
151
|
+
def __exit__(self, *_):
|
|
152
|
+
return False
|
|
153
|
+
|
|
154
|
+
def __del__(self):
|
|
155
|
+
self._log()
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class _AsyncStreamWrapper(_StreamLogger):
|
|
159
|
+
r"""Async stream wrapper with logging."""
|
|
160
|
+
|
|
161
|
+
def __init__(
|
|
162
|
+
self,
|
|
163
|
+
stream: Union[
|
|
164
|
+
AsyncStream[ChatCompletionChunk],
|
|
165
|
+
AsyncGenerator[ChatCompletionChunk, None],
|
|
166
|
+
],
|
|
167
|
+
log_path: Optional[str],
|
|
168
|
+
log_enabled: bool,
|
|
169
|
+
):
|
|
170
|
+
super().__init__(log_path, log_enabled)
|
|
171
|
+
self._stream = stream
|
|
172
|
+
|
|
173
|
+
def __aiter__(self):
|
|
174
|
+
return self
|
|
175
|
+
|
|
176
|
+
async def __anext__(self) -> ChatCompletionChunk:
|
|
177
|
+
try:
|
|
178
|
+
chunk = await self._stream.__anext__()
|
|
179
|
+
self._collect(chunk)
|
|
180
|
+
return chunk
|
|
181
|
+
except StopAsyncIteration:
|
|
182
|
+
self._log()
|
|
183
|
+
raise
|
|
184
|
+
|
|
185
|
+
async def __aenter__(self):
|
|
186
|
+
return self
|
|
187
|
+
|
|
188
|
+
async def __aexit__(self, *_):
|
|
189
|
+
return False
|
|
190
|
+
|
|
191
|
+
def __del__(self):
|
|
192
|
+
self._log()
|
|
31
193
|
|
|
32
194
|
|
|
33
195
|
class ModelBackendMeta(abc.ABCMeta):
|
|
@@ -71,6 +233,8 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
|
|
|
71
233
|
:obj:`OpenAITokenCounter` will be used. (default: :obj:`None`)
|
|
72
234
|
timeout (Optional[float], optional): The timeout value in seconds for
|
|
73
235
|
API calls. (default: :obj:`None`)
|
|
236
|
+
max_retries (int, optional): Maximum number of retries
|
|
237
|
+
for API calls. (default: :obj:`3`)
|
|
74
238
|
"""
|
|
75
239
|
|
|
76
240
|
def __init__(
|
|
@@ -80,7 +244,8 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
|
|
|
80
244
|
api_key: Optional[str] = None,
|
|
81
245
|
url: Optional[str] = None,
|
|
82
246
|
token_counter: Optional[BaseTokenCounter] = None,
|
|
83
|
-
timeout: Optional[float] =
|
|
247
|
+
timeout: Optional[float] = Constants.TIMEOUT_THRESHOLD,
|
|
248
|
+
max_retries: int = 3,
|
|
84
249
|
) -> None:
|
|
85
250
|
self.model_type: UnifiedModelType = UnifiedModelType(model_type)
|
|
86
251
|
if model_config_dict is None:
|
|
@@ -90,7 +255,13 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
|
|
|
90
255
|
self._url = url
|
|
91
256
|
self._token_counter = token_counter
|
|
92
257
|
self._timeout = timeout
|
|
93
|
-
self.
|
|
258
|
+
self._max_retries = max_retries
|
|
259
|
+
# Initialize logging configuration
|
|
260
|
+
self._log_enabled = (
|
|
261
|
+
os.environ.get("CAMEL_MODEL_LOG_ENABLED", "False").lower()
|
|
262
|
+
== "true"
|
|
263
|
+
)
|
|
264
|
+
self._log_dir = os.environ.get("CAMEL_LOG_DIR", "camel_logs")
|
|
94
265
|
|
|
95
266
|
@property
|
|
96
267
|
@abstractmethod
|
|
@@ -228,13 +399,130 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
|
|
|
228
399
|
|
|
229
400
|
return formatted_messages
|
|
230
401
|
|
|
402
|
+
def _log_request(self, messages: List[OpenAIMessage]) -> Optional[str]:
|
|
403
|
+
r"""Log the request messages to a JSON file if logging is enabled.
|
|
404
|
+
|
|
405
|
+
Args:
|
|
406
|
+
messages (List[OpenAIMessage]): The messages to log.
|
|
407
|
+
|
|
408
|
+
Returns:
|
|
409
|
+
Optional[str]: The path to the log file if logging is enabled,
|
|
410
|
+
None otherwise.
|
|
411
|
+
"""
|
|
412
|
+
if not self._log_enabled:
|
|
413
|
+
return None
|
|
414
|
+
|
|
415
|
+
import json
|
|
416
|
+
from datetime import datetime
|
|
417
|
+
|
|
418
|
+
from camel.utils.agent_context import get_current_agent_id
|
|
419
|
+
|
|
420
|
+
agent_id = get_current_agent_id()
|
|
421
|
+
|
|
422
|
+
# Remove _context_summarizer suffix to keep all logs in one directory
|
|
423
|
+
log_agent_id = agent_id
|
|
424
|
+
if agent_id and agent_id.endswith("_context_summarizer"):
|
|
425
|
+
log_agent_id = agent_id[: -len("_context_summarizer")]
|
|
426
|
+
|
|
427
|
+
log_subdir = (
|
|
428
|
+
os.path.join(self._log_dir, log_agent_id)
|
|
429
|
+
if log_agent_id
|
|
430
|
+
else self._log_dir
|
|
431
|
+
)
|
|
432
|
+
os.makedirs(log_subdir, exist_ok=True)
|
|
433
|
+
|
|
434
|
+
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S_%f')
|
|
435
|
+
log_file_path = os.path.join(log_subdir, f"conv_{timestamp}.json")
|
|
436
|
+
|
|
437
|
+
log_entry = {
|
|
438
|
+
"request_timestamp": datetime.now().isoformat(),
|
|
439
|
+
"model": str(self.model_type),
|
|
440
|
+
"agent_id": agent_id,
|
|
441
|
+
"request": {"messages": messages},
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
with open(log_file_path, "w") as f:
|
|
445
|
+
json.dump(log_entry, f, indent=4)
|
|
446
|
+
|
|
447
|
+
return log_file_path
|
|
448
|
+
|
|
449
|
+
def _log_response(self, log_path: str, response: Any) -> None:
|
|
450
|
+
r"""Log the response to the existing log file.
|
|
451
|
+
|
|
452
|
+
Args:
|
|
453
|
+
log_path (str): The path to the log file.
|
|
454
|
+
response (Any): The response to log.
|
|
455
|
+
"""
|
|
456
|
+
if not self._log_enabled or not log_path:
|
|
457
|
+
return
|
|
458
|
+
|
|
459
|
+
import json
|
|
460
|
+
from datetime import datetime
|
|
461
|
+
|
|
462
|
+
with open(log_path, "r+") as f:
|
|
463
|
+
log_data = json.load(f)
|
|
464
|
+
|
|
465
|
+
log_data["response_timestamp"] = datetime.now().isoformat()
|
|
466
|
+
if isinstance(response, BaseModel):
|
|
467
|
+
log_data["response"] = response.model_dump()
|
|
468
|
+
else:
|
|
469
|
+
try:
|
|
470
|
+
json.dumps(response)
|
|
471
|
+
log_data["response"] = response
|
|
472
|
+
except TypeError:
|
|
473
|
+
log_data["response"] = str(response)
|
|
474
|
+
|
|
475
|
+
f.seek(0)
|
|
476
|
+
json.dump(log_data, f, indent=4)
|
|
477
|
+
f.truncate()
|
|
478
|
+
|
|
479
|
+
def _log_and_trace(self) -> None:
|
|
480
|
+
r"""Update Langfuse trace with session metadata.
|
|
481
|
+
|
|
482
|
+
This method updates the current Langfuse trace with agent session
|
|
483
|
+
information and model metadata. Called at the start of _run() and
|
|
484
|
+
_arun() methods before API execution.
|
|
485
|
+
"""
|
|
486
|
+
agent_session_id = get_current_agent_session_id()
|
|
487
|
+
update_langfuse_trace(
|
|
488
|
+
session_id=agent_session_id,
|
|
489
|
+
metadata={
|
|
490
|
+
"source": "camel",
|
|
491
|
+
"agent_id": agent_session_id,
|
|
492
|
+
"agent_type": "camel_chat_agent",
|
|
493
|
+
"model_type": str(self.model_type),
|
|
494
|
+
},
|
|
495
|
+
tags=["CAMEL-AI", str(self.model_type)],
|
|
496
|
+
)
|
|
497
|
+
|
|
231
498
|
@abstractmethod
|
|
232
499
|
def _run(
|
|
233
500
|
self,
|
|
234
501
|
messages: List[OpenAIMessage],
|
|
235
502
|
response_format: Optional[Type[BaseModel]] = None,
|
|
236
503
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
237
|
-
) -> Union[
|
|
504
|
+
) -> Union[
|
|
505
|
+
ChatCompletion,
|
|
506
|
+
Stream[ChatCompletionChunk],
|
|
507
|
+
ChatCompletionStreamManager[BaseModel],
|
|
508
|
+
]:
|
|
509
|
+
r"""Runs the query to the backend model in a non-stream mode.
|
|
510
|
+
|
|
511
|
+
Args:
|
|
512
|
+
messages (List[OpenAIMessage]): Message list with the chat history
|
|
513
|
+
in OpenAI API format.
|
|
514
|
+
response_format (Optional[Type[BaseModel]]): The format of the
|
|
515
|
+
response.
|
|
516
|
+
tools (Optional[List[Dict[str, Any]]]): The schema of the tools to
|
|
517
|
+
use for the request.
|
|
518
|
+
|
|
519
|
+
Returns:
|
|
520
|
+
Union[ChatCompletion, Stream[ChatCompletionChunk], Any]:
|
|
521
|
+
`ChatCompletion` in the non-stream mode, or
|
|
522
|
+
`Stream[ChatCompletionChunk]` in the stream mode,
|
|
523
|
+
or `ChatCompletionStreamManager[BaseModel]` in the structured
|
|
524
|
+
stream mode.
|
|
525
|
+
"""
|
|
238
526
|
pass
|
|
239
527
|
|
|
240
528
|
@abstractmethod
|
|
@@ -243,15 +531,41 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
|
|
|
243
531
|
messages: List[OpenAIMessage],
|
|
244
532
|
response_format: Optional[Type[BaseModel]] = None,
|
|
245
533
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
246
|
-
) -> Union[
|
|
534
|
+
) -> Union[
|
|
535
|
+
ChatCompletion,
|
|
536
|
+
AsyncStream[ChatCompletionChunk],
|
|
537
|
+
AsyncChatCompletionStreamManager[BaseModel],
|
|
538
|
+
]:
|
|
539
|
+
r"""Runs the query to the backend model in async non-stream mode.
|
|
540
|
+
|
|
541
|
+
Args:
|
|
542
|
+
messages (List[OpenAIMessage]): Message list with the chat history
|
|
543
|
+
in OpenAI API format.
|
|
544
|
+
response_format (Optional[Type[BaseModel]]): The format of the
|
|
545
|
+
response.
|
|
546
|
+
tools (Optional[List[Dict[str, Any]]]): The schema of the tools to
|
|
547
|
+
use for the request.
|
|
548
|
+
|
|
549
|
+
Returns:
|
|
550
|
+
Union[ChatCompletion, AsyncStream[ChatCompletionChunk], Any]:
|
|
551
|
+
`ChatCompletion` in the non-stream mode, or
|
|
552
|
+
`AsyncStream[ChatCompletionChunk]` in the stream mode,
|
|
553
|
+
or `AsyncChatCompletionStreamManager[BaseModel]` in the
|
|
554
|
+
structured stream mode.
|
|
555
|
+
"""
|
|
247
556
|
pass
|
|
248
557
|
|
|
558
|
+
@observe()
|
|
249
559
|
def run(
|
|
250
560
|
self,
|
|
251
561
|
messages: List[OpenAIMessage],
|
|
252
562
|
response_format: Optional[Type[BaseModel]] = None,
|
|
253
563
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
254
|
-
) -> Union[
|
|
564
|
+
) -> Union[
|
|
565
|
+
ChatCompletion,
|
|
566
|
+
Stream[ChatCompletionChunk],
|
|
567
|
+
ChatCompletionStreamManager[BaseModel],
|
|
568
|
+
]:
|
|
255
569
|
r"""Runs the query to the backend model.
|
|
256
570
|
|
|
257
571
|
Args:
|
|
@@ -265,24 +579,50 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
|
|
|
265
579
|
(default: :obj:`None`)
|
|
266
580
|
|
|
267
581
|
Returns:
|
|
268
|
-
Union[ChatCompletion, Stream[ChatCompletionChunk]]:
|
|
269
|
-
`ChatCompletion` in the non-stream mode,
|
|
270
|
-
`Stream[ChatCompletionChunk]` in the stream mode
|
|
582
|
+
Union[ChatCompletion, Stream[ChatCompletionChunk], Any]:
|
|
583
|
+
`ChatCompletion` in the non-stream mode,
|
|
584
|
+
`Stream[ChatCompletionChunk]` in the stream mode, or
|
|
585
|
+
`ChatCompletionStreamManager[BaseModel]` in the structured
|
|
586
|
+
stream mode.
|
|
271
587
|
"""
|
|
588
|
+
# Log the request if logging is enabled
|
|
589
|
+
log_path = self._log_request(messages)
|
|
590
|
+
|
|
272
591
|
# None -> use default tools
|
|
273
592
|
if tools is None:
|
|
274
593
|
tools = self.model_config_dict.get("tools", None)
|
|
275
594
|
# Empty -> use no tools
|
|
276
595
|
elif not tools:
|
|
277
596
|
tools = None
|
|
278
|
-
return self._run(messages, response_format, tools)
|
|
279
597
|
|
|
598
|
+
logger.info("Running model: %s", self.model_type)
|
|
599
|
+
logger.info("Messages: %s", messages)
|
|
600
|
+
logger.info("Response format: %s", response_format)
|
|
601
|
+
logger.info("Tools: %s", tools)
|
|
602
|
+
|
|
603
|
+
result = self._run(messages, response_format, tools)
|
|
604
|
+
logger.info("Result: %s", result)
|
|
605
|
+
|
|
606
|
+
# For streaming responses, wrap with logging; otherwise log immediately
|
|
607
|
+
if isinstance(result, Stream) or inspect.isgenerator(result):
|
|
608
|
+
return _SyncStreamWrapper( # type: ignore[return-value]
|
|
609
|
+
result, log_path, self._log_enabled
|
|
610
|
+
)
|
|
611
|
+
if log_path:
|
|
612
|
+
self._log_response(log_path, result)
|
|
613
|
+
return result
|
|
614
|
+
|
|
615
|
+
@observe()
|
|
280
616
|
async def arun(
|
|
281
617
|
self,
|
|
282
618
|
messages: List[OpenAIMessage],
|
|
283
619
|
response_format: Optional[Type[BaseModel]] = None,
|
|
284
620
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
285
|
-
) -> Union[
|
|
621
|
+
) -> Union[
|
|
622
|
+
ChatCompletion,
|
|
623
|
+
AsyncStream[ChatCompletionChunk],
|
|
624
|
+
AsyncChatCompletionStreamManager[BaseModel],
|
|
625
|
+
]:
|
|
286
626
|
r"""Runs the query to the backend model asynchronously.
|
|
287
627
|
|
|
288
628
|
Args:
|
|
@@ -296,26 +636,36 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
|
|
|
296
636
|
(default: :obj:`None`)
|
|
297
637
|
|
|
298
638
|
Returns:
|
|
299
|
-
Union[ChatCompletion, AsyncStream[ChatCompletionChunk]]:
|
|
300
|
-
`ChatCompletion` in the non-stream mode,
|
|
301
|
-
`AsyncStream[ChatCompletionChunk]` in the stream mode
|
|
639
|
+
Union[ChatCompletion, AsyncStream[ChatCompletionChunk], Any]:
|
|
640
|
+
`ChatCompletion` in the non-stream mode,
|
|
641
|
+
`AsyncStream[ChatCompletionChunk]` in the stream mode, or
|
|
642
|
+
`AsyncChatCompletionStreamManager[BaseModel]` in the structured
|
|
643
|
+
stream mode.
|
|
302
644
|
"""
|
|
645
|
+
# Log the request if logging is enabled
|
|
646
|
+
log_path = self._log_request(messages)
|
|
647
|
+
|
|
303
648
|
if tools is None:
|
|
304
649
|
tools = self.model_config_dict.get("tools", None)
|
|
305
650
|
elif not tools:
|
|
306
651
|
tools = None
|
|
307
|
-
return await self._arun(messages, response_format, tools)
|
|
308
652
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
653
|
+
logger.info("Running model: %s", self.model_type)
|
|
654
|
+
logger.info("Messages: %s", messages)
|
|
655
|
+
logger.info("Response format: %s", response_format)
|
|
656
|
+
logger.info("Tools: %s", tools)
|
|
313
657
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
658
|
+
result = await self._arun(messages, response_format, tools)
|
|
659
|
+
logger.info("Result: %s", result)
|
|
660
|
+
|
|
661
|
+
# For streaming responses, wrap with logging; otherwise log immediately
|
|
662
|
+
if isinstance(result, AsyncStream) or inspect.isasyncgen(result):
|
|
663
|
+
return _AsyncStreamWrapper( # type: ignore[return-value]
|
|
664
|
+
result, log_path, self._log_enabled
|
|
665
|
+
)
|
|
666
|
+
if log_path:
|
|
667
|
+
self._log_response(log_path, result)
|
|
668
|
+
return result
|
|
319
669
|
|
|
320
670
|
def count_tokens_from_messages(self, messages: List[OpenAIMessage]) -> int:
|
|
321
671
|
r"""Count the number of tokens in the messages using the specific
|
|
@@ -367,10 +717,7 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
|
|
|
367
717
|
Returns:
|
|
368
718
|
int: The maximum token limit for the given model.
|
|
369
719
|
"""
|
|
370
|
-
return
|
|
371
|
-
self.model_config_dict.get("max_tokens")
|
|
372
|
-
or self.model_type.token_limit
|
|
373
|
-
)
|
|
720
|
+
return self.model_type.token_limit
|
|
374
721
|
|
|
375
722
|
@property
|
|
376
723
|
def stream(self) -> bool:
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
# ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
14
|
+
import os
|
|
15
|
+
from typing import Any, Dict, Optional, Union
|
|
16
|
+
|
|
17
|
+
from camel.configs import CerebrasConfig
|
|
18
|
+
from camel.models.openai_compatible_model import OpenAICompatibleModel
|
|
19
|
+
from camel.types import ModelType
|
|
20
|
+
from camel.utils import (
|
|
21
|
+
BaseTokenCounter,
|
|
22
|
+
api_keys_required,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class CerebrasModel(OpenAICompatibleModel):
|
|
27
|
+
r"""LLM API served by Cerebras in a unified
|
|
28
|
+
OpenAICompatibleModel interface.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
model_type (Union[ModelType, str]): Model for which a backend is
|
|
32
|
+
created.
|
|
33
|
+
model_config_dict (Optional[Dict[str, Any]], optional): A dictionary
|
|
34
|
+
that will be fed into:obj:`openai.ChatCompletion.create()`.
|
|
35
|
+
If:obj:`None`, :obj:`CerebrasConfig().as_dict()` will be used.
|
|
36
|
+
(default: :obj:`None`)
|
|
37
|
+
api_key (Optional[str], optional): The API key for authenticating
|
|
38
|
+
with the Cerebras service. (default: :obj:`None`).
|
|
39
|
+
url (Optional[str], optional): The url to the Cerebras service.
|
|
40
|
+
(default: :obj:`None`)
|
|
41
|
+
token_counter (Optional[BaseTokenCounter], optional): Token counter to
|
|
42
|
+
use for the model. If not provided, :obj:`OpenAITokenCounter(
|
|
43
|
+
ModelType.GPT_4O_MINI)` will be used.
|
|
44
|
+
(default: :obj:`None`)
|
|
45
|
+
timeout (Optional[float], optional): The timeout value in seconds for
|
|
46
|
+
API calls. If not provided, will fall back to the MODEL_TIMEOUT
|
|
47
|
+
environment variable or default to 180 seconds.
|
|
48
|
+
(default: :obj:`None`)
|
|
49
|
+
max_retries (int, optional): Maximum number of retries for API calls.
|
|
50
|
+
(default: :obj:`3`)
|
|
51
|
+
**kwargs (Any): Additional arguments to pass to the client
|
|
52
|
+
initialization.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
@api_keys_required([("api_key", "CEREBRAS_API_KEY")])
|
|
56
|
+
def __init__(
|
|
57
|
+
self,
|
|
58
|
+
model_type: Union[ModelType, str],
|
|
59
|
+
model_config_dict: Optional[Dict[str, Any]] = None,
|
|
60
|
+
api_key: Optional[str] = None,
|
|
61
|
+
url: Optional[str] = None,
|
|
62
|
+
token_counter: Optional[BaseTokenCounter] = None,
|
|
63
|
+
timeout: Optional[float] = None,
|
|
64
|
+
max_retries: int = 3,
|
|
65
|
+
**kwargs: Any,
|
|
66
|
+
) -> None:
|
|
67
|
+
if model_config_dict is None:
|
|
68
|
+
model_config_dict = CerebrasConfig().as_dict()
|
|
69
|
+
api_key = api_key or os.environ.get("CEREBRAS_API_KEY")
|
|
70
|
+
url = url or os.environ.get(
|
|
71
|
+
"CEREBRAS_API_BASE_URL", "https://api.cerebras.ai/v1"
|
|
72
|
+
)
|
|
73
|
+
timeout = timeout or float(os.environ.get("MODEL_TIMEOUT", 180))
|
|
74
|
+
super().__init__(
|
|
75
|
+
model_type=model_type,
|
|
76
|
+
model_config_dict=model_config_dict,
|
|
77
|
+
api_key=api_key,
|
|
78
|
+
url=url,
|
|
79
|
+
token_counter=token_counter,
|
|
80
|
+
timeout=timeout,
|
|
81
|
+
max_retries=max_retries,
|
|
82
|
+
**kwargs,
|
|
83
|
+
)
|