From eec1262d4fb9dc3ad700d18585a36ae30c860562 Mon Sep 17 00:00:00 2001 From: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com> Date: Fri, 11 Jul 2025 23:22:26 +0530 Subject: [PATCH] Fix agent knowledge (#2831) * Added add_sources() * Fixed the agent knowledge querying * Added test cases * Fixed linting issue * Fixed logic * Seems like a falky test case * Minor changes * Added knowledge attriute to the crew documentation * Flaky test * fixed spaces * Flaky Test Case * Seems like a flaky test case --------- Co-authored-by: Lucas Gomide --- docs/en/concepts/crews.mdx | 1 + src/crewai/agent.py | 39 ++--- tests/agent_test.py | 74 +++++++++ ...gent_knowledege_with_crewai_knowledge.yaml | 150 +++++++++++++++++ ...th_knowledge_with_no_crewai_knowledge.yaml | 151 ++++++++++++++++++ ...test_agent_with_only_crewai_knowledge.yaml | 150 +++++++++++++++++ 6 files changed, 547 insertions(+), 18 deletions(-) create mode 100644 tests/cassettes/test_agent_knowledege_with_crewai_knowledge.yaml create mode 100644 tests/cassettes/test_agent_with_knowledge_with_no_crewai_knowledge.yaml create mode 100644 tests/cassettes/test_agent_with_only_crewai_knowledge.yaml diff --git a/docs/en/concepts/crews.mdx b/docs/en/concepts/crews.mdx index 3c6f4b507..9ab961f3c 100644 --- a/docs/en/concepts/crews.mdx +++ b/docs/en/concepts/crews.mdx @@ -32,6 +32,7 @@ A crew in crewAI represents a collaborative group of agents working together to | **Prompt File** _(optional)_ | `prompt_file` | Path to the prompt JSON file to be used for the crew. | | **Planning** *(optional)* | `planning` | Adds planning ability to the Crew. When activated before each Crew iteration, all Crew data is sent to an AgentPlanner that will plan the tasks and this plan will be added to each task description. | | **Planning LLM** *(optional)* | `planning_llm` | The language model used by the AgentPlanner in a planning process. | +| **Knowledge Sources** _(optional)_ | `knowledge_sources` | Knowledge sources available at the crew level, accessible to all the agents. | **Crew Max RPM**: The `max_rpm` attribute sets the maximum number of requests per minute the crew can perform to avoid rate limits and will override individual agents' `max_rpm` settings if you set it. diff --git a/src/crewai/agent.py b/src/crewai/agent.py index 09c28397e..a08b4f83b 100644 --- a/src/crewai/agent.py +++ b/src/crewai/agent.py @@ -210,7 +210,6 @@ class Agent(BaseAgent): sources=self.knowledge_sources, embedder=self.embedder, collection_name=self.role, - storage=self.knowledge_storage or None, ) self.knowledge.add_sources() except (TypeError, ValueError) as e: @@ -341,7 +340,8 @@ class Agent(BaseAgent): self.knowledge_config.model_dump() if self.knowledge_config else {} ) - if self.knowledge: + + if self.knowledge or (self.crew and self.crew.knowledge): crewai_event_bus.emit( self, event=KnowledgeRetrievalStartedEvent( @@ -353,25 +353,28 @@ class Agent(BaseAgent): task_prompt ) if self.knowledge_search_query: - agent_knowledge_snippets = self.knowledge.query( - [self.knowledge_search_query], **knowledge_config - ) - if agent_knowledge_snippets: - self.agent_knowledge_context = extract_knowledge_context( - agent_knowledge_snippets - ) - if self.agent_knowledge_context: - task_prompt += self.agent_knowledge_context - if self.crew: - knowledge_snippets = self.crew.query_knowledge( + # Quering agent specific knowledge + if self.knowledge: + agent_knowledge_snippets = self.knowledge.query( [self.knowledge_search_query], **knowledge_config ) - if knowledge_snippets: - self.crew_knowledge_context = extract_knowledge_context( - knowledge_snippets + if agent_knowledge_snippets: + self.agent_knowledge_context = extract_knowledge_context( + agent_knowledge_snippets ) - if self.crew_knowledge_context: - task_prompt += self.crew_knowledge_context + if self.agent_knowledge_context: + task_prompt += self.agent_knowledge_context + + # Quering crew specific knowledge + knowledge_snippets = self.crew.query_knowledge( + [self.knowledge_search_query], **knowledge_config + ) + if knowledge_snippets: + self.crew_knowledge_context = extract_knowledge_context( + knowledge_snippets + ) + if self.crew_knowledge_context: + task_prompt += self.crew_knowledge_context crewai_event_bus.emit( self, diff --git a/tests/agent_test.py b/tests/agent_test.py index 5711bef18..e460a94e7 100644 --- a/tests/agent_test.py +++ b/tests/agent_test.py @@ -1896,6 +1896,80 @@ def test_agent_with_knowledge_sources_generate_search_query(): assert "red" in result.raw.lower() +@pytest.mark.vcr(record_mode='none', filter_headers=["authorization"]) +def test_agent_with_knowledge_with_no_crewai_knowledge(): + mock_knowledge = MagicMock(spec=Knowledge) + + agent = Agent( + role="Information Agent", + goal="Provide information based on knowledge sources", + backstory="You have access to specific knowledge sources.", + llm=LLM(model="openrouter/openai/gpt-4o-mini",api_key=os.getenv('OPENROUTER_API_KEY')), + knowledge=mock_knowledge + ) + + # Create a task that requires the agent to use the knowledge + task = Task( + description="What is Vidit's favorite color?", + expected_output="Vidit's favorclearite color.", + agent=agent, + ) + + crew = Crew(agents=[agent], tasks=[task]) + crew.kickoff() + mock_knowledge.query.assert_called_once() + + +@pytest.mark.vcr(record_mode='none', filter_headers=["authorization"]) +def test_agent_with_only_crewai_knowledge(): + mock_knowledge = MagicMock(spec=Knowledge) + + agent = Agent( + role="Information Agent", + goal="Provide information based on knowledge sources", + backstory="You have access to specific knowledge sources.", + llm=LLM(model="openrouter/openai/gpt-4o-mini",api_key=os.getenv('OPENROUTER_API_KEY')) + ) + + # Create a task that requires the agent to use the knowledge + task = Task( + description="What is Vidit's favorite color?", + expected_output="Vidit's favorclearite color.", + agent=agent + ) + + crew = Crew(agents=[agent], tasks=[task],knowledge=mock_knowledge) + crew.kickoff() + mock_knowledge.query.assert_called_once() + + +@pytest.mark.vcr(record_mode='none', filter_headers=["authorization"]) +def test_agent_knowledege_with_crewai_knowledge(): + crew_knowledge = MagicMock(spec=Knowledge) + agent_knowledge = MagicMock(spec=Knowledge) + + + agent = Agent( + role="Information Agent", + goal="Provide information based on knowledge sources", + backstory="You have access to specific knowledge sources.", + llm=LLM(model="openrouter/openai/gpt-4o-mini",api_key=os.getenv('OPENROUTER_API_KEY')), + knowledge=agent_knowledge + ) + + # Create a task that requires the agent to use the knowledge + task = Task( + description="What is Vidit's favorite color?", + expected_output="Vidit's favorclearite color.", + agent=agent, + ) + + crew = Crew(agents=[agent],tasks=[task],knowledge=crew_knowledge) + crew.kickoff() + agent_knowledge.query.assert_called_once() + crew_knowledge.query.assert_called_once() + + @pytest.mark.vcr(filter_headers=["authorization"]) def test_litellm_auth_error_handling(): """Test that LiteLLM authentication errors are handled correctly and not retried.""" diff --git a/tests/cassettes/test_agent_knowledege_with_crewai_knowledge.yaml b/tests/cassettes/test_agent_knowledege_with_crewai_knowledge.yaml new file mode 100644 index 000000000..1f9d3daf5 --- /dev/null +++ b/tests/cassettes/test_agent_knowledege_with_crewai_knowledge.yaml @@ -0,0 +1,150 @@ +interactions: +- request: + body: '{"model": "openai/gpt-4o-mini", "messages": [{"role": "system", "content": + "Your goal is to rewrite the user query so that it is optimized for retrieval + from a vector database. Consider how the query will be used to find relevant + documents, and aim to make it more specific and context-aware. \n\n Do not include + any other text than the rewritten query, especially any preamble or postamble + and only add expected output format if its relevant to the rewritten query. + \n\n Focus on the key words of the intended task and to retrieve the most relevant + information. \n\n There will be some extra context provided that might need + to be removed such as expected_output formats structured_outputs and other instructions."}, + {"role": "user", "content": "The original query is: What is Vidit''s favorite + color?\n\nThis is the expected criteria for your final answer: Vidit''s favorclearite + color.\nyou MUST return the actual complete content as the final answer, not + a summary.."}], "stream": false, "stop": ["\nObservation:"]}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '1017' + content-type: + - application/json + host: + - openrouter.ai + http-referer: + - https://litellm.ai + user-agent: + - litellm/1.68.0 + x-title: + - liteLLM + method: POST + uri: https://openrouter.ai/api/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAAwAAAP//4lKAAS4AAAAA//90kE1vE0EMhv9K9V64TMrmgyadG8ceECAhhIrQarrj + 3bidHY/GTgSK9r+jpUpaJLja78djn8ARHgPlxXK72a6X6+12szhq7Id72d2V8b58/nbzQb98gkOp + cuRIFR4fC+X3d3AYJVKChxTKgd8OxRYbWYycGQ7y8EidwaPbB7vuZCyJjCXDoasUjCL8S61Dtxfu + SOG/n5BkKFUeFD4fUnLoObPu20pBJcNDTQoccjA+UvufLedIP+Ebh5FUw0DwJ1RJBI+gymoh20wj + 2SjPpF85sr3Rqz4cpbLRVSdJ6jUcKvUHDenM81zFeXgeTNMPB/2lRuMMM1Atlf8k9qVt1rer3WrV + 3DZwOJw5SpWxWGvyRFnnR7ybQc4/usxvHEwspBfhbun+NreRLHDSObUL3Z7iRdxM/wh9rb/c8coy + Tb8BAAD//wMAqVt3JyMCAAA= + headers: + Access-Control-Allow-Origin: + - '*' + CF-RAY: + - 9402cb503aec46c0-BOM + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Thu, 15 May 2025 12:56:14 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + x-clerk-auth-message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + x-clerk-auth-reason: + - token-invalid + x-clerk-auth-status: + - signed-out + status: + code: 200 + message: OK +- request: + body: '{"model": "openai/gpt-4o-mini", "messages": [{"role": "system", "content": + "You are Information Agent. You have access to specific knowledge sources.\nYour + personal goal is: Provide information based on knowledge sources\nTo give my + best complete final answer to the task respond using the exact following format:\n\nThought: + I now can give a great answer\nFinal Answer: Your final answer must be the great + and the most complete as possible, it must be outcome described.\n\nI MUST use + these formats, my job depends on it!"}, {"role": "user", "content": "\nCurrent + Task: What is Vidit''s favorite color?\n\nThis is the expected criteria for + your final answer: Vidit''s favorclearite color.\nyou MUST return the actual + complete content as the final answer, not a summary.\n\nBegin! This is VERY + important to you, use the tools available and give your best Final Answer, your + job depends on it!\n\nThought:"}], "stream": false, "stop": ["\nObservation:"]}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '951' + content-type: + - application/json + host: + - openrouter.ai + http-referer: + - https://litellm.ai + user-agent: + - litellm/1.68.0 + x-title: + - liteLLM + method: POST + uri: https://openrouter.ai/api/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAAwAAAP//4lKAAS4AAAAA///iQjABAAAA//90kE9rG0EMxb/K8C69jNON7WJ7boFS + CD2ENm2g/1jGs/Ja7aw0zIydBuPvXjbBcQrtUU9P0u/pAO7g0JNMLhfzxexytli8mdy8r7c6/3Lb + v13eff00088fPj7AImXdc0cZDjeJ5OoaFoN2FOGgicTz6z7VyVwnAwvDQtc/KVQ4hK2vF0GHFKmy + CixCJl+pgzuftQhb5UAF7tsBUfuUdV3gZBejxYaFy7bN5IsKHErVBAvxlffU/qfL0tFvuMZioFJ8 + T3AHZI0EB18Kl+qljjQqlWQkvTai9yZ4MT3vyXjTj6DGS7mnbMx3ecfio7l6rJ25447rq2I2fq+Z + K5mgUbPhYtZxRxewyLTZFR9PMZ4IWfon4Xj8YVEeSqVhzNBTTpkfQTapbWar6XI6bVYNLHYn/JR1 + SLWt+oukjP9rRv7Ta8/6yqJq9fGsLFf27+m2o+o5lnFt8GFL3bO5Of5j60v/c5AXI8fjHwAAAP// + AwDEkP8dZgIAAA== + headers: + Access-Control-Allow-Origin: + - '*' + CF-RAY: + - 9402cb55c9fe46c0-BOM + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Thu, 15 May 2025 12:56:15 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + x-clerk-auth-message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + x-clerk-auth-reason: + - token-invalid + x-clerk-auth-status: + - signed-out + status: + code: 200 + message: OK +version: 1 diff --git a/tests/cassettes/test_agent_with_knowledge_with_no_crewai_knowledge.yaml b/tests/cassettes/test_agent_with_knowledge_with_no_crewai_knowledge.yaml new file mode 100644 index 000000000..9bc66c5ff --- /dev/null +++ b/tests/cassettes/test_agent_with_knowledge_with_no_crewai_knowledge.yaml @@ -0,0 +1,151 @@ +interactions: +- request: + body: '{"model": "openai/gpt-4o-mini", "messages": [{"role": "system", "content": + "Your goal is to rewrite the user query so that it is optimized for retrieval + from a vector database. Consider how the query will be used to find relevant + documents, and aim to make it more specific and context-aware. \n\n Do not include + any other text than the rewritten query, especially any preamble or postamble + and only add expected output format if its relevant to the rewritten query. + \n\n Focus on the key words of the intended task and to retrieve the most relevant + information. \n\n There will be some extra context provided that might need + to be removed such as expected_output formats structured_outputs and other instructions."}, + {"role": "user", "content": "The original query is: What is Vidit''s favorite + color?\n\nThis is the expected criteria for your final answer: Vidit''s favorclearite + color.\nyou MUST return the actual complete content as the final answer, not + a summary.."}], "stream": false, "stop": ["\nObservation:"]}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '1017' + content-type: + - application/json + host: + - openrouter.ai + http-referer: + - https://litellm.ai + user-agent: + - litellm/1.68.0 + x-title: + - liteLLM + method: POST + uri: https://openrouter.ai/api/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAAwAAAP//4lKAAS4AAAAA//90kE1vE0EMhv9K9V64TGCbNGQ7N46gIg6IXhBaTWed + Xbez49HYiaii/e9oqRKKBFf7/XjsE7iHx0B5db272W2uN++b3ep585k+jcmo/XqnYXvX5m/3cChV + jtxThceXQvnDRzhM0lOChxTKgd8NxVY3spo4Mxzk4ZGiwSOOwd5GmUoiY8lwiJWCUQ9/qW0d4igc + SeG/n5BkKFUeFD4fUnLYc2Ydu0pBJcNDTQoccjA+UvefLeeefsI3DhOphoHgT6iSCB5BldVCtoVG + slFeSO+5Z3ujV/twlMpGV1GSVDhU2h80pDPOSxPn4WUwzz8c9FmNpoVloFoq/w7cl67Z3K7b9bq5 + beBwOGOUKlOxzuSJsi5/2C4c5xdd5lsHEwvpj7Bt3N/mricLnHRJjSGO1F/EzfyP0Nf6yx2vLPP8 + CwAA//8DAOHu/cIiAgAA + headers: + Access-Control-Allow-Origin: + - '*' + CF-RAY: + - 9402c73df9d8859c-BOM + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Thu, 15 May 2025 12:53:27 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + x-clerk-auth-message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + x-clerk-auth-reason: + - token-invalid + x-clerk-auth-status: + - signed-out + status: + code: 200 + message: OK +- request: + body: '{"model": "openai/gpt-4o-mini", "messages": [{"role": "system", "content": + "You are Information Agent. You have access to specific knowledge sources.\nYour + personal goal is: Provide information based on knowledge sources\nTo give my + best complete final answer to the task respond using the exact following format:\n\nThought: + I now can give a great answer\nFinal Answer: Your final answer must be the great + and the most complete as possible, it must be outcome described.\n\nI MUST use + these formats, my job depends on it!"}, {"role": "user", "content": "\nCurrent + Task: What is Vidit''s favorite color?\n\nThis is the expected criteria for + your final answer: Vidit''s favorclearite color.\nyou MUST return the actual + complete content as the final answer, not a summary.\n\nBegin! This is VERY + important to you, use the tools available and give your best Final Answer, your + job depends on it!\n\nThought:"}], "stream": false, "stop": ["\nObservation:"]}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '951' + content-type: + - application/json + host: + - openrouter.ai + http-referer: + - https://litellm.ai + user-agent: + - litellm/1.68.0 + x-title: + - liteLLM + method: POST + uri: https://openrouter.ai/api/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAAwAAAP//4lKAAS4AAAAA///iQjABAAAA//90kUGPEzEMhf+K5QuXdJmlpbvkthIg + emFXQoIDoMpNPFNDJo6STLul6n9H09KyIDjmxc9+/rxH8Wix4zi5vpndTK+n8+Z2wo9vXj28fHff + vW4+PNT5j1l6/wkNpqwb8ZzR4n3ieLdAg716DmhRE0eS512qk5lOeomCBnX1jV1Fi25N9cppnwJX + 0YgGXWaq7NH+HmvQrVUcF7Sf9xi0S1lXBW0cQjDYSpSyXmamohEtlqoJDUaqsuHlf34len5E2xjs + uRTqGO0eswZGi1SKlEqxjmk0Vo5j0gVE3YKjCJ1sGAi6MShQLFvOAF/iW4kU4O74tvBRvNRnBVra + aJbK4DRoBikQtcJWPIcdeHVDz7GyB4mQhlUQF3ZAG5JAq8BQdMiOi4GisBiHj+ZftIHA87hePeY5 + 5cjcUfYSO1hLgZLYSSvurxRXaDBzOxQKZ4gnPhK7k3A4fDVYdqVyPxLsOKcsRwxtWvoVOZo3vm3Q + 4HCGl7L2qS6rfudYxus1I73zYS/69NZg1UrhorwYD/yHe+m5koQytnXk1uwvxc3hH12f1l8WeWI5 + HH4CAAD//wMAhZKqO+QCAAA= + headers: + Access-Control-Allow-Origin: + - '*' + CF-RAY: + - 9402c7459f3f859c-BOM + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Thu, 15 May 2025 12:53:28 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + x-clerk-auth-message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + x-clerk-auth-reason: + - token-invalid + x-clerk-auth-status: + - signed-out + status: + code: 200 + message: OK +version: 1 diff --git a/tests/cassettes/test_agent_with_only_crewai_knowledge.yaml b/tests/cassettes/test_agent_with_only_crewai_knowledge.yaml new file mode 100644 index 000000000..7472675b2 --- /dev/null +++ b/tests/cassettes/test_agent_with_only_crewai_knowledge.yaml @@ -0,0 +1,150 @@ +interactions: +- request: + body: '{"model": "openai/gpt-4o-mini", "messages": [{"role": "system", "content": + "Your goal is to rewrite the user query so that it is optimized for retrieval + from a vector database. Consider how the query will be used to find relevant + documents, and aim to make it more specific and context-aware. \n\n Do not include + any other text than the rewritten query, especially any preamble or postamble + and only add expected output format if its relevant to the rewritten query. + \n\n Focus on the key words of the intended task and to retrieve the most relevant + information. \n\n There will be some extra context provided that might need + to be removed such as expected_output formats structured_outputs and other instructions."}, + {"role": "user", "content": "The original query is: What is Vidit''s favorite + color?\n\nThis is the expected criteria for your final answer: Vidit''s favorclearite + color.\nyou MUST return the actual complete content as the final answer, not + a summary.."}], "stream": false, "stop": ["\nObservation:"]}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '1017' + content-type: + - application/json + host: + - openrouter.ai + http-referer: + - https://litellm.ai + user-agent: + - litellm/1.68.0 + x-title: + - liteLLM + method: POST + uri: https://openrouter.ai/api/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAAwAAAP//4lKAAS4AAAAA//90kE1PIzEMhv8Kei97Sdnplwq5gTgAF8ShcFitRmnG + nTFk4ihxq11V899Xs6gFJLja78djH8ANLFqKk+lqsZpP56vpYqJhublfP1eP65v1i79Lt9fdMwxS + lj03lGHxkChe3cGgl4YCLCRRdPyzTTpZyKTnyDCQzQt5hYXvnJ576VMgZYkw8JmcUgP7XmvgO2FP + BfbXAUHalGVTYOMuBIMtRy5dnckVibAoKgkG0Snvqf5my7GhP7CVQU+luJZgD8gSCBauFC7qoo40 + EpXiSPrEDeuPcrZ1e8msdOYlSIZBpu2uuHDEeWvi2L4NhuG3QflblPqRpaWcMv8P3Ka6ml/OLmaz + 6rKCwe6IkbL0SWuVV4pl/MNy5Di+6DRfGqioC+/Ci8p8NtcNqeNQxlTvfEfNSVwNX4R+1J/u+GAZ + hn8AAAD//wMAIwJ79CICAAA= + headers: + Access-Control-Allow-Origin: + - '*' + CF-RAY: + - 9402c9db99ec4722-BOM + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Thu, 15 May 2025 12:55:14 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + x-clerk-auth-message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + x-clerk-auth-reason: + - token-invalid + x-clerk-auth-status: + - signed-out + status: + code: 200 + message: OK +- request: + body: '{"model": "openai/gpt-4o-mini", "messages": [{"role": "system", "content": + "You are Information Agent. You have access to specific knowledge sources.\nYour + personal goal is: Provide information based on knowledge sources\nTo give my + best complete final answer to the task respond using the exact following format:\n\nThought: + I now can give a great answer\nFinal Answer: Your final answer must be the great + and the most complete as possible, it must be outcome described.\n\nI MUST use + these formats, my job depends on it!"}, {"role": "user", "content": "\nCurrent + Task: What is Vidit''s favorite color?\n\nThis is the expected criteria for + your final answer: Vidit''s favorclearite color.\nyou MUST return the actual + complete content as the final answer, not a summary.\n\nBegin! This is VERY + important to you, use the tools available and give your best Final Answer, your + job depends on it!\n\nThought:"}], "stream": false, "stop": ["\nObservation:"]}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '951' + content-type: + - application/json + host: + - openrouter.ai + http-referer: + - https://litellm.ai + user-agent: + - litellm/1.68.0 + x-title: + - liteLLM + method: POST + uri: https://openrouter.ai/api/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAAwAAAP//4lKAAS4AAAAA///iQjABAAAA//90kN1qGzEQRl9FfNdyul4nday73ARy + VUpLE2jLIu+O15NoZ4QkOy1moa/R1+uTlE1wnEB7qU/zc84cwB0cepLZfHm+XMwXy/nF7II/3d7V + H+tOPvsS3le3d+keFjHpnjtKcPgQSa5uYDFoRwEOGkk8v+tjmZ3rbGBhWOj6ntoCh3bry1mrQwxU + WAUWbSJfqIM7rbVot8otZbivBwTtY9J1hpNdCBYbFs7bJpHPKnDIRSMsxBfeU/OfX5aOfsBVFgPl + 7HuCOyBpIDj4nDkXL2WiUSkkE+mNEX00rRfT856MN/0EarzkR0rGfJNrFh/M1dPbmS/ccfnz63c2 + G7/XxIVMq0GT4WzWYUdnsEi02WUfjiLPjCz9czCO3y3yz1xomCx6SjHxE8omNtViVV/WdbWqYLE7 + CsSkQyxN0QeSPF2wmgyOxz3lK4uixYdTcrmyb7ubjornkKexrW+31L0UV+M/pr6ufxF51TKOfwEA + AP//AwBybekMaAIAAA== + headers: + Access-Control-Allow-Origin: + - '*' + CF-RAY: + - 9402c9e1b94a4722-BOM + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Thu, 15 May 2025 12:55:15 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + x-clerk-auth-message: + - Invalid JWT form. A JWT consists of three parts separated by dots. (reason=token-invalid, + token-carrier=header) + x-clerk-auth-reason: + - token-invalid + x-clerk-auth-status: + - signed-out + status: + code: 200 + message: OK +version: 1