Compare commits

...

14 Commits

Author SHA1 Message Date
Devin AI
97449a5f80 style: Fix import sorting in all files
Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 20:06:44 +00:00
Devin AI
17ff29bc8e style: Fix import sorting
Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 20:04:44 +00:00
Devin AI
b7f5064f31 style: Fix code formatting
- Fix method parameter formatting
- Add trailing commas for consistency

Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 20:03:03 +00:00
Devin AI
c10665c897 refactor: Improve feedback message formatting
- Use i18n for feedback message formatting
- Enhance method documentation
- Improve code organization

Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 20:02:39 +00:00
Devin AI
0fd72fc5d9 refactor: Improve training feedback handling
- Add comprehensive docstrings
- Add error handling for training feedback
- Add proper type hints

Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 20:01:52 +00:00
Devin AI
8195aaedea docs: Enhance method documentation and type hints
- Add comprehensive docstrings
- Improve type hints clarity
- Add missing error documentation

Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 20:01:22 +00:00
Devin AI
3ffe98bf39 refactor: Improve feedback handling documentation and error handling
- Add comprehensive docstrings
- Enhance error handling in LLM feedback response
- Add proper type hints

Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 20:00:56 +00:00
Devin AI
e65a6b523a refactor: Improve feedback handling code quality
- Add type hints and docstrings
- Enhance error handling in feedback processing
- Standardize message formatting

Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 20:00:23 +00:00
Devin AI
d842529b13 chore: Add test cassettes to gitignore
Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 19:55:54 +00:00
Devin AI
a304c9573b feat: Add feedback validation and error handling
- Add FeedbackProcessingError for feedback handling
- Add validation for empty and long feedback messages
- Add test coverage for edge cases

Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 19:54:02 +00:00
Devin AI
f8a5df9d5a feat: Add feedback validation and error handling
- Add FeedbackProcessingError for feedback handling
- Add validation for empty and long feedback messages
- Add test coverage for edge cases

Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 19:53:41 +00:00
Devin AI
3dd79fed82 feat: Add FeedbackProcessingError for feedback handling
- Add custom exception for feedback processing errors
- Add proper error inheritance and docstrings
- Make exception importable via __init__.py

Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 17:36:24 +00:00
Devin AI
b7d8fadfad refactor: Improve feedback handling code quality
- Use _format_msg consistently for feedback messages
- Add comprehensive type hints
- Improve method documentation
- Add error handling for feedback processing

Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 17:33:50 +00:00
Devin AI
537aac0785 fix: Add proper role to human feedback messages for LiteLLM
- Update _handle_human_feedback to set user role for feedback messages
- Add test coverage for message format
- Fixes #2111

Co-Authored-By: Joe Moura <joao@crewai.com>
2025-02-12 17:30:59 +00:00
7 changed files with 600 additions and 39 deletions

3
.gitignore vendored
View File

@@ -21,4 +21,5 @@ crew_tasks_output.json
.mypy_cache
.ruff_cache
.venv
agentops.log
agentops.log
tests/cassettes/

View File

