versionhq 1.2.4.5__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.
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/PKG-INFO +1 -1
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/agent/index.md +1 -1
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/agent-network/ref.md +11 -11
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/task/reference.md +4 -3
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/pyproject.toml +1 -1
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/__init__.py +12 -3
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/_prompt/auto_feedback.py +1 -1
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/_prompt/model.py +11 -8
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/_utils/__init__.py +2 -0
- versionhq-1.2.4.6/src/versionhq/_utils/convert_img_url.py +15 -0
- versionhq-1.2.4.6/src/versionhq/_utils/is_valid_enum.py +25 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/_utils/llm_as_a_judge.py +0 -1
- versionhq-1.2.4.6/src/versionhq/_utils/usage_metrics.py +93 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/agent/model.py +91 -27
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/agent_network/formation.py +3 -9
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/agent_network/model.py +3 -4
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/clients/customer/__init__.py +2 -2
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/clients/product/model.py +4 -4
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/clients/workflow/model.py +1 -1
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/llm/llm_vars.py +0 -2
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/storage/task_output_storage.py +2 -2
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/task/model.py +72 -59
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/task_graph/model.py +30 -26
- {versionhq-1.2.4.5/tests/agent → versionhq-1.2.4.6/src/versionhq/tool/composio}/__init__.py +0 -0
- versionhq-1.2.4.5/src/versionhq/tool/composio_tool.py → versionhq-1.2.4.6/src/versionhq/tool/composio/model.py +4 -5
- versionhq-1.2.4.6/src/versionhq/tool/gpt/__init__.py +6 -0
- versionhq-1.2.4.6/src/versionhq/tool/gpt/_enum.py +28 -0
- versionhq-1.2.4.6/src/versionhq/tool/gpt/cup.py +145 -0
- versionhq-1.2.4.6/src/versionhq/tool/gpt/file_search.py +163 -0
- versionhq-1.2.4.6/src/versionhq/tool/gpt/web_search.py +89 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq.egg-info/PKG-INFO +1 -1
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq.egg-info/SOURCES.txt +11 -2
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/_prompt/auto_feedback_test.py +1 -1
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/agent/agent_test.py +1 -2
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/agent/doc_test.py +1 -4
- {versionhq-1.2.4.5/tests/knowledge → versionhq-1.2.4.6/tests/cli}/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/clients/product_test.py +1 -1
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/clients/workflow_test.py +1 -1
- {versionhq-1.2.4.5/tests/llm → versionhq-1.2.4.6/tests/knowledge}/__init__.py +0 -0
- {versionhq-1.2.4.5/tests/memory → versionhq-1.2.4.6/tests/llm}/__init__.py +0 -0
- {versionhq-1.2.4.5/tests/task → versionhq-1.2.4.6/tests/memory}/__init__.py +0 -0
- {versionhq-1.2.4.5/tests/task_graph → versionhq-1.2.4.6/tests/task}/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/task/doc_test.py +5 -8
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/task/eval_test.py +1 -2
- {versionhq-1.2.4.5/tests/tool → versionhq-1.2.4.6/tests/task_graph}/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/task_graph/doc_test.py +4 -6
- versionhq-1.2.4.6/tests/tool/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/tool/composio_test.py +4 -4
- versionhq-1.2.4.6/tests/tool/gpt_test.py +143 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/usecase_test.py +4 -7
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/uv.lock +13 -13
- versionhq-1.2.4.5/src/versionhq/_utils/usage_metrics.py +0 -72
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/.env.sample +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/.github/workflows/deploy_docs.yml +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/.github/workflows/publish.yml +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/.github/workflows/publish_testpypi.yml +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/.github/workflows/run_tests.yml +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/.github/workflows/security_check.yml +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/.gitignore +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/.pre-commit-config.yaml +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/.python-version +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/LICENSE +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/README.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/SECURITY.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/db/preprocess.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/CNAME +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/_logos/favicon.ico +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/_logos/logo192.png +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/agent/config.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/agent/task-handling.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/agent-network/config.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/agent-network/form.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/agent-network/index.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/knowledge.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/llm/index.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/memory.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/rag-tool.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/task/evaluation.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/task/index.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/task/response-field.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/task/task-execution.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/task/task-output.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/task/task-strc-response.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/task-graph/index.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/core/tool.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/index.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/quickstart.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/stylesheets/main.css +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/docs/tags.md +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/mkdocs.yml +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/requirements-dev.txt +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/requirements.txt +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/runtime.txt +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/setup.cfg +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/_prompt/constants.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/_utils/i18n.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/_utils/is_valid_url.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/_utils/logger.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/_utils/process_config.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/_utils/vars.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/agent/TEMPLATES/Backstory.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/agent/TEMPLATES/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/agent/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/agent/inhouse_agents.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/agent/parser.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/agent/rpm_controller.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/agent_network/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/cli/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/clients/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/clients/customer/model.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/clients/product/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/clients/workflow/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/knowledge/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/knowledge/_utils.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/knowledge/embedding.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/knowledge/model.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/knowledge/source.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/knowledge/source_docling.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/knowledge/storage.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/llm/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/llm/model.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/memory/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/memory/contextual_memory.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/memory/model.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/storage/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/storage/base.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/storage/ltm_sqlite_storage.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/storage/mem0_storage.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/storage/rag_storage.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/storage/utils.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/task/TEMPLATES/Description.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/task/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/task/evaluation.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/task/formatter.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/task/structured_response.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/task_graph/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/task_graph/colors.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/task_graph/draft.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/tool/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/tool/cache_handler.py +0 -0
- /versionhq-1.2.4.5/src/versionhq/tool/composio_tool_vars.py → /versionhq-1.2.4.6/src/versionhq/tool/composio/params.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/tool/decorator.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/tool/model.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/tool/rag_tool.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq/tool/tool_handler.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq.egg-info/dependency_links.txt +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq.egg-info/requires.txt +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/src/versionhq.egg-info/top_level.txt +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/_prompt/prompt_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/_sample/sample.csv +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/_sample/sample.json +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/_sample/sample.mp3 +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/_sample/screenshot.png +0 -0
- {versionhq-1.2.4.5/tests/agent_network → versionhq-1.2.4.6/tests/agent}/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/agent_network/Prompts/Demo_test.py +0 -0
- {versionhq-1.2.4.5/tests/cli → versionhq-1.2.4.6/tests/agent_network}/__init__.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/agent_network/agent_network_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/agent_network/doc_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/clients/customer_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/conftest.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/doc_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/formation_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/knowledge/knowledge_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/knowledge/mock_report_compressed.pdf +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/llm/llm_connection_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/llm/llm_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/memory/memory_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/task/doc_eval_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/task/doc_taskoutput_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/task/task_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/task_graph/task_graph_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/tool/doc_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/tool/rag_tool_test.py +0 -0
- {versionhq-1.2.4.5 → versionhq-1.2.4.6}/tests/tool/tool_test.py +0 -0
@@ -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
|
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`]
|
56
|
-
| **`is_manager`** | bool
|
57
|
-
| **`can_share_knowledge`** | bool
|
58
|
-
| **`can_share_memory`** | bool
|
59
|
-
| **`tasks`** | List[InstanceOf[`Task`]]
|
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
|
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(
|
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(
|
136
|
+
class TaskHandlingProcess(IntEnum):
|
137
137
|
HIERARCHY = 1
|
138
138
|
SEQUENTIAL = 2
|
139
139
|
CONSENSUAL = 3
|
@@ -8,7 +8,7 @@
|
|
8
8
|
| **`name`** | Optional[str] | None | Stores a task name (Inherited as `node` identifier if the task is dependent) |
|
9
9
|
| **`description`** | str | None | Required field to store a concise task description |
|
10
10
|
| **`response_schema`** | Optional[Type[BaseModel] \| List[ResponseField]] | None | Response schema for structured output. |
|
11
|
-
| **`tools`** | Optional[List[
|
11
|
+
| **`tools`** | Optional[List[Any]] | None | Tools, tool sets, or RAG tools |
|
12
12
|
| **`can_use_agent_tools`** | bool | True | Whether to use the agent tools |
|
13
13
|
| **`tool_res_as_final`** | bool | False | Whether to make a tool output as a final response from the agent |
|
14
14
|
| **`image`** | Optional[str] | None | Absolute file path or URL to the image file |
|
@@ -69,10 +69,11 @@
|
|
69
69
|
| **`raw`** | str | None | Stores response in plane text format. `None` or `""` when the model returned errors.|
|
70
70
|
| **`json_dict`** | Dict[str, Any] | None | Stores response in JSON serializable dictionary. |
|
71
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
|
72
|
+
| **`tool_output`** | Optional[Any] | None | Stores results from the tools of the task or agents when `tool_res_as_final` == True |
|
73
73
|
| **`callback_output`** | Optional[Any] | None | Stores results from callback functions if any. |
|
74
|
-
| **`
|
74
|
+
| **`annotations`** | Optional[Dict[str, Any]] | None | Stores annotations given by the model. |
|
75
75
|
| **`evaluation`** | Optional[InstanceOf[`Evaluation`]] | None | Stores overall evaluations and usage of the task output. |
|
76
|
+
| **`usage`** | Optional[InstanceOf[`UsageMetrics]`] | None | Usage related values. |
|
76
77
|
|
77
78
|
|
78
79
|
### Class Methods
|
@@ -15,7 +15,7 @@ exclude = ["test*", "__pycache__", "*.egg-info"]
|
|
15
15
|
|
16
16
|
[project]
|
17
17
|
name = "versionhq"
|
18
|
-
version = "1.2.4.
|
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.
|
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.
|
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
|
-
"
|
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
|
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
|
|
@@ -4,7 +4,7 @@ from textwrap import dedent
|
|
4
4
|
|
5
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:
|
@@ -99,12 +99,9 @@ Ref. Output image: {output_formats_to_follow}
|
|
99
99
|
content_messages = {}
|
100
100
|
|
101
101
|
if self.task.image:
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
encoded_file = base64.b64encode(content).decode("utf-8")
|
106
|
-
img_url = f"data:image/jpeg;base64,{encoded_file}"
|
107
|
-
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 }})
|
108
105
|
|
109
106
|
if self.task.file:
|
110
107
|
if is_valid_url(self.task.file):
|
@@ -146,7 +143,7 @@ Ref. Output image: {output_formats_to_follow}
|
|
146
143
|
return "\n".join(task_slices)
|
147
144
|
|
148
145
|
|
149
|
-
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]]]:
|
150
147
|
"""Formats prompt messages sent to the LLM, then returns task prompt, developer prompt, and messages."""
|
151
148
|
|
152
149
|
from versionhq.knowledge._utils import extract_knowledge_context
|
@@ -168,6 +165,12 @@ Ref. Output image: {output_formats_to_follow}
|
|
168
165
|
if rag_tool_context:
|
169
166
|
user_prompt += ",".join(rag_tool_context) if isinstance(rag_tool_context, list) else str(rag_tool_context)
|
170
167
|
|
168
|
+
if gpt_tools:
|
169
|
+
for item in gpt_tools:
|
170
|
+
raw, _, _ = item.run()
|
171
|
+
if raw:
|
172
|
+
user_prompt += str(raw)
|
173
|
+
|
171
174
|
if self.agent.with_memory == True:
|
172
175
|
contextual_memory = ContextualMemory(
|
173
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
|
@@ -0,0 +1,93 @@
|
|
1
|
+
import uuid
|
2
|
+
import datetime
|
3
|
+
from enum import IntEnum
|
4
|
+
from typing import Dict, List
|
5
|
+
from typing_extensions import Self
|
6
|
+
|
7
|
+
from pydantic import BaseModel, UUID4, InstanceOf
|
8
|
+
|
9
|
+
|
10
|
+
class ErrorType(IntEnum):
|
11
|
+
FORMAT = 1
|
12
|
+
TOOL = 2
|
13
|
+
API = 3
|
14
|
+
OVERFITTING = 4
|
15
|
+
HUMAN_INTERACTION = 5
|
16
|
+
|
17
|
+
|
18
|
+
class UsageMetrics(BaseModel):
|
19
|
+
"""A Pydantic model to manage token usage, errors, job latency."""
|
20
|
+
|
21
|
+
id: UUID4 = uuid.uuid4() # stores task id or task graph id
|
22
|
+
total_tokens: int = 0
|
23
|
+
prompt_tokens: int = 0
|
24
|
+
completion_tokens: int = 0
|
25
|
+
input_tokens: int = 0
|
26
|
+
output_tokens: int = 0
|
27
|
+
successful_requests: int = 0
|
28
|
+
total_errors: int = 0
|
29
|
+
error_breakdown: Dict[ErrorType, int] = dict()
|
30
|
+
latency: float = 0.0 # in ms
|
31
|
+
|
32
|
+
|
33
|
+
def record_token_usage(self, *args, **kwargs) -> None:
|
34
|
+
"""Records usage metrics from the raw response of the model."""
|
35
|
+
|
36
|
+
if args:
|
37
|
+
for item in args:
|
38
|
+
match item:
|
39
|
+
case dict():
|
40
|
+
if hasattr(self, k):
|
41
|
+
setattr(self, k, int(getattr(self, k)) + int(v))
|
42
|
+
case UsageMetrics():
|
43
|
+
self = self.aggregate(metrics=item)
|
44
|
+
case _:
|
45
|
+
try:
|
46
|
+
self.completion_tokens += item.completion_tokens if hasattr(item, "completion_tokens") else 0
|
47
|
+
self.prompt_tokens += item.prompt_tokens if hasattr(item, "prompt_tokens") else 0
|
48
|
+
self.total_tokens += item.total_tokens if hasattr(item, "total_tokens") else 0
|
49
|
+
self.input_tokens += item.input_tokens if hasattr(item, "input_tokens") else 0
|
50
|
+
self.output_tokens += item.output_tokens if hasattr(item, "output_tokens") else 0
|
51
|
+
except:
|
52
|
+
pass
|
53
|
+
if kwargs:
|
54
|
+
for k, v in kwargs.items():
|
55
|
+
if hasattr(self, k):
|
56
|
+
setattr(self, k, int(getattr(self, k)) + int(v))
|
57
|
+
|
58
|
+
|
59
|
+
def record_errors(self, type: ErrorType = None) -> None:
|
60
|
+
self.total_errors += 1
|
61
|
+
if type:
|
62
|
+
if type in self.error_breakdown:
|
63
|
+
self.error_breakdown[type] += 1
|
64
|
+
else:
|
65
|
+
self.error_breakdown[type] = 1
|
66
|
+
|
67
|
+
|
68
|
+
def record_latency(self, start_dt: datetime.datetime, end_dt: datetime.datetime) -> None:
|
69
|
+
self.latency += round((end_dt - start_dt).total_seconds() * 1000, 3)
|
70
|
+
|
71
|
+
|
72
|
+
def aggregate(self, metrics: InstanceOf["UsageMetrics"]) -> Self:
|
73
|
+
if not metrics:
|
74
|
+
return self
|
75
|
+
|
76
|
+
self.total_tokens += metrics.total_tokens
|
77
|
+
self.prompt_tokens += metrics.prompt_tokens
|
78
|
+
self.completion_tokens += metrics.completion_tokens
|
79
|
+
self.input_tokens += metrics.input_tokens
|
80
|
+
self.output_tokens += metrics.output_tokens
|
81
|
+
self.successful_requests += metrics.successful_requests
|
82
|
+
self.total_errors += metrics.total_errors
|
83
|
+
self.latency += metrics.latency
|
84
|
+
self.latency = round(self.latency, 3)
|
85
|
+
|
86
|
+
if metrics.error_breakdown:
|
87
|
+
for k, v in metrics.error_breakdown.items():
|
88
|
+
if self.error_breakdown and k in self.error_breakdown:
|
89
|
+
self.error_breakdown[k] += int(v)
|
90
|
+
else:
|
91
|
+
self.error_breakdown.update({ k: v })
|
92
|
+
|
93
|
+
return self
|
@@ -11,7 +11,7 @@ from versionhq.agent.rpm_controller import RPMController
|
|
11
11
|
from versionhq.tool.model import Tool, ToolSet, BaseTool
|
12
12
|
from versionhq.knowledge.model import BaseKnowledgeSource, Knowledge
|
13
13
|
from versionhq.memory.model import ShortTermMemory, LongTermMemory, UserMemory
|
14
|
-
from versionhq._utils import Logger, process_config, is_valid_url, ErrorType
|
14
|
+
from versionhq._utils import Logger, process_config, is_valid_url, ErrorType, UsageMetrics
|
15
15
|
|
16
16
|
|
17
17
|
load_dotenv(override=True)
|
@@ -124,6 +124,9 @@ class Agent(BaseModel):
|
|
124
124
|
Similar to the LLM set up, when the agent has tools, we will declare them using the Tool class.
|
125
125
|
"""
|
126
126
|
from versionhq.tool.rag_tool import RagTool
|
127
|
+
from versionhq.tool.gpt.web_search import GPTToolWebSearch
|
128
|
+
from versionhq.tool.gpt.file_search import GPTToolFileSearch
|
129
|
+
from versionhq.tool.gpt.cup import GPTToolCUP
|
127
130
|
|
128
131
|
if not self.tools:
|
129
132
|
return self
|
@@ -131,7 +134,7 @@ class Agent(BaseModel):
|
|
131
134
|
tool_list = []
|
132
135
|
for item in self.tools:
|
133
136
|
match item:
|
134
|
-
case RagTool() | BaseTool():
|
137
|
+
case RagTool() | BaseTool() | GPTToolCUP() | GPTToolFileSearch() | GPTToolWebSearch():
|
135
138
|
tool_list.append(item)
|
136
139
|
|
137
140
|
case Tool():
|
@@ -353,8 +356,8 @@ class Agent(BaseModel):
|
|
353
356
|
response_format: Optional[Dict[str, Any]] = None,
|
354
357
|
tools: Optional[List[InstanceOf[Tool]| InstanceOf[ToolSet] | Type[Tool]]] = None,
|
355
358
|
tool_res_as_final: bool = False,
|
356
|
-
task: Any = None
|
357
|
-
) ->
|
359
|
+
# task: Any = None
|
360
|
+
) -> Tuple[str, UsageMetrics]:
|
358
361
|
"""
|
359
362
|
Create formatted prompts using the developer prompt and the agent's backstory, then call the base model.
|
360
363
|
- Execute the task up to `self.max_retry_limit` times in case of receiving an error or empty response.
|
@@ -364,6 +367,7 @@ class Agent(BaseModel):
|
|
364
367
|
task_execution_counter = 0
|
365
368
|
iterations = 0
|
366
369
|
raw_response = None
|
370
|
+
usage = UsageMetrics()
|
367
371
|
|
368
372
|
try:
|
369
373
|
if self._rpm_controller and self.max_rpm:
|
@@ -373,17 +377,17 @@ class Agent(BaseModel):
|
|
373
377
|
|
374
378
|
if tool_res_as_final:
|
375
379
|
raw_response = self.func_calling_llm.call(messages=messages, tools=tools, tool_res_as_final=True)
|
376
|
-
|
380
|
+
usage.record_token_usage(*self.func_calling_llm._usages)
|
377
381
|
else:
|
378
382
|
raw_response = self.llm.call(messages=messages, response_format=response_format, tools=tools)
|
379
|
-
|
383
|
+
usage.record_token_usage(*self.llm._usages)
|
380
384
|
|
381
385
|
task_execution_counter += 1
|
382
386
|
Logger(**self._logger_config, filename=self.key).log(level="info", message=f"Agent response: {raw_response}", color="green")
|
383
|
-
return raw_response
|
387
|
+
return raw_response, usage
|
384
388
|
|
385
389
|
except Exception as e:
|
386
|
-
|
390
|
+
usage.record_errors(type=ErrorType.API)
|
387
391
|
Logger(**self._logger_config, filename=self.key).log(level="error", message=f"An error occured. The agent will retry: {str(e)}", color="red")
|
388
392
|
|
389
393
|
while not raw_response and task_execution_counter <= self.max_retry_limit:
|
@@ -392,12 +396,12 @@ class Agent(BaseModel):
|
|
392
396
|
self._rpm_controller.check_or_wait()
|
393
397
|
|
394
398
|
raw_response = self.llm.call(messages=messages, response_format=response_format, tools=tools)
|
395
|
-
|
399
|
+
usage.record_token_usage(*self.llm._usages)
|
396
400
|
iterations += 1
|
397
401
|
|
398
402
|
task_execution_counter += 1
|
399
403
|
Logger(**self._logger_config, filename=self.key).log(level="info", message=f"Agent #{task_execution_counter} response: {raw_response}", color="green")
|
400
|
-
return raw_response
|
404
|
+
return raw_response, usage
|
401
405
|
|
402
406
|
if not raw_response:
|
403
407
|
Logger(**self._logger_config, filename=self.key).log(level="error", message="Received None or empty response from the model", color="red")
|
@@ -423,6 +427,57 @@ class Agent(BaseModel):
|
|
423
427
|
return self.set_up_llm()
|
424
428
|
|
425
429
|
|
430
|
+
def _sort_tools(self, task = None) -> Tuple[List[Any], List[Any], List[Any]]:
|
431
|
+
"""Sorts agent and task tools by class."""
|
432
|
+
|
433
|
+
from versionhq.tool.rag_tool import RagTool
|
434
|
+
from versionhq.tool.gpt.web_search import GPTToolWebSearch
|
435
|
+
from versionhq.tool.gpt.file_search import GPTToolFileSearch
|
436
|
+
from versionhq.tool.gpt.cup import GPTToolCUP
|
437
|
+
|
438
|
+
all_tools = []
|
439
|
+
if task: all_tools = task.tools + self.tools if task.can_use_agent_tools else task.tools
|
440
|
+
else: all_tools = self.tools
|
441
|
+
|
442
|
+
rag_tools, gpt_tools, tools = [], [], []
|
443
|
+
if all_tools:
|
444
|
+
for item in all_tools:
|
445
|
+
match item:
|
446
|
+
case RagTool():
|
447
|
+
rag_tools.append(item)
|
448
|
+
|
449
|
+
case GPTToolCUP() | GPTToolFileSearch() | GPTToolWebSearch():
|
450
|
+
gpt_tools.append(item)
|
451
|
+
|
452
|
+
case Tool() | BaseTool() | ToolSet():
|
453
|
+
tools.append(item)
|
454
|
+
|
455
|
+
return rag_tools, gpt_tools, tools
|
456
|
+
|
457
|
+
|
458
|
+
def _handle_gpt_tools(self, gpt_tools: list[Any] = None) -> Any: # TaskOutput
|
459
|
+
"""Generates k, v pairs from multiple GPT tool results and stores them in TaskOutput class."""
|
460
|
+
|
461
|
+
from versionhq.task.model import TaskOutput
|
462
|
+
from versionhq._utils import UsageMetrics
|
463
|
+
|
464
|
+
if not gpt_tools:
|
465
|
+
return
|
466
|
+
|
467
|
+
tool_res = dict()
|
468
|
+
annotation_set = dict()
|
469
|
+
total_usage = UsageMetrics()
|
470
|
+
|
471
|
+
for i, item in enumerate(gpt_tools):
|
472
|
+
raw, annotations, usage = item.run()
|
473
|
+
tool_res.update({ str(i): raw })
|
474
|
+
annotation_set.update({ str(i): annotations })
|
475
|
+
total_usage.aggregate(metrics=usage)
|
476
|
+
|
477
|
+
res = TaskOutput(raw=str(tool_res), tool_output=tool_res, usage=total_usage, annotations=annotation_set)
|
478
|
+
return res
|
479
|
+
|
480
|
+
|
426
481
|
def update(self, **kwargs) -> Self:
|
427
482
|
"""
|
428
483
|
Update the existing agent. Address variables that require runnning set_up_x methods first, then update remaining variables.
|
@@ -482,15 +537,21 @@ class Agent(BaseModel):
|
|
482
537
|
image: str = None,
|
483
538
|
file: str = None,
|
484
539
|
audio: str = None
|
485
|
-
) ->
|
540
|
+
) -> Any:
|
486
541
|
"""
|
487
542
|
Defines and executes a task, then returns TaskOutput object with the generated task.
|
488
543
|
"""
|
489
544
|
|
545
|
+
from versionhq.task.model import Task
|
546
|
+
|
490
547
|
if not self.role:
|
491
|
-
return None
|
548
|
+
return None, None
|
492
549
|
|
493
|
-
|
550
|
+
_, gpt_tools, _ = self._sort_tools()
|
551
|
+
|
552
|
+
if gpt_tools and tool_res_as_final == True:
|
553
|
+
res = self._handle_gpt_tools(gpt_tools=gpt_tools)
|
554
|
+
return res
|
494
555
|
|
495
556
|
class Output(BaseModel):
|
496
557
|
result: str
|
@@ -503,44 +564,47 @@ class Agent(BaseModel):
|
|
503
564
|
image=image, #REFINEME - query memory/knowledge or self create
|
504
565
|
file=file,
|
505
566
|
audio=audio,
|
567
|
+
can_use_agent_tools=True if self.tools else False,
|
506
568
|
)
|
507
569
|
res = task.execute(agent=self, context=context)
|
508
|
-
return res
|
570
|
+
return res
|
509
571
|
|
510
572
|
|
511
|
-
def execute_task(self, task, context: Optional[Any] = None
|
573
|
+
def execute_task(self, task, context: Optional[Any] = None) -> Tuple[str, str, Any, UsageMetrics]:
|
512
574
|
"""Handling task execution."""
|
513
575
|
|
514
|
-
from versionhq.task.model import Task
|
515
|
-
from versionhq.tool.rag_tool import RagTool
|
516
576
|
from versionhq._prompt.model import Prompt
|
577
|
+
from versionhq.task.model import Task
|
517
578
|
|
518
579
|
task: InstanceOf[Task] = task
|
519
|
-
|
520
|
-
|
521
|
-
|
580
|
+
rag_tools, gpt_tools, tools = self._sort_tools(task=task)
|
581
|
+
raw_response = ""
|
582
|
+
user_prompt, dev_prompt = "", ""
|
583
|
+
usage = UsageMetrics(id=task.id)
|
522
584
|
|
523
585
|
if self.max_rpm and self._rpm_controller:
|
524
586
|
self._rpm_controller._reset_request_count()
|
525
587
|
|
526
|
-
|
588
|
+
if task.tool_res_as_final == True and gpt_tools:
|
589
|
+
self._times_executed += 1
|
590
|
+
res = self._handle_gpt_tools(gpt_tools=gpt_tools)
|
591
|
+
return user_prompt, dev_prompt, res, res.usage
|
592
|
+
|
593
|
+
user_prompt, dev_prompt, messages = Prompt(task=task, agent=self, context=context).format_core(rag_tools=rag_tools, gpt_tools=gpt_tools)
|
527
594
|
|
528
595
|
try:
|
529
596
|
self._times_executed += 1
|
530
|
-
raw_response = self._invoke(
|
597
|
+
raw_response, usage = self._invoke(
|
531
598
|
messages=messages,
|
532
599
|
response_format=task._structure_response_format(model_provider=self.llm.provider),
|
533
600
|
tools=tools,
|
534
601
|
tool_res_as_final=task.tool_res_as_final,
|
535
|
-
task=task
|
536
602
|
)
|
537
|
-
if raw_response:
|
538
|
-
task._usage.successful_requests += 1
|
539
603
|
|
540
604
|
except Exception as e:
|
541
605
|
self._times_executed += 1
|
542
606
|
Logger(**self._logger_config, filename=self.key).log(level="error", message=f"The agent failed to execute the task. Error: {str(e)}", color="red")
|
543
|
-
user_prompt, dev_prompt, raw_response = self.execute_task(task, context
|
607
|
+
user_prompt, dev_prompt, raw_response, usage = self.execute_task(task, context)
|
544
608
|
|
545
609
|
if self._times_executed > self.max_retry_limit:
|
546
610
|
Logger(**self._logger_config, filename=self.key).log(level="error", message=f"Max retry limit has exceeded.", color="red")
|
@@ -549,7 +613,7 @@ class Agent(BaseModel):
|
|
549
613
|
if self.max_rpm and self._rpm_controller:
|
550
614
|
self._rpm_controller.stop_rpm_counter()
|
551
615
|
|
552
|
-
return user_prompt, dev_prompt, raw_response
|
616
|
+
return user_prompt, dev_prompt, raw_response, usage
|
553
617
|
|
554
618
|
|
555
619
|
@property
|
@@ -7,7 +7,7 @@ from versionhq.task.model import Task
|
|
7
7
|
from versionhq.agent.model import Agent
|
8
8
|
from versionhq.agent_network.model import AgentNetwork, Member, Formation
|
9
9
|
from versionhq.agent.inhouse_agents import vhq_formation_planner
|
10
|
-
from versionhq._utils import Logger
|
10
|
+
from versionhq._utils import Logger, is_valid_enum
|
11
11
|
|
12
12
|
import chromadb
|
13
13
|
chromadb.api.client.SharedSystemClient.clear_system_cache()
|
@@ -83,14 +83,6 @@ def form_agent_network(
|
|
83
83
|
|
84
84
|
res = vhq_task.execute(agent=vhq_formation_planner, context=context)
|
85
85
|
|
86
|
-
formation_keys = []
|
87
|
-
if hasattr(res.pydantic, "formation"):
|
88
|
-
formation_keys = [k for k in Formation._member_map_.keys() if k == res.pydantic.formation.upper()]
|
89
|
-
elif "formation" in res.json_dict:
|
90
|
-
formation_keys = [k for k in Formation._member_map_.keys() if k == res.json_dict["formation"].upper()]
|
91
|
-
|
92
|
-
_formation = Formation[formation_keys[0]] if formation_keys else Formation.SUPERVISING
|
93
|
-
|
94
86
|
network_tasks = []
|
95
87
|
members = []
|
96
88
|
leader = res._fetch_value_of(key="leader_agent")
|
@@ -98,6 +90,8 @@ def form_agent_network(
|
|
98
90
|
created_agents = [Agent(role=str(item), goal=str(item)) for item in agent_roles] if agent_roles else []
|
99
91
|
task_descriptions = res._fetch_value_of(key="task_descriptions")
|
100
92
|
task_outcomes = res._fetch_value_of(key="task_outcomes")
|
93
|
+
formation_key = res.json_dict["formation"] if "formation" in res.json_dict else None
|
94
|
+
_formation = Formation[formation_key] if is_valid_enum(key=formation_key, enum=Formation) else Formation.SUPERVISING
|
101
95
|
|
102
96
|
if agents:
|
103
97
|
for i, agent in enumerate(created_agents):
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import uuid
|
2
2
|
import warnings
|
3
|
-
from enum import
|
4
|
-
from concurrent.futures import Future
|
3
|
+
from enum import IntEnum
|
5
4
|
from hashlib import md5
|
6
5
|
from typing import Any, Dict, List, Callable, Optional, Tuple
|
7
6
|
from typing_extensions import Self
|
@@ -30,7 +29,7 @@ GenerateSchema.match_type = match_type
|
|
30
29
|
warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd")
|
31
30
|
|
32
31
|
|
33
|
-
class Formation(
|
32
|
+
class Formation(IntEnum):
|
34
33
|
SOLO = 1
|
35
34
|
SUPERVISING = 2
|
36
35
|
SQUAD = 3
|
@@ -38,7 +37,7 @@ class Formation(str, Enum):
|
|
38
37
|
HYBRID = 10
|
39
38
|
|
40
39
|
|
41
|
-
class TaskHandlingProcess(
|
40
|
+
class TaskHandlingProcess(IntEnum):
|
42
41
|
"""
|
43
42
|
A class representing task handling processes to tackle multiple tasks.
|
44
43
|
When the agent network has multiple tasks that connect with edges, follow the edge conditions.
|