Compare commits

...

43 Commits

Author SHA1 Message Date
Gui Vieira
8f5f67de41 Fix threading 2024-11-21 15:33:20 -03:00
Andy Bromberg
f8ca49d8df Update Perplexity example in documentation (#1623) 2024-11-20 21:54:04 -03:00
Bob Conan
c119230fd6 Updated README.md, fix typo(s) (#1637) 2024-11-20 21:52:41 -03:00
Brandon Hancock (bhancock_ai)
14a36d3f5e Knowledge (#1567)
* initial knowledge

* WIP

* Adding core knowledge sources

* Improve types and better support for file paths

* added additional sources

* fix linting

* update yaml to include optional deps

* adding in lorenze feedback

* ensure embeddings are persisted

* improvements all around Knowledge class

* return this

* properly reset memory

* properly reset memory+knowledge

* consolodation and improvements

* linted

* cleanup rm unused embedder

* fix test

* fix duplicate

* generating cassettes for knowledge test

* updated default embedder

* None embedder to use default on pipeline cloning

* improvements

* fixed text_file_knowledge

* mypysrc fixes

* type check fixes

* added extra cassette

* just mocks

* linted

* mock knowledge query to not spin up db

* linted

* verbose run

* put a flag

* fix

* adding docs

* better docs

* improvements from review

* more docs

* linted

* rm print

* more fixes

* clearer docs

* added docstrings and type hints for cli

---------

Co-authored-by: João Moura <joaomdmoura@gmail.com>
Co-authored-by: Lorenze Jay <lorenzejaytech@gmail.com>
2024-11-20 15:40:08 -08:00
Gui Vieira
fde1ee45f9 Merge pull request #1636 from crewAIInc/gui/make-it-green
Make it green!
2024-11-20 16:12:58 -03:00
Gui Vieira
6774bc2c53 Make mypy happy 2024-11-20 16:08:08 -03:00
Gui Vieira
94c62263ed Merge pull request #1635 from crewAIInc/gui/kickoff-callbacks
Move kickoff callbacks to crew's domain
2024-11-20 14:37:52 -03:00
Gui Vieira
495c3859af Cassettes 2024-11-20 10:26:00 -03:00
Gui Vieira
3e003f5e32 Move kickoff callbacks to crew's domain 2024-11-20 10:06:49 -03:00
Tony Kipkemboi
1c8b509d7d Merge pull request #1634 from crewAIInc/github_tool_update
docs: add gh_token documentation to GithubSearchTool
2024-11-20 07:21:24 -05:00
theCyberTech
58af5c08f9 docs: add gh_token documentation to GithubSearchTool 2024-11-20 19:23:09 +08:00
Tony Kipkemboi
55e968c9e0 Update CLI Watson supported models + docs (#1628) 2024-11-19 19:42:54 -03:00
João Moura
0b9092702b adding before and after crew 2024-11-18 00:21:36 -03:00
João Moura
8376698534 preparing enw version 2024-11-18 00:21:36 -03:00
Lorenze Jay
3dc02310b6 upgrade chroma and adjust embedder function generator (#1607)
* upgrade chroma and adjust embedder function generator

* >= version

* linted
2024-11-14 14:13:12 -08:00
Dev Khant
e70bc94ab6 Add support for retrieving user preferences and memories using Mem0 (#1209)
* Integrate Mem0

* Update src/crewai/memory/contextual/contextual_memory.py

Co-authored-by: Deshraj Yadav <deshraj@gatech.edu>

* pending commit for _fetch_user_memories

* update poetry.lock

* fixes mypy issues

* fix mypy checks

* New fixes for user_id

* remove memory_provider

* handle memory_provider

* checks for memory_config

* add mem0 to dependency

* Update pyproject.toml

Co-authored-by: Deshraj Yadav <deshraj@gatech.edu>

* update docs

* update doc

* bump mem0 version

* fix api error msg and mypy issue

* mypy fix

* resolve comments

* fix memory usage without mem0

* mem0 version bump

* lazy import mem0

---------

Co-authored-by: Deshraj Yadav <deshraj@gatech.edu>
Co-authored-by: João Moura <joaomdmoura@gmail.com>
Co-authored-by: Brandon Hancock (bhancock_ai) <109994880+bhancockio@users.noreply.github.com>
2024-11-14 10:59:24 -08:00
Eduardo Chiarotti
9285ebf8a2 feat: Reduce level for Bandit and fix code to adapt (#1604) 2024-11-14 13:12:35 -03:00
Thiago Moretto
4ca785eb15 Merge pull request #1597 from crewAIInc/tm-fix-crew-train-test
Fix crew_train_success test
2024-11-13 10:52:49 -03:00
Thiago Moretto
c57cbd8591 Fix crew_train_success test 2024-11-13 10:47:49 -03:00
Thiago Moretto
7fb1289205 Merge pull request #1596 from crewAIInc/tm-recording-cached-prompt-tokens
Add cached prompt tokens info on usage metrics
2024-11-13 10:37:29 -03:00
Thiago Moretto
f02681ae01 Merge branch 'main' into tm-recording-cached-prompt-tokens 2024-11-13 10:19:02 -03:00
Thiago Moretto
c725105b1f do not include cached on total 2024-11-13 10:18:30 -03:00
Thiago Moretto
36aa4bcb46 Cached prompt tokens on usage metrics 2024-11-13 10:16:30 -03:00
Eduardo Chiarotti
b98f8f9fe1 fix: Step callback issue (#1595)
* fix: Step callback issue

* fix: Add empty thought since its required
2024-11-13 10:07:28 -03:00
João Moura
bcfcf88e78 removing prints 2024-11-12 18:37:57 -03:00
Thiago Moretto
fd0de3a47e Merge pull request #1588 from crewAIInc/tm-workaround-litellm-bug
fixing LiteLLM callback replacement bug
2024-11-12 17:19:01 -03:00
Thiago Moretto
c7b9ae02fd fix test_agent_usage_metrics_are_captured_for_hierarchical_process 2024-11-12 16:43:43 -03:00
Thiago Moretto
4afb022572 fix LiteLLM callback replacement 2024-11-12 15:04:57 -03:00
João Moura
8610faef22 add missing init 2024-11-11 02:29:40 -03:00
João Moura
6d677541c7 preparing new version 2024-11-11 00:03:52 -03:00
João Moura
49220ec163 preparing new version 2024-11-10 23:46:38 -03:00
João Moura
40a676b7ac curring new version 2024-11-10 21:16:36 -03:00
João Moura
50bf146d1e preparing new version 2024-11-10 20:47:56 -03:00
João Moura
40d378abfb updating LLM docs 2024-11-10 11:36:03 -03:00
João Moura
1b09b085a7 preparing new version 2024-11-10 11:00:16 -03:00
João Moura
9f2acfe91f making sure we don't check for agents that were not used in the crew 2024-11-06 23:07:23 -03:00
Brandon Hancock (bhancock_ai)
e856359e23 fix missing config (#1557) 2024-11-05 12:07:29 -05:00
Brandon Hancock (bhancock_ai)
faa231e278 Fix flows to support cycles and added in test (#1556) 2024-11-05 12:02:54 -05:00
Brandon Hancock (bhancock_ai)
3d44795476 Feat/watson in cli (#1535)
* getting cli and .env to work together for different models

* support new models

* clean up prints

* Add support for cerebras

* Fix watson keys
2024-11-05 12:01:57 -05:00
Tony Kipkemboi
f50e709985 docs update (#1558)
* add llm providers accordion group

* fix numbering

* Fix directory tree & add llms to accordion

* update crewai enterprise link in docs
2024-11-05 11:26:19 -05:00
Brandon Hancock (bhancock_ai)
d70c542547 Raise an error if an LLM doesnt return a response (#1548) 2024-11-04 11:42:38 -05:00
Gui Vieira
57201fb856 Increase providers fetching timeout 2024-11-01 18:54:40 -03:00
Brandon Hancock (bhancock_ai)
9b142e580b add inputs to flows (#1553)
* add inputs to flows

* fix flows lint
2024-11-01 14:37:02 -07:00
101 changed files with 8422 additions and 737 deletions

View File

@@ -19,5 +19,5 @@ jobs:
run: pip install bandit
- name: Run Bandit
run: bandit -c pyproject.toml -r src/ -lll
run: bandit -c pyproject.toml -r src/ -ll

View File

@@ -26,7 +26,7 @@ jobs:
run: uv python install 3.11.9
- name: Install the project
run: uv sync --dev
run: uv sync --dev --all-extras
- name: Run tests
run: uv run pytest tests
run: uv run pytest tests -vv

4
.gitignore vendored
View File

@@ -17,3 +17,7 @@ rc-tests/*
temp/*
.vscode/*
crew_tasks_output.json
.codesight
.mypy_cache
.ruff_cache
.venv

View File

@@ -100,7 +100,7 @@ You can now start developing your crew by editing the files in the `src/my_proje
#### Example of a simple crew with a sequential process:
Instatiate your crew:
Instantiate your crew:
```shell
crewai create crew latest-ai-development
@@ -399,7 +399,7 @@ Data collected includes:
- Roles of agents in a crew
- Understand high level use cases so we can build better tools, integrations and examples about it
- Tools names available
- Understand out of the publically available tools, which ones are being used the most so we can improve them
- Understand out of the publicly available tools, which ones are being used the most so we can improve them
Users can opt-in to Further Telemetry, sharing the complete telemetry data by setting the `share_crew` attribute to `True` on their Crews. Enabling `share_crew` results in the collection of detailed crew and task execution data, including `goal`, `backstory`, `context`, and `output` of tasks. This enables a deeper insight into usage patterns while respecting the user's choice to share.

View File

@@ -22,7 +22,8 @@ A crew in crewAI represents a collaborative group of agents working together to
| **Max RPM** _(optional)_ | `max_rpm` | Maximum requests per minute the crew adheres to during execution. Defaults to `None`. |
| **Language** _(optional)_ | `language` | Language used for the crew, defaults to English. |
| **Language File** _(optional)_ | `language_file` | Path to the language file to be used for the crew. |
| **Memory** _(optional)_ | `memory` | Utilized for storing execution memories (short-term, long-term, entity memory). Defaults to `False`. |
| **Memory** _(optional)_ | `memory` | Utilized for storing execution memories (short-term, long-term, entity memory). |
| **Memory Config** _(optional)_ | `memory_config` | Configuration for the memory provider to be used by the crew. |
| **Cache** _(optional)_ | `cache` | Specifies whether to use a cache for storing the results of tools' execution. Defaults to `True`. |
| **Embedder** _(optional)_ | `embedder` | Configuration for the embedder to be used by the crew. Mostly used by memory for now. Default is `{"provider": "openai"}`. |
| **Full Output** _(optional)_ | `full_output` | Whether the crew should return the full output with all tasks outputs or just the final output. Defaults to `False`. |

View File

@@ -18,60 +18,63 @@ Flows allow you to create structured, event-driven workflows. They provide a sea
4. **Flexible Control Flow**: Implement conditional logic, loops, and branching within your workflows.
5. **Input Flexibility**: Flows can accept inputs to initialize or update their state, with different handling for structured and unstructured state management.
## Getting Started
Let's create a simple Flow where you will use OpenAI to generate a random city in one task and then use that city to generate a fun fact in another task.
```python Code
### Passing Inputs to Flows
Flows can accept inputs to initialize or update their state before execution. The way inputs are handled depends on whether the flow uses structured or unstructured state management.
#### Structured State Management
In structured state management, the flow's state is defined using a Pydantic `BaseModel`. Inputs must match the model's schema, and any updates will overwrite the default values.
```python
from crewai.flow.flow import Flow, listen, start
from dotenv import load_dotenv
from litellm import completion
from pydantic import BaseModel
class ExampleState(BaseModel):
counter: int = 0
message: str = ""
class ExampleFlow(Flow):
model = "gpt-4o-mini"
class StructuredExampleFlow(Flow[ExampleState]):
@start()
def generate_city(self):
print("Starting flow")
def first_method(self):
# Implementation
response = completion(
model=self.model,
messages=[
{
"role": "user",
"content": "Return the name of a random city in the world.",
},
],
)
flow = StructuredExampleFlow()
flow.kickoff(inputs={"counter": 10})
```
random_city = response["choices"][0]["message"]["content"]
print(f"Random City: {random_city}")
In this example, the `counter` is initialized to `10`, while `message` retains its default value.
return random_city
#### Unstructured State Management
@listen(generate_city)
def generate_fun_fact(self, random_city):
response = completion(
model=self.model,
messages=[
{
"role": "user",
"content": f"Tell me a fun fact about {random_city}",
},
],
)
In unstructured state management, the flow's state is a dictionary. You can pass any dictionary to update the state.
fun_fact = response["choices"][0]["message"]["content"]
return fun_fact
```python
from crewai.flow.flow import Flow, listen, start
class UnstructuredExampleFlow(Flow):
@start()
def first_method(self):
# Implementation
flow = UnstructuredExampleFlow()
flow.kickoff(inputs={"counter": 5, "message": "Initial message"})
```
flow = ExampleFlow()
result = flow.kickoff()
Here, both `counter` and `message` are updated based on the provided inputs.
print(f"Generated fun fact: {result}")
**Note:** Ensure that inputs for structured state management adhere to the defined schema to avoid validation errors.
### Example Flow
```python
# Existing example code
```
In the above example, we have created a simple Flow that generates a random city using OpenAI and then generates a fun fact about that city. The Flow consists of two tasks: `generate_city` and `generate_fun_fact`. The `generate_city` task is the starting point of the Flow, and the `generate_fun_fact` task listens for the output of the `generate_city` task.
@@ -94,14 +97,14 @@ The `@listen()` decorator can be used in several ways:
1. **Listening to a Method by Name**: You can pass the name of the method you want to listen to as a string. When that method completes, the listener method will be triggered.
```python Code
```python
@listen("generate_city")
def generate_fun_fact(self, random_city):
# Implementation
```
2. **Listening to a Method Directly**: You can pass the method itself. When that method completes, the listener method will be triggered.
```python Code
```python
@listen(generate_city)
def generate_fun_fact(self, random_city):
# Implementation
@@ -118,7 +121,7 @@ When you run a Flow, the final output is determined by the last method that comp
Here's how you can access the final output:
<CodeGroup>
```python Code
```python
from crewai.flow.flow import Flow, listen, start
class OutputExampleFlow(Flow):
@@ -130,18 +133,17 @@ class OutputExampleFlow(Flow):
def second_method(self, first_output):
return f"Second method received: {first_output}"
flow = OutputExampleFlow()
final_output = flow.kickoff()
print("---- Final Output ----")
print(final_output)
````
```
``` text Output
```text
---- Final Output ----
Second method received: Output from first_method
````
```
</CodeGroup>
@@ -156,7 +158,7 @@ Here's an example of how to update and access the state:
<CodeGroup>
```python Code
```python
from crewai.flow.flow import Flow, listen, start
from pydantic import BaseModel
@@ -184,7 +186,7 @@ print("Final State:")
print(flow.state)
```
```text Output
```text
Final Output: Hello from first_method - updated by second_method
Final State:
counter=2 message='Hello from first_method - updated by second_method'
@@ -208,10 +210,10 @@ allowing developers to choose the approach that best fits their application's ne
In unstructured state management, all state is stored in the `state` attribute of the `Flow` class.
This approach offers flexibility, enabling developers to add or modify state attributes on the fly without defining a strict schema.
```python Code
```python
from crewai.flow.flow import Flow, listen, start
class UntructuredExampleFlow(Flow):
class UnstructuredExampleFlow(Flow):
@start()
def first_method(self):
@@ -230,8 +232,7 @@ class UntructuredExampleFlow(Flow):
print(f"State after third_method: {self.state}")
flow = UntructuredExampleFlow()
flow = UnstructuredExampleFlow()
flow.kickoff()
```
@@ -245,16 +246,14 @@ flow.kickoff()
Structured state management leverages predefined schemas to ensure consistency and type safety across the workflow.
By using models like Pydantic's `BaseModel`, developers can define the exact shape of the state, enabling better validation and auto-completion in development environments.
```python Code
```python
from crewai.flow.flow import Flow, listen, start
from pydantic import BaseModel
class ExampleState(BaseModel):
counter: int = 0
message: str = ""
class StructuredExampleFlow(Flow[ExampleState]):
@start()
@@ -273,7 +272,6 @@ class StructuredExampleFlow(Flow[ExampleState]):
print(f"State after third_method: {self.state}")
flow = StructuredExampleFlow()
flow.kickoff()
```
@@ -307,7 +305,7 @@ The `or_` function in Flows allows you to listen to multiple methods and trigger
<CodeGroup>
```python Code
```python
from crewai.flow.flow import Flow, listen, or_, start
class OrExampleFlow(Flow):
@@ -324,13 +322,11 @@ class OrExampleFlow(Flow):
def logger(self, result):
print(f"Logger: {result}")
flow = OrExampleFlow()
flow.kickoff()
```
```text Output
```text
Logger: Hello from the start method
Logger: Hello from the second method
```
@@ -346,7 +342,7 @@ The `and_` function in Flows allows you to listen to multiple methods and trigge
<CodeGroup>
```python Code
```python
from crewai.flow.flow import Flow, and_, listen, start
class AndExampleFlow(Flow):
@@ -368,7 +364,7 @@ flow = AndExampleFlow()
flow.kickoff()
```
```text Output
```text
---- Logger ----
{'greeting': 'Hello from the start method', 'joke': 'What do computers eat? Microchips.'}
```
@@ -385,7 +381,7 @@ You can specify different routes based on the output of the method, allowing you
<CodeGroup>
```python Code
```python
import random
from crewai.flow.flow import Flow, listen, router, start
from pydantic import BaseModel
@@ -416,12 +412,11 @@ class RouterFlow(Flow[ExampleState]):
def fourth_method(self):
print("Fourth method running")
flow = RouterFlow()
flow.kickoff()
```
```text Output
```text
Starting the structured flow
Third method running
Fourth method running
@@ -484,7 +479,7 @@ The `main.py` file is where you create your flow and connect the crews together.
Here's an example of how you can connect the `poem_crew` in the `main.py` file:
```python Code
```python
#!/usr/bin/env python
from random import randint
@@ -612,7 +607,7 @@ CrewAI provides two convenient methods to generate plots of your flows:
If you are working directly with a flow instance, you can generate a plot by calling the `plot()` method on your flow object. This method will create an HTML file containing the interactive plot of your flow.
```python Code
```python
# Assuming you have a flow instance
flow.plot("my_flow_plot")
```

View File

@@ -0,0 +1,75 @@
---
title: Knowledge
description: What is knowledge in CrewAI and how to use it.
icon: book
---
# Using Knowledge in CrewAI
## Introduction
The Knowledge class in CrewAI provides a powerful way to manage and query knowledge sources for your AI agents. This guide will show you how to implement knowledge management in your CrewAI projects.
Additionally, we have specific tools for generate knowledge sources for strings, text files, PDF's, and Spreadsheets. You can expand on any source type by extending the `KnowledgeSource` class.
## Basic Implementation
Here's a simple example of how to use the Knowledge class:
```python
from crewai import Agent, Task, Crew, Process, LLM
from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource
# Create a knowledge source
content = "Users name is John. He is 30 years old and lives in San Francisco."
string_source = StringKnowledgeSource(
content=content, metadata={"preference": "personal"}
)
llm = LLM(model="gpt-4o-mini", temperature=0)
# Create an agent with the knowledge store
agent = Agent(
role="About User",
goal="You know everything about the user.",
backstory="""You are a master at understanding people and their preferences.""",
verbose=True,
allow_delegation=False,
llm=llm,
)
task = Task(
description="Answer the following questions about the user: {question}",
expected_output="An answer to the question.",
agent=agent,
)
crew = Crew(
agents=[agent],
tasks=[task],
verbose=True,
process=Process.sequential,
knowledge={"sources": [string_source], "metadata": {"preference": "personal"}}, # Enable knowledge by adding the sources here. You can also add more sources to the sources list.
)
result = crew.kickoff(inputs={"question": "What city does John live in and how old is he?"})
```
## Embedder Configuration
You can also configure the embedder for the knowledge store. This is useful if you want to use a different embedder for the knowledge store than the one used for the agents.
```python
...
string_source = StringKnowledgeSource(
content="Users name is John. He is 30 years old and lives in San Francisco.",
metadata={"preference": "personal"}
)
crew = Crew(
...
knowledge={
"sources": [string_source],
"metadata": {"preference": "personal"},
"embedder_config": {"provider": "openai", "config": {"model": "text-embedding-3-small"}},
},
)
```

View File

@@ -25,7 +25,102 @@ By default, CrewAI uses the `gpt-4o-mini` model. It uses environment variables i
- `OPENAI_API_BASE`
- `OPENAI_API_KEY`
### 2. Custom LLM Objects
### 2. Updating YAML files
You can update the `agents.yml` file to refer to the LLM you want to use:
```yaml Code
researcher:
role: Research Specialist
goal: Conduct comprehensive research and analysis to gather relevant information,
synthesize findings, and produce well-documented insights.
backstory: A dedicated research professional with years of experience in academic
investigation, literature review, and data analysis, known for thorough and
methodical approaches to complex research questions.
verbose: true
llm: openai/gpt-4o
# llm: azure/gpt-4o-mini
# llm: gemini/gemini-pro
# llm: anthropic/claude-3-5-sonnet-20240620
# llm: bedrock/anthropic.claude-3-sonnet-20240229-v1:0
# llm: mistral/mistral-large-latest
# llm: ollama/llama3:70b
# llm: groq/llama-3.2-90b-vision-preview
# llm: watsonx/meta-llama/llama-3-1-70b-instruct
# llm: nvidia_nim/meta/llama3-70b-instruct
# llm: sambanova/Meta-Llama-3.1-8B-Instruct
# ...
```
Keep in mind that you will need to set certain ENV vars depending on the model you are
using to account for the credentials or set a custom LLM object like described below.
Here are some of the required ENV vars for some of the LLM integrations:
<AccordionGroup>
<Accordion title="OpenAI">
```python Code
OPENAI_API_KEY=<your-api-key>
OPENAI_API_BASE=<optional-custom-base-url>
OPENAI_MODEL_NAME=<openai-model-name>
OPENAI_ORGANIZATION=<your-org-id> # OPTIONAL
OPENAI_API_BASE=<openaiai-api-base> # OPTIONAL
```
</Accordion>
<Accordion title="Anthropic">
```python Code
ANTHROPIC_API_KEY=<your-api-key>
```
</Accordion>
<Accordion title="Google">
```python Code
GEMINI_API_KEY=<your-api-key>
```
</Accordion>
<Accordion title="Azure">
```python Code
AZURE_API_KEY=<your-api-key> # "my-azure-api-key"
AZURE_API_BASE=<your-resource-url> # "https://example-endpoint.openai.azure.com"
AZURE_API_VERSION=<api-version> # "2023-05-15"
AZURE_AD_TOKEN=<your-azure-ad-token> # Optional
AZURE_API_TYPE=<your-azure-api-type> # Optional
```
</Accordion>
<Accordion title="AWS Bedrock">
```python Code
AWS_ACCESS_KEY_ID=<your-access-key>
AWS_SECRET_ACCESS_KEY=<your-secret-key>
AWS_DEFAULT_REGION=<your-region>
```
</Accordion>
<Accordion title="Mistral">
```python Code
MISTRAL_API_KEY=<your-api-key>
```
</Accordion>
<Accordion title="Groq">
```python Code
GROQ_API_KEY=<your-api-key>
```
</Accordion>
<Accordion title="IBM watsonx.ai">
```python Code
WATSONX_URL=<your-url> # (required) Base URL of your WatsonX instance
WATSONX_APIKEY=<your-apikey> # (required) IBM cloud API key
WATSONX_TOKEN=<your-token> # (required) IAM auth token (alternative to APIKEY)
WATSONX_PROJECT_ID=<your-project-id> # (optional) Project ID of your WatsonX instance
WATSONX_DEPLOYMENT_SPACE_ID=<your-space-id> # (optional) ID of deployment space for deployed models
```
</Accordion>
</AccordionGroup>
### 3. Custom LLM Objects
Pass a custom LLM implementation or object from another library.
@@ -102,7 +197,7 @@ When configuring an LLM for your agent, you have access to a wide range of param
These are examples of how to configure LLMs for your agent.
<AccordionGroup>
<AccordionGroup>
<Accordion title="OpenAI">
```python Code
@@ -133,10 +228,10 @@ These are examples of how to configure LLMs for your agent.
model="cerebras/llama-3.1-70b",
api_key="your-api-key-here"
)
agent = Agent(llm=llm, ...)
agent = Agent(llm=llm, ...)
```
</Accordion>
<Accordion title="Ollama (Local LLMs)">
CrewAI supports using Ollama for running open-source models locally:
@@ -150,7 +245,7 @@ These are examples of how to configure LLMs for your agent.
agent = Agent(
llm=LLM(
model="ollama/llama3.1",
model="ollama/llama3.1",
base_url="http://localhost:11434"
),
...
@@ -164,7 +259,7 @@ These are examples of how to configure LLMs for your agent.
from crewai import LLM
llm = LLM(
model="groq/llama3-8b-8192",
model="groq/llama3-8b-8192",
api_key="your-api-key-here"
)
agent = Agent(llm=llm, ...)
@@ -189,7 +284,7 @@ These are examples of how to configure LLMs for your agent.
from crewai import LLM
llm = LLM(
model="fireworks_ai/accounts/fireworks/models/llama-v3-70b-instruct",
model="fireworks_ai/accounts/fireworks/models/llama-v3-70b-instruct",
api_key="your-api-key-here"
)
agent = Agent(llm=llm, ...)
@@ -215,8 +310,8 @@ These are examples of how to configure LLMs for your agent.
from crewai import LLM
llm = LLM(
model="perplexity/mistral-7b-instruct",
base_url="https://api.perplexity.ai/v1",
model="llama-3.1-sonar-large-128k-online",
base_url="https://api.perplexity.ai/",
api_key="your-api-key-here"
)
agent = Agent(llm=llm, ...)
@@ -224,6 +319,29 @@ These are examples of how to configure LLMs for your agent.
</Accordion>
<Accordion title="IBM watsonx.ai">
You can use IBM Watson by seeting the following ENV vars:
```python Code
WATSONX_URL=<your-url>
WATSONX_APIKEY=<your-apikey>
WATSONX_PROJECT_ID=<your-project-id>
```
You can then define your agents llms by updating the `agents.yml`
```yaml Code
researcher:
role: Research Specialist
goal: Conduct comprehensive research and analysis to gather relevant information,
synthesize findings, and produce well-documented insights.
backstory: A dedicated research professional with years of experience in academic
investigation, literature review, and data analysis, known for thorough and
methodical approaches to complex research questions.
verbose: true
llm: watsonx/meta-llama/llama-3-1-70b-instruct
```
You can also set up agents more dynamically as a base level LLM instance, like bellow:
```python Code
from crewai import LLM
@@ -247,7 +365,7 @@ These are examples of how to configure LLMs for your agent.
api_key="your-api-key-here",
base_url="your_api_endpoint"
)
agent = Agent(llm=llm, ...)
agent = Agent(llm=llm, ...)
```
</Accordion>
</AccordionGroup>
@@ -282,4 +400,4 @@ This is particularly useful when working with OpenAI-compatible APIs or when you
- **API Errors**: Check your API key, network connection, and rate limits.
- **Unexpected Outputs**: Refine your prompts and adjust temperature or top_p.
- **Performance Issues**: Consider using a more powerful model or optimizing your queries.
- **Timeout Errors**: Increase the `timeout` parameter or optimize your input.
- **Timeout Errors**: Increase the `timeout` parameter or optimize your input.

View File

@@ -18,6 +18,7 @@ reason, and learn from past interactions.
| **Long-Term Memory** | Preserves valuable insights and learnings from past executions, allowing agents to build and refine their knowledge over time. |
| **Entity Memory** | Captures and organizes information about entities (people, places, concepts) encountered during tasks, facilitating deeper understanding and relationship mapping. Uses `RAG` for storing entity information. |
| **Contextual Memory**| Maintains the context of interactions by combining `ShortTermMemory`, `LongTermMemory`, and `EntityMemory`, aiding in the coherence and relevance of agent responses over a sequence of tasks or a conversation. |
| **User Memory** | Stores user-specific information and preferences, enhancing personalization and user experience. |
## How Memory Systems Empower Agents
@@ -92,6 +93,47 @@ my_crew = Crew(
)
```
## Integrating Mem0 for Enhanced User Memory
[Mem0](https://mem0.ai/) is a self-improving memory layer for LLM applications, enabling personalized AI experiences.
To include user-specific memory you can get your API key [here](https://app.mem0.ai/dashboard/api-keys) and refer the [docs](https://docs.mem0.ai/platform/quickstart#4-1-create-memories) for adding user preferences.
```python Code
import os
from crewai import Crew, Process
from mem0 import MemoryClient
# Set environment variables for Mem0
os.environ["MEM0_API_KEY"] = "m0-xx"
# Step 1: Record preferences based on past conversation or user input
client = MemoryClient()
messages = [
{"role": "user", "content": "Hi there! I'm planning a vacation and could use some advice."},
{"role": "assistant", "content": "Hello! I'd be happy to help with your vacation planning. What kind of destination do you prefer?"},
{"role": "user", "content": "I am more of a beach person than a mountain person."},
{"role": "assistant", "content": "That's interesting. Do you like hotels or Airbnb?"},
{"role": "user", "content": "I like Airbnb more."},
]
client.add(messages, user_id="john")
# Step 2: Create a Crew with User Memory
crew = Crew(
agents=[...],
tasks=[...],
verbose=True,
process=Process.sequential,
memory=True,
memory_config={
"provider": "mem0",
"config": {"user_id": "john"},
},
)
```
## Additional Embedding Providers

View File

@@ -330,4 +330,4 @@ This will clear the crew's memory, allowing for a fresh start.
## Deploying Your Project
The easiest way to deploy your crew is through [CrewAI Enterprise](https://www.crewai.com/crewaiplus), where you can deploy your crew in a few clicks.
The easiest way to deploy your crew is through [CrewAI Enterprise](http://app.crewai.com/), where you can deploy your crew in a few clicks.

View File

@@ -34,6 +34,7 @@ from crewai_tools import GithubSearchTool
# Initialize the tool for semantic searches within a specific GitHub repository
tool = GithubSearchTool(
github_repo='https://github.com/example/repo',
gh_token='your_github_personal_access_token',
content_types=['code', 'issue'] # Options: code, repo, pr, issue
)
@@ -41,6 +42,7 @@ tool = GithubSearchTool(
# Initialize the tool for semantic searches within a specific GitHub repository, so the agent can search any repository if it learns about during its execution
tool = GithubSearchTool(
gh_token='your_github_personal_access_token',
content_types=['code', 'issue'] # Options: code, repo, pr, issue
)
```
@@ -48,6 +50,7 @@ tool = GithubSearchTool(
## Arguments
- `github_repo` : The URL of the GitHub repository where the search will be conducted. This is a mandatory field and specifies the target repository for your search.
- `gh_token` : Your GitHub Personal Access Token (PAT) required for authentication. You can create one in your GitHub account settings under Developer Settings > Personal Access Tokens.
- `content_types` : Specifies the types of content to include in your search. You must provide a list of content types from the following options: `code` for searching within the code,
`repo` for searching within the repository's general information, `pr` for searching within pull requests, and `issue` for searching within issues.
This field is mandatory and allows tailoring the search to specific content types within the GitHub repository.
@@ -77,5 +80,4 @@ tool = GithubSearchTool(
),
),
)
)
```
)

6
poetry.lock generated
View File

@@ -1597,12 +1597,12 @@ files = [
google-auth = ">=2.14.1,<3.0.dev0"
googleapis-common-protos = ">=1.56.2,<2.0.dev0"
grpcio = [
{version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
{version = ">=1.33.2,<2.0dev", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""},
{version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
]
grpcio-status = [
{version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
{version = ">=1.33.2,<2.0.dev0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""},
{version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
]
proto-plus = ">=1.22.3,<2.0.0dev"
protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0"
@@ -4286,8 +4286,8 @@ files = [
[package.dependencies]
numpy = [
{version = ">=1.23.2", markers = "python_version == \"3.11\""},
{version = ">=1.22.4", markers = "python_version < \"3.11\""},
{version = ">=1.23.2", markers = "python_version == \"3.11\""},
{version = ">=1.26.0", markers = "python_version >= \"3.12\""},
]
python-dateutil = ">=2.8.2"

View File

@@ -1,6 +1,6 @@
[project]
name = "crewai"
version = "0.76.9"
version = "0.80.0"
description = "Cutting-edge framework for orchestrating role-playing, autonomous AI agents. By fostering collaborative intelligence, CrewAI empowers agents to work together seamlessly, tackling complex tasks."
readme = "README.md"
requires-python = ">=3.10,<=3.13"
@@ -16,7 +16,7 @@ dependencies = [
"opentelemetry-exporter-otlp-proto-http>=1.22.0",
"instructor>=1.3.3",
"regex>=2024.9.11",
"crewai-tools>=0.13.4",
"crewai-tools>=0.14.0",
"click>=8.1.7",
"python-dotenv>=1.0.0",
"appdirs>=1.4.4",
@@ -27,8 +27,8 @@ dependencies = [
"pyvis>=0.3.2",
"uv>=0.4.25",
"tomli-w>=1.1.0",
"chromadb>=0.4.24",
"tomli>=2.0.2",
"chromadb>=0.5.18",
]
[project.urls]
@@ -37,8 +37,19 @@ Documentation = "https://docs.crewai.com"
Repository = "https://github.com/crewAIInc/crewAI"
[project.optional-dependencies]
tools = ["crewai-tools>=0.13.4"]
tools = ["crewai-tools>=0.14.0"]
agentops = ["agentops>=0.3.0"]
fastembed = ["fastembed>=0.4.1"]
pdfplumber = [
"pdfplumber>=0.11.4",
]
pandas = [
"pandas>=2.2.3",
]
openpyxl = [
"openpyxl>=3.1.5",
]
mem0 = ["mem0ai>=0.1.29"]
[tool.uv]
dev-dependencies = [
@@ -52,7 +63,7 @@ dev-dependencies = [
"mkdocs-material-extensions>=1.3.1",
"pillow>=10.2.0",
"cairosvg>=2.7.1",
"crewai-tools>=0.13.4",
"crewai-tools>=0.14.0",
"pytest>=8.0.0",
"pytest-vcr>=1.0.2",
"python-dotenv>=1.0.0",

View File

@@ -1,7 +1,9 @@
import warnings
from crewai.agent import Agent
from crewai.crew import Crew
from crewai.flow.flow import Flow
from crewai.knowledge.knowledge import Knowledge
from crewai.llm import LLM
from crewai.pipeline import Pipeline
from crewai.process import Process
@@ -14,5 +16,15 @@ warnings.filterwarnings(
category=UserWarning,
module="pydantic.main",
)
__version__ = "0.76.9"
__all__ = ["Agent", "Crew", "Process", "Task", "Pipeline", "Router", "LLM", "Flow"]
__version__ = "0.80.0"
__all__ = [
"Agent",
"Crew",
"Process",
"Task",
"Pipeline",
"Router",
"LLM",
"Flow",
"Knowledge",
]

View File

@@ -8,10 +8,11 @@ from pydantic import Field, InstanceOf, PrivateAttr, model_validator
from crewai.agents import CacheHandler
from crewai.agents.agent_builder.base_agent import BaseAgent
from crewai.agents.crew_agent_executor import CrewAgentExecutor
from crewai.cli.constants import ENV_VARS
from crewai.llm import LLM
from crewai.memory.contextual.contextual_memory import ContextualMemory
from crewai.tools.agent_tools.agent_tools import AgentTools
from crewai.tools import BaseTool
from crewai.tools.agent_tools.agent_tools import AgentTools
from crewai.utilities import Converter, Prompts
from crewai.utilities.constants import TRAINED_AGENTS_DATA_FILE, TRAINING_DATA_FILE
from crewai.utilities.token_counter_callback import TokenCalcHandler
@@ -51,6 +52,7 @@ class Agent(BaseAgent):
role: The role of the agent.
goal: The objective of the agent.
backstory: The backstory of the agent.
knowledge: The knowledge base of the agent.
config: Dict representation of agent configuration.
llm: The language model that will run the agent.
function_calling_llm: The language model that will handle the tool calling for this agent, it overrides the crew function_calling_llm.
@@ -122,6 +124,11 @@ class Agent(BaseAgent):
@model_validator(mode="after")
def post_init_setup(self):
self.agent_ops_agent_name = self.role
unnacepted_attributes = [
"AWS_ACCESS_KEY_ID",
"AWS_SECRET_ACCESS_KEY",
"AWS_REGION_NAME",
]
# Handle different cases for self.llm
if isinstance(self.llm, str):
@@ -131,8 +138,12 @@ class Agent(BaseAgent):
# If it's already an LLM instance, keep it as is
pass
elif self.llm is None:
# If it's None, use environment variables or default
model_name = os.environ.get("OPENAI_MODEL_NAME", "gpt-4o-mini")
# Determine the model name from environment variables or use default
model_name = (
os.environ.get("OPENAI_MODEL_NAME")
or os.environ.get("MODEL")
or "gpt-4o-mini"
)
llm_params = {"model": model_name}
api_base = os.environ.get("OPENAI_API_BASE") or os.environ.get(
@@ -141,9 +152,44 @@ class Agent(BaseAgent):
if api_base:
llm_params["base_url"] = api_base
api_key = os.environ.get("OPENAI_API_KEY")
if api_key:
llm_params["api_key"] = api_key
set_provider = model_name.split("/")[0] if "/" in model_name else "openai"
# Iterate over all environment variables to find matching API keys or use defaults
for provider, env_vars in ENV_VARS.items():
if provider == set_provider:
for env_var in env_vars:
if env_var["key_name"] in unnacepted_attributes:
continue
# Check if the environment variable is set
if "key_name" in env_var:
env_value = os.environ.get(env_var["key_name"])
if env_value:
# Map key names containing "API_KEY" to "api_key"
key_name = (
"api_key"
if "API_KEY" in env_var["key_name"]
else env_var["key_name"]
)
# Map key names containing "API_BASE" to "api_base"
key_name = (
"api_base"
if "API_BASE" in env_var["key_name"]
else key_name
)
# Map key names containing "API_VERSION" to "api_version"
key_name = (
"api_version"
if "API_VERSION" in env_var["key_name"]
else key_name
)
llm_params[key_name] = env_value
# Check for default values if the environment variable is not set
elif env_var.get("default", False):
for key, value in env_var.items():
if key not in ["prompt", "key_name", "default"]:
# Only add default if the key is already set in os.environ
if key in os.environ:
llm_params[key] = value
self.llm = LLM(**llm_params)
else:
@@ -217,14 +263,28 @@ class Agent(BaseAgent):
if self.crew and self.crew.memory:
contextual_memory = ContextualMemory(
self.crew.memory_config,
self.crew._short_term_memory,
self.crew._long_term_memory,
self.crew._entity_memory,
self.crew._user_memory,
)
memory = contextual_memory.build_context_for_task(task, context)
if memory.strip() != "":
task_prompt += self.i18n.slice("memory").format(memory=memory)
# Integrate the knowledge base
if self.crew and self.crew.knowledge:
knowledge_snippets = self.crew.knowledge.query([task.prompt()])
valid_snippets = [
result["context"]
for result in knowledge_snippets
if result and result.get("context")
]
if valid_snippets:
formatted_knowledge = "\n".join(valid_snippets)
task_prompt += f"\n\nAdditional Information:\n{formatted_knowledge}"
tools = tools or self.tools or []
self.create_agent_executor(tools=tools, task=task)

View File

@@ -4,6 +4,7 @@ from crewai.types.usage_metrics import UsageMetrics
class TokenProcess:
total_tokens: int = 0
prompt_tokens: int = 0
cached_prompt_tokens: int = 0
completion_tokens: int = 0
successful_requests: int = 0
@@ -15,6 +16,9 @@ class TokenProcess:
self.completion_tokens = self.completion_tokens + tokens
self.total_tokens = self.total_tokens + tokens
def sum_cached_prompt_tokens(self, tokens: int):
self.cached_prompt_tokens = self.cached_prompt_tokens + tokens
def sum_successful_requests(self, requests: int):
self.successful_requests = self.successful_requests + requests
@@ -22,6 +26,7 @@ class TokenProcess:
return UsageMetrics(
total_tokens=self.total_tokens,
prompt_tokens=self.prompt_tokens,
cached_prompt_tokens=self.cached_prompt_tokens,
completion_tokens=self.completion_tokens,
successful_requests=self.successful_requests,
)

View File

@@ -117,6 +117,15 @@ class CrewAgentExecutor(CrewAgentExecutorMixin):
callbacks=self.callbacks,
)
if answer is None or answer == "":
self._printer.print(
content="Received None or empty response from LLM call.",
color="red",
)
raise ValueError(
"Invalid response from LLM call - None or empty."
)
if not self.use_stop_words:
try:
self._format_answer(answer)
@@ -136,25 +145,26 @@ class CrewAgentExecutor(CrewAgentExecutorMixin):
formatted_answer.result = action_result
self._show_logs(formatted_answer)
if self.step_callback:
self.step_callback(formatted_answer)
if self.step_callback:
self.step_callback(formatted_answer)
if self._should_force_answer():
if self.have_forced_answer:
return AgentFinish(
output=self._i18n.errors(
"force_final_answer_error"
).format(formatted_answer.text),
text=formatted_answer.text,
)
else:
formatted_answer.text += (
f'\n{self._i18n.errors("force_final_answer")}'
)
self.have_forced_answer = True
self.messages.append(
self._format_msg(formatted_answer.text, role="assistant")
)
if self._should_force_answer():
if self.have_forced_answer:
return AgentFinish(
thought="",
output=self._i18n.errors(
"force_final_answer_error"
).format(formatted_answer.text),
text=formatted_answer.text,
)
else:
formatted_answer.text += (
f'\n{self._i18n.errors("force_final_answer")}'
)
self.have_forced_answer = True
self.messages.append(
self._format_msg(formatted_answer.text, role="assistant")
)
except OutputParserException as e:
self.messages.append({"role": "user", "content": e.error})
@@ -323,9 +333,9 @@ class CrewAgentExecutor(CrewAgentExecutorMixin):
if self.crew is not None and hasattr(self.crew, "_train_iteration"):
train_iteration = self.crew._train_iteration
if agent_id in training_data and isinstance(train_iteration, int):
training_data[agent_id][train_iteration][
"improved_output"
] = result.output
training_data[agent_id][train_iteration]["improved_output"] = (
result.output
)
training_handler.save(training_data)
else:
self._logger.log(
@@ -376,4 +386,5 @@ class CrewAgentExecutor(CrewAgentExecutorMixin):
return CrewAgentParser(agent=self.agent).parse(answer)
def _format_msg(self, prompt: str, role: str = "user") -> Dict[str, str]:
prompt = prompt.rstrip()
return {"role": role, "content": prompt}

View File

@@ -54,7 +54,7 @@ def create_embedded_crew(crew_name: str, parent_folder: Path) -> None:
templates_dir = Path(__file__).parent / "templates" / "crew"
config_template_files = ["agents.yaml", "tasks.yaml"]
crew_template_file = f"{folder_name}_crew.py" # Updated file name
crew_template_file = f"{folder_name}.py" # Updated file name
for file_name in config_template_files:
src_file = templates_dir / "config" / file_name

View File

@@ -34,7 +34,9 @@ class AuthenticationCommand:
"scope": "openid",
"audience": AUTH0_AUDIENCE,
}
response = requests.post(url=self.DEVICE_CODE_URL, data=device_code_payload)
response = requests.post(
url=self.DEVICE_CODE_URL, data=device_code_payload, timeout=20
)
response.raise_for_status()
return response.json()
@@ -54,7 +56,7 @@ class AuthenticationCommand:
attempts = 0
while True and attempts < 5:
response = requests.post(self.TOKEN_URL, data=token_payload)
response = requests.post(self.TOKEN_URL, data=token_payload, timeout=30)
token_data = response.json()
if response.status_code == 200:

View File

@@ -136,6 +136,7 @@ def log_tasks_outputs() -> None:
@click.option("-l", "--long", is_flag=True, help="Reset LONG TERM memory")
@click.option("-s", "--short", is_flag=True, help="Reset SHORT TERM memory")
@click.option("-e", "--entities", is_flag=True, help="Reset ENTITIES memory")
@click.option("-kn", "--knowledge", is_flag=True, help="Reset KNOWLEDGE storage")
@click.option(
"-k",
"--kickoff-outputs",
@@ -143,17 +144,24 @@ def log_tasks_outputs() -> None:
help="Reset LATEST KICKOFF TASK OUTPUTS",
)
@click.option("-a", "--all", is_flag=True, help="Reset ALL memories")
def reset_memories(long, short, entities, kickoff_outputs, all):
def reset_memories(
long: bool,
short: bool,
entities: bool,
knowledge: bool,
kickoff_outputs: bool,
all: bool,
) -> None:
"""
Reset the crew memories (long, short, entity, latest_crew_kickoff_ouputs). This will delete all the data saved.
"""
try:
if not all and not (long or short or entities or kickoff_outputs):
if not all and not (long or short or entities or knowledge or kickoff_outputs):
click.echo(
"Please specify at least one memory type to reset using the appropriate flags."
)
return
reset_memories_command(long, short, entities, kickoff_outputs, all)
reset_memories_command(long, short, entities, knowledge, kickoff_outputs, all)
except Exception as e:
click.echo(f"An error occurred while resetting memories: {e}", err=True)

View File

@@ -1,19 +1,161 @@
ENV_VARS = {
'openai': ['OPENAI_API_KEY'],
'anthropic': ['ANTHROPIC_API_KEY'],
'gemini': ['GEMINI_API_KEY'],
'groq': ['GROQ_API_KEY'],
'ollama': ['FAKE_KEY'],
"openai": [
{
"prompt": "Enter your OPENAI API key (press Enter to skip)",
"key_name": "OPENAI_API_KEY",
}
],
"anthropic": [
{
"prompt": "Enter your ANTHROPIC API key (press Enter to skip)",
"key_name": "ANTHROPIC_API_KEY",
}
],
"gemini": [
{
"prompt": "Enter your GEMINI API key (press Enter to skip)",
"key_name": "GEMINI_API_KEY",
}
],
"groq": [
{
"prompt": "Enter your GROQ API key (press Enter to skip)",
"key_name": "GROQ_API_KEY",
}
],
"watson": [
{
"prompt": "Enter your WATSONX URL (press Enter to skip)",
"key_name": "WATSONX_URL",
},
{
"prompt": "Enter your WATSONX API Key (press Enter to skip)",
"key_name": "WATSONX_APIKEY",
},
{
"prompt": "Enter your WATSONX Project Id (press Enter to skip)",
"key_name": "WATSONX_PROJECT_ID",
},
],
"ollama": [
{
"default": True,
"API_BASE": "http://localhost:11434",
}
],
"bedrock": [
{
"prompt": "Enter your AWS Access Key ID (press Enter to skip)",
"key_name": "AWS_ACCESS_KEY_ID",
},
{
"prompt": "Enter your AWS Secret Access Key (press Enter to skip)",
"key_name": "AWS_SECRET_ACCESS_KEY",
},
{
"prompt": "Enter your AWS Region Name (press Enter to skip)",
"key_name": "AWS_REGION_NAME",
},
],
"azure": [
{
"prompt": "Enter your Azure deployment name (must start with 'azure/')",
"key_name": "model",
},
{
"prompt": "Enter your AZURE API key (press Enter to skip)",
"key_name": "AZURE_API_KEY",
},
{
"prompt": "Enter your AZURE API base URL (press Enter to skip)",
"key_name": "AZURE_API_BASE",
},
{
"prompt": "Enter your AZURE API version (press Enter to skip)",
"key_name": "AZURE_API_VERSION",
},
],
"cerebras": [
{
"prompt": "Enter your Cerebras model name (must start with 'cerebras/')",
"key_name": "model",
},
{
"prompt": "Enter your Cerebras API version (press Enter to skip)",
"key_name": "CEREBRAS_API_KEY",
},
],
}
PROVIDERS = ['openai', 'anthropic', 'gemini', 'groq', 'ollama']
PROVIDERS = [
"openai",
"anthropic",
"gemini",
"groq",
"ollama",
"watson",
"bedrock",
"azure",
"cerebras",
]
MODELS = {
'openai': ['gpt-4', 'gpt-4o', 'gpt-4o-mini', 'o1-mini', 'o1-preview'],
'anthropic': ['claude-3-5-sonnet-20240620', 'claude-3-sonnet-20240229', 'claude-3-opus-20240229', 'claude-3-haiku-20240307'],
'gemini': ['gemini-1.5-flash', 'gemini-1.5-pro', 'gemini-gemma-2-9b-it', 'gemini-gemma-2-27b-it'],
'groq': ['llama-3.1-8b-instant', 'llama-3.1-70b-versatile', 'llama-3.1-405b-reasoning', 'gemma2-9b-it', 'gemma-7b-it'],
'ollama': ['llama3.1', 'mixtral'],
"openai": ["gpt-4", "gpt-4o", "gpt-4o-mini", "o1-mini", "o1-preview"],
"anthropic": [
"claude-3-5-sonnet-20240620",
"claude-3-sonnet-20240229",
"claude-3-opus-20240229",
"claude-3-haiku-20240307",
],
"gemini": [
"gemini/gemini-1.5-flash",
"gemini/gemini-1.5-pro",
"gemini/gemini-gemma-2-9b-it",
"gemini/gemini-gemma-2-27b-it",
],
"groq": [
"groq/llama-3.1-8b-instant",
"groq/llama-3.1-70b-versatile",
"groq/llama-3.1-405b-reasoning",
"groq/gemma2-9b-it",
"groq/gemma-7b-it",
],
"ollama": ["ollama/llama3.1", "ollama/mixtral"],
"watson": [
"watsonx/meta-llama/llama-3-1-70b-instruct",
"watsonx/meta-llama/llama-3-1-8b-instruct",
"watsonx/meta-llama/llama-3-2-11b-vision-instruct",
"watsonx/meta-llama/llama-3-2-1b-instruct",
"watsonx/meta-llama/llama-3-2-90b-vision-instruct",
"watsonx/meta-llama/llama-3-405b-instruct",
"watsonx/mistral/mistral-large",
"watsonx/ibm/granite-3-8b-instruct",
],
"bedrock": [
"bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0",
"bedrock/anthropic.claude-3-sonnet-20240229-v1:0",
"bedrock/anthropic.claude-3-haiku-20240307-v1:0",
"bedrock/anthropic.claude-3-opus-20240229-v1:0",
"bedrock/anthropic.claude-v2:1",
"bedrock/anthropic.claude-v2",
"bedrock/anthropic.claude-instant-v1",
"bedrock/meta.llama3-1-405b-instruct-v1:0",
"bedrock/meta.llama3-1-70b-instruct-v1:0",
"bedrock/meta.llama3-1-8b-instruct-v1:0",
"bedrock/meta.llama3-70b-instruct-v1:0",
"bedrock/meta.llama3-8b-instruct-v1:0",
"bedrock/amazon.titan-text-lite-v1",
"bedrock/amazon.titan-text-express-v1",
"bedrock/cohere.command-text-v14",
"bedrock/ai21.j2-mid-v1",
"bedrock/ai21.j2-ultra-v1",
"bedrock/ai21.jamba-instruct-v1:0",
"bedrock/meta.llama2-13b-chat-v1",
"bedrock/meta.llama2-70b-chat-v1",
"bedrock/mistral.mistral-7b-instruct-v0:2",
"bedrock/mistral.mixtral-8x7b-instruct-v0:1",
],
}
JSON_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
JSON_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"

View File

@@ -1,11 +1,11 @@
import shutil
import sys
from pathlib import Path
import click
from crewai.cli.constants import ENV_VARS
from crewai.cli.constants import ENV_VARS, MODELS
from crewai.cli.provider import (
PROVIDERS,
get_provider_data,
select_model,
select_provider,
@@ -29,20 +29,20 @@ def create_folder_structure(name, parent_folder=None):
click.secho("Operation cancelled.", fg="yellow")
sys.exit(0)
click.secho(f"Overriding folder {folder_name}...", fg="green", bold=True)
else:
click.secho(
f"Creating {'crew' if parent_folder else 'folder'} {folder_name}...",
fg="green",
bold=True,
)
shutil.rmtree(folder_path) # Delete the existing folder and its contents
if not folder_path.exists():
folder_path.mkdir(parents=True)
(folder_path / "tests").mkdir(exist_ok=True)
if not parent_folder:
(folder_path / "src" / folder_name).mkdir(parents=True)
(folder_path / "src" / folder_name / "tools").mkdir(parents=True)
(folder_path / "src" / folder_name / "config").mkdir(parents=True)
click.secho(
f"Creating {'crew' if parent_folder else 'folder'} {folder_name}...",
fg="green",
bold=True,
)
folder_path.mkdir(parents=True)
(folder_path / "tests").mkdir(exist_ok=True)
if not parent_folder:
(folder_path / "src" / folder_name).mkdir(parents=True)
(folder_path / "src" / folder_name / "tools").mkdir(parents=True)
(folder_path / "src" / folder_name / "config").mkdir(parents=True)
return folder_path, folder_name, class_name
@@ -92,7 +92,10 @@ def create_crew(name, provider=None, skip_provider=False, parent_folder=None):
existing_provider = None
for provider, env_keys in ENV_VARS.items():
if any(key in env_vars for key in env_keys):
if any(
"key_name" in details and details["key_name"] in env_vars
for details in env_keys
):
existing_provider = provider
break
@@ -118,47 +121,48 @@ def create_crew(name, provider=None, skip_provider=False, parent_folder=None):
"No provider selected. Please try again or press 'q' to exit.", fg="red"
)
while True:
selected_model = select_model(selected_provider, provider_models)
if selected_model is None: # User typed 'q'
click.secho("Exiting...", fg="yellow")
sys.exit(0)
if selected_model: # Valid selection
break
click.secho(
"No model selected. Please try again or press 'q' to exit.", fg="red"
)
# Check if the selected provider has predefined models
if selected_provider in MODELS and MODELS[selected_provider]:
while True:
selected_model = select_model(selected_provider, provider_models)
if selected_model is None: # User typed 'q'
click.secho("Exiting...", fg="yellow")
sys.exit(0)
if selected_model: # Valid selection
break
click.secho(
"No model selected. Please try again or press 'q' to exit.",
fg="red",
)
env_vars["MODEL"] = selected_model
if selected_provider in PROVIDERS:
api_key_var = ENV_VARS[selected_provider][0]
else:
api_key_var = click.prompt(
f"Enter the environment variable name for your {selected_provider.capitalize()} API key",
type=str,
default="",
)
# Check if the selected provider requires API keys
if selected_provider in ENV_VARS:
provider_env_vars = ENV_VARS[selected_provider]
for details in provider_env_vars:
if details.get("default", False):
# Automatically add default key-value pairs
for key, value in details.items():
if key not in ["prompt", "key_name", "default"]:
env_vars[key] = value
elif "key_name" in details:
# Prompt for non-default key-value pairs
prompt = details["prompt"]
key_name = details["key_name"]
api_key_value = click.prompt(prompt, default="", show_default=False)
api_key_value = ""
click.echo(
f"Enter your {selected_provider.capitalize()} API key (press Enter to skip): ",
nl=False,
)
try:
api_key_value = input()
except (KeyboardInterrupt, EOFError):
api_key_value = ""
if api_key_value.strip():
env_vars[key_name] = api_key_value
if api_key_value.strip():
env_vars = {api_key_var: api_key_value}
if env_vars:
write_env_file(folder_path, env_vars)
click.secho("API key saved to .env file", fg="green")
click.secho("API keys and model saved to .env file", fg="green")
else:
click.secho(
"No API key provided. Skipping .env file creation.", fg="yellow"
"No API keys provided. Skipping .env file creation.", fg="yellow"
)
env_vars["MODEL"] = selected_model
click.secho(f"Selected model: {selected_model}", fg="green")
click.secho(f"Selected model: {env_vars.get('MODEL', 'N/A')}", fg="green")
package_dir = Path(__file__).parent
templates_dir = package_dir / "templates" / "crew"

View File

@@ -164,7 +164,7 @@ def fetch_provider_data(cache_file):
- dict or None: The fetched provider data or None if the operation fails.
"""
try:
response = requests.get(JSON_URL, stream=True, timeout=10)
response = requests.get(JSON_URL, stream=True, timeout=60)
response.raise_for_status()
data = download_data(response)
with open(cache_file, "w") as f:

View File

@@ -5,9 +5,17 @@ from crewai.memory.entity.entity_memory import EntityMemory
from crewai.memory.long_term.long_term_memory import LongTermMemory
from crewai.memory.short_term.short_term_memory import ShortTermMemory
from crewai.utilities.task_output_storage_handler import TaskOutputStorageHandler
from crewai.knowledge.storage.knowledge_storage import KnowledgeStorage
def reset_memories_command(long, short, entity, kickoff_outputs, all) -> None:
def reset_memories_command(
long,
short,
entity,
knowledge,
kickoff_outputs,
all,
) -> None:
"""
Reset the crew memories.
@@ -17,6 +25,7 @@ def reset_memories_command(long, short, entity, kickoff_outputs, all) -> None:
entity (bool): Whether to reset the entity memory.
kickoff_outputs (bool): Whether to reset the latest kickoff task outputs.
all (bool): Whether to reset all memories.
knowledge (bool): Whether to reset the knowledge.
"""
try:
@@ -25,6 +34,7 @@ def reset_memories_command(long, short, entity, kickoff_outputs, all) -> None:
EntityMemory().reset()
LongTermMemory().reset()
TaskOutputStorageHandler().reset()
KnowledgeStorage().reset()
click.echo("All memories have been reset.")
else:
if long:
@@ -40,6 +50,9 @@ def reset_memories_command(long, short, entity, kickoff_outputs, all) -> None:
if kickoff_outputs:
TaskOutputStorageHandler().reset()
click.echo("Latest Kickoff outputs stored has been reset.")
if knowledge:
KnowledgeStorage().reset()
click.echo("Knowledge has been reset.")
except subprocess.CalledProcessError as e:
click.echo(f"An error occurred while resetting the memories: {e}", err=True)

View File

@@ -24,7 +24,6 @@ def run_crew() -> None:
f"Please run `crewai update` to update your pyproject.toml to use uv.",
fg="red",
)
print()
try:
subprocess.run(command, capture_output=False, text=True, check=True)

View File

@@ -8,9 +8,12 @@ from crewai.project import CrewBase, agent, crew, task
# from crewai_tools import SerperDevTool
@CrewBase
class {{crew_name}}Crew():
class {{crew_name}}():
"""{{crew_name}} crew"""
agents_config = 'config/agents.yaml'
tasks_config = 'config/tasks.yaml'
@agent
def researcher(self) -> Agent:
return Agent(
@@ -48,4 +51,4 @@ class {{crew_name}}Crew():
process=Process.sequential,
verbose=True,
# process=Process.hierarchical, # In case you wanna use that instead https://docs.crewai.com/how-to/Hierarchical/
)
)

View File

@@ -1,6 +1,10 @@
#!/usr/bin/env python
import sys
from {{folder_name}}.crew import {{crew_name}}Crew
import warnings
from {{folder_name}}.crew import {{crew_name}}
warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd")
# This main file is intended to be a way for you to run your
# crew locally, so refrain from adding unnecessary logic into this file.
@@ -14,7 +18,7 @@ def run():
inputs = {
'topic': 'AI LLMs'
}
{{crew_name}}Crew().crew().kickoff(inputs=inputs)
{{crew_name}}().crew().kickoff(inputs=inputs)
def train():
@@ -25,7 +29,7 @@ def train():
"topic": "AI LLMs"
}
try:
{{crew_name}}Crew().crew().train(n_iterations=int(sys.argv[1]), filename=sys.argv[2], inputs=inputs)
{{crew_name}}().crew().train(n_iterations=int(sys.argv[1]), filename=sys.argv[2], inputs=inputs)
except Exception as e:
raise Exception(f"An error occurred while training the crew: {e}")
@@ -35,7 +39,7 @@ def replay():
Replay the crew execution from a specific task.
"""
try:
{{crew_name}}Crew().crew().replay(task_id=sys.argv[1])
{{crew_name}}().crew().replay(task_id=sys.argv[1])
except Exception as e:
raise Exception(f"An error occurred while replaying the crew: {e}")
@@ -48,7 +52,7 @@ def test():
"topic": "AI LLMs"
}
try:
{{crew_name}}Crew().crew().test(n_iterations=int(sys.argv[1]), openai_model_name=sys.argv[2], inputs=inputs)
{{crew_name}}().crew().test(n_iterations=int(sys.argv[1]), openai_model_name=sys.argv[2], inputs=inputs)
except Exception as e:
raise Exception(f"An error occurred while replaying the crew: {e}")

View File

@@ -5,7 +5,7 @@ description = "{{name}} using crewAI"
authors = [{ name = "Your Name", email = "you@example.com" }]
requires-python = ">=3.10,<=3.13"
dependencies = [
"crewai[tools]>=0.76.9,<1.0.0"
"crewai[tools]>=0.80.0,<1.0.0"
]
[project.scripts]

View File

@@ -5,7 +5,7 @@ description = "{{name}} using crewAI"
authors = [{ name = "Your Name", email = "you@example.com" }]
requires-python = ">=3.10,<=3.13"
dependencies = [
"crewai[tools]>=0.76.9,<1.0.0",
"crewai[tools]>=0.80.0,<1.0.0",
]
[project.scripts]

View File

@@ -6,7 +6,7 @@ authors = ["Your Name <you@example.com>"]
[tool.poetry.dependencies]
python = ">=3.10,<=3.13"
crewai = { extras = ["tools"], version = ">=0.76.9,<1.0.0" }
crewai = { extras = ["tools"], version = ">=0.80.0,<1.0.0" }
asyncio = "*"
[tool.poetry.scripts]

View File

@@ -5,7 +5,7 @@ description = "{{name}} using crewAI"
authors = ["Your Name <you@example.com>"]
requires-python = ">=3.10,<=3.13"
dependencies = [
"crewai[tools]>=0.76.9,<1.0.0"
"crewai[tools]>=0.80.0,<1.0.0"
]
[project.scripts]

View File

@@ -5,6 +5,6 @@ description = "Power up your crews with {{folder_name}}"
readme = "README.md"
requires-python = ">=3.10,<=3.13"
dependencies = [
"crewai[tools]>=0.76.9"
"crewai[tools]>=0.80.0"
]

View File

@@ -5,7 +5,7 @@ import uuid
import warnings
from concurrent.futures import Future
from hashlib import md5
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Union
from pydantic import (
UUID4,
@@ -27,6 +27,8 @@ from crewai.llm import LLM
from crewai.memory.entity.entity_memory import EntityMemory
from crewai.memory.long_term.long_term_memory import LongTermMemory
from crewai.memory.short_term.short_term_memory import ShortTermMemory
from crewai.knowledge.knowledge import Knowledge
from crewai.memory.user.user_memory import UserMemory
from crewai.process import Process
from crewai.task import Task
from crewai.tasks.conditional_task import ConditionalTask
@@ -35,9 +37,7 @@ from crewai.telemetry import Telemetry
from crewai.tools.agent_tools.agent_tools import AgentTools
from crewai.types.usage_metrics import UsageMetrics
from crewai.utilities import I18N, FileHandler, Logger, RPMController
from crewai.utilities.constants import (
TRAINING_DATA_FILE,
)
from crewai.utilities.constants import TRAINING_DATA_FILE
from crewai.utilities.evaluators.crew_evaluator_handler import CrewEvaluator
from crewai.utilities.evaluators.task_evaluator import TaskEvaluator
from crewai.utilities.formatter import (
@@ -71,6 +71,7 @@ class Crew(BaseModel):
manager_llm: The language model that will run manager agent.
manager_agent: Custom agent that will be used as manager.
memory: Whether the crew should use memory to store memories of it's execution.
memory_config: Configuration for the memory to be used for the crew.
cache: Whether the crew should use a cache to store the results of the tools execution.
function_calling_llm: The language model that will run the tool calling for all the agents.
process: The process flow that the crew will follow (e.g., sequential, hierarchical).
@@ -94,6 +95,7 @@ class Crew(BaseModel):
_short_term_memory: Optional[InstanceOf[ShortTermMemory]] = PrivateAttr()
_long_term_memory: Optional[InstanceOf[LongTermMemory]] = PrivateAttr()
_entity_memory: Optional[InstanceOf[EntityMemory]] = PrivateAttr()
_user_memory: Optional[InstanceOf[UserMemory]] = PrivateAttr()
_train: Optional[bool] = PrivateAttr(default=False)
_train_iteration: Optional[int] = PrivateAttr()
_inputs: Optional[Dict[str, Any]] = PrivateAttr(default=None)
@@ -114,6 +116,10 @@ class Crew(BaseModel):
default=False,
description="Whether the crew should use memory to store memories of it's execution",
)
memory_config: Optional[Dict[str, Any]] = Field(
default=None,
description="Configuration for the memory to be used for the crew.",
)
short_term_memory: Optional[InstanceOf[ShortTermMemory]] = Field(
default=None,
description="An Instance of the ShortTermMemory to be used by the Crew",
@@ -126,7 +132,11 @@ class Crew(BaseModel):
default=None,
description="An Instance of the EntityMemory to be used by the Crew",
)
embedder: Optional[Any] = Field(
user_memory: Optional[InstanceOf[UserMemory]] = Field(
default=None,
description="An instance of the UserMemory to be used by the Crew to store/fetch memories of a specific user.",
)
embedder: Optional[dict] = Field(
default=None,
description="Configuration for the embedder to be used for the crew.",
)
@@ -154,6 +164,16 @@ class Crew(BaseModel):
default=None,
description="Callback to be executed after each task for all agents execution.",
)
before_kickoff_callbacks: List[
Callable[[Optional[Dict[str, Any]]], Optional[Dict[str, Any]]]
] = Field(
default_factory=list,
description="List of callbacks to be executed before crew kickoff. It may be used to adjust inputs before the crew is executed.",
)
after_kickoff_callbacks: List[Callable[[CrewOutput], CrewOutput]] = Field(
default_factory=list,
description="List of callbacks to be executed after crew kickoff. It may be used to adjust the output of the crew.",
)
max_rpm: Optional[int] = Field(
default=None,
description="Maximum number of requests per minute for the crew execution to be respected.",
@@ -182,6 +202,10 @@ class Crew(BaseModel):
default=[],
description="List of execution logs for tasks",
)
knowledge: Optional[Dict[str, Any]] = Field(
default=None, description="Knowledge for the crew. Add knowledge sources to the knowledge object."
)
@field_validator("id", mode="before")
@classmethod
@@ -238,13 +262,31 @@ class Crew(BaseModel):
self._short_term_memory = (
self.short_term_memory
if self.short_term_memory
else ShortTermMemory(crew=self, embedder_config=self.embedder)
else ShortTermMemory(
crew=self,
embedder_config=self.embedder,
)
)
self._entity_memory = (
self.entity_memory
if self.entity_memory
else EntityMemory(crew=self, embedder_config=self.embedder)
)
if hasattr(self, "memory_config") and self.memory_config is not None:
self._user_memory = (
self.user_memory if self.user_memory else UserMemory(crew=self)
)
else:
self._user_memory = None
return self
@model_validator(mode="after")
def create_crew_knowledge(self) -> "Crew":
if self.knowledge:
try:
self.knowledge = Knowledge(**self.knowledge) if isinstance(self.knowledge, dict) else self.knowledge
except (TypeError, ValueError) as e:
raise ValueError(f"Invalid knowledge configuration: {str(e)}")
return self
@model_validator(mode="after")
@@ -445,18 +487,22 @@ class Crew(BaseModel):
training_data = CrewTrainingHandler(TRAINING_DATA_FILE).load()
for agent in train_crew.agents:
result = TaskEvaluator(agent).evaluate_training_data(
training_data=training_data, agent_id=str(agent.id)
)
if training_data.get(str(agent.id)):
result = TaskEvaluator(agent).evaluate_training_data(
training_data=training_data, agent_id=str(agent.id)
)
CrewTrainingHandler(filename).save_trained_data(
agent_id=str(agent.role), trained_data=result.model_dump()
)
CrewTrainingHandler(filename).save_trained_data(
agent_id=str(agent.role), trained_data=result.model_dump()
)
def kickoff(
self,
inputs: Optional[Dict[str, Any]] = None,
) -> CrewOutput:
for before_callback in self.before_kickoff_callbacks:
inputs = before_callback(inputs)
"""Starts the crew to work on its assigned tasks."""
self._execution_span = self._telemetry.crew_execution_span(self, inputs)
self._task_output_handler.reset()
@@ -499,6 +545,9 @@ class Crew(BaseModel):
f"The process '{self.process}' is not implemented yet."
)
for after_callback in self.after_kickoff_callbacks:
result = after_callback(result)
metrics += [agent._token_process.get_summary() for agent in self.agents]
self.usage_metrics = UsageMetrics()

View File

@@ -1,8 +1,20 @@
import asyncio
import inspect
from typing import Any, Callable, Dict, Generic, List, Set, Type, TypeVar, Union
from typing import (
Any,
Callable,
Dict,
Generic,
List,
Optional,
Set,
Type,
TypeVar,
Union,
cast,
)
from pydantic import BaseModel
from pydantic import BaseModel, ValidationError
from crewai.flow.flow_visualizer import plot_flow
from crewai.flow.utils import get_possible_return_constants
@@ -119,7 +131,6 @@ class FlowMeta(type):
condition_type = getattr(attr_value, "__condition_type__", "OR")
listeners[attr_name] = (condition_type, methods)
# TODO: should we add a check for __condition_type__ 'AND'?
elif hasattr(attr_value, "__is_router__"):
routers[attr_value.__router_for__] = attr_name
possible_returns = get_possible_return_constants(attr_value)
@@ -159,8 +170,7 @@ class Flow(Generic[T], metaclass=FlowMeta):
def __init__(self) -> None:
self._methods: Dict[str, Callable] = {}
self._state: T = self._create_initial_state()
self._executed_methods: Set[str] = set()
self._scheduled_tasks: Set[str] = set()
self._method_execution_counts: Dict[str, int] = {}
self._pending_and_listeners: Dict[str, Set[str]] = {}
self._method_outputs: List[Any] = [] # List to store all method outputs
@@ -191,10 +201,74 @@ class Flow(Generic[T], metaclass=FlowMeta):
"""Returns the list of all outputs from executed methods."""
return self._method_outputs
def kickoff(self) -> Any:
def _initialize_state(self, inputs: Dict[str, Any]) -> None:
"""
Initializes or updates the state with the provided inputs.
Args:
inputs: Dictionary of inputs to initialize or update the state.
Raises:
ValueError: If inputs do not match the structured state model.
TypeError: If state is neither a BaseModel instance nor a dictionary.
"""
if isinstance(self._state, BaseModel):
# Structured state management
try:
# Define a function to create the dynamic class
def create_model_with_extra_forbid(
base_model: Type[BaseModel],
) -> Type[BaseModel]:
class ModelWithExtraForbid(base_model): # type: ignore
model_config = base_model.model_config.copy()
model_config["extra"] = "forbid"
return ModelWithExtraForbid
# Create the dynamic class
ModelWithExtraForbid = create_model_with_extra_forbid(
self._state.__class__
)
# Create a new instance using the combined state and inputs
self._state = cast(
T, ModelWithExtraForbid(**{**self._state.model_dump(), **inputs})
)
except ValidationError as e:
raise ValueError(f"Invalid inputs for structured state: {e}") from e
elif isinstance(self._state, dict):
# Unstructured state management
self._state.update(inputs)
else:
raise TypeError("State must be a BaseModel instance or a dictionary.")
def kickoff(self, inputs: Optional[Dict[str, Any]] = None) -> Any:
"""
Starts the execution of the flow synchronously.
Args:
inputs: Optional dictionary of inputs to initialize or update the state.
Returns:
The final output from the flow execution.
"""
if inputs is not None:
self._initialize_state(inputs)
return asyncio.run(self.kickoff_async())
async def kickoff_async(self) -> Any:
async def kickoff_async(self, inputs: Optional[Dict[str, Any]] = None) -> Any:
"""
Starts the execution of the flow asynchronously.
Args:
inputs: Optional dictionary of inputs to initialize or update the state.
Returns:
The final output from the flow execution.
"""
if inputs is not None:
self._initialize_state(inputs)
if not self._start_methods:
raise ValueError("No start method defined")
@@ -233,7 +307,10 @@ class Flow(Generic[T], metaclass=FlowMeta):
)
self._method_outputs.append(result) # Store the output
self._executed_methods.add(method_name)
# Track method execution counts
self._method_execution_counts[method_name] = (
self._method_execution_counts.get(method_name, 0) + 1
)
return result
@@ -243,35 +320,34 @@ class Flow(Generic[T], metaclass=FlowMeta):
if trigger_method in self._routers:
router_method = self._methods[self._routers[trigger_method]]
path = await self._execute_method(
trigger_method, router_method
) # TODO: Change or not?
# Use the path as the new trigger method
self._routers[trigger_method], router_method
)
trigger_method = path
for listener_name, (condition_type, methods) in self._listeners.items():
if condition_type == "OR":
if trigger_method in methods:
if (
listener_name not in self._executed_methods
and listener_name not in self._scheduled_tasks
):
self._scheduled_tasks.add(listener_name)
listener_tasks.append(
self._execute_single_listener(listener_name, result)
)
# Schedule the listener without preventing re-execution
listener_tasks.append(
self._execute_single_listener(listener_name, result)
)
elif condition_type == "AND":
if all(method in self._executed_methods for method in methods):
if (
listener_name not in self._executed_methods
and listener_name not in self._scheduled_tasks
):
self._scheduled_tasks.add(listener_name)
listener_tasks.append(
self._execute_single_listener(listener_name, result)
)
# Initialize pending methods for this listener if not already done
if listener_name not in self._pending_and_listeners:
self._pending_and_listeners[listener_name] = set(methods)
# Remove the trigger method from pending methods
self._pending_and_listeners[listener_name].discard(trigger_method)
if not self._pending_and_listeners[listener_name]:
# All required methods have been executed
listener_tasks.append(
self._execute_single_listener(listener_name, result)
)
# Reset pending methods for this listener
self._pending_and_listeners.pop(listener_name, None)
# Run all listener tasks concurrently and wait for them to complete
await asyncio.gather(*listener_tasks)
if listener_tasks:
await asyncio.gather(*listener_tasks)
async def _execute_single_listener(self, listener_name: str, result: Any) -> None:
try:
@@ -291,9 +367,6 @@ class Flow(Generic[T], metaclass=FlowMeta):
# If listener does not expect parameters, call without arguments
listener_result = await self._execute_method(listener_name, method)
# Remove from scheduled tasks after execution
self._scheduled_tasks.discard(listener_name)
# Execute listeners of this listener
await self._execute_listeners(listener_name, listener_result)
except Exception as e:

View File

View File

@@ -0,0 +1,55 @@
from abc import ABC, abstractmethod
from typing import List
import numpy as np
class BaseEmbedder(ABC):
"""
Abstract base class for text embedding models
"""
@abstractmethod
def embed_chunks(self, chunks: List[str]) -> np.ndarray:
"""
Generate embeddings for a list of text chunks
Args:
chunks: List of text chunks to embed
Returns:
Array of embeddings
"""
pass
@abstractmethod
def embed_texts(self, texts: List[str]) -> np.ndarray:
"""
Generate embeddings for a list of texts
Args:
texts: List of texts to embed
Returns:
Array of embeddings
"""
pass
@abstractmethod
def embed_text(self, text: str) -> np.ndarray:
"""
Generate embedding for a single text
Args:
text: Text to embed
Returns:
Embedding array
"""
pass
@property
@abstractmethod
def dimension(self) -> int:
"""Get the dimension of the embeddings"""
pass

View File

@@ -0,0 +1,93 @@
from pathlib import Path
from typing import List, Optional, Union
import numpy as np
from .base_embedder import BaseEmbedder
try:
from fastembed_gpu import TextEmbedding # type: ignore
FASTEMBED_AVAILABLE = True
except ImportError:
try:
from fastembed import TextEmbedding
FASTEMBED_AVAILABLE = True
except ImportError:
FASTEMBED_AVAILABLE = False
class FastEmbed(BaseEmbedder):
"""
A wrapper class for text embedding models using FastEmbed
"""
def __init__(
self,
model_name: str = "BAAI/bge-small-en-v1.5",
cache_dir: Optional[Union[str, Path]] = None,
):
"""
Initialize the embedding model
Args:
model_name: Name of the model to use
cache_dir: Directory to cache the model
gpu: Whether to use GPU acceleration
"""
if not FASTEMBED_AVAILABLE:
raise ImportError(
"FastEmbed is not installed. Please install it with: "
"uv pip install fastembed or uv pip install fastembed-gpu for GPU support"
)
self.model = TextEmbedding(
model_name=model_name,
cache_dir=str(cache_dir) if cache_dir else None,
)
def embed_chunks(self, chunks: List[str]) -> List[np.ndarray]:
"""
Generate embeddings for a list of text chunks
Args:
chunks: List of text chunks to embed
Returns:
List of embeddings
"""
embeddings = list(self.model.embed(chunks))
return embeddings
def embed_texts(self, texts: List[str]) -> List[np.ndarray]:
"""
Generate embeddings for a list of texts
Args:
texts: List of texts to embed
Returns:
List of embeddings
"""
embeddings = list(self.model.embed(texts))
return embeddings
def embed_text(self, text: str) -> np.ndarray:
"""
Generate embedding for a single text
Args:
text: Text to embed
Returns:
Embedding array
"""
return self.embed_texts([text])[0]
@property
def dimension(self) -> int:
"""Get the dimension of the embeddings"""
# Generate a test embedding to get dimensions
test_embed = self.embed_text("test")
return len(test_embed)

View File

@@ -0,0 +1,54 @@
import os
from typing import List, Optional, Dict, Any
from pydantic import BaseModel, ConfigDict, Field
from crewai.knowledge.source.base_knowledge_source import BaseKnowledgeSource
from crewai.knowledge.storage.knowledge_storage import KnowledgeStorage
from crewai.utilities.logger import Logger
from crewai.utilities.constants import DEFAULT_SCORE_THRESHOLD
os.environ["TOKENIZERS_PARALLELISM"] = "false" # removes logging from fastembed
class Knowledge(BaseModel):
"""
Knowledge is a collection of sources and setup for the vector store to save and query relevant context.
Args:
sources: List[BaseKnowledgeSource] = Field(default_factory=list)
storage: KnowledgeStorage = Field(default_factory=KnowledgeStorage)
embedder_config: Optional[Dict[str, Any]] = None
"""
sources: List[BaseKnowledgeSource] = Field(default_factory=list)
model_config = ConfigDict(arbitrary_types_allowed=True)
storage: KnowledgeStorage = Field(default_factory=KnowledgeStorage)
embedder_config: Optional[Dict[str, Any]] = None
def __init__(self, embedder_config: Optional[Dict[str, Any]] = None, **data):
super().__init__(**data)
self.storage = KnowledgeStorage(embedder_config=embedder_config or None)
try:
for source in self.sources:
source.add()
except Exception as e:
Logger(verbose=True).log(
"warning",
f"Failed to init knowledge: {e}",
color="yellow",
)
def query(
self, query: List[str], limit: int = 3, preference: Optional[str] = None
) -> List[Dict[str, Any]]:
"""
Query across all knowledge sources to find the most relevant information.
Returns the top_k most relevant chunks.
"""
results = self.storage.search(
query,
limit,
filter={"preference": preference} if preference else None,
score_threshold=DEFAULT_SCORE_THRESHOLD,
)
return results

View File

View File

@@ -0,0 +1,36 @@
from pathlib import Path
from typing import Union, List
from pydantic import Field
from crewai.knowledge.source.base_knowledge_source import BaseKnowledgeSource
from typing import Dict, Any
from crewai.knowledge.storage.knowledge_storage import KnowledgeStorage
class BaseFileKnowledgeSource(BaseKnowledgeSource):
"""Base class for knowledge sources that load content from files."""
file_path: Union[Path, List[Path]] = Field(...)
content: Dict[Path, str] = Field(init=False, default_factory=dict)
storage: KnowledgeStorage = Field(default_factory=KnowledgeStorage)
def model_post_init(self, _):
"""Post-initialization method to load content."""
self.content = self.load_content()
def load_content(self) -> Dict[Path, str]:
"""Load and preprocess file content. Should be overridden by subclasses."""
paths = [self.file_path] if isinstance(self.file_path, Path) else self.file_path
for path in paths:
if not path.exists():
raise FileNotFoundError(f"File not found: {path}")
if not path.is_file():
raise ValueError(f"Path is not a file: {path}")
return {}
def save_documents(self, metadata: Dict[str, Any]):
"""Save the documents to the storage."""
chunk_metadatas = [metadata.copy() for _ in self.chunks]
self.storage.save(self.chunks, chunk_metadatas)

View File

@@ -0,0 +1,48 @@
from abc import ABC, abstractmethod
from typing import List, Dict, Any
import numpy as np
from pydantic import BaseModel, ConfigDict, Field
from crewai.knowledge.storage.knowledge_storage import KnowledgeStorage
class BaseKnowledgeSource(BaseModel, ABC):
"""Abstract base class for knowledge sources."""
chunk_size: int = 4000
chunk_overlap: int = 200
chunks: List[str] = Field(default_factory=list)
chunk_embeddings: List[np.ndarray] = Field(default_factory=list)
model_config = ConfigDict(arbitrary_types_allowed=True)
storage: KnowledgeStorage = Field(default_factory=KnowledgeStorage)
metadata: Dict[str, Any] = Field(default_factory=dict)
@abstractmethod
def load_content(self) -> Dict[Any, str]:
"""Load and preprocess content from the source."""
pass
@abstractmethod
def add(self) -> None:
"""Process content, chunk it, compute embeddings, and save them."""
pass
def get_embeddings(self) -> List[np.ndarray]:
"""Return the list of embeddings for the chunks."""
return self.chunk_embeddings
def _chunk_text(self, text: str) -> List[str]:
"""Utility method to split text into chunks."""
return [
text[i : i + self.chunk_size]
for i in range(0, len(text), self.chunk_size - self.chunk_overlap)
]
def save_documents(self, metadata: Dict[str, Any]):
"""
Save the documents to the storage.
This method should be called after the chunks and embeddings are generated.
"""
self.storage.save(self.chunks, metadata)

View File

@@ -0,0 +1,44 @@
import csv
from typing import Dict, List
from pathlib import Path
from crewai.knowledge.source.base_file_knowledge_source import BaseFileKnowledgeSource
class CSVKnowledgeSource(BaseFileKnowledgeSource):
"""A knowledge source that stores and queries CSV file content using embeddings."""
def load_content(self) -> Dict[Path, str]:
"""Load and preprocess CSV file content."""
super().load_content() # Validate the file path
file_path = (
self.file_path[0] if isinstance(self.file_path, list) else self.file_path
)
file_path = Path(file_path) if isinstance(file_path, str) else file_path
with open(file_path, "r", encoding="utf-8") as csvfile:
reader = csv.reader(csvfile)
content = ""
for row in reader:
content += " ".join(row) + "\n"
return {file_path: content}
def add(self) -> None:
"""
Add CSV file content to the knowledge source, chunk it, compute embeddings,
and save the embeddings.
"""
content_str = (
str(self.content) if isinstance(self.content, dict) else self.content
)
new_chunks = self._chunk_text(content_str)
self.chunks.extend(new_chunks)
self.save_documents(metadata=self.metadata)
def _chunk_text(self, text: str) -> List[str]:
"""Utility method to split text into chunks."""
return [
text[i : i + self.chunk_size]
for i in range(0, len(text), self.chunk_size - self.chunk_overlap)
]

View File

@@ -0,0 +1,56 @@
from typing import Dict, List
from pathlib import Path
from crewai.knowledge.source.base_file_knowledge_source import BaseFileKnowledgeSource
class ExcelKnowledgeSource(BaseFileKnowledgeSource):
"""A knowledge source that stores and queries Excel file content using embeddings."""
def load_content(self) -> Dict[Path, str]:
"""Load and preprocess Excel file content."""
super().load_content() # Validate the file path
pd = self._import_dependencies()
if isinstance(self.file_path, list):
file_path = self.file_path[0]
else:
file_path = self.file_path
df = pd.read_excel(file_path)
content = df.to_csv(index=False)
return {file_path: content}
def _import_dependencies(self):
"""Dynamically import dependencies."""
try:
import openpyxl # noqa
import pandas as pd
return pd
except ImportError as e:
missing_package = str(e).split()[-1]
raise ImportError(
f"{missing_package} is not installed. Please install it with: pip install {missing_package}"
)
def add(self) -> None:
"""
Add Excel file content to the knowledge source, chunk it, compute embeddings,
and save the embeddings.
"""
# Convert dictionary values to a single string if content is a dictionary
if isinstance(self.content, dict):
content_str = "\n".join(str(value) for value in self.content.values())
else:
content_str = str(self.content)
new_chunks = self._chunk_text(content_str)
self.chunks.extend(new_chunks)
self.save_documents(metadata=self.metadata)
def _chunk_text(self, text: str) -> List[str]:
"""Utility method to split text into chunks."""
return [
text[i : i + self.chunk_size]
for i in range(0, len(text), self.chunk_size - self.chunk_overlap)
]

View File

@@ -0,0 +1,54 @@
import json
from typing import Any, Dict, List
from pathlib import Path
from crewai.knowledge.source.base_file_knowledge_source import BaseFileKnowledgeSource
class JSONKnowledgeSource(BaseFileKnowledgeSource):
"""A knowledge source that stores and queries JSON file content using embeddings."""
def load_content(self) -> Dict[Path, str]:
"""Load and preprocess JSON file content."""
super().load_content() # Validate the file path
paths = [self.file_path] if isinstance(self.file_path, Path) else self.file_path
content: Dict[Path, str] = {}
for path in paths:
with open(path, "r", encoding="utf-8") as json_file:
data = json.load(json_file)
content[path] = self._json_to_text(data)
return content
def _json_to_text(self, data: Any, level: int = 0) -> str:
"""Recursively convert JSON data to a text representation."""
text = ""
indent = " " * level
if isinstance(data, dict):
for key, value in data.items():
text += f"{indent}{key}: {self._json_to_text(value, level + 1)}\n"
elif isinstance(data, list):
for item in data:
text += f"{indent}- {self._json_to_text(item, level + 1)}\n"
else:
text += f"{str(data)}"
return text
def add(self) -> None:
"""
Add JSON file content to the knowledge source, chunk it, compute embeddings,
and save the embeddings.
"""
content_str = (
str(self.content) if isinstance(self.content, dict) else self.content
)
new_chunks = self._chunk_text(content_str)
self.chunks.extend(new_chunks)
self.save_documents(metadata=self.metadata)
def _chunk_text(self, text: str) -> List[str]:
"""Utility method to split text into chunks."""
return [
text[i : i + self.chunk_size]
for i in range(0, len(text), self.chunk_size - self.chunk_overlap)
]

View File

@@ -0,0 +1,54 @@
from typing import List, Dict
from pathlib import Path
from crewai.knowledge.source.base_file_knowledge_source import BaseFileKnowledgeSource
class PDFKnowledgeSource(BaseFileKnowledgeSource):
"""A knowledge source that stores and queries PDF file content using embeddings."""
def load_content(self) -> Dict[Path, str]:
"""Load and preprocess PDF file content."""
super().load_content() # Validate the file paths
pdfplumber = self._import_pdfplumber()
paths = [self.file_path] if isinstance(self.file_path, Path) else self.file_path
content = {}
for path in paths:
text = ""
with pdfplumber.open(path) as pdf:
for page in pdf.pages:
page_text = page.extract_text()
if page_text:
text += page_text + "\n"
content[path] = text
return content
def _import_pdfplumber(self):
"""Dynamically import pdfplumber."""
try:
import pdfplumber
return pdfplumber
except ImportError:
raise ImportError(
"pdfplumber is not installed. Please install it with: pip install pdfplumber"
)
def add(self) -> None:
"""
Add PDF file content to the knowledge source, chunk it, compute embeddings,
and save the embeddings.
"""
for _, text in self.content.items():
new_chunks = self._chunk_text(text)
self.chunks.extend(new_chunks)
self.save_documents(metadata=self.metadata)
def _chunk_text(self, text: str) -> List[str]:
"""Utility method to split text into chunks."""
return [
text[i : i + self.chunk_size]
for i in range(0, len(text), self.chunk_size - self.chunk_overlap)
]

View File

@@ -0,0 +1,33 @@
from typing import List
from pydantic import Field
from crewai.knowledge.source.base_knowledge_source import BaseKnowledgeSource
class StringKnowledgeSource(BaseKnowledgeSource):
"""A knowledge source that stores and queries plain text content using embeddings."""
content: str = Field(...)
def model_post_init(self, _):
"""Post-initialization method to validate content."""
self.load_content()
def load_content(self):
"""Validate string content."""
if not isinstance(self.content, str):
raise ValueError("StringKnowledgeSource only accepts string content")
def add(self) -> None:
"""Add string content to the knowledge source, chunk it, compute embeddings, and save them."""
new_chunks = self._chunk_text(self.content)
self.chunks.extend(new_chunks)
self.save_documents(metadata=self.metadata)
def _chunk_text(self, text: str) -> List[str]:
"""Utility method to split text into chunks."""
return [
text[i : i + self.chunk_size]
for i in range(0, len(text), self.chunk_size - self.chunk_overlap)
]

View File

@@ -0,0 +1,35 @@
from typing import Dict, List
from pathlib import Path
from crewai.knowledge.source.base_file_knowledge_source import BaseFileKnowledgeSource
class TextFileKnowledgeSource(BaseFileKnowledgeSource):
"""A knowledge source that stores and queries text file content using embeddings."""
def load_content(self) -> Dict[Path, str]:
"""Load and preprocess text file content."""
super().load_content()
paths = [self.file_path] if isinstance(self.file_path, Path) else self.file_path
content = {}
for path in paths:
with path.open("r", encoding="utf-8") as f:
content[path] = f.read() # type: ignore
return content
def add(self) -> None:
"""
Add text file content to the knowledge source, chunk it, compute embeddings,
and save the embeddings.
"""
for _, text in self.content.items():
new_chunks = self._chunk_text(text)
self.chunks.extend(new_chunks)
self.save_documents(metadata=self.metadata)
def _chunk_text(self, text: str) -> List[str]:
"""Utility method to split text into chunks."""
return [
text[i : i + self.chunk_size]
for i in range(0, len(text), self.chunk_size - self.chunk_overlap)
]

View File

View File

@@ -0,0 +1,29 @@
from abc import ABC, abstractmethod
from typing import Dict, Any, List, Optional
class BaseKnowledgeStorage(ABC):
"""Abstract base class for knowledge storage implementations."""
@abstractmethod
def search(
self,
query: List[str],
limit: int = 3,
filter: Optional[dict] = None,
score_threshold: float = 0.35,
) -> List[Dict[str, Any]]:
"""Search for documents in the knowledge base."""
pass
@abstractmethod
def save(
self, documents: List[str], metadata: Dict[str, Any] | List[Dict[str, Any]]
) -> None:
"""Save documents to the knowledge base."""
pass
@abstractmethod
def reset(self) -> None:
"""Reset the knowledge base."""
pass

View File

@@ -0,0 +1,132 @@
import contextlib
import io
import logging
import chromadb
import os
from crewai.utilities.paths import db_storage_path
from typing import Optional, List
from typing import Dict, Any
from crewai.utilities import EmbeddingConfigurator
from crewai.knowledge.storage.base_knowledge_storage import BaseKnowledgeStorage
import hashlib
@contextlib.contextmanager
def suppress_logging(
logger_name="chromadb.segment.impl.vector.local_persistent_hnsw",
level=logging.ERROR,
):
logger = logging.getLogger(logger_name)
original_level = logger.getEffectiveLevel()
logger.setLevel(level)
with (
contextlib.redirect_stdout(io.StringIO()),
contextlib.redirect_stderr(io.StringIO()),
contextlib.suppress(UserWarning),
):
yield
logger.setLevel(original_level)
class KnowledgeStorage(BaseKnowledgeStorage):
"""
Extends Storage to handle embeddings for memory entries, improving
search efficiency.
"""
collection: Optional[chromadb.Collection] = None
def __init__(self, embedder_config: Optional[Dict[str, Any]] = None):
self._initialize_app(embedder_config or {})
def search(
self,
query: List[str],
limit: int = 3,
filter: Optional[dict] = None,
score_threshold: float = 0.35,
) -> List[Dict[str, Any]]:
with suppress_logging():
if self.collection:
fetched = self.collection.query(
query_texts=query,
n_results=limit,
where=filter,
)
results = []
for i in range(len(fetched["ids"][0])): # type: ignore
result = {
"id": fetched["ids"][0][i], # type: ignore
"metadata": fetched["metadatas"][0][i], # type: ignore
"context": fetched["documents"][0][i], # type: ignore
"score": fetched["distances"][0][i], # type: ignore
}
if result["score"] >= score_threshold: # type: ignore
results.append(result)
return results
else:
raise Exception("Collection not initialized")
def _initialize_app(self, embedder_config: Optional[Dict[str, Any]] = None):
import chromadb
from chromadb.config import Settings
self._set_embedder_config(embedder_config)
chroma_client = chromadb.PersistentClient(
path=f"{db_storage_path()}/knowledge",
settings=Settings(allow_reset=True),
)
self.app = chroma_client
try:
self.collection = self.app.get_or_create_collection(name="knowledge")
except Exception:
raise Exception("Failed to create or get collection")
def reset(self):
if self.app:
self.app.reset()
def save(
self, documents: List[str], metadata: Dict[str, Any] | List[Dict[str, Any]]
):
if self.collection:
metadatas = [metadata] if isinstance(metadata, dict) else metadata
ids = [
hashlib.sha256(doc.encode("utf-8")).hexdigest() for doc in documents
]
self.collection.upsert(
documents=documents,
metadatas=metadatas,
ids=ids,
)
else:
raise Exception("Collection not initialized")
def _create_default_embedding_function(self):
from chromadb.utils.embedding_functions.openai_embedding_function import (
OpenAIEmbeddingFunction,
)
return OpenAIEmbeddingFunction(
api_key=os.getenv("OPENAI_API_KEY"), model_name="text-embedding-3-small"
)
def _set_embedder_config(
self, embedder_config: Optional[Dict[str, Any]] = None
) -> None:
"""Set the embedding configuration for the knowledge storage.
Args:
embedder_config (Optional[Dict[str, Any]]): Configuration dictionary for the embedder.
If None or empty, defaults to the default embedding function.
"""
self.embedder_config = (
EmbeddingConfigurator().configure_embedder(embedder_config)
if embedder_config
else self._create_default_embedding_function()
)

View File

@@ -1,7 +1,10 @@
import logging
import sys
import threading
import warnings
from contextlib import contextmanager
from typing import Any, Dict, List, Optional, Union
import logging
import warnings
import litellm
from litellm import get_supported_openai_params
@@ -9,20 +12,26 @@ from crewai.utilities.exceptions.context_window_exceeding_exception import (
LLMContextLengthExceededException,
)
import sys
import io
class FilteredStream:
def __init__(self, original_stream):
self._original_stream = original_stream
self._lock = threading.Lock()
class FilteredStream(io.StringIO):
def write(self, s):
if (
"Give Feedback / Get Help: https://github.com/BerriAI/litellm/issues/new"
in s
or "LiteLLM.Info: If you need to debug this error, use `litellm.set_verbose=True`"
in s
):
return
super().write(s)
def write(self, s) -> int:
with self._lock:
if (
"Give Feedback / Get Help: https://github.com/BerriAI/litellm/issues/new"
in s
or "LiteLLM.Info: If you need to debug this error, use `litellm.set_verbose=True`"
in s
):
return 0
return self._original_stream.write(s)
def flush(self):
with self._lock:
return self._original_stream.flush()
LLM_CONTEXT_WINDOW_SIZES = {
@@ -60,8 +69,8 @@ def suppress_warnings():
# Redirect stdout and stderr
old_stdout = sys.stdout
old_stderr = sys.stderr
sys.stdout = FilteredStream()
sys.stderr = FilteredStream()
sys.stdout = FilteredStream(old_stdout)
sys.stderr = FilteredStream(old_stderr)
try:
yield
@@ -118,12 +127,12 @@ class LLM:
litellm.drop_params = True
litellm.set_verbose = False
litellm.callbacks = callbacks
self.set_callbacks(callbacks)
def call(self, messages: List[Dict[str, str]], callbacks: List[Any] = []) -> str:
with suppress_warnings():
if callbacks and len(callbacks) > 0:
litellm.callbacks = callbacks
self.set_callbacks(callbacks)
try:
params = {
@@ -181,3 +190,15 @@ class LLM:
def get_context_window_size(self) -> int:
# Only using 75% of the context window size to avoid cutting the message in the middle
return int(LLM_CONTEXT_WINDOW_SIZES.get(self.model, 8192) * 0.75)
def set_callbacks(self, callbacks: List[Any]):
callback_types = [type(callback) for callback in callbacks]
for callback in litellm.success_callback[:]:
if type(callback) in callback_types:
litellm.success_callback.remove(callback)
for callback in litellm._async_success_callback[:]:
if type(callback) in callback_types:
litellm._async_success_callback.remove(callback)
litellm.callbacks = callbacks

View File

@@ -1,5 +1,6 @@
from .entity.entity_memory import EntityMemory
from .long_term.long_term_memory import LongTermMemory
from .short_term.short_term_memory import ShortTermMemory
from .user.user_memory import UserMemory
__all__ = ["EntityMemory", "LongTermMemory", "ShortTermMemory"]
__all__ = ["UserMemory", "EntityMemory", "LongTermMemory", "ShortTermMemory"]

View File

@@ -1,13 +1,25 @@
from typing import Optional
from typing import Optional, Dict, Any
from crewai.memory import EntityMemory, LongTermMemory, ShortTermMemory
from crewai.memory import EntityMemory, LongTermMemory, ShortTermMemory, UserMemory
class ContextualMemory:
def __init__(self, stm: ShortTermMemory, ltm: LongTermMemory, em: EntityMemory):
def __init__(
self,
memory_config: Optional[Dict[str, Any]],
stm: ShortTermMemory,
ltm: LongTermMemory,
em: EntityMemory,
um: UserMemory,
):
if memory_config is not None:
self.memory_provider = memory_config.get("provider")
else:
self.memory_provider = None
self.stm = stm
self.ltm = ltm
self.em = em
self.um = um
def build_context_for_task(self, task, context) -> str:
"""
@@ -23,6 +35,8 @@ class ContextualMemory:
context.append(self._fetch_ltm_context(task.description))
context.append(self._fetch_stm_context(query))
context.append(self._fetch_entity_context(query))
if self.memory_provider == "mem0":
context.append(self._fetch_user_context(query))
return "\n".join(filter(None, context))
def _fetch_stm_context(self, query) -> str:
@@ -32,9 +46,11 @@ class ContextualMemory:
"""
stm_results = self.stm.search(query)
formatted_results = "\n".join(
[f"- {result['context']}" for result in stm_results]
[
f"- {result['memory'] if self.memory_provider == 'mem0' else result['context']}"
for result in stm_results
]
)
print("formatted_results stm", formatted_results)
return f"Recent Insights:\n{formatted_results}" if stm_results else ""
def _fetch_ltm_context(self, task) -> Optional[str]:
@@ -54,8 +70,6 @@ class ContextualMemory:
formatted_results = list(dict.fromkeys(formatted_results))
formatted_results = "\n".join([f"- {result}" for result in formatted_results]) # type: ignore # Incompatible types in assignment (expression has type "str", variable has type "list[str]")
print("formatted_results ltm", formatted_results)
return f"Historical Data:\n{formatted_results}" if ltm_results else ""
def _fetch_entity_context(self, query) -> str:
@@ -65,7 +79,26 @@ class ContextualMemory:
"""
em_results = self.em.search(query)
formatted_results = "\n".join(
[f"- {result['context']}" for result in em_results] # type: ignore # Invalid index type "str" for "str"; expected type "SupportsIndex | slice"
[
f"- {result['memory'] if self.memory_provider == 'mem0' else result['context']}"
for result in em_results
] # type: ignore # Invalid index type "str" for "str"; expected type "SupportsIndex | slice"
)
print("formatted_results em", formatted_results)
return f"Entities:\n{formatted_results}" if em_results else ""
def _fetch_user_context(self, query: str) -> str:
"""
Fetches and formats relevant user information from User Memory.
Args:
query (str): The search query to find relevant user memories.
Returns:
str: Formatted user memories as bullet points, or an empty string if none found.
"""
user_memories = self.um.search(query)
if not user_memories:
return ""
formatted_memories = "\n".join(
f"- {result['memory']}" for result in user_memories
)
return f"User memories/preferences:\n{formatted_memories}"

View File

@@ -11,21 +11,43 @@ class EntityMemory(Memory):
"""
def __init__(self, crew=None, embedder_config=None, storage=None):
storage = (
storage
if storage
else RAGStorage(
type="entities",
allow_reset=True,
embedder_config=embedder_config,
crew=crew,
if hasattr(crew, "memory_config") and crew.memory_config is not None:
self.memory_provider = crew.memory_config.get("provider")
else:
self.memory_provider = None
if self.memory_provider == "mem0":
try:
from crewai.memory.storage.mem0_storage import Mem0Storage
except ImportError:
raise ImportError(
"Mem0 is not installed. Please install it with `pip install mem0ai`."
)
storage = Mem0Storage(type="entities", crew=crew)
else:
storage = (
storage
if storage
else RAGStorage(
type="entities",
allow_reset=True,
embedder_config=embedder_config,
crew=crew,
)
)
)
super().__init__(storage)
def save(self, item: EntityMemoryItem) -> None: # type: ignore # BUG?: Signature of "save" incompatible with supertype "Memory"
"""Saves an entity item into the SQLite storage."""
data = f"{item.name}({item.type}): {item.description}"
if self.memory_provider == "mem0":
data = f"""
Remember details about the following entity:
Name: {item.name}
Type: {item.type}
Entity Description: {item.description}
"""
else:
data = f"{item.name}({item.type}): {item.description}"
super().save(data, item.metadata)
def reset(self) -> None:

View File

@@ -23,5 +23,12 @@ class Memory:
self.storage.save(value, metadata)
def search(self, query: str) -> List[Dict[str, Any]]:
return self.storage.search(query)
def search(
self,
query: str,
limit: int = 3,
score_threshold: float = 0.35,
) -> List[Any]:
return self.storage.search(
query=query, limit=limit, score_threshold=score_threshold
)

View File

@@ -14,13 +14,27 @@ class ShortTermMemory(Memory):
"""
def __init__(self, crew=None, embedder_config=None, storage=None):
storage = (
storage
if storage
else RAGStorage(
type="short_term", embedder_config=embedder_config, crew=crew
if hasattr(crew, "memory_config") and crew.memory_config is not None:
self.memory_provider = crew.memory_config.get("provider")
else:
self.memory_provider = None
if self.memory_provider == "mem0":
try:
from crewai.memory.storage.mem0_storage import Mem0Storage
except ImportError:
raise ImportError(
"Mem0 is not installed. Please install it with `pip install mem0ai`."
)
storage = Mem0Storage(type="short_term", crew=crew)
else:
storage = (
storage
if storage
else RAGStorage(
type="short_term", embedder_config=embedder_config, crew=crew
)
)
)
super().__init__(storage)
def save(
@@ -30,11 +44,20 @@ class ShortTermMemory(Memory):
agent: Optional[str] = None,
) -> None:
item = ShortTermMemoryItem(data=value, metadata=metadata, agent=agent)
if self.memory_provider == "mem0":
item.data = f"Remember the following insights from Agent run: {item.data}"
super().save(value=item.data, metadata=item.metadata, agent=item.agent)
def search(self, query: str, score_threshold: float = 0.35):
return self.storage.search(query=query, score_threshold=score_threshold) # type: ignore # BUG? The reference is to the parent class, but the parent class does not have this parameters
def search(
self,
query: str,
limit: int = 3,
score_threshold: float = 0.35,
):
return self.storage.search(
query=query, limit=limit, score_threshold=score_threshold
) # type: ignore # BUG? The reference is to the parent class, but the parent class does not have this parameters
def reset(self) -> None:
try:

View File

@@ -7,8 +7,10 @@ class Storage:
def save(self, value: Any, metadata: Dict[str, Any]) -> None:
pass
def search(self, key: str) -> List[Dict[str, Any]]: # type: ignore
pass
def search(
self, query: str, limit: int, score_threshold: float
) -> Dict[str, Any] | List[Any]:
return {}
def reset(self) -> None:
pass

View File

@@ -103,7 +103,7 @@ class KickoffTaskOutputsSQLiteStorage:
else value
)
query = f"UPDATE latest_kickoff_task_outputs SET {', '.join(fields)} WHERE task_index = ?"
query = f"UPDATE latest_kickoff_task_outputs SET {', '.join(fields)} WHERE task_index = ?" # nosec
values.append(task_index)
cursor.execute(query, tuple(values))

View File

@@ -83,7 +83,7 @@ class LTMSQLiteStorage:
WHERE task_description = ?
ORDER BY datetime DESC, score ASC
LIMIT {latest_n}
""",
""", # nosec
(task_description,),
)
rows = cursor.fetchall()

View File

@@ -0,0 +1,104 @@
import os
from typing import Any, Dict, List
from mem0 import MemoryClient
from crewai.memory.storage.interface import Storage
class Mem0Storage(Storage):
"""
Extends Storage to handle embedding and searching across entities using Mem0.
"""
def __init__(self, type, crew=None):
super().__init__()
if type not in ["user", "short_term", "long_term", "entities"]:
raise ValueError("Invalid type for Mem0Storage. Must be 'user' or 'agent'.")
self.memory_type = type
self.crew = crew
self.memory_config = crew.memory_config
# User ID is required for user memory type "user" since it's used as a unique identifier for the user.
user_id = self._get_user_id()
if type == "user" and not user_id:
raise ValueError("User ID is required for user memory type")
# API key in memory config overrides the environment variable
mem0_api_key = self.memory_config.get("config", {}).get("api_key") or os.getenv(
"MEM0_API_KEY"
)
self.memory = MemoryClient(api_key=mem0_api_key)
def _sanitize_role(self, role: str) -> str:
"""
Sanitizes agent roles to ensure valid directory names.
"""
return role.replace("\n", "").replace(" ", "_").replace("/", "_")
def save(self, value: Any, metadata: Dict[str, Any]) -> None:
user_id = self._get_user_id()
agent_name = self._get_agent_name()
if self.memory_type == "user":
self.memory.add(value, user_id=user_id, metadata={**metadata})
elif self.memory_type == "short_term":
agent_name = self._get_agent_name()
self.memory.add(
value, agent_id=agent_name, metadata={"type": "short_term", **metadata}
)
elif self.memory_type == "long_term":
agent_name = self._get_agent_name()
self.memory.add(
value,
agent_id=agent_name,
infer=False,
metadata={"type": "long_term", **metadata},
)
elif self.memory_type == "entities":
entity_name = None
self.memory.add(
value, user_id=entity_name, metadata={"type": "entity", **metadata}
)
def search(
self,
query: str,
limit: int = 3,
score_threshold: float = 0.35,
) -> List[Any]:
params = {"query": query, "limit": limit}
if self.memory_type == "user":
user_id = self._get_user_id()
params["user_id"] = user_id
elif self.memory_type == "short_term":
agent_name = self._get_agent_name()
params["agent_id"] = agent_name
params["metadata"] = {"type": "short_term"}
elif self.memory_type == "long_term":
agent_name = self._get_agent_name()
params["agent_id"] = agent_name
params["metadata"] = {"type": "long_term"}
elif self.memory_type == "entities":
agent_name = self._get_agent_name()
params["agent_id"] = agent_name
params["metadata"] = {"type": "entity"}
# Discard the filters for now since we create the filters
# automatically when the crew is created.
results = self.memory.search(**params)
return [r for r in results if r["score"] >= score_threshold]
def _get_user_id(self):
if self.memory_type == "user":
if hasattr(self, "memory_config") and self.memory_config is not None:
return self.memory_config.get("config", {}).get("user_id")
else:
return None
return None
def _get_agent_name(self):
agents = self.crew.agents if self.crew else []
agents = [self._sanitize_role(agent.role) for agent in agents]
agents = "_".join(agents)
return agents

View File

@@ -4,13 +4,12 @@ import logging
import os
import shutil
import uuid
from typing import Any, Dict, List, Optional, cast
from chromadb import Documents, EmbeddingFunction, Embeddings
from typing import Any, Dict, List, Optional
from chromadb.api import ClientAPI
from chromadb.api.types import validate_embedding_function
from crewai.memory.storage.base_rag_storage import BaseRAGStorage
from crewai.utilities.paths import db_storage_path
from crewai.utilities import EmbeddingConfigurator
@contextlib.contextmanager
@@ -51,117 +50,8 @@ class RAGStorage(BaseRAGStorage):
self._initialize_app()
def _set_embedder_config(self):
import chromadb.utils.embedding_functions as embedding_functions
if self.embedder_config is None:
self.embedder_config = self._create_default_embedding_function()
if isinstance(self.embedder_config, dict):
provider = self.embedder_config.get("provider")
config = self.embedder_config.get("config", {})
model_name = config.get("model")
if provider == "openai":
self.embedder_config = embedding_functions.OpenAIEmbeddingFunction(
api_key=config.get("api_key") or os.getenv("OPENAI_API_KEY"),
model_name=model_name,
)
elif provider == "azure":
self.embedder_config = embedding_functions.OpenAIEmbeddingFunction(
api_key=config.get("api_key"),
api_base=config.get("api_base"),
api_type=config.get("api_type", "azure"),
api_version=config.get("api_version"),
model_name=model_name,
)
elif provider == "ollama":
from openai import OpenAI
class OllamaEmbeddingFunction(EmbeddingFunction):
def __call__(self, input: Documents) -> Embeddings:
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key=config.get("api_key", "ollama"),
)
try:
response = client.embeddings.create(
input=input, model=model_name
)
embeddings = [item.embedding for item in response.data]
return cast(Embeddings, embeddings)
except Exception as e:
raise e
self.embedder_config = OllamaEmbeddingFunction()
elif provider == "vertexai":
self.embedder_config = (
embedding_functions.GoogleVertexEmbeddingFunction(
model_name=model_name,
api_key=config.get("api_key"),
)
)
elif provider == "google":
self.embedder_config = (
embedding_functions.GoogleGenerativeAiEmbeddingFunction(
model_name=model_name,
api_key=config.get("api_key"),
)
)
elif provider == "cohere":
self.embedder_config = embedding_functions.CohereEmbeddingFunction(
model_name=model_name,
api_key=config.get("api_key"),
)
elif provider == "huggingface":
self.embedder_config = embedding_functions.HuggingFaceEmbeddingServer(
url=config.get("api_url"),
)
elif provider == "watson":
try:
import ibm_watsonx_ai.foundation_models as watson_models
from ibm_watsonx_ai import Credentials
from ibm_watsonx_ai.metanames import (
EmbedTextParamsMetaNames as EmbedParams,
)
except ImportError as e:
raise ImportError(
"IBM Watson dependencies are not installed. Please install them to use Watson embedding."
) from e
class WatsonEmbeddingFunction(EmbeddingFunction):
def __call__(self, input: Documents) -> Embeddings:
if isinstance(input, str):
input = [input]
embed_params = {
EmbedParams.TRUNCATE_INPUT_TOKENS: 3,
EmbedParams.RETURN_OPTIONS: {"input_text": True},
}
embedding = watson_models.Embeddings(
model_id=config.get("model"),
params=embed_params,
credentials=Credentials(
api_key=config.get("api_key"), url=config.get("api_url")
),
project_id=config.get("project_id"),
)
try:
embeddings = embedding.embed_documents(input)
return cast(Embeddings, embeddings)
except Exception as e:
print("Error during Watson embedding:", e)
raise e
self.embedder_config = WatsonEmbeddingFunction()
else:
raise Exception(
f"Unsupported embedding provider: {provider}, supported providers: [openai, azure, ollama, vertexai, google, cohere, huggingface, watson]"
)
else:
validate_embedding_function(self.embedder_config)
self.embedder_config = self.embedder_config
configurator = EmbeddingConfigurator()
self.embedder_config = configurator.configure_embedder(self.embedder_config)
def _initialize_app(self):
import chromadb
@@ -253,8 +143,10 @@ class RAGStorage(BaseRAGStorage):
)
def _create_default_embedding_function(self):
import chromadb.utils.embedding_functions as embedding_functions
from chromadb.utils.embedding_functions.openai_embedding_function import (
OpenAIEmbeddingFunction,
)
return embedding_functions.OpenAIEmbeddingFunction(
return OpenAIEmbeddingFunction(
api_key=os.getenv("OPENAI_API_KEY"), model_name="text-embedding-3-small"
)

View File

View File

@@ -0,0 +1,45 @@
from typing import Any, Dict, Optional
from crewai.memory.memory import Memory
class UserMemory(Memory):
"""
UserMemory class for handling user memory storage and retrieval.
Inherits from the Memory class and utilizes an instance of a class that
adheres to the Storage for data storage, specifically working with
MemoryItem instances.
"""
def __init__(self, crew=None):
try:
from crewai.memory.storage.mem0_storage import Mem0Storage
except ImportError:
raise ImportError(
"Mem0 is not installed. Please install it with `pip install mem0ai`."
)
storage = Mem0Storage(type="user", crew=crew)
super().__init__(storage)
def save(
self,
value,
metadata: Optional[Dict[str, Any]] = None,
agent: Optional[str] = None,
) -> None:
# TODO: Change this function since we want to take care of the case where we save memories for the usr
data = f"Remember the details about the user: {value}"
super().save(data, metadata)
def search(
self,
query: str,
limit: int = 3,
score_threshold: float = 0.35,
):
results = super().search(
query=query,
limit=limit,
score_threshold=score_threshold,
)
return results

View File

@@ -0,0 +1,8 @@
from typing import Any, Dict, Optional
class UserMemoryItem:
def __init__(self, data: Any, user: str, metadata: Optional[Dict[str, Any]] = None):
self.data = data
self.user = user
self.metadata = metadata if metadata is not None else {}

View File

@@ -1,5 +1,7 @@
from .annotations import (
after_kickoff,
agent,
before_kickoff,
cache_handler,
callback,
crew,
@@ -26,4 +28,6 @@ __all__ = [
"llm",
"cache_handler",
"pipeline",
"before_kickoff",
"after_kickoff",
]

View File

@@ -5,6 +5,16 @@ from crewai import Crew
from crewai.project.utils import memoize
def before_kickoff(func):
func.is_before_kickoff = True
return func
def after_kickoff(func):
func.is_after_kickoff = True
return func
def task(func):
func.is_task = True
@@ -99,6 +109,19 @@ def crew(func) -> Callable[..., Crew]:
self.agents = instantiated_agents
self.tasks = instantiated_tasks
return func(self, *args, **kwargs)
crew = func(self, *args, **kwargs)
return wrapper
def callback_wrapper(callback, instance):
def wrapper(*args, **kwargs):
return callback(instance, *args, **kwargs)
return wrapper
for _, callback in self._before_kickoff.items():
crew.before_kickoff_callbacks.append(callback_wrapper(callback, self))
for _, callback in self._after_kickoff.items():
crew.after_kickoff_callbacks.append(callback_wrapper(callback, self))
return crew
return memoize(wrapper)

View File

@@ -34,18 +34,39 @@ def CrewBase(cls: T) -> T:
self.map_all_agent_variables()
self.map_all_task_variables()
# Preserve task and agent information
self._original_tasks = {
# Preserve all decorated functions
self._original_functions = {
name: method
for name, method in cls.__dict__.items()
if hasattr(method, "is_task") and method.is_task
}
self._original_agents = {
name: method
for name, method in cls.__dict__.items()
if hasattr(method, "is_agent") and method.is_agent
if any(
hasattr(method, attr)
for attr in [
"is_task",
"is_agent",
"is_before_kickoff",
"is_after_kickoff",
"is_kickoff",
]
)
}
# Store specific function types
self._original_tasks = self._filter_functions(
self._original_functions, "is_task"
)
self._original_agents = self._filter_functions(
self._original_functions, "is_agent"
)
self._before_kickoff = self._filter_functions(
self._original_functions, "is_before_kickoff"
)
self._after_kickoff = self._filter_functions(
self._original_functions, "is_after_kickoff"
)
self._kickoff = self._filter_functions(
self._original_functions, "is_kickoff"
)
@staticmethod
def load_yaml(config_path: Path):
try:

View File

@@ -20,10 +20,10 @@ from pydantic import (
from pydantic_core import PydanticCustomError
from crewai.agents.agent_builder.base_agent import BaseAgent
from crewai.tools.base_tool import BaseTool
from crewai.tasks.output_format import OutputFormat
from crewai.tasks.task_output import TaskOutput
from crewai.telemetry.telemetry import Telemetry
from crewai.tools.base_tool import BaseTool
from crewai.utilities.config import process_config
from crewai.utilities.converter import Converter, convert_to_model
from crewai.utilities.i18n import I18N
@@ -208,7 +208,9 @@ class Task(BaseModel):
"""Execute the task asynchronously."""
future: Future[TaskOutput] = Future()
threading.Thread(
target=self._execute_task_async, args=(agent, context, tools, future)
daemon=True,
target=self._execute_task_async,
args=(agent, context, tools, future),
).start()
return future
@@ -277,7 +279,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)

View File

View File

@@ -8,6 +8,7 @@ class UsageMetrics(BaseModel):
Attributes:
total_tokens: Total number of tokens used.
prompt_tokens: Number of tokens used in prompts.
cached_prompt_tokens: Number of cached prompt tokens used.
completion_tokens: Number of tokens used in completions.
successful_requests: Number of successful requests made.
"""
@@ -16,6 +17,9 @@ class UsageMetrics(BaseModel):
prompt_tokens: int = Field(
default=0, description="Number of tokens used in prompts."
)
cached_prompt_tokens: int = Field(
default=0, description="Number of cached prompt tokens used."
)
completion_tokens: int = Field(
default=0, description="Number of tokens used in completions."
)
@@ -32,5 +36,6 @@ class UsageMetrics(BaseModel):
"""
self.total_tokens += usage_metrics.total_tokens
self.prompt_tokens += usage_metrics.prompt_tokens
self.cached_prompt_tokens += usage_metrics.cached_prompt_tokens
self.completion_tokens += usage_metrics.completion_tokens
self.successful_requests += usage_metrics.successful_requests

View File

@@ -10,6 +10,7 @@ from .rpm_controller import RPMController
from .exceptions.context_window_exceeding_exception import (
LLMContextLengthExceededException,
)
from .embedding_configurator import EmbeddingConfigurator
__all__ = [
"Converter",
@@ -23,4 +24,5 @@ __all__ = [
"RPMController",
"YamlParser",
"LLMContextLengthExceededException",
"EmbeddingConfigurator",
]

View File

@@ -1,2 +1,3 @@
TRAINING_DATA_FILE = "training_data.pkl"
TRAINED_AGENTS_DATA_FILE = "trained_agents_data.pkl"
DEFAULT_SCORE_THRESHOLD = 0.35

View File

@@ -0,0 +1,183 @@
import os
from typing import Any, Dict, cast
from chromadb import EmbeddingFunction, Documents, Embeddings
from chromadb.api.types import validate_embedding_function
class EmbeddingConfigurator:
def __init__(self):
self.embedding_functions = {
"openai": self._configure_openai,
"azure": self._configure_azure,
"ollama": self._configure_ollama,
"vertexai": self._configure_vertexai,
"google": self._configure_google,
"cohere": self._configure_cohere,
"bedrock": self._configure_bedrock,
"huggingface": self._configure_huggingface,
"watson": self._configure_watson,
}
def configure_embedder(
self,
embedder_config: Dict[str, Any] | None = None,
) -> EmbeddingFunction:
"""Configures and returns an embedding function based on the provided config."""
if embedder_config is None:
return self._create_default_embedding_function()
provider = embedder_config.get("provider")
config = embedder_config.get("config", {})
model_name = config.get("model")
if isinstance(provider, EmbeddingFunction):
try:
validate_embedding_function(provider)
return provider
except Exception as e:
raise ValueError(f"Invalid custom embedding function: {str(e)}")
if provider not in self.embedding_functions:
raise Exception(
f"Unsupported embedding provider: {provider}, supported providers: {list(self.embedding_functions.keys())}"
)
return self.embedding_functions[provider](config, model_name)
@staticmethod
def _create_default_embedding_function():
from chromadb.utils.embedding_functions.openai_embedding_function import (
OpenAIEmbeddingFunction,
)
return OpenAIEmbeddingFunction(
api_key=os.getenv("OPENAI_API_KEY"), model_name="text-embedding-3-small"
)
@staticmethod
def _configure_openai(config, model_name):
from chromadb.utils.embedding_functions.openai_embedding_function import (
OpenAIEmbeddingFunction,
)
return OpenAIEmbeddingFunction(
api_key=config.get("api_key") or os.getenv("OPENAI_API_KEY"),
model_name=model_name,
)
@staticmethod
def _configure_azure(config, model_name):
from chromadb.utils.embedding_functions.openai_embedding_function import (
OpenAIEmbeddingFunction,
)
return OpenAIEmbeddingFunction(
api_key=config.get("api_key"),
api_base=config.get("api_base"),
api_type=config.get("api_type", "azure"),
api_version=config.get("api_version"),
model_name=model_name,
)
@staticmethod
def _configure_ollama(config, model_name):
from chromadb.utils.embedding_functions.ollama_embedding_function import (
OllamaEmbeddingFunction,
)
return OllamaEmbeddingFunction(
url=config.get("url", "http://localhost:11434/api/embeddings"),
model_name=model_name,
)
@staticmethod
def _configure_vertexai(config, model_name):
from chromadb.utils.embedding_functions.google_embedding_function import (
GoogleVertexEmbeddingFunction,
)
return GoogleVertexEmbeddingFunction(
model_name=model_name,
api_key=config.get("api_key"),
)
@staticmethod
def _configure_google(config, model_name):
from chromadb.utils.embedding_functions.google_embedding_function import (
GoogleGenerativeAiEmbeddingFunction,
)
return GoogleGenerativeAiEmbeddingFunction(
model_name=model_name,
api_key=config.get("api_key"),
)
@staticmethod
def _configure_cohere(config, model_name):
from chromadb.utils.embedding_functions.cohere_embedding_function import (
CohereEmbeddingFunction,
)
return CohereEmbeddingFunction(
model_name=model_name,
api_key=config.get("api_key"),
)
@staticmethod
def _configure_bedrock(config, model_name):
from chromadb.utils.embedding_functions.amazon_bedrock_embedding_function import (
AmazonBedrockEmbeddingFunction,
)
return AmazonBedrockEmbeddingFunction(
session=config.get("session"),
)
@staticmethod
def _configure_huggingface(config, model_name):
from chromadb.utils.embedding_functions.huggingface_embedding_function import (
HuggingFaceEmbeddingServer,
)
return HuggingFaceEmbeddingServer(
url=config.get("api_url"),
)
@staticmethod
def _configure_watson(config, model_name):
try:
import ibm_watsonx_ai.foundation_models as watson_models
from ibm_watsonx_ai import Credentials
from ibm_watsonx_ai.metanames import EmbedTextParamsMetaNames as EmbedParams
except ImportError as e:
raise ImportError(
"IBM Watson dependencies are not installed. Please install them to use Watson embedding."
) from e
class WatsonEmbeddingFunction(EmbeddingFunction):
def __call__(self, input: Documents) -> Embeddings:
if isinstance(input, str):
input = [input]
embed_params = {
EmbedParams.TRUNCATE_INPUT_TOKENS: 3,
EmbedParams.RETURN_OPTIONS: {"input_text": True},
}
embedding = watson_models.Embeddings(
model_id=config.get("model"),
params=embed_params,
credentials=Credentials(
api_key=config.get("api_key"), url=config.get("api_url")
),
project_id=config.get("project_id"),
)
try:
embeddings = embedding.embed_documents(input)
return cast(Embeddings, embeddings)
except Exception as e:
print("Error during Watson embedding:", e)
raise e
return WatsonEmbeddingFunction()

View File

@@ -16,7 +16,11 @@ class FileHandler:
def log(self, **kwargs):
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
message = f"{now}: " + ", ".join([f"{key}=\"{value}\"" for key, value in kwargs.items()]) + "\n"
message = (
f"{now}: "
+ ", ".join([f'{key}="{value}"' for key, value in kwargs.items()])
+ "\n"
)
with open(self._path, "a", encoding="utf-8") as file:
file.write(message + "\n")
@@ -63,7 +67,7 @@ class PickleHandler:
with open(self.file_path, "rb") as file:
try:
return pickle.load(file)
return pickle.load(file) # nosec
except EOFError:
return {} # Return an empty dictionary if the file is empty or corrupted
except Exception:

View File

@@ -1,5 +1,5 @@
from litellm.integrations.custom_logger import CustomLogger
from litellm.types.utils import Usage
from crewai.agents.agent_builder.utilities.base_token_process import TokenProcess
@@ -11,8 +11,11 @@ class TokenCalcHandler(CustomLogger):
if self.token_cost_process is None:
return
usage : Usage = response_obj["usage"]
self.token_cost_process.sum_successful_requests(1)
self.token_cost_process.sum_prompt_tokens(response_obj["usage"].prompt_tokens)
self.token_cost_process.sum_completion_tokens(
response_obj["usage"].completion_tokens
)
self.token_cost_process.sum_prompt_tokens(usage.prompt_tokens)
self.token_cost_process.sum_completion_tokens(usage.completion_tokens)
if usage.prompt_tokens_details:
self.token_cost_process.sum_cached_prompt_tokens(
usage.prompt_tokens_details.cached_tokens
)

View File

@@ -10,10 +10,11 @@ from crewai import Agent, Crew, Task
from crewai.agents.cache import CacheHandler
from crewai.agents.crew_agent_executor import CrewAgentExecutor
from crewai.agents.parser import AgentAction, CrewAgentParser, OutputParserException
from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource
from crewai.llm import LLM
from crewai.tools import tool
from crewai.tools.tool_calling import InstructorToolCalling
from crewai.tools.tool_usage import ToolUsage
from crewai.tools import tool
from crewai.tools.tool_usage_events import ToolUsageFinished
from crewai.utilities import RPMController
from crewai.utilities.events import Emitter
@@ -1574,3 +1575,42 @@ def test_agent_execute_task_with_ollama():
result = agent.execute_task(task)
assert len(result.split(".")) == 2
assert "AI" in result or "artificial intelligence" in result.lower()
@pytest.mark.vcr(filter_headers=["authorization"])
def test_agent_with_knowledge_sources():
# Create a knowledge source with some content
content = "Brandon's favorite color is blue and he likes Mexican food."
string_source = StringKnowledgeSource(
content=content, metadata={"preference": "personal"}
)
with patch('crewai.knowledge.storage.knowledge_storage.KnowledgeStorage') as MockKnowledge:
mock_knowledge_instance = MockKnowledge.return_value
mock_knowledge_instance.sources = [string_source]
mock_knowledge_instance.query.return_value = [{
"content": content,
"metadata": {"preference": "personal"}
}]
agent = Agent(
role="Information Agent",
goal="Provide information based on knowledge sources",
backstory="You have access to specific knowledge sources.",
llm=LLM(model="gpt-4o-mini"),
)
# Create a task that requires the agent to use the knowledge
task = Task(
description="What is Brandon's favorite color?",
expected_output="Brandon's favorite color.",
agent=agent,
)
crew = Crew(agents=[agent], tasks=[task])
result = crew.kickoff()
# Assert that the agent provides the correct information
assert "blue" in result.raw.lower()

View File

@@ -0,0 +1,449 @@
interactions:
- request:
body: !!binary |
CuMOCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSug4KEgoQY3Jld2FpLnRl
bGVtZXRyeRKSDAoQK+dPhrB8w3HKFlxX60XzYRIIk5aB+A8oCWQqDENyZXcgQ3JlYXRlZDABObix
K+HWrwgYQcBiMeHWrwgYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODAuMEoaCg5weXRob25fdmVy
c2lvbhIICgYzLjExLjdKLgoIY3Jld19rZXkSIgogZjM0NmE5YWQ2ZDczMDYzZTA2NzdiMTdjZTlj
NTAxNzdKMQoHY3Jld19pZBImCiQ3NjRjZWM1YS04NzkxLTRmN2MtOWY0MC1hNTMzMzJmOTk3YzBK
HAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdf
bnVtYmVyX29mX3Rhc2tzEgIYAkobChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgCSqwFCgtjcmV3
X2FnZW50cxKcBQqZBVt7ImtleSI6ICI3M2MzNDljOTNjMTYzYjVkNGRmOThhNjRmYWMxYzQzMCIs
ICJpZCI6ICJjZDgwYjlhNy1hN2QzLTQzNTQtYjUyOC1jMzAyODA0MjA3YzgiLCAicm9sZSI6ICJ7
dG9waWN9IFNlbmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJ2ZXJib3NlPyI6IGZhbHNlLCAibWF4
X2l0ZXIiOiAyMCwgIm1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwg
ImxsbSI6ICJncHQtNG8iLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29k
ZV9leGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMi
OiBbXX0sIHsia2V5IjogImJiMDY4Mzc3YzE2NDFiZTZkN2Q5N2E1MTY1OWRiNjEzIiwgImlkIjog
ImJmZjc3YmUyLWU4MjQtNGEyOS1hZTFlLTQyMWFjMzc2MjY2YyIsICJyb2xlIjogInt0b3BpY30g
UmVwb3J0aW5nIEFuYWx5c3RcbiIsICJ2ZXJib3NlPyI6IGZhbHNlLCAibWF4X2l0ZXIiOiAyMCwg
Im1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwgImxsbSI6ICJncHQt
NG8iLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29kZV9leGVjdXRpb24/
IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMiOiBbXX1dSpMECgpj
cmV3X3Rhc2tzEoQECoEEW3sia2V5IjogIjZhZmM0YjM5NjI1OWZiYjc2ODFmNTZjNzc1NWNjOTM3
IiwgImlkIjogIjRmNTFlYzM2LTVlMDctNGU4Ni1iYzIxLWU1MTQ0Mzg2YmIyYSIsICJhc3luY19l
eGVjdXRpb24/IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAi
e3RvcGljfSBTZW5pb3IgRGF0YSBSZXNlYXJjaGVyXG4iLCAiYWdlbnRfa2V5IjogIjczYzM0OWM5
M2MxNjNiNWQ0ZGY5OGE2NGZhYzFjNDMwIiwgInRvb2xzX25hbWVzIjogW119LCB7ImtleSI6ICJi
MTdiMTg4ZGJmMTRmOTNhOThlNWI5NWFhZDM2NzU3NyIsICJpZCI6ICIwMGJmZDY5ZC03OWZiLTRj
MjctYTM0Yi02NzBkZWJlMzU0NWYiLCAiYXN5bmNfZXhlY3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5f
aW5wdXQ/IjogZmFsc2UsICJhZ2VudF9yb2xlIjogInt0b3BpY30gUmVwb3J0aW5nIEFuYWx5c3Rc
biIsICJhZ2VudF9rZXkiOiAiYmIwNjgzNzdjMTY0MWJlNmQ3ZDk3YTUxNjU5ZGI2MTMiLCAidG9v
bHNfbmFtZXMiOiBbXX1degIYAYUBAAEAABKOAgoQsN5cQC9ZzBr2B0OKBR2WCxII3ULL7Wk965Yq
DFRhc2sgQ3JlYXRlZDABOWB9ROHWrwgYQfg0ReHWrwgYSi4KCGNyZXdfa2V5EiIKIGYzNDZhOWFk
NmQ3MzA2M2UwNjc3YjE3Y2U5YzUwMTc3SjEKB2NyZXdfaWQSJgokNzY0Y2VjNWEtODc5MS00Zjdj
LTlmNDAtYTUzMzMyZjk5N2MwSi4KCHRhc2tfa2V5EiIKIDZhZmM0YjM5NjI1OWZiYjc2ODFmNTZj
Nzc1NWNjOTM3SjEKB3Rhc2tfaWQSJgokNGY1MWVjMzYtNWUwNy00ZTg2LWJjMjEtZTUxNDQzODZi
YjJhegIYAYUBAAEAAA==
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '1894'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Sun, 17 Nov 2024 07:09:57 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are LLMs Senior Data Researcher\n.
You''re a seasoned researcher with a knack for uncovering the latest developments
in LLMs. Known for your ability to find the most relevant information and present
it in a clear and concise manner.\n\nYour personal goal is: Uncover cutting-edge
developments in LLMs\n\nTo give my best complete final answer to the task use
the exact following format:\n\nThought: I now can give a great answer\nFinal
Answer: Your final answer must be the great and the most complete as possible,
it must be outcome described.\n\nI MUST use these formats, my job depends on
it!"}, {"role": "user", "content": "\nCurrent Task: Conduct a thorough research
about LLMs Make sure you find any interesting and relevant information given
the current year is 2024.\n\n\nThis is the expect criteria for your final answer:
A list with 10 bullet points of the most relevant information about LLMs\n\nyou
MUST return the actual complete content as the final answer, not a summary.\n\nBegin!
This is VERY important to you, use the tools available and give your best Final
Answer, your job depends on it!\n\nThought:"}], "model": "gpt-4o", "stop": ["\nObservation:"],
"stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '1235'
content-type:
- application/json
cookie:
- __cf_bm=08pKRcLhS1PDw0mYfL2jz19ac6M.T31GoiMuI5DlX6w-1731827382-1.0.1.1-UfOLu3AaIUuXP1sGzdV6oggJ1q7iMTC46t08FDhYVrKcW5YmD4CbifudOJiSgx8h0JLTwZdgk.aG05S0eAO_PQ;
_cfuvid=74kaPOoAcp8YRSA0XocQ1FFNksu9V0_KiWdQfo7wQuQ-1731827382509-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
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
AhiZyAcAAP//AwCidyXxtw8AAA==
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e3de5de7b6c6217-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Sun, 17 Nov 2024 07:10:00 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '6026'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29999713'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_553f04a622d026a28dd3c5da55568fcd
status:
code: 200
message: OK
- request:
body: !!binary |
Cs4CCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSpQIKEgoQY3Jld2FpLnRl
bGVtZXRyeRKOAgoQIn+FuHJydyMnR3y/Qfb8GBII2zXFs4gynEgqDFRhc2sgQ3JlYXRlZDABOShs
9ljYrwgYQQiP+FjYrwgYSi4KCGNyZXdfa2V5EiIKIGYzNDZhOWFkNmQ3MzA2M2UwNjc3YjE3Y2U5
YzUwMTc3SjEKB2NyZXdfaWQSJgokNzY0Y2VjNWEtODc5MS00ZjdjLTlmNDAtYTUzMzMyZjk5N2Mw
Si4KCHRhc2tfa2V5EiIKIGIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3SjEKB3Rhc2tf
aWQSJgokMDBiZmQ2OWQtNzlmYi00YzI3LWEzNGItNjcwZGViZTM1NDVmegIYAYUBAAEAAA==
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '337'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Sun, 17 Nov 2024 07:10:01 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are LLMs Reporting Analyst\n.
You''re a meticulous analyst with a keen eye for detail. You''re known for your
ability to turn complex data into clear and concise reports, making it easy
for others to understand and act on the information you provide.\nYour personal
goal is: Create detailed reports based on LLMs data analysis and research findings\n\nTo
give my best complete final answer to the task use the exact following format:\n\nThought:
I now can give a great answer\nFinal Answer: Your final answer must be the great
and the most complete as possible, it must be outcome described.\n\nI MUST use
these formats, my job depends on it!"}, {"role": "user", "content": "\nCurrent
Task: Review the context you got and expand each topic into a full section for
a report. Make sure the report is detailed and contains any and all relevant
information.\n\n\nThis is the expect criteria for your final answer: A fully
fledge reports with the mains topics, each with a full section of information.
Formatted as markdown without ''```''\n\nyou MUST return the actual complete
content as the final answer, not a summary.\n\nThis is the context you''re working
with:\n1. **OpenAI''s GPT-4 Released**: OpenAI released GPT-4, which further
improves contextual understanding and generation capabilities. It offers increased
accuracy, creativity, and coherence in responses compared to its predecessors,
making it an essential tool for businesses, educators, and developers.\n\n2.
**Google''s Gemini Model**: In 2024, Google launched the Gemini model, focusing
on merging language understanding with multimodal capabilities. This model can
process text, audio, and images simultaneously, enhancing its applications in
fields like voice assistants and image captioning.\n\n3. **Anthropic''s Claude**:
Claude, by Anthropic, is designed to prioritize safety and ethical considerations
in LLM usage. It''s built to minimize harmful outputs and biases prevalent in
earlier language models, demonstrating a shift towards responsible AI deployment.\n\n4.
**Meta''s Open Pre-trained Transformer (OPT) 3.0**: Meta has introduced OPT
3.0, boasting efficient training approaches that lower computational costs while
maintaining high performance. The model excels in translation tasks and has
become a popular choice for academic research due to its open-access policy.\n\n5.
**Language Model Distillation Advances**: Recent advances in model distillation
techniques have allowed developers to deploy smaller, more efficient language
models on edge devices without notably compromising performance, expanding the
accessibility and application of LLMs in mobile and IoT devices.\n\n6. **Fine-Tuning
with Limited Data**: Methods for fine-tuning LLMs with limited data have improved,
enabling customization for niche applications without the need for vast datasets.
This development has opened doors to using LLMs in specialized industries, like
legal and medical sectors.\n\n7. **Ethical and Transparent AI Use**: 2024 has
seen a significant emphasis on ethical AI, with organizations establishing standardized
frameworks for LLM transparency and accountability. More companies are adopting
practices like AI model cards to disclose model capabilities, limitations, and
data sources.\n\n8. **The Rise of Prompt Engineering**: As models become more
advanced, prompt engineering has emerged as a crucial technique for optimizing
model outputs. This involves designing specific input prompts that guide LLMs
to yield desired results, thus enhancing usability in content creation and customer
service.\n\n9. **Integration with Augmented Reality**: Language models in 2024
are increasingly being integrated with AR technologies to provide real-time
language translation, virtual assistants in immersive environments, and interactive
educational tools, enriching the user''s experience with contextualized AI assistance.\n\n10.
**Regulatory Developments**: Governments worldwide are progressing towards formalizing
regulations around LLM usage, focusing on data privacy, security, and ethical
concerns. These developments aim to safeguard users while encouraging innovation
in AI technology.\n\nThese points reflect the cutting-edge advancements and
trends in the field of large language models (LLMs) as of 2024, highlighting
their growing influence and the increasing focus on ethical and practical deployment.\n\nBegin!
This is VERY important to you, use the tools available and give your best Final
Answer, your job depends on it!\n\nThought:"}], "model": "gpt-4o", "stop": ["\nObservation:"],
"stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '4624'
content-type:
- application/json
cookie:
- __cf_bm=08pKRcLhS1PDw0mYfL2jz19ac6M.T31GoiMuI5DlX6w-1731827382-1.0.1.1-UfOLu3AaIUuXP1sGzdV6oggJ1q7iMTC46t08FDhYVrKcW5YmD4CbifudOJiSgx8h0JLTwZdgk.aG05S0eAO_PQ;
_cfuvid=74kaPOoAcp8YRSA0XocQ1FFNksu9V0_KiWdQfo7wQuQ-1731827382509-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
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
AAAA//8DAMIhqlTfHQAA
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e3de605dca06217-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Sun, 17 Nov 2024 07:10:10 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '9951'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29998873'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 2ms
x-request-id:
- req_52a4f98f9c08fbaa1724634d237f3245
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,487 @@
interactions:
- request:
body: !!binary |
CusOCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSwg4KEgoQY3Jld2FpLnRl
bGVtZXRyeRKaDAoQJ2RtlOW3xhPcNjmbKwSJaxIIMUF8zJjQkvQqDENyZXcgQ3JlYXRlZDABOThF
x7PrrgkYQWiczLPrrgkYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODAuMEoaCg5weXRob25fdmVy
c2lvbhIICgYzLjEyLjdKLgoIY3Jld19rZXkSIgogMWYxMjhiZGI3YmFhNGI2NzcxNGYxZGFlZGMy
ZjNhYjZKMQoHY3Jld19pZBImCiQzNGJiYzZjYS03MmRiLTQwMzktODQzMy01NTFmOWNmNDM0YTdK
HAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdf
bnVtYmVyX29mX3Rhc2tzEgIYAkobChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgCSrQFCgtjcmV3
X2FnZW50cxKkBQqhBVt7ImtleSI6ICI3M2MzNDljOTNjMTYzYjVkNGRmOThhNjRmYWMxYzQzMCIs
ICJpZCI6ICI4MjJkOGM2OC01NzlkLTQ4ZWUtOTBhMi1hNjJiNDgzY2JhNGUiLCAicm9sZSI6ICJ7
dG9waWN9IFNlbmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJ2ZXJib3NlPyI6IHRydWUsICJtYXhf
aXRlciI6IDIwLCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAi
bGxtIjogImdwdC00by1taW5pIiwgImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93
X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25h
bWVzIjogW119LCB7ImtleSI6ICIxMDRmZTA2NTllMTBiNDI2Y2Y4OGYwMjRmYjU3MTU1MyIsICJp
ZCI6ICI0YTY4NDQwZi0xMjRkLTQ3YmEtYWEzNy1hZTZmMTI2NzlkMmIiLCAicm9sZSI6ICJ7dG9w
aWN9IFJlcG9ydGluZyBBbmFseXN0XG4iLCAidmVyYm9zZT8iOiB0cnVlLCAibWF4X2l0ZXIiOiAy
MCwgIm1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwgImxsbSI6ICJn
cHQtNG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4
ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtd
fV1KkwQKCmNyZXdfdGFza3MShAQKgQRbeyJrZXkiOiAiNmFmYzRiMzk2MjU5ZmJiNzY4MWY1NmM3
NzU1Y2M5MzciLCAiaWQiOiAiODE2YzI1ZDgtNDg3NC00MmMxLWJmNzEtODc2OTcxZDNmYmExIiwg
ImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRf
cm9sZSI6ICJ7dG9waWN9IFNlbmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJhZ2VudF9rZXkiOiAi
NzNjMzQ5YzkzYzE2M2I1ZDRkZjk4YTY0ZmFjMWM0MzAiLCAidG9vbHNfbmFtZXMiOiBbXX0sIHsi
a2V5IjogImIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3IiwgImlkIjogIjM4YzU1NTI5
LTc2ODAtNDc5OS1iODdiLTFmMDY2NjE5MGU2NyIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2Us
ICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAie3RvcGljfSBSZXBvcnRpbmcg
QW5hbHlzdFxuIiwgImFnZW50X2tleSI6ICIxMDRmZTA2NTllMTBiNDI2Y2Y4OGYwMjRmYjU3MTU1
MyIsICJ0b29sc19uYW1lcyI6IFtdfV16AhgBhQEAAQAAEo4CChCo3E4xT/U6O20NrD4/Zkt6EggD
/w74tbrrOCoMVGFzayBDcmVhdGVkMAE5SPTas+uuCRhB6IDbs+uuCRhKLgoIY3Jld19rZXkSIgog
MWYxMjhiZGI3YmFhNGI2NzcxNGYxZGFlZGMyZjNhYjZKMQoHY3Jld19pZBImCiQzNGJiYzZjYS03
MmRiLTQwMzktODQzMy01NTFmOWNmNDM0YTdKLgoIdGFza19rZXkSIgogNmFmYzRiMzk2MjU5ZmJi
NzY4MWY1NmM3NzU1Y2M5MzdKMQoHdGFza19pZBImCiQ4MTZjMjVkOC00ODc0LTQyYzEtYmY3MS04
NzY5NzFkM2ZiYTF6AhgBhQEAAQAA
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '1902'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Wed, 20 Nov 2024 13:04:24 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are Bicycles Senior Data
Researcher\n. You''re a seasoned researcher with a knack for uncovering the
latest developments in Bicycles. Known for your ability to find the most relevant
information and present it in a clear and concise manner.\n\nYour personal goal
is: Uncover cutting-edge developments in Bicycles\n\nTo give my best complete
final answer to the task use the exact following format:\n\nThought: I now can
give a great answer\nFinal Answer: Your final answer must be the great and the
most complete as possible, it must be outcome described.\n\nI MUST use these
formats, my job depends on it!"}, {"role": "user", "content": "\nCurrent Task:
Conduct a thorough research about Bicycles Make sure you find any interesting
and relevant information given the current year is 2024.\n\n\nThis is the expect
criteria for your final answer: A list with 10 bullet points of the most relevant
information about Bicycles\n\nyou MUST return the actual complete content as
the final answer, not a summary.\n\nBegin! This is VERY important to you, use
the tools available and give your best Final Answer, your job depends on it!\n\nThought:"}],
"model": "gpt-4o-mini", "stop": ["\nObservation:"], "stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '1260'
content-type:
- application/json
cookie:
- __cf_bm=CkK4UvBd9ukXvn50uJwGambJcz5zERAJfeXJ9xge6H4-1732107842-1.0.1.1-IOK2yVL3RlD75MgmnKzIEyE38HNknwn6I8BBJ1wjGz4jCTd0YWIBPnvUm9gB8D_zLlUA9G7p_wbrfyc4mO_Bmg;
_cfuvid=MmeN9oHWrBLThkEJdaSFHBfWe95JvA8iFnnt7CC92tk-1732107842102-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-AVefTnyhy126z54bX4Wq0TjWFUGJI\",\n \"object\":
\"chat.completion\",\n \"created\": 1732107859,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"I now can give a great answer. \\nFinal
Answer: \\n\\n1. **E-Bike Boom**: Electric bikes (e-bikes) have seen a significant
rise in popularity, with industry reports indicating a projected growth of 60%
in sales compared to previous years. Many cities are paving bike lanes specifically
designed for e-bikes to accommodate this surge.\\n\\n2. **Sustainability in
Manufacturing**: Bicycle manufacturers are increasingly adopting sustainable
practices, such as using recycled materials for frames and parts, and implementing
environmentally friendly production processes. This shift is driven by consumer
demand for greener products.\\n\\n3. **Smart Bicycles**: The integration of
technology in bicycles has progressed with smart bikes featuring built-in GPS,
automated gear shifting, and performance analytics. These innovations enhance
the cycling experience and cater to data-driven enthusiasts.\\n\\n4. **Bike
Sharing Programs**: Urban areas are continuing to expand bike-sharing programs,
with some cities introducing electric bike options and introducing smartphone
apps to streamline the renting process, increasing accessibility and convenience
for riders.\\n\\n5. **Safety Innovations**: Advances in safety technology such
as smart helmets that incorporate lights and indicators, anti-collision systems
using sensor technology, and built-in communication systems to connect with
smartphones are on the rise, aimed at reducing accidents.\\n\\n6. **Adventure
Cycling Trends**: There is a growing popularity in adventure and gravel cycling,
with more cyclists seeking off-road experiences. This has prompted manufacturers
to develop dedicated bikes that cater to rugged terrains, with features such
as wider tires and durable frames.\\n\\n7. **Customization and Personalization**:
The market for customizable bicycles is expanding. Consumers are now able to
choose colors, styles, and features that suit their personal preferences, leading
to a more personalized cycling experience.\\n\\n8. **Communities and Events**:
Cycling communities are thriving globally, with an increase in events such as
group rides, competitive races, and festivals celebrating biking culture. This
fosters social engagement and promotes cycling as a lifestyle.\\n\\n9. **Cargo
Bikes for Urban Living**: The rise of cargo bikes, particularly in urban environments,
allows for efficient transportation of goods, making them an appealing choice
for small businesses and families. This trend is encouraged by city planners
promoting cycling as an alternative to car deliveries.\\n\\n10. **Regulatory
Changes**: Governments around the world are increasingly implementing policies
to support cycling infrastructure, such as funding for bike lanes, subsidies
for bicycle purchases, and stricter emissions standards for motor vehicles,
making cycling a more attractive option for commuting.\\n\\nEach of these points
represents the latest developments in the bicycle industry as we move through
2024, highlighting advancements in technology, trends in user preferences, and
a broader societal shift towards sustainability and health.\",\n \"refusal\":
null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n
\ }\n ],\n \"usage\": {\n \"prompt_tokens\": 237,\n \"completion_tokens\":
539,\n \"total_tokens\": 776,\n \"prompt_tokens_details\": {\n \"cached_tokens\":
0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": {\n
\ \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"system_fingerprint\":
\"fp_0705bf87c0\"\n}\n"
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e58a5276a096225-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Wed, 20 Nov 2024 13:04:26 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '7355'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149999708'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_5536f2a242886d3949f0cdc1628b2996
http_version: HTTP/1.1
status_code: 200
- request:
body: !!binary |
Cs4CCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSpQIKEgoQY3Jld2FpLnRl
bGVtZXRyeRKOAgoQpBIRwGH/fJtGJT1cIWsC5BIIM3YyJZEYUUgqDFRhc2sgQ3JlYXRlZDABOYgb
lILtrgkYQZBnlYLtrgkYSi4KCGNyZXdfa2V5EiIKIDFmMTI4YmRiN2JhYTRiNjc3MTRmMWRhZWRj
MmYzYWI2SjEKB2NyZXdfaWQSJgokMzRiYmM2Y2EtNzJkYi00MDM5LTg0MzMtNTUxZjljZjQzNGE3
Si4KCHRhc2tfa2V5EiIKIGIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3SjEKB3Rhc2tf
aWQSJgokMzhjNTU1MjktNzY4MC00Nzk5LWI4N2ItMWYwNjY2MTkwZTY3egIYAYUBAAEAAA==
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '337'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Wed, 20 Nov 2024 13:04:29 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are Bicycles Reporting
Analyst\n. You''re a meticulous analyst with a keen eye for detail. You''re
known for your ability to turn complex data into clear and concise reports,
making it easy for others to understand and act on the information you provide.\n\nYour
personal goal is: Create detailed reports based on Bicycles data analysis and
research findings\n\nTo give my best complete final answer to the task use the
exact following format:\n\nThought: I now can give a great answer\nFinal Answer:
Your final answer must be the great and the most complete as possible, it must
be outcome described.\n\nI MUST use these formats, my job depends on it!"},
{"role": "user", "content": "\nCurrent Task: Review the context you got and
expand each topic into a full section for a report. Make sure the report is
detailed and contains any and all relevant information.\n\n\nThis is the expect
criteria for your final answer: A fully fledge reports with the mains topics,
each with a full section of information. Formatted as markdown without ''```''\n\nyou
MUST return the actual complete content as the final answer, not a summary.\n\nThis
is the context you''re working with:\n1. **E-Bike Boom**: Electric bikes (e-bikes)
have seen a significant rise in popularity, with industry reports indicating
a projected growth of 60% in sales compared to previous years. Many cities are
paving bike lanes specifically designed for e-bikes to accommodate this surge.\n\n2.
**Sustainability in Manufacturing**: Bicycle manufacturers are increasingly
adopting sustainable practices, such as using recycled materials for frames
and parts, and implementing environmentally friendly production processes. This
shift is driven by consumer demand for greener products.\n\n3. **Smart Bicycles**:
The integration of technology in bicycles has progressed with smart bikes featuring
built-in GPS, automated gear shifting, and performance analytics. These innovations
enhance the cycling experience and cater to data-driven enthusiasts.\n\n4. **Bike
Sharing Programs**: Urban areas are continuing to expand bike-sharing programs,
with some cities introducing electric bike options and introducing smartphone
apps to streamline the renting process, increasing accessibility and convenience
for riders.\n\n5. **Safety Innovations**: Advances in safety technology such
as smart helmets that incorporate lights and indicators, anti-collision systems
using sensor technology, and built-in communication systems to connect with
smartphones are on the rise, aimed at reducing accidents.\n\n6. **Adventure
Cycling Trends**: There is a growing popularity in adventure and gravel cycling,
with more cyclists seeking off-road experiences. This has prompted manufacturers
to develop dedicated bikes that cater to rugged terrains, with features such
as wider tires and durable frames.\n\n7. **Customization and Personalization**:
The market for customizable bicycles is expanding. Consumers are now able to
choose colors, styles, and features that suit their personal preferences, leading
to a more personalized cycling experience.\n\n8. **Communities and Events**:
Cycling communities are thriving globally, with an increase in events such as
group rides, competitive races, and festivals celebrating biking culture. This
fosters social engagement and promotes cycling as a lifestyle.\n\n9. **Cargo
Bikes for Urban Living**: The rise of cargo bikes, particularly in urban environments,
allows for efficient transportation of goods, making them an appealing choice
for small businesses and families. This trend is encouraged by city planners
promoting cycling as an alternative to car deliveries.\n\n10. **Regulatory Changes**:
Governments around the world are increasingly implementing policies to support
cycling infrastructure, such as funding for bike lanes, subsidies for bicycle
purchases, and stricter emissions standards for motor vehicles, making cycling
a more attractive option for commuting.\n\nEach of these points represents the
latest developments in the bicycle industry as we move through 2024, highlighting
advancements in technology, trends in user preferences, and a broader societal
shift towards sustainability and health.\n\nBegin! This is VERY important to
you, use the tools available and give your best Final Answer, your job depends
on it!\n\nThought:"}], "model": "gpt-4o-mini", "stop": ["\nObservation:"], "stream":
false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '4457'
content-type:
- application/json
cookie:
- __cf_bm=CkK4UvBd9ukXvn50uJwGambJcz5zERAJfeXJ9xge6H4-1732107842-1.0.1.1-IOK2yVL3RlD75MgmnKzIEyE38HNknwn6I8BBJ1wjGz4jCTd0YWIBPnvUm9gB8D_zLlUA9G7p_wbrfyc4mO_Bmg;
_cfuvid=MmeN9oHWrBLThkEJdaSFHBfWe95JvA8iFnnt7CC92tk-1732107842102-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-AVefbpMLcvelEguI3pyXOpfbaXLGG\",\n \"object\":
\"chat.completion\",\n \"created\": 1732107867,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"I now can give a great answer \\nFinal
Answer: \\n\\n# Comprehensive Report on the Latest Developments in the Bicycle
Industry (2024)\\n\\n## 1. E-Bike Boom\\nThe popularity of electric bikes (e-bikes)
has surged dramatically in recent years, with industry reports indicating a
projected growth of 60% in sales compared to previous years. This growth can
be attributed to increasing urbanization, the rising need for more sustainable
modes of transport, and technological advancements that have made e-bikes more
accessible and desirable. Cities worldwide are responding to this boom by developing
dedicated bike lanes specifically designed for e-bikes, which not only promotes
safety but also encourages more individuals to consider cycling as a primary
mode of transportation.\\n\\n## 2. Sustainability in Manufacturing\\nIn line
with global trends towards sustainability, bicycle manufacturers are increasingly
adopting eco-friendlier practices. They are utilizing recycled materials for
frames and components and implementing environmentally friendly production processes.
This shift is not just a response to regulatory pressures but also driven by
consumer demand for greener products. Companies that prioritize sustainability
are seeing a competitive edge in an increasingly eco-conscious market, as consumers
are more likely to align their purchases with their values regarding environmental
responsibility.\\n\\n## 3. Smart Bicycles\\nThe integration of technology in
bicycles has advanced significantly, resulting in the emergence of smart bikes.
These bicycles often feature built-in GPS for navigation, automated gear shifting
for smoother rides, and performance analytics that allow users to track their
cycling metrics. Such innovations enhance the overall cycling experience and
cater to performance-focused cyclists who seek data to optimize their rides.
By merging cycling with technology, manufacturers are not only attracting tech
enthusiasts but also making cycling more mainstream.\\n\\n## 4. Bike Sharing
Programs\\nBike-sharing programs are rapidly expanding, particularly in urban
areas. Many cities have started introducing electric bike options within these
programs to meet the growing demand. The introduction of smartphone apps has
streamlined the renting process, increasing accessibility and convenience for
users. This trend not only promotes a healthier lifestyle but also reduces traffic
congestion and environmental impact in densely populated areas, making cycling
a more viable option for commuting.\\n\\n## 5. Safety Innovations\\nRecent advancements
in safety technology are working towards making cycling safer. Innovations such
as smart helmets equipped with lights and turn indicators, anti-collision systems
utilizing sensor technology, and integrated communication systems linking bicycles
with smartphones are increasingly gaining traction. These developments aim to
minimize accidents and enhance the overall sense of security for cyclists, thereby
encouraging more people to take up cycling as a daily activity.\\n\\n## 6. Adventure
Cycling Trends\\nAdventure and gravel cycling are witnessing a renaissance,
with many cyclists seeking off-road experiences that enable a connection with
nature. This trend has led manufacturers to innovate by developing dedicated
bikes suited for rugged terrains, characterized by features like wider tires
and durable frames. As consumers become more adventurous in their hobbies, manufacturers
are recognizing the need to cater to this niche market, fostering the growth
of adventure cycling as a distinct segment in the industry.\\n\\n## 7. Customization
and Personalization\\nThe demand for customizable bicycles is on the rise, allowing
consumers to choose various aspects of their bikes, including colors, styles,
and features. This trend towards personalization is enhancing the cycling experience,
as riders can tailor their bicycles to their preferences. The flourishing market
for custom bikes reflects a broader societal shift towards individuality and
self-expression, as consumers are no longer content with one-size-fits-all solutions.\\n\\n##
8. Communities and Events\\nCycling communities are thriving worldwide, reflected
in an increase in events such as group rides, competitive races, and festivals
celebrating biking culture. These gatherings not only foster a sense of camaraderie
among cyclists but also promote cycling as a lifestyle choice to the wider community.
The growth of these events is instrumental in building a culture around cycling,
driving advocacy for cycling infrastructure and safety, and ultimately increasing
the number of people who cycle.\\n\\n## 9. Cargo Bikes for Urban Living\\nThe
rise of cargo bikes, especially in urban settings, represents an innovative
solution for transporting goods efficiently while reducing reliance on motor
vehicles. Such bikes serve as an appealing alternative for small businesses
and families alike, allowing for easy deliveries and shopping. City planners
are increasingly promoting cargo bikes within urban transport strategies, recognizing
them as a sustainable option that aligns with broader goals for reducing carbon
footprints and enhancing urban mobility.\\n\\n## 10. Regulatory Changes\\nGovernments
around the globe are progressively enacting regulations to support and grow
cycling infrastructure. Initiatives include funding for bike lanes, subsidies
for bicycle purchases, and stricter emissions standards for cars. These regulatory
changes are making cycling a more attractive option for commuting and are an
acknowledgment of the role that cycling plays in reducing pollution and traffic
congestion. Such policies are instrumental in fostering a cycling-friendly environment
and encouraging more people to adopt biking as a daily mode of transportation.\\n\\nThis
report highlights the most significant developments in the bicycle industry
as we advance through 2024, showcasing the technological breakthroughs, shifts
in user preferences, and an overarching movement toward sustainability and health.
These trends are indicative of a vibrant cycling culture that continues to evolve
to meet the needs of modern society.\",\n \"refusal\": null\n },\n
\ \"logprobs\": null,\n \"finish_reason\": \"stop\"\n }\n ],\n
\ \"usage\": {\n \"prompt_tokens\": 790,\n \"completion_tokens\": 1022,\n
\ \"total_tokens\": 1812,\n \"prompt_tokens_details\": {\n \"cached_tokens\":
0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": {\n
\ \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"system_fingerprint\":
\"fp_0705bf87c0\"\n}\n"
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e58a5580add6225-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Wed, 20 Nov 2024 13:04:46 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '18921'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149998916'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_32b801874a2fed46b91251052364ec47
http_version: HTTP/1.1
status_code: 200
version: 1

View File

@@ -0,0 +1,115 @@
interactions:
- request:
body: '{"messages": [{"role": "system", "content": "You are Information Agent.
You have access to specific knowledge sources.\nYour personal goal is: Provide
information based on knowledge sources\nTo give my best complete final answer
to the task use the exact following format:\n\nThought: I now can give a great
answer\nFinal Answer: Your final answer must be the great and the most complete
as possible, it must be outcome described.\n\nI MUST use these formats, my job
depends on it!"}, {"role": "user", "content": "\nCurrent Task: What is Brandon''s
favorite color?\n\nThis is the expect criteria for your final answer: Brandon''s
favorite color.\nyou MUST return the actual complete content as the final answer,
not a summary.\n\nBegin! This is VERY important to you, use the tools available
and give your best Final Answer, your job depends on it!\n\nThought:"}], "model":
"gpt-4o-mini", "stop": ["\nObservation:"], "stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '931'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.9
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
H4sIAAAAAAAAA4xSQW7bMBC86xULXnqxAtmxI1e3FEWBtJekCXJpC4GmVhIdapcgqbhN4L8HlB1L
QVOgFwGa2RnOLPmcAAhdiQKEamVQnTXp5f3d9lsdbndh++C+757Or6/bm6uvn59WH/FGzKKCN1tU
4VV1prizBoNmOtDKoQwYXef5+SK7WK3ny4HouEITZY0N6ZLTTpNOF9limWZ5Ol8f1S1rhV4U8CMB
AHgevjEnVfhbFJDNXpEOvZcNiuI0BCAcm4gI6b32QVIQs5FUTAFpiH4FxDtQkqDRjwgSmhgbJPkd
OoCf9EWTNHA5/BfwyUmqmD54qOUjOx0QFBt2oD1sTI9n02Mc1r2XsSr1xhzx/Sm34cY63vgjf8Jr
Tdq3pUPpmWJGH9iKgd0nAL+G/fRvKgvruLOhDPyAFA3nF/nBT4zXMmHXRzJwkGaKr2bv+JUVBqmN
n2xYKKlarEbpeB2yrzRPiGTS+u8073kfmmtq/sd+JJRCG7AqrcNKq7eNxzGH8dX+a+y05SGw8H98
wK6sNTXorNOHN1PbMsuz1aZe5yoTyT55AQAA//8DAPaYLdRBAwAA
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e54a2a7d81467f7-SJC
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Wed, 20 Nov 2024 01:23:34 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=DoHo1Z11nN9bxkwZmJGnaxRhyrWE0UfyimYuUVRU6A4-1732065814-1.0.1.1-JVRvFrIJLHEq9OaFQS0qcgYcawE7t2XQ4Tpqd58n2Yfx3mvEqD34MJmooi1LtvdvjB2J8x1Rs.rCdXD.msLlKw;
path=/; expires=Wed, 20-Nov-24 01:53:34 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=n3RrNhFMqC3HtJ7n3e3agyxnM1YOQ6eKESz_eeXLtZA-1732065814630-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '344'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149999790'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_8f1622677c64913753a595f679596614
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,445 @@
interactions:
- request:
body: '{"messages": [{"role": "system", "content": "You are Bicycles Senior Data
Researcher\n. You''re a seasoned researcher with a knack for uncovering the
latest developments in Bicycles. Known for your ability to find the most relevant
information and present it in a clear and concise manner.\n\nYour personal goal
is: Uncover cutting-edge developments in Bicycles\n\nTo give my best complete
final answer to the task use the exact following format:\n\nThought: I now can
give a great answer\nFinal Answer: Your final answer must be the great and the
most complete as possible, it must be outcome described.\n\nI MUST use these
formats, my job depends on it!"}, {"role": "user", "content": "\nCurrent Task:
Conduct a thorough research about Bicycles Make sure you find any interesting
and relevant information given the current year is 2024.\n\n\nThis is the expect
criteria for your final answer: A list with 10 bullet points of the most relevant
information about Bicycles\n\nyou MUST return the actual complete content as
the final answer, not a summary.\n\nBegin! This is VERY important to you, use
the tools available and give your best Final Answer, your job depends on it!\n\nThought:"}],
"model": "gpt-4o", "stop": ["\nObservation:"], "stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '1255'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
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
Ag4AAA==
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e44d29989a61ab0-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Mon, 18 Nov 2024 03:20:10 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=elWqsM.3Jt5.vyzDrpCmVftKrlxb0_fRVMZxBGUYfcE-1731900010-1.0.1.1-AxUZI4aRPPnqgUcewvytSN0TcEpcfBqYEZ.h2A96g3wUsy6Ui_pr4y81nyHf2Pcn1S3lz4zSmufsGDmnNKtHDQ;
path=/; expires=Mon, 18-Nov-24 03:50:10 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=lzrs54cKet3l28qlaoF9_vtIs55.7H9Sbr6IhTssBmk-1731900010790-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '5249'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29999708'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_a9781a68655042f161d8089cc3819728
status:
code: 200
message: OK
- request:
body: !!binary |
CuEOCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSuA4KEgoQY3Jld2FpLnRl
bGVtZXRyeRKQDAoQ2G6ncUKutPIsOmTplHC6bBIIclCMqGiNvUoqDENyZXcgQ3JlYXRlZDABOcBv
KPXg8QgYQXAFLvXg8QgYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODAuMEoaCg5weXRob25fdmVy
c2lvbhIICgYzLjExLjdKLgoIY3Jld19rZXkSIgogMWYxMjhiZGI3YmFhNGI2NzcxNGYxZGFlZGMy
ZjNhYjZKMQoHY3Jld19pZBImCiQzNDEwYmI2Mi01NzYxLTRhMGQtOGY1Zi1hOTliZWY5NDYxM2VK
HAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdf
bnVtYmVyX29mX3Rhc2tzEgIYAkobChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgCSqoFCgtjcmV3
X2FnZW50cxKaBQqXBVt7ImtleSI6ICI3M2MzNDljOTNjMTYzYjVkNGRmOThhNjRmYWMxYzQzMCIs
ICJpZCI6ICI1YzgyZGRkOS1kMTM3LTQ3MDMtODY0My1iNTFmZDBlMTUxMjkiLCAicm9sZSI6ICJ7
dG9waWN9IFNlbmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJ2ZXJib3NlPyI6IHRydWUsICJtYXhf
aXRlciI6IDIwLCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAi
bGxtIjogImdwdC00byIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2Rl
X2V4ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6
IFtdfSwgeyJrZXkiOiAiMTA0ZmUwNjU5ZTEwYjQyNmNmODhmMDI0ZmI1NzE1NTMiLCAiaWQiOiAi
ODdlYmRiYTMtNDRmZS00ODBmLWI2MWQtMWYzZjIyMWE5MDE2IiwgInJvbGUiOiAie3RvcGljfSBS
ZXBvcnRpbmcgQW5hbHlzdFxuIiwgInZlcmJvc2U/IjogdHJ1ZSwgIm1heF9pdGVyIjogMjAsICJt
YXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogIiIsICJsbG0iOiAiZ3B0LTRv
IiwgImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6
IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25hbWVzIjogW119XUqTBAoKY3Jl
d190YXNrcxKEBAqBBFt7ImtleSI6ICI2YWZjNGIzOTYyNTlmYmI3NjgxZjU2Yzc3NTVjYzkzNyIs
ICJpZCI6ICI2ZTIzZmMzMS02OGI2LTRjZTMtODZjNC0zMDcxZGUwZDdjMWIiLCAiYXN5bmNfZXhl
Y3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5faW5wdXQ/IjogZmFsc2UsICJhZ2VudF9yb2xlIjogInt0
b3BpY30gU2VuaW9yIERhdGEgUmVzZWFyY2hlclxuIiwgImFnZW50X2tleSI6ICI3M2MzNDljOTNj
MTYzYjVkNGRmOThhNjRmYWMxYzQzMCIsICJ0b29sc19uYW1lcyI6IFtdfSwgeyJrZXkiOiAiYjE3
YjE4OGRiZjE0ZjkzYTk4ZTViOTVhYWQzNjc1NzciLCAiaWQiOiAiNzRhOWVhMjMtNzVmYy00NWFi
LWIyMDAtMTllZTk0ZjU0Y2JkIiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lu
cHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJ7dG9waWN9IFJlcG9ydGluZyBBbmFseXN0XG4i
LCAiYWdlbnRfa2V5IjogIjEwNGZlMDY1OWUxMGI0MjZjZjg4ZjAyNGZiNTcxNTUzIiwgInRvb2xz
X25hbWVzIjogW119XXoCGAGFAQABAAASjgIKEDkgSkh9vBYObKyMriyidxwSCG3RsAoOYBU/KgxU
YXNrIENyZWF0ZWQwATkgjkr14PEIGEHYFkv14PEIGEouCghjcmV3X2tleRIiCiAxZjEyOGJkYjdi
YWE0YjY3NzE0ZjFkYWVkYzJmM2FiNkoxCgdjcmV3X2lkEiYKJDM0MTBiYjYyLTU3NjEtNGEwZC04
ZjVmLWE5OWJlZjk0NjEzZUouCgh0YXNrX2tleRIiCiA2YWZjNGIzOTYyNTlmYmI3NjgxZjU2Yzc3
NTVjYzkzN0oxCgd0YXNrX2lkEiYKJDZlMjNmYzMxLTY4YjYtNGNlMy04NmM0LTMwNzFkZTBkN2Mx
YnoCGAGFAQABAAA=
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '1892'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Mon, 18 Nov 2024 03:20:10 GMT
status:
code: 200
message: OK
- request:
body: !!binary |
Cs4CCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSpQIKEgoQY3Jld2FpLnRl
bGVtZXRyeRKOAgoQwB8k3adY9mK031pcBVZJKhII3fxizKFNiGkqDFRhc2sgQ3JlYXRlZDABOaj7
K0Xi8QgYQUiCLUXi8QgYSi4KCGNyZXdfa2V5EiIKIDFmMTI4YmRiN2JhYTRiNjc3MTRmMWRhZWRj
MmYzYWI2SjEKB2NyZXdfaWQSJgokMzQxMGJiNjItNTc2MS00YTBkLThmNWYtYTk5YmVmOTQ2MTNl
Si4KCHRhc2tfa2V5EiIKIGIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3SjEKB3Rhc2tf
aWQSJgokNzRhOWVhMjMtNzVmYy00NWFiLWIyMDAtMTllZTk0ZjU0Y2JkegIYAYUBAAEAAA==
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '337'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Mon, 18 Nov 2024 03:20:15 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are Bicycles Reporting
Analyst\n. You''re a meticulous analyst with a keen eye for detail. You''re
known for your ability to turn complex data into clear and concise reports,
making it easy for others to understand and act on the information you provide.\n\nYour
personal goal is: Create detailed reports based on Bicycles data analysis and
research findings\n\nTo give my best complete final answer to the task use the
exact following format:\n\nThought: I now can give a great answer\nFinal Answer:
Your final answer must be the great and the most complete as possible, it must
be outcome described.\n\nI MUST use these formats, my job depends on it!"},
{"role": "user", "content": "\nCurrent Task: Review the context you got and
expand each topic into a full section for a report. Make sure the report is
detailed and contains any and all relevant information.\n\n\nThis is the expect
criteria for your final answer: A fully fledge reports with the mains topics,
each with a full section of information. Formatted as markdown without ''```''\n\nyou
MUST return the actual complete content as the final answer, not a summary.\n\nThis
is the context you''re working with:\n1. **Electric Bicycles (E-Bikes) Dominate
the Market:** In 2024, e-bikes continue to lead in sales growth globally. Their
popularity is fueled by the advancement in battery technology, offering longer
ranges and shorter charging times, making commuting more efficient and sustainable
in urban environments.\n\n2. **Integration with Smart Technology:** Bicycle
manufacturers are increasingly incorporating IoT technology to enhance user
experience. Features like GPS tracking, fitness data logging, and anti-theft
systems directly linked to smartphones are becoming standard in newer models.\n\n3.
**Sustainable Manufacturing Techniques:** Environmental concerns have pushed
companies to adopt greener manufacturing processes, such as utilizing recycled
materials, reducing carbon footprints in production, and implementing circular
economies within the bicycle industry.\n\n4. **Innovations in Lightweight Materials:**
The development of new composite materials, including carbon and graphene, results
in extremely lightweight and durable frames. This advancement is particularly
noticeable in racing and mountain bikes, enhancing performance and speed.\n\n5.
**Customizable and Modular Bike Designs:** In 2024, there is a notable trend
toward bikes with modular designs that allow riders to customize parts and accessories
easily. This trend caters to diverse consumer needs and promotes longer bike
life cycles by allowing for parts replacement instead of whole bikes.\n\n6.
**Expansion of Urban Cycling Infrastructure:** More cities worldwide are investing
in cycling-friendly infrastructure, such as dedicated bike lanes and bike-sharing
schemes, to encourage eco-friendly commuting and reduce traffic congestion.\n\n7.
**Health and Wellness Benefits:** With growing awareness of health and fitness,
more people are choosing cycling as a daily exercise routine. The industry sees
a surge in sales of fitness-oriented bicycles designed to maximize cardiovascular
and strength training benefits.\n\n8. **Rise of Cargo and Utility Bicycles:**
There is an increase in demand for cargo bicycles, which are used for transporting
goods over short distances, reflecting a shift towards sustainable business
delivery options, particularly in urban settings.\n\n9. **Competitive Cycling
and Esports:** Competitive cycling has embraced digital platforms, with virtual
reality and augmented reality races gaining traction among cycling enthusiasts
and professional athletes for training and competition purposes.\n\n10. **Focus
on Bike Safety Innovations:** Advances in bicycle safety technology, including
smart helmets with built-in communication systems and advanced lighting for
night visibility, are considerably improving rider security, making cycling
a safer mode of transport.\n\nBegin! This is VERY important to you, use the
tools available and give your best Final Answer, your job depends on it!\n\nThought:"}],
"model": "gpt-4o", "stop": ["\nObservation:"], "stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '4197'
content-type:
- application/json
cookie:
- __cf_bm=elWqsM.3Jt5.vyzDrpCmVftKrlxb0_fRVMZxBGUYfcE-1731900010-1.0.1.1-AxUZI4aRPPnqgUcewvytSN0TcEpcfBqYEZ.h2A96g3wUsy6Ui_pr4y81nyHf2Pcn1S3lz4zSmufsGDmnNKtHDQ;
_cfuvid=lzrs54cKet3l28qlaoF9_vtIs55.7H9Sbr6IhTssBmk-1731900010790-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
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
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e44d2bc2bec1ab0-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Mon, 18 Nov 2024 03:20:25 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '13936'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29998979'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 2ms
x-request-id:
- req_602e9ec1c4bc0da2fdb284f809c50872
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,438 @@
interactions:
- request:
body: !!binary |
CuMOCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSug4KEgoQY3Jld2FpLnRl
bGVtZXRyeRKSDAoQf/zeqxfqyNP5BgW6rZrC0BIIiXyYjb3bUBcqDENyZXcgQ3JlYXRlZDABOXha
vrnarwgYQcCbxrnarwgYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODAuMEoaCg5weXRob25fdmVy
c2lvbhIICgYzLjExLjdKLgoIY3Jld19rZXkSIgogZjM0NmE5YWQ2ZDczMDYzZTA2NzdiMTdjZTlj
NTAxNzdKMQoHY3Jld19pZBImCiQ2Yzg5NDczNy0zNWJjLTRhZDEtYjE2Ni1hZTY3ODhhMTA4YWZK
HAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdf
bnVtYmVyX29mX3Rhc2tzEgIYAkobChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgCSqwFCgtjcmV3
X2FnZW50cxKcBQqZBVt7ImtleSI6ICI3M2MzNDljOTNjMTYzYjVkNGRmOThhNjRmYWMxYzQzMCIs
ICJpZCI6ICIzNDQ2YWRlOS05YWM0LTQ1NTUtOTlkNS0zYWM0MzdhMmMxNmUiLCAicm9sZSI6ICJ7
dG9waWN9IFNlbmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJ2ZXJib3NlPyI6IGZhbHNlLCAibWF4
X2l0ZXIiOiAyMCwgIm1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwg
ImxsbSI6ICJncHQtNG8iLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29k
ZV9leGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMi
OiBbXX0sIHsia2V5IjogImJiMDY4Mzc3YzE2NDFiZTZkN2Q5N2E1MTY1OWRiNjEzIiwgImlkIjog
IjExMzVjODkzLTRlZGUtNDRiNC1hMjZmLTIxYWUxNzA0ZDRlZCIsICJyb2xlIjogInt0b3BpY30g
UmVwb3J0aW5nIEFuYWx5c3RcbiIsICJ2ZXJib3NlPyI6IGZhbHNlLCAibWF4X2l0ZXIiOiAyMCwg
Im1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwgImxsbSI6ICJncHQt
NG8iLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29kZV9leGVjdXRpb24/
IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMiOiBbXX1dSpMECgpj
cmV3X3Rhc2tzEoQECoEEW3sia2V5IjogIjZhZmM0YjM5NjI1OWZiYjc2ODFmNTZjNzc1NWNjOTM3
IiwgImlkIjogImIxZjQ5ODJiLTRjZGItNDk1MC04ZmNjLWMwZDcxNzRhYzY0NiIsICJhc3luY19l
eGVjdXRpb24/IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAi
e3RvcGljfSBTZW5pb3IgRGF0YSBSZXNlYXJjaGVyXG4iLCAiYWdlbnRfa2V5IjogIjczYzM0OWM5
M2MxNjNiNWQ0ZGY5OGE2NGZhYzFjNDMwIiwgInRvb2xzX25hbWVzIjogW119LCB7ImtleSI6ICJi
MTdiMTg4ZGJmMTRmOTNhOThlNWI5NWFhZDM2NzU3NyIsICJpZCI6ICIyY2VkNGVhNC01YjcwLTRh
MDctOTEyOS00MzQ2ZDQ1OWM4NjIiLCAiYXN5bmNfZXhlY3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5f
aW5wdXQ/IjogZmFsc2UsICJhZ2VudF9yb2xlIjogInt0b3BpY30gUmVwb3J0aW5nIEFuYWx5c3Rc
biIsICJhZ2VudF9rZXkiOiAiYmIwNjgzNzdjMTY0MWJlNmQ3ZDk3YTUxNjU5ZGI2MTMiLCAidG9v
bHNfbmFtZXMiOiBbXX1degIYAYUBAAEAABKOAgoQOaRyuH2UERJ3sHC1ImhOgxIIq8DZc4P2KYMq
DFRhc2sgQ3JlYXRlZDABOTA127narwgYQVjV27narwgYSi4KCGNyZXdfa2V5EiIKIGYzNDZhOWFk
NmQ3MzA2M2UwNjc3YjE3Y2U5YzUwMTc3SjEKB2NyZXdfaWQSJgokNmM4OTQ3MzctMzViYy00YWQx
LWIxNjYtYWU2Nzg4YTEwOGFmSi4KCHRhc2tfa2V5EiIKIDZhZmM0YjM5NjI1OWZiYjc2ODFmNTZj
Nzc1NWNjOTM3SjEKB3Rhc2tfaWQSJgokYjFmNDk4MmItNGNkYi00OTUwLThmY2MtYzBkNzE3NGFj
NjQ2egIYAYUBAAEAAA==
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '1894'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Sun, 17 Nov 2024 07:10:11 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are {topic} Senior Data
Researcher\n. You''re a seasoned researcher with a knack for uncovering the
latest developments in {topic}. Known for your ability to find the most relevant
information and present it in a clear and concise manner.\n\nYour personal goal
is: Uncover cutting-edge developments in {topic}\n\nTo give my best complete
final answer to the task use the exact following format:\n\nThought: I now can
give a great answer\nFinal Answer: Your final answer must be the great and the
most complete as possible, it must be outcome described.\n\nI MUST use these
formats, my job depends on it!"}, {"role": "user", "content": "\nCurrent Task:
Conduct a thorough research about {topic} Make sure you find any interesting
and relevant information given the current year is 2024.\n\n\nThis is the expect
criteria for your final answer: A list with 10 bullet points of the most relevant
information about {topic}\n\nyou MUST return the actual complete content as
the final answer, not a summary.\n\nBegin! This is VERY important to you, use
the tools available and give your best Final Answer, your job depends on it!\n\nThought:"}],
"model": "gpt-4o", "stop": ["\nObservation:"], "stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '1250'
content-type:
- application/json
cookie:
- __cf_bm=08pKRcLhS1PDw0mYfL2jz19ac6M.T31GoiMuI5DlX6w-1731827382-1.0.1.1-UfOLu3AaIUuXP1sGzdV6oggJ1q7iMTC46t08FDhYVrKcW5YmD4CbifudOJiSgx8h0JLTwZdgk.aG05S0eAO_PQ;
_cfuvid=74kaPOoAcp8YRSA0XocQ1FFNksu9V0_KiWdQfo7wQuQ-1731827382509-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
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
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e3de645a8666217-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Sun, 17 Nov 2024 07:10:16 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '5537'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29999711'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_220e7945d04e84ab7b58c252c98630b5
status:
code: 200
message: OK
- request:
body: !!binary |
Cs4CCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSpQIKEgoQY3Jld2FpLnRl
bGVtZXRyeRKOAgoQrqG+rs9H9Iyyqr2ZU1qS4RIIWspPh5zdoVMqDFRhc2sgQ3JlYXRlZDABOeiB
tw7crwgYQZgvuQ7crwgYSi4KCGNyZXdfa2V5EiIKIGYzNDZhOWFkNmQ3MzA2M2UwNjc3YjE3Y2U5
YzUwMTc3SjEKB2NyZXdfaWQSJgokNmM4OTQ3MzctMzViYy00YWQxLWIxNjYtYWU2Nzg4YTEwOGFm
Si4KCHRhc2tfa2V5EiIKIGIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3SjEKB3Rhc2tf
aWQSJgokMmNlZDRlYTQtNWI3MC00YTA3LTkxMjktNDM0NmQ0NTljODYyegIYAYUBAAEAAA==
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '337'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Sun, 17 Nov 2024 07:10:22 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are {topic} Reporting
Analyst\n. You''re a meticulous analyst with a keen eye for detail. You''re
known for your ability to turn complex data into clear and concise reports,
making it easy for others to understand and act on the information you provide.\nYour
personal goal is: Create detailed reports based on {topic} data analysis and
research findings\n\nTo give my best complete final answer to the task use the
exact following format:\n\nThought: I now can give a great answer\nFinal Answer:
Your final answer must be the great and the most complete as possible, it must
be outcome described.\n\nI MUST use these formats, my job depends on it!"},
{"role": "user", "content": "\nCurrent Task: Review the context you got and
expand each topic into a full section for a report. Make sure the report is
detailed and contains any and all relevant information.\n\n\nThis is the expect
criteria for your final answer: A fully fledge reports with the mains topics,
each with a full section of information. Formatted as markdown without ''```''\n\nyou
MUST return the actual complete content as the final answer, not a summary.\n\nThis
is the context you''re working with:\n1. **Breakthrough in Quantum Computing**:
By 2024, advancements in quantum computing have led to more reliable qubit processing,
paving the way for practical applications in cryptography, complex system simulations,
and optimization problems.\n\n2. **AI Integration in Healthcare**: Artificial
intelligence continues to transform healthcare, with AI algorithms now more
accurately diagnosing diseases, predicting patient outcomes, and personalizing
treatment plans than ever before.\n\n3. **Renewable Energy Innovations**: The
year 2024 has seen significant improvements in renewable energy technologies.
Next-generation solar panels and wind turbines are more efficient, leading to
widespread adoption and reduced reliance on fossil fuels.\n\n4. **5G Expansion
and 6G Development**: The global rollout of 5G technology reaches near completion,
and research into 6G has commenced. This development promises to introduce unprecedented
data transfer speeds and connectivity.\n\n5. **Advances in Biotechnology**:
Gene-editing technologies, such as CRISPR, have advanced to a stage where genetic
disorders can be effectively treated, sparking ethical debates and regulatory
considerations.\n\n6. **Space Exploration Milestones**: The space industry achieves
new milestones with the establishment of permanent lunar bases and the first
manned missions to Mars, driven by both government and private sector collaboration.\n\n7.
**Sustainable Agriculture Practices**: In response to climate change challenges,
sustainable agriculture practices, including vertical farming and precision
agriculture, are gaining traction globally, boosting food production and reducing
environmental impact.\n\n8. **Cybersecurity Enhancements**: With increasing
digital threats, 2024 sees robust advancements in cybersecurity technologies,
including AI-driven threat detection, and enhanced data encryption methodologies.\n\n9.
**Transportation Innovation**: Public transportation and electric vehicle technology
continue to evolve with the introduction of autonomous public transit systems
and improvements in EV battery longevity and charging infrastructures.\n\n10.
**Mental Health Awareness**: A global increase in mental health awareness leads
to increased funding for research and the integration of digital therapies and
apps that provide more accessible mental health support.\n\nThese bullet points
summarize significant areas of development and interest in the given topic in
2024, highlighting the profound impacts in various fields.\n\nBegin! This is
VERY important to you, use the tools available and give your best Final Answer,
your job depends on it!\n\nThought:"}], "model": "gpt-4o", "stop": ["\nObservation:"],
"stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '3935'
content-type:
- application/json
cookie:
- __cf_bm=08pKRcLhS1PDw0mYfL2jz19ac6M.T31GoiMuI5DlX6w-1731827382-1.0.1.1-UfOLu3AaIUuXP1sGzdV6oggJ1q7iMTC46t08FDhYVrKcW5YmD4CbifudOJiSgx8h0JLTwZdgk.aG05S0eAO_PQ;
_cfuvid=74kaPOoAcp8YRSA0XocQ1FFNksu9V0_KiWdQfo7wQuQ-1731827382509-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
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
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e3de6697f976217-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Sun, 17 Nov 2024 07:10:27 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '10658'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29999045'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 1ms
x-request-id:
- req_f0af67637da5bc0e6b11fc3e5db59f62
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,500 @@
interactions:
- request:
body: !!binary |
CusOCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSwg4KEgoQY3Jld2FpLnRl
bGVtZXRyeRKaDAoQFHOMv8VK3fCTALziX07PIRIIN6Cmi+pyjGkqDENyZXcgQ3JlYXRlZDABORgw
kr/lrgkYQWDinL/lrgkYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODAuMEoaCg5weXRob25fdmVy
c2lvbhIICgYzLjEyLjdKLgoIY3Jld19rZXkSIgogMWYxMjhiZGI3YmFhNGI2NzcxNGYxZGFlZGMy
ZjNhYjZKMQoHY3Jld19pZBImCiQ5MWYxYTY2OC05Y2MwLTQxODctYWZmOS03NzJkNzZlMzg3NDlK
HAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdf
bnVtYmVyX29mX3Rhc2tzEgIYAkobChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgCSrQFCgtjcmV3
X2FnZW50cxKkBQqhBVt7ImtleSI6ICI3M2MzNDljOTNjMTYzYjVkNGRmOThhNjRmYWMxYzQzMCIs
ICJpZCI6ICIxNDFhOGY2NS0zODRjLTQxMDMtODgwZS02ODMzNTQ0NmVkN2YiLCAicm9sZSI6ICJ7
dG9waWN9IFNlbmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJ2ZXJib3NlPyI6IHRydWUsICJtYXhf
aXRlciI6IDIwLCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAi
bGxtIjogImdwdC00by1taW5pIiwgImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93
X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25h
bWVzIjogW119LCB7ImtleSI6ICIxMDRmZTA2NTllMTBiNDI2Y2Y4OGYwMjRmYjU3MTU1MyIsICJp
ZCI6ICI5YWFkMWUxMi00MTgxLTQ5NTctYmNlNS01ZWNhODg2YjMxYWYiLCAicm9sZSI6ICJ7dG9w
aWN9IFJlcG9ydGluZyBBbmFseXN0XG4iLCAidmVyYm9zZT8iOiB0cnVlLCAibWF4X2l0ZXIiOiAy
MCwgIm1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwgImxsbSI6ICJn
cHQtNG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4
ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtd
fV1KkwQKCmNyZXdfdGFza3MShAQKgQRbeyJrZXkiOiAiNmFmYzRiMzk2MjU5ZmJiNzY4MWY1NmM3
NzU1Y2M5MzciLCAiaWQiOiAiNTI5YmU1NTMtM2Y3Mi00YTU2LWFhNWItYWE0ZTZmMzhlOWJhIiwg
ImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRf
cm9sZSI6ICJ7dG9waWN9IFNlbmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJhZ2VudF9rZXkiOiAi
NzNjMzQ5YzkzYzE2M2I1ZDRkZjk4YTY0ZmFjMWM0MzAiLCAidG9vbHNfbmFtZXMiOiBbXX0sIHsi
a2V5IjogImIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3IiwgImlkIjogImI2NzQyNmI0
LTM2NTAtNDY5MS1iYTU4LWYwZTRmOWM0NTk3YyIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2Us
ICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAie3RvcGljfSBSZXBvcnRpbmcg
QW5hbHlzdFxuIiwgImFnZW50X2tleSI6ICIxMDRmZTA2NTllMTBiNDI2Y2Y4OGYwMjRmYjU3MTU1
MyIsICJ0b29sc19uYW1lcyI6IFtdfV16AhgBhQEAAQAAEo4CChBM7T06NWnnx9b1Sl8dbVH+Eghz
9rR/8DUNEioMVGFzayBDcmVhdGVkMAE5yJqzv+WuCRhBqEa0v+WuCRhKLgoIY3Jld19rZXkSIgog
MWYxMjhiZGI3YmFhNGI2NzcxNGYxZGFlZGMyZjNhYjZKMQoHY3Jld19pZBImCiQ5MWYxYTY2OC05
Y2MwLTQxODctYWZmOS03NzJkNzZlMzg3NDlKLgoIdGFza19rZXkSIgogNmFmYzRiMzk2MjU5ZmJi
NzY4MWY1NmM3NzU1Y2M5MzdKMQoHdGFza19pZBImCiQ1MjliZTU1My0zZjcyLTRhNTYtYWE1Yi1h
YTRlNmYzOGU5YmF6AhgBhQEAAQAA
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '1902'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Wed, 20 Nov 2024 13:03:59 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are Bicycles Senior Data
Researcher\n. You''re a seasoned researcher with a knack for uncovering the
latest developments in Bicycles. Known for your ability to find the most relevant
information and present it in a clear and concise manner.\n\nYour personal goal
is: Uncover cutting-edge developments in Bicycles\n\nTo give my best complete
final answer to the task use the exact following format:\n\nThought: I now can
give a great answer\nFinal Answer: Your final answer must be the great and the
most complete as possible, it must be outcome described.\n\nI MUST use these
formats, my job depends on it!"}, {"role": "user", "content": "\nCurrent Task:
Conduct a thorough research about Bicycles Make sure you find any interesting
and relevant information given the current year is 2024.\n\n\nThis is the expect
criteria for your final answer: A list with 10 bullet points of the most relevant
information about Bicycles\n\nyou MUST return the actual complete content as
the final answer, not a summary.\n\nBegin! This is VERY important to you, use
the tools available and give your best Final Answer, your job depends on it!\n\nThought:"}],
"model": "gpt-4o-mini", "stop": ["\nObservation:"], "stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '1260'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-AVef48hbtmEEfHJzc9KI6SOG72L6j\",\n \"object\":
\"chat.completion\",\n \"created\": 1732107834,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"I now can give a great answer. \\nFinal
Answer: \\n\\n1. **E-Bike Market Growth**: The e-bike market has experienced
unprecedented growth, with sales increasing by over 45% in 2023 compared to
the previous year, driven by rising fuel prices and increased urbanization.
For 2024, predictions suggest this trend will continue as more consumers seek
sustainable transportation options.\\n\\n2. **Smart Technology Integration**:
Bicycle manufacturers are increasingly integrating smart technology into their
models. Features like GPS navigation, smartphone connectivity, anti-theft alarms,
and fitness tracking are becoming standard, enhancing the cycling experience
while providing riders with valuable data.\\n\\n3. **Sustainable Materials**:
Many companies are now focusing on using sustainable and eco-friendly materials
for bicycle production, with significant advancements in recycled aluminum and
carbon fiber technologies. This approach not only reduces environmental impact
but also appeals to eco-conscious consumers.\\n\\n4. **Urban Infrastructure
Improvements**: Cities worldwide are investing heavily in improving cycling
infrastructure, including the addition of dedicated bike lanes, bike-sharing
programs, and parking facilities, aiming to promote cycling as a primary mode
of transport and improve safety for cyclists.\\n\\n5. **Global Cycling Tourism
Increase**: Cycling tourism has seen a surge in popularity, with destinations
specifically catering to cyclists emerging across Europe, North America, and
Asia. This trend encourages eco-friendly travel options and boosts local economies,
offering curated cycling paths and accommodations.\\n\\n6. **Bike Repair & Maintenance
Innovations**: Innovative solutions like mobile bike repair services and self-service
bike repair stations are becoming more common, addressing the maintenance needs
of cyclists and reducing barriers to cycling.\\n\\n7. **Safety Innovations**:
The development of safety features such as automatic lights that respond to
ambient light, integrated turn signals in helmets, and advanced brake systems
have become essential selling points for new bikes, increasing rider visibility
and safety.\\n\\n8. **Performance Enhancements**: Advances in bike design and
materials, such as lightweight titanium and carbon fiber frames, have enhanced
performance for competitive cyclists. Additionally, innovations in gear shifting
and suspension systems are improving efficiency and comfort.\\n\\n9. **Inclusivity
in Cycling**: An increasing number of brands are focusing on inclusivity, producing
step-through frames and bikes tailored for various body types and abilities,
thus promoting cycling for people of all ages and physical conditions.\\n\\n10.
**Data Analytics for Cycling Trends**: The use of data analytics to study cycling
patterns has increased, helping cities and businesses understand cycling behaviors
and improve services. Insights gathered are being used to optimize bike-sharing
programs and enhance cycling infrastructure strategically.\\n\\nThis comprehensive
understanding highlights the diverse and exciting developments in the bicycle
industry, reflective of the shifting trends and technological advancements as
we move through 2024.\",\n \"refusal\": null\n },\n \"logprobs\":
null,\n \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\":
237,\n \"completion_tokens\": 540,\n \"total_tokens\": 777,\n \"prompt_tokens_details\":
{\n \"cached_tokens\": 0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\":
{\n \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"system_fingerprint\":
\"fp_0705bf87c0\"\n}\n"
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e58a48a783d6225-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Wed, 20 Nov 2024 13:04:02 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=CkK4UvBd9ukXvn50uJwGambJcz5zERAJfeXJ9xge6H4-1732107842-1.0.1.1-IOK2yVL3RlD75MgmnKzIEyE38HNknwn6I8BBJ1wjGz4jCTd0YWIBPnvUm9gB8D_zLlUA9G7p_wbrfyc4mO_Bmg;
path=/; expires=Wed, 20-Nov-24 13:34:02 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=MmeN9oHWrBLThkEJdaSFHBfWe95JvA8iFnnt7CC92tk-1732107842102-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '7649'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149999708'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_60a333db2dbe3378c077ae0b2af16f8e
http_version: HTTP/1.1
status_code: 200
- request:
body: !!binary |
Cs4CCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSpQIKEgoQY3Jld2FpLnRl
bGVtZXRyeRKOAgoQU4pBe1pQxsUBVChkPK41ghII8dnGjmMshHkqDFRhc2sgQ3JlYXRlZDABOQiW
uMjnrgkYQYjOucjnrgkYSi4KCGNyZXdfa2V5EiIKIDFmMTI4YmRiN2JhYTRiNjc3MTRmMWRhZWRj
MmYzYWI2SjEKB2NyZXdfaWQSJgokOTFmMWE2NjgtOWNjMC00MTg3LWFmZjktNzcyZDc2ZTM4NzQ5
Si4KCHRhc2tfa2V5EiIKIGIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3SjEKB3Rhc2tf
aWQSJgokYjY3NDI2YjQtMzY1MC00NjkxLWJhNTgtZjBlNGY5YzQ1OTdjegIYAYUBAAEAAA==
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '337'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Wed, 20 Nov 2024 13:04:04 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are Bicycles Reporting
Analyst\n. You''re a meticulous analyst with a keen eye for detail. You''re
known for your ability to turn complex data into clear and concise reports,
making it easy for others to understand and act on the information you provide.\n\nYour
personal goal is: Create detailed reports based on Bicycles data analysis and
research findings\n\nTo give my best complete final answer to the task use the
exact following format:\n\nThought: I now can give a great answer\nFinal Answer:
Your final answer must be the great and the most complete as possible, it must
be outcome described.\n\nI MUST use these formats, my job depends on it!"},
{"role": "user", "content": "\nCurrent Task: Review the context you got and
expand each topic into a full section for a report. Make sure the report is
detailed and contains any and all relevant information.\n\n\nThis is the expect
criteria for your final answer: A fully fledge reports with the mains topics,
each with a full section of information. Formatted as markdown without ''```''\n\nyou
MUST return the actual complete content as the final answer, not a summary.\n\nThis
is the context you''re working with:\n1. **E-Bike Market Growth**: The e-bike
market has experienced unprecedented growth, with sales increasing by over 45%
in 2023 compared to the previous year, driven by rising fuel prices and increased
urbanization. For 2024, predictions suggest this trend will continue as more
consumers seek sustainable transportation options.\n\n2. **Smart Technology
Integration**: Bicycle manufacturers are increasingly integrating smart technology
into their models. Features like GPS navigation, smartphone connectivity, anti-theft
alarms, and fitness tracking are becoming standard, enhancing the cycling experience
while providing riders with valuable data.\n\n3. **Sustainable Materials**:
Many companies are now focusing on using sustainable and eco-friendly materials
for bicycle production, with significant advancements in recycled aluminum and
carbon fiber technologies. This approach not only reduces environmental impact
but also appeals to eco-conscious consumers.\n\n4. **Urban Infrastructure Improvements**:
Cities worldwide are investing heavily in improving cycling infrastructure,
including the addition of dedicated bike lanes, bike-sharing programs, and parking
facilities, aiming to promote cycling as a primary mode of transport and improve
safety for cyclists.\n\n5. **Global Cycling Tourism Increase**: Cycling tourism
has seen a surge in popularity, with destinations specifically catering to cyclists
emerging across Europe, North America, and Asia. This trend encourages eco-friendly
travel options and boosts local economies, offering curated cycling paths and
accommodations.\n\n6. **Bike Repair & Maintenance Innovations**: Innovative
solutions like mobile bike repair services and self-service bike repair stations
are becoming more common, addressing the maintenance needs of cyclists and reducing
barriers to cycling.\n\n7. **Safety Innovations**: The development of safety
features such as automatic lights that respond to ambient light, integrated
turn signals in helmets, and advanced brake systems have become essential selling
points for new bikes, increasing rider visibility and safety.\n\n8. **Performance
Enhancements**: Advances in bike design and materials, such as lightweight titanium
and carbon fiber frames, have enhanced performance for competitive cyclists.
Additionally, innovations in gear shifting and suspension systems are improving
efficiency and comfort.\n\n9. **Inclusivity in Cycling**: An increasing number
of brands are focusing on inclusivity, producing step-through frames and bikes
tailored for various body types and abilities, thus promoting cycling for people
of all ages and physical conditions.\n\n10. **Data Analytics for Cycling Trends**:
The use of data analytics to study cycling patterns has increased, helping cities
and businesses understand cycling behaviors and improve services. Insights gathered
are being used to optimize bike-sharing programs and enhance cycling infrastructure
strategically.\n\nThis comprehensive understanding highlights the diverse and
exciting developments in the bicycle industry, reflective of the shifting trends
and technological advancements as we move through 2024.\n\nBegin! This is VERY
important to you, use the tools available and give your best Final Answer, your
job depends on it!\n\nThought:"}], "model": "gpt-4o-mini", "stop": ["\nObservation:"],
"stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '4587'
content-type:
- application/json
cookie:
- __cf_bm=CkK4UvBd9ukXvn50uJwGambJcz5zERAJfeXJ9xge6H4-1732107842-1.0.1.1-IOK2yVL3RlD75MgmnKzIEyE38HNknwn6I8BBJ1wjGz4jCTd0YWIBPnvUm9gB8D_zLlUA9G7p_wbrfyc4mO_Bmg;
_cfuvid=MmeN9oHWrBLThkEJdaSFHBfWe95JvA8iFnnt7CC92tk-1732107842102-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-AVefC4hfHvHYaSnPpfpnDBIn5IOgg\",\n \"object\":
\"chat.completion\",\n \"created\": 1732107842,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"I now can give a great answer \\nFinal
Answer: \\n\\n# Detailed Report on Current Bicycle Industry Trends\\n\\n## 1.
E-Bike Market Growth\\nThe e-bike market has experienced unprecedented growth
in 2023, with sales skyrocketing by over 45% compared to the previous year.
The surge in popularity is largely attributed to rising fuel prices that compel
consumers to explore alternative modes of transportation, as well as increased
urbanization that pushes individuals towards more sustainable commuting options.
In 2024, forecasts indicate that this robust growth is likely to persist as
more consumers prioritize eco-friendly transportation solutions. Factors driving
this momentum include government incentives for electric vehicle purchases,
improved battery technology providing longer ranges, and the appeal of e-bikes
as a viable solution for first-and-last-mile connectivity in urban environments.\\n\\n##
2. Smart Technology Integration\\nThe bicycle manufacturing industry is witnessing
an increasing trend towards integrating smart technology into their products.
Modern bicycles now come equipped with features such as GPS navigation systems,
Bluetooth connectivity, anti-theft alarms, and fitness tracking capabilities.
These enhancements not only enrich the cycling experience by providing cyclists
with valuable data\u2014such as speed, distance traveled, and route optimization\u2014but
also position cycling as a technologically advanced means of transport. Such
innovations cater particularly to tech-savvy consumers looking for a comprehensive
solution that addresses both utility and convenience.\\n\\n## 3. Sustainable
Materials\\nIn response to growing environmental concerns, many bicycle manufacturers
are now focusing on the use of sustainable and eco-friendly materials in their
production processes. Innovations in recycled aluminum production and advancements
in carbon fiber manufacturing are leading the way to minimize the ecological
footprint of bicycles. The shift to sustainable materials not only attracts
eco-conscious consumers but also aligns with the broader movement towards sustainability
within various industries. This commitment to responsible sourcing and production
practices is intended to resonate with consumers increasingly prioritizing sustainability
in their purchasing decisions.\\n\\n## 4. Urban Infrastructure Improvements\\nCities
across the globe are investing significantly to enhance cycling infrastructure,
which includes creating dedicated bike lanes, establishing bike-sharing programs,
and increasing the availability of secure bike parking facilities. The aim of
these investment strategies is to promote cycling as a primary mode of transportation,
thereby alleviating traffic congestion and reducing urban air pollution. These
improvements not only make cycling safer and more appealing but also encourage
a cultural shift towards embracing cycling as a sustainable form of transport,
contributing to healthier urban populations.\\n\\n## 5. Global Cycling Tourism
Increase\\nCycling tourism has emerged as a rapidly growing sector, with numerous
destinations catering specifically to the needs of cyclists. Regions in Europe,
North America, and Asia have begun to promote curated cycling paths and accommodations
that enhance the travel experience for biking enthusiasts. This trend encourages
eco-friendly travel options and provides a substantial boost to local economies
reliant on tourism. With more travelers seeking unique and sustainable adventure
experiences, cycling tourism is cementing its place as a desirable and responsible
leisure activity.\\n\\n## 6. Bike Repair & Maintenance Innovations\\nAs cycling
becomes more popular, addressing the maintenance needs of bicycles is critical.
The advent of innovative solutions such as mobile bike repair services and self-service
repair stations is helping cyclists maintain their bikes more conveniently.
These services remove barriers to cycling by providing quick access to repair
assistance, thus ensuring that cyclists can get back on the road with minimal
downtime. Additionally, the proliferation of these services reflects an increasingly
proactive approach to bicycle maintenance within the industry.\\n\\n## 7. Safety
Innovations\\nSafety remains a paramount concern for cyclists, prompting the
development of several innovative features that enhance visibility and rider
protection. New safety technologies include automatic lights that adjust to
ambient lighting, integrated turn signals built into helmets, and advanced braking
systems that improve stopping power. These innovations not only elevate the
overall safety of new bicycles but also serve as essential selling points for
manufacturers, helping to reassure potential buyers about the security of their
cycling experiences.\\n\\n## 8. Performance Enhancements\\nContinual advancements
in bike design and materials have significantly improved performance for competitive
cyclists. The adoption of lightweight materials like titanium and carbon fiber
frames enhances speed and maneuverability. Moreover, state-of-the-art gear shifting
mechanisms and suspension systems are optimizing cycling efficiency and rider
comfort. These innovations cater to both amateur and professional cyclists alike,
emphasizing the drive for enhanced performance in the marketplace.\\n\\n## 9.
Inclusivity in Cycling\\nThe bicycle industry is progressively recognizing the
importance of inclusivity by producing more diverse models catering to a wide
range of body types and abilities. This includes step-through frames designed
for easier mounting and dismounting as well as specialized bikes accommodating
unique ergonomic needs. By promoting cycling as an approachable and accessible
activity for individuals of various ages and physical conditions, brands are
broadening their market reach and fostering a more inclusive cycling community.\\n\\n##
10. Data Analytics for Cycling Trends\\nThe utilization of data analytics in
cycling is on the rise, as cities and businesses increasingly turn to data-driven
insights to understand cyclist behaviors and optimize offerings. Analytics are
being harnessed to fine-tune bike-sharing programs, enhancing user experience
through informed decision-making. This strategic approach not only aids in the
identification of high-demand cycling routes but also informs infrastructure
investments, ensuring that cycling continues to become a more viable and attractive
option for urban transport.\\n\\nIn summary, these trends reflect a dynamic
and rapidly evolving bicycle industry characterized by technological advancements,
sustainability efforts, and a commitment to inclusivity. As we advance through
2024, these developments will shape the future of cycling, making it not just
a mode of transport but a lifestyle choice that emphasizes health, environment,
and community engagement.\",\n \"refusal\": null\n },\n \"logprobs\":
null,\n \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\":
791,\n \"completion_tokens\": 1102,\n \"total_tokens\": 1893,\n \"prompt_tokens_details\":
{\n \"cached_tokens\": 0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\":
{\n \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"system_fingerprint\":
\"fp_0705bf87c0\"\n}\n"
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e58a4be3c906225-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Wed, 20 Nov 2024 13:04:18 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '16287'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149998883'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_bb43402829dc4dc60bf6f4b76a72e6c9
http_version: HTTP/1.1
status_code: 200
version: 1

View File

@@ -0,0 +1,492 @@
interactions:
- request:
body: !!binary |
CusOCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSwg4KEgoQY3Jld2FpLnRl
bGVtZXRyeRKaDAoQ4G43ZjKxBKDC/tbsjP4YXxIINS4tBd9tcREqDENyZXcgQ3JlYXRlZDABOQB0
FQ7yrgkYQdg+GA7yrgkYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODAuMEoaCg5weXRob25fdmVy
c2lvbhIICgYzLjEyLjdKLgoIY3Jld19rZXkSIgogMWYxMjhiZGI3YmFhNGI2NzcxNGYxZGFlZGMy
ZjNhYjZKMQoHY3Jld19pZBImCiQzNTE4YjRjNS0xYTM5LTRkYjEtODEwMy03MzllNjQ5YzAwZDhK
HAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdf
bnVtYmVyX29mX3Rhc2tzEgIYAkobChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgCSrQFCgtjcmV3
X2FnZW50cxKkBQqhBVt7ImtleSI6ICI3M2MzNDljOTNjMTYzYjVkNGRmOThhNjRmYWMxYzQzMCIs
ICJpZCI6ICIyZmFkNjUwMC0wYTk1LTRmMTMtYjk5YS0zMTE1YzRkOTM3ODgiLCAicm9sZSI6ICJ7
dG9waWN9IFNlbmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJ2ZXJib3NlPyI6IHRydWUsICJtYXhf
aXRlciI6IDIwLCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAi
bGxtIjogImdwdC00by1taW5pIiwgImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93
X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25h
bWVzIjogW119LCB7ImtleSI6ICIxMDRmZTA2NTllMTBiNDI2Y2Y4OGYwMjRmYjU3MTU1MyIsICJp
ZCI6ICIxYTQ0MjFiOC1lZWMzLTQ1ZjItODY1NS01NDcyMWIyOTk5NDciLCAicm9sZSI6ICJ7dG9w
aWN9IFJlcG9ydGluZyBBbmFseXN0XG4iLCAidmVyYm9zZT8iOiB0cnVlLCAibWF4X2l0ZXIiOiAy
MCwgIm1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwgImxsbSI6ICJn
cHQtNG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4
ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtd
fV1KkwQKCmNyZXdfdGFza3MShAQKgQRbeyJrZXkiOiAiNmFmYzRiMzk2MjU5ZmJiNzY4MWY1NmM3
NzU1Y2M5MzciLCAiaWQiOiAiMmY2ODFlY2YtNmY0Yy00NzlhLWE0ZWEtY2Y0ZTVmNGM2ZWFlIiwg
ImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRf
cm9sZSI6ICJ7dG9waWN9IFNlbmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJhZ2VudF9rZXkiOiAi
NzNjMzQ5YzkzYzE2M2I1ZDRkZjk4YTY0ZmFjMWM0MzAiLCAidG9vbHNfbmFtZXMiOiBbXX0sIHsi
a2V5IjogImIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3IiwgImlkIjogIjgwM2Q5YWYy
LTdhYjAtNDYzNy1iMWJjLTkxNDJmMWJkMDM0YSIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2Us
ICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAie3RvcGljfSBSZXBvcnRpbmcg
QW5hbHlzdFxuIiwgImFnZW50X2tleSI6ICIxMDRmZTA2NTllMTBiNDI2Y2Y4OGYwMjRmYjU3MTU1
MyIsICJ0b29sc19uYW1lcyI6IFtdfV16AhgBhQEAAQAAEo4CChCkKf4+mBo3buykKHqmcwYdEgit
HkuXVEC4UCoMVGFzayBDcmVhdGVkMAE5uJAnDvKuCRhBcBkoDvKuCRhKLgoIY3Jld19rZXkSIgog
MWYxMjhiZGI3YmFhNGI2NzcxNGYxZGFlZGMyZjNhYjZKMQoHY3Jld19pZBImCiQzNTE4YjRjNS0x
YTM5LTRkYjEtODEwMy03MzllNjQ5YzAwZDhKLgoIdGFza19rZXkSIgogNmFmYzRiMzk2MjU5ZmJi
NzY4MWY1NmM3NzU1Y2M5MzdKMQoHdGFza19pZBImCiQyZjY4MWVjZi02ZjRjLTQ3OWEtYTRlYS1j
ZjRlNWY0YzZlYWV6AhgBhQEAAQAA
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '1902'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Wed, 20 Nov 2024 13:04:49 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are {topic} Senior Data
Researcher\n. You''re a seasoned researcher with a knack for uncovering the
latest developments in {topic}. Known for your ability to find the most relevant
information and present it in a clear and concise manner.\n\nYour personal goal
is: Uncover cutting-edge developments in {topic}\n\nTo give my best complete
final answer to the task use the exact following format:\n\nThought: I now can
give a great answer\nFinal Answer: Your final answer must be the great and the
most complete as possible, it must be outcome described.\n\nI MUST use these
formats, my job depends on it!"}, {"role": "user", "content": "\nCurrent Task:
Conduct a thorough research about {topic} Make sure you find any interesting
and relevant information given the current year is 2024.\n\n\nThis is the expect
criteria for your final answer: A list with 10 bullet points of the most relevant
information about {topic}\n\nyou MUST return the actual complete content as
the final answer, not a summary.\n\nBegin! This is VERY important to you, use
the tools available and give your best Final Answer, your job depends on it!\n\nThought:"}],
"model": "gpt-4o-mini", "stop": ["\nObservation:"], "stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '1255'
content-type:
- application/json
cookie:
- __cf_bm=CkK4UvBd9ukXvn50uJwGambJcz5zERAJfeXJ9xge6H4-1732107842-1.0.1.1-IOK2yVL3RlD75MgmnKzIEyE38HNknwn6I8BBJ1wjGz4jCTd0YWIBPnvUm9gB8D_zLlUA9G7p_wbrfyc4mO_Bmg;
_cfuvid=MmeN9oHWrBLThkEJdaSFHBfWe95JvA8iFnnt7CC92tk-1732107842102-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-AVefuCEPMJPCqhgvBPhOk55hlNQ0m\",\n \"object\":
\"chat.completion\",\n \"created\": 1732107886,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"I now can give a great answer. \\nFinal
Answer: \\n\\n1. **Artificial Intelligence Advancements**: In 2024, AI has made
significant strides in natural language processing and computer vision, with
models achieving near-human-level understanding and interpretation capabilities.
This has led to more sophisticated AI applications across industries.\\n\\n2.
**Quantum Computing Progress**: Quantum computers are now capable of surpassing
traditional computing power for specific tasks, with breakthroughs in error
correction and qubit coherence. This achievement is paving the way for real-world
applications in cryptography and complex problem-solving.\\n\\n3. **Sustainable
Energy Technologies**: The shift toward renewable energy sources has accelerated,
with innovations in solar panel efficiency and the rise of hydrogen fuel cells
gaining traction as viable alternatives for energy storage and transportation.\\n\\n4.
**Augmented Reality Enhancements**: In 2024, augmented reality (AR) technologies
are being integrated into everyday applications, from retail to education, providing
immersive experiences that enhance learning and consumer engagement.\\n\\n5.
**5G Expansion and 6G Development**: The rollout of 5G continues to expand globally,
while foundational work on 6G is underway, promising enhanced connectivity speeds,
low latency, and the potential for new applications like smart cities and automated
industries.\\n\\n6. **Data Privacy Regulations**: As data breaches become increasingly
sophisticated, worldwide regulations around data privacy have tightened, with
new laws being implemented to protect consumer information and corporate accountability
in data handling.\\n\\n7. **Biotechnology Breakthroughs**: Advances in gene
editing technologies, particularly CRISPR, have progressed rapidly, making personalized
medicine and agricultural improvements more feasible, aiming to address genetic
diseases and food security.\\n\\n8. **Blockchain Applications**: Beyond cryptocurrencies,
blockchain technology is being applied in supply chain management and digital
identity verification, offering transparent and secure methods for transactions
and record-keeping.\\n\\n9. **Mental Health Technology**: The integration of
technology in mental health care is expanding, with virtual reality and AI-driven
apps providing new therapeutic options for patients, drastically improving accessibility
and treatment personalization.\\n\\n10. **Transportation Innovations**: Electric
vehicles (EVs) have seen increased adoption due to advancements in battery technology,
while autonomous vehicles are becoming more prevalent, with pilot programs indicating
potential for widespread urban deployment by 2025.\",\n \"refusal\":
null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n
\ }\n ],\n \"usage\": {\n \"prompt_tokens\": 234,\n \"completion_tokens\":
457,\n \"total_tokens\": 691,\n \"prompt_tokens_details\": {\n \"cached_tokens\":
0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": {\n
\ \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"system_fingerprint\":
\"fp_0705bf87c0\"\n}\n"
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e58a5d1ef736225-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Wed, 20 Nov 2024 13:04:50 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '3814'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149999710'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_0e0bf8c81c9997414688b5188337104b
http_version: HTTP/1.1
status_code: 200
- request:
body: !!binary |
Cs4CCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSpQIKEgoQY3Jld2FpLnRl
bGVtZXRyeRKOAgoQT0LRe4bJ4FgqPQObXTZKYRIIpR3A/gdzzPQqDFRhc2sgQ3JlYXRlZDABOfCJ
CAXzrgkYQcAICgXzrgkYSi4KCGNyZXdfa2V5EiIKIDFmMTI4YmRiN2JhYTRiNjc3MTRmMWRhZWRj
MmYzYWI2SjEKB2NyZXdfaWQSJgokMzUxOGI0YzUtMWEzOS00ZGIxLTgxMDMtNzM5ZTY0OWMwMGQ4
Si4KCHRhc2tfa2V5EiIKIGIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3SjEKB3Rhc2tf
aWQSJgokODAzZDlhZjItN2FiMC00NjM3LWIxYmMtOTE0MmYxYmQwMzRhegIYAYUBAAEAAA==
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '337'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Wed, 20 Nov 2024 13:04:54 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are {topic} Reporting
Analyst\n. You''re a meticulous analyst with a keen eye for detail. You''re
known for your ability to turn complex data into clear and concise reports,
making it easy for others to understand and act on the information you provide.\n\nYour
personal goal is: Create detailed reports based on {topic} data analysis and
research findings\n\nTo give my best complete final answer to the task use the
exact following format:\n\nThought: I now can give a great answer\nFinal Answer:
Your final answer must be the great and the most complete as possible, it must
be outcome described.\n\nI MUST use these formats, my job depends on it!"},
{"role": "user", "content": "\nCurrent Task: Review the context you got and
expand each topic into a full section for a report. Make sure the report is
detailed and contains any and all relevant information.\n\n\nThis is the expect
criteria for your final answer: A fully fledge reports with the mains topics,
each with a full section of information. Formatted as markdown without ''```''\n\nyou
MUST return the actual complete content as the final answer, not a summary.\n\nThis
is the context you''re working with:\n1. **Artificial Intelligence Advancements**:
In 2024, AI has made significant strides in natural language processing and
computer vision, with models achieving near-human-level understanding and interpretation
capabilities. This has led to more sophisticated AI applications across industries.\n\n2.
**Quantum Computing Progress**: Quantum computers are now capable of surpassing
traditional computing power for specific tasks, with breakthroughs in error
correction and qubit coherence. This achievement is paving the way for real-world
applications in cryptography and complex problem-solving.\n\n3. **Sustainable
Energy Technologies**: The shift toward renewable energy sources has accelerated,
with innovations in solar panel efficiency and the rise of hydrogen fuel cells
gaining traction as viable alternatives for energy storage and transportation.\n\n4.
**Augmented Reality Enhancements**: In 2024, augmented reality (AR) technologies
are being integrated into everyday applications, from retail to education, providing
immersive experiences that enhance learning and consumer engagement.\n\n5. **5G
Expansion and 6G Development**: The rollout of 5G continues to expand globally,
while foundational work on 6G is underway, promising enhanced connectivity speeds,
low latency, and the potential for new applications like smart cities and automated
industries.\n\n6. **Data Privacy Regulations**: As data breaches become increasingly
sophisticated, worldwide regulations around data privacy have tightened, with
new laws being implemented to protect consumer information and corporate accountability
in data handling.\n\n7. **Biotechnology Breakthroughs**: Advances in gene editing
technologies, particularly CRISPR, have progressed rapidly, making personalized
medicine and agricultural improvements more feasible, aiming to address genetic
diseases and food security.\n\n8. **Blockchain Applications**: Beyond cryptocurrencies,
blockchain technology is being applied in supply chain management and digital
identity verification, offering transparent and secure methods for transactions
and record-keeping.\n\n9. **Mental Health Technology**: The integration of technology
in mental health care is expanding, with virtual reality and AI-driven apps
providing new therapeutic options for patients, drastically improving accessibility
and treatment personalization.\n\n10. **Transportation Innovations**: Electric
vehicles (EVs) have seen increased adoption due to advancements in battery technology,
while autonomous vehicles are becoming more prevalent, with pilot programs indicating
potential for widespread urban deployment by 2025.\n\nBegin! This is VERY important
to you, use the tools available and give your best Final Answer, your job depends
on it!\n\nThought:"}], "model": "gpt-4o-mini", "stop": ["\nObservation:"], "stream":
false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '4065'
content-type:
- application/json
cookie:
- __cf_bm=CkK4UvBd9ukXvn50uJwGambJcz5zERAJfeXJ9xge6H4-1732107842-1.0.1.1-IOK2yVL3RlD75MgmnKzIEyE38HNknwn6I8BBJ1wjGz4jCTd0YWIBPnvUm9gB8D_zLlUA9G7p_wbrfyc4mO_Bmg;
_cfuvid=MmeN9oHWrBLThkEJdaSFHBfWe95JvA8iFnnt7CC92tk-1732107842102-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-AVefym1A3aTi6N7szB8ei85GCHkyG\",\n \"object\":
\"chat.completion\",\n \"created\": 1732107890,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"I now can give a great answer \\nFinal
Answer: \\n\\n# Comprehensive Report on Key Technology Trends in 2024\\n\\n##
1. Artificial Intelligence Advancements\\nIn 2024, artificial intelligence (AI)
has undergone remarkable advancements, particularly in the fields of natural
language processing (NLP) and computer vision. AI models are now achieving near-human-level
understanding and interpretation capabilities, enabling more nuanced interactions
between humans and machines. This progression has spurred the development of
sophisticated AI applications across various sectors, from healthcare, where
AI can analyze medical images and assist in diagnostic processes, to finance,
where predictive analytics enhances decision-making and risk management. With
AI being employed in customer service chatbots and personal assistants, the
technology's integration into daily operations significantly improves productivity
and user experience.\\n\\n## 2. Quantum Computing Progress\\nThe capabilities
of quantum computers have expanded significantly, showcasing their potential
to exceed traditional computing power for specific tasks. In 2024, key breakthroughs
have been made in areas such as error correction and qubit coherence, addressing
longstanding challenges in the field. These advancements are not only enhancing
the performance of quantum systems but are also paving the way for practical
applications in cryptography, where quantum encryption could revolutionize data
security protocols, and in complex problem-solving scenarios across scientific
research and logistics. As quantum technology matures, it holds the promise
to solve problems that are currently intractable for classical computers.\\n\\n##
3. Sustainable Energy Technologies\\nThe global shift towards sustainable energy
sources has gained remarkable momentum in 2024, driven by innovations in solar
panel efficiency and the adoption of hydrogen fuel cells. Advances in photovoltaic
technology have led to the development of more efficient solar panels capable
of capturing a higher percentage of sunlight, reducing reliance on fossil fuels.
Simultaneously, hydrogen fuel cells are emerging as a viable alternative for
energy storage and transportation, particularly in heavy-duty vehicles and public
transport systems. This transformation towards greener energy solutions is critical
in combating climate change while fostering economic growth through new job
creation in the clean technology sector.\\n\\n## 4. Augmented Reality Enhancements\\nAugmented
reality (AR) technologies are becoming increasingly integrated into everyday
applications as of 2024, providing immersive experiences across various industries,
including retail and education. In retail, AR is enhancing consumer engagement
by allowing customers to visualize products in a real-world context before making
a purchase. In education, AR is facilitating interactive learning experiences,
enabling students to engage with complex subjects through visual simulations
and augmented textbooks. These advancements not only improve user engagement
but also foster greater understanding and retention of information.\\n\\n##
5. 5G Expansion and 6G Development\\nThe global rollout of 5G technology continues
at a rapid pace, significantly enhancing connectivity speeds and reducing latency.
As 2024 progresses, foundational work on the next-generation 6G networks is
also underway, promising even greater improvements in connectivity and the potential
for groundbreaking applications. These advancements are facilitating the emergence
of smart cities, automated industries, and enhanced telecommunications services.
The increased bandwidth provided by 5G and the anticipation surrounding 6G enable
new possibilities in mobile communications, Internet of Things (IoT) implementations,
and real-time data processing.\\n\\n## 6. Data Privacy Regulations\\nAs data
breaches become increasingly sophisticated and pervasive, regulations surrounding
data privacy have intensified globally in 2024. Many countries have enacted
new laws aimed at protecting consumer information and holding businesses accountable
for their data handling practices. This regulatory environment requires organizations
to implement robust data protection measures, maintain transparency, and establish
trust with consumers. The emphasis on data privacy not only safeguards individuals'
personal information but also promotes ethical practices within the tech industry,
thereby fostering greater public confidence in emerging digital services.\\n\\n##
7. Biotechnology Breakthroughs\\nThe biotechnology sector has experienced significant
developments in 2024, particularly regarding gene editing technologies such
as CRISPR. These advances enable researchers to make precise modifications to
genetic material, paving the way for personalized medicine that targets genetic
diseases at the source. Agricultural improvements are also on the horizon as
genetically modified crops become more resilient to climate change and pests,
addressing global food security challenges. With ongoing research and clinical
trials, the potential applications of biotechnology in healthcare and agriculture
present transformative opportunities to improve quality of life and sustainability.\\n\\n##
8. Blockchain Applications\\nBeyond its initial use in cryptocurrencies, blockchain
technology is finding diverse applications in areas such as supply chain management
and digital identity verification. In 2024, businesses leverage blockchain's
inherent transparency and security to streamline operations, enhance traceability,
and foster trust among stakeholders. For example, in supply chain management,
blockchain allows for real-time tracking of products, enabling greater accountability
and efficient inventory management. Similarly, digital identity verification
is becoming more secure through decentralized systems, reducing the risk of
identity theft and fraud, thereby enhancing overall trust in digital transactions.\\n\\n##
9. Mental Health Technology\\nIn recent years, technology's role in mental health
care has expanded dramatically, with innovative solutions such as virtual reality
(VR) therapy and AI-driven mental health applications emerging in 2024. These
technologies offer patients new therapeutic options that enhance accessibility
and treatment personalization. VR environments can simulate therapeutic situations
for exposure therapy while AI algorithms tailor mental health interventions
according to individual needs, improving overall efficacy. This integration
of technology into mental health care has the potential to bridge gaps in traditional
therapy access, providing vital support to those in need.\\n\\n## 10. Transportation
Innovations\\nTransportation has seen significant innovations as of 2024, driven
primarily by advancements in electric vehicles (EVs) and autonomous technology.
Increasing adoption of EVs is correlated with enhanced battery technologies
that extend range and reduce charging time, making them more appealing to consumers.
Simultaneously, pilot programs for autonomous vehicles are indicating promising
results for safe integration into urban environments. These developments present
the opportunity for reduced traffic congestion, lower emissions, and enhanced
mobility solutions, fundamentally reshaping the landscape of transportation
in cities worldwide by 2025. \\n\\nThrough these comprehensive explorations
of emerging technologies, it is clear that 2024 marks a pivotal year for innovation,
shaping future directions in various industries and enhancing societal progress.\",\n
\ \"refusal\": null\n },\n \"logprobs\": null,\n \"finish_reason\":
\"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": 708,\n \"completion_tokens\":
1223,\n \"total_tokens\": 1931,\n \"prompt_tokens_details\": {\n \"cached_tokens\":
0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": {\n
\ \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"system_fingerprint\":
\"fp_0705bf87c0\"\n}\n"
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e58a5ec0f936225-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Wed, 20 Nov 2024 13:05:05 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '15043'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149999013'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_4bd436f5144121694f8df654ed8514ea
http_version: HTTP/1.1
status_code: 200
version: 1

View File

@@ -10,7 +10,8 @@ interactions:
criteria for your final answer: 1 bullet point about dog that''s under 15 words.\nyou
MUST return the actual complete content as the final answer, not a summary.\n\nBegin!
This is VERY important to you, use the tools available and give your best Final
Answer, your job depends on it!\n\nThought:"}], "model": "gpt-4o"}'
Answer, your job depends on it!\n\nThought:"}], "model": "gpt-4o-mini", "stop":
["\nObservation:"], "stream": false}'
headers:
accept:
- application/json
@@ -19,49 +20,50 @@ interactions:
connection:
- keep-alive
content-length:
- '869'
- '919'
content-type:
- application/json
cookie:
- __cf_bm=9.8sBYBkvBR8R1K_bVF7xgU..80XKlEIg3N2OBbTSCU-1727214102-1.0.1.1-.qiTLXbPamYUMSuyNsOEB9jhGu.jOifujOrx9E2JZvStbIZ9RTIiE44xKKNfLPxQkOi6qAT3h6htK8lPDGV_5g;
_cfuvid=lbRdAddVWV6W3f5Dm9SaOPWDUOxqtZBSPr_fTW26nEA-1727213194587-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.47.0
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
- Linux
x-stainless-package-version:
- 1.47.0
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
- 3.11.9
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-AB7auGDrAVE0iXSBBhySZp3xE8gvP\",\n \"object\":
\"chat.completion\",\n \"created\": 1727214164,\n \"model\": \"gpt-4o-2024-05-13\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"I now can give a great answer\\nFinal
Answer: Dogs are unparalleled in loyalty and companionship to humans.\",\n \"refusal\":
null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n
\ }\n ],\n \"usage\": {\n \"prompt_tokens\": 175,\n \"completion_tokens\":
21,\n \"total_tokens\": 196,\n \"completion_tokens_details\": {\n \"reasoning_tokens\":
0\n }\n },\n \"system_fingerprint\": \"fp_e375328146\"\n}\n"
body:
string: !!binary |
H4sIAAAAAAAAA4xSy27bMBC86ysWPEuB7ciV7VuAIkUObQ+59QFhTa0kttQuS9Jx08D/XkhyLAVJ
gV4EaGdnMLPDpwRAmUrtQOkWo+6czW7u41q2t3+cvCvuPvxafSG+58XHTzXlxWeV9gzZ/yAdn1lX
WjpnKRrhEdaeMFKvuiyul3m+uV7lA9BJRbanNS5muWSdYZOtFqs8WxTZcnNmt2I0BbWDrwkAwNPw
7X1yRb/VDhbp86SjELAhtbssASgvtp8oDMGEiBxVOoFaOBIP1u+A5QgaGRrzQIDQ9LYBORzJA3zj
W8No4Wb438F7aQKgJ7DyiBb6zMhGOKRA3CJrww10xBEttIQ2toBcgTyQR2vhSNZmezLcXM39eKoP
Afub8MHa8/x0CWilcV724Yxf5rVhE9rSEwbhPkyI4tSAnhKA78MhDy9uo5yXzsUyyk/iMHSzHvXU
1N+Ejo0BqCgR7Yy13aZv6JUVRTQ2zKpQGnVL1USdesNDZWQGJLPUr928pT0mN9z8j/wEaE0uUlU6
T5XRLxNPa5765/2vtcuVB8MqPIZIXVkbbsg7b8bHVbuyXm9xs8xXRa2SU/IXAAD//wMAq2ZCBWoD
AAA=
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8c85f22ddda01cf3-GRU
- 8e19bf36db158761-GRU
Connection:
- keep-alive
Content-Encoding:
@@ -69,19 +71,27 @@ interactions:
Content-Type:
- application/json
Date:
- Tue, 24 Sep 2024 21:42:44 GMT
- Tue, 12 Nov 2024 21:52:04 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=MkvcnvacGpTyn.y0OkFRoFXuAwg4oxjMhViZJTt9mw0-1731448324-1.0.1.1-oekkH_B0xOoPnIFw15LpqFCkZ2cu7VBTJVLDGylan4I67NjX.tlPvOiX9kvtP5Acewi28IE2IwlwtrZWzCH3vw;
path=/; expires=Tue, 12-Nov-24 22:22:04 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=4.17346mfw5npZfYNbCx3Vj1VAVPy.tH0Jm2gkTteJ8-1731448324998-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
- user-tqfegqsiobpvvjmn0giaipdq
openai-processing-ms:
- '349'
- '601'
openai-version:
- '2020-10-01'
strict-transport-security:
@@ -89,19 +99,20 @@ interactions:
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
- '200000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29999792'
- '199793'
x-ratelimit-reset-requests:
- 6ms
- 8.64s
x-ratelimit-reset-tokens:
- 0s
- 62ms
x-request-id:
- req_4c8cd76fdfba7b65e5ce85397b33c22b
http_version: HTTP/1.1
status_code: 200
- req_77fb166b4e272bfd45c37c08d2b93b0c
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are cat Researcher. You
have a lot of experience with cat.\nYour personal goal is: Express hot takes
@@ -113,7 +124,8 @@ interactions:
criteria for your final answer: 1 bullet point about cat that''s under 15 words.\nyou
MUST return the actual complete content as the final answer, not a summary.\n\nBegin!
This is VERY important to you, use the tools available and give your best Final
Answer, your job depends on it!\n\nThought:"}], "model": "gpt-4o"}'
Answer, your job depends on it!\n\nThought:"}], "model": "gpt-4o-mini", "stop":
["\nObservation:"], "stream": false}'
headers:
accept:
- application/json
@@ -122,49 +134,53 @@ interactions:
connection:
- keep-alive
content-length:
- '869'
- '919'
content-type:
- application/json
cookie:
- __cf_bm=9.8sBYBkvBR8R1K_bVF7xgU..80XKlEIg3N2OBbTSCU-1727214102-1.0.1.1-.qiTLXbPamYUMSuyNsOEB9jhGu.jOifujOrx9E2JZvStbIZ9RTIiE44xKKNfLPxQkOi6qAT3h6htK8lPDGV_5g;
_cfuvid=lbRdAddVWV6W3f5Dm9SaOPWDUOxqtZBSPr_fTW26nEA-1727213194587-0.0.1.1-604800000
- __cf_bm=MkvcnvacGpTyn.y0OkFRoFXuAwg4oxjMhViZJTt9mw0-1731448324-1.0.1.1-oekkH_B0xOoPnIFw15LpqFCkZ2cu7VBTJVLDGylan4I67NjX.tlPvOiX9kvtP5Acewi28IE2IwlwtrZWzCH3vw;
_cfuvid=4.17346mfw5npZfYNbCx3Vj1VAVPy.tH0Jm2gkTteJ8-1731448324998-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.47.0
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
- Linux
x-stainless-package-version:
- 1.47.0
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
- 3.11.9
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-AB7auNbAqjT3rgBX92rhxBLuhaLBj\",\n \"object\":
\"chat.completion\",\n \"created\": 1727214164,\n \"model\": \"gpt-4o-2024-05-13\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"Thought: I now can give a great answer\\nFinal
Answer: Cats are highly independent, agile, and intuitive creatures beloved
by millions worldwide.\",\n \"refusal\": null\n },\n \"logprobs\":
null,\n \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\":
175,\n \"completion_tokens\": 28,\n \"total_tokens\": 203,\n \"completion_tokens_details\":
{\n \"reasoning_tokens\": 0\n }\n },\n \"system_fingerprint\": \"fp_e375328146\"\n}\n"
body:
string: !!binary |
H4sIAAAAAAAAA4xSy27bMBC86ysWPFuB7MhN6ltQIGmBnlL00BcEmlxJ21JLhlzFLQL/eyH5IRlt
gV4EaGZnMLPLlwxAkVUbUKbVYrrg8rsPsg4P+Orxs9XvPz0U8eP966dS6sdo3wa1GBR++x2NnFRX
xnfBoZDnA20iasHBdXlzvSzL2+vVeiQ6b9ENsiZIXvq8I6Z8VazKvLjJl7dHdevJYFIb+JIBALyM
3yEnW/ypNlAsTkiHKekG1eY8BKCidwOidEqURLOoxUQaz4I8Rn8H7HdgNENDzwgamiE2aE47jABf
+Z5YO7gb/zfwRksCHRGGGAHZIg/D1GmXFiBtpGfiBjyDtEgR/I5BMHYJNFvomZ56hIAxedaOhDBd
zYNFrPukh+Vw79wR35+bOt+E6LfpyJ/xmphSW0XUyfPQKokPamT3GcC3caP9xZJUiL4LUon/gZzG
I60Pfmo65MSuTqR40W6GF8c7XPpVFkWTS7ObKKNNi3aSTgfUvSU/I7JZ6z/T/M370Jy4+R/7iTAG
g6CtQkRL5rLxNBZxeOf/GjtveQys0q8k2FU1cYMxRDq8sjpUxVYXdrkq66XK9tlvAAAA//8DAIjK
KzJzAwAA
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8c85f2321c1c1cf3-GRU
- 8e19bf3fae118761-GRU
Connection:
- keep-alive
Content-Encoding:
@@ -172,7 +188,7 @@ interactions:
Content-Type:
- application/json
Date:
- Tue, 24 Sep 2024 21:42:45 GMT
- Tue, 12 Nov 2024 21:52:05 GMT
Server:
- cloudflare
Transfer-Encoding:
@@ -181,10 +197,12 @@ interactions:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
- user-tqfegqsiobpvvjmn0giaipdq
openai-processing-ms:
- '430'
- '464'
openai-version:
- '2020-10-01'
strict-transport-security:
@@ -192,19 +210,20 @@ interactions:
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
- '200000'
x-ratelimit-remaining-requests:
- '9999'
- '9998'
x-ratelimit-remaining-tokens:
- '29999792'
- '199792'
x-ratelimit-reset-requests:
- 6ms
- 16.369s
x-ratelimit-reset-tokens:
- 0s
- 62ms
x-request-id:
- req_ace859b7d9e83d9fa7753ce23bb03716
http_version: HTTP/1.1
status_code: 200
- req_91706b23d0ef23458ba63ec18304cd28
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are apple Researcher.
You have a lot of experience with apple.\nYour personal goal is: Express hot
@@ -217,7 +236,7 @@ interactions:
under 15 words.\nyou MUST return the actual complete content as the final answer,
not a summary.\n\nBegin! This is VERY important to you, use the tools available
and give your best Final Answer, your job depends on it!\n\nThought:"}], "model":
"gpt-4o"}'
"gpt-4o-mini", "stop": ["\nObservation:"], "stream": false}'
headers:
accept:
- application/json
@@ -226,49 +245,53 @@ interactions:
connection:
- keep-alive
content-length:
- '879'
- '929'
content-type:
- application/json
cookie:
- __cf_bm=9.8sBYBkvBR8R1K_bVF7xgU..80XKlEIg3N2OBbTSCU-1727214102-1.0.1.1-.qiTLXbPamYUMSuyNsOEB9jhGu.jOifujOrx9E2JZvStbIZ9RTIiE44xKKNfLPxQkOi6qAT3h6htK8lPDGV_5g;
_cfuvid=lbRdAddVWV6W3f5Dm9SaOPWDUOxqtZBSPr_fTW26nEA-1727213194587-0.0.1.1-604800000
- __cf_bm=MkvcnvacGpTyn.y0OkFRoFXuAwg4oxjMhViZJTt9mw0-1731448324-1.0.1.1-oekkH_B0xOoPnIFw15LpqFCkZ2cu7VBTJVLDGylan4I67NjX.tlPvOiX9kvtP5Acewi28IE2IwlwtrZWzCH3vw;
_cfuvid=4.17346mfw5npZfYNbCx3Vj1VAVPy.tH0Jm2gkTteJ8-1731448324998-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.47.0
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
- Linux
x-stainless-package-version:
- 1.47.0
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
- 3.11.9
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-AB7avZ0yqY18ukQS7SnLkZydsx72b\",\n \"object\":
\"chat.completion\",\n \"created\": 1727214165,\n \"model\": \"gpt-4o-2024-05-13\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"I now can give a great answer.\\n\\nFinal
Answer: Apples are incredibly versatile, nutritious, and a staple in diets globally.\",\n
\ \"refusal\": null\n },\n \"logprobs\": null,\n \"finish_reason\":
\"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": 175,\n \"completion_tokens\":
25,\n \"total_tokens\": 200,\n \"completion_tokens_details\": {\n \"reasoning_tokens\":
0\n }\n },\n \"system_fingerprint\": \"fp_a5d11b2ef2\"\n}\n"
body:
string: !!binary |
H4sIAAAAAAAAA4xSPW/bMBDd9SsOXLpIgeTITarNS4t26JJubSHQ5IliSh1ZHv0RBP7vhSTHctAU
6CJQ7909vHd3zxmAsFo0IFQvkxqCKzYPaf1b2/hhW+8PR9N9Kh9W5Zdhjebr4zeRjx1++4gqvXTd
KD8Eh8l6mmkVUSYcVau726qu729X7ydi8Brd2GZCKmpfDJZssSpXdVHeFdX9ubv3ViGLBr5nAADP
03f0SRqPooEyf0EGZJYGRXMpAhDRuxERktlykpREvpDKU0KarH8G8gdQksDYPYIEM9oGSXzACPCD
PlqSDjbTfwObEBy+Y0Dl+YkTDmApoYkyIUMvoz7IiDmw79L8kqSBMe7HMMAoB4fM7ikHpF6SsmRg
xxgBjwGjRVJ4c+00YrdjOU6Lds6d8dMluvMmRL/lM3/BO0uW+zaiZE9jTE4+iIk9ZQA/pxHvXk1N
hOiHkNrkfyHxtLX1rCeWzS7svEsAkXyS7govq/wNvVZjktbx1ZKEkqpHvbQuG5U7bf0VkV2l/tvN
W9pzckvmf+QXQikMCXUbImqrXideyiKOh/+vssuUJ8NiPpO2s2Qwhmjns+tCW25lqatV3VUiO2V/
AAAA//8DAPtpFJCEAwAA
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8c85f2369a761cf3-GRU
- 8e19bf447ba48761-GRU
Connection:
- keep-alive
Content-Encoding:
@@ -276,7 +299,7 @@ interactions:
Content-Type:
- application/json
Date:
- Tue, 24 Sep 2024 21:42:46 GMT
- Tue, 12 Nov 2024 21:52:06 GMT
Server:
- cloudflare
Transfer-Encoding:
@@ -285,10 +308,12 @@ interactions:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
- user-tqfegqsiobpvvjmn0giaipdq
openai-processing-ms:
- '389'
- '655'
openai-version:
- '2020-10-01'
strict-transport-security:
@@ -296,17 +321,18 @@ interactions:
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
- '200000'
x-ratelimit-remaining-requests:
- '9999'
- '9997'
x-ratelimit-remaining-tokens:
- '29999791'
- '199791'
x-ratelimit-reset-requests:
- 6ms
- 24.239s
x-ratelimit-reset-tokens:
- 0s
- 62ms
x-request-id:
- req_0167388f0a7a7f1a1026409834ceb914
http_version: HTTP/1.1
status_code: 200
- req_a228208b0e965ecee334a6947d6c9e7c
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,232 @@
interactions:
- request:
body: !!binary |
Cv1YCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkS1FgKEgoQY3Jld2FpLnRl
bGVtZXRyeRLADQoQ5TzgW9QzcBbzMl1hJozLcxIIl3adf7U81wwqDENyZXcgQ3JlYXRlZDABOaAJ
txhffgkYQfiVuRhffgkYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODAuMEoaCg5weXRob25fdmVy
c2lvbhIICgYzLjEyLjVKLgoIY3Jld19rZXkSIgogM2Y4ZDVjM2FiODgyZDY4NjlkOTNjYjgxZjBl
MmVkNGFKMQoHY3Jld19pZBImCiRjYjRiY2Q1Zi0xYWJkLTQyYmYtOGQ1OC02ZmEzMDU3ZDFjOTZK
HAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdf
bnVtYmVyX29mX3Rhc2tzEgIYA0obChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgCSpIFCgtjcmV3
X2FnZW50cxKCBQr/BFt7ImtleSI6ICI4YmQyMTM5YjU5NzUxODE1MDZlNDFmZDljNDU2M2Q3NSIs
ICJpZCI6ICI1ZThjNTM1MS1jNWVlLTRhZGUtODY5MC1kM2RhOWI1NzI5YzciLCAicm9sZSI6ICJS
ZXNlYXJjaGVyIiwgInZlcmJvc2U/IjogZmFsc2UsICJtYXhfaXRlciI6IDIwLCAibWF4X3JwbSI6
IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAibGxtIjogImdwdC00by1taW5pIiwg
ImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6IGZh
bHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25hbWVzIjogW119LCB7ImtleSI6ICI5
YTUwMTVlZjQ4OTVkYzYyNzhkNTQ4MThiYTQ0NmFmNyIsICJpZCI6ICJhMTcwODczOC0yYWE2LTRk
ZmYtODFlNy00OGFkMDNjNWFjY2QiLCAicm9sZSI6ICJTZW5pb3IgV3JpdGVyIiwgInZlcmJvc2U/
IjogZmFsc2UsICJtYXhfaXRlciI6IDIwLCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxs
aW5nX2xsbSI6ICIiLCAibGxtIjogImdwdC00by1taW5pIiwgImRlbGVnYXRpb25fZW5hYmxlZD8i
OiBmYWxzZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0
IjogMiwgInRvb2xzX25hbWVzIjogW119XUrbBQoKY3Jld190YXNrcxLMBQrJBVt7ImtleSI6ICI2
Nzg0OWZmNzE3ZGJhZGFiYTFiOTVkNWYyZGZjZWVhMSIsICJpZCI6ICIyNzkxNTMxMy0wNDBhLTRk
ZWItOTVkMy1mNWVmMzg2Mjk3NTEiLCAiYXN5bmNfZXhlY3V0aW9uPyI6IHRydWUsICJodW1hbl9p
bnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAiUmVzZWFyY2hlciIsICJhZ2VudF9rZXkiOiAi
OGJkMjEzOWI1OTc1MTgxNTA2ZTQxZmQ5YzQ1NjNkNzUiLCAidG9vbHNfbmFtZXMiOiBbXX0sIHsi
a2V5IjogImZjNTZkZWEzOGM5OTc0YjZmNTVhMmUyOGMxNDk5ODg2IiwgImlkIjogIjc3NzQ3MmVl
LWYzNzAtNDQyZS05NWMyLWVlMGVkYzZiMTgyZiIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2Us
ICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAiUmVzZWFyY2hlciIsICJhZ2Vu
dF9rZXkiOiAiOGJkMjEzOWI1OTc1MTgxNTA2ZTQxZmQ5YzQ1NjNkNzUiLCAidG9vbHNfbmFtZXMi
OiBbXX0sIHsia2V5IjogIjk0YTgyNmMxOTMwNTU5Njg2YmFmYjQwOWVlODM4NzZmIiwgImlkIjog
ImM4OWEzODA2LTg5MDItNGQ2My1iYzA0LTdjMzRhZTJmM2UxNyIsICJhc3luY19leGVjdXRpb24/
IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAiU2VuaW9yIFdy
aXRlciIsICJhZ2VudF9rZXkiOiAiOWE1MDE1ZWY0ODk1ZGM2Mjc4ZDU0ODE4YmE0NDZhZjciLCAi
dG9vbHNfbmFtZXMiOiBbXX1degIYAYUBAAEAABKOAgoQSqupTllrk2mxgu2AqenZUhIIspWxig2+
1M0qDFRhc2sgQ3JlYXRlZDABOcCj1BhffgkYQfhq1RhffgkYSi4KCGNyZXdfa2V5EiIKIDNmOGQ1
YzNhYjg4MmQ2ODY5ZDkzY2I4MWYwZTJlZDRhSjEKB2NyZXdfaWQSJgokY2I0YmNkNWYtMWFiZC00
MmJmLThkNTgtNmZhMzA1N2QxYzk2Si4KCHRhc2tfa2V5EiIKIDY3ODQ5ZmY3MTdkYmFkYWJhMWI5
NWQ1ZjJkZmNlZWExSjEKB3Rhc2tfaWQSJgokMjc5MTUzMTMtMDQwYS00ZGViLTk1ZDMtZjVlZjM4
NjI5NzUxegIYAYUBAAEAABKOAgoQ3dJesXQA5ISCqVgmwvBMgRIIdrWBiVQuihcqDFRhc2sgQ3Jl
YXRlZDABOdjAch1ffgkYQVh8cx1ffgkYSi4KCGNyZXdfa2V5EiIKIDNmOGQ1YzNhYjg4MmQ2ODY5
ZDkzY2I4MWYwZTJlZDRhSjEKB2NyZXdfaWQSJgokY2I0YmNkNWYtMWFiZC00MmJmLThkNTgtNmZh
MzA1N2QxYzk2Si4KCHRhc2tfa2V5EiIKIGZjNTZkZWEzOGM5OTc0YjZmNTVhMmUyOGMxNDk5ODg2
SjEKB3Rhc2tfaWQSJgokNzc3NDcyZWUtZjM3MC00NDJlLTk1YzItZWUwZWRjNmIxODJmegIYAYUB
AAEAABKOAgoQCBmV+4VbArZNiL5MaefbahII1fRxaC46KKgqDFRhc2sgQ3JlYXRlZDABOaDs4SNf
fgkYQai74iNffgkYSi4KCGNyZXdfa2V5EiIKIDNmOGQ1YzNhYjg4MmQ2ODY5ZDkzY2I4MWYwZTJl
ZDRhSjEKB2NyZXdfaWQSJgokY2I0YmNkNWYtMWFiZC00MmJmLThkNTgtNmZhMzA1N2QxYzk2Si4K
CHRhc2tfa2V5EiIKIDk0YTgyNmMxOTMwNTU5Njg2YmFmYjQwOWVlODM4NzZmSjEKB3Rhc2tfaWQS
JgokYzg5YTM4MDYtODkwMi00ZDYzLWJjMDQtN2MzNGFlMmYzZTE3egIYAYUBAAEAABKiBwoQhITI
U8q3JLgneRv1MZQY8RIIF2CpEmiZsP4qDENyZXcgQ3JlYXRlZDABOZDBCytffgkYQTDFDStffgkY
ShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODAuMEoaCg5weXRob25fdmVyc2lvbhIICgYzLjEyLjVK
LgoIY3Jld19rZXkSIgogYTljYzVkNDMzOTViMjFiMTgxYzgwYmQ0MzUxY2NlYzhKMQoHY3Jld19p
ZBImCiQ2MTMwMWVmYS0yOGQ4LTQyNTItOWVjNi1iM2JmZDcyMWM0MzVKHAoMY3Jld19wcm9jZXNz
EgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdfbnVtYmVyX29mX3Rhc2tz
EgIYAUobChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgBStECCgtjcmV3X2FnZW50cxLBAgq+Alt7
ImtleSI6ICI4YmQyMTM5YjU5NzUxODE1MDZlNDFmZDljNDU2M2Q3NSIsICJpZCI6ICI3NWRjOTUw
OS02MjQ4LTQ0YWQtYTExZC1iZjdlZWVhOWI0NTQiLCAicm9sZSI6ICJSZXNlYXJjaGVyIiwgInZl
cmJvc2U/IjogZmFsc2UsICJtYXhfaXRlciI6IDIwLCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlv
bl9jYWxsaW5nX2xsbSI6ICIiLCAibGxtIjogImdwdC00by1taW5pIiwgImRlbGVnYXRpb25fZW5h
YmxlZD8iOiBmYWxzZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5
X2xpbWl0IjogMiwgInRvb2xzX25hbWVzIjogW119XUr+AQoKY3Jld190YXNrcxLvAQrsAVt7Imtl
eSI6ICJlOWU2YjcyYWFjMzI2NDU5ZGQ3MDY4ZjBiMTcxN2MxYyIsICJpZCI6ICIxOTBlMGQ1Zi0y
NDg1LTQ3N2ItYWIxNC1kMTlmNDE5YTFlYjQiLCAiYXN5bmNfZXhlY3V0aW9uPyI6IHRydWUsICJo
dW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAiUmVzZWFyY2hlciIsICJhZ2VudF9r
ZXkiOiAiOGJkMjEzOWI1OTc1MTgxNTA2ZTQxZmQ5YzQ1NjNkNzUiLCAidG9vbHNfbmFtZXMiOiBb
XX1degIYAYUBAAEAABKOAgoQxgDNe1lQGKnixKPk3O1TDBIISyqKkjcA7OYqDFRhc2sgQ3JlYXRl
ZDABOfCYJCtffgkYQZAlJStffgkYSi4KCGNyZXdfa2V5EiIKIGE5Y2M1ZDQzMzk1YjIxYjE4MWM4
MGJkNDM1MWNjZWM4SjEKB2NyZXdfaWQSJgokNjEzMDFlZmEtMjhkOC00MjUyLTllYzYtYjNiZmQ3
MjFjNDM1Si4KCHRhc2tfa2V5EiIKIGU5ZTZiNzJhYWMzMjY0NTlkZDcwNjhmMGIxNzE3YzFjSjEK
B3Rhc2tfaWQSJgokMTkwZTBkNWYtMjQ4NS00NzdiLWFiMTQtZDE5ZjQxOWExZWI0egIYAYUBAAEA
ABK/DQoQwwR54Z8nOGgj2VSb63WRwhIIonLT+7Mwj00qDENyZXcgQ3JlYXRlZDABObDfvzhffgkY
QfBvwjhffgkYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODAuMEoaCg5weXRob25fdmVyc2lvbhII
CgYzLjEyLjVKLgoIY3Jld19rZXkSIgogNjZhOTYwZGM2OWZmZjU3OGIyNmM2MWQ0ZjdjNWE5ZmVK
MQoHY3Jld19pZBImCiQxNThhMTkzOS01OWUzLTRlODgtYTRkYi04M2IzN2U5MjgxZWVKHAoMY3Jl
d19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdfbnVtYmVy
X29mX3Rhc2tzEgIYA0obChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgCSpIFCgtjcmV3X2FnZW50
cxKCBQr/BFt7ImtleSI6ICI4YmQyMTM5YjU5NzUxODE1MDZlNDFmZDljNDU2M2Q3NSIsICJpZCI6
ICI1ZThjNTM1MS1jNWVlLTRhZGUtODY5MC1kM2RhOWI1NzI5YzciLCAicm9sZSI6ICJSZXNlYXJj
aGVyIiwgInZlcmJvc2U/IjogZmFsc2UsICJtYXhfaXRlciI6IDIwLCAibWF4X3JwbSI6IG51bGws
ICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAibGxtIjogImdwdC00by1taW5pIiwgImRlbGVn
YXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAi
bWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25hbWVzIjogW119LCB7ImtleSI6ICI5YTUwMTVl
ZjQ4OTVkYzYyNzhkNTQ4MThiYTQ0NmFmNyIsICJpZCI6ICJhMTcwODczOC0yYWE2LTRkZmYtODFl
Ny00OGFkMDNjNWFjY2QiLCAicm9sZSI6ICJTZW5pb3IgV3JpdGVyIiwgInZlcmJvc2U/IjogZmFs
c2UsICJtYXhfaXRlciI6IDIwLCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xs
bSI6ICIiLCAibGxtIjogImdwdC00by1taW5pIiwgImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxz
ZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwg
InRvb2xzX25hbWVzIjogW119XUraBQoKY3Jld190YXNrcxLLBQrIBVt7ImtleSI6ICI5NDRhZWYw
YmFjODQwZjFjMjdiZDgzYTkzN2JjMzYxYiIsICJpZCI6ICIzN2FkNzI5MC04Yjg5LTRjNWEtYmNl
Zi03YzY0ZWJhMWM5NjciLCAiYXN5bmNfZXhlY3V0aW9uPyI6IHRydWUsICJodW1hbl9pbnB1dD8i
OiBmYWxzZSwgImFnZW50X3JvbGUiOiAiUmVzZWFyY2hlciIsICJhZ2VudF9rZXkiOiAiOGJkMjEz
OWI1OTc1MTgxNTA2ZTQxZmQ5YzQ1NjNkNzUiLCAidG9vbHNfbmFtZXMiOiBbXX0sIHsia2V5Ijog
ImZjNTZkZWEzOGM5OTc0YjZmNTVhMmUyOGMxNDk5ODg2IiwgImlkIjogIjZhMmViMGY2LTgwZTIt
NDkxOC05Zjk3LWVhNDY3OTNkMjI2YyIsICJhc3luY19leGVjdXRpb24/IjogdHJ1ZSwgImh1bWFu
X2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJSZXNlYXJjaGVyIiwgImFnZW50X2tleSI6
ICI4YmQyMTM5YjU5NzUxODE1MDZlNDFmZDljNDU2M2Q3NSIsICJ0b29sc19uYW1lcyI6IFtdfSwg
eyJrZXkiOiAiOTRhODI2YzE5MzA1NTk2ODZiYWZiNDA5ZWU4Mzg3NmYiLCAiaWQiOiAiZGQ2Yzkz
NzAtOGYwNC00ZDFmLThjODMtMmFiM2IyYzIwYWI3IiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxz
ZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJTZW5pb3IgV3JpdGVyIiwg
ImFnZW50X2tleSI6ICI5YTUwMTVlZjQ4OTVkYzYyNzhkNTQ4MThiYTQ0NmFmNyIsICJ0b29sc19u
YW1lcyI6IFtdfV16AhgBhQEAAQAAErMHChBV+1WNQzpVlY6l4C/mUgHzEgi3vWQXjOQJ5CoMQ3Jl
dyBDcmVhdGVkMAE5sH1kPF9+CRhBaH1mPF9+CRhKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC44MC4w
ShoKDnB5dGhvbl92ZXJzaW9uEggKBjMuMTIuNUouCghjcmV3X2tleRIiCiBlZTY3NDVkN2M4YWU4
MmUwMGRmOTRkZTBmN2Y4NzExOEoxCgdjcmV3X2lkEiYKJDAwOThmODNmLTdkNTAtNGI2Mi1hYmIy
LTJlNTc0N2ZlMWE4OUocCgxjcmV3X3Byb2Nlc3MSDAoKc2VxdWVudGlhbEoRCgtjcmV3X21lbW9y
eRICEABKGgoUY3Jld19udW1iZXJfb2ZfdGFza3MSAhgBShsKFWNyZXdfbnVtYmVyX29mX2FnZW50
cxICGAFK2QIKC2NyZXdfYWdlbnRzEskCCsYCW3sia2V5IjogImYzMzg2ZjZkOGRhNzVhYTQxNmE2
ZTMxMDA1M2Y3Njk4IiwgImlkIjogIjEzODI4ZDViLWIyOWMtNDllMy05NWVhLTkyOGQ2ZmZhY2I0
NSIsICJyb2xlIjogInt0b3BpY30gUmVzZWFyY2hlciIsICJ2ZXJib3NlPyI6IGZhbHNlLCAibWF4
X2l0ZXIiOiAyMCwgIm1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwg
ImxsbSI6ICJncHQtNG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxv
d19jb2RlX2V4ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19u
YW1lcyI6IFtdfV1KhwIKCmNyZXdfdGFza3MS+AEK9QFbeyJrZXkiOiAiMDZhNzMyMjBmNDE0OGE0
YmJkNWJhY2IwZDBiNDRmY2UiLCAiaWQiOiAiNWM4MjM1ZmYtNWVjNy00NzFhLWI4NWEtNWFkZjk3
YzJkYzI3IiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNl
LCAiYWdlbnRfcm9sZSI6ICJ7dG9waWN9IFJlc2VhcmNoZXIiLCAiYWdlbnRfa2V5IjogImYzMzg2
ZjZkOGRhNzVhYTQxNmE2ZTMxMDA1M2Y3Njk4IiwgInRvb2xzX25hbWVzIjogW119XXoCGAGFAQAB
AAASjgIKEHOZ/a+LQwTLSkMO0sPwg9gSCL1SwQw1+0iKKgxUYXNrIENyZWF0ZWQwATl4kX48X34J
GEFIFn88X34JGEouCghjcmV3X2tleRIiCiBlZTY3NDVkN2M4YWU4MmUwMGRmOTRkZTBmN2Y4NzEx
OEoxCgdjcmV3X2lkEiYKJDAwOThmODNmLTdkNTAtNGI2Mi1hYmIyLTJlNTc0N2ZlMWE4OUouCgh0
YXNrX2tleRIiCiAwNmE3MzIyMGY0MTQ4YTRiYmQ1YmFjYjBkMGI0NGZjZUoxCgd0YXNrX2lkEiYK
JDVjODIzNWZmLTVlYzctNDcxYS1iODVhLTVhZGY5N2MyZGMyN3oCGAGFAQABAAASswcKEHZQCRd7
z4ZBCh4+06qs1r4SCNzrNsw+dn2zKgxDcmV3IENyZWF0ZWQwATlgWdtDX34JGEGIcN1DX34JGEoa
Cg5jcmV3YWlfdmVyc2lvbhIICgYwLjgwLjBKGgoOcHl0aG9uX3ZlcnNpb24SCAoGMy4xMi41Si4K
CGNyZXdfa2V5EiIKIGVlNjc0NWQ3YzhhZTgyZTAwZGY5NGRlMGY3Zjg3MTE4SjEKB2NyZXdfaWQS
JgokZTgzMTdjNzEtNmZiZS00MjI5LWE3MzctYTkxM2I0ZmU0ZTU0ShwKDGNyZXdfcHJvY2VzcxIM
CgpzZXF1ZW50aWFsShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251bWJlcl9vZl90YXNrcxIC
GAFKGwoVY3Jld19udW1iZXJfb2ZfYWdlbnRzEgIYAUrZAgoLY3Jld19hZ2VudHMSyQIKxgJbeyJr
ZXkiOiAiZjMzODZmNmQ4ZGE3NWFhNDE2YTZlMzEwMDUzZjc2OTgiLCAiaWQiOiAiNjAwMzU5OTYt
ZWU1ZS00YmZhLThmODctMGM1ZTY0OTBlMmE4IiwgInJvbGUiOiAie3RvcGljfSBSZXNlYXJjaGVy
IiwgInZlcmJvc2U/IjogZmFsc2UsICJtYXhfaXRlciI6IDIwLCAibWF4X3JwbSI6IG51bGwsICJm
dW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAibGxtIjogImdwdC00by1taW5pIiwgImRlbGVnYXRp
b25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4
X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25hbWVzIjogW119XUqHAgoKY3Jld190YXNrcxL4AQr1
AVt7ImtleSI6ICIwNmE3MzIyMGY0MTQ4YTRiYmQ1YmFjYjBkMGI0NGZjZSIsICJpZCI6ICI4MDc3
MDhjNS0yN2RkLTQ4ZDEtYTU0ZC1lZTRkNTZmMzBiZTQiLCAiYXN5bmNfZXhlY3V0aW9uPyI6IGZh
bHNlLCAiaHVtYW5faW5wdXQ/IjogZmFsc2UsICJhZ2VudF9yb2xlIjogInt0b3BpY30gUmVzZWFy
Y2hlciIsICJhZ2VudF9rZXkiOiAiZjMzODZmNmQ4ZGE3NWFhNDE2YTZlMzEwMDUzZjc2OTgiLCAi
dG9vbHNfbmFtZXMiOiBbXX1degIYAYUBAAEAABKOAgoQtqHg5uy2kZsnJlJTYgmZoxIIlgUHkQ7m
LugqDFRhc2sgQ3JlYXRlZDABOTi470NffgkYQQg98ENffgkYSi4KCGNyZXdfa2V5EiIKIGVlNjc0
NWQ3YzhhZTgyZTAwZGY5NGRlMGY3Zjg3MTE4SjEKB2NyZXdfaWQSJgokZTgzMTdjNzEtNmZiZS00
MjI5LWE3MzctYTkxM2I0ZmU0ZTU0Si4KCHRhc2tfa2V5EiIKIDA2YTczMjIwZjQxNDhhNGJiZDVi
YWNiMGQwYjQ0ZmNlSjEKB3Rhc2tfaWQSJgokODA3NzA4YzUtMjdkZC00OGQxLWE1NGQtZWU0ZDU2
ZjMwYmU0egIYAYUBAAEAABKzBwoQpfKhpM9cCoiT5Mun1aoNQhII4HhX0QHHc/0qDENyZXcgQ3Jl
YXRlZDABORiH20lffgkYQcix3UlffgkYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODAuMEoaCg5w
eXRob25fdmVyc2lvbhIICgYzLjEyLjVKLgoIY3Jld19rZXkSIgogZWU2NzQ1ZDdjOGFlODJlMDBk
Zjk0ZGUwZjdmODcxMThKMQoHY3Jld19pZBImCiRmZDk2MmQwMi0wNGY0LTQ3NDUtODc5YS02NTFm
MzFmMmZhOTZKHAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAA
ShoKFGNyZXdfbnVtYmVyX29mX3Rhc2tzEgIYAUobChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgB
StkCCgtjcmV3X2FnZW50cxLJAgrGAlt7ImtleSI6ICJmMzM4NmY2ZDhkYTc1YWE0MTZhNmUzMTAw
NTNmNzY5OCIsICJpZCI6ICIzNmZhMTEyZS02ZDVlLTRhMzgtODk0Yy01M2M5YjAzNTI5ODUiLCAi
cm9sZSI6ICJ7dG9waWN9IFJlc2VhcmNoZXIiLCAidmVyYm9zZT8iOiBmYWxzZSwgIm1heF9pdGVy
IjogMjAsICJtYXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogIiIsICJsbG0i
OiAiZ3B0LTRvLW1pbmkiLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29k
ZV9leGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMi
OiBbXX1dSocCCgpjcmV3X3Rhc2tzEvgBCvUBW3sia2V5IjogIjA2YTczMjIwZjQxNDhhNGJiZDVi
YWNiMGQwYjQ0ZmNlIiwgImlkIjogIjY3NTE3ZjY1LThhYzMtNDIyZi1hMmJhLTM4NDcyZDRkYmZl
NSIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFn
ZW50X3JvbGUiOiAie3RvcGljfSBSZXNlYXJjaGVyIiwgImFnZW50X2tleSI6ICJmMzM4NmY2ZDhk
YTc1YWE0MTZhNmUzMTAwNTNmNzY5OCIsICJ0b29sc19uYW1lcyI6IFtdfV16AhgBhQEAAQAAEo4C
ChAzGUzQMDZOgJ090im3887lEgik7+/nVnqntioMVGFzayBDcmVhdGVkMAE5UO7rSV9+CRhBWEDs
SV9+CRhKLgoIY3Jld19rZXkSIgogZWU2NzQ1ZDdjOGFlODJlMDBkZjk0ZGUwZjdmODcxMThKMQoH
Y3Jld19pZBImCiRmZDk2MmQwMi0wNGY0LTQ3NDUtODc5YS02NTFmMzFmMmZhOTZKLgoIdGFza19r
ZXkSIgogMDZhNzMyMjBmNDE0OGE0YmJkNWJhY2IwZDBiNDRmY2VKMQoHdGFza19pZBImCiQ2NzUx
N2Y2NS04YWMzLTQyMmYtYTJiYS0zODQ3MmQ0ZGJmZTV6AhgBhQEAAQAAErMHChCB1TPvVbWX62DF
102NfOHLEghdZ/LjI40W8SoMQ3JldyBDcmVhdGVkMAE5sJDUT19+CRhBEHXWT19+CRhKGgoOY3Jl
d2FpX3ZlcnNpb24SCAoGMC44MC4wShoKDnB5dGhvbl92ZXJzaW9uEggKBjMuMTIuNUouCghjcmV3
X2tleRIiCiBlZTY3NDVkN2M4YWU4MmUwMGRmOTRkZTBmN2Y4NzExOEoxCgdjcmV3X2lkEiYKJDUx
YmI1NGQ0LWM4MTAtNDA0Yy04MTQzLWVmNTgwMTlhN2Q2OEocCgxjcmV3X3Byb2Nlc3MSDAoKc2Vx
dWVudGlhbEoRCgtjcmV3X21lbW9yeRICEABKGgoUY3Jld19udW1iZXJfb2ZfdGFza3MSAhgBShsK
FWNyZXdfbnVtYmVyX29mX2FnZW50cxICGAFK2QIKC2NyZXdfYWdlbnRzEskCCsYCW3sia2V5Ijog
ImYzMzg2ZjZkOGRhNzVhYTQxNmE2ZTMxMDA1M2Y3Njk4IiwgImlkIjogIjRlNTExYTRhLTM1Yzkt
NDA0NC1iMzBlLWM4OGZjZTJiMzc5YiIsICJyb2xlIjogInt0b3BpY30gUmVzZWFyY2hlciIsICJ2
ZXJib3NlPyI6IGZhbHNlLCAibWF4X2l0ZXIiOiAyMCwgIm1heF9ycG0iOiBudWxsLCAiZnVuY3Rp
b25fY2FsbGluZ19sbG0iOiAiIiwgImxsbSI6ICJncHQtNG8tbWluaSIsICJkZWxlZ2F0aW9uX2Vu
YWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRy
eV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtdfV1KhwIKCmNyZXdfdGFza3MS+AEK9QFbeyJr
ZXkiOiAiMDZhNzMyMjBmNDE0OGE0YmJkNWJhY2IwZDBiNDRmY2UiLCAiaWQiOiAiOTIzMWJmZjIt
ODFmOS00MjU4LTgyMDktMjkzMjUyOWI1ZjlmIiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwg
Imh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJ7dG9waWN9IFJlc2VhcmNoZXIi
LCAiYWdlbnRfa2V5IjogImYzMzg2ZjZkOGRhNzVhYTQxNmE2ZTMxMDA1M2Y3Njk4IiwgInRvb2xz
X25hbWVzIjogW119XXoCGAGFAQABAAASjgIKECTO19lNFYzBivlrqiZfSxASCIAH8VhjiPfQKgxU
YXNrIENyZWF0ZWQwATnIr+NPX34JGEHQAeRPX34JGEouCghjcmV3X2tleRIiCiBlZTY3NDVkN2M4
YWU4MmUwMGRmOTRkZTBmN2Y4NzExOEoxCgdjcmV3X2lkEiYKJDUxYmI1NGQ0LWM4MTAtNDA0Yy04
MTQzLWVmNTgwMTlhN2Q2OEouCgh0YXNrX2tleRIiCiAwNmE3MzIyMGY0MTQ4YTRiYmQ1YmFjYjBk
MGI0NGZjZUoxCgd0YXNrX2lkEiYKJDkyMzFiZmYyLTgxZjktNDI1OC04MjA5LTI5MzI1MjliNWY5
ZnoCGAGFAQABAAASswcKEHGb7KITfOkYfQT7CRjWfUcSCIn6YlQJ1QVbKgxDcmV3IENyZWF0ZWQw
ATmYH/BYX34JGEEgJ/JYX34JGEoaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjgwLjBKGgoOcHl0aG9u
X3ZlcnNpb24SCAoGMy4xMi41Si4KCGNyZXdfa2V5EiIKIGVlNjc0NWQ3YzhhZTgyZTAwZGY5NGRl
MGY3Zjg3MTE4SjEKB2NyZXdfaWQSJgokZDc5Y2UyMWUtYmU1Ny00NTdiLWExMzEtNjZkMDFmZjQx
ZTI2ShwKDGNyZXdfcHJvY2VzcxIMCgpzZXF1ZW50aWFsShEKC2NyZXdfbWVtb3J5EgIQAEoaChRj
cmV3X251bWJlcl9vZl90YXNrcxICGAFKGwoVY3Jld19udW1iZXJfb2ZfYWdlbnRzEgIYAUrZAgoL
Y3Jld19hZ2VudHMSyQIKxgJbeyJrZXkiOiAiZjMzODZmNmQ4ZGE3NWFhNDE2YTZlMzEwMDUzZjc2
OTgiLCAiaWQiOiAiNzRhNDUxNzgtNmExOS00N2RjLThlZjktZDdhZmQ5YzUwMDQ0IiwgInJvbGUi
OiAie3RvcGljfSBSZXNlYXJjaGVyIiwgInZlcmJvc2U/IjogZmFsc2UsICJtYXhfaXRlciI6IDIw
LCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAibGxtIjogImdw
dC00by1taW5pIiwgImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93X2NvZGVfZXhl
Y3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25hbWVzIjogW119
XUqHAgoKY3Jld190YXNrcxL4AQr1AVt7ImtleSI6ICIwNmE3MzIyMGY0MTQ4YTRiYmQ1YmFjYjBk
MGI0NGZjZSIsICJpZCI6ICJjZWZiYjE1ZS01Y2M4LTQwZTctYTViMS03ODkzYjJlZGFkYmQiLCAi
YXN5bmNfZXhlY3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5faW5wdXQ/IjogZmFsc2UsICJhZ2VudF9y
b2xlIjogInt0b3BpY30gUmVzZWFyY2hlciIsICJhZ2VudF9rZXkiOiAiZjMzODZmNmQ4ZGE3NWFh
NDE2YTZlMzEwMDUzZjc2OTgiLCAidG9vbHNfbmFtZXMiOiBbXX1degIYAYUBAAEAAA==
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '11392'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Tue, 19 Nov 2024 22:14:39 GMT
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,205 @@
interactions:
- request:
body: '{"messages": [{"role": "user", "content": "Hello, world!"}], "model": "gpt-4o-mini",
"stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '101'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- Linux
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.9
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
H4sIAAAAAAAAA4xSwWrcMBS8+ytedY6LvWvYZi8lpZSkBJLSQiChGK307FUi66nSc9Ml7L8H2e56
l7bQiw8zb8Yzg14yAGG0WINQW8mq8za/+Oqv5MUmXv+8+/Hl3uO3j59u1efreHO+/PAszpKCNo+o
+LfqraLOW2RDbqRVQMmYXMvVsqyWy1VVDERHGm2StZ7zivLOOJMvikWVF6u8fDept2QURrGGhwwA
4GX4ppxO4y+xhsFrQDqMUbYo1ocjABHIJkTIGE1k6ViczaQix+iG6JdoLb2BS3oGJR1cwSiAHfXA
pOXu/bEwYNNHmcK73toJ3x+SWGp9oE2c+APeGGfitg4oI7n018jkxcDuM4DvQ+P+pITwgTrPNdMT
umRYlqOdmHeeyfOJY2JpZ3gxjXRqVmtkaWw8GkwoqbaoZ+W8ruy1oSMiO6r8Z5a/eY+1jWv/x34m
lELPqGsfUBt12nc+C5ge4b/ODhMPgUXcRcauboxrMfhgxifQ+LrYyEKXi6opRbbPXgEAAP//AwAM
DMWoEAMAAA==
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e185b2c1b790303-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Tue, 12 Nov 2024 17:49:00 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=l.QrRLcNZkML_KSfxjir6YCV35B8GNTitBTNh7cPGc4-1731433740-1.0.1.1-j1ejlmykyoI8yk6i6pQjtPoovGzfxI2f5vG6u0EqodQMjCvhbHfNyN_wmYkeT._BMvFi.zDQ8m_PqEHr8tSdEQ;
path=/; expires=Tue, 12-Nov-24 18:19:00 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=jcCDyMK__Fd0V5DMeqt9yXdlKc7Hsw87a1K01pZu9l0-1731433740848-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- user-tqfegqsiobpvvjmn0giaipdq
openai-processing-ms:
- '322'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '200000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '199978'
x-ratelimit-reset-requests:
- 8.64s
x-ratelimit-reset-tokens:
- 6ms
x-request-id:
- req_037288753767e763a51a04eae757ca84
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "user", "content": "Hello, world from another agent!"}],
"model": "gpt-4o-mini", "stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '120'
content-type:
- application/json
cookie:
- __cf_bm=l.QrRLcNZkML_KSfxjir6YCV35B8GNTitBTNh7cPGc4-1731433740-1.0.1.1-j1ejlmykyoI8yk6i6pQjtPoovGzfxI2f5vG6u0EqodQMjCvhbHfNyN_wmYkeT._BMvFi.zDQ8m_PqEHr8tSdEQ;
_cfuvid=jcCDyMK__Fd0V5DMeqt9yXdlKc7Hsw87a1K01pZu9l0-1731433740848-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- Linux
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.9
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
H4sIAAAAAAAAA4xSy27bMBC86yu2PFuBZAt14UvRU5MA7aVAEKAIBJpcSUwoLkuu6jiB/z3QI5aM
tkAvPMzsDGZ2+ZoACKPFDoRqJKvW2/TLD3+z//oiD8dfL7d339zvW125x9zX90/3mVj1Cto/ouJ3
1ZWi1ltkQ26kVUDJ2Lvm201ebDbbIh+IljTaXlZ7TgtKW+NMus7WRZpt0/zTpG7IKIxiBz8TAIDX
4e1zOo3PYgfZ6h1pMUZZo9idhwBEINsjQsZoIkvHYjWTihyjG6Jfo7X0Ab4bhcAEipxDxXAw3IB0
xA0GkDU6voJrOoCSDm5gNIUjdcCk5fHz0jxg1UXZF3SdtRN+Oqe1VPtA+zjxZ7wyzsSmDCgjuT5Z
ZPJiYE8JwMOwle6iqPCBWs8l0xO63jAvRjsx32JBfpxIJpZ2xjfTJi/dSo0sjY2LrQolVYN6Vs4n
kJ02tCCSRec/w/zNe+xtXP0/9jOhFHpGXfqA2qjLwvNYwP6n/mvsvOMhsIjHyNiWlXE1Bh/M+E8q
X2Z7mel8XVS5SE7JGwAAAP//AwA/cK4yNQMAAA==
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e185b31398a0303-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Tue, 12 Nov 2024 17:49:02 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- user-tqfegqsiobpvvjmn0giaipdq
openai-processing-ms:
- '889'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '200000'
x-ratelimit-remaining-requests:
- '9998'
x-ratelimit-remaining-tokens:
- '199975'
x-ratelimit-reset-requests:
- 16.489s
x-ratelimit-reset-tokens:
- 7ms
x-request-id:
- req_bde3810b36a4859688e53d1df64bdd20
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,565 @@
interactions:
- request:
body: !!binary |
CoBACiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkS1z8KEgoQY3Jld2FpLnRl
bGVtZXRyeRKQDAoQsz1SskG+EjJPD44lvCSFCxIIlcKcY48gxQAqDENyZXcgQ3JlYXRlZDABORht
kkfU8QgYQZgEmUfU8QgYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODAuMEoaCg5weXRob25fdmVy
c2lvbhIICgYzLjExLjdKLgoIY3Jld19rZXkSIgogMWYxMjhiZGI3YmFhNGI2NzcxNGYxZGFlZGMy
ZjNhYjZKMQoHY3Jld19pZBImCiQ0MzA0ODRhNS0zODM3LTRkZDktOTBmYS1kMTg3NDM0MjRmZDRK
HAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdf
bnVtYmVyX29mX3Rhc2tzEgIYAkobChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgCSqoFCgtjcmV3
X2FnZW50cxKaBQqXBVt7ImtleSI6ICI3M2MzNDljOTNjMTYzYjVkNGRmOThhNjRmYWMxYzQzMCIs
ICJpZCI6ICI0NWU2MTcyOC04MDQzLTQ4ZTUtYjY1YS1mZjAxM2E5OGIwZjMiLCAicm9sZSI6ICJ7
dG9waWN9IFNlbmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJ2ZXJib3NlPyI6IHRydWUsICJtYXhf
aXRlciI6IDIwLCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAi
bGxtIjogImdwdC00byIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2Rl
X2V4ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6
IFtdfSwgeyJrZXkiOiAiMTA0ZmUwNjU5ZTEwYjQyNmNmODhmMDI0ZmI1NzE1NTMiLCAiaWQiOiAi
MTgyOGQ3NTktYzgzMS00YTBhLTk5YmQtNzU4OWM3ZGMzNjM1IiwgInJvbGUiOiAie3RvcGljfSBS
ZXBvcnRpbmcgQW5hbHlzdFxuIiwgInZlcmJvc2U/IjogdHJ1ZSwgIm1heF9pdGVyIjogMjAsICJt
YXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogIiIsICJsbG0iOiAiZ3B0LTRv
IiwgImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6
IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25hbWVzIjogW119XUqTBAoKY3Jl
d190YXNrcxKEBAqBBFt7ImtleSI6ICI2YWZjNGIzOTYyNTlmYmI3NjgxZjU2Yzc3NTVjYzkzNyIs
ICJpZCI6ICIxZWQ2YmQ5Yy0wNTFhLTRhYjUtYjQ5NC01NzI1NDY1OWIyODQiLCAiYXN5bmNfZXhl
Y3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5faW5wdXQ/IjogZmFsc2UsICJhZ2VudF9yb2xlIjogInt0
b3BpY30gU2VuaW9yIERhdGEgUmVzZWFyY2hlclxuIiwgImFnZW50X2tleSI6ICI3M2MzNDljOTNj
MTYzYjVkNGRmOThhNjRmYWMxYzQzMCIsICJ0b29sc19uYW1lcyI6IFtdfSwgeyJrZXkiOiAiYjE3
YjE4OGRiZjE0ZjkzYTk4ZTViOTVhYWQzNjc1NzciLCAiaWQiOiAiZWE2MmJjM2EtMGYzNi00NGFl
LWJiYTktOWJlY2RmNTFlNGE4IiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lu
cHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJ7dG9waWN9IFJlcG9ydGluZyBBbmFseXN0XG4i
LCAiYWdlbnRfa2V5IjogIjEwNGZlMDY1OWUxMGI0MjZjZjg4ZjAyNGZiNTcxNTUzIiwgInRvb2xz
X25hbWVzIjogW119XXoCGAGFAQABAAASjgIKEJohcMRpBfZqBQCPSM3m2SQSCIXDnmVDTos7KgxU
YXNrIENyZWF0ZWQwATnAMqxH1PEIGEHAr6xH1PEIGEouCghjcmV3X2tleRIiCiAxZjEyOGJkYjdi
YWE0YjY3NzE0ZjFkYWVkYzJmM2FiNkoxCgdjcmV3X2lkEiYKJDQzMDQ4NGE1LTM4MzctNGRkOS05
MGZhLWQxODc0MzQyNGZkNEouCgh0YXNrX2tleRIiCiA2YWZjNGIzOTYyNTlmYmI3NjgxZjU2Yzc3
NTVjYzkzN0oxCgd0YXNrX2lkEiYKJDFlZDZiZDljLTA1MWEtNGFiNS1iNDk0LTU3MjU0NjU5YjI4
NHoCGAGFAQABAAASjgIKEFme5tfbl7IKlOtxKXOBwbkSCEkXsxaQXDs+KgxUYXNrIENyZWF0ZWQw
ATloDuBJ1PEIGEGABOFJ1PEIGEouCghjcmV3X2tleRIiCiAxZjEyOGJkYjdiYWE0YjY3NzE0ZjFk
YWVkYzJmM2FiNkoxCgdjcmV3X2lkEiYKJDQzMDQ4NGE1LTM4MzctNGRkOS05MGZhLWQxODc0MzQy
NGZkNEouCgh0YXNrX2tleRIiCiBiMTdiMTg4ZGJmMTRmOTNhOThlNWI5NWFhZDM2NzU3N0oxCgd0
YXNrX2lkEiYKJGVhNjJiYzNhLTBmMzYtNDRhZS1iYmE5LTliZWNkZjUxZTRhOHoCGAGFAQABAAAS
kAwKEFJJx8FrKG3eBx+YFpoVWbsSCPJRoDF/VPvQKgxDcmV3IENyZWF0ZWQwATnYWWZO1PEIGEGw
JGlO1PEIGEoaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjgwLjBKGgoOcHl0aG9uX3ZlcnNpb24SCAoG
My4xMS43Si4KCGNyZXdfa2V5EiIKIDFmMTI4YmRiN2JhYTRiNjc3MTRmMWRhZWRjMmYzYWI2SjEK
B2NyZXdfaWQSJgokYmViNmFlOTEtYTdjMS00YWVmLTg0ZjUtMzNhZjUwYTc3NjVhShwKDGNyZXdf
cHJvY2VzcxIMCgpzZXF1ZW50aWFsShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251bWJlcl9v
Zl90YXNrcxICGAJKGwoVY3Jld19udW1iZXJfb2ZfYWdlbnRzEgIYAkqqBQoLY3Jld19hZ2VudHMS
mgUKlwVbeyJrZXkiOiAiNzNjMzQ5YzkzYzE2M2I1ZDRkZjk4YTY0ZmFjMWM0MzAiLCAiaWQiOiAi
MTk5NmFkYzctODQzNy00ODM3LThhYWYtNzQ1NWFlNjU1MzNkIiwgInJvbGUiOiAie3RvcGljfSBT
ZW5pb3IgRGF0YSBSZXNlYXJjaGVyXG4iLCAidmVyYm9zZT8iOiB0cnVlLCAibWF4X2l0ZXIiOiAy
MCwgIm1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwgImxsbSI6ICJn
cHQtNG8iLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29kZV9leGVjdXRp
b24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMiOiBbXX0sIHsi
a2V5IjogIjEwNGZlMDY1OWUxMGI0MjZjZjg4ZjAyNGZiNTcxNTUzIiwgImlkIjogIjhiYTA2NGM3
LWQ2NTItNGFmMi1hYjQ0LWJhNDA2NDRkMDJlMSIsICJyb2xlIjogInt0b3BpY30gUmVwb3J0aW5n
IEFuYWx5c3RcbiIsICJ2ZXJib3NlPyI6IHRydWUsICJtYXhfaXRlciI6IDIwLCAibWF4X3JwbSI6
IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAibGxtIjogImdwdC00byIsICJkZWxl
Z2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8iOiBmYWxzZSwg
Im1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtdfV1KkwQKCmNyZXdfdGFza3MS
hAQKgQRbeyJrZXkiOiAiNmFmYzRiMzk2MjU5ZmJiNzY4MWY1NmM3NzU1Y2M5MzciLCAiaWQiOiAi
YTQzMTgxZjUtYzkwYi00ZDk0LWI1NTAtMTI2ZmNjM2Y4NjU3IiwgImFzeW5jX2V4ZWN1dGlvbj8i
OiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJ7dG9waWN9IFNl
bmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJhZ2VudF9rZXkiOiAiNzNjMzQ5YzkzYzE2M2I1ZDRk
Zjk4YTY0ZmFjMWM0MzAiLCAidG9vbHNfbmFtZXMiOiBbXX0sIHsia2V5IjogImIxN2IxODhkYmYx
NGY5M2E5OGU1Yjk1YWFkMzY3NTc3IiwgImlkIjogImE3NzczMTA2LTEwNDEtNDI2ZS05NjVhLTRj
YzExYjNkMjhiNyIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBm
YWxzZSwgImFnZW50X3JvbGUiOiAie3RvcGljfSBSZXBvcnRpbmcgQW5hbHlzdFxuIiwgImFnZW50
X2tleSI6ICIxMDRmZTA2NTllMTBiNDI2Y2Y4OGYwMjRmYjU3MTU1MyIsICJ0b29sc19uYW1lcyI6
IFtdfV16AhgBhQEAAQAAEo4CChCfS8p2nUmN4gbwYTXM780iEgiD3bJ3GYKbCyoMVGFzayBDcmVh
dGVkMAE5oK91TtTxCBhBoCx2TtTxCBhKLgoIY3Jld19rZXkSIgogMWYxMjhiZGI3YmFhNGI2Nzcx
NGYxZGFlZGMyZjNhYjZKMQoHY3Jld19pZBImCiRiZWI2YWU5MS1hN2MxLTRhZWYtODRmNS0zM2Fm
NTBhNzc2NWFKLgoIdGFza19rZXkSIgogNmFmYzRiMzk2MjU5ZmJiNzY4MWY1NmM3NzU1Y2M5MzdK
MQoHdGFza19pZBImCiRhNDMxODFmNS1jOTBiLTRkOTQtYjU1MC0xMjZmY2MzZjg2NTd6AhgBhQEA
AQAAEo4CChD6YglTfqRETeD91myfQQucEgjVnKDpP/acdSoMVGFzayBDcmVhdGVkMAE54FB+UNTx
CBhBOOl+UNTxCBhKLgoIY3Jld19rZXkSIgogMWYxMjhiZGI3YmFhNGI2NzcxNGYxZGFlZGMyZjNh
YjZKMQoHY3Jld19pZBImCiRiZWI2YWU5MS1hN2MxLTRhZWYtODRmNS0zM2FmNTBhNzc2NWFKLgoI
dGFza19rZXkSIgogYjE3YjE4OGRiZjE0ZjkzYTk4ZTViOTVhYWQzNjc1NzdKMQoHdGFza19pZBIm
CiRhNzc3MzEwNi0xMDQxLTQyNmUtOTY1YS00Y2MxMWIzZDI4Yjd6AhgBhQEAAQAAEpAMChD6odHS
2zFS6x5ow3o0vrPMEgjfWriALnu/VyoMQ3JldyBDcmVhdGVkMAE5gE7+UNTxCBhB6IQAUdTxCBhK
GgoOY3Jld2FpX3ZlcnNpb24SCAoGMC44MC4wShoKDnB5dGhvbl92ZXJzaW9uEggKBjMuMTEuN0ou
CghjcmV3X2tleRIiCiAxZjEyOGJkYjdiYWE0YjY3NzE0ZjFkYWVkYzJmM2FiNkoxCgdjcmV3X2lk
EiYKJDAxN2I1M2M0LWU0N2EtNDRjMy1hZTZhLWE4NDc2N2Q3MDEwMkocCgxjcmV3X3Byb2Nlc3MS
DAoKc2VxdWVudGlhbEoRCgtjcmV3X21lbW9yeRICEABKGgoUY3Jld19udW1iZXJfb2ZfdGFza3MS
AhgCShsKFWNyZXdfbnVtYmVyX29mX2FnZW50cxICGAJKqgUKC2NyZXdfYWdlbnRzEpoFCpcFW3si
a2V5IjogIjczYzM0OWM5M2MxNjNiNWQ0ZGY5OGE2NGZhYzFjNDMwIiwgImlkIjogImE1YjNmZjcz
LTVjMmQtNDI5Ny05M2ExLTY2NDMyOWJmNGNiYiIsICJyb2xlIjogInt0b3BpY30gU2VuaW9yIERh
dGEgUmVzZWFyY2hlclxuIiwgInZlcmJvc2U/IjogdHJ1ZSwgIm1heF9pdGVyIjogMjAsICJtYXhf
cnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogIiIsICJsbG0iOiAiZ3B0LTRvIiwg
ImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6IGZh
bHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25hbWVzIjogW119LCB7ImtleSI6ICIx
MDRmZTA2NTllMTBiNDI2Y2Y4OGYwMjRmYjU3MTU1MyIsICJpZCI6ICJiMTU4Y2RjNS1iYzZmLTQ3
YTktYjE2NS1kNDQ2YzFmODhkNDUiLCAicm9sZSI6ICJ7dG9waWN9IFJlcG9ydGluZyBBbmFseXN0
XG4iLCAidmVyYm9zZT8iOiB0cnVlLCAibWF4X2l0ZXIiOiAyMCwgIm1heF9ycG0iOiBudWxsLCAi
ZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwgImxsbSI6ICJncHQtNG8iLCAiZGVsZWdhdGlvbl9l
bmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29kZV9leGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0
cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMiOiBbXX1dSpMECgpjcmV3X3Rhc2tzEoQECoEEW3si
a2V5IjogIjZhZmM0YjM5NjI1OWZiYjc2ODFmNTZjNzc1NWNjOTM3IiwgImlkIjogImY0ZjZiZWI0
LWRhOGQtNDU1MC05ZWVhLThlOWM5NzY1NWNlNCIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2Us
ICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAie3RvcGljfSBTZW5pb3IgRGF0
YSBSZXNlYXJjaGVyXG4iLCAiYWdlbnRfa2V5IjogIjczYzM0OWM5M2MxNjNiNWQ0ZGY5OGE2NGZh
YzFjNDMwIiwgInRvb2xzX25hbWVzIjogW119LCB7ImtleSI6ICJiMTdiMTg4ZGJmMTRmOTNhOThl
NWI5NWFhZDM2NzU3NyIsICJpZCI6ICJlMzA0ZWI4ZC1jYTViLTRmYmMtYmRiNS1mODZlNjE3ZWJl
ZDYiLCAiYXN5bmNfZXhlY3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5faW5wdXQ/IjogZmFsc2UsICJh
Z2VudF9yb2xlIjogInt0b3BpY30gUmVwb3J0aW5nIEFuYWx5c3RcbiIsICJhZ2VudF9rZXkiOiAi
MTA0ZmUwNjU5ZTEwYjQyNmNmODhmMDI0ZmI1NzE1NTMiLCAidG9vbHNfbmFtZXMiOiBbXX1degIY
AYUBAAEAABKOAgoQ4nBhY/C/2pvPVCF+gQM4/xIIZfcNXrNnmOMqDFRhc2sgQ3JlYXRlZDABORiU
EVHU8QgYQUgJElHU8QgYSi4KCGNyZXdfa2V5EiIKIDFmMTI4YmRiN2JhYTRiNjc3MTRmMWRhZWRj
MmYzYWI2SjEKB2NyZXdfaWQSJgokMDE3YjUzYzQtZTQ3YS00NGMzLWFlNmEtYTg0NzY3ZDcwMTAy
Si4KCHRhc2tfa2V5EiIKIDZhZmM0YjM5NjI1OWZiYjc2ODFmNTZjNzc1NWNjOTM3SjEKB3Rhc2tf
aWQSJgokZjRmNmJlYjQtZGE4ZC00NTUwLTllZWEtOGU5Yzk3NjU1Y2U0egIYAYUBAAEAABKOAgoQ
/NE8mExW1Yc4m8BzpCjK4BII6h0SL5AwtM8qDFRhc2sgQ3JlYXRlZDABObAHR1HU8QgYQeB8R1HU
8QgYSi4KCGNyZXdfa2V5EiIKIDFmMTI4YmRiN2JhYTRiNjc3MTRmMWRhZWRjMmYzYWI2SjEKB2Ny
ZXdfaWQSJgokMDE3YjUzYzQtZTQ3YS00NGMzLWFlNmEtYTg0NzY3ZDcwMTAySi4KCHRhc2tfa2V5
EiIKIGIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3SjEKB3Rhc2tfaWQSJgokZTMwNGVi
OGQtY2E1Yi00ZmJjLWJkYjUtZjg2ZTYxN2ViZWQ2egIYAYUBAAEAABKQDAoQ3X0ZU0/DPkeXYe62
8W/vqRII03hxvkN2cu4qDENyZXcgQ3JlYXRlZDABOUDsalnU8QgYQZAmbVnU8QgYShoKDmNyZXdh
aV92ZXJzaW9uEggKBjAuODAuMEoaCg5weXRob25fdmVyc2lvbhIICgYzLjExLjdKLgoIY3Jld19r
ZXkSIgogMWYxMjhiZGI3YmFhNGI2NzcxNGYxZGFlZGMyZjNhYjZKMQoHY3Jld19pZBImCiQ5NjNm
ODBkMy1jYTJkLTQ4MDktODRmMC1hNjgxNzEzM2YzOWFKHAoMY3Jld19wcm9jZXNzEgwKCnNlcXVl
bnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdfbnVtYmVyX29mX3Rhc2tzEgIYAkobChVj
cmV3X251bWJlcl9vZl9hZ2VudHMSAhgCSqoFCgtjcmV3X2FnZW50cxKaBQqXBVt7ImtleSI6ICI3
M2MzNDljOTNjMTYzYjVkNGRmOThhNjRmYWMxYzQzMCIsICJpZCI6ICJmNDFlMTI2YS0wZTNhLTRm
OWEtODdhNi05MzQ3ZGU5YTUxODQiLCAicm9sZSI6ICJ7dG9waWN9IFNlbmlvciBEYXRhIFJlc2Vh
cmNoZXJcbiIsICJ2ZXJib3NlPyI6IHRydWUsICJtYXhfaXRlciI6IDIwLCAibWF4X3JwbSI6IG51
bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAibGxtIjogImdwdC00byIsICJkZWxlZ2F0
aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8iOiBmYWxzZSwgIm1h
eF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtdfSwgeyJrZXkiOiAiMTA0ZmUwNjU5
ZTEwYjQyNmNmODhmMDI0ZmI1NzE1NTMiLCAiaWQiOiAiMGZkMzJmYzAtNGY4Mi00OWNiLWI1MDct
MWZmZTU5YzBlNWRmIiwgInJvbGUiOiAie3RvcGljfSBSZXBvcnRpbmcgQW5hbHlzdFxuIiwgInZl
cmJvc2U/IjogdHJ1ZSwgIm1heF9pdGVyIjogMjAsICJtYXhfcnBtIjogbnVsbCwgImZ1bmN0aW9u
X2NhbGxpbmdfbGxtIjogIiIsICJsbG0iOiAiZ3B0LTRvIiwgImRlbGVnYXRpb25fZW5hYmxlZD8i
OiBmYWxzZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0
IjogMiwgInRvb2xzX25hbWVzIjogW119XUqTBAoKY3Jld190YXNrcxKEBAqBBFt7ImtleSI6ICI2
YWZjNGIzOTYyNTlmYmI3NjgxZjU2Yzc3NTVjYzkzNyIsICJpZCI6ICI1YjlkYTE0Ni0xOGQ1LTQ1
NjctODYwNi1hMTU3MGU3YzQyYTgiLCAiYXN5bmNfZXhlY3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5f
aW5wdXQ/IjogZmFsc2UsICJhZ2VudF9yb2xlIjogInt0b3BpY30gU2VuaW9yIERhdGEgUmVzZWFy
Y2hlclxuIiwgImFnZW50X2tleSI6ICI3M2MzNDljOTNjMTYzYjVkNGRmOThhNjRmYWMxYzQzMCIs
ICJ0b29sc19uYW1lcyI6IFtdfSwgeyJrZXkiOiAiYjE3YjE4OGRiZjE0ZjkzYTk4ZTViOTVhYWQz
Njc1NzciLCAiaWQiOiAiZDI1ZjVlZmQtZjMzNC00YjRjLWE1NjktNTI2ZjAyZGY3MDAzIiwgImFz
eW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9s
ZSI6ICJ7dG9waWN9IFJlcG9ydGluZyBBbmFseXN0XG4iLCAiYWdlbnRfa2V5IjogIjEwNGZlMDY1
OWUxMGI0MjZjZjg4ZjAyNGZiNTcxNTUzIiwgInRvb2xzX25hbWVzIjogW119XXoCGAGFAQABAAAS
jgIKEDpNX1u5dj3lqgySCZra2sISCEMmeziSVN2NKgxUYXNrIENyZWF0ZWQwATmoV3lZ1PEIGEHQ
93lZ1PEIGEouCghjcmV3X2tleRIiCiAxZjEyOGJkYjdiYWE0YjY3NzE0ZjFkYWVkYzJmM2FiNkox
CgdjcmV3X2lkEiYKJDk2M2Y4MGQzLWNhMmQtNDgwOS04NGYwLWE2ODE3MTMzZjM5YUouCgh0YXNr
X2tleRIiCiA2YWZjNGIzOTYyNTlmYmI3NjgxZjU2Yzc3NTVjYzkzN0oxCgd0YXNrX2lkEiYKJDVi
OWRhMTQ2LTE4ZDUtNDU2Ny04NjA2LWExNTcwZTdjNDJhOHoCGAGFAQABAAA=
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '8195'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Mon, 18 Nov 2024 03:19:16 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are plants Senior Data
Researcher\n. You''re a seasoned researcher with a knack for uncovering the
latest developments in plants. Known for your ability to find the most relevant
information and present it in a clear and concise manner.\n\nYour personal goal
is: Uncover cutting-edge developments in plants\n\nTo give my best complete
final answer to the task use the exact following format:\n\nThought: I now can
give a great answer\nFinal Answer: Your final answer must be the great and the
most complete as possible, it must be outcome described.\n\nI MUST use these
formats, my job depends on it!"}, {"role": "user", "content": "\nCurrent Task:
Conduct a thorough research about plants Make sure you find any interesting
and relevant information given the current year is 2024.\n\n\nThis is the expect
criteria for your final answer: A list with 10 bullet points of the most relevant
information about plants\n\nyou MUST return the actual complete content as the
final answer, not a summary.\n\nBegin! This is VERY important to you, use the
tools available and give your best Final Answer, your job depends on it!\n\nThought:"}],
"model": "gpt-4o", "stop": ["\nObservation:"], "stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '1245'
content-type:
- application/json
cookie:
- _cfuvid=74kaPOoAcp8YRSA0XocQ1FFNksu9V0_KiWdQfo7wQuQ-1731827382509-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
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
IimVsFkOAAA=
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e44d146eed6a423-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Mon, 18 Nov 2024 03:19:25 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=TExeV_B53ShoY.Ag2_Czvi.2L9gx.ekuTvv6twEsyZs-1731899965-1.0.1.1-TI1CwjC1TYPFLagqlZnBGPwghLqfQ14IMBF7MxpAfc1ZVDU6ahhzFq9sUtZDpajNRPyefUF9MUCXzF8vfGAyPw;
path=/; expires=Mon, 18-Nov-24 03:49:25 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '13765'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29999712'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_2d538d2fe02ebd3efaa4c15c43b6f88a
status:
code: 200
message: OK
- request:
body: !!binary |
Cs4CCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSpQIKEgoQY3Jld2FpLnRl
bGVtZXRyeRKOAgoQGHdygqOzofI91Tjg07fdjRIIXwWg5RZ9w0oqDFRhc2sgQ3JlYXRlZDABOej4
TaXX8QgYQcgbUKXX8QgYSi4KCGNyZXdfa2V5EiIKIDFmMTI4YmRiN2JhYTRiNjc3MTRmMWRhZWRj
MmYzYWI2SjEKB2NyZXdfaWQSJgokOTYzZjgwZDMtY2EyZC00ODA5LTg0ZjAtYTY4MTcxMzNmMzlh
Si4KCHRhc2tfa2V5EiIKIGIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3SjEKB3Rhc2tf
aWQSJgokZDI1ZjVlZmQtZjMzNC00YjRjLWE1NjktNTI2ZjAyZGY3MDAzegIYAYUBAAEAAA==
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '337'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Mon, 18 Nov 2024 03:19:26 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are plants Reporting Analyst\n.
You''re a meticulous analyst with a keen eye for detail. You''re known for your
ability to turn complex data into clear and concise reports, making it easy
for others to understand and act on the information you provide.\n\nYour personal
goal is: Create detailed reports based on plants data analysis and research
findings\n\nTo give my best complete final answer to the task use the exact
following format:\n\nThought: I now can give a great answer\nFinal Answer: Your
final answer must be the great and the most complete as possible, it must be
outcome described.\n\nI MUST use these formats, my job depends on it!"}, {"role":
"user", "content": "\nCurrent Task: Review the context you got and expand each
topic into a full section for a report. Make sure the report is detailed and
contains any and all relevant information.\n\n\nThis is the expect criteria
for your final answer: A fully fledge reports with the mains topics, each with
a full section of information. Formatted as markdown without ''```''\n\nyou
MUST return the actual complete content as the final answer, not a summary.\n\nThis
is the context you''re working with:\n1. **Vertical Farming Advancements**:
In 2024, vertical farming is set to revolutionize how we grow plants by maximizing
space and resource efficiency. New technologies allow for urban agriculture
with minimal ecological impact, using hydroponics and aeroponics to cultivate
fresh produce in city environments.\n\n2. **CRISPR and Plant Genetics**: CRISPR
technology has advanced significantly, enabling precise genome editing in plants.
This allows for the development of crops that are more resistant to diseases,
pests, and climate change, potentially increasing yield and food security worldwide.\n\n3.
**Biodiversity Conservation**: Efforts to conserve plant biodiversity have gained
traction, with initiatives focusing on seed banks and botanical gardens. These
efforts aim to preserve the genetic diversity necessary for ecological resilience
in the face of changing environmental conditions.\n\n4. **Carbon Sequestration
Research**: Plants'' role in carbon capture is being harnessed more effectively,
with research focused on enhancing the carbon-sequestering abilities of trees
and soil through improved plant varieties and land management practices.\n\n5.
**Phytoremediation Technologies**: Innovative use of plants to clean up polluted
environments, known as phytoremediation, has advanced. Researchers are developing
plants specifically engineered to absorb heavy metals and other toxins from
the soil and water, aiding in environmental restoration.\n\n6. **Synthetic Botany**:
This emerging field involves redesigning plant biological processes to create
new functionalities such as biofuels, pharmaceuticals, and other valuable compounds.
This interdisciplinary approach opens new avenues for plant-based technology.\n\n7.
**Climate-Resilient Crops**: With climate change posing significant threats
to agriculture, developing crops that can withstand extreme weather conditions
such as drought and floods is a top priority. 2024 sees breakthroughs in engineering
crops that maintain productivity under these stressors.\n\n8. **Algae Farming
Innovations**: Algae are increasingly used in various industries due to their
efficiency in photosynthesis and rapid growth. Innovations in algae farming
are contributing to biofuel production, carbon capture, and sustainable aquaculture
feeds.\n\n9. **Edible Plant Packaging**: The trend towards sustainability in
reducing plastic waste has led to innovations in plant-based, edible packaging.
These biodegradable solutions are making headway in food safety, reducing waste,
and providing a more sustainable packaging alternative.\n\n10. **Forest Restoration
Projects**: Large-scale reforestation efforts are underway globally to combat
deforestation and habitat loss. These projects integrate traditional knowledge
with modern practices to restore ecosystems, promote biodiversity, and mitigate
climate impacts.\n\nBegin! This is VERY important to you, use the tools available
and give your best Final Answer, your job depends on it!\n\nThought:"}], "model":
"gpt-4o", "stop": ["\nObservation:"], "stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '4283'
content-type:
- application/json
cookie:
- _cfuvid=74kaPOoAcp8YRSA0XocQ1FFNksu9V0_KiWdQfo7wQuQ-1731827382509-0.0.1.1-604800000;
__cf_bm=TExeV_B53ShoY.Ag2_Czvi.2L9gx.ekuTvv6twEsyZs-1731899965-1.0.1.1-TI1CwjC1TYPFLagqlZnBGPwghLqfQ14IMBF7MxpAfc1ZVDU6ahhzFq9sUtZDpajNRPyefUF9MUCXzF8vfGAyPw
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
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
75799uz/AAAA//8DAD3tznO2JQAA
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e44d19eed83a423-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Mon, 18 Nov 2024 03:19:42 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '17464'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29998958'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 2ms
x-request-id:
- req_9b9ed646842761c5b091045f5e85bfd3
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,495 @@
interactions:
- request:
body: !!binary |
CusOCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSwg4KEgoQY3Jld2FpLnRl
bGVtZXRyeRKaDAoQoIrabVYsFbbHfYiDTst34xIIG0YGNNs8p2gqDENyZXcgQ3JlYXRlZDABOYhW
grn2rgkYQUBQhbn2rgkYShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuODAuMEoaCg5weXRob25fdmVy
c2lvbhIICgYzLjEyLjdKLgoIY3Jld19rZXkSIgogMWYxMjhiZGI3YmFhNGI2NzcxNGYxZGFlZGMy
ZjNhYjZKMQoHY3Jld19pZBImCiQzM2Q1NTk3MS1iZmI2LTQ5MTgtODNhZC1iZWMxZmEyYzc0NjhK
HAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdf
bnVtYmVyX29mX3Rhc2tzEgIYAkobChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgCSrQFCgtjcmV3
X2FnZW50cxKkBQqhBVt7ImtleSI6ICI3M2MzNDljOTNjMTYzYjVkNGRmOThhNjRmYWMxYzQzMCIs
ICJpZCI6ICIwZGZjYzg3MS01ZGI5LTRkYjItOWIyNy0xN2I0MmIyZmZiMTAiLCAicm9sZSI6ICJ7
dG9waWN9IFNlbmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJ2ZXJib3NlPyI6IHRydWUsICJtYXhf
aXRlciI6IDIwLCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAi
bGxtIjogImdwdC00by1taW5pIiwgImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93
X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25h
bWVzIjogW119LCB7ImtleSI6ICIxMDRmZTA2NTllMTBiNDI2Y2Y4OGYwMjRmYjU3MTU1MyIsICJp
ZCI6ICJiZjFkODdkZC0zZmUyLTRjYTctOTI1My0xYTQyYTljNWE5NjYiLCAicm9sZSI6ICJ7dG9w
aWN9IFJlcG9ydGluZyBBbmFseXN0XG4iLCAidmVyYm9zZT8iOiB0cnVlLCAibWF4X2l0ZXIiOiAy
MCwgIm1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGluZ19sbG0iOiAiIiwgImxsbSI6ICJn
cHQtNG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4
ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtd
fV1KkwQKCmNyZXdfdGFza3MShAQKgQRbeyJrZXkiOiAiNmFmYzRiMzk2MjU5ZmJiNzY4MWY1NmM3
NzU1Y2M5MzciLCAiaWQiOiAiNjhhZmY3NzctODEwYy00N2Q0LTlmMjItMjBlY2VhY2Y3ZTFhIiwg
ImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRf
cm9sZSI6ICJ7dG9waWN9IFNlbmlvciBEYXRhIFJlc2VhcmNoZXJcbiIsICJhZ2VudF9rZXkiOiAi
NzNjMzQ5YzkzYzE2M2I1ZDRkZjk4YTY0ZmFjMWM0MzAiLCAidG9vbHNfbmFtZXMiOiBbXX0sIHsi
a2V5IjogImIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3IiwgImlkIjogImNlZmFlNzU1
LTMzNzctNGE3OS1hNGMyLTZkMDk5Yzk0YmRlYiIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2Us
ICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAie3RvcGljfSBSZXBvcnRpbmcg
QW5hbHlzdFxuIiwgImFnZW50X2tleSI6ICIxMDRmZTA2NTllMTBiNDI2Y2Y4OGYwMjRmYjU3MTU1
MyIsICJ0b29sc19uYW1lcyI6IFtdfV16AhgBhQEAAQAAEo4CChAk4SmgCGgI1cLD7bspORIREgiA
ME8JXP1gfioMVGFzayBDcmVhdGVkMAE56EuWufauCRhBWOCWufauCRhKLgoIY3Jld19rZXkSIgog
MWYxMjhiZGI3YmFhNGI2NzcxNGYxZGFlZGMyZjNhYjZKMQoHY3Jld19pZBImCiQzM2Q1NTk3MS1i
ZmI2LTQ5MTgtODNhZC1iZWMxZmEyYzc0NjhKLgoIdGFza19rZXkSIgogNmFmYzRiMzk2MjU5ZmJi
NzY4MWY1NmM3NzU1Y2M5MzdKMQoHdGFza19pZBImCiQ2OGFmZjc3Ny04MTBjLTQ3ZDQtOWYyMi0y
MGVjZWFjZjdlMWF6AhgBhQEAAQAA
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '1902'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Wed, 20 Nov 2024 13:05:09 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are plants Senior Data
Researcher\n. You''re a seasoned researcher with a knack for uncovering the
latest developments in plants. Known for your ability to find the most relevant
information and present it in a clear and concise manner.\n\nYour personal goal
is: Uncover cutting-edge developments in plants\n\nTo give my best complete
final answer to the task use the exact following format:\n\nThought: I now can
give a great answer\nFinal Answer: Your final answer must be the great and the
most complete as possible, it must be outcome described.\n\nI MUST use these
formats, my job depends on it!"}, {"role": "user", "content": "\nCurrent Task:
Conduct a thorough research about plants Make sure you find any interesting
and relevant information given the current year is 2024.\n\n\nThis is the expect
criteria for your final answer: A list with 10 bullet points of the most relevant
information about plants\n\nyou MUST return the actual complete content as the
final answer, not a summary.\n\nBegin! This is VERY important to you, use the
tools available and give your best Final Answer, your job depends on it!\n\nThought:"}],
"model": "gpt-4o-mini", "stop": ["\nObservation:"], "stream": false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '1250'
content-type:
- application/json
cookie:
- __cf_bm=CkK4UvBd9ukXvn50uJwGambJcz5zERAJfeXJ9xge6H4-1732107842-1.0.1.1-IOK2yVL3RlD75MgmnKzIEyE38HNknwn6I8BBJ1wjGz4jCTd0YWIBPnvUm9gB8D_zLlUA9G7p_wbrfyc4mO_Bmg;
_cfuvid=MmeN9oHWrBLThkEJdaSFHBfWe95JvA8iFnnt7CC92tk-1732107842102-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-AVegEGAMTASvlfwjAjy5PsqGwtN6X\",\n \"object\":
\"chat.completion\",\n \"created\": 1732107906,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"I now can give a great answer \\nFinal
Answer: \\n1. **Plant-Based Plastics**: 2024 has seen significant advancements
in bioplastics derived from plants such as corn and sugarcane, which are being
used as sustainable alternatives to petroleum-based plastics. These innovations
aim to reduce plastic waste and reliance on fossil fuels.\\n\\n2. **Gene Editing
Breakthroughs**: CRISPR technology continues to revolutionize agricultural practices.
Researchers have developed genetically modified crops that are more resistant
to pests and diseases, thereby decreasing the need for chemical pesticides and
increasing food security.\\n\\n3. **Vertical Farming Expansion**: Urban agriculture
has gained momentum with vertical farming techniques that utilize less water
and space. In 2024, cities worldwide are adopting these innovative systems to
meet the growing food demand while reducing transportation emissions.\\n\\n4.
**Climate-Resilient Plants**: Scientists are identifying and breeding plant
varieties that can withstand extreme weather conditions such as droughts, floods,
and high temperatures, helping farmers adapt to climate change and ensuring
crop yields remain stable.\\n\\n5. **Edible Vaccines in Plants**: Research into
producing vaccines in plants has progressed, with trials showing that certain
plants can be engineered to express antigens that could serve as edible vaccines,
offering a low-cost and easy delivery method for immunizations.\\n\\n6. **Fungi
and Plant Collaborations**: The study of mycorrhizal fungi and their symbiotic
relationships with plants has gained traction. Research indicates that these
fungi enhance nutrient uptake and enhance plant resilience to environmental
stressors, making them pivotal in sustainable agriculture.\\n\\n7. **Biophilic
Design**: The trend of integrating nature into architecture and urban planning
has expanded, with an emphasis on incorporating plants into building designs
to improve air quality, enhance mental well-being, and reduce overall energy
consumption.\\n\\n8. **Deciduous Trees and Urban Cooling**: Research shows that
strategically planted deciduous trees can significantly lower urban temperatures,
reduce energy consumption for cooling, and improve urban biodiversity, highlighting
the importance of green infrastructure.\\n\\n9. **Carnivorous Plant Studies**:
The understanding of carnivorous plants and their unique adaptations has advanced,
with findings suggesting potential applications in pest control and sustainable
agriculture due to their natural predatory methods.\\n\\n10. **Smart Agriculture
Technology**: The integration of IoT and AI in agriculture is revolutionizing
plant cultivation. Farmers now use sensors and data analytics to monitor plant
health in real-time, optimize water usage, and increase crop yields sustainably.\\n\\nThese
insights underline the ongoing research and innovations in the plant science
field that can lead to more sustainable and resilient agricultural practices
while addressing critical global challenges.\",\n \"refusal\": null\n
\ },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n }\n
\ ],\n \"usage\": {\n \"prompt_tokens\": 227,\n \"completion_tokens\":
529,\n \"total_tokens\": 756,\n \"prompt_tokens_details\": {\n \"cached_tokens\":
0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\": {\n
\ \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"system_fingerprint\":
\"fp_0705bf87c0\"\n}\n"
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e58a64f3a306225-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Wed, 20 Nov 2024 13:05:13 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '7289'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149999711'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_250abe3944c3c859e59c2c976b0a1248
http_version: HTTP/1.1
status_code: 200
- request:
body: !!binary |
Cs4CCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSpQIKEgoQY3Jld2FpLnRl
bGVtZXRyeRKOAgoQDrK/EDJCqiT+GyzEBtuJzBIIDx9rCaKAVKMqDFRhc2sgQ3JlYXRlZDABOTCH
rYH4rgkYQdCQroH4rgkYSi4KCGNyZXdfa2V5EiIKIDFmMTI4YmRiN2JhYTRiNjc3MTRmMWRhZWRj
MmYzYWI2SjEKB2NyZXdfaWQSJgokMzNkNTU5NzEtYmZiNi00OTE4LTgzYWQtYmVjMWZhMmM3NDY4
Si4KCHRhc2tfa2V5EiIKIGIxN2IxODhkYmYxNGY5M2E5OGU1Yjk1YWFkMzY3NTc3SjEKB3Rhc2tf
aWQSJgokY2VmYWU3NTUtMzM3Ny00YTc5LWE0YzItNmQwOTljOTRiZGViegIYAYUBAAEAAA==
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '337'
Content-Type:
- application/x-protobuf
User-Agent:
- OTel-OTLP-Exporter-Python/1.27.0
method: POST
uri: https://telemetry.crewai.com:4319/v1/traces
response:
body:
string: "\n\0"
headers:
Content-Length:
- '2'
Content-Type:
- application/x-protobuf
Date:
- Wed, 20 Nov 2024 13:05:19 GMT
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "system", "content": "You are plants Reporting Analyst\n.
You''re a meticulous analyst with a keen eye for detail. You''re known for your
ability to turn complex data into clear and concise reports, making it easy
for others to understand and act on the information you provide.\n\nYour personal
goal is: Create detailed reports based on plants data analysis and research
findings\n\nTo give my best complete final answer to the task use the exact
following format:\n\nThought: I now can give a great answer\nFinal Answer: Your
final answer must be the great and the most complete as possible, it must be
outcome described.\n\nI MUST use these formats, my job depends on it!"}, {"role":
"user", "content": "\nCurrent Task: Review the context you got and expand each
topic into a full section for a report. Make sure the report is detailed and
contains any and all relevant information.\n\n\nThis is the expect criteria
for your final answer: A fully fledge reports with the mains topics, each with
a full section of information. Formatted as markdown without ''```''\n\nyou
MUST return the actual complete content as the final answer, not a summary.\n\nThis
is the context you''re working with:\n1. **Plant-Based Plastics**: 2024 has
seen significant advancements in bioplastics derived from plants such as corn
and sugarcane, which are being used as sustainable alternatives to petroleum-based
plastics. These innovations aim to reduce plastic waste and reliance on fossil
fuels.\n\n2. **Gene Editing Breakthroughs**: CRISPR technology continues to
revolutionize agricultural practices. Researchers have developed genetically
modified crops that are more resistant to pests and diseases, thereby decreasing
the need for chemical pesticides and increasing food security.\n\n3. **Vertical
Farming Expansion**: Urban agriculture has gained momentum with vertical farming
techniques that utilize less water and space. In 2024, cities worldwide are
adopting these innovative systems to meet the growing food demand while reducing
transportation emissions.\n\n4. **Climate-Resilient Plants**: Scientists are
identifying and breeding plant varieties that can withstand extreme weather
conditions such as droughts, floods, and high temperatures, helping farmers
adapt to climate change and ensuring crop yields remain stable.\n\n5. **Edible
Vaccines in Plants**: Research into producing vaccines in plants has progressed,
with trials showing that certain plants can be engineered to express antigens
that could serve as edible vaccines, offering a low-cost and easy delivery method
for immunizations.\n\n6. **Fungi and Plant Collaborations**: The study of mycorrhizal
fungi and their symbiotic relationships with plants has gained traction. Research
indicates that these fungi enhance nutrient uptake and enhance plant resilience
to environmental stressors, making them pivotal in sustainable agriculture.\n\n7.
**Biophilic Design**: The trend of integrating nature into architecture and
urban planning has expanded, with an emphasis on incorporating plants into building
designs to improve air quality, enhance mental well-being, and reduce overall
energy consumption.\n\n8. **Deciduous Trees and Urban Cooling**: Research shows
that strategically planted deciduous trees can significantly lower urban temperatures,
reduce energy consumption for cooling, and improve urban biodiversity, highlighting
the importance of green infrastructure.\n\n9. **Carnivorous Plant Studies**:
The understanding of carnivorous plants and their unique adaptations has advanced,
with findings suggesting potential applications in pest control and sustainable
agriculture due to their natural predatory methods.\n\n10. **Smart Agriculture
Technology**: The integration of IoT and AI in agriculture is revolutionizing
plant cultivation. Farmers now use sensors and data analytics to monitor plant
health in real-time, optimize water usage, and increase crop yields sustainably.\n\nThese
insights underline the ongoing research and innovations in the plant science
field that can lead to more sustainable and resilient agricultural practices
while addressing critical global challenges.\n\nBegin! This is VERY important
to you, use the tools available and give your best Final Answer, your job depends
on it!\n\nThought:"}], "model": "gpt-4o-mini", "stop": ["\nObservation:"], "stream":
false}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '4383'
content-type:
- application/json
cookie:
- __cf_bm=CkK4UvBd9ukXvn50uJwGambJcz5zERAJfeXJ9xge6H4-1732107842-1.0.1.1-IOK2yVL3RlD75MgmnKzIEyE38HNknwn6I8BBJ1wjGz4jCTd0YWIBPnvUm9gB8D_zLlUA9G7p_wbrfyc4mO_Bmg;
_cfuvid=MmeN9oHWrBLThkEJdaSFHBfWe95JvA8iFnnt7CC92tk-1732107842102-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.52.1
x-stainless-arch:
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.52.1
x-stainless-raw-response:
- 'true'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
content: "{\n \"id\": \"chatcmpl-AVegMn5Ai2jlIz10QbT0vQQ6TPvD0\",\n \"object\":
\"chat.completion\",\n \"created\": 1732107914,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n
\ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\":
\"assistant\",\n \"content\": \"I now can give a great answer \\nFinal
Answer: \\n\\n# Comprehensive Report on Advancements in Plant Science (2024)\\n\\n##
1. Plant-Based Plastics\\n2024 has witnessed remarkable progress in the development
of plant-based plastics, particularly those derived from renewable resources
such as corn and sugarcane. Unlike traditional petroleum-based plastics, these
bioplastics are designed to be more environmentally friendly, addressing pressing
concerns regarding plastic waste and the continuous reliance on fossil fuels.
The production processes have been optimized to ensure lower carbon footprints
and reduced greenhouse gas emissions. Moreover, major manufacturers are beginning
to scale up production of these materials, integrating them into a wide array
of products, from packaging to consumer goods, thereby offering sustainable
alternatives and contributing positively to circular economy initiatives.\\n\\n##
2. Gene Editing Breakthroughs\\nThe introduction of CRISPR technology has emerged
as a game-changer in agricultural methodologies. In 2024, cutting-edge research
has led to the development of genetically modified crops that exhibit enhanced
resistance to pests and diseases. This advancement not only supports increased
food production but also significantly reduces dependency on chemical pesticides,
which can have detrimental effects on both environmental health and biodiversity.
By facilitating the creation of hardier crops, these innovations play a crucial
role in bolstering food security, enabling farmers to achieve higher yields
even under challenging agricultural conditions.\\n\\n## 3. Vertical Farming
Expansion\\nVertical farming techniques have surged in popularity as urban agriculture
continues to evolve in 2024. These innovative systems are engineered to optimize
space and resource usage, utilizing cutting-edge hydroponic and aeroponic methods
to grow food in controlled environments. Cities around the globe are implementing
vertical farms to tackle the increasing demand for fresh produce while simultaneously
minimizing transportation emissions and enhancing food security in urban settings.
By using significantly less water and land compared to traditional farming,
vertical farming represents a sustainable solution to urban food production
challenges in the face of rapid urbanization.\\n\\n## 4. Climate-Resilient Plants\\nIn
response to the unpredictable impacts of climate change, researchers are focused
on identifying and breeding plant varieties capable of enduring extreme weather
conditions, such as droughts, floods, and extreme temperatures. This initiative
aims to empower farmers with viable options to adapt to shifting climate patterns,
ensuring stable crop yields despite adverse environmental conditions. The development
of these climate-resilient plants is vital for maintaining food supply chains
and safeguarding agricultural biodiversity, ultimately contributing to the long-term
sustainability of farming practices.\\n\\n## 5. Edible Vaccines in Plants\\nInnovative
research in the area of edible vaccines is making significant strides in 2024.
Scientists are exploring the potential of genetically engineered plants to express
specific antigens that can serve as immunizations. These advancements hold promising
implications for public health, particularly in developing regions where traditional
vaccine delivery systems may be less feasible. Edible vaccines offer a cost-effective,
accessible, and non-invasive way to promote immunity against various diseases,
highlighting the intersection of agriculture and health science in addressing
global health challenges.\\n\\n## 6. Fungi and Plant Collaborations\\nThe symbiotic
relationships between mycorrhizal fungi and plants have gained increasing attention
in research circles. Studies conducted in 2024 reveal that these fungi enhance
nutrient uptake, improve soil health, and bolster plant resilience when faced
with environmental stressors, such as drought and soil degradation. The incorporation
of these beneficial fungi into sustainable agricultural practices not only promotes
plant health but also contributes to organic farming resiliency, highlighting
the importance of understanding and utilizing biological partnerships in cultivating
healthy crops.\\n\\n## 7. Biophilic Design\\nThe concept of biophilic design
continues to gain traction in architecture and urban planning throughout 2024,
underscoring the importance of integrating nature into built environments. This
approach encourages the incorporation of plants and green spaces into architectural
designs, enhancing air quality and promoting mental well-being. By reducing
reliance on artificial heating and cooling systems, biophilic design offers
opportunities to lower overall energy consumption. As cities recognize the benefits
of urban greenery, significant investments are being made to create healthier,
more sustainable urban ecosystems.\\n\\n## 8. Deciduous Trees and Urban Cooling\\nResearch
conducted this year has demonstrated that strategic planting of deciduous trees
in urban areas can lead to significant temperature reductions. These trees act
as natural air conditioners by providing shade and releasing moisture. The benefits
extend beyond cooling cities\u2014for instance, they contribute to lower energy
consumption for air conditioning, enhance local biodiversity, and improve overall
urban livability. Understanding the role of green infrastructure in combating
urban heat islands is essential for developing climate-responsive cities.\\n\\n##
9. Carnivorous Plant Studies\\nRecent advancements in the study of carnivorous
plants reveal exciting potential applications in sustainable pest control and
agriculture. By understanding their unique adaptations and natural predatory
methods, researchers envision the use of these plants as biological pest management
tools in crop production. In 2024, interest in harnessing the ecological roles
of these plants may lead to more sustainable farming practices, alleviating
the need for chemical pesticides and promoting healthier ecosystems.\\n\\n##
10. Smart Agriculture Technology\\nThe integration of Internet of Things (IoT)
and Artificial Intelligence (AI) into agriculture has transformed how farming
is conducted in 2024. Smart agriculture technologies enable farmers to monitor
plant health, soil conditions, and microclimates through advanced sensors and
data analytics. This real-time data helps optimize water usage, elevate crop
yields, and foster sustainable farming practices. As farmers harness these technological
advancements, the sector moves toward a more efficient and environmentally conscious
model of production.\\n\\nIn conclusion, these insights reflect ongoing research
and innovation in the field of plant science, laying the groundwork for more
sustainable and resilient agricultural practices. As the world faces critical
global challenges, these advancements illustrate the potential to leverage plant
science in creating solutions that address both environmental concerns and food
security.\",\n \"refusal\": null\n },\n \"logprobs\": null,\n
\ \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\":
777,\n \"completion_tokens\": 1163,\n \"total_tokens\": 1940,\n \"prompt_tokens_details\":
{\n \"cached_tokens\": 0,\n \"audio_tokens\": 0\n },\n \"completion_tokens_details\":
{\n \"reasoning_tokens\": 0,\n \"audio_tokens\": 0,\n \"accepted_prediction_tokens\":
0,\n \"rejected_prediction_tokens\": 0\n }\n },\n \"system_fingerprint\":
\"fp_0705bf87c0\"\n}\n"
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8e58a67f18856225-GRU
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Wed, 20 Nov 2024 13:05:35 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '20960'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '30000'
x-ratelimit-limit-tokens:
- '150000000'
x-ratelimit-remaining-requests:
- '29999'
x-ratelimit-remaining-tokens:
- '149998934'
x-ratelimit-reset-requests:
- 2ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_1a11ba8b9c0cb1803e99cd95fa1fb890
http_version: HTTP/1.1
status_code: 200
version: 1

21
tests/config/agents.yaml Normal file
View File

@@ -0,0 +1,21 @@
researcher:
role: >
{topic} Senior Data Researcher
goal: >
Uncover cutting-edge developments in {topic}
backstory: >
You're a seasoned researcher with a knack for uncovering the latest
developments in {topic}. Known for your ability to find the most relevant
information and present it in a clear and concise manner.
verbose: true
reporting_analyst:
role: >
{topic} Reporting Analyst
goal: >
Create detailed reports based on {topic} data analysis and research findings
backstory: >
You're a meticulous analyst with a keen eye for detail. You're known for
your ability to turn complex data into clear and concise reports, making
it easy for others to understand and act on the information you provide.
verbose: true

17
tests/config/tasks.yaml Normal file
View File

@@ -0,0 +1,17 @@
research_task:
description: >
Conduct a thorough research about {topic}
Make sure you find any interesting and relevant information given
the current year is 2024.
expected_output: >
A list with 10 bullet points of the most relevant information about {topic}
agent: researcher
reporting_task:
description: >
Review the context you got and expand each topic into a full section for a report.
Make sure the report is detailed and contains any and all relevant information.
expected_output: >
A fully fledge reports with the mains topics, each with a full section of information.
Formatted as markdown without '```'
agent: reporting_analyst

View File

@@ -564,6 +564,7 @@ def test_crew_kickoff_usage_metrics():
assert result.token_usage.prompt_tokens > 0
assert result.token_usage.completion_tokens > 0
assert result.token_usage.successful_requests > 0
assert result.token_usage.cached_prompt_tokens == 0
def test_agents_rpm_is_never_set_if_crew_max_RPM_is_not_set():
@@ -1280,10 +1281,11 @@ def test_agent_usage_metrics_are_captured_for_hierarchical_process():
assert result.raw == "Howdy!"
assert result.token_usage == UsageMetrics(
total_tokens=2626,
prompt_tokens=2482,
completion_tokens=144,
successful_requests=5,
total_tokens=1673,
prompt_tokens=1562,
completion_tokens=111,
successful_requests=3,
cached_prompt_tokens=0
)
@@ -1777,26 +1779,22 @@ def test_crew_train_success(
]
)
crew_training_handler.assert_has_calls(
[
mock.call("training_data.pkl"),
mock.call().load(),
mock.call("trained_agents_data.pkl"),
mock.call().save_trained_data(
agent_id="Researcher",
trained_data=task_evaluator().evaluate_training_data().model_dump(),
),
mock.call("trained_agents_data.pkl"),
mock.call().save_trained_data(
agent_id="Senior Writer",
trained_data=task_evaluator().evaluate_training_data().model_dump(),
),
mock.call(),
mock.call().load(),
mock.call(),
mock.call().load(),
]
)
crew_training_handler.assert_any_call("training_data.pkl")
crew_training_handler().load.assert_called()
crew_training_handler.assert_any_call("trained_agents_data.pkl")
crew_training_handler().load.assert_called()
crew_training_handler().save_trained_data.assert_has_calls([
mock.call(
agent_id="Researcher",
trained_data=task_evaluator().evaluate_training_data().model_dump(),
),
mock.call(
agent_id="Senior Writer",
trained_data=task_evaluator().evaluate_training_data().model_dump(),
)
])
def test_crew_train_error():

264
tests/flow_test.py Normal file
View File

@@ -0,0 +1,264 @@
"""Test Flow creation and execution basic functionality."""
import asyncio
import pytest
from crewai.flow.flow import Flow, and_, listen, or_, router, start
def test_simple_sequential_flow():
"""Test a simple flow with two steps called sequentially."""
execution_order = []
class SimpleFlow(Flow):
@start()
def step_1(self):
execution_order.append("step_1")
@listen(step_1)
def step_2(self):
execution_order.append("step_2")
flow = SimpleFlow()
flow.kickoff()
assert execution_order == ["step_1", "step_2"]
def test_flow_with_multiple_starts():
"""Test a flow with multiple start methods."""
execution_order = []
class MultiStartFlow(Flow):
@start()
def step_a(self):
execution_order.append("step_a")
@start()
def step_b(self):
execution_order.append("step_b")
@listen(step_a)
def step_c(self):
execution_order.append("step_c")
@listen(step_b)
def step_d(self):
execution_order.append("step_d")
flow = MultiStartFlow()
flow.kickoff()
assert "step_a" in execution_order
assert "step_b" in execution_order
assert "step_c" in execution_order
assert "step_d" in execution_order
assert execution_order.index("step_c") > execution_order.index("step_a")
assert execution_order.index("step_d") > execution_order.index("step_b")
def test_cyclic_flow():
"""Test a cyclic flow that runs a finite number of iterations."""
execution_order = []
class CyclicFlow(Flow):
iteration = 0
max_iterations = 3
@start("loop")
def step_1(self):
if self.iteration >= self.max_iterations:
return # Do not proceed further
execution_order.append(f"step_1_{self.iteration}")
@listen(step_1)
def step_2(self):
execution_order.append(f"step_2_{self.iteration}")
@router(step_2)
def step_3(self):
execution_order.append(f"step_3_{self.iteration}")
self.iteration += 1
if self.iteration < self.max_iterations:
return "loop"
return "exit"
flow = CyclicFlow()
flow.kickoff()
expected_order = []
for i in range(flow.max_iterations):
expected_order.extend([f"step_1_{i}", f"step_2_{i}", f"step_3_{i}"])
assert execution_order == expected_order
def test_flow_with_and_condition():
"""Test a flow where a step waits for multiple other steps to complete."""
execution_order = []
class AndConditionFlow(Flow):
@start()
def step_1(self):
execution_order.append("step_1")
@start()
def step_2(self):
execution_order.append("step_2")
@listen(and_(step_1, step_2))
def step_3(self):
execution_order.append("step_3")
flow = AndConditionFlow()
flow.kickoff()
assert "step_1" in execution_order
assert "step_2" in execution_order
assert execution_order[-1] == "step_3"
assert execution_order.index("step_3") > execution_order.index("step_1")
assert execution_order.index("step_3") > execution_order.index("step_2")
def test_flow_with_or_condition():
"""Test a flow where a step is triggered when any of multiple steps complete."""
execution_order = []
class OrConditionFlow(Flow):
@start()
def step_a(self):
execution_order.append("step_a")
@start()
def step_b(self):
execution_order.append("step_b")
@listen(or_(step_a, step_b))
def step_c(self):
execution_order.append("step_c")
flow = OrConditionFlow()
flow.kickoff()
assert "step_a" in execution_order or "step_b" in execution_order
assert "step_c" in execution_order
assert execution_order.index("step_c") > min(
execution_order.index("step_a"), execution_order.index("step_b")
)
def test_flow_with_router():
"""Test a flow that uses a router method to determine the next step."""
execution_order = []
class RouterFlow(Flow):
@start()
def start_method(self):
execution_order.append("start_method")
@router(start_method)
def router(self):
execution_order.append("router")
# Ensure the condition is set to True to follow the "step_if_true" path
condition = True
return "step_if_true" if condition else "step_if_false"
@listen("step_if_true")
def truthy(self):
execution_order.append("step_if_true")
@listen("step_if_false")
def falsy(self):
execution_order.append("step_if_false")
flow = RouterFlow()
flow.kickoff()
assert execution_order == ["start_method", "router", "step_if_true"]
def test_async_flow():
"""Test an asynchronous flow."""
execution_order = []
class AsyncFlow(Flow):
@start()
async def step_1(self):
execution_order.append("step_1")
await asyncio.sleep(0.1)
@listen(step_1)
async def step_2(self):
execution_order.append("step_2")
await asyncio.sleep(0.1)
flow = AsyncFlow()
asyncio.run(flow.kickoff_async())
assert execution_order == ["step_1", "step_2"]
def test_flow_with_exceptions():
"""Test flow behavior when exceptions occur in steps."""
execution_order = []
class ExceptionFlow(Flow):
@start()
def step_1(self):
execution_order.append("step_1")
raise ValueError("An error occurred in step_1")
@listen(step_1)
def step_2(self):
execution_order.append("step_2")
flow = ExceptionFlow()
with pytest.raises(ValueError):
flow.kickoff()
# Ensure step_2 did not execute
assert execution_order == ["step_1"]
def test_flow_restart():
"""Test restarting a flow after it has completed."""
execution_order = []
class RestartableFlow(Flow):
@start()
def step_1(self):
execution_order.append("step_1")
@listen(step_1)
def step_2(self):
execution_order.append("step_2")
flow = RestartableFlow()
flow.kickoff()
flow.kickoff() # Restart the flow
assert execution_order == ["step_1", "step_2", "step_1", "step_2"]
def test_flow_with_custom_state():
"""Test a flow that maintains and modifies internal state."""
class StateFlow(Flow):
def __init__(self):
super().__init__()
self.counter = 0
@start()
def step_1(self):
self.counter += 1
@listen(step_1)
def step_2(self):
self.counter *= 2
assert self.counter == 2
flow = StateFlow()
flow.kickoff()
assert flow.counter == 2

View File

Binary file not shown.

View File

@@ -0,0 +1,545 @@
"""Test Knowledge creation and querying functionality."""
from pathlib import Path
from unittest.mock import patch
from crewai.knowledge.source.csv_knowledge_source import CSVKnowledgeSource
from crewai.knowledge.source.excel_knowledge_source import ExcelKnowledgeSource
from crewai.knowledge.source.json_knowledge_source import JSONKnowledgeSource
from crewai.knowledge.source.pdf_knowledge_source import PDFKnowledgeSource
from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource
from crewai.knowledge.source.text_file_knowledge_source import TextFileKnowledgeSource
import pytest
@pytest.fixture(autouse=True)
def mock_vector_db():
"""Mock vector database operations."""
with patch("crewai.knowledge.storage.knowledge_storage.KnowledgeStorage") as mock:
# Mock the query method to return a predefined response
instance = mock.return_value
instance.query.return_value = [
{
"context": "Brandon's favorite color is blue and he likes Mexican food.",
"score": 0.9,
}
]
instance.reset.return_value = None
yield instance
@pytest.fixture(autouse=True)
def reset_knowledge_storage(mock_vector_db):
"""Fixture to reset knowledge storage before each test."""
yield
def test_single_short_string(mock_vector_db):
# Create a knowledge base with a single short string
content = "Brandon's favorite color is blue and he likes Mexican food."
string_source = StringKnowledgeSource(
content=content, metadata={"preference": "personal"}
)
mock_vector_db.sources = [string_source]
mock_vector_db.query.return_value = [{"context": content, "score": 0.9}]
# Perform a query
query = "What is Brandon's favorite color?"
results = mock_vector_db.query(query)
# Assert that the results contain the expected information
assert any("blue" in result["context"].lower() for result in results)
# Verify the mock was called
mock_vector_db.query.assert_called_once()
# @pytest.mark.vcr(filter_headers=["authorization"])
def test_single_2k_character_string(mock_vector_db):
# Create a 2k character string with various facts about Brandon
content = (
"Brandon is a software engineer who lives in San Francisco. "
"He enjoys hiking and often visits the trails in the Bay Area. "
"Brandon has a pet dog named Max, who is a golden retriever. "
"He loves reading science fiction books, and his favorite author is Isaac Asimov. "
"Brandon's favorite movie is Inception, and he enjoys watching it with his friends. "
"He is also a fan of Mexican cuisine, especially tacos and burritos. "
"Brandon plays the guitar and often performs at local open mic nights. "
"He is learning French and plans to visit Paris next year. "
"Brandon is passionate about technology and often attends tech meetups in the city. "
"He is also interested in AI and machine learning, and he is currently working on a project related to natural language processing. "
"Brandon's favorite color is blue, and he often wears blue shirts. "
"He enjoys cooking and often tries new recipes on weekends. "
"Brandon is a morning person and likes to start his day with a run in the park. "
"He is also a coffee enthusiast and enjoys trying different coffee blends. "
"Brandon is a member of a local book club and enjoys discussing books with fellow members. "
"He is also a fan of board games and often hosts game nights at his place. "
"Brandon is an advocate for environmental conservation and volunteers for local clean-up drives. "
"He is also a mentor for aspiring software developers and enjoys sharing his knowledge with others. "
"Brandon's favorite sport is basketball, and he often plays with his friends on weekends. "
"He is also a fan of the Golden State Warriors and enjoys watching their games. "
)
string_source = StringKnowledgeSource(
content=content, metadata={"preference": "personal"}
)
mock_vector_db.sources = [string_source]
mock_vector_db.query.return_value = [{"context": content, "score": 0.9}]
# Perform a query
query = "What is Brandon's favorite movie?"
results = mock_vector_db.query(query)
# Assert that the results contain the expected information
assert any("inception" in result["context"].lower() for result in results)
mock_vector_db.query.assert_called_once()
def test_multiple_short_strings(mock_vector_db):
# Create multiple short string sources
contents = [
"Brandon loves hiking.",
"Brandon has a dog named Max.",
"Brandon enjoys painting landscapes.",
]
string_sources = [
StringKnowledgeSource(content=content, metadata={"preference": "personal"})
for content in contents
]
# Mock the vector db query response
mock_vector_db.query.return_value = [
{"context": "Brandon has a dog named Max.", "score": 0.9}
]
mock_vector_db.sources = string_sources
# Perform a query
query = "What is the name of Brandon's pet?"
results = mock_vector_db.query(query)
# Assert that the correct information is retrieved
assert any("max" in result["context"].lower() for result in results)
# Verify the mock was called
mock_vector_db.query.assert_called_once()
def test_multiple_2k_character_strings(mock_vector_db):
# Create multiple 2k character strings with various facts about Brandon
contents = [
(
"Brandon is a software engineer who lives in San Francisco. "
"He enjoys hiking and often visits the trails in the Bay Area. "
"Brandon has a pet dog named Max, who is a golden retriever. "
"He loves reading science fiction books, and his favorite author is Isaac Asimov. "
"Brandon's favorite movie is Inception, and he enjoys watching it with his friends. "
"He is also a fan of Mexican cuisine, especially tacos and burritos. "
"Brandon plays the guitar and often performs at local open mic nights. "
"He is learning French and plans to visit Paris next year. "
"Brandon is passionate about technology and often attends tech meetups in the city. "
"He is also interested in AI and machine learning, and he is currently working on a project related to natural language processing. "
"Brandon's favorite color is blue, and he often wears blue shirts. "
"He enjoys cooking and often tries new recipes on weekends. "
"Brandon is a morning person and likes to start his day with a run in the park. "
"He is also a coffee enthusiast and enjoys trying different coffee blends. "
"Brandon is a member of a local book club and enjoys discussing books with fellow members. "
"He is also a fan of board games and often hosts game nights at his place. "
"Brandon is an advocate for environmental conservation and volunteers for local clean-up drives. "
"He is also a mentor for aspiring software developers and enjoys sharing his knowledge with others. "
"Brandon's favorite sport is basketball, and he often plays with his friends on weekends. "
"He is also a fan of the Golden State Warriors and enjoys watching their games. "
)
* 2, # Repeat to ensure it's 2k characters
(
"Brandon loves traveling and has visited over 20 countries. "
"He is fluent in Spanish and often practices with his friends. "
"Brandon's favorite city is Barcelona, where he enjoys the architecture and culture. "
"He is a foodie and loves trying new cuisines, with a particular fondness for sushi. "
"Brandon is an avid cyclist and participates in local cycling events. "
"He is also a photographer and enjoys capturing landscapes and cityscapes. "
"Brandon is a tech enthusiast and follows the latest trends in gadgets and software. "
"He is also a fan of virtual reality and owns a VR headset. "
"Brandon's favorite book is 'The Hitchhiker's Guide to the Galaxy'. "
"He enjoys watching documentaries and learning about history and science. "
"Brandon is a coffee lover and has a collection of coffee mugs from different countries. "
"He is also a fan of jazz music and often attends live performances. "
"Brandon is a member of a local running club and participates in marathons. "
"He is also a volunteer at a local animal shelter and helps with dog walking. "
"Brandon's favorite holiday is Christmas, and he enjoys decorating his home. "
"He is also a fan of classic movies and has a collection of DVDs. "
"Brandon is a mentor for young professionals and enjoys giving career advice. "
"He is also a fan of puzzles and enjoys solving them in his free time. "
"Brandon's favorite sport is soccer, and he often plays with his friends. "
"He is also a fan of FC Barcelona and enjoys watching their matches. "
)
* 2, # Repeat to ensure it's 2k characters
]
string_sources = [
StringKnowledgeSource(content=content, metadata={"preference": "personal"})
for content in contents
]
mock_vector_db.sources = string_sources
mock_vector_db.query.return_value = [{"context": contents[1], "score": 0.9}]
# Perform a query
query = "What is Brandon's favorite book?"
results = mock_vector_db.query(query)
# Assert that the correct information is retrieved
assert any(
"the hitchhiker's guide to the galaxy" in result["context"].lower()
for result in results
)
mock_vector_db.query.assert_called_once()
def test_single_short_file(mock_vector_db, tmpdir):
# Create a single short text file
content = "Brandon's favorite sport is basketball."
file_path = Path(tmpdir.join("short_file.txt"))
with open(file_path, "w") as f:
f.write(content)
file_source = TextFileKnowledgeSource(
file_path=file_path, metadata={"preference": "personal"}
)
mock_vector_db.sources = [file_source]
mock_vector_db.query.return_value = [{"context": content, "score": 0.9}]
# Perform a query
query = "What sport does Brandon like?"
results = mock_vector_db.query(query)
# Assert that the results contain the expected information
assert any("basketball" in result["context"].lower() for result in results)
mock_vector_db.query.assert_called_once()
def test_single_2k_character_file(mock_vector_db, tmpdir):
# Create a single 2k character text file with various facts about Brandon
content = (
"Brandon is a software engineer who lives in San Francisco. "
"He enjoys hiking and often visits the trails in the Bay Area. "
"Brandon has a pet dog named Max, who is a golden retriever. "
"He loves reading science fiction books, and his favorite author is Isaac Asimov. "
"Brandon's favorite movie is Inception, and he enjoys watching it with his friends. "
"He is also a fan of Mexican cuisine, especially tacos and burritos. "
"Brandon plays the guitar and often performs at local open mic nights. "
"He is learning French and plans to visit Paris next year. "
"Brandon is passionate about technology and often attends tech meetups in the city. "
"He is also interested in AI and machine learning, and he is currently working on a project related to natural language processing. "
"Brandon's favorite color is blue, and he often wears blue shirts. "
"He enjoys cooking and often tries new recipes on weekends. "
"Brandon is a morning person and likes to start his day with a run in the park. "
"He is also a coffee enthusiast and enjoys trying different coffee blends. "
"Brandon is a member of a local book club and enjoys discussing books with fellow members. "
"He is also a fan of board games and often hosts game nights at his place. "
"Brandon is an advocate for environmental conservation and volunteers for local clean-up drives. "
"He is also a mentor for aspiring software developers and enjoys sharing his knowledge with others. "
"Brandon's favorite sport is basketball, and he often plays with his friends on weekends. "
"He is also a fan of the Golden State Warriors and enjoys watching their games. "
) * 2 # Repeat to ensure it's 2k characters
file_path = Path(tmpdir.join("long_file.txt"))
with open(file_path, "w") as f:
f.write(content)
file_source = TextFileKnowledgeSource(
file_path=file_path, metadata={"preference": "personal"}
)
mock_vector_db.sources = [file_source]
mock_vector_db.query.return_value = [{"context": content, "score": 0.9}]
# Perform a query
query = "What is Brandon's favorite movie?"
results = mock_vector_db.query(query)
# Assert that the results contain the expected information
assert any("inception" in result["context"].lower() for result in results)
mock_vector_db.query.assert_called_once()
def test_multiple_short_files(mock_vector_db, tmpdir):
# Create multiple short text files
contents = [
{
"content": "Brandon works as a software engineer.",
"metadata": {"category": "profession", "source": "occupation"},
},
{
"content": "Brandon lives in New York.",
"metadata": {"category": "city", "source": "personal"},
},
{
"content": "Brandon enjoys cooking Italian food.",
"metadata": {"category": "hobby", "source": "personal"},
},
]
file_paths = []
for i, item in enumerate(contents):
file_path = Path(tmpdir.join(f"file_{i}.txt"))
with open(file_path, "w") as f:
f.write(item["content"])
file_paths.append((file_path, item["metadata"]))
file_sources = [
TextFileKnowledgeSource(file_path=path, metadata=metadata)
for path, metadata in file_paths
]
mock_vector_db.sources = file_sources
mock_vector_db.query.return_value = [
{"context": "Brandon lives in New York.", "score": 0.9}
]
# Perform a query
query = "What city does he reside in?"
results = mock_vector_db.query(query)
# Assert that the correct information is retrieved
assert any("new york" in result["context"].lower() for result in results)
mock_vector_db.query.assert_called_once()
def test_multiple_2k_character_files(mock_vector_db, tmpdir):
# Create multiple 2k character text files with various facts about Brandon
contents = [
(
"Brandon loves traveling and has visited over 20 countries. "
"He is fluent in Spanish and often practices with his friends. "
"Brandon's favorite city is Barcelona, where he enjoys the architecture and culture. "
"He is a foodie and loves trying new cuisines, with a particular fondness for sushi. "
"Brandon is an avid cyclist and participates in local cycling events. "
"He is also a photographer and enjoys capturing landscapes and cityscapes. "
"Brandon is a tech enthusiast and follows the latest trends in gadgets and software. "
"He is also a fan of virtual reality and owns a VR headset. "
"Brandon's favorite book is 'The Hitchhiker's Guide to the Galaxy'. "
"He enjoys watching documentaries and learning about history and science. "
"Brandon is a coffee lover and has a collection of coffee mugs from different countries. "
"He is also a fan of jazz music and often attends live performances. "
"Brandon is a member of a local running club and participates in marathons. "
"He is also a volunteer at a local animal shelter and helps with dog walking. "
"Brandon's favorite holiday is Christmas, and he enjoys decorating his home. "
"He is also a fan of classic movies and has a collection of DVDs. "
"Brandon is a mentor for young professionals and enjoys giving career advice. "
"He is also a fan of puzzles and enjoys solving them in his free time. "
"Brandon's favorite sport is soccer, and he often plays with his friends. "
"He is also a fan of FC Barcelona and enjoys watching their matches. "
)
* 2, # Repeat to ensure it's 2k characters
(
"Brandon is a software engineer who lives in San Francisco. "
"He enjoys hiking and often visits the trails in the Bay Area. "
"Brandon has a pet dog named Max, who is a golden retriever. "
"He loves reading science fiction books, and his favorite author is Isaac Asimov. "
"Brandon's favorite movie is Inception, and he enjoys watching it with his friends. "
"He is also a fan of Mexican cuisine, especially tacos and burritos. "
"Brandon plays the guitar and often performs at local open mic nights. "
"He is learning French and plans to visit Paris next year. "
"Brandon is passionate about technology and often attends tech meetups in the city. "
"He is also interested in AI and machine learning, and he is currently working on a project related to natural language processing. "
"Brandon's favorite color is blue, and he often wears blue shirts. "
"He enjoys cooking and often tries new recipes on weekends. "
"Brandon is a morning person and likes to start his day with a run in the park. "
"He is also a coffee enthusiast and enjoys trying different coffee blends. "
"Brandon is a member of a local book club and enjoys discussing books with fellow members. "
"He is also a fan of board games and often hosts game nights at his place. "
"Brandon is an advocate for environmental conservation and volunteers for local clean-up drives. "
"He is also a mentor for aspiring software developers and enjoys sharing his knowledge with others. "
"Brandon's favorite sport is basketball, and he often plays with his friends on weekends. "
"He is also a fan of the Golden State Warriors and enjoys watching their games. "
)
* 2, # Repeat to ensure it's 2k characters
]
file_paths = []
for i, content in enumerate(contents):
file_path = Path(tmpdir.join(f"long_file_{i}.txt"))
with open(file_path, "w") as f:
f.write(content)
file_paths.append(file_path)
file_sources = [
TextFileKnowledgeSource(file_path=path, metadata={"preference": "personal"})
for path in file_paths
]
mock_vector_db.sources = file_sources
mock_vector_db.query.return_value = [
{
"context": "Brandon's favorite book is 'The Hitchhiker's Guide to the Galaxy'.",
"score": 0.9,
}
]
# Perform a query
query = "What is Brandon's favorite book?"
results = mock_vector_db.query(query)
# Assert that the correct information is retrieved
assert any(
"the hitchhiker's guide to the galaxy" in result["context"].lower()
for result in results
)
mock_vector_db.query.assert_called_once()
@pytest.mark.vcr(filter_headers=["authorization"])
def test_hybrid_string_and_files(mock_vector_db, tmpdir):
# Create string sources
string_contents = [
"Brandon is learning French.",
"Brandon visited Paris last summer.",
]
string_sources = [
StringKnowledgeSource(content=content, metadata={"preference": "personal"})
for content in string_contents
]
# Create file sources
file_contents = [
"Brandon prefers tea over coffee.",
"Brandon's favorite book is 'The Alchemist'.",
]
file_paths = []
for i, content in enumerate(file_contents):
file_path = Path(tmpdir.join(f"file_{i}.txt"))
with open(file_path, "w") as f:
f.write(content)
file_paths.append(file_path)
file_sources = [
TextFileKnowledgeSource(file_path=path, metadata={"preference": "personal"})
for path in file_paths
]
# Combine string and file sources
mock_vector_db.sources = string_sources + file_sources
mock_vector_db.query.return_value = [{"context": file_contents[1], "score": 0.9}]
# Perform a query
query = "What is Brandon's favorite book?"
results = mock_vector_db.query(query)
# Assert that the correct information is retrieved
assert any("the alchemist" in result["context"].lower() for result in results)
mock_vector_db.query.assert_called_once()
def test_pdf_knowledge_source(mock_vector_db):
# Get the directory of the current file
current_dir = Path(__file__).parent
# Construct the path to the PDF file
pdf_path = current_dir / "crewai_quickstart.pdf"
# Create a PDFKnowledgeSource
pdf_source = PDFKnowledgeSource(
file_path=pdf_path, metadata={"preference": "personal"}
)
mock_vector_db.sources = [pdf_source]
mock_vector_db.query.return_value = [
{"context": "crewai create crew latest-ai-development", "score": 0.9}
]
# Perform a query
query = "How do you create a crew?"
results = mock_vector_db.query(query)
# Assert that the correct information is retrieved
assert any(
"crewai create crew latest-ai-development" in result["context"].lower()
for result in results
)
mock_vector_db.query.assert_called_once()
@pytest.mark.vcr(filter_headers=["authorization"])
def test_csv_knowledge_source(mock_vector_db, tmpdir):
"""Test CSVKnowledgeSource with a simple CSV file."""
# Create a CSV file with sample data
csv_content = [
["Name", "Age", "City"],
["Brandon", "30", "New York"],
["Alice", "25", "Los Angeles"],
["Bob", "35", "Chicago"],
]
csv_path = Path(tmpdir.join("data.csv"))
with open(csv_path, "w", encoding="utf-8") as f:
for row in csv_content:
f.write(",".join(row) + "\n")
# Create a CSVKnowledgeSource
csv_source = CSVKnowledgeSource(
file_path=csv_path, metadata={"preference": "personal"}
)
mock_vector_db.sources = [csv_source]
mock_vector_db.query.return_value = [
{"context": "Brandon is 30 years old.", "score": 0.9}
]
# Perform a query
query = "How old is Brandon?"
results = mock_vector_db.query(query)
# Assert that the correct information is retrieved
assert any("30" in result["context"] for result in results)
mock_vector_db.query.assert_called_once()
def test_json_knowledge_source(mock_vector_db, tmpdir):
"""Test JSONKnowledgeSource with a simple JSON file."""
# Create a JSON file with sample data
json_data = {
"people": [
{"name": "Brandon", "age": 30, "city": "New York"},
{"name": "Alice", "age": 25, "city": "Los Angeles"},
{"name": "Bob", "age": 35, "city": "Chicago"},
]
}
json_path = Path(tmpdir.join("data.json"))
with open(json_path, "w", encoding="utf-8") as f:
import json
json.dump(json_data, f)
# Create a JSONKnowledgeSource
json_source = JSONKnowledgeSource(
file_path=json_path, metadata={"preference": "personal"}
)
mock_vector_db.sources = [json_source]
mock_vector_db.query.return_value = [
{"context": "Alice lives in Los Angeles.", "score": 0.9}
]
# Perform a query
query = "Where does Alice reside?"
results = mock_vector_db.query(query)
# Assert that the correct information is retrieved
assert any("los angeles" in result["context"].lower() for result in results)
mock_vector_db.query.assert_called_once()
def test_excel_knowledge_source(mock_vector_db, tmpdir):
"""Test ExcelKnowledgeSource with a simple Excel file."""
# Create an Excel file with sample data
import pandas as pd
excel_data = {
"Name": ["Brandon", "Alice", "Bob"],
"Age": [30, 25, 35],
"City": ["New York", "Los Angeles", "Chicago"],
}
df = pd.DataFrame(excel_data)
excel_path = Path(tmpdir.join("data.xlsx"))
df.to_excel(excel_path, index=False)
# Create an ExcelKnowledgeSource
excel_source = ExcelKnowledgeSource(
file_path=excel_path, metadata={"preference": "personal"}
)
mock_vector_db.sources = [excel_source]
mock_vector_db.query.return_value = [
{"context": "Brandon is 30 years old.", "score": 0.9}
]
# Perform a query
query = "What is Brandon's age?"
results = mock_vector_db.query(query)
# Assert that the correct information is retrieved
assert any("30" in result["context"] for result in results)
mock_vector_db.query.assert_called_once()

30
tests/llm_test.py Normal file
View File

@@ -0,0 +1,30 @@
import pytest
from crewai.agents.agent_builder.utilities.base_token_process import TokenProcess
from crewai.llm import LLM
from crewai.utilities.token_counter_callback import TokenCalcHandler
@pytest.mark.vcr(filter_headers=["authorization"])
def test_llm_callback_replacement():
llm = LLM(model="gpt-4o-mini")
calc_handler_1 = TokenCalcHandler(token_cost_process=TokenProcess())
calc_handler_2 = TokenCalcHandler(token_cost_process=TokenProcess())
llm.call(
messages=[{"role": "user", "content": "Hello, world!"}],
callbacks=[calc_handler_1],
)
usage_metrics_1 = calc_handler_1.token_cost_process.get_summary()
llm.call(
messages=[{"role": "user", "content": "Hello, world from another agent!"}],
callbacks=[calc_handler_2],
)
usage_metrics_2 = calc_handler_2.token_cost_process.get_summary()
# The first handler should not have been updated
assert usage_metrics_1.successful_requests == 1
assert usage_metrics_2.successful_requests == 1
assert usage_metrics_1 == calc_handler_1.token_cost_process.get_summary()

View File

@@ -0,0 +1,270 @@
interactions:
- request:
body: ''
headers:
accept:
- '*/*'
accept-encoding:
- gzip, deflate
connection:
- keep-alive
host:
- api.mem0.ai
user-agent:
- python-httpx/0.27.0
method: GET
uri: https://api.mem0.ai/v1/memories/?user_id=test
response:
body:
string: '[]'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8b477138bad847b9-BOM
Connection:
- keep-alive
Content-Length:
- '2'
Content-Type:
- application/json
Date:
- Sat, 17 Aug 2024 06:00:11 GMT
NEL:
- '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}'
Report-To:
- '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=uuyH2foMJVDpV%2FH52g1q%2FnvXKe3dBKVzvsK0mqmSNezkiszNR9OgrEJfVqmkX%2FlPFRP2sH4zrOuzGo6k%2FjzsjYJczqSWJUZHN2pPujiwnr1E9W%2BdLGKmG6%2FqPrGYAy2SBRWkkJVWsTO3OQ%3D%3D"}],"group":"cf-nel","max_age":604800}'
Server:
- cloudflare
allow:
- GET, POST, DELETE, OPTIONS
alt-svc:
- h3=":443"; ma=86400
cross-origin-opener-policy:
- same-origin
referrer-policy:
- same-origin
vary:
- Accept, origin, Cookie
x-content-type-options:
- nosniff
x-frame-options:
- DENY
status:
code: 200
message: OK
- request:
body: '{"batch": [{"properties": {"python_version": "3.12.4 (v3.12.4:8e8a4baf65,
Jun 6 2024, 17:33:18) [Clang 13.0.0 (clang-1300.0.29.30)]", "os": "darwin",
"os_version": "Darwin Kernel Version 23.4.0: Wed Feb 21 21:44:54 PST 2024; root:xnu-10063.101.15~2/RELEASE_ARM64_T6030",
"os_release": "23.4.0", "processor": "arm", "machine": "arm64", "function":
"mem0.client.main.MemoryClient", "$lib": "posthog-python", "$lib_version": "3.5.0",
"$geoip_disable": true}, "timestamp": "2024-08-17T06:00:11.526640+00:00", "context":
{}, "distinct_id": "fd411bd3-99a2-42d6-acd7-9fca8ad09580", "event": "client.init"}],
"historical_migration": false, "sentAt": "2024-08-17T06:00:11.701621+00:00",
"api_key": "phc_hgJkUVJFYtmaJqrvf6CYN67TIQ8yhXAkWzUn9AMU4yX"}'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '740'
Content-Type:
- application/json
User-Agent:
- posthog-python/3.5.0
method: POST
uri: https://us.i.posthog.com/batch/
response:
body:
string: '{"status":"Ok"}'
headers:
Connection:
- keep-alive
Content-Length:
- '15'
Content-Type:
- application/json
Date:
- Sat, 17 Aug 2024 06:00:12 GMT
access-control-allow-credentials:
- 'true'
server:
- envoy
vary:
- origin, access-control-request-method, access-control-request-headers
x-envoy-upstream-service-time:
- '69'
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "user", "content": "Remember the following insights
from Agent run: test value with provider"}], "metadata": {"task": "test_task_provider",
"agent": "test_agent_provider"}, "app_id": "Researcher"}'
headers:
accept:
- '*/*'
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '219'
content-type:
- application/json
host:
- api.mem0.ai
user-agent:
- python-httpx/0.27.0
method: POST
uri: https://api.mem0.ai/v1/memories/
response:
body:
string: '{"message":"ok"}'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8b477140282547b9-BOM
Connection:
- keep-alive
Content-Length:
- '16'
Content-Type:
- application/json
Date:
- Sat, 17 Aug 2024 06:00:13 GMT
NEL:
- '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}'
Report-To:
- '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=FRjJKSk3YxVj03wA7S05H8ts35KnWfqS3wb6Rfy4kVZ4BgXfw7nJbm92wI6vEv5fWcAcHVnOlkJDggs11B01BMuB2k3a9RqlBi0dJNiMuk%2Bgm5xE%2BODMPWJctYNRwQMjNVbteUpS%2Fad8YA%3D%3D"}],"group":"cf-nel","max_age":604800}'
Server:
- cloudflare
allow:
- GET, POST, DELETE, OPTIONS
alt-svc:
- h3=":443"; ma=86400
cross-origin-opener-policy:
- same-origin
referrer-policy:
- same-origin
vary:
- Accept, origin, Cookie
x-content-type-options:
- nosniff
x-frame-options:
- DENY
status:
code: 200
message: OK
- request:
body: '{"query": "test value with provider", "limit": 3, "app_id": "Researcher"}'
headers:
accept:
- '*/*'
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '73'
content-type:
- application/json
host:
- api.mem0.ai
user-agent:
- python-httpx/0.27.0
method: POST
uri: https://api.mem0.ai/v1/memories/search/
response:
body:
string: '[]'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8b47714d083b47b9-BOM
Connection:
- keep-alive
Content-Length:
- '2'
Content-Type:
- application/json
Date:
- Sat, 17 Aug 2024 06:00:14 GMT
NEL:
- '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}'
Report-To:
- '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=2DRWL1cdKdMvnE8vx1fPUGeTITOgSGl3N5g84PS6w30GRqpfz79BtSx6REhpnOiFV8kM6KGqln0iCZ5yoHc2jBVVJXhPJhQ5t0uerD9JFnkphjISrJOU1MJjZWneT9PlNABddxvVNCmluA%3D%3D"}],"group":"cf-nel","max_age":604800}'
Server:
- cloudflare
allow:
- POST, OPTIONS
alt-svc:
- h3=":443"; ma=86400
cross-origin-opener-policy:
- same-origin
referrer-policy:
- same-origin
vary:
- Accept, origin, Cookie
x-content-type-options:
- nosniff
x-frame-options:
- DENY
status:
code: 200
message: OK
- request:
body: '{"batch": [{"properties": {"python_version": "3.12.4 (v3.12.4:8e8a4baf65,
Jun 6 2024, 17:33:18) [Clang 13.0.0 (clang-1300.0.29.30)]", "os": "darwin",
"os_version": "Darwin Kernel Version 23.4.0: Wed Feb 21 21:44:54 PST 2024; root:xnu-10063.101.15~2/RELEASE_ARM64_T6030",
"os_release": "23.4.0", "processor": "arm", "machine": "arm64", "function":
"mem0.client.main.MemoryClient", "$lib": "posthog-python", "$lib_version": "3.5.0",
"$geoip_disable": true}, "timestamp": "2024-08-17T06:00:13.593952+00:00", "context":
{}, "distinct_id": "fd411bd3-99a2-42d6-acd7-9fca8ad09580", "event": "client.add"}],
"historical_migration": false, "sentAt": "2024-08-17T06:00:13.858277+00:00",
"api_key": "phc_hgJkUVJFYtmaJqrvf6CYN67TIQ8yhXAkWzUn9AMU4yX"}'
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '739'
Content-Type:
- application/json
User-Agent:
- posthog-python/3.5.0
method: POST
uri: https://us.i.posthog.com/batch/
response:
body:
string: '{"status":"Ok"}'
headers:
Connection:
- keep-alive
Content-Length:
- '15'
Content-Type:
- application/json
Date:
- Sat, 17 Aug 2024 06:00:13 GMT
access-control-allow-credentials:
- 'true'
server:
- envoy
vary:
- origin, access-control-request-method, access-control-request-headers
x-envoy-upstream-service-time:
- '33'
status:
code: 200
message: OK
version: 1

View File

@@ -38,6 +38,7 @@ def mock_crew_factory():
crew = MockCrew()
crew.name = name
crew.knowledge = None
task_output = TaskOutput(
description="Test task", raw="Task output", agent="Test Agent"
@@ -67,6 +68,7 @@ def mock_crew_factory():
crew.process = Process.sequential
crew.config = None
crew.cache = True
crew.embedder = None
# Add non-empty agents and tasks
mock_agent = MagicMock(spec=Agent)

View File

@@ -1,5 +1,8 @@
import pytest
from crewai.agent import Agent
from crewai.project import agent, task
from crewai.crew import Crew
from crewai.project import CrewBase, after_kickoff, agent, before_kickoff, crew, task
from crewai.task import Task
@@ -23,6 +26,43 @@ class SimpleCrew:
)
@CrewBase
class TestCrew:
agents_config = "config/agents.yaml"
tasks_config = "config/tasks.yaml"
@agent
def researcher(self):
return Agent(config=self.agents_config["researcher"])
@agent
def reporting_analyst(self):
return Agent(config=self.agents_config["reporting_analyst"])
@task
def research_task(self):
return Task(config=self.tasks_config["research_task"])
@task
def reporting_task(self):
return Task(config=self.tasks_config["reporting_task"])
@before_kickoff
def modify_inputs(self, inputs):
if inputs:
inputs["topic"] = "Bicycles"
return inputs
@after_kickoff
def modify_outputs(self, outputs):
outputs.raw = outputs.raw + " post processed"
return outputs
@crew
def crew(self):
return Crew(agents=self.agents, tasks=self.tasks, verbose=True)
def test_agent_memoization():
crew = SimpleCrew()
first_call_result = crew.simple_agent()
@@ -43,6 +83,16 @@ def test_task_memoization():
), "Task memoization is not working as expected"
def test_crew_memoization():
crew = TestCrew()
first_call_result = crew.crew()
second_call_result = crew.crew()
assert (
first_call_result is second_call_result
), "Crew references should point to the same object"
def test_task_name():
simple_task = SimpleCrew().simple_task()
assert (
@@ -53,3 +103,84 @@ def test_task_name():
assert (
custom_named_task.name == "Custom"
), "Custom task name is not being set as expected"
@pytest.mark.vcr(filter_headers=["authorization"])
def test_before_kickoff_modification():
crew = TestCrew()
inputs = {"topic": "LLMs"}
result = crew.crew().kickoff(inputs=inputs)
assert "bicycles" in result.raw, "Before kickoff function did not modify inputs"
@pytest.mark.vcr(filter_headers=["authorization"])
def test_after_kickoff_modification():
crew = TestCrew()
# Assuming the crew execution returns a dict
result = crew.crew().kickoff({"topic": "LLMs"})
assert (
"post processed" in result.raw
), "After kickoff function did not modify outputs"
@pytest.mark.vcr(filter_headers=["authorization"])
def test_before_kickoff_with_none_input():
crew = TestCrew()
crew.crew().kickoff(None)
# Test should pass without raising exceptions
@pytest.mark.vcr(filter_headers=["authorization"])
def test_multiple_before_after_kickoff():
@CrewBase
class MultipleHooksCrew:
agents_config = "config/agents.yaml"
tasks_config = "config/tasks.yaml"
@agent
def researcher(self):
return Agent(config=self.agents_config["researcher"])
@agent
def reporting_analyst(self):
return Agent(config=self.agents_config["reporting_analyst"])
@task
def research_task(self):
return Task(config=self.tasks_config["research_task"])
@task
def reporting_task(self):
return Task(config=self.tasks_config["reporting_task"])
@before_kickoff
def first_before(self, inputs):
inputs["topic"] = "Bicycles"
return inputs
@before_kickoff
def second_before(self, inputs):
inputs["topic"] = "plants"
return inputs
@after_kickoff
def first_after(self, outputs):
outputs.raw = outputs.raw + " processed first"
return outputs
@after_kickoff
def second_after(self, outputs):
outputs.raw = outputs.raw + " processed second"
return outputs
@crew
def crew(self):
return Crew(agents=self.agents, tasks=self.tasks, verbose=True)
crew = MultipleHooksCrew()
result = crew.crew().kickoff({"topic": "LLMs"})
assert "plants" in result.raw, "First before_kickoff not executed"
assert "processed first" in result.raw, "First after_kickoff not executed"
assert "processed second" in result.raw, "Second after_kickoff not executed"

Some files were not shown because too many files have changed in this diff Show More