aiqtoolkit-crewai 1.2.0rc4__py3-none-any.whl → 1.2rc9__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.
@@ -1,13 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiqtoolkit-crewai
3
- Version: 1.2.0rc4
4
- Summary: Subpackage for CrewAI integration in AIQtoolkit
5
- Keywords: ai,rag,agents
3
+ Version: 1.2rc9
4
+ Summary: Transitional package for nvidia-nat-crewai, this package is deprecated and will be removed in the future.
6
5
  Classifier: Programming Language :: Python
7
- Requires-Python: <3.13,>=3.11
8
6
  Description-Content-Type: text/markdown
9
- Requires-Dist: aiqtoolkit==v1.2.0-rc4
10
- Requires-Dist: crewai~=0.95.0
7
+ Requires-Dist: nvidia-nat[crewai]==v1.2-rc9
11
8
 
12
9
  <!--
13
10
  SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
@@ -26,9 +23,7 @@ See the License for the specific language governing permissions and
26
23
  limitations under the License.
27
24
  -->
28
25
 
29
- ![NVIDIA Agent Intelligence Toolkit](https://media.githubusercontent.com/media/NVIDIA/NeMo-Agent-Toolkit/refs/heads/main/docs/source/_static/aiqtoolkit_banner.png "AIQ toolkit banner image")
26
+ # Transitional Package for `nvidia-nat-crewai`
27
+ This is a transitional package for `nvidia-nat-crewai` to help ease the migration to `nvidia-nat-crewai`, and will be removed in a future release. It is recommended to use `nvidia-nat-crewai` directly for new projects.
30
28
 
31
- # NVIDIA Agent Intelligence Toolkit Subpackage
32
- This is a subpackage for CrewAI integration in AIQ toolkit.
33
-
34
- For more information about AIQ toolkit, please visit the [AIQ toolkit package](https://pypi.org/project/aiqtoolkit/).
29
+ For more information about the NVIDIA NeMo Agent toolkit, please visit the [NeMo Agent toolkit package](https://pypi.org/project/nvidia-nat-crewai/).
@@ -0,0 +1,4 @@
1
+ aiqtoolkit_crewai-1.2rc9.dist-info/METADATA,sha256=kZngIgFy4B8deHOEUn6zwxC9Mi4XHcYHwgl8HhushqA,1387
2
+ aiqtoolkit_crewai-1.2rc9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
3
+ aiqtoolkit_crewai-1.2rc9.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
4
+ aiqtoolkit_crewai-1.2rc9.dist-info/RECORD,,
aiq/meta/pypi.md DELETED
@@ -1,23 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3
- SPDX-License-Identifier: Apache-2.0
4
-
5
- Licensed under the Apache License, Version 2.0 (the "License");
6
- you may not use this file except in compliance with the License.
7
- You may obtain a copy of the License at
8
-
9
- http://www.apache.org/licenses/LICENSE-2.0
10
-
11
- Unless required by applicable law or agreed to in writing, software
12
- distributed under the License is distributed on an "AS IS" BASIS,
13
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- See the License for the specific language governing permissions and
15
- limitations under the License.
16
- -->
17
-
18
- ![NVIDIA Agent Intelligence Toolkit](https://media.githubusercontent.com/media/NVIDIA/NeMo-Agent-Toolkit/refs/heads/main/docs/source/_static/aiqtoolkit_banner.png "AIQ toolkit banner image")
19
-
20
- # NVIDIA Agent Intelligence Toolkit Subpackage
21
- This is a subpackage for CrewAI integration in AIQ toolkit.
22
-
23
- For more information about AIQ toolkit, please visit the [AIQ toolkit package](https://pypi.org/project/aiqtoolkit/).
File without changes
@@ -1,205 +0,0 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
- # SPDX-License-Identifier: Apache-2.0
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
-
16
- import copy
17
- import logging
18
- import threading
19
- import time
20
- from collections.abc import Callable
21
- from typing import Any
22
-
23
- import litellm
24
- from crewai.tools import tool_usage
25
-
26
- from aiq.builder.context import AIQContext
27
- from aiq.builder.framework_enum import LLMFrameworkEnum
28
- from aiq.data_models.intermediate_step import IntermediateStepPayload
29
- from aiq.data_models.intermediate_step import IntermediateStepType
30
- from aiq.data_models.intermediate_step import StreamEventData
31
- from aiq.data_models.intermediate_step import TraceMetadata
32
- from aiq.data_models.intermediate_step import UsageInfo
33
- from aiq.profiler.callbacks.base_callback_class import BaseProfilerCallback
34
- from aiq.profiler.callbacks.token_usage_base_model import TokenUsageBaseModel
35
-
36
- logger = logging.getLogger(__name__)
37
-
38
-
39
- class CrewAIProfilerHandler(BaseProfilerCallback):
40
- """
41
- A callback manager/handler for CrewAI that intercepts calls to:
42
- - ToolUsage._use
43
- - LLM Calls
44
- to collect usage statistics (tokens, inputs, outputs, time intervals, etc.)
45
- and store them in AIQ Toolkit's usage_stats queue for subsequent analysis.
46
- """
47
-
48
- def __init__(self) -> None:
49
- super().__init__()
50
- self._lock = threading.Lock()
51
- self.last_call_ts = time.time()
52
- self.step_manager = AIQContext.get().intermediate_step_manager
53
-
54
- # Original references to CrewAI methods (for uninstrumenting if needed)
55
- self._original_tool_use = None
56
- self._original_llm_call = None
57
-
58
- def instrument(self) -> None:
59
- """
60
- Monkey-patch the relevant CrewAI methods with usage-stat collection logic.
61
- Assumes the 'crewai' library is installed.
62
- """
63
-
64
- # Save the originals
65
- self._original_tool_use = getattr(tool_usage.ToolUsage, "_use", None)
66
- self._original_llm_call = getattr(litellm, "completion", None)
67
-
68
- # Patch if available
69
- if self._original_tool_use:
70
- tool_usage.ToolUsage._use = self._tool_use_monkey_patch()
71
-
72
- if self._original_llm_call:
73
- litellm.completion = self._llm_call_monkey_patch()
74
-
75
- logger.debug("CrewAIProfilerHandler instrumentation applied successfully.")
76
-
77
- def _tool_use_monkey_patch(self) -> Callable[..., Any]:
78
- """
79
- Returns a function that wraps calls to ToolUsage._use(...) with usage-logging.
80
- """
81
- original_func = self._original_tool_use
82
-
83
- def wrapped_tool_use(tool_usage_instance, *args, **kwargs) -> Any:
84
- """
85
- Replicates _tool_use_wrapper logic without wrapt: collects usage stats,
86
- calls the original, and captures output stats.
87
- """
88
- now = time.time()
89
- tool_name = ""
90
-
91
- try:
92
- tool_info = kwargs.get("tool", "")
93
-
94
- if tool_info:
95
- tool_name = tool_info.name
96
- except Exception as e:
97
- logger.exception("Error getting tool name: %s", e, exc_info=True)
98
-
99
- try:
100
- # Pre-call usage event
101
- stats = IntermediateStepPayload(event_type=IntermediateStepType.TOOL_START,
102
- framework=LLMFrameworkEnum.CREWAI,
103
- name=tool_name,
104
- data=StreamEventData(),
105
- metadata=TraceMetadata(tool_inputs={
106
- "args": args, "kwargs": dict(kwargs)
107
- }),
108
- usage_info=UsageInfo(token_usage=TokenUsageBaseModel()))
109
-
110
- self.step_manager.push_intermediate_step(stats)
111
-
112
- self.last_call_ts = now
113
-
114
- # Call the original _use(...)
115
- result = original_func(tool_usage_instance, *args, **kwargs)
116
- now = time.time()
117
- # Post-call usage stats
118
- usage_stat = IntermediateStepPayload(
119
- event_type=IntermediateStepType.TOOL_END,
120
- span_event_timestamp=now,
121
- framework=LLMFrameworkEnum.CREWAI,
122
- name=tool_name,
123
- data=StreamEventData(input={
124
- "args": args, "kwargs": dict(kwargs)
125
- }, output=str(result)),
126
- metadata=TraceMetadata(tool_outputs={"result": str(result)}),
127
- usage_info=UsageInfo(token_usage=TokenUsageBaseModel()),
128
- )
129
-
130
- self.step_manager.push_intermediate_step(usage_stat)
131
-
132
- return result
133
-
134
- except Exception as e:
135
- logger.exception("ToolUsage._use error: %s", e)
136
- raise
137
-
138
- return wrapped_tool_use
139
-
140
- def _llm_call_monkey_patch(self) -> Callable[..., Any]:
141
- """
142
- Returns a function that wraps calls to litellm.completion(...) with usage-logging.
143
- """
144
- original_func = self._original_llm_call
145
-
146
- def wrapped_llm_call(*args, **kwargs) -> Any:
147
- """
148
- Replicates _llm_call_wrapper logic without wrapt: collects usage stats,
149
- calls the original, and captures output stats.
150
- """
151
-
152
- now = time.time()
153
- seconds_between_calls = int(now - self.last_call_ts)
154
- model_name = kwargs.get('model', "")
155
-
156
- model_input = ""
157
- try:
158
- for message in kwargs.get('messages', []):
159
- model_input += message.get('content', "")
160
- except Exception as e:
161
- logger.exception("Error getting model input: %s", e, exc_info=True)
162
-
163
- # Record the start event
164
- input_stats = IntermediateStepPayload(
165
- event_type=IntermediateStepType.LLM_START,
166
- framework=LLMFrameworkEnum.CREWAI,
167
- name=model_name,
168
- data=StreamEventData(input=model_input),
169
- metadata=TraceMetadata(chat_inputs=copy.deepcopy(kwargs.get('messages', []))),
170
- usage_info=UsageInfo(token_usage=TokenUsageBaseModel(),
171
- num_llm_calls=1,
172
- seconds_between_calls=seconds_between_calls))
173
-
174
- self.step_manager.push_intermediate_step(input_stats)
175
-
176
- # Call the original litellm.completion(...)
177
- output = original_func(*args, **kwargs)
178
-
179
- model_output = ""
180
- try:
181
- for choice in output.choices:
182
- msg = choice.model_extra["message"]
183
- model_output += msg.get('content', "")
184
- except Exception as e:
185
- logger.exception("Error getting model output: %s", e, exc_info=True)
186
-
187
- now = time.time()
188
- # Record the end event
189
- output_stats = IntermediateStepPayload(
190
- event_type=IntermediateStepType.LLM_END,
191
- span_event_timestamp=now,
192
- framework=LLMFrameworkEnum.CREWAI,
193
- name=model_name,
194
- data=StreamEventData(input=model_input, output=model_output),
195
- metadata=TraceMetadata(chat_responses=output.choices[0].model_dump()),
196
- usage_info=UsageInfo(token_usage=TokenUsageBaseModel(**output.model_extra['usage'].model_dump()),
197
- num_llm_calls=1,
198
- seconds_between_calls=seconds_between_calls))
199
-
200
- self.step_manager.push_intermediate_step(output_stats)
201
-
202
- # (Note: the original code did NOT update self.last_call_ts here)
203
- return output
204
-
205
- return wrapped_llm_call
aiq/plugins/crewai/llm.py DELETED
@@ -1,80 +0,0 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
- # SPDX-License-Identifier: Apache-2.0
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
-
16
- import os
17
-
18
- from aiq.builder.builder import Builder
19
- from aiq.builder.framework_enum import LLMFrameworkEnum
20
- from aiq.cli.register_workflow import register_llm_client
21
- from aiq.data_models.retry_mixin import RetryMixin
22
- from aiq.llm.nim_llm import NIMModelConfig
23
- from aiq.llm.openai_llm import OpenAIModelConfig
24
- from aiq.utils.exception_handlers.automatic_retries import patch_with_retry
25
-
26
-
27
- @register_llm_client(config_type=NIMModelConfig, wrapper_type=LLMFrameworkEnum.CREWAI)
28
- async def nim_crewai(llm_config: NIMModelConfig, builder: Builder):
29
-
30
- from crewai import LLM
31
-
32
- config_obj = {
33
- **llm_config.model_dump(exclude={"type"}, by_alias=True),
34
- "model": f"nvidia_nim/{llm_config.model_name}",
35
- }
36
-
37
- # Because CrewAI uses a different environment variable for the API key, we need to set it here manually
38
- if ("api_key" not in config_obj or config_obj["api_key"] is None):
39
-
40
- if ("NVIDIA_NIM_API_KEY" in os.environ):
41
- # Dont need to do anything. User has already set the correct key
42
- pass
43
- else:
44
- nvidai_api_key = os.getenv("NVIDIA_API_KEY")
45
-
46
- if (nvidai_api_key is not None):
47
- # Transfer the key to the correct environment variable for LiteLLM
48
- os.environ["NVIDIA_NIM_API_KEY"] = nvidai_api_key
49
-
50
- client = LLM(**config_obj)
51
-
52
- if isinstance(llm_config, RetryMixin):
53
-
54
- client = patch_with_retry(client,
55
- retries=llm_config.num_retries,
56
- retry_codes=llm_config.retry_on_status_codes,
57
- retry_on_messages=llm_config.retry_on_errors)
58
-
59
- yield client
60
-
61
-
62
- @register_llm_client(config_type=OpenAIModelConfig, wrapper_type=LLMFrameworkEnum.CREWAI)
63
- async def openai_crewai(llm_config: OpenAIModelConfig, builder: Builder):
64
-
65
- from crewai import LLM
66
-
67
- config_obj = {
68
- **llm_config.model_dump(exclude={"type"}, by_alias=True),
69
- }
70
-
71
- client = LLM(**config_obj)
72
-
73
- if isinstance(llm_config, RetryMixin):
74
-
75
- client = patch_with_retry(client,
76
- retries=llm_config.num_retries,
77
- retry_codes=llm_config.retry_on_status_codes,
78
- retry_on_messages=llm_config.retry_on_errors)
79
-
80
- yield client
@@ -1,23 +0,0 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
- # SPDX-License-Identifier: Apache-2.0
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
-
16
- # pylint: disable=unused-import
17
- # flake8: noqa
18
- # isort:skip_file
19
-
20
- # Import any providers which need to be automatically registered here
21
-
22
- from . import llm
23
- from . import tool_wrapper
@@ -1,40 +0,0 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
- # SPDX-License-Identifier: Apache-2.0
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
-
16
- import asyncio
17
-
18
- from aiq.builder.builder import Builder
19
- from aiq.builder.framework_enum import LLMFrameworkEnum
20
- from aiq.builder.function import Function
21
- from aiq.cli.register_workflow import register_tool_wrapper
22
-
23
-
24
- @register_tool_wrapper(wrapper_type=LLMFrameworkEnum.CREWAI)
25
- def crewai_tool_wrapper(name: str, fn: Function, builder: Builder):
26
-
27
- from crewai.tools.base_tool import Tool
28
-
29
- # Capture the loop at the time this is called
30
- loop = asyncio.get_event_loop()
31
-
32
- # Capture the coroutine at the time this is called
33
- runnable = fn.acall_invoke
34
-
35
- # Because CrewAI tools are not async, we need to wrap the coroutine in a normal function
36
- def wrapper(*args, **kwargs):
37
-
38
- return asyncio.run_coroutine_threadsafe(runnable(*args, **kwargs), loop).result()
39
-
40
- return Tool(name=name, description=fn.description or "", args_schema=fn.input_schema, func=wrapper)
@@ -1,11 +0,0 @@
1
- aiq/meta/pypi.md,sha256=mAJKaBmH4UyD5wCe3_BfPGv3ihPTg8BNfS3zu2Z4-70,1083
2
- aiq/plugins/crewai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- aiq/plugins/crewai/crewai_callback_handler.py,sha256=mFNWmtDsOUVsa6LKw7BBjBl7lsytAEaYKZfPgl9yY1o,8396
4
- aiq/plugins/crewai/llm.py,sha256=FsNt5TFYNpPU_FxB0dW0Cq_ZkviwJOmvivSYcVPtPvg,3000
5
- aiq/plugins/crewai/register.py,sha256=RKXyuaXy4ftA5IL2RrCofIBjpie_-2lP9YZoHAiyPU0,863
6
- aiq/plugins/crewai/tool_wrapper.py,sha256=LuL5VHHxOXf-CBd5E6kA6OsUz2N_aGin_r5KF59srL0,1569
7
- aiqtoolkit_crewai-1.2.0rc4.dist-info/METADATA,sha256=WBYEzReKrF9Q86t1negNJW0Fd6EZNLva9jOd0Co-uJo,1410
8
- aiqtoolkit_crewai-1.2.0rc4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
- aiqtoolkit_crewai-1.2.0rc4.dist-info/entry_points.txt,sha256=gY-k52LFDNWYEcSYiFs78LRKWeGijnGCkwcOroG4T3E,58
10
- aiqtoolkit_crewai-1.2.0rc4.dist-info/top_level.txt,sha256=fo7AzYcNhZ_tRWrhGumtxwnxMew4xrT1iwouDy_f0Kc,4
11
- aiqtoolkit_crewai-1.2.0rc4.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- [aiq.components]
2
- aiq_crewai = aiq.plugins.crewai.register
@@ -1 +0,0 @@
1
- aiq