Compare commits

..

61 Commits

Author SHA1 Message Date
Lorenze Jay
a9e7bf6727 adding index + 1 so its in order 2024-07-12 15:10:07 -07:00
Lorenze Jay
f39bce18a9 created cli command for listing completed tasks ids 2024-07-12 15:08:53 -07:00
Lorenze Jay
96af6027bd fixing changes 2024-07-12 13:53:40 -07:00
Lorenze Jay
010db7790a easier cli command name 2024-07-12 13:46:30 -07:00
Lorenze Jay
b47d0c48a2 added replay feature to crew docs 2024-07-12 12:09:04 -07:00
Lorenze Jay
b24304a4fc added better tests 2024-07-12 11:47:01 -07:00
Lorenze Jay
0e65091c43 better typing for stored_outputs and separated task_output_handler 2024-07-12 11:06:05 -07:00
Lorenze Jay
8b7040577f ensure hierarchical works 2024-07-12 08:56:47 -07:00
Lorenze Jay
af4579f773 ensure replay is delcared when replaying specific tasks 2024-07-12 08:34:59 -07:00
Lorenze Jay
e1589befb4 cleaner code 2024-07-11 17:22:42 -07:00
Lorenze Jay
a9873ff90d fix logging now all tests should pass 2024-07-11 13:05:05 -07:00
Lorenze Jay
1cf4b47404 removed todo comments and fixed some tests 2024-07-11 12:44:30 -07:00
Lorenze Jay
a55a835d54 added better tests 2024-07-11 12:14:37 -07:00
Lorenze Jay
c7bf609e18 refactoring for cleaner code 2024-07-11 11:14:43 -07:00
Lorenze Jay
3aa5d16a6f added cli command + code cleanup TODO: need better refactoring 2024-07-11 10:06:21 -07:00
Lorenze Jay
28929e1c5f fixed context 2024-07-11 07:38:49 -07:00
Lorenze Jay
ce4e28fc79 Merge branch 'main' of github.com:joaomdmoura/crewAI into temp-feature/replay_from_task 2024-07-11 07:23:43 -07:00
Lorenze Jay
fa530ea2e8 replay working for both seq and hier just need tests 2024-07-10 22:51:40 -07:00
Lorenze Jay
d7b765ab32 Merge branch 'feature/kickoff-consistent-output' of https://github.com/bhancockio/crewAI into temp-feature/replay_from_task 2024-07-10 12:33:32 -07:00
Lorenze Jay
3613bd469a better logic for seq and hier 2024-07-10 12:27:09 -07:00
Brandon Hancock
39d6a9a643 Update validators and tests 2024-07-10 13:51:54 -04:00
Lorenze Jay
7c4b91b852 WIP: core logic of seq and heir for executing tasks added into one 2024-07-10 07:58:32 -07:00
Lorenze Jay
626e30d4d1 WIP: working replay feat fixing inputs, need tests 2024-07-09 14:55:13 -07:00
Brandon Hancock
6f6b02cfc0 Add in validation for async cannot depend on other async tasks. 2024-07-09 17:54:42 -04:00
Brandon Hancock
0b575ae69c Add more tests to fully test CrewOutput and TaskOutput changes 2024-07-09 17:24:36 -04:00
Brandon Hancock
2abc971035 Fix linting and type-checker issues 2024-07-09 16:52:18 -04:00
Brandon Hancock
9fdaffc073 Fix final failing test 2024-07-09 15:49:24 -04:00
Brandon Hancock
7518cb9def The majority of tasks are working now. Need to fix converter class 2024-07-09 15:40:39 -04:00
Brandon Hancock
ecc3d913da Implement major fixes from yesterdays group conversation. Now working on tests. 2024-07-09 10:27:39 -04:00
Lorenze Jay
92fca9bbe9 WIP: replay working with async. need to add tests 2024-07-08 21:59:00 -07:00
Brandon Hancock
fffe4df8c3 WIP 2024-07-08 20:04:27 -04:00
Lorenze Jay
5c04c63127 WIP need to fix encoder 2024-07-08 14:37:19 -07:00
Lorenze Jay
1a44a34c17 WIP: need to fix json encoder 2024-07-08 14:36:41 -07:00
Brandon Hancock
363ce5e9ce Fixing issues brought about by merge 2024-07-08 09:00:36 -04:00
Brandon Hancock
10b84955ad Merge branch 'main' into feature/kickoff-consistent-output 2024-07-08 08:59:38 -04:00
Brandon Hancock
a3bdc09f2d Merge branch 'bugfix/kickoff-for-each-usage-metrics' into feature/kickoff-consistent-output 2024-07-03 11:36:06 -04:00
Brandon Hancock
bae9c70730 Merge branch 'main' into bugfix/kickoff-for-each-usage-metrics 2024-07-03 11:22:42 -04:00
Brandon Hancock
55af7e0f15 WIP. Needing team to review change 2024-07-03 11:09:19 -04:00
Brandon Hancock
e745094d73 Fixing missing function. Working on tests. 2024-07-02 15:31:32 -04:00
Brandon Hancock
053d8a0449 Merge branch 'bugfix/kickoff-for-each-usage-metrics' into feature/kickoff-consistent-output 2024-07-01 18:27:05 -04:00
Brandon Hancock
0bfa549477 use BaseAgent instead of Agent where applicable 2024-07-01 17:22:46 -04:00
Brandon Hancock
5334e9e585 Fix linting errors 2024-07-01 17:09:50 -04:00
Brandon Hancock
68de393534 Fix renaming issue 2024-07-01 16:13:21 -04:00
Brandon Hancock
f36f73e035 Moving copy functionality from Agent to BaseAgent 2024-07-01 16:06:02 -04:00
Brandon Hancock
1f9166f61b Final cleanup. Ready for review. 2024-07-01 15:34:06 -04:00
Brandon Hancock
5a5276eb5d Add new tests 2024-07-01 15:29:08 -04:00
Brandon Hancock
60c8f86345 Clean up code for review 2024-07-01 14:56:42 -04:00
Brandon Hancock
6a47eb4f9e Merge branch 'main' into bugfix/kickoff-for-each-usage-metrics 2024-07-01 14:09:32 -04:00
Brandon Hancock
2efe16eac9 Merge in main to bugfix/kickoff-for-each-usage-metrics 2024-07-01 14:00:13 -04:00
Brandon Hancock
1d2827e9a5 Update parent crew who is managing for_each loop 2024-07-01 12:16:59 -04:00
Brandon Hancock
5091712a2d WIP. It looks like usage metrics has always been broken for async 2024-07-01 11:28:50 -04:00
Brandon Hancock
764234c426 more wip. 2024-06-26 20:18:23 -07:00
Brandon Hancock
be0a4c2fe5 Cleaned up logs now that I've isolated the issue to the LLM 2024-06-25 16:22:56 -07:00
Brandon Hancock
cc1c97e87d WIP. Figuring out disconnect issue. 2024-06-25 15:23:32 -07:00
Brandon Hancock
5775ed3fcb working on tests. WIP 2024-06-23 09:42:33 -04:00
Brandon Hancock
5f820cedcc Encountering issues with callback. Need to test on main. WIP 2024-06-21 16:38:09 -04:00
Brandon Hancock
f86e4a1990 Merge branch 'main' into feature/kickoff-consistent-output 2024-06-21 16:15:16 -04:00
Brandon Hancock
ee4a996de3 Major rehaul of TaskOutput and CrewOutput. Updated all tests to work with new change. Need to add in a few final tricky async tests and add a few more to verify output types on TaskOutput and CrewOutput. 2024-06-21 16:13:59 -04:00
Brandon Hancock
5c504f4087 outline tests I need to create going forward 2024-06-20 15:39:59 -04:00
Brandon Hancock
26489ced1a Consistently storing async and sync output for context 2024-06-20 13:47:37 -04:00
Brandon Hancock
ea5a784877 Cleaned up task execution to now have separate paths for async and sync execution. Updating all kickoff functions to return CrewOutput. WIP. Waiting for Joao feedback on async task execution with task_output 2024-06-20 12:11:27 -04:00
36 changed files with 6255 additions and 808 deletions

3
.gitignore vendored
View File

