versionhq 1.2.4.3__tar.gz → 1.2.4.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/PKG-INFO +4 -4
  2. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/README.md +3 -3
  3. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/agent/index.md +1 -1
  4. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/agent-network/ref.md +11 -11
  5. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/llm/index.md +5 -3
  6. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/task/evaluation.md +1 -1
  7. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/task/reference.md +28 -28
  8. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/task/task-output.md +1 -1
  9. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/task/task-strc-response.md +11 -15
  10. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/quickstart.md +3 -3
  11. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/pyproject.toml +1 -1
  12. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/__init__.py +12 -3
  13. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/_prompt/auto_feedback.py +2 -2
  14. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/_prompt/model.py +24 -29
  15. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/_utils/__init__.py +2 -0
  16. versionhq-1.2.4.6/src/versionhq/_utils/convert_img_url.py +15 -0
  17. versionhq-1.2.4.6/src/versionhq/_utils/is_valid_enum.py +25 -0
  18. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/_utils/llm_as_a_judge.py +0 -1
  19. versionhq-1.2.4.6/src/versionhq/_utils/usage_metrics.py +93 -0
  20. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/agent/inhouse_agents.py +2 -2
  21. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/agent/model.py +100 -29
  22. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/agent_network/formation.py +6 -12
  23. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/agent_network/model.py +4 -5
  24. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/clients/customer/__init__.py +2 -2
  25. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/clients/product/model.py +4 -4
  26. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/clients/workflow/model.py +1 -1
  27. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/llm/llm_vars.py +7 -6
  28. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/llm/model.py +3 -1
  29. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/storage/task_output_storage.py +2 -2
  30. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/task/model.py +112 -100
  31. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/task_graph/draft.py +4 -4
  32. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/task_graph/model.py +34 -30
  33. {versionhq-1.2.4.3/tests/agent → versionhq-1.2.4.6/src/versionhq/tool/composio}/__init__.py +0 -0
  34. versionhq-1.2.4.3/src/versionhq/tool/composio_tool.py → versionhq-1.2.4.6/src/versionhq/tool/composio/model.py +4 -5
  35. versionhq-1.2.4.6/src/versionhq/tool/gpt/__init__.py +6 -0
  36. versionhq-1.2.4.6/src/versionhq/tool/gpt/_enum.py +28 -0
  37. versionhq-1.2.4.6/src/versionhq/tool/gpt/cup.py +145 -0
  38. versionhq-1.2.4.6/src/versionhq/tool/gpt/file_search.py +163 -0
  39. versionhq-1.2.4.6/src/versionhq/tool/gpt/web_search.py +89 -0
  40. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq.egg-info/PKG-INFO +4 -4
  41. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq.egg-info/SOURCES.txt +11 -2
  42. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/_prompt/auto_feedback_test.py +3 -3
  43. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/_prompt/prompt_test.py +1 -1
  44. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/agent/agent_test.py +9 -10
  45. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/agent/doc_test.py +0 -1
  46. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/agent_network/agent_network_test.py +15 -15
  47. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/agent_network/doc_test.py +3 -2
  48. {versionhq-1.2.4.3/tests/knowledge → versionhq-1.2.4.6/tests/cli}/__init__.py +0 -0
  49. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/clients/product_test.py +1 -1
  50. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/clients/workflow_test.py +1 -1
  51. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/doc_test.py +3 -3
  52. {versionhq-1.2.4.3/tests/llm → versionhq-1.2.4.6/tests/knowledge}/__init__.py +0 -0
  53. {versionhq-1.2.4.3/tests/memory → versionhq-1.2.4.6/tests/llm}/__init__.py +0 -0
  54. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/llm/llm_connection_test.py +36 -4
  55. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/llm/llm_test.py +1 -1
  56. {versionhq-1.2.4.3/tests/task → versionhq-1.2.4.6/tests/memory}/__init__.py +0 -0
  57. {versionhq-1.2.4.3/tests/task_graph → versionhq-1.2.4.6/tests/task}/__init__.py +0 -0
  58. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/task/doc_eval_test.py +1 -1
  59. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/task/doc_taskoutput_test.py +1 -1
  60. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/task/doc_test.py +12 -14
  61. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/task/eval_test.py +3 -4
  62. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/task/task_test.py +3 -3
  63. {versionhq-1.2.4.3/tests/tool → versionhq-1.2.4.6/tests/task_graph}/__init__.py +0 -0
  64. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/task_graph/doc_test.py +5 -7
  65. versionhq-1.2.4.6/tests/tool/__init__.py +0 -0
  66. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/tool/composio_test.py +4 -4
  67. versionhq-1.2.4.6/tests/tool/gpt_test.py +143 -0
  68. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/usecase_test.py +2 -3
  69. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/uv.lock +28 -28
  70. versionhq-1.2.4.3/src/versionhq/_utils/usage_metrics.py +0 -72
  71. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/.env.sample +0 -0
  72. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/.github/workflows/deploy_docs.yml +0 -0
  73. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/.github/workflows/publish.yml +0 -0
  74. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/.github/workflows/publish_testpypi.yml +0 -0
  75. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/.github/workflows/run_tests.yml +0 -0
  76. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/.github/workflows/security_check.yml +0 -0
  77. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/.gitignore +0 -0
  78. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/.pre-commit-config.yaml +0 -0
  79. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/.python-version +0 -0
  80. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/LICENSE +0 -0
  81. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/SECURITY.md +0 -0
  82. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/db/preprocess.py +0 -0
  83. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/CNAME +0 -0
  84. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/_logos/favicon.ico +0 -0
  85. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/_logos/logo192.png +0 -0
  86. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/agent/config.md +0 -0
  87. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/agent/task-handling.md +0 -0
  88. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/agent-network/config.md +0 -0
  89. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/agent-network/form.md +0 -0
  90. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/agent-network/index.md +0 -0
  91. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/knowledge.md +0 -0
  92. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/memory.md +0 -0
  93. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/rag-tool.md +0 -0
  94. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/task/index.md +0 -0
  95. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/task/response-field.md +0 -0
  96. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/task/task-execution.md +0 -0
  97. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/task-graph/index.md +0 -0
  98. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/core/tool.md +0 -0
  99. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/index.md +0 -0
  100. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/stylesheets/main.css +0 -0
  101. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/docs/tags.md +0 -0
  102. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/mkdocs.yml +0 -0
  103. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/requirements-dev.txt +0 -0
  104. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/requirements.txt +0 -0
  105. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/runtime.txt +0 -0
  106. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/setup.cfg +0 -0
  107. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/_prompt/constants.py +0 -0
  108. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/_utils/i18n.py +0 -0
  109. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/_utils/is_valid_url.py +0 -0
  110. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/_utils/logger.py +0 -0
  111. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/_utils/process_config.py +0 -0
  112. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/_utils/vars.py +0 -0
  113. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/agent/TEMPLATES/Backstory.py +0 -0
  114. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/agent/TEMPLATES/__init__.py +0 -0
  115. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/agent/__init__.py +0 -0
  116. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/agent/parser.py +0 -0
  117. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/agent/rpm_controller.py +0 -0
  118. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/agent_network/__init__.py +0 -0
  119. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/cli/__init__.py +0 -0
  120. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/clients/__init__.py +0 -0
  121. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/clients/customer/model.py +0 -0
  122. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/clients/product/__init__.py +0 -0
  123. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/clients/workflow/__init__.py +0 -0
  124. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/knowledge/__init__.py +0 -0
  125. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/knowledge/_utils.py +0 -0
  126. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/knowledge/embedding.py +0 -0
  127. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/knowledge/model.py +0 -0
  128. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/knowledge/source.py +0 -0
  129. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/knowledge/source_docling.py +0 -0
  130. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/knowledge/storage.py +0 -0
  131. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/llm/__init__.py +0 -0
  132. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/memory/__init__.py +0 -0
  133. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/memory/contextual_memory.py +0 -0
  134. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/memory/model.py +0 -0
  135. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/storage/__init__.py +0 -0
  136. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/storage/base.py +0 -0
  137. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/storage/ltm_sqlite_storage.py +0 -0
  138. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/storage/mem0_storage.py +0 -0
  139. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/storage/rag_storage.py +0 -0
  140. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/storage/utils.py +0 -0
  141. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/task/TEMPLATES/Description.py +0 -0
  142. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/task/__init__.py +0 -0
  143. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/task/evaluation.py +0 -0
  144. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/task/formatter.py +0 -0
  145. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/task/structured_response.py +0 -0
  146. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/task_graph/__init__.py +0 -0
  147. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/task_graph/colors.py +0 -0
  148. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/tool/__init__.py +0 -0
  149. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/tool/cache_handler.py +0 -0
  150. /versionhq-1.2.4.3/src/versionhq/tool/composio_tool_vars.py → /versionhq-1.2.4.6/src/versionhq/tool/composio/params.py +0 -0
  151. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/tool/decorator.py +0 -0
  152. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/tool/model.py +0 -0
  153. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/tool/rag_tool.py +0 -0
  154. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq/tool/tool_handler.py +0 -0
  155. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq.egg-info/dependency_links.txt +0 -0
  156. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq.egg-info/requires.txt +0 -0
  157. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/src/versionhq.egg-info/top_level.txt +0 -0
  158. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/__init__.py +0 -0
  159. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/_sample/sample.csv +0 -0
  160. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/_sample/sample.json +0 -0
  161. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/_sample/sample.mp3 +0 -0
  162. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/_sample/screenshot.png +0 -0
  163. {versionhq-1.2.4.3/tests/agent_network → versionhq-1.2.4.6/tests/agent}/__init__.py +0 -0
  164. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/agent_network/Prompts/Demo_test.py +0 -0
  165. {versionhq-1.2.4.3/tests/cli → versionhq-1.2.4.6/tests/agent_network}/__init__.py +0 -0
  166. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/clients/customer_test.py +0 -0
  167. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/conftest.py +0 -0
  168. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/formation_test.py +0 -0
  169. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/knowledge/knowledge_test.py +0 -0
  170. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/knowledge/mock_report_compressed.pdf +0 -0
  171. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/memory/memory_test.py +0 -0
  172. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/task_graph/task_graph_test.py +0 -0
  173. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/tool/doc_test.py +0 -0
  174. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/tool/rag_tool_test.py +0 -0
  175. {versionhq-1.2.4.3 → versionhq-1.2.4.6}/tests/tool/tool_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: versionhq
