From 64804682fc3a90a05c3bd754f4a8d33d92d1136e Mon Sep 17 00:00:00 2001 From: "Brandon Hancock (bhancock_ai)" <109994880+bhancockio@users.noreply.github.com> Date: Thu, 20 Feb 2025 12:01:49 -0500 Subject: [PATCH] imporve HITL (#2169) * imporve HITL * fix failing test * fix failing test part 2 * Drop extra logs that were causing confusion --------- Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com> --- .../base_agent_executor_mixin.py | 11 +- src/crewai/agents/crew_agent_executor.py | 30 +- src/crewai/translations/en.json | 1 - tests/agent_test.py | 31 +- tests/cassettes/test_agent_human_input.yaml | 520 ------------------ 5 files changed, 31 insertions(+), 562 deletions(-) delete mode 100644 tests/cassettes/test_agent_human_input.yaml diff --git a/src/crewai/agents/agent_builder/base_agent_executor_mixin.py b/src/crewai/agents/agent_builder/base_agent_executor_mixin.py index 924cef71c..e7917f2bd 100644 --- a/src/crewai/agents/agent_builder/base_agent_executor_mixin.py +++ b/src/crewai/agents/agent_builder/base_agent_executor_mixin.py @@ -114,10 +114,15 @@ class CrewAgentExecutorMixin: prompt = ( "\n\n=====\n" "## HUMAN FEEDBACK: Provide feedback on the Final Result and Agent's actions.\n" - "Respond with 'looks good' to accept or provide specific improvement requests.\n" - "You can provide multiple rounds of feedback until satisfied.\n" + "Please follow these guidelines:\n" + " - If you are happy with the result, simply hit Enter without typing anything.\n" + " - Otherwise, provide specific improvement requests.\n" + " - You can provide multiple rounds of feedback until satisfied.\n" "=====\n" ) self._printer.print(content=prompt, color="bold_yellow") - return input() + response = input() + if response.strip() != "": + self._printer.print(content="\nProcessing your feedback...", color="cyan") + return response diff --git a/src/crewai/agents/crew_agent_executor.py b/src/crewai/agents/crew_agent_executor.py index fad24b702..302beb625 100644 --- a/src/crewai/agents/crew_agent_executor.py +++ b/src/crewai/agents/crew_agent_executor.py @@ -548,10 +548,6 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): self, initial_answer: AgentFinish, feedback: str ) -> AgentFinish: """Process feedback for training scenarios with single iteration.""" - self._printer.print( - content="\nProcessing training feedback.\n", - color="yellow", - ) self._handle_crew_training_output(initial_answer, feedback) self.messages.append( self._format_msg( @@ -571,9 +567,8 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): answer = current_answer while self.ask_for_human_input: - response = self._get_llm_feedback_response(feedback) - - if not self._feedback_requires_changes(response): + # If the user provides a blank response, assume they are happy with the result + if feedback.strip() == "": self.ask_for_human_input = False else: answer = self._process_feedback_iteration(feedback) @@ -581,27 +576,6 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): return answer - def _get_llm_feedback_response(self, feedback: str) -> Optional[str]: - """Get LLM classification of whether feedback requires changes.""" - prompt = self._i18n.slice("human_feedback_classification").format( - feedback=feedback - ) - message = self._format_msg(prompt, role="system") - - for retry in range(MAX_LLM_RETRY): - try: - response = self.llm.call([message], callbacks=self.callbacks) - return response.strip().lower() if response else None - except Exception as error: - self._log_feedback_error(retry, error) - - self._log_max_retries_exceeded() - return None - - def _feedback_requires_changes(self, response: Optional[str]) -> bool: - """Determine if feedback response indicates need for changes.""" - return response == "true" if response else False - def _process_feedback_iteration(self, feedback: str) -> AgentFinish: """Process a single feedback iteration.""" self.messages.append( diff --git a/src/crewai/translations/en.json b/src/crewai/translations/en.json index f09f1dba0..4c28fc5d5 100644 --- a/src/crewai/translations/en.json +++ b/src/crewai/translations/en.json @@ -23,7 +23,6 @@ "summary": "This is a summary of our conversation so far:\n{merged_summary}", "manager_request": "Your best answer to your coworker asking you this, accounting for the context shared.", "formatted_task_instructions": "Ensure your final answer contains only the content in the following format: {output_format}\n\nEnsure the final output does not include any code block markers like ```json or ```python.", - "human_feedback_classification": "Determine if the following feedback indicates that the user is satisfied or if further changes are needed. Respond with 'True' if further changes are needed, or 'False' if the user is satisfied. **Important** Do not include any additional commentary outside of your 'True' or 'False' response.\n\nFeedback: \"{feedback}\"", "conversation_history_instruction": "You are a member of a crew collaborating to achieve a common goal. Your task is a specific action that contributes to this larger objective. For additional context, please review the conversation history between you and the user that led to the initiation of this crew. Use any relevant information or feedback from the conversation to inform your task execution and ensure your response aligns with both the immediate task and the crew's overall goals.", "feedback_instructions": "User feedback: {feedback}\nInstructions: Use this feedback to enhance the next output iteration.\nNote: Do not respond or add commentary." }, diff --git a/tests/agent_test.py b/tests/agent_test.py index 3547398e5..1d07da23e 100644 --- a/tests/agent_test.py +++ b/tests/agent_test.py @@ -1,7 +1,6 @@ """Test Agent creation and execution basic functionality.""" import os -from datetime import UTC, datetime, timezone from unittest import mock from unittest.mock import patch @@ -9,7 +8,7 @@ import pytest from crewai import Agent, Crew, Task from crewai.agents.cache import CacheHandler -from crewai.agents.crew_agent_executor import CrewAgentExecutor +from crewai.agents.crew_agent_executor import AgentFinish, CrewAgentExecutor from crewai.agents.parser import AgentAction, CrewAgentParser, OutputParserException from crewai.knowledge.source.base_knowledge_source import BaseKnowledgeSource from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource @@ -999,23 +998,35 @@ def test_agent_human_input(): # Side effect function for _ask_human_input to simulate multiple feedback iterations feedback_responses = iter( [ - "Don't say hi, say Hello instead!", # First feedback - "looks good", # Second feedback to exit loop + "Don't say hi, say Hello instead!", # First feedback: instruct change + "", # Second feedback: empty string signals acceptance ] ) def ask_human_input_side_effect(*args, **kwargs): return next(feedback_responses) - with patch.object( - CrewAgentExecutor, "_ask_human_input", side_effect=ask_human_input_side_effect - ) as mock_human_input: + # Patch both _ask_human_input and _invoke_loop to avoid real API/network calls. + with ( + patch.object( + CrewAgentExecutor, + "_ask_human_input", + side_effect=ask_human_input_side_effect, + ) as mock_human_input, + patch.object( + CrewAgentExecutor, + "_invoke_loop", + return_value=AgentFinish(output="Hello", thought="", text=""), + ) as mock_invoke_loop, + ): # Execute the task output = agent.execute_task(task) - # Assertions to ensure the agent behaves correctly - assert mock_human_input.call_count == 2 # Should have asked for feedback twice - assert output.strip().lower() == "hello" # Final output should be 'Hello' + # Assertions to ensure the agent behaves correctly. + # It should have requested feedback twice. + assert mock_human_input.call_count == 2 + # The final result should be processed to "Hello" + assert output.strip().lower() == "hello" def test_interpolate_inputs(): diff --git a/tests/cassettes/test_agent_human_input.yaml b/tests/cassettes/test_agent_human_input.yaml deleted file mode 100644 index 8c5fd3a80..000000000 --- a/tests/cassettes/test_agent_human_input.yaml +++ /dev/null @@ -1,520 +0,0 @@ -interactions: -- request: - body: !!binary | - CqcXCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkS/hYKEgoQY3Jld2FpLnRl - bGVtZXRyeRJ5ChBuJJtOdNaB05mOW/p3915eEgj2tkAd3rZcASoQVG9vbCBVc2FnZSBFcnJvcjAB - OYa7/URvKBUYQUpcFEVvKBUYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODYuMEoPCgNsbG0SCAoG - Z3B0LTRvegIYAYUBAAEAABLJBwoQifhX01E5i+5laGdALAlZBBIIBuGM1aN+OPgqDENyZXcgQ3Jl - YXRlZDABORVGruBvKBUYQaipwOBvKBUYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODYuMEoaCg5w - eXRob25fdmVyc2lvbhIICgYzLjEyLjdKLgoIY3Jld19rZXkSIgogN2U2NjA4OTg5ODU5YTY3ZWVj - ODhlZWY3ZmNlODUyMjVKMQoHY3Jld19pZBImCiRiOThiNWEwMC01YTI1LTQxMDctYjQwNS1hYmYz - MjBhOGYzYThKHAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAA - ShoKFGNyZXdfbnVtYmVyX29mX3Rhc2tzEgIYAUobChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgB - SuQCCgtjcmV3X2FnZW50cxLUAgrRAlt7ImtleSI6ICIyMmFjZDYxMWU0NGVmNWZhYzA1YjUzM2Q3 - NWU4ODkzYiIsICJpZCI6ICJkNWIyMzM1YS0yMmIyLTQyZWEtYmYwNS03OTc3NmU3MmYzOTIiLCAi - cm9sZSI6ICJEYXRhIFNjaWVudGlzdCIsICJ2ZXJib3NlPyI6IGZhbHNlLCAibWF4X2l0ZXIiOiAy - MCwgIm1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwgImxsbSI6ICJn - cHQtNG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4 - ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFsi - Z2V0IGdyZWV0aW5ncyJdfV1KkgIKCmNyZXdfdGFza3MSgwIKgAJbeyJrZXkiOiAiYTI3N2IzNGIy - YzE0NmYwYzU2YzVlMTM1NmU4ZjhhNTciLCAiaWQiOiAiMjJiZWMyMzEtY2QyMS00YzU4LTgyN2Ut - MDU4MWE4ZjBjMTExIiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6 - IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJEYXRhIFNjaWVudGlzdCIsICJhZ2VudF9rZXkiOiAiMjJh - Y2Q2MTFlNDRlZjVmYWMwNWI1MzNkNzVlODg5M2IiLCAidG9vbHNfbmFtZXMiOiBbImdldCBncmVl - dGluZ3MiXX1degIYAYUBAAEAABKOAgoQ5WYoxRtTyPjge4BduhL0rRIIv2U6rvWALfwqDFRhc2sg - Q3JlYXRlZDABOX068uBvKBUYQZkv8+BvKBUYSi4KCGNyZXdfa2V5EiIKIDdlNjYwODk4OTg1OWE2 - N2VlYzg4ZWVmN2ZjZTg1MjI1SjEKB2NyZXdfaWQSJgokYjk4YjVhMDAtNWEyNS00MTA3LWI0MDUt - YWJmMzIwYThmM2E4Si4KCHRhc2tfa2V5EiIKIGEyNzdiMzRiMmMxNDZmMGM1NmM1ZTEzNTZlOGY4 - YTU3SjEKB3Rhc2tfaWQSJgokMjJiZWMyMzEtY2QyMS00YzU4LTgyN2UtMDU4MWE4ZjBjMTExegIY - AYUBAAEAABKQAQoQXyeDtJDFnyp2Fjk9YEGTpxIIaNE7gbhPNYcqClRvb2wgVXNhZ2UwATkaXTvj - bygVGEGvx0rjbygVGEoaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjg2LjBKHAoJdG9vbF9uYW1lEg8K - DUdldCBHcmVldGluZ3NKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABLVBwoQMWfznt0qwauEzl7T - UOQxRBII9q+pUS5EdLAqDENyZXcgQ3JlYXRlZDABORONPORvKBUYQSAoS+RvKBUYShoKDmNyZXdh - aV92ZXJzaW9uEggKBjAuODYuMEoaCg5weXRob25fdmVyc2lvbhIICgYzLjEyLjdKLgoIY3Jld19r - ZXkSIgogYzMwNzYwMDkzMjY3NjE0NDRkNTdjNzFkMWRhM2YyN2NKMQoHY3Jld19pZBImCiQ3OTQw - MTkyNS1iOGU5LTQ3MDgtODUzMC00NDhhZmEzYmY4YjBKHAoMY3Jld19wcm9jZXNzEgwKCnNlcXVl - bnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdfbnVtYmVyX29mX3Rhc2tzEgIYAUobChVj - cmV3X251bWJlcl9vZl9hZ2VudHMSAhgBSuoCCgtjcmV3X2FnZW50cxLaAgrXAlt7ImtleSI6ICI5 - OGYzYjFkNDdjZTk2OWNmMDU3NzI3Yjc4NDE0MjVjZCIsICJpZCI6ICI5OTJkZjYyZi1kY2FiLTQy - OTUtOTIwNi05MDBkNDExNGIxZTkiLCAicm9sZSI6ICJGcmllbmRseSBOZWlnaGJvciIsICJ2ZXJi - b3NlPyI6IGZhbHNlLCAibWF4X2l0ZXIiOiAyMCwgIm1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25f - Y2FsbGluZ19sbG0iOiAiIiwgImxsbSI6ICJncHQtNG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJs - ZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9s - aW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFsiZGVjaWRlIGdyZWV0aW5ncyJdfV1KmAIKCmNyZXdf - dGFza3MSiQIKhgJbeyJrZXkiOiAiODBkN2JjZDQ5MDk5MjkwMDgzODMyZjBlOTgzMzgwZGYiLCAi - aWQiOiAiMmZmNjE5N2UtYmEyNy00YjczLWI0YTctNGZhMDQ4ZTYyYjQ3IiwgImFzeW5jX2V4ZWN1 - dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJGcmll - bmRseSBOZWlnaGJvciIsICJhZ2VudF9rZXkiOiAiOThmM2IxZDQ3Y2U5NjljZjA1NzcyN2I3ODQx - NDI1Y2QiLCAidG9vbHNfbmFtZXMiOiBbImRlY2lkZSBncmVldGluZ3MiXX1degIYAYUBAAEAABKO - AgoQnjTp5boK7/+DQxztYIpqihIIgGnMUkBtzHEqDFRhc2sgQ3JlYXRlZDABOcpYcuRvKBUYQalE - c+RvKBUYSi4KCGNyZXdfa2V5EiIKIGMzMDc2MDA5MzI2NzYxNDQ0ZDU3YzcxZDFkYTNmMjdjSjEK - B2NyZXdfaWQSJgokNzk0MDE5MjUtYjhlOS00NzA4LTg1MzAtNDQ4YWZhM2JmOGIwSi4KCHRhc2tf - a2V5EiIKIDgwZDdiY2Q0OTA5OTI5MDA4MzgzMmYwZTk4MzM4MGRmSjEKB3Rhc2tfaWQSJgokMmZm - NjE5N2UtYmEyNy00YjczLWI0YTctNGZhMDQ4ZTYyYjQ3egIYAYUBAAEAABKTAQoQ26H9pLUgswDN - p9XhJwwL6BIIx3bw7mAvPYwqClRvb2wgVXNhZ2UwATmy7NPlbygVGEEvb+HlbygVGEoaCg5jcmV3 - YWlfdmVyc2lvbhIICgYwLjg2LjBKHwoJdG9vbF9uYW1lEhIKEERlY2lkZSBHcmVldGluZ3NKDgoI - YXR0ZW1wdHMSAhgBegIYAYUBAAEAAA== - headers: - Accept: - - '*/*' - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - Content-Length: - - '2986' - Content-Type: - - application/x-protobuf - User-Agent: - - OTel-OTLP-Exporter-Python/1.27.0 - method: POST - uri: https://telemetry.crewai.com:4319/v1/traces - response: - body: - string: "\n\0" - headers: - Content-Length: - - '2' - Content-Type: - - application/x-protobuf - Date: - - Fri, 27 Dec 2024 22:14:53 GMT - status: - code: 200 - message: OK -- request: - body: '{"messages": [{"role": "system", "content": "You are test role. test backstory\nYour - personal goal is: test goal\nTo give my best complete final answer to the task - use 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: Say the word: Hi\n\nThis - is the expect criteria for your final answer: The word: Hi\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:"}], "model": "gpt-4o-mini", "stop": ["\nObservation:"], - "stream": false}' - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - connection: - - keep-alive - content-length: - - '824' - content-type: - - application/json - cookie: - - _cfuvid=ePJSDFdHag2D8lj21_ijAMWjoA6xfnPNxN4uekvC728-1727226247743-0.0.1.1-604800000 - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.52.1 - x-stainless-arch: - - x64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - Linux - x-stainless-package-version: - - 1.52.1 - x-stainless-raw-response: - - 'true' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.7 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - content: "{\n \"id\": \"chatcmpl-AjCtZLLrWi8ZASpP9bz6HaCV7xBIn\",\n \"object\": - \"chat.completion\",\n \"created\": 1735337693,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": \"I now can give a great answer \\nFinal - Answer: Hi\",\n \"refusal\": null\n },\n \"logprobs\": null,\n - \ \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": - 158,\n \"completion_tokens\": 12,\n \"total_tokens\": 170,\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 \"system_fingerprint\": - \"fp_0aa8d3e20b\"\n}\n" - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8f8caa83deca756b-SEA - Connection: - - keep-alive - Content-Encoding: - - gzip - Content-Type: - - application/json - Date: - - Fri, 27 Dec 2024 22:14:53 GMT - Server: - - cloudflare - Set-Cookie: - - __cf_bm=wJkq_yLkzE3OdxE0aMJz.G0kce969.9JxRmZ0ratl4c-1735337693-1.0.1.1-OKpUoRrSPFGvWv5Hp5ET1PNZ7iZNHPKEAuakpcQUxxPSeisUIIR3qIOZ31MGmYugqB5.wkvidgbxOAagqJvmnw; - path=/; expires=Fri, 27-Dec-24 22:44:53 GMT; domain=.api.openai.com; HttpOnly; - Secure; SameSite=None - - _cfuvid=A_ASCLNAVfQoyucWOAIhecWtEpNotYoZr0bAFihgNxs-1735337693273-0.0.1.1-604800000; - path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: - - crewai-iuxna1 - openai-processing-ms: - - '404' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999816' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_6ac84634bff9193743c4b0911c09b4a6 - http_version: HTTP/1.1 - status_code: 200 -- request: - body: '{"messages": [{"role": "system", "content": "Determine if the following - feedback indicates that the user is satisfied or if further changes are needed. - Respond with ''True'' if further changes are needed, or ''False'' if the user - is satisfied. **Important** Do not include any additional commentary outside - of your ''True'' or ''False'' response.\n\nFeedback: \"Don''t say hi, say Hello - instead!\""}], "model": "gpt-4o-mini", "stop": ["\nObservation:"], "stream": - false}' - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - connection: - - keep-alive - content-length: - - '461' - content-type: - - application/json - cookie: - - _cfuvid=A_ASCLNAVfQoyucWOAIhecWtEpNotYoZr0bAFihgNxs-1735337693273-0.0.1.1-604800000; - __cf_bm=wJkq_yLkzE3OdxE0aMJz.G0kce969.9JxRmZ0ratl4c-1735337693-1.0.1.1-OKpUoRrSPFGvWv5Hp5ET1PNZ7iZNHPKEAuakpcQUxxPSeisUIIR3qIOZ31MGmYugqB5.wkvidgbxOAagqJvmnw - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.52.1 - x-stainless-arch: - - x64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - Linux - x-stainless-package-version: - - 1.52.1 - x-stainless-raw-response: - - 'true' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.7 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - content: "{\n \"id\": \"chatcmpl-AjCtZNlWdrrPZhq0MJDqd16sMuQEJ\",\n \"object\": - \"chat.completion\",\n \"created\": 1735337693,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": \"True\",\n \"refusal\": null\n - \ },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n }\n - \ ],\n \"usage\": {\n \"prompt_tokens\": 78,\n \"completion_tokens\": - 1,\n \"total_tokens\": 79,\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 \"system_fingerprint\": - \"fp_0aa8d3e20b\"\n}\n" - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8f8caa87094f756b-SEA - Connection: - - keep-alive - Content-Encoding: - - gzip - Content-Type: - - application/json - Date: - - Fri, 27 Dec 2024 22:14:53 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: - - crewai-iuxna1 - openai-processing-ms: - - '156' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999898' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_ec74bef2a9ef7b2144c03fd7f7bbeab0 - http_version: HTTP/1.1 - status_code: 200 -- request: - body: '{"messages": [{"role": "system", "content": "You are test role. test backstory\nYour - personal goal is: test goal\nTo give my best complete final answer to the task - use 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: Say the word: Hi\n\nThis - is the expect criteria for your final answer: The word: Hi\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:"}, {"role": "assistant", "content": "I now - can give a great answer \nFinal Answer: Hi"}, {"role": "user", "content": "Feedback: - Don''t say hi, say Hello instead!"}], "model": "gpt-4o-mini", "stop": ["\nObservation:"], - "stream": false}' - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - connection: - - keep-alive - content-length: - - '986' - content-type: - - application/json - cookie: - - _cfuvid=A_ASCLNAVfQoyucWOAIhecWtEpNotYoZr0bAFihgNxs-1735337693273-0.0.1.1-604800000; - __cf_bm=wJkq_yLkzE3OdxE0aMJz.G0kce969.9JxRmZ0ratl4c-1735337693-1.0.1.1-OKpUoRrSPFGvWv5Hp5ET1PNZ7iZNHPKEAuakpcQUxxPSeisUIIR3qIOZ31MGmYugqB5.wkvidgbxOAagqJvmnw - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.52.1 - x-stainless-arch: - - x64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - Linux - x-stainless-package-version: - - 1.52.1 - x-stainless-raw-response: - - 'true' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.7 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - content: "{\n \"id\": \"chatcmpl-AjCtZGv4f3h7GDdhyOy9G0sB1lRgC\",\n \"object\": - \"chat.completion\",\n \"created\": 1735337693,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": \"Thought: I understand the feedback and - will adjust my response accordingly. \\nFinal Answer: Hello\",\n \"refusal\": - null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n - \ }\n ],\n \"usage\": {\n \"prompt_tokens\": 188,\n \"completion_tokens\": - 18,\n \"total_tokens\": 206,\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 \"system_fingerprint\": - \"fp_0aa8d3e20b\"\n}\n" - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8f8caa88cac4756b-SEA - Connection: - - keep-alive - Content-Encoding: - - gzip - Content-Type: - - application/json - Date: - - Fri, 27 Dec 2024 22:14:54 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: - - crewai-iuxna1 - openai-processing-ms: - - '358' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999793' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_ae1ab6b206d28ded6fee3c83ed0c2ab7 - http_version: HTTP/1.1 - status_code: 200 -- request: - body: '{"messages": [{"role": "system", "content": "Determine if the following - feedback indicates that the user is satisfied or if further changes are needed. - Respond with ''True'' if further changes are needed, or ''False'' if the user - is satisfied. **Important** Do not include any additional commentary outside - of your ''True'' or ''False'' response.\n\nFeedback: \"looks good\""}], "model": - "gpt-4o-mini", "stop": ["\nObservation:"], "stream": false}' - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - connection: - - keep-alive - content-length: - - '439' - content-type: - - application/json - cookie: - - _cfuvid=A_ASCLNAVfQoyucWOAIhecWtEpNotYoZr0bAFihgNxs-1735337693273-0.0.1.1-604800000; - __cf_bm=wJkq_yLkzE3OdxE0aMJz.G0kce969.9JxRmZ0ratl4c-1735337693-1.0.1.1-OKpUoRrSPFGvWv5Hp5ET1PNZ7iZNHPKEAuakpcQUxxPSeisUIIR3qIOZ31MGmYugqB5.wkvidgbxOAagqJvmnw - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.52.1 - x-stainless-arch: - - x64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - Linux - x-stainless-package-version: - - 1.52.1 - x-stainless-raw-response: - - 'true' - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.7 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - content: "{\n \"id\": \"chatcmpl-AjCtaiHL4TY8Dssk0j2miqmjrzquy\",\n \"object\": - \"chat.completion\",\n \"created\": 1735337694,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n - \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": \"False\",\n \"refusal\": null\n - \ },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n }\n - \ ],\n \"usage\": {\n \"prompt_tokens\": 73,\n \"completion_tokens\": - 1,\n \"total_tokens\": 74,\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 \"system_fingerprint\": - \"fp_0aa8d3e20b\"\n}\n" - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8f8caa8bdd26756b-SEA - Connection: - - keep-alive - Content-Encoding: - - gzip - Content-Type: - - application/json - Date: - - Fri, 27 Dec 2024 22:14:54 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: - - crewai-iuxna1 - openai-processing-ms: - - '184' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999902' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_652891f79c1104a7a8436275d78a69f1 - http_version: HTTP/1.1 - status_code: 200 -version: 1