Skip to content

Commit 75b916c

Browse files
authored
Lorenze/fix tool call twice (#3495)
* test: add test to ensure tool is called only once during crew execution - Introduced a new test case to validate that the counting_tool is executed exactly once during crew execution. - Created a CountingTool class to track execution counts and log call history. - Enhanced the test suite with a YAML cassette for consistent tool behavior verification. * ensure tool function called only once * refactor: simplify error handling in CrewStructuredTool - Removed unnecessary try-except block around the tool function call to streamline execution flow. - Ensured that the tool function is called directly, improving readability and maintainability. * linted * need to ignore for now as we cant infer the complex generic type within pydantic create_model_func * fix tests
1 parent 01be26c commit 75b916c

File tree

5 files changed

+581
-231
lines changed

5 files changed

+581
-231
lines changed

src/crewai/tools/structured_tool.py

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
11
from __future__ import annotations
22

33
import asyncio
4-
54
import inspect
65
import textwrap
7-
from typing import Any, Callable, Optional, Union, get_type_hints
6+
from collections.abc import Callable
7+
from typing import TYPE_CHECKING, Any, get_type_hints
88

99
from pydantic import BaseModel, Field, create_model
1010

1111
from crewai.utilities.logger import Logger
1212

13-
from typing import TYPE_CHECKING
14-
1513
if TYPE_CHECKING:
1614
from crewai.tools.base_tool import BaseTool
1715

1816

19-
class ToolUsageLimitExceeded(Exception):
17+
class ToolUsageLimitExceededError(Exception):
2018
"""Exception raised when a tool has reached its maximum usage limit."""
2119

22-
pass
23-
2420

2521
class CrewStructuredTool:
2622
"""A structured tool that can operate on any number of inputs.
@@ -69,10 +65,10 @@ def __init__(
6965
def from_function(
7066
cls,
7167
func: Callable,
72-
name: Optional[str] = None,
73-
description: Optional[str] = None,
68+
name: str | None = None,
69+
description: str | None = None,
7470
return_direct: bool = False,
75-
args_schema: Optional[type[BaseModel]] = None,
71+
args_schema: type[BaseModel] | None = None,
7672
infer_schema: bool = True,
7773
**kwargs: Any,
7874
) -> CrewStructuredTool:
@@ -164,7 +160,7 @@ def _create_schema_from_function(
164160

165161
# Create model
166162
schema_name = f"{name.title()}Schema"
167-
return create_model(schema_name, **fields)
163+
return create_model(schema_name, **fields) # type: ignore[call-overload]
168164

169165
def _validate_function_signature(self) -> None:
170166
"""Validate that the function signature matches the args schema."""
@@ -192,7 +188,7 @@ def _validate_function_signature(self) -> None:
192188
f"not found in args_schema"
193189
)
194190

195-
def _parse_args(self, raw_args: Union[str, dict]) -> dict:
191+
def _parse_args(self, raw_args: str | dict) -> dict:
196192
"""Parse and validate the input arguments against the schema.
197193
198194
Args:
@@ -207,18 +203,18 @@ def _parse_args(self, raw_args: Union[str, dict]) -> dict:
207203

208204
raw_args = json.loads(raw_args)
209205
except json.JSONDecodeError as e:
210-
raise ValueError(f"Failed to parse arguments as JSON: {e}")
206+
raise ValueError(f"Failed to parse arguments as JSON: {e}") from e
211207

212208
try:
213209
validated_args = self.args_schema.model_validate(raw_args)
214210
return validated_args.model_dump()
215211
except Exception as e:
216-
raise ValueError(f"Arguments validation failed: {e}")
212+
raise ValueError(f"Arguments validation failed: {e}") from e
217213

218214
async def ainvoke(
219215
self,
220-
input: Union[str, dict],
221-
config: Optional[dict] = None,
216+
input: str | dict,
217+
config: dict | None = None,
222218
**kwargs: Any,
223219
) -> Any:
224220
"""Asynchronously invoke the tool.
@@ -234,7 +230,7 @@ async def ainvoke(
234230
parsed_args = self._parse_args(input)
235231

236232
if self.has_reached_max_usage_count():
237-
raise ToolUsageLimitExceeded(
233+
raise ToolUsageLimitExceededError(
238234
f"Tool '{self.name}' has reached its maximum usage limit of {self.max_usage_count}. You should not use the {self.name} tool again."
239235
)
240236

@@ -243,44 +239,37 @@ async def ainvoke(
243239
try:
244240
if inspect.iscoroutinefunction(self.func):
245241
return await self.func(**parsed_args, **kwargs)
246-
else:
247-
# Run sync functions in a thread pool
248-
import asyncio
242+
# Run sync functions in a thread pool
243+
import asyncio
249244

250-
return await asyncio.get_event_loop().run_in_executor(
251-
None, lambda: self.func(**parsed_args, **kwargs)
252-
)
245+
return await asyncio.get_event_loop().run_in_executor(
246+
None, lambda: self.func(**parsed_args, **kwargs)
247+
)
253248
except Exception:
254249
raise
255250

256251
def _run(self, *args, **kwargs) -> Any:
257252
"""Legacy method for compatibility."""
258253
# Convert args/kwargs to our expected format
259-
input_dict = dict(zip(self.args_schema.model_fields.keys(), args))
254+
input_dict = dict(zip(self.args_schema.model_fields.keys(), args, strict=False))
260255
input_dict.update(kwargs)
261256
return self.invoke(input_dict)
262257

263258
def invoke(
264-
self, input: Union[str, dict], config: Optional[dict] = None, **kwargs: Any
259+
self, input: str | dict, config: dict | None = None, **kwargs: Any
265260
) -> Any:
266261
"""Main method for tool execution."""
267262
parsed_args = self._parse_args(input)
268263

269264
if self.has_reached_max_usage_count():
270-
raise ToolUsageLimitExceeded(
265+
raise ToolUsageLimitExceededError(
271266
f"Tool '{self.name}' has reached its maximum usage limit of {self.max_usage_count}. You should not use the {self.name} tool again."
272267
)
273268

274269
self._increment_usage_count()
275270

276271
if inspect.iscoroutinefunction(self.func):
277-
result = asyncio.run(self.func(**parsed_args, **kwargs))
278-
return result
279-
280-
try:
281-
result = self.func(**parsed_args, **kwargs)
282-
except Exception:
283-
raise
272+
return asyncio.run(self.func(**parsed_args, **kwargs))
284273

285274
result = self.func(**parsed_args, **kwargs)
286275

tests/cassettes/test_get_knowledge_search_query.yaml

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,4 +330,222 @@ interactions:
330330
status:
331331
code: 200
332332
message: OK
333+
- request:
334+
body: '{"input": ["Capital of France"], "model": "text-embedding-3-small", "encoding_format":
335+
"base64"}'
336+
headers:
337+
accept:
338+
- application/json
339+
accept-encoding:
340+
- gzip, deflate, zstd
341+
connection:
342+
- keep-alive
343+
content-length:
344+
- '96'
345+
content-type:
346+
- application/json
347+
cookie:
348+
- _cfuvid=rvDDZbBWaissP0luvtyuyyAWcPx3AiaoZS9LkAuK4sM-1746636999152-0.0.1.1-604800000
349+
host:
350+
- api.openai.com
351+
user-agent:
352+
- OpenAI/Python 1.93.0
353+
x-stainless-arch:
354+
- arm64
355+
x-stainless-async:
356+
- 'false'
357+
x-stainless-lang:
358+
- python
359+
x-stainless-os:
360+
- MacOS
361+
x-stainless-package-version:
362+
- 1.93.0
363+
x-stainless-read-timeout:
364+
- '600'
365+
x-stainless-retry-count:
366+
- '0'
367+
x-stainless-runtime:
368+
- CPython
369+
x-stainless-runtime-version:
370+
- 3.12.9
371+
method: POST
372+
uri: https://api.openai.com/v1/embeddings
373+
response:
374+
body:
375+
string: !!binary |
376+
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
485+
headers:
486+
CF-RAY:
487+
- 97d174615cfef96b-SJC
488+
Connection:
489+
- keep-alive
490+
Content-Encoding:
491+
- gzip
492+
Content-Type:
493+
- application/json
494+
Date:
495+
- Wed, 10 Sep 2025 19:50:30 GMT
496+
Server:
497+
- cloudflare
498+
Set-Cookie:
499+
- __cf_bm=eYh.U8kiOc9xS0U2L8g4MiopA6w9E7lUuodx4D.rMOU-1757533830-1.0.1.1-YO2od1GbrHRgwOEdJSw3gCcNy8XFBF_O.jT_f8F2z6dWZsBIS7XPLWUpJAzenthO1wXRkx7OZDmVrPCPro2sSj1srJCxCY8KgIwcjw5NWGU;
500+
path=/; expires=Wed, 10-Sep-25 20:20:30 GMT; domain=.api.openai.com; HttpOnly;
501+
Secure; SameSite=None
502+
- _cfuvid=vkbBikeJy.dDV.o7ZB2HjcJaD_hkp9dDeCEBfHZxG94-1757533830280-0.0.1.1-604800000;
503+
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
504+
Transfer-Encoding:
505+
- chunked
506+
X-Content-Type-Options:
507+
- nosniff
508+
access-control-allow-origin:
509+
- '*'
510+
access-control-expose-headers:
511+
- X-Request-ID
512+
alt-svc:
513+
- h3=":443"; ma=86400
514+
cf-cache-status:
515+
- DYNAMIC
516+
openai-model:
517+
- text-embedding-3-small
518+
openai-organization:
519+
- crewai-iuxna1
520+
openai-processing-ms:
521+
- '172'
522+
openai-project:
523+
- proj_xitITlrFeen7zjNSzML82h9x
524+
openai-version:
525+
- '2020-10-01'
526+
strict-transport-security:
527+
- max-age=31536000; includeSubDomains; preload
528+
via:
529+
- envoy-router-59c745856-z5gxd
530+
x-envoy-upstream-service-time:
531+
- '267'
532+
x-openai-proxy-wasm:
533+
- v0.1
534+
x-ratelimit-limit-requests:
535+
- '10000'
536+
x-ratelimit-limit-tokens:
537+
- '10000000'
538+
x-ratelimit-remaining-requests:
539+
- '9999'
540+
x-ratelimit-remaining-tokens:
541+
- '9999996'
542+
x-ratelimit-reset-requests:
543+
- 6ms
544+
x-ratelimit-reset-tokens:
545+
- 0s
546+
x-request-id:
547+
- req_06f3f9465f1a4af0ae5a4d8a58f19321
548+
status:
549+
code: 200
550+
message: OK
333551
version: 1

0 commit comments

Comments
 (0)