3
- Version: 1.2.4.3
3
+ Version: 1.2.4.6
4
4
  Summary: Autonomous agent networks for task automation with multi-step reasoning.
5
5
  Author-email: Kuriko Iwai <kuriko@versi0n.io>
6
6
  License: MIT License
@@ -295,7 +295,7 @@ def dummy_func(message: str, test1: str, test2: list[str]) -> str:
295
295
 
296
296
  task = vhq.Task(
297
297
  description="Amazing task",
298
- pydantic_output=CustomOutput,
298
+ response_schema=CustomOutput,
299
299
  callback=dummy_func,
300
300
  callback_kwargs=dict(message="Hi! Here is the result: ")
301
301
  )
@@ -317,13 +317,13 @@ agent_b = vhq.Agent(role="Leader", llm="gemini-2.0")
317
317
 
318
318
  task_1 = vhq.Task(
319
319
  description="Analyze the client's business model.",
320
- response_fields=[vhq.ResponseField(title="test1", data_type=str, required=True),],
320
+ response_schema=[vhq.ResponseField(title="test1", data_type=str, required=True),],
321
321
  allow_delegation=True
322
322
  )
323
323
 
324
324
  task_2 = vhq.Task(
325
325
  description="Define a cohort.",
326
- response_fields=[vhq.ResponseField(title="test1", data_type=int, required=True),],
326
+ response_schema=[vhq.ResponseField(title="test1", data_type=int, required=True),],
327
327
  allow_delegation=False
328
328
  )
329
329
 
@@ -212,7 +212,7 @@ def dummy_func(message: str, test1: str, test2: list[str]) -> str:
212
212
 
213
213
  task = vhq.Task(
214
214
  description="Amazing task",
215
- pydantic_output=CustomOutput,
215
+ response_schema=CustomOutput,
216
216
  callback=dummy_func,
217
217
  callback_kwargs=dict(message="Hi! Here is the result: ")
218
218
  )
@@ -234,13 +234,13 @@ agent_b = vhq.Agent(role="Leader", llm="gemini-2.0")
234
234
 
235
235
  task_1 = vhq.Task(
236
236
  description="Analyze the client's business model.",
237
- response_fields=[vhq.ResponseField(title="test1", data_type=str, required=True),],
237
+ response_schema=[vhq.ResponseField(title="test1", data_type=str, required=True),],
238
238
  allow_delegation=True
239
239
  )
240
240
 
241
241
  task_2 = vhq.Task(
242
242
  description="Define a cohort.",
243
- response_fields=[vhq.ResponseField(title="test1", data_type=int, required=True),],
243
+ response_schema=[vhq.ResponseField(title="test1", data_type=int, required=True),],
244
244
  allow_delegation=False
245
245
  )
246
246
 
@@ -14,7 +14,7 @@ A Pydantic class to store an `Agent` object that handles `Task` execution.
14
14
 
15
15
  By defining its role and goal in a simple sentence, the AI agent will be set up to run on <bold>`gpt-4o`</bold> by default.
16
16
 
17
- Calling `.start()` method can start the agent operation, then generate response in text and JSON formats stored in the `TaskOutput` object.
17
+ Calling `.start()` method can start the agent operation and generate response in text and JSON formats stored in the `TaskOutput` object.
18
18
 
19
19
  ```python
20
20
  import versionhq as vhq
@@ -22,7 +22,7 @@ tags:
22
22
  | **`pre_launch_callbacks`** | List[Callable[..., Any]] | list() | Stores callbacks to run before the network launch. |
23
23
  | **`post_launch_callbacks`** | List[Callable[..., Any]] | list() | Stores callbacks to run after the network launch. |
24
24
  | **`step_callbacks`** | Callable[..., Any] | None | Stores callbacks to run at every step of each member agent takes during the activation. |
25
- | **`cache`** | bool | True | Whether to store cache. |
25
+ | **`cache`** | bool | True | Whether to store cache. |
26
26
  | **`execution_logs`** | List[Dict[str, Any]] | list() | Stores a list of execution logs of all the tasks in the network. |
27
27
 
28
28
 
@@ -50,13 +50,13 @@ tags:
50
50
 
51
51
  ### Variable
52
52
 
53
- | <div style="width:200px">**Variable**</div> | **Data Type** | **Default** | **Description** |
54
- | :--- | :--- | :--- | :--- |
55
- | **`agent`** | InstanceOf[`Agent`] | None | Agent as a member |
56
- | **`is_manager`** | bool | False | Whether the member is a manager. |
57
- | **`can_share_knowledge`** | bool | True | Whether the member can share its knowledge among the other network members. |
58
- | **`can_share_memory`** | bool | True | Whether the member can share its memories among the other network members. |
59
- | **`tasks`** | List[InstanceOf[`Task`]] | list() | Assinged tasks. |
53
+ | <div style="width:200px">**Variable**</div> | **Data Type** | **Default** | **Description** |
54
+ | :--- | :--- | :--- | :--- |
55
+ | **`agent`** | InstanceOf[`Agent`] | None | Agent as a member |
56
+ | **`is_manager`** | bool | False | Whether the member is a manager. |
57
+ | **`can_share_knowledge`** | bool | True | Whether the member can share its knowledge among the other network members. |
58
+ | **`can_share_memory`** | bool | True | Whether the member can share its memories among the other network members. |
59
+ | **`tasks`** | List[InstanceOf[`Task`]] | list() | Assinged tasks. |
60
60
 
61
61
 
62
62
  ### Properties
@@ -109,7 +109,7 @@ tags:
109
109
  | :--- | :--- | :--- | :--- |
110
110
  | **`update`** | **kwargs: Any | Self | Updates agents with given kwargs. Invalid keys will be ignored. |
111
111
  | **`start`** | context: Any = None <br> tool_res_as_final: bool = False | `TaskOutput` \| None | Starts to operate the agent. |
112
- | **`execute_task`** | task: [Task] <br> context: Any = None <br> task_tools: Optional[List[Tool \| ToolSet]] = list() | str | Returns response from the model in plane text format. |
112
+ | **`execute_task`** | task: [Task] <br> context: Any = None | Tuple[str, str, Any, UsageMetrics] | Returns response from the model in plane text format. |
113
113
 
114
114
 
115
115
  ### Properties
@@ -122,7 +122,7 @@ tags:
122
122
  ## ENUM `Formation`
123
123
 
124
124
  ```python
125
- class Formation(str, Enum):
125
+ class Formation(IntEnum):
126
126
  SOLO = 1
127
127
  SUPERVISING = 2
128
128
  SQUAD = 3
@@ -133,7 +133,7 @@ class Formation(str, Enum):
133
133
  ## ENUM `TaskHandlingProcess`
134
134
 
135
135
  ```python
136
- class TaskHandlingProcess(str, Enum):
136
+ class TaskHandlingProcess(IntEnum):
137
137
  HIERARCHY = 1
138
138
  SEQUENTIAL = 2
139
139
  CONSENSUAL = 3
@@ -17,16 +17,17 @@ You can specify a model and integration platform from the list. Else, we'll use
17
17
  ```python
18
18
  "openai": [
19
19
  "gpt-4.5-preview-2025-02-27",
20
+ "gpt-4",
20
21
  "gpt-4o",
21
22
  "gpt-4o-mini",
22
- "gpt-4",
23
23
  "o1-mini",
24
24
  "o1-preview",
25
25
  ],
26
26
  "gemini": [
27
- "gemini/gemini-1.5-flash",
28
- "gemini/gemini-1.5-pro",
29
27
  "gemini/gemini-2.0-flash-exp",
28
+ "gemini/gemini-2.0-flash",
29
+ "gemini/gemini-2.0-flash-thinking-exp",
30
+ "gemini/gemini-2.0-flash-lite-preview-02-05",
30
31
  ],
31
32
  "anthropic": [
32
33
  "claude-3-7-sonnet-latest",
@@ -47,6 +48,7 @@ You can specify a model and integration platform from the list. Else, we'll use
47
48
  "bedrock/us.meta.llama3-2-1b-instruct-v1:0",
48
49
  "bedrock/us.meta.llama3-2-3b-instruct-v1:0",
49
50
  "bedrock/us.meta.llama3-2-11b-instruct-v1:0",
51
+ "bedrock/us.meta.llama3-2-90b-instruct-v1:0",
50
52
  "bedrock/mistral.mistral-7b-instruct-v0:2",
51
53
  "bedrock/mistral.mixtral-8x7b-instruct-v0:1",
52
54
  "bedrock/mistral.mistral-large-2407-v1:0",
@@ -59,7 +59,7 @@ class CustomOutput(BaseModel):
59
59
 
60
60
  task = vhq.Task(
61
61
  description="Research a topic to teach a kid aged 6 about math.",
62
- pydantic_output=CustomOutput,
62
+ response_schema=CustomOutput,
63
63
  should_evaluate=True, # triggers evaluation
64
64
  eval_criteria=["uniquness", "audience fit",],
65
65
 
@@ -2,30 +2,29 @@
2
2
 
3
3
  ### Variables
4
4
 
5
- | <div style="width:160px">**Variable**</div> | **Data Type** | **Default** | **Description** |
6
- | :--- | :--- | :--- | :--- |
7
- | **`id`** | UUID | uuid.uuid4() | Stores task `id` as an identifier. |
8
- | **`name`** | Optional[str] | None | Stores a task name (Inherited as `node` identifier if the task is dependent) |
9
- | **`description`** | str | None | Required field to store a concise task description |
10
- | **`pydantic_output`** | Optional[Type[BaseModel]] | None | Stores pydantic custom output class for structured response |
11
- | **`response_fields`** | Optional[List[ResponseField]] | list() | Stores JSON formats for stuructured response |
12
- | **`tools`** | Optional[List[BaseTool \| ToolSet]] | None | Stores tools to be called when the agent executes the task. |
13
- | **`can_use_agent_tools`** | bool | True | Whether to use the agent tools |
14
- | **`tool_res_as_final`** | bool | False | Whether to make a tool output as a final response from the agent |
15
- | **`image`** | Optional[str] | None | Stores an absolute file path or URL to the image file in string |
16
- | **`file`** | Optional[str] | None | Stores an absolute file path or URL to the file in string |
17
- | **`audio`** | Optional[str] | None | Stores an absolute file path or URL to the audio file in string |
18
- | **`should_test_run`** | bool | False | Whether to turn on auto-feedback learning |
19
- | **`human`** | bool | False | Whether to ask human input during the task execution |
20
- | **`execution_type`** | TaskExecutionType | TaskExecutionType.SYNC | Sync or async execution |
21
- | **`allow_delegation`** | bool | False | Whether to allow the agent to delegate the task to another agent |
22
- | **`callback`** | Optional[Callable] | None | Callback function to be executed after LLM calling |
23
- | **`callback_kwargs`** | Optional[Dict[str, Any]] | dict() | Args for the callback function (if any)|
24
- | **`should_evaluate`** | bool | False | Whether to evaluate the task output using eval criteria |
25
- | **`eval_criteria`** | Optional[List[str]] | list() | Evaluation criteria given by the human client |
26
- | **`fsls`** | Optional[List[str]] | None | Examples of competitive and/or weak responses |
27
- | **`processed_agents`** | Set[str] | set() | Stores keys of agents that executed the task |
28
- | **`output`** | Optional[TaskOutput] | None | Stores `TaskOutput` object after the execution |
5
+ | <div style="width:160px">**Variable**</div> | **Data Type** | **Default** | **Description** |
6
+ | :--- | :--- | :--- | :--- |
7
+ | **`id`** | UUID | uuid.uuid4() | Stores task `id` as an identifier. |
8
+ | **`name`** | Optional[str] | None | Stores a task name (Inherited as `node` identifier if the task is dependent) |
9
+ | **`description`** | str | None | Required field to store a concise task description |
10
+ | **`response_schema`** | Optional[Type[BaseModel] \| List[ResponseField]] | None | Response schema for structured output. |
11
+ | **`tools`** | Optional[List[Any]] | None | Tools, tool sets, or RAG tools |
12
+ | **`can_use_agent_tools`** | bool | True | Whether to use the agent tools |
13
+ | **`tool_res_as_final`** | bool | False | Whether to make a tool output as a final response from the agent |
14
+ | **`image`** | Optional[str] | None | Absolute file path or URL to the image file |
15
+ | **`file`** | Optional[str] | None | Absolute file path or URL to the file |
16
+ | **`audio`** | Optional[str] | None | Absolute file path or URL to the audio file |
17
+ | **`should_test_run`** | bool | False | Whether to turn on auto-feedback learning |
18
+ | **`human`** | bool | False | Whether to ask human input during the task execution |
19
+ | **`execution_type`** | TaskExecutionType | TaskExecutionType.SYNC | Sync or async execution |
20
+ | **`allow_delegation`** | bool | False | Whether to allow the agent to delegate the task to another agent |
21
+ | **`callback`** | Optional[Callable] | None | Callback function to be executed after LLM calling |
22
+ | **`callback_kwargs`** | Optional[Dict[str, Any]] | dict() | Args for the callback function (if any)|
23
+ | **`should_evaluate`** | bool | False | Whether to evaluate the task output using eval criteria |
24
+ | **`eval_criteria`** | Optional[List[str]] | list() | Evaluation criteria given by the human client |
25
+ | **`fsls`** | Optional[List[str]] | None | Examples of competitive and/or weak responses |
26
+ | **`processed_agents`** | Set[str] | set() | Stores keys of agents that executed the task |
27
+ | **`output`** | Optional[TaskOutput] | None | Stores `TaskOutput` object after the execution |
29
28
 
30
29
 
31
30
  ### Class Methods
@@ -68,12 +67,13 @@
68
67
  | :--- | :--- | :--- | :--- |
69
68
  | **`task_id`** | UUID | uuid.uuid4() | Stores task `id` as an identifier. |
70
69
  | **`raw`** | str | None | Stores response in plane text format. `None` or `""` when the model returned errors.|
71
- | **`json_dict`** | Dict[str, Any] | None | Stores response in JSON serializable dictionary. When the system failed formatting or executing tasks without response_fields, `{ output: <res.raw> }` will be returned. |
72
- | **`pydantic`** | Type[`BaseModel`] | None | Populates and stores Pydantic class object defined in the `pydantic_output` field if given. |
73
- | **`tool_output`** | Optional[Any] | None | Stores results from the tools of the task or agents ONLY when `tool_res_as_final` set as `True`. |
70
+ | **`json_dict`** | Dict[str, Any] | None | Stores response in JSON serializable dictionary. |
71
+ | **`pydantic`** | Type[`BaseModel`] | None | Populates the given response schema in pydantic class |
72
+ | **`tool_output`** | Optional[Any] | None | Stores results from the tools of the task or agents when `tool_res_as_final` == True |
74
73
  | **`callback_output`** | Optional[Any] | None | Stores results from callback functions if any. |
75
- | **`latency`** | Optional[float] | None | Stores job latency in milseconds. |
74
+ | **`annotations`** | Optional[Dict[str, Any]] | None | Stores annotations given by the model. |
76
75
  | **`evaluation`** | Optional[InstanceOf[`Evaluation`]] | None | Stores overall evaluations and usage of the task output. |
76
+ | **`usage`** | Optional[InstanceOf[`UsageMetrics]`] | None | Usage related values. |
77
77
 
78
78
 
79
79
  ### Class Methods
@@ -27,7 +27,7 @@ def summarize_response(message: str, test1: str, test2: list[str]) -> str:
27
27
 
28
28
  task = vhq.Task(
29
29
  description="Research a topic to teach a kid aged 6 about math.",
30
- pydantic_output=CustomOutput,
30
+ response_schema=CustomOutput,
31
31
  tools=[dummy_tool],
32
32
  callback=summarize_response,
33
33
  callback_kwargs=dict(message="Hi! Here is the result: "),
@@ -8,11 +8,11 @@ But you can choose to generate Pydantic class or specifig JSON object as respons
8
8
 
9
9
  <hr />
10
10
 
11
- ## 1. Pydantic
11
+ `[var]`<bold>`response_schema: Optional[Type[BaseModel] | List[ResponseField]] = None`</bold>
12
12
 
13
- `[var]`<bold>`pydantic_output: Optional[Type[BaseModel]] = None`</bold>
13
+ ## 1. Pydantic
14
14
 
15
- Add a `custom Pydantic class` as a structured response format to the `pydantic_output` field.
15
+ Add a `custom Pydantic class` to the `response_schema` field to generate a structured response.
16
16
 
17
17
  The custom class can accept **one layer of a nested child** as you can see in the following code snippet:
18
18
 
@@ -44,7 +44,7 @@ class Demo(BaseModel):
44
44
  # 2. Define a task
45
45
  task = vhq.Task(
46
46
  description="generate random output that strictly follows the given format",
47
- pydantic_output=Demo,
47
+ response_schema=Demo,
48
48
  )
49
49
 
50
50
  # 3. Execute
@@ -63,8 +63,6 @@ assert [
63
63
 
64
64
  ## 2. JSON
65
65
 
66
- `[var]`<bold>`response_fields: List[InstanceOf[ResponseField]] = None`</bold>
67
-
68
66
  Similar to Pydantic, JSON output structure can be defined by using a list of `ResponseField` objects.
69
67
 
70
68
  The following code snippet demonstrates how to use `ResponseField` to generate output with a maximum of one level of nesting.
@@ -75,16 +73,15 @@ Custom JSON outputs can accept **one layer of a nested child**.
75
73
 
76
74
  - `demo_response_fields` in the following case is identical to the previous Demo class, except that titles are specified for nested fields.
77
75
 
78
- - Agents generate JSON output by default, whether or not `response_fields` are used.
76
+ - Agents generate JSON output by default, whether or not `response_schema` is given.
79
77
 
80
- - However, response_fields are REQUIRED to specify JSON key titles and data types.
78
+ - However, `response_schema` is required to specify the key value sets.
81
79
 
82
80
  ```python
83
81
  import versionhq as vhq
84
82
 
85
83
  # 1. Define a list of ResponseField objects.
86
84
  demo_response_fields = [
87
- # no nesting
88
85
  vhq.ResponseField(title="demo_1", data_type=int),
89
86
  vhq.ResponseField(title="demo_2", data_type=float),
90
87
  vhq.ResponseField(title="demo_3", data_type=str),
@@ -125,16 +122,15 @@ demo_response_fields = [
125
122
  # 2. Define a task
126
123
  task = vhq.Task(
127
124
  description="Output random values strictly following the data type defined in the given response format.",
128
- response_fields=demo_response_fields
125
+ response_schema=demo_response_fields
129
126
  )
130
127
 
131
128
 
132
129
  # 3. Execute
133
130
  res = task.execute()
134
131
 
135
- assert isinstance(res, vhq.TaskOutput) and res.task_id is task.id
136
- assert res.raw and res.json and res.pydantic is None
137
- assert [v and type(v) == task.response_fields[i].data_type for i, (k, v) in enumerate(res.json_dict.items())]
132
+ assert isinstance(res, vhq.TaskOutput)
133
+ assert [v and type(v) == task.response_schema[i].data_type for i, (k, v) in enumerate(res.json_dict.items())]
138
134
  ```
139
135
 
140
136
  * Ref. <a href="/core/task/response-field">`ResponseField`</a> class
@@ -172,7 +168,7 @@ class Sub(BaseModel):
172
168
 
173
169
  sub_task = vhq.Task(
174
170
  description="generate random values that strictly follows the given format.",
175
- pydantic_output=Sub
171
+ response_schema=Sub
176
172
  )
177
173
  sub_res = sub_task.execute()
178
174
 
@@ -190,7 +186,7 @@ def format_response(sub, main1, main2) -> Main:
190
186
  # 3. Executes
191
187
  main_task = vhq.Task(
192
188
  description="generate random values that strictly follows the given format.",
193
- pydantic_output=Main,
189
+ response_schema=Main,
194
190
  callback=format_response,
195
191
  callback_kwargs=dict(sub=sub_res.json_dict),
196
192
  )
@@ -52,7 +52,7 @@ agent = vhq.Agent(role="demo manager")
52
52
 
53
53
  task = vhq.Task(
54
54
  description="Amazing task",
55
- pydantic_output=CustomOutput,
55
+ response_schema=CustomOutput,
56
56
  callback=dummy_func,
57
57
  callback_kwargs=dict(message="Hi! Here is the result: ")
58
58
  )
@@ -88,13 +88,13 @@ agent_b = vhq.Agent(role="agent b", goal="My amazing goals", llm="llm-of-your-ch
88
88
 
89
89
  task_1 = vhq.Task(
90
90
  description="Analyze the client's business model.",
91
- response_fields=[vhq.ResponseField(title="test1", data_type=str, required=True),],
91
+ response_schema=[vhq.ResponseField(title="test1", data_type=str, required=True),],
92
92
  allow_delegation=True
93
93
  )
94
94
 
95
95
  task_2 = vhq.Task(
96
96
  description="Define a cohort.",
97
- response_fields=[vhq.ResponseField(title="test1", data_type=int, required=True),],
97
+ response_schema=[vhq.ResponseField(title="test1", data_type=int, required=True),],
98
98
  allow_delegation=False
99
99
  )
100
100
 
@@ -15,7 +15,7 @@ exclude = ["test*", "__pycache__", "*.egg-info"]
15
15
 
16
16
  [project]
17
17
  name = "versionhq"
18
- version = "1.2.4.3"
18
+ version = "1.2.4.6"
19
19
  authors = [{ name = "Kuriko Iwai", email = "kuriko@versi0n.io" }]
20
20
  description = "Autonomous agent networks for task automation with multi-step reasoning."
21
21
  readme = "README.md"
@@ -24,7 +24,10 @@ from versionhq.tool.model import Tool, ToolSet
24
24
  from versionhq.tool.rag_tool import RagTool
25
25
  from versionhq.tool.cache_handler import CacheHandler
26
26
  from versionhq.tool.tool_handler import ToolHandler
27
- from versionhq.tool.composio_tool import ComposioHandler
27
+ from versionhq.tool.composio.model import ComposioBaseTool
28
+ from versionhq.tool.gpt.cup import GPTToolCUP, CUPToolSchema
29
+ from versionhq.tool.gpt.file_search import GPTToolFileSearch, FilterSchema
30
+ from versionhq.tool.gpt.web_search import GPTToolWebSearch
28
31
  from versionhq.memory.contextual_memory import ContextualMemory
29
32
  from versionhq.memory.model import ShortTermMemory,LongTermMemory, UserMemory, MemoryItem
30
33
 
@@ -32,7 +35,7 @@ from versionhq.agent_network.formation import form_agent_network
32
35
  from versionhq.task_graph.draft import workflow
33
36
 
34
37
 
35
- __version__ = "1.2.4.3"
38
+ __version__ = "1.2.4.6"
36
39
  __all__ = [
37
40
  "Agent",
38
41
 
@@ -85,7 +88,13 @@ __all__ = [
85
88
  "RagTool",
86
89
  "CacheHandler",
87
90
  "ToolHandler",
88
- "ComposioHandler",
91
+ "ComposioBaseTool",
92
+
93
+ "GPTToolCUP",
94
+ "CUPToolSchema",
95
+ "GPTToolFileSearch",
96
+ "FilterSchema",
97
+ "GPTToolWebSearch",
89
98
 
90
99
  "ContextualMemory",
91
100
  "ShortTermMemory",
@@ -5,7 +5,7 @@ from pydantic import InstanceOf, Field
5
5
 
6
6
  from versionhq.agent.model import Agent
7
7
  from versionhq.task.model import Task
8
- from versionhq.task_graph.model import TaskGraph, Node, DependencyType, ReformTriggerEvent
8
+ from versionhq.task_graph.model import TaskGraph, Node, DependencyType
9
9
  from versionhq._prompt.model import Prompt
10
10
  from versionhq._prompt.constants import REFLECT, INTEGRATE, parameter_sets
11
11
 
@@ -67,7 +67,7 @@ class PromptFeedbackGraph(TaskGraph):
67
67
  if not agents:
68
68
  return None
69
69
 
70
- self.concl_template = base_task.pydantic_output if base_task.pydantic_output else base_task.response_fields if base_task.response_fields else None
70
+ self.concl_response_schema = base_task.response_schema
71
71
  base_agent.callbacks.append(self._reflect)
72
72
  init_node = Node(task=base_task, assigned_to=base_agent)
73
73
  self.add_node(init_node)
@@ -2,9 +2,9 @@
2
2
  from typing import Dict, List, Tuple, Any
3
3
  from textwrap import dedent
4
4
 
5
- from pydantic import InstanceOf
5
+ from pydantic import InstanceOf, BaseModel
6
6
 
7
- from versionhq._utils import is_valid_url
7
+ from versionhq._utils import is_valid_url, convert_img_url
8
8
 
9
9
 
10
10
  class Prompt:
@@ -25,34 +25,26 @@ class Prompt:
25
25
 
26
26
 
27
27
  def _draft_output_prompt(self) -> str:
28
- """Drafts prompt for output either from `pydantic_output` or `response_fields`"""
28
+ """Drafts prompt for output format using `response_schema`."""
29
29
 
30
- from versionhq.llm.model import DEFAULT_MODEL_PROVIDER_NAME
30
+ from versionhq.task.model import ResponseField
31
31
 
32
32
  output_prompt = ""
33
- model_provider = self.agent.llm.provider if self.agent else DEFAULT_MODEL_PROVIDER_NAME
33
+ output_formats_to_follow = dict()
34
34
 
35
- if self.task.pydantic_output:
36
- output_prompt, output_formats_to_follow = "", dict()
37
- response_format = str(self.task._structure_response_format(model_provider=model_provider))
38
- for k, v in self.task.pydantic_output.model_fields.items():
39
- output_formats_to_follow[k] = f"<Return your answer in {v.annotation}>"
35
+ if self.task.response_schema:
36
+ if isinstance(self.task.response_schema, list):
37
+ for item in self.task.response_schema:
38
+ if isinstance(item, ResponseField):
39
+ output_formats_to_follow[item.title] = f"<Return your answer in {item.data_type.__name__}>"
40
40
 
41
- output_prompt = f"""Your response MUST be a valid JSON string that strictly follows the response format. Use double quotes for all keys and string values. Do not use single quotes, trailing commas, or any other non-standard JSON syntax.
42
- Response format: {response_format}
43
- Ref. Output image: {output_formats_to_follow}
44
- """
45
- elif self.task.response_fields:
46
- output_prompt, output_formats_to_follow = "", dict()
47
- response_format = str(self.task._structure_response_format(model_provider=model_provider))
48
- for item in self.task.response_fields:
49
- if item:
50
- output_formats_to_follow[item.title] = f"<Return your answer in {item.data_type.__name__}>"
41
+ elif issubclass(self.task.response_schema, BaseModel):
42
+ for k, v in self.task.response_schema.model_fields.items():
43
+ output_formats_to_follow[k] = f"<Return your answer in {v.annotation}>"
51
44
 
52
45
  output_prompt = f"""Your response MUST be a valid JSON string that strictly follows the response format. Use double quotes for all keys and string values. Do not use single quotes, trailing commas, or any other non-standard JSON syntax.
53
- Response format: {response_format}
54
46
  Ref. Output image: {output_formats_to_follow}
55
- """
47
+ """
56
48
  else:
57
49
  output_prompt = "You MUST return your response as a valid JSON serializable string, enclosed in double quotes. Use double quotes for all keys and string values. Do NOT use single quotes, trailing commas, or other non-standard JSON syntax."
58
50
 
@@ -107,12 +99,9 @@ Ref. Output image: {output_formats_to_follow}
107
99
  content_messages = {}
108
100
 
109
101
  if self.task.image:
110
- with open(self.task.image, "rb") as file:
111
- content = file.read()
112
- if content:
113
- encoded_file = base64.b64encode(content).decode("utf-8")
114
- img_url = f"data:image/jpeg;base64,{encoded_file}"
115
- content_messages.update({ "type": "image_url", "image_url": { "url": img_url }})
102
+ img_url = convert_img_url(self.task.image)
103
+ if img_url:
104
+ content_messages.update({ "type": "image_url", "image_url": { "url": img_url }})
116
105
 
117
106
  if self.task.file:
118
107
  if is_valid_url(self.task.file):
@@ -154,7 +143,7 @@ Ref. Output image: {output_formats_to_follow}
154
143
  return "\n".join(task_slices)
155
144
 
156
145
 
157
- def format_core(self, rag_tools: List[Any] = None) -> Tuple[str, str, List[Dict[str, str]]]:
146
+ def format_core(self, rag_tools: List[Any] = None, gpt_tools: List[Any] = None) -> Tuple[str, str, List[Dict[str, str]]]:
158
147
  """Formats prompt messages sent to the LLM, then returns task prompt, developer prompt, and messages."""
159
148
 
160
149
  from versionhq.knowledge._utils import extract_knowledge_context
@@ -176,6 +165,12 @@ Ref. Output image: {output_formats_to_follow}
176
165
  if rag_tool_context:
177
166
  user_prompt += ",".join(rag_tool_context) if isinstance(rag_tool_context, list) else str(rag_tool_context)
178
167
 
168
+ if gpt_tools:
169
+ for item in gpt_tools:
170
+ raw, _, _ = item.run()
171
+ if raw:
172
+ user_prompt += str(raw)
173
+
179
174
  if self.agent.with_memory == True:
180
175
  contextual_memory = ContextualMemory(
181
176
  memory_config=self.agent.memory_config, stm=self.agent.short_term_memory, ltm=self.agent.long_term_memory, um=self.agent.user_memory
@@ -3,3 +3,5 @@ from versionhq._utils.process_config import process_config
3
3
  from versionhq._utils.vars import KNOWLEDGE_DIRECTORY, MAX_FILE_NAME_LENGTH
4
4
  from versionhq._utils.is_valid_url import is_valid_url
5
5
  from versionhq._utils.usage_metrics import UsageMetrics, ErrorType
6
+ from versionhq._utils.convert_img_url import convert_img_url
7
+ from versionhq._utils.is_valid_enum import is_valid_enum
@@ -0,0 +1,15 @@
1
+ import base64
2
+
3
+ def convert_img_url(img_url: str) -> str | None:
4
+ try:
5
+ with open(img_url, "rb") as file:
6
+ content = file.read()
7
+ if content:
8
+ encoded_file = base64.b64encode(content).decode("utf-8")
9
+ img_url = f"data:image/jpeg;base64,{encoded_file}"
10
+ return img_url
11
+
12
+ else: return None
13
+
14
+ except:
15
+ return None
@@ -0,0 +1,25 @@
1
+ from enum import Enum, IntEnum
2
+ from typing import Any
3
+
4
+
5
+ def is_valid_enum(enum: Enum | IntEnum, key: str = None, val: str | Enum | IntEnum = None) -> bool:
6
+ if not enum: return False
7
+
8
+ if key:
9
+ key = key.upper()
10
+ matched = [k for k in enum._member_map_.keys() if hasattr(enum, "_member_map_") and k == key]
11
+ return bool(matched)
12
+
13
+ elif val:
14
+ match val:
15
+ case str():
16
+ matched = [k for k in enum._value2member_map_.keys() if hasattr(enum, "_value2member_map_") and k == val]
17
+ return bool(matched)
18
+
19
+ case Enum() | IntEnum():
20
+ return val in enum
21
+
22
+ case _:
23
+ return False
24
+
25
+ else: return False
@@ -2,7 +2,6 @@ import json
2
2
  import numpy as np
3
3
  from sklearn.metrics import precision_score, recall_score, roc_auc_score, cohen_kappa_score
4
4
  from typing import List, Tuple, Dict, Any
5
- from pathlib import Path
6
5
 
7
6
 
8
7
  class LLMJudge: