diff --git a/src/crewai/agents/crew_agent_executor.py b/src/crewai/agents/crew_agent_executor.py index 11b3fed5f..f7bf57e8c 100644 --- a/src/crewai/agents/crew_agent_executor.py +++ b/src/crewai/agents/crew_agent_executor.py @@ -104,11 +104,23 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): try: while not isinstance(formatted_answer, AgentFinish): if not self.request_within_rpm_limit or self.request_within_rpm_limit(): - answer = LLM( - self.llm, - stop=self.stop if self.use_stop_words else None, - callbacks=self.callbacks, - ).call(self.messages) + if isinstance(self.llm, str): + llm = LLM( + model=self.llm, + stop=self.stop if self.use_stop_words else None, + callbacks=self.callbacks, + ) + elif isinstance(self.llm, LLM): + llm = self.llm + else: + llm = LLM( + model=self.llm.model, + provider=getattr(self.llm, "provider", "litellm"), + stop=self.stop if self.use_stop_words else None, + callbacks=self.callbacks, + **getattr(self.llm, "llm_kwargs", {}), + ) + answer = llm.call(self.messages) if not self.use_stop_words: try: @@ -241,7 +253,16 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): return tool_result def _summarize_messages(self) -> None: - llm = LLM(self.llm) + if isinstance(self.llm, str): + llm = LLM(model=self.llm) + elif isinstance(self.llm, LLM): + llm = self.llm + else: + llm = LLM( + model=self.llm.model, + provider=getattr(self.llm, "provider", "litellm"), + **getattr(self.llm, "llm_kwargs", {}), + ) messages_groups = [] for message in self.messages: diff --git a/src/crewai/llm.py b/src/crewai/llm.py index 3fc1006cc..8c9f8ecfe 100644 --- a/src/crewai/llm.py +++ b/src/crewai/llm.py @@ -1,20 +1,86 @@ -from typing import Any, Dict, List -from litellm import completion +from typing import Any, Dict, List, Optional, Union +import logging import litellm class LLM: - def __init__(self, model: str, stop: List[str] = [], callbacks: List[Any] = []): - self.stop = stop + def __init__( + self, + model: str, + timeout: Optional[Union[float, int]] = None, + temperature: Optional[float] = None, + top_p: Optional[float] = None, + n: Optional[int] = None, + stop: Optional[Union[str, List[str]]] = None, + max_completion_tokens: Optional[int] = None, + max_tokens: Optional[int] = None, + presence_penalty: Optional[float] = None, + frequency_penalty: Optional[float] = None, + logit_bias: Optional[Dict[int, float]] = None, + response_format: Optional[Dict[str, Any]] = None, + seed: Optional[int] = None, + logprobs: Optional[bool] = None, + top_logprobs: Optional[int] = None, + base_url: Optional[str] = None, + api_version: Optional[str] = None, + api_key: Optional[str] = None, + callbacks: List[Any] = [], + **kwargs, + ): self.model = model + self.timeout = timeout + self.temperature = temperature + self.top_p = top_p + self.n = n + self.stop = stop + self.max_completion_tokens = max_completion_tokens + self.max_tokens = max_tokens + self.presence_penalty = presence_penalty + self.frequency_penalty = frequency_penalty + self.logit_bias = logit_bias + self.response_format = response_format + self.seed = seed + self.logprobs = logprobs + self.top_logprobs = top_logprobs + self.base_url = base_url + self.api_version = api_version + self.api_key = api_key + self.callbacks = callbacks + self.kwargs = kwargs + litellm.callbacks = callbacks - def call(self, messages: List[Dict[str, str]]) -> Dict[str, Any]: - response = completion( - stop=self.stop, model=self.model, messages=messages, num_retries=5 - ) - return response["choices"][0]["message"]["content"] + def call(self, messages: List[Dict[str, str]]) -> str: + try: + params = { + "model": self.model, + "messages": messages, + "timeout": self.timeout, + "temperature": self.temperature, + "top_p": self.top_p, + "n": self.n, + "stop": self.stop, + "max_tokens": self.max_tokens or self.max_completion_tokens, + "presence_penalty": self.presence_penalty, + "frequency_penalty": self.frequency_penalty, + "logit_bias": self.logit_bias, + "response_format": self.response_format, + "seed": self.seed, + "logprobs": self.logprobs, + "top_logprobs": self.top_logprobs, + "api_base": self.base_url, + "api_version": self.api_version, + "api_key": self.api_key, + **self.kwargs, + } + # Remove None values to avoid passing unnecessary parameters + params = {k: v for k, v in params.items() if v is not None} - def _call_callbacks(self, formatted_answer): - for callback in self.callbacks: - callback(formatted_answer) + response = litellm.completion(**params) + return response["choices"][0]["message"]["content"] + except Exception as e: + logging.error(f"LiteLLM call failed: {str(e)}") + raise # Re-raise the exception after logging + + def __getattr__(self, name): + return self.kwargs.get(name) diff --git a/src/crewai/utilities/converter.py b/src/crewai/utilities/converter.py index 23508d8a5..7a1664784 100644 --- a/src/crewai/utilities/converter.py +++ b/src/crewai/utilities/converter.py @@ -27,7 +27,8 @@ class Converter(OutputConverter): if self.is_gpt: return self._create_instructor().to_pydantic() else: - return LLM(model=self.llm).call( + llm = self._create_llm() + return llm.call( [ {"role": "system", "content": self.instructions}, {"role": "user", "content": self.text}, @@ -46,8 +47,9 @@ class Converter(OutputConverter): if self.is_gpt: return self._create_instructor().to_json() else: + llm = self._create_llm() return json.dumps( - LLM(model=self.llm).call( + llm.call( [ {"role": "system", "content": self.instructions}, {"role": "user", "content": self.text}, @@ -59,6 +61,19 @@ class Converter(OutputConverter): return self.to_json(current_attempt + 1) return ConverterError(f"Failed to convert text into JSON, error: {e}.") + def _create_llm(self): + """Create an LLM instance.""" + if isinstance(self.llm, str): + return LLM(model=self.llm) + elif isinstance(self.llm, LLM): + return self.llm + else: + return LLM( + model=self.llm.model, + provider=getattr(self.llm, "provider", "litellm"), + **getattr(self.llm, "llm_kwargs", {}), + ) + def _create_instructor(self): """Create an instructor.""" from crewai.utilities import InternalInstructor diff --git a/tests/agent_test.py b/tests/agent_test.py index 75ecc8d89..7fbc03587 100644 --- a/tests/agent_test.py +++ b/tests/agent_test.py @@ -51,6 +51,50 @@ def test_custom_llm_with_langchain(): assert agent.llm == "gpt-4" +def test_custom_llm_temperature_preservation(): + from langchain_openai import ChatOpenAI + + langchain_llm = ChatOpenAI(temperature=0.7, model="gpt-4") + agent = Agent( + role="temperature test role", + goal="temperature test goal", + backstory="temperature test backstory", + llm=langchain_llm, + ) + + assert isinstance(agent.llm, LLM) + assert agent.llm.model == "gpt-4" + assert agent.llm.temperature == 0.7 + + +@pytest.mark.vcr(filter_headers=["authorization"]) +def test_agent_execute_task(): + from langchain_openai import ChatOpenAI + from crewai import Task + + agent = Agent( + role="Math Tutor", + goal="Solve math problems accurately", + backstory="You are an experienced math tutor with a knack for explaining complex concepts simply.", + llm=ChatOpenAI(temperature=0.7, model="gpt-4o-mini"), + ) + + task = Task( + description="Calculate the area of a circle with radius 5 cm.", + expected_output="The calculated area of the circle in square centimeters.", + agent=agent, + ) + + result = agent.execute_task(task) + + assert result is not None + assert ( + "The area of a circle with a radius of 5 cm is calculated using the formula A = πr^2, where A is the area and r is the...in the values, we get A = π*5^2 = 25π square centimeters. Therefore, the area of the circle is 25π square centimeters." + in result + ) + assert "square centimeters" in result.lower() + + @pytest.mark.vcr(filter_headers=["authorization"]) def test_agent_execution(): agent = Agent( @@ -67,7 +111,7 @@ def test_agent_execution(): ) output = agent.execute_task(task) - assert output == "1 + 1 = 2" + assert output == "The result of the math operation 1 + 1 is 2." @pytest.mark.vcr(filter_headers=["authorization"]) @@ -182,7 +226,7 @@ def test_cache_hitting(): task = Task( description="What is 2 times 6? Ignore correctness and just return the result of the multiplication tool, you must use the tool.", agent=agent, - expected_output="The number that is the result of the multiplication.", + expected_output="The number that is the result of the multiplication tool.", ) output = agent.execute_task(task) assert output == "0" @@ -1102,6 +1146,88 @@ def test_agent_max_retry_limit(): ) +def test_agent_with_llm(): + agent = Agent( + role="test role", + goal="test goal", + backstory="test backstory", + llm=LLM(model="gpt-3.5-turbo", temperature=0.7), + ) + + assert isinstance(agent.llm, LLM) + assert agent.llm.model == "gpt-3.5-turbo" + assert agent.llm.temperature == 0.7 + + +def test_agent_with_custom_stop_words(): + stop_words = ["STOP", "END"] + agent = Agent( + role="test role", + goal="test goal", + backstory="test backstory", + llm=LLM(model="gpt-3.5-turbo", stop=stop_words), + ) + + assert isinstance(agent.llm, LLM) + assert agent.llm.stop == stop_words + + +def test_agent_with_callbacks(): + def dummy_callback(response): + pass + + agent = Agent( + role="test role", + goal="test goal", + backstory="test backstory", + llm=LLM(model="gpt-3.5-turbo", callbacks=[dummy_callback]), + ) + + assert isinstance(agent.llm, LLM) + assert len(agent.llm.callbacks) == 1 + assert agent.llm.callbacks[0] == dummy_callback + + +def test_agent_with_additional_kwargs(): + agent = Agent( + role="test role", + goal="test goal", + backstory="test backstory", + llm=LLM( + model="gpt-3.5-turbo", + temperature=0.8, + top_p=0.9, + presence_penalty=0.1, + frequency_penalty=0.1, + ), + ) + + assert isinstance(agent.llm, LLM) + assert agent.llm.model == "gpt-3.5-turbo" + assert agent.llm.temperature == 0.8 + assert agent.llm.top_p == 0.9 + assert agent.llm.presence_penalty == 0.1 + assert agent.llm.frequency_penalty == 0.1 + + +@pytest.mark.vcr(filter_headers=["authorization"]) +def test_llm_call(): + llm = LLM(model="gpt-3.5-turbo") + messages = [{"role": "user", "content": "Say 'Hello, World!'"}] + + response = llm.call(messages) + assert "Hello, World!" in response + + +@pytest.mark.vcr(filter_headers=["authorization"]) +def test_llm_call_with_error(): + llm = LLM(model="non-existent-model") + messages = [{"role": "user", "content": "This should fail"}] + + with pytest.raises(Exception): + llm.call(messages) + + @pytest.mark.vcr(filter_headers=["authorization"]) def test_handle_context_length_exceeds_limit(): agent = Agent( @@ -1172,3 +1298,213 @@ def test_handle_context_length_exceeds_limit_cli_no(): CrewAgentExecutor, "_handle_context_length" ) as mock_handle_context: mock_handle_context.assert_not_called() + + +def test_agent_with_all_llm_attributes(): + agent = Agent( + role="test role", + goal="test goal", + backstory="test backstory", + llm=LLM( + model="gpt-3.5-turbo", + timeout=10, + temperature=0.7, + top_p=0.9, + n=1, + stop=["STOP", "END"], + max_tokens=100, + presence_penalty=0.1, + frequency_penalty=0.1, + logit_bias={50256: -100}, # Example: bias against the EOT token + response_format={"type": "json_object"}, + seed=42, + logprobs=True, + top_logprobs=5, + base_url="https://api.openai.com/v1", + api_version="2023-05-15", + api_key="sk-your-api-key-here", + ), + ) + + assert isinstance(agent.llm, LLM) + assert agent.llm.model == "gpt-3.5-turbo" + assert agent.llm.timeout == 10 + assert agent.llm.temperature == 0.7 + assert agent.llm.top_p == 0.9 + assert agent.llm.n == 1 + assert agent.llm.stop == ["STOP", "END"] + assert agent.llm.max_tokens == 100 + assert agent.llm.presence_penalty == 0.1 + assert agent.llm.frequency_penalty == 0.1 + assert agent.llm.logit_bias == {50256: -100} + assert agent.llm.response_format == {"type": "json_object"} + assert agent.llm.seed == 42 + assert agent.llm.logprobs + assert agent.llm.top_logprobs == 5 + assert agent.llm.base_url == "https://api.openai.com/v1" + assert agent.llm.api_version == "2023-05-15" + assert agent.llm.api_key == "sk-your-api-key-here" + + +@pytest.mark.vcr(filter_headers=["authorization"]) +def test_llm_call_with_all_attributes(): + llm = LLM( + model="gpt-3.5-turbo", + temperature=0.7, + max_tokens=50, + stop=["STOP"], + presence_penalty=0.1, + frequency_penalty=0.1, + ) + messages = [{"role": "user", "content": "Say 'Hello, World!' and then say STOP"}] + + response = llm.call(messages) + assert "Hello, World!" in response + assert "STOP" not in response + + +@pytest.mark.vcr(filter_headers=["authorization"]) +def test_agent_with_ollama_gemma(): + agent = Agent( + role="test role", + goal="test goal", + backstory="test backstory", + llm=LLM( + model="ollama/gemma2:latest", + base_url="http://localhost:8080", + ), + ) + + assert isinstance(agent.llm, LLM) + assert agent.llm.model == "ollama/gemma2:latest" + assert agent.llm.base_url == "http://localhost:8080" + + task = "Respond in 20 words. Who are you?" + response = agent.llm.call([{"role": "user", "content": task}]) + + assert response + assert len(response.split()) <= 25 # Allow a little flexibility in word count + assert "Gemma" in response or "AI" in response or "language model" in response + + +@pytest.mark.vcr(filter_headers=["authorization"]) +def test_llm_call_with_ollama_gemma(): + llm = LLM( + model="ollama/gemma2:latest", + base_url="http://localhost:8080", + temperature=0.7, + max_tokens=30, + ) + messages = [{"role": "user", "content": "Respond in 20 words. Who are you?"}] + + response = llm.call(messages) + + assert response + assert len(response.split()) <= 25 # Allow a little flexibility in word count + assert "Gemma" in response or "AI" in response or "language model" in response + + +@pytest.mark.vcr(filter_headers=["authorization"]) +def test_agent_execute_task_basic(): + agent = Agent( + role="test role", + goal="test goal", + backstory="test backstory", + llm=LLM(model="gpt-3.5-turbo"), + ) + + task = Task( + description="Calculate 2 + 2", + expected_output="The result of the calculation", + agent=agent, + ) + + result = agent.execute_task(task) + assert "4" in result + + +@pytest.mark.vcr(filter_headers=["authorization"]) +def test_agent_execute_task_with_context(): + agent = Agent( + role="test role", + goal="test goal", + backstory="test backstory", + llm=LLM(model="gpt-3.5-turbo"), + ) + + task = Task( + description="Summarize the given context in one sentence", + expected_output="A one-sentence summary", + agent=agent, + ) + + context = "The quick brown fox jumps over the lazy dog. This sentence contains every letter of the alphabet." + + result = agent.execute_task(task, context=context) + assert len(result.split(".")) == 3 + assert "fox" in result.lower() and "dog" in result.lower() + + +@pytest.mark.vcr(filter_headers=["authorization"]) +def test_agent_execute_task_with_tool(): + @tool + def dummy_tool(query: str) -> str: + """Useful for when you need to get a dummy result for a query.""" + return f"Dummy result for: {query}" + + agent = Agent( + role="test role", + goal="test goal", + backstory="test backstory", + llm=LLM(model="gpt-3.5-turbo"), + tools=[dummy_tool], + ) + + task = Task( + description="Use the dummy tool to get a result for 'test query'", + expected_output="The result from the dummy tool", + agent=agent, + ) + + result = agent.execute_task(task) + assert "Dummy result for: test query" in result + + +@pytest.mark.vcr(filter_headers=["authorization"]) +def test_agent_execute_task_with_custom_llm(): + agent = Agent( + role="test role", + goal="test goal", + backstory="test backstory", + llm=LLM(model="gpt-3.5-turbo", temperature=0.7, max_tokens=50), + ) + + task = Task( + description="Write a haiku about AI", + expected_output="A haiku (3 lines, 5-7-5 syllable pattern) about AI", + agent=agent, + ) + + result = agent.execute_task(task) + assert len(result.split("\n")) == 3 + assert "AI" in result or "artificial intelligence" in result.lower() + + +@pytest.mark.vcr(filter_headers=["authorization"]) +def test_agent_execute_task_with_ollama(): + agent = Agent( + role="test role", + goal="test goal", + backstory="test backstory", + llm=LLM(model="ollama/gemma2:latest", base_url="http://localhost:8080"), + ) + + task = Task( + description="Explain what AI is in one sentence", + expected_output="A one-sentence explanation of AI", + agent=agent, + ) + + result = agent.execute_task(task) + assert len(result.split(".")) == 2 + assert "AI" in result or "artificial intelligence" in result.lower() diff --git a/tests/cassettes/test_agent_execute_task.yaml b/tests/cassettes/test_agent_execute_task.yaml new file mode 100644 index 000000000..02e74b099 --- /dev/null +++ b/tests/cassettes/test_agent_execute_task.yaml @@ -0,0 +1,113 @@ +interactions: +- request: + body: '{"messages": [{"role": "system", "content": "You are Math Tutor. You are + an experienced math tutor with a knack for explaining complex concepts simply.\nYour + personal goal is: Solve math problems accurately\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: Calculate + the area of a circle with radius 5 cm.\n\nThis is the expect criteria for your + final answer: The calculated area of the circle in square centimeters.\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-3.5-turbo", "temperature": + 0.7}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '971' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.47.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.47.0 + x-stainless-raw-response: + - 'true' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.11.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + content: "{\n \"id\": \"chatcmpl-AAS0lhHgefJ8xPU6zCPtob5F78940\",\n \"object\": + \"chat.completion\",\n \"created\": 1727054319,\n \"model\": \"gpt-3.5-turbo-0125\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"I now can give a great answer\\n\\nFinal + Answer: The area of a circle with a radius of 5 cm is calculated using the formula + A = \u03C0r^2, where A is the area and r is the radius. Plugging in the values, + we get A = \u03C0*5^2 = 25\u03C0 square centimeters. Therefore, the area of + the circle is 25\u03C0 square centimeters.\",\n \"refusal\": null\n },\n + \ \"logprobs\": null,\n \"finish_reason\": \"stop\"\n }\n ],\n + \ \"usage\": {\n \"prompt_tokens\": 183,\n \"completion_tokens\": 84,\n + \ \"total_tokens\": 267,\n \"completion_tokens_details\": {\n \"reasoning_tokens\": + 0\n }\n },\n \"system_fingerprint\": null\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8c76b3b72c793349-MIA + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Mon, 23 Sep 2024 01:18:40 GMT + Server: + - cloudflare + Set-Cookie: + - __cf_bm=TeTRbPiJaFK4ahD.Jcn.OXJKBhZ9em1uRlh96HCWPrw-1727054320-1.0.1.1-wynsdWOtpQFneOccmdqt94MLYqbP4aS3uErVbl5gzBp48yD2CWJx.S83LGs73v2rv70MrWf67VaH_Df8zmYvFA; + path=/; expires=Mon, 23-Sep-24 01:48:40 GMT; domain=.api.openai.com; HttpOnly; + Secure; SameSite=None + - _cfuvid=ufNZ8SuxXI8q3rj.hIWfLMY49QRTHLKc5qY0rZhKi9Y-1727054320731-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 + openai-organization: + - crewai-iuxna1 + openai-processing-ms: + - '1390' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=15552000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '50000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '49999774' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_55824505fec1d9fbaa123884d57d4a75 + http_version: HTTP/1.1 + status_code: 200 +version: 1 diff --git a/tests/cassettes/test_agent_execute_task_basic.yaml b/tests/cassettes/test_agent_execute_task_basic.yaml new file mode 100644 index 000000000..d3e0cb218 --- /dev/null +++ b/tests/cassettes/test_agent_execute_task_basic.yaml @@ -0,0 +1,103 @@ +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 + 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: Calculate 2 + 2\n\nThis + is the expect criteria for your final answer: The result of the calculation\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-3.5-turbo"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '797' + content-type: + - application/json + cookie: + - _cfuvid=ntPBCCgVUz_nq5Umsn4Dh2nras_FFFm.Om6wrSeiU00-1727053206899-0.0.1.1-604800000; + __cf_bm=XKEjZqa9jLHDkJm09f6GoOFObGBsS.2iO2iQsVxfDtg-1727053206-1.0.1.1-AhT2h4tFAfFhcbWhI7x8he9L6T0eCndS2.n6pMSK3iFkx0qYlA5Y.iniDaQVaO1ukiEEoEJGaV2tL967WYm1uA + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.47.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.47.0 + x-stainless-raw-response: + - 'true' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.11.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + content: "{\n \"id\": \"chatcmpl-AARwTz7nEspXcCfGPhfX4gOWPMiLA\",\n \"object\": + \"chat.completion\",\n \"created\": 1727054053,\n \"model\": \"gpt-3.5-turbo-0125\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"I now can give a great answer\\n\\nFinal + Answer: 2 + 2 equals 4.\",\n \"refusal\": null\n },\n \"logprobs\": + null,\n \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": + 159,\n \"completion_tokens\": 20,\n \"total_tokens\": 179,\n \"completion_tokens_details\": + {\n \"reasoning_tokens\": 0\n }\n },\n \"system_fingerprint\": null\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8c76ad36998e8db8-MIA + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Mon, 23 Sep 2024 01:14:13 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + openai-organization: + - crewai-iuxna1 + openai-processing-ms: + - '424' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=15552000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '50000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '49999813' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_0042687a7f7155cdd6c0a7c1e2559776 + http_version: HTTP/1.1 + status_code: 200 +version: 1 diff --git a/tests/cassettes/test_agent_execute_task_with_context.yaml b/tests/cassettes/test_agent_execute_task_with_context.yaml new file mode 100644 index 000000000..fb97f3169 --- /dev/null +++ b/tests/cassettes/test_agent_execute_task_with_context.yaml @@ -0,0 +1,106 @@ +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 + 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: Summarize the given context + in one sentence\n\nThis is the expect criteria for your final answer: A one-sentence + summary\nyou MUST return the actual complete content as the final answer, not + a summary.\n\nThis is the context you''re working with:\nThe quick brown fox + jumps over the lazy dog. This sentence contains every letter of the alphabet.\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-3.5-turbo"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '961' + content-type: + - application/json + cookie: + - _cfuvid=ntPBCCgVUz_nq5Umsn4Dh2nras_FFFm.Om6wrSeiU00-1727053206899-0.0.1.1-604800000; + __cf_bm=XKEjZqa9jLHDkJm09f6GoOFObGBsS.2iO2iQsVxfDtg-1727053206-1.0.1.1-AhT2h4tFAfFhcbWhI7x8he9L6T0eCndS2.n6pMSK3iFkx0qYlA5Y.iniDaQVaO1ukiEEoEJGaV2tL967WYm1uA + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.47.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.47.0 + x-stainless-raw-response: + - 'true' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.11.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + content: "{\n \"id\": \"chatcmpl-AARwTOWtkUdr9uvFYYWDMqA3O3Vvn\",\n \"object\": + \"chat.completion\",\n \"created\": 1727054053,\n \"model\": \"gpt-3.5-turbo-0125\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"I now can give a great answer.\\n\\nFinal + Answer: The quick brown fox jumps over the lazy dog. This sentence contains + every letter of the alphabet.\",\n \"refusal\": null\n },\n \"logprobs\": + null,\n \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": + 190,\n \"completion_tokens\": 30,\n \"total_tokens\": 220,\n \"completion_tokens_details\": + {\n \"reasoning_tokens\": 0\n }\n },\n \"system_fingerprint\": null\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8c76ad3b686f8db8-MIA + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Mon, 23 Sep 2024 01:14:14 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + openai-organization: + - crewai-iuxna1 + openai-processing-ms: + - '328' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=15552000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '50000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '49999772' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_5da2e2d9161cf5f4f9e5869ff64b9133 + http_version: HTTP/1.1 + status_code: 200 +version: 1 diff --git a/tests/cassettes/test_agent_execute_task_with_custom_llm.yaml b/tests/cassettes/test_agent_execute_task_with_custom_llm.yaml new file mode 100644 index 000000000..e82fd0a7b --- /dev/null +++ b/tests/cassettes/test_agent_execute_task_with_custom_llm.yaml @@ -0,0 +1,105 @@ +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 + 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: Write a haiku about AI\n\nThis + is the expect criteria for your final answer: A haiku (3 lines, 5-7-5 syllable + pattern) about AI\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-3.5-turbo", "max_tokens": 50, "temperature": 0.7}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '863' + content-type: + - application/json + cookie: + - _cfuvid=ntPBCCgVUz_nq5Umsn4Dh2nras_FFFm.Om6wrSeiU00-1727053206899-0.0.1.1-604800000; + __cf_bm=XKEjZqa9jLHDkJm09f6GoOFObGBsS.2iO2iQsVxfDtg-1727053206-1.0.1.1-AhT2h4tFAfFhcbWhI7x8he9L6T0eCndS2.n6pMSK3iFkx0qYlA5Y.iniDaQVaO1ukiEEoEJGaV2tL967WYm1uA + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.47.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.47.0 + x-stainless-raw-response: + - 'true' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.11.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + content: "{\n \"id\": \"chatcmpl-AARwUOwdCef7zlbZVd35TW4Dh7TCb\",\n \"object\": + \"chat.completion\",\n \"created\": 1727054054,\n \"model\": \"gpt-3.5-turbo-0125\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"I now can give a great answer\\n\\nFinal + Answer: Artificial minds,\\nLearning, evolving, creating,\\nAI's future shines.\",\n + \ \"refusal\": null\n },\n \"logprobs\": null,\n \"finish_reason\": + \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": 173,\n \"completion_tokens\": + 25,\n \"total_tokens\": 198,\n \"completion_tokens_details\": {\n \"reasoning_tokens\": + 0\n }\n },\n \"system_fingerprint\": null\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8c76ad41c8748db8-MIA + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Mon, 23 Sep 2024 01:14:15 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + openai-organization: + - crewai-iuxna1 + openai-processing-ms: + - '309' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=15552000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '50000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '49999771' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_99e66f59c3f84fd35bc2613cfabc05fb + http_version: HTTP/1.1 + status_code: 200 +version: 1 diff --git a/tests/cassettes/test_agent_execute_task_with_ollama.yaml b/tests/cassettes/test_agent_execute_task_with_ollama.yaml new file mode 100644 index 000000000..98a2d27a6 --- /dev/null +++ b/tests/cassettes/test_agent_execute_task_with_ollama.yaml @@ -0,0 +1,426 @@ +interactions: +- request: + body: !!binary | + CuWbAQokCiIKDHNlcnZpY2UubmFtZRISChBjcmV3QUktdGVsZW1ldHJ5ErubAQoSChBjcmV3YWku + dGVsZW1ldHJ5ErEHChBBZJ7PYzbEDjTtQdgrPfBuEgg5It3s4JT45yoMQ3JldyBDcmVhdGVkMAE5 + oBgwiYK69xdBMHgxiYK69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42MS4wShoKDnB5dGhvbl92 + ZXJzaW9uEggKBjMuMTEuN0ouCghjcmV3X2tleRIiCiBkNTUxMTNiZTRhYTQxYmE2NDNkMzI2MDQy + YjJmMDNmMUoxCgdjcmV3X2lkEiYKJGJjNDQwNThlLWIxNDMtNDNjYi04MWZhLWY5N2I0MmFjYjE0 + NkocCgxjcmV3X3Byb2Nlc3MSDAoKc2VxdWVudGlhbEoRCgtjcmV3X21lbW9yeRICEABKGgoUY3Jl + d19udW1iZXJfb2ZfdGFza3MSAhgBShsKFWNyZXdfbnVtYmVyX29mX2FnZW50cxICGAFKzgIKC2Ny + ZXdfYWdlbnRzEr4CCrsCW3sia2V5IjogImUxNDhlNTMyMDI5MzQ5OWY4Y2ViZWE4MjZlNzI1ODJi + IiwgImlkIjogIjAyMjIxYzM5LTY0MDctNDgzZS05NTMyLTBmOTYxOTQyMzA3NCIsICJyb2xlIjog + InRlc3Qgcm9sZSIsICJ2ZXJib3NlPyI6IHRydWUsICJtYXhfaXRlciI6IDQsICJtYXhfcnBtIjog + MTAsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6IG51bGwsICJsbG0iOiAiZ3B0LTRvLW1pbmkiLCAi + ZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29kZV9leGVjdXRpb24/IjogZmFs + c2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMiOiBbXX1dSpACCgpjcmV3X3Rh + c2tzEoECCv4BW3sia2V5IjogIjRhMzFiODUxMzNhM2EyOTRjNjg1M2RhNzU3ZDRiYWU3IiwgImlk + IjogImUyNjBmZTAwLWJmYWUtNGVhYi1hZTk3LWQ4MjdiMTQ1MWZkOCIsICJhc3luY19leGVjdXRp + b24/IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAidGVzdCBy + b2xlIiwgImFnZW50X2tleSI6ICJlMTQ4ZTUzMjAyOTM0OTlmOGNlYmVhODI2ZTcyNTgyYiIsICJ0 + b29sc19uYW1lcyI6IFsiZ2V0X2ZpbmFsX2Fuc3dlciJdfV16AhgBhQEAAQAAEo4CChDMPKWZ/a1f + FgDkPKtY4+SfEggLYooU0vVPFSoMVGFzayBDcmVhdGVkMAE5aPc9iYK69xdBiEU+iYK69xdKLgoI + Y3Jld19rZXkSIgogZDU1MTEzYmU0YWE0MWJhNjQzZDMyNjA0MmIyZjAzZjFKMQoHY3Jld19pZBIm + CiRiYzQ0MDU4ZS1iMTQzLTQzY2ItODFmYS1mOTdiNDJhY2IxNDZKLgoIdGFza19rZXkSIgogNGEz + MWI4NTEzM2EzYTI5NGM2ODUzZGE3NTdkNGJhZTdKMQoHdGFza19pZBImCiRlMjYwZmUwMC1iZmFl + LTRlYWItYWU5Ny1kODI3YjE0NTFmZDh6AhgBhQEAAQAAEpMBChC5KZDqzWUtR9YQocAIKVIxEgg7 + q28qvWlLGioKVG9vbCBVc2FnZTABOajecImCuvcXQViScYmCuvcXShoKDmNyZXdhaV92ZXJzaW9u + EggKBjAuNjEuMEofCgl0b29sX25hbWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxIC + GAF6AhgBhQEAAQAAEpwBChC+gf4UfL1zxayMkkdRy3N4EgjqNOJNVxzVwioTVG9vbCBSZXBlYXRl + ZCBVc2FnZTABOegBmomCuvcXQeCpmomCuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEof + Cgl0b29sX25hbWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAA + EpMBChDdI+nOxRAr4azVcEBaUJKxEgjWqAeF/Rfc6CoKVG9vbCBVc2FnZTABOZA9yomCuvcXQRD5 + yomCuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEofCgl0b29sX25hbWUSEgoQZ2V0X2Zp + bmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpMBChCU1SqkGUyL521cU9rN7cKY + EghCsIEYjqVHOyoKVG9vbCBVc2FnZTABOShS+omCuvcXQZjm+omCuvcXShoKDmNyZXdhaV92ZXJz + aW9uEggKBjAuNjEuMEofCgl0b29sX25hbWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0 + cxICGAF6AhgBhQEAAQAAEpACChCCE3d7/3axG1/dvzJevV8EEggZMvEKjSITOSoOVGFzayBFeGVj + dXRpb24wATk4fD6Jgrr3F0GwOSuKgrr3F0ouCghjcmV3X2tleRIiCiBkNTUxMTNiZTRhYTQxYmE2 + NDNkMzI2MDQyYjJmMDNmMUoxCgdjcmV3X2lkEiYKJGJjNDQwNThlLWIxNDMtNDNjYi04MWZhLWY5 + N2I0MmFjYjE0NkouCgh0YXNrX2tleRIiCiA0YTMxYjg1MTMzYTNhMjk0YzY4NTNkYTc1N2Q0YmFl + N0oxCgd0YXNrX2lkEiYKJGUyNjBmZTAwLWJmYWUtNGVhYi1hZTk3LWQ4MjdiMTQ1MWZkOHoCGAGF + AQABAAAS3AsKEG7QBv1rCGhRtSdsVl0ffQ4SCPludOUOhyoLKgxDcmV3IENyZWF0ZWQwATlguYeK + grr3F0GwdomKgrr3F0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjYxLjBKGgoOcHl0aG9uX3ZlcnNp + b24SCAoGMy4xMS43Si4KCGNyZXdfa2V5EiIKIDk0YzMwZDZjM2IyYWM4ZmI5NGIyZGNmYzU3MmQw + ZjU5SjEKB2NyZXdfaWQSJgokZTFiYTM1OTQtM2EzYy00M2RjLWIyOWEtODA1ZjEyMjYzYTlhShwK + DGNyZXdfcHJvY2VzcxIMCgpzZXF1ZW50aWFsShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251 + bWJlcl9vZl90YXNrcxICGAJKGwoVY3Jld19udW1iZXJfb2ZfYWdlbnRzEgIYAkqMBQoLY3Jld19h + Z2VudHMS/AQK+QRbeyJrZXkiOiAiZTE0OGU1MzIwMjkzNDk5ZjhjZWJlYTgyNmU3MjU4MmIiLCAi + aWQiOiAiOTE1Y2NkOTAtOGMyNC00MWQ0LTkzNTQtMjJkNWZhMDc2ODIwIiwgInJvbGUiOiAidGVz + dCByb2xlIiwgInZlcmJvc2U/IjogdHJ1ZSwgIm1heF9pdGVyIjogMiwgIm1heF9ycG0iOiAxMCwg + ImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogbnVsbCwgImxsbSI6ICJncHQtNG8tbWluaSIsICJkZWxl + Z2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8iOiBmYWxzZSwg + Im1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtdfSwgeyJrZXkiOiAiZTdlOGVl + YTg4NmJjYjhmMTA0NWFiZWVjZjE0MjVkYjciLCAiaWQiOiAiZDFkYjZlNmQtNDAyZC00ZmM5LWFk + OGItZmVhZjE2MjM2YjZjIiwgInJvbGUiOiAidGVzdCByb2xlMiIsICJ2ZXJib3NlPyI6IHRydWUs + ICJtYXhfaXRlciI6IDEsICJtYXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjog + bnVsbCwgImxsbSI6ICJncHQtNG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2Us + ICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0 + b29sc19uYW1lcyI6IFtdfV1K/QMKCmNyZXdfdGFza3MS7gMK6wNbeyJrZXkiOiAiMzIyZGRhZTNi + YzgwYzFkNDViODVmYTc3NTZkYjg2NjUiLCAiaWQiOiAiMDNkMWIyNDQtMTUzMC00YWY1LWE3ZDYt + ZTg4MmUzOWE1OWVlIiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6 + IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJ0ZXN0IHJvbGUiLCAiYWdlbnRfa2V5IjogImUxNDhlNTMy + MDI5MzQ5OWY4Y2ViZWE4MjZlNzI1ODJiIiwgInRvb2xzX25hbWVzIjogW119LCB7ImtleSI6ICI1 + ZTljYTdkNjRiNDIwNWJiN2M0N2UwYjNmY2I1ZDIxZiIsICJpZCI6ICJjODlkODhiMC0zNmI1LTQw + YTYtOWUxNS0wMjc3YzJkNTg3MWIiLCAiYXN5bmNfZXhlY3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5f + aW5wdXQ/IjogZmFsc2UsICJhZ2VudF9yb2xlIjogInRlc3Qgcm9sZTIiLCAiYWdlbnRfa2V5Ijog + ImU3ZThlZWE4ODZiY2I4ZjEwNDVhYmVlY2YxNDI1ZGI3IiwgInRvb2xzX25hbWVzIjogWyJnZXRf + ZmluYWxfYW5zd2VyIl19XXoCGAGFAQABAAASjgIKEJenfV2z7SA7CIkmcY2sgmMSCBDEk2lk0bS6 + KgxUYXNrIENyZWF0ZWQwATloOpWKgrr3F0GIiJWKgrr3F0ouCghjcmV3X2tleRIiCiA5NGMzMGQ2 + YzNiMmFjOGZiOTRiMmRjZmM1NzJkMGY1OUoxCgdjcmV3X2lkEiYKJGUxYmEzNTk0LTNhM2MtNDNk + Yy1iMjlhLTgwNWYxMjI2M2E5YUouCgh0YXNrX2tleRIiCiAzMjJkZGFlM2JjODBjMWQ0NWI4NWZh + Nzc1NmRiODY2NUoxCgd0YXNrX2lkEiYKJDAzZDFiMjQ0LTE1MzAtNGFmNS1hN2Q2LWU4ODJlMzlh + NTllZXoCGAGFAQABAAASkAIKEPtukDfYLYvLy84jtLlLVbUSCCRL85ZMPiFYKg5UYXNrIEV4ZWN1 + dGlvbjABOZivlYqCuvcXQfg+uoqCuvcXSi4KCGNyZXdfa2V5EiIKIDk0YzMwZDZjM2IyYWM4ZmI5 + NGIyZGNmYzU3MmQwZjU5SjEKB2NyZXdfaWQSJgokZTFiYTM1OTQtM2EzYy00M2RjLWIyOWEtODA1 + ZjEyMjYzYTlhSi4KCHRhc2tfa2V5EiIKIDMyMmRkYWUzYmM4MGMxZDQ1Yjg1ZmE3NzU2ZGI4NjY1 + SjEKB3Rhc2tfaWQSJgokMDNkMWIyNDQtMTUzMC00YWY1LWE3ZDYtZTg4MmUzOWE1OWVlegIYAYUB + AAEAABKOAgoQy0Z3iNMXUq8f33wQIJRXcRIIq7I1tVYsNdgqDFRhc2sgQ3JlYXRlZDABOehkwoqC + uvcXQdi6woqCuvcXSi4KCGNyZXdfa2V5EiIKIDk0YzMwZDZjM2IyYWM4ZmI5NGIyZGNmYzU3MmQw + ZjU5SjEKB2NyZXdfaWQSJgokZTFiYTM1OTQtM2EzYy00M2RjLWIyOWEtODA1ZjEyMjYzYTlhSi4K + CHRhc2tfa2V5EiIKIDVlOWNhN2Q2NGI0MjA1YmI3YzQ3ZTBiM2ZjYjVkMjFmSjEKB3Rhc2tfaWQS + JgokYzg5ZDg4YjAtMzZiNS00MGE2LTllMTUtMDI3N2MyZDU4NzFiegIYAYUBAAEAABKTAQoQnMQh + peX8Rj715M/aM19j+BIILcc3C5FEoZ8qClRvb2wgVXNhZ2UwATmIufWKgrr3F0EgcfaKgrr3F0oa + Cg5jcmV3YWlfdmVyc2lvbhIICgYwLjYxLjBKHwoJdG9vbF9uYW1lEhIKEGdldF9maW5hbF9hbnN3 + ZXJKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABKQAgoQSQmx9FLRNmXu5jj4j/FifhII3uueCe0D + uHkqDlRhc2sgRXhlY3V0aW9uMAE56OHCioK69xdBwKIai4K69xdKLgoIY3Jld19rZXkSIgogOTRj + MzBkNmMzYjJhYzhmYjk0YjJkY2ZjNTcyZDBmNTlKMQoHY3Jld19pZBImCiRlMWJhMzU5NC0zYTNj + LTQzZGMtYjI5YS04MDVmMTIyNjNhOWFKLgoIdGFza19rZXkSIgogNWU5Y2E3ZDY0YjQyMDViYjdj + NDdlMGIzZmNiNWQyMWZKMQoHdGFza19pZBImCiRjODlkODhiMC0zNmI1LTQwYTYtOWUxNS0wMjc3 + YzJkNTg3MWJ6AhgBhQEAAQAAErMHChDpApe2L3FgzRhc01KV1D1UEghciCBxsPBkxyoMQ3JldyBD + cmVhdGVkMAE5GDhai4K69xdBENpbi4K69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42MS4wShoK + DnB5dGhvbl92ZXJzaW9uEggKBjMuMTEuN0ouCghjcmV3X2tleRIiCiA3M2FhYzI4NWU2NzQ2NjY3 + Zjc1MTQ3NjcwMDAzNDExMEoxCgdjcmV3X2lkEiYKJDU2YzI2OWMyLWRkOGMtNGY1Zi1hNjAwLWQ4 + MjRmNDQ5MDQ0NkocCgxjcmV3X3Byb2Nlc3MSDAoKc2VxdWVudGlhbEoRCgtjcmV3X21lbW9yeRIC + EABKGgoUY3Jld19udW1iZXJfb2ZfdGFza3MSAhgBShsKFWNyZXdfbnVtYmVyX29mX2FnZW50cxIC + GAFK0AIKC2NyZXdfYWdlbnRzEsACCr0CW3sia2V5IjogImUxNDhlNTMyMDI5MzQ5OWY4Y2ViZWE4 + MjZlNzI1ODJiIiwgImlkIjogImRlZjNjZTcyLTY3MTItNDdjNS05YTdiLWM5YjU5ZTQ2MGZjMSIs + ICJyb2xlIjogInRlc3Qgcm9sZSIsICJ2ZXJib3NlPyI6IHRydWUsICJtYXhfaXRlciI6IDEsICJt + YXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogbnVsbCwgImxsbSI6ICJncHQt + NG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1 + dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtdfV1K + kAIKCmNyZXdfdGFza3MSgQIK/gFbeyJrZXkiOiAiZjdhOWY3YmIxYWVlNGI2ZWYyYzUyNmQwYThj + MmYyYWMiLCAiaWQiOiAiOTAxOTE1YzctZTUzYi00YTUxLTlkN2EtODM4ODAyNTBhMmZmIiwgImFz + eW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9s + ZSI6ICJ0ZXN0IHJvbGUiLCAiYWdlbnRfa2V5IjogImUxNDhlNTMyMDI5MzQ5OWY4Y2ViZWE4MjZl + NzI1ODJiIiwgInRvb2xzX25hbWVzIjogWyJnZXRfZmluYWxfYW5zd2VyIl19XXoCGAGFAQABAAAS + jgIKEE6dNc/JOrEkmqPY5B0+8cwSCHYnXjk3nc3uKgxUYXNrIENyZWF0ZWQwATkoyXKLgrr3F0Ew + G3OLgrr3F0ouCghjcmV3X2tleRIiCiA3M2FhYzI4NWU2NzQ2NjY3Zjc1MTQ3NjcwMDAzNDExMEox + CgdjcmV3X2lkEiYKJDU2YzI2OWMyLWRkOGMtNGY1Zi1hNjAwLWQ4MjRmNDQ5MDQ0NkouCgh0YXNr + X2tleRIiCiBmN2E5ZjdiYjFhZWU0YjZlZjJjNTI2ZDBhOGMyZjJhY0oxCgd0YXNrX2lkEiYKJDkw + MTkxNWM3LWU1M2ItNGE1MS05ZDdhLTgzODgwMjUwYTJmZnoCGAGFAQABAAASeQoQ5s8IY575ov6g + dTdJvR7XexIIrE8QEnWZeRYqEFRvb2wgVXNhZ2UgRXJyb3IwATnQ8qWLgrr3F0FQrqaLgrr3F0oa + Cg5jcmV3YWlfdmVyc2lvbhIICgYwLjYxLjBKDwoDbGxtEggKBmdwdC00b3oCGAGFAQABAAASkAIK + EPjnnZBW5foM8VfKeXi4sa0SCLiq+s8hCImuKg5UYXNrIEV4ZWN1dGlvbjABOUBCc4uCuvcXQSBJ + zYuCuvcXSi4KCGNyZXdfa2V5EiIKIDczYWFjMjg1ZTY3NDY2NjdmNzUxNDc2NzAwMDM0MTEwSjEK + B2NyZXdfaWQSJgokNTZjMjY5YzItZGQ4Yy00ZjVmLWE2MDAtZDgyNGY0NDkwNDQ2Si4KCHRhc2tf + a2V5EiIKIGY3YTlmN2JiMWFlZTRiNmVmMmM1MjZkMGE4YzJmMmFjSjEKB3Rhc2tfaWQSJgokOTAx + OTE1YzctZTUzYi00YTUxLTlkN2EtODM4ODAyNTBhMmZmegIYAYUBAAEAABKzBwoQQKTAPRzCaprG + DlxUZuNZcxIIMufgv1JcDggqDENyZXcgQ3JlYXRlZDABObDBMoyCuvcXQYBANIyCuvcXShoKDmNy + ZXdhaV92ZXJzaW9uEggKBjAuNjEuMEoaCg5weXRob25fdmVyc2lvbhIICgYzLjExLjdKLgoIY3Jl + d19rZXkSIgogZDU1MTEzYmU0YWE0MWJhNjQzZDMyNjA0MmIyZjAzZjFKMQoHY3Jld19pZBImCiQz + MjlkMjNkNi0zOTA3LTQ1ZGYtODVjYS00OTNiZDMyOWIxMTdKHAoMY3Jld19wcm9jZXNzEgwKCnNl + cXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdfbnVtYmVyX29mX3Rhc2tzEgIYAUob + ChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgBStACCgtjcmV3X2FnZW50cxLAAgq9Alt7ImtleSI6 + ICJlMTQ4ZTUzMjAyOTM0OTlmOGNlYmVhODI2ZTcyNTgyYiIsICJpZCI6ICI3ZTU2YWQzZC00NDY0 + LTQ3NmItYjUzNi1iNTk1OGZjNDJiNjYiLCAicm9sZSI6ICJ0ZXN0IHJvbGUiLCAidmVyYm9zZT8i + OiB0cnVlLCAibWF4X2l0ZXIiOiA2LCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5n + X2xsbSI6IG51bGwsICJsbG0iOiAiZ3B0LTRvLW1pbmkiLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6 + IGZhbHNlLCAiYWxsb3dfY29kZV9leGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQi + OiAyLCAidG9vbHNfbmFtZXMiOiBbXX1dSpACCgpjcmV3X3Rhc2tzEoECCv4BW3sia2V5IjogIjRh + MzFiODUxMzNhM2EyOTRjNjg1M2RhNzU3ZDRiYWU3IiwgImlkIjogImVkNTdmNWYxLTM1NjctNDg4 + ZC1iODBhLTAxYTUwY2Q3N2FiOSIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2UsICJodW1hbl9p + bnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAidGVzdCByb2xlIiwgImFnZW50X2tleSI6ICJl + MTQ4ZTUzMjAyOTM0OTlmOGNlYmVhODI2ZTcyNTgyYiIsICJ0b29sc19uYW1lcyI6IFsiZ2V0X2Zp + bmFsX2Fuc3dlciJdfV16AhgBhQEAAQAAEo4CChBFkNHwiAapJQ8vz6meDO5gEgjPL7+VrYZWMSoM + VGFzayBDcmVhdGVkMAE5oNU9jIK69xdB8Bs+jIK69xdKLgoIY3Jld19rZXkSIgogZDU1MTEzYmU0 + YWE0MWJhNjQzZDMyNjA0MmIyZjAzZjFKMQoHY3Jld19pZBImCiQzMjlkMjNkNi0zOTA3LTQ1ZGYt + ODVjYS00OTNiZDMyOWIxMTdKLgoIdGFza19rZXkSIgogNGEzMWI4NTEzM2EzYTI5NGM2ODUzZGE3 + NTdkNGJhZTdKMQoHdGFza19pZBImCiRlZDU3ZjVmMS0zNTY3LTQ4OGQtYjgwYS0wMWE1MGNkNzdh + Yjl6AhgBhQEAAQAAEpMBChBtpu64G/X3Ak/j1v+2WvZtEggtklCPgHXHgCoKVG9vbCBVc2FnZTAB + OTjGc4yCuvcXQeh5dIyCuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEofCgl0b29sX25h + bWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpwBChCgMEAw + nFgXFVk2RXS+xpXwEghWvF0oVlx0fSoTVG9vbCBSZXBlYXRlZCBVc2FnZTABOcgvnYyCuvcXQfDP + nYyCuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEofCgl0b29sX25hbWUSEgoQZ2V0X2Zp + bmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpwBChDjIxzbGKQ2AtAKjTJuwQEv + Egj3o2K+W28PMSoTVG9vbCBSZXBlYXRlZCBVc2FnZTABORjTzIyCuvcXQRB7zYyCuvcXShoKDmNy + ZXdhaV92ZXJzaW9uEggKBjAuNjEuMEofCgl0b29sX25hbWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoO + CghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpwBChD2uAPFDVmViLVxyikmmwDGEgjPyGudxw/suyoT + VG9vbCBSZXBlYXRlZCBVc2FnZTABOSg5AY2CuvcXQVDZAY2CuvcXShoKDmNyZXdhaV92ZXJzaW9u + EggKBjAuNjEuMEofCgl0b29sX25hbWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxIC + GAF6AhgBhQEAAQAAEpwBChDDYZerLjiZ0rYSlkb7eQe4EghSbAg6mjUB7CoTVG9vbCBSZXBlYXRl + ZCBVc2FnZTABOTifNY2CuvcXQQgkNo2CuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEof + Cgl0b29sX25hbWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAA + EpwBChDw2TTgrwOmG9oIuzI8VSaNEgiphV7iTInI3CoTVG9vbCBSZXBlYXRlZCBVc2FnZTABOSC+ + b42CuvcXQdhGcI2CuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEofCgl0b29sX25hbWUS + EgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpACChCTaKeZOaVJ + 7DZT7/wT1GDhEggw6V15+Sv9+yoOVGFzayBFeGVjdXRpb24wATm4Tj6Mgrr3F0HoiKqNgrr3F0ou + CghjcmV3X2tleRIiCiBkNTUxMTNiZTRhYTQxYmE2NDNkMzI2MDQyYjJmMDNmMUoxCgdjcmV3X2lk + EiYKJDMyOWQyM2Q2LTM5MDctNDVkZi04NWNhLTQ5M2JkMzI5YjExN0ouCgh0YXNrX2tleRIiCiA0 + YTMxYjg1MTMzYTNhMjk0YzY4NTNkYTc1N2Q0YmFlN0oxCgd0YXNrX2lkEiYKJGVkNTdmNWYxLTM1 + NjctNDg4ZC1iODBhLTAxYTUwY2Q3N2FiOXoCGAGFAQABAAASvA0KEI/f3YEuP4w0rcm9gVuLJy8S + CIXLSg8BK0BRKgxDcmV3IENyZWF0ZWQwATnwMPCNgrr3F0Ewx/GNgrr3F0oaCg5jcmV3YWlfdmVy + c2lvbhIICgYwLjYxLjBKGgoOcHl0aG9uX3ZlcnNpb24SCAoGMy4xMS43Si4KCGNyZXdfa2V5EiIK + IDExMWI4NzJkOGYwY2Y3MDNmMmVmZWYwNGNmM2FjNzk4SjEKB2NyZXdfaWQSJgokOThlNzRkOTEt + ZWE4Ni00MTZlLThkOTAtNjZlMjljOTMwYjQ0ShwKDGNyZXdfcHJvY2VzcxIMCgpzZXF1ZW50aWFs + ShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251bWJlcl9vZl90YXNrcxICGANKGwoVY3Jld19u + dW1iZXJfb2ZfYWdlbnRzEgIYAkqSBQoLY3Jld19hZ2VudHMSggUK/wRbeyJrZXkiOiAiZTE0OGU1 + MzIwMjkzNDk5ZjhjZWJlYTgyNmU3MjU4MmIiLCAiaWQiOiAiZmZjZWMwNTYtYThiNC00NTM0LTgz + Y2QtNGFlNjczYWZlMzZkIiwgInJvbGUiOiAidGVzdCByb2xlIiwgInZlcmJvc2U/IjogZmFsc2Us + ICJtYXhfaXRlciI6IDE1LCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6 + IG51bGwsICJsbG0iOiAiZ3B0LTRvLW1pbmkiLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNl + LCAiYWxsb3dfY29kZV9leGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAi + dG9vbHNfbmFtZXMiOiBbXX0sIHsia2V5IjogImU3ZThlZWE4ODZiY2I4ZjEwNDVhYmVlY2YxNDI1 + ZGI3IiwgImlkIjogImM2NWMzMDYwLTI0YTAtNDNmMS1iNGM5LTlmYWFkNWYyMWM0MSIsICJyb2xl + IjogInRlc3Qgcm9sZTIiLCAidmVyYm9zZT8iOiBmYWxzZSwgIm1heF9pdGVyIjogMTUsICJtYXhf + cnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogbnVsbCwgImxsbSI6ICJncHQtNG8t + bWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlv + bj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtdfV1K1wUK + CmNyZXdfdGFza3MSyAUKxQVbeyJrZXkiOiAiMzIyZGRhZTNiYzgwYzFkNDViODVmYTc3NTZkYjg2 + NjUiLCAiaWQiOiAiMWVjODU4MDctM2I3OS00ODFjLWE1ZDktMjg1ZGUzZDdjMDgwIiwgImFzeW5j + X2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6 + ICJ0ZXN0IHJvbGUiLCAiYWdlbnRfa2V5IjogImUxNDhlNTMyMDI5MzQ5OWY4Y2ViZWE4MjZlNzI1 + ODJiIiwgInRvb2xzX25hbWVzIjogW119LCB7ImtleSI6ICJjYzQ4NzZmNmU1ODhlNzEzNDliYmQz + YTY1ODg4YzNlOSIsICJpZCI6ICI5YmJjNjJhMy1iMDQ5LTQ5YjgtODVlMC1lY2QxODlkZGU0ZDEi + LCAiYXN5bmNfZXhlY3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5faW5wdXQ/IjogZmFsc2UsICJhZ2Vu + dF9yb2xlIjogInRlc3Qgcm9sZSIsICJhZ2VudF9rZXkiOiAiZTE0OGU1MzIwMjkzNDk5ZjhjZWJl + YTgyNmU3MjU4MmIiLCAidG9vbHNfbmFtZXMiOiBbXX0sIHsia2V5IjogImUwYjEzZTEwZDdhMTQ2 + ZGNjNGM0ODhmY2Y4ZDc0OGEwIiwgImlkIjogIjljMTBhNzliLTJkYjctNDliOC04NTdhLWRlNDI4 + YmMxZmJlNiIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxz + ZSwgImFnZW50X3JvbGUiOiAidGVzdCByb2xlMiIsICJhZ2VudF9rZXkiOiAiZTdlOGVlYTg4NmJj + YjhmMTA0NWFiZWVjZjE0MjVkYjciLCAidG9vbHNfbmFtZXMiOiBbXX1degIYAYUBAAEAABKOAgoQ + v9XHGuXR9UMaM5yQZB3tChIIdiK/9URkBAwqDFRhc2sgQ3JlYXRlZDABOZjN+42CuvcXQbgb/I2C + uvcXSi4KCGNyZXdfa2V5EiIKIDExMWI4NzJkOGYwY2Y3MDNmMmVmZWYwNGNmM2FjNzk4SjEKB2Ny + ZXdfaWQSJgokOThlNzRkOTEtZWE4Ni00MTZlLThkOTAtNjZlMjljOTMwYjQ0Si4KCHRhc2tfa2V5 + EiIKIDMyMmRkYWUzYmM4MGMxZDQ1Yjg1ZmE3NzU2ZGI4NjY1SjEKB3Rhc2tfaWQSJgokMWVjODU4 + MDctM2I3OS00ODFjLWE1ZDktMjg1ZGUzZDdjMDgwegIYAYUBAAEAABKQAgoQ2tQcRcB2PuTEvqwc + IHWv5hII6+gCfLXBX0gqDlRhc2sgRXhlY3V0aW9uMAE54D78jYK69xdBoMQfjoK69xdKLgoIY3Jl + d19rZXkSIgogMTExYjg3MmQ4ZjBjZjcwM2YyZWZlZjA0Y2YzYWM3OThKMQoHY3Jld19pZBImCiQ5 + OGU3NGQ5MS1lYTg2LTQxNmUtOGQ5MC02NmUyOWM5MzBiNDRKLgoIdGFza19rZXkSIgogMzIyZGRh + ZTNiYzgwYzFkNDViODVmYTc3NTZkYjg2NjVKMQoHdGFza19pZBImCiQxZWM4NTgwNy0zYjc5LTQ4 + MWMtYTVkOS0yODVkZTNkN2MwODB6AhgBhQEAAQAAEo4CChDPtyCdwriHAcMdJSpbUBBeEgh89U6t + 0t2XOCoMVGFzayBDcmVhdGVkMAE5+K8njoK69xdBuA0ojoK69xdKLgoIY3Jld19rZXkSIgogMTEx + Yjg3MmQ4ZjBjZjcwM2YyZWZlZjA0Y2YzYWM3OThKMQoHY3Jld19pZBImCiQ5OGU3NGQ5MS1lYTg2 + LTQxNmUtOGQ5MC02NmUyOWM5MzBiNDRKLgoIdGFza19rZXkSIgogY2M0ODc2ZjZlNTg4ZTcxMzQ5 + YmJkM2E2NTg4OGMzZTlKMQoHdGFza19pZBImCiQ5YmJjNjJhMy1iMDQ5LTQ5YjgtODVlMC1lY2Qx + ODlkZGU0ZDF6AhgBhQEAAQAAEpACChBc1jDzVY0OzmA01H378iPcEghNxSy0i8HxJCoOVGFzayBF + eGVjdXRpb24wATngMCiOgrr3F0FAQ0yOgrr3F0ouCghjcmV3X2tleRIiCiAxMTFiODcyZDhmMGNm + NzAzZjJlZmVmMDRjZjNhYzc5OEoxCgdjcmV3X2lkEiYKJDk4ZTc0ZDkxLWVhODYtNDE2ZS04ZDkw + LTY2ZTI5YzkzMGI0NEouCgh0YXNrX2tleRIiCiBjYzQ4NzZmNmU1ODhlNzEzNDliYmQzYTY1ODg4 + YzNlOUoxCgd0YXNrX2lkEiYKJDliYmM2MmEzLWIwNDktNDliOC04NWUwLWVjZDE4OWRkZTRkMXoC + GAGFAQABAAASjgIKENZ82kI8VE7x4jhYeGarbssSCCFDIftElxsrKgxUYXNrIENyZWF0ZWQwATm4 + dlWOgrr3F0Ew4FWOgrr3F0ouCghjcmV3X2tleRIiCiAxMTFiODcyZDhmMGNmNzAzZjJlZmVmMDRj + ZjNhYzc5OEoxCgdjcmV3X2lkEiYKJDk4ZTc0ZDkxLWVhODYtNDE2ZS04ZDkwLTY2ZTI5YzkzMGI0 + NEouCgh0YXNrX2tleRIiCiBlMGIxM2UxMGQ3YTE0NmRjYzRjNDg4ZmNmOGQ3NDhhMEoxCgd0YXNr + X2lkEiYKJDljMTBhNzliLTJkYjctNDliOC04NTdhLWRlNDI4YmMxZmJlNnoCGAGFAQABAAASkAIK + EOZkELicMaPAmpQXyYUVUpQSCOyC4WGtF/x5Kg5UYXNrIEV4ZWN1dGlvbjABOUAHVo6CuvcXQSgt + eo6CuvcXSi4KCGNyZXdfa2V5EiIKIDExMWI4NzJkOGYwY2Y3MDNmMmVmZWYwNGNmM2FjNzk4SjEK + B2NyZXdfaWQSJgokOThlNzRkOTEtZWE4Ni00MTZlLThkOTAtNjZlMjljOTMwYjQ0Si4KCHRhc2tf + a2V5EiIKIGUwYjEzZTEwZDdhMTQ2ZGNjNGM0ODhmY2Y4ZDc0OGEwSjEKB3Rhc2tfaWQSJgokOWMx + MGE3OWItMmRiNy00OWI4LTg1N2EtZGU0MjhiYzFmYmU2egIYAYUBAAEAABLDBwoQI/lC4M0ubT9r + 2+LvOAoNbBIIlKDOdKS/WXgqDENyZXcgQ3JlYXRlZDABORAO6I6CuvcXQUB96Y6CuvcXShoKDmNy + ZXdhaV92ZXJzaW9uEggKBjAuNjEuMEoaCg5weXRob25fdmVyc2lvbhIICgYzLjExLjdKLgoIY3Jl + d19rZXkSIgogNDk0ZjM2NTcyMzdhZDhhMzAzNWIyZjFiZWVjZGM2NzdKMQoHY3Jld19pZBImCiRl + OGU2YzUzNy1lZjAwLTQ0NGEtYmQyYS04NDk1MTQxODkxNzZKHAoMY3Jld19wcm9jZXNzEgwKCnNl + cXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdfbnVtYmVyX29mX3Rhc2tzEgIYAUob + ChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgBSuICCgtjcmV3X2FnZW50cxLSAgrPAlt7ImtleSI6 + ICJlMTQ4ZTUzMjAyOTM0OTlmOGNlYmVhODI2ZTcyNTgyYiIsICJpZCI6ICJjMGRjMTNiZi04OTgy + LTQwODctODZlMC0wYjIxYmM1YjI5NmQiLCAicm9sZSI6ICJ0ZXN0IHJvbGUiLCAidmVyYm9zZT8i + OiBmYWxzZSwgIm1heF9pdGVyIjogMTUsICJtYXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxp + bmdfbGxtIjogbnVsbCwgImxsbSI6ICJncHQtNG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/ + IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1p + dCI6IDIsICJ0b29sc19uYW1lcyI6IFsibGVhcm5fYWJvdXRfYWkiXX1dSo4CCgpjcmV3X3Rhc2tz + Ev8BCvwBW3sia2V5IjogImYyNTk3Yzc4NjdmYmUzMjRkYzY1ZGMwOGRmZGJmYzZjIiwgImlkIjog + IjhhNDViYWUzLTRjNTctNGMzYS04M2YxLWJlZjZkYTFlNmEyYyIsICJhc3luY19leGVjdXRpb24/ + IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAidGVzdCByb2xl + IiwgImFnZW50X2tleSI6ICJlMTQ4ZTUzMjAyOTM0OTlmOGNlYmVhODI2ZTcyNTgyYiIsICJ0b29s + c19uYW1lcyI6IFsibGVhcm5fYWJvdXRfYWkiXX1degIYAYUBAAEAABKOAgoQ4o5FndQB9Gue7JIS + wMA30RIII+v2810EckIqDFRhc2sgQ3JlYXRlZDABOWjJ946CuvcXQdAL+I6CuvcXSi4KCGNyZXdf + a2V5EiIKIDQ5NGYzNjU3MjM3YWQ4YTMwMzViMmYxYmVlY2RjNjc3SjEKB2NyZXdfaWQSJgokZThl + NmM1MzctZWYwMC00NDRhLWJkMmEtODQ5NTE0MTg5MTc2Si4KCHRhc2tfa2V5EiIKIGYyNTk3Yzc4 + NjdmYmUzMjRkYzY1ZGMwOGRmZGJmYzZjSjEKB3Rhc2tfaWQSJgokOGE0NWJhZTMtNGM1Ny00YzNh + LTgzZjEtYmVmNmRhMWU2YTJjegIYAYUBAAEAABKRAQoQx8RJL4aeBfQMN1mCJceEvRIIAHhs2SeF + 7cgqClRvb2wgVXNhZ2UwATkAZyaPgrr3F0EINiePgrr3F0oaCg5jcmV3YWlfdmVyc2lvbhIICgYw + LjYxLjBKHQoJdG9vbF9uYW1lEhAKDmxlYXJuX2Fib3V0X0FJSg4KCGF0dGVtcHRzEgIYAXoCGAGF + AQABAAASmgEKEDTuMOl4qZsTya+MPhdP3zwSCApbJNedzwECKhNUb29sIFJlcGVhdGVkIFVzYWdl + MAE5GN5Qj4K69xdBcHZRj4K69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42MS4wSh0KCXRvb2xf + bmFtZRIQCg5sZWFybl9hYm91dF9BSUoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpoBChAru58B + SCPUvOvY5Met9I1cEgjHVBruY1fy9ioTVG9vbCBSZXBlYXRlZCBVc2FnZTABOXhDfI+CuvcXQXDr + fI+CuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEodCgl0b29sX25hbWUSEAoObGVhcm5f + YWJvdXRfQUlKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABKaAQoQiodhKA6z0Pt19Ex1+oOpaBII + Mn0Z+77B1X0qE1Rvb2wgUmVwZWF0ZWQgVXNhZ2UwATnwjKuPgrr3F0GQGayPgrr3F0oaCg5jcmV3 + YWlfdmVyc2lvbhIICgYwLjYxLjBKHQoJdG9vbF9uYW1lEhAKDmxlYXJuX2Fib3V0X0FJSg4KCGF0 + dGVtcHRzEgIYAXoCGAGFAQABAAASkQEKEGjJuIkBTuZmGtxsFSkx+dkSCFMo1QV0ob1mKgpUb29s + IFVzYWdlMAE5OCXkj4K69xdBwLXkj4K69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42MS4wSh0K + CXRvb2xfbmFtZRIQCg5sZWFybl9hYm91dF9BSUoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpEB + ChCvw+R1bu6M0v2tltTdkYDKEggOs4AqHPioHyoKVG9vbCBVc2FnZTABOWjTGZCCuvcXQWhQGpCC + uvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEodCgl0b29sX25hbWUSEAoObGVhcm5fYWJv + dXRfQUlKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABKRAQoQ77/QdFrKp7NnT1x/BFhIOxII8MJj + 6aWkhvwqClRvb2wgVXNhZ2UwATn4uFiQgrr3F0H4NVmQgrr3F0oaCg5jcmV3YWlfdmVyc2lvbhII + CgYwLjYxLjBKHQoJdG9vbF9uYW1lEhAKDmxlYXJuX2Fib3V0X0FJSg4KCGF0dGVtcHRzEgIYAXoC + GAGFAQABAAASkQEKENUkrekhmilu6cVGf8WNkKcSCEzWQ9AbY94cKgpUb29sIFVzYWdlMAE5kNib + kIK69xdBoHyckIK69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42MS4wSh0KCXRvb2xfbmFtZRIQ + Cg5sZWFybl9hYm91dF9BSUoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpACChDVgM/C7sCfK8S/ + SCJMqa2IEgihQnHLjWO9yCoOVGFzayBFeGVjdXRpb24wATn4LviOgrr3F0Gg2x6Rgrr3F0ouCghj + cmV3X2tleRIiCiA0OTRmMzY1NzIzN2FkOGEzMDM1YjJmMWJlZWNkYzY3N0oxCgdjcmV3X2lkEiYK + JGU4ZTZjNTM3LWVmMDAtNDQ0YS1iZDJhLTg0OTUxNDE4OTE3NkouCgh0YXNrX2tleRIiCiBmMjU5 + N2M3ODY3ZmJlMzI0ZGM2NWRjMDhkZmRiZmM2Y0oxCgd0YXNrX2lkEiYKJDhhNDViYWUzLTRjNTct + NGMzYS04M2YxLWJlZjZkYTFlNmEyY3oCGAGFAQABAAASwQcKECxcoAjrURPDagway/WNCC4SCM/V + NErX5oUJKgxDcmV3IENyZWF0ZWQwATnQBH+Rgrr3F0FoOYCRgrr3F0oaCg5jcmV3YWlfdmVyc2lv + bhIICgYwLjYxLjBKGgoOcHl0aG9uX3ZlcnNpb24SCAoGMy4xMS43Si4KCGNyZXdfa2V5EiIKIDQ5 + NGYzNjU3MjM3YWQ4YTMwMzViMmYxYmVlY2RjNjc3SjEKB2NyZXdfaWQSJgokNmIxZjU4MzEtY2Ez + Zi00ZWJjLWIzYTMtMzQ5ZGI2N2Q0MzQ3ShwKDGNyZXdfcHJvY2VzcxIMCgpzZXF1ZW50aWFsShEK + C2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251bWJlcl9vZl90YXNrcxICGAFKGwoVY3Jld19udW1i + ZXJfb2ZfYWdlbnRzEgIYAUrgAgoLY3Jld19hZ2VudHMS0AIKzQJbeyJrZXkiOiAiZTE0OGU1MzIw + MjkzNDk5ZjhjZWJlYTgyNmU3MjU4MmIiLCAiaWQiOiAiNTQ5NGI2YWQtN2IwYi00MTFiLTlmZWUt + MjRhMzk3ZjZjODVjIiwgInJvbGUiOiAidGVzdCByb2xlIiwgInZlcmJvc2U/IjogZmFsc2UsICJt + YXhfaXRlciI6IDIsICJtYXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogImdw + dC00byIsICJsbG0iOiAiZ3B0LTRvIiwgImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFs + bG93X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xz + X25hbWVzIjogWyJsZWFybl9hYm91dF9haSJdfV1KjgIKCmNyZXdfdGFza3MS/wEK/AFbeyJrZXki + OiAiZjI1OTdjNzg2N2ZiZTMyNGRjNjVkYzA4ZGZkYmZjNmMiLCAiaWQiOiAiNjNlMTlkZjItZmFk + Zi00ZmI0LTgyYmUtODc1YmFmOWUwNTNlIiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1 + bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJ0ZXN0IHJvbGUiLCAiYWdlbnRfa2V5 + IjogImUxNDhlNTMyMDI5MzQ5OWY4Y2ViZWE4MjZlNzI1ODJiIiwgInRvb2xzX25hbWVzIjogWyJs + ZWFybl9hYm91dF9haSJdfV16AhgBhQEAAQAAEo4CChALMs+Ul0F8F+BnQux42315EggvsxOGUnlg + aSoMVGFzayBDcmVhdGVkMAE5GKWMkYK69xdBmOOMkYK69xdKLgoIY3Jld19rZXkSIgogNDk0ZjM2 + NTcyMzdhZDhhMzAzNWIyZjFiZWVjZGM2NzdKMQoHY3Jld19pZBImCiQ2YjFmNTgzMS1jYTNmLTRl + YmMtYjNhMy0zNDlkYjY3ZDQzNDdKLgoIdGFza19rZXkSIgogZjI1OTdjNzg2N2ZiZTMyNGRjNjVk + YzA4ZGZkYmZjNmNKMQoHdGFza19pZBImCiQ2M2UxOWRmMi1mYWRmLTRmYjQtODJiZS04NzViYWY5 + ZTA1M2V6AhgBhQEAAQAAEpACChC5Afc9HYQEx6M9pF0yt8xXEgiN4bEf+mfSNSoOVGFzayBFeGVj + dXRpb24wATnYAo2Rgrr3F0FgvuiSgrr3F0ouCghjcmV3X2tleRIiCiA0OTRmMzY1NzIzN2FkOGEz + MDM1YjJmMWJlZWNkYzY3N0oxCgdjcmV3X2lkEiYKJDZiMWY1ODMxLWNhM2YtNGViYy1iM2EzLTM0 + OWRiNjdkNDM0N0ouCgh0YXNrX2tleRIiCiBmMjU5N2M3ODY3ZmJlMzI0ZGM2NWRjMDhkZmRiZmM2 + Y0oxCgd0YXNrX2lkEiYKJDYzZTE5ZGYyLWZhZGYtNGZiNC04MmJlLTg3NWJhZjllMDUzZXoCGAGF + AQABAAASywcKEEH8cxqDwpRggGwqWXDMaQESCN+MT/kn4+AUKgxDcmV3IENyZWF0ZWQwATnoH1mT + grr3F0EAk1qTgrr3F0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjYxLjBKGgoOcHl0aG9uX3ZlcnNp + b24SCAoGMy4xMS43Si4KCGNyZXdfa2V5EiIKIDdlNjYwODk4OTg1OWE2N2VlYzg4ZWVmN2ZjZTg1 + MjI1SjEKB2NyZXdfaWQSJgokMTcyZWUwMjItYTYwMi00YzVlLTgzNzItZmJlZjliYmU2MDZkShwK + DGNyZXdfcHJvY2VzcxIMCgpzZXF1ZW50aWFsShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251 + bWJlcl9vZl90YXNrcxICGAFKGwoVY3Jld19udW1iZXJfb2ZfYWdlbnRzEgIYAUrmAgoLY3Jld19h + Z2VudHMS1gIK0wJbeyJrZXkiOiAiMjJhY2Q2MTFlNDRlZjVmYWMwNWI1MzNkNzVlODg5M2IiLCAi + aWQiOiAiZjM4OWRmYzEtNTY2NS00NmFjLWJiMTMtYWNmZTY1M2Q5MTEzIiwgInJvbGUiOiAiRGF0 + YSBTY2llbnRpc3QiLCAidmVyYm9zZT8iOiBmYWxzZSwgIm1heF9pdGVyIjogMTUsICJtYXhfcnBt + IjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogbnVsbCwgImxsbSI6ICJncHQtNG8tbWlu + aSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8i + OiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFsiZ2V0IGdyZWV0 + aW5ncyJdfV1KkgIKCmNyZXdfdGFza3MSgwIKgAJbeyJrZXkiOiAiYTI3N2IzNGIyYzE0NmYwYzU2 + YzVlMTM1NmU4ZjhhNTciLCAiaWQiOiAiNmU5NDRiMmMtOWI3Mi00ODk5LWIyM2UtZmM5Y2VlOGJh + NTRlIiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAi + YWdlbnRfcm9sZSI6ICJEYXRhIFNjaWVudGlzdCIsICJhZ2VudF9rZXkiOiAiMjJhY2Q2MTFlNDRl + ZjVmYWMwNWI1MzNkNzVlODg5M2IiLCAidG9vbHNfbmFtZXMiOiBbImdldCBncmVldGluZ3MiXX1d + egIYAYUBAAEAABKOAgoQLVMGH1Z9gZX6zP+hvZclzRIIiiQbTOzRBOsqDFRhc2sgQ3JlYXRlZDAB + OYjbZpOCuvcXQfAdZ5OCuvcXSi4KCGNyZXdfa2V5EiIKIDdlNjYwODk4OTg1OWE2N2VlYzg4ZWVm + N2ZjZTg1MjI1SjEKB2NyZXdfaWQSJgokMTcyZWUwMjItYTYwMi00YzVlLTgzNzItZmJlZjliYmU2 + MDZkSi4KCHRhc2tfa2V5EiIKIGEyNzdiMzRiMmMxNDZmMGM1NmM1ZTEzNTZlOGY4YTU3SjEKB3Rh + c2tfaWQSJgokNmU5NDRiMmMtOWI3Mi00ODk5LWIyM2UtZmM5Y2VlOGJhNTRlegIYAYUBAAEAABKQ + AQoQ1UF8gj+Uc4rJWeduJSa9ThIIXbxMg/RED9QqClRvb2wgVXNhZ2UwATmA7JSTgrr3F0FgmJWT + grr3F0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjYxLjBKHAoJdG9vbF9uYW1lEg8KDUdldCBHcmVl + dGluZ3NKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABKQAgoQCDUIHElmwDrCGBanMbeU6xIIiXna + h60oSicqDlRhc2sgRXhlY3V0aW9uMAE5MD1nk4K69xdBeKq7k4K69xdKLgoIY3Jld19rZXkSIgog + N2U2NjA4OTg5ODU5YTY3ZWVjODhlZWY3ZmNlODUyMjVKMQoHY3Jld19pZBImCiQxNzJlZTAyMi1h + NjAyLTRjNWUtODM3Mi1mYmVmOWJiZTYwNmRKLgoIdGFza19rZXkSIgogYTI3N2IzNGIyYzE0NmYw + YzU2YzVlMTM1NmU4ZjhhNTdKMQoHdGFza19pZBImCiQ2ZTk0NGIyYy05YjcyLTQ4OTktYjIzZS1m + YzljZWU4YmE1NGV6AhgBhQEAAQAAEtcHChAOR3e8D6M9d5euFCyALx/BEgjC/aHWsS84pyoMQ3Jl + dyBDcmVhdGVkMAE5oEARlIK69xdBqIYTlIK69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42MS4w + ShoKDnB5dGhvbl92ZXJzaW9uEggKBjMuMTEuN0ouCghjcmV3X2tleRIiCiBjMzA3NjAwOTMyNjc2 + MTQ0NGQ1N2M3MWQxZGEzZjI3Y0oxCgdjcmV3X2lkEiYKJDVlNTE4ODEwLThhZDktNDJmMi1iNDdm + LWYyYmQ0MDA2MjFjYUocCgxjcmV3X3Byb2Nlc3MSDAoKc2VxdWVudGlhbEoRCgtjcmV3X21lbW9y + eRICEABKGgoUY3Jld19udW1iZXJfb2ZfdGFza3MSAhgBShsKFWNyZXdfbnVtYmVyX29mX2FnZW50 + cxICGAFK7AIKC2NyZXdfYWdlbnRzEtwCCtkCW3sia2V5IjogIjk4ZjNiMWQ0N2NlOTY5Y2YwNTc3 + MjdiNzg0MTQyNWNkIiwgImlkIjogIjk3NzFlNGQ3LTE3NWUtNGY1Ny05NmQ5LTA0MWJlZjdkYTQw + NiIsICJyb2xlIjogIkZyaWVuZGx5IE5laWdoYm9yIiwgInZlcmJvc2U/IjogZmFsc2UsICJtYXhf + aXRlciI6IDE1LCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6IG51bGws + ICJsbG0iOiAiZ3B0LTRvLW1pbmkiLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxs + b3dfY29kZV9leGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNf + bmFtZXMiOiBbImRlY2lkZSBncmVldGluZ3MiXX1dSpgCCgpjcmV3X3Rhc2tzEokCCoYCW3sia2V5 + IjogIjgwZDdiY2Q0OTA5OTI5MDA4MzgzMmYwZTk4MzM4MGRmIiwgImlkIjogIjEwOGUwNTVhLTFh + NzAtNDkxOC1hMGVhLWY2YWRmZjc0ZDhjZiIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2UsICJo + dW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAiRnJpZW5kbHkgTmVpZ2hib3IiLCAi + YWdlbnRfa2V5IjogIjk4ZjNiMWQ0N2NlOTY5Y2YwNTc3MjdiNzg0MTQyNWNkIiwgInRvb2xzX25h + bWVzIjogWyJkZWNpZGUgZ3JlZXRpbmdzIl19XXoCGAGFAQABAAASjgIKEMku7u2Sdz0w1FPPkCe3 + I3cSCIeAvUWC+eGNKgxUYXNrIENyZWF0ZWQwATlgUB6Ugrr3F0Hgjh6Ugrr3F0ouCghjcmV3X2tl + eRIiCiBjMzA3NjAwOTMyNjc2MTQ0NGQ1N2M3MWQxZGEzZjI3Y0oxCgdjcmV3X2lkEiYKJDVlNTE4 + ODEwLThhZDktNDJmMi1iNDdmLWYyYmQ0MDA2MjFjYUouCgh0YXNrX2tleRIiCiA4MGQ3YmNkNDkw + OTkyOTAwODM4MzJmMGU5ODMzODBkZkoxCgd0YXNrX2lkEiYKJDEwOGUwNTVhLTFhNzAtNDkxOC1h + MGVhLWY2YWRmZjc0ZDhjZnoCGAGFAQABAAASkwEKELN9e5T/Ns1B1nq0G10um1sSCCaY2it6tqJl + KgpUb29sIFVzYWdlMAE54OVOlIK69xdBeJ1PlIK69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42 + MS4wSh8KCXRvb2xfbmFtZRISChBEZWNpZGUgR3JlZXRpbmdzSg4KCGF0dGVtcHRzEgIYAXoCGAGF + AQABAAASkAIKEKkB0f+LKM+LdJ7WKxoQdpMSCKph6HtOkxKcKg5UYXNrIEV4ZWN1dGlvbjABOQiy + HpSCuvcXQejQdJSCuvcXSi4KCGNyZXdfa2V5EiIKIGMzMDc2MDA5MzI2NzYxNDQ0ZDU3YzcxZDFk + YTNmMjdjSjEKB2NyZXdfaWQSJgokNWU1MTg4MTAtOGFkOS00MmYyLWI0N2YtZjJiZDQwMDYyMWNh + Si4KCHRhc2tfa2V5EiIKIDgwZDdiY2Q0OTA5OTI5MDA4MzgzMmYwZTk4MzM4MGRmSjEKB3Rhc2tf + aWQSJgokMTA4ZTA1NWEtMWE3MC00OTE4LWEwZWEtZjZhZGZmNzRkOGNmegIYAYUBAAEAAA== + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '19945' + 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, 23 Sep 2024 01:14:18 GMT + status: + code: 200 + message: OK +- request: + body: '{"model": "gemma2:latest", "prompt": "### System:\nYou are test role. test + backstory\nYour personal goal is: test goal\nTo give my best complete final + answer to the task use the exact following format:\n\nThought: I now can give + a great answer\nFinal Answer: Your final answer must be the great and the most + complete as possible, it must be outcome described.\n\nI MUST use these formats, + my job depends on it!\n\n### User:\n\nCurrent Task: Explain what AI is in one + sentence\n\nThis is the expect criteria for your final answer: A one-sentence + explanation of AI\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:\n\n", + "options": {}, "stream": false}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '815' + Content-Type: + - application/json + User-Agent: + - python-requests/2.31.0 + method: POST + uri: http://localhost:8080/api/generate + response: + body: + string: '{"model":"gemma2:latest","created_at":"2024-09-23T01:14:31.890398Z","response":"Thought: + I can definitely explain AI in one sentence! \n\nFinal Answer: Artificial + intelligence (AI) refers to the ability of computer systems to perform tasks + that typically require human intelligence, such as learning, problem-solving, + and decision-making. \n","done":true,"done_reason":"stop","context":[106,1645,108,6176,1479,235292,108,2045,708,2121,4731,235265,2121,135147,108,6922,3749,6789,603,235292,2121,6789,108,1469,2734,970,1963,3407,2048,3448,577,573,6911,1281,573,5463,2412,5920,235292,109,65366,235292,590,1490,798,2734,476,1775,3448,108,11263,10358,235292,3883,2048,3448,2004,614,573,1775,578,573,1546,3407,685,3077,235269,665,2004,614,17526,6547,235265,109,235285,44472,1281,1450,32808,235269,970,3356,12014,611,665,235341,109,6176,4926,235292,109,6846,12297,235292,36576,1212,16481,603,575,974,13060,109,1596,603,573,5246,12830,604,861,2048,3448,235292,586,974,235290,47366,15844,576,16481,108,4747,44472,2203,573,5579,3407,3381,685,573,2048,3448,235269,780,476,13367,235265,109,12694,235341,1417,603,50471,2845,577,692,235269,1281,573,8112,2506,578,2734,861,1963,14124,10358,235269,861,3356,12014,611,665,235341,109,65366,235292,109,107,108,106,2516,108,65366,235292,590,798,8118,10200,16481,575,974,13060,235341,235248,109,11263,10358,235292,42456,17273,591,11716,235275,20604,577,573,7374,576,6875,5188,577,3114,13333,674,15976,2817,3515,17273,235269,1582,685,6044,235269,3210,235290,60495,235269,578,4530,235290,14577,235265,139,108],"total_duration":16624546667,"load_duration":13368281042,"prompt_eval_count":173,"prompt_eval_duration":693217000,"eval_count":53,"eval_duration":2558047000}' + headers: + Content-Length: + - '1695' + Content-Type: + - application/json; charset=utf-8 + Date: + - Mon, 23 Sep 2024 01:14:31 GMT + status: + code: 200 + message: OK +version: 1 diff --git a/tests/cassettes/test_agent_execute_task_with_tool.yaml b/tests/cassettes/test_agent_execute_task_with_tool.yaml new file mode 100644 index 000000000..50b110aba --- /dev/null +++ b/tests/cassettes/test_agent_execute_task_with_tool.yaml @@ -0,0 +1,229 @@ +interactions: +- request: + body: '{"messages": [{"role": "system", "content": "You are test role. test backstory\nYour + personal goal is: test goal\nYou ONLY have access to the following tools, and + should NEVER make up tools that are not listed here:\n\nTool Name: dummy_tool(*args: + Any, **kwargs: Any) -> Any\nTool Description: dummy_tool(query: ''string'') + - Useful for when you need to get a dummy result for a query. \nTool Arguments: + {''query'': {''title'': ''Query'', ''type'': ''string''}}\n\nUse the following + format:\n\nThought: you should always think about what to do\nAction: the action + to take, only one name of [dummy_tool], just the name, exactly as it''s written.\nAction + Input: the input to the action, just a simple python dictionary, enclosed in + curly braces, using \" to wrap keys and values.\nObservation: the result of + the action\n\nOnce all necessary information is gathered:\n\nThought: I now + know the final answer\nFinal Answer: the final answer to the original input + question\n"}, {"role": "user", "content": "\nCurrent Task: Use the dummy tool + to get a result for ''test query''\n\nThis is the expect criteria for your final + answer: The result from the dummy tool\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-3.5-turbo"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '1385' + content-type: + - application/json + cookie: + - _cfuvid=ntPBCCgVUz_nq5Umsn4Dh2nras_FFFm.Om6wrSeiU00-1727053206899-0.0.1.1-604800000; + __cf_bm=XKEjZqa9jLHDkJm09f6GoOFObGBsS.2iO2iQsVxfDtg-1727053206-1.0.1.1-AhT2h4tFAfFhcbWhI7x8he9L6T0eCndS2.n6pMSK3iFkx0qYlA5Y.iniDaQVaO1ukiEEoEJGaV2tL967WYm1uA + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.47.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.47.0 + x-stainless-raw-response: + - 'true' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.11.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + content: "{\n \"id\": \"chatcmpl-AARydRDFzcD2NUmMGzemsV0dp6kkG\",\n \"object\": + \"chat.completion\",\n \"created\": 1727054187,\n \"model\": \"gpt-3.5-turbo-0125\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"I should use the dummy tool to get a + result for 'test query'.\\n\\nAction: \\ndummy_tool\\n\\nAction Input: \\n{\\\"query\\\": + \\\"test query\\\"}\\n\\nObservation:\",\n \"refusal\": null\n },\n + \ \"logprobs\": null,\n \"finish_reason\": \"stop\"\n }\n ],\n + \ \"usage\": {\n \"prompt_tokens\": 295,\n \"completion_tokens\": 35,\n + \ \"total_tokens\": 330,\n \"completion_tokens_details\": {\n \"reasoning_tokens\": + 0\n }\n },\n \"system_fingerprint\": null\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8c76b07cac90a658-MIA + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Mon, 23 Sep 2024 01:16:27 GMT + Server: + - cloudflare + Set-Cookie: + - __cf_bm=FPv5AG0QfMct7pC4bGELrm0mofIR9eOmKbA9ZOBKH1A-1727054187-1.0.1.1-yGihcpK8XfnbQp9TshK.R3aGtK0umkkBzW1cEJ4BUaLxTvhxuQ3Bd7zP14Qol_FycSsfzHXZoM_upbtrAH5EtQ; + path=/; expires=Mon, 23-Sep-24 01:46:27 GMT; domain=.api.openai.com; HttpOnly; + Secure; SameSite=None + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + openai-organization: + - crewai-iuxna1 + openai-processing-ms: + - '437' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=15552000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '50000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '49999668' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_4528f488436ec971e75e0da5f926a802 + http_version: HTTP/1.1 + status_code: 200 +- request: + body: '{"messages": [{"role": "system", "content": "You are test role. test backstory\nYour + personal goal is: test goal\nYou ONLY have access to the following tools, and + should NEVER make up tools that are not listed here:\n\nTool Name: dummy_tool(*args: + Any, **kwargs: Any) -> Any\nTool Description: dummy_tool(query: ''string'') + - Useful for when you need to get a dummy result for a query. \nTool Arguments: + {''query'': {''title'': ''Query'', ''type'': ''string''}}\n\nUse the following + format:\n\nThought: you should always think about what to do\nAction: the action + to take, only one name of [dummy_tool], just the name, exactly as it''s written.\nAction + Input: the input to the action, just a simple python dictionary, enclosed in + curly braces, using \" to wrap keys and values.\nObservation: the result of + the action\n\nOnce all necessary information is gathered:\n\nThought: I now + know the final answer\nFinal Answer: the final answer to the original input + question\n"}, {"role": "user", "content": "\nCurrent Task: Use the dummy tool + to get a result for ''test query''\n\nThis is the expect criteria for your final + answer: The result from the dummy tool\nyou MUST return the actual complete + content as the final answer, not a summary.\n\nBegin! This is VERY important + to you, use the tools available and give your best Final Answer, your job depends + on it!\n\nThought:"}, {"role": "user", "content": "I should use the dummy tool + to get a result for ''test query''.\n\nAction: \ndummy_tool\n\nAction Input: + \n{\"query\": \"test query\"}\n\nObservation:\nObservation: Dummy result for: + test query"}], "model": "gpt-3.5-turbo"}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '1609' + content-type: + - application/json + cookie: + - _cfuvid=ntPBCCgVUz_nq5Umsn4Dh2nras_FFFm.Om6wrSeiU00-1727053206899-0.0.1.1-604800000; + __cf_bm=FPv5AG0QfMct7pC4bGELrm0mofIR9eOmKbA9ZOBKH1A-1727054187-1.0.1.1-yGihcpK8XfnbQp9TshK.R3aGtK0umkkBzW1cEJ4BUaLxTvhxuQ3Bd7zP14Qol_FycSsfzHXZoM_upbtrAH5EtQ + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.47.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.47.0 + x-stainless-raw-response: + - 'true' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.11.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + content: "{\n \"id\": \"chatcmpl-AARyetCGaZezXJxRa6LAmYL8UMQiI\",\n \"object\": + \"chat.completion\",\n \"created\": 1727054188,\n \"model\": \"gpt-3.5-turbo-0125\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"Final Answer: Dummy result for: test + query\",\n \"refusal\": null\n },\n \"logprobs\": null,\n \"finish_reason\": + \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": 343,\n \"completion_tokens\": + 9,\n \"total_tokens\": 352,\n \"completion_tokens_details\": {\n \"reasoning_tokens\": + 0\n }\n },\n \"system_fingerprint\": null\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8c76b082bc53a658-MIA + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Mon, 23 Sep 2024 01:16:28 GMT + Server: + - cloudflare + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + openai-organization: + - crewai-iuxna1 + openai-processing-ms: + - '172' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=15552000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '50000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '49999624' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_9f59c353b6d763db5393356e52f0ceaa + http_version: HTTP/1.1 + status_code: 200 +version: 1 diff --git a/tests/cassettes/test_agent_execution.yaml b/tests/cassettes/test_agent_execution.yaml index eda38c301..f1f23c34f 100644 --- a/tests/cassettes/test_agent_execution.yaml +++ b/tests/cassettes/test_agent_execution.yaml @@ -9,7 +9,8 @@ interactions: is the expect criteria for your final answer: the result of the math operation.\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:"]}' + Answer, your job depends on it!\n\nThought:"}], "model": "gpt-4o-mini", "stop": + ["\nObservation:"]}' headers: accept: - application/json @@ -18,13 +19,13 @@ interactions: connection: - keep-alive content-length: - - '825' + - '830' content-type: - application/json host: - api.openai.com user-agent: - - OpenAI/Python 1.46.0 + - OpenAI/Python 1.47.0 x-stainless-arch: - arm64 x-stainless-async: @@ -34,7 +35,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.46.0 + - 1.47.0 x-stainless-raw-response: - 'true' x-stainless-runtime: @@ -44,19 +45,20 @@ interactions: method: POST uri: https://api.openai.com/v1/chat/completions response: - content: "{\n \"id\": \"chatcmpl-A8iqOpq4zQ2mP10QxzoPKaEknM2lF\",\n \"object\": - \"chat.completion\",\n \"created\": 1726642368,\n \"model\": \"gpt-4o-2024-05-13\",\n + content: "{\n \"id\": \"chatcmpl-AAOztw2xap7QYw8IXRCCAMJWfio9A\",\n \"object\": + \"chat.completion\",\n \"created\": 1727042733,\n \"model\": \"gpt-4o-mini-2024-07-18\",\n \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": - \"assistant\",\n \"content\": \"Thought: I now can give a great answer\\nFinal - Answer: 1 + 1 = 2\",\n \"refusal\": null\n },\n \"logprobs\": - null,\n \"finish_reason\": \"stop\"\n }\n ],\n \"usage\": {\n \"prompt_tokens\": - 163,\n \"completion_tokens\": 21,\n \"total_tokens\": 184,\n \"completion_tokens_details\": - {\n \"reasoning_tokens\": 0\n }\n },\n \"system_fingerprint\": \"fp_a5d11b2ef2\"\n}\n" + \"assistant\",\n \"content\": \"I now can give a great answer \\nFinal + Answer: The result of the math operation 1 + 1 is 2.\",\n \"refusal\": + null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n + \ }\n ],\n \"usage\": {\n \"prompt_tokens\": 163,\n \"completion_tokens\": + 26,\n \"total_tokens\": 189,\n \"completion_tokens_details\": {\n \"reasoning_tokens\": + 0\n }\n },\n \"system_fingerprint\": \"fp_1bb46167f9\"\n}\n" headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8c4f6a52a98ba67a-MIA + - 8c7598d848b9dad1-MIA Connection: - keep-alive Content-Encoding: @@ -64,14 +66,14 @@ interactions: Content-Type: - application/json Date: - - Wed, 18 Sep 2024 06:52:49 GMT + - Sun, 22 Sep 2024 22:05:33 GMT Server: - cloudflare Set-Cookie: - - __cf_bm=.8.5x0rqghNdtUCxfmwblfhuXiKyPm_cRq.NIa0heL0-1726642369-1.0.1.1-VbsAGqjOt45ZD50K2QW2oZrByLLIh6w8K4nAkLthTbXgU5qTgdf0mhvFId8Q2F3DcHUw9E72lVIZEN.YVlYINQ; - path=/; expires=Wed, 18-Sep-24 07:22:49 GMT; domain=.api.openai.com; HttpOnly; + - __cf_bm=UU82yEuNCTgl7wjFbcJEr2G.foI0pXlMqeJMd.pbTuk-1727042733-1.0.1.1-xYoQDLA8IccsoD9pG0d3FJSOOD8ByW5TNGUPX393kjTotXSUEW_PkKJg9dD_fIghDgHa0BXRQgO.u3g2lBnSPw; + path=/; expires=Sun, 22-Sep-24 22:35:33 GMT; domain=.api.openai.com; HttpOnly; Secure; SameSite=None - - _cfuvid=o5s1Ux898x0eFNtzUCnG996iqyX3LgXDXq99C5oqnVE-1726642369248-0.0.1.1-604800000; + - _cfuvid=7K_eaD_xGFyVkU_8XCBnbyvAO.pgSZQfDXm2KHhKt2A-1727042733333-0.0.1.1-604800000; path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None Transfer-Encoding: - chunked @@ -79,30 +81,28 @@ interactions: - nosniff access-control-expose-headers: - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 openai-organization: - crewai-iuxna1 openai-processing-ms: - - '472' + - '280' openai-version: - '2020-10-01' strict-transport-security: - max-age=15552000; includeSubDomains; preload x-ratelimit-limit-requests: - - '10000' + - '30000' x-ratelimit-limit-tokens: - - '30000000' + - '150000000' x-ratelimit-remaining-requests: - - '9999' + - '29999' x-ratelimit-remaining-tokens: - - '29999811' + - '149999810' x-ratelimit-reset-requests: - - 6ms + - 2ms x-ratelimit-reset-tokens: - 0s x-request-id: - - req_2aa1ae9216cd0ca8e23e1b9857477e2b + - req_7205ad3556c28752658f9dc89a279492 http_version: HTTP/1.1 status_code: 200 version: 1 diff --git a/tests/cassettes/test_agent_with_ollama_gemma.yaml b/tests/cassettes/test_agent_with_ollama_gemma.yaml new file mode 100644 index 000000000..8b864a96a --- /dev/null +++ b/tests/cassettes/test_agent_with_ollama_gemma.yaml @@ -0,0 +1,414 @@ +interactions: +- request: + body: !!binary | + CuWbAQokCiIKDHNlcnZpY2UubmFtZRISChBjcmV3QUktdGVsZW1ldHJ5ErubAQoSChBjcmV3YWku + dGVsZW1ldHJ5ErEHChA66lnCZAp0jmamY2z3VccfEgi8r2tfYjXZASoMQ3JldyBDcmVhdGVkMAE5 + cPdwWTG69xdBYEdyWTG69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42MS4wShoKDnB5dGhvbl92 + ZXJzaW9uEggKBjMuMTEuN0ouCghjcmV3X2tleRIiCiBkNTUxMTNiZTRhYTQxYmE2NDNkMzI2MDQy + YjJmMDNmMUoxCgdjcmV3X2lkEiYKJDgyNGQ4YjYyLTNhMjItNDI4Ny04N2I4LTQ5ZDFiYjAzODYx + YkocCgxjcmV3X3Byb2Nlc3MSDAoKc2VxdWVudGlhbEoRCgtjcmV3X21lbW9yeRICEABKGgoUY3Jl + d19udW1iZXJfb2ZfdGFza3MSAhgBShsKFWNyZXdfbnVtYmVyX29mX2FnZW50cxICGAFKzgIKC2Ny + ZXdfYWdlbnRzEr4CCrsCW3sia2V5IjogImUxNDhlNTMyMDI5MzQ5OWY4Y2ViZWE4MjZlNzI1ODJi + IiwgImlkIjogImZlNGVlMjZjLTk5OTQtNDEyZi1iMzQ1LTMxZmM5MjczMjkwYyIsICJyb2xlIjog + InRlc3Qgcm9sZSIsICJ2ZXJib3NlPyI6IHRydWUsICJtYXhfaXRlciI6IDQsICJtYXhfcnBtIjog + MTAsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6IG51bGwsICJsbG0iOiAiZ3B0LTRvLW1pbmkiLCAi + ZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxsb3dfY29kZV9leGVjdXRpb24/IjogZmFs + c2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNfbmFtZXMiOiBbXX1dSpACCgpjcmV3X3Rh + c2tzEoECCv4BW3sia2V5IjogIjRhMzFiODUxMzNhM2EyOTRjNjg1M2RhNzU3ZDRiYWU3IiwgImlk + IjogImQyNWI0YmNlLTFhNmUtNGI1ZS05YTU1LWE1YmVlN2NiNzEzMiIsICJhc3luY19leGVjdXRp + b24/IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAidGVzdCBy + b2xlIiwgImFnZW50X2tleSI6ICJlMTQ4ZTUzMjAyOTM0OTlmOGNlYmVhODI2ZTcyNTgyYiIsICJ0 + b29sc19uYW1lcyI6IFsiZ2V0X2ZpbmFsX2Fuc3dlciJdfV16AhgBhQEAAQAAEo4CChDUsKBelZ6l + BZKehmrJBxZNEgiWJ9xcT6HzGCoMVGFzayBDcmVhdGVkMAE5aFd9WTG69xdBoKF9WTG69xdKLgoI + Y3Jld19rZXkSIgogZDU1MTEzYmU0YWE0MWJhNjQzZDMyNjA0MmIyZjAzZjFKMQoHY3Jld19pZBIm + CiQ4MjRkOGI2Mi0zYTIyLTQyODctODdiOC00OWQxYmIwMzg2MWJKLgoIdGFza19rZXkSIgogNGEz + MWI4NTEzM2EzYTI5NGM2ODUzZGE3NTdkNGJhZTdKMQoHdGFza19pZBImCiRkMjViNGJjZS0xYTZl + LTRiNWUtOWE1NS1hNWJlZTdjYjcxMzJ6AhgBhQEAAQAAEpMBChBu6jr/KNyBlerXOQp9Wn4cEgiJ + 0Upcmlb7RioKVG9vbCBVc2FnZTABOSBVqVkxuvcXQWDxqVkxuvcXShoKDmNyZXdhaV92ZXJzaW9u + EggKBjAuNjEuMEofCgl0b29sX25hbWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxIC + GAF6AhgBhQEAAQAAEpwBChDVfPL/pwJAXIwLdzOqAS1DEgjEA+G+zrckYSoTVG9vbCBSZXBlYXRl + ZCBVc2FnZTABOQAdz1kxuvcXQSi9z1kxuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEof + Cgl0b29sX25hbWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAA + EpMBChAYYvAkCEeJg2hNexqNUfkIEghDjDngCeFqPCoKVG9vbCBVc2FnZTABOfDP/lkxuvcXQTBs + /1kxuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEofCgl0b29sX25hbWUSEgoQZ2V0X2Zp + bmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpMBChA/tDobjs7QfmRIr1COid+x + EghPI17pKfHlCyoKVG9vbCBVc2FnZTABOWiWLloxuvcXQZA2L1oxuvcXShoKDmNyZXdhaV92ZXJz + aW9uEggKBjAuNjEuMEofCgl0b29sX25hbWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0 + cxICGAF6AhgBhQEAAQAAEpACChBdYo0KAOplXx47fWyrjxQMEghDZ/U2cSTMlioOVGFzayBFeGVj + dXRpb24wATkg4H1ZMbr3F0Fwwl5aMbr3F0ouCghjcmV3X2tleRIiCiBkNTUxMTNiZTRhYTQxYmE2 + NDNkMzI2MDQyYjJmMDNmMUoxCgdjcmV3X2lkEiYKJDgyNGQ4YjYyLTNhMjItNDI4Ny04N2I4LTQ5 + ZDFiYjAzODYxYkouCgh0YXNrX2tleRIiCiA0YTMxYjg1MTMzYTNhMjk0YzY4NTNkYTc1N2Q0YmFl + N0oxCgd0YXNrX2lkEiYKJGQyNWI0YmNlLTFhNmUtNGI1ZS05YTU1LWE1YmVlN2NiNzEzMnoCGAGF + AQABAAAS3AsKEEOJrIAAIocihPqD92Mu9gMSCIKjot4jT63cKgxDcmV3IENyZWF0ZWQwATlIALda + Mbr3F0HYX7haMbr3F0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjYxLjBKGgoOcHl0aG9uX3ZlcnNp + b24SCAoGMy4xMS43Si4KCGNyZXdfa2V5EiIKIDk0YzMwZDZjM2IyYWM4ZmI5NGIyZGNmYzU3MmQw + ZjU5SjEKB2NyZXdfaWQSJgokZDk5YTRhMDItZWUyMy00YmY4LWFmNzUtYmUyNDg3NWY2YWE3ShwK + DGNyZXdfcHJvY2VzcxIMCgpzZXF1ZW50aWFsShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251 + bWJlcl9vZl90YXNrcxICGAJKGwoVY3Jld19udW1iZXJfb2ZfYWdlbnRzEgIYAkqMBQoLY3Jld19h + Z2VudHMS/AQK+QRbeyJrZXkiOiAiZTE0OGU1MzIwMjkzNDk5ZjhjZWJlYTgyNmU3MjU4MmIiLCAi + aWQiOiAiYTUwZWJmYzItNGMwZS00ZDkzLWI2YTQtZTBhMGY5MzFiNDBmIiwgInJvbGUiOiAidGVz + dCByb2xlIiwgInZlcmJvc2U/IjogdHJ1ZSwgIm1heF9pdGVyIjogMiwgIm1heF9ycG0iOiAxMCwg + ImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogbnVsbCwgImxsbSI6ICJncHQtNG8tbWluaSIsICJkZWxl + Z2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8iOiBmYWxzZSwg + Im1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtdfSwgeyJrZXkiOiAiZTdlOGVl + YTg4NmJjYjhmMTA0NWFiZWVjZjE0MjVkYjciLCAiaWQiOiAiNzFhYzQ4YmYtZThhMi00YWEzLWE3 + YjktYTRhMjYzZmY2ZDMxIiwgInJvbGUiOiAidGVzdCByb2xlMiIsICJ2ZXJib3NlPyI6IHRydWUs + ICJtYXhfaXRlciI6IDEsICJtYXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjog + bnVsbCwgImxsbSI6ICJncHQtNG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2Us + ICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0 + b29sc19uYW1lcyI6IFtdfV1K/QMKCmNyZXdfdGFza3MS7gMK6wNbeyJrZXkiOiAiMzIyZGRhZTNi + YzgwYzFkNDViODVmYTc3NTZkYjg2NjUiLCAiaWQiOiAiMGNkMWE1ZTktYzBkZS00Yzk0LTk4ZGYt + NDk5ZjBiNzg0ZWNlIiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6 + IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJ0ZXN0IHJvbGUiLCAiYWdlbnRfa2V5IjogImUxNDhlNTMy + MDI5MzQ5OWY4Y2ViZWE4MjZlNzI1ODJiIiwgInRvb2xzX25hbWVzIjogW119LCB7ImtleSI6ICI1 + ZTljYTdkNjRiNDIwNWJiN2M0N2UwYjNmY2I1ZDIxZiIsICJpZCI6ICJhMDVhMzAyZi0zZTljLTQ4 + ZGYtYmRiNy0yZjA0NzgxNDA5OTciLCAiYXN5bmNfZXhlY3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5f + aW5wdXQ/IjogZmFsc2UsICJhZ2VudF9yb2xlIjogInRlc3Qgcm9sZTIiLCAiYWdlbnRfa2V5Ijog + ImU3ZThlZWE4ODZiY2I4ZjEwNDVhYmVlY2YxNDI1ZGI3IiwgInRvb2xzX25hbWVzIjogWyJnZXRf + ZmluYWxfYW5zd2VyIl19XXoCGAGFAQABAAASjgIKEHLo30A1L7t/kKvIbmbWulYSCCvMsf1Ow30B + KgxUYXNrIENyZWF0ZWQwATmYe8NaMbr3F0G4ycNaMbr3F0ouCghjcmV3X2tleRIiCiA5NGMzMGQ2 + YzNiMmFjOGZiOTRiMmRjZmM1NzJkMGY1OUoxCgdjcmV3X2lkEiYKJGQ5OWE0YTAyLWVlMjMtNGJm + OC1hZjc1LWJlMjQ4NzVmNmFhN0ouCgh0YXNrX2tleRIiCiAzMjJkZGFlM2JjODBjMWQ0NWI4NWZh + Nzc1NmRiODY2NUoxCgd0YXNrX2lkEiYKJDBjZDFhNWU5LWMwZGUtNGM5NC05OGRmLTQ5OWYwYjc4 + NGVjZXoCGAGFAQABAAASkAIKECulgsfsiJGvxQ4E7sgbpgESCOakKapIN5nYKg5UYXNrIEV4ZWN1 + dGlvbjABOcjww1oxuvcXQUCO5VoxuvcXSi4KCGNyZXdfa2V5EiIKIDk0YzMwZDZjM2IyYWM4ZmI5 + NGIyZGNmYzU3MmQwZjU5SjEKB2NyZXdfaWQSJgokZDk5YTRhMDItZWUyMy00YmY4LWFmNzUtYmUy + NDg3NWY2YWE3Si4KCHRhc2tfa2V5EiIKIDMyMmRkYWUzYmM4MGMxZDQ1Yjg1ZmE3NzU2ZGI4NjY1 + SjEKB3Rhc2tfaWQSJgokMGNkMWE1ZTktYzBkZS00Yzk0LTk4ZGYtNDk5ZjBiNzg0ZWNlegIYAYUB + AAEAABKOAgoQc1n32+/V7Zxaaq02sT+weBIIMCEDCslVReUqDFRhc2sgQ3JlYXRlZDABORBg7lox + uvcXQei57loxuvcXSi4KCGNyZXdfa2V5EiIKIDk0YzMwZDZjM2IyYWM4ZmI5NGIyZGNmYzU3MmQw + ZjU5SjEKB2NyZXdfaWQSJgokZDk5YTRhMDItZWUyMy00YmY4LWFmNzUtYmUyNDg3NWY2YWE3Si4K + CHRhc2tfa2V5EiIKIDVlOWNhN2Q2NGI0MjA1YmI3YzQ3ZTBiM2ZjYjVkMjFmSjEKB3Rhc2tfaWQS + JgokYTA1YTMwMmYtM2U5Yy00OGRmLWJkYjctMmYwNDc4MTQwOTk3egIYAYUBAAEAABKTAQoQwiXr + jVHCps3rRFKmZ+Ca8BIINyKrZynSg/QqClRvb2wgVXNhZ2UwATm4EiBbMbr3F0HoBCFbMbr3F0oa + Cg5jcmV3YWlfdmVyc2lvbhIICgYwLjYxLjBKHwoJdG9vbF9uYW1lEhIKEGdldF9maW5hbF9hbnN3 + ZXJKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABKQAgoQeWiicAGw+RAEWli88X108xII8DIvIe2a + G/UqDlRhc2sgRXhlY3V0aW9uMAE5+ODuWjG69xdBYJBFWzG69xdKLgoIY3Jld19rZXkSIgogOTRj + MzBkNmMzYjJhYzhmYjk0YjJkY2ZjNTcyZDBmNTlKMQoHY3Jld19pZBImCiRkOTlhNGEwMi1lZTIz + LTRiZjgtYWY3NS1iZTI0ODc1ZjZhYTdKLgoIdGFza19rZXkSIgogNWU5Y2E3ZDY0YjQyMDViYjdj + NDdlMGIzZmNiNWQyMWZKMQoHdGFza19pZBImCiRhMDVhMzAyZi0zZTljLTQ4ZGYtYmRiNy0yZjA0 + NzgxNDA5OTd6AhgBhQEAAQAAErMHChBEKXGbj8Q/mkeB3c+6ltl6Eghku1BOTY8NvCoMQ3JldyBD + cmVhdGVkMAE5mOOCWzG69xdBuCuEWzG69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42MS4wShoK + DnB5dGhvbl92ZXJzaW9uEggKBjMuMTEuN0ouCghjcmV3X2tleRIiCiA3M2FhYzI4NWU2NzQ2NjY3 + Zjc1MTQ3NjcwMDAzNDExMEoxCgdjcmV3X2lkEiYKJDFkMTQwN2U3LWE1MjQtNGI1ZC04MTE2LTQx + NmIwNDBkYTY0Y0ocCgxjcmV3X3Byb2Nlc3MSDAoKc2VxdWVudGlhbEoRCgtjcmV3X21lbW9yeRIC + EABKGgoUY3Jld19udW1iZXJfb2ZfdGFza3MSAhgBShsKFWNyZXdfbnVtYmVyX29mX2FnZW50cxIC + GAFK0AIKC2NyZXdfYWdlbnRzEsACCr0CW3sia2V5IjogImUxNDhlNTMyMDI5MzQ5OWY4Y2ViZWE4 + MjZlNzI1ODJiIiwgImlkIjogImM3YTYzNDc1LTIzNDMtNDhkNC1hNTRjLTQyZDE5YTYwNzEzZSIs + ICJyb2xlIjogInRlc3Qgcm9sZSIsICJ2ZXJib3NlPyI6IHRydWUsICJtYXhfaXRlciI6IDEsICJt + YXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogbnVsbCwgImxsbSI6ICJncHQt + NG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1 + dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtdfV1K + kAIKCmNyZXdfdGFza3MSgQIK/gFbeyJrZXkiOiAiZjdhOWY3YmIxYWVlNGI2ZWYyYzUyNmQwYThj + MmYyYWMiLCAiaWQiOiAiYTA3NTIyZTItMDRhNS00NDc4LWFjZjQtMmQwYjJiYTU0MmEyIiwgImFz + eW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9s + ZSI6ICJ0ZXN0IHJvbGUiLCAiYWdlbnRfa2V5IjogImUxNDhlNTMyMDI5MzQ5OWY4Y2ViZWE4MjZl + NzI1ODJiIiwgInRvb2xzX25hbWVzIjogWyJnZXRfZmluYWxfYW5zd2VyIl19XXoCGAGFAQABAAAS + jgIKECg0tu1LauV9kQ6zOL0KF4wSCIREvErggJ5fKgxUYXNrIENyZWF0ZWQwATnAR41bMbr3F0Eo + io1bMbr3F0ouCghjcmV3X2tleRIiCiA3M2FhYzI4NWU2NzQ2NjY3Zjc1MTQ3NjcwMDAzNDExMEox + CgdjcmV3X2lkEiYKJDFkMTQwN2U3LWE1MjQtNGI1ZC04MTE2LTQxNmIwNDBkYTY0Y0ouCgh0YXNr + X2tleRIiCiBmN2E5ZjdiYjFhZWU0YjZlZjJjNTI2ZDBhOGMyZjJhY0oxCgd0YXNrX2lkEiYKJGEw + NzUyMmUyLTA0YTUtNDQ3OC1hY2Y0LTJkMGIyYmE1NDJhMnoCGAGFAQABAAASeQoQkue3s7a8LH95 + BSK7yPMZcxIIUBw0RVdZMZgqEFRvb2wgVXNhZ2UgRXJyb3IwATmIbLlbMbr3F0GwDLpbMbr3F0oa + Cg5jcmV3YWlfdmVyc2lvbhIICgYwLjYxLjBKDwoDbGxtEggKBmdwdC00b3oCGAGFAQABAAASkAIK + EPmZ7KU1dsuWMef7j8iG6QUSCKOBb3Id5ubtKg5UYXNrIEV4ZWN1dGlvbjABOWipjVsxuvcXQWg6 + 3lsxuvcXSi4KCGNyZXdfa2V5EiIKIDczYWFjMjg1ZTY3NDY2NjdmNzUxNDc2NzAwMDM0MTEwSjEK + B2NyZXdfaWQSJgokMWQxNDA3ZTctYTUyNC00YjVkLTgxMTYtNDE2YjA0MGRhNjRjSi4KCHRhc2tf + a2V5EiIKIGY3YTlmN2JiMWFlZTRiNmVmMmM1MjZkMGE4YzJmMmFjSjEKB3Rhc2tfaWQSJgokYTA3 + NTIyZTItMDRhNS00NDc4LWFjZjQtMmQwYjJiYTU0MmEyegIYAYUBAAEAABKzBwoQeJA6NPDnXshY + kvyLHLWcjRIIj0nuurgzSH0qDENyZXcgQ3JlYXRlZDABOThhQVwxuvcXQSixQlwxuvcXShoKDmNy + ZXdhaV92ZXJzaW9uEggKBjAuNjEuMEoaCg5weXRob25fdmVyc2lvbhIICgYzLjExLjdKLgoIY3Jl + d19rZXkSIgogZDU1MTEzYmU0YWE0MWJhNjQzZDMyNjA0MmIyZjAzZjFKMQoHY3Jld19pZBImCiQw + NzNkMGIzMS1iNzZjLTRmYTgtOTc5MC0yMTM1NzM0YjdiZjdKHAoMY3Jld19wcm9jZXNzEgwKCnNl + cXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdfbnVtYmVyX29mX3Rhc2tzEgIYAUob + ChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgBStACCgtjcmV3X2FnZW50cxLAAgq9Alt7ImtleSI6 + ICJlMTQ4ZTUzMjAyOTM0OTlmOGNlYmVhODI2ZTcyNTgyYiIsICJpZCI6ICJmZmMwZGQzNy0xY2Ix + LTQ1MzYtODIzYy1lMTg0NGI1YzI3NmQiLCAicm9sZSI6ICJ0ZXN0IHJvbGUiLCAidmVyYm9zZT8i + OiB0cnVlLCAibWF4X2l0ZXIiOiA2LCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5n + X2xsbSI6IG51bGwsICJsbG0iOiAiZ3B0LTRvLW1pbmkiLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6 + IGZhbHNlLCAiYWxsb3dfY29kZV9leGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQi + OiAyLCAidG9vbHNfbmFtZXMiOiBbXX1dSpACCgpjcmV3X3Rhc2tzEoECCv4BW3sia2V5IjogIjRh + MzFiODUxMzNhM2EyOTRjNjg1M2RhNzU3ZDRiYWU3IiwgImlkIjogIjMxYmY2OTQ0LTY1ODItNDI4 + Ni05YTE5LWQwMzQ4YTJmN2NkNiIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2UsICJodW1hbl9p + bnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAidGVzdCByb2xlIiwgImFnZW50X2tleSI6ICJl + MTQ4ZTUzMjAyOTM0OTlmOGNlYmVhODI2ZTcyNTgyYiIsICJ0b29sc19uYW1lcyI6IFsiZ2V0X2Zp + bmFsX2Fuc3dlciJdfV16AhgBhQEAAQAAEo4CChC4wbFNzz2spD82UARQUvmyEggyaiqAc36icCoM + VGFzayBDcmVhdGVkMAE5QHdLXDG69xdBwLVLXDG69xdKLgoIY3Jld19rZXkSIgogZDU1MTEzYmU0 + YWE0MWJhNjQzZDMyNjA0MmIyZjAzZjFKMQoHY3Jld19pZBImCiQwNzNkMGIzMS1iNzZjLTRmYTgt + OTc5MC0yMTM1NzM0YjdiZjdKLgoIdGFza19rZXkSIgogNGEzMWI4NTEzM2EzYTI5NGM2ODUzZGE3 + NTdkNGJhZTdKMQoHdGFza19pZBImCiQzMWJmNjk0NC02NTgyLTQyODYtOWExOS1kMDM0OGEyZjdj + ZDZ6AhgBhQEAAQAAEpMBChDFwxqDcGBo/EMFDXR29VSgEgiA1uiow8dQkCoKVG9vbCBVc2FnZTAB + OWCZfFwxuvcXQUBFfVwxuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEofCgl0b29sX25h + bWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpwBChBgPvcw + zdQZe95bIFZ5cYA0Egh/vzzL1K04KSoTVG9vbCBSZXBlYXRlZCBVc2FnZTABORBXpVwxuvcXQVDz + pVwxuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEofCgl0b29sX25hbWUSEgoQZ2V0X2Zp + bmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpwBChDH26gsph3MsoUUP+48lGHG + Egg6KKr6O7peSSoTVG9vbCBSZXBlYXRlZCBVc2FnZTABOfB30VwxuvcXQWAM0lwxuvcXShoKDmNy + ZXdhaV92ZXJzaW9uEggKBjAuNjEuMEofCgl0b29sX25hbWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoO + CghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpwBChAlAPo1vE80Ytk5j/gxUiFkEggkrUu0vKvu1SoT + VG9vbCBSZXBlYXRlZCBVc2FnZTABOahLBF0xuvcXQXjQBF0xuvcXShoKDmNyZXdhaV92ZXJzaW9u + EggKBjAuNjEuMEofCgl0b29sX25hbWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxIC + GAF6AhgBhQEAAQAAEpwBChDAi4YfDxl1XGitu+UfRZ64Egh8DOC5/gmH4SoTVG9vbCBSZXBlYXRl + ZCBVc2FnZTABOZAXN10xuvcXQWCcN10xuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEof + Cgl0b29sX25hbWUSEgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAA + EpwBChClq81QoLUyX83qB0IF8/uoEghzOPq6U0yZnioTVG9vbCBSZXBlYXRlZCBVc2FnZTABOUjB + cF0xuvcXQRhGcV0xuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEofCgl0b29sX25hbWUS + EgoQZ2V0X2ZpbmFsX2Fuc3dlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpACChC+6iqMvnU2 + fBtH6jGke1iUEgggB0v9vpHCiCoOVGFzayBFeGVjdXRpb24wATmg5EtcMbr3F0Gwp6ldMbr3F0ou + CghjcmV3X2tleRIiCiBkNTUxMTNiZTRhYTQxYmE2NDNkMzI2MDQyYjJmMDNmMUoxCgdjcmV3X2lk + EiYKJDA3M2QwYjMxLWI3NmMtNGZhOC05NzkwLTIxMzU3MzRiN2JmN0ouCgh0YXNrX2tleRIiCiA0 + YTMxYjg1MTMzYTNhMjk0YzY4NTNkYTc1N2Q0YmFlN0oxCgd0YXNrX2lkEiYKJDMxYmY2OTQ0LTY1 + ODItNDI4Ni05YTE5LWQwMzQ4YTJmN2NkNnoCGAGFAQABAAASvA0KEFD+TKUJtmoBZpdcH08Gxn0S + CGDDfX3hDPKPKgxDcmV3IENyZWF0ZWQwATkY4eldMbr3F0HYOOtdMbr3F0oaCg5jcmV3YWlfdmVy + c2lvbhIICgYwLjYxLjBKGgoOcHl0aG9uX3ZlcnNpb24SCAoGMy4xMS43Si4KCGNyZXdfa2V5EiIK + IDExMWI4NzJkOGYwY2Y3MDNmMmVmZWYwNGNmM2FjNzk4SjEKB2NyZXdfaWQSJgokMmQ4NjhhNjYt + YmYzOC00NTk4LTk1YjktZGU2MDQ0OTNlZmEyShwKDGNyZXdfcHJvY2VzcxIMCgpzZXF1ZW50aWFs + ShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251bWJlcl9vZl90YXNrcxICGANKGwoVY3Jld19u + dW1iZXJfb2ZfYWdlbnRzEgIYAkqSBQoLY3Jld19hZ2VudHMSggUK/wRbeyJrZXkiOiAiZTE0OGU1 + MzIwMjkzNDk5ZjhjZWJlYTgyNmU3MjU4MmIiLCAiaWQiOiAiODI1NDdmNDAtNGE2NC00ZjVlLTll + YzktMjI5NjQxZjIyYmNlIiwgInJvbGUiOiAidGVzdCByb2xlIiwgInZlcmJvc2U/IjogZmFsc2Us + ICJtYXhfaXRlciI6IDE1LCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6 + IG51bGwsICJsbG0iOiAiZ3B0LTRvLW1pbmkiLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNl + LCAiYWxsb3dfY29kZV9leGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAi + dG9vbHNfbmFtZXMiOiBbXX0sIHsia2V5IjogImU3ZThlZWE4ODZiY2I4ZjEwNDVhYmVlY2YxNDI1 + ZGI3IiwgImlkIjogImFlNjEwMGI0LTE1NTQtNGRlMS05NDI5LTMwNTQwZjIwN2M4ZSIsICJyb2xl + IjogInRlc3Qgcm9sZTIiLCAidmVyYm9zZT8iOiBmYWxzZSwgIm1heF9pdGVyIjogMTUsICJtYXhf + cnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogbnVsbCwgImxsbSI6ICJncHQtNG8t + bWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlv + bj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFtdfV1K1wUK + CmNyZXdfdGFza3MSyAUKxQVbeyJrZXkiOiAiMzIyZGRhZTNiYzgwYzFkNDViODVmYTc3NTZkYjg2 + NjUiLCAiaWQiOiAiMWZlOTU1M2YtMDE5Yy00MjkxLTkyMjQtNmFlZmRhMTBhZTdlIiwgImFzeW5j + X2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6 + ICJ0ZXN0IHJvbGUiLCAiYWdlbnRfa2V5IjogImUxNDhlNTMyMDI5MzQ5OWY4Y2ViZWE4MjZlNzI1 + ODJiIiwgInRvb2xzX25hbWVzIjogW119LCB7ImtleSI6ICJjYzQ4NzZmNmU1ODhlNzEzNDliYmQz + YTY1ODg4YzNlOSIsICJpZCI6ICI3ZmQyOGViNi00MmQ3LTQ3YjMtOTQ4Ni1mMmM5MGQ3YjVlZjki + LCAiYXN5bmNfZXhlY3V0aW9uPyI6IGZhbHNlLCAiaHVtYW5faW5wdXQ/IjogZmFsc2UsICJhZ2Vu + dF9yb2xlIjogInRlc3Qgcm9sZSIsICJhZ2VudF9rZXkiOiAiZTE0OGU1MzIwMjkzNDk5ZjhjZWJl + YTgyNmU3MjU4MmIiLCAidG9vbHNfbmFtZXMiOiBbXX0sIHsia2V5IjogImUwYjEzZTEwZDdhMTQ2 + ZGNjNGM0ODhmY2Y4ZDc0OGEwIiwgImlkIjogImYzZTA3NWExLTU1YzMtNDA5Ni1iNmI1LTdjODQ4 + MDk5OTVjYSIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxz + ZSwgImFnZW50X3JvbGUiOiAidGVzdCByb2xlMiIsICJhZ2VudF9rZXkiOiAiZTdlOGVlYTg4NmJj + YjhmMTA0NWFiZWVjZjE0MjVkYjciLCAidG9vbHNfbmFtZXMiOiBbXX1degIYAYUBAAEAABKOAgoQ + o1N6YHHCr5jUZzS/ycXtLxIIT9AOCM9UZ5wqDFRhc2sgQ3JlYXRlZDABORgc9V0xuvcXQThq9V0x + uvcXSi4KCGNyZXdfa2V5EiIKIDExMWI4NzJkOGYwY2Y3MDNmMmVmZWYwNGNmM2FjNzk4SjEKB2Ny + ZXdfaWQSJgokMmQ4NjhhNjYtYmYzOC00NTk4LTk1YjktZGU2MDQ0OTNlZmEySi4KCHRhc2tfa2V5 + EiIKIDMyMmRkYWUzYmM4MGMxZDQ1Yjg1ZmE3NzU2ZGI4NjY1SjEKB3Rhc2tfaWQSJgokMWZlOTU1 + M2YtMDE5Yy00MjkxLTkyMjQtNmFlZmRhMTBhZTdlegIYAYUBAAEAABKQAgoQCHxqPXqNgAROL6iH + d5V86hIIYFjnWSdcD2UqDlRhc2sgRXhlY3V0aW9uMAE5eIn1XTG69xdB0NgWXjG69xdKLgoIY3Jl + d19rZXkSIgogMTExYjg3MmQ4ZjBjZjcwM2YyZWZlZjA0Y2YzYWM3OThKMQoHY3Jld19pZBImCiQy + ZDg2OGE2Ni1iZjM4LTQ1OTgtOTViOS1kZTYwNDQ5M2VmYTJKLgoIdGFza19rZXkSIgogMzIyZGRh + ZTNiYzgwYzFkNDViODVmYTc3NTZkYjg2NjVKMQoHdGFza19pZBImCiQxZmU5NTUzZi0wMTljLTQy + OTEtOTIyNC02YWVmZGExMGFlN2V6AhgBhQEAAQAAEo4CChBL6m032v7GXUDa4LNan34aEgj8plKo + R1qInSoMVGFzayBDcmVhdGVkMAE5UGoeXjG69xdBQMAeXjG69xdKLgoIY3Jld19rZXkSIgogMTEx + Yjg3MmQ4ZjBjZjcwM2YyZWZlZjA0Y2YzYWM3OThKMQoHY3Jld19pZBImCiQyZDg2OGE2Ni1iZjM4 + LTQ1OTgtOTViOS1kZTYwNDQ5M2VmYTJKLgoIdGFza19rZXkSIgogY2M0ODc2ZjZlNTg4ZTcxMzQ5 + YmJkM2E2NTg4OGMzZTlKMQoHdGFza19pZBImCiQ3ZmQyOGViNi00MmQ3LTQ3YjMtOTQ4Ni1mMmM5 + MGQ3YjVlZjl6AhgBhQEAAQAAEpACChCeuw2vzs3Zn11PaSM+C+pvEgjWDq+EL8vbWioOVGFzayBF + eGVjdXRpb24wATmA3x5eMbr3F0HIB0BeMbr3F0ouCghjcmV3X2tleRIiCiAxMTFiODcyZDhmMGNm + NzAzZjJlZmVmMDRjZjNhYzc5OEoxCgdjcmV3X2lkEiYKJDJkODY4YTY2LWJmMzgtNDU5OC05NWI5 + LWRlNjA0NDkzZWZhMkouCgh0YXNrX2tleRIiCiBjYzQ4NzZmNmU1ODhlNzEzNDliYmQzYTY1ODg4 + YzNlOUoxCgd0YXNrX2lkEiYKJDdmZDI4ZWI2LTQyZDctNDdiMy05NDg2LWYyYzkwZDdiNWVmOXoC + GAGFAQABAAASjgIKEOQtiJbfWOa3D1b1n0qJllISCMRsgl2dX71VKgxUYXNrIENyZWF0ZWQwATn4 + TEheMbr3F0G4qkheMbr3F0ouCghjcmV3X2tleRIiCiAxMTFiODcyZDhmMGNmNzAzZjJlZmVmMDRj + ZjNhYzc5OEoxCgdjcmV3X2lkEiYKJDJkODY4YTY2LWJmMzgtNDU5OC05NWI5LWRlNjA0NDkzZWZh + MkouCgh0YXNrX2tleRIiCiBlMGIxM2UxMGQ3YTE0NmRjYzRjNDg4ZmNmOGQ3NDhhMEoxCgd0YXNr + X2lkEiYKJGYzZTA3NWExLTU1YzMtNDA5Ni1iNmI1LTdjODQ4MDk5OTVjYXoCGAGFAQABAAASkAIK + EC/GgPcV8FOnDajKDog7Qb4SCJNsCh/hc5O5Kg5UYXNrIEV4ZWN1dGlvbjABOeDNSF4xuvcXQSCS + bF4xuvcXSi4KCGNyZXdfa2V5EiIKIDExMWI4NzJkOGYwY2Y3MDNmMmVmZWYwNGNmM2FjNzk4SjEK + B2NyZXdfaWQSJgokMmQ4NjhhNjYtYmYzOC00NTk4LTk1YjktZGU2MDQ0OTNlZmEySi4KCHRhc2tf + a2V5EiIKIGUwYjEzZTEwZDdhMTQ2ZGNjNGM0ODhmY2Y4ZDc0OGEwSjEKB3Rhc2tfaWQSJgokZjNl + MDc1YTEtNTVjMy00MDk2LWI2YjUtN2M4NDgwOTk5NWNhegIYAYUBAAEAABLDBwoQfWXIePQJWpwK + Oo0nX5pRgRIIf+KH0XBoHMgqDENyZXcgQ3JlYXRlZDABOaBC114xuvcXQTCi2F4xuvcXShoKDmNy + ZXdhaV92ZXJzaW9uEggKBjAuNjEuMEoaCg5weXRob25fdmVyc2lvbhIICgYzLjExLjdKLgoIY3Jl + d19rZXkSIgogNDk0ZjM2NTcyMzdhZDhhMzAzNWIyZjFiZWVjZGM2NzdKMQoHY3Jld19pZBImCiQ2 + ZmQxZjUwMy01ODljLTRmZjgtYmYzOC05MTc0NTdmMDdmNWJKHAoMY3Jld19wcm9jZXNzEgwKCnNl + cXVlbnRpYWxKEQoLY3Jld19tZW1vcnkSAhAAShoKFGNyZXdfbnVtYmVyX29mX3Rhc2tzEgIYAUob + ChVjcmV3X251bWJlcl9vZl9hZ2VudHMSAhgBSuICCgtjcmV3X2FnZW50cxLSAgrPAlt7ImtleSI6 + ICJlMTQ4ZTUzMjAyOTM0OTlmOGNlYmVhODI2ZTcyNTgyYiIsICJpZCI6ICI3OTc4NDA5YS1kYjBk + LTQ1YjEtYTI3OC1hNDA5MmNiODEwMWIiLCAicm9sZSI6ICJ0ZXN0IHJvbGUiLCAidmVyYm9zZT8i + OiBmYWxzZSwgIm1heF9pdGVyIjogMTUsICJtYXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxp + bmdfbGxtIjogbnVsbCwgImxsbSI6ICJncHQtNG8tbWluaSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/ + IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8iOiBmYWxzZSwgIm1heF9yZXRyeV9saW1p + dCI6IDIsICJ0b29sc19uYW1lcyI6IFsibGVhcm5fYWJvdXRfYWkiXX1dSo4CCgpjcmV3X3Rhc2tz + Ev8BCvwBW3sia2V5IjogImYyNTk3Yzc4NjdmYmUzMjRkYzY1ZGMwOGRmZGJmYzZjIiwgImlkIjog + IjdkZGRjZjRjLTYzZWItNDllZC1iMDRiLWZiMzM4ZThiYjg3ZiIsICJhc3luY19leGVjdXRpb24/ + IjogZmFsc2UsICJodW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAidGVzdCByb2xl + IiwgImFnZW50X2tleSI6ICJlMTQ4ZTUzMjAyOTM0OTlmOGNlYmVhODI2ZTcyNTgyYiIsICJ0b29s + c19uYW1lcyI6IFsibGVhcm5fYWJvdXRfYWkiXX1degIYAYUBAAEAABKOAgoQPpfyYNjj3j+wBL71 + IyT5rxIIrmHtSGsmMmcqDFRhc2sgQ3JlYXRlZDABObhV6F4xuvcXQTiU6F4xuvcXSi4KCGNyZXdf + a2V5EiIKIDQ5NGYzNjU3MjM3YWQ4YTMwMzViMmYxYmVlY2RjNjc3SjEKB2NyZXdfaWQSJgokNmZk + MWY1MDMtNTg5Yy00ZmY4LWJmMzgtOTE3NDU3ZjA3ZjViSi4KCHRhc2tfa2V5EiIKIGYyNTk3Yzc4 + NjdmYmUzMjRkYzY1ZGMwOGRmZGJmYzZjSjEKB3Rhc2tfaWQSJgokN2RkZGNmNGMtNjNlYi00OWVk + LWIwNGItZmIzMzhlOGJiODdmegIYAYUBAAEAABKRAQoQPsls9GpYeODbW1lMDNMTShIIhiaeao1O + /jQqClRvb2wgVXNhZ2UwATmgRRVfMbr3F0HI5RVfMbr3F0oaCg5jcmV3YWlfdmVyc2lvbhIICgYw + LjYxLjBKHQoJdG9vbF9uYW1lEhAKDmxlYXJuX2Fib3V0X0FJSg4KCGF0dGVtcHRzEgIYAXoCGAGF + AQABAAASmgEKELh9naXbcbP48RBxUjRWtS4SCAgZX5zXj12nKhNUb29sIFJlcGVhdGVkIFVzYWdl + MAE5OJw6XzG69xdBqDA7XzG69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42MS4wSh0KCXRvb2xf + bmFtZRIQCg5sZWFybl9hYm91dF9BSUoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpoBChA8OXgd + geN1QrW+iMiwSKMEEgioOtafQLN2SCoTVG9vbCBSZXBlYXRlZCBVc2FnZTABOTBIZF8xuvcXQdDU + ZF8xuvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEodCgl0b29sX25hbWUSEAoObGVhcm5f + YWJvdXRfQUlKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABKaAQoQP7zTP/ghho4dPzHqShuYKxII + NVDNbbsPYxIqE1Rvb2wgUmVwZWF0ZWQgVXNhZ2UwATkArZNfMbr3F0FYRZRfMbr3F0oaCg5jcmV3 + YWlfdmVyc2lvbhIICgYwLjYxLjBKHQoJdG9vbF9uYW1lEhAKDmxlYXJuX2Fib3V0X0FJSg4KCGF0 + dGVtcHRzEgIYAXoCGAGFAQABAAASkQEKEKdSfsLwuf9aMPhM6RtjDlASCARdJ6t00k7eKgpUb29s + IFVzYWdlMAE5MGHIXzG69xdB6OnIXzG69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42MS4wSh0K + CXRvb2xfbmFtZRIQCg5sZWFybl9hYm91dF9BSUoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpEB + ChAUEO/lzHqc8Xy9R73aZOgGEghxKMxON+3EoSoKVG9vbCBVc2FnZTABOVBr/V8xuvcXQdj7/V8x + uvcXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuNjEuMEodCgl0b29sX25hbWUSEAoObGVhcm5fYWJv + dXRfQUlKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABKRAQoQ1q8Q9l7OXCcRGKdQIwMvlRIIaj2O + L2w6AyUqClRvb2wgVXNhZ2UwATlA1jhgMbr3F0EQWzlgMbr3F0oaCg5jcmV3YWlfdmVyc2lvbhII + CgYwLjYxLjBKHQoJdG9vbF9uYW1lEhAKDmxlYXJuX2Fib3V0X0FJSg4KCGF0dGVtcHRzEgIYAXoC + GAGFAQABAAASkQEKEI8pTqXg3/pOnacGcamQ+1USCHAgIqdrIB5EKgpUb29sIFVzYWdlMAE5sNJ7 + YDG69xdBsE98YDG69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42MS4wSh0KCXRvb2xfbmFtZRIQ + Cg5sZWFybl9hYm91dF9BSUoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpACChC9K8+3LiRv8w53 + mzCVpJQPEgjcZRryiyMwgSoOVGFzayBFeGVjdXRpb24wATl4s+heMbr3F0HoCvxgMbr3F0ouCghj + cmV3X2tleRIiCiA0OTRmMzY1NzIzN2FkOGEzMDM1YjJmMWJlZWNkYzY3N0oxCgdjcmV3X2lkEiYK + JDZmZDFmNTAzLTU4OWMtNGZmOC1iZjM4LTkxNzQ1N2YwN2Y1YkouCgh0YXNrX2tleRIiCiBmMjU5 + N2M3ODY3ZmJlMzI0ZGM2NWRjMDhkZmRiZmM2Y0oxCgd0YXNrX2lkEiYKJDdkZGRjZjRjLTYzZWIt + NDllZC1iMDRiLWZiMzM4ZThiYjg3ZnoCGAGFAQABAAASwQcKEMji0BuV/C9342KH5RROsnUSCB2v + RauVUTiRKgxDcmV3IENyZWF0ZWQwATnoU1hhMbr3F0EQcVlhMbr3F0oaCg5jcmV3YWlfdmVyc2lv + bhIICgYwLjYxLjBKGgoOcHl0aG9uX3ZlcnNpb24SCAoGMy4xMS43Si4KCGNyZXdfa2V5EiIKIDQ5 + NGYzNjU3MjM3YWQ4YTMwMzViMmYxYmVlY2RjNjc3SjEKB2NyZXdfaWQSJgokMmYwOWRkMTUtYjhk + NS00NmEyLWE3ZmEtZWNlMzRkNjE3YzUyShwKDGNyZXdfcHJvY2VzcxIMCgpzZXF1ZW50aWFsShEK + C2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251bWJlcl9vZl90YXNrcxICGAFKGwoVY3Jld19udW1i + ZXJfb2ZfYWdlbnRzEgIYAUrgAgoLY3Jld19hZ2VudHMS0AIKzQJbeyJrZXkiOiAiZTE0OGU1MzIw + MjkzNDk5ZjhjZWJlYTgyNmU3MjU4MmIiLCAiaWQiOiAiNTQ0YTRkMmItZjQzZS00YjViLWJmNmUt + OGQ3NDVhZDJjNzA1IiwgInJvbGUiOiAidGVzdCByb2xlIiwgInZlcmJvc2U/IjogZmFsc2UsICJt + YXhfaXRlciI6IDIsICJtYXhfcnBtIjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogImdw + dC00byIsICJsbG0iOiAiZ3B0LTRvIiwgImRlbGVnYXRpb25fZW5hYmxlZD8iOiBmYWxzZSwgImFs + bG93X2NvZGVfZXhlY3V0aW9uPyI6IGZhbHNlLCAibWF4X3JldHJ5X2xpbWl0IjogMiwgInRvb2xz + X25hbWVzIjogWyJsZWFybl9hYm91dF9haSJdfV1KjgIKCmNyZXdfdGFza3MS/wEK/AFbeyJrZXki + OiAiZjI1OTdjNzg2N2ZiZTMyNGRjNjVkYzA4ZGZkYmZjNmMiLCAiaWQiOiAiYzc4OWJkNzktODhm + ZC00Y2MwLTlkMGQtYzYyMjk0MTM5MTg2IiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1 + bWFuX2lucHV0PyI6IGZhbHNlLCAiYWdlbnRfcm9sZSI6ICJ0ZXN0IHJvbGUiLCAiYWdlbnRfa2V5 + IjogImUxNDhlNTMyMDI5MzQ5OWY4Y2ViZWE4MjZlNzI1ODJiIiwgInRvb2xzX25hbWVzIjogWyJs + ZWFybl9hYm91dF9haSJdfV16AhgBhQEAAQAAEo4CChB6h/qJrRlWwxAH5esv3MpZEghH4onPhmD9 + 2ioMVGFzayBDcmVhdGVkMAE5kGdlYTG69xdBEKZlYTG69xdKLgoIY3Jld19rZXkSIgogNDk0ZjM2 + NTcyMzdhZDhhMzAzNWIyZjFiZWVjZGM2NzdKMQoHY3Jld19pZBImCiQyZjA5ZGQxNS1iOGQ1LTQ2 + YTItYTdmYS1lY2UzNGQ2MTdjNTJKLgoIdGFza19rZXkSIgogZjI1OTdjNzg2N2ZiZTMyNGRjNjVk + YzA4ZGZkYmZjNmNKMQoHdGFza19pZBImCiRjNzg5YmQ3OS04OGZkLTRjYzAtOWQwZC1jNjIyOTQx + MzkxODZ6AhgBhQEAAQAAEpACChATBXliaJFV7CD6oib3IC0YEggWOoYmUOkZGyoOVGFzayBFeGVj + dXRpb24wATlQxWVhMbr3F0HgLLNiMbr3F0ouCghjcmV3X2tleRIiCiA0OTRmMzY1NzIzN2FkOGEz + MDM1YjJmMWJlZWNkYzY3N0oxCgdjcmV3X2lkEiYKJDJmMDlkZDE1LWI4ZDUtNDZhMi1hN2ZhLWVj + ZTM0ZDYxN2M1MkouCgh0YXNrX2tleRIiCiBmMjU5N2M3ODY3ZmJlMzI0ZGM2NWRjMDhkZmRiZmM2 + Y0oxCgd0YXNrX2lkEiYKJGM3ODliZDc5LTg4ZmQtNGNjMC05ZDBkLWM2MjI5NDEzOTE4NnoCGAGF + AQABAAASywcKEN5kDnCmLtjVwRRXH/W3GOASCJn9JNjr422AKgxDcmV3IENyZWF0ZWQwATlIZB1j + Mbr3F0HYwx5jMbr3F0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjYxLjBKGgoOcHl0aG9uX3ZlcnNp + b24SCAoGMy4xMS43Si4KCGNyZXdfa2V5EiIKIDdlNjYwODk4OTg1OWE2N2VlYzg4ZWVmN2ZjZTg1 + MjI1SjEKB2NyZXdfaWQSJgokNmVmNjBhNWEtM2ZhYS00ZmVhLTk4YjQtMDYwNmNmNTQyMjE4ShwK + DGNyZXdfcHJvY2VzcxIMCgpzZXF1ZW50aWFsShEKC2NyZXdfbWVtb3J5EgIQAEoaChRjcmV3X251 + bWJlcl9vZl90YXNrcxICGAFKGwoVY3Jld19udW1iZXJfb2ZfYWdlbnRzEgIYAUrmAgoLY3Jld19h + Z2VudHMS1gIK0wJbeyJrZXkiOiAiMjJhY2Q2MTFlNDRlZjVmYWMwNWI1MzNkNzVlODg5M2IiLCAi + aWQiOiAiM2I1ZTgwMjQtZGQ2MS00ZWU2LThkNjUtZTdiMjQ1ZmNlNDBkIiwgInJvbGUiOiAiRGF0 + YSBTY2llbnRpc3QiLCAidmVyYm9zZT8iOiBmYWxzZSwgIm1heF9pdGVyIjogMTUsICJtYXhfcnBt + IjogbnVsbCwgImZ1bmN0aW9uX2NhbGxpbmdfbGxtIjogbnVsbCwgImxsbSI6ICJncHQtNG8tbWlu + aSIsICJkZWxlZ2F0aW9uX2VuYWJsZWQ/IjogZmFsc2UsICJhbGxvd19jb2RlX2V4ZWN1dGlvbj8i + OiBmYWxzZSwgIm1heF9yZXRyeV9saW1pdCI6IDIsICJ0b29sc19uYW1lcyI6IFsiZ2V0IGdyZWV0 + aW5ncyJdfV1KkgIKCmNyZXdfdGFza3MSgwIKgAJbeyJrZXkiOiAiYTI3N2IzNGIyYzE0NmYwYzU2 + YzVlMTM1NmU4ZjhhNTciLCAiaWQiOiAiY2NhZGNkMzgtYWZiYi00MWEyLTk5NzctNTBlZjkzOTVm + M2RjIiwgImFzeW5jX2V4ZWN1dGlvbj8iOiBmYWxzZSwgImh1bWFuX2lucHV0PyI6IGZhbHNlLCAi + YWdlbnRfcm9sZSI6ICJEYXRhIFNjaWVudGlzdCIsICJhZ2VudF9rZXkiOiAiMjJhY2Q2MTFlNDRl + ZjVmYWMwNWI1MzNkNzVlODg5M2IiLCAidG9vbHNfbmFtZXMiOiBbImdldCBncmVldGluZ3MiXX1d + egIYAYUBAAEAABKOAgoQqiyAnxIfoShk85pxpoaR1BII66GZDQsVZlQqDFRhc2sgQ3JlYXRlZDAB + OQAcK2MxuvcXQWheK2MxuvcXSi4KCGNyZXdfa2V5EiIKIDdlNjYwODk4OTg1OWE2N2VlYzg4ZWVm + N2ZjZTg1MjI1SjEKB2NyZXdfaWQSJgokNmVmNjBhNWEtM2ZhYS00ZmVhLTk4YjQtMDYwNmNmNTQy + MjE4Si4KCHRhc2tfa2V5EiIKIGEyNzdiMzRiMmMxNDZmMGM1NmM1ZTEzNTZlOGY4YTU3SjEKB3Rh + c2tfaWQSJgokY2NhZGNkMzgtYWZiYi00MWEyLTk5NzctNTBlZjkzOTVmM2RjegIYAYUBAAEAABKQ + AQoQFMY7o05XdXG46JiOKivD2RIIhijg1XJ8u0QqClRvb2wgVXNhZ2UwATmo5lhjMbr3F0EI0Vlj + Mbr3F0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjYxLjBKHAoJdG9vbF9uYW1lEg8KDUdldCBHcmVl + dGluZ3NKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABKQAgoQuAJS499ah/heU2Zd83EPahII6sKN + gGkZYwcqDlRhc2sgRXhlY3V0aW9uMAE5qH0rYzG69xdB0AGEYzG69xdKLgoIY3Jld19rZXkSIgog + N2U2NjA4OTg5ODU5YTY3ZWVjODhlZWY3ZmNlODUyMjVKMQoHY3Jld19pZBImCiQ2ZWY2MGE1YS0z + ZmFhLTRmZWEtOThiNC0wNjA2Y2Y1NDIyMThKLgoIdGFza19rZXkSIgogYTI3N2IzNGIyYzE0NmYw + YzU2YzVlMTM1NmU4ZjhhNTdKMQoHdGFza19pZBImCiRjY2FkY2QzOC1hZmJiLTQxYTItOTk3Ny01 + MGVmOTM5NWYzZGN6AhgBhQEAAQAAEtcHChAiig529TQaPEvvqDMUP2RCEgh9G9ouq8OtSCoMQ3Jl + dyBDcmVhdGVkMAE5OMPXYzG69xdB0PHZYzG69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42MS4w + ShoKDnB5dGhvbl92ZXJzaW9uEggKBjMuMTEuN0ouCghjcmV3X2tleRIiCiBjMzA3NjAwOTMyNjc2 + MTQ0NGQ1N2M3MWQxZGEzZjI3Y0oxCgdjcmV3X2lkEiYKJGE5YmE5NjYyLWUxZjUtNDFlOC05ZDAy + LTIxZTM5MTNlNDUzMEocCgxjcmV3X3Byb2Nlc3MSDAoKc2VxdWVudGlhbEoRCgtjcmV3X21lbW9y + eRICEABKGgoUY3Jld19udW1iZXJfb2ZfdGFza3MSAhgBShsKFWNyZXdfbnVtYmVyX29mX2FnZW50 + cxICGAFK7AIKC2NyZXdfYWdlbnRzEtwCCtkCW3sia2V5IjogIjk4ZjNiMWQ0N2NlOTY5Y2YwNTc3 + MjdiNzg0MTQyNWNkIiwgImlkIjogIjZiNTRiNWYxLTM5MWYtNDk5Ni04MmJhLTNkODFkZDAwNGU3 + ZSIsICJyb2xlIjogIkZyaWVuZGx5IE5laWdoYm9yIiwgInZlcmJvc2U/IjogZmFsc2UsICJtYXhf + aXRlciI6IDE1LCAibWF4X3JwbSI6IG51bGwsICJmdW5jdGlvbl9jYWxsaW5nX2xsbSI6IG51bGws + ICJsbG0iOiAiZ3B0LTRvLW1pbmkiLCAiZGVsZWdhdGlvbl9lbmFibGVkPyI6IGZhbHNlLCAiYWxs + b3dfY29kZV9leGVjdXRpb24/IjogZmFsc2UsICJtYXhfcmV0cnlfbGltaXQiOiAyLCAidG9vbHNf + bmFtZXMiOiBbImRlY2lkZSBncmVldGluZ3MiXX1dSpgCCgpjcmV3X3Rhc2tzEokCCoYCW3sia2V5 + IjogIjgwZDdiY2Q0OTA5OTI5MDA4MzgzMmYwZTk4MzM4MGRmIiwgImlkIjogIjMzMWM1Njg0LTll + ZWItNGQxYS04M2JlLTUzOWFhYzcxMDFlYyIsICJhc3luY19leGVjdXRpb24/IjogZmFsc2UsICJo + dW1hbl9pbnB1dD8iOiBmYWxzZSwgImFnZW50X3JvbGUiOiAiRnJpZW5kbHkgTmVpZ2hib3IiLCAi + YWdlbnRfa2V5IjogIjk4ZjNiMWQ0N2NlOTY5Y2YwNTc3MjdiNzg0MTQyNWNkIiwgInRvb2xzX25h + bWVzIjogWyJkZWNpZGUgZ3JlZXRpbmdzIl19XXoCGAGFAQABAAASjgIKEJs8Mv/UlB7rtDQlcTwb + xkUSCF7HzvF+Jv+NKgxUYXNrIENyZWF0ZWQwATkwoORjMbr3F0Gw3uRjMbr3F0ouCghjcmV3X2tl + eRIiCiBjMzA3NjAwOTMyNjc2MTQ0NGQ1N2M3MWQxZGEzZjI3Y0oxCgdjcmV3X2lkEiYKJGE5YmE5 + NjYyLWUxZjUtNDFlOC05ZDAyLTIxZTM5MTNlNDUzMEouCgh0YXNrX2tleRIiCiA4MGQ3YmNkNDkw + OTkyOTAwODM4MzJmMGU5ODMzODBkZkoxCgd0YXNrX2lkEiYKJDMzMWM1Njg0LTllZWItNGQxYS04 + M2JlLTUzOWFhYzcxMDFlY3oCGAGFAQABAAASkwEKEBhmxDJBQXBJQEYdfsZF8IoSCISCNNJHYQxr + KgpUb29sIFVzYWdlMAE5oCASZDG69xdBUNQSZDG69xdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC42 + MS4wSh8KCXRvb2xfbmFtZRISChBEZWNpZGUgR3JlZXRpbmdzSg4KCGF0dGVtcHRzEgIYAXoCGAGF + AQABAAASkAIKEL+NN0PPuC5jOyKsha1ap/ESCGdViZqeYEYtKg5UYXNrIEV4ZWN1dGlvbjABOdgB + 5WMxuvcXQeBbN2QxuvcXSi4KCGNyZXdfa2V5EiIKIGMzMDc2MDA5MzI2NzYxNDQ0ZDU3YzcxZDFk + YTNmMjdjSjEKB2NyZXdfaWQSJgokYTliYTk2NjItZTFmNS00MWU4LTlkMDItMjFlMzkxM2U0NTMw + Si4KCHRhc2tfa2V5EiIKIDgwZDdiY2Q0OTA5OTI5MDA4MzgzMmYwZTk4MzM4MGRmSjEKB3Rhc2tf + aWQSJgokMzMxYzU2ODQtOWVlYi00ZDFhLTgzYmUtNTM5YWFjNzEwMWVjegIYAYUBAAEAAA== + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '19945' + 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, 23 Sep 2024 01:08:29 GMT + status: + code: 200 + message: OK +- request: + body: '{"model": "gemma2:latest", "prompt": "### User:\nRespond in 20 words. Who + are you?\n\n", "options": {}, "stream": false}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '120' + Content-Type: + - application/json + User-Agent: + - python-requests/2.31.0 + method: POST + uri: http://localhost:8080/api/generate + response: + body: + string: '{"model":"gemma2:latest","created_at":"2024-09-23T01:08:41.087953Z","response":"I + am Gemma, an open-weights AI assistant, trained by Google DeepMind. \n","done":true,"done_reason":"stop","context":[106,1645,108,6176,4926,235292,108,54657,575,235248,235284,235276,3907,235265,7702,708,692,235336,109,107,108,106,2516,108,235285,1144,137061,235269,671,2174,235290,30316,16481,20409,235269,17363,731,6238,20555,35777,235265,139,108],"total_duration":17629147958,"load_duration":16557181458,"prompt_eval_count":25,"prompt_eval_duration":165374000,"eval_count":20,"eval_duration":892785000}' + headers: + Content-Length: + - '586' + Content-Type: + - application/json; charset=utf-8 + Date: + - Mon, 23 Sep 2024 01:08:41 GMT + status: + code: 200 + message: OK +version: 1 diff --git a/tests/cassettes/test_llm_call.yaml b/tests/cassettes/test_llm_call.yaml new file mode 100644 index 000000000..21073806a --- /dev/null +++ b/tests/cassettes/test_llm_call.yaml @@ -0,0 +1,100 @@ +interactions: +- request: + body: '{"messages": [{"role": "user", "content": "Say ''Hello, World!''"}], "model": + "gpt-3.5-turbo", "stop": []}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '104' + content-type: + - application/json + cookie: + - _cfuvid=7K_eaD_xGFyVkU_8XCBnbyvAO.pgSZQfDXm2KHhKt2A-1727042733333-0.0.1.1-604800000 + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.47.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.47.0 + x-stainless-raw-response: + - 'true' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.11.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + content: "{\n \"id\": \"chatcmpl-AAQPWuxVwbHi7g7feaoWsZ6Zq6LS2\",\n \"object\": + \"chat.completion\",\n \"created\": 1727048166,\n \"model\": \"gpt-3.5-turbo-0125\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"Hello, World!\",\n \"refusal\": + null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n + \ }\n ],\n \"usage\": {\n \"prompt_tokens\": 13,\n \"completion_tokens\": + 4,\n \"total_tokens\": 17,\n \"completion_tokens_details\": {\n \"reasoning_tokens\": + 0\n }\n },\n \"system_fingerprint\": null\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8c761d7c9f871d27-GRU + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Sun, 22 Sep 2024 23:36:06 GMT + Server: + - cloudflare + Set-Cookie: + - __cf_bm=_gC.xJkKcwzBxtax4MhKQ0DAp_ylhdSaowqm7lrfdA4-1727048166-1.0.1.1-qvPyGoAeO0VlJ5oTDrv9A6Y2jnnujAZpwu6ukvg.0vUine1I3k90Py4l5XoqAwIt6t0zCjIGgfoCgsYMm3fydQ; + path=/; expires=Mon, 23-Sep-24 00:06:06 GMT; domain=.api.openai.com; HttpOnly; + Secure; SameSite=None + - _cfuvid=FFmP82tY.BP0BFYwK4ix5zIa5fG5Ye7tnJ1DN70SSx4-1727048166266-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 + openai-organization: + - crewai-iuxna1 + openai-processing-ms: + - '97' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=15552000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '50000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '49999978' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_07e05ef0aa76dd4c22d59317a81f011d + http_version: HTTP/1.1 + status_code: 200 +version: 1 diff --git a/tests/cassettes/test_llm_call_with_all_attributes.yaml b/tests/cassettes/test_llm_call_with_all_attributes.yaml new file mode 100644 index 000000000..9fe8a79a6 --- /dev/null +++ b/tests/cassettes/test_llm_call_with_all_attributes.yaml @@ -0,0 +1,101 @@ +interactions: +- request: + body: '{"messages": [{"role": "user", "content": "Say ''Hello, World!'' and then + say STOP"}], "model": "gpt-3.5-turbo", "frequency_penalty": 0.1, "max_tokens": + 50, "presence_penalty": 0.1, "stop": ["STOP"], "temperature": 0.7}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '217' + content-type: + - application/json + cookie: + - _cfuvid=FFmP82tY.BP0BFYwK4ix5zIa5fG5Ye7tnJ1DN70SSx4-1727048166266-0.0.1.1-604800000 + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.47.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.47.0 + x-stainless-raw-response: + - 'true' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.11.7 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + content: "{\n \"id\": \"chatcmpl-AARioD9fe66arqP951Q6m1N5BgDqV\",\n \"object\": + \"chat.completion\",\n \"created\": 1727053206,\n \"model\": \"gpt-3.5-turbo-0125\",\n + \ \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": + \"assistant\",\n \"content\": \"Hello, World!\\n\",\n \"refusal\": + null\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n + \ }\n ],\n \"usage\": {\n \"prompt_tokens\": 17,\n \"completion_tokens\": + 4,\n \"total_tokens\": 21,\n \"completion_tokens_details\": {\n \"reasoning_tokens\": + 0\n }\n },\n \"system_fingerprint\": null\n}\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8c76988ceede8759-MIA + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Mon, 23 Sep 2024 01:00:06 GMT + Server: + - cloudflare + Set-Cookie: + - __cf_bm=XKEjZqa9jLHDkJm09f6GoOFObGBsS.2iO2iQsVxfDtg-1727053206-1.0.1.1-AhT2h4tFAfFhcbWhI7x8he9L6T0eCndS2.n6pMSK3iFkx0qYlA5Y.iniDaQVaO1ukiEEoEJGaV2tL967WYm1uA; + path=/; expires=Mon, 23-Sep-24 01:30:06 GMT; domain=.api.openai.com; HttpOnly; + Secure; SameSite=None + - _cfuvid=ntPBCCgVUz_nq5Umsn4Dh2nras_FFFm.Om6wrSeiU00-1727053206899-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 + openai-organization: + - crewai-iuxna1 + openai-processing-ms: + - '110' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=15552000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '50000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '49999938' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_e2bb166ffe6d65c17da2b1d3afaef830 + http_version: HTTP/1.1 + status_code: 200 +version: 1 diff --git a/tests/cassettes/test_llm_call_with_ollama_gemma.yaml b/tests/cassettes/test_llm_call_with_ollama_gemma.yaml new file mode 100644 index 000000000..57fcf242c --- /dev/null +++ b/tests/cassettes/test_llm_call_with_ollama_gemma.yaml @@ -0,0 +1,35 @@ +interactions: +- request: + body: '{"model": "gemma2:latest", "prompt": "### User:\nRespond in 20 words. Who + are you?\n\n", "options": {"num_predict": 30, "temperature": 0.7}, "stream": + false}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '157' + Content-Type: + - application/json + User-Agent: + - python-requests/2.31.0 + method: POST + uri: http://localhost:8080/api/generate + response: + body: + string: '{"model":"gemma2:latest","created_at":"2024-09-23T01:08:42.06813Z","response":"I + am Gemma, an open-weights AI assistant developed by Google DeepMind. \n","done":true,"done_reason":"stop","context":[106,1645,108,6176,4926,235292,108,54657,575,235248,235284,235276,3907,235265,7702,708,692,235336,109,107,108,106,2516,108,235285,1144,137061,235269,671,2174,235290,30316,16481,20409,6990,731,6238,20555,35777,235265,139,108],"total_duration":915752416,"load_duration":23754750,"prompt_eval_count":25,"prompt_eval_duration":47893000,"eval_count":19,"eval_duration":843461000}' + headers: + Content-Length: + - '572' + Content-Type: + - application/json; charset=utf-8 + Date: + - Mon, 23 Sep 2024 01:08:42 GMT + status: + code: 200 + message: OK +version: 1