@@ -21,6 +21,9 @@ from crewai.utilities.constants import MAX_LLM_RETRY, TRAINING_DATA_FILE
from crewai.utilities.exceptions.context_window_exceeding_exception import (
LLMContextLengthExceededException,
)
from crewai.utilities.exceptions.feedback_processing_exception import (
FeedbackProcessingError,
)
from crewai.utilities.logger import Logger
from crewai.utilities.training_handler import CrewTrainingHandler
@@ -487,17 +490,40 @@ class CrewAgentExecutor(CrewAgentExecutorMixin):
return CrewAgentParser(agent=self.agent).parse(answer)
def _format_msg(self, prompt: str, role: str = "user") -> Dict[str, str]:
"""Format a message with role and content.
Args:
prompt (str): The message content
role (str): The message role (default: "user")
Returns:
Dict[str, str]: Formatted message with role and content
Raises:
FeedbackProcessingError: If prompt is empty or exceeds max length
"""
if not prompt or not prompt.strip():
raise FeedbackProcessingError("Feedback message cannot be empty")
if len(prompt) > 8192: # Standard context window size
raise FeedbackProcessingError("Feedback message exceeds maximum length")
prompt = prompt.rstrip()
return {"role": role, "content": prompt}
def _handle_human_feedback(self, formatted_answer: AgentFinish) -> AgentFinish:
"""Handle human feedback with different flows for training vs regular use.
This method processes human feedback by either handling it as training data
or as regular feedback requiring potential multiple iterations.
Args:
formatted_answer: The initial AgentFinish result to get feedback on
formatted_answer (AgentFinish): The initial AgentFinish result to get feedback on
Returns:
AgentFinish: The final answer after processing feedback
Raises:
FeedbackProcessingError: If feedback processing fails
"""
human_feedback = self._ask_human_input(formatted_answer.output)
@@ -511,44 +537,97 @@ class CrewAgentExecutor(CrewAgentExecutorMixin):
return bool(self.crew and self.crew._train)
def _handle_training_feedback(
self, initial_answer: AgentFinish, feedback: str
self,
initial_answer: AgentFinish,
feedback: str,
) -> AgentFinish:
"""Process feedback for training scenarios with single iteration."""
self._printer.print(
content="\nProcessing training feedback.\n",
color="yellow",
)
self._handle_crew_training_output(initial_answer, feedback)
self.messages.append(
self._format_msg(
self._i18n.slice("feedback_instructions").format(feedback=feedback)
"""Process feedback for training scenarios with single iteration.
Args:
initial_answer (AgentFinish): The initial answer to improve
feedback (str): The feedback to process
Returns:
AgentFinish: The improved answer after processing feedback
Raises:
FeedbackProcessingError: If feedback processing fails
"""
try:
self._printer.print(
content="\nProcessing training feedback.\n",
color="yellow",
)
)
improved_answer = self._invoke_loop()
self._handle_crew_training_output(improved_answer)
self.ask_for_human_input = False
return improved_answer
self._handle_crew_training_output(initial_answer, feedback)
improved_answer = self._process_feedback_iteration(feedback)
self._handle_crew_training_output(improved_answer)
self.ask_for_human_input = False
return improved_answer
except Exception as e:
error_msg = f"Failed to process training feedback: {str(e)}"
self._printer.print(
content=error_msg,
color="red"
)
raise FeedbackProcessingError(error_msg, original_error=e)
def _handle_regular_feedback(
self, current_answer: AgentFinish, initial_feedback: str
self,
current_answer: AgentFinish,
initial_feedback: str,
) -> AgentFinish:
"""Process feedback for regular use with potential multiple iterations."""
feedback = initial_feedback
answer = current_answer
"""Process feedback for regular use with potential multiple iterations.
while self.ask_for_human_input:
response = self._get_llm_feedback_response(feedback)
This method handles the iterative feedback process where the agent continues
to improve its answer based on user feedback until no more changes are needed.
if not self._feedback_requires_changes(response):
self.ask_for_human_input = False
else:
answer = self._process_feedback_iteration(feedback)
feedback = self._ask_human_input(answer.output)
Args:
current_answer (AgentFinish): The current answer from the agent
initial_feedback (str): The initial feedback from the user
return answer
Returns:
AgentFinish: The final answer after processing all feedback iterations
Raises:
FeedbackProcessingError: If feedback processing or validation fails
"""
try:
feedback = initial_feedback
answer = current_answer
while self.ask_for_human_input:
# Add feedback message with user role using standard formatter
feedback_msg = self._i18n.slice("feedback_message").format(feedback=feedback)
self.messages.append(self._format_msg(feedback_msg, role="user"))
response = self._get_llm_feedback_response(feedback)
if not self._feedback_requires_changes(response):
self.ask_for_human_input = False
else:
answer = self._process_feedback_iteration(feedback)
feedback = self._ask_human_input(answer.output)
return answer
except Exception as e:
error_msg = f"Failed to process feedback: {str(e)}"
self._printer.print(
content=error_msg,
color="red"
)
raise FeedbackProcessingError(error_msg, original_error=e)
def _get_llm_feedback_response(self, feedback: str) -> Optional[str]:
"""Get LLM classification of whether feedback requires changes."""
"""Get LLM classification of whether feedback requires changes.
Args:
feedback (str): The feedback to classify
Returns:
Optional[str]: The LLM's response indicating if changes are needed
Raises:
FeedbackProcessingError: If LLM call fails after max retries
"""
prompt = self._i18n.slice("human_feedback_classification").format(
feedback=feedback
)
@@ -561,21 +640,45 @@ class CrewAgentExecutor(CrewAgentExecutorMixin):
except Exception as error:
self._log_feedback_error(retry, error)
error_msg = f"Failed to get LLM feedback response after {MAX_LLM_RETRY} retries"
self._log_max_retries_exceeded()
return None
raise FeedbackProcessingError(error_msg)
def _feedback_requires_changes(self, response: Optional[str]) -> bool:
"""Determine if feedback response indicates need for changes."""
"""Determine if feedback response indicates need for changes.
Args:
response (Optional[str]): The LLM's response to feedback classification
Returns:
bool: True if feedback requires changes, False otherwise
"""
return response == "true" if response else False
def _process_feedback_iteration(self, feedback: str) -> AgentFinish:
"""Process a single feedback iteration."""
self.messages.append(
self._format_msg(
self._i18n.slice("feedback_instructions").format(feedback=feedback)
"""Process a single feedback iteration.
Args:
feedback (str): The feedback to process from the user
Returns:
AgentFinish: The processed agent response after incorporating feedback
"""
try:
# Add feedback instructions with user role
self.messages.append(
self._format_msg(
self._i18n.slice("feedback_instructions").format(feedback=feedback),
role="user"
)
)
)
return self._invoke_loop()
return self._invoke_loop()
except Exception as e:
self._printer.print(
content=f"Error processing feedback iteration: {str(e)}",
color="red"
)
raise
def _log_feedback_error(self, retry_count: int, error: Exception) -> None:
"""Log feedback processing errors."""

View File

@@ -0,0 +1,5 @@
"""Exceptions module for CrewAI."""
from .feedback_processing_exception import FeedbackProcessingError
__all__ = ["FeedbackProcessingError"]

View File

@@ -0,0 +1,8 @@
from typing import Optional
class FeedbackProcessingError(Exception):
"""Exception raised when feedback processing fails."""
def __init__(self, message: str, original_error: Optional[Exception] = None):
self.original_error = original_error
super().__init__(message)

View File

@@ -2,7 +2,7 @@
import os
from unittest import mock
from unittest.mock import patch
from unittest.mock import MagicMock, patch
import pytest
@@ -19,6 +19,9 @@ from crewai.tools.tool_usage import ToolUsage
from crewai.tools.tool_usage_events import ToolUsageFinished
from crewai.utilities import RPMController
from crewai.utilities.events import Emitter
from crewai.utilities.exceptions.feedback_processing_exception import (
FeedbackProcessingError,
)
def test_agent_llm_creation_with_env_vars():
@@ -1001,6 +1004,53 @@ def test_agent_human_input():
assert mock_human_input.call_count == 2 # Should have asked for feedback twice
assert output.strip().lower() == "hello" # Final output should be 'Hello'
# Verify message format for human feedback
messages = agent.agent_executor.messages
feedback_messages = [m for m in messages if "Feedback:" in m.get("content", "")]
assert len(feedback_messages) == 2 # Two feedback messages
for msg in feedback_messages:
assert msg["role"] == "user" # All feedback messages should have user role
@pytest.fixture
def mock_executor():
"""Create a mock executor for testing."""
agent = Agent(
role="test role",
goal="test goal",
backstory="test backstory"
)
task = Task(
description="Test task",
expected_output="Test output",
human_input=True,
agent=agent
)
executor = CrewAgentExecutor(
agent=agent,
task=task,
llm=agent.llm,
crew=None,
prompt="",
max_iter=1,
tools=[],
tools_names=[],
stop_words=[],
tools_description="",
tools_handler=None
)
return executor
def test_empty_feedback_handling(mock_executor):
"""Test that empty feedback is properly handled."""
with pytest.raises(FeedbackProcessingError):
mock_executor._format_msg("")
def test_long_feedback_handling(mock_executor):
"""Test that very long feedback is properly handled."""
very_long_feedback = "x" * 10000
with pytest.raises(FeedbackProcessingError):
mock_executor._format_msg(very_long_feedback)
def test_interpolate_inputs():
agent = Agent(

View File

@@ -0,0 +1,307 @@
interactions:
- request:
body: !!binary |
CrV6CiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkSjHoKEgoQY3Jld2FpLnRl
bGVtZXRyeRKwBwoQdpCOuOkexoT4NZTCVljP1BIIfEulX5blckkqDENyZXcgQ3JlYXRlZDABOUQI
kgemhyMYQfVkoQemhyMYShsKDmNyZXdhaV92ZXJzaW9uEgkKBzAuMTAwLjFKGgoOcHl0aG9uX3Zl
cnNpb24SCAoGMy4xMi43Si4KCGNyZXdfa2V5EiIKIGQ1NTExM2JlNGFhNDFiYTY0M2QzMjYwNDJi
MmYwM2YxSjEKB2NyZXdfaWQSJgokMmQxNThmMjctOWExOC00OTg0LTk0OTktYjZhMzc1NTc2YTU4
ShwKDGNyZXdfcHJvY2VzcxIMCgpzZXF1ZW50aWFsShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3
X251bWJlcl9vZl90YXNrcxICGAFKGwoVY3Jld19udW1iZXJfb2ZfYWdlbnRzEgIYAUrMAgoLY3Jl
d19hZ2VudHMSvAIKuQJbeyJrZXkiOiAiZTE0OGU1MzIwMjkzNDk5ZjhjZWJlYTgyNmU3MjU4MmIi
LCAiaWQiOiAiNmVhZDNhYzYtMGRmMS00YTY0LTgwM2ItZTE2MWFmMDZiZTgxIiwgInJvbGUiOiAi
dGVzdCByb2xlIiwgInZlcmJvc2U/IjogdHJ1ZSwgIm1heF9pdGVyIjogNCwgIm1heF9ycG0iOiAx
MCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogIiIsICJsbG0iOiAiZ3B0LTRvLW1pbmkiLCAiZGVs
ZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29kZV9leGVjdXRpb24/IjogZmFsc2Us
ICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMiOiBbXX1dSpACCgpjcmV3X3Rhc2tz
EoECCv4BW3sia2V5IjogIjRhMzFiODUxMzNhM2EyOTRjNjg1M2RhNzU3ZDRiYWU3IiwgImlkIjog
ImQzNTU0M2UzLWIwMTAtNGNhYS04NzI5LTYzYjkxZTI2OTY2MiIsICJhc3luY19leGVjdXRpb24/
IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAidGVzdCByb2xl
IiwgImFnZW50X2tleSI6ICJlMTQ4ZTUzMjAyOTM0OTlmOGNlYmVhODI2ZTcyNTgyYiIsICJ0b29s
c19uYW1lcyI6IFsiZ2V0X2ZpbmFsX2Fuc3dlciJdfV16AhgBhQEAAQAAEo4CChAegf7PNU+P5e79
MNur6PVkEghMT+0stJYWYCoMVGFzayBDcmVhdGVkMAE51eexB6aHIxhBZ9ayB6aHIxhKLgoIY3Jl
d19rZXkSIgogZDU1MTEzYmU0YWE0MWJhNjQzZDMyNjA0MmIyZjAzZjFKMQoHY3Jld19pZBImCiQy
ZDE1OGYyNy05YTE4LTQ5ODQtOTQ5OS1iNmEzNzU1NzZhNThKLgoIdGFza19rZXkSIgogNGEzMWI4
NTEzM2EzYTI5NGM2ODUzZGE3NTdkNGJhZTdKMQoHdGFza19pZBImCiRkMzU1NDNlMy1iMDEwLTRj
YWEtODcyOS02M2I5MWUyNjk2NjJ6AhgBhQEAAQAAEpQBChCFfsLseVYHybPhCFlrXiZ5EggL0Wm/
Us0FrioKVG9vbCBVc2FnZTABOeEoMAimhyMYQT2MPgimhyMYShsKDmNyZXdhaV92ZXJzaW9uEgkK
BzAuMTAwLjFKHwoJdG9vbF9uYW1lEhIKEGdldF9maW5hbF9hbnN3ZXJKDgoIYXR0ZW1wdHMSAhgB
egIYAYUBAAEAABKdAQoQFOiE21qjZmK2nnmrBQB/ohIIs0uE2IV3DCoqE1Rvb2wgUmVwZWF0ZWQg
VXNhZ2UwATkwrcIIpocjGEGHi9AIpocjGEobCg5jcmV3YWlfdmVyc2lvbhIJCgcwLjEwMC4xSh8K
CXRvb2xfbmFtZRISChBnZXRfZmluYWxfYW5zd2VySg4KCGF0dGVtcHRzEgIYAXoCGAGFAQABAAAS
nQEKELIZVIO+Smd1JULqNEumKHoSCDH9vnKQrFuxKhNUb29sIFJlcGVhdGVkIFVzYWdlMAE5Xktd
CaaHIxhBU1B0CaaHIxhKGwoOY3Jld2FpX3ZlcnNpb24SCQoHMC4xMDAuMUofCgl0b29sX25hbWUS
EgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEp0BChBLm/Rev7ii
1RmsETsVKbiHEgi88x3U6BT3PioTVG9vbCBSZXBlYXRlZCBVc2FnZTABOXVXDQqmhyMYQRYUHAqm
hyMYShsKDmNyZXdhaV92ZXJzaW9uEgkKBzAuMTAwLjFKHwoJdG9vbF9uYW1lEhIKEGdldF9maW5h
bF9hbnN3ZXJKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABLZCwoQCbZhwqrhbqnALZ4Hz/X4AxII
vcjAPkNUb5kqDENyZXcgQ3JlYXRlZDABOQMbpwumhyMYQUvYtgumhyMYShsKDmNyZXdhaV92ZXJz
aW9uEgkKBzAuMTAwLjFKGgoOcHl0aG9uX3ZlcnNpb24SCAoGMy4xMi43Si4KCGNyZXdfa2V5EiIK
IDY2MmM2ZGVjOTYwOTU3ZjA0Y2JlNjQyNzFiYjE2NzNlSjEKB2NyZXdfaWQSJgokNjMwMjBhNzAt
YmViMS00Mzc4LTkxZDgtYWJiMzI4ZGNhYTZlShwKDGNyZXdfcHJvY2VzcxIMCgpzZXF1ZW50aWFs
ShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251bWJlcl9vZl90YXNrcxICGAJKGwoVY3Jld19u
dW1iZXJfb2ZfYWdlbnRzEgIYAkqIBQoLY3Jld19hZ2VudHMS+AQK9QRbeyJrZXkiOiAiZTE0OGU1
MzIwMjkzNDk5ZjhjZWJlYTgyNmU3MjU4MmIiLCAiaWQiOiAiMDhmOGQzODEtMWFhNC00MDI3LWFl
MjctZmMyMTE0ZjE3ZWY4IiwgInJvbGUiOiAidGVzdCByb2xlIiwgInZlcmJvc2U/IjogdHJ1ZSwg
Im1heF9pdGVyIjogMiwgIm1heF9ycG0iOiAxMCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogIiIs
ICJsbG0iOiAiZ3B0LTRvLW1pbmkiLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxs
b3dfY29kZV9leGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNf
bmFtZXMiOiBbXX0sIHsia2V5IjogImU3ZThlZWE4ODZiY2I4ZjEwNDVhYmVlY2YxNDI1ZGI3Iiwg
ImlkIjogIjIyM2IxYjYwLTNkMzYtNGNkZS1iNWUzLTNhOWJmNGJlODU0MiIsICJyb2xlIjogInRl
c3Qgcm9sZTIiLCAidmVyYm9zZT8iOiB0cnVlLCAibWF4X2l0ZXIiOiA1LCAibWF4X3JwbSI6IG51
bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAibGxtIjogImdwdC00by1taW5pIiwgImRl
bGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNl
LCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25hbWVzIjogW119XUr9AwoKY3Jld190YXNr
cxLuAwrrA1t7ImtleSI6ICIzMjJkZGFlM2JjODBjMWQ0NWI4NWZhNzc1NmRiODY2NSIsICJpZCI6
ICI5YmI3OTE1OC05NzFkLTQxNGQtYTY2Ny05NWJjNzAxNWVjMjkiLCAiYXN5bmNfZXhlY3V0aW9u
PyI6IGZhbHNlLCAiaHVtYW5faW5wdXQ/IjogZmFsc2UsICJhZ2VudF9yb2xlIjogInRlc3Qgcm9s
ZSIsICJhZ2VudF9rZXkiOiAiZTE0OGU1MzIwMjkzNDk5ZjhjZWJlYTgyNmU3MjU4MmIiLCAidG9v
bHNfbmFtZXMiOiBbXX0sIHsia2V5IjogImQ1YzQ1MjNlNGNhMzQ0NGRlMzViZjYzMGI1MmY3YWRj
IiwgImlkIjogImY1MjE3NDRjLTAzMDItNDI0MC05NDhjLTNjOWNiM2FjZTI2YyIsICJhc3luY19l
eGVjdXRpb24/IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAi
dGVzdCByb2xlMiIsICJhZ2VudF9rZXkiOiAiZTdlOGVlYTg4NmJjYjhmMTA0NWFiZWVjZjE0MjVk
YjciLCAidG9vbHNfbmFtZXMiOiBbImdldF9maW5hbF9hbnN3ZXIiXX1degIYAYUBAAEAABKOAgoQ
7y/W8t37iRoWm0uvUYIMUhIIS62FJ0+mHJAqDFRhc2sgQ3JlYXRlZDABOd1azAumhyMYQfBfzQum
hyMYSi4KCGNyZXdfa2V5EiIKIDY2MmM2ZGVjOTYwOTU3ZjA0Y2JlNjQyNzFiYjE2NzNlSjEKB2Ny
ZXdfaWQSJgokNjMwMjBhNzAtYmViMS00Mzc4LTkxZDgtYWJiMzI4ZGNhYTZlSi4KCHRhc2tfa2V5
EiIKIDMyMmRkYWUzYmM4MGMxZDQ1Yjg1ZmE3NzU2ZGI4NjY1SjEKB3Rhc2tfaWQSJgokOWJiNzkx
NTgtOTcxZC00MTRkLWE2NjctOTViYzcwMTVlYzI5egIYAYUBAAEAABKOAgoQ+BQWq7+d9rQAlNhl
Pl/8zxII1JpKXFy7LYAqDFRhc2sgQ3JlYXRlZDABOT9FTgymhyMYQcxYTwymhyMYSi4KCGNyZXdf
a2V5EiIKIDY2MmM2ZGVjOTYwOTU3ZjA0Y2JlNjQyNzFiYjE2NzNlSjEKB2NyZXdfaWQSJgokNjMw
MjBhNzAtYmViMS00Mzc4LTkxZDgtYWJiMzI4ZGNhYTZlSi4KCHRhc2tfa2V5EiIKIGQ1YzQ1MjNl
NGNhMzQ0NGRlMzViZjYzMGI1MmY3YWRjSjEKB3Rhc2tfaWQSJgokZjUyMTc0NGMtMDMwMi00MjQw
LTk0OGMtM2M5Y2IzYWNlMjZjegIYAYUBAAEAABKUAQoQV34P2QyEIPkc/ibS8FHiNhIIrkMe+DzL
MDUqClRvb2wgVXNhZ2UwATmIr9IMpocjGEHEyuAMpocjGEobCg5jcmV3YWlfdmVyc2lvbhIJCgcw
LjEwMC4xSh8KCXRvb2xfbmFtZRISChBnZXRfZmluYWxfYW5zd2VySg4KCGF0dGVtcHRzEgIYAXoC
GAGFAQABAAASsgcKEGkkxCNWp39iZUAo3mi2q28SCIV+msckPzvFKgxDcmV3IENyZWF0ZWQwATnn
QukNpocjGEFCivYNpocjGEobCg5jcmV3YWlfdmVyc2lvbhIJCgcwLjEwMC4xShoKDnB5dGhvbl92
ZXJzaW9uEggKBjMuMTIuN0ouCghjcmV3X2tleRIiCiA3M2FhYzI4NWU2NzQ2NjY3Zjc1MTQ3Njcw
MDAzNDExMEoxCgdjcmV3X2lkEiYKJDM4Y2YzMGI4LTVkZTktNDBjOC04YTE0LTNkN2M2ODg2NTI1
NkocCgxjcmV3X3Byb2Nlc3MSDAoKc2VxdWVudGlhbEoRCgtjcmV3X21lbW9yeRICEABKGgoUY3Jl
d19udW1iZXJfb2ZfdGFza3MSAhgBShsKFWNyZXdfbnVtYmVyX29mX2FnZW50cxICGAFKzgIKC2Ny
ZXdfYWdlbnRzEr4CCrsCW3sia2V5IjogImUxNDhlNTMyMDI5MzQ5OWY4Y2ViZWE4MjZlNzI1ODJi
IiwgImlkIjogImVkMjlhYWFiLTIxMWEtNGU1Yi1iODMyLTZjMzhhMDkzZTVmYyIsICJyb2xlIjog
InRlc3Qgcm9sZSIsICJ2ZXJib3NlPyI6IHRydWUsICJtYXhfaXRlciI6IDEsICJtYXhfcnBtIjog
bnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogIiIsICJsbG0iOiAiZ3B0LTRvLW1pbmkiLCAi
ZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29kZV9leGVjdXRpb24/IjogZmFs
c2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMiOiBbXX1dSpACCgpjcmV3X3Rh
c2tzEoECCv4BW3sia2V5IjogImY3YTlmN2JiMWFlZTRiNmVmMmM1MjZkMGE4YzJmMmFjIiwgImlk
IjogIjc0ZWJlOTdmLTc1NDEtNDllYS05MGQ2LTk0MTkyM2FkMzhjYyIsICJhc3luY19leGVjdXRp
b24/IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAidGVzdCBy
b2xlIiwgImFnZW50X2tleSI6ICJlMTQ4ZTUzMjAyOTM0OTlmOGNlYmVhODI2ZTcyNTgyYiIsICJ0
b29sc19uYW1lcyI6IFsiZ2V0X2ZpbmFsX2Fuc3dlciJdfV16AhgBhQEAAQAAEo4CChDoONvPxkry
DEs+JOeCy8PREgjXCZBRp7vclCoMVGFzayBDcmVhdGVkMAE5BisFDqaHIxhBjvwFDqaHIxhKLgoI
Y3Jld19rZXkSIgogNzNhYWMyODVlNjc0NjY2N2Y3NTE0NzY3MDAwMzQxMTBKMQoHY3Jld19pZBIm
CiQzOGNmMzBiOC01ZGU5LTQwYzgtOGExNC0zZDdjNjg4NjUyNTZKLgoIdGFza19rZXkSIgogZjdh
OWY3YmIxYWVlNGI2ZWYyYzUyNmQwYThjMmYyYWNKMQoHdGFza19pZBImCiQ3NGViZTk3Zi03NTQx
LTQ5ZWEtOTBkNi05NDE5MjNhZDM4Y2N6AhgBhQEAAQAAEnoKEI0vUGKYu+8WE4fMmZTS22ISCO0J
DOoPb7UuKhBUb29sIFVzYWdlIEVycm9yMAE5Tel7DqaHIxhB8YOZDqaHIxhKGwoOY3Jld2FpX3Zl
cnNpb24SCQoHMC4xMDAuMUoPCgNsbG0SCAoGZ3B0LTRvegIYAYUBAAEAABKyBwoQMvqS/DMlHmIr
4XWzZfwN+BIImIMB8+nKOO0qDENyZXcgQ3JlYXRlZDABOTNO6w+mhyMYQeUq+Q+mhyMYShsKDmNy
ZXdhaV92ZXJzaW9uEgkKBzAuMTAwLjFKGgoOcHl0aG9uX3ZlcnNpb24SCAoGMy4xMi43Si4KCGNy
ZXdfa2V5EiIKIGQ1NTExM2JlNGFhNDFiYTY0M2QzMjYwNDJiMmYwM2YxSjEKB2NyZXdfaWQSJgok
MDY4YTJkNjEtOTAzYS00MzZiLTg4MDItNDIxZTZiNmE3MGJjShwKDGNyZXdfcHJvY2VzcxIMCgpz
ZXF1ZW50aWFsShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251bWJlcl9vZl90YXNrcxICGAFK
GwoVY3Jld19udW1iZXJfb2ZfYWdlbnRzEgIYAUrOAgoLY3Jld19hZ2VudHMSvgIKuwJbeyJrZXki
OiAiZTE0OGU1MzIwMjkzNDk5ZjhjZWJlYTgyNmU3MjU4MmIiLCAiaWQiOiAiOTM2ZWE4ODYtZjU3
ZS00MjgxLTk0ZGQtZjJlMjVlYjJhMTNkIiwgInJvbGUiOiAidGVzdCByb2xlIiwgInZlcmJvc2U/
IjogdHJ1ZSwgIm1heF9pdGVyIjogNiwgIm1heF9ycG0iOiBudWxsLCAiZnVuY3Rpb25fY2FsbGlu
Z19sbG0iOiAiIiwgImxsbSI6ICJncHQtNG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/Ijog
ZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6
IDIsICJ0b29sc19uYW1lcyI6IFtdfV1KkAIKCmNyZXdfdGFza3MSgQIK/gFbeyJrZXkiOiAiNGEz
MWI4NTEzM2EzYTI5NGM2ODUzZGE3NTdkNGJhZTciLCAiaWQiOiAiNjdlOGU2OWUtMjE2Zi00NDMz
LWJkZTktODUzMDkxYmQ2M2ZiIiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lu
cHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJ0ZXN0IHJvbGUiLCAiYWdlbnRfa2V5IjogImUx
NDhlNTMyMDI5MzQ5OWY4Y2ViZWE4MjZlNzI1ODJiIiwgInRvb2xzX25hbWVzIjogWyJnZXRfZmlu
YWxfYW5zd2VyIl19XXoCGAGFAQABAAASjgIKEGaV58NpXTIH37392KbVZVgSCELTtfkQZY08KgxU
YXNrIENyZWF0ZWQwATn9twYQpocjGEEOfgcQpocjGEouCghjcmV3X2tleRIiCiBkNTUxMTNiZTRh
YTQxYmE2NDNkMzI2MDQyYjJmMDNmMUoxCgdjcmV3X2lkEiYKJDA2OGEyZDYxLTkwM2EtNDM2Yi04
ODAyLTQyMWU2YjZhNzBiY0ouCgh0YXNrX2tleRIiCiA0YTMxYjg1MTMzYTNhMjk0YzY4NTNkYTc1
N2Q0YmFlN0oxCgd0YXNrX2lkEiYKJDY3ZThlNjllLTIxNmYtNDQzMy1iZGU5LTg1MzA5MWJkNjNm
YnoCGAGFAQABAAASlAEKEEh8AzAk2LS47mJPi2BhJPoSCHXE9RN6/ozHKgpUb29sIFVzYWdlMAE5
9cp6EKaHIxhBR1aJEKaHIxhKGwoOY3Jld2FpX3ZlcnNpb24SCQoHMC4xMDAuMUofCgl0b29sX25h
bWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEp0BChCzd3ky
pwukySIl175RWJzvEggrqq6SZW6W6ioTVG9vbCBSZXBlYXRlZCBVc2FnZTABORziHRGmhyMYQSTb
KxGmhyMYShsKDmNyZXdhaV92ZXJzaW9uEgkKBzAuMTAwLjFKHwoJdG9vbF9uYW1lEhIKEGdldF9m
aW5hbF9hbnN3ZXJKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABKUAQoQUYj+smQA6GbrNV4GT9DH
BhIIGsr/6DK5CMgqClRvb2wgVXNhZ2UwATlH37URpocjGEFtfs0RpocjGEobCg5jcmV3YWlfdmVy
c2lvbhIJCgcwLjEwMC4xSh8KCXRvb2xfbmFtZRISChBnZXRfZmluYWxfYW5zd2VySg4KCGF0dGVt
cHRzEgIYAXoCGAGFAQABAAASnQEKEDOBcAEbzyT+AMpoVKVLWugSCPK2SYZnBhipKhNUb29sIFJl
cGVhdGVkIFVzYWdlMAE5hbMiE6aHIxhBmQgxE6aHIxhKGwoOY3Jld2FpX3ZlcnNpb24SCQoHMC4x
MDAuMUofCgl0b29sX25hbWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgB
hQEAAQAAEpQBChB3FfYjXtxkIEzP4nC9KB/sEgghrwSEFvS8oSoKVG9vbCBVc2FnZTABOWnQ5xOm
hyMYQWRg/hOmhyMYShsKDmNyZXdhaV92ZXJzaW9uEgkKBzAuMTAwLjFKHwoJdG9vbF9uYW1lEhIK
EGdldF9maW5hbF9hbnN3ZXJKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABK5DQoQXIROu558ieRP
fHllAZD4CxIIEOqEEUcv8/kqDENyZXcgQ3JlYXRlZDABOW/9eRWmhyMYQdELiRWmhyMYShsKDmNy
ZXdhaV92ZXJzaW9uEgkKBzAuMTAwLjFKGgoOcHl0aG9uX3ZlcnNpb24SCAoGMy4xMi43Si4KCGNy
ZXdfa2V5EiIKIDExMWI4NzJkOGYwY2Y3MDNmMmVmZWYwNGNmM2FjNzk4SjEKB2NyZXdfaWQSJgok
MzNmYTM5YmMtZjFlYy00ZmUwLWJlNmQtMTQ3ZTc0ZGQ1NGNjShwKDGNyZXdfcHJvY2VzcxIMCgpz
ZXF1ZW50aWFsShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251bWJlcl9vZl90YXNrcxICGANK
GwoVY3Jld19udW1iZXJfb2ZfYWdlbnRzEgIYAkqOBQoLY3Jld19hZ2VudHMS/gQK+wRbeyJrZXki
OiAiZTE0OGU1MzIwMjkzNDk5ZjhjZWJlYTgyNmU3MjU4MmIiLCAiaWQiOiAiOTYwMmQxZTItZjlh
Yy00ZGIyLTkwOWEtODAwY2I3NWY5ZTE1IiwgInJvbGUiOiAidGVzdCByb2xlIiwgInZlcmJvc2U/
IjogZmFsc2UsICJtYXhfaXRlciI6IDI1LCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxs
aW5nX2xsbSI6ICIiLCAibGxtIjogImdwdC00by1taW5pIiwgImRlbGVnYXRpb25fZW5hYmxlZD8i
OiBmYWxzZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0
IjogMiwgInRvb2xzX25hbWVzIjogW119LCB7ImtleSI6ICJlN2U4ZWVhODg2YmNiOGYxMDQ1YWJl
ZWNmMTQyNWRiNyIsICJpZCI6ICIwZGE4OWUyZi0zYTQwLTQ1YzktOWRmMS1mNzFhNGU2Y2QzYzUi
LCAicm9sZSI6ICJ0ZXN0IHJvbGUyIiwgInZlcmJvc2U/IjogZmFsc2UsICJtYXhfaXRlciI6IDI1
LCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6ICIiLCAibGxtIjogImdw
dC00by1taW5pIiwgImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFsbG93X2NvZGVfZXhl
Y3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xzX25hbWVzIjogW119
XUrXBQoKY3Jld190YXNrcxLIBQrFBVt7ImtleSI6ICIzMjJkZGFlM2JjODBjMWQ0NWI4NWZhNzc1
NmRiODY2NSIsICJpZCI6ICI5OTg4NmI2My01Nzg4LTQ0NTItODRmOC0zYzY0MDczOTYwYzciLCAi
YXN5bmNfZXhlY3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5faW5wdXQ/IjogZmFsc2UsICJhZ2VudF9y
b2xlIjogInRlc3Qgcm9sZSIsICJhZ2VudF9rZXkiOiAiZTE0OGU1MzIwMjkzNDk5ZjhjZWJlYTgy
NmU3MjU4MmIiLCAidG9vbHNfbmFtZXMiOiBbXX0sIHsia2V5IjogImNjNDg3NmY2ZTU4OGU3MTM0
OWJiZDNhNjU4ODhjM2U5IiwgImlkIjogIjMzMjA4N2YyLTFjMTEtNDAwMS1hMTEyLWFmY2FiYmI5
Njk1MyIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxzZSwg
ImFnZW50X3JvbGUiOiAidGVzdCByb2xlIiwgImFnZW50X2tleSI6ICJlMTQ4ZTUzMjAyOTM0OTlm
OGNlYmVhODI2ZTcyNTgyYiIsICJ0b29sc19uYW1lcyI6IFtdfSwgeyJrZXkiOiAiZTBiMTNlMTBk
N2ExNDZkY2M0YzQ4OGZjZjhkNzQ4YTAiLCAiaWQiOiAiY2U5NmRlN2QtZGExMC00Njk2LTlhNTkt
YTg1MDhmZTY2NWMyIiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6
IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJ0ZXN0IHJvbGUyIiwgImFnZW50X2tleSI6ICJlN2U4ZWVh
ODg2YmNiOGYxMDQ1YWJlZWNmMTQyNWRiNyIsICJ0b29sc19uYW1lcyI6IFtdfV16AhgBhQEAAQAA
Eo4CChDqXo3uZlXRf0tyERPYj7KwEghUu1XP/N+QEioMVGFzayBDcmVhdGVkMAE57i+dFaaHIxhB
OCueFaaHIxhKLgoIY3Jld19rZXkSIgogMTExYjg3MmQ4ZjBjZjcwM2YyZWZlZjA0Y2YzYWM3OThK
MQoHY3Jld19pZBImCiQzM2ZhMzliYy1mMWVjLTRmZTAtYmU2ZC0xNDdlNzRkZDU0Y2NKLgoIdGFz
a19rZXkSIgogMzIyZGRhZTNiYzgwYzFkNDViODVmYTc3NTZkYjg2NjVKMQoHdGFza19pZBImCiQ5
OTg4NmI2My01Nzg4LTQ0NTItODRmOC0zYzY0MDczOTYwYzd6AhgBhQEAAQAAEo4CChD2ppz92+1X
nsFyeUidGflsEgjs++pdB/O4vCoMVGFzayBDcmVhdGVkMAE50rwbFqaHIxhBOt4cFqaHIxhKLgoI
Y3Jld19rZXkSIgogMTExYjg3MmQ4ZjBjZjcwM2YyZWZlZjA0Y2YzYWM3OThKMQoHY3Jld19pZBIm
CiQzM2ZhMzliYy1mMWVjLTRmZTAtYmU2ZC0xNDdlNzRkZDU0Y2NKLgoIdGFza19rZXkSIgogY2M0
ODc2ZjZlNTg4ZTcxMzQ5YmJkM2E2NTg4OGMzZTlKMQoHdGFza19pZBImCiQzMzIwODdmMi0xYzEx
LTQwMDEtYTExMi1hZmNhYmJiOTY5NTN6AhgBhQEAAQAAEo4CChBKTvTil7rKpq45TVdxFxqREggS
zhu00X/2PSoMVGFzayBDcmVhdGVkMAE5iSuaFqaHIxhBHUebFqaHIxhKLgoIY3Jld19rZXkSIgog
MTExYjg3MmQ4ZjBjZjcwM2YyZWZlZjA0Y2YzYWM3OThKMQoHY3Jld19pZBImCiQzM2ZhMzliYy1m
MWVjLTRmZTAtYmU2ZC0xNDdlNzRkZDU0Y2NKLgoIdGFza19rZXkSIgogZTBiMTNlMTBkN2ExNDZk
Y2M0YzQ4OGZjZjhkNzQ4YTBKMQoHdGFza19pZBImCiRjZTk2ZGU3ZC1kYTEwLTQ2OTYtOWE1OS1h
ODUwOGZlNjY1YzJ6AhgBhQEAAQAAEsIHChAlrVT+CvbPT7TFNWhLq8emEggMSwlN59fjTioMQ3Jl
dyBDcmVhdGVkMAE5QzavF6aHIxhBcmC9F6aHIxhKGwoOY3Jld2FpX3ZlcnNpb24SCQoHMC4xMDAu
MUoaCg5weXRob25fdmVyc2lvbhIICgYzLjEyLjdKLgoIY3Jld19rZXkSIgogNDk0ZjM2NTcyMzdh
ZDhhMzAzNWIyZjFiZWVjZGM2NzdKMQoHY3Jld19pZBImCiRhY2Q2MjVhZS00MzlkLTRhODEtYTA5
My1kZWIxMGU0M2Q1NTRKHAoMY3Jld19wcm9jZXNzEgwKCnNlcXVlbnRpYWxKEQoLY3Jld19tZW1v
cnkSAhAAShoKFGNyZXdfbnVtYmVyX29mX3Rhc2tzEgIYAUobChVjcmV3X251bWJlcl9vZl9hZ2Vu
dHMSAhgBSuACCgtjcmV3X2FnZW50cxLQAgrNAlt7ImtleSI6ICJlMTQ4ZTUzMjAyOTM0OTlmOGNl
YmVhODI2ZTcyNTgyYiIsICJpZCI6ICIyYjNjMGFmYS1jOTk2LTRhM2QtODM1NC1hNDkwY2U3OGIy
OTQiLCAicm9sZSI6ICJ0ZXN0IHJvbGUiLCAidmVyYm9zZT8iOiBmYWxzZSwgIm1heF9pdGVyIjog
MjUsICJtYXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogIiIsICJsbG0iOiAi
Z3B0LTRvLW1pbmkiLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29kZV9l
eGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMiOiBb
ImxlYXJuX2Fib3V0X2FpIl19XUqOAgoKY3Jld190YXNrcxL/AQr8AVt7ImtleSI6ICJmMjU5N2M3
ODY3ZmJlMzI0ZGM2NWRjMDhkZmRiZmM2YyIsICJpZCI6ICI5M2U0MjdkMS04YmIxLTRlMDAtODZk
Yy01ZDk2MmI1MmE1ZGQiLCAiYXN5bmNfZXhlY3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5faW5wdXQ/
IjogZmFsc2UsICJhZ2VudF9yb2xlIjogInRlc3Qgcm9sZSIsICJhZ2VudF9rZXkiOiAiZTE0OGU1
MzIwMjkzNDk5ZjhjZWJlYTgyNmU3MjU4MmIiLCAidG9vbHNfbmFtZXMiOiBbImxlYXJuX2Fib3V0
X2FpIl19XXoCGAGFAQABAAASjgIKEBir/i8Yuwo5eqCwrCXydXISCKC4mPrpqM5hKgxUYXNrIENy
ZWF0ZWQwATk2q88XpocjGEHxetAXpocjGEouCghjcmV3X2tleRIiCiA0OTRmMzY1NzIzN2FkOGEz
MDM1YjJmMWJlZWNkYzY3N0oxCgdjcmV3X2lkEiYKJGFjZDYyNWFlLTQzOWQtNGE4MS1hMDkzLWRl
YjEwZTQzZDU1NEouCgh0YXNrX2tleRIiCiBmMjU5N2M3ODY3ZmJlMzI0ZGM2NWRjMDhkZmRiZmM2
Y0oxCgd0YXNrX2lkEiYKJDkzZTQyN2QxLThiYjEtNGUwMC04NmRjLTVkOTYyYjUyYTVkZHoCGAGF
AQABAAASkgEKEMZPEzWpSFQyx5JvYLLY+BESCOdcWyQw5t+1KgpUb29sIFVzYWdlMAE53AREGKaH
IxhB1YJSGKaHIxhKGwoOY3Jld2FpX3ZlcnNpb24SCQoHMC4xMDAuMUodCgl0b29sX25hbWUSEAoO
bGVhcm5fYWJvdXRfQUlKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABLCBwoQomj0lr7AK5BqLSUX
aDeRMBIIFHur5REs4QoqDENyZXcgQ3JlYXRlZDABOY7TUZumhyMYQZILZ5umhyMYShsKDmNyZXdh
aV92ZXJzaW9uEgkKBzAuMTAwLjFKGgoOcHl0aG9uX3ZlcnNpb24SCAoGMy4xMi43Si4KCGNyZXdf
a2V5EiIKIDQ5NGYzNjU3MjM3YWQ4YTMwMzViMmYxYmVlY2RjNjc3SjEKB2NyZXdfaWQSJgokMzMy
YzE5OGUtZDYxYy00YjBiLThlZGUtYjc3ZTQ5MDExM2E4ShwKDGNyZXdfcHJvY2VzcxIMCgpzZXF1
ZW50aWFsShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251bWJlcl9vZl90YXNrcxICGAFKGwoV
Y3Jld19udW1iZXJfb2ZfYWdlbnRzEgIYAUrgAgoLY3Jld19hZ2VudHMS0AIKzQJbeyJrZXkiOiAi
ZTE0OGU1MzIwMjkzNDk5ZjhjZWJlYTgyNmU3MjU4MmIiLCAiaWQiOiAiYTNmMGQ3MGQtMTc3Mi00
YjczLTk1MzAtMmM5Y2IwZDBiOTVhIiwgInJvbGUiOiAidGVzdCByb2xlIiwgInZlcmJvc2U/Ijog
ZmFsc2UsICJtYXhfaXRlciI6IDIsICJtYXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdf
bGxtIjogImdwdC00byIsICJsbG0iOiAiZ3B0LTRvIiwgImRlbGVnYXRpb25fZW5hYmxlZD8iOiBm
YWxzZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0Ijog
MiwgInRvb2xzX25hbWVzIjogWyJsZWFybl9hYm91dF9haSJdfV1KjgIKCmNyZXdfdGFza3MS/wEK
/AFbeyJrZXkiOiAiZjI1OTdjNzg2N2ZiZTMyNGRjNjVkYzA4ZGZkYmZjNmMiLCAiaWQiOiAiZDFi
ZmI3NDktMmZiYy00ZGE2LTlhM2MtOTliMTJlNzUyYjQ0IiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBm
YWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJ0ZXN0IHJvbGUiLCAi
YWdlbnRfa2V5IjogImUxNDhlNTMyMDI5MzQ5OWY4Y2ViZWE4MjZlNzI1ODJiIiwgInRvb2xzX25h
bWVzIjogWyJsZWFybl9hYm91dF9haSJdfV16AhgBhQEAAQAAEo4CChDjFahoUTbbMYvI8KwBF9Tr
EggmfAwRdRRm5SoMVGFzayBDcmVhdGVkMAE5J+h8m6aHIxhBOeR9m6aHIxhKLgoIY3Jld19rZXkS
IgogNDk0ZjM2NTcyMzdhZDhhMzAzNWIyZjFiZWVjZGM2NzdKMQoHY3Jld19pZBImCiQzMzJjMTk4
ZS1kNjFjLTRiMGItOGVkZS1iNzdlNDkwMTEzYThKLgoIdGFza19rZXkSIgogZjI1OTdjNzg2N2Zi
ZTMyNGRjNjVkYzA4ZGZkYmZjNmNKMQoHdGFza19pZBImCiRkMWJmYjc0OS0yZmJjLTRkYTYtOWEz
Yy05OWIxMmU3NTJiNDR6AhgBhQEAAQAAEnoKED9v1dCouoYEnAdjpclmSm8SCL0zBBWtAqsyKhBU
b29sIFVzYWdlIEVycm9yMAE5Wnx6n6aHIxhBvWGun6aHIxhKGwoOY3Jld2FpX3ZlcnNpb24SCQoH
MC4xMDAuMUoPCgNsbG0SCAoGZ3B0LTRvegIYAYUBAAEAABJ6ChCENZSS4wMA5EFWIKBlfO6QEggA
tZqec6JSdCoQVG9vbCBVc2FnZSBFcnJvcjABOfvbiaKmhyMYQYCamqKmhyMYShsKDmNyZXdhaV92
ZXJzaW9uEgkKBzAuMTAwLjFKDwoDbGxtEggKBmdwdC00b3oCGAGFAQABAAASygcKEN1aqPyHcoWp
eE1b1N1vJi0SCOEmnsEv+HMpKgxDcmV3IENyZWF0ZWQwATlLquClpocjGEFQBfKlpocjGEobCg5j
cmV3YWlfdmVyc2lvbhIJCgcwLjEwMC4xShoKDnB5dGhvbl92ZXJzaW9uEggKBjMuMTIuN0ouCghj
cmV3X2tleRIiCiA3ZTY2MDg5ODk4NTlhNjdlZWM4OGVlZjdmY2U4NTIyNUoxCgdjcmV3X2lkEiYK
JDJkNGE4Y2RhLWZlOTgtNGZjZi1hNzcxLTNlNjhhNmE4NTJjN0ocCgxjcmV3X3Byb2Nlc3MSDAoK
c2VxdWVudGlhbEoRCgtjcmV3X21lbW9yeRICEABKGgoUY3Jld19udW1iZXJfb2ZfdGFza3MSAhgB
ShsKFWNyZXdfbnVtYmVyX29mX2FnZW50cxICGAFK5AIKC2NyZXdfYWdlbnRzEtQCCtECW3sia2V5
IjogIjIyYWNkNjExZTQ0ZWY1ZmFjMDViNTMzZDc1ZTg4OTNiIiwgImlkIjogImEzYzZkMjMxLTcy
OTctNDgyNC04NmQyLWU3NTZiZWU3ZGE1YSIsICJyb2xlIjogIkRhdGEgU2NpZW50aXN0IiwgInZl
cmJvc2U/IjogZmFsc2UsICJtYXhfaXRlciI6IDI1LCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlv
bl9jYWxsaW5nX2xsbSI6ICIiLCAibGxtIjogImdwdC00by1taW5pIiwgImRlbGVnYXRpb25fZW5h
YmxlZD8iOiBmYWxzZSwgImFsbG93X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5
X2xpbWl0IjogMiwgInRvb2xzX25hbWVzIjogWyJnZXQgZ3JlZXRpbmdzIl19XUqSAgoKY3Jld190
YXNrcxKDAgqAAlt7ImtleSI6ICJhMjc3YjM0YjJjMTQ2ZjBjNTZjNWUxMzU2ZThmOGE1NyIsICJp
ZCI6ICI5MWQ0ZWU3NS1mNDY0LTQ4YzEtYjJkZC0wYjZmZTMyYzAxMmIiLCAiYXN5bmNfZXhlY3V0
aW9uPyI6IGZhbHNlLCAiaHVtYW5faW5wdXQ/IjogZmFsc2UsICJhZ2VudF9yb2xlIjogIkRhdGEg
U2NpZW50aXN0IiwgImFnZW50X2tleSI6ICIyMmFjZDYxMWU0NGVmNWZhYzA1YjUzM2Q3NWU4ODkz
YiIsICJ0b29sc19uYW1lcyI6IFsiZ2V0IGdyZWV0aW5ncyJdfV16AhgBhQEAAQAAEo4CChBUckKs
B6Al8OagM3U/UHTpEghEvQvFRhWPqCoMVGFzayBDcmVhdGVkMAE57xcDpqaHIxhBuwoEpqaHIxhK
LgoIY3Jld19rZXkSIgogN2U2NjA4OTg5ODU5YTY3ZWVjODhlZWY3ZmNlODUyMjVKMQoHY3Jld19p
ZBImCiQyZDRhOGNkYS1mZTk4LTRmY2YtYTc3MS0zZTY4YTZhODUyYzdKLgoIdGFza19rZXkSIgog
YTI3N2IzNGIyYzE0NmYwYzU2YzVlMTM1NmU4ZjhhNTdKMQoHdGFza19pZBImCiQ5MWQ0ZWU3NS1m
NDY0LTQ4YzEtYjJkZC0wYjZmZTMyYzAxMmJ6AhgBhQEAAQAAEpEBChBElVMk3xFnvFvmGOoU1XfF
EgjUz8AahspUaSoKVG9vbCBVc2FnZTABOWXFmaamhyMYQc4NqqamhyMYShsKDmNyZXdhaV92ZXJz
aW9uEgkKBzAuMTAwLjFKHAoJdG9vbF9uYW1lEg8KDUdldCBHcmVldGluZ3NKDgoIYXR0ZW1wdHMS
AhgBegIYAYUBAAEAABLWBwoQTaWq89khjN2C0KBrprtQwxIInOhi64SISYsqDENyZXcgQ3JlYXRl
ZDABOSt3VqemhyMYQYs4Z6emhyMYShsKDmNyZXdhaV92ZXJzaW9uEgkKBzAuMTAwLjFKGgoOcHl0
aG9uX3ZlcnNpb24SCAoGMy4xMi43Si4KCGNyZXdfa2V5EiIKIGMzMDc2MDA5MzI2NzYxNDQ0ZDU3
YzcxZDFkYTNmMjdjSjEKB2NyZXdfaWQSJgokMThkMzYxNGMtOGYzMy00YmNjLTgyZjEtNTJjOGEz
NDQ0YWJiShwKDGNyZXdfcHJvY2VzcxIMCgpzZXF1ZW50aWFsShEKC2NyZXdfbWVtb3J5EgIQAEoa
ChRjcmV3X251bWJlcl9vZl90YXNrcxICGAFKGwoVY3Jld19udW1iZXJfb2ZfYWdlbnRzEgIYAUrq
AgoLY3Jld19hZ2VudHMS2gIK1wJbeyJrZXkiOiAiOThmM2IxZDQ3Y2U5NjljZjA1NzcyN2I3ODQx
NDI1Y2QiLCAiaWQiOiAiNGE2NzUzNTEtYWYxZS00MzE0LWI1ZjItYzI2ZTQ1MmEwNzExIiwgInJv
bGUiOiAiRnJpZW5kbHkgTmVpZ2hib3IiLCAidmVyYm9zZT8iOiBmYWxzZSwgIm1heF9pdGVyIjog
MjUsICJtYXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogIiIsICJsbG0iOiAi
Z3B0LTRvLW1pbmkiLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29kZV9l
eGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMiOiBb
ImRlY2lkZSBncmVldGluZ3MiXX1dSpgCCgpjcmV3X3Rhc2tzEokCCoYCW3sia2V5IjogIjgwZDdi
Y2Q0OTA5OTI5MDA4MzgzMmYwZTk4MzM4MGRmIiwgImlkIjogIjIxYWY3MGNmLTAwMjgtNDMzMy1i
OTQ0LTNmZGRlMDk0Yzk1YiIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2UsICJodW1hbl9pbnB1
dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAiRnJpZW5kbHkgTmVpZ2hib3IiLCAiYWdlbnRfa2V5
IjogIjk4ZjNiMWQ0N2NlOTY5Y2YwNTc3MjdiNzg0MTQyNWNkIiwgInRvb2xzX25hbWVzIjogWyJk
ZWNpZGUgZ3JlZXRpbmdzIl19XXoCGAGFAQABAAASjgIKECu51qyePo8nKoICNJZ02pMSCCjCEeTQ
OjkdKgxUYXNrIENyZWF0ZWQwATnBBninpocjGEE/9XinpocjGEouCghjcmV3X2tleRIiCiBjMzA3
NjAwOTMyNjc2MTQ0NGQ1N2M3MWQxZGEzZjI3Y0oxCgdjcmV3X2lkEiYKJDE4ZDM2MTRjLThmMzMt
NGJjYy04MmYxLTUyYzhhMzQ0NGFiYkouCgh0YXNrX2tleRIiCiA4MGQ3YmNkNDkwOTkyOTAwODM4
MzJmMGU5ODMzODBkZkoxCgd0YXNrX2lkEiYKJDIxYWY3MGNmLTAwMjgtNDMzMy1iOTQ0LTNmZGRl
MDk0Yzk1YnoCGAGFAQABAAASlAEKEP375HtPk4PSSyJYXfVClzMSCD4pN5nJzh+6KgpUb29sIFVz
YWdlMAE5340IqKaHIxhBuEQZqKaHIxhKGwoOY3Jld2FpX3ZlcnNpb24SCQoHMC4xMDAuMUofCgl0
b29sX25hbWUSEgoQRGVjaWRlIEdyZWV0aW5nc0oOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAA
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '15672'
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, 12 Feb 2025 17:57:13 GMT
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,87 @@
interactions:
- request:
body: '{"messages": [{"role": "system", "content": "You are test role. test backstory\nYour
personal goal is: test goal\nTo give my best complete final answer to the task
respond using the exact following format:\n\nThought: I now can give a great
answer\nFinal Answer: Your final answer must be the great and the most complete
as possible, it must be outcome described.\n\nI MUST use these formats, my job
depends on it!"}, {"role": "user", "content": "\nCurrent Task: Test task\n\nThis
is the expected criteria for your final answer: Test output\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:"]}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '811'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.61.0
x-stainless-arch:
- x64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- Linux
x-stainless-package-version:
- 1.61.0
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 \"error\": {\n \"message\": \"Incorrect API key provided:
sk-proj-********************************************************************************************************************************************************sLcA.
You can find your API key at https://platform.openai.com/account/api-keys.\",\n
\ \"type\": \"invalid_request_error\",\n \"param\": null,\n \"code\":
\"invalid_api_key\"\n }\n}\n"
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 910f1c7ccc8127f2-SEA
Connection:
- keep-alive
Content-Length:
- '414'
Content-Type:
- application/json; charset=utf-8
Date:
- Wed, 12 Feb 2025 19:51:04 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=uoaTXzwc1Tflq58CAcpdIc5LJh9YYja0fjw1f6h9WAw-1739389864-1.0.1.1-Ka49kxdgi8wyYRkDXc.Os2ipvsC.ix_sMqVQlLOpR2S1GwoPVnJhFDI59yvwNeTdTgt.BGGvVafkitRFhUAikw;
path=/; expires=Wed, 12-Feb-25 20:21:04 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=0mZZJhB4.6zG3zb_yZrfjjsFaLI9JTnoBgNzXw6chnU-1739389864561-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
X-Content-Type-Options:
- nosniff
alt-svc:
- h3=":443"; ma=86400
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
vary:
- Origin
x-request-id:
- req_aad5d7ba9d16d23112bcbae8689a4630
http_version: HTTP/1.1
status_code: 401
version: 1