mirror of
https://github.com/crewAIInc/crewAI.git
synced 2025-12-19 05:48:32 +00:00
Compare commits
28 Commits
bugfix/asy
...
brandon/en
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6d33f626c | ||
|
|
b1960ecb4c | ||
|
|
dfb2b4b47a | ||
|
|
b171e82990 | ||
|
|
d77902c537 | ||
|
|
90d610ed7e | ||
|
|
9f8293349c | ||
|
|
fb763885eb | ||
|
|
389d5a9982 | ||
|
|
91144a692a | ||
|
|
58a8c442da | ||
|
|
0b70b3c8b4 | ||
|
|
8833ccc123 | ||
|
|
37ad9f9d9e | ||
|
|
3f20ef101c | ||
|
|
d4afe9fe66 | ||
|
|
acb0d7e056 | ||
|
|
9fb98dbf01 | ||
|
|
219af9baa8 | ||
|
|
2b976e1f63 | ||
|
|
c653a2e691 | ||
|
|
6a4d3eb269 | ||
|
|
52133ebf99 | ||
|
|
d6e7750965 | ||
|
|
6ad314af8c | ||
|
|
0dc2582ce1 | ||
|
|
26053c9d1a | ||
|
|
2107512e84 |
@@ -86,7 +86,7 @@ class Agent(BaseAgent):
|
|||||||
llm: Union[str, InstanceOf[LLM], Any] = Field(
|
llm: Union[str, InstanceOf[LLM], Any] = Field(
|
||||||
description="Language model that will run the agent.", default=None
|
description="Language model that will run the agent.", default=None
|
||||||
)
|
)
|
||||||
function_calling_llm: Optional[Any] = Field(
|
function_calling_llm: Optional[Union[str, InstanceOf[LLM], Any]] = Field(
|
||||||
description="Language model that will run the agent.", default=None
|
description="Language model that will run the agent.", default=None
|
||||||
)
|
)
|
||||||
system_template: Optional[str] = Field(
|
system_template: Optional[str] = Field(
|
||||||
@@ -142,7 +142,8 @@ class Agent(BaseAgent):
|
|||||||
self.agent_ops_agent_name = self.role
|
self.agent_ops_agent_name = self.role
|
||||||
|
|
||||||
self.llm = create_llm(self.llm)
|
self.llm = create_llm(self.llm)
|
||||||
self.function_calling_llm = create_llm(self.function_calling_llm)
|
if self.function_calling_llm and not isinstance(self.function_calling_llm, LLM):
|
||||||
|
self.function_calling_llm = create_llm(self.function_calling_llm)
|
||||||
|
|
||||||
if not self.agent_executor:
|
if not self.agent_executor:
|
||||||
self._setup_agent_executor()
|
self._setup_agent_executor()
|
||||||
|
|||||||
@@ -145,8 +145,6 @@ class CrewAgentExecutor(CrewAgentExecutorMixin):
|
|||||||
if self._is_context_length_exceeded(e):
|
if self._is_context_length_exceeded(e):
|
||||||
self._handle_context_length()
|
self._handle_context_length()
|
||||||
continue
|
continue
|
||||||
else:
|
|
||||||
raise e
|
|
||||||
|
|
||||||
self._show_logs(formatted_answer)
|
self._show_logs(formatted_answer)
|
||||||
return formatted_answer
|
return formatted_answer
|
||||||
@@ -316,7 +314,7 @@ class CrewAgentExecutor(CrewAgentExecutorMixin):
|
|||||||
agent=self.agent,
|
agent=self.agent,
|
||||||
action=agent_action,
|
action=agent_action,
|
||||||
)
|
)
|
||||||
tool_calling = tool_usage.parse(agent_action.text)
|
tool_calling = tool_usage.parse_tool_calling(agent_action.text)
|
||||||
|
|
||||||
if isinstance(tool_calling, ToolUsageErrorException):
|
if isinstance(tool_calling, ToolUsageErrorException):
|
||||||
tool_result = tool_calling.message
|
tool_result = tool_calling.message
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ from crewai.utilities.formatter import (
|
|||||||
aggregate_raw_outputs_from_task_outputs,
|
aggregate_raw_outputs_from_task_outputs,
|
||||||
aggregate_raw_outputs_from_tasks,
|
aggregate_raw_outputs_from_tasks,
|
||||||
)
|
)
|
||||||
|
from crewai.utilities.llm_utils import create_llm
|
||||||
from crewai.utilities.planning_handler import CrewPlanner
|
from crewai.utilities.planning_handler import CrewPlanner
|
||||||
from crewai.utilities.task_output_storage_handler import TaskOutputStorageHandler
|
from crewai.utilities.task_output_storage_handler import TaskOutputStorageHandler
|
||||||
from crewai.utilities.training_handler import CrewTrainingHandler
|
from crewai.utilities.training_handler import CrewTrainingHandler
|
||||||
@@ -149,7 +150,7 @@ class Crew(BaseModel):
|
|||||||
manager_agent: Optional[BaseAgent] = Field(
|
manager_agent: Optional[BaseAgent] = Field(
|
||||||
description="Custom agent that will be used as manager.", default=None
|
description="Custom agent that will be used as manager.", default=None
|
||||||
)
|
)
|
||||||
function_calling_llm: Optional[Any] = Field(
|
function_calling_llm: Optional[Union[str, InstanceOf[LLM], Any]] = Field(
|
||||||
description="Language model that will run the agent.", default=None
|
description="Language model that will run the agent.", default=None
|
||||||
)
|
)
|
||||||
config: Optional[Union[Json, Dict[str, Any]]] = Field(default=None)
|
config: Optional[Union[Json, Dict[str, Any]]] = Field(default=None)
|
||||||
@@ -245,15 +246,9 @@ class Crew(BaseModel):
|
|||||||
if self.output_log_file:
|
if self.output_log_file:
|
||||||
self._file_handler = FileHandler(self.output_log_file)
|
self._file_handler = FileHandler(self.output_log_file)
|
||||||
self._rpm_controller = RPMController(max_rpm=self.max_rpm, logger=self._logger)
|
self._rpm_controller = RPMController(max_rpm=self.max_rpm, logger=self._logger)
|
||||||
if self.function_calling_llm:
|
if self.function_calling_llm and not isinstance(self.function_calling_llm, LLM):
|
||||||
if isinstance(self.function_calling_llm, str):
|
self.function_calling_llm = create_llm(self.function_calling_llm)
|
||||||
self.function_calling_llm = LLM(model=self.function_calling_llm)
|
|
||||||
elif not isinstance(self.function_calling_llm, LLM):
|
|
||||||
self.function_calling_llm = LLM(
|
|
||||||
model=getattr(self.function_calling_llm, "model_name", None)
|
|
||||||
or getattr(self.function_calling_llm, "deployment_name", None)
|
|
||||||
or str(self.function_calling_llm)
|
|
||||||
)
|
|
||||||
self._telemetry = Telemetry()
|
self._telemetry = Telemetry()
|
||||||
self._telemetry.set_tracer()
|
self._telemetry.set_tracer()
|
||||||
return self
|
return self
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
import ast
|
import ast
|
||||||
import datetime
|
import datetime
|
||||||
|
import json
|
||||||
|
import re
|
||||||
import time
|
import time
|
||||||
from difflib import SequenceMatcher
|
from difflib import SequenceMatcher
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
from typing import Any, List, Union
|
from typing import Any, Dict, List, Union
|
||||||
|
|
||||||
|
from json_repair import repair_json
|
||||||
|
|
||||||
import crewai.utilities.events as events
|
import crewai.utilities.events as events
|
||||||
from crewai.agents.tools_handler import ToolsHandler
|
from crewai.agents.tools_handler import ToolsHandler
|
||||||
@@ -19,7 +23,15 @@ try:
|
|||||||
import agentops # type: ignore
|
import agentops # type: ignore
|
||||||
except ImportError:
|
except ImportError:
|
||||||
agentops = None
|
agentops = None
|
||||||
OPENAI_BIGGER_MODELS = ["gpt-4", "gpt-4o", "o1-preview", "o1-mini", "o1", "o3", "o3-mini"]
|
OPENAI_BIGGER_MODELS = [
|
||||||
|
"gpt-4",
|
||||||
|
"gpt-4o",
|
||||||
|
"o1-preview",
|
||||||
|
"o1-mini",
|
||||||
|
"o1",
|
||||||
|
"o3",
|
||||||
|
"o3-mini",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class ToolUsageErrorException(Exception):
|
class ToolUsageErrorException(Exception):
|
||||||
@@ -80,7 +92,7 @@ class ToolUsage:
|
|||||||
self._max_parsing_attempts = 2
|
self._max_parsing_attempts = 2
|
||||||
self._remember_format_after_usages = 4
|
self._remember_format_after_usages = 4
|
||||||
|
|
||||||
def parse(self, tool_string: str):
|
def parse_tool_calling(self, tool_string: str):
|
||||||
"""Parse the tool string and return the tool calling."""
|
"""Parse the tool string and return the tool calling."""
|
||||||
return self._tool_calling(tool_string)
|
return self._tool_calling(tool_string)
|
||||||
|
|
||||||
@@ -94,7 +106,6 @@ class ToolUsage:
|
|||||||
self.task.increment_tools_errors()
|
self.task.increment_tools_errors()
|
||||||
return error
|
return error
|
||||||
|
|
||||||
# BUG? The code below seems to be unreachable
|
|
||||||
try:
|
try:
|
||||||
tool = self._select_tool(calling.tool_name)
|
tool = self._select_tool(calling.tool_name)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -116,7 +127,7 @@ class ToolUsage:
|
|||||||
self._printer.print(content=f"\n\n{error}\n", color="red")
|
self._printer.print(content=f"\n\n{error}\n", color="red")
|
||||||
return error
|
return error
|
||||||
|
|
||||||
return f"{self._use(tool_string=tool_string, tool=tool, calling=calling)}" # type: ignore # BUG?: "_use" of "ToolUsage" does not return a value (it only ever returns None)
|
return f"{self._use(tool_string=tool_string, tool=tool, calling=calling)}"
|
||||||
|
|
||||||
def _use(
|
def _use(
|
||||||
self,
|
self,
|
||||||
@@ -349,13 +360,13 @@ class ToolUsage:
|
|||||||
tool_name = self.action.tool
|
tool_name = self.action.tool
|
||||||
tool = self._select_tool(tool_name)
|
tool = self._select_tool(tool_name)
|
||||||
try:
|
try:
|
||||||
tool_input = self._validate_tool_input(self.action.tool_input)
|
arguments = self._validate_tool_input(self.action.tool_input)
|
||||||
arguments = ast.literal_eval(tool_input)
|
|
||||||
except Exception:
|
except Exception:
|
||||||
if raise_error:
|
if raise_error:
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
return ToolUsageErrorException( # type: ignore # Incompatible return value type (got "ToolUsageErrorException", expected "ToolCalling | InstructorToolCalling")
|
return ToolUsageErrorException(
|
||||||
f'{self._i18n.errors("tool_arguments_error")}'
|
f'{self._i18n.errors("tool_arguments_error")}'
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -363,14 +374,14 @@ class ToolUsage:
|
|||||||
if raise_error:
|
if raise_error:
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
return ToolUsageErrorException( # type: ignore # Incompatible return value type (got "ToolUsageErrorException", expected "ToolCalling | InstructorToolCalling")
|
return ToolUsageErrorException(
|
||||||
f'{self._i18n.errors("tool_arguments_error")}'
|
f'{self._i18n.errors("tool_arguments_error")}'
|
||||||
)
|
)
|
||||||
|
|
||||||
return ToolCalling(
|
return ToolCalling(
|
||||||
tool_name=tool.name,
|
tool_name=tool.name,
|
||||||
arguments=arguments,
|
arguments=arguments,
|
||||||
log=tool_string, # type: ignore
|
log=tool_string,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _tool_calling(
|
def _tool_calling(
|
||||||
@@ -396,57 +407,28 @@ class ToolUsage:
|
|||||||
)
|
)
|
||||||
return self._tool_calling(tool_string)
|
return self._tool_calling(tool_string)
|
||||||
|
|
||||||
def _validate_tool_input(self, tool_input: str) -> str:
|
def _validate_tool_input(self, tool_input: str) -> Dict[str, Any]:
|
||||||
try:
|
try:
|
||||||
ast.literal_eval(tool_input)
|
# Replace Python literals with JSON equivalents
|
||||||
return tool_input
|
replacements = {
|
||||||
except Exception:
|
r"'": '"',
|
||||||
# Clean and ensure the string is properly enclosed in braces
|
r"None": "null",
|
||||||
tool_input = tool_input.strip()
|
r"True": "true",
|
||||||
if not tool_input.startswith("{"):
|
r"False": "false",
|
||||||
tool_input = "{" + tool_input
|
}
|
||||||
if not tool_input.endswith("}"):
|
for pattern, replacement in replacements.items():
|
||||||
tool_input += "}"
|
tool_input = re.sub(pattern, replacement, tool_input)
|
||||||
|
|
||||||
# Manually split the input into key-value pairs
|
arguments = json.loads(tool_input)
|
||||||
entries = tool_input.strip("{} ").split(",")
|
except json.JSONDecodeError:
|
||||||
formatted_entries = []
|
# Attempt to repair JSON string
|
||||||
|
repaired_input = repair_json(tool_input)
|
||||||
|
try:
|
||||||
|
arguments = json.loads(repaired_input)
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
raise Exception(f"Invalid tool input JSON: {e}")
|
||||||
|
|
||||||
for entry in entries:
|
return arguments
|
||||||
if ":" not in entry:
|
|
||||||
continue # Skip malformed entries
|
|
||||||
key, value = entry.split(":", 1)
|
|
||||||
|
|
||||||
# Remove extraneous white spaces and quotes, replace single quotes
|
|
||||||
key = key.strip().strip('"').replace("'", '"')
|
|
||||||
value = value.strip()
|
|
||||||
|
|
||||||
# Handle replacement of single quotes at the start and end of the value string
|
|
||||||
if value.startswith("'") and value.endswith("'"):
|
|
||||||
value = value[1:-1] # Remove single quotes
|
|
||||||
value = (
|
|
||||||
'"' + value.replace('"', '\\"') + '"'
|
|
||||||
) # Re-encapsulate with double quotes
|
|
||||||
elif value.isdigit(): # Check if value is a digit, hence integer
|
|
||||||
value = value
|
|
||||||
elif value.lower() in [
|
|
||||||
"true",
|
|
||||||
"false",
|
|
||||||
]: # Check for boolean and null values
|
|
||||||
value = value.lower().capitalize()
|
|
||||||
elif value.lower() == "null":
|
|
||||||
value = "None"
|
|
||||||
else:
|
|
||||||
# Assume the value is a string and needs quotes
|
|
||||||
value = '"' + value.replace('"', '\\"') + '"'
|
|
||||||
|
|
||||||
# Rebuild the entry with proper quoting
|
|
||||||
formatted_entry = f'"{key}": {value}'
|
|
||||||
formatted_entries.append(formatted_entry)
|
|
||||||
|
|
||||||
# Reconstruct the JSON string
|
|
||||||
new_json_string = "{" + ", ".join(formatted_entries) + "}"
|
|
||||||
return new_json_string
|
|
||||||
|
|
||||||
def on_tool_error(self, tool: Any, tool_calling: ToolCalling, e: Exception) -> None:
|
def on_tool_error(self, tool: Any, tool_calling: ToolCalling, e: Exception) -> None:
|
||||||
event_data = self._prepare_event_data(tool, tool_calling)
|
event_data = self._prepare_event_data(tool, tool_calling)
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
"task": "\nCurrent Task: {input}\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:",
|
"task": "\nCurrent Task: {input}\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:",
|
||||||
"memory": "\n\n# Useful context: \n{memory}",
|
"memory": "\n\n# Useful context: \n{memory}",
|
||||||
"role_playing": "You are {role}. {backstory}\nYour personal goal is: {goal}",
|
"role_playing": "You are {role}. {backstory}\nYour personal goal is: {goal}",
|
||||||
"tools": "\nYou ONLY have access to the following tools, and should NEVER make up tools that are not listed here:\n\n{tools}\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, only one name of [{tool_names}], just the name, exactly as it's written.\nAction Input: the input to the action, just a simple python dictionary, enclosed in curly braces, using \" to wrap keys and values.\nObservation: the result of the action\n\nOnce all necessary information is gathered:\n\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n",
|
"tools": "\nYou ONLY have access to the following tools, and should NEVER make up tools that are not listed here:\n\n{tools}\n\nIMPORTANT: Use the following format in your response:\n\n```\nThought: you should always think about what to do\nAction: the action to take, only one name of [{tool_names}], just the name, exactly as it's written.\nAction Input: the input to the action, just a simple JSON object, enclosed in curly braces, using \" to wrap keys and values.\nObservation: the result of the action\n```\n\nOnce all necessary information is gathered, return the following format:\n\n```\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n```",
|
||||||
"no_tools": "\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!",
|
"no_tools": "\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!",
|
||||||
"format": "I MUST either use a tool (use one at time) OR give my best final answer not both at the same time. To Use the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of [{tool_names}]\nAction Input: the input to the action, dictionary enclosed in curly braces\nObservation: the result of the action\n... (this Thought/Action/Action Input/Result can repeat N times)\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\n",
|
"format": "I MUST either use a tool (use one at time) OR give my best final answer not both at the same time. When responding, I must use the following format:\n\n```\nThought: you should always think about what to do\nAction: the action to take, should be one of [{tool_names}]\nAction Input: the input to the action, dictionary enclosed in curly braces\nObservation: the result of the action\n```\nThis Thought/Action/Action Input/Result can repeat N times. Once I know the final answer, I must return the following format:\n\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\n```",
|
||||||
"final_answer_format": "If you don't need to use any more tools, you must give your best complete final answer, make sure it satisfies the expected criteria, use the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer: my best complete final answer to the task.\n\n",
|
"final_answer_format": "If you don't need to use any more tools, you must give your best complete final answer, make sure it satisfies the expected criteria, use the EXACT format below:\n\n```\nThought: I now can give a great answer\nFinal Answer: my best complete final answer to the task.\n\n```",
|
||||||
"format_without_tools": "\nSorry, I didn't use the right format. I MUST either use a tool (among the available ones), OR give my best final answer.\nI just remembered the expected format I must follow:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [{tool_names}]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Result can repeat N times)\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\n",
|
"format_without_tools": "\nSorry, I didn't use the right format. I MUST either use a tool (among the available ones), OR give my best final answer.\nHere is the expected format I must follow:\n\n```\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [{tool_names}]\nAction Input: the input to the action\nObservation: the result of the action\n```\n This Thought/Action/Action Input/Result process can repeat N times. Once I know the final answer, I must return the following format:\n\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\n```",
|
||||||
"task_with_context": "{task}\n\nThis is the context you're working with:\n{context}",
|
"task_with_context": "{task}\n\nThis is the context you're working with:\n{context}",
|
||||||
"expected_output": "\nThis is the expect criteria for your final answer: {expected_output}\nyou MUST return the actual complete content as the final answer, not a summary.",
|
"expected_output": "\nThis is the expect criteria for your final answer: {expected_output}\nyou MUST return the actual complete content as the final answer, not a summary.",
|
||||||
"human_feedback": "You got human feedback on your work, re-evaluate it and give a new Final Answer when ready.\n {human_feedback}",
|
"human_feedback": "You got human feedback on your work, re-evaluate it and give a new Final Answer when ready.\n {human_feedback}",
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
interactions:
|
||||||
|
- request:
|
||||||
|
body: '{"messages": [{"role": "system", "content": "You are Futel Official Infopoint.
|
||||||
|
Futel Football Club info\nYour personal goal is: Answer questions about Futel\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: Test task\n\nThis is the expect criteria for your
|
||||||
|
final answer: Your best answer to your coworker asking you this, accounting
|
||||||
|
for the context shared.\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", "stop": ["\nObservation:"], "stream": false}'
|
||||||
|
headers:
|
||||||
|
accept:
|
||||||
|
- application/json
|
||||||
|
accept-encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
connection:
|
||||||
|
- keep-alive
|
||||||
|
content-length:
|
||||||
|
- '939'
|
||||||
|
content-type:
|
||||||
|
- application/json
|
||||||
|
cookie:
|
||||||
|
- __cf_bm=cwWdOaPJjFMNJaLtJfa8Kjqavswg5bzVRFzBX4gneGw-1736458417-1.0.1.1-bvf2HshgcMtgn7GdxqwySFDAIacGccDFfEXniBFTTDmbGMCiIIwf6t2DiwWnBldmUHixwc5kDO9gYs08g.feBA;
|
||||||
|
_cfuvid=WMw7PSqkYqQOieguBRs0uNkwNU92A.ZKbgDbCAcV3EQ-1736458417825-0.0.1.1-604800000
|
||||||
|
host:
|
||||||
|
- api.openai.com
|
||||||
|
user-agent:
|
||||||
|
- OpenAI/Python 1.52.1
|
||||||
|
x-stainless-arch:
|
||||||
|
- arm64
|
||||||
|
x-stainless-async:
|
||||||
|
- 'false'
|
||||||
|
x-stainless-lang:
|
||||||
|
- python
|
||||||
|
x-stainless-os:
|
||||||
|
- MacOS
|
||||||
|
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-AnuRlxiTxduAVoXHHY58Fvfbll5IS\",\n \"object\":
|
||||||
|
\"chat.completion\",\n \"created\": 1736458417,\n \"model\": \"gpt-4o-2024-08-06\",\n
|
||||||
|
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
|
||||||
|
\"assistant\",\n \"content\": \"I now can give a great answer \\nFinal
|
||||||
|
Answer: This is a test task, and the context or question from the coworker is
|
||||||
|
not specified. Therefore, my best effort would be to affirm my readiness to
|
||||||
|
answer accurately and in detail any question about Futel Football Club based
|
||||||
|
on the context described. If provided with specific information or questions,
|
||||||
|
I will ensure to respond comprehensively as required by my job directives.\",\n
|
||||||
|
\ \"refusal\": null\n },\n \"logprobs\": null,\n \"finish_reason\":
|
||||||
|
\"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": 177,\n \"completion_tokens\":
|
||||||
|
82,\n \"total_tokens\": 259,\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_703d4ff298\"\n}\n"
|
||||||
|
headers:
|
||||||
|
CF-Cache-Status:
|
||||||
|
- DYNAMIC
|
||||||
|
CF-RAY:
|
||||||
|
- 8ff78bf7bd6cc002-ATL
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
Content-Encoding:
|
||||||
|
- gzip
|
||||||
|
Content-Type:
|
||||||
|
- application/json
|
||||||
|
Date:
|
||||||
|
- Thu, 09 Jan 2025 21:33:40 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:
|
||||||
|
- '2263'
|
||||||
|
openai-version:
|
||||||
|
- '2020-10-01'
|
||||||
|
strict-transport-security:
|
||||||
|
- max-age=31536000; includeSubDomains; preload
|
||||||
|
x-ratelimit-limit-requests:
|
||||||
|
- '10000'
|
||||||
|
x-ratelimit-limit-tokens:
|
||||||
|
- '30000000'
|
||||||
|
x-ratelimit-remaining-requests:
|
||||||
|
- '9999'
|
||||||
|
x-ratelimit-remaining-tokens:
|
||||||
|
- '29999786'
|
||||||
|
x-ratelimit-reset-requests:
|
||||||
|
- 6ms
|
||||||
|
x-ratelimit-reset-tokens:
|
||||||
|
- 0s
|
||||||
|
x-request-id:
|
||||||
|
- req_7c1a31da73cd103e9f410f908e59187f
|
||||||
|
http_version: HTTP/1.1
|
||||||
|
status_code: 200
|
||||||
|
version: 1
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
interactions:
|
||||||
|
- request:
|
||||||
|
body: '{"messages": [{"role": "system", "content": "You are Futel Official Infopoint.
|
||||||
|
Futel Football Club info\nYour personal goal is: Answer questions about Futel\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: Test task\n\nThis is the expect criteria for your
|
||||||
|
final answer: Your best answer to your coworker asking you this, accounting
|
||||||
|
for the context shared.\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", "stop": ["\nObservation:"], "stream": false}'
|
||||||
|
headers:
|
||||||
|
accept:
|
||||||
|
- application/json
|
||||||
|
accept-encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
connection:
|
||||||
|
- keep-alive
|
||||||
|
content-length:
|
||||||
|
- '939'
|
||||||
|
content-type:
|
||||||
|
- application/json
|
||||||
|
cookie:
|
||||||
|
- __cf_bm=cwWdOaPJjFMNJaLtJfa8Kjqavswg5bzVRFzBX4gneGw-1736458417-1.0.1.1-bvf2HshgcMtgn7GdxqwySFDAIacGccDFfEXniBFTTDmbGMCiIIwf6t2DiwWnBldmUHixwc5kDO9gYs08g.feBA;
|
||||||
|
_cfuvid=WMw7PSqkYqQOieguBRs0uNkwNU92A.ZKbgDbCAcV3EQ-1736458417825-0.0.1.1-604800000
|
||||||
|
host:
|
||||||
|
- api.openai.com
|
||||||
|
user-agent:
|
||||||
|
- OpenAI/Python 1.52.1
|
||||||
|
x-stainless-arch:
|
||||||
|
- arm64
|
||||||
|
x-stainless-async:
|
||||||
|
- 'false'
|
||||||
|
x-stainless-lang:
|
||||||
|
- python
|
||||||
|
x-stainless-os:
|
||||||
|
- MacOS
|
||||||
|
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-AnuRrFJZGKw8cIEshvuW1PKwFZFKs\",\n \"object\":
|
||||||
|
\"chat.completion\",\n \"created\": 1736458423,\n \"model\": \"gpt-4o-2024-08-06\",\n
|
||||||
|
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
|
||||||
|
\"assistant\",\n \"content\": \"I now can give a great answer \\nFinal
|
||||||
|
Answer: Although you mentioned this being a \\\"Test task\\\" and haven't provided
|
||||||
|
a specific question regarding Futel Football Club, your request appears to involve
|
||||||
|
ensuring accuracy and detail in responses. For a proper answer about Futel,
|
||||||
|
I'd be ready to provide details about the club's history, management, players,
|
||||||
|
match schedules, and recent performance statistics. Remember to ask specific
|
||||||
|
questions to receive a targeted response. If this were a real context where
|
||||||
|
information was shared, I would respond precisely to what's been asked regarding
|
||||||
|
Futel Football Club.\",\n \"refusal\": null\n },\n \"logprobs\":
|
||||||
|
null,\n \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\":
|
||||||
|
177,\n \"completion_tokens\": 113,\n \"total_tokens\": 290,\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_703d4ff298\"\n}\n"
|
||||||
|
headers:
|
||||||
|
CF-Cache-Status:
|
||||||
|
- DYNAMIC
|
||||||
|
CF-RAY:
|
||||||
|
- 8ff78c1d0ecdc002-ATL
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
Content-Encoding:
|
||||||
|
- gzip
|
||||||
|
Content-Type:
|
||||||
|
- application/json
|
||||||
|
Date:
|
||||||
|
- Thu, 09 Jan 2025 21:33:47 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:
|
||||||
|
- '3097'
|
||||||
|
openai-version:
|
||||||
|
- '2020-10-01'
|
||||||
|
strict-transport-security:
|
||||||
|
- max-age=31536000; includeSubDomains; preload
|
||||||
|
x-ratelimit-limit-requests:
|
||||||
|
- '10000'
|
||||||
|
x-ratelimit-limit-tokens:
|
||||||
|
- '30000000'
|
||||||
|
x-ratelimit-remaining-requests:
|
||||||
|
- '9999'
|
||||||
|
x-ratelimit-remaining-tokens:
|
||||||
|
- '29999786'
|
||||||
|
x-ratelimit-reset-requests:
|
||||||
|
- 6ms
|
||||||
|
x-ratelimit-reset-tokens:
|
||||||
|
- 0s
|
||||||
|
x-request-id:
|
||||||
|
- req_179e1d56e2b17303e40480baffbc7b08
|
||||||
|
http_version: HTTP/1.1
|
||||||
|
status_code: 200
|
||||||
|
version: 1
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
interactions:
|
||||||
|
- request:
|
||||||
|
body: '{"messages": [{"role": "system", "content": "You are Futel Official Infopoint.
|
||||||
|
Futel Football Club info\nYour personal goal is: Answer questions about Futel\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: Test task\n\nThis is the expect criteria for your
|
||||||
|
final answer: Your best answer to your coworker asking you this, accounting
|
||||||
|
for the context shared.\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", "stop": ["\nObservation:"], "stream": false}'
|
||||||
|
headers:
|
||||||
|
accept:
|
||||||
|
- application/json
|
||||||
|
accept-encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
connection:
|
||||||
|
- keep-alive
|
||||||
|
content-length:
|
||||||
|
- '939'
|
||||||
|
content-type:
|
||||||
|
- application/json
|
||||||
|
cookie:
|
||||||
|
- __cf_bm=cwWdOaPJjFMNJaLtJfa8Kjqavswg5bzVRFzBX4gneGw-1736458417-1.0.1.1-bvf2HshgcMtgn7GdxqwySFDAIacGccDFfEXniBFTTDmbGMCiIIwf6t2DiwWnBldmUHixwc5kDO9gYs08g.feBA;
|
||||||
|
_cfuvid=WMw7PSqkYqQOieguBRs0uNkwNU92A.ZKbgDbCAcV3EQ-1736458417825-0.0.1.1-604800000
|
||||||
|
host:
|
||||||
|
- api.openai.com
|
||||||
|
user-agent:
|
||||||
|
- OpenAI/Python 1.52.1
|
||||||
|
x-stainless-arch:
|
||||||
|
- arm64
|
||||||
|
x-stainless-async:
|
||||||
|
- 'false'
|
||||||
|
x-stainless-lang:
|
||||||
|
- python
|
||||||
|
x-stainless-os:
|
||||||
|
- MacOS
|
||||||
|
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-AnuRqgg7eiHnDi2DOqdk99fiqOboz\",\n \"object\":
|
||||||
|
\"chat.completion\",\n \"created\": 1736458422,\n \"model\": \"gpt-4o-2024-08-06\",\n
|
||||||
|
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
|
||||||
|
\"assistant\",\n \"content\": \"I now can give a great answer \\nFinal
|
||||||
|
Answer: Your best answer to your coworker asking you this, accounting for the
|
||||||
|
context shared. You MUST return the actual complete content as the final answer,
|
||||||
|
not a summary.\",\n \"refusal\": null\n },\n \"logprobs\":
|
||||||
|
null,\n \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\":
|
||||||
|
177,\n \"completion_tokens\": 44,\n \"total_tokens\": 221,\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_703d4ff298\"\n}\n"
|
||||||
|
headers:
|
||||||
|
CF-Cache-Status:
|
||||||
|
- DYNAMIC
|
||||||
|
CF-RAY:
|
||||||
|
- 8ff78c164ad2c002-ATL
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
Content-Encoding:
|
||||||
|
- gzip
|
||||||
|
Content-Type:
|
||||||
|
- application/json
|
||||||
|
Date:
|
||||||
|
- Thu, 09 Jan 2025 21:33:43 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:
|
||||||
|
- '899'
|
||||||
|
openai-version:
|
||||||
|
- '2020-10-01'
|
||||||
|
strict-transport-security:
|
||||||
|
- max-age=31536000; includeSubDomains; preload
|
||||||
|
x-ratelimit-limit-requests:
|
||||||
|
- '10000'
|
||||||
|
x-ratelimit-limit-tokens:
|
||||||
|
- '30000000'
|
||||||
|
x-ratelimit-remaining-requests:
|
||||||
|
- '9999'
|
||||||
|
x-ratelimit-remaining-tokens:
|
||||||
|
- '29999786'
|
||||||
|
x-ratelimit-reset-requests:
|
||||||
|
- 6ms
|
||||||
|
x-ratelimit-reset-tokens:
|
||||||
|
- 0s
|
||||||
|
x-request-id:
|
||||||
|
- req_9f5226208edb90a27987aaf7e0ca03d3
|
||||||
|
http_version: HTTP/1.1
|
||||||
|
status_code: 200
|
||||||
|
version: 1
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
interactions:
|
||||||
|
- request:
|
||||||
|
body: '{"messages": [{"role": "system", "content": "You are Futel Official Infopoint.
|
||||||
|
Futel Football Club info\nYour personal goal is: Answer questions about Futel\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: Test task\n\nThis is the expect criteria for your
|
||||||
|
final answer: Your best answer to your coworker asking you this, accounting
|
||||||
|
for the context shared.\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", "stop": ["\nObservation:"], "stream": false}'
|
||||||
|
headers:
|
||||||
|
accept:
|
||||||
|
- application/json
|
||||||
|
accept-encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
connection:
|
||||||
|
- keep-alive
|
||||||
|
content-length:
|
||||||
|
- '939'
|
||||||
|
content-type:
|
||||||
|
- application/json
|
||||||
|
host:
|
||||||
|
- api.openai.com
|
||||||
|
user-agent:
|
||||||
|
- OpenAI/Python 1.52.1
|
||||||
|
x-stainless-arch:
|
||||||
|
- arm64
|
||||||
|
x-stainless-async:
|
||||||
|
- 'false'
|
||||||
|
x-stainless-lang:
|
||||||
|
- python
|
||||||
|
x-stainless-os:
|
||||||
|
- MacOS
|
||||||
|
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-AnuRjmwH5mrykLxQhFwTqqTiDtuTf\",\n \"object\":
|
||||||
|
\"chat.completion\",\n \"created\": 1736458415,\n \"model\": \"gpt-4o-2024-08-06\",\n
|
||||||
|
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
|
||||||
|
\"assistant\",\n \"content\": \"I now can give a great answer \\nFinal
|
||||||
|
Answer: As this is a test task, please note that Futel Football Club is fictional
|
||||||
|
and any specific details about it would not be available. However, if you have
|
||||||
|
specific questions or need information about a particular aspect of Futel or
|
||||||
|
any general football club inquiry, feel free to ask, and I'll do my best to
|
||||||
|
assist you with your query!\",\n \"refusal\": null\n },\n \"logprobs\":
|
||||||
|
null,\n \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\":
|
||||||
|
177,\n \"completion_tokens\": 79,\n \"total_tokens\": 256,\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_703d4ff298\"\n}\n"
|
||||||
|
headers:
|
||||||
|
CF-Cache-Status:
|
||||||
|
- DYNAMIC
|
||||||
|
CF-RAY:
|
||||||
|
- 8ff78be5eebfc002-ATL
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
Content-Encoding:
|
||||||
|
- gzip
|
||||||
|
Content-Type:
|
||||||
|
- application/json
|
||||||
|
Date:
|
||||||
|
- Thu, 09 Jan 2025 21:33:37 GMT
|
||||||
|
Server:
|
||||||
|
- cloudflare
|
||||||
|
Set-Cookie:
|
||||||
|
- __cf_bm=cwWdOaPJjFMNJaLtJfa8Kjqavswg5bzVRFzBX4gneGw-1736458417-1.0.1.1-bvf2HshgcMtgn7GdxqwySFDAIacGccDFfEXniBFTTDmbGMCiIIwf6t2DiwWnBldmUHixwc5kDO9gYs08g.feBA;
|
||||||
|
path=/; expires=Thu, 09-Jan-25 22:03:37 GMT; domain=.api.openai.com; HttpOnly;
|
||||||
|
Secure; SameSite=None
|
||||||
|
- _cfuvid=WMw7PSqkYqQOieguBRs0uNkwNU92A.ZKbgDbCAcV3EQ-1736458417825-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:
|
||||||
|
- '2730'
|
||||||
|
openai-version:
|
||||||
|
- '2020-10-01'
|
||||||
|
strict-transport-security:
|
||||||
|
- max-age=31536000; includeSubDomains; preload
|
||||||
|
x-ratelimit-limit-requests:
|
||||||
|
- '10000'
|
||||||
|
x-ratelimit-limit-tokens:
|
||||||
|
- '30000000'
|
||||||
|
x-ratelimit-remaining-requests:
|
||||||
|
- '9999'
|
||||||
|
x-ratelimit-remaining-tokens:
|
||||||
|
- '29999786'
|
||||||
|
x-ratelimit-reset-requests:
|
||||||
|
- 6ms
|
||||||
|
x-ratelimit-reset-tokens:
|
||||||
|
- 0s
|
||||||
|
x-request-id:
|
||||||
|
- req_014478ba748f860d10ac250ca0ba824a
|
||||||
|
http_version: HTTP/1.1
|
||||||
|
status_code: 200
|
||||||
|
version: 1
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
interactions:
|
||||||
|
- request:
|
||||||
|
body: '{"messages": [{"role": "system", "content": "You are Futel Official Infopoint.
|
||||||
|
Futel Football Club info\nYour personal goal is: Answer questions about Futel\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: Test task\n\nThis is the expect criteria for your
|
||||||
|
final answer: Your best answer to your coworker asking you this, accounting
|
||||||
|
for the context shared.\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", "stop": ["\nObservation:"], "stream": false}'
|
||||||
|
headers:
|
||||||
|
accept:
|
||||||
|
- application/json
|
||||||
|
accept-encoding:
|
||||||
|
- gzip, deflate
|
||||||
|
connection:
|
||||||
|
- keep-alive
|
||||||
|
content-length:
|
||||||
|
- '939'
|
||||||
|
content-type:
|
||||||
|
- application/json
|
||||||
|
cookie:
|
||||||
|
- __cf_bm=cwWdOaPJjFMNJaLtJfa8Kjqavswg5bzVRFzBX4gneGw-1736458417-1.0.1.1-bvf2HshgcMtgn7GdxqwySFDAIacGccDFfEXniBFTTDmbGMCiIIwf6t2DiwWnBldmUHixwc5kDO9gYs08g.feBA;
|
||||||
|
_cfuvid=WMw7PSqkYqQOieguBRs0uNkwNU92A.ZKbgDbCAcV3EQ-1736458417825-0.0.1.1-604800000
|
||||||
|
host:
|
||||||
|
- api.openai.com
|
||||||
|
user-agent:
|
||||||
|
- OpenAI/Python 1.52.1
|
||||||
|
x-stainless-arch:
|
||||||
|
- arm64
|
||||||
|
x-stainless-async:
|
||||||
|
- 'false'
|
||||||
|
x-stainless-lang:
|
||||||
|
- python
|
||||||
|
x-stainless-os:
|
||||||
|
- MacOS
|
||||||
|
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-AnuRofLgmzWcDya5LILqYwIJYgFoq\",\n \"object\":
|
||||||
|
\"chat.completion\",\n \"created\": 1736458420,\n \"model\": \"gpt-4o-2024-08-06\",\n
|
||||||
|
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
|
||||||
|
\"assistant\",\n \"content\": \"I now can give a great answer \\nFinal
|
||||||
|
Answer: As an official Futel Football Club infopoint, my responsibility is to
|
||||||
|
provide detailed and accurate information about the club. This includes answering
|
||||||
|
questions regarding team statistics, player performances, upcoming fixtures,
|
||||||
|
ticketing and fan zone details, club history, and community initiatives. Our
|
||||||
|
focus is to ensure that fans and stakeholders have access to the latest and
|
||||||
|
most precise information about the club's on and off-pitch activities. If there's
|
||||||
|
anything specific you need to know, just let me know, and I'll be more than
|
||||||
|
happy to assist!\",\n \"refusal\": null\n },\n \"logprobs\":
|
||||||
|
null,\n \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\":
|
||||||
|
177,\n \"completion_tokens\": 115,\n \"total_tokens\": 292,\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_703d4ff298\"\n}\n"
|
||||||
|
headers:
|
||||||
|
CF-Cache-Status:
|
||||||
|
- DYNAMIC
|
||||||
|
CF-RAY:
|
||||||
|
- 8ff78c066f37c002-ATL
|
||||||
|
Connection:
|
||||||
|
- keep-alive
|
||||||
|
Content-Encoding:
|
||||||
|
- gzip
|
||||||
|
Content-Type:
|
||||||
|
- application/json
|
||||||
|
Date:
|
||||||
|
- Thu, 09 Jan 2025 21:33:42 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:
|
||||||
|
- '2459'
|
||||||
|
openai-version:
|
||||||
|
- '2020-10-01'
|
||||||
|
strict-transport-security:
|
||||||
|
- max-age=31536000; includeSubDomains; preload
|
||||||
|
x-ratelimit-limit-requests:
|
||||||
|
- '10000'
|
||||||
|
x-ratelimit-limit-tokens:
|
||||||
|
- '30000000'
|
||||||
|
x-ratelimit-remaining-requests:
|
||||||
|
- '9999'
|
||||||
|
x-ratelimit-remaining-tokens:
|
||||||
|
- '29999786'
|
||||||
|
x-ratelimit-reset-requests:
|
||||||
|
- 6ms
|
||||||
|
x-ratelimit-reset-tokens:
|
||||||
|
- 0s
|
||||||
|
x-request-id:
|
||||||
|
- req_a146dd27f040f39a576750970cca0f52
|
||||||
|
http_version: HTTP/1.1
|
||||||
|
status_code: 200
|
||||||
|
version: 1
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1464,39 +1464,35 @@ def test_dont_set_agents_step_callback_if_already_set():
|
|||||||
|
|
||||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||||
def test_crew_function_calling_llm():
|
def test_crew_function_calling_llm():
|
||||||
from unittest.mock import patch
|
|
||||||
|
|
||||||
|
from crewai import LLM
|
||||||
from crewai.tools import tool
|
from crewai.tools import tool
|
||||||
|
|
||||||
llm = "gpt-4o"
|
llm = LLM(model="gpt-4o-mini")
|
||||||
|
|
||||||
@tool
|
@tool
|
||||||
def learn_about_AI() -> str:
|
def look_up_greeting() -> str:
|
||||||
"""Useful for when you need to learn about AI to write an paragraph about it."""
|
"""Tool used to retrieve a greeting."""
|
||||||
return "AI is a very broad field."
|
return "Howdy!"
|
||||||
|
|
||||||
agent1 = Agent(
|
agent1 = Agent(
|
||||||
role="test role",
|
role="Greeter",
|
||||||
goal="test goal",
|
goal="Say hello.",
|
||||||
backstory="test backstory",
|
backstory="You are a friendly greeter.",
|
||||||
tools=[learn_about_AI],
|
tools=[look_up_greeting],
|
||||||
llm="gpt-4o-mini",
|
llm="gpt-4o-mini",
|
||||||
function_calling_llm=llm,
|
function_calling_llm=llm,
|
||||||
)
|
)
|
||||||
|
|
||||||
essay = Task(
|
essay = Task(
|
||||||
description="Write and then review an small paragraph on AI until it's AMAZING",
|
description="Look up the greeting and say it.",
|
||||||
expected_output="The final paragraph.",
|
expected_output="A greeting.",
|
||||||
agent=agent1,
|
agent=agent1,
|
||||||
)
|
)
|
||||||
tasks = [essay]
|
|
||||||
crew = Crew(agents=[agent1], tasks=tasks)
|
|
||||||
|
|
||||||
with patch.object(
|
crew = Crew(agents=[agent1], tasks=[essay])
|
||||||
instructor, "from_litellm", wraps=instructor.from_litellm
|
result = crew.kickoff()
|
||||||
) as mock_from_litellm:
|
assert result.raw == "Howdy!"
|
||||||
crew.kickoff()
|
|
||||||
mock_from_litellm.assert_called()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
from unittest.mock import MagicMock
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from crewai import Agent, Task
|
from crewai import Agent
|
||||||
from crewai.tools.agent_tools.base_agent_tools import BaseAgentTool
|
from crewai.tools.agent_tools.base_agent_tools import BaseAgentTool
|
||||||
|
|
||||||
|
|
||||||
@@ -22,12 +20,9 @@ class InternalAgentTool(BaseAgentTool):
|
|||||||
("Futel Official Infopoint\n", True), # trailing newline
|
("Futel Official Infopoint\n", True), # trailing newline
|
||||||
('"Futel Official Infopoint"', True), # embedded quotes
|
('"Futel Official Infopoint"', True), # embedded quotes
|
||||||
(" FUTEL\nOFFICIAL INFOPOINT ", True), # multiple whitespace and newline
|
(" FUTEL\nOFFICIAL INFOPOINT ", True), # multiple whitespace and newline
|
||||||
("futel official infopoint", True), # lowercase
|
|
||||||
("FUTEL OFFICIAL INFOPOINT", True), # uppercase
|
|
||||||
("Non Existent Agent", False), # non-existent agent
|
|
||||||
(None, False), # None agent name
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||||
def test_agent_tool_role_matching(role_name, should_match):
|
def test_agent_tool_role_matching(role_name, should_match):
|
||||||
"""Test that agent tools can match roles regardless of case, whitespace, and special characters."""
|
"""Test that agent tools can match roles regardless of case, whitespace, and special characters."""
|
||||||
# Create test agent
|
# Create test agent
|
||||||
|
|||||||
@@ -121,3 +121,113 @@ def test_tool_usage_render():
|
|||||||
"Tool Name: Random Number Generator\nTool Arguments: {'min_value': {'description': 'The minimum value of the range (inclusive)', 'type': 'int'}, 'max_value': {'description': 'The maximum value of the range (inclusive)', 'type': 'int'}}\nTool Description: Generates a random number within a specified range"
|
"Tool Name: Random Number Generator\nTool Arguments: {'min_value': {'description': 'The minimum value of the range (inclusive)', 'type': 'int'}, 'max_value': {'description': 'The maximum value of the range (inclusive)', 'type': 'int'}}\nTool Description: Generates a random number within a specified range"
|
||||||
in rendered
|
in rendered
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_tool_input_booleans_and_none():
|
||||||
|
# Create a ToolUsage instance with mocks
|
||||||
|
tool_usage = ToolUsage(
|
||||||
|
tools_handler=MagicMock(),
|
||||||
|
tools=[],
|
||||||
|
original_tools=[],
|
||||||
|
tools_description="",
|
||||||
|
tools_names="",
|
||||||
|
task=MagicMock(),
|
||||||
|
function_calling_llm=MagicMock(),
|
||||||
|
agent=MagicMock(),
|
||||||
|
action=MagicMock(),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Input with booleans and None
|
||||||
|
tool_input = '{"key1": True, "key2": False, "key3": None}'
|
||||||
|
expected_arguments = {"key1": True, "key2": False, "key3": None}
|
||||||
|
|
||||||
|
arguments = tool_usage._validate_tool_input(tool_input)
|
||||||
|
assert arguments == expected_arguments
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_tool_input_mixed_types():
|
||||||
|
# Create a ToolUsage instance with mocks
|
||||||
|
tool_usage = ToolUsage(
|
||||||
|
tools_handler=MagicMock(),
|
||||||
|
tools=[],
|
||||||
|
original_tools=[],
|
||||||
|
tools_description="",
|
||||||
|
tools_names="",
|
||||||
|
task=MagicMock(),
|
||||||
|
function_calling_llm=MagicMock(),
|
||||||
|
agent=MagicMock(),
|
||||||
|
action=MagicMock(),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Input with mixed types
|
||||||
|
tool_input = '{"number": 123, "text": "Some text", "flag": True}'
|
||||||
|
expected_arguments = {"number": 123, "text": "Some text", "flag": True}
|
||||||
|
|
||||||
|
arguments = tool_usage._validate_tool_input(tool_input)
|
||||||
|
assert arguments == expected_arguments
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_tool_input_single_quotes():
|
||||||
|
# Create a ToolUsage instance with mocks
|
||||||
|
tool_usage = ToolUsage(
|
||||||
|
tools_handler=MagicMock(),
|
||||||
|
tools=[],
|
||||||
|
original_tools=[],
|
||||||
|
tools_description="",
|
||||||
|
tools_names="",
|
||||||
|
task=MagicMock(),
|
||||||
|
function_calling_llm=MagicMock(),
|
||||||
|
agent=MagicMock(),
|
||||||
|
action=MagicMock(),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Input with single quotes instead of double quotes
|
||||||
|
tool_input = "{'key': 'value', 'flag': True}"
|
||||||
|
expected_arguments = {"key": "value", "flag": True}
|
||||||
|
|
||||||
|
arguments = tool_usage._validate_tool_input(tool_input)
|
||||||
|
assert arguments == expected_arguments
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_tool_input_invalid_json_repairable():
|
||||||
|
# Create a ToolUsage instance with mocks
|
||||||
|
tool_usage = ToolUsage(
|
||||||
|
tools_handler=MagicMock(),
|
||||||
|
tools=[],
|
||||||
|
original_tools=[],
|
||||||
|
tools_description="",
|
||||||
|
tools_names="",
|
||||||
|
task=MagicMock(),
|
||||||
|
function_calling_llm=MagicMock(),
|
||||||
|
agent=MagicMock(),
|
||||||
|
action=MagicMock(),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Invalid JSON input that can be repaired
|
||||||
|
tool_input = '{"key": "value", "list": [1, 2, 3,]}'
|
||||||
|
expected_arguments = {"key": "value", "list": [1, 2, 3]}
|
||||||
|
|
||||||
|
arguments = tool_usage._validate_tool_input(tool_input)
|
||||||
|
assert arguments == expected_arguments
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_tool_input_with_special_characters():
|
||||||
|
# Create a ToolUsage instance with mocks
|
||||||
|
tool_usage = ToolUsage(
|
||||||
|
tools_handler=MagicMock(),
|
||||||
|
tools=[],
|
||||||
|
original_tools=[],
|
||||||
|
tools_description="",
|
||||||
|
tools_names="",
|
||||||
|
task=MagicMock(),
|
||||||
|
function_calling_llm=MagicMock(),
|
||||||
|
agent=MagicMock(),
|
||||||
|
action=MagicMock(),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Input with special characters
|
||||||
|
tool_input = '{"message": "Hello, world! \u263A", "valid": True}'
|
||||||
|
expected_arguments = {"message": "Hello, world! ☺", "valid": True}
|
||||||
|
|
||||||
|
arguments = tool_usage._validate_tool_input(tool_input)
|
||||||
|
assert arguments == expected_arguments
|
||||||
|
|||||||
Reference in New Issue
Block a user