nvidia-nat-crewai 1.3.0.dev2__py3-none-any.whl → 1.3.0rc2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,6 +41,7 @@ class CrewAIProfilerHandler(BaseProfilerCallback):
41
41
  A callback manager/handler for CrewAI that intercepts calls to:
42
42
  - ToolUsage._use
43
43
  - LLM Calls
44
+
44
45
  to collect usage statistics (tokens, inputs, outputs, time intervals, etc.)
45
46
  and store them in NAT's usage_stats queue for subsequent analysis.
46
47
  """
@@ -94,7 +95,7 @@ class CrewAIProfilerHandler(BaseProfilerCallback):
94
95
  if tool_info:
95
96
  tool_name = tool_info.name
96
97
  except Exception as e:
97
- logger.exception("Error getting tool name: %s", e, exc_info=True)
98
+ logger.exception("Error getting tool name: %s", e)
98
99
 
99
100
  try:
100
101
  # Pre-call usage event
@@ -132,7 +133,7 @@ class CrewAIProfilerHandler(BaseProfilerCallback):
132
133
  return result
133
134
 
134
135
  except Exception as e:
135
- logger.exception("ToolUsage._use error: %s", e)
136
+ logger.error("ToolUsage._use error: %s", e)
136
137
  raise
137
138
 
138
139
  return wrapped_tool_use
@@ -158,7 +159,7 @@ class CrewAIProfilerHandler(BaseProfilerCallback):
158
159
  for message in kwargs.get('messages', []):
159
160
  model_input += message.get('content', "")
160
161
  except Exception as e:
161
- logger.exception("Error getting model input: %s", e, exc_info=True)
162
+ logger.exception("Error getting model input: %s", e)
162
163
 
163
164
  # Record the start event
164
165
  input_stats = IntermediateStepPayload(
@@ -182,7 +183,7 @@ class CrewAIProfilerHandler(BaseProfilerCallback):
182
183
  msg = choice.model_extra["message"]
183
184
  model_output += msg.get('content', "")
184
185
  except Exception as e:
185
- logger.exception("Error getting model output: %s", e, exc_info=True)
186
+ logger.exception("Error getting model output: %s", e)
186
187
 
187
188
  now = time.time()
188
189
  # Record the end event
nat/plugins/crewai/llm.py CHANGED
@@ -14,15 +14,50 @@
14
14
  # limitations under the License.
15
15
 
16
16
  import os
17
+ from typing import TypeVar
17
18
 
18
19
  from nat.builder.builder import Builder
19
20
  from nat.builder.framework_enum import LLMFrameworkEnum
20
21
  from nat.cli.register_workflow import register_llm_client
22
+ from nat.data_models.llm import LLMBaseConfig
21
23
  from nat.data_models.retry_mixin import RetryMixin
24
+ from nat.data_models.thinking_mixin import ThinkingMixin
22
25
  from nat.llm.azure_openai_llm import AzureOpenAIModelConfig
26
+ from nat.llm.litellm_llm import LiteLlmModelConfig
23
27
  from nat.llm.nim_llm import NIMModelConfig
24
28
  from nat.llm.openai_llm import OpenAIModelConfig
29
+ from nat.llm.utils.thinking import BaseThinkingInjector
30
+ from nat.llm.utils.thinking import FunctionArgumentWrapper
31
+ from nat.llm.utils.thinking import patch_with_thinking
25
32
  from nat.utils.exception_handlers.automatic_retries import patch_with_retry
33
+ from nat.utils.type_utils import override
34
+
35
+ ModelType = TypeVar("ModelType")
36
+
37
+
38
+ def _patch_llm_based_on_config(client: ModelType, llm_config: LLMBaseConfig) -> ModelType:
39
+
40
+ class CrewAIThinkingInjector(BaseThinkingInjector):
41
+
42
+ @override
43
+ def inject(self, messages: list[dict[str, str]], *args, **kwargs) -> FunctionArgumentWrapper:
44
+ new_messages = [{"role": "system", "content": self.system_prompt}] + messages
45
+ return FunctionArgumentWrapper(new_messages, *args, **kwargs)
46
+
47
+ if isinstance(llm_config, RetryMixin):
48
+ client = patch_with_retry(client,
49
+ retries=llm_config.num_retries,
50
+ retry_codes=llm_config.retry_on_status_codes,
51
+ retry_on_messages=llm_config.retry_on_errors)
52
+
53
+ if isinstance(llm_config, ThinkingMixin) and llm_config.thinking_system_prompt is not None:
54
+ client = patch_with_thinking(
55
+ client, CrewAIThinkingInjector(
56
+ system_prompt=llm_config.thinking_system_prompt,
57
+ function_names=["call"],
58
+ ))
59
+
60
+ return client
26
61
 
27
62
 
28
63
  @register_llm_client(config_type=AzureOpenAIModelConfig, wrapper_type=LLMFrameworkEnum.CREWAI)
@@ -32,42 +67,37 @@ async def azure_openai_crewai(llm_config: AzureOpenAIModelConfig, _builder: Buil
32
67
 
33
68
  # https://docs.crewai.com/en/concepts/llms#azure
34
69
 
35
- config_obj = {
36
- **llm_config.model_dump(exclude={
37
- "type",
38
- "api_key",
39
- "azure_endpoint",
40
- "azure_deployment",
41
- }, by_alias=True),
42
- }
43
-
44
- api_key = config_obj.get("api_key") or os.environ.get("AZURE_OPENAI_API_KEY") or os.environ.get("AZURE_API_KEY")
70
+ api_key = llm_config.api_key or os.environ.get("AZURE_OPENAI_API_KEY") or os.environ.get("AZURE_API_KEY")
45
71
  if api_key is None:
46
72
  raise ValueError("Azure API key is not set")
47
73
  os.environ["AZURE_API_KEY"] = api_key
48
- api_base = (config_obj.get("azure_endpoint") or os.environ.get("AZURE_OPENAI_ENDPOINT")
74
+ api_base = (llm_config.azure_endpoint or os.environ.get("AZURE_OPENAI_ENDPOINT")
49
75
  or os.environ.get("AZURE_API_BASE"))
50
76
  if api_base is None:
51
77
  raise ValueError("Azure endpoint is not set")
52
78
  os.environ["AZURE_API_BASE"] = api_base
53
79
 
54
80
  os.environ["AZURE_API_VERSION"] = llm_config.api_version
55
- model = config_obj.get("azure_deployment") or os.environ.get("AZURE_MODEL_DEPLOYMENT")
81
+ model = llm_config.azure_deployment or os.environ.get("AZURE_MODEL_DEPLOYMENT")
56
82
  if model is None:
57
83
  raise ValueError("Azure model deployment is not set")
58
84
 
59
- config_obj["model"] = model
60
-
61
- client = LLM(**config_obj)
62
-
63
- if isinstance(llm_config, RetryMixin):
64
-
65
- client = patch_with_retry(client,
66
- retries=llm_config.num_retries,
67
- retry_codes=llm_config.retry_on_status_codes,
68
- retry_on_messages=llm_config.retry_on_errors)
85
+ client = LLM(
86
+ **llm_config.model_dump(
87
+ exclude={
88
+ "type",
89
+ "api_key",
90
+ "azure_endpoint",
91
+ "azure_deployment",
92
+ "thinking",
93
+ },
94
+ by_alias=True,
95
+ exclude_none=True,
96
+ ),
97
+ model=model,
98
+ )
69
99
 
70
- yield client
100
+ yield _patch_llm_based_on_config(client, llm_config)
71
101
 
72
102
 
73
103
  @register_llm_client(config_type=NIMModelConfig, wrapper_type=LLMFrameworkEnum.CREWAI)
@@ -75,34 +105,18 @@ async def nim_crewai(llm_config: NIMModelConfig, _builder: Builder):
75
105
 
76
106
  from crewai import LLM
77
107
 
78
- config_obj = {
79
- **llm_config.model_dump(exclude={"type"}, by_alias=True),
80
- "model": f"nvidia_nim/{llm_config.model_name}",
81
- }
82
-
83
108
  # Because CrewAI uses a different environment variable for the API key, we need to set it here manually
84
- if ("api_key" not in config_obj or config_obj["api_key"] is None):
85
-
86
- if ("NVIDIA_NIM_API_KEY" in os.environ):
87
- # Dont need to do anything. User has already set the correct key
88
- pass
89
- else:
90
- nvidai_api_key = os.getenv("NVIDIA_API_KEY")
91
-
92
- if (nvidai_api_key is not None):
93
- # Transfer the key to the correct environment variable for LiteLLM
94
- os.environ["NVIDIA_NIM_API_KEY"] = nvidai_api_key
109
+ if llm_config.api_key is None and "NVIDIA_NIM_API_KEY" not in os.environ:
110
+ nvidia_api_key = os.getenv("NVIDIA_API_KEY")
111
+ if nvidia_api_key is not None:
112
+ os.environ["NVIDIA_NIM_API_KEY"] = nvidia_api_key
95
113
 
96
- client = LLM(**config_obj)
97
-
98
- if isinstance(llm_config, RetryMixin):
99
-
100
- client = patch_with_retry(client,
101
- retries=llm_config.num_retries,
102
- retry_codes=llm_config.retry_on_status_codes,
103
- retry_on_messages=llm_config.retry_on_errors)
114
+ client = LLM(
115
+ **llm_config.model_dump(exclude={"type", "model_name", "thinking"}, by_alias=True, exclude_none=True),
116
+ model=f"nvidia_nim/{llm_config.model_name}",
117
+ )
104
118
 
105
- yield client
119
+ yield _patch_llm_based_on_config(client, llm_config)
106
120
 
107
121
 
108
122
  @register_llm_client(config_type=OpenAIModelConfig, wrapper_type=LLMFrameworkEnum.CREWAI)
@@ -110,17 +124,16 @@ async def openai_crewai(llm_config: OpenAIModelConfig, _builder: Builder):
110
124
 
111
125
  from crewai import LLM
112
126
 
113
- config_obj = {
114
- **llm_config.model_dump(exclude={"type"}, by_alias=True),
115
- }
127
+ client = LLM(**llm_config.model_dump(exclude={"type", "thinking"}, by_alias=True, exclude_none=True))
116
128
 
117
- client = LLM(**config_obj)
129
+ yield _patch_llm_based_on_config(client, llm_config)
118
130
 
119
- if isinstance(llm_config, RetryMixin):
120
131
 
121
- client = patch_with_retry(client,
122
- retries=llm_config.num_retries,
123
- retry_codes=llm_config.retry_on_status_codes,
124
- retry_on_messages=llm_config.retry_on_errors)
132
+ @register_llm_client(config_type=LiteLlmModelConfig, wrapper_type=LLMFrameworkEnum.CREWAI)
133
+ async def litellm_crewai(llm_config: LiteLlmModelConfig, _builder: Builder):
134
+
135
+ from crewai import LLM
136
+
137
+ client = LLM(**llm_config.model_dump(exclude={"type", "thinking"}, by_alias=True, exclude_none=True))
125
138
 
126
- yield client
139
+ yield _patch_llm_based_on_config(client, llm_config)
@@ -13,7 +13,6 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- # pylint: disable=unused-import
17
16
  # flake8: noqa
18
17
  # isort:skip_file
19
18
 
@@ -1,13 +1,16 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nvidia-nat-crewai
3
- Version: 1.3.0.dev2
3
+ Version: 1.3.0rc2
4
4
  Summary: Subpackage for CrewAI integration in NeMo Agent toolkit
5
5
  Keywords: ai,rag,agents
6
6
  Classifier: Programming Language :: Python
7
- Requires-Python: <3.13,>=3.11
7
+ Classifier: Programming Language :: Python :: 3.11
8
+ Classifier: Programming Language :: Python :: 3.12
9
+ Classifier: Programming Language :: Python :: 3.13
10
+ Requires-Python: <3.14,>=3.11
8
11
  Description-Content-Type: text/markdown
9
- Requires-Dist: nvidia-nat==v1.3.0-dev2
10
- Requires-Dist: crewai~=0.95.0
12
+ Requires-Dist: nvidia-nat[litellm]==v1.3.0-rc2
13
+ Requires-Dist: crewai~=0.193.2
11
14
 
12
15
  <!--
13
16
  SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
@@ -0,0 +1,11 @@
1
+ nat/meta/pypi.md,sha256=T68FnThRzDGFf1LR8u-okM-r11-skSnKqSyI6HOktQY,1107
2
+ nat/plugins/crewai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ nat/plugins/crewai/crewai_callback_handler.py,sha256=m5u0RqUd94F0iIuUvknhVHn1SxYltg3lxAhN_3AogPQ,8334
4
+ nat/plugins/crewai/llm.py,sha256=T57f7hZ5Aa4MUdc6PJLfU6TkF_dO87DWh2KvyAsCt7g,5493
5
+ nat/plugins/crewai/register.py,sha256=_R3bhGmz___696_NwyIcpw3koMBiWqIFoWEFJ0VAgXs,831
6
+ nat/plugins/crewai/tool_wrapper.py,sha256=BNKEPQQCLKtXNzGDAKBLCdmGJXe9lBOVI1hObha8hoI,1569
7
+ nvidia_nat_crewai-1.3.0rc2.dist-info/METADATA,sha256=eHoD5XexO6TdXgWTuzOl8z0fdZtwRadG3HgEFeIm9ms,1605
8
+ nvidia_nat_crewai-1.3.0rc2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
+ nvidia_nat_crewai-1.3.0rc2.dist-info/entry_points.txt,sha256=YF5PUdQGr_OUDXB4TykElHJTsKT8yKkuE0bMX5n_RXs,58
10
+ nvidia_nat_crewai-1.3.0rc2.dist-info/top_level.txt,sha256=8-CJ2cP6-f0ZReXe5Hzqp-5pvzzHz-5Ds5H2bGqh1-U,4
11
+ nvidia_nat_crewai-1.3.0rc2.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- nat/meta/pypi.md,sha256=T68FnThRzDGFf1LR8u-okM-r11-skSnKqSyI6HOktQY,1107
2
- nat/plugins/crewai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- nat/plugins/crewai/crewai_callback_handler.py,sha256=LDOctDQC9qdba1SVGoVkceCOSYuDj_mnl3HCuq2nIuQ,8382
4
- nat/plugins/crewai/llm.py,sha256=ErsUXsHpQ-chWqFhYjp-OhARAnCl-HdV_tkrrTZzIOU,4665
5
- nat/plugins/crewai/register.py,sha256=RKXyuaXy4ftA5IL2RrCofIBjpie_-2lP9YZoHAiyPU0,863
6
- nat/plugins/crewai/tool_wrapper.py,sha256=BNKEPQQCLKtXNzGDAKBLCdmGJXe9lBOVI1hObha8hoI,1569
7
- nvidia_nat_crewai-1.3.0.dev2.dist-info/METADATA,sha256=WnIqCrZBOK3zpDqC789LaKaFJ1RO3L0XQDXWxTcMjT0,1445
8
- nvidia_nat_crewai-1.3.0.dev2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
- nvidia_nat_crewai-1.3.0.dev2.dist-info/entry_points.txt,sha256=YF5PUdQGr_OUDXB4TykElHJTsKT8yKkuE0bMX5n_RXs,58
10
- nvidia_nat_crewai-1.3.0.dev2.dist-info/top_level.txt,sha256=8-CJ2cP6-f0ZReXe5Hzqp-5pvzzHz-5Ds5H2bGqh1-U,4
11
- nvidia_nat_crewai-1.3.0.dev2.dist-info/RECORD,,