@@ -14,4 +14,5 @@ test.py
rc-tests/*
*.pkl
temp/*
.vscode/*
.vscode/*
crew_tasks_output.json

View File

@@ -155,4 +155,23 @@ for async_result in async_results:
print(async_result)
```
### Replaying from specific task:
You can now replay from a specific task using our cli command replay.
The replay_from_tasks feature in CrewAI allows you to replay from a specific task using the command-line interface (CLI). By running the command `crewai replay -t <task_id>`, you can specify the task name for the replay process.
Kickoffs will now create a `crew_tasks_ouput.json` file with the output of the tasks which you use to retrieve the task id to replay.
### Replaying from specific task Using the CLI
To use the replay feature, follow these steps:
1. Open your terminal or command prompt.
2. Navigate to the directory where your CrewAI project is located.
3. Run the following command:
```shell
crewai replay -t <task_id>
```
These methods provide flexibility in how you manage and execute tasks within your crew, allowing for both synchronous and asynchronous workflows tailored to your needs

View File

@@ -127,7 +127,7 @@ llm = HuggingFaceHub(
```
## OpenAI Compatible API Endpoints
Switch between APIs and models seamlessly using environment variables, supporting platforms like FastChat, LM Studio, Groq, and Mistral AI.
Switch between APIs and models seamlessly using environment variables, supporting platforms like FastChat, LM Studio, and Mistral AI.
### Configuration Examples
#### FastChat
@@ -144,13 +144,6 @@ OPENAI_API_BASE="http://localhost:1234/v1"
OPENAI_API_KEY="lm-studio"
```
#### Groq API
```sh
OPENAI_API_KEY=your-groq-api-key
OPENAI_MODEL_NAME='llama3-8b-8192'
OPENAI_API_BASE=https://api.groq.com/openai/v1
```
#### Mistral API
```sh
OPENAI_API_KEY=your-mistral-api-key
@@ -218,4 +211,4 @@ azure_agent = Agent(
```
## Conclusion
Integrating CrewAI with different LLMs expands the framework's versatility, allowing for customized, efficient AI solutions across various domains and platforms.
Integrating CrewAI with different LLMs expands the framework's versatility, allowing for customized, efficient AI solutions across various domains and platforms.

23
poetry.lock generated
View File

@@ -2282,17 +2282,6 @@ files = [
{file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"},
]
[[package]]
name = "json-repair"
version = "0.25.2"
description = "A package to repair broken json strings"
optional = false
python-versions = ">=3.7"
files = [
{file = "json_repair-0.25.2-py3-none-any.whl", hash = "sha256:51d67295c3184b6c41a3572689661c6128cef6cfc9fb04db63130709adfc5bf0"},
{file = "json_repair-0.25.2.tar.gz", hash = "sha256:161a56d7e6bbfd4cad3a614087e3e0dbd0e10d402dd20dc7db418432428cb32b"},
]
[[package]]
name = "jsonpatch"
version = "1.33"
@@ -2406,8 +2395,8 @@ langchain-core = ">=0.2.10,<0.3.0"
langchain-text-splitters = ">=0.2.0,<0.3.0"
langsmith = ">=0.1.17,<0.2.0"
numpy = [
{version = ">=1,<2", markers = "python_version < \"3.12\""},
{version = ">=1.26.0,<2.0.0", markers = "python_version >= \"3.12\""},
{version = ">=1,<2", markers = "python_version < \"3.12\""},
]
pydantic = ">=1,<3"
PyYAML = ">=5.3"
@@ -2448,8 +2437,8 @@ langchain = ">=0.2.6,<0.3.0"
langchain-core = ">=0.2.10,<0.3.0"
langsmith = ">=0.1.0,<0.2.0"
numpy = [
{version = ">=1,<2", markers = "python_version < \"3.12\""},
{version = ">=1.26.0,<2.0.0", markers = "python_version >= \"3.12\""},
{version = ">=1,<2", markers = "python_version < \"3.12\""},
]
PyYAML = ">=5.3"
requests = ">=2,<3"
@@ -2472,8 +2461,8 @@ jsonpatch = ">=1.33,<2.0"
langsmith = ">=0.1.75,<0.2.0"
packaging = ">=23.2,<25"
pydantic = [
{version = ">=1,<3", markers = "python_full_version < \"3.12.4\""},
{version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""},
{version = ">=1,<3", markers = "python_full_version < \"3.12.4\""},
]
PyYAML = ">=5.3"
tenacity = ">=8.1.0,<8.4.0 || >8.4.0,<9.0.0"
@@ -2522,8 +2511,8 @@ files = [
[package.dependencies]
orjson = ">=3.9.14,<4.0.0"
pydantic = [
{version = ">=1,<3", markers = "python_full_version < \"3.12.4\""},
{version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""},
{version = ">=1,<3", markers = "python_full_version < \"3.12.4\""},
]
requests = ">=2,<3"
@@ -4000,8 +3989,8 @@ files = [
annotated-types = ">=0.4.0"
pydantic-core = "2.20.1"
typing-extensions = [
{version = ">=4.6.1", markers = "python_version < \"3.13\""},
{version = ">=4.12.2", markers = "python_version >= \"3.13\""},
{version = ">=4.6.1", markers = "python_version < \"3.13\""},
]
[package.extras]
@@ -6101,4 +6090,4 @@ tools = ["crewai-tools"]
[metadata]
lock-version = "2.0"
python-versions = ">=3.10,<=3.13"
content-hash = "2cf5a3904e7cbcfebb85e198b6035252d47213a9b0dd3dd51837516e03b38d3e"
content-hash = "0dbf6f6e2e841fb3eec4ff87ea5d6b430f29702118fee91307983c6b2581e59e"

View File

@@ -28,7 +28,6 @@ appdirs = "^1.4.4"
jsonref = "^1.1.0"
agentops = { version = "^0.1.9", optional = true }
embedchain = "^0.1.114"
json-repair = "^0.25.2"
[tool.poetry.extras]
tools = ["crewai-tools"]

View File

@@ -1,14 +1,13 @@
import os
from inspect import signature
from typing import Any, List, Optional, Tuple
from langchain.agents.agent import RunnableAgent
from langchain.agents.tools import BaseTool
from langchain.agents.tools import tool as LangChainTool
from langchain.tools.render import render_text_description
from langchain_core.agents import AgentAction
from langchain_core.callbacks import BaseCallbackHandler
from langchain_openai import ChatOpenAI
from pydantic import Field, InstanceOf, PrivateAttr, model_validator
from pydantic import Field, InstanceOf, model_validator
from crewai.agents import CacheHandler, CrewAgentExecutor, CrewAgentParser
from crewai.agents.agent_builder.base_agent import BaseAgent
@@ -55,11 +54,8 @@ class Agent(BaseAgent):
tools: Tools at agents disposal
step_callback: Callback to be executed after each step of the agent execution.
callbacks: A list of callback functions from the langchain library that are triggered during the agent's execution process
allow_code_execution: Enable code execution for the agent.
max_retry_limit: Maximum number of retries for an agent to execute a task when an error occurs.
"""
_times_executed: int = PrivateAttr(default=0)
max_execution_time: Optional[int] = Field(
default=None,
description="Maximum execution time for an agent to execute a task",
@@ -100,10 +96,6 @@ class Agent(BaseAgent):
allow_code_execution: Optional[bool] = Field(
default=False, description="Enable code execution for the agent."
)
max_retry_limit: int = Field(
default=2,
description="Maximum number of retries for an agent to execute a task when an error occurs.",
)
def __init__(__pydantic_self__, **data):
config = data.pop("config", {})
@@ -175,15 +167,14 @@ class Agent(BaseAgent):
if memory.strip() != "":
task_prompt += self.i18n.slice("memory").format(memory=memory)
tools = tools or self.tools or []
parsed_tools = self._parse_tools(tools)
tools = tools or self.tools
parsed_tools = self._parse_tools(tools or []) # type: ignore # Argument 1 to "_parse_tools" of "Agent" has incompatible type "list[Any] | None"; expected "list[Any]"
self.create_agent_executor(tools=tools)
self.agent_executor.tools = parsed_tools
self.agent_executor.task = task
self.agent_executor.tools_description = self._render_text_description_and_args(
parsed_tools
)
self.agent_executor.tools_description = render_text_description(parsed_tools)
self.agent_executor.tools_names = self.__tools_names(parsed_tools)
if self.crew and self.crew._train:
@@ -191,20 +182,13 @@ class Agent(BaseAgent):
else:
task_prompt = self._use_trained_data(task_prompt=task_prompt)
try:
result = self.agent_executor.invoke(
{
"input": task_prompt,
"tool_names": self.agent_executor.tools_names,
"tools": self.agent_executor.tools_description,
}
)["output"]
except Exception as e:
self._times_executed += 1
if self._times_executed > self.max_retry_limit:
raise e
result = self.execute_task(task, context, tools)
result = self.agent_executor.invoke(
{
"input": task_prompt,
"tool_names": self.agent_executor.tools_names,
"tools": self.agent_executor.tools_description,
}
)["output"]
if self.max_rpm:
self._rpm_controller.stop_rpm_counter()
@@ -236,7 +220,7 @@ class Agent(BaseAgent):
Returns:
An instance of the CrewAgentExecutor class.
"""
tools = tools or self.tools or []
tools = tools or self.tools
agent_args = {
"input": lambda x: x["input"],
@@ -331,7 +315,6 @@ class Agent(BaseAgent):
tools_list = []
for tool in tools:
tools_list.append(tool)
return tools_list
def _training_handler(self, task_prompt: str) -> str:
@@ -358,52 +341,6 @@ class Agent(BaseAgent):
)
return task_prompt
def _render_text_description(self, tools: List[BaseTool]) -> str:
"""Render the tool name and description in plain text.
Output will be in the format of:
.. code-block:: markdown
search: This tool is used for search
calculator: This tool is used for math
"""
description = "\n".join(
[
f"Tool name: {tool.name}\nTool description:\n{tool.description}"
for tool in tools
]
)
return description
def _render_text_description_and_args(self, tools: List[BaseTool]) -> str:
"""Render the tool name, description, and args in plain text.
Output will be in the format of:
.. code-block:: markdown
search: This tool is used for search, args: {"query": {"type": "string"}}
calculator: This tool is used for math, \
args: {"expression": {"type": "string"}}
"""
tool_strings = []
for tool in tools:
args_schema = str(tool.args)
if hasattr(tool, "func") and tool.func:
sig = signature(tool.func)
description = (
f"Tool Name: {tool.name}{sig}\nTool Description: {tool.description}"
)
else:
description = (
f"Tool Name: {tool.name}\nTool Description: {tool.description}"
)
tool_strings.append(f"{description}\nTool Arguments: {args_schema}")
return "\n".join(tool_strings)
@staticmethod
def __tools_names(tools) -> str:
return ", ".join([t.name for t in tools])

View File

@@ -24,7 +24,6 @@ class BaseAgentTools(BaseModel, ABC):
is_list = coworker.startswith("[") and coworker.endswith("]")
if is_list:
coworker = coworker[1:-1].split(",")[0]
return coworker
def delegate_work(
@@ -41,13 +40,11 @@ class BaseAgentTools(BaseModel, ABC):
coworker = self._get_coworker(coworker, **kwargs)
return self._execute(coworker, question, context)
def _execute(
self, agent_name: Union[str, None], task: str, context: Union[str, None]
):
def _execute(self, agent: Union[str, None], task: str, context: Union[str, None]):
"""Execute the command."""
try:
if agent_name is None:
agent_name = ""
if agent is None:
agent = ""
# It is important to remove the quotes from the agent name.
# The reason we have to do this is because less-powerful LLM's
@@ -56,7 +53,7 @@ class BaseAgentTools(BaseModel, ABC):
# {"task": "....", "coworker": "....
# when it should look like this:
# {"task": "....", "coworker": "...."}
agent_name = agent_name.casefold().replace('"', "").replace("\n", "")
agent_name = agent.casefold().replace('"', "").replace("\n", "")
agent = [ # type: ignore # Incompatible types in assignment (expression has type "list[BaseAgent]", variable has type "str | None")
available_agent
@@ -78,9 +75,9 @@ class BaseAgentTools(BaseModel, ABC):
)
agent = agent[0]
task_with_assigned_agent = Task( # type: ignore # Incompatible types in assignment (expression has type "Task", variable has type "str")
task = Task( # type: ignore # Incompatible types in assignment (expression has type "Task", variable has type "str")
description=task,
agent=agent,
expected_output="Your best answer to your coworker asking you this, accounting for the context shared.",
)
return agent.execute_task(task_with_assigned_agent, context)
return agent.execute_task(task, context) # type: ignore # "str" has no attribute "execute_task"

View File

@@ -1,7 +1,7 @@
from abc import ABC, abstractmethod
from typing import Any, Optional
from pydantic import BaseModel, Field
from pydantic import BaseModel, Field, PrivateAttr
class OutputConverter(BaseModel, ABC):
@@ -21,6 +21,7 @@ class OutputConverter(BaseModel, ABC):
max_attempts (int): Maximum number of conversion attempts (default: 3).
"""
_is_gpt: bool = PrivateAttr(default=True)
text: str = Field(description="Text to be converted.")
llm: Any = Field(description="The language model to be used to convert the text.")
model: Any = Field(description="The model to be used to convert the text.")
@@ -40,8 +41,7 @@ class OutputConverter(BaseModel, ABC):
"""Convert text to json."""
pass
@property
@abstractmethod
def is_gpt(self) -> bool:
@abstractmethod # type: ignore # Name "_is_gpt" already defined on line 25
def _is_gpt(self, llm): # type: ignore # Name "_is_gpt" already defined on line 25
"""Return if llm provided is of gpt from openai."""
pass

View File

@@ -1,6 +1,14 @@
import threading
import time
from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
from typing import (
Any,
Dict,
Iterator,
List,
Optional,
Tuple,
Union,
)
from langchain.agents import AgentExecutor
from langchain.agents.agent import ExceptionTool
@@ -11,7 +19,9 @@ from langchain_core.tools import BaseTool
from langchain_core.utils.input import get_color_mapping
from pydantic import InstanceOf
from crewai.agents.agent_builder.base_agent_executor_mixin import CrewAgentExecutorMixin
from crewai.agents.agent_builder.base_agent_executor_mixin import (
CrewAgentExecutorMixin,
)
from crewai.agents.tools_handler import ToolsHandler
from crewai.tools.tool_usage import ToolUsage, ToolUsageErrorException
from crewai.utilities import I18N

View File

@@ -1,7 +1,6 @@
import re
from typing import Any, Union
from json_repair import repair_json
from langchain.agents.output_parsers import ReActSingleInputOutputParser
from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.exceptions import OutputParserException
@@ -49,15 +48,11 @@ class CrewAgentParser(ReActSingleInputOutputParser):
raise OutputParserException(
f"{FINAL_ANSWER_AND_PARSABLE_ACTION_ERROR_MESSAGE}: {text}"
)
action = action_match.group(1)
clean_action = self._clean_action(action)
action_input = action_match.group(2).strip()
tool_input = action_input.strip(" ").strip('"')
safe_tool_input = self._safe_repair_json(tool_input)
return AgentAction(clean_action, safe_tool_input, text)
action = action_match.group(1).strip()
action_input = action_match.group(2)
tool_input = action_input.strip(" ")
tool_input = tool_input.strip('"')
return AgentAction(action, tool_input, text)
elif includes_answer:
return AgentFinish(
@@ -92,30 +87,3 @@ class CrewAgentParser(ReActSingleInputOutputParser):
llm_output=text,
send_to_llm=True,
)
def _clean_action(self, text: str) -> str:
"""Clean action string by removing non-essential formatting characters."""
return re.sub(r"^\s*\*+\s*|\s*\*+\s*$", "", text).strip()
def _safe_repair_json(self, tool_input: str) -> str:
UNABLE_TO_REPAIR_JSON_RESULTS = ['""', "{}"]
# Skip repair if the input starts and ends with square brackets
# Explanation: The JSON parser has issues handling inputs that are enclosed in square brackets ('[]').
# These are typically valid JSON arrays or strings that do not require repair. Attempting to repair such inputs
# might lead to unintended alterations, such as wrapping the entire input in additional layers or modifying
# the structure in a way that changes its meaning. By skipping the repair for inputs that start and end with
# square brackets, we preserve the integrity of these valid JSON structures and avoid unnecessary modifications.
if tool_input.startswith("[") and tool_input.endswith("]"):
return tool_input
# Before repair, handle common LLM issues:
# 1. Replace """ with " to avoid JSON parser errors
tool_input = tool_input.replace('"""', '"')
result = repair_json(tool_input)
if result in UNABLE_TO_REPAIR_JSON_RESULTS:
return tool_input
return str(result)

View File

@@ -1,8 +1,11 @@
import click
import pkg_resources
from .create_crew import create_crew
from .train_crew import train_crew
from .replay_from_task import replay_task_command
from .list_task_outputs import show_task_outputs
@click.group()
@@ -48,5 +51,32 @@ def train(n_iterations: int):
train_crew(n_iterations)
@crewai.command()
@click.option(
"-t",
"--task_id",
type=str,
help="Replay the crew from this task ID, including all subsequent tasks.",
)
def replay(task_id: str) -> None:
"""
Replay the crew execution from a specific task.
Args:
task_id (str): The ID of the task to replay from.
"""
try:
click.echo(f"Replaying the crew from task {task_id}")
replay_task_command(task_id)
except Exception as e:
click.echo(f"An error occurred while replaying: {e}", err=True)
@crewai.command()
def list_completed_tasks_ids():
"""List all task outputs saved from crew_tasks_output.json."""
show_task_outputs()
if __name__ == "__main__":
crewai()

View File

@@ -0,0 +1,34 @@
import subprocess
import click
from pathlib import Path
import json
def show_task_outputs() -> None:
"""
Replay the crew execution from a specific task.
Args:
task_id (str): The ID of the task to replay from.
"""
try:
file_path = Path("crew_tasks_output.json")
if not file_path.exists():
click.echo("crew_tasks_output.json not found.")
return
with open(file_path, "r") as f:
tasks = json.load(f)
for index, task in enumerate(tasks):
click.echo(f"Task {index + 1}: {task['task_id']}")
click.echo(f"Description: {task['output']['description']}")
click.echo("---")
except subprocess.CalledProcessError as e:
click.echo(f"An error occurred while replaying the task: {e}", err=True)
click.echo(e.output, err=True)
except Exception as e:
click.echo(f"An unexpected error occurred: {e}", err=True)

View File

@@ -0,0 +1,24 @@
import subprocess
import click
def replay_task_command(task_id: str) -> None:
"""
Replay the crew execution from a specific task.
Args:
task_id (str): The ID of the task to replay from.
"""
command = ["poetry", "run", "replay_from_task", task_id]
try:
result = subprocess.run(command, capture_output=False, text=True, check=True)
if result.stderr:
click.echo(result.stderr, err=True)
except subprocess.CalledProcessError as e:
click.echo(f"An error occurred while replaying the task: {e}", err=True)
click.echo(e.output, err=True)
except Exception as e:
click.echo(f"An unexpected error occurred: {e}", err=True)

View File

@@ -21,3 +21,13 @@ def train():
except Exception as e:
raise Exception(f"An error occurred while training the crew: {e}")
def replay_from_task():
"""
Replay the crew execution from a specific task.
"""
try:
{{crew_name}}Crew().crew().replay_from_task(task_id=sys.argv[1])
except Exception as e:
raise Exception(f"An error occurred while replaying the crew: {e}")

View File

@@ -11,6 +11,7 @@ crewai = { extras = ["tools"], version = "^0.35.8" }
[tool.poetry.scripts]
{{folder_name}} = "{{folder_name}}.main:run"
train = "{{folder_name}}.main:train"
replay = "{{folder_name}}.main:replay_from_task"
[build-system]
requires = ["poetry-core"]

View File

@@ -6,15 +6,15 @@ from typing import Any, Dict, List, Optional, Tuple, Union
from langchain_core.callbacks import BaseCallbackHandler
from pydantic import (
UUID4,
BaseModel,
ConfigDict,
Field,
InstanceOf,
Json,
PrivateAttr,
field_validator,
model_validator,
UUID4,
BaseModel,
ConfigDict,
Field,
InstanceOf,
Json,
PrivateAttr,
field_validator,
model_validator,
)
from pydantic_core import PydanticCustomError
@@ -31,8 +31,16 @@ from crewai.tasks.task_output import TaskOutput
from crewai.telemetry import Telemetry
from crewai.tools.agent_tools import AgentTools
from crewai.utilities import I18N, FileHandler, Logger, RPMController
from crewai.utilities.constants import TRAINED_AGENTS_DATA_FILE, TRAINING_DATA_FILE
from crewai.utilities.constants import (
CREW_TASKS_OUTPUT_FILE,
TRAINED_AGENTS_DATA_FILE,
TRAINING_DATA_FILE,
)
from crewai.utilities.evaluators.task_evaluator import TaskEvaluator
from crewai.utilities.task_output_handler import (
ExecutionLog,
TaskOutputJsonHandler,
)
from crewai.utilities.formatter import (
aggregate_raw_outputs_from_task_outputs,
aggregate_raw_outputs_from_tasks,
@@ -80,6 +88,10 @@ class Crew(BaseModel):
_entity_memory: Optional[InstanceOf[EntityMemory]] = PrivateAttr()
_train: Optional[bool] = PrivateAttr(default=False)
_train_iteration: Optional[int] = PrivateAttr()
_inputs: Optional[Dict[str, Any]] = PrivateAttr(default=None)
_logging_color: str = PrivateAttr(
default="bold_purple",
)
cache: bool = Field(default=True)
model_config = ConfigDict(arbitrary_types_allowed=True)
@@ -135,6 +147,14 @@ class Crew(BaseModel):
default=False,
description="output_log_file",
)
task_execution_output_json_files: Optional[List[str]] = Field(
default=None,
description="List of file paths for task execution JSON files.",
)
execution_logs: List[ExecutionLog] = Field(
default=[],
description="List of execution logs for tasks",
)
@field_validator("id", mode="before")
@classmethod
@@ -170,6 +190,7 @@ class Crew(BaseModel):
self._rpm_controller = RPMController(max_rpm=self.max_rpm, logger=self._logger)
self._telemetry = Telemetry()
self._telemetry.set_tracer()
self._telemetry.crew_creation(self)
return self
@model_validator(mode="after")
@@ -376,7 +397,12 @@ class Crew(BaseModel):
) -> CrewOutput:
"""Starts the crew to work on its assigned tasks."""
self._execution_span = self._telemetry.crew_execution_span(self, inputs)
TaskOutputJsonHandler(CREW_TASKS_OUTPUT_FILE).initialize_file()
TaskOutputJsonHandler(CREW_TASKS_OUTPUT_FILE).reset()
self._logging_color = "bold_purple"
if inputs is not None:
self._inputs = inputs
self._interpolate_inputs(inputs)
self._set_tasks_callbacks()
@@ -403,7 +429,7 @@ class Crew(BaseModel):
if self.process == Process.sequential:
result = self._run_sequential_process()
elif self.process == Process.hierarchical:
result = self._run_hierarchical_process() # type: ignore # Incompatible types in assignment (expression has type "str | dict[str, Any]", variable has type "str")
result = self._run_hierarchical_process()
else:
raise NotImplementedError(
f"The process '{self.process}' is not implemented yet."
@@ -491,126 +517,51 @@ class Crew(BaseModel):
return results
def _store_execution_log(
self,
task: Task,
output: TaskOutput,
task_index: int,
was_replayed: bool = False,
):
if self._inputs:
inputs = self._inputs
else:
inputs = {}
log = ExecutionLog(
task_id=str(task.id),
expected_output=task.expected_output,
output={
"description": output.description,
"summary": output.summary,
"raw": output.raw,
"pydantic": output.pydantic,
"json_dict": output.json_dict,
"output_format": output.output_format,
"agent": output.agent,
},
task_index=task_index,
inputs=inputs,
was_replayed=was_replayed,
)
if task_index < len(self.execution_logs):
self.execution_logs[task_index] = log
else:
self.execution_logs.append(log)
TaskOutputJsonHandler(CREW_TASKS_OUTPUT_FILE).update(task_index, log)
def _run_sequential_process(self) -> CrewOutput:
"""Executes tasks sequentially and returns the final output."""
task_outputs: List[TaskOutput] = []
futures: List[Tuple[Task, Future[TaskOutput]]] = []
return self._execute_tasks(self.tasks)
for task in self.tasks:
if task.agent and task.agent.allow_delegation:
agents_for_delegation = [
agent for agent in self.agents if agent != task.agent
]
if len(self.agents) > 1 and len(agents_for_delegation) > 0:
delegation_tools = task.agent.get_delegation_tools(
agents_for_delegation
)
# Add tools if they are not already in task.tools
for new_tool in delegation_tools:
# Find the index of the tool with the same name
existing_tool_index = next(
(
index
for index, tool in enumerate(task.tools or [])
if tool.name == new_tool.name
),
None,
)
if not task.tools:
task.tools = []
if existing_tool_index is not None:
# Replace the existing tool
task.tools[existing_tool_index] = new_tool
else:
# Add the new tool
task.tools.append(new_tool)
role = task.agent.role if task.agent is not None else "None"
self._logger.log("debug", f"== Working Agent: {role}", color="bold_purple")
self._logger.log(
"info", f"== Starting Task: {task.description}", color="bold_purple"
)
if self.output_log_file:
self._file_handler.log(
agent=role, task=task.description, status="started"
)
if task.async_execution:
context = (
aggregate_raw_outputs_from_tasks(task.context)
if task.context
else aggregate_raw_outputs_from_task_outputs(task_outputs)
)
future = task.execute_async(
agent=task.agent, context=context, tools=task.tools
)
futures.append((task, future))
else:
# Before executing a synchronous task, wait for all async tasks to complete
if futures:
# Clear task_outputs before processing async tasks
task_outputs = []
for future_task, future in futures:
task_output = future.result()
task_outputs.append(task_output)
self._process_task_result(future_task, task_output)
# Clear the futures list after processing all async results
futures.clear()
context = (
aggregate_raw_outputs_from_tasks(task.context)
if task.context
else aggregate_raw_outputs_from_task_outputs(task_outputs)
)
task_output = task.execute_sync(
agent=task.agent, context=context, tools=task.tools
)
task_outputs = [task_output]
self._process_task_result(task, task_output)
if futures:
# Clear task_outputs before processing async tasks
task_outputs = []
for future_task, future in futures:
task_output = future.result()
task_outputs.append(task_output)
self._process_task_result(future_task, task_output)
# Important: There should only be one task output in the list
# If there are more or 0, something went wrong.
if len(task_outputs) != 1:
raise ValueError(
"Something went wrong. Kickoff should return only one task output."
)
final_task_output = task_outputs[0]
final_string_output = final_task_output.raw
self._finish_execution(final_string_output)
token_usage = self.calculate_usage_metrics()
return CrewOutput(
raw=final_task_output.raw,
pydantic=final_task_output.pydantic,
json_dict=final_task_output.json_dict,
tasks_output=[task.output for task in self.tasks if task.output],
token_usage=token_usage,
)
def _process_task_result(self, task: Task, output: TaskOutput) -> None:
role = task.agent.role if task.agent is not None else "None"
self._logger.log("debug", f"== [{role}] Task output: {output}\n\n")
if self.output_log_file:
self._file_handler.log(agent=role, task=output, status="completed")
# TODO: @joao, Breaking change. Changed return type. Usage metrics is included in crewoutput
def _run_hierarchical_process(self) -> CrewOutput:
"""Creates and assigns a manager agent to make sure the crew completes the tasks."""
self._create_manager_agent()
return self._execute_tasks(self.tasks, self.manager_agent)
def _create_manager_agent(self):
i18n = I18N(prompt_file=self.prompt_file)
if self.manager_agent is not None:
self.manager_agent.allow_delegation = True
@@ -629,74 +580,127 @@ class Crew(BaseModel):
)
self.manager_agent = manager
def _execute_tasks(
self,
tasks: List[Task],
manager: Optional[BaseAgent] = None,
start_index: Optional[int] = 0,
was_replayed: bool = False,
) -> CrewOutput:
"""Executes tasks sequentially and returns the final output.
Args:
tasks (List[Task]): List of tasks to execute
manager (Optional[BaseAgent], optional): Manager agent to use for delegation. Defaults to None.
Returns:
CrewOutput: Final output of the crew
"""
task_outputs: List[TaskOutput] = []
futures: List[Tuple[Task, Future[TaskOutput]]] = []
futures: List[Tuple[Task, Future[TaskOutput], int]] = []
last_sync_output: Optional[TaskOutput] = None
# TODO: IF USER OVERRIDE THE CONTEXT, PASS THAT
for task in self.tasks:
self._logger.log("debug", f"Working Agent: {manager.role}")
self._logger.log("info", f"Starting Task: {task.description}")
for task_index, task in enumerate(tasks):
if start_index is not None and task_index < start_index:
if task.output:
if task.async_execution:
task_outputs.append(task.output)
else:
task_outputs = [task.output]
last_sync_output = task.output
continue
if self.output_log_file:
self._file_handler.log(
agent=manager.role, task=task.description, status="started"
self._prepare_task(task, manager)
if self.process == Process.hierarchical:
agent_to_use = manager
else:
agent_to_use = task.agent
if agent_to_use is None:
raise ValueError(
f"No agent available for task: {task.description}. Ensure that either the task has an assigned agent or a manager agent is provided."
)
self._log_task_start(task, agent_to_use)
if task.async_execution:
context = (
aggregate_raw_outputs_from_tasks(task.context)
if task.context
else aggregate_raw_outputs_from_task_outputs(task_outputs)
context = self._get_context(
task, [last_sync_output] if last_sync_output else []
)
future = task.execute_async(
agent=manager, context=context, tools=manager.tools
agent=agent_to_use,
context=context,
tools=agent_to_use.tools,
)
futures.append((task, future))
futures.append((task, future, task_index))
else:
# Before executing a synchronous task, wait for all async tasks to complete
if futures:
# Clear task_outputs before processing async tasks
task_outputs = []
for future_task, future in futures:
task_output = future.result()
task_outputs.append(task_output)
self._process_task_result(future_task, task_output)
# Clear the futures list after processing all async results
task_outputs.extend(
self._process_async_tasks(futures, was_replayed)
)
futures.clear()
context = (
aggregate_raw_outputs_from_tasks(task.context)
if task.context
else aggregate_raw_outputs_from_task_outputs(task_outputs)
)
context = self._get_context(task, task_outputs)
task_output = task.execute_sync(
agent=manager, context=context, tools=manager.tools
agent=agent_to_use,
context=context,
tools=agent_to_use.tools,
)
task_outputs = [task_output]
self._process_task_result(task, task_output)
self._store_execution_log(task, task_output, task_index, was_replayed)
# Process any remaining async results
if futures:
# Clear task_outputs before processing async tasks
task_outputs = []
for future_task, future in futures:
task_output = future.result()
task_outputs.append(task_output)
self._process_task_result(future_task, task_output)
task_outputs = self._process_async_tasks(futures, was_replayed)
# Important: There should only be one task output in the list
# If there are more or 0, something went wrong.
return self._create_crew_output(task_outputs)
def _prepare_task(self, task: Task, manager: Optional[BaseAgent]):
if self.process == Process.hierarchical:
self._update_manager_tools(task, manager)
elif task.agent and task.agent.allow_delegation:
self._add_delegation_tools(task)
def _add_delegation_tools(self, task: Task):
agents_for_delegation = [agent for agent in self.agents if agent != task.agent]
if len(self.agents) > 1 and agents_for_delegation:
task.tools += task.agent.get_delegation_tools(agents_for_delegation) # type: ignore
def _log_task_start(self, task: Task, agent: Optional[BaseAgent]):
color = self._logging_color
role = agent.role if agent else "None"
self._logger.log("debug", f"== Working Agent: {role}", color=color)
self._logger.log("info", f"== Starting Task: {task.description}", color=color)
if self.output_log_file:
self._file_handler.log(agent=role, task=task.description, status="started")
def _update_manager_tools(self, task: Task, manager: Optional[BaseAgent]):
if task.agent and manager:
manager.tools = task.agent.get_delegation_tools([task.agent])
if manager:
manager.tools = manager.get_delegation_tools(self.agents)
def _get_context(self, task: Task, task_outputs: List[TaskOutput]):
context = (
aggregate_raw_outputs_from_tasks(task.context)
if task.context
else aggregate_raw_outputs_from_task_outputs(task_outputs)
)
return context
def _process_task_result(self, task: Task, output: TaskOutput) -> None:
role = task.agent.role if task.agent is not None else "None"
self._logger.log("debug", f"== [{role}] Task output: {output}\n\n")
if self.output_log_file:
self._file_handler.log(agent=role, task=output, status="completed")
def _create_crew_output(self, task_outputs: List[TaskOutput]) -> CrewOutput:
if len(task_outputs) != 1:
raise ValueError(
"Something went wrong. Kickoff should return only one task output."
)
final_task_output = task_outputs[0]
final_string_output = final_task_output.raw
self._finish_execution(final_string_output)
token_usage = self.calculate_usage_metrics()
return CrewOutput(
@@ -707,6 +711,69 @@ class Crew(BaseModel):
token_usage=token_usage,
)
def _process_async_tasks(
self,
futures: List[Tuple[Task, Future[TaskOutput], int]],
was_replayed: bool = False,
) -> List[TaskOutput]:
task_outputs = []
for future_task, future, task_index in futures:
task_output = future.result()
task_outputs.append(task_output)
self._process_task_result(future_task, task_output)
self._store_execution_log(
future_task, task_output, task_index, was_replayed
)
return task_outputs
def _find_task_index(
self, task_id: str, stored_outputs: List[Any]
) -> Optional[int]:
return next(
(
index
for (index, d) in enumerate(stored_outputs)
if d["task_id"] == str(task_id)
),
None,
)
def replay_from_task(
self, task_id: str, inputs: Optional[Dict[str, Any]] = None
) -> CrewOutput:
stored_outputs = TaskOutputJsonHandler(CREW_TASKS_OUTPUT_FILE).load()
start_index = self._find_task_index(task_id, stored_outputs)
if start_index is None:
raise ValueError(f"Task with id {task_id} not found in the crew's tasks.")
replay_inputs = (
inputs if inputs is not None else stored_outputs[start_index]["inputs"]
)
self._inputs = replay_inputs
if replay_inputs:
self._interpolate_inputs(replay_inputs)
if self.process == Process.hierarchical:
self._create_manager_agent()
for i in range(start_index):
stored_output = stored_outputs[i]["output"]
task_output = TaskOutput(
description=stored_output["description"],
agent=stored_output["agent"],
raw=stored_output["raw"],
pydantic=stored_output["pydantic"],
json_dict=stored_output["json_dict"],
output_format=stored_output["output_format"],
)
self.tasks[i].output = task_output
self._logging_color = "bold_blue"
result = self._execute_tasks(self.tasks, self.manager_agent, start_index, True)
return result
def copy(self):
"""Create a deep copy of the Crew."""

View File

@@ -24,8 +24,6 @@ class CrewOutput(BaseModel):
description="Processed token summary", default={}
)
# TODO: Joao - Adding this safety check breakes when people want to see
# The full output of a CrewOutput.
# @property
# def pydantic(self) -> Optional[BaseModel]:
# # Check if the final task output included a pydantic model

View File

@@ -204,6 +204,7 @@ class Task(BaseModel):
tools: Optional[List[Any]],
) -> TaskOutput:
"""Run the core execution logic of the task."""
self.agent = agent
agent = agent or self.agent
if not agent:
raise Exception(
@@ -244,7 +245,9 @@ class Task(BaseModel):
content = (
json_output
if json_output
else pydantic_output.model_dump_json() if pydantic_output else result
else pydantic_output.model_dump_json()
if pydantic_output
else result
)
self._save_file(content)
@@ -378,7 +381,7 @@ class Task(BaseModel):
def _convert_with_instructions(
self, result: str, model: Type[BaseModel]
) -> Union[dict, BaseModel, str]:
llm = self.agent.function_calling_llm or self.agent.llm
llm = self.agent.function_calling_llm or self.agent.llm # type: ignore # Item "None" of "BaseAgent | None" has no attribute "function_calling_llm"
instructions = self._get_conversion_instructions(model, llm)
converter = self._create_converter(

View File

@@ -11,9 +11,7 @@ class TaskOutput(BaseModel):
description: str = Field(description="Description of the task")
summary: Optional[str] = Field(description="Summary of the task", default=None)
raw: str = Field(
description="Raw output of the task", default=""
) # TODO: @joao: breaking change, by renaming raw_output to raw, but now consistent with CrewOutput
raw: str = Field(description="Raw output of the task", default="")
pydantic: Optional[BaseModel] = Field(
description="Pydantic output of task", default=None
)
@@ -32,8 +30,6 @@ class TaskOutput(BaseModel):
self.summary = f"{excerpt}..."
return self
# TODO: Joao - Adding this safety check breakes when people want to see
# The full output of a TaskOutput or CrewOutput.
# @property
# def pydantic(self) -> Optional[BaseModel]:
# # Check if the final task output included a pydantic model

View File

@@ -80,7 +80,7 @@ class Telemetry:
self.ready = False
self.trace_set = False
def crew_creation(self, crew: Crew, inputs: dict[str, Any] | None):
def crew_creation(self, crew):
"""Records the creation of a crew."""
if self.ready:
try:
@@ -93,12 +93,6 @@ class Telemetry:
)
self._add_attribute(span, "python_version", platform.python_version())
self._add_attribute(span, "crew_id", str(crew.id))
if crew.share_crew:
self._add_attribute(
span, "crew_inputs", json.dumps(inputs) if inputs else None
)
self._add_attribute(span, "crew_process", crew.process)
self._add_attribute(span, "crew_memory", crew.memory)
self._add_attribute(span, "crew_number_of_tasks", len(crew.tasks))
@@ -120,7 +114,7 @@ class Telemetry:
"llm": json.dumps(self._safe_llm_attributes(agent.llm)),
"delegation_enabled?": agent.allow_delegation,
"tools_names": [
tool.name.casefold() for tool in agent.tools or []
tool.name.casefold() for tool in agent.tools
],
}
for agent in crew.agents
@@ -145,7 +139,7 @@ class Telemetry:
else None
),
"tools_names": [
tool.name.casefold() for tool in task.tools or []
tool.name.casefold() for tool in task.tools
],
}
for task in crew.tasks
@@ -167,11 +161,10 @@ class Telemetry:
if self.ready:
try:
tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Task Execution")
created_span = tracer.start_span("Task Created")
self._add_attribute(created_span, "crew_id", str(crew.id))
self._add_attribute(created_span, "task_index", crew.tasks.index(task))
self._add_attribute(created_span, "task_id", str(task.id))
if crew.share_crew:
@@ -185,10 +178,6 @@ class Telemetry:
created_span.set_status(Status(StatusCode.OK))
created_span.end()
span = tracer.start_span("Task Execution")
self._add_attribute(span, "crew_id", str(crew.id))
self._add_attribute(span, "task_index", crew.tasks.index(task))
self._add_attribute(span, "task_id", str(task.id))
if crew.share_crew:
@@ -286,8 +275,6 @@ class Telemetry:
"""
if (self.ready) and (crew.share_crew):
try:
self.crew_creation(crew, inputs)
tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Crew Execution")
self._add_attribute(
@@ -296,9 +283,7 @@ class Telemetry:
pkg_resources.get_distribution("crewai").version,
)
self._add_attribute(span, "crew_id", str(crew.id))
self._add_attribute(
span, "crew_inputs", json.dumps(inputs) if inputs else None
)
self._add_attribute(span, "inputs", json.dumps(inputs))
self._add_attribute(
span,
"crew_agents",

View File

@@ -7,7 +7,7 @@ class AgentTools(BaseAgentTools):
"""Default tools around agent delegation"""
def tools(self):
coworkers = ", ".join([f"{agent.role}" for agent in self.agents])
coworkers = f"[{', '.join([f'{agent.role}' for agent in self.agents])}]"
tools = [
StructuredTool.from_function(
func=self.delegate_work,

View File

@@ -1,2 +1,3 @@
TRAINING_DATA_FILE = "training_data.pkl"
TRAINED_AGENTS_DATA_FILE = "trained_agents_data.pkl"
CREW_TASKS_OUTPUT_FILE = "crew_tasks_output.json"

View File

@@ -2,8 +2,10 @@ import json
from langchain.schema import HumanMessage, SystemMessage
from langchain_openai import ChatOpenAI
from crewai.agents.agent_builder.utilities.base_output_converter import OutputConverter
from pydantic import model_validator
from crewai.agents.agent_builder.utilities.base_output_converter_base import (
OutputConverter,
)
class ConverterError(Exception):
@@ -17,10 +19,15 @@ class ConverterError(Exception):
class Converter(OutputConverter):
"""Class that converts text into either pydantic or json."""
@model_validator(mode="after")
def check_llm_provider(self):
if not self._is_gpt(self.llm):
self._is_gpt = False
def to_pydantic(self, current_attempt=1):
"""Convert text to pydantic."""
try:
if self.is_gpt:
if self._is_gpt:
return self._create_instructor().to_pydantic()
else:
return self._create_chain().invoke({})
@@ -34,7 +41,7 @@ class Converter(OutputConverter):
def to_json(self, current_attempt=1):
"""Convert text to json."""
try:
if self.is_gpt:
if self._is_gpt:
return self._create_instructor().to_json()
else:
return json.dumps(self._create_chain().invoke({}).model_dump())
@@ -68,7 +75,5 @@ class Converter(OutputConverter):
)
return new_prompt | self.llm | parser
@property
def is_gpt(self) -> bool:
"""Return if llm provided is of gpt from openai."""
return isinstance(self.llm, ChatOpenAI) and self.llm.openai_api_base is None
def _is_gpt(self, llm) -> bool: # type: ignore # BUG? Name "_is_gpt" defined on line 20 hides name from outer scope
return isinstance(llm, ChatOpenAI) and llm.openai_api_base is None

View File

@@ -0,0 +1,31 @@
from datetime import datetime
import json
from uuid import UUID
from pydantic import BaseModel
class CrewJSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, BaseModel):
return self._handle_pydantic_model(obj)
elif isinstance(obj, UUID):
return str(obj)
elif isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
def _handle_pydantic_model(self, obj):
try:
data = obj.model_dump()
# Remove circular references
for key, value in data.items():
if isinstance(value, BaseModel):
data[key] = str(
value
) # Convert nested models to string representation
return data
except RecursionError:
return str(
obj
) # Fall back to string representation if circular reference is detected

View File

@@ -1,5 +1,7 @@
import os
import pickle
from datetime import datetime

View File

@@ -8,6 +8,8 @@ class Printer:
self._print_bold_green(content)
elif color == "bold_purple":
self._print_bold_purple(content)
elif color == "bold_blue":
self._print_bold_blue(content)
else:
print(content)
@@ -22,3 +24,6 @@ class Printer:
def _print_red(self, content):
print("\033[91m {}\033[00m".format(content))
def _print_bold_blue(self, content):
print("\033[1m\033[94m {}\033[00m".format(content))

View File

@@ -0,0 +1,69 @@
import json
import os
from pydantic import BaseModel, Field
from datetime import datetime
from typing import Dict, Any, Optional, List
from crewai.utilities.crew_json_encoder import CrewJSONEncoder
class ExecutionLog(BaseModel):
task_id: str
expected_output: Optional[str] = None
output: Dict[str, Any]
timestamp: datetime = Field(default_factory=datetime.now)
task_index: int
inputs: Dict[str, Any] = Field(default_factory=dict)
was_replayed: bool = False
def __getitem__(self, key: str) -> Any:
return getattr(self, key)
class TaskOutputJsonHandler:
def __init__(self, file_name: str) -> None:
self.file_path = os.path.join(os.getcwd(), file_name)
def initialize_file(self) -> None:
if not os.path.exists(self.file_path) or os.path.getsize(self.file_path) == 0:
with open(self.file_path, "w") as file:
json.dump([], file)
def update(self, task_index: int, log: ExecutionLog):
logs = self.load()
if task_index < len(logs):
logs[task_index] = log
else:
logs.append(log)
self.save(logs)
def save(self, logs: List[ExecutionLog]):
with open(self.file_path, "w") as file:
json.dump(logs, file, indent=2, cls=CrewJSONEncoder)
def reset(self):
"""Reset the JSON file by creating an empty file."""
with open(self.file_path, "w") as f:
json.dump([], f)
def load(self) -> List[ExecutionLog]:
try:
if (
not os.path.exists(self.file_path)
or os.path.getsize(self.file_path) == 0
):
return []
with open(self.file_path, "r") as file:
return json.load(file)
except FileNotFoundError:
print(f"File {self.file_path} not found. Returning empty list.")
return []
except json.JSONDecodeError:
print(
f"Error decoding JSON from file {self.file_path}. Returning empty list."
)
return []
except Exception as e:
print(f"An unexpected error occurred: {e}")
return []

View File

@@ -963,54 +963,3 @@ def test_agent_use_trained_data(crew_training_handler):
crew_training_handler.assert_has_calls(
[mock.call(), mock.call("trained_agents_data.pkl"), mock.call().load()]
)
def test_agent_max_retry_limit():
agent = Agent(
role="test role",
goal="test goal",
backstory="test backstory",
max_retry_limit=1,
)
task = Task(
agent=agent,
description="Say the word: Hi",
expected_output="The word: Hi",
human_input=True,
)
error_message = "Error happening while sending prompt to model."
with patch.object(
CrewAgentExecutor, "invoke", wraps=agent.agent_executor.invoke
) as invoke_mock:
invoke_mock.side_effect = Exception(error_message)
assert agent._times_executed == 0
assert agent.max_retry_limit == 1
with pytest.raises(Exception) as e:
agent.execute_task(
task=task,
)
assert e.value.args[0] == error_message
assert agent._times_executed == 2
invoke_mock.assert_has_calls(
[
mock.call(
{
"input": "Say the word: Hi\n\nThis is the expect criteria for your final answer: The word: Hi \n you MUST return the actual complete content as the final answer, not a summary.",
"tool_names": "",
"tools": "",
}
),
mock.call(
{
"input": "Say the word: Hi\n\nThis is the expect criteria for your final answer: The word: Hi \n you MUST return the actual complete content as the final answer, not a summary.",
"tool_names": "",
"tools": "",
}
),
]
)

View File

@@ -1,378 +0,0 @@
import pytest
from crewai.agents.parser import CrewAgentParser
from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.exceptions import OutputParserException
@pytest.fixture
def parser():
p = CrewAgentParser()
p.agent = MockAgent()
return p
def test_valid_action_parsing_special_characters(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: what's the temperature in SF?"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what's the temperature in SF?"
def test_valid_action_parsing_with_json_tool_input(parser):
text = """
Thought: Let's find the information
Action: query
Action Input: ** {"task": "What are some common challenges or barriers that you have observed or experienced when implementing AI-powered solutions in healthcare settings?", "context": "As we've discussed recent advancements in AI applications in healthcare, it's crucial to acknowledge the potential hurdles. Some possible obstacles include...", "coworker": "Senior Researcher"}
"""
result = parser.parse(text)
assert isinstance(result, AgentAction)
expected_tool_input = '{"task": "What are some common challenges or barriers that you have observed or experienced when implementing AI-powered solutions in healthcare settings?", "context": "As we\'ve discussed recent advancements in AI applications in healthcare, it\'s crucial to acknowledge the potential hurdles. Some possible obstacles include...", "coworker": "Senior Researcher"}'
assert result.tool == "query"
assert result.tool_input == expected_tool_input
def test_valid_action_parsing_with_quotes(parser):
text = 'Thought: Let\'s find the temperature\nAction: search\nAction Input: "temperature in SF"'
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "temperature in SF"
def test_valid_action_parsing_with_curly_braces(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: {temperature in SF}"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "{temperature in SF}"
def test_valid_action_parsing_with_angle_brackets(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: <temperature in SF>"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "<temperature in SF>"
def test_valid_action_parsing_with_parentheses(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: (temperature in SF)"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "(temperature in SF)"
def test_valid_action_parsing_with_mixed_brackets(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: [temperature in {SF}]"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "[temperature in {SF}]"
def test_valid_action_parsing_with_nested_quotes(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: \"what's the temperature in 'SF'?\""
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what's the temperature in 'SF'?"
def test_valid_action_parsing_with_incomplete_json(parser):
text = 'Thought: Let\'s find the temperature\nAction: search\nAction Input: {"query": "temperature in SF"'
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == '{"query": "temperature in SF"}'
def test_valid_action_parsing_with_special_characters(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: what is the temperature in SF? @$%^&*"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what is the temperature in SF? @$%^&*"
def test_valid_action_parsing_with_combination(parser):
text = 'Thought: Let\'s find the temperature\nAction: search\nAction Input: "[what is the temperature in SF?]"'
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "[what is the temperature in SF?]"
def test_valid_action_parsing_with_mixed_quotes(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: \"what's the temperature in SF?\""
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what's the temperature in SF?"
def test_valid_action_parsing_with_newlines(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: what is\nthe temperature in SF?"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what is\nthe temperature in SF?"
def test_valid_action_parsing_with_escaped_characters(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: what is the temperature in SF? \\n"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what is the temperature in SF? \\n"
def test_valid_action_parsing_with_json_string(parser):
text = 'Thought: Let\'s find the temperature\nAction: search\nAction Input: {"query": "temperature in SF"}'
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == '{"query": "temperature in SF"}'
def test_valid_action_parsing_with_unbalanced_quotes(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: \"what is the temperature in SF?"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what is the temperature in SF?"
def test_clean_action_no_formatting(parser):
action = "Ask question to senior researcher"
cleaned_action = parser._clean_action(action)
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_leading_asterisks(parser):
action = "** Ask question to senior researcher"
cleaned_action = parser._clean_action(action)
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_trailing_asterisks(parser):
action = "Ask question to senior researcher **"
cleaned_action = parser._clean_action(action)
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_leading_and_trailing_asterisks(parser):
action = "** Ask question to senior researcher **"
cleaned_action = parser._clean_action(action)
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_multiple_leading_asterisks(parser):
action = "**** Ask question to senior researcher"
cleaned_action = parser._clean_action(action)
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_multiple_trailing_asterisks(parser):
action = "Ask question to senior researcher ****"
cleaned_action = parser._clean_action(action)
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_spaces_and_asterisks(parser):
action = " ** Ask question to senior researcher ** "
cleaned_action = parser._clean_action(action)
print(f"Original action: '{action}'")
print(f"Cleaned action: '{cleaned_action}'")
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_only_asterisks(parser):
action = "****"
cleaned_action = parser._clean_action(action)
assert cleaned_action == ""
def test_clean_action_with_empty_string(parser):
action = ""
cleaned_action = parser._clean_action(action)
assert cleaned_action == ""
def test_valid_final_answer_parsing(parser):
text = (
"Thought: I found the information\nFinal Answer: The temperature is 100 degrees"
)
result = parser.parse(text)
assert isinstance(result, AgentFinish)
assert result.return_values["output"] == "The temperature is 100 degrees"
def test_missing_action_error(parser):
text = "Thought: Let's find the temperature\nAction Input: what is the temperature in SF?"
with pytest.raises(OutputParserException) as exc_info:
parser.parse(text)
assert "Could not parse LLM output" in str(exc_info.value)
def test_missing_action_input_error(parser):
text = "Thought: Let's find the temperature\nAction: search"
with pytest.raises(OutputParserException) as exc_info:
parser.parse(text)
assert "Could not parse LLM output" in str(exc_info.value)
def test_action_and_final_answer_error(parser):
text = "Thought: I found the information\nAction: search\nAction Input: what is the temperature in SF?\nFinal Answer: The temperature is 100 degrees"
with pytest.raises(OutputParserException) as exc_info:
parser.parse(text)
assert "both perform Action and give a Final Answer" in str(exc_info.value)
def test_safe_repair_json(parser):
invalid_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": Senior Researcher'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_unrepairable(parser):
invalid_json = "{invalid_json"
result = parser._safe_repair_json(invalid_json)
print("result:", invalid_json)
assert result == invalid_json # Should return the original if unrepairable
def test_safe_repair_json_missing_quotes(parser):
invalid_json = (
'{task: "Research XAI", context: "Explainable AI", coworker: Senior Researcher}'
)
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_unclosed_brackets(parser):
invalid_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_extra_commas(parser):
invalid_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher",}'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_trailing_commas(parser):
invalid_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher",}'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_single_quotes(parser):
invalid_json = "{'task': 'Research XAI', 'context': 'Explainable AI', 'coworker': 'Senior Researcher'}"
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_mixed_quotes(parser):
invalid_json = "{'task': \"Research XAI\", 'context': \"Explainable AI\", 'coworker': 'Senior Researcher'}"
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_unescaped_characters(parser):
invalid_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher\n"}'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
print("result:", result)
assert result == expected_repaired_json
def test_safe_repair_json_missing_colon(parser):
invalid_json = '{"task" "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_missing_comma(parser):
invalid_json = '{"task": "Research XAI" "context": "Explainable AI", "coworker": "Senior Researcher"}'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_unexpected_trailing_characters(parser):
invalid_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"} random text'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_special_characters_key(parser):
invalid_json = '{"task!@#": "Research XAI", "context$%^": "Explainable AI", "coworker&*()": "Senior Researcher"}'
expected_repaired_json = '{"task!@#": "Research XAI", "context$%^": "Explainable AI", "coworker&*()": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_parsing_with_whitespace(parser):
text = " Thought: Let's find the temperature \n Action: search \n Action Input: what is the temperature in SF? "
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what is the temperature in SF?"
def test_parsing_with_special_characters(parser):
text = 'Thought: Let\'s find the temperature\nAction: search\nAction Input: "what is the temperature in SF?"'
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what is the temperature in SF?"
def test_integration_valid_and_invalid(parser):
text = """
Thought: Let's find the temperature
Action: search
Action Input: what is the temperature in SF?
Thought: I found the information
Final Answer: The temperature is 100 degrees
Thought: Missing action
Action Input: invalid
Thought: Missing action input
Action: invalid
"""
parts = text.strip().split("\n\n")
results = []
for part in parts:
try:
result = parser.parse(part.strip())
results.append(result)
except OutputParserException as e:
results.append(e)
assert isinstance(results[0], AgentAction)
assert isinstance(results[1], AgentFinish)
assert isinstance(results[2], OutputParserException)
assert isinstance(results[3], OutputParserException)
class MockAgent:
def increment_formatting_errors(self):
pass
# TODO: ADD TEST TO MAKE SURE ** REMOVAL DOESN'T MESS UP ANYTHING

View File

@@ -0,0 +1,697 @@
interactions:
- request:
body: '{"messages": [{"content": "You are Researcher. You''re an expert researcher,
specialized in technology, software engineering, AI and startups. You work as
a freelancer and is now working on doing research and analysis for a new customer.\nYour
personal goal is: Make the best research and analysis on content about AI and
AI agentsTo 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: my best complete
final answer to the task.\nYour 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!\nCurrent Task: Generate a list of 5 interesting ideas
to explore for an article, where each bulletpoint is under 15 words.\n\nThis
is the expect criteria for your final answer: Bullet point list of 5 important
events. No additional commentary. \n you 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:\n", "role": "user"}], "model": "gpt-4o", "n": 1, "stop": ["\nObservation"],
"stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
connection:
- keep-alive
content-length:
- '1237'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.3
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.3
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.5
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Ethical"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
implications"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
of"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
decision"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-making"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
healthcare"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":".\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
agents"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
revolution"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"izing"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
customer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
service"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
e"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-commerce"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":".\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Advances"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-driven"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
predictive"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
maintenance"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
for"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
industries"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":".\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
The"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
role"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
of"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
autonomous"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
vehicle"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
safety"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":".\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
personalized"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
education"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Adaptive"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
learning"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
technologies"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a097b99ad909e50-SJC
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Tue, 09 Jul 2024 15:52:44 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=3B5vxI0ieroGmK5h7cD7a8bCSrrPh4hLjrbw87J9XRE-1720540364-1.0.1.1-BXhaEwefXZ7Ez0Fg7.8O4AAnOoPc5b7O.4CdzhLnbo9WIF30RlsTzH58YBRxoQipeSCQMxhePm2HaNR6nNfWEQ;
path=/; expires=Tue, 09-Jul-24 16:22:44 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=D7VkuRYil_ytD3F4vcJzvO0gmVHyb3ZlnhCIjCrlyWE-1720540364005-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- user-soijsnuwuk3xvbf91w0jc33c
openai-processing-ms:
- '114'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '5000'
x-ratelimit-limit-tokens:
- '450000'
x-ratelimit-remaining-requests:
- '4999'
x-ratelimit-remaining-tokens:
- '449712'
x-ratelimit-reset-requests:
- 12ms
x-ratelimit-reset-tokens:
- 38ms
x-request-id:
- req_94f0907cc8b2065f1e223070d2be2a85
status:
code: 200
message: OK
- request:
body: '{"messages": [{"content": "You are Researcher. You''re an expert researcher,
specialized in technology, software engineering, AI and startups. You work as
a freelancer and is now working on doing research and analysis for a new customer.\nYour
personal goal is: Make the best research and analysis on content about AI and
AI agentsTo 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: my best complete
final answer to the task.\nYour 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!\nCurrent Task: Generate a list of 5 interesting ideas
to explore for an article, where each bulletpoint is under 15 words.\n\nThis
is the expect criteria for your final answer: Bullet point list of 5 important
events. No additional commentary. \n you 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:\n", "role": "user"}], "model": "gpt-4o", "n": 1, "stop": ["\nObservation"],
"stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
connection:
- keep-alive
content-length:
- '1237'
content-type:
- application/json
cookie:
- __cf_bm=3B5vxI0ieroGmK5h7cD7a8bCSrrPh4hLjrbw87J9XRE-1720540364-1.0.1.1-BXhaEwefXZ7Ez0Fg7.8O4AAnOoPc5b7O.4CdzhLnbo9WIF30RlsTzH58YBRxoQipeSCQMxhePm2HaNR6nNfWEQ;
_cfuvid=D7VkuRYil_ytD3F4vcJzvO0gmVHyb3ZlnhCIjCrlyWE-1720540364005-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.3
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.3
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.5
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Evolution"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
of"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Agents"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Customer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Service"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Healthcare"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Transform"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"ing"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Diagnostics"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
and"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Treatment"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Ethical"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Imp"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"lications"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
of"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Autonomous"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Systems"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"Driven"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Start"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"ups"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Dis"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"ruption"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
and"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Innovation"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
and"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Cyber"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"security"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Def"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"ending"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Against"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Modern"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Threat"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"s"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a097ba2bc449e50-SJC
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Tue, 09 Jul 2024 15:52:45 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- user-soijsnuwuk3xvbf91w0jc33c
openai-processing-ms:
- '117'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '5000'
x-ratelimit-limit-tokens:
- '450000'
x-ratelimit-remaining-requests:
- '4999'
x-ratelimit-remaining-tokens:
- '449712'
x-ratelimit-reset-requests:
- 12ms
x-ratelimit-reset-tokens:
- 38ms
x-request-id:
- req_a28d912698f7b75be87900d3a64bc91f
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,161 @@
interactions:
- request:
body: '{"messages": [{"content": "You are test_agent. Test Description\nYour personal
goal is: Test GoalTo 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:
my best complete final answer to the task.\nYour 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!\nCurrent Task: Test Task\n\nThis is the
expect criteria for your final answer: Say Hi to John \n you MUST return the
actual complete content as the final answer, not a summary.\n\nThis is the context
you''re working with:\ncontext raw output\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:\n", "role": "user"}], "model": "gpt-4o", "n": 1, "stop":
["\nObservation"], "stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
connection:
- keep-alive
content-length:
- '918'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.3
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.3
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.5
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
Hi"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
John"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a2327f1190467c1-SJC
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Fri, 12 Jul 2024 18:39:27 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=df.hIcEr2QTS045wWa7HSF0ATx6AeLAoPPW0FoIx7W4-1720809567-1.0.1.1-1Y2nQ4DHdc5HUHFO08LdQOoWZykmQ0xe67vzmv2dS4OnnKEHYd9GMzcq.vWODTXoI.BoSxQiRrylKYuuO2t8Tw;
path=/; expires=Fri, 12-Jul-24 19:09:27 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=Zmb0XRHa49q2R664FqlS3F.aojtATJKKGnkUiQoH92I-1720809567257-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '83'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '22000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '21999792'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_4fd8c7c8d47e20be017fb8de1ccb07c9
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,472 @@
interactions:
- request:
body: '{"messages": [{"content": "You are test_agent. Test Description\nYour personal
goal is: Test GoalTo 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:
my best complete final answer to the task.\nYour 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!\nCurrent Task: Context Task\n\nThis is
the expect criteria for your final answer: Say John \n you 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:\n", "role": "user"}], "model": "gpt-4o", "n":
1, "stop": ["\nObservation"], "stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
connection:
- keep-alive
content-length:
- '851'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.3
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.3
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.5
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
Say"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
John"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a23033dc9abce48-SJC
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Fri, 12 Jul 2024 18:14:23 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=iykqFZ5ecR102MDyK48cHc9Ge3aXJBNKkesB4w9tCz4-1720808063-1.0.1.1-Eg_rjCINHV9hw7HzDFtJgxfwBfr9SahyJnbyo.JfBNFYax9M.ZcSVwmQwySE6AzVg.5AaLC05iljPfXmN26FrA;
path=/; expires=Fri, 12-Jul-24 18:44:23 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=KWM5AhkXkvM2JvJ6J7QHiC9iposfEkI9eZRl8w6aVTY-1720808063923-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '84'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '22000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '21999807'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_e6b4b9610f2f254a228ad44dda349115
status:
code: 200
message: OK
- request:
body: '{"messages": [{"content": "You are test_agent. Test Description\nYour personal
goal is: Test GoalTo 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:
my best complete final answer to the task.\nYour 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!\nCurrent Task: Test Task\n\nThis is the
expect criteria for your final answer: Say Hi to John \n you MUST return the
actual complete content as the final answer, not a summary.\n\nThis is the context
you''re working with:\nSay John\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:\n",
"role": "user"}], "model": "gpt-4o", "n": 1, "stop": ["\nObservation"], "stream":
true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
connection:
- keep-alive
content-length:
- '908'
content-type:
- application/json
cookie:
- __cf_bm=iykqFZ5ecR102MDyK48cHc9Ge3aXJBNKkesB4w9tCz4-1720808063-1.0.1.1-Eg_rjCINHV9hw7HzDFtJgxfwBfr9SahyJnbyo.JfBNFYax9M.ZcSVwmQwySE6AzVg.5AaLC05iljPfXmN26FrA;
_cfuvid=KWM5AhkXkvM2JvJ6J7QHiC9iposfEkI9eZRl8w6aVTY-1720808063923-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.3
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.3
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.5
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
Hi"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
John"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a230340ec4cce48-SJC
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Fri, 12 Jul 2024 18:14:24 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '69'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '22000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '21999795'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_f3233314439a85e7a197be3d067c6d1c
status:
code: 200
message: OK
- request:
body: '{"messages": [{"content": "You are test_agent. Test Description\nYour personal
goal is: Test GoalTo 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:
my best complete final answer to the task.\nYour 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!\nCurrent Task: Test Task\n\nThis is the
expect criteria for your final answer: Say Hi to John \n you MUST return the
actual complete content as the final answer, not a summary.\n\nThis is the context
you''re working with:\ncontext raw output\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:\n", "role": "user"}], "model": "gpt-4o", "n": 1, "stop":
["\nObservation"], "stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
connection:
- keep-alive
content-length:
- '918'
content-type:
- application/json
cookie:
- __cf_bm=iykqFZ5ecR102MDyK48cHc9Ge3aXJBNKkesB4w9tCz4-1720808063-1.0.1.1-Eg_rjCINHV9hw7HzDFtJgxfwBfr9SahyJnbyo.JfBNFYax9M.ZcSVwmQwySE6AzVg.5AaLC05iljPfXmN26FrA;
_cfuvid=KWM5AhkXkvM2JvJ6J7QHiC9iposfEkI9eZRl8w6aVTY-1720808063923-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.3
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.3
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.5
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
Hi"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
John"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a2303443f0cce48-SJC
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Fri, 12 Jul 2024 18:14:24 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '86'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '22000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '21999791'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_649687e24793d5b5782ecf58bc76386a
status:
code: 200
message: OK
version: 1

View File

@@ -1,5 +1,6 @@
"""Test Agent creation and execution basic functionality."""
import os
import json
from concurrent.futures import Future
from unittest import mock
@@ -15,8 +16,10 @@ from crewai.crews.crew_output import CrewOutput
from crewai.memory.contextual.contextual_memory import ContextualMemory
from crewai.process import Process
from crewai.task import Task
from crewai.tasks.output_format import OutputFormat
from crewai.tasks.task_output import TaskOutput
from crewai.utilities import Logger, RPMController
from crewai.utilities.constants import CREW_TASKS_OUTPUT_FILE
ceo = Agent(
role="CEO",
@@ -136,7 +139,6 @@ def test_async_task_cannot_include_sequential_async_tasks_in_context():
def test_context_no_future_tasks():
task2 = Task(
description="Task 2",
expected_output="output",
@@ -584,7 +586,6 @@ def test_sequential_async_task_execution_completion():
@pytest.mark.vcr(filter_headers=["authorization"])
def test_single_task_with_async_execution():
researcher_agent = Agent(
role="Researcher",
goal="Make the best research and analysis on content about AI and AI agents",
@@ -740,7 +741,6 @@ def test_async_task_execution_call_count():
) as mock_execute_sync, patch.object(
Task, "execute_async", return_value=mock_future
) as mock_execute_async:
crew.kickoff()
assert mock_execute_async.call_count == 2
@@ -1148,7 +1148,6 @@ def test_code_execution_flag_adds_code_tool_upon_kickoff():
@pytest.mark.vcr(filter_headers=["authorization"])
def test_delegation_is_not_enabled_if_there_are_only_one_agent():
researcher = Agent(
role="Researcher",
goal="Make the best research and analysis on content about AI and AI agents",
@@ -1238,10 +1237,10 @@ def test_agent_usage_metrics_are_captured_for_hierarchical_process():
print(crew.usage_metrics)
assert crew.usage_metrics == {
"total_tokens": 2217,
"prompt_tokens": 1847,
"completion_tokens": 370,
"successful_requests": 4,
"total_tokens": 311,
"prompt_tokens": 224,
"completion_tokens": 87,
"successful_requests": 1,
}
@@ -1271,7 +1270,7 @@ def test_hierarchical_crew_creation_tasks_with_agents():
assert crew.manager_agent.tools is not None
print("TOOL DESCRIPTION", crew.manager_agent.tools[0].description)
assert crew.manager_agent.tools[0].description.startswith(
"Delegate a specific task to one of the following coworkers: Senior Writer"
"Delegate a specific task to one of the following coworkers: [Senior Writer, Researcher]"
)
@@ -1380,7 +1379,6 @@ def test_crew_does_not_interpolate_without_inputs():
interpolate_task_inputs.assert_not_called()
# TODO: Ask @joao if we want to start throwing errors if inputs are not provided
# def test_crew_partial_inputs():
# agent = Agent(
# role="{topic} Researcher",
@@ -1404,7 +1402,6 @@ def test_crew_does_not_interpolate_without_inputs():
# assert crew.agents[0].backstory == "You have a lot of experience with AI."
# TODO: If we do want ot throw errors if we are missing inputs. Add in this test.
# def test_crew_invalid_inputs():
# agent = Agent(
# role="{topic} Researcher",
@@ -1806,3 +1803,472 @@ def test__setup_for_training():
for agent in agents:
assert agent.allow_delegation is False
@pytest.mark.vcr(filter_headers=["authorization"])
def test_replay_feature():
list_ideas = Task(
description="Generate a list of 5 interesting ideas to explore for an article, where each bulletpoint is under 15 words.",
expected_output="Bullet point list of 5 important events. No additional commentary.",
agent=researcher,
)
write = Task(
description="Write a sentence about the events",
expected_output="A sentence about the events",
agent=writer,
context=[list_ideas],
)
crew = Crew(
agents=[researcher, writer],
tasks=[list_ideas, write],
process=Process.sequential,
)
with patch.object(Task, "execute_sync") as mock_execute_task:
mock_execute_task.return_value = TaskOutput(
description="Mock description",
raw="Mocked output for list of ideas",
agent="Researcher",
json_dict=None,
output_format=OutputFormat.RAW,
pydantic=None,
summary="Mocked output for list of ideas",
)
crew.kickoff()
crew.replay_from_task(str(write.id))
# Ensure context was passed correctly
assert mock_execute_task.call_count == 3
@pytest.mark.vcr(filter_headers=["authorization"])
def test_crew_replay_from_task_error():
task = Task(
description="Come up with a list of 5 interesting ideas to explore for an article",
expected_output="5 bullet points with a paragraph for each idea.",
agent=researcher,
)
crew = Crew(
agents=[researcher, writer],
tasks=[task],
)
with pytest.raises(TypeError) as e:
crew.replay_from_task() # type: ignore purposefully throwing err
assert "task_id is required" in str(e)
@pytest.mark.vcr(filter_headers=["authorization"])
def test_crew_task_output_file_creation():
agent = Agent(
role="Content Writer",
goal="Write engaging content on various topics.",
backstory="You have a background in journalism and creative writing.",
)
task = Task(
description="Write a detailed article about AI in healthcare.",
expected_output="A 1 paragraph article about AI.",
agent=agent,
)
crew = Crew(agents=[agent], tasks=[task])
with patch.object(Task, "execute_sync") as mock_execute_task:
mock_execute_task.return_value = TaskOutput(
description="Write about AI in healthcare.",
raw="Artificial Intelligence (AI) is revolutionizing healthcare by enhancing diagnostic accuracy, personalizing treatment plans, and streamlining administrative tasks.",
agent="Content Writer",
json_dict=None,
output_format=OutputFormat.RAW,
pydantic=None,
summary="Write about AI in healthcare...",
)
crew.kickoff()
# Check if the crew_tasks_output.json file is created
assert os.path.exists(CREW_TASKS_OUTPUT_FILE)
# Clean up the file after test
if os.path.exists(CREW_TASKS_OUTPUT_FILE):
os.remove(CREW_TASKS_OUTPUT_FILE)
@pytest.mark.vcr(filter_headers=["authorization"])
def test_replay_without_output_tasks_json():
agent = Agent(
role="Technical Writer",
goal="Write detailed technical documentation.",
backstory="You have a background in software engineering and technical writing.",
)
task = Task(
description="Document the process of setting up a Python project.",
expected_output="A step-by-step guide on setting up a Python project.",
agent=agent,
)
crew = Crew(agents=[agent], tasks=[task])
with patch.object(Task, "execute_sync") as mock_execute_task:
mock_execute_task.return_value = TaskOutput(
description="Document the process of setting up a Python project.",
raw="To set up a Python project, first create a virtual environment...",
agent="Technical Writer",
json_dict=None,
output_format=OutputFormat.RAW,
pydantic=None,
summary="Document the process of setting up a Python project...",
)
if os.path.exists(CREW_TASKS_OUTPUT_FILE):
os.remove(CREW_TASKS_OUTPUT_FILE)
with pytest.raises(ValueError):
crew.replay_from_task(str(task.id))
@pytest.mark.vcr(filter_headers=["authorization"])
def test_replay_task_with_context():
agent1 = Agent(
role="Researcher",
goal="Research AI advancements.",
backstory="You are an expert in AI research.",
)
agent2 = Agent(
role="Writer",
goal="Write detailed articles on AI.",
backstory="You have a background in journalism and AI.",
)
task1 = Task(
description="Research the latest advancements in AI.",
expected_output="A detailed report on AI advancements.",
agent=agent1,
)
task2 = Task(
description="Summarize the AI advancements report.",
expected_output="A summary of the AI advancements report.",
agent=agent2,
)
task3 = Task(
description="Write an article based on the AI advancements summary.",
expected_output="An article on AI advancements.",
agent=agent2,
)
task4 = Task(
description="Create a presentation based on the AI advancements article.",
expected_output="A presentation on AI advancements.",
agent=agent2,
context=[task1],
)
crew = Crew(
agents=[agent1, agent2],
tasks=[task1, task2, task3, task4],
process=Process.sequential,
)
mock_task_output1 = TaskOutput(
description="Research the latest advancements in AI.",
raw="Detailed report on AI advancements...",
agent="Researcher",
json_dict=None,
output_format=OutputFormat.RAW,
pydantic=None,
summary="Detailed report on AI advancements...",
)
mock_task_output2 = TaskOutput(
description="Summarize the AI advancements report.",
raw="Summary of the AI advancements report...",
agent="Writer",
json_dict=None,
output_format=OutputFormat.RAW,
pydantic=None,
summary="Summary of the AI advancements report...",
)
mock_task_output3 = TaskOutput(
description="Write an article based on the AI advancements summary.",
raw="Article on AI advancements...",
agent="Writer",
json_dict=None,
output_format=OutputFormat.RAW,
pydantic=None,
summary="Article on AI advancements...",
)
mock_task_output4 = TaskOutput(
description="Create a presentation based on the AI advancements article.",
raw="Presentation on AI advancements...",
agent="Writer",
json_dict=None,
output_format=OutputFormat.RAW,
pydantic=None,
summary="Presentation on AI advancements...",
)
with patch.object(Task, "execute_sync") as mock_execute_task:
mock_execute_task.side_effect = [
mock_task_output1,
mock_task_output2,
mock_task_output3,
mock_task_output4,
]
crew.kickoff()
# Check if the crew_tasks_output.json file is created
assert os.path.exists(CREW_TASKS_OUTPUT_FILE)
# Replay task4 and ensure it uses task1's context properly
with patch.object(Task, "execute_sync") as mock_replay_task:
mock_replay_task.return_value = mock_task_output4
replayed_output = crew.replay_from_task(str(task4.id))
assert replayed_output.raw == "Presentation on AI advancements..."
# Clean up the file after test
if os.path.exists(CREW_TASKS_OUTPUT_FILE):
os.remove(CREW_TASKS_OUTPUT_FILE)
def test_replay_from_task_with_context():
agent = Agent(role="test_agent", backstory="Test Description", goal="Test Goal")
task1 = Task(
description="Context Task", expected_output="Say Task Output", agent=agent
)
task2 = Task(
description="Test Task", expected_output="Say Hi", agent=agent, context=[task1]
)
context_output = TaskOutput(
description="Context Task Output",
agent="test_agent",
raw="context raw output",
pydantic=None,
json_dict={},
output_format=OutputFormat.RAW,
)
task1.output = context_output
crew = Crew(agents=[agent], tasks=[task1, task2], process=Process.sequential)
with patch(
"crewai.utilities.task_output_handler.TaskOutputJsonHandler.load",
return_value=[
{
"task_id": str(task1.id),
"output": {
"description": context_output.description,
"summary": context_output.summary,
"raw": context_output.raw,
"pydantic": context_output.pydantic,
"json_dict": context_output.json_dict,
"output_format": context_output.output_format,
"agent": context_output.agent,
},
"inputs": {},
},
{
"task_id": str(task2.id),
"output": {
"description": "Test Task Output",
"summary": None,
"raw": "test raw output",
"pydantic": None,
"json_dict": {},
"output_format": "json",
"agent": "test_agent",
},
"inputs": {},
},
],
):
crew.replay_from_task(str(task2.id))
assert crew.tasks[1].context[0].output.raw == "context raw output"
@pytest.mark.vcr(filter_headers=["authorization"])
def test_replay_with_invalid_task_id():
agent = Agent(role="test_agent", backstory="Test Description", goal="Test Goal")
task1 = Task(
description="Context Task", expected_output="Say Task Output", agent=agent
)
task2 = Task(
description="Test Task", expected_output="Say Hi", agent=agent, context=[task1]
)
context_output = TaskOutput(
description="Context Task Output",
agent="test_agent",
raw="context raw output",
pydantic=None,
json_dict={},
output_format=OutputFormat.RAW,
)
task1.output = context_output
crew = Crew(agents=[agent], tasks=[task1, task2], process=Process.sequential)
with patch(
"crewai.utilities.task_output_handler.TaskOutputJsonHandler.load",
return_value=[
{
"task_id": str(task1.id),
"output": {
"description": context_output.description,
"summary": context_output.summary,
"raw": context_output.raw,
"pydantic": context_output.pydantic,
"json_dict": context_output.json_dict,
"output_format": context_output.output_format,
"agent": context_output.agent,
},
"inputs": {},
},
{
"task_id": str(task2.id),
"output": {
"description": "Test Task Output",
"summary": None,
"raw": "test raw output",
"pydantic": None,
"json_dict": {},
"output_format": "json",
"agent": "test_agent",
},
"inputs": {},
},
],
):
with pytest.raises(
ValueError,
match="Task with id bf5b09c9-69bd-4eb8-be12-f9e5bae31c2d not found in the crew's tasks.",
):
crew.replay_from_task("bf5b09c9-69bd-4eb8-be12-f9e5bae31c2d")
@patch.object(Crew, "_interpolate_inputs")
def test_replay_interpolates_inputs_properly(mock_interpolate_inputs):
agent = Agent(role="test_agent", backstory="Test Description", goal="Test Goal")
task1 = Task(description="Context Task", expected_output="Say {name}", agent=agent)
task2 = Task(
description="Test Task",
expected_output="Say Hi to {name}",
agent=agent,
context=[task1],
)
context_output = TaskOutput(
description="Context Task Output",
agent="test_agent",
raw="context raw output",
pydantic=None,
json_dict={},
output_format=OutputFormat.RAW,
)
task1.output = context_output
crew = Crew(agents=[agent], tasks=[task1, task2], process=Process.sequential)
crew.kickoff(inputs={"name": "John"})
with patch(
"crewai.utilities.task_output_handler.TaskOutputJsonHandler.load",
return_value=[
{
"task_id": str(task1.id),
"output": {
"description": context_output.description,
"summary": context_output.summary,
"raw": context_output.raw,
"pydantic": context_output.pydantic,
"json_dict": context_output.json_dict,
"output_format": context_output.output_format,
"agent": context_output.agent,
},
"inputs": {"name": "John"},
},
{
"task_id": str(task2.id),
"output": {
"description": "Test Task Output",
"summary": None,
"raw": "test raw output",
"pydantic": None,
"json_dict": {},
"output_format": "json",
"agent": "test_agent",
},
"inputs": {"name": "John"},
},
],
):
crew.replay_from_task(str(task2.id))
assert crew._inputs == {"name": "John"}
assert mock_interpolate_inputs.call_count == 2
@pytest.mark.vcr(filter_headers=["authorization"])
def test_replay_from_task_setup_context():
agent = Agent(role="test_agent", backstory="Test Description", goal="Test Goal")
task1 = Task(description="Context Task", expected_output="Say {name}", agent=agent)
task2 = Task(
description="Test Task",
expected_output="Say Hi to {name}",
agent=agent,
)
context_output = TaskOutput(
description="Context Task Output",
agent="test_agent",
raw="context raw output",
pydantic=None,
json_dict={},
output_format=OutputFormat.RAW,
)
task1.output = context_output
crew = Crew(agents=[agent], tasks=[task1, task2], process=Process.sequential)
with patch(
"crewai.utilities.task_output_handler.TaskOutputJsonHandler.load",
return_value=[
{
"task_id": str(task1.id),
"output": {
"description": context_output.description,
"summary": context_output.summary,
"raw": context_output.raw,
"pydantic": context_output.pydantic,
"json_dict": context_output.json_dict,
"output_format": context_output.output_format,
"agent": context_output.agent,
},
"inputs": {"name": "John"},
},
{
"task_id": str(task2.id),
"output": {
"description": "Test Task Output",
"summary": None,
"raw": "test raw output",
"pydantic": None,
"json_dict": {},
"output_format": "json",
"agent": "test_agent",
},
"inputs": {"name": "John"},
},
],
):
crew.replay_from_task(str(task2.id))
# Check if the first task's output was set correctly
assert crew.tasks[0].output is not None
assert isinstance(crew.tasks[0].output, TaskOutput)
assert crew.tasks[0].output.description == "Context Task Output"
assert crew.tasks[0].output.agent == "test_agent"
assert crew.tasks[0].output.raw == "context raw output"
assert crew.tasks[0].output.output_format == OutputFormat.RAW
assert crew.tasks[1].prompt_context == "context raw output"

View File

@@ -81,7 +81,7 @@ def test_task_prompt_includes_expected_output():
with patch.object(Agent, "execute_task") as execute:
execute.return_value = "ok"
task.execute_sync()
task.execute_sync(agent=researcher)
execute.assert_called_once_with(task=task, context=None, tools=[])
@@ -104,7 +104,7 @@ def test_task_callback():
with patch.object(Agent, "execute_task") as execute:
execute.return_value = "ok"
task.execute_sync()
task.execute_sync(agent=researcher)
task_completed.assert_called_once_with(task.output)
@@ -129,7 +129,7 @@ def test_task_callback_returns_task_ouput():
with patch.object(Agent, "execute_task") as execute:
execute.return_value = "exported_ok"
task.execute_sync()
task.execute_sync(agent=researcher)
# Ensure the callback is called with a TaskOutput object serialized to JSON
task_completed.assert_called_once()
callback_data = task_completed.call_args[0][0]
@@ -521,9 +521,7 @@ def test_save_task_json_output():
with patch.object(Task, "_save_file") as save_file:
save_file.return_value = None
crew.kickoff()
save_file.assert_called_once_with(
{"score": 4}
) # TODO: @Joao, should this be a dict or a json string?
save_file.assert_called_once_with({"score": 4})
@pytest.mark.vcr(filter_headers=["authorization"])