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.

Files changed (509) hide show
  1. camel/__init__.py +3 -3
  2. camel/agents/__init__.py +2 -2
  3. camel/agents/_types.py +9 -4
  4. camel/agents/_utils.py +40 -2
  5. camel/agents/base.py +2 -2
  6. camel/agents/chat_agent.py +5107 -995
  7. camel/agents/critic_agent.py +2 -2
  8. camel/agents/deductive_reasoner_agent.py +56 -56
  9. camel/agents/embodied_agent.py +2 -2
  10. camel/agents/knowledge_graph_agent.py +20 -20
  11. camel/agents/mcp_agent.py +35 -36
  12. camel/agents/multi_hop_generator_agent.py +3 -3
  13. camel/agents/programmed_agent_instruction.py +2 -2
  14. camel/agents/repo_agent.py +4 -3
  15. camel/agents/role_assignment_agent.py +2 -2
  16. camel/agents/search_agent.py +2 -2
  17. camel/agents/task_agent.py +2 -2
  18. camel/agents/tool_agents/__init__.py +2 -2
  19. camel/agents/tool_agents/base.py +2 -2
  20. camel/agents/tool_agents/hugging_face_tool_agent.py +3 -3
  21. camel/benchmarks/__init__.py +2 -2
  22. camel/benchmarks/apibank.py +5 -5
  23. camel/benchmarks/apibench.py +2 -2
  24. camel/benchmarks/base.py +2 -2
  25. camel/benchmarks/browsecomp.py +44 -33
  26. camel/benchmarks/gaia.py +17 -13
  27. camel/benchmarks/mock_website/README.md +1 -3
  28. camel/benchmarks/mock_website/mock_web.py +2 -2
  29. camel/benchmarks/mock_website/requirements.txt +1 -1
  30. camel/benchmarks/mock_website/shopping_mall/app.py +2 -2
  31. camel/benchmarks/mock_website/task.json +1 -1
  32. camel/benchmarks/nexus.py +3 -3
  33. camel/benchmarks/ragbench.py +2 -2
  34. camel/bots/__init__.py +2 -2
  35. camel/bots/discord/__init__.py +2 -2
  36. camel/bots/discord/discord_app.py +2 -2
  37. camel/bots/discord/discord_installation.py +2 -2
  38. camel/bots/discord/discord_store.py +3 -3
  39. camel/bots/slack/__init__.py +2 -2
  40. camel/bots/slack/models.py +4 -4
  41. camel/bots/slack/slack_app.py +2 -2
  42. camel/bots/telegram_bot.py +2 -2
  43. camel/configs/__init__.py +29 -2
  44. camel/configs/aihubmix_config.py +90 -0
  45. camel/configs/aiml_config.py +2 -2
  46. camel/configs/amd_config.py +70 -0
  47. camel/configs/anthropic_config.py +2 -2
  48. camel/configs/base_config.py +2 -2
  49. camel/configs/bedrock_config.py +5 -3
  50. camel/configs/cerebras_config.py +98 -0
  51. camel/configs/cohere_config.py +2 -2
  52. camel/configs/cometapi_config.py +106 -0
  53. camel/configs/crynux_config.py +2 -2
  54. camel/configs/deepseek_config.py +9 -8
  55. camel/configs/function_gemma_config.py +59 -0
  56. camel/configs/gemini_config.py +6 -4
  57. camel/configs/groq_config.py +6 -4
  58. camel/configs/internlm_config.py +6 -4
  59. camel/configs/litellm_config.py +2 -2
  60. camel/configs/lmstudio_config.py +6 -4
  61. camel/configs/minimax_config.py +95 -0
  62. camel/configs/mistral_config.py +2 -2
  63. camel/configs/modelscope_config.py +5 -3
  64. camel/configs/moonshot_config.py +2 -2
  65. camel/configs/nebius_config.py +105 -0
  66. camel/configs/netmind_config.py +2 -2
  67. camel/configs/novita_config.py +2 -2
  68. camel/configs/nvidia_config.py +2 -2
  69. camel/configs/ollama_config.py +2 -2
  70. camel/configs/openai_config.py +5 -3
  71. camel/configs/openrouter_config.py +6 -4
  72. camel/configs/ppio_config.py +2 -2
  73. camel/configs/qianfan_config.py +85 -0
  74. camel/configs/qwen_config.py +2 -2
  75. camel/configs/reka_config.py +2 -2
  76. camel/configs/samba_config.py +6 -4
  77. camel/configs/sglang_config.py +2 -2
  78. camel/configs/siliconflow_config.py +2 -2
  79. camel/configs/togetherai_config.py +2 -2
  80. camel/configs/vllm_config.py +4 -2
  81. camel/configs/watsonx_config.py +2 -2
  82. camel/configs/yi_config.py +6 -4
  83. camel/configs/zhipuai_config.py +6 -4
  84. camel/data_collectors/__init__.py +2 -2
  85. camel/data_collectors/alpaca_collector.py +18 -9
  86. camel/data_collectors/base.py +2 -2
  87. camel/data_collectors/sharegpt_collector.py +2 -2
  88. camel/datagen/__init__.py +2 -2
  89. camel/datagen/cot_datagen.py +3 -3
  90. camel/datagen/evol_instruct/__init__.py +2 -2
  91. camel/datagen/evol_instruct/evol_instruct.py +2 -2
  92. camel/datagen/evol_instruct/scorer.py +12 -12
  93. camel/datagen/evol_instruct/templates.py +16 -16
  94. camel/datagen/self_improving_cot.py +5 -5
  95. camel/datagen/self_instruct/__init__.py +2 -2
  96. camel/datagen/self_instruct/filter/__init__.py +2 -2
  97. camel/datagen/self_instruct/filter/filter_function.py +2 -2
  98. camel/datagen/self_instruct/filter/filter_registry.py +2 -2
  99. camel/datagen/self_instruct/filter/instruction_filter.py +2 -2
  100. camel/datagen/self_instruct/self_instruct.py +2 -2
  101. camel/datagen/self_instruct/templates.py +47 -47
  102. camel/datagen/source2synth/__init__.py +2 -2
  103. camel/datagen/source2synth/data_processor.py +2 -2
  104. camel/datagen/source2synth/models.py +2 -2
  105. camel/datagen/source2synth/user_data_processor_config.py +2 -2
  106. camel/datahubs/__init__.py +2 -2
  107. camel/datahubs/base.py +2 -2
  108. camel/datahubs/huggingface.py +2 -2
  109. camel/datahubs/models.py +2 -2
  110. camel/datasets/__init__.py +2 -2
  111. camel/datasets/base_generator.py +41 -12
  112. camel/datasets/few_shot_generator.py +18 -18
  113. camel/datasets/models.py +2 -2
  114. camel/datasets/self_instruct_generator.py +2 -2
  115. camel/datasets/static_dataset.py +2 -2
  116. camel/embeddings/__init__.py +2 -2
  117. camel/embeddings/azure_embedding.py +2 -2
  118. camel/embeddings/base.py +2 -2
  119. camel/embeddings/gemini_embedding.py +2 -2
  120. camel/embeddings/jina_embedding.py +2 -2
  121. camel/embeddings/mistral_embedding.py +2 -2
  122. camel/embeddings/openai_compatible_embedding.py +2 -2
  123. camel/embeddings/openai_embedding.py +2 -2
  124. camel/embeddings/sentence_transformers_embeddings.py +2 -2
  125. camel/embeddings/together_embedding.py +2 -2
  126. camel/embeddings/vlm_embedding.py +2 -2
  127. camel/environments/__init__.py +14 -2
  128. camel/environments/models.py +2 -2
  129. camel/environments/multi_step.py +2 -2
  130. camel/environments/rlcards_env.py +860 -0
  131. camel/environments/single_step.py +30 -5
  132. camel/environments/tic_tac_toe.py +3 -3
  133. camel/extractors/__init__.py +2 -2
  134. camel/extractors/base.py +2 -2
  135. camel/extractors/python_strategies.py +2 -2
  136. camel/generators.py +2 -2
  137. camel/human.py +2 -2
  138. camel/interpreters/__init__.py +4 -2
  139. camel/interpreters/base.py +2 -2
  140. camel/interpreters/docker/Dockerfile +14 -24
  141. camel/interpreters/docker_interpreter.py +5 -4
  142. camel/interpreters/e2b_interpreter.py +36 -3
  143. camel/interpreters/internal_python_interpreter.py +53 -4
  144. camel/interpreters/interpreter_error.py +2 -2
  145. camel/interpreters/ipython_interpreter.py +2 -2
  146. camel/interpreters/microsandbox_interpreter.py +395 -0
  147. camel/interpreters/subprocess_interpreter.py +2 -2
  148. camel/loaders/__init__.py +13 -4
  149. camel/loaders/apify_reader.py +2 -2
  150. camel/loaders/base_io.py +2 -2
  151. camel/loaders/base_loader.py +85 -0
  152. camel/loaders/chunkr_reader.py +11 -2
  153. camel/loaders/crawl4ai_reader.py +2 -2
  154. camel/loaders/firecrawl_reader.py +6 -6
  155. camel/loaders/jina_url_reader.py +2 -2
  156. camel/loaders/markitdown.py +2 -2
  157. camel/loaders/mineru_extractor.py +2 -2
  158. camel/loaders/mistral_reader.py +2 -2
  159. camel/loaders/scrapegraph_reader.py +2 -2
  160. camel/loaders/unstructured_io.py +2 -2
  161. camel/logger.py +5 -5
  162. camel/memories/__init__.py +2 -2
  163. camel/memories/agent_memories.py +86 -3
  164. camel/memories/base.py +36 -2
  165. camel/memories/blocks/__init__.py +2 -2
  166. camel/memories/blocks/chat_history_block.py +125 -7
  167. camel/memories/blocks/vectordb_block.py +10 -3
  168. camel/memories/context_creators/__init__.py +2 -2
  169. camel/memories/context_creators/score_based.py +109 -230
  170. camel/memories/records.py +90 -10
  171. camel/messages/__init__.py +2 -2
  172. camel/messages/base.py +178 -43
  173. camel/messages/conversion/__init__.py +2 -2
  174. camel/messages/conversion/alpaca.py +2 -2
  175. camel/messages/conversion/conversation_models.py +2 -2
  176. camel/messages/conversion/sharegpt/__init__.py +2 -2
  177. camel/messages/conversion/sharegpt/function_call_formatter.py +2 -2
  178. camel/messages/conversion/sharegpt/hermes/__init__.py +2 -2
  179. camel/messages/conversion/sharegpt/hermes/hermes_function_formatter.py +2 -2
  180. camel/messages/func_message.py +54 -17
  181. camel/models/__init__.py +18 -2
  182. camel/models/_utils.py +3 -3
  183. camel/models/aihubmix_model.py +83 -0
  184. camel/models/aiml_model.py +11 -18
  185. camel/models/amd_model.py +101 -0
  186. camel/models/anthropic_model.py +127 -20
  187. camel/models/aws_bedrock_model.py +12 -35
  188. camel/models/azure_openai_model.py +214 -115
  189. camel/models/base_audio_model.py +5 -3
  190. camel/models/base_model.py +378 -31
  191. camel/models/cerebras_model.py +83 -0
  192. camel/models/cohere_model.py +18 -49
  193. camel/models/cometapi_model.py +83 -0
  194. camel/models/crynux_model.py +11 -18
  195. camel/models/deepseek_model.py +20 -84
  196. camel/models/fish_audio_model.py +8 -2
  197. camel/models/function_gemma_model.py +889 -0
  198. camel/models/gemini_model.py +391 -52
  199. camel/models/groq_model.py +11 -19
  200. camel/models/internlm_model.py +11 -18
  201. camel/models/litellm_model.py +57 -49
  202. camel/models/lmstudio_model.py +17 -20
  203. camel/models/minimax_model.py +83 -0
  204. camel/models/mistral_model.py +20 -47
  205. camel/models/model_factory.py +39 -3
  206. camel/models/model_manager.py +26 -8
  207. camel/models/modelscope_model.py +13 -193
  208. camel/models/moonshot_model.py +183 -21
  209. camel/models/nebius_model.py +83 -0
  210. camel/models/nemotron_model.py +19 -9
  211. camel/models/netmind_model.py +11 -18
  212. camel/models/novita_model.py +11 -18
  213. camel/models/nvidia_model.py +11 -18
  214. camel/models/ollama_model.py +14 -21
  215. camel/models/openai_audio_models.py +2 -2
  216. camel/models/openai_compatible_model.py +190 -71
  217. camel/models/openai_model.py +192 -86
  218. camel/models/openrouter_model.py +11 -19
  219. camel/models/ppio_model.py +11 -18
  220. camel/models/qianfan_model.py +89 -0
  221. camel/models/qwen_model.py +13 -193
  222. camel/models/reka_model.py +23 -49
  223. camel/models/reward/__init__.py +2 -2
  224. camel/models/reward/base_reward_model.py +2 -2
  225. camel/models/reward/evaluator.py +2 -2
  226. camel/models/reward/nemotron_model.py +2 -2
  227. camel/models/reward/skywork_model.py +2 -2
  228. camel/models/samba_model.py +50 -75
  229. camel/models/sglang_model.py +90 -68
  230. camel/models/siliconflow_model.py +12 -35
  231. camel/models/stub_model.py +10 -7
  232. camel/models/togetherai_model.py +11 -18
  233. camel/models/vllm_model.py +10 -18
  234. camel/models/volcano_model.py +158 -19
  235. camel/models/watsonx_model.py +9 -47
  236. camel/models/yi_model.py +11 -18
  237. camel/models/zhipuai_model.py +70 -18
  238. camel/parsers/__init__.py +18 -0
  239. camel/parsers/mcp_tool_call_parser.py +176 -0
  240. camel/personas/__init__.py +2 -2
  241. camel/personas/persona.py +2 -2
  242. camel/personas/persona_hub.py +2 -2
  243. camel/prompts/__init__.py +2 -2
  244. camel/prompts/ai_society.py +2 -2
  245. camel/prompts/base.py +2 -2
  246. camel/prompts/code.py +2 -2
  247. camel/prompts/evaluation.py +2 -2
  248. camel/prompts/generate_text_embedding_data.py +2 -2
  249. camel/prompts/image_craft.py +2 -2
  250. camel/prompts/misalignment.py +2 -2
  251. camel/prompts/multi_condition_image_craft.py +2 -2
  252. camel/prompts/object_recognition.py +2 -2
  253. camel/prompts/persona_hub.py +3 -3
  254. camel/prompts/prompt_templates.py +2 -2
  255. camel/prompts/role_description_prompt_template.py +2 -2
  256. camel/prompts/solution_extraction.py +8 -8
  257. camel/prompts/task_prompt_template.py +2 -2
  258. camel/prompts/translation.py +2 -2
  259. camel/prompts/video_description_prompt.py +3 -3
  260. camel/responses/__init__.py +2 -2
  261. camel/responses/agent_responses.py +2 -2
  262. camel/retrievers/__init__.py +2 -2
  263. camel/retrievers/auto_retriever.py +3 -2
  264. camel/retrievers/base.py +2 -2
  265. camel/retrievers/bm25_retriever.py +2 -2
  266. camel/retrievers/cohere_rerank_retriever.py +2 -2
  267. camel/retrievers/hybrid_retrival.py +2 -2
  268. camel/retrievers/vector_retriever.py +2 -2
  269. camel/runtimes/Dockerfile.multi-toolkit +90 -0
  270. camel/runtimes/__init__.py +2 -2
  271. camel/runtimes/api.py +79 -23
  272. camel/runtimes/base.py +2 -2
  273. camel/runtimes/configs.py +13 -13
  274. camel/runtimes/daytona_runtime.py +17 -18
  275. camel/runtimes/docker_runtime.py +12 -12
  276. camel/runtimes/llm_guard_runtime.py +26 -26
  277. camel/runtimes/remote_http_runtime.py +11 -11
  278. camel/runtimes/ubuntu_docker_runtime.py +2 -2
  279. camel/runtimes/utils/__init__.py +2 -2
  280. camel/runtimes/utils/function_risk_toolkit.py +2 -2
  281. camel/runtimes/utils/ignore_risk_toolkit.py +2 -2
  282. camel/schemas/__init__.py +2 -2
  283. camel/schemas/base.py +2 -2
  284. camel/schemas/openai_converter.py +3 -3
  285. camel/schemas/outlines_converter.py +2 -2
  286. camel/services/agent_openapi_server.py +380 -0
  287. camel/societies/__init__.py +4 -2
  288. camel/societies/babyagi_playing.py +2 -2
  289. camel/societies/role_playing.py +201 -80
  290. camel/societies/workforce/__init__.py +10 -3
  291. camel/societies/workforce/base.py +2 -2
  292. camel/societies/workforce/events.py +145 -0
  293. camel/societies/workforce/prompts.py +259 -33
  294. camel/societies/workforce/role_playing_worker.py +88 -31
  295. camel/societies/workforce/single_agent_worker.py +638 -40
  296. camel/societies/workforce/structured_output_handler.py +512 -0
  297. camel/societies/workforce/task_channel.py +182 -38
  298. camel/societies/workforce/utils.py +780 -65
  299. camel/societies/workforce/worker.py +92 -26
  300. camel/societies/workforce/workflow_memory_manager.py +1746 -0
  301. camel/societies/workforce/workforce.py +5354 -372
  302. camel/societies/workforce/workforce_callback.py +103 -0
  303. camel/societies/workforce/workforce_logger.py +647 -0
  304. camel/societies/workforce/workforce_metrics.py +33 -0
  305. camel/storages/__init__.py +6 -2
  306. camel/storages/graph_storages/__init__.py +2 -2
  307. camel/storages/graph_storages/base.py +2 -2
  308. camel/storages/graph_storages/graph_element.py +2 -2
  309. camel/storages/graph_storages/nebula_graph.py +4 -4
  310. camel/storages/graph_storages/neo4j_graph.py +7 -7
  311. camel/storages/key_value_storages/__init__.py +2 -2
  312. camel/storages/key_value_storages/base.py +2 -2
  313. camel/storages/key_value_storages/in_memory.py +2 -2
  314. camel/storages/key_value_storages/json.py +17 -4
  315. camel/storages/key_value_storages/mem0_cloud.py +50 -49
  316. camel/storages/key_value_storages/redis.py +2 -2
  317. camel/storages/object_storages/__init__.py +2 -2
  318. camel/storages/object_storages/amazon_s3.py +2 -2
  319. camel/storages/object_storages/azure_blob.py +2 -2
  320. camel/storages/object_storages/base.py +2 -2
  321. camel/storages/object_storages/google_cloud.py +3 -3
  322. camel/storages/vectordb_storages/__init__.py +8 -2
  323. camel/storages/vectordb_storages/base.py +2 -2
  324. camel/storages/vectordb_storages/chroma.py +731 -0
  325. camel/storages/vectordb_storages/faiss.py +2 -2
  326. camel/storages/vectordb_storages/milvus.py +2 -2
  327. camel/storages/vectordb_storages/oceanbase.py +15 -15
  328. camel/storages/vectordb_storages/pgvector.py +349 -0
  329. camel/storages/vectordb_storages/qdrant.py +6 -6
  330. camel/storages/vectordb_storages/surreal.py +372 -0
  331. camel/storages/vectordb_storages/tidb.py +11 -8
  332. camel/storages/vectordb_storages/weaviate.py +2 -2
  333. camel/tasks/__init__.py +2 -2
  334. camel/tasks/task.py +348 -26
  335. camel/tasks/task_prompt.py +3 -3
  336. camel/terminators/__init__.py +2 -2
  337. camel/terminators/base.py +2 -2
  338. camel/terminators/response_terminator.py +2 -2
  339. camel/terminators/token_limit_terminator.py +2 -2
  340. camel/toolkits/__init__.py +57 -10
  341. camel/toolkits/aci_toolkit.py +66 -21
  342. camel/toolkits/arxiv_toolkit.py +8 -8
  343. camel/toolkits/ask_news_toolkit.py +2 -2
  344. camel/toolkits/async_browser_toolkit.py +4 -4
  345. camel/toolkits/audio_analysis_toolkit.py +3 -3
  346. camel/toolkits/base.py +106 -6
  347. camel/toolkits/bohrium_toolkit.py +2 -2
  348. camel/toolkits/browser_toolkit.py +34 -21
  349. camel/toolkits/browser_toolkit_commons.py +4 -4
  350. camel/toolkits/code_execution.py +31 -4
  351. camel/toolkits/context_summarizer_toolkit.py +684 -0
  352. camel/toolkits/craw4ai_toolkit.py +93 -0
  353. camel/toolkits/dappier_toolkit.py +12 -8
  354. camel/toolkits/data_commons_toolkit.py +2 -2
  355. camel/toolkits/dingtalk.py +1135 -0
  356. camel/toolkits/earth_science_toolkit.py +5367 -0
  357. camel/toolkits/edgeone_pages_mcp_toolkit.py +49 -0
  358. camel/toolkits/excel_toolkit.py +905 -71
  359. camel/toolkits/file_toolkit.py +1402 -0
  360. camel/toolkits/function_tool.py +205 -27
  361. camel/toolkits/github_toolkit.py +109 -22
  362. camel/toolkits/gmail_toolkit.py +1839 -0
  363. camel/toolkits/google_calendar_toolkit.py +40 -6
  364. camel/toolkits/google_drive_mcp_toolkit.py +54 -0
  365. camel/toolkits/google_maps_toolkit.py +2 -2
  366. camel/toolkits/google_scholar_toolkit.py +2 -2
  367. camel/toolkits/human_toolkit.py +36 -12
  368. camel/toolkits/hybrid_browser_toolkit/__init__.py +18 -0
  369. camel/toolkits/hybrid_browser_toolkit/config_loader.py +185 -0
  370. camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +246 -0
  371. camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +1958 -0
  372. camel/toolkits/hybrid_browser_toolkit/installer.py +203 -0
  373. camel/toolkits/hybrid_browser_toolkit/ts/package-lock.json +4589 -0
  374. camel/toolkits/hybrid_browser_toolkit/ts/package.json +33 -0
  375. camel/toolkits/hybrid_browser_toolkit/ts/src/browser-scripts.js +125 -0
  376. camel/toolkits/hybrid_browser_toolkit/ts/src/browser-session.ts +1940 -0
  377. camel/toolkits/hybrid_browser_toolkit/ts/src/config-loader.ts +233 -0
  378. camel/toolkits/hybrid_browser_toolkit/ts/src/hybrid-browser-toolkit.ts +589 -0
  379. camel/toolkits/hybrid_browser_toolkit/ts/src/index.ts +7 -0
  380. camel/toolkits/hybrid_browser_toolkit/ts/src/parent-child-filter.ts +226 -0
  381. camel/toolkits/hybrid_browser_toolkit/ts/src/snapshot-parser.ts +219 -0
  382. camel/toolkits/hybrid_browser_toolkit/ts/src/som-screenshot-injected.ts +543 -0
  383. camel/toolkits/hybrid_browser_toolkit/ts/src/types.ts +129 -0
  384. camel/toolkits/hybrid_browser_toolkit/ts/tsconfig.json +27 -0
  385. camel/toolkits/hybrid_browser_toolkit/ts/websocket-server.js +325 -0
  386. camel/toolkits/hybrid_browser_toolkit/ws_wrapper.py +1037 -0
  387. camel/toolkits/hybrid_browser_toolkit_py/__init__.py +17 -0
  388. camel/toolkits/hybrid_browser_toolkit_py/actions.py +575 -0
  389. camel/toolkits/hybrid_browser_toolkit_py/agent.py +311 -0
  390. camel/toolkits/hybrid_browser_toolkit_py/browser_session.py +787 -0
  391. camel/toolkits/hybrid_browser_toolkit_py/config_loader.py +490 -0
  392. camel/toolkits/hybrid_browser_toolkit_py/hybrid_browser_toolkit.py +2390 -0
  393. camel/toolkits/hybrid_browser_toolkit_py/snapshot.py +233 -0
  394. camel/toolkits/hybrid_browser_toolkit_py/stealth_script.js +0 -0
  395. camel/toolkits/hybrid_browser_toolkit_py/unified_analyzer.js +1043 -0
  396. camel/toolkits/image_analysis_toolkit.py +3 -6
  397. camel/toolkits/image_generation_toolkit.py +390 -0
  398. camel/toolkits/jina_reranker_toolkit.py +5 -6
  399. camel/toolkits/klavis_toolkit.py +7 -3
  400. camel/toolkits/linkedin_toolkit.py +2 -2
  401. camel/toolkits/markitdown_toolkit.py +104 -0
  402. camel/toolkits/math_toolkit.py +66 -12
  403. camel/toolkits/mcp_toolkit.py +412 -36
  404. camel/toolkits/memory_toolkit.py +7 -3
  405. camel/toolkits/meshy_toolkit.py +2 -2
  406. camel/toolkits/message_agent_toolkit.py +608 -0
  407. camel/toolkits/message_integration.py +728 -0
  408. camel/toolkits/microsoft_outlook_mail_toolkit.py +1885 -0
  409. camel/toolkits/mineru_toolkit.py +2 -2
  410. camel/toolkits/minimax_mcp_toolkit.py +195 -0
  411. camel/toolkits/networkx_toolkit.py +2 -2
  412. camel/toolkits/note_taking_toolkit.py +277 -0
  413. camel/toolkits/notion_mcp_toolkit.py +224 -0
  414. camel/toolkits/notion_toolkit.py +2 -2
  415. camel/toolkits/open_api_specs/biztoc/__init__.py +2 -2
  416. camel/toolkits/open_api_specs/biztoc/ai-plugin.json +1 -1
  417. camel/toolkits/open_api_specs/coursera/__init__.py +2 -2
  418. camel/toolkits/open_api_specs/create_qr_code/__init__.py +2 -2
  419. camel/toolkits/open_api_specs/klarna/__init__.py +2 -2
  420. camel/toolkits/open_api_specs/nasa_apod/__init__.py +2 -2
  421. camel/toolkits/open_api_specs/outschool/__init__.py +2 -2
  422. camel/toolkits/open_api_specs/outschool/ai-plugin.json +1 -1
  423. camel/toolkits/open_api_specs/outschool/openapi.yaml +1 -1
  424. camel/toolkits/open_api_specs/outschool/paths/__init__.py +2 -2
  425. camel/toolkits/open_api_specs/outschool/paths/get_classes.py +2 -2
  426. camel/toolkits/open_api_specs/outschool/paths/search_teachers.py +2 -2
  427. camel/toolkits/open_api_specs/security_config.py +2 -2
  428. camel/toolkits/open_api_specs/speak/__init__.py +2 -2
  429. camel/toolkits/open_api_specs/web_scraper/__init__.py +2 -2
  430. camel/toolkits/open_api_specs/web_scraper/ai-plugin.json +1 -1
  431. camel/toolkits/open_api_specs/web_scraper/paths/__init__.py +2 -2
  432. camel/toolkits/open_api_specs/web_scraper/paths/scraper.py +2 -2
  433. camel/toolkits/open_api_toolkit.py +2 -2
  434. camel/toolkits/openbb_toolkit.py +7 -3
  435. camel/toolkits/origene_mcp_toolkit.py +56 -0
  436. camel/toolkits/page_script.js +53 -53
  437. camel/toolkits/playwright_mcp_toolkit.py +13 -31
  438. camel/toolkits/pptx_toolkit.py +36 -23
  439. camel/toolkits/pubmed_toolkit.py +2 -2
  440. camel/toolkits/pulse_mcp_search_toolkit.py +2 -2
  441. camel/toolkits/pyautogui_toolkit.py +2 -2
  442. camel/toolkits/reddit_toolkit.py +2 -2
  443. camel/toolkits/resend_toolkit.py +168 -0
  444. camel/toolkits/retrieval_toolkit.py +2 -2
  445. camel/toolkits/screenshot_toolkit.py +213 -0
  446. camel/toolkits/search_toolkit.py +606 -156
  447. camel/toolkits/searxng_toolkit.py +2 -2
  448. camel/toolkits/semantic_scholar_toolkit.py +2 -2
  449. camel/toolkits/slack_toolkit.py +108 -58
  450. camel/toolkits/sql_toolkit.py +712 -0
  451. camel/toolkits/stripe_toolkit.py +2 -2
  452. camel/toolkits/sympy_toolkit.py +3 -3
  453. camel/toolkits/task_planning_toolkit.py +5 -5
  454. camel/toolkits/terminal_toolkit/__init__.py +18 -0
  455. camel/toolkits/terminal_toolkit/terminal_toolkit.py +1281 -0
  456. camel/toolkits/terminal_toolkit/utils.py +659 -0
  457. camel/toolkits/thinking_toolkit.py +3 -3
  458. camel/toolkits/twitter_toolkit.py +2 -2
  459. camel/toolkits/vertex_ai_veo_toolkit.py +590 -0
  460. camel/toolkits/video_analysis_toolkit.py +109 -29
  461. camel/toolkits/video_download_toolkit.py +19 -16
  462. camel/toolkits/weather_toolkit.py +2 -2
  463. camel/toolkits/web_deploy_toolkit.py +1219 -0
  464. camel/toolkits/wechat_official_toolkit.py +483 -0
  465. camel/toolkits/whatsapp_toolkit.py +2 -2
  466. camel/toolkits/wolfram_alpha_toolkit.py +2 -2
  467. camel/toolkits/zapier_toolkit.py +7 -3
  468. camel/types/__init__.py +4 -4
  469. camel/types/agents/__init__.py +2 -2
  470. camel/types/agents/tool_calling_record.py +6 -3
  471. camel/types/enums.py +381 -41
  472. camel/types/mcp_registries.py +2 -2
  473. camel/types/openai_types.py +4 -4
  474. camel/types/unified_model_type.py +46 -10
  475. camel/utils/__init__.py +5 -2
  476. camel/utils/agent_context.py +41 -0
  477. camel/utils/async_func.py +2 -2
  478. camel/utils/chunker/__init__.py +2 -2
  479. camel/utils/chunker/base.py +2 -2
  480. camel/utils/chunker/code_chunker.py +2 -2
  481. camel/utils/chunker/uio_chunker.py +2 -2
  482. camel/utils/commons.py +38 -7
  483. camel/utils/constants.py +5 -2
  484. camel/utils/context_utils.py +1134 -0
  485. camel/utils/deduplication.py +2 -2
  486. camel/utils/filename.py +2 -2
  487. camel/utils/langfuse.py +18 -10
  488. camel/utils/mcp.py +140 -6
  489. camel/utils/mcp_client.py +48 -38
  490. camel/utils/message_summarizer.py +148 -0
  491. camel/utils/response_format.py +2 -2
  492. camel/utils/token_counting.py +45 -22
  493. camel/utils/tool_result.py +44 -0
  494. camel/verifiers/__init__.py +2 -2
  495. camel/verifiers/base.py +2 -2
  496. camel/verifiers/math_verifier.py +2 -2
  497. camel/verifiers/models.py +2 -2
  498. camel/verifiers/physics_verifier.py +2 -2
  499. camel/verifiers/python_verifier.py +2 -2
  500. {camel_ai-0.2.65.dist-info → camel_ai-0.2.83a6.dist-info}/METADATA +355 -117
  501. camel_ai-0.2.83a6.dist-info/RECORD +511 -0
  502. {camel_ai-0.2.65.dist-info → camel_ai-0.2.83a6.dist-info}/WHEEL +1 -1
  503. {camel_ai-0.2.65.dist-info → camel_ai-0.2.83a6.dist-info}/licenses/LICENSE +1 -1
  504. camel/loaders/pandas_reader.py +0 -368
  505. camel/toolkits/dalle_toolkit.py +0 -175
  506. camel/toolkits/file_write_toolkit.py +0 -444
  507. camel/toolkits/openai_agent_toolkit.py +0 -135
  508. camel/toolkits/terminal_toolkit.py +0 -1037
  509. camel_ai-0.2.65.dist-info/RECORD +0 -426
@@ -0,0 +1,684 @@
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
+
15
+ import glob
16
+ import os
17
+ from datetime import datetime
18
+ from pathlib import Path
19
+ from typing import TYPE_CHECKING, List, Optional
20
+
21
+ from camel.logger import get_logger
22
+ from camel.toolkits import FunctionTool
23
+ from camel.toolkits.base import BaseToolkit
24
+ from camel.utils.context_utils import ContextUtility
25
+
26
+ if TYPE_CHECKING:
27
+ from camel.agents import ChatAgent
28
+ from camel.memories.records import MemoryRecord
29
+
30
+ logger = get_logger(__name__)
31
+
32
+
33
+ class ContextSummarizerToolkit(BaseToolkit):
34
+ r"""A toolkit that provides intelligent context summarization and
35
+ management for agents.
36
+
37
+ This toolkit enables agents to compress conversation context through
38
+ intelligent summarization, save conversation history to markdown files,
39
+ and search through past conversations. It handles all context management
40
+ needs in a single toolkit.
41
+
42
+ Key features:
43
+ - Intelligent context compression with over-compression prevention
44
+ - Markdown file storage with session management
45
+ - Simple text-based search through conversation history
46
+ - Configurable summarization prompts
47
+ - Context loading and saving capabilities
48
+ """
49
+
50
+ def __init__(
51
+ self,
52
+ agent: "ChatAgent",
53
+ working_directory: Optional[str] = None,
54
+ timeout: Optional[float] = None,
55
+ summary_prompt_template: Optional[str] = None,
56
+ ):
57
+ r"""Initialize the ContextSummarizerToolkit.
58
+
59
+ Args:
60
+ agent (ChatAgent): The agent that is using the toolkit.
61
+ This is required to access the agent's memory.
62
+ working_directory (str, optional): The directory path where notes
63
+ will be stored. If not provided, a default directory will be
64
+ used.
65
+ timeout (Optional[float]): The timeout for the toolkit.
66
+ summary_prompt_template (Optional[str]): Custom prompt template
67
+ for summarization. If None, a default task-focused template
68
+ is used. Users can customize this for different use cases.
69
+ """
70
+ super().__init__(timeout=timeout)
71
+
72
+ self.agent = agent
73
+ self.working_directory_param = working_directory
74
+ self.summary_prompt_template = summary_prompt_template
75
+
76
+ # compression tracking to prevent over-compression
77
+ self.compressed_message_uuids: set = set()
78
+ self.compression_count = 0
79
+ self.existing_summary: Optional[str] = ""
80
+
81
+ # Create a separate agent for summarization without tools to avoid
82
+ # circular calls
83
+ from camel.agents import ChatAgent
84
+
85
+ self.summary_agent = ChatAgent(
86
+ system_message="You are a helpful assistant that creates concise "
87
+ "summaries of conversations.",
88
+ model=self.agent.model_backend,
89
+ agent_id=f"{self.agent.agent_id}_summarizer",
90
+ )
91
+
92
+ # Setup storage and file management using ContextUtility
93
+ self._setup_storage(working_directory)
94
+
95
+ def _setup_storage(self, working_directory: Optional[str]) -> None:
96
+ r"""Initialize storage paths and create session-specific directories
97
+ using ContextUtility for file management."""
98
+ # Determine the base directory for context compression
99
+ if working_directory:
100
+ base_dir = working_directory
101
+ else:
102
+ camel_workdir = os.environ.get("CAMEL_WORKDIR")
103
+ if camel_workdir:
104
+ base_dir = str(Path(camel_workdir) / "context_compression")
105
+ else:
106
+ base_dir = "context_compression"
107
+
108
+ # Initialize ContextUtility with the base directory
109
+ self.context_util = ContextUtility(working_directory=base_dir)
110
+
111
+ # Store references for compatibility
112
+ self.working_directory = self.context_util.get_working_directory()
113
+ self.session_id = self.context_util.get_session_id()
114
+
115
+ # File names
116
+ self.summary_filename = "agent_memory_summary"
117
+ self.history_filename = "agent_memory_history"
118
+
119
+ # ========= CORE COMPRESSION METHODS =========
120
+
121
+ def _summarize_messages(
122
+ self,
123
+ memory_records: List["MemoryRecord"],
124
+ ) -> str:
125
+ r"""Generate a summary of the conversation context.
126
+
127
+ Args:
128
+ memory_records (List["MemoryRecord"]): A list of memory records to
129
+ summarize.
130
+
131
+ Returns:
132
+ str: The summary of the conversation context.
133
+ """
134
+ if not memory_records:
135
+ logger.warning(
136
+ "No memory records provided. Returning existing summary."
137
+ )
138
+ return self.existing_summary or ""
139
+
140
+ # check for over-compression prevention
141
+ record_uuids = {record.uuid for record in memory_records}
142
+ already_compressed = record_uuids.intersection(
143
+ self.compressed_message_uuids
144
+ )
145
+
146
+ if already_compressed:
147
+ logger.warning(
148
+ f"Preventing over-compression: {len(already_compressed)} "
149
+ f"records have already been compressed. Returning existing "
150
+ f"summary."
151
+ )
152
+ return self.existing_summary or ""
153
+
154
+ try:
155
+ # 1. reset summary agent state for clean summarization
156
+ self.summary_agent.reset()
157
+
158
+ # 2. format the conversation
159
+ conversation_text = self._format_conversation(memory_records)
160
+
161
+ # 3. create the summary prompt
162
+ summary_prompt = self._create_summary_prompt(conversation_text)
163
+
164
+ # 4. generate summary using the agent
165
+ response = self.summary_agent.step(summary_prompt)
166
+
167
+ # 5. extract the summary from response and store
168
+ summary_content = response.msgs[-1].content.strip()
169
+ self.existing_summary = summary_content
170
+
171
+ # 6. mark these records as compressed to prevent re-compression
172
+ record_uuids = {record.uuid for record in memory_records}
173
+ self.compressed_message_uuids.update(record_uuids)
174
+ self.compression_count += 1
175
+
176
+ logger.info(
177
+ f"Successfully generated summary for {len(memory_records)} "
178
+ f"messages. Compression count: {self.compression_count}"
179
+ )
180
+ return summary_content
181
+
182
+ except Exception as e:
183
+ logger.error(f"Error generating summary: {e}")
184
+ return self.existing_summary or ""
185
+
186
+ def _save_summary(self, summary: str) -> str:
187
+ r"""Persist conversation summary to markdown file with metadata
188
+ including timestamp and session information.
189
+
190
+ Args:
191
+ summary (str): The summary text to save.
192
+
193
+ Returns:
194
+ str: "success" or error message starting with "Error:".
195
+ """
196
+ try:
197
+ # prepare metadata for unified markdown saving
198
+ timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
199
+ metadata = {
200
+ 'Save Time': timestamp,
201
+ 'Session ID': self.session_id,
202
+ }
203
+
204
+ # use ContextUtility's unified markdown saving
205
+ return self.context_util.save_markdown_file(
206
+ filename=self.summary_filename,
207
+ content=f"## Summary\n\n{summary}\n",
208
+ title=f"Conversation Summary: {self.session_id}",
209
+ metadata=metadata,
210
+ )
211
+ except Exception as e:
212
+ logger.error(f"Error saving summary: {e}")
213
+ return f"Error saving summary: {e}"
214
+
215
+ def _save_history(self, memory_records: List["MemoryRecord"]) -> str:
216
+ r"""Export complete conversation transcript as formatted markdown
217
+ with message roles, agent IDs, and content structure preserved.
218
+
219
+ Args:
220
+ memory_records (List["MemoryRecord"]): The list of memory records
221
+ to save.
222
+
223
+ Returns:
224
+ str: "success" or error message starting with "Error:".
225
+ """
226
+ try:
227
+ # prepare metadata for markdown saving
228
+ timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
229
+ metadata = {
230
+ 'Save Time': timestamp,
231
+ 'Total Messages': len(memory_records),
232
+ 'Session ID': self.session_id,
233
+ }
234
+
235
+ # format the transcript for markdown
236
+ transcript_content = "## Full Transcript\n\n"
237
+ for i, record in enumerate(memory_records):
238
+ message = record.message
239
+ role = getattr(message, "role_name", "unknown")
240
+ content = getattr(message, "content", str(message))
241
+ agent_id = record.agent_id or "unknown"
242
+ role_at_backend = (
243
+ record.role_at_backend.value
244
+ if hasattr(record.role_at_backend, 'value')
245
+ else str(record.role_at_backend)
246
+ )
247
+
248
+ transcript_content += f"### Message {i + 1} - {role}\n"
249
+ transcript_content += f"**Agent ID:** {agent_id} \n"
250
+ transcript_content += (
251
+ f"**Backend Role:** {role_at_backend} \n"
252
+ )
253
+ transcript_content += f"**Content:**\n```\n{content}\n```\n\n"
254
+ transcript_content += "---\n\n"
255
+
256
+ # use ContextUtility's markdown saving
257
+ return self.context_util.save_markdown_file(
258
+ filename=self.history_filename,
259
+ content=transcript_content,
260
+ title=f"Conversation History: {self.session_id}",
261
+ metadata=metadata,
262
+ )
263
+ except Exception as e:
264
+ logger.error(f"Error saving history: {e}")
265
+ return f"Error saving history: {e}"
266
+
267
+ def _compress_and_save(self, memory_records: List["MemoryRecord"]) -> str:
268
+ r"""Complete compression pipeline: summarize and save both history and
269
+ summary.
270
+
271
+ Args:
272
+ memory_records (List["MemoryRecord"]): The memory records to
273
+ compress and save.
274
+
275
+ Returns:
276
+ str: The generated summary text.
277
+ """
278
+ try:
279
+ # generate summary
280
+ summary = self._summarize_messages(memory_records)
281
+
282
+ # save both history and summary
283
+ history_result = self._save_history(memory_records)
284
+ summary_result = self._save_summary(summary)
285
+
286
+ if "Error" not in history_result and "Error" not in summary_result:
287
+ return summary
288
+ else:
289
+ error_msg = (
290
+ f"Compression partially failed. History: {history_result},"
291
+ f" Summary: {summary_result}"
292
+ )
293
+ logger.error(error_msg)
294
+ raise Exception(error_msg)
295
+
296
+ except Exception as e:
297
+ logger.error(f"Error in compress_and_save: {e}")
298
+ return self.existing_summary or ""
299
+
300
+ # ========= FILE MANAGEMENT METHODS =========
301
+
302
+ def _load_summary(self) -> str:
303
+ r"""Retrieve previously saved conversation summary from disk
304
+ for context restoration or continuation.
305
+
306
+ Returns:
307
+ str: The summary content, or empty string if not found.
308
+ """
309
+ return self.context_util.load_markdown_file(self.summary_filename)
310
+
311
+ def _load_history(self) -> str:
312
+ r"""Retrieve complete conversation transcript from saved markdown
313
+ file including all message details and formatting.
314
+
315
+ Returns:
316
+ str: The history content, or empty string if not found.
317
+ """
318
+ return self.context_util.load_markdown_file(self.history_filename)
319
+
320
+ # ========= PROMPT GENERATION METHODS =========
321
+
322
+ def _format_conversation(
323
+ self,
324
+ memory_records: List["MemoryRecord"],
325
+ ) -> str:
326
+ r"""Convert memory records into human-readable conversation format
327
+ with role names and message content for summarization processing.
328
+
329
+ Args:
330
+ memory_records (List["MemoryRecord"]): A list of memory records to
331
+ format.
332
+
333
+ Returns:
334
+ str: The formatted conversation.
335
+ """
336
+ return self.context_util.format_memory_as_conversation(memory_records)
337
+
338
+ def _create_summary_prompt(
339
+ self,
340
+ conversation_text: str,
341
+ ) -> str:
342
+ r"""Construct detailed summarization prompt with instructions
343
+ for extracting key information, goals, and progress from conversation.
344
+
345
+ Args:
346
+ conversation_text (str): The formatted conversation to summarize.
347
+
348
+ Returns:
349
+ str: The complete prompt for summarization.
350
+ """
351
+
352
+ # use custom template if provided, otherwise use default
353
+ if self.summary_prompt_template:
354
+ base_prompt = self.summary_prompt_template
355
+ else:
356
+ base_prompt = """The following is a conversation history of a \
357
+ large language model agent.
358
+ Analyze it and extract the key information from it. The information will be
359
+ passed on to a new agent that will use it to understand the problem and \
360
+ continue working on it without having to start from scratch. Focus on:
361
+ - User's main goal (e.g. "The user wants my help with data analysis of \
362
+ customer sales data.")
363
+ - Key information about the user and their preferences (e.g. "The user is a \
364
+ student who prefers concise bullet-point responses.")
365
+ - Tasks that were accomplished (e.g. "I found the top 10 customers by total \
366
+ sales amounts, wrote a Python script to...")
367
+ - Tools and methods that were used **if tool/function calls have been made** \
368
+ (e.g. "I used CodeExecutionToolkit to execute a Python script to analyze the \
369
+ data.")
370
+ - Important discoveries or solutions found (e.g. "I found there are duplicate \
371
+ entries in the customer name column, which must be taken care of before \
372
+ proceeding with the analysis.")
373
+ - Technical approaches that worked **if the task is technical** (e.g. "Using \
374
+ Pandas + matplotlib seem to yield the best responses for the user's \
375
+ queries.)
376
+ Return only there summary with no preamble or extra words"""
377
+
378
+ # if we want to extend an existing summary
379
+ if self.existing_summary:
380
+ base_prompt += f"""
381
+
382
+ Existing summary from before:
383
+ {self.existing_summary}
384
+
385
+ Provide an updated summary that incorporates both the previous work and the \
386
+ new conversation."""
387
+
388
+ prompt = f"""{base_prompt}
389
+
390
+ Conversation:
391
+ {conversation_text}
392
+
393
+ Summary:"""
394
+ return prompt
395
+
396
+ # ========= PUBLIC TOOL INTERFACE METHODS =========
397
+
398
+ def summarize_full_conversation_history(self) -> str:
399
+ r"""Save the conversation history and generate an intelligent summary.
400
+
401
+ This function should be used when the memory becomes cluttered with too
402
+ many unrelated conversations or information that might be irrelevant to
403
+ the core task. It will generate a summary and save both the summary
404
+ and full conversation history to markdown files. Then it clears the
405
+ memory and replaces it with the summary for a context refresh. The
406
+ conversation must flow naturally from the summary.
407
+
408
+ Returns:
409
+ str: Success message with brief summary, or error message.
410
+ """
411
+ try:
412
+ # Get memory records using ContextUtility
413
+ memory_records = self.context_util.get_agent_memory_records(
414
+ self.agent
415
+ )
416
+ message_count = len(memory_records)
417
+
418
+ if message_count == 0:
419
+ return "No conversation history found to save."
420
+
421
+ # Use compression service directly to avoid tool calling loops
422
+ summary = self._compress_and_save(memory_records)
423
+
424
+ # empty memory and replace it with the summary
425
+ self._refresh_context_with_summary(summary)
426
+
427
+ logger.info(
428
+ f"Context compression completed - {message_count} "
429
+ f"messages processed"
430
+ )
431
+
432
+ return (
433
+ "Full context summarized, summary added as user message, "
434
+ "and full history removed."
435
+ )
436
+
437
+ except Exception as e:
438
+ error_msg = f"Failed to save conversation memory: {e}"
439
+ logger.error(error_msg)
440
+ return error_msg
441
+
442
+ def _refresh_context_with_summary(self, summary: str) -> bool:
443
+ r"""Empty the agent's memory and replace it with a summary
444
+ of the conversation history.
445
+
446
+ Args:
447
+ summary (str): The summary of the conversation history.
448
+
449
+ Returns:
450
+ bool: True if the context was refreshed successfully, False
451
+ otherwise.
452
+ """
453
+ try:
454
+ # clear the memory
455
+ self.agent.clear_memory()
456
+
457
+ # add summary as context as a USER message
458
+ if summary and summary.strip():
459
+ from camel.messages import BaseMessage
460
+ from camel.types import OpenAIBackendRole
461
+
462
+ summary_message = BaseMessage.make_user_message(
463
+ role_name="User",
464
+ content=f"[Context Summary from Previous "
465
+ f"Conversation]\n\n{summary}",
466
+ )
467
+ self.agent.update_memory(
468
+ summary_message, OpenAIBackendRole.USER
469
+ )
470
+ return True
471
+ return False
472
+
473
+ except Exception as e:
474
+ logger.error(
475
+ f"Failed to empty memory and replace it with summary: {e}"
476
+ )
477
+ return False
478
+
479
+ def get_conversation_memory_info(self) -> str:
480
+ r"""Get information about the current conversation memory state
481
+ and saved files. The information includes:
482
+ - Number of messages in memory
483
+ - Save directory
484
+ - If summary and history files exist and how many
485
+ characters they have
486
+
487
+ Returns:
488
+ str: Information about current memory and saved files.
489
+ """
490
+ try:
491
+ # Current memory info using ContextUtility
492
+ memory_records = self.context_util.get_agent_memory_records(
493
+ self.agent
494
+ )
495
+ current_count = len(memory_records)
496
+
497
+ info_msg = f"Current messages in memory: {current_count}\n"
498
+ info_msg += f"Save directory: {self.working_directory}\n"
499
+
500
+ # Check if saved files exist
501
+ try:
502
+ summary_content = self._load_summary()
503
+ history_content = self._load_history()
504
+
505
+ if summary_content.strip():
506
+ info_msg += (
507
+ f"Summary file: Available ({len(summary_content)} "
508
+ f"chars)\n"
509
+ )
510
+ else:
511
+ info_msg += "Summary file: Not found\n"
512
+
513
+ if history_content.strip():
514
+ info_msg += (
515
+ f"History file: Available ({len(history_content)} "
516
+ f"chars)\n"
517
+ )
518
+ else:
519
+ info_msg += "History file: Not found\n"
520
+
521
+ except Exception:
522
+ info_msg += "Saved files: Unable to check\n"
523
+
524
+ # Add search capability status
525
+ info_msg += "Text search: Enabled (lightweight file-based)\n"
526
+
527
+ # Count available session histories
528
+ base_dir = self.working_directory.parent
529
+ session_pattern = str(
530
+ base_dir / "session_*" / f"{self.history_filename}.md"
531
+ )
532
+ session_count = len(glob.glob(session_pattern))
533
+ info_msg += f"Searchable sessions: {session_count}\n"
534
+
535
+ return info_msg
536
+
537
+ except Exception as e:
538
+ error_msg = f"Failed to get memory info: {e}"
539
+ logger.error(error_msg)
540
+ return error_msg
541
+
542
+ def search_full_conversation_history(
543
+ self,
544
+ keywords: List[str],
545
+ top_k: int = 4,
546
+ ) -> str:
547
+ r"""Search the conversation history using keyword matching. This is
548
+ used when information is missing from the summary and the current
549
+ conversation, and can potentially be found in the full conversation
550
+ history before it was summarized.
551
+
552
+ Searches through the current session's history.md file to find the
553
+ top messages that contain the most keywords.
554
+
555
+ Args:
556
+ keywords (List[str]): List of keywords to search for. The
557
+ keywords must be explicitly related to the information
558
+ the user is looking for, and not general terms that
559
+ might be found about any topic. For example, if the user
560
+ is searching for the price of the flight to "Paris"
561
+ which was discussed previously, the keywords should be
562
+ ["Paris", "price", "flight", "$", "costs"].
563
+ top_k (int): The number of results to return (default 4).
564
+
565
+ Returns:
566
+ str: The search results or error message.
567
+ """
568
+ try:
569
+ # Only search current session history
570
+ current_history = (
571
+ self.working_directory / f"{self.history_filename}.md"
572
+ )
573
+ if not current_history.exists():
574
+ return "No history file found in current session."
575
+
576
+ logger.info("Searching through current session history")
577
+
578
+ # Perform keyword-based search directly
579
+ search_results = self.context_util.search_in_file(
580
+ current_history, keywords, top_k
581
+ )
582
+
583
+ if search_results and search_results.strip():
584
+ keywords_str = ", ".join(keywords)
585
+ formatted_results = (
586
+ f"Found relevant conversation excerpts for keywords: "
587
+ f"'{keywords_str}'\n\n"
588
+ f"--- Search Results ---\n"
589
+ f"{search_results}\n"
590
+ f"--- End Results ---\n\n"
591
+ f"Note: Results are ordered by keyword match count."
592
+ )
593
+ return formatted_results
594
+ else:
595
+ keywords_str = ", ".join(keywords)
596
+ return (
597
+ f"No relevant conversations found for keywords: "
598
+ f"'{keywords_str}'. "
599
+ f"Try different keywords."
600
+ )
601
+
602
+ except Exception as e:
603
+ error_msg = f"Failed to search conversation history: {e}"
604
+ logger.error(error_msg)
605
+ return error_msg
606
+
607
+ def should_compress_context(
608
+ self, message_limit: int = 40, token_limit: Optional[int] = None
609
+ ) -> bool:
610
+ r"""Check if context should be compressed based on limits.
611
+
612
+ Args:
613
+ message_limit (int): Maximum number of messages before compression.
614
+ token_limit (Optional[int]): Maximum number of tokens before
615
+ compression.
616
+
617
+ Returns:
618
+ bool: True if context should be compressed.
619
+ """
620
+ try:
621
+ # check token limit first (more efficient)
622
+ if token_limit:
623
+ _, token_count = self.agent.memory.get_context()
624
+ if token_count > token_limit:
625
+ return True
626
+
627
+ # check message limit
628
+ memory_records = self.context_util.get_agent_memory_records(
629
+ self.agent
630
+ )
631
+ if len(memory_records) > message_limit:
632
+ return True
633
+
634
+ return False
635
+
636
+ except Exception as e:
637
+ logger.error(
638
+ f"Error checking if context should be compressed: {e}"
639
+ )
640
+ return False
641
+
642
+ # ========= UTILITY METHODS =========
643
+
644
+ def reset(self) -> None:
645
+ r"""Clear all compression state including stored summaries,
646
+ compressed message tracking, and compression counters."""
647
+ self.existing_summary = None
648
+ self.compressed_message_uuids.clear()
649
+ self.compression_count = 0
650
+ logger.info(
651
+ "Context summarizer toolkit reset - previous summary and "
652
+ "compression tracking cleared"
653
+ )
654
+
655
+ def get_current_summary(self) -> Optional[str]:
656
+ r"""Retrieve the in-memory summary without triggering new
657
+ summarization or file operations.
658
+
659
+ Returns:
660
+ Optional[str]: The current summary, or None if no summary exists.
661
+ """
662
+ return self.existing_summary
663
+
664
+ def set_summary(self, summary: str) -> None:
665
+ r"""Override the current in-memory summary with provided content
666
+ without affecting saved files or compression tracking.
667
+
668
+ Args:
669
+ summary (str): The summary to store.
670
+ """
671
+ self.existing_summary = summary
672
+ logger.info("Summary manually set")
673
+
674
+ def get_tools(self) -> List[FunctionTool]:
675
+ r"""Get the tools for the ContextSummarizerToolkit.
676
+
677
+ Returns:
678
+ List[FunctionTool]: The list of tools.
679
+ """
680
+ return [
681
+ FunctionTool(self.summarize_full_conversation_history),
682
+ FunctionTool(self.search_full_conversation_history),
683
+ FunctionTool(self.get_conversation_memory_info),
684
+ ]