diff --git a/lib/crewai-files/src/crewai_files/core/sources.py b/lib/crewai-files/src/crewai_files/core/sources.py index d2df10f56..821a195c6 100644 --- a/lib/crewai-files/src/crewai_files/core/sources.py +++ b/lib/crewai-files/src/crewai_files/core/sources.py @@ -3,6 +3,7 @@ from __future__ import annotations from collections.abc import AsyncIterator, Iterator +import inspect import mimetypes from pathlib import Path from typing import Annotated, Any, BinaryIO, Protocol, cast, runtime_checkable @@ -401,7 +402,7 @@ class AsyncFileStream(BaseModel): """Async close the underlying stream.""" if hasattr(self.stream, "close"): result = self.stream.close() - if hasattr(result, "__await__"): + if inspect.isawaitable(result): await result async def __aenter__(self) -> AsyncFileStream: diff --git a/lib/crewai/tests/cassettes/test_llm_call_with_string_input_and_callbacks.yaml b/lib/crewai/tests/cassettes/test_llm_call_with_string_input_and_callbacks.yaml index b0032cf13..a4781481e 100644 --- a/lib/crewai/tests/cassettes/test_llm_call_with_string_input_and_callbacks.yaml +++ b/lib/crewai/tests/cassettes/test_llm_call_with_string_input_and_callbacks.yaml @@ -1,100 +1,111 @@ interactions: - request: - body: '{"messages": [{"role": "user", "content": "Tell me a joke."}], "model": - "gpt-4o-mini"}' + body: '{"messages":[{"role":"user","content":"Tell me a joke."}],"model":"gpt-4o-mini"}' headers: + User-Agent: + - X-USER-AGENT-XXX accept: - application/json accept-encoding: - - gzip, deflate + - ACCEPT-ENCODING-XXX + authorization: + - AUTHORIZATION-XXX connection: - keep-alive content-length: - - '86' + - '80' content-type: - application/json - cookie: - - _cfuvid=8NrWEBP3dDmc8p2.csR.EdsSwS8zFvzWI1kPICaK_fM-1737568015338-0.0.1.1-604800000; - __cf_bm=pKr3NwXmTZN9rMSlKvEX40VPKbrxF93QwDNHunL2v8Y-1737568015-1.0.1.1-nR0EA7hYIwWpIBYUI53d9xQrUnl5iML6lgz4AGJW4ZGPBDxFma3PZ2cBhlr_hE7wKa5fV3r32eMu_rNWMXD.eA host: - api.openai.com - user-agent: - - OpenAI/Python 1.59.6 x-stainless-arch: - - arm64 + - X-STAINLESS-ARCH-XXX x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - MacOS + - X-STAINLESS-OS-XXX x-stainless-package-version: - - 1.59.6 + - 1.83.0 x-stainless-raw-response: - 'true' + x-stainless-read-timeout: + - X-STAINLESS-READ-TIMEOUT-XXX x-stainless-retry-count: - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.10 method: POST uri: https://api.openai.com/v1/chat/completions response: - content: "{\n \"id\": \"chatcmpl-AsZ6VyjuUcXYpChXmD8rUSy6nSGq8\",\n \"object\": - \"chat.completion\",\n \"created\": 1737568015,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": \"Why did the scarecrow win an award? \\n\\nBecause - he was outstanding in his field!\",\n \"refusal\": null\n },\n \"logprobs\": - null,\n \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": - 12,\n \"completion_tokens\": 19,\n \"total_tokens\": 31,\n \"prompt_tokens_details\": - {\n \"cached_tokens\": 0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": - {\n \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\": - 0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"service_tier\": - \"default\",\n \"system_fingerprint\": \"fp_72ed7ab54c\"\n}\n" + body: + string: "{\n \"id\": \"chatcmpl-D15ryhvyvvu79lrroG2NtZbdHnsNq\",\n \"object\": + \"chat.completion\",\n \"created\": 1769153262,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"Why don't skeletons fight each other? + \\n\\nThey don't have the guts!\",\n \"refusal\": null,\n \"annotations\": + []\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n + \ }\n ],\n \"usage\": {\n \"prompt_tokens\": 12,\n \"completion_tokens\": + 15,\n \"total_tokens\": 27,\n \"prompt_tokens_details\": {\n \"cached_tokens\": + 0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": + {\n \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\": + 0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"service_tier\": + \"default\",\n \"system_fingerprint\": \"fp_29330a9688\"\n}\n" headers: - CF-Cache-Status: - - DYNAMIC CF-RAY: - - 90615dc03b6c5cb1-RDU + - CF-RAY-XXX Connection: - keep-alive Content-Type: - application/json Date: - - Wed, 22 Jan 2025 17:46:56 GMT + - Fri, 23 Jan 2026 07:27:43 GMT Server: - cloudflare + Set-Cookie: + - SET-COOKIE-XXX + Strict-Transport-Security: + - STS-XXX Transfer-Encoding: - chunked X-Content-Type-Options: - - nosniff + - X-CONTENT-TYPE-XXX access-control-expose-headers: - - X-Request-ID + - ACCESS-CONTROL-XXX alt-svc: - h3=":443"; ma=86400 + cf-cache-status: + - DYNAMIC openai-organization: - - crewai-iuxna1 + - OPENAI-ORG-XXX openai-processing-ms: - - '825' + - '444' + openai-project: + - OPENAI-PROJECT-XXX openai-version: - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload + x-envoy-upstream-service-time: + - '464' + x-openai-proxy-wasm: + - v0.1 x-ratelimit-limit-requests: - - '30000' + - X-RATELIMIT-LIMIT-REQUESTS-XXX x-ratelimit-limit-tokens: - - '150000000' + - X-RATELIMIT-LIMIT-TOKENS-XXX x-ratelimit-remaining-requests: - - '29999' + - X-RATELIMIT-REMAINING-REQUESTS-XXX x-ratelimit-remaining-tokens: - - '149999979' + - X-RATELIMIT-REMAINING-TOKENS-XXX x-ratelimit-reset-requests: - - 2ms + - X-RATELIMIT-RESET-REQUESTS-XXX x-ratelimit-reset-tokens: - - 0s + - X-RATELIMIT-RESET-TOKENS-XXX x-request-id: - - req_4c1485d44e7461396d4a7316a63ff353 - http_version: HTTP/1.1 - status_code: 200 + - X-REQUEST-ID-XXX + status: + code: 200 + message: OK version: 1 diff --git a/lib/crewai/tests/cassettes/test_llm_call_with_tool_and_string_input.yaml b/lib/crewai/tests/cassettes/test_llm_call_with_tool_and_string_input.yaml index eb6198a42..b0db1a951 100644 --- a/lib/crewai/tests/cassettes/test_llm_call_with_tool_and_string_input.yaml +++ b/lib/crewai/tests/cassettes/test_llm_call_with_tool_and_string_input.yaml @@ -1,105 +1,113 @@ interactions: - request: - body: '{"messages": [{"role": "user", "content": "What is the current year?"}], - "model": "gpt-4o-mini", "tools": [{"type": "function", "function": {"name": - "get_current_year", "description": "Returns the current year as a string.", - "parameters": {"type": "object", "properties": {}, "required": []}}}]}' + body: '{"messages":[{"role":"user","content":"What is the current year?"}],"model":"gpt-4o-mini","tool_choice":"auto","tools":[{"type":"function","function":{"name":"get_current_year","description":"Returns + the current year as a string.","parameters":{"type":"object","properties":{},"required":[]}}}]}' headers: + User-Agent: + - X-USER-AGENT-XXX accept: - application/json accept-encoding: - - gzip, deflate + - ACCEPT-ENCODING-XXX + authorization: + - AUTHORIZATION-XXX connection: - keep-alive content-length: - '295' content-type: - application/json - cookie: - - _cfuvid=8NrWEBP3dDmc8p2.csR.EdsSwS8zFvzWI1kPICaK_fM-1737568015338-0.0.1.1-604800000; - __cf_bm=pKr3NwXmTZN9rMSlKvEX40VPKbrxF93QwDNHunL2v8Y-1737568015-1.0.1.1-nR0EA7hYIwWpIBYUI53d9xQrUnl5iML6lgz4AGJW4ZGPBDxFma3PZ2cBhlr_hE7wKa5fV3r32eMu_rNWMXD.eA host: - api.openai.com - user-agent: - - OpenAI/Python 1.59.6 x-stainless-arch: - - arm64 + - X-STAINLESS-ARCH-XXX x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - MacOS + - X-STAINLESS-OS-XXX x-stainless-package-version: - - 1.59.6 - x-stainless-raw-response: - - 'true' + - 1.83.0 + x-stainless-read-timeout: + - X-STAINLESS-READ-TIMEOUT-XXX x-stainless-retry-count: - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.10 method: POST uri: https://api.openai.com/v1/chat/completions response: - content: "{\n \"id\": \"chatcmpl-AsZJ8HKXQU9nTB7xbGAkKxqrg9BZ2\",\n \"object\": - \"chat.completion\",\n \"created\": 1737568798,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": null,\n \"tool_calls\": [\n {\n - \ \"id\": \"call_mfvEs2jngeFloVZpZOHZVaKY\",\n \"type\": - \"function\",\n \"function\": {\n \"name\": \"get_current_year\",\n - \ \"arguments\": \"{}\"\n }\n }\n ],\n - \ \"refusal\": null\n },\n \"logprobs\": null,\n \"finish_reason\": - \"tool_calls\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": 46,\n \"completion_tokens\": - 12,\n \"total_tokens\": 58,\n \"prompt_tokens_details\": {\n \"cached_tokens\": - 0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": {\n - \ \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\": - 0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"service_tier\": - \"default\",\n \"system_fingerprint\": \"fp_72ed7ab54c\"\n}\n" + body: + string: "{\n \"id\": \"chatcmpl-D15uNk8ZEDswsGxSAFnY295JUwSjB\",\n \"object\": + \"chat.completion\",\n \"created\": 1769153411,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": null,\n \"tool_calls\": [\n {\n + \ \"id\": \"call_8D2y8EMY7MLv9kCeWmezXrzs\",\n \"type\": + \"function\",\n \"function\": {\n \"name\": \"get_current_year\",\n + \ \"arguments\": \"{}\"\n }\n }\n ],\n + \ \"refusal\": null,\n \"annotations\": []\n },\n \"logprobs\": + null,\n \"finish_reason\": \"tool_calls\"\n }\n ],\n \"usage\": + {\n \"prompt_tokens\": 46,\n \"completion_tokens\": 11,\n \"total_tokens\": + 57,\n \"prompt_tokens_details\": {\n \"cached_tokens\": 0,\n \"audio_tokens\": + 0\n },\n \"completion_tokens_details\": {\n \"reasoning_tokens\": + 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\": 0,\n + \ \"rejected_prediction_tokens\": 0\n }\n },\n \"service_tier\": + \"default\",\n \"system_fingerprint\": \"fp_29330a9688\"\n}\n" headers: - CF-Cache-Status: - - DYNAMIC CF-RAY: - - 906170e038281775-IAD + - CF-RAY-XXX Connection: - keep-alive Content-Type: - application/json Date: - - Wed, 22 Jan 2025 17:59:59 GMT + - Fri, 23 Jan 2026 07:30:11 GMT Server: - cloudflare + Set-Cookie: + - SET-COOKIE-XXX + Strict-Transport-Security: + - STS-XXX Transfer-Encoding: - chunked X-Content-Type-Options: - - nosniff + - X-CONTENT-TYPE-XXX access-control-expose-headers: - - X-Request-ID + - ACCESS-CONTROL-XXX alt-svc: - h3=":443"; ma=86400 + cf-cache-status: + - DYNAMIC openai-organization: - - crewai-iuxna1 + - OPENAI-ORG-XXX openai-processing-ms: - - '416' + - '405' + openai-project: + - OPENAI-PROJECT-XXX openai-version: - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload + x-envoy-upstream-service-time: + - '559' + x-openai-proxy-wasm: + - v0.1 x-ratelimit-limit-requests: - - '30000' + - X-RATELIMIT-LIMIT-REQUESTS-XXX x-ratelimit-limit-tokens: - - '150000000' + - X-RATELIMIT-LIMIT-TOKENS-XXX x-ratelimit-remaining-requests: - - '29999' + - X-RATELIMIT-REMAINING-REQUESTS-XXX x-ratelimit-remaining-tokens: - - '149999975' + - X-RATELIMIT-REMAINING-TOKENS-XXX x-ratelimit-reset-requests: - - 2ms + - X-RATELIMIT-RESET-REQUESTS-XXX x-ratelimit-reset-tokens: - - 0s + - X-RATELIMIT-RESET-TOKENS-XXX x-request-id: - - req_4039a5e5772d1790a3131f0b1ea06139 - http_version: HTTP/1.1 - status_code: 200 + - X-REQUEST-ID-XXX + status: + code: 200 + message: OK version: 1 diff --git a/lib/crewai/tests/cassettes/test_o3_mini_reasoning_effort_medium.yaml b/lib/crewai/tests/cassettes/test_o3_mini_reasoning_effort_medium.yaml index e3cb62615..e5b79f4eb 100644 --- a/lib/crewai/tests/cassettes/test_o3_mini_reasoning_effort_medium.yaml +++ b/lib/crewai/tests/cassettes/test_o3_mini_reasoning_effort_medium.yaml @@ -1,100 +1,108 @@ interactions: - request: - body: '{"messages": [{"role": "user", "content": "What is the capital of France?"}], - "model": "o3-mini", "reasoning_effort": "medium", "stop": []}' + body: '{"messages":[{"role":"user","content":"What is the capital of France?"}],"model":"o3-mini"}' headers: + User-Agent: + - X-USER-AGENT-XXX accept: - application/json accept-encoding: - - gzip, deflate + - ACCEPT-ENCODING-XXX + authorization: + - AUTHORIZATION-XXX connection: - keep-alive content-length: - - '139' + - '91' content-type: - application/json - cookie: - - _cfuvid=JBfx8Sl7w82A0S_K1tQd5ZcwzWaZP5Gg5W1dqAdgwNU-1738683830528-0.0.1.1-604800000; - __cf_bm=.AP74BirsYr.lu61bSaimK2HRF6126qr5vCrr3HC6ak-1738683830-1.0.1.1-feh.bcMOv9wYnitoPpr.7UR7JrzCsbRLlzct09xCDm2SwmnRQQk5ZSSV41Ywer2S0rptbvufFwklV9wo9ATvWw host: - api.openai.com - user-agent: - - OpenAI/Python 1.61.0 x-stainless-arch: - - arm64 + - X-STAINLESS-ARCH-XXX x-stainless-async: - 'false' x-stainless-lang: - python x-stainless-os: - - MacOS + - X-STAINLESS-OS-XXX x-stainless-package-version: - - 1.61.0 - x-stainless-raw-response: - - 'true' + - 1.83.0 + x-stainless-read-timeout: + - X-STAINLESS-READ-TIMEOUT-XXX x-stainless-retry-count: - '0' x-stainless-runtime: - CPython x-stainless-runtime-version: - - 3.12.7 + - 3.12.10 method: POST uri: https://api.openai.com/v1/chat/completions response: - content: "{\n \"id\": \"chatcmpl-AxFS8IuMeYs6Rky2UbG8wH8P5PR4k\",\n \"object\": - \"chat.completion\",\n \"created\": 1738684116,\n \"model\": \"o3-mini-2025-01-31\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": \"The capital of France is Paris.\",\n - \ \"refusal\": null\n },\n \"finish_reason\": \"stop\"\n }\n - \ ],\n \"usage\": {\n \"prompt_tokens\": 13,\n \"completion_tokens\": - 145,\n \"total_tokens\": 158,\n \"prompt_tokens_details\": {\n \"cached_tokens\": - 0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": {\n - \ \"reasoning_tokens\": 128,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\": - 0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"service_tier\": - \"default\",\n \"system_fingerprint\": \"fp_8bcaa0ca21\"\n}\n" + body: + string: "{\n \"id\": \"chatcmpl-D15uNqDUbZIUh2hLx3GF5EiaK3am4\",\n \"object\": + \"chat.completion\",\n \"created\": 1769153411,\n \"model\": \"o3-mini-2025-01-31\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"The capital of France is Paris.\",\n + \ \"refusal\": null,\n \"annotations\": []\n },\n \"finish_reason\": + \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": 13,\n \"completion_tokens\": + 84,\n \"total_tokens\": 97,\n \"prompt_tokens_details\": {\n \"cached_tokens\": + 0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": + {\n \"reasoning_tokens\": 64,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\": + 0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"service_tier\": + \"default\",\n \"system_fingerprint\": \"fp_d48b29c73d\"\n}\n" headers: CF-RAY: - - 90cbce51b946afb4-ATL + - CF-RAY-XXX Connection: - keep-alive Content-Type: - application/json Date: - - Tue, 04 Feb 2025 15:48:39 GMT + - Fri, 23 Jan 2026 07:30:13 GMT Server: - cloudflare + Set-Cookie: + - SET-COOKIE-XXX + Strict-Transport-Security: + - STS-XXX Transfer-Encoding: - chunked X-Content-Type-Options: - - nosniff + - X-CONTENT-TYPE-XXX access-control-expose-headers: - - X-Request-ID + - ACCESS-CONTROL-XXX alt-svc: - h3=":443"; ma=86400 cf-cache-status: - DYNAMIC openai-organization: - - crewai-iuxna1 + - OPENAI-ORG-XXX openai-processing-ms: - - '2365' + - '1291' + openai-project: + - OPENAI-PROJECT-XXX openai-version: - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload + x-envoy-upstream-service-time: + - '1313' + x-openai-proxy-wasm: + - v0.1 x-ratelimit-limit-requests: - - '30000' + - X-RATELIMIT-LIMIT-REQUESTS-XXX x-ratelimit-limit-tokens: - - '150000000' + - X-RATELIMIT-LIMIT-TOKENS-XXX x-ratelimit-remaining-requests: - - '29999' + - X-RATELIMIT-REMAINING-REQUESTS-XXX x-ratelimit-remaining-tokens: - - '149999974' + - X-RATELIMIT-REMAINING-TOKENS-XXX x-ratelimit-reset-requests: - - 2ms + - X-RATELIMIT-RESET-REQUESTS-XXX x-ratelimit-reset-tokens: - - 0s + - X-RATELIMIT-RESET-TOKENS-XXX x-request-id: - - req_bfd83679e674c3894991477f1fb043b2 - http_version: HTTP/1.1 - status_code: 200 + - X-REQUEST-ID-XXX + status: + code: 200 + message: OK version: 1 diff --git a/lib/crewai/tests/test_llm.py b/lib/crewai/tests/test_llm.py index 1f7a1d01f..71cb69790 100644 --- a/lib/crewai/tests/test_llm.py +++ b/lib/crewai/tests/test_llm.py @@ -930,7 +930,7 @@ def test_usage_info_streaming_with_call(): @pytest.mark.vcr(record_mode="once",decode_compressed_response=True,match_on=["method", "scheme", "host", "path", "body"]) async def test_usage_info_non_streaming_with_acall(): llm = LLM( - model="openai/gpt-4o-mini", + model="openai/gpt-4o-mini", is_litellm=True, stream=False, ) @@ -992,7 +992,7 @@ async def test_usage_info_non_streaming_with_acall_and_stop(): @pytest.mark.asyncio -@pytest.mark.vcr(record_mode="none",decode_compressed_response=True,match_on=["method", "scheme", "host", "path", "body"]) +@pytest.mark.vcr() async def test_usage_info_streaming_with_acall(): llm = LLM( model="gpt-4o-mini", @@ -1008,7 +1008,7 @@ async def test_usage_info_streaming_with_acall(): "successful_requests": 0, "cached_prompt_tokens": 0, } - + with patch.object( llm, "_ahandle_streaming_response", wraps=llm._ahandle_streaming_response ) as mock_handle: @@ -1021,4 +1021,4 @@ async def test_usage_info_streaming_with_acall(): assert llm._token_usage["completion_tokens"] > 0 assert llm._token_usage["total_tokens"] > 0 - assert len(result) > 0 \ No newline at end of file + assert len(result) > 0