dhti-elixir-base 1.5.0__tar.gz → 1.5.2__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.
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/CHANGELOG.md +16 -5
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/PKG-INFO +2 -2
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/pyproject.toml +1 -1
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/crewai/agent_wrapper.py +12 -11
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/crewai/chain_tool_wrapper.py +32 -23
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/crewai/langchain_tool_wrapper.py +13 -10
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/crewai/llm_wrapper.py +57 -40
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/uv.lock +2790 -2567
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.devcontainer/Dockerfile +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.devcontainer/devcontainer.json +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.devcontainer/postCreateCommand.sh +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.github/actions/setup-python-env/action.yml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.github/config.yml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.github/dependabot.yml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.github/workflows/bump.yml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.github/workflows/docs.yml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.github/workflows/github-dependents-info.yml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.github/workflows/pr.yml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.github/workflows/publish.yml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.github/workflows/pytest.yml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.github/workflows/tox.yml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.github/workflows/upgrade.yml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/.gitignore +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/AUTHORS.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/CONTRIBUTING.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/Dockerfile +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/LICENSE +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/Makefile +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/README.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/codecov.yaml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/docs/contributing.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/docs/crewai.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/docs/github-dependents-info.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/docs/index.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/docs/modules.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/examples/chain.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/examples/crewai_test.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/examples/graph.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/examples/graph_limitations.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/mkdocs.yml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/notes/cds-hook.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/notes/crewai_future_improvements.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/notes/parlant.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/notes/vllm-images.md +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/__init__.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/agent.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/cds_hook/__init__.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/cds_hook/card.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/cds_hook/generate_cards.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/cds_hook/request.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/cds_hook/request_parser.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/cds_hook/routes.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/cds_hook/service.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/chain.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/chatllm.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/crewai/__init__.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/embedding.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/fhir/__init__.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/fhir/fhir_search.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/fhir/smart_on_fhir.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/graph.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/llm.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/mcp.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/model.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/mydi.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/parlant_agent.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/rag/__init__.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/rag/process.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/rag/redis_schema.yaml +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/server.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/t_install.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/__init__.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/bootstrap.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/cds_hook/__init__.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/cds_hook/test_card.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/cds_hook/test_generate_cards.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/cds_hook/test_request.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/cds_hook/test_request_parser.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/cds_hook/test_service.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/conftest.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/crewai/__init__.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/crewai/test_agent_wrapper.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/crewai/test_chain_tool_wrapper.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/crewai/test_langchain_tool_wrapper.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/crewai/test_llm_wrapper.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/fhir/__init__.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/fhir/test_fhir_search.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/fhir/test_smart_on_fhir_search.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/rag/__init__.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/rag/test_process.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/test_agent.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/test_chain.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/test_chatllm.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/test_embedding.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/test_graph.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/test_llm.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/test_model.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/test_parlant_agent.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tests/test_server.py +0 -0
- {dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/tox.ini +0 -0
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased](https://github.com/dermatologist/dhti-elixir-base/tree/HEAD)
|
|
4
4
|
|
|
5
|
-
[Full Changelog](https://github.com/dermatologist/dhti-elixir-base/compare/v1.
|
|
6
|
-
|
|
7
|
-
**Implemented enhancements:**
|
|
8
|
-
|
|
9
|
-
- Add CrewAI wrappers for LLMs, Tools and Agents [\#77](https://github.com/dermatologist/dhti-elixir-base/issues/77)
|
|
5
|
+
[Full Changelog](https://github.com/dermatologist/dhti-elixir-base/compare/v1.5.1...HEAD)
|
|
10
6
|
|
|
11
7
|
**Merged pull requests:**
|
|
12
8
|
|
|
9
|
+
- Refactor code structure for improved readability and maintainability [\#106](https://github.com/dermatologist/dhti-elixir-base/pull/106) ([dermatologist](https://github.com/dermatologist))
|
|
10
|
+
- \[Automated\] Dependencies upgrade [\#84](https://github.com/dermatologist/dhti-elixir-base/pull/84) ([github-actions[bot]](https://github.com/apps/github-actions))
|
|
11
|
+
- Feature/fix return type 1 [\#79](https://github.com/dermatologist/dhti-elixir-base/pull/79) ([dermatologist](https://github.com/dermatologist))
|
|
13
12
|
- Add CrewAI wrappers for LLMs, Tools, and Agents [\#78](https://github.com/dermatologist/dhti-elixir-base/pull/78) ([Copilot](https://github.com/apps/copilot-swe-agent))
|
|
14
13
|
- \[Automated\] Dependencies upgrade [\#76](https://github.com/dermatologist/dhti-elixir-base/pull/76) ([github-actions[bot]](https://github.com/apps/github-actions))
|
|
15
14
|
- fix\(routes\): Improve response handling in invoke\_chain function [\#73](https://github.com/dermatologist/dhti-elixir-base/pull/73) ([dermatologist](https://github.com/dermatologist))
|
|
@@ -40,6 +39,18 @@
|
|
|
40
39
|
- Feature/uv build 1 [\#40](https://github.com/dermatologist/dhti-elixir-base/pull/40) ([dermatologist](https://github.com/dermatologist))
|
|
41
40
|
- Feature/mcp 1 [\#39](https://github.com/dermatologist/dhti-elixir-base/pull/39) ([dermatologist](https://github.com/dermatologist))
|
|
42
41
|
|
|
42
|
+
## [v1.5.1](https://github.com/dermatologist/dhti-elixir-base/tree/v1.5.1) (2026-02-10)
|
|
43
|
+
|
|
44
|
+
[Full Changelog](https://github.com/dermatologist/dhti-elixir-base/compare/v1.5.0...v1.5.1)
|
|
45
|
+
|
|
46
|
+
## [v1.5.0](https://github.com/dermatologist/dhti-elixir-base/tree/v1.5.0) (2026-02-09)
|
|
47
|
+
|
|
48
|
+
[Full Changelog](https://github.com/dermatologist/dhti-elixir-base/compare/v1.4.1...v1.5.0)
|
|
49
|
+
|
|
50
|
+
**Implemented enhancements:**
|
|
51
|
+
|
|
52
|
+
- Add CrewAI wrappers for LLMs, Tools and Agents [\#77](https://github.com/dermatologist/dhti-elixir-base/issues/77)
|
|
53
|
+
|
|
43
54
|
## [v1.4.1](https://github.com/dermatologist/dhti-elixir-base/tree/v1.4.1) (2026-01-18)
|
|
44
55
|
|
|
45
56
|
[Full Changelog](https://github.com/dermatologist/dhti-elixir-base/compare/v1.4.0...v1.4.1)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dhti-elixir-base
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.2
|
|
4
4
|
Summary: DHTI Elixir Base
|
|
5
5
|
Project-URL: Documentation, https://github.com/dermatologist/dhti
|
|
6
6
|
Project-URL: Homepage, https://nuchange.ca
|
|
@@ -32,7 +32,7 @@ Requires-Dist: kink
|
|
|
32
32
|
Requires-Dist: langchain-community
|
|
33
33
|
Requires-Dist: langchain-core
|
|
34
34
|
Requires-Dist: langchain-mcp-adapters
|
|
35
|
-
Requires-Dist: langchain
|
|
35
|
+
Requires-Dist: langchain>=1.0.0
|
|
36
36
|
Requires-Dist: langgraph
|
|
37
37
|
Requires-Dist: langserve
|
|
38
38
|
Requires-Dist: mcp
|
{dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/crewai/agent_wrapper.py
RENAMED
|
@@ -100,23 +100,24 @@ class CrewAIAgentWrapper(CrewAIAgent):
|
|
|
100
100
|
try:
|
|
101
101
|
from crewai.tools import BaseTool as CrewAIBaseTool
|
|
102
102
|
except ImportError:
|
|
103
|
-
from
|
|
103
|
+
from crewai.tools.base_tool import BaseTool as CrewAIBaseTool
|
|
104
104
|
|
|
105
105
|
from .langchain_tool_wrapper import CrewAILangChainToolWrapper
|
|
106
106
|
|
|
107
107
|
validated_tools = []
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
108
|
+
tool_list = tools if isinstance(tools, list) else [tools]
|
|
109
|
+
for tool in tool_list:
|
|
110
|
+
try:
|
|
111
|
+
# If it's already a BaseTool, use it as is
|
|
112
|
+
if isinstance(tool, CrewAIBaseTool):
|
|
113
|
+
validated_tools.append(tool)
|
|
114
|
+
# Try to wrap as a LangChain tool
|
|
115
|
+
else:
|
|
115
116
|
wrapped = CrewAILangChainToolWrapper(langchain_tool=tool)
|
|
116
117
|
validated_tools.append(wrapped)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
except Exception as e:
|
|
119
|
+
# Log but skip tools that can't be wrapped
|
|
120
|
+
pass
|
|
120
121
|
tools = validated_tools if validated_tools else None
|
|
121
122
|
|
|
122
123
|
# Initialize CrewAI Agent
|
{dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/crewai/chain_tool_wrapper.py
RENAMED
|
@@ -21,7 +21,7 @@ from pydantic import PrivateAttr
|
|
|
21
21
|
try:
|
|
22
22
|
from crewai.tools import BaseTool as CrewAIBaseTool
|
|
23
23
|
except ImportError:
|
|
24
|
-
from
|
|
24
|
+
from crewai.tools.base_tool import BaseTool as CrewAIBaseTool
|
|
25
25
|
|
|
26
26
|
from ..chain import BaseChain
|
|
27
27
|
|
|
@@ -114,30 +114,39 @@ class CrewAIChainToolWrapper(CrewAIBaseTool):
|
|
|
114
114
|
|
|
115
115
|
Returns:
|
|
116
116
|
str: The result of the chain execution
|
|
117
|
+
|
|
118
|
+
Raises:
|
|
119
|
+
ValueError: If neither positional nor keyword arguments are provided
|
|
120
|
+
RuntimeError: If chain execution fails
|
|
117
121
|
"""
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
raise ValueError(
|
|
126
|
-
"Either provide input as a keyword argument or as a positional argument"
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
# Convert result to string
|
|
130
|
-
if isinstance(result, dict):
|
|
131
|
-
# If result is a dict, try to extract the most relevant value
|
|
132
|
-
if "cards" in result:
|
|
133
|
-
# Handle CDS Hook response format
|
|
134
|
-
return str(result.get("cards", []))
|
|
135
|
-
elif "output" in result:
|
|
136
|
-
return str(result["output"])
|
|
122
|
+
try:
|
|
123
|
+
# If kwargs are provided, use them directly
|
|
124
|
+
if kwargs:
|
|
125
|
+
result = self._dhti_chain.invoke(**kwargs)
|
|
126
|
+
# If a single positional arg is provided, treat it as the input
|
|
127
|
+
elif args:
|
|
128
|
+
result = self._dhti_chain.invoke(input=args[0])
|
|
137
129
|
else:
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
130
|
+
raise ValueError(
|
|
131
|
+
"Either provide input as a keyword argument or as a positional argument"
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
# Convert result to string
|
|
135
|
+
if isinstance(result, dict):
|
|
136
|
+
# If result is a dict, try to extract the most relevant value
|
|
137
|
+
if "cards" in result:
|
|
138
|
+
# Handle CDS Hook response format
|
|
139
|
+
return str(result.get("cards", []))
|
|
140
|
+
elif "output" in result:
|
|
141
|
+
return str(result["output"])
|
|
142
|
+
else:
|
|
143
|
+
return str(result)
|
|
144
|
+
|
|
145
|
+
return str(result)
|
|
146
|
+
except ValueError:
|
|
147
|
+
raise
|
|
148
|
+
except Exception as e:
|
|
149
|
+
raise RuntimeError(f"Chain execution failed: {e}") from e
|
|
141
150
|
|
|
142
151
|
def __str__(self) -> str:
|
|
143
152
|
"""Return string representation of the wrapper."""
|
|
@@ -21,7 +21,7 @@ from pydantic import PrivateAttr
|
|
|
21
21
|
try:
|
|
22
22
|
from crewai.tools import BaseTool as CrewAIBaseTool
|
|
23
23
|
except ImportError:
|
|
24
|
-
from
|
|
24
|
+
from crewai.tools.base_tool import BaseTool as CrewAIBaseTool
|
|
25
25
|
|
|
26
26
|
from langchain_core.tools import BaseTool as LangChainBaseTool
|
|
27
27
|
|
|
@@ -104,11 +104,11 @@ class CrewAILangChainToolWrapper(CrewAIBaseTool):
|
|
|
104
104
|
|
|
105
105
|
Returns:
|
|
106
106
|
str: The result of the tool execution
|
|
107
|
+
|
|
108
|
+
Raises:
|
|
109
|
+
AttributeError: If no valid invocation method is found on the tool
|
|
107
110
|
"""
|
|
108
|
-
# Try different invocation methods based on the tool type
|
|
109
111
|
try:
|
|
110
|
-
result = None
|
|
111
|
-
|
|
112
112
|
# Try using the run method (common in LangChain tools)
|
|
113
113
|
if hasattr(self._langchain_tool, "run"):
|
|
114
114
|
try:
|
|
@@ -117,18 +117,18 @@ class CrewAILangChainToolWrapper(CrewAIBaseTool):
|
|
|
117
117
|
elif kwargs:
|
|
118
118
|
result = self._langchain_tool.run(**kwargs)
|
|
119
119
|
else:
|
|
120
|
-
result = self._langchain_tool.run()
|
|
120
|
+
result = self._langchain_tool.run(tool_input={})
|
|
121
121
|
return str(result)
|
|
122
122
|
except (AttributeError, TypeError):
|
|
123
123
|
# run method doesn't exist or failed, try next option
|
|
124
124
|
pass
|
|
125
125
|
|
|
126
|
-
#
|
|
126
|
+
# Try using the invoke method (newer LangChain tools)
|
|
127
127
|
if hasattr(self._langchain_tool, "invoke"):
|
|
128
128
|
try:
|
|
129
129
|
if args and not kwargs:
|
|
130
130
|
result = self._langchain_tool.invoke(
|
|
131
|
-
args[0] if len(args) == 1 else args
|
|
131
|
+
args[0] if len(args) == 1 else args # type: ignore
|
|
132
132
|
)
|
|
133
133
|
elif kwargs:
|
|
134
134
|
result = self._langchain_tool.invoke(kwargs)
|
|
@@ -139,7 +139,7 @@ class CrewAILangChainToolWrapper(CrewAIBaseTool):
|
|
|
139
139
|
# invoke method doesn't exist or failed, try next option
|
|
140
140
|
pass
|
|
141
141
|
|
|
142
|
-
# Check if __call__ is explicitly set
|
|
142
|
+
# Check if __call__ is explicitly set on the object (for test mocks)
|
|
143
143
|
if "__call__" in self._langchain_tool.__dict__:
|
|
144
144
|
__call_method = self._langchain_tool.__dict__["__call__"]
|
|
145
145
|
if args and not kwargs:
|
|
@@ -165,11 +165,14 @@ class CrewAILangChainToolWrapper(CrewAIBaseTool):
|
|
|
165
165
|
pass
|
|
166
166
|
|
|
167
167
|
# If we got here, no valid method was found
|
|
168
|
+
tool_type = type(self._langchain_tool).__name__
|
|
168
169
|
raise AttributeError(
|
|
169
|
-
f"LangChain tool {
|
|
170
|
-
"run, invoke, or __call__ methods"
|
|
170
|
+
f"LangChain tool '{tool_type}' does not have any of the following: "
|
|
171
|
+
"run(), invoke(), or __call__() methods"
|
|
171
172
|
)
|
|
172
173
|
|
|
174
|
+
except AttributeError:
|
|
175
|
+
raise
|
|
173
176
|
except Exception as e:
|
|
174
177
|
return f"Error executing LangChain tool: {e!s}"
|
|
175
178
|
|
{dhti_elixir_base-1.5.0 → dhti_elixir_base-1.5.2}/src/dhti_elixir_base/crewai/llm_wrapper.py
RENAMED
|
@@ -17,6 +17,7 @@ limitations under the License.
|
|
|
17
17
|
from typing import Any
|
|
18
18
|
|
|
19
19
|
from crewai.llms.base_llm import BaseLLM as CrewAIBaseLLM
|
|
20
|
+
from crewai.types.usage_metrics import UsageMetrics
|
|
20
21
|
|
|
21
22
|
from ..chatllm import BaseChatLLM
|
|
22
23
|
from ..llm import BaseLLM
|
|
@@ -72,40 +73,51 @@ class CrewAILLMWrapper(CrewAIBaseLLM):
|
|
|
72
73
|
|
|
73
74
|
Returns:
|
|
74
75
|
str: The generated response from the LLM
|
|
75
|
-
"""
|
|
76
|
-
# Convert messages to the format expected by DHTI LLMs
|
|
77
|
-
if isinstance(self._dhti_llm, BaseChatLLM):
|
|
78
|
-
# For BaseChatLLM, convert to LangChain messages
|
|
79
|
-
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
|
|
80
|
-
|
|
81
|
-
lc_messages = []
|
|
82
|
-
for msg in messages:
|
|
83
|
-
role = msg.get("role", "user")
|
|
84
|
-
content = msg.get("content", "")
|
|
85
|
-
|
|
86
|
-
if role == "system":
|
|
87
|
-
lc_messages.append(SystemMessage(content=content))
|
|
88
|
-
elif role == "assistant":
|
|
89
|
-
lc_messages.append(AIMessage(content=content))
|
|
90
|
-
else: # user or any other role
|
|
91
|
-
lc_messages.append(HumanMessage(content=content))
|
|
92
|
-
|
|
93
|
-
result = self._dhti_llm.invoke(lc_messages)
|
|
94
|
-
return result.content if hasattr(result, "content") else str(result)
|
|
95
|
-
else:
|
|
96
|
-
# For BaseLLM, combine messages into a single prompt
|
|
97
|
-
prompt = "\n".join(
|
|
98
|
-
[
|
|
99
|
-
f"{msg.get('role', 'user')}: {msg.get('content', '')}"
|
|
100
|
-
for msg in messages
|
|
101
|
-
]
|
|
102
|
-
)
|
|
103
|
-
return self._dhti_llm.invoke(prompt)
|
|
104
76
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
77
|
+
Raises:
|
|
78
|
+
ValueError: If messages list is empty or malformed
|
|
79
|
+
RuntimeError: If LLM invocation fails
|
|
80
|
+
"""
|
|
81
|
+
if not messages:
|
|
82
|
+
raise ValueError("Messages list cannot be empty")
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
# Convert messages to the format expected by DHTI LLMs
|
|
86
|
+
if isinstance(self._dhti_llm, BaseChatLLM):
|
|
87
|
+
# For BaseChatLLM, convert to LangChain messages
|
|
88
|
+
from langchain_core.messages import (
|
|
89
|
+
AIMessage,
|
|
90
|
+
HumanMessage,
|
|
91
|
+
SystemMessage,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
lc_messages = []
|
|
95
|
+
for msg in messages:
|
|
96
|
+
role = msg.get("role", "user")
|
|
97
|
+
content = msg.get("content", "")
|
|
98
|
+
|
|
99
|
+
if role == "system":
|
|
100
|
+
lc_messages.append(SystemMessage(content=content))
|
|
101
|
+
elif role == "assistant":
|
|
102
|
+
lc_messages.append(AIMessage(content=content))
|
|
103
|
+
else: # user or any other role
|
|
104
|
+
lc_messages.append(HumanMessage(content=content))
|
|
105
|
+
|
|
106
|
+
result = self._dhti_llm.invoke(lc_messages)
|
|
107
|
+
return result.content if hasattr(result, "content") else str(result) # type: ignore
|
|
108
|
+
else:
|
|
109
|
+
# For BaseLLM, combine messages into a single prompt
|
|
110
|
+
prompt = "\n".join(
|
|
111
|
+
[
|
|
112
|
+
f"{msg.get('role', 'user')}: {msg.get('content', '')}"
|
|
113
|
+
for msg in messages
|
|
114
|
+
]
|
|
115
|
+
)
|
|
116
|
+
return self._dhti_llm.invoke(prompt)
|
|
117
|
+
except Exception as e:
|
|
118
|
+
raise RuntimeError(f"Failed to invoke LLM: {e}") from e
|
|
119
|
+
|
|
120
|
+
is_litellm: bool = False
|
|
109
121
|
|
|
110
122
|
@property
|
|
111
123
|
def model(self) -> str:
|
|
@@ -117,19 +129,24 @@ class CrewAILLMWrapper(CrewAIBaseLLM):
|
|
|
117
129
|
"""Return the provider name."""
|
|
118
130
|
return "dhti-elixir"
|
|
119
131
|
|
|
132
|
+
@provider.setter
|
|
133
|
+
def provider(self, value: str) -> None:
|
|
134
|
+
# Read-only property; setter is a no-op to satisfy base class signature
|
|
135
|
+
pass
|
|
136
|
+
|
|
120
137
|
def get_context_window_size(self) -> int:
|
|
121
138
|
"""Get the context window size for the model."""
|
|
122
139
|
# Default context window size
|
|
123
140
|
# This can be overridden in subclasses for specific models
|
|
124
|
-
return 4096
|
|
141
|
+
return 4096 * 2
|
|
125
142
|
|
|
126
|
-
def get_token_usage_summary(self) ->
|
|
143
|
+
def get_token_usage_summary(self) -> UsageMetrics:
|
|
127
144
|
"""Get token usage summary."""
|
|
128
|
-
return
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
145
|
+
return UsageMetrics(
|
|
146
|
+
prompt_tokens=0,
|
|
147
|
+
completion_tokens=0,
|
|
148
|
+
total_tokens=0,
|
|
149
|
+
)
|
|
133
150
|
|
|
134
151
|
def supports_stop_words(self) -> bool:
|
|
135
152
|
"""Check if the model supports stop words."